]> git.proxmox.com Git - rustc.git/commitdiff
Imported Upstream version 1.0.0~beta
authorAngus Lees <gus@inodes.org>
Thu, 16 Apr 2015 10:08:53 +0000 (20:08 +1000)
committerAngus Lees <gus@inodes.org>
Thu, 16 Apr 2015 10:08:53 +0000 (20:08 +1000)
3839 files changed:
AUTHORS.txt
CONTRIBUTING.md
Makefile.in
README.md
RELEASES.md
configure
man/rustc.1
man/rustdoc.1
mk/cfg/x86_64-unknown-bitrig.mk [new file with mode: 0644]
mk/cfg/x86_64-unknown-linux-gnu.mk
mk/crates.mk
mk/debuggers.mk
mk/dist.mk
mk/docs.mk
mk/llvm.mk
mk/main.mk
mk/platform.mk
mk/prepare.mk
mk/target.mk
mk/tests.mk
mk/util.mk
src/compiletest/common.rs
src/compiletest/compiletest.rs
src/compiletest/errors.rs
src/compiletest/header.rs
src/compiletest/procsrv.rs
src/compiletest/runtest.rs
src/compiletest/util.rs
src/doc/complement-design-faq.md
src/doc/grammar.md
src/doc/guide-tasks.md
src/doc/index.md
src/doc/intro.md
src/doc/not_found.md
src/doc/reference.md
src/doc/rust.css
src/doc/style/errors/ergonomics.md
src/doc/trpl/README.md
src/doc/trpl/SUMMARY.md
src/doc/trpl/advanced-macros.md
src/doc/trpl/arrays-vectors-and-slices.md
src/doc/trpl/associated-types.md [new file with mode: 0644]
src/doc/trpl/basic.md
src/doc/trpl/benchmark-tests.md [new file with mode: 0644]
src/doc/trpl/box-syntax-and-patterns.md [new file with mode: 0644]
src/doc/trpl/closures.md
src/doc/trpl/comments.md
src/doc/trpl/compound-data-types.md
src/doc/trpl/concurrency.md
src/doc/trpl/crates-and-modules.md
src/doc/trpl/documentation.md
src/doc/trpl/error-handling.md
src/doc/trpl/ffi.md
src/doc/trpl/functions.md
src/doc/trpl/glossary.md
src/doc/trpl/guessing-game.md [deleted file]
src/doc/trpl/hello-cargo.md
src/doc/trpl/if.md
src/doc/trpl/inline-assembly.md [new file with mode: 0644]
src/doc/trpl/installing-rust.md
src/doc/trpl/intrinsics.md [new file with mode: 0644]
src/doc/trpl/iterators.md
src/doc/trpl/lang-items.md [new file with mode: 0644]
src/doc/trpl/link-args.md [new file with mode: 0644]
src/doc/trpl/looping.md
src/doc/trpl/macros.md
src/doc/trpl/method-syntax.md
src/doc/trpl/more-strings.md
src/doc/trpl/no-stdlib.md [new file with mode: 0644]
src/doc/trpl/ownership.md
src/doc/trpl/patterns.md
src/doc/trpl/plugins.md
src/doc/trpl/pointers.md
src/doc/trpl/standard-input.md [deleted file]
src/doc/trpl/static-and-dynamic-dispatch.md
src/doc/trpl/strings.md
src/doc/trpl/testing.md
src/doc/trpl/tracing-macros.md [new file with mode: 0644]
src/doc/trpl/traits.md
src/doc/trpl/unsafe.md
src/doc/trpl/unstable.md [new file with mode: 0644]
src/driver/driver.rs
src/etc/check-sanitycheck.py [new file with mode: 0644]
src/etc/featureck.py
src/etc/gdb_rust_pretty_printing.py
src/etc/htmldocck.py
src/etc/libc.c
src/etc/lldb_rust_formatters.py
src/etc/local_stage0.sh
src/etc/mingw-fix-include/README.txt
src/etc/mklldeps.py
src/etc/rustup.sh
src/etc/snapshot.py
src/etc/snapshot.pyc
src/etc/third-party/COPYING.RUNTIME
src/etc/tidy.py
src/etc/unicode.py
src/jemalloc/VERSION
src/jemalloc/configure
src/jemalloc/configure.ac
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/liballoc/boxed_test.rs
src/liballoc/heap.rs
src/liballoc/lib.rs
src/liballoc/rc.rs
src/libarena/lib.rs
src/libbacktrace/Makefile.am
src/libbacktrace/Makefile.in
src/libbacktrace/alloc.c
src/libbacktrace/atomic.c
src/libbacktrace/backtrace-supported.h.in
src/libbacktrace/backtrace.c
src/libbacktrace/backtrace.h
src/libbacktrace/btest.c
src/libbacktrace/configure
src/libbacktrace/configure.ac
src/libbacktrace/dwarf.c
src/libbacktrace/elf.c
src/libbacktrace/fileline.c
src/libbacktrace/hashtab.h
src/libbacktrace/internal.h
src/libbacktrace/ltmain.sh
src/libbacktrace/mmap.c
src/libbacktrace/mmapio.c
src/libbacktrace/nounwind.c
src/libbacktrace/posix.c
src/libbacktrace/print.c
src/libbacktrace/read.c
src/libbacktrace/simple.c
src/libbacktrace/state.c
src/libbacktrace/unknown.c
src/libcollections/bench.rs [deleted file]
src/libcollections/binary_heap.rs
src/libcollections/bit.rs
src/libcollections/borrow.rs
src/libcollections/borrow_stage0.rs [deleted file]
src/libcollections/btree/map.rs
src/libcollections/btree/node.rs
src/libcollections/btree/set.rs
src/libcollections/enum_set.rs
src/libcollections/fmt.rs
src/libcollections/lib.rs
src/libcollections/linked_list.rs
src/libcollections/macros.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcollections/vec_deque.rs
src/libcollections/vec_map.rs
src/libcollectionstest/bench.rs [new file with mode: 0644]
src/libcollectionstest/binary_heap.rs [new file with mode: 0644]
src/libcollectionstest/bit/mod.rs [new file with mode: 0644]
src/libcollectionstest/bit/set.rs [new file with mode: 0644]
src/libcollectionstest/bit/vec.rs [new file with mode: 0644]
src/libcollectionstest/btree/map.rs [new file with mode: 0644]
src/libcollectionstest/btree/mod.rs [new file with mode: 0644]
src/libcollectionstest/btree/set.rs [new file with mode: 0644]
src/libcollectionstest/enum_set.rs [new file with mode: 0644]
src/libcollectionstest/fmt.rs [new file with mode: 0644]
src/libcollectionstest/lib.rs [new file with mode: 0644]
src/libcollectionstest/linked_list.rs [new file with mode: 0644]
src/libcollectionstest/slice.rs [new file with mode: 0644]
src/libcollectionstest/str.rs [new file with mode: 0644]
src/libcollectionstest/string.rs [new file with mode: 0644]
src/libcollectionstest/vec.rs [new file with mode: 0644]
src/libcollectionstest/vec_deque.rs [new file with mode: 0644]
src/libcollectionstest/vec_map.rs [new file with mode: 0644]
src/libcore/any.rs
src/libcore/array.rs
src/libcore/atomic.rs
src/libcore/cell.rs
src/libcore/char.rs
src/libcore/clone.rs
src/libcore/cmp.rs
src/libcore/cmp_macros.rs [new file with mode: 0644]
src/libcore/convert.rs [new file with mode: 0644]
src/libcore/default.rs
src/libcore/error.rs [deleted file]
src/libcore/finally.rs [deleted file]
src/libcore/fmt/builders.rs [new file with mode: 0644]
src/libcore/fmt/float.rs
src/libcore/fmt/mod.rs
src/libcore/fmt/num.rs
src/libcore/fmt/rt/v1.rs
src/libcore/hash/mod.rs
src/libcore/hash/sip.rs
src/libcore/intrinsics.rs
src/libcore/iter.rs
src/libcore/lib.rs
src/libcore/macros.rs
src/libcore/marker.rs
src/libcore/mem.rs
src/libcore/num/f32.rs
src/libcore/num/f64.rs
src/libcore/num/float_macros.rs
src/libcore/num/int.rs [deleted file]
src/libcore/num/int_macros.rs
src/libcore/num/mod.rs
src/libcore/num/uint.rs [deleted file]
src/libcore/num/uint_macros.rs
src/libcore/num/wrapping.rs [new file with mode: 0644]
src/libcore/ops.rs
src/libcore/option.rs
src/libcore/panicking.rs
src/libcore/prelude.rs
src/libcore/ptr.rs
src/libcore/raw.rs
src/libcore/result.rs
src/libcore/simd.rs
src/libcore/slice.rs
src/libcore/str/mod.rs
src/libcore/str/pattern.rs [new file with mode: 0644]
src/libcore/tuple.rs
src/libcoretest/any.rs
src/libcoretest/cell.rs
src/libcoretest/char.rs
src/libcoretest/cmp.rs
src/libcoretest/finally.rs [deleted file]
src/libcoretest/fmt/builders.rs [new file with mode: 0644]
src/libcoretest/fmt/mod.rs
src/libcoretest/fmt/num.rs
src/libcoretest/hash/mod.rs
src/libcoretest/hash/sip.rs
src/libcoretest/intrinsics.rs
src/libcoretest/iter.rs
src/libcoretest/lib.rs
src/libcoretest/mem.rs
src/libcoretest/nonzero.rs
src/libcoretest/num/int.rs [deleted file]
src/libcoretest/num/int_macros.rs
src/libcoretest/num/mod.rs
src/libcoretest/num/uint.rs [deleted file]
src/libcoretest/num/uint_macros.rs
src/libcoretest/ops.rs
src/libcoretest/option.rs
src/libcoretest/ptr.rs
src/libcoretest/result.rs
src/libcoretest/slice.rs
src/libcoretest/str.rs
src/libflate/lib.rs
src/libfmt_macros/lib.rs
src/libgetopts/lib.rs
src/libgraphviz/lib.rs
src/liblibc/lib.rs
src/liblog/lib.rs
src/liblog/macros.rs
src/librand/chacha.rs
src/librand/distributions/exponential.rs
src/librand/distributions/gamma.rs
src/librand/distributions/mod.rs
src/librand/distributions/normal.rs
src/librand/distributions/range.rs
src/librand/isaac.rs
src/librand/lib.rs
src/librand/rand_impls.rs
src/librand/reseeding.rs
src/librbml/io.rs [deleted file]
src/librbml/lib.rs
src/librustc/README.md [new file with mode: 0644]
src/librustc/README.txt [deleted file]
src/librustc/diagnostics.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/macro_import.rs
src/librustc/metadata/tydecode.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/astconv_util.rs
src/librustc/middle/astencode.rs
src/librustc/middle/cfg/construct.rs
src/librustc/middle/cfg/graphviz.rs
src/librustc/middle/cfg/mod.rs
src/librustc/middle/check_const.rs
src/librustc/middle/check_loop.rs
src/librustc/middle/check_match.rs
src/librustc/middle/check_static_recursion.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/dependency_format.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/bivariate.rs
src/librustc/middle/infer/combine.rs
src/librustc/middle/infer/equate.rs
src/librustc/middle/infer/error_reporting.rs
src/librustc/middle/infer/freshen.rs
src/librustc/middle/infer/glb.rs
src/librustc/middle/infer/higher_ranked/mod.rs
src/librustc/middle/infer/lattice.rs
src/librustc/middle/infer/lub.rs
src/librustc/middle/infer/mod.rs
src/librustc/middle/infer/region_inference/README.md
src/librustc/middle/infer/region_inference/graphviz.rs
src/librustc/middle/infer/region_inference/mod.rs
src/librustc/middle/infer/resolve.rs
src/librustc/middle/infer/sub.rs
src/librustc/middle/infer/type_variable.rs
src/librustc/middle/infer/unify.rs
src/librustc/middle/intrinsicck.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/pat_util.rs
src/librustc/middle/privacy.rs
src/librustc/middle/reachable.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/middle/subst.rs
src/librustc/middle/traits/coherence.rs
src/librustc/middle/traits/error_reporting.rs
src/librustc/middle/traits/fulfill.rs
src/librustc/middle/traits/mod.rs
src/librustc/middle/traits/object_safety.rs
src/librustc/middle/traits/project.rs
src/librustc/middle/traits/select.rs
src/librustc/middle/traits/util.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/middle/ty_match.rs [new file with mode: 0644]
src/librustc/middle/ty_relate/mod.rs [new file with mode: 0644]
src/librustc/middle/ty_walk.rs
src/librustc/plugin/load.rs
src/librustc/plugin/mod.rs
src/librustc/plugin/registry.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc/session/search_paths.rs
src/librustc/util/common.rs
src/librustc/util/lev_distance.rs
src/librustc/util/nodemap.rs
src/librustc/util/ppaux.rs
src/librustc/util/snapshot_vec.rs
src/librustc_back/abi.rs
src/librustc_back/archive.rs
src/librustc_back/arm.rs
src/librustc_back/fs.rs
src/librustc_back/lib.rs
src/librustc_back/mips.rs
src/librustc_back/mipsel.rs
src/librustc_back/rpath.rs
src/librustc_back/sha2.rs
src/librustc_back/svh.rs
src/librustc_back/target/apple_ios_base.rs
src/librustc_back/target/bitrig_base.rs [new file with mode: 0644]
src/librustc_back/target/dragonfly_base.rs
src/librustc_back/target/freebsd_base.rs
src/librustc_back/target/mod.rs
src/librustc_back/target/openbsd_base.rs
src/librustc_back/target/x86_64_unknown_bitrig.rs [new file with mode: 0644]
src/librustc_back/tempdir.rs [new file with mode: 0644]
src/librustc_back/x86.rs
src/librustc_back/x86_64.rs
src/librustc_bitflags/lib.rs
src/librustc_borrowck/borrowck/README.md
src/librustc_borrowck/borrowck/check_loans.rs
src/librustc_borrowck/borrowck/fragments.rs
src/librustc_borrowck/borrowck/gather_loans/lifetime.rs
src/librustc_borrowck/borrowck/gather_loans/mod.rs
src/librustc_borrowck/borrowck/gather_loans/move_error.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_borrowck/borrowck/move_data.rs
src/librustc_borrowck/graphviz.rs
src/librustc_borrowck/lib.rs
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_driver/pretty.rs
src/librustc_driver/test.rs
src/librustc_lint/builtin.rs [new file with mode: 0644]
src/librustc_lint/lib.rs [new file with mode: 0644]
src/librustc_llvm/archive_ro.rs
src/librustc_llvm/diagnostic.rs
src/librustc_llvm/lib.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/check_unused.rs
src/librustc_resolve/diagnostics.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/record_exports.rs
src/librustc_resolve/resolve_imports.rs [new file with mode: 0644]
src/librustc_trans/README.txt
src/librustc_trans/back/link.rs
src/librustc_trans/back/lto.rs
src/librustc_trans/back/write.rs
src/librustc_trans/lib.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/build.rs
src/librustc_trans/trans/builder.rs
src/librustc_trans/trans/cabi.rs
src/librustc_trans/trans/cabi_aarch64.rs
src/librustc_trans/trans/cabi_arm.rs
src/librustc_trans/trans/cabi_mips.rs
src/librustc_trans/trans/cabi_powerpc.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/consts.rs
src/librustc_trans/trans/context.rs
src/librustc_trans/trans/controlflow.rs
src/librustc_trans/trans/datum.rs
src/librustc_trans/trans/debuginfo.rs
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/foreign.rs
src/librustc_trans/trans/glue.rs
src/librustc_trans/trans/inline.rs
src/librustc_trans/trans/intrinsic.rs
src/librustc_trans/trans/llrepr.rs
src/librustc_trans/trans/machine.rs
src/librustc_trans/trans/meth.rs
src/librustc_trans/trans/mod.rs
src/librustc_trans/trans/monomorphize.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/_match.rs
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/implicator.rs
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/op.rs [new file with mode: 0644]
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/upvar.rs
src/librustc_typeck/check/vtable.rs
src/librustc_typeck/check/wf.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/coherence/impls.rs [deleted file]
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/orphan.rs
src/librustc_typeck/coherence/overlap.rs
src/librustc_typeck/coherence/unsafety.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/diagnostics.rs
src/librustc_typeck/lib.rs
src/librustc_typeck/rscope.rs
src/librustc_typeck/variance.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/core.rs
src/librustdoc/doctree.rs
src/librustdoc/externalfiles.rs
src/librustdoc/flock.rs
src/librustdoc/fold.rs
src/librustdoc/html/format.rs
src/librustdoc/html/highlight.rs
src/librustdoc/html/item_type.rs
src/librustdoc/html/layout.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/Heuristica-LICENSE.txt
src/librustdoc/html/static/SourceCodePro-LICENSE.txt
src/librustdoc/html/static/SourceSerifPro-LICENSE.txt
src/librustdoc/html/static/main.css
src/librustdoc/html/static/main.js
src/librustdoc/html/static/playpen.js
src/librustdoc/html/toc.rs
src/librustdoc/lib.rs
src/librustdoc/markdown.rs
src/librustdoc/passes.rs
src/librustdoc/plugins.rs
src/librustdoc/stability_summary.rs
src/librustdoc/test.rs
src/librustdoc/visit_ast.rs
src/libserialize/collection_impls.rs
src/libserialize/hex.rs
src/libserialize/json.rs
src/libserialize/lib.rs
src/libserialize/serialize.rs
src/libstd/array.rs [new file with mode: 0644]
src/libstd/ascii.rs
src/libstd/bool.rs
src/libstd/collections/hash/bench.rs
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/map_stage0.rs [deleted file]
src/libstd/collections/hash/mod.rs
src/libstd/collections/hash/set.rs
src/libstd/collections/hash/set_stage0.rs [deleted file]
src/libstd/collections/hash/state.rs
src/libstd/collections/hash/table.rs
src/libstd/collections/mod.rs
src/libstd/dynamic_lib.rs
src/libstd/env.rs
src/libstd/error.rs [new file with mode: 0644]
src/libstd/ffi/c_str.rs
src/libstd/ffi/mod.rs
src/libstd/ffi/os_str.rs
src/libstd/fs.rs
src/libstd/io/buffered.rs
src/libstd/io/cursor.rs
src/libstd/io/error.rs
src/libstd/io/impls.rs
src/libstd/io/lazy.rs [new file with mode: 0644]
src/libstd/io/mod.rs
src/libstd/io/prelude.rs
src/libstd/io/stdio.rs [new file with mode: 0644]
src/libstd/io/util.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/net/addr.rs
src/libstd/net/ip.rs
src/libstd/net/mod.rs
src/libstd/net/parser.rs
src/libstd/net/tcp.rs
src/libstd/net/test.rs
src/libstd/net/udp.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/num/float_macros.rs
src/libstd/num/int.rs [deleted file]
src/libstd/num/mod.rs
src/libstd/num/strconv.rs
src/libstd/num/uint.rs [deleted file]
src/libstd/num/uint_macros.rs
src/libstd/old_io/buffered.rs
src/libstd/old_io/comm_adapters.rs
src/libstd/old_io/extensions.rs
src/libstd/old_io/fs.rs
src/libstd/old_io/mem.rs
src/libstd/old_io/mod.rs
src/libstd/old_io/net/addrinfo.rs
src/libstd/old_io/net/ip.rs
src/libstd/old_io/net/mod.rs
src/libstd/old_io/net/pipe.rs
src/libstd/old_io/net/tcp.rs
src/libstd/old_io/net/udp.rs
src/libstd/old_io/pipe.rs
src/libstd/old_io/process.rs
src/libstd/old_io/result.rs
src/libstd/old_io/stdio.rs
src/libstd/old_io/tempfile.rs
src/libstd/old_io/test.rs
src/libstd/old_io/timer.rs
src/libstd/old_io/util.rs
src/libstd/old_path/mod.rs
src/libstd/old_path/posix.rs
src/libstd/old_path/windows.rs
src/libstd/os.rs
src/libstd/panicking.rs
src/libstd/path.rs [changed mode: 0755->0644]
src/libstd/prelude/v1.rs
src/libstd/process.rs
src/libstd/rand/mod.rs
src/libstd/rand/os.rs
src/libstd/rand/reader.rs
src/libstd/rt/args.rs
src/libstd/rt/at_exit_imp.rs
src/libstd/rt/libunwind.rs
src/libstd/rt/mod.rs
src/libstd/rt/unwind.rs
src/libstd/rt/util.rs
src/libstd/rtdeps.rs
src/libstd/sync/barrier.rs
src/libstd/sync/condvar.rs
src/libstd/sync/future.rs
src/libstd/sync/mod.rs
src/libstd/sync/mpsc/blocking.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/mpsc/mpsc_queue.rs
src/libstd/sync/mpsc/oneshot.rs
src/libstd/sync/mpsc/select.rs
src/libstd/sync/mpsc/shared.rs
src/libstd/sync/mpsc/spsc_queue.rs
src/libstd/sync/mpsc/stream.rs
src/libstd/sync/mpsc/sync.rs
src/libstd/sync/mutex.rs
src/libstd/sync/once.rs
src/libstd/sync/poison.rs
src/libstd/sync/rwlock.rs
src/libstd/sync/semaphore.rs
src/libstd/sync/task_pool.rs [deleted file]
src/libstd/sys/common/backtrace.rs
src/libstd/sys/common/helper_thread.rs
src/libstd/sys/common/mod.rs
src/libstd/sys/common/net.rs
src/libstd/sys/common/net2.rs
src/libstd/sys/common/rwlock.rs
src/libstd/sys/common/stack.rs
src/libstd/sys/common/thread.rs
src/libstd/sys/common/thread_info.rs
src/libstd/sys/common/thread_local.rs
src/libstd/sys/common/wtf8.rs
src/libstd/sys/unix/backtrace.rs
src/libstd/sys/unix/c.rs
src/libstd/sys/unix/condvar.rs
src/libstd/sys/unix/ext.rs
src/libstd/sys/unix/fd.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/fs2.rs
src/libstd/sys/unix/helper_signal.rs
src/libstd/sys/unix/mod.rs
src/libstd/sys/unix/mutex.rs
src/libstd/sys/unix/net.rs
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/os_str.rs
src/libstd/sys/unix/pipe.rs
src/libstd/sys/unix/process.rs
src/libstd/sys/unix/process2.rs
src/libstd/sys/unix/rwlock.rs
src/libstd/sys/unix/stack_overflow.rs
src/libstd/sys/unix/stdio.rs [new file with mode: 0644]
src/libstd/sys/unix/sync.rs
src/libstd/sys/unix/tcp.rs
src/libstd/sys/unix/thread.rs
src/libstd/sys/unix/thread_local.rs
src/libstd/sys/unix/time.rs
src/libstd/sys/unix/timer.rs
src/libstd/sys/unix/tty.rs
src/libstd/sys/windows/backtrace.rs
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/condvar.rs
src/libstd/sys/windows/ext.rs
src/libstd/sys/windows/fs.rs
src/libstd/sys/windows/fs2.rs
src/libstd/sys/windows/handle.rs
src/libstd/sys/windows/mod.rs
src/libstd/sys/windows/mutex.rs
src/libstd/sys/windows/net.rs
src/libstd/sys/windows/os.rs
src/libstd/sys/windows/os_str.rs
src/libstd/sys/windows/pipe.rs
src/libstd/sys/windows/process.rs
src/libstd/sys/windows/process2.rs
src/libstd/sys/windows/rwlock.rs
src/libstd/sys/windows/stack_overflow.rs
src/libstd/sys/windows/stdio.rs [new file with mode: 0644]
src/libstd/sys/windows/tcp.rs
src/libstd/sys/windows/thread.rs
src/libstd/sys/windows/thread_local.rs
src/libstd/sys/windows/time.rs
src/libstd/sys/windows/timer.rs
src/libstd/sys/windows/tty.rs
src/libstd/thread.rs [deleted file]
src/libstd/thread/local.rs [new file with mode: 0644]
src/libstd/thread/mod.rs [new file with mode: 0644]
src/libstd/thread/scoped.rs [new file with mode: 0644]
src/libstd/thread_local/mod.rs [deleted file]
src/libstd/thread_local/scoped.rs [deleted file]
src/libstd/thunk.rs
src/libstd/time/duration.rs
src/libstd/tuple.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/config.rs
src/libsyntax/diagnostic.rs
src/libsyntax/diagnostics/macros.rs
src/libsyntax/diagnostics/plugin.rs
src/libsyntax/ext/asm.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/cfg.rs
src/libsyntax/ext/concat.rs
src/libsyntax/ext/concat_idents.rs
src/libsyntax/ext/deriving/bounds.rs
src/libsyntax/ext/deriving/clone.rs
src/libsyntax/ext/deriving/cmp/eq.rs
src/libsyntax/ext/deriving/cmp/ord.rs
src/libsyntax/ext/deriving/cmp/totaleq.rs
src/libsyntax/ext/deriving/cmp/totalord.rs
src/libsyntax/ext/deriving/decodable.rs
src/libsyntax/ext/deriving/default.rs
src/libsyntax/ext/deriving/encodable.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/deriving/hash.rs
src/libsyntax/ext/deriving/mod.rs
src/libsyntax/ext/deriving/primitive.rs
src/libsyntax/ext/deriving/rand.rs
src/libsyntax/ext/deriving/show.rs
src/libsyntax/ext/env.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/format.rs
src/libsyntax/ext/mtwt.rs
src/libsyntax/ext/quote.rs
src/libsyntax/ext/source_util.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/lib.rs
src/libsyntax/owned_slice.rs
src/libsyntax/parse/attr.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/ptr.rs
src/libsyntax/std_inject.rs
src/libsyntax/test.rs
src/libsyntax/util/interner.rs
src/libsyntax/util/parser_testing.rs
src/libsyntax/util/small_vector.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/libterm/win.rs
src/libtest/lib.rs
src/libtest/stats.rs
src/libunicode/char.rs [new file with mode: 0644]
src/libunicode/lib.rs
src/libunicode/tables.rs
src/libunicode/u_char.rs [deleted file]
src/libunicode/u_str.rs
src/llvm/autoconf/config.sub
src/llvm/autoconf/configure.ac
src/llvm/configure
src/llvm/docs/ReleaseNotes.rst
src/llvm/docs/index.rst
src/llvm/examples/Kaleidoscope/Chapter4/CMakeLists.txt
src/llvm/include/llvm/CodeGen/MachineModuleInfo.h
src/llvm/include/llvm/CodeGen/SelectionDAG.h
src/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
src/llvm/include/llvm/Config/config.h.cmake
src/llvm/include/llvm/Config/llvm-config.h.cmake
src/llvm/include/llvm/Config/llvm-config.h.in
src/llvm/include/llvm/IR/Constants.h
src/llvm/include/llvm/Target/TargetLibraryInfo.h
src/llvm/lib/Analysis/IPA/InlineCost.cpp
src/llvm/lib/Analysis/MemoryBuiltins.cpp
src/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
src/llvm/lib/Bitcode/Reader/BitcodeReader.h
src/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
src/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h
src/llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp
src/llvm/lib/CodeGen/AsmPrinter/Win64Exception.h
src/llvm/lib/CodeGen/MachineModuleInfo.cpp
src/llvm/lib/CodeGen/Passes.cpp
src/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
src/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
src/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
src/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
src/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
src/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
src/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
src/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
src/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
src/llvm/lib/ExecutionEngine/CMakeLists.txt
src/llvm/lib/ExecutionEngine/LLVMBuild.txt
src/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp [deleted file]
src/llvm/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
src/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp [new file with mode: 0644]
src/llvm/lib/IR/Constants.cpp
src/llvm/lib/IR/DebugInfo.cpp
src/llvm/lib/IR/Type.cpp
src/llvm/lib/MC/WinCOFFObjectWriter.cpp
src/llvm/lib/Target/TargetLibraryInfo.cpp
src/llvm/lib/Target/X86/X86ISelLowering.cpp
src/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
src/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
src/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
src/llvm/lib/Transforms/Scalar/MergedLoadStoreMotion.cpp
src/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
src/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
src/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
src/llvm/tools/gold/gold-plugin.cpp
src/llvm/tools/lli/CMakeLists.txt
src/llvm/unittests/ExecutionEngine/CMakeLists.txt
src/llvm/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
src/llvm/utils/llvm-build/llvmbuild/__init__.pyc
src/llvm/utils/llvm-build/llvmbuild/componentinfo.pyc
src/llvm/utils/llvm-build/llvmbuild/configutil.pyc
src/llvm/utils/llvm-build/llvmbuild/main.pyc
src/llvm/utils/llvm-build/llvmbuild/util.pyc
src/rt/arch/x86_64/morestack.S
src/rt/msvc/typeof.h
src/rt/rust_builtin.c
src/rt/valgrind/memcheck.h
src/rust-installer/.gitmodules
src/rust-installer/combine-installers.sh [changed mode: 0644->0755]
src/rust-installer/gen-install-script.sh
src/rust-installer/gen-installer.sh
src/rust-installer/install-template.sh
src/rust-installer/test.sh
src/rustbook/book.rs
src/rustbook/build.rs
src/rustbook/error.rs
src/rustbook/help.rs
src/rustbook/main.rs
src/rustbook/serve.rs
src/rustbook/subcommand.rs
src/rustbook/term.rs
src/rustbook/test.rs
src/rustllvm/PassWrapper.cpp
src/rustllvm/RustWrapper.cpp
src/rustllvm/llvm-auto-clean-trigger
src/snapshots.txt
src/test/auxiliary/ambig_impl_2_lib.rs
src/test/auxiliary/anon-extern-mod-cross-crate-1.rs
src/test/auxiliary/anon_trait_static_method_lib.rs
src/test/auxiliary/associated-types-cc-lib.rs
src/test/auxiliary/cci_borrow_lib.rs
src/test/auxiliary/cci_class.rs
src/test/auxiliary/cci_class_2.rs
src/test/auxiliary/cci_class_3.rs
src/test/auxiliary/cci_class_4.rs
src/test/auxiliary/cci_class_5.rs
src/test/auxiliary/cci_class_6.rs
src/test/auxiliary/cci_class_cast.rs
src/test/auxiliary/cci_const.rs
src/test/auxiliary/cci_const_block.rs
src/test/auxiliary/cci_impl_lib.rs
src/test/auxiliary/cci_intrinsic.rs
src/test/auxiliary/cci_iter_lib.rs
src/test/auxiliary/cci_nested_lib.rs
src/test/auxiliary/cci_no_inline_lib.rs
src/test/auxiliary/cfg_inner_static.rs
src/test/auxiliary/changing-crates-a2.rs
src/test/auxiliary/changing-crates-b.rs
src/test/auxiliary/check_static_recursion_foreign_helper.rs
src/test/auxiliary/coherence-lib.rs [deleted file]
src/test/auxiliary/coherence-orphan-lib.rs [deleted file]
src/test/auxiliary/coherence_copy_like_lib.rs [new file with mode: 0644]
src/test/auxiliary/coherence_lib.rs [new file with mode: 0644]
src/test/auxiliary/coherence_orphan_lib.rs [new file with mode: 0644]
src/test/auxiliary/crate_with_invalid_spans.rs [new file with mode: 0644]
src/test/auxiliary/crate_with_invalid_spans_macros.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve1-1.rs
src/test/auxiliary/crateresolve1-2.rs
src/test/auxiliary/crateresolve1-3.rs
src/test/auxiliary/crateresolve3-1.rs
src/test/auxiliary/crateresolve3-2.rs
src/test/auxiliary/crateresolve4a-1.rs
src/test/auxiliary/crateresolve4a-2.rs
src/test/auxiliary/crateresolve4b-1.rs
src/test/auxiliary/crateresolve4b-2.rs
src/test/auxiliary/crateresolve5-1.rs
src/test/auxiliary/crateresolve5-2.rs
src/test/auxiliary/crateresolve7x.rs
src/test/auxiliary/crateresolve8-1.rs
src/test/auxiliary/crateresolve_calories-1.rs
src/test/auxiliary/crateresolve_calories-2.rs
src/test/auxiliary/cross_crate_spans.rs [new file with mode: 0644]
src/test/auxiliary/custom_derive_plugin.rs [new file with mode: 0644]
src/test/auxiliary/default_type_params_xc.rs
src/test/auxiliary/extern-crosscrate-source.rs
src/test/auxiliary/extern_calling_convention.rs
src/test/auxiliary/foreign_lib.rs
src/test/auxiliary/go_trait.rs
src/test/auxiliary/impl_privacy_xc_1.rs
src/test/auxiliary/impl_privacy_xc_2.rs
src/test/auxiliary/inherit_struct_lib.rs
src/test/auxiliary/inherited_stability.rs
src/test/auxiliary/inner_static.rs
src/test/auxiliary/internal_unstable.rs [new file with mode: 0644]
src/test/auxiliary/iss.rs
src/test/auxiliary/issue-11224.rs
src/test/auxiliary/issue-11225-1.rs
src/test/auxiliary/issue-11225-2.rs
src/test/auxiliary/issue-11529.rs
src/test/auxiliary/issue-11680.rs [deleted file]
src/test/auxiliary/issue-12133-dylib2.rs
src/test/auxiliary/issue-12612-1.rs [deleted file]
src/test/auxiliary/issue-12612-2.rs [deleted file]
src/test/auxiliary/issue-13560-3.rs
src/test/auxiliary/issue-13620-2.rs
src/test/auxiliary/issue-13872-2.rs
src/test/auxiliary/issue-13872-3.rs
src/test/auxiliary/issue-14422.rs
src/test/auxiliary/issue-16725.rs [deleted file]
src/test/auxiliary/issue-17718-const-privacy.rs [deleted file]
src/test/auxiliary/issue-17718.rs
src/test/auxiliary/issue-21202.rs [deleted file]
src/test/auxiliary/issue-2414-a.rs
src/test/auxiliary/issue-2526.rs
src/test/auxiliary/issue-2631-a.rs
src/test/auxiliary/issue-3012-1.rs
src/test/auxiliary/issue-5521.rs
src/test/auxiliary/issue-8044.rs
src/test/auxiliary/issue-9906.rs
src/test/auxiliary/issue13213aux.rs
src/test/auxiliary/issue13507.rs
src/test/auxiliary/issue_11680.rs [new file with mode: 0644]
src/test/auxiliary/issue_12612_1.rs [new file with mode: 0644]
src/test/auxiliary/issue_12612_2.rs [new file with mode: 0644]
src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
src/test/auxiliary/issue_16725.rs [new file with mode: 0644]
src/test/auxiliary/issue_17718_const_privacy.rs [new file with mode: 0644]
src/test/auxiliary/issue_19293.rs
src/test/auxiliary/issue_21202.rs [new file with mode: 0644]
src/test/auxiliary/issue_2723_a.rs
src/test/auxiliary/issue_3907.rs
src/test/auxiliary/issue_3979_traits.rs
src/test/auxiliary/issue_5844_aux.rs
src/test/auxiliary/issue_8401.rs
src/test/auxiliary/issue_9123.rs
src/test/auxiliary/issue_9188.rs
src/test/auxiliary/kinds_in_metadata.rs
src/test/auxiliary/lang-item-public.rs
src/test/auxiliary/linkage-visibility.rs
src/test/auxiliary/linkage1.rs
src/test/auxiliary/lint-unused-extern-crate.rs [deleted file]
src/test/auxiliary/lint_for_crate.rs [new file with mode: 0644]
src/test/auxiliary/lint_group_plugin_test.rs
src/test/auxiliary/lint_output_format.rs [changed mode: 0755->0644]
src/test/auxiliary/lint_plugin_test.rs
src/test/auxiliary/lint_stability.rs
src/test/auxiliary/lint_stability_fields.rs [new file with mode: 0644]
src/test/auxiliary/lint_unused_extern_crate.rs [new file with mode: 0644]
src/test/auxiliary/logging_right_crate.rs
src/test/auxiliary/macro_crate_MacroRulesTT.rs
src/test/auxiliary/macro_crate_nonterminal.rs
src/test/auxiliary/macro_crate_test.rs
src/test/auxiliary/macro_reexport_1.rs
src/test/auxiliary/method_self_arg1.rs
src/test/auxiliary/method_self_arg2.rs
src/test/auxiliary/moves_based_on_type_lib.rs
src/test/auxiliary/namespaced_enum_emulate_flat.rs
src/test/auxiliary/namespaced_enums.rs
src/test/auxiliary/nested_item.rs
src/test/auxiliary/newtype_struct_xc.rs
src/test/auxiliary/noexporttypelib.rs
src/test/auxiliary/plugin_args.rs
src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs
src/test/auxiliary/plugin_with_plugin_lib.rs
src/test/auxiliary/priv-impl-prim-ty.rs
src/test/auxiliary/privacy-tuple-struct.rs [deleted file]
src/test/auxiliary/privacy_reexport.rs
src/test/auxiliary/privacy_tuple_struct.rs [new file with mode: 0644]
src/test/auxiliary/private_trait_xc.rs
src/test/auxiliary/procedural_mbe_matching.rs [new file with mode: 0644]
src/test/auxiliary/pub_static_array.rs [new file with mode: 0644]
src/test/auxiliary/pub_use_xcrate1.rs
src/test/auxiliary/reexported_static_methods.rs
src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs [deleted file]
src/test/auxiliary/regions_bounded_method_type_parameters_cross_crate_lib.rs [new file with mode: 0644]
src/test/auxiliary/rlib_crate_test.rs
src/test/auxiliary/roman_numerals.rs
src/test/auxiliary/sepcomp-extern-lib.rs
src/test/auxiliary/sepcomp_cci_lib.rs
src/test/auxiliary/sepcomp_lib.rs
src/test/auxiliary/static-function-pointer-aux.rs
src/test/auxiliary/static-methods-crate.rs
src/test/auxiliary/static_fn_inline_xc_aux.rs
src/test/auxiliary/static_fn_trait_xc_aux.rs
src/test/auxiliary/static_mut_xc.rs
src/test/auxiliary/static_priv_by_default.rs
src/test/auxiliary/struct-field-privacy.rs [deleted file]
src/test/auxiliary/struct_destructuring_cross_crate.rs
src/test/auxiliary/struct_field_privacy.rs [new file with mode: 0644]
src/test/auxiliary/struct_variant_privacy.rs
src/test/auxiliary/struct_variant_xc_aux.rs
src/test/auxiliary/svh-a-base.rs
src/test/auxiliary/svh-a-change-lit.rs
src/test/auxiliary/svh-a-change-significant-cfg.rs
src/test/auxiliary/svh-a-change-trait-bound.rs
src/test/auxiliary/svh-a-change-type-arg.rs
src/test/auxiliary/svh-a-change-type-ret.rs
src/test/auxiliary/svh-a-change-type-static.rs
src/test/auxiliary/svh-a-comment.rs
src/test/auxiliary/svh-a-doc.rs
src/test/auxiliary/svh-a-macro.rs
src/test/auxiliary/svh-a-no-change.rs
src/test/auxiliary/svh-a-redundant-cfg.rs
src/test/auxiliary/svh-a-whitespace.rs
src/test/auxiliary/svh-uta-base.rs
src/test/auxiliary/svh-uta-change-use-trait.rs
src/test/auxiliary/syntax_extension_with_dll_deps_1.rs
src/test/auxiliary/syntax_extension_with_dll_deps_2.rs
src/test/auxiliary/trait-safety-lib.rs [deleted file]
src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
src/test/auxiliary/trait_default_method_xc_aux.rs
src/test/auxiliary/trait_default_method_xc_aux_2.rs
src/test/auxiliary/trait_impl_conflict.rs
src/test/auxiliary/trait_inheritance_auto_xc_2_aux.rs
src/test/auxiliary/trait_inheritance_auto_xc_aux.rs
src/test/auxiliary/trait_inheritance_cross_trait_call_xc_aux.rs
src/test/auxiliary/trait_inheritance_overloading_xc.rs
src/test/auxiliary/trait_safety_lib.rs [new file with mode: 0644]
src/test/auxiliary/typeck_default_trait_impl_cross_crate_coherence_lib.rs [new file with mode: 0644]
src/test/auxiliary/typeid-intrinsic.rs
src/test/auxiliary/typeid-intrinsic2.rs
src/test/auxiliary/unboxed-closures-cross-crate.rs
src/test/auxiliary/unreachable-variant.rs [deleted file]
src/test/auxiliary/unreachable_variant.rs [new file with mode: 0644]
src/test/auxiliary/weak-lang-items.rs
src/test/auxiliary/where_clauses_xc.rs
src/test/auxiliary/xc_private_method_lib.rs
src/test/auxiliary/xcrate_address_insignificant.rs
src/test/auxiliary/xcrate_static_addresses.rs
src/test/auxiliary/xcrate_struct_aliases.rs
src/test/auxiliary/xcrate_unit_struct.rs
src/test/bench/core-map.rs
src/test/bench/core-set.rs
src/test/bench/core-std.rs
src/test/bench/msgsend-pipes-shared.rs
src/test/bench/msgsend-pipes.rs
src/test/bench/msgsend-ring-mutex-arcs.rs
src/test/bench/noise.rs
src/test/bench/shootout-binarytrees.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-fasta.rs
src/test/bench/shootout-k-nucleotide-pipes.rs
src/test/bench/shootout-k-nucleotide.rs
src/test/bench/shootout-mandelbrot.rs
src/test/bench/shootout-meteor.rs
src/test/bench/shootout-nbody.rs
src/test/bench/shootout-pfib.rs
src/test/bench/shootout-reverse-complement.rs
src/test/bench/shootout-spectralnorm.rs
src/test/bench/std-smallintmap.rs
src/test/bench/sudoku.rs
src/test/bench/task-perf-alloc-unwind.rs
src/test/bench/task-perf-jargon-metal-smoke.rs
src/test/codegen/iterate-over-array.rs
src/test/codegen/scalar-function-call.rs
src/test/codegen/single-return-value.rs
src/test/codegen/small-dense-int-switch.rs
src/test/codegen/static-method-call-multi.rs
src/test/codegen/static-method-call.rs
src/test/codegen/virtual-method-call-struct-return.rs
src/test/codegen/virtual-method-call.rs
src/test/compile-fail-fulldeps/gated-macro-reexports.rs [new file with mode: 0644]
src/test/compile-fail-fulldeps/gated-quote.rs [new file with mode: 0644]
src/test/compile-fail-fulldeps/issue-15778-fail.rs [new file with mode: 0644]
src/test/compile-fail-fulldeps/issue-18986.rs
src/test/compile-fail/array-not-vector.rs
src/test/compile-fail/asm-in-bad-modifier.rs
src/test/compile-fail/asm-misplaced-option.rs
src/test/compile-fail/asm-out-assign-imm.rs
src/test/compile-fail/asm-out-no-modifier.rs
src/test/compile-fail/assign-to-method.rs
src/test/compile-fail/assignment-operator-unimplemented.rs
src/test/compile-fail/associated-type-projection-ambig-between-bound-and-where-clause.rs [new file with mode: 0644]
src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
src/test/compile-fail/associated-types-coherence-failure.rs
src/test/compile-fail/associated-types-eq-expr-path.rs
src/test/compile-fail/associated-types-in-ambiguous-context.rs
src/test/compile-fail/associated-types-issue-17359.rs
src/test/compile-fail/bad-bang-ann-3.rs
src/test/compile-fail/bad-bang-ann.rs
src/test/compile-fail/bad-const-type.rs
src/test/compile-fail/bad-crate-id.rs [deleted file]
src/test/compile-fail/bad-crate-id2.rs [deleted file]
src/test/compile-fail/bad-method-typaram-kind.rs
src/test/compile-fail/bad-mid-path-type-params.rs
src/test/compile-fail/binop-fail-3.rs [deleted file]
src/test/compile-fail/binop-logic-float.rs
src/test/compile-fail/binop-logic-int.rs
src/test/compile-fail/borrow-immutable-upvar-mutation.rs
src/test/compile-fail/borrow-tuple-fields.rs
src/test/compile-fail/borrowck-bad-nested-calls-free.rs
src/test/compile-fail/borrowck-bad-nested-calls-move.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-borrow-immut-deref-of-box-as-mut.rs
src/test/compile-fail/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs
src/test/compile-fail/borrowck-borrowed-uniq-rvalue.rs
src/test/compile-fail/borrowck-box-insensitivity.rs
src/test/compile-fail/borrowck-call-is-borrow-issue-12224.rs
src/test/compile-fail/borrowck-closures-mut-and-imm.rs
src/test/compile-fail/borrowck-closures-two-mut.rs
src/test/compile-fail/borrowck-closures-unique-imm.rs
src/test/compile-fail/borrowck-closures-use-after-free.rs
src/test/compile-fail/borrowck-consume-unsize-vec.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-consume-upcast-box.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-field-sensitivity.rs
src/test/compile-fail/borrowck-fn-in-const-a.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-fn-in-const-b.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-fn-in-const-c.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-for-loop-correct-cmt-for-pattern.rs
src/test/compile-fail/borrowck-for-loop-head-linkage.rs
src/test/compile-fail/borrowck-issue-14498.rs
src/test/compile-fail/borrowck-issue-2657-1.rs
src/test/compile-fail/borrowck-issue-2657-2.rs
src/test/compile-fail/borrowck-lend-flow-if.rs
src/test/compile-fail/borrowck-lend-flow-loop.rs
src/test/compile-fail/borrowck-lend-flow.rs
src/test/compile-fail/borrowck-let-suggestion.rs
src/test/compile-fail/borrowck-loan-blocks-move-cc.rs
src/test/compile-fail/borrowck-loan-blocks-mut-uniq.rs
src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
src/test/compile-fail/borrowck-match-binding-is-assignment.rs
src/test/compile-fail/borrowck-move-by-capture.rs
src/test/compile-fail/borrowck-move-error-with-note.rs
src/test/compile-fail/borrowck-move-from-subpath-of-borrowed-path.rs
src/test/compile-fail/borrowck-move-moved-value-into-closure.rs
src/test/compile-fail/borrowck-move-mut-base-ptr.rs
src/test/compile-fail/borrowck-move-out-of-vec-tail.rs
src/test/compile-fail/borrowck-multiple-captures.rs
src/test/compile-fail/borrowck-mut-borrow-of-mut-base-ptr.rs
src/test/compile-fail/borrowck-mutate-in-guard.rs
src/test/compile-fail/borrowck-no-cycle-in-exchange-heap.rs
src/test/compile-fail/borrowck-object-lifetime.rs
src/test/compile-fail/borrowck-object-mutability.rs
src/test/compile-fail/borrowck-overloaded-call.rs
src/test/compile-fail/borrowck-overloaded-index-2.rs [deleted file]
src/test/compile-fail/borrowck-overloaded-index-and-overloaded-deref.rs
src/test/compile-fail/borrowck-overloaded-index-autoderef.rs
src/test/compile-fail/borrowck-overloaded-index-move-from-vec.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-overloaded-index-move-index.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-overloaded-index-ref-index.rs [new file with mode: 0644]
src/test/compile-fail/borrowck-overloaded-index.rs [deleted file]
src/test/compile-fail/borrowck-partial-reinit-2.rs
src/test/compile-fail/borrowck-report-with-custom-diagnostic.rs
src/test/compile-fail/borrowck-swap-mut-base-ptr.rs
src/test/compile-fail/borrowck-unboxed-closures.rs
src/test/compile-fail/borrowck-uniq-via-lend.rs
src/test/compile-fail/borrowck-use-mut-borrow.rs
src/test/compile-fail/borrowck-vec-pattern-element-loan.rs
src/test/compile-fail/borrowck-vec-pattern-loan-from-mut.rs
src/test/compile-fail/borrowck-vec-pattern-move-tail.rs
src/test/compile-fail/borrowck-vec-pattern-nesting.rs
src/test/compile-fail/borrowck-vec-pattern-tail-element-loan.rs
src/test/compile-fail/cannot-mutate-captured-non-mut-var.rs
src/test/compile-fail/cfg-attr-unknown-attribute-macro-expansion.rs [new file with mode: 0644]
src/test/compile-fail/class-method-missing.rs
src/test/compile-fail/class-missing-self.rs
src/test/compile-fail/closure-reform-bad.rs
src/test/compile-fail/coerce-unsafe-to-closure.rs
src/test/compile-fail/coercion-slice.rs
src/test/compile-fail/coherence-all-remote.rs
src/test/compile-fail/coherence-bigint-param.rs
src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs
src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs
src/test/compile-fail/coherence-blanket-conflicts-with-specific-cross-crate.rs
src/test/compile-fail/coherence-blanket-conflicts-with-specific-multidispatch.rs
src/test/compile-fail/coherence-blanket-conflicts-with-specific.rs
src/test/compile-fail/coherence-cow-1.rs [new file with mode: 0644]
src/test/compile-fail/coherence-cow-2.rs [new file with mode: 0644]
src/test/compile-fail/coherence-cow-no-cover.rs
src/test/compile-fail/coherence-default-trait-impl.rs [new file with mode: 0644]
src/test/compile-fail/coherence-impls-builtin.rs [deleted file]
src/test/compile-fail/coherence-impls-copy.rs [new file with mode: 0644]
src/test/compile-fail/coherence-impls-send.rs [new file with mode: 0644]
src/test/compile-fail/coherence-impls-sized.rs [new file with mode: 0644]
src/test/compile-fail/coherence-lone-type-parameter.rs
src/test/compile-fail/coherence-orphan.rs
src/test/compile-fail/coherence-overlap-issue-23516.rs [new file with mode: 0644]
src/test/compile-fail/coherence-overlapping-pairs.rs
src/test/compile-fail/coherence-pair-covered-uncovered-1.rs
src/test/compile-fail/coherence-pair-covered-uncovered.rs
src/test/compile-fail/coherence-tuple-conflict.rs
src/test/compile-fail/coherence-vec-local-2.rs [new file with mode: 0644]
src/test/compile-fail/coherence-vec-local.rs [new file with mode: 0644]
src/test/compile-fail/coherence_copy_like_err_fundamental_struct.rs [new file with mode: 0644]
src/test/compile-fail/coherence_copy_like_err_fundamental_struct_ref.rs [new file with mode: 0644]
src/test/compile-fail/coherence_copy_like_err_fundamental_struct_tuple.rs [new file with mode: 0644]
src/test/compile-fail/coherence_copy_like_err_struct.rs [new file with mode: 0644]
src/test/compile-fail/coherence_copy_like_err_tuple.rs [new file with mode: 0644]
src/test/compile-fail/coherence_local.rs [new file with mode: 0644]
src/test/compile-fail/coherence_local_err_struct.rs [new file with mode: 0644]
src/test/compile-fail/coherence_local_err_tuple.rs [new file with mode: 0644]
src/test/compile-fail/coherence_local_ref.rs [new file with mode: 0644]
src/test/compile-fail/const-array-oob.rs [new file with mode: 0644]
src/test/compile-fail/const-block-non-item-statement.rs
src/test/compile-fail/const-eval-overflow-2.rs [new file with mode: 0644]
src/test/compile-fail/const-eval-overflow-3.rs [new file with mode: 0644]
src/test/compile-fail/const-eval-overflow-3b.rs [new file with mode: 0644]
src/test/compile-fail/const-eval-overflow-4.rs [new file with mode: 0644]
src/test/compile-fail/const-eval-overflow-4b.rs [new file with mode: 0644]
src/test/compile-fail/const-eval-overflow.rs [new file with mode: 0644]
src/test/compile-fail/const-len-underflow-separate-spans.rs [new file with mode: 0644]
src/test/compile-fail/const-len-underflow-subspans.rs [new file with mode: 0644]
src/test/compile-fail/cross-borrow-trait.rs
src/test/compile-fail/custom_attribute.rs
src/test/compile-fail/cycle-projection-based-on-where-clause.rs [new file with mode: 0644]
src/test/compile-fail/cycle-trait-default-type-trait.rs [new file with mode: 0644]
src/test/compile-fail/cycle-trait-supertrait-direct.rs [new file with mode: 0644]
src/test/compile-fail/cycle-trait-supertrait-indirect.rs [new file with mode: 0644]
src/test/compile-fail/deprecated-phase.rs [deleted file]
src/test/compile-fail/derive-assoc-type-not-impl.rs [new file with mode: 0644]
src/test/compile-fail/derive-no-std-not-supported.rs
src/test/compile-fail/deriving-bounds.rs
src/test/compile-fail/deriving-is-deprecated.rs [deleted file]
src/test/compile-fail/deriving-meta-unknown-trait.rs
src/test/compile-fail/deriving-non-type.rs
src/test/compile-fail/destructor-restrictions.rs
src/test/compile-fail/discrim-ill-typed.rs [new file with mode: 0644]
src/test/compile-fail/discrim-overflow-2.rs [new file with mode: 0644]
src/test/compile-fail/discrim-overflow.rs [new file with mode: 0644]
src/test/compile-fail/drop-with-active-borrows-1.rs
src/test/compile-fail/dropck_arr_cycle_checked.rs
src/test/compile-fail/dropck_no_diverge_on_nonregular_1.rs [new file with mode: 0644]
src/test/compile-fail/dropck_no_diverge_on_nonregular_2.rs [new file with mode: 0644]
src/test/compile-fail/dropck_no_diverge_on_nonregular_3.rs [new file with mode: 0644]
src/test/compile-fail/dropck_tarena_cycle_checked.rs
src/test/compile-fail/dropck_vec_cycle_checked.rs
src/test/compile-fail/dst-bad-assign-2.rs
src/test/compile-fail/dst-bad-assign.rs
src/test/compile-fail/dst-bad-coerce1.rs
src/test/compile-fail/dst-index.rs
src/test/compile-fail/duplicate-parameter.rs
src/test/compile-fail/duplicate-trait-bounds.rs [deleted file]
src/test/compile-fail/duplicate-type-parameter.rs
src/test/compile-fail/empty-extern-arg.rs
src/test/compile-fail/enum-discrim-too-small.rs
src/test/compile-fail/estr-subtyping.rs
src/test/compile-fail/eval-enum.rs
src/test/compile-fail/exclusive-drop-and-copy.rs
src/test/compile-fail/explicit-self-lifetime-mismatch.rs
src/test/compile-fail/extern-with-type-bounds.rs
src/test/compile-fail/extern-wrong-value-type.rs
src/test/compile-fail/feature-gate-advanced-slice-features.rs
src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-allow-internal-unstable.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-box-expr.rs
src/test/compile-fail/feature-gate-int-uint.rs [deleted file]
src/test/compile-fail/feature-gate-intrinsics-and-lang-items.rs [deleted file]
src/test/compile-fail/feature-gate-intrinsics.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-lang-items.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-rust-call.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-simd-ffi.rs
src/test/compile-fail/feature-gate-start.rs
src/test/compile-fail/feature-gate-static-assert.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-unboxed-closures-manual-impls.rs
src/test/compile-fail/feature-gated-feature-in-macro-arg.rs
src/test/compile-fail/fn-compare-mismatch.rs
src/test/compile-fail/fn-trait-formatting.rs
src/test/compile-fail/fn-variance-1.rs
src/test/compile-fail/gated-box-patterns.rs [new file with mode: 0644]
src/test/compile-fail/gated-box-syntax.rs [new file with mode: 0644]
src/test/compile-fail/gated-link-args.rs [new file with mode: 0644]
src/test/compile-fail/gated-link-llvm-intrinsics.rs [new file with mode: 0644]
src/test/compile-fail/gated-plugin_registrar.rs
src/test/compile-fail/gated-simd-ffi.rs [new file with mode: 0644]
src/test/compile-fail/gated-thread-local.rs [new file with mode: 0644]
src/test/compile-fail/gated-unsafe-destructor.rs [new file with mode: 0644]
src/test/compile-fail/generic-impl-less-params-with-defaults.rs
src/test/compile-fail/generic-impl-more-params-with-defaults.rs
src/test/compile-fail/generic-no-mangle.rs
src/test/compile-fail/glob-resolve1.rs
src/test/compile-fail/hrtb-precedence-of-plus-error-message.rs [deleted file]
src/test/compile-fail/huge-array-simple.rs
src/test/compile-fail/if-loop.rs [new file with mode: 0644]
src/test/compile-fail/impl-duplicate-methods.rs
src/test/compile-fail/impl-not-adjacent-to-type.rs [deleted file]
src/test/compile-fail/import-glob-circular.rs
src/test/compile-fail/index-bot.rs
src/test/compile-fail/indexing-requires-a-uint.rs
src/test/compile-fail/infinite-instantiation.rs
src/test/compile-fail/infinite-macro-expansion.rs
src/test/compile-fail/infinite-vec-type-recursion.rs
src/test/compile-fail/inner-static-type-parameter.rs
src/test/compile-fail/integral-indexing.rs
src/test/compile-fail/internal-unstable-noallow.rs [new file with mode: 0644]
src/test/compile-fail/internal-unstable-thread-local.rs [new file with mode: 0644]
src/test/compile-fail/internal-unstable.rs [new file with mode: 0755]
src/test/compile-fail/intrinsic-return-address.rs
src/test/compile-fail/invalid-inline.rs [new file with mode: 0644]
src/test/compile-fail/issue-10291.rs
src/test/compile-fail/issue-10398.rs
src/test/compile-fail/issue-10536.rs
src/test/compile-fail/issue-11192.rs
src/test/compile-fail/issue-11374.rs
src/test/compile-fail/issue-11515.rs
src/test/compile-fail/issue-11593.rs
src/test/compile-fail/issue-11680.rs
src/test/compile-fail/issue-11714.rs
src/test/compile-fail/issue-11771.rs
src/test/compile-fail/issue-11844.rs
src/test/compile-fail/issue-11925.rs
src/test/compile-fail/issue-12041.rs
src/test/compile-fail/issue-12127.rs
src/test/compile-fail/issue-12369.rs
src/test/compile-fail/issue-12567.rs
src/test/compile-fail/issue-12612.rs
src/test/compile-fail/issue-12729.rs [deleted file]
src/test/compile-fail/issue-13058.rs
src/test/compile-fail/issue-13352.rs [new file with mode: 0644]
src/test/compile-fail/issue-13407.rs [new file with mode: 0644]
src/test/compile-fail/issue-13446.rs
src/test/compile-fail/issue-13466.rs
src/test/compile-fail/issue-13482-2.rs
src/test/compile-fail/issue-13482.rs
src/test/compile-fail/issue-13641.rs
src/test/compile-fail/issue-13853-3.rs [deleted file]
src/test/compile-fail/issue-13853-4.rs [deleted file]
src/test/compile-fail/issue-14092.rs
src/test/compile-fail/issue-14254.rs
src/test/compile-fail/issue-14845.rs
src/test/compile-fail/issue-15094.rs
src/test/compile-fail/issue-15381.rs
src/test/compile-fail/issue-16149.rs
src/test/compile-fail/issue-16338.rs
src/test/compile-fail/issue-16465.rs [deleted file]
src/test/compile-fail/issue-16538.rs
src/test/compile-fail/issue-16725.rs
src/test/compile-fail/issue-16747.rs
src/test/compile-fail/issue-16922.rs [new file with mode: 0644]
src/test/compile-fail/issue-17263.rs
src/test/compile-fail/issue-17283.rs
src/test/compile-fail/issue-17441.rs
src/test/compile-fail/issue-17651.rs
src/test/compile-fail/issue-17718-const-bad-values.rs
src/test/compile-fail/issue-17718-const-privacy.rs
src/test/compile-fail/issue-17718-patterns.rs
src/test/compile-fail/issue-17913.rs
src/test/compile-fail/issue-17933.rs
src/test/compile-fail/issue-18107.rs
src/test/compile-fail/issue-18252.rs
src/test/compile-fail/issue-18389.rs
src/test/compile-fail/issue-18400.rs
src/test/compile-fail/issue-18566.rs
src/test/compile-fail/issue-18783.rs
src/test/compile-fail/issue-18919.rs [new file with mode: 0644]
src/test/compile-fail/issue-18959.rs
src/test/compile-fail/issue-19244-1.rs
src/test/compile-fail/issue-19244-2.rs
src/test/compile-fail/issue-19660.rs
src/test/compile-fail/issue-19883.rs
src/test/compile-fail/issue-19982.rs [new file with mode: 0644]
src/test/compile-fail/issue-19991.rs
src/test/compile-fail/issue-20225.rs [new file with mode: 0644]
src/test/compile-fail/issue-20261.rs [new file with mode: 0644]
src/test/compile-fail/issue-20714.rs [new file with mode: 0644]
src/test/compile-fail/issue-20801.rs
src/test/compile-fail/issue-21202.rs
src/test/compile-fail/issue-2149.rs
src/test/compile-fail/issue-2150.rs
src/test/compile-fail/issue-22426-1.rs [new file with mode: 0644]
src/test/compile-fail/issue-22426-2.rs [new file with mode: 0644]
src/test/compile-fail/issue-22426-3.rs [new file with mode: 0644]
src/test/compile-fail/issue-22912.rs [new file with mode: 0644]
src/test/compile-fail/issue-23080-2.rs [new file with mode: 0644]
src/test/compile-fail/issue-23080.rs [new file with mode: 0644]
src/test/compile-fail/issue-2356.rs
src/test/compile-fail/issue-3008-2.rs
src/test/compile-fail/issue-3521-2.rs
src/test/compile-fail/issue-3521.rs
src/test/compile-fail/issue-3668-2.rs
src/test/compile-fail/issue-3668.rs
src/test/compile-fail/issue-3763.rs
src/test/compile-fail/issue-3907.rs
src/test/compile-fail/issue-3953.rs [deleted file]
src/test/compile-fail/issue-3973.rs
src/test/compile-fail/issue-4265.rs
src/test/compile-fail/issue-4335.rs
src/test/compile-fail/issue-4517.rs
src/test/compile-fail/issue-5239-1.rs
src/test/compile-fail/issue-5543.rs [deleted file]
src/test/compile-fail/issue-5844.rs
src/test/compile-fail/issue-6804.rs
src/test/compile-fail/issue-7575.rs
src/test/compile-fail/issue-7607-1.rs
src/test/compile-fail/issue-7607-2.rs [deleted file]
src/test/compile-fail/issue-7867.rs
src/test/compile-fail/issue-7950.rs [new file with mode: 0644]
src/test/compile-fail/issue-8460-const.rs
src/test/compile-fail/issue-8767.rs
src/test/compile-fail/issue-9814.rs
src/test/compile-fail/kindck-copy.rs
src/test/compile-fail/kindck-destructor-owned.rs [deleted file]
src/test/compile-fail/kindck-impl-type-params-2.rs
src/test/compile-fail/kindck-impl-type-params.rs
src/test/compile-fail/kindck-inherited-copy-bound.rs
src/test/compile-fail/kindck-nonsendable-1.rs
src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs
src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-2.rs
src/test/compile-fail/linkage1.rs
src/test/compile-fail/linkage3.rs
src/test/compile-fail/lint-dead-code-3.rs
src/test/compile-fail/lint-dead-code-4.rs
src/test/compile-fail/lint-exceeding-bitshifts.rs
src/test/compile-fail/lint-missing-doc.rs
src/test/compile-fail/lint-non-camel-case-types.rs
src/test/compile-fail/lint-output-format.rs
src/test/compile-fail/lint-stability-fields.rs [new file with mode: 0644]
src/test/compile-fail/lint-stability.rs
src/test/compile-fail/lint-stability3.rs
src/test/compile-fail/lint-type-limits.rs
src/test/compile-fail/lint-unnecessary-casts.rs [deleted file]
src/test/compile-fail/lint-unsafe-block.rs [deleted file]
src/test/compile-fail/lint-unsafe-code.rs [new file with mode: 0644]
src/test/compile-fail/lint-unused-extern-crate.rs
src/test/compile-fail/lint-uppercase-variables.rs
src/test/compile-fail/liveness-issue-2163.rs
src/test/compile-fail/liveness-return-last-stmt-semi.rs
src/test/compile-fail/liveness-unused.rs
src/test/compile-fail/liveness-use-after-move.rs
src/test/compile-fail/loop-labeled-break-value.rs [new file with mode: 0644]
src/test/compile-fail/macro-inner-attributes.rs
src/test/compile-fail/macro-no-implicit-reexport.rs
src/test/compile-fail/macro-outer-attributes.rs
src/test/compile-fail/macro-reexport-not-locally-visible.rs
src/test/compile-fail/malformed-derive-entry.rs [new file with mode: 0644]
src/test/compile-fail/malformed-plugin-1.rs
src/test/compile-fail/malformed-plugin-2.rs
src/test/compile-fail/malformed-plugin-3.rs
src/test/compile-fail/manual-link-bad-form.rs
src/test/compile-fail/manual-link-bad-kind.rs
src/test/compile-fail/manual-link-bad-search-path.rs [new file with mode: 0644]
src/test/compile-fail/manual-link-framework.rs
src/test/compile-fail/map-types.rs
src/test/compile-fail/match-ref-ice.rs [new file with mode: 0644]
src/test/compile-fail/match-ref-mut-invariance.rs [new file with mode: 0644]
src/test/compile-fail/match-ref-mut-let-invariance.rs [new file with mode: 0644]
src/test/compile-fail/match-vec-fixed.rs
src/test/compile-fail/match-vec-mismatch-2.rs
src/test/compile-fail/match-vec-mismatch.rs
src/test/compile-fail/match-vec-unreachable.rs
src/test/compile-fail/method-ambig-two-traits-cross-crate.rs
src/test/compile-fail/method-macro-backtrace.rs
src/test/compile-fail/method-missing-call.rs
src/test/compile-fail/method-self-arg-1.rs
src/test/compile-fail/method-suggestion-no-duplication.rs
src/test/compile-fail/move-in-guard-1.rs [new file with mode: 0644]
src/test/compile-fail/move-in-guard-2.rs [new file with mode: 0644]
src/test/compile-fail/move-out-of-tuple-field.rs
src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs
src/test/compile-fail/mut-cross-borrowing.rs
src/test/compile-fail/mut-pattern-mismatched.rs
src/test/compile-fail/mutable-class-fields-2.rs
src/test/compile-fail/mutable-class-fields.rs
src/test/compile-fail/no-implicit-prelude-nested.rs
src/test/compile-fail/no-implicit-prelude.rs
src/test/compile-fail/non-constant-enum-for-vec-repeat.rs
src/test/compile-fail/non-constant-expr-for-fixed-len-vec.rs
src/test/compile-fail/non-constant-expr-for-vec-repeat.rs
src/test/compile-fail/non-exhaustive-match-nested.rs
src/test/compile-fail/non-exhaustive-match.rs
src/test/compile-fail/non-exhaustive-pattern-witness.rs
src/test/compile-fail/nonbool_static_assert.rs [new file with mode: 0644]
src/test/compile-fail/object-lifetime-default-elision.rs
src/test/compile-fail/object-lifetime-default-from-box-error.rs
src/test/compile-fail/object-safety-by-value-self-use.rs [new file with mode: 0644]
src/test/compile-fail/object-safety-by-value-self.rs
src/test/compile-fail/object-safety-generics.rs
src/test/compile-fail/object-safety-mentions-Self.rs
src/test/compile-fail/opt-in-copy.rs
src/test/compile-fail/or-patter-mismatch.rs
src/test/compile-fail/overloaded-calls-bad.rs
src/test/compile-fail/overloaded-calls-nontuple.rs
src/test/compile-fail/pattern-bindings-after-at.rs
src/test/compile-fail/pattern-ident-path-generics.rs
src/test/compile-fail/phantom-oibit.rs [new file with mode: 0644]
src/test/compile-fail/plugin-extern-crate-attr-deprecated.rs [deleted file]
src/test/compile-fail/priv_in_pub_sig_priv_mod.rs [new file with mode: 0644]
src/test/compile-fail/privacy1.rs
src/test/compile-fail/privacy5.rs
src/test/compile-fail/private-method.rs
src/test/compile-fail/private-struct-field-cross-crate.rs
src/test/compile-fail/pub-method-macro.rs
src/test/compile-fail/range-1.rs
src/test/compile-fail/recursion.rs
src/test/compile-fail/recursion_limit.rs
src/test/compile-fail/reflect-assoc.rs [new file with mode: 0644]
src/test/compile-fail/reflect-object-param.rs [new file with mode: 0644]
src/test/compile-fail/reflect.rs [new file with mode: 0644]
src/test/compile-fail/region-bound-on-closure-outlives-call.rs
src/test/compile-fail/region-object-lifetime-1.rs
src/test/compile-fail/region-object-lifetime-2.rs
src/test/compile-fail/region-object-lifetime-3.rs
src/test/compile-fail/region-object-lifetime-4.rs
src/test/compile-fail/region-object-lifetime-5.rs
src/test/compile-fail/region-object-lifetime-in-coercion.rs
src/test/compile-fail/regionck-unboxed-closure-lifetimes.rs
src/test/compile-fail/regions-addr-of-self.rs
src/test/compile-fail/regions-addr-of-upvar-self.rs
src/test/compile-fail/regions-bounded-method-type-parameters-cross-crate.rs
src/test/compile-fail/regions-close-associated-type-into-object.rs
src/test/compile-fail/regions-close-object-into-object-1.rs
src/test/compile-fail/regions-close-object-into-object-3.rs
src/test/compile-fail/regions-close-object-into-object-4.rs
src/test/compile-fail/regions-close-object-into-object-5.rs
src/test/compile-fail/regions-close-over-type-parameter-1.rs
src/test/compile-fail/regions-close-over-type-parameter-multiple.rs
src/test/compile-fail/regions-close-param-into-object.rs
src/test/compile-fail/regions-creating-enums.rs
src/test/compile-fail/regions-nested-fns.rs
src/test/compile-fail/regions-pattern-typing-issue-19552.rs
src/test/compile-fail/regions-pattern-typing-issue-19997.rs
src/test/compile-fail/regions-proc-bound-capture.rs
src/test/compile-fail/regions-return-ref-to-upvar-issue-17403.rs
src/test/compile-fail/regions-steal-closure.rs
src/test/compile-fail/regions-trait-1.rs
src/test/compile-fail/regions-trait-object-subtyping.rs [new file with mode: 0644]
src/test/compile-fail/reject-specialized-drops-8142.rs [new file with mode: 0644]
src/test/compile-fail/repeat_count.rs
src/test/compile-fail/reserved-attr-on-macro.rs [new file with mode: 0644]
src/test/compile-fail/resolve-conflict-extern-crate-vs-extern-crate.rs
src/test/compile-fail/resolve-conflict-import-vs-extern-crate.rs
src/test/compile-fail/resolve-conflict-import-vs-import.rs
src/test/compile-fail/resolve-conflict-item-vs-extern-crate.rs
src/test/compile-fail/resolve-conflict-item-vs-import.rs
src/test/compile-fail/resolve-unknown-trait.rs
src/test/compile-fail/retslot-cast.rs [new file with mode: 0644]
src/test/compile-fail/send-is-not-static-ensures-scoping.rs [changed mode: 0755->0644]
src/test/compile-fail/send-is-not-static-std-sync-2.rs [new file with mode: 0644]
src/test/compile-fail/send-is-not-static-std-sync.rs [new file with mode: 0644]
src/test/compile-fail/shadowing-in-the-same-pattern.rs
src/test/compile-fail/shift-various-bad-types.rs
src/test/compile-fail/simd-binop.rs
src/test/compile-fail/single-derive-attr.rs [new file with mode: 0644]
src/test/compile-fail/single-primitive-inherent-impl.rs [new file with mode: 0644]
src/test/compile-fail/slice-1.rs [deleted file]
src/test/compile-fail/static-array-across-crate.rs [new file with mode: 0644]
src/test/compile-fail/static-assert.rs
src/test/compile-fail/static-assert2.rs
src/test/compile-fail/static-region-bound.rs
src/test/compile-fail/struct-field-privacy.rs
src/test/compile-fail/struct-variant-privacy-xc.rs
src/test/compile-fail/structure-constructor-type-mismatch.rs
src/test/compile-fail/suggest-private-fields.rs [new file with mode: 0644]
src/test/compile-fail/syntaxt-default-trait-impls.rs [new file with mode: 0644]
src/test/compile-fail/tail-typeck.rs
src/test/compile-fail/trait-as-struct-constructor.rs
src/test/compile-fail/trait-bounds-impl-comparison-2.rs
src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs
src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs
src/test/compile-fail/trait-bounds-on-structs-and-enums-xc.rs
src/test/compile-fail/trait-bounds-on-structs-and-enums-xc1.rs
src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
src/test/compile-fail/trait-coercion-generic-bad.rs
src/test/compile-fail/trait-coercion-generic-regions.rs
src/test/compile-fail/trait-impl-2.rs [deleted file]
src/test/compile-fail/trait-impl-for-module.rs
src/test/compile-fail/trait-or-new-type-instead.rs
src/test/compile-fail/trait-safety-trait-impl-cc.rs
src/test/compile-fail/trait-test-2.rs
src/test/compile-fail/traits-assoc-type-in-supertrait-bad.rs [new file with mode: 0644]
src/test/compile-fail/traits-issue-23003-overflow.rs [new file with mode: 0644]
src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs
src/test/compile-fail/traits-repeated-supertrait-ambig.rs [new file with mode: 0644]
src/test/compile-fail/transmute-different-sizes.rs
src/test/compile-fail/trivial_casts.rs [new file with mode: 0644]
src/test/compile-fail/tuple-index-out-of-bounds.rs
src/test/compile-fail/type-mismatch-multiple.rs
src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs
src/test/compile-fail/type-params-in-different-spaces-1.rs
src/test/compile-fail/type-params-in-different-spaces-2.rs
src/test/compile-fail/type-params-in-different-spaces-3.rs
src/test/compile-fail/typeck-builtin-bound-type-parameters.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-assoc-type.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-cross-crate-coherence.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-negation-send.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-negation-sync.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-negation.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-precedence.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-send-param.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-superregion.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-supertrait.rs [new file with mode: 0644]
src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs [new file with mode: 0644]
src/test/compile-fail/typeck-negative-impls-builtin.rs
src/test/compile-fail/typeck_type_placeholder_item.rs
src/test/compile-fail/ufcs-explicit-self-bad.rs
src/test/compile-fail/ufcs-qpath-missing-params.rs
src/test/compile-fail/ufcs-qpath-self-mismatch.rs
src/test/compile-fail/unboxed-closure-illegal-move.rs
src/test/compile-fail/unboxed-closure-immutable-capture.rs
src/test/compile-fail/unboxed-closure-region.rs
src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs
src/test/compile-fail/unboxed-closure-sugar-not-used-on-fn.rs
src/test/compile-fail/unboxed-closure-sugar-used-on-struct-1.rs
src/test/compile-fail/unboxed-closure-sugar-used-on-struct.rs
src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs
src/test/compile-fail/unboxed-closures-borrow-conflict.rs
src/test/compile-fail/unboxed-closures-fnmut-as-fn.rs
src/test/compile-fail/unboxed-closures-infer-explicit-call-too-early.rs
src/test/compile-fail/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.rs
src/test/compile-fail/unboxed-closures-mutate-upvar.rs
src/test/compile-fail/unboxed-closures-mutated-upvar-from-fn-closure.rs
src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
src/test/compile-fail/unboxed-closures-static-call-wrong-trait.rs
src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs
src/test/compile-fail/unboxed-closures-vtable-mismatch.rs
src/test/compile-fail/unboxed-closures-wrong-abi.rs
src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs
src/test/compile-fail/unique-pinned-nocopy.rs
src/test/compile-fail/unique-unique-kind.rs
src/test/compile-fail/unique-vec-res.rs
src/test/compile-fail/unnecessary-private.rs
src/test/compile-fail/unreachable-arm.rs
src/test/compile-fail/unreachable-variant.rs
src/test/compile-fail/unsafe-destructor-check-crash.rs [deleted file]
src/test/compile-fail/unsafe-fn-assign-deref-ptr.rs
src/test/compile-fail/unsafe-subtyping.rs [new file with mode: 0644]
src/test/compile-fail/unsafe-trait-impl.rs [new file with mode: 0644]
src/test/compile-fail/unsafe_no_drop_flag-gate.rs [new file with mode: 0644]
src/test/compile-fail/unsendable-class.rs [deleted file]
src/test/compile-fail/unsized4.rs [deleted file]
src/test/compile-fail/unused-macro-with-bad-frag-spec.rs [new file with mode: 0644]
src/test/compile-fail/unused-macro-with-follow-violation.rs [new file with mode: 0644]
src/test/compile-fail/use-after-move-implicity-coerced-object.rs
src/test/compile-fail/use-from-trait.rs
src/test/compile-fail/use-meta-mismatch.rs
src/test/compile-fail/useless-priv.rs
src/test/compile-fail/useless-priv2.rs [deleted file]
src/test/compile-fail/variadic-ffi.rs
src/test/compile-fail/variance-deprecated-markers.rs [deleted file]
src/test/compile-fail/variance-issue-20533.rs
src/test/compile-fail/variance-region-bounds.rs [new file with mode: 0644]
src/test/compile-fail/variance-trait-matching.rs
src/test/compile-fail/vec-must-not-hide-type-from-dropck.rs
src/test/compile-fail/vec_refs_data_with_early_death.rs
src/test/compile-fail/vector-cast-weirdness.rs
src/test/compile-fail/vtable-res-trait-param.rs
src/test/compile-fail/walk-struct-literal-with.rs
src/test/compile-fail/weak-lang-item.rs
src/test/compile-fail/where-clauses-unsatisfied.rs
src/test/debuginfo/associated-types.rs
src/test/debuginfo/basic-types-globals-metadata.rs
src/test/debuginfo/basic-types-globals.rs
src/test/debuginfo/basic-types-mut-globals.rs
src/test/debuginfo/basic-types.rs
src/test/debuginfo/borrowed-basic.rs
src/test/debuginfo/borrowed-struct.rs
src/test/debuginfo/borrowed-unique-basic.rs
src/test/debuginfo/boxed-struct.rs
src/test/debuginfo/by-value-non-immediate-argument.rs
src/test/debuginfo/by-value-self-argument-in-trait-impl.rs
src/test/debuginfo/c-style-enum.rs
src/test/debuginfo/closure-in-generic-function.rs
src/test/debuginfo/constant-debug-locs.rs [new file with mode: 0644]
src/test/debuginfo/cross-crate-spans.rs [new file with mode: 0644]
src/test/debuginfo/destructured-fn-argument.rs
src/test/debuginfo/destructured-local.rs
src/test/debuginfo/extern-c-fn.rs [new file with mode: 0644]
src/test/debuginfo/function-arg-initialization.rs
src/test/debuginfo/function-arguments.rs
src/test/debuginfo/function-prologue-stepping-no-stack-check.rs
src/test/debuginfo/function-prologue-stepping-regular.rs
src/test/debuginfo/gdb-pretty-std.rs [new file with mode: 0644]
src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs
src/test/debuginfo/gdb-pretty-struct-and-enums.rs
src/test/debuginfo/generic-function.rs
src/test/debuginfo/generic-method-on-generic-struct.rs
src/test/debuginfo/generic-static-method-on-struct-and-enum.rs
src/test/debuginfo/generic-struct-style-enum.rs
src/test/debuginfo/generic-struct.rs
src/test/debuginfo/generic-trait-generic-static-default-method.rs
src/test/debuginfo/generic-tuple-style-enum.rs
src/test/debuginfo/issue12886.rs
src/test/debuginfo/issue13213.rs
src/test/debuginfo/issue22656.rs [new file with mode: 0644]
src/test/debuginfo/lexical-scope-in-match.rs
src/test/debuginfo/lexical-scope-in-parameterless-closure.rs
src/test/debuginfo/lexical-scope-in-stack-closure.rs
src/test/debuginfo/lexical-scope-in-unique-closure.rs
src/test/debuginfo/lexical-scopes-in-block-expression.rs
src/test/debuginfo/limited-debuginfo.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/no-debug-attribute.rs
src/test/debuginfo/recursive-struct.rs
src/test/debuginfo/self-in-default-method.rs
src/test/debuginfo/self-in-generic-default-method.rs
src/test/debuginfo/simd.rs
src/test/debuginfo/simple-struct.rs
src/test/debuginfo/simple-tuple.rs
src/test/debuginfo/static-method-on-struct-and-enum.rs
src/test/debuginfo/struct-in-enum.rs
src/test/debuginfo/struct-style-enum.rs
src/test/debuginfo/trait-generic-static-default-method.rs
src/test/debuginfo/trait-pointers.rs
src/test/debuginfo/tuple-style-enum.rs
src/test/debuginfo/type-names.rs
src/test/debuginfo/unique-enum.rs
src/test/debuginfo/unreachable-locals.rs
src/test/debuginfo/var-captured-in-nested-closure.rs
src/test/debuginfo/var-captured-in-sendable-closure.rs
src/test/debuginfo/var-captured-in-stack-closure.rs
src/test/debuginfo/vec-slices.rs
src/test/parse-fail/ascii-only-character-escape.rs
src/test/parse-fail/bad-lit-suffixes.rs
src/test/parse-fail/byte-literals.rs
src/test/parse-fail/byte-string-literals.rs
src/test/parse-fail/circular_modules_main.rs
src/test/parse-fail/class-implements-bad-trait.rs
src/test/parse-fail/closure-return-syntax.rs [new file with mode: 0644]
src/test/parse-fail/column-offset-1-based.rs
src/test/parse-fail/empty-impl-semicolon.rs
src/test/parse-fail/extern-crate-as-no-string-help.rs [deleted file]
src/test/parse-fail/extern-foreign-crate.rs
src/test/parse-fail/issue-10392-2.rs
src/test/parse-fail/issue-1655.rs
src/test/parse-fail/issue-17718-const-mut.rs
src/test/parse-fail/issue-1802-1.rs
src/test/parse-fail/issue-20711-2.rs
src/test/parse-fail/issue-21153.rs
src/test/parse-fail/issue-22647.rs [new file with mode: 0644]
src/test/parse-fail/issue-22712.rs [new file with mode: 0644]
src/test/parse-fail/issue-2354-1.rs
src/test/parse-fail/issue-23620-invalid-escapes.rs [new file with mode: 0644]
src/test/parse-fail/issue-5544-b.rs
src/test/parse-fail/issue-5806.rs
src/test/parse-fail/keywords-followed-by-double-colon.rs
src/test/parse-fail/lex-bad-binary-literal.rs [new file with mode: 0644]
src/test/parse-fail/lex-bad-char-literals.rs
src/test/parse-fail/lex-bad-numeric-literals.rs
src/test/parse-fail/lex-bad-octal-literal.rs [new file with mode: 0644]
src/test/parse-fail/macro-attribute.rs
src/test/parse-fail/macros-no-semicolon.rs
src/test/parse-fail/multitrait.rs
src/test/parse-fail/new-unicode-escapes-4.rs
src/test/parse-fail/obsolete-closure-kind.rs [new file with mode: 0644]
src/test/parse-fail/obsolete-for-sized.rs [deleted file]
src/test/parse-fail/obsolete-proc.rs
src/test/parse-fail/raw-byte-string-eof.rs
src/test/parse-fail/raw-byte-string-literals.rs
src/test/parse-fail/regions-trait-2.rs
src/test/parse-fail/struct-literal-in-for.rs
src/test/parse-fail/struct-literal-in-if.rs
src/test/parse-fail/struct-literal-in-match-discriminant.rs
src/test/parse-fail/struct-literal-in-while.rs
src/test/parse-fail/trailing-plus-in-bounds.rs
src/test/parse-fail/trait-bounds-not-on-impl.rs
src/test/parse-fail/trait-pub-assoc-ty.rs [new file with mode: 0644]
src/test/parse-fail/trait-pub-method.rs [new file with mode: 0644]
src/test/parse-fail/type-parameters-in-field-exprs.rs
src/test/parse-fail/unboxed-closure-sugar-used-on-struct-3.rs
src/test/parse-fail/use-mod-4.rs
src/test/parse-fail/where-clauses-no-bounds-or-predicates.rs
src/test/pretty/asm-clobbers.rs
src/test/pretty/blank-lines.rs
src/test/pretty/block-comment-wchar.pp
src/test/pretty/block-comment-wchar.rs
src/test/pretty/block-disambig.rs
src/test/pretty/closure-reform-pretty.rs
src/test/pretty/default-trait-impl.rs [new file with mode: 0644]
src/test/pretty/disamb-stmt-expr.rs
src/test/pretty/do1.rs
src/test/pretty/empty-impl.rs
src/test/pretty/empty-lines.rs
src/test/pretty/for-comment.rs
src/test/pretty/issue-4264.pp
src/test/pretty/issue-4264.rs
src/test/pretty/issue-929.rs [deleted file]
src/test/pretty/path-type-bounds.rs
src/test/pretty/raw-str-nonexpr.rs
src/test/pretty/record-trailing-comma.rs
src/test/pretty/struct-tuple.rs
src/test/pretty/trait-safety.rs
src/test/pretty/unary-op-disambig.rs
src/test/pretty/where-clauses.rs
src/test/run-fail/args-panic.rs
src/test/run-fail/assert-eq-macro-panic.rs
src/test/run-fail/binop-fail-3.rs [new file with mode: 0644]
src/test/run-fail/bounds-check-no-overflow.rs
src/test/run-fail/bug-2470-bounds-check-overflow-2.rs
src/test/run-fail/bug-2470-bounds-check-overflow-3.rs
src/test/run-fail/bug-2470-bounds-check-overflow.rs
src/test/run-fail/bug-811.rs
src/test/run-fail/die-macro-expr.rs
src/test/run-fail/expr-if-panic-fn.rs
src/test/run-fail/expr-match-panic-fn.rs
src/test/run-fail/extern-panic.rs
src/test/run-fail/hashmap-capacity-overflow.rs
src/test/run-fail/if-check-panic.rs
src/test/run-fail/issue-2061.rs
src/test/run-fail/issue-23354-2.rs [new file with mode: 0644]
src/test/run-fail/issue-23354.rs [new file with mode: 0644]
src/test/run-fail/issue-2444.rs
src/test/run-fail/issue-948.rs
src/test/run-fail/match-bot-panic.rs
src/test/run-fail/match-disc-bot.rs
src/test/run-fail/match-wildcards.rs
src/test/run-fail/overflowing-add.rs [new file with mode: 0644]
src/test/run-fail/overflowing-lsh-1.rs [new file with mode: 0644]
src/test/run-fail/overflowing-lsh-2.rs [new file with mode: 0644]
src/test/run-fail/overflowing-lsh-3.rs [new file with mode: 0644]
src/test/run-fail/overflowing-lsh-4.rs [new file with mode: 0644]
src/test/run-fail/overflowing-mul.rs [new file with mode: 0644]
src/test/run-fail/overflowing-rsh-1.rs [new file with mode: 0644]
src/test/run-fail/overflowing-rsh-2.rs [new file with mode: 0644]
src/test/run-fail/overflowing-rsh-3.rs [new file with mode: 0644]
src/test/run-fail/overflowing-rsh-4.rs [new file with mode: 0644]
src/test/run-fail/overflowing-sub.rs [new file with mode: 0644]
src/test/run-fail/panic-arg.rs
src/test/run-fail/panic-macro-any-wrapped.rs
src/test/run-fail/result-get-panic.rs
src/test/run-fail/rt-set-exit-status-panic.rs
src/test/run-fail/rt-set-exit-status-panic2.rs
src/test/run-fail/rt-set-exit-status.rs
src/test/run-fail/test-should-fail-bad-message.rs
src/test/run-fail/test-tasks-invalid-value.rs
src/test/run-fail/unique-panic.rs
src/test/run-fail/unwind-rec.rs
src/test/run-fail/unwind-rec2.rs
src/test/run-fail/unwind-unique.rs
src/test/run-fail/vec-overrun.rs
src/test/run-fail/while-body-panics.rs
src/test/run-make/allow-non-lint-warnings-cmdline/Makefile
src/test/run-make/allow-non-lint-warnings-cmdline/foo.rs
src/test/run-make/allow-warnings-cmdline-stability/Makefile
src/test/run-make/allow-warnings-cmdline-stability/foo.rs
src/test/run-make/bare-outfile/Makefile [new file with mode: 0644]
src/test/run-make/bare-outfile/foo.rs [new file with mode: 0644]
src/test/run-make/cannot-read-embedded-idents/create_and_compile.rs
src/test/run-make/compiler-lookup-paths/c.rs
src/test/run-make/crate-name-priority/foo1.rs
src/test/run-make/debug-assertions/Makefile [new file with mode: 0644]
src/test/run-make/debug-assertions/debug.rs [new file with mode: 0644]
src/test/run-make/extern-flag-disambiguates/Makefile
src/test/run-make/extern-flag-fun/bar.rs
src/test/run-make/extern-fn-reachable/main.rs
src/test/run-make/extern-fn-with-packed-struct/test.rs
src/test/run-make/extern-overrides-distribution/main.rs
src/test/run-make/graphviz-flowgraph/f07.dot-expected.dot
src/test/run-make/graphviz-flowgraph/f07.rs
src/test/run-make/graphviz-flowgraph/f13.dot-expected.dot
src/test/run-make/graphviz-flowgraph/f20.dot-expected.dot
src/test/run-make/graphviz-flowgraph/f20.rs
src/test/run-make/interdependent-c-libraries/Makefile
src/test/run-make/interdependent-c-libraries/bar.rs
src/test/run-make/intrinsic-unreachable/exit-ret.rs
src/test/run-make/intrinsic-unreachable/exit-unreachable.rs
src/test/run-make/issue-14500/Makefile
src/test/run-make/issue-19371/foo.rs
src/test/run-make/issue-7349/foo.rs
src/test/run-make/libs-and-bins/Makefile
src/test/run-make/link-path-order/Makefile
src/test/run-make/link-path-order/main.rs
src/test/run-make/linkage-attr-on-static/Makefile
src/test/run-make/lto-syntax-extension/main.rs
src/test/run-make/manual-link/Makefile
src/test/run-make/many-crates-but-no-match/Makefile
src/test/run-make/metadata-flag-frobs-symbols/foo.rs
src/test/run-make/mismatching-target-triples/bar.rs [changed mode: 0755->0644]
src/test/run-make/mismatching-target-triples/foo.rs [changed mode: 0755->0644]
src/test/run-make/missing-crate-dependency/Makefile
src/test/run-make/mixing-deps/both.rs
src/test/run-make/mixing-deps/dylib.rs
src/test/run-make/mixing-deps/prog.rs
src/test/run-make/mixing-formats/baz2.rs
src/test/run-make/no-duplicate-libs/bar.rs
src/test/run-make/no-duplicate-libs/foo.rs
src/test/run-make/obey-crate-type-flag/test.rs
src/test/run-make/output-with-hyphens/Makefile [new file with mode: 0644]
src/test/run-make/output-with-hyphens/foo-bar.rs [new file with mode: 0644]
src/test/run-make/pretty-expanded-hygiene/input.pp.rs [changed mode: 0755->0644]
src/test/run-make/pretty-expanded-hygiene/input.rs [changed mode: 0755->0644]
src/test/run-make/pretty-expanded/input.rs
src/test/run-make/pretty-print-path-suffix/foo_method.pp
src/test/run-make/pretty-print-path-suffix/input.rs
src/test/run-make/rustdoc-default-impl/Makefile [new file with mode: 0644]
src/test/run-make/rustdoc-default-impl/bar.rs [new file with mode: 0644]
src/test/run-make/rustdoc-default-impl/foo.rs [new file with mode: 0644]
src/test/run-make/rustdoc-extern-default-method/Makefile [new file with mode: 0644]
src/test/run-make/rustdoc-extern-default-method/ext.rs [new file with mode: 0644]
src/test/run-make/rustdoc-extern-default-method/lib.rs [new file with mode: 0644]
src/test/run-make/rustdoc-extern-method/Makefile
src/test/run-make/rustdoc-extern-method/bar.rs
src/test/run-make/rustdoc-extern-method/foo.rs
src/test/run-make/rustdoc-negative-impl/Makefile
src/test/run-make/rustdoc-recursion/Makefile
src/test/run-make/rustdoc-recursion/foo.rs
src/test/run-make/rustdoc-smoke/foo.rs
src/test/run-make/rustdoc-src-links/Makefile [new file with mode: 0644]
src/test/run-make/rustdoc-src-links/foo.rs [new file with mode: 0644]
src/test/run-make/rustdoc-src-links/qux/mod.rs [new file with mode: 0644]
src/test/run-make/rustdoc-viewpath-self/Makefile
src/test/run-make/rustdoc-where/Makefile
src/test/run-make/save-analysis/foo.rs
src/test/run-make/sepcomp-cci-copies/cci_lib.rs
src/test/run-make/sepcomp-cci-copies/foo.rs
src/test/run-make/sepcomp-separate/foo.rs
src/test/run-make/simd-ffi/simd.rs [changed mode: 0755->0644]
src/test/run-make/symbols-are-reasonable/lib.rs
src/test/run-make/target-cpu-native/Makefile [new file with mode: 0644]
src/test/run-make/target-cpu-native/foo.rs [new file with mode: 0644]
src/test/run-make/target-specs/foo.rs
src/test/run-make/tools.mk
src/test/run-make/unicode-input/multiple_files.rs
src/test/run-make/unicode-input/span_length.rs
src/test/run-make/volatile-intrinsics/main.rs
src/test/run-make/weird-output-filenames/Makefile
src/test/run-pass-fulldeps/compiler-calls.rs
src/test/run-pass-fulldeps/create-dir-all-bare.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/derive-totalsum.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/issue-13560.rs
src/test/run-pass-fulldeps/issue-15778-pass.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/issue-16822.rs
src/test/run-pass-fulldeps/issue-16992.rs
src/test/run-pass-fulldeps/issue-18502.rs
src/test/run-pass-fulldeps/issue-18763-quote-token-tree.rs
src/test/run-pass-fulldeps/macro-crate.rs
src/test/run-pass-fulldeps/mbe_matching_test_macro.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/qquote.rs
src/test/run-pass-fulldeps/quote-tokens.rs
src/test/run-pass-fulldeps/quote-unused-sp-no-warning.rs
src/test/run-pass-fulldeps/rename-directory.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs
src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
src/test/run-pass-valgrind/cleanup-stdin.rs
src/test/run-pass-valgrind/dst-dtor-1.rs
src/test/run-pass-valgrind/dst-dtor-2.rs
src/test/run-pass/alias-uninit-value.rs
src/test/run-pass/alloca-from-derived-tydesc.rs
src/test/run-pass/anon-extern-mod-cross-crate-2.rs
src/test/run-pass/anon-extern-mod.rs
src/test/run-pass/anon-trait-static-method.rs
src/test/run-pass/argument-passing.rs
src/test/run-pass/arith-0.rs
src/test/run-pass/arith-1.rs
src/test/run-pass/arith-2.rs
src/test/run-pass/arith-unsigned.rs
src/test/run-pass/artificial-block.rs
src/test/run-pass/as-precedence.rs
src/test/run-pass/asm-concat-src.rs
src/test/run-pass/asm-in-out-operand.rs
src/test/run-pass/asm-out-assign.rs
src/test/run-pass/assert-eq-macro-success.rs
src/test/run-pass/assign-assign.rs
src/test/run-pass/assignability-trait.rs
src/test/run-pass/associated-types-basic.rs
src/test/run-pass/associated-types-binding-in-trait.rs
src/test/run-pass/associated-types-binding-in-where-clause.rs
src/test/run-pass/associated-types-bound.rs
src/test/run-pass/associated-types-cc.rs
src/test/run-pass/associated-types-conditional-dispatch.rs
src/test/run-pass/associated-types-constant-type.rs
src/test/run-pass/associated-types-doubleendediterator-object.rs
src/test/run-pass/associated-types-duplicate-binding-in-env-hrtb.rs
src/test/run-pass/associated-types-duplicate-binding-in-env.rs
src/test/run-pass/associated-types-enum-field-named.rs
src/test/run-pass/associated-types-enum-field-numbered.rs
src/test/run-pass/associated-types-eq-obj.rs
src/test/run-pass/associated-types-in-default-method.rs
src/test/run-pass/associated-types-in-fn.rs
src/test/run-pass/associated-types-in-impl-generics.rs
src/test/run-pass/associated-types-in-inherent-method.rs
src/test/run-pass/associated-types-issue-20220.rs
src/test/run-pass/associated-types-issue-20371.rs
src/test/run-pass/associated-types-issue-21212.rs
src/test/run-pass/associated-types-iterator-binding.rs
src/test/run-pass/associated-types-nested-projections.rs
src/test/run-pass/associated-types-normalize-in-bounds-binding.rs
src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs
src/test/run-pass/associated-types-normalize-in-bounds.rs
src/test/run-pass/associated-types-normalize-unifield-struct.rs
src/test/run-pass/associated-types-project-from-type-param-via-bound-in-where-clause.rs [new file with mode: 0644]
src/test/run-pass/associated-types-projection-bound-in-supertraits.rs
src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs
src/test/run-pass/associated-types-projection-in-object-type.rs
src/test/run-pass/associated-types-projection-in-supertrait.rs
src/test/run-pass/associated-types-projection-in-where-clause.rs
src/test/run-pass/associated-types-qualified-path-with-trait-with-type-parameters.rs
src/test/run-pass/associated-types-ref-from-struct.rs
src/test/run-pass/associated-types-ref-in-struct-literal.rs
src/test/run-pass/associated-types-region-erasure-issue-20582.rs
src/test/run-pass/associated-types-resolve-lifetime.rs
src/test/run-pass/associated-types-return.rs
src/test/run-pass/associated-types-simple.rs
src/test/run-pass/associated-types-stream.rs
src/test/run-pass/associated-types-struct-field-named.rs
src/test/run-pass/associated-types-struct-field-numbered.rs
src/test/run-pass/associated-types-sugar-path.rs
src/test/run-pass/astconv-cycle-between-trait-and-type.rs
src/test/run-pass/attr-before-view-item.rs
src/test/run-pass/attr-before-view-item2.rs
src/test/run-pass/attr-main-2.rs
src/test/run-pass/attr-main.rs
src/test/run-pass/attr-mix-new.rs
src/test/run-pass/attr-no-drop-flag-size.rs
src/test/run-pass/attr-start.rs
src/test/run-pass/attr.rs
src/test/run-pass/auto-encode.rs
src/test/run-pass/auto-instantiate.rs
src/test/run-pass/auto-loop.rs
src/test/run-pass/auto-ref-bounded-ty-param.rs
src/test/run-pass/auto-ref-sliceable.rs
src/test/run-pass/auto-ref.rs
src/test/run-pass/autobind.rs
src/test/run-pass/autoderef-and-borrow-method-receiver.rs
src/test/run-pass/autoderef-method-on-trait.rs
src/test/run-pass/autoderef-method-priority.rs
src/test/run-pass/autoderef-method-twice-but-not-thrice.rs
src/test/run-pass/autoderef-method-twice.rs
src/test/run-pass/autoderef-method.rs
src/test/run-pass/autoref-intermediate-types-issue-3585.rs
src/test/run-pass/backtrace-debuginfo-aux.rs [new file with mode: 0644]
src/test/run-pass/backtrace-debuginfo.rs [new file with mode: 0644]
src/test/run-pass/backtrace.rs
src/test/run-pass/bare-fn-implements-fn-mut.rs
src/test/run-pass/big-literals.rs
src/test/run-pass/binary-minus-without-space.rs
src/test/run-pass/bind-by-move.rs
src/test/run-pass/bind-field-short-with-modifiers.rs
src/test/run-pass/binops-issue-22743.rs [new file with mode: 0644]
src/test/run-pass/binops.rs
src/test/run-pass/bitv-perf-test.rs
src/test/run-pass/bitwise.rs
src/test/run-pass/blind-item-mixed-crate-use-item.rs
src/test/run-pass/blind-item-mixed-use-item.rs
src/test/run-pass/block-arg-call-as.rs
src/test/run-pass/block-explicit-types.rs
src/test/run-pass/block-expr-precedence.rs
src/test/run-pass/block-fn-coerce.rs
src/test/run-pass/block-iter-1.rs
src/test/run-pass/block-iter-2.rs
src/test/run-pass/bool-not.rs
src/test/run-pass/bool.rs
src/test/run-pass/borrow-by-val-method-receiver.rs
src/test/run-pass/borrow-tuple-fields.rs
src/test/run-pass/borrowck-assign-to-subfield.rs
src/test/run-pass/borrowck-binding-mutbl.rs
src/test/run-pass/borrowck-borrow-from-expr-block.rs
src/test/run-pass/borrowck-borrow-of-mut-base-ptr-safe.rs
src/test/run-pass/borrowck-closures-two-imm.rs
src/test/run-pass/borrowck-field-sensitivity.rs
src/test/run-pass/borrowck-fixed-length-vecs.rs
src/test/run-pass/borrowck-freeze-frozen-mut.rs
src/test/run-pass/borrowck-lend-args.rs
src/test/run-pass/borrowck-macro-interaction-issue-6304.rs
src/test/run-pass/borrowck-move-by-capture-ok.rs
src/test/run-pass/borrowck-mut-uniq.rs
src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs
src/test/run-pass/borrowck-nested-calls.rs
src/test/run-pass/borrowck-pat-enum.rs
src/test/run-pass/borrowck-pat-reassign-no-binding.rs
src/test/run-pass/borrowck-rvalues-mutable.rs
src/test/run-pass/borrowck-scope-of-deref-issue-4666.rs
src/test/run-pass/borrowck-static-item-in-fn.rs
src/test/run-pass/borrowck-trait-lifetime.rs
src/test/run-pass/borrowck-uniq-via-ref.rs
src/test/run-pass/borrowck-univariant-enum.rs
src/test/run-pass/borrowck-use-mut-borrow.rs
src/test/run-pass/borrowed-ptr-pattern-2.rs
src/test/run-pass/borrowed-ptr-pattern-3.rs
src/test/run-pass/borrowed-ptr-pattern-infallible.rs
src/test/run-pass/borrowed-ptr-pattern-option.rs
src/test/run-pass/borrowed-ptr-pattern.rs
src/test/run-pass/box-new.rs
src/test/run-pass/box-of-array-of-drop-1.rs [new file with mode: 0644]
src/test/run-pass/box-of-array-of-drop-2.rs [new file with mode: 0644]
src/test/run-pass/break-value.rs
src/test/run-pass/break.rs
src/test/run-pass/bug-7183-generics.rs
src/test/run-pass/bug-7295.rs
src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
src/test/run-pass/builtin-superkinds-capabilities-xc.rs
src/test/run-pass/builtin-superkinds-capabilities.rs
src/test/run-pass/builtin-superkinds-in-metadata.rs
src/test/run-pass/builtin-superkinds-phantom-typaram.rs
src/test/run-pass/builtin-superkinds-self-type.rs
src/test/run-pass/builtin-superkinds-simple.rs
src/test/run-pass/builtin-superkinds-typaram.rs
src/test/run-pass/by-value-self-in-mut-slot.rs
src/test/run-pass/byte-literals.rs
src/test/run-pass/c-stack-as-value.rs
src/test/run-pass/c-stack-returning-int64.rs
src/test/run-pass/call-closure-from-overloaded-op.rs
src/test/run-pass/can-copy-pod.rs
src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs
src/test/run-pass/capture-clauses-boxed-closures.rs
src/test/run-pass/capture-clauses-unboxed-closures.rs
src/test/run-pass/capturing-logging.rs
src/test/run-pass/cast-in-array-size.rs
src/test/run-pass/cast-region-to-uint.rs
src/test/run-pass/cast.rs
src/test/run-pass/cci_borrow.rs
src/test/run-pass/cci_capture_clause.rs
src/test/run-pass/cci_impl_exe.rs
src/test/run-pass/cci_iter_exe.rs
src/test/run-pass/cci_nested_exe.rs
src/test/run-pass/cci_no_inline_exe.rs
src/test/run-pass/cell-does-not-clone.rs
src/test/run-pass/cfg-attr-cfg.rs
src/test/run-pass/cfg-attr-crate.rs
src/test/run-pass/cfg-family.rs
src/test/run-pass/cfg-macros-foo.rs
src/test/run-pass/cfg-macros-notfoo.rs
src/test/run-pass/cfg-match-arm.rs
src/test/run-pass/cfg-target-family.rs
src/test/run-pass/cfg_inner_static.rs
src/test/run-pass/cfgs-on-items.rs
src/test/run-pass/char.rs
src/test/run-pass/check-static-mut-slices.rs
src/test/run-pass/check-static-recursion-foreign.rs
src/test/run-pass/check-static-slice.rs
src/test/run-pass/child-outlives-parent.rs
src/test/run-pass/class-cast-to-trait-cross-crate-2.rs
src/test/run-pass/class-cast-to-trait-multiple-types.rs
src/test/run-pass/class-cast-to-trait.rs
src/test/run-pass/class-dtor.rs
src/test/run-pass/class-exports.rs
src/test/run-pass/class-impl-very-parameterized-trait.rs
src/test/run-pass/class-implement-trait-cross-crate.rs
src/test/run-pass/class-implement-traits.rs
src/test/run-pass/class-method-cross-crate.rs
src/test/run-pass/class-methods-cross-crate.rs
src/test/run-pass/class-methods.rs
src/test/run-pass/class-poly-methods-cross-crate.rs
src/test/run-pass/class-poly-methods.rs
src/test/run-pass/class-separate-impl.rs
src/test/run-pass/class-str-field.rs
src/test/run-pass/class-typarams.rs
src/test/run-pass/classes-cross-crate.rs
src/test/run-pass/classes-self-referential.rs
src/test/run-pass/classes-simple-cross-crate.rs
src/test/run-pass/classes-simple-method.rs
src/test/run-pass/classes-simple.rs
src/test/run-pass/classes.rs
src/test/run-pass/cleanup-arm-conditional.rs
src/test/run-pass/cleanup-rvalue-during-if-and-while.rs
src/test/run-pass/cleanup-rvalue-temp-during-incomplete-alloc.rs
src/test/run-pass/cleanup-shortcircuit.rs
src/test/run-pass/clone-with-exterior.rs
src/test/run-pass/closure-bounds-can-capture-chan.rs
src/test/run-pass/closure-inference.rs
src/test/run-pass/closure-inference2.rs
src/test/run-pass/closure-reform.rs
src/test/run-pass/cmp-default.rs
src/test/run-pass/coerce-expect-unsized.rs
src/test/run-pass/coerce-match-calls.rs
src/test/run-pass/coerce-match.rs
src/test/run-pass/coerce-overloaded-autoderef.rs
src/test/run-pass/coerce-reborrow-imm-ptr-arg.rs
src/test/run-pass/coerce-reborrow-imm-ptr-rcvr.rs
src/test/run-pass/coerce-reborrow-imm-vec-arg.rs
src/test/run-pass/coerce-reborrow-imm-vec-rcvr.rs
src/test/run-pass/coerce-reborrow-mut-ptr-arg.rs
src/test/run-pass/coerce-reborrow-mut-ptr-rcvr.rs
src/test/run-pass/coerce-reborrow-mut-vec-arg.rs
src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs
src/test/run-pass/coerce-unify-return.rs
src/test/run-pass/coherence-bigint-int.rs
src/test/run-pass/coherence-bigint-vecint.rs
src/test/run-pass/coherence-blanket.rs
src/test/run-pass/coherence-covered-type-parameter.rs
src/test/run-pass/coherence-cow-1.rs [deleted file]
src/test/run-pass/coherence-cow-2.rs [deleted file]
src/test/run-pass/coherence-impl-in-fn.rs
src/test/run-pass/coherence-iterator-vec-any-elem.rs
src/test/run-pass/coherence-iterator-vec.rs
src/test/run-pass/coherence-local-1.rs [deleted file]
src/test/run-pass/coherence-local-2.rs [deleted file]
src/test/run-pass/coherence-multidispatch-tuple.rs
src/test/run-pass/coherence-negative-impls-safe.rs
src/test/run-pass/coherence-where-clause.rs
src/test/run-pass/coherence_copy_like.rs [new file with mode: 0644]
src/test/run-pass/colorful-write-macros.rs
src/test/run-pass/comm.rs
src/test/run-pass/compare-generic-enums.rs
src/test/run-pass/complex.rs
src/test/run-pass/concat.rs
src/test/run-pass/conditional-compile-arch.rs
src/test/run-pass/conditional-compile.rs
src/test/run-pass/conditional-debug-macro-off.rs
src/test/run-pass/const-autoderef.rs
src/test/run-pass/const-big-enum.rs
src/test/run-pass/const-binops.rs
src/test/run-pass/const-block-cross-crate-fn.rs
src/test/run-pass/const-block-item-macro-codegen.rs
src/test/run-pass/const-block-item.rs
src/test/run-pass/const-block.rs
src/test/run-pass/const-bound.rs
src/test/run-pass/const-cast-ptr-int.rs
src/test/run-pass/const-cast.rs
src/test/run-pass/const-const.rs
src/test/run-pass/const-contents.rs
src/test/run-pass/const-cross-crate-const.rs
src/test/run-pass/const-cross-crate-extern.rs
src/test/run-pass/const-deref.rs
src/test/run-pass/const-enum-byref-self.rs
src/test/run-pass/const-enum-byref.rs
src/test/run-pass/const-enum-cast.rs
src/test/run-pass/const-enum-ptr.rs
src/test/run-pass/const-enum-struct.rs
src/test/run-pass/const-enum-struct2.rs
src/test/run-pass/const-enum-structlike.rs
src/test/run-pass/const-enum-tuple.rs
src/test/run-pass/const-enum-tuple2.rs
src/test/run-pass/const-enum-tuplestruct.rs
src/test/run-pass/const-enum-tuplestruct2.rs
src/test/run-pass/const-enum-vec-index.rs
src/test/run-pass/const-enum-vec-ptr.rs
src/test/run-pass/const-enum-vector.rs
src/test/run-pass/const-expr-in-fixed-length-vec.rs
src/test/run-pass/const-expr-in-vec-repeat.rs
src/test/run-pass/const-extern-function.rs
src/test/run-pass/const-fields-and-indexing.rs
src/test/run-pass/const-fn-val.rs
src/test/run-pass/const-negative.rs
src/test/run-pass/const-nullary-enum.rs
src/test/run-pass/const-nullary-univariant-enum.rs
src/test/run-pass/const-polymorphic-paths.rs [deleted file]
src/test/run-pass/const-region-ptrs-noncopy.rs
src/test/run-pass/const-region-ptrs.rs
src/test/run-pass/const-str-ptr.rs
src/test/run-pass/const-struct-offsets.rs
src/test/run-pass/const-struct.rs
src/test/run-pass/const-tuple-struct.rs
src/test/run-pass/const-unit-struct.rs
src/test/run-pass/const-vec-of-fns.rs
src/test/run-pass/const-vec-syntax.rs
src/test/run-pass/const-vecs-and-slices.rs
src/test/run-pass/const.rs
src/test/run-pass/consts-in-patterns.rs
src/test/run-pass/copy-out-of-array-1.rs
src/test/run-pass/core-run-destroy.rs
src/test/run-pass/crate-leading-sep.rs
src/test/run-pass/crate-method-reexport-grrrrrrr.rs
src/test/run-pass/crate-name-attr-used.rs
src/test/run-pass/cross-crate-const-pat.rs
src/test/run-pass/cross-crate-newtype-struct-pat.rs
src/test/run-pass/cycle-generic-bound.rs [new file with mode: 0644]
src/test/run-pass/cycle-trait-type-trait.rs [new file with mode: 0644]
src/test/run-pass/dead-code-leading-underscore.rs
src/test/run-pass/deep.rs
src/test/run-pass/default-method-parsing.rs
src/test/run-pass/default-method-simple.rs
src/test/run-pass/default-method-supertrait-vtable.rs
src/test/run-pass/deprecated-derive.rs [new file with mode: 0644]
src/test/run-pass/deprecated-no-split-stack.rs [deleted file]
src/test/run-pass/deref-lval.rs
src/test/run-pass/deref-mut-on-ref.rs
src/test/run-pass/deref-on-ref.rs
src/test/run-pass/deref-rc.rs
src/test/run-pass/deref.rs
src/test/run-pass/derive-no-std.rs
src/test/run-pass/deriving-associated-types.rs [new file with mode: 0644]
src/test/run-pass/deriving-bounds.rs
src/test/run-pass/deriving-clone-enum.rs
src/test/run-pass/deriving-clone-generic-enum.rs
src/test/run-pass/deriving-clone-generic-struct.rs
src/test/run-pass/deriving-clone-generic-tuple-struct.rs
src/test/run-pass/deriving-clone-struct.rs
src/test/run-pass/deriving-clone-tuple-struct.rs
src/test/run-pass/deriving-cmp-generic-enum.rs
src/test/run-pass/deriving-cmp-generic-struct-enum.rs
src/test/run-pass/deriving-cmp-generic-struct.rs
src/test/run-pass/deriving-cmp-generic-tuple-struct.rs
src/test/run-pass/deriving-cmp-shortcircuit.rs
src/test/run-pass/deriving-default-box.rs
src/test/run-pass/deriving-encodable-decodable-box.rs
src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs
src/test/run-pass/deriving-encodable-decodable.rs
src/test/run-pass/deriving-enum-single-variant.rs
src/test/run-pass/deriving-eq-ord-boxed-slice.rs
src/test/run-pass/deriving-global.rs
src/test/run-pass/deriving-hash.rs
src/test/run-pass/deriving-in-fn.rs
src/test/run-pass/deriving-in-macro.rs
src/test/run-pass/deriving-meta-multiple.rs
src/test/run-pass/deriving-meta.rs
src/test/run-pass/deriving-primitive.rs
src/test/run-pass/deriving-rand.rs
src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs
src/test/run-pass/deriving-self-lifetime.rs
src/test/run-pass/deriving-show-2.rs
src/test/run-pass/deriving-show.rs
src/test/run-pass/deriving-via-extension-enum.rs
src/test/run-pass/deriving-via-extension-hash-enum.rs
src/test/run-pass/deriving-via-extension-hash-struct.rs
src/test/run-pass/deriving-via-extension-struct-like-enum-variant.rs
src/test/run-pass/deriving-via-extension-struct-tuple.rs
src/test/run-pass/deriving-via-extension-struct.rs
src/test/run-pass/deriving-via-extension-type-params.rs
src/test/run-pass/destructure-array-1.rs
src/test/run-pass/die-macro.rs
src/test/run-pass/discrim-explicit-23030.rs [new file with mode: 0644]
src/test/run-pass/div-mod.rs
src/test/run-pass/double-ref.rs
src/test/run-pass/drop-flag-sanity-check.rs [new file with mode: 0644]
src/test/run-pass/drop-flag-skip-sanity-check.rs [new file with mode: 0644]
src/test/run-pass/drop-on-empty-block-exit.rs
src/test/run-pass/drop-on-ret.rs
src/test/run-pass/drop-struct-as-object.rs
src/test/run-pass/drop-trait-enum.rs
src/test/run-pass/drop-trait.rs
src/test/run-pass/drop-uninhabited-enum.rs
src/test/run-pass/drop-with-type-ascription-1.rs
src/test/run-pass/drop-with-type-ascription-2.rs
src/test/run-pass/dropck_tarena_sound_drop.rs
src/test/run-pass/dst-coercions.rs
src/test/run-pass/dst-deref-mut.rs
src/test/run-pass/dst-deref.rs
src/test/run-pass/dst-index.rs
src/test/run-pass/dst-raw.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/dupe-first-attr.rc
src/test/run-pass/duplicated-external-mods.rs
src/test/run-pass/early-ret-binop-add.rs
src/test/run-pass/early-vtbl-resolution.rs
src/test/run-pass/else-if.rs
src/test/run-pass/empty-allocation-non-null.rs
src/test/run-pass/empty-allocation-rvalue-non-null.rs
src/test/run-pass/empty-mutable-vec.rs
src/test/run-pass/empty-tag.rs
src/test/run-pass/enum-alignment.rs
src/test/run-pass/enum-clike-ffi-as-int.rs
src/test/run-pass/enum-discr.rs
src/test/run-pass/enum-discrim-autosizing.rs
src/test/run-pass/enum-discrim-manual-sizing.rs
src/test/run-pass/enum-discrim-range-overflow.rs
src/test/run-pass/enum-discrim-width-stuff.rs
src/test/run-pass/enum-disr-val-pretty.rs
src/test/run-pass/enum-export-inheritance.rs
src/test/run-pass/enum-null-pointer-opt.rs
src/test/run-pass/enum-nullable-const-null-with-fields.rs
src/test/run-pass/enum-nullable-simplifycfg-misopt.rs
src/test/run-pass/enum-size-variance.rs
src/test/run-pass/enum-variants.rs
src/test/run-pass/enum-vec-initializer.rs
src/test/run-pass/env-home-dir.rs
src/test/run-pass/env-vars.rs
src/test/run-pass/eq-multidispatch.rs
src/test/run-pass/estr-uniq.rs
src/test/run-pass/evec-internal.rs
src/test/run-pass/evec-slice.rs
src/test/run-pass/exec-env.rs
src/test/run-pass/explicit-i-suffix.rs
src/test/run-pass/explicit-self-closures.rs
src/test/run-pass/explicit-self-generic.rs
src/test/run-pass/explicit-self-objects-uniq.rs
src/test/run-pass/explicit-self.rs
src/test/run-pass/explicit_self_xcrate_exe.rs
src/test/run-pass/exponential-notation.rs
src/test/run-pass/export-abstract-tag.rs
src/test/run-pass/export-glob-imports-target.rs
src/test/run-pass/export-multi.rs
src/test/run-pass/export-non-interference3.rs
src/test/run-pass/export-tag-variant.rs
src/test/run-pass/export-unexported-dep.rs [deleted file]
src/test/run-pass/expr-block-fn.rs
src/test/run-pass/expr-block-generic-unique2.rs
src/test/run-pass/expr-block-generic.rs
src/test/run-pass/expr-block-slot.rs
src/test/run-pass/expr-block-unique.rs
src/test/run-pass/expr-block.rs
src/test/run-pass/expr-copy.rs
src/test/run-pass/expr-empty-ret.rs
src/test/run-pass/expr-fn.rs
src/test/run-pass/expr-if-generic.rs
src/test/run-pass/expr-if-panic-all.rs
src/test/run-pass/expr-if-panic.rs
src/test/run-pass/expr-if-struct.rs
src/test/run-pass/expr-if-unique.rs
src/test/run-pass/expr-if.rs
src/test/run-pass/expr-match-generic-unique1.rs
src/test/run-pass/expr-match-generic-unique2.rs
src/test/run-pass/expr-match-generic.rs
src/test/run-pass/expr-match-panic-all.rs
src/test/run-pass/expr-match-panic.rs
src/test/run-pass/expr-match-struct.rs
src/test/run-pass/expr-match-unique.rs
src/test/run-pass/expr-match.rs
src/test/run-pass/expr-scope.rs
src/test/run-pass/ext-expand-inner-exprs.rs
src/test/run-pass/exterior.rs
src/test/run-pass/extern-1.rs
src/test/run-pass/extern-call-deep.rs
src/test/run-pass/extern-call-deep2.rs
src/test/run-pass/extern-call-direct.rs
src/test/run-pass/extern-call-indirect.rs
src/test/run-pass/extern-call-scrub.rs
src/test/run-pass/extern-calling-convention-test.rs
src/test/run-pass/extern-compare-with-return-type.rs
src/test/run-pass/extern-crosscrate.rs
src/test/run-pass/extern-foreign-crate.rs
src/test/run-pass/extern-methods.rs [new file with mode: 0644]
src/test/run-pass/extern-mod-abi.rs
src/test/run-pass/extern-mod-ordering-exe.rs
src/test/run-pass/extern-mod-syntax.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/extern-pass-char.rs
src/test/run-pass/extern-pass-double.rs
src/test/run-pass/extern-pass-empty.rs
src/test/run-pass/extern-pass-u32.rs
src/test/run-pass/extern-pass-u64.rs
src/test/run-pass/extern-pub.rs
src/test/run-pass/extern-return-TwoU16s.rs
src/test/run-pass/extern-return-TwoU32s.rs
src/test/run-pass/extern-return-TwoU64s.rs
src/test/run-pass/extern-return-TwoU8s.rs
src/test/run-pass/extern-rust.rs
src/test/run-pass/extern-stress.rs [deleted file]
src/test/run-pass/extern-take-value.rs
src/test/run-pass/extern-yield.rs [deleted file]
src/test/run-pass/extoption_env-not-defined.rs
src/test/run-pass/fact.rs
src/test/run-pass/field-destruction-order.rs
src/test/run-pass/filter-block-view-items.rs
src/test/run-pass/fixed_length_copy.rs
src/test/run-pass/fixup-deref-mut.rs
src/test/run-pass/float-nan.rs
src/test/run-pass/float2.rs
src/test/run-pass/floatlits.rs
src/test/run-pass/fn-abi.rs
src/test/run-pass/fn-bare-assign.rs
src/test/run-pass/fn-bare-coerce-to-block.rs
src/test/run-pass/fn-bare-size.rs
src/test/run-pass/fn-bare-spawn.rs
src/test/run-pass/fn-coerce-field.rs
src/test/run-pass/fn-item-type-cast.rs
src/test/run-pass/fn-item-type-coerce.rs
src/test/run-pass/fn-lval.rs
src/test/run-pass/fn-pattern-expected-type-2.rs
src/test/run-pass/fn-pattern-expected-type.rs
src/test/run-pass/fn-type-infer.rs
src/test/run-pass/for-destruct.rs
src/test/run-pass/for-loop-goofiness.rs
src/test/run-pass/for-loop-into-iterator.rs
src/test/run-pass/for-loop-no-std.rs
src/test/run-pass/for-loop-panic.rs
src/test/run-pass/foreach-external-iterators-break.rs
src/test/run-pass/foreach-external-iterators-hashmap-break-restart.rs
src/test/run-pass/foreach-external-iterators-hashmap.rs
src/test/run-pass/foreach-external-iterators-loop.rs
src/test/run-pass/foreach-external-iterators-nested.rs
src/test/run-pass/foreach-external-iterators.rs
src/test/run-pass/foreach-nested.rs
src/test/run-pass/foreach-put-structured.rs
src/test/run-pass/foreach-simple-outer-slot.rs
src/test/run-pass/foreign-call-no-runtime.rs
src/test/run-pass/foreign-dupe.rs
src/test/run-pass/foreign-fn-linkname.rs
src/test/run-pass/foreign-fn-with-byval.rs
src/test/run-pass/foreign-mod-unused-const.rs
src/test/run-pass/foreign-no-abi.rs
src/test/run-pass/foreign-struct.rs
src/test/run-pass/foreign2.rs
src/test/run-pass/format-nan.rs
src/test/run-pass/format-no-std.rs
src/test/run-pass/format-ref-cell.rs
src/test/run-pass/fsu-moves-and-copies.rs
src/test/run-pass/fun-call-variants.rs
src/test/run-pass/fun-indirect-call.rs
src/test/run-pass/func-arg-incomplete-pattern.rs
src/test/run-pass/func-arg-ref-pattern.rs
src/test/run-pass/func-arg-wild-pattern.rs
src/test/run-pass/functional-struct-upd.rs
src/test/run-pass/generic-alias-unique.rs
src/test/run-pass/generic-default-type-params-cross-crate.rs
src/test/run-pass/generic-default-type-params.rs
src/test/run-pass/generic-derived-type.rs
src/test/run-pass/generic-exterior-unique.rs
src/test/run-pass/generic-extern-mangle.rs
src/test/run-pass/generic-fn-infer.rs
src/test/run-pass/generic-fn-twice.rs
src/test/run-pass/generic-fn.rs
src/test/run-pass/generic-ivec-leak.rs
src/test/run-pass/generic-newtype-struct.rs
src/test/run-pass/generic-object.rs
src/test/run-pass/generic-recursive-tag.rs
src/test/run-pass/generic-static-methods.rs
src/test/run-pass/generic-tag-corruption.rs
src/test/run-pass/generic-tag-local.rs
src/test/run-pass/generic-tag-match.rs
src/test/run-pass/generic-tag-values.rs
src/test/run-pass/generic-tag.rs
src/test/run-pass/generic-temporary.rs
src/test/run-pass/generic-type-synonym.rs
src/test/run-pass/generic-type.rs
src/test/run-pass/generic-unique.rs
src/test/run-pass/getopts_ref.rs
src/test/run-pass/global-scope.rs
src/test/run-pass/guards-not-exhaustive.rs
src/test/run-pass/guards.rs
src/test/run-pass/hashmap-memory.rs
src/test/run-pass/hrtb-binder-levels-in-object-types.rs
src/test/run-pass/hrtb-debruijn-object-types-in-closures.rs
src/test/run-pass/hrtb-fn-like-trait-object.rs
src/test/run-pass/hrtb-fn-like-trait.rs
src/test/run-pass/hrtb-opt-in-copy.rs
src/test/run-pass/hrtb-parse.rs
src/test/run-pass/hrtb-precedence-of-plus-where-clause.rs
src/test/run-pass/hrtb-precedence-of-plus.rs
src/test/run-pass/hrtb-resolve-lifetime.rs
src/test/run-pass/hrtb-trait-object-paren-notation.rs
src/test/run-pass/hrtb-trait-object-passed-to-closure.rs
src/test/run-pass/hrtb-unboxed-closure-trait.rs
src/test/run-pass/huge-largest-array.rs
src/test/run-pass/hygiene-dodging-1.rs
src/test/run-pass/hygienic-labels-in-let.rs
src/test/run-pass/hygienic-labels.rs
src/test/run-pass/i32-sub.rs
src/test/run-pass/i8-incr.rs
src/test/run-pass/if-bot.rs
src/test/run-pass/if-check.rs
src/test/run-pass/if-let.rs
src/test/run-pass/if-ret.rs
src/test/run-pass/ifmt.rs
src/test/run-pass/ignore-all-the-things.rs
src/test/run-pass/impl-implicit-trait.rs
src/test/run-pass/impl-inherent-non-conflict.rs [new file with mode: 0644]
src/test/run-pass/impl-inherent-prefer-over-trait.rs [new file with mode: 0644]
src/test/run-pass/impl-not-adjacent-to-type.rs [new file with mode: 0644]
src/test/run-pass/impl-privacy-xc-1.rs
src/test/run-pass/import-crate-with-invalid-spans.rs [new file with mode: 0644]
src/test/run-pass/import-from.rs
src/test/run-pass/import-glob-crate.rs
src/test/run-pass/import-in-block.rs
src/test/run-pass/import-trailing-comma.rs
src/test/run-pass/import.rs
src/test/run-pass/import2.rs
src/test/run-pass/import3.rs
src/test/run-pass/import4.rs
src/test/run-pass/import5.rs
src/test/run-pass/import6.rs
src/test/run-pass/import7.rs
src/test/run-pass/import8.rs
src/test/run-pass/inconsistent-lifetime-mismatch.rs
src/test/run-pass/infer-container-across-object-cast.rs [deleted file]
src/test/run-pass/infer-fn-tail-expr.rs
src/test/run-pass/inferred-suffix-in-pattern-range.rs
src/test/run-pass/infinite-loops.rs
src/test/run-pass/inherent-trait-method-order.rs
src/test/run-pass/init-large-type.rs
src/test/run-pass/init-res-into-things.rs
src/test/run-pass/inner-attrs-on-impl.rs
src/test/run-pass/inner-static.rs
src/test/run-pass/instantiable.rs
src/test/run-pass/int.rs
src/test/run-pass/integer-literal-radix.rs
src/test/run-pass/integer-literal-suffix-inference-2.rs
src/test/run-pass/integer-literal-suffix-inference-3.rs
src/test/run-pass/integer-literal-suffix-inference.rs
src/test/run-pass/into-iterator-type-inference-shift.rs
src/test/run-pass/intrinsic-alignment.rs
src/test/run-pass/intrinsic-assume.rs
src/test/run-pass/intrinsic-atomics-cc.rs
src/test/run-pass/intrinsic-atomics.rs
src/test/run-pass/intrinsic-move-val.rs
src/test/run-pass/intrinsic-return-address.rs
src/test/run-pass/intrinsic-uninit.rs
src/test/run-pass/intrinsic-unreachable.rs
src/test/run-pass/intrinsics-integer.rs
src/test/run-pass/intrinsics-math.rs
src/test/run-pass/invoke-external-foreign.rs
src/test/run-pass/irrefutable-unit.rs
src/test/run-pass/issue-10025.rs
src/test/run-pass/issue-10028.rs
src/test/run-pass/issue-10031.rs
src/test/run-pass/issue-10228.rs
src/test/run-pass/issue-10392.rs
src/test/run-pass/issue-10456.rs
src/test/run-pass/issue-10626.rs
src/test/run-pass/issue-10638.rs
src/test/run-pass/issue-10682.rs
src/test/run-pass/issue-10683.rs
src/test/run-pass/issue-10714.rs
src/test/run-pass/issue-10718.rs
src/test/run-pass/issue-10734.rs
src/test/run-pass/issue-10763.rs
src/test/run-pass/issue-10764.rs
src/test/run-pass/issue-10767.rs
src/test/run-pass/issue-10802.rs
src/test/run-pass/issue-10806.rs
src/test/run-pass/issue-10853.rs
src/test/run-pass/issue-10902.rs
src/test/run-pass/issue-11085.rs
src/test/run-pass/issue-1112.rs
src/test/run-pass/issue-11205.rs
src/test/run-pass/issue-11224.rs
src/test/run-pass/issue-11225-1.rs
src/test/run-pass/issue-11225-2.rs
src/test/run-pass/issue-11267.rs
src/test/run-pass/issue-11384.rs
src/test/run-pass/issue-11508.rs
src/test/run-pass/issue-11529.rs
src/test/run-pass/issue-11552.rs
src/test/run-pass/issue-11577.rs
src/test/run-pass/issue-11592.rs [new file with mode: 0644]
src/test/run-pass/issue-11612.rs
src/test/run-pass/issue-11677.rs
src/test/run-pass/issue-11709.rs
src/test/run-pass/issue-11736.rs
src/test/run-pass/issue-11820.rs [new file with mode: 0644]
src/test/run-pass/issue-11869.rs
src/test/run-pass/issue-11881.rs
src/test/run-pass/issue-11940.rs
src/test/run-pass/issue-11958.rs
src/test/run-pass/issue-12133-1.rs
src/test/run-pass/issue-12133-2.rs
src/test/run-pass/issue-12133-3.rs
src/test/run-pass/issue-12285.rs
src/test/run-pass/issue-1251.rs
src/test/run-pass/issue-1257.rs
src/test/run-pass/issue-12612.rs
src/test/run-pass/issue-12660.rs
src/test/run-pass/issue-12677.rs
src/test/run-pass/issue-12684.rs
src/test/run-pass/issue-12699.rs
src/test/run-pass/issue-12729.rs [new file with mode: 0644]
src/test/run-pass/issue-12744.rs
src/test/run-pass/issue-12860.rs
src/test/run-pass/issue-12909.rs
src/test/run-pass/issue-13027.rs
src/test/run-pass/issue-13105.rs
src/test/run-pass/issue-13167.rs
src/test/run-pass/issue-13204.rs
src/test/run-pass/issue-13214.rs
src/test/run-pass/issue-13259-windows-tcb-trash.rs
src/test/run-pass/issue-13264.rs
src/test/run-pass/issue-13304.rs
src/test/run-pass/issue-13323.rs
src/test/run-pass/issue-13352.rs [deleted file]
src/test/run-pass/issue-13405.rs
src/test/run-pass/issue-13494.rs
src/test/run-pass/issue-13507-2.rs
src/test/run-pass/issue-13620.rs
src/test/run-pass/issue-13655.rs
src/test/run-pass/issue-13665.rs
src/test/run-pass/issue-13703.rs
src/test/run-pass/issue-13763.rs
src/test/run-pass/issue-13775.rs
src/test/run-pass/issue-13808.rs
src/test/run-pass/issue-13837.rs
src/test/run-pass/issue-13867.rs
src/test/run-pass/issue-13872.rs
src/test/run-pass/issue-14021.rs
src/test/run-pass/issue-14082.rs
src/test/run-pass/issue-14254.rs
src/test/run-pass/issue-14308.rs
src/test/run-pass/issue-14330.rs
src/test/run-pass/issue-14393.rs
src/test/run-pass/issue-14399.rs
src/test/run-pass/issue-14421.rs
src/test/run-pass/issue-14422.rs
src/test/run-pass/issue-14456.rs
src/test/run-pass/issue-1451.rs
src/test/run-pass/issue-14589.rs
src/test/run-pass/issue-1460.rs
src/test/run-pass/issue-14837.rs
src/test/run-pass/issue-14865.rs
src/test/run-pass/issue-14901.rs
src/test/run-pass/issue-14919.rs
src/test/run-pass/issue-14933.rs
src/test/run-pass/issue-14936.rs
src/test/run-pass/issue-14940.rs
src/test/run-pass/issue-14958.rs
src/test/run-pass/issue-14959.rs
src/test/run-pass/issue-15043.rs
src/test/run-pass/issue-15080.rs
src/test/run-pass/issue-15104.rs
src/test/run-pass/issue-15108.rs
src/test/run-pass/issue-15129.rs
src/test/run-pass/issue-15149.rs
src/test/run-pass/issue-15155.rs
src/test/run-pass/issue-15221.rs
src/test/run-pass/issue-15261.rs
src/test/run-pass/issue-15444.rs
src/test/run-pass/issue-15562.rs
src/test/run-pass/issue-15571.rs
src/test/run-pass/issue-15673.rs
src/test/run-pass/issue-15689-1.rs
src/test/run-pass/issue-15689-2.rs
src/test/run-pass/issue-15730.rs
src/test/run-pass/issue-15734.rs
src/test/run-pass/issue-15763.rs
src/test/run-pass/issue-15774.rs
src/test/run-pass/issue-15793.rs
src/test/run-pass/issue-15858.rs
src/test/run-pass/issue-15881-model-lexer-dotdotdot.rs
src/test/run-pass/issue-15924.rs
src/test/run-pass/issue-16151.rs
src/test/run-pass/issue-16256.rs
src/test/run-pass/issue-16272.rs
src/test/run-pass/issue-16278.rs
src/test/run-pass/issue-16441.rs
src/test/run-pass/issue-16452.rs
src/test/run-pass/issue-16492.rs
src/test/run-pass/issue-16530.rs
src/test/run-pass/issue-16560.rs
src/test/run-pass/issue-16596.rs
src/test/run-pass/issue-16597.rs
src/test/run-pass/issue-1660.rs
src/test/run-pass/issue-16643.rs
src/test/run-pass/issue-16648.rs
src/test/run-pass/issue-16668.rs
src/test/run-pass/issue-16671.rs
src/test/run-pass/issue-16739.rs
src/test/run-pass/issue-16774.rs
src/test/run-pass/issue-16783.rs
src/test/run-pass/issue-16922.rs [new file with mode: 0644]
src/test/run-pass/issue-1696.rs
src/test/run-pass/issue-1701.rs
src/test/run-pass/issue-17068.rs
src/test/run-pass/issue-17074.rs
src/test/run-pass/issue-17121.rs
src/test/run-pass/issue-17216.rs
src/test/run-pass/issue-17233.rs [new file with mode: 0644]
src/test/run-pass/issue-17302.rs
src/test/run-pass/issue-17322.rs
src/test/run-pass/issue-17351.rs
src/test/run-pass/issue-17361.rs
src/test/run-pass/issue-17503.rs
src/test/run-pass/issue-17662.rs
src/test/run-pass/issue-17718-parse-const.rs
src/test/run-pass/issue-17718-static-unsafe-interior.rs
src/test/run-pass/issue-17718.rs
src/test/run-pass/issue-17732.rs
src/test/run-pass/issue-17734.rs
src/test/run-pass/issue-17746.rs [new file with mode: 0644]
src/test/run-pass/issue-17771.rs
src/test/run-pass/issue-17816.rs
src/test/run-pass/issue-17877.rs
src/test/run-pass/issue-17897.rs
src/test/run-pass/issue-17904.rs
src/test/run-pass/issue-18110.rs
src/test/run-pass/issue-18188.rs
src/test/run-pass/issue-1821.rs
src/test/run-pass/issue-18232.rs
src/test/run-pass/issue-18352.rs
src/test/run-pass/issue-18353.rs
src/test/run-pass/issue-18412.rs
src/test/run-pass/issue-18425.rs
src/test/run-pass/issue-18501.rs
src/test/run-pass/issue-18514.rs
src/test/run-pass/issue-18539.rs
src/test/run-pass/issue-18619.rs
src/test/run-pass/issue-18652.rs
src/test/run-pass/issue-1866.rs
src/test/run-pass/issue-18661.rs
src/test/run-pass/issue-18685.rs
src/test/run-pass/issue-18711.rs
src/test/run-pass/issue-18738.rs
src/test/run-pass/issue-18767.rs
src/test/run-pass/issue-18859.rs
src/test/run-pass/issue-18906.rs
src/test/run-pass/issue-19037.rs
src/test/run-pass/issue-19098.rs
src/test/run-pass/issue-19100.rs
src/test/run-pass/issue-19121.rs
src/test/run-pass/issue-19127.rs
src/test/run-pass/issue-19129-1.rs
src/test/run-pass/issue-19129-2.rs
src/test/run-pass/issue-19244.rs
src/test/run-pass/issue-19293.rs
src/test/run-pass/issue-19340-1.rs
src/test/run-pass/issue-19340-2.rs
src/test/run-pass/issue-19358.rs
src/test/run-pass/issue-19398.rs
src/test/run-pass/issue-19479.rs
src/test/run-pass/issue-19499.rs
src/test/run-pass/issue-19631.rs
src/test/run-pass/issue-19632.rs
src/test/run-pass/issue-1974.rs
src/test/run-pass/issue-19811-escape-unicode.rs
src/test/run-pass/issue-19850.rs
src/test/run-pass/issue-19982.rs [new file with mode: 0644]
src/test/run-pass/issue-20009.rs
src/test/run-pass/issue-20055-box-trait.rs
src/test/run-pass/issue-20055-box-unsized-array.rs
src/test/run-pass/issue-20091.rs
src/test/run-pass/issue-20313.rs
src/test/run-pass/issue-20343.rs
src/test/run-pass/issue-20389.rs
src/test/run-pass/issue-20396.rs [new file with mode: 0644]
src/test/run-pass/issue-20414.rs
src/test/run-pass/issue-20454.rs
src/test/run-pass/issue-20575.rs
src/test/run-pass/issue-20644.rs
src/test/run-pass/issue-20676.rs
src/test/run-pass/issue-2074.rs
src/test/run-pass/issue-20763-1.rs
src/test/run-pass/issue-20763-2.rs
src/test/run-pass/issue-20797.rs
src/test/run-pass/issue-20823.rs
src/test/run-pass/issue-21033.rs
src/test/run-pass/issue-21058.rs
src/test/run-pass/issue-21245.rs
src/test/run-pass/issue-21296.rs
src/test/run-pass/issue-21306.rs
src/test/run-pass/issue-21350.rs
src/test/run-pass/issue-21361.rs
src/test/run-pass/issue-21363.rs
src/test/run-pass/issue-21384.rs
src/test/run-pass/issue-21402.rs
src/test/run-pass/issue-21475.rs [new file with mode: 0644]
src/test/run-pass/issue-21520.rs
src/test/run-pass/issue-21634.rs
src/test/run-pass/issue-21655.rs
src/test/run-pass/issue-21721.rs [new file with mode: 0644]
src/test/run-pass/issue-21726.rs
src/test/run-pass/issue-2185.rs
src/test/run-pass/issue-21891.rs
src/test/run-pass/issue-2190-1.rs
src/test/run-pass/issue-21909.rs
src/test/run-pass/issue-22036.rs
src/test/run-pass/issue-2214.rs
src/test/run-pass/issue-22356.rs [new file with mode: 0644]
src/test/run-pass/issue-22426.rs [new file with mode: 0644]
src/test/run-pass/issue-22536-copy-mustnt-zero.rs [new file with mode: 0644]
src/test/run-pass/issue-22577.rs [new file with mode: 0644]
src/test/run-pass/issue-22629.rs [new file with mode: 0644]
src/test/run-pass/issue-22777.rs [new file with mode: 0644]
src/test/run-pass/issue-22828.rs [new file with mode: 0644]
src/test/run-pass/issue-2284.rs
src/test/run-pass/issue-2288.rs
src/test/run-pass/issue-23037.rs [new file with mode: 0644]
src/test/run-pass/issue-2311-2.rs
src/test/run-pass/issue-2311.rs
src/test/run-pass/issue-2312.rs
src/test/run-pass/issue-2316-c.rs
src/test/run-pass/issue-23435.rs [new file with mode: 0644]
src/test/run-pass/issue-23485.rs [new file with mode: 0644]
src/test/run-pass/issue-23550.rs [new file with mode: 0644]
src/test/run-pass/issue-23781.rs [new file with mode: 0644]
src/test/run-pass/issue-2380-b.rs
src/test/run-pass/issue-2383.rs
src/test/run-pass/issue-2414-c.rs
src/test/run-pass/issue-2428.rs
src/test/run-pass/issue-2445-b.rs
src/test/run-pass/issue-2445.rs
src/test/run-pass/issue-2463.rs
src/test/run-pass/issue-2472.rs
src/test/run-pass/issue-2487-a.rs
src/test/run-pass/issue-2502.rs
src/test/run-pass/issue-2526-a.rs
src/test/run-pass/issue-2550.rs
src/test/run-pass/issue-2611-3.rs
src/test/run-pass/issue-2631-b.rs
src/test/run-pass/issue-2633-2.rs
src/test/run-pass/issue-2633.rs
src/test/run-pass/issue-2642.rs
src/test/run-pass/issue-2708.rs
src/test/run-pass/issue-2718.rs
src/test/run-pass/issue-2723-b.rs
src/test/run-pass/issue-2734.rs
src/test/run-pass/issue-2735-2.rs
src/test/run-pass/issue-2735-3.rs
src/test/run-pass/issue-2735.rs
src/test/run-pass/issue-2748-a.rs
src/test/run-pass/issue-2748-b.rs
src/test/run-pass/issue-2804-2.rs
src/test/run-pass/issue-2804.rs
src/test/run-pass/issue-2895.rs
src/test/run-pass/issue-2904.rs
src/test/run-pass/issue-2935.rs
src/test/run-pass/issue-2936.rs
src/test/run-pass/issue-2989.rs
src/test/run-pass/issue-3012-2.rs
src/test/run-pass/issue-3026.rs
src/test/run-pass/issue-3037.rs
src/test/run-pass/issue-3052.rs
src/test/run-pass/issue-3091.rs
src/test/run-pass/issue-3121.rs
src/test/run-pass/issue-3149.rs
src/test/run-pass/issue-3220.rs
src/test/run-pass/issue-3290.rs
src/test/run-pass/issue-333.rs
src/test/run-pass/issue-3424.rs
src/test/run-pass/issue-3429.rs
src/test/run-pass/issue-3500.rs
src/test/run-pass/issue-3559.rs
src/test/run-pass/issue-3563-2.rs
src/test/run-pass/issue-3563-3.rs
src/test/run-pass/issue-3574.rs
src/test/run-pass/issue-3609.rs
src/test/run-pass/issue-3656.rs
src/test/run-pass/issue-3683.rs
src/test/run-pass/issue-3743.rs
src/test/run-pass/issue-3753.rs
src/test/run-pass/issue-3794.rs
src/test/run-pass/issue-3847.rs
src/test/run-pass/issue-3874.rs
src/test/run-pass/issue-3878.rs
src/test/run-pass/issue-3888-2.rs
src/test/run-pass/issue-3895.rs
src/test/run-pass/issue-3935.rs
src/test/run-pass/issue-3979-2.rs
src/test/run-pass/issue-3979-generics.rs
src/test/run-pass/issue-3979-xcrate.rs
src/test/run-pass/issue-3979.rs
src/test/run-pass/issue-3991.rs
src/test/run-pass/issue-4016.rs
src/test/run-pass/issue-4036.rs
src/test/run-pass/issue-4107.rs
src/test/run-pass/issue-4208.rs
src/test/run-pass/issue-4228.rs
src/test/run-pass/issue-4241.rs
src/test/run-pass/issue-4252.rs
src/test/run-pass/issue-4333.rs
src/test/run-pass/issue-4387.rs
src/test/run-pass/issue-4446.rs
src/test/run-pass/issue-4448.rs
src/test/run-pass/issue-4464.rs
src/test/run-pass/issue-4542.rs
src/test/run-pass/issue-4545.rs
src/test/run-pass/issue-4734.rs
src/test/run-pass/issue-4735.rs
src/test/run-pass/issue-4759-1.rs
src/test/run-pass/issue-4759.rs
src/test/run-pass/issue-4830.rs
src/test/run-pass/issue-4875.rs
src/test/run-pass/issue-5060.rs
src/test/run-pass/issue-5192.rs
src/test/run-pass/issue-5239-2.rs
src/test/run-pass/issue-5243.rs
src/test/run-pass/issue-5315.rs
src/test/run-pass/issue-5321-immediates-with-bare-self.rs
src/test/run-pass/issue-5353.rs
src/test/run-pass/issue-5518.rs
src/test/run-pass/issue-5521.rs
src/test/run-pass/issue-5530.rs
src/test/run-pass/issue-5550.rs
src/test/run-pass/issue-5554.rs
src/test/run-pass/issue-5572.rs
src/test/run-pass/issue-5666.rs
src/test/run-pass/issue-5688.rs
src/test/run-pass/issue-5708.rs
src/test/run-pass/issue-5718.rs
src/test/run-pass/issue-5741.rs
src/test/run-pass/issue-5754.rs
src/test/run-pass/issue-5791.rs
src/test/run-pass/issue-5884.rs
src/test/run-pass/issue-5900.rs
src/test/run-pass/issue-5917.rs
src/test/run-pass/issue-5950.rs
src/test/run-pass/issue-5988.rs
src/test/run-pass/issue-5997.rs
src/test/run-pass/issue-6117.rs
src/test/run-pass/issue-6128.rs
src/test/run-pass/issue-6130.rs
src/test/run-pass/issue-6153.rs
src/test/run-pass/issue-6157.rs
src/test/run-pass/issue-6318.rs
src/test/run-pass/issue-6334.rs
src/test/run-pass/issue-6341.rs
src/test/run-pass/issue-6344-let.rs
src/test/run-pass/issue-6344-match.rs
src/test/run-pass/issue-6449.rs
src/test/run-pass/issue-6470.rs
src/test/run-pass/issue-6557.rs
src/test/run-pass/issue-6892.rs
src/test/run-pass/issue-6898.rs
src/test/run-pass/issue-6919.rs
src/test/run-pass/issue-7012.rs
src/test/run-pass/issue-7178.rs
src/test/run-pass/issue-7222.rs
src/test/run-pass/issue-7268.rs
src/test/run-pass/issue-7344.rs
src/test/run-pass/issue-7519-match-unit-in-arg.rs
src/test/run-pass/issue-7563.rs
src/test/run-pass/issue-7575.rs
src/test/run-pass/issue-7607-2.rs [new file with mode: 0644]
src/test/run-pass/issue-7660.rs
src/test/run-pass/issue-7663.rs
src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
src/test/run-pass/issue-7784.rs
src/test/run-pass/issue-7899.rs
src/test/run-pass/issue-8044.rs
src/test/run-pass/issue-8171-default-method-self-inherit-builtin-trait.rs
src/test/run-pass/issue-8248.rs
src/test/run-pass/issue-8249.rs
src/test/run-pass/issue-8259.rs
src/test/run-pass/issue-8351-1.rs
src/test/run-pass/issue-8351-2.rs
src/test/run-pass/issue-8391.rs
src/test/run-pass/issue-8398.rs
src/test/run-pass/issue-8401.rs
src/test/run-pass/issue-8460.rs
src/test/run-pass/issue-8498.rs
src/test/run-pass/issue-8506.rs
src/test/run-pass/issue-8578.rs
src/test/run-pass/issue-868.rs
src/test/run-pass/issue-8709.rs
src/test/run-pass/issue-8783.rs
src/test/run-pass/issue-8827.rs
src/test/run-pass/issue-8851.rs
src/test/run-pass/issue-8860.rs
src/test/run-pass/issue-8898.rs
src/test/run-pass/issue-9047.rs
src/test/run-pass/issue-9110.rs
src/test/run-pass/issue-9123.rs
src/test/run-pass/issue-9129.rs
src/test/run-pass/issue-9188.rs
src/test/run-pass/issue-9249.rs
src/test/run-pass/issue-9259.rs
src/test/run-pass/issue-9382.rs
src/test/run-pass/issue-9394-inherited-trait-calls.rs
src/test/run-pass/issue-9396.rs
src/test/run-pass/issue-9719.rs
src/test/run-pass/issue-979.rs
src/test/run-pass/issue-9906.rs
src/test/run-pass/issue-9918.rs
src/test/run-pass/issue-9942.rs
src/test/run-pass/issue-9951.rs [new file with mode: 0644]
src/test/run-pass/issue-9968.rs
src/test/run-pass/issue2170exe.rs
src/test/run-pass/issue22346.rs
src/test/run-pass/issue_3136_b.rs
src/test/run-pass/issue_9155.rs
src/test/run-pass/istr.rs
src/test/run-pass/item-attributes.rs
src/test/run-pass/item-name-overload.rs
src/test/run-pass/iter-cloned-type-inference.rs [new file with mode: 0644]
src/test/run-pass/iter-range.rs
src/test/run-pass/ivec-pass-by-value.rs
src/test/run-pass/ivec-tag.rs
src/test/run-pass/keyword-changes-2012-07-31.rs
src/test/run-pass/kindck-implicit-close-over-mut-var.rs
src/test/run-pass/kindck-owned-trait-contains-1.rs
src/test/run-pass/kinds-in-metadata.rs
src/test/run-pass/labeled-break.rs
src/test/run-pass/lambda-infer-unresolved.rs
src/test/run-pass/lambda-var-hygiene.rs
src/test/run-pass/lang-item-public.rs
src/test/run-pass/large-records.rs
src/test/run-pass/last-use-in-block.rs
src/test/run-pass/last-use-in-cap-clause.rs
src/test/run-pass/last-use-is-capture.rs
src/test/run-pass/lazy-and-or.rs
src/test/run-pass/lazy-init.rs
src/test/run-pass/leak-unique-as-tydesc.rs
src/test/run-pass/let-assignability.rs
src/test/run-pass/let-destruct-ref.rs
src/test/run-pass/let-var-hygiene.rs
src/test/run-pass/linear-for-loop.rs
src/test/run-pass/link-section.rs
src/test/run-pass/linkage-visibility.rs
src/test/run-pass/linkage1.rs
src/test/run-pass/lint-cstack.rs [deleted file]
src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs
src/test/run-pass/lint-non-camel-case-with-trailing-underscores.rs
src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs
src/test/run-pass/list.rs
src/test/run-pass/liveness-assign-imm-local-after-loop.rs
src/test/run-pass/liveness-assign-imm-local-after-ret.rs
src/test/run-pass/liveness-move-in-loop.rs
src/test/run-pass/log-knows-the-names-of-variants-in-std.rs
src/test/run-pass/log_syntax-trace_macros-macro-locations.rs
src/test/run-pass/logging-enabled-debug.rs
src/test/run-pass/logging-enabled.rs
src/test/run-pass/logging-only-prints-once.rs
src/test/run-pass/logging-right-crate.rs
src/test/run-pass/logging-separate-lines.rs
src/test/run-pass/logging_before_rt_started.rs
src/test/run-pass/long-while.rs
src/test/run-pass/loop-break-cont-1.rs
src/test/run-pass/loop-diverges.rs
src/test/run-pass/loop-label-shadowing.rs
src/test/run-pass/loop-labeled-break-value.rs [new file with mode: 0644]
src/test/run-pass/loop-no-reinit-needed-post-bot.rs
src/test/run-pass/loop-scope.rs
src/test/run-pass/macro-2.rs
src/test/run-pass/macro-attributes.rs
src/test/run-pass/macro-block-nonterminal.rs
src/test/run-pass/macro-crate-def-only.rs
src/test/run-pass/macro-crate-nonterminal-renamed.rs
src/test/run-pass/macro-crate-use.rs
src/test/run-pass/macro-deep_expansion.rs
src/test/run-pass/macro-delimiter-significance.rs
src/test/run-pass/macro-interpolation.rs
src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs
src/test/run-pass/macro-meta-items.rs
src/test/run-pass/macro-method-issue-4621.rs
src/test/run-pass/macro-nt-list.rs
src/test/run-pass/macro-of-higher-order.rs
src/test/run-pass/macro-pat.rs
src/test/run-pass/macro-path.rs
src/test/run-pass/macro-stmt.rs
src/test/run-pass/macro-with-attrs1.rs
src/test/run-pass/macro-with-attrs2.rs
src/test/run-pass/macro-with-braces-in-expr-position.rs
src/test/run-pass/macro_with_super_2.rs
src/test/run-pass/match-arm-statics.rs
src/test/run-pass/match-borrowed_str.rs
src/test/run-pass/match-bot-2.rs
src/test/run-pass/match-bot.rs
src/test/run-pass/match-enum-struct-0.rs
src/test/run-pass/match-enum-struct-1.rs
src/test/run-pass/match-implicit-copy-unique.rs
src/test/run-pass/match-in-macro.rs
src/test/run-pass/match-join.rs
src/test/run-pass/match-naked-record-expr.rs
src/test/run-pass/match-naked-record.rs
src/test/run-pass/match-path.rs
src/test/run-pass/match-pattern-bindings.rs
src/test/run-pass/match-pattern-lit.rs
src/test/run-pass/match-pattern-no-type-params.rs
src/test/run-pass/match-pattern-simple.rs
src/test/run-pass/match-phi.rs
src/test/run-pass/match-pipe-binding.rs
src/test/run-pass/match-range-static.rs
src/test/run-pass/match-reassign.rs [new file with mode: 0644]
src/test/run-pass/match-ref-binding-in-guard-3256.rs
src/test/run-pass/match-ref-binding-mut-option.rs
src/test/run-pass/match-ref-binding-mut.rs
src/test/run-pass/match-ref-binding.rs
src/test/run-pass/match-ref-unsized.rs [new file with mode: 0644]
src/test/run-pass/match-static-const-rename.rs
src/test/run-pass/match-str.rs
src/test/run-pass/match-struct-0.rs
src/test/run-pass/match-tag.rs
src/test/run-pass/match-value-binding-in-guard-3291.rs
src/test/run-pass/match-vec-alternatives.rs
src/test/run-pass/match-vec-rvalue.rs
src/test/run-pass/match-with-ret-arm.rs
src/test/run-pass/max-min-classes.rs
src/test/run-pass/method-attributes.rs
src/test/run-pass/method-early-bound-lifetimes-on-self.rs
src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
src/test/run-pass/method-normalize-bounds-issue-20604.rs
src/test/run-pass/method-projection.rs
src/test/run-pass/method-recursive-blanket-impl.rs
src/test/run-pass/method-self-arg-aux1.rs
src/test/run-pass/method-self-arg-aux2.rs
src/test/run-pass/method-self-arg-trait.rs
src/test/run-pass/method-self-arg.rs
src/test/run-pass/method-two-trait-defer-resolution-1.rs
src/test/run-pass/method-two-trait-defer-resolution-2.rs
src/test/run-pass/method-two-traits-distinguished-via-where-clause.rs
src/test/run-pass/method-where-clause.rs
src/test/run-pass/mid-path-type-params.rs
src/test/run-pass/minmax-stability-issue-23687.rs [new file with mode: 0644]
src/test/run-pass/mod-inside-fn.rs
src/test/run-pass/mod-view-items.rs
src/test/run-pass/mod_dir_implicit_aux/mod.rs
src/test/run-pass/mod_dir_simple/test.rs
src/test/run-pass/mod_file_aux.rs
src/test/run-pass/module-qualified-struct-destructure.rs
src/test/run-pass/monad.rs
src/test/run-pass/monomorphize-abi-alignment.rs
src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs
src/test/run-pass/move-1-unique.rs
src/test/run-pass/move-2-unique.rs
src/test/run-pass/move-2.rs
src/test/run-pass/move-3-unique.rs
src/test/run-pass/move-4-unique.rs
src/test/run-pass/move-4.rs
src/test/run-pass/move-arg-2-unique.rs
src/test/run-pass/move-arg-2.rs
src/test/run-pass/move-arg.rs
src/test/run-pass/move-guard-const.rs [new file with mode: 0644]
src/test/run-pass/move-nullary-fn.rs
src/test/run-pass/move-out-of-field.rs
src/test/run-pass/move-scalar.rs
src/test/run-pass/moves-based-on-type-capture-clause.rs
src/test/run-pass/moves-based-on-type-cross-crate.rs
src/test/run-pass/multi-let.rs
src/test/run-pass/multidispatch1.rs
src/test/run-pass/multidispatch2.rs
src/test/run-pass/multiline-comment.rs
src/test/run-pass/multiple-trait-bounds.rs
src/test/run-pass/mut-function-arguments.rs
src/test/run-pass/mut-in-ident-patterns.rs
src/test/run-pass/mut-vstore-expr.rs
src/test/run-pass/mutability-inherits-through-fixed-length-vec.rs
src/test/run-pass/mutable-alias-vec.rs
src/test/run-pass/mutual-recursion-group.rs
src/test/run-pass/namespaced-enum-emulate-flat-xc.rs
src/test/run-pass/namespaced-enum-emulate-flat.rs
src/test/run-pass/namespaced-enum-glob-import-xcrate.rs
src/test/run-pass/namespaced-enum-glob-import.rs
src/test/run-pass/namespaced-enums-xcrate.rs
src/test/run-pass/namespaced-enums.rs
src/test/run-pass/native-print-no-runtime.rs
src/test/run-pass/negative.rs
src/test/run-pass/nested-block-comment.rs
src/test/run-pass/nested-class.rs
src/test/run-pass/nested-enum-same-names.rs
src/test/run-pass/nested-exhaustive-match.rs
src/test/run-pass/nested-function-names-issue-8587.rs
src/test/run-pass/nested-matchs.rs
src/test/run-pass/nested-pattern.rs
src/test/run-pass/nested-vec-1.rs [new file with mode: 0644]
src/test/run-pass/nested-vec-2.rs [new file with mode: 0644]
src/test/run-pass/nested-vec-3.rs [new file with mode: 0644]
src/test/run-pass/nested_item_main.rs
src/test/run-pass/new-box-syntax.rs
src/test/run-pass/new-box.rs
src/test/run-pass/new-impl-syntax.rs
src/test/run-pass/new-style-constants.rs
src/test/run-pass/new-style-fixed-length-vec.rs
src/test/run-pass/new-unicode-escapes.rs
src/test/run-pass/new-unsafe-pointers.rs
src/test/run-pass/newlambdas-ret-infer.rs
src/test/run-pass/newlambdas-ret-infer2.rs
src/test/run-pass/newlambdas.rs
src/test/run-pass/newtype-polymorphic.rs
src/test/run-pass/newtype-struct-drop-run.rs
src/test/run-pass/newtype-struct-with-dtor.rs
src/test/run-pass/newtype-struct-xc-2.rs
src/test/run-pass/newtype-struct-xc.rs
src/test/run-pass/newtype-temporary.rs
src/test/run-pass/newtype.rs
src/test/run-pass/nil-decl-in-foreign.rs
src/test/run-pass/nil-pattern.rs
src/test/run-pass/no-landing-pads.rs
src/test/run-pass/no-std-xcrate2.rs
src/test/run-pass/non-built-in-quote.rs
src/test/run-pass/non-legacy-modes.rs
src/test/run-pass/nondrop-cycle.rs
src/test/run-pass/nul-characters.rs
src/test/run-pass/nullable-pointer-ffi-compat.rs
src/test/run-pass/nullable-pointer-iotareduction.rs
src/test/run-pass/nullable-pointer-size.rs
src/test/run-pass/nullary-or-pattern.rs
src/test/run-pass/numeric-method-autoexport.rs
src/test/run-pass/object-lifetime-default-default-to-static.rs
src/test/run-pass/object-lifetime-default-from-ref-struct.rs
src/test/run-pass/object-lifetime-default-from-rptr-box.rs
src/test/run-pass/object-lifetime-default-from-rptr-mut.rs
src/test/run-pass/object-lifetime-default-from-rptr-struct.rs
src/test/run-pass/object-lifetime-default-from-rptr.rs
src/test/run-pass/object-method-numbering.rs
src/test/run-pass/object-one-type-two-traits.rs
src/test/run-pass/object-safety-sized-self-by-value-self.rs [new file with mode: 0644]
src/test/run-pass/object-safety-sized-self-generic-method.rs [new file with mode: 0644]
src/test/run-pass/object-safety-sized-self-return-Self.rs [new file with mode: 0644]
src/test/run-pass/objects-coerce-freeze-borrored.rs
src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs
src/test/run-pass/objects-owned-object-owned-method.rs
src/test/run-pass/once-move-out-on-heap.rs
src/test/run-pass/one-tuple.rs
src/test/run-pass/opeq.rs
src/test/run-pass/operator-associativity.rs
src/test/run-pass/operator-multidispatch.rs
src/test/run-pass/operator-overloading.rs
src/test/run-pass/option-ext.rs
src/test/run-pass/option-unwrap.rs
src/test/run-pass/or-pattern.rs
src/test/run-pass/order-drop-with-match.rs
src/test/run-pass/osx-frameworks.rs
src/test/run-pass/out-of-stack-new-thread-no-split.rs
src/test/run-pass/out-of-stack-no-split.rs
src/test/run-pass/out-of-stack.rs
src/test/run-pass/out-pointer-aliasing.rs
src/test/run-pass/output-slot-variants.rs
src/test/run-pass/over-constrained-vregs.rs
src/test/run-pass/overloaded-autoderef-count.rs
src/test/run-pass/overloaded-autoderef-indexing.rs
src/test/run-pass/overloaded-autoderef-order.rs
src/test/run-pass/overloaded-autoderef-vtable.rs
src/test/run-pass/overloaded-autoderef-xcrate.rs
src/test/run-pass/overloaded-autoderef.rs
src/test/run-pass/overloaded-calls-object-one-arg.rs
src/test/run-pass/overloaded-calls-object-two-args.rs
src/test/run-pass/overloaded-calls-object-zero-args.rs
src/test/run-pass/overloaded-calls-param-vtables.rs
src/test/run-pass/overloaded-calls-simple.rs
src/test/run-pass/overloaded-calls-zero-args.rs
src/test/run-pass/overloaded-deref-count.rs
src/test/run-pass/overloaded-deref.rs
src/test/run-pass/overloaded-index-assoc-list.rs
src/test/run-pass/overloaded-index-autoderef.rs
src/test/run-pass/overloaded-index-in-field.rs
src/test/run-pass/overloaded-index.rs
src/test/run-pass/owned-implies-static.rs
src/test/run-pass/packed-struct-borrow-element.rs
src/test/run-pass/packed-struct-generic-layout.rs
src/test/run-pass/packed-struct-generic-size.rs
src/test/run-pass/packed-struct-layout.rs
src/test/run-pass/packed-struct-match.rs
src/test/run-pass/packed-struct-size-xc.rs
src/test/run-pass/packed-struct-size.rs
src/test/run-pass/packed-struct-vec.rs
src/test/run-pass/packed-tuple-struct-layout.rs
src/test/run-pass/packed-tuple-struct-size.rs
src/test/run-pass/panic-in-dtor-drops-fields.rs
src/test/run-pass/parameterized-trait-with-bounds.rs
src/test/run-pass/parse-assoc-type-lt.rs
src/test/run-pass/parse-complex-macro-invoc-op.rs
src/test/run-pass/path.rs
src/test/run-pass/pattern-bound-var-in-for-each.rs
src/test/run-pass/pattern-in-closure.rs
src/test/run-pass/placement-new-arena.rs
src/test/run-pass/pred-not-bool.rs
src/test/run-pass/preempt.rs
src/test/run-pass/priv-impl-prim-ty.rs
src/test/run-pass/privacy-ns.rs
src/test/run-pass/privacy-reexport.rs
src/test/run-pass/privacy1.rs
src/test/run-pass/private-class-field.rs
src/test/run-pass/private-method.rs
src/test/run-pass/process-exit.rs [new file with mode: 0644]
src/test/run-pass/process-remove-from-env.rs
src/test/run-pass/process-spawn-with-unicode-params.rs
src/test/run-pass/ptr-coercion.rs
src/test/run-pass/pub-extern-privacy.rs
src/test/run-pass/pub-item-inside-macro.rs
src/test/run-pass/pub-method-inside-macro.rs
src/test/run-pass/pub-use-xcrate.rs
src/test/run-pass/pub_use_mods_xcrate_exe.rs
src/test/run-pass/pure-sum.rs
src/test/run-pass/range-type-infer.rs
src/test/run-pass/range.rs
src/test/run-pass/ranges-precedence.rs
src/test/run-pass/raw-str.rs
src/test/run-pass/rcvr-borrowed-to-region.rs
src/test/run-pass/rcvr-borrowed-to-slice.rs
src/test/run-pass/readalias.rs
src/test/run-pass/realloc-16687.rs
src/test/run-pass/rec-align-u32.rs
src/test/run-pass/rec-align-u64.rs
src/test/run-pass/rec-extend.rs
src/test/run-pass/rec-tup.rs
src/test/run-pass/rec.rs
src/test/run-pass/record-pat.rs
src/test/run-pass/reexport-should-still-link.rs
src/test/run-pass/reexport-star.rs
src/test/run-pass/reexported-static-methods-cross-crate.rs
src/test/run-pass/regions-addr-of-interior-of-unique-box.rs
src/test/run-pass/regions-addr-of-ret.rs
src/test/run-pass/regions-assoc-type-region-bound.rs
src/test/run-pass/regions-assoc-type-static-bound.rs
src/test/run-pass/regions-borrow-at.rs
src/test/run-pass/regions-borrow-evec-fixed.rs
src/test/run-pass/regions-borrow-evec-uniq.rs
src/test/run-pass/regions-borrow-uniq.rs
src/test/run-pass/regions-bot.rs
src/test/run-pass/regions-close-over-type-parameter-successfully.rs
src/test/run-pass/regions-copy-closure.rs
src/test/run-pass/regions-creating-enums2.rs
src/test/run-pass/regions-creating-enums5.rs
src/test/run-pass/regions-debruijn-of-object.rs
src/test/run-pass/regions-dependent-addr-of.rs
src/test/run-pass/regions-dependent-autofn.rs
src/test/run-pass/regions-dependent-autoslice.rs
src/test/run-pass/regions-dependent-let-ref.rs
src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs
src/test/run-pass/regions-early-bound-trait-param.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-escape-into-other-fn.rs
src/test/run-pass/regions-expl-self.rs
src/test/run-pass/regions-fn-subtyping-2.rs
src/test/run-pass/regions-fn-subtyping.rs
src/test/run-pass/regions-infer-borrow-scope-addr-of.rs
src/test/run-pass/regions-infer-borrow-scope-view.rs
src/test/run-pass/regions-infer-borrow-scope-within-loop-ok.rs
src/test/run-pass/regions-infer-borrow-scope.rs
src/test/run-pass/regions-infer-call-2.rs
src/test/run-pass/regions-infer-call.rs
src/test/run-pass/regions-infer-contravariance-due-to-ret.rs
src/test/run-pass/regions-infer-reborrow-ref-mut-recurse.rs
src/test/run-pass/regions-infer-region-in-fn-but-not-type.rs
src/test/run-pass/regions-infer-static-from-proc.rs
src/test/run-pass/regions-issue-21422.rs
src/test/run-pass/regions-issue-22246.rs
src/test/run-pass/regions-lifetime-nonfree-late-bound.rs
src/test/run-pass/regions-lifetime-static-items-enclosing-scopes.rs
src/test/run-pass/regions-link-fn-args.rs
src/test/run-pass/regions-mock-tcx.rs
src/test/run-pass/regions-mock-trans.rs
src/test/run-pass/regions-no-bound-in-argument-cleanup.rs
src/test/run-pass/regions-no-variance-from-fn-generics.rs
src/test/run-pass/regions-nullary-variant.rs
src/test/run-pass/regions-params.rs
src/test/run-pass/regions-reassign-let-bound-pointer.rs
src/test/run-pass/regions-reassign-match-bound-pointer.rs
src/test/run-pass/regions-refcell.rs
src/test/run-pass/regions-relate-bound-regions-on-closures-to-inference-variables.rs
src/test/run-pass/regions-return-interior-of-option.rs
src/test/run-pass/regions-scope-chain-example.rs
src/test/run-pass/regions-self-impls.rs
src/test/run-pass/regions-self-in-enums.rs
src/test/run-pass/regions-simple.rs
src/test/run-pass/regions-static-closure.rs
src/test/run-pass/regions-trait-object-1.rs
src/test/run-pass/regions-variance-contravariant-use-contravariant.rs
src/test/run-pass/regions-variance-covariant-use-covariant.rs
src/test/run-pass/rename-directory.rs [deleted file]
src/test/run-pass/repeat-expr-in-static.rs
src/test/run-pass/resolve-issue-2428.rs
src/test/run-pass/resource-assign-is-not-copy.rs
src/test/run-pass/resource-destruct.rs
src/test/run-pass/resource-in-struct.rs
src/test/run-pass/ret-bang.rs
src/test/run-pass/ret-none.rs
src/test/run-pass/return-from-closure.rs
src/test/run-pass/return-nil.rs
src/test/run-pass/running-with-no-runtime.rs
src/test/run-pass/rust-log-filter.rs
src/test/run-pass/segfault-no-out-of-stack.rs
src/test/run-pass/self-impl.rs
src/test/run-pass/self-in-mut-slot-default-method.rs
src/test/run-pass/self-in-mut-slot-immediate-value.rs
src/test/run-pass/self-re-assign.rs
src/test/run-pass/self-shadowing-import.rs
src/test/run-pass/self-type-param.rs
src/test/run-pass/send-is-not-static-par-for.rs [changed mode: 0755->0644]
src/test/run-pass/send-resource.rs
src/test/run-pass/send-type-inference.rs
src/test/run-pass/send_str_hashmap.rs
src/test/run-pass/send_str_treemap.rs
src/test/run-pass/sendable-class.rs
src/test/run-pass/sendfn-is-a-block.rs
src/test/run-pass/sendfn-spawn-with-fn-arg.rs
src/test/run-pass/sepcomp-cci.rs
src/test/run-pass/sepcomp-extern.rs
src/test/run-pass/sepcomp-fns-backwards.rs
src/test/run-pass/sepcomp-fns.rs
src/test/run-pass/sepcomp-lib-lto.rs
src/test/run-pass/sepcomp-lib.rs
src/test/run-pass/sepcomp-statics.rs
src/test/run-pass/sepcomp-unwind.rs
src/test/run-pass/seq-compare.rs
src/test/run-pass/shadow.rs
src/test/run-pass/shift-near-oflo.rs [new file with mode: 0644]
src/test/run-pass/shift-various-types.rs
src/test/run-pass/shift.rs
src/test/run-pass/show-boxed-slice.rs
src/test/run-pass/signal-exit-status.rs
src/test/run-pass/signed-shift-const-eval.rs
src/test/run-pass/sigpipe-should-be-ignored.rs
src/test/run-pass/simd-binop.rs
src/test/run-pass/simd-generics.rs
src/test/run-pass/simd-issue-10604.rs
src/test/run-pass/simd-size-align.rs
src/test/run-pass/simd-type.rs
src/test/run-pass/simple-generic-match.rs
src/test/run-pass/simple-generic-tag.rs
src/test/run-pass/simple-match-generic-tag.rs
src/test/run-pass/single-derive-attr-with-gate.rs [new file with mode: 0644]
src/test/run-pass/size-and-align.rs
src/test/run-pass/sized-borrowed-pointer.rs
src/test/run-pass/sized-owned-pointer.rs
src/test/run-pass/slice-2.rs
src/test/run-pass/slice-panic-1.rs
src/test/run-pass/slice-panic-2.rs
src/test/run-pass/slice.rs
src/test/run-pass/small-enum-range-edge.rs
src/test/run-pass/small-enums-with-fields.rs
src/test/run-pass/smallest-hello-world.rs
src/test/run-pass/snake-case-no-lowercase-equivalent.rs
src/test/run-pass/spawn-fn.rs
src/test/run-pass/spawn-types.rs
src/test/run-pass/spawn.rs
src/test/run-pass/spawn2.rs
src/test/run-pass/stable-addr-of.rs
src/test/run-pass/stat.rs [deleted file]
src/test/run-pass/static-assert.rs
src/test/run-pass/static-fn-inline-xc.rs
src/test/run-pass/static-fn-trait-xc.rs
src/test/run-pass/static-function-pointer-xc.rs
src/test/run-pass/static-function-pointer.rs
src/test/run-pass/static-impl.rs
src/test/run-pass/static-method-in-trait-with-tps-intracrate.rs
src/test/run-pass/static-method-xcrate.rs
src/test/run-pass/static-methods-in-traits.rs
src/test/run-pass/static-methods-in-traits2.rs
src/test/run-pass/static-mut-foreign.rs
src/test/run-pass/static-mut-xc.rs
src/test/run-pass/std-sync-right-kind-impls.rs [new file with mode: 0644]
src/test/run-pass/str-multiline.rs
src/test/run-pass/string-escapes.rs
src/test/run-pass/string-self-append.rs
src/test/run-pass/struct-aliases-xcrate.rs
src/test/run-pass/struct-aliases.rs
src/test/run-pass/struct-destructuring-cross-crate.rs
src/test/run-pass/struct-like-variant-construct.rs
src/test/run-pass/struct-like-variant-match.rs
src/test/run-pass/struct-new-as-field-name.rs
src/test/run-pass/struct-order-of-eval-1.rs
src/test/run-pass/struct-order-of-eval-2.rs
src/test/run-pass/struct-order-of-eval-3.rs [new file with mode: 0644]
src/test/run-pass/struct-order-of-eval-4.rs [new file with mode: 0644]
src/test/run-pass/struct-partial-move-1.rs
src/test/run-pass/struct-partial-move-2.rs
src/test/run-pass/struct-pattern-matching.rs
src/test/run-pass/struct-return.rs
src/test/run-pass/struct-variant-field-visibility.rs
src/test/run-pass/struct_variant_xc.rs
src/test/run-pass/struct_variant_xc_match.rs
src/test/run-pass/structured-compare.rs
src/test/run-pass/super-fast-paren-parsing.rs
src/test/run-pass/super.rs
src/test/run-pass/supertrait-default-generics.rs
src/test/run-pass/supported-cast.rs
src/test/run-pass/svh-add-comment.rs
src/test/run-pass/svh-add-doc.rs
src/test/run-pass/svh-add-macro.rs
src/test/run-pass/svh-add-nothing.rs
src/test/run-pass/svh-add-redundant-cfg.rs
src/test/run-pass/svh-add-whitespace.rs
src/test/run-pass/swap-1.rs
src/test/run-pass/swap-2.rs
src/test/run-pass/swap-overlapping.rs
src/test/run-pass/sync-send-iterators-in-libcollections.rs [new file with mode: 0644]
src/test/run-pass/syntax-extension-cfg.rs
src/test/run-pass/syntax-extension-source-utils-files/includeme.fragment
src/test/run-pass/syntax-extension-source-utils.rs
src/test/run-pass/syntax-trait-polarity.rs
src/test/run-pass/tag-align-dyn-u64.rs
src/test/run-pass/tag-align-dyn-variants.rs
src/test/run-pass/tag-align-shape.rs
src/test/run-pass/tag-align-u64.rs
src/test/run-pass/tag-exports.rs
src/test/run-pass/tag-in-block.rs
src/test/run-pass/tag-variant-disr-type-mismatch.rs
src/test/run-pass/tag-variant-disr-val.rs
src/test/run-pass/tag.rs
src/test/run-pass/tail-call-arg-leak.rs
src/test/run-pass/tail-cps.rs
src/test/run-pass/tail-direct.rs
src/test/run-pass/task-comm-0.rs
src/test/run-pass/task-comm-1.rs
src/test/run-pass/task-comm-10.rs
src/test/run-pass/task-comm-11.rs
src/test/run-pass/task-comm-12.rs
src/test/run-pass/task-comm-13.rs
src/test/run-pass/task-comm-14.rs
src/test/run-pass/task-comm-15.rs
src/test/run-pass/task-comm-16.rs
src/test/run-pass/task-comm-17.rs
src/test/run-pass/task-comm-3.rs
src/test/run-pass/task-comm-4.rs
src/test/run-pass/task-comm-5.rs
src/test/run-pass/task-comm-6.rs
src/test/run-pass/task-comm-7.rs
src/test/run-pass/task-comm-9.rs
src/test/run-pass/task-comm-chan-nil.rs
src/test/run-pass/task-life-0.rs
src/test/run-pass/task-spawn-move-and-copy.rs
src/test/run-pass/task-stderr.rs
src/test/run-pass/tcp-accept-stress.rs
src/test/run-pass/tcp-connect-timeouts.rs
src/test/run-pass/tcp-stress.rs
src/test/run-pass/tempfile.rs
src/test/run-pass/terminate-in-initializer.rs
src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs
src/test/run-pass/test-should-fail-good-message.rs
src/test/run-pass/threads.rs
src/test/run-pass/trailing-comma.rs
src/test/run-pass/trait-bounds-basic.rs
src/test/run-pass/trait-bounds-impl-comparison-duplicates.rs
src/test/run-pass/trait-bounds-in-arc.rs
src/test/run-pass/trait-bounds-on-structs-and-enums.rs
src/test/run-pass/trait-bounds-recursion.rs
src/test/run-pass/trait-bounds.rs
src/test/run-pass/trait-cache-issue-18209.rs
src/test/run-pass/trait-coercion-generic.rs
src/test/run-pass/trait-coercion.rs
src/test/run-pass/trait-composition-trivial.rs
src/test/run-pass/trait-contravariant-self.rs
src/test/run-pass/trait-default-method-bound-subst.rs
src/test/run-pass/trait-default-method-bound-subst2.rs
src/test/run-pass/trait-default-method-bound-subst3.rs
src/test/run-pass/trait-default-method-bound-subst4.rs
src/test/run-pass/trait-default-method-bound.rs
src/test/run-pass/trait-default-method-xc-2.rs
src/test/run-pass/trait-default-method-xc.rs
src/test/run-pass/trait-false-ambiguity-where-clause-builtin-bound.rs
src/test/run-pass/trait-generic.rs
src/test/run-pass/trait-impl-2.rs [new file with mode: 0644]
src/test/run-pass/trait-impl.rs
src/test/run-pass/trait-inheritance-auto-xc-2.rs
src/test/run-pass/trait-inheritance-auto-xc.rs
src/test/run-pass/trait-inheritance-auto.rs
src/test/run-pass/trait-inheritance-call-bound-inherited.rs
src/test/run-pass/trait-inheritance-call-bound-inherited2.rs
src/test/run-pass/trait-inheritance-cast-without-call-to-supertrait.rs
src/test/run-pass/trait-inheritance-cast.rs
src/test/run-pass/trait-inheritance-cross-trait-call-xc.rs
src/test/run-pass/trait-inheritance-cross-trait-call.rs
src/test/run-pass/trait-inheritance-diamond.rs
src/test/run-pass/trait-inheritance-multiple-inheritors.rs
src/test/run-pass/trait-inheritance-multiple-params.rs
src/test/run-pass/trait-inheritance-num.rs
src/test/run-pass/trait-inheritance-num0.rs
src/test/run-pass/trait-inheritance-num1.rs
src/test/run-pass/trait-inheritance-num2.rs
src/test/run-pass/trait-inheritance-num3.rs
src/test/run-pass/trait-inheritance-num5.rs
src/test/run-pass/trait-inheritance-overloading-simple.rs
src/test/run-pass/trait-inheritance-overloading-xc-exe.rs
src/test/run-pass/trait-inheritance-overloading.rs
src/test/run-pass/trait-inheritance-self-in-supertype.rs
src/test/run-pass/trait-inheritance-self.rs
src/test/run-pass/trait-inheritance-simple.rs
src/test/run-pass/trait-inheritance-static.rs
src/test/run-pass/trait-inheritance-static2.rs
src/test/run-pass/trait-inheritance-subst.rs
src/test/run-pass/trait-inheritance-subst2.rs
src/test/run-pass/trait-inheritance-visibility.rs
src/test/run-pass/trait-inheritance2.rs
src/test/run-pass/trait-object-generics.rs
src/test/run-pass/trait-object-with-lifetime-bound.rs
src/test/run-pass/trait-region-pointer-simple.rs
src/test/run-pass/trait-safety-ok-cc.rs
src/test/run-pass/trait-safety-ok.rs
src/test/run-pass/trait-static-method-overwriting.rs
src/test/run-pass/trait-to-str.rs
src/test/run-pass/trait-where-clause-vs-impl.rs
src/test/run-pass/trait-with-bounds-default.rs
src/test/run-pass/traits-assoc-type-in-supertrait.rs [new file with mode: 0644]
src/test/run-pass/traits-conditional-dispatch.rs
src/test/run-pass/traits-conditional-model-fn.rs
src/test/run-pass/traits-default-method-macro.rs
src/test/run-pass/traits-default-method-mut.rs
src/test/run-pass/traits-default-method-self.rs
src/test/run-pass/traits-default-method-trivial.rs
src/test/run-pass/traits-issue-22019.rs
src/test/run-pass/traits-issue-22110.rs
src/test/run-pass/traits-issue-22655.rs [new file with mode: 0644]
src/test/run-pass/traits-issue-23003.rs [new file with mode: 0644]
src/test/run-pass/traits-multidispatch-infer-convert-target.rs
src/test/run-pass/traits-repeated-supertrait.rs [new file with mode: 0644]
src/test/run-pass/trans-tag-static-padding.rs
src/test/run-pass/transmute-non-immediate-to-immediate.rs
src/test/run-pass/trivial_casts.rs [new file with mode: 0644]
src/test/run-pass/tup.rs
src/test/run-pass/tuple-index-fat-types.rs
src/test/run-pass/tuple-index.rs
src/test/run-pass/tuple-struct-construct.rs
src/test/run-pass/tuple-struct-constructor-pointer.rs
src/test/run-pass/tuple-struct-destructuring.rs
src/test/run-pass/tuple-struct-matching.rs
src/test/run-pass/tuple-struct-trivial.rs
src/test/run-pass/tydesc-name.rs
src/test/run-pass/type-id-higher-rank.rs
src/test/run-pass/type-in-nested-module.rs
src/test/run-pass/type-namespace.rs
src/test/run-pass/type-param-constraints.rs
src/test/run-pass/type-param.rs
src/test/run-pass/type-params-in-for-each.rs
src/test/run-pass/type-ptr.rs
src/test/run-pass/type-sizes.rs
src/test/run-pass/type-use-i1-versus-i8.rs
src/test/run-pass/typeck-macro-interaction-issue-8852.rs
src/test/run-pass/typeck_type_placeholder_1.rs
src/test/run-pass/typeid-intrinsic.rs
src/test/run-pass/typestate-cfg-nesting.rs
src/test/run-pass/typestate-multi-decl.rs
src/test/run-pass/u32-decr.rs
src/test/run-pass/u8-incr-decr.rs
src/test/run-pass/u8-incr.rs
src/test/run-pass/ufcs-explicit-self.rs
src/test/run-pass/ufcs-polymorphic-paths.rs [new file with mode: 0644]
src/test/run-pass/ufcs-trait-object.rs
src/test/run-pass/ufcs-type-params.rs
src/test/run-pass/uint.rs
src/test/run-pass/unary-minus-suffix-inference.rs
src/test/run-pass/unboxed-closures-all-traits.rs
src/test/run-pass/unboxed-closures-blanket-fn-mut.rs [new file with mode: 0644]
src/test/run-pass/unboxed-closures-blanket-fn.rs [new file with mode: 0644]
src/test/run-pass/unboxed-closures-boxed.rs
src/test/run-pass/unboxed-closures-by-ref.rs
src/test/run-pass/unboxed-closures-call-fn-autoderef.rs
src/test/run-pass/unboxed-closures-call-sugar-autoderef.rs
src/test/run-pass/unboxed-closures-call-sugar-object-autoderef.rs
src/test/run-pass/unboxed-closures-call-sugar-object.rs
src/test/run-pass/unboxed-closures-counter-not-moved.rs
src/test/run-pass/unboxed-closures-cross-crate.rs
src/test/run-pass/unboxed-closures-direct-sugary-call.rs
src/test/run-pass/unboxed-closures-drop.rs
src/test/run-pass/unboxed-closures-extern-fn-hr.rs
src/test/run-pass/unboxed-closures-extern-fn.rs
src/test/run-pass/unboxed-closures-fn-as-fnmut-and-fnonce.rs
src/test/run-pass/unboxed-closures-fnmut-as-fnonce.rs
src/test/run-pass/unboxed-closures-generic.rs
src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-bound.rs
src/test/run-pass/unboxed-closures-infer-argument-types-from-expected-object-type.rs
src/test/run-pass/unboxed-closures-infer-argument-types-with-bound-regions-from-expected-bound.rs
src/test/run-pass/unboxed-closures-infer-fnmut-calling-fnmut.rs
src/test/run-pass/unboxed-closures-infer-fnmut-move.rs
src/test/run-pass/unboxed-closures-infer-fnmut.rs
src/test/run-pass/unboxed-closures-infer-fnonce-move.rs
src/test/run-pass/unboxed-closures-infer-fnonce.rs
src/test/run-pass/unboxed-closures-infer-kind.rs
src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
src/test/run-pass/unboxed-closures-infer-upvar.rs
src/test/run-pass/unboxed-closures-manual-impl.rs
src/test/run-pass/unboxed-closures-monomorphization.rs
src/test/run-pass/unboxed-closures-move-mutable.rs
src/test/run-pass/unboxed-closures-move-some-upvars-in-by-ref-closure.rs
src/test/run-pass/unboxed-closures-prelude.rs
src/test/run-pass/unboxed-closures-simple.rs
src/test/run-pass/unboxed-closures-single-word-env.rs
src/test/run-pass/unboxed-closures-static-call-fn-once.rs
src/test/run-pass/unboxed-closures-sugar-object.rs
src/test/run-pass/unboxed-closures-unique-type-id.rs
src/test/run-pass/unboxed-closures-zero-args.rs
src/test/run-pass/unfold-cross-crate.rs
src/test/run-pass/unify-return-ty.rs
src/test/run-pass/uninit-empty-types.rs
src/test/run-pass/uniq-self-in-mut-slot.rs
src/test/run-pass/unique-assign-copy.rs
src/test/run-pass/unique-assign-drop.rs
src/test/run-pass/unique-assign-generic.rs
src/test/run-pass/unique-assign.rs
src/test/run-pass/unique-autoderef-field.rs
src/test/run-pass/unique-autoderef-index.rs
src/test/run-pass/unique-cmp.rs
src/test/run-pass/unique-containing-tag.rs
src/test/run-pass/unique-create.rs
src/test/run-pass/unique-decl-init-copy.rs
src/test/run-pass/unique-decl-init.rs
src/test/run-pass/unique-decl-move.rs
src/test/run-pass/unique-decl.rs
src/test/run-pass/unique-deref.rs
src/test/run-pass/unique-destructure.rs
src/test/run-pass/unique-drop-complex.rs
src/test/run-pass/unique-fn-arg-move.rs
src/test/run-pass/unique-fn-arg-mut.rs
src/test/run-pass/unique-fn-arg.rs
src/test/run-pass/unique-fn-ret.rs
src/test/run-pass/unique-generic-assign.rs
src/test/run-pass/unique-in-tag.rs
src/test/run-pass/unique-in-vec-copy.rs
src/test/run-pass/unique-in-vec.rs
src/test/run-pass/unique-init.rs
src/test/run-pass/unique-kinds.rs
src/test/run-pass/unique-log.rs
src/test/run-pass/unique-match-discrim.rs
src/test/run-pass/unique-move-drop.rs
src/test/run-pass/unique-move-temp.rs
src/test/run-pass/unique-move.rs
src/test/run-pass/unique-mutable.rs
src/test/run-pass/unique-object-move.rs
src/test/run-pass/unique-pat-2.rs
src/test/run-pass/unique-pat-3.rs
src/test/run-pass/unique-pat.rs
src/test/run-pass/unique-rec.rs
src/test/run-pass/unique-send-2.rs
src/test/run-pass/unique-send.rs
src/test/run-pass/unique-swap.rs
src/test/run-pass/unit-like-struct-drop-run.rs
src/test/run-pass/unit.rs
src/test/run-pass/unnamed_argument_mode.rs
src/test/run-pass/unreachable-code-1.rs
src/test/run-pass/unreachable-code.rs
src/test/run-pass/unsafe-coercion.rs [new file with mode: 0644]
src/test/run-pass/unsafe-fn-called-from-unsafe-blk.rs
src/test/run-pass/unsafe-fn-called-from-unsafe-fn.rs
src/test/run-pass/unsafe-pointer-assignability.rs
src/test/run-pass/unsized.rs
src/test/run-pass/unsized2.rs
src/test/run-pass/unsized3.rs
src/test/run-pass/unused-move-capture.rs
src/test/run-pass/unused-move.rs
src/test/run-pass/unwind-resource.rs
src/test/run-pass/unwind-unique.rs
src/test/run-pass/use-crate-name-alias.rs
src/test/run-pass/use-import-export.rs
src/test/run-pass/use-mod.rs
src/test/run-pass/use-trait-before-def.rs
src/test/run-pass/use-uninit-match.rs
src/test/run-pass/use-uninit-match2.rs
src/test/run-pass/use.rs
src/test/run-pass/use_inline_dtor.rs
src/test/run-pass/utf8.rs
src/test/run-pass/utf8_chars.rs
src/test/run-pass/utf8_idents.rs
src/test/run-pass/variadic-ffi.rs
src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs
src/test/run-pass/variance-trait-matching.rs
src/test/run-pass/variance-vec-covariant.rs
src/test/run-pass/variant-attributes.rs
src/test/run-pass/variant-structs-trivial.rs
src/test/run-pass/vec-concat.rs
src/test/run-pass/vec-dst.rs
src/test/run-pass/vec-fixed-length.rs
src/test/run-pass/vec-growth.rs
src/test/run-pass/vec-late-init.rs
src/test/run-pass/vec-macro-no-std.rs
src/test/run-pass/vec-macro-repeat.rs
src/test/run-pass/vec-macro-rvalue-scope.rs
src/test/run-pass/vec-macro-with-brackets.rs
src/test/run-pass/vec-macro-with-trailing-comma.rs
src/test/run-pass/vec-matching-autoslice.rs
src/test/run-pass/vec-matching-fixed.rs
src/test/run-pass/vec-matching-fold.rs
src/test/run-pass/vec-matching-legal-tail-element-borrow.rs
src/test/run-pass/vec-matching.rs
src/test/run-pass/vec-push.rs
src/test/run-pass/vec-repeat-with-cast.rs
src/test/run-pass/vec-slice-drop.rs
src/test/run-pass/vec-slice.rs
src/test/run-pass/vec-tail-matching.rs
src/test/run-pass/vec-to_str.rs
src/test/run-pass/vec.rs
src/test/run-pass/vector-no-ann-2.rs
src/test/run-pass/vector-sort-panic-safe.rs
src/test/run-pass/visible-private-types-feature-gate.rs
src/test/run-pass/wait-forked-but-failed-child.rs
src/test/run-pass/warn-ctypes-inhibit.rs
src/test/run-pass/weak-lang-item.rs
src/test/run-pass/weird-exprs.rs
src/test/run-pass/wf-bound-region-in-object-type.rs
src/test/run-pass/where-clause-bounds-inconsistency.rs
src/test/run-pass/where-clause-early-bound-lifetimes.rs
src/test/run-pass/where-clause-method-substituion.rs
src/test/run-pass/where-clause-region-outlives.rs
src/test/run-pass/where-clauses-cross-crate.rs
src/test/run-pass/where-clauses-lifetimes.rs
src/test/run-pass/where-clauses-unboxed-closures.rs
src/test/run-pass/where-clauses.rs
src/test/run-pass/where-for-self.rs
src/test/run-pass/while-flow-graph.rs
src/test/run-pass/while-label.rs
src/test/run-pass/while-let.rs
src/test/run-pass/while-loop-constraints-2.rs
src/test/run-pass/while-prelude-drop.rs
src/test/run-pass/while-with-break.rs
src/test/run-pass/while.rs
src/test/run-pass/writealias.rs
src/test/run-pass/x86stdcall.rs
src/test/run-pass/x86stdcall2.rs
src/test/run-pass/xcrate-address-insignificant.rs
src/test/run-pass/xcrate-static-addresses.rs
src/test/run-pass/xcrate-trait-lifetime-param.rs
src/test/run-pass/xcrate-unit-struct.rs
src/test/run-pass/yield2.rs
src/test/run-pass/zero-size-type-destructors.rs
src/test/run-pass/zero_sized_subslice_match.rs

index f7934b2fa7051874bc77fa7f69da8c2db716535d..4109797a55ee707811bd3073b1c33bd484682e1e 100644 (file)
@@ -606,7 +606,7 @@ Peter Schuller <peter.schuller@infidyne.com>
 Peter Williams <peter@newton.cx>
 Peter Zotov <whitequark@whitequark.org>
 Petter Remen <petter.remen@gmail.com>
-Phil Dawes <pdawes@drw.com>
+Phil Dawes <phil@phildawes.net>
 Phil Ruffwind <rf@rufflewind.com>
 Philip Munksgaard <pmunksgaard@gmail.com>
 Philipp Brüschweiler <blei42@gmail.com>
index a4656dd415bbd3ec0972c1daad931a0945bba38c..71b20cb0946c482b519edbe74ba93b8ae12ff00c 100644 (file)
@@ -14,7 +14,7 @@ links to the major sections:
 If you have questions, please make a post on [internals.rust-lang.org][internals] or
 hop on [#rust-internals][pound-rust-internals].
 
-As a reminder, all contributors are expected to follow our [Code of Conduct](coc).
+As a reminder, all contributors are expected to follow our [Code of Conduct][coc].
 
 [pound-rust-internals]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals
 [internals]: http://internals.rust-lang.org
index a760155bbd91aeeee3a961599f7a7cf86c4b331a..e7ad2aec7be0af4be5390c40443f5f7c5262fcfa 100644 (file)
 #     make check-stage1-rpass TESTNAME=my-shiny-new-test
 #
 #     // Having trouble figuring out which test is failing? Turn off parallel tests
-#     make check-stage1-std RUST_TEST_TASKS=1
-#
-# This is hardly all there is to know of The Rust Build System's
-# mysteries. The tale continues on the wiki[1].
-#
-# [1]: https://github.com/rust-lang/rust/wiki/Note-testsuite
+#     make check-stage1-std RUST_TEST_THREADS=1
 #
 # If you really feel like getting your hands dirty, then:
 #
index b6a73730d351cc9f37c39a0fdc8d49bb59e75aca..f92fc653e0ef32719d45f95e5a842d85e8d3bece 100644 (file)
--- a/README.md
+++ b/README.md
@@ -15,28 +15,34 @@ Read ["Installing Rust"] from [The Book].
 ## Building from Source
 
 1. Make sure you have installed the dependencies:
-    * `g++` 4.7 or `clang++` 3.x
-    * `python` 2.6 or later (but not 3.x)
-    * GNU `make` 3.81 or later
-    * `curl`
-    * `git`
+
+   * `g++` 4.7 or `clang++` 3.x
+   * `python` 2.6 or later (but not 3.x)
+   * GNU `make` 3.81 or later
+   * `curl`
+   * `git`
 
 2. Clone the [source] with `git`:
 
-        $ git clone https://github.com/rust-lang/rust.git
-        $ cd rust
+   ```sh
+   $ git clone https://github.com/rust-lang/rust.git
+   $ cd rust
+   ```
 
 [source]: https://github.com/rust-lang/rust
 
 3. Build and install:
 
-        $ ./configure
-        $ make && make install
+    ```sh
+    $ ./configure
+    $ make && make install
+    ```
 
-    > ***Note:*** You may need to use `sudo make install` if you do not normally have
-    > permission to modify the destination directory. The install locations can
-    > be adjusted by passing a `--prefix` argument to `configure`. Various other
-    > options are also supported, pass `--help` for more information on them.
+    > ***Note:*** You may need to use `sudo make install` if you do not
+    > normally have permission to modify the destination directory. The
+    > install locations can be adjusted by passing a `--prefix` argument
+    > to `configure`. Various other options are also supported – pass
+    > `--help` for more information on them.
 
     When complete, `make install` will place several programs into
     `/usr/local/bin`: `rustc`, the Rust compiler, and `rustdoc`, the
@@ -47,27 +53,30 @@ Read ["Installing Rust"] from [The Book].
 
 ### Building on Windows
 
-To easily build on windows we can use [MSYS2](http://msys2.github.io/):
+[MSYS2](http://msys2.github.io/) can be used to easily build Rust on Windows:
 
 1. Grab the latest MSYS2 installer and go through the installer.
-2. Now from the MSYS2 terminal we want to install the mingw64 toolchain and the other
-   tools we need.
 
-```bash
-# choose one based on platform
-$ pacman -S mingw-w64-i686-toolchain
-$ pacman -S mingw-w64-x86_64-toolchain
+2. From the MSYS2 terminal, install the `mingw64` toolchain and other required
+   tools.
+
+   ```sh
+   # Choose one based on platform:
+   $ pacman -S mingw-w64-i686-toolchain
+   $ pacman -S mingw-w64-x86_64-toolchain
+
+   $ pacman -S base-devel
+   ```
 
-$ pacman -S base-devel
-```
+3. Run `mingw32_shell.bat` or `mingw64_shell.bat` from wherever you installed
+   MYSY2 (i.e. `C:\msys`), depending on whether you want 32-bit or 64-bit Rust.
 
-3. With that now start `mingw32_shell.bat` or `mingw64_shell.bat`
-   from where you installed MSYS2 (i.e. `C:\msys`). Which one you
-   choose depends on if you want 32 or 64 bit Rust.
-4. From there just navigate to where you have Rust's source code, configure and build it:
+4. Navigate to Rust's source code, configure and build it:
 
-        $ ./configure
-        $ make && make install
+   ```sh
+   $ ./configure
+   $ make && make install
+   ```
 
 ## Notes
 
@@ -92,26 +101,26 @@ There is more advice about hacking on Rust in [CONTRIBUTING.md].
 
 [CONTRIBUTING.md]: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md
 
-## Getting help
+## Getting Help
 
 The Rust community congregates in a few places:
 
-* [StackOverflow] - Direct questions about using the language here.
-* [users.rust-lang.org] - General discussion, broader questions.
+* [Stack Overflow] - Direct questions about using the language.
+* [users.rust-lang.org] - General discussion and broader questions.
 * [/r/rust] - News and general discussion.
 
-[StackOverflow]: http://stackoverflow.com/questions/tagged/rust
+[Stack Overflow]: http://stackoverflow.com/questions/tagged/rust
 [/r/rust]: http://reddit.com/r/rust
 [users.rust-lang.org]: http://users.rust-lang.org/
 
 ## Contributing
 
-To contribute to Rust, please see [CONTRIBUTING.md](CONTRIBUTING.md).
+To contribute to Rust, please see [CONTRIBUTING](CONTRIBUTING.md).
 
 Rust has an [IRC] culture and most real-time collaboration happens in a
 variety of channels on Mozilla's IRC network, irc.mozilla.org. The
 most popular channel is [#rust], a venue for general discussion about
-Rust, and a good place to ask for help,
+Rust, and a good place to ask for help.
 
 [IRC]: https://en.wikipedia.org/wiki/Internet_Relay_Chat
 [#rust]: irc://irc.mozilla.org/rust
@@ -122,4 +131,4 @@ Rust is primarily distributed under the terms of both the MIT license
 and the Apache License (Version 2.0), with portions covered by various
 BSD-like licenses.
 
-See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.
+See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and [COPYRIGHT](COPYRIGHT) for details.
index 09929eee9230d3cefe236d3ecb66ee20770b6098..7da73afb4111f4f7f221b6ef90eb907023e2bc4a 100644 (file)
@@ -1,3 +1,102 @@
+Version 1.0.0-beta (April 2015)
+-------------------------------------
+
+* ~1100 changes, numerous bugfixes
+
+* Highlights
+
+    * The big news is that the vast majority of the standard library
+      is now `#[stable]` -- 75% of the non-deprecated API surface at
+      last count. Numerous crates are now running on stable
+      Rust. Starting with this release, it is not possible to use
+      unstable features on a stable build.
+    * Arithmetic on basic integer types now
+      [checks for overflow in debug builds][overflow].
+
+* Language
+
+    * [`Send` no longer implies `'static`][send-rfc], which made
+      possible the [`thread::scoped` API][scoped]. Scoped threads can
+      borrow data from their parent's stack frame -- safely!
+    * [UFCS now supports trait-less associated paths][moar-ufcs] like
+      `MyType::default()`.
+    * Primitive types [now have inherent methods][prim-inherent],
+      obviating the need for extension traits like `SliceExt`.
+    * Methods with `Self: Sized` in their `where` clause are
+      [considered object-safe][self-sized], allowing many extension
+      traits like `IteratorExt` to be merged into the traits they
+      extended.
+    * You can now [refer to associated types][assoc-where] whose
+      corresponding trait bounds appear only in a `where` clause.
+    * The final bits of [OIBIT landed][oibit-final], meaning that
+      traits like `Send` and `Sync` are now library-defined.
+    * A [Reflect trait][reflect] was introduced, which means that
+      downcasting via the `Any` trait is effectively limited to
+      concrete types. This helps retain the potentially-important
+      "parametricity" property: generic code cannot behave differently
+      for different type arguments except in minor ways.
+    * The `unsafe_destructor` feature is now deprecated in favor of
+      the [new `dropck`][dropck]. This change is a major reduction in
+      unsafe code.
+    * Trait coherence was [revised again][fundamental], this time with
+      an eye toward API evolution over time.
+
+* Libraries
+
+    * The new path and IO modules are complete and `#[stable]`. This
+      was the major library focus for this cycle.
+    * The path API was [revised][path-normalize] to normalize `.`,
+      adjusting the tradeoffs in favor of the most common usage.
+    * A large number of remaining APIs in `std` were also stabilized
+      during this cycle; about 75% of the non-deprecated API surface
+      is now stable.
+    * The new [string pattern API][string-pattern] landed, which makes
+      the string slice API much more internally consistent and flexible.
+    * A shiny [framework for Debug implementations][debug-builder] landed.
+      This makes it possible to opt in to "pretty-printed" debugging output.
+    * A new set of [generic conversion traits][conversion] replaced
+      many existing ad hoc traits.
+    * Generic numeric traits were
+      [completely removed][num-traits]. This was made possible thanks
+      to inherent methods for primitive types, and the removal gives
+      maximal flexibility for designing a numeric hierarchy in the future.
+    * The `Fn` traits are now related via [inheritance][fn-inherit]
+      and provide ergonomic [blanket implementations][fn-blanket].
+    * The `Index` and `IndexMut` traits were changed to
+      [take the index by value][index-value], enabling code like
+      `hash_map["string"]` to work.
+    * `Copy` now [inherits][copy-clone] from `Clone`, meaning that all
+      `Copy` data is known to be `Clone` as well.
+
+* Infrastructure
+
+    * Metadata was tuned, shrinking binaries [by 27%][metadata-shrink].
+    * Much headway was made on ecosystem-wide CI, making it possible
+      to [compare builds for breakage][ci-compare].
+
+[send-rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0458-send-improvements.md
+[scoped]: http://static.rust-lang.org/doc/master/std/thread/fn.scoped.html
+[moar-ufcs]: https://github.com/rust-lang/rust/pull/22172
+[prim-inherent]: https://github.com/rust-lang/rust/pull/23104
+[overflow]: https://github.com/rust-lang/rfcs/blob/master/text/0560-integer-overflow.md
+[metadata-shrink]: https://github.com/rust-lang/rust/pull/22971
+[self-sized]: https://github.com/rust-lang/rust/pull/22301
+[assoc-where]: https://github.com/rust-lang/rust/pull/22512
+[string-pattern]: https://github.com/rust-lang/rust/pull/22466
+[oibit-final]: https://github.com/rust-lang/rust/pull/21689
+[reflect]: https://github.com/rust-lang/rust/pull/23712
+[debug-builder]: https://github.com/rust-lang/rfcs/blob/master/text/0640-debug-improvements.md
+[conversion]: https://github.com/rust-lang/rfcs/pull/529
+[num-traits]: https://github.com/rust-lang/rust/pull/23549
+[index-value]: https://github.com/rust-lang/rust/pull/23601
+[dropck]: https://github.com/rust-lang/rfcs/pull/769
+[fundamental]: https://github.com/rust-lang/rfcs/pull/1023
+[ci-compare]: https://gist.github.com/brson/a30a77836fbec057cbee
+[fn-inherit]: https://github.com/rust-lang/rust/pull/23282
+[fn-blanket]: https://github.com/rust-lang/rust/pull/23895
+[copy-clone]: https://github.com/rust-lang/rust/pull/23860
+[path-normalize]: https://github.com/rust-lang/rust/pull/23229
+
 Version 1.0.0-alpha.2 (February 2015)
 -------------------------------------
 
@@ -51,7 +150,7 @@ Version 1.0.0-alpha.2 (February 2015)
     * Abstract [OS-specific string types][osstr], `std::ff::{OsString,
       OsStr}`, provide strings in platform-specific encodings for easier
       interop with system APIs. [RFC][osstr-rfc].
-    * The `boxed::into_raw` and `Box::frow_raw` functions [convert
+    * The `boxed::into_raw` and `Box::from_raw` functions [convert
       between `Box<T>` and `*mut T`][boxraw], a common pattern for
       creating raw pointers.
 
index d1b27a96f93b9caf7da8a4fbb9ac0b9e06a24a63..ca73c1cf8b1c37e15be146d436a8f3731633cf28 100755 (executable)
--- a/configure
+++ b/configure
@@ -374,8 +374,12 @@ case $CFG_OSTYPE in
         CFG_OSTYPE=unknown-dragonfly
         ;;
 
+    Bitrig)
+        CFG_OSTYPE=unknown-bitrig
+        ;;
+
     OpenBSD)
-       CFG_OSTYPE=unknown-openbsd
+        CFG_OSTYPE=unknown-openbsd
        ;;
 
     Darwin)
@@ -400,7 +404,7 @@ case $CFG_OSTYPE in
         CFG_OSTYPE=pc-windows-gnu
         ;;
 
-# Thad's Cygwin identifers below
+# Thad's Cygwin identifiers below
 
 #   Vista 32 bit
     CYGWIN_NT-6.0)
@@ -426,6 +430,10 @@ case $CFG_OSTYPE in
         CFG_CPUTYPE=x86_64
         ;;
 
+#   Win 8 # uname -s on 64-bit cygwin does not contain WOW64, so simply use uname -m to detect arch (works in my install)
+    CYGWIN_NT-6.3)
+       CFG_OSTYPE=pc-windows-gnu
+       ;;
 # We do not detect other OS such as XP/2003 using 64 bit using uname.
 # If we want to in the future, we will need to use Cygwin - Chuck's csih helper in /usr/lib/csih/winProductName.exe or alternative.
     *)
@@ -453,7 +461,10 @@ case $CFG_CPUTYPE in
         CFG_CPUTYPE=aarch64
         ;;
 
-    powerpc)
+    # At some point, when ppc64[le] support happens, this will need to do
+    # something clever. For now it's safe to assume that we're only ever
+    # interested in building 32 bit.
+    powerpc | ppc | ppc64)
         CFG_CPUTYPE=powerpc
         ;;
 
@@ -468,10 +479,19 @@ esac
 # Detect 64 bit linux systems with 32 bit userland and force 32 bit compilation
 if [ $CFG_OSTYPE = unknown-linux-gnu -a $CFG_CPUTYPE = x86_64 ]
 then
-    file -L "$SHELL" | grep -q "x86[_-]64"
-    if [ $? != 0 ]; then
-        CFG_CPUTYPE=i686
+    # $SHELL does not exist in standard 'sh', so probably only exists
+    # if configure is running in an interactive bash shell. /usr/bin/env
+    # exists *everywhere*.
+    BIN_TO_PROBE="$SHELL"
+    if [ -z "$BIN_TO_PROBE" -a -e "/usr/bin/env" ]; then
+       BIN_TO_PROBE="/usr/bin/env"
     fi
+    if [ -n "$BIN_TO_PROBE" ]; then
+       file -L "$BIN_TO_PROBE" | grep -q "x86[_-]64"
+       if [ $? != 0 ]; then
+            CFG_CPUTYPE=i686
+       fi
+     fi
 fi
 
 
@@ -506,7 +526,8 @@ VAL_OPTIONS=""
 opt valgrind 0 "run tests with valgrind (memcheck by default)"
 opt helgrind 0 "run tests with helgrind instead of memcheck"
 opt valgrind-rpass 1 "run rpass-valgrind tests with valgrind"
-opt docs     1 "build documentation"
+opt docs     1 "build standard library documentation"
+opt compiler-docs     0 "build compiler documentation"
 opt optimize 1 "build optimized rust code"
 opt optimize-cxx 1 "build optimized C++ code"
 opt optimize-llvm 1 "build optimized LLVM"
@@ -693,15 +714,17 @@ probe CFG_ADB        adb
 
 if [ ! -z "$CFG_PANDOC" ]
 then
-    PV_MAJOR_MINOR=$(pandoc --version | grep '^pandoc\(.exe\)\? ' |
-        # extract the first 2 version fields, ignore everything else
-        sed 's/pandoc\(.exe\)\? \([0-9]*\)\.\([0-9]*\).*/\2 \3/')
+    # Extract "MAJOR MINOR" from Pandoc's version number
+    PV_MAJOR_MINOR=$(pandoc --version | grep '^pandoc' |
+        sed -E 's/pandoc(.exe)? ([0-9]+)\.([0-9]+).*/\2 \3/')
 
     MIN_PV_MAJOR="1"
     MIN_PV_MINOR="9"
+
     # these patterns are shell globs, *not* regexps
     PV_MAJOR=${PV_MAJOR_MINOR% *}
     PV_MINOR=${PV_MAJOR_MINOR#* }
+
     if [ "$PV_MAJOR" -lt "$MIN_PV_MAJOR" ] || [ "$PV_MINOR" -lt "$MIN_PV_MINOR" ]
     then
         step_msg "pandoc $PV_MAJOR.$PV_MINOR is too old. Need at least $MIN_PV_MAJOR.$MIN_PV_MINOR. Disabling"
@@ -747,6 +770,14 @@ then
     CFG_ENABLE_CLANG=1
 fi
 
+# Force bitrig to build with clang; gcc doesn't like us there
+if [ $CFG_OSTYPE = unknown-bitrig ]
+then
+    step_msg "on Bitrig, forcing use of clang, disabling jemalloc"
+    CFG_ENABLE_CLANG=1
+    CFG_ENABLE_JEMALLOC=0
+fi
+
 if [ -z "$CFG_ENABLE_CLANG" -a -z "$CFG_GCC" ]
 then
     err "either clang or gcc is required"
@@ -805,11 +836,11 @@ then
     LLVM_VERSION=$($LLVM_CONFIG --version)
 
     case $LLVM_VERSION in
-        (3.[2-6]*)
+        (3.[5-6]*)
             msg "found ok version of LLVM: $LLVM_VERSION"
             ;;
         (*)
-            err "bad LLVM version: $LLVM_VERSION, need >=3.0svn"
+            err "bad LLVM version: $LLVM_VERSION, need >=3.5"
             ;;
     esac
 fi
@@ -864,7 +895,7 @@ then
             | cut -d ' ' -f 2)
 
         case $CFG_CLANG_VERSION in
-            (3.0svn | 3.0 | 3.1* | 3.2* | 3.3* | 3.4* | 3.5* | 3.6*)
+            (3.2* | 3.3* | 3.4* | 3.5* | 3.6*)
             step_msg "found ok version of CLANG: $CFG_CLANG_VERSION"
             if [ -z "$CC" ]
             then
index 49056afa045abb46f7e970696fd03f6ec1ef0b24..b15829db431dfef89f5d7b6a4fb6217c98874b3b 100644 (file)
@@ -7,224 +7,289 @@ rustc \- The Rust compiler
 
 .SH DESCRIPTION
 This program is a compiler for the Rust language, available at
-<\fBhttps://www.rust-lang.org\fR>.
+.UR https://www.rust\-lang.org
+.UE .
 
 .SH OPTIONS
 
 .TP
 \fB\-h\fR, \fB\-\-help\fR
-Display the help message
+Display the help message.
 .TP
-\fB\-\-cfg\fR SPEC
-Configure the compilation environment
+\fB\-\-cfg\fR \fISPEC\fR
+Configure the compilation environment.
 .TP
-\fB\-L\fR [KIND=]PATH
-Add a directory to the library search path. The optional KIND can be one of:
-    dependency = only lookup transitive dependencies here
-    crate = only lookup local `extern crate` directives here
-    native = only lookup native libraries here
-    framework = only look for OSX frameworks here
-    all = look for anything here (the default)
+\fB\-L\fR [\fIKIND\fR=]\fIPATH\fR
+Add a directory to the library search path.
+The optional \fIKIND\fR can be one of:
+.RS
 .TP
-\fB\-l\fR [KIND=]NAME
-Link the generated crate(s) to the specified native library NAME. The optional
-KIND can be one of, static, dylib, or framework. If omitted, dylib is assumed.
+\fBdependency\fR
+only lookup transitive dependencies here
 .TP
-\fB\-\-crate-type\fR [bin|lib|rlib|dylib|staticlib]
-Comma separated list of types of crates for the compiler to emit
+.B crate
+only lookup local `extern crate` directives here
 .TP
-\fB\-\-crate-name NAME\fR
-Specify the name of the crate being built
+.B native
+only lookup native libraries here
 .TP
-\fB\-\-emit\fR [asm|llvm-bc|llvm-ir|obj|link|dep-info]
-Configure the output that rustc will produce
+.B framework
+only look for OSX frameworks here
 .TP
-\fB\-\-print\fR [crate-name|file-names|sysroot]
-Comma separated list of compiler information to print on stdout
+.B all
+look for anything here (the default)
+.RE
+.TP
+\fB\-l\fR [\fIKIND\fR=]\fINAME\fR
+Link the generated crate(s) to the specified native library \fINAME\fR.
+The optional \fIKIND\fR can be one of \fIstatic\fR, \fIdylib\fR, or
+\fIframework\fR.
+If omitted, \fIdylib\fR is assumed.
+.TP
+\fB\-\-crate\-type\fR [bin|lib|rlib|dylib|staticlib]
+Comma separated list of types of crates for the compiler to emit.
+.TP
+\fB\-\-crate\-name\fR \fINAME\fR
+Specify the name of the crate being built.
+.TP
+\fB\-\-emit\fR [asm|llvm\-bc|llvm\-ir|obj|link|dep\-info]
+Configure the output that \fBrustc\fR will produce.
+.TP
+\fB\-\-print\fR [crate\-name|file\-names|sysroot]
+Comma separated list of compiler information to print on stdout.
 .TP
 \fB\-g\fR
-Equivalent to \fI\-C\fR debuginfo=2
+Equivalent to \fI\-C\ debuginfo=2\fR.
 .TP
 \fB\-O\fR
-Equivalent to \fI\-C\fR opt-level=2
+Equivalent to \fI\-C\ opt\-level=2\fR.
 .TP
-\fB\-o\fR FILENAME
-Write output to <filename>. Ignored if multiple \fI\-\-emit\fR outputs are
-specified.
+\fB\-o\fR \fIFILENAME\fR
+Write output to \fIFILENAME\fR.
+Ignored if multiple \fI\-\-emit\fR outputs are specified.
 .TP
-\fB\-\-out\-dir\fR DIR
-Write output to compiler-chosen filename in <dir>. Ignored if \fI\-o\fR is
-specified. Defaults to the current directory.
+\fB\-\-out\-dir\fR \fIDIR\fR
+Write output to compiler\[hy]chosen filename in \fIDIR\fR.
+Ignored if \fI\-o\fR is specified.
+Defaults to the current directory.
 .TP
-\fB\-\-explain\fR OPT
-Provide a detailed explanation of an error message
+\fB\-\-explain\fR \fIOPT\fR
+Provide a detailed explanation of an error message.
 .TP
 \fB\-\-test\fR
-Build a test harness
+Build a test harness.
 .TP
-\fB\-\-target\fR TRIPLE
-Target triple cpu-manufacturer-kernel[-os] to compile for (see chapter 3.4 of
-http://www.sourceware.org/autobook/ for details)
+\fB\-\-target\fR \fITRIPLE\fR
+Target triple \fIcpu\fR\-\fImanufacturer\fR\-\fIkernel\fR[\-\fIos\fR]
+to compile for (see chapter 3.4 of
+.UR http://www.sourceware.org/autobook/
+.UE
+for details).
 .TP
-\fB\-W\fR help
-Print 'lint' options and default settings
+\fB\-W help\fR
+Print 'lint' options and default settings.
 .TP
-\fB\-W\fR OPT, \fB\-\-warn\fR OPT
-Set lint warnings
+\fB\-W\fR \fIOPT\fR, \fB\-\-warn\fR \fIOPT\fR
+Set lint warnings.
 .TP
-\fB\-A\fR OPT, \fB\-\-allow\fR OPT
-Set lint allowed
+\fB\-A\fR \fIOPT\fR, \fB\-\-allow\fR \fIOPT\fR
+Set lint allowed.
 .TP
-\fB\-D\fR OPT, \fB\-\-deny\fR OPT
-Set lint denied
+\fB\-D\fR \fIOPT\fR, \fB\-\-deny\fR \fIOPT\fR
+Set lint denied.
 .TP
-\fB\-F\fR OPT, \fB\-\-forbid\fR OPT
-Set lint forbidden
+\fB\-F\fR \fIOPT\fR, \fB\-\-forbid\fR \fIOPT\fR
+Set lint forbidden.
 .TP
-\fB\-C\fR FLAG[=VAL], \fB\-\-codegen\fR FLAG[=VAL]
-Set a codegen-related flag to the value specified. Use "-C help" to print
-available flags. See CODEGEN OPTIONS below
+\fB\-C\fR \fIFLAG\fR[=\fIVAL\fR], \fB\-\-codegen\fR \fIFLAG\fR[=\fIVAL\fR]
+Set a codegen\[hy]related flag to the value specified.
+Use \fI\-C help\fR to print available flags.
+See CODEGEN OPTIONS below.
 .TP
 \fB\-V\fR, \fB\-\-version\fR
-Print version info and exit
+Print version info and exit.
 .TP
 \fB\-v\fR, \fB\-\-verbose\fR
-Use verbose output
+Use verbose output.
 .TP
-\fB\-\-extern\fR NAME=PATH
-Specify where an external rust library is located
+\fB\-\-extern\fR \fINAME\fR=\fIPATH\fR
+Specify where an external rust library is located.
 .TP
-\fB\-\-sysroot\fR PATH
-Override the system root
+\fB\-\-sysroot\fR \fIPATH\fR
+Override the system root.
 .TP
-\fB\-Z\fR FLAG
-Set internal debugging options. Use "-Z help" to print available options.
+\fB\-Z\fR \fIFLAG\fR
+Set internal debugging options.
+Use \fI\-Z help\fR to print available options.
 .TP
 \fB\-\-color\fR auto|always|never
 Configure coloring of output:
-    auto = colorize, if output goes to a tty (default);
-    always = always colorize output;
-    never = never colorize output
+.RS
+.TP
+.B auto
+colorize, if output goes to a tty (default);
+.TP
+.B always
+always colorize output;
+.TP
+.B never
+never colorize output.
+.RE
 
 .SH CODEGEN OPTIONS
 
 .TP
-\fBar\fR=/path/to/ar
+\fBar\fR=\fI/path/to/ar\fR
 Path to the archive utility to use when assembling archives.
 .TP
-\fBlinker\fR=/path/to/cc
+\fBlinker\fR=\fI/path/to/cc\fR
 Path to the linker utility to use when linking libraries, executables, and
 objects.
 .TP
-\fBlink-args\fR='-flag1 -flag2'
-A space-separated list of extra arguments to pass to the linker when the linker
+\fBlink\-args\fR='\fI\-flag1 \-flag2\fR'
+A space\[hy]separated list of extra arguments to pass to the linker when the linker
 is invoked.
 .TP
 \fBlto\fR
-Perform LLVM link-time optimizations.
+Perform LLVM link\[hy]time optimizations.
 .TP
-\fBtarget-cpu\fR=help
-Selects a target processor. If the value is 'help', then a list of available
-CPUs is printed.
+\fBtarget\-cpu\fR=\fIhelp\fR
+Selects a target processor.
+If the value is 'help', then a list of available CPUs is printed.
 .TP
-\fBtarget-feature\fR='+feature1,-feature2'
-A comma-separated list of features to enable or disable for the target. A
-preceding '+' enables a feature while a preceding '-' disables it. Available
-features can be discovered through target-cpu=help.
+\fBtarget\-feature\fR='\fI+feature1\fR,\fI\-feature2\fR'
+A comma\[hy]separated list of features to enable or disable for the target.
+A preceding '+' enables a feature while a preceding '\-' disables it.
+Available features can be discovered through \fItarget\-cpu=help\fR.
 .TP
-\fBpasses\fR=list
-A space-separated list of extra LLVM passes to run. A value of 'list' will
-cause rustc to print all known passes and exit. The passes specified are
-appended at the end of the normal pass manager.
+\fBpasses\fR=\fIval\fR
+A space\[hy]separated list of extra LLVM passes to run.
+A value of 'list' will cause \fBrustc\fR to print all known passes and
+exit.
+The passes specified are appended at the end of the normal pass manager.
 .TP
-\fBllvm-args\fR='-arg1 -arg2'
-A space-separated list of arguments to pass through to LLVM.
+\fBllvm\-args\fR='\fI\-arg1\fR \fI\-arg2\fR'
+A space\[hy]separated list of arguments to pass through to LLVM.
 .TP
-\fBsave-temps\fR
-If specified, the compiler will save more files (.bc, .o, .no-opt.bc) generated
+\fBsave\-temps\fR
+If specified, the compiler will save more files (.bc, .o, .no\-opt.bc) generated
 throughout compilation in the output directory.
 .TP
 \fBrpath\fR
 If specified, then the rpath value for dynamic libraries will be set in
 either dynamic library or executable outputs.
 .TP
-\fBno-prepopulate-passes\fR
-Suppresses pre-population of the LLVM pass manager that is run over the module.
+\fBno\-prepopulate\-passes\fR
+Suppresses pre\[hy]population of the LLVM pass manager that is run over the module.
 .TP
-\fBno-vectorize-loops\fR
+\fBno\-vectorize\-loops\fR
 Suppresses running the loop vectorization LLVM pass, regardless of optimization
 level.
 .TP
-\fBno-vectorize-slp\fR
+\fBno\-vectorize\-slp\fR
 Suppresses running the LLVM SLP vectorization pass, regardless of optimization
 level.
 .TP
-\fBsoft-float\fR
+\fBsoft\-float\fR
 Generates software floating point library calls instead of hardware
 instructions.
 .TP
-\fBprefer-dynamic\fR
+\fBprefer\-dynamic\fR
 Prefers dynamic linking to static linking.
 .TP
-\fBno-integrated-as\fR
+\fBno\-integrated\-as\fR
 Force usage of an external assembler rather than LLVM's integrated one.
 .TP
-\fBno-redzone\fR
+\fBno\-redzone\fR
 Disable the use of the redzone.
 .TP
-\fBrelocation-model\fR=[pic,static,dynamic-no-pic]
-The relocation model to use. (Default: pic)
+\fBrelocation\-model\fR=[pic,static,dynamic\-no\-pic]
+The relocation model to use.
+(Default: \fIpic\fR)
 .TP
-\fBcode-model\fR=[small,kernel,medium,large]
+\fBcode\-model\fR=[small,kernel,medium,large]
 Choose the code model to use.
 .TP
-\fBmetadata\fR=val
+\fBmetadata\fR=\fIval\fR
 Metadata to mangle symbol names with.
 .TP
-\fBextra-filename\fR=val
+\fBextra\-filename\fR=\fIval\fR
 Extra data to put in each output filename.
 .TP
-\fBcodegen-units\fR=val
-Divide crate into N units to optimize in parallel.
+\fBcodegen\-units\fR=\fIn\fR
+Divide crate into \fIn\fR units to optimize in parallel.
 .TP
-\fBremark\fR=val
+\fBremark\fR=\fIval\fR
 Print remarks for these optimization passes (space separated, or "all").
 .TP
-\fBno-stack-check\fR
-Disable checks for stack exhaustion (a memory-safety hazard!).
+\fBno\-stack\-check\fR
+Disable checks for stack exhaustion (a memory\[hy]safety hazard!).
 .TP
-\fBdebuginfo\fR=val
+\fBdebuginfo\fR=\fIval\fR
 Debug info emission level:
-    0 = no debug info;
-    1 = line-tables only (for stacktraces and breakpoints);
-    2 = full debug info with variable and type information.
+.RS
+.TP
+.B 0
+no debug info;
+.TP
+.B 1
+line\[hy]tables only (for stacktraces and breakpoints);
+.TP
+.B 2
+full debug info with variable and type information.
+.RE
+.TP
+\fBopt\-level\fR=\fIVAL\fR
+Optimize with possible levels 0\[en]3
+
+.SH ENVIRONMENT
+
+Some of these affect the output of the compiler, while others affect programs
+which link to the standard library.
+
+.TP
+\fBRUST_TEST_THREADS\fR
+The test framework Rust provides executes tests in parallel. This variable sets
+the maximum number of threads used for this purpose.
+
+.TP
+\fBRUST_TEST_NOCAPTURE\fR
+A synonym for the --nocapture flag.
+
+.TP
+\fBRUST_MIN_STACK\fR
+Sets the minimum stack size for new threads.
+
 .TP
-\fBopt-level\fR=val
-Optimize with possible levels 0-3
+\fBRUST_BACKTRACE\fR
+If set, produces a backtrace in the output of a program which panics.
 
 .SH "EXAMPLES"
 To build an executable from a source file with a main function:
-    $ rustc -o hello hello.rs
+    $ rustc \-o hello hello.rs
 
 To build a library from a source file:
-    $ rustc --crate-type=lib hello-lib.rs
+    $ rustc \-\-crate\-type=lib hello\-lib.rs
 
 To build either with a crate (.rs) file:
     $ rustc hello.rs
 
 To build an executable with debug info:
-    $ rustc -g -o hello hello.rs
+    $ rustc \-g \-o hello hello.rs
 
 .SH "SEE ALSO"
 
-rustdoc
+.BR rustdoc (1)
 
 .SH "BUGS"
-See <\fBhttps://github.com/rust-lang/rust/issues\fR> for issues.
+See
+.UR https://github.com/rust\-lang/rust/issues
+.UE
+for issues.
 
 .SH "AUTHOR"
-See \fBAUTHORS.txt\fR in the Rust source distribution.
+See \fIAUTHORS.txt\fR in the Rust source distribution.
 
 .SH "COPYRIGHT"
-This work is dual-licensed under Apache 2.0 and MIT terms.  See \fBCOPYRIGHT\fR
-file in the rust source distribution.
+This work is dual\[hy]licensed under Apache\ 2.0 and MIT terms.
+See \fICOPYRIGHT\fR file in the rust source distribution.
index 830884b19bde204400dc43c82c372a34932305cb..1738354fb43d50b6d01376755e688d54925f1680 100644 (file)
@@ -8,76 +8,79 @@ rustdoc \- generate documentation from Rust source code
 .SH DESCRIPTION
 This tool generates API reference documentation by extracting comments from
 source code written in the Rust language, available at
-<\fBhttps://www.rust-lang.org\fR>. It accepts several input formats and provides
-several output formats for the generated documentation.
+.UR https://www.rust\-lang.org
+.UE .
+It accepts several input formats and provides several output formats
+for the generated documentation.
 
 .SH OPTIONS
 
 .TP
--r --input-format <val>
+\fB\-r\fR, \fB\-\-input\-format\fR \fIFORMAT\fR
 html or json (default: inferred)
 .TP
--w --output-format <val>
+\fB\-w\fR, \fB\-\-output\-format\fR \fIFORMAT\fR
 html or json (default: html)
 .TP
--o --output <val>
-where to place the output (default: doc/ for html, doc.json for json)
+\fB\-o\fR, \fB\-\-output\fR \fIOUTPUT\fR
+where to place the output (default: \fIdoc/\fR for html,
+\fIdoc.json\fR for json)
 .TP
---passes <val>
-space-separated list of passes to run (default: '')
+\fB\-\-passes\fR \fILIST\fR
+space\[hy]separated list of passes to run (default: '')
 .TP
---no-defaults
+\fB\-\-no\-defaults\fR
 don't run the default passes
 .TP
---plugins <val>
+\fB\-\-plugins\fR \fILIST\fR
 space-separated list of plugins to run (default: '')
 .TP
---plugin-path <val>
-directory to load plugins from (default: /tmp/rustdoc_ng/plugins)
+\fB\-\-plugin\-path\fR \fIDIR\fR
+directory to load plugins from (default: \fI/tmp/rustdoc_ng/plugins\fR)
 .TP
---target <val>
+\fB\-\-target\fR \fITRIPLE\fR
 target triple to document
 .TP
---crate-name <val>
+\fB\-\-crate\-name\fR \fINAME\fR
 specify the name of this crate
 .TP
--L --library-path <val>
+\fB\-L\fR, \fB\-\-library\-path\fR \fIDIR\fR
 directory to add to crate search path
 .TP
---cfg <val>
-pass a --cfg to rustc
+\fB\-\-cfg\fR \fISPEC\fR
+pass a \fI\-\-cfg\fR to rustc
 .TP
---extern <val>
-pass an --extern to rustc
+\fB\-\-extern\fR \fIVAL\fR
+pass an \fI\-\-extern\fR to rustc
 .TP
---test
+\fB\-\-test\fR
 run code examples as tests
 .TP
---test-args <val>
+\fB\-\-test\-args\fR \fIARGS\fR
 pass arguments to the test runner
 .TP
---html-in-header <val>
+\fB\-\-html\-in\-header\fR \fIFILE\fR
 file to add to <head>
 .TP
---html-before-content <val>
+\fB\-\-html\-before\-content\fR \fIFILE\fR
 file to add in <body>, before content
 .TP
---html-after-content <val>
+\fB\-\-html\-after\-content\fR \fIFILE\fR
 file to add in <body>, after content
 .TP
---markdown-css <val>
+\fB\-\-markdown\-css\fR \fIFILE\fR
 CSS files to include via <link> in a rendered Markdown file
 .TP
---markdown-playground-url <val>
+\fB\-\-markdown\-playground\-url\fR \fIURL\fR
 URL to send code snippets to
 .TP
---markdown-no-toc
+\fB\-\-markdown\-no\-toc\fR
 don't include table of contents
 .TP
--h, --help
+\fB\-h\fR, \fB\-\-help\fR
 Print help
 .TP
--V, --version
+\fB\-V\fR, \fB\-\-version\fR
 Print rustdoc's version
 
 .SH "OUTPUT FORMATS"
@@ -85,14 +88,15 @@ Print rustdoc's version
 The rustdoc tool can generate output in either an HTML or JSON format.
 
 If using an HTML format, then the specified output destination will be the root
-directory of an HTML structure for all the documentation. Pages will be placed
-into this directory, and source files will also possibly be rendered into it as
-well.
+directory of an HTML structure for all the documentation.
+Pages will be placed into this directory, and source files will also
+possibly be rendered into it as well.
 
 If using a JSON format, then the specified output destination will have the
-rustdoc output serialized as JSON into it. This output format exists to
-pre-compile documentation for crates, and for usage in non-rustdoc tools. The
-JSON output is the following hash:
+rustdoc output serialized as JSON into it.
+This output format exists to pre\[hy]compile documentation for crates,
+and for usage in non\[hy]rustdoc tools.
+The JSON output is the following hash:
 
     {
         "schema": VERSION,
@@ -100,11 +104,12 @@ JSON output is the following hash:
         "plugins": ...,
     }
 
-The schema version indicates what the structure of crate/plugins will look
-like. Within a schema version the structure will remain the same. The `crate`
-field will contain all relevant documentation for the source being documented,
-and the `plugins` field will contain the output of the plugins run over the
-crate.
+The schema version indicates what the structure of crate/plugins will
+look like.
+Within a schema version the structure will remain the same.
+The \fIcrate\fR field will contain all relevant documentation for the
+source being documented, and the \fIplugins\fR field will contain the
+output of the plugins run over the crate.
 
 .SH "EXAMPLES"
 
@@ -112,25 +117,28 @@ To generate documentation for the source in the current directory:
     $ rustdoc hello.rs
 
 List all available passes that rustdoc has, along with default passes:
-    $ rustdoc --passes list
+    $ rustdoc \-\-passes list
 
 To precompile the documentation for a crate, and then use it to render html at
 a later date:
-    $ rustdoc -w json hello.rs
+    $ rustdoc \-w json hello.rs
     $ rustdoc doc.json
 
 The generated HTML can be viewed with any standard web browser.
 
 .SH "SEE ALSO"
 
-rustc
+.BR rustc (1)
 
 .SH "BUGS"
-See <\fBhttps://github.com/rust-lang/rust/issues\fR> for issues.
+See
+.UR https://github.com/rust\-lang/rust/issues
+.UE
+for issues.
 
 .SH "AUTHOR"
-See \fBAUTHORS.txt\fR in the Rust source distribution.
+See \fIAUTHORS.txt\fR in the Rust source distribution.
 
 .SH "COPYRIGHT"
-This work is dual-licensed under Apache 2.0 and MIT terms.  See \fBCOPYRIGHT\fR
-file in the rust source distribution.
+This work is dual\[hy]licensed under Apache\ 2.0 and MIT terms.
+See \fICOPYRIGHT\fR file in the rust source distribution.
diff --git a/mk/cfg/x86_64-unknown-bitrig.mk b/mk/cfg/x86_64-unknown-bitrig.mk
new file mode 100644 (file)
index 0000000..ad34988
--- /dev/null
@@ -0,0 +1,26 @@
+# x86_64-unknown-bitrig-elf configuration
+CC_x86_64-unknown-bitrig=$(CC)
+CXX_x86_64-unknown-bitrig=$(CXX)
+CPP_x86_64-unknown-bitrig=$(CPP)
+AR_x86_64-unknown-bitrig=$(AR)
+CFG_LIB_NAME_x86_64-unknown-bitrig=lib$(1).so
+CFG_STATIC_LIB_NAME_x86_64-unknown-bitrig=lib$(1).a
+CFG_LIB_GLOB_x86_64-unknown-bitrig=lib$(1)-*.so
+CFG_LIB_DSYM_GLOB_x86_64-unknown-bitrig=$(1)-*.dylib.dSYM
+CFG_JEMALLOC_CFLAGS_x86_64-unknown-bitrig := -m64 -I/usr/include $(CFLAGS)
+CFG_GCCISH_CFLAGS_x86_64-unknown-bitrig := -Wall -Werror -fPIC -m64 -I/usr/include $(CFLAGS)
+CFG_GCCISH_LINK_FLAGS_x86_64-unknown-bitrig := -shared -pic -pthread -m64 $(LDFLAGS)
+CFG_GCCISH_DEF_FLAG_x86_64-unknown-bitrig := -Wl,--export-dynamic,--dynamic-list=
+CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-bitrig := -Wl,-pic -Wl,-whole-archive
+CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-bitrig := -Wl,-no-whole-archive
+CFG_DEF_SUFFIX_x86_64-unknown-bitrig := .bsd.def
+CFG_LLC_FLAGS_x86_64-unknown-bitrig :=
+CFG_INSTALL_NAME_x86_64-unknown-bitrig =
+CFG_EXE_SUFFIX_x86_64-unknown-bitrig :=
+CFG_WINDOWSY_x86_64-unknown-bitrig :=
+CFG_UNIXY_x86_64-unknown-bitrig := 1
+CFG_PATH_MUNGE_x86_64-unknown-bitrig :=
+CFG_LDPATH_x86_64-unknown-bitrig :=
+CFG_RUN_x86_64-unknown-bitrig=$(2)
+CFG_RUN_TARG_x86_64-unknown-bitrig=$(call CFG_RUN_x86_64-unknown-bitrig,,$(2))
+CFG_GNU_TRIPLE_x86_64-unknown-bitrig := x86_64-unknown-bitrig
index 845f9c1c52d19fedb6aeef1c3bb362bfad9ce342..e5866094ee84f7b181fc0de2f8c86d4210c5f881 100644 (file)
@@ -25,4 +25,3 @@ CFG_LDPATH_x86_64-unknown-linux-gnu :=
 CFG_RUN_x86_64-unknown-linux-gnu=$(2)
 CFG_RUN_TARG_x86_64-unknown-linux-gnu=$(call CFG_RUN_x86_64-unknown-linux-gnu,,$(2))
 CFG_GNU_TRIPLE_x86_64-unknown-linux-gnu := x86_64-unknown-linux-gnu
-
index be1965b7edadddd6358ab898816e33828121d57e..f594a6a19f1580ab9f5c489b7fcb969dc2ff4b7d 100644 (file)
@@ -54,7 +54,7 @@ TARGET_CRATES := libc std flate arena term \
                  log graphviz core rbml alloc \
                  unicode rustc_bitflags
 RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \
-                rustc_trans rustc_back rustc_llvm rustc_privacy
+                rustc_trans rustc_back rustc_llvm rustc_privacy rustc_lint
 HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc fmt_macros
 CRATES := $(TARGET_CRATES) $(HOST_CRATES)
 TOOLS := compiletest rustdoc rustc rustbook
@@ -70,7 +70,7 @@ DEPS_graphviz := std
 DEPS_syntax := std term serialize log fmt_macros arena libc
 DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \
                      rustc_typeck rustc_resolve log syntax serialize rustc_llvm \
-                    rustc_trans rustc_privacy
+                    rustc_trans rustc_privacy rustc_lint
 
 DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \
                        log syntax serialize rustc_llvm
@@ -78,12 +78,13 @@ DEPS_rustc_typeck := rustc syntax
 DEPS_rustc_borrowck := rustc log graphviz syntax
 DEPS_rustc_resolve := rustc log syntax
 DEPS_rustc_privacy := rustc log syntax
+DEPS_rustc_lint := rustc log syntax
 DEPS_rustc := syntax flate arena serialize getopts rbml \
               log graphviz rustc_llvm rustc_back
 DEPS_rustc_llvm := native:rustllvm libc std
 DEPS_rustc_back := std syntax rustc_llvm flate log libc
 DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
-                test
+                test rustc_lint
 DEPS_rustc_bitflags := core
 DEPS_flate := std native:miniz
 DEPS_arena := std
@@ -121,18 +122,37 @@ ONLY_RLIB_rustc_bitflags := 1
 # You should not need to edit below this line
 ################################################################################
 
+# On channels where the only usable crate is std, only build documentation for
+# std. This keeps distributions small and doesn't clutter up the API docs with
+# confusing internal details from the crates behind the facade.
+#
+# (Disabled while cmr figures out how to change rustdoc to make reexports work
+# slightly nicer. Otherwise, all cross-crate links to Vec will go to
+# libcollections, breaking them, and [src] links for anything reexported will
+# not work.)
+
+#ifeq ($(CFG_RELEASE_CHANNEL),stable)
+#DOC_CRATES := std
+#else
+#ifeq ($(CFG_RELEASE_CHANNEL),beta)
+#DOC_CRATES := std
+#else
 DOC_CRATES := $(filter-out rustc, \
-              $(filter-out rustc_trans, \
-              $(filter-out rustc_typeck, \
-              $(filter-out rustc_borrowck, \
-              $(filter-out rustc_resolve, \
-              $(filter-out rustc_driver, \
-              $(filter-out rustc_privacy, \
-              $(filter-out log, \
-              $(filter-out getopts, \
-              $(filter-out syntax, $(CRATES)))))))))))
+          $(filter-out rustc_trans, \
+          $(filter-out rustc_typeck, \
+          $(filter-out rustc_borrowck, \
+          $(filter-out rustc_resolve, \
+          $(filter-out rustc_driver, \
+          $(filter-out rustc_privacy, \
+          $(filter-out rustc_lint, \
+          $(filter-out log, \
+          $(filter-out getopts, \
+          $(filter-out syntax, $(CRATES))))))))))))
+#endif
+#endif
 COMPILER_DOC_CRATES := rustc rustc_trans rustc_borrowck rustc_resolve \
-                       rustc_typeck rustc_driver syntax rustc_privacy
+                       rustc_typeck rustc_driver syntax rustc_privacy \
+                       rustc_lint
 
 # This macro creates some simple definitions for each crate being built, just
 # some munging of all of the parameters above.
index 899cc42d066e4a2032a37a5646925fecb7e913d2..e6a2174f84a82dab0104b0520535561d298aa692 100644 (file)
@@ -56,29 +56,32 @@ define DEF_INSTALL_DEBUGGER_SCRIPTS_HOST
 tmp/install-debugger-scripts$(1)_H_$(2)-gdb.done: \
   $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
   $$(DEBUGGER_BIN_SCRIPTS_GDB_ABS)
+       $(Q)touch $$@.start_time
        $(Q)mkdir -p $$(HBIN$(1)_H_$(2))
        $(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
        $(Q)install $$(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $$(HBIN$(1)_H_$(2))
        $(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
-       $(Q)touch $$@
+       $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
 
 tmp/install-debugger-scripts$(1)_H_$(2)-lldb.done: \
   $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) \
   $$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
+       $(Q)touch $$@.start_time
        $(Q)mkdir -p $$(HBIN$(1)_H_$(2))
        $(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
        $(Q)install $$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $$(HBIN$(1)_H_$(2))
        $(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
-       $(Q)touch $$@
+       $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
 
 tmp/install-debugger-scripts$(1)_H_$(2)-all.done: \
   $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) \
   $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS)
+       $(Q)touch $$@.start_time
        $(Q)mkdir -p $$(HBIN$(1)_H_$(2))
        $(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
        $(Q)install $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS) $$(HBIN$(1)_H_$(2))
        $(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
-       $(Q)touch $$@
+       $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
 
 tmp/install-debugger-scripts$(1)_H_$(2)-none.done:
        $(Q)touch $$@
@@ -98,29 +101,32 @@ define DEF_INSTALL_DEBUGGER_SCRIPTS_TARGET
 tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-gdb.done: \
   $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
   $$(DEBUGGER_BIN_SCRIPTS_GDB_ABS)
+       $(Q)touch $$@.start_time
        $(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
        $(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
        $(Q)install $(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
        $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
-       $(Q)touch $$@
+       $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
 
 tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-lldb.done: \
   $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) \
   $$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
+       $(Q)touch $$@.start_time
        $(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
        $(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
        $(Q)install $(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
        $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
-       $(Q)touch $$@
+       $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
 
 tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-all.done: \
   $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) \
   $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS)
+       $(Q)touch $$@.start_time
        $(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
        $(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
        $(Q)install $(DEBUGGER_BIN_SCRIPTS_ALL_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
        $(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
-       $(Q)touch $$@
+       $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
 
 tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-none.done:
        $(Q)touch $$@
index 831225556f3fc8d4beade567fe09f69afff9e6a7..57adaee51980be5c8bf14e35c06ac61fa6bfbf45 100644 (file)
@@ -53,6 +53,7 @@ PKG_FILES := \
       driver                                   \
       etc                                      \
       $(foreach crate,$(CRATES),lib$(crate))   \
+      libcollectionstest                       \
       libcoretest                              \
       libbacktrace                             \
       rt                                       \
index 743032f676d217d4201246b9cf8d5984ff8608d0..d297055ba9acb6e3b5c2b322f38ddcccc3b35949 100644 (file)
@@ -259,7 +259,10 @@ doc/$(1)/index.html: $$(LIB_DOC_DEP_$(1)) doc/$(1)/
 endef
 
 $(foreach crate,$(DOC_CRATES),$(eval $(call DEF_LIB_DOC,$(crate),DOC_TARGETS)))
-$(foreach crate,$(COMPILER_DOC_CRATES),$(eval $(call DEF_LIB_DOC,$(crate),COMPILER_DOC_TARGETS)))
+
+ifdef CFG_COMPILER_DOCS
+  $(foreach crate,$(COMPILER_DOC_CRATES),$(eval $(call DEF_LIB_DOC,$(crate),COMPILER_DOC_TARGETS)))
+endif
 
 ifdef CFG_DISABLE_DOCS
   $(info cfg: disabling doc build (CFG_DISABLE_DOCS))
@@ -273,11 +276,13 @@ compiler-docs: $(COMPILER_DOC_TARGETS)
 trpl: doc/book/index.html
 
 doc/book/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md) | doc/
+       @$(call E, rustbook: $@)
        $(Q)rm -rf doc/book
        $(Q)$(RUSTBOOK) build $(S)src/doc/trpl doc/book
 
 style: doc/style/index.html
 
 doc/style/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/style/*.md) | doc/
+       @$(call E, rustbook: $@)
        $(Q)rm -rf doc/style
        $(Q)$(RUSTBOOK) build $(S)src/doc/style doc/style
index ba2e073803935b89632a9e476a40a4293fd45cfb..1861dd313ce71c02e81b5d2893ca3ec02e3f8000 100644 (file)
@@ -38,15 +38,16 @@ endif
 # the stamp in the source dir.
 $$(LLVM_STAMP_$(1)): $(S)src/rustllvm/llvm-auto-clean-trigger
        @$$(call E, make: cleaning llvm)
+       $(Q)touch $$@.start_time
        $(Q)$(MAKE) clean-llvm$(1)
        @$$(call E, make: done cleaning llvm)
-       touch $$@
+       touch -r $$@.start_time $$@ && rm $$@.start_time
 
 ifeq ($$(CFG_ENABLE_LLVM_STATIC_STDCPP),1)
-LLVM_STDCPP_LOCATION_$(1) = $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
-                                       -print-file-name=libstdc++.a)
+LLVM_STDCPP_RUSTFLAGS_$(1) = -L "$$(dir $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
+                                       -print-file-name=libstdc++.a))"
 else
-LLVM_STDCPP_LOCATION_$(1) =
+LLVM_STDCPP_RUSTFLAGS_$(1) =
 endif
 
 
index 9752ee233b6e3ab0035f30af74c0cf047362046f..b9f2cf1cce89c730dbe08f3ccf49ffa879b3c43c 100644 (file)
@@ -18,7 +18,7 @@ CFG_RELEASE_NUM=1.0.0
 # An optional number to put after the label, e.g. '.2' -> '-beta.2'
 # NB Make sure it starts with a dot to conform to semver pre-release
 # versions (section 9)
-CFG_PRERELEASE_VERSION=.2
+CFG_PRERELEASE_VERSION=
 
 CFG_FILENAME_EXTRA=4e7c5e5c
 
@@ -30,8 +30,8 @@ CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)
 CFG_DISABLE_UNSTABLE_FEATURES=1
 endif
 ifeq ($(CFG_RELEASE_CHANNEL),beta)
-CFG_RELEASE=$(CFG_RELEASE_NUM)-alpha$(CFG_PRERELEASE_VERSION)
-CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-alpha$(CFG_PRERELEASE_VERSION)
+CFG_RELEASE=$(CFG_RELEASE_NUM)-beta$(CFG_PRERELEASE_VERSION)
+CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta$(CFG_PRERELEASE_VERSION)
 CFG_DISABLE_UNSTABLE_FEATURES=1
 endif
 ifeq ($(CFG_RELEASE_CHANNEL),nightly)
@@ -130,7 +130,7 @@ ifdef CFG_DISABLE_DEBUG
   CFG_RUSTC_FLAGS += --cfg ndebug
 else
   $(info cfg: enabling more debugging (CFG_ENABLE_DEBUG))
-  CFG_RUSTC_FLAGS += --cfg debug
+  CFG_RUSTC_FLAGS += --cfg debug -C debug-assertions=on
 endif
 
 ifdef SAVE_TEMPS
@@ -290,6 +290,7 @@ LLVM_VERSION_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --version)
 LLVM_BINDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --bindir)
 LLVM_INCDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --includedir)
 LLVM_LIBDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --libdir)
+LLVM_LIBDIR_RUSTFLAGS_$(1)=-L "$$(LLVM_LIBDIR_$(1))"
 LLVM_LIBS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --libs $$(LLVM_COMPONENTS))
 LLVM_LDFLAGS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --ldflags)
 # On FreeBSD, it may search wrong headers (that are for pre-installed LLVM),
index 78c1057c2fe524ca28a19e6d9164c0f1d08ab771..cd86b273c6de21a952bdbc524cec890d1788728f 100644 (file)
@@ -144,14 +144,14 @@ FIND_COMPILER = $(word 1,$(1:ccache=))
 define CFG_MAKE_TOOLCHAIN
   # Prepend the tools with their prefix if cross compiling
   ifneq ($(CFG_BUILD),$(1))
-       CC_$(1)=$(CROSS_PREFIX_$(1))$(CC_$(1))
-       CXX_$(1)=$(CROSS_PREFIX_$(1))$(CXX_$(1))
-       CPP_$(1)=$(CROSS_PREFIX_$(1))$(CPP_$(1))
-       AR_$(1)=$(CROSS_PREFIX_$(1))$(AR_$(1))
-       RUSTC_CROSS_FLAGS_$(1)=-C linker=$$(call FIND_COMPILER,$$(CC_$(1))) \
-           -C ar=$$(call FIND_COMPILER,$$(AR_$(1))) $(RUSTC_CROSS_FLAGS_$(1))
-
-       RUSTC_FLAGS_$(1)=$$(RUSTC_CROSS_FLAGS_$(1)) $(RUSTC_FLAGS_$(1))
+       CC_$(1)=$(CROSS_PREFIX_$(1))$(CC_$(1))
+       CXX_$(1)=$(CROSS_PREFIX_$(1))$(CXX_$(1))
+       CPP_$(1)=$(CROSS_PREFIX_$(1))$(CPP_$(1))
+       AR_$(1)=$(CROSS_PREFIX_$(1))$(AR_$(1))
+       RUSTC_CROSS_FLAGS_$(1)=-C linker=$$(call FIND_COMPILER,$$(CC_$(1))) \
+           -C ar=$$(call FIND_COMPILER,$$(AR_$(1))) $(RUSTC_CROSS_FLAGS_$(1))
+
+       RUSTC_FLAGS_$(1)=$$(RUSTC_CROSS_FLAGS_$(1)) $(RUSTC_FLAGS_$(1))
   endif
 
   CFG_COMPILE_C_$(1) = $$(CC_$(1)) \
@@ -179,11 +179,19 @@ define CFG_MAKE_TOOLCHAIN
 
   ifeq ($$(findstring $(HOST_$(1)),arm aarch64 mips mipsel powerpc),)
 
+  # On Bitrig, we need the relocation model to be PIC for everything
+  ifeq (,$(filter $(OSTYPE_$(1)),bitrig))
+    LLVM_MC_RELOCATION_MODEL="pic"
+  else
+    LLVM_MC_RELOCATION_MODEL="default"
+  endif
+
   # We're using llvm-mc as our assembler because it supports
   # .cfi pseudo-ops on mac
   CFG_ASSEMBLE_$(1)=$$(CPP_$(1)) -E $$(CFG_DEPEND_FLAGS) $$(2) | \
                     $$(LLVM_MC_$$(CFG_BUILD)) \
                     -assemble \
+                    -relocation-model=$$(LLVM_MC_RELOCATION_MODEL) \
                     -filetype=obj \
                     -triple=$(1) \
                     -o=$$(1)
@@ -192,7 +200,7 @@ define CFG_MAKE_TOOLCHAIN
   # For the ARM, AARCH64, MIPS and POWER crosses, use the toolchain assembler
   # FIXME: We should be able to use the LLVM assembler
   CFG_ASSEMBLE_$(1)=$$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
-                   $$(CFG_DEPEND_FLAGS) $$(2) -c -o $$(1)
+                   $$(CFG_DEPEND_FLAGS) $$(2) -c -o $$(1)
 
   endif
 
index f1c4aa65f5ffe5943b302698eda17ebdd7697bcc..4ded8a7916b9ba4d386d61f3d5198fffc5109063 100644 (file)
@@ -221,5 +221,3 @@ prepare-maybe-clean-$(1):
 
 
 endef
-
-
index 1f67d9ed8da2934a6f3c68cdf2fc6e3823d255b7..8cc74a9cbfb76f81b77d67843c569725bf7da40c 100644 (file)
@@ -72,9 +72,11 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): CFG_COMPILER_HOST_TRIPLE = $(2)
 $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
                $$(CRATEFILE_$(4)) \
                $$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
+               $$(LLVM_CONFIG_$(2)) \
                $$(TSREQ$(1)_T_$(2)_H_$(3)) \
                | $$(TLIB$(1)_T_$(2)_H_$(3))/
        @$$(call E, rustc: $$(@D)/lib$(4))
+       @touch $$@.start_time
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES, \
            $$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES, \
@@ -83,13 +85,13 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
            $$(subst @,,$$(STAGE$(1)_T_$(2)_H_$(3))) \
                $$(RUST_LIB_FLAGS_ST$(1)) \
                -L "$$(RT_OUTPUT_DIR_$(2))" \
-               -L "$$(LLVM_LIBDIR_$(2))" \
-               -L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \
+               $$(LLVM_LIBDIR_RUSTFLAGS_$(2)) \
+               $$(LLVM_STDCPP_RUSTFLAGS_$(2)) \
                $$(RUSTFLAGS_$(4)) \
                --out-dir $$(@D) \
                -C extra-filename=-$$(CFG_FILENAME_EXTRA) \
                $$<
-       @touch $$@
+       @touch -r $$@.start_time $$@ && rm $$@.start_time
        $$(call LIST_ALL_OLD_GLOB_MATCHES, \
            $$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
        $$(call LIST_ALL_OLD_GLOB_MATCHES, \
@@ -130,7 +132,7 @@ endef
 # on $$(TSREQ$(1)_T_$(2)_H_$(3)), to ensure that no products will be
 # put into the target area until after the get-snapshot.py script has
 # had its chance to clean it out; otherwise the other products will be
-# inadvertantly included in the clean out.
+# inadvertently included in the clean out.
 SNAPSHOT_RUSTC_POST_CLEANUP=$(HBIN0_H_$(CFG_BUILD))/rustc$(X_$(CFG_BUILD))
 
 define TARGET_HOST_RULES
index 692d28bfad3d56c5e5cba49ea9489b7268bb45b1..48ebe4e540e3d008ea24f838939a0e23c06a8122 100644 (file)
 DEPS_coretest :=
 $(eval $(call RUST_CRATE,coretest))
 
-TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) coretest
+DEPS_collectionstest :=
+$(eval $(call RUST_CRATE,collectionstest))
+
+TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) collectionstest coretest
 TEST_DOC_CRATES = $(DOC_CRATES)
-TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_resolve rustc_trans,\
+TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_resolve rustc_trans rustc_lint,\
                      $(HOST_CRATES))
 TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
 
@@ -163,7 +166,7 @@ $(foreach file,$(wildcard $(S)src/doc/trpl/*.md), \
 ######################################################################
 
 # The main testing target. Tests lots of stuff.
-check: cleantmptestlogs cleantestlibs all check-stage2 tidy
+check: check-sanitycheck cleantmptestlogs cleantestlibs all check-stage2 tidy
        $(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log
 
 # As above but don't bother running tidy.
@@ -190,6 +193,11 @@ check-docs: cleantestlibs cleantmptestlogs check-stage2-docs
 # Not run as part of the normal test suite, but tested by bors on checkin.
 check-secondary: check-build-compiletest check-build-lexer-verifier check-lexer check-pretty
 
+.PHONY: check-sanitycheck
+
+check-sanitycheck:
+       $(Q)$(CFG_PYTHON) $(S)src/etc/check-sanitycheck.py
+
 # check + check-secondary.
 #
 # Issue #17883: build check-secondary first so hidden dependencies in
@@ -372,7 +380,7 @@ $(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): \
        $(Q)CFG_LLVM_LINKAGE_FILE=$$(LLVM_LINKAGE_PATH_$(3)) \
            $$(subst @,,$$(STAGE$(1)_T_$(2)_H_$(3))) -o $$@ $$< --test \
                -L "$$(RT_OUTPUT_DIR_$(2))" \
-               -L "$$(LLVM_LIBDIR_$(2))" \
+               $$(LLVM_LIBDIR_RUSTFLAGS_$(2)) \
                $$(RUSTFLAGS_$(4))
 
 endef
@@ -389,10 +397,11 @@ check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4
 $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
                $(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2))
        @$$(call E, run: $$<)
+       $$(Q)touch $$@.start_time
        $$(Q)$$(call CFG_RUN_TEST_$(2),$$<,$(1),$(2),$(3)) $$(TESTARGS) \
            --logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \
            $$(call CRATE_TEST_EXTRA_ARGS,$(1),$(2),$(3),$(4)) \
-           && touch $$@
+           && touch -r $$@.start_time $$@ && rm $$@.start_time
 endef
 
 define DEF_TEST_CRATE_RULES_android
@@ -401,6 +410,7 @@ check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4
 $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
                $(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2))
        @$$(call E, run: $$< via adb)
+       $$(Q)touch $$@.start_time
        $$(Q)$(CFG_ADB) push $$< $(CFG_ADB_TEST_DIR)
        $$(Q)$(CFG_ADB) shell '(cd $(CFG_ADB_TEST_DIR); LD_LIBRARY_PATH=./$(2) \
                ./$$(notdir $$<) \
@@ -414,7 +424,7 @@ $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
        @if grep -q "result: ok" tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \
        then \
                rm tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \
-               touch $$@; \
+               touch -r $$@.start_time $$@ && rm $$@.start_time; \
        else \
                rm tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \
                exit 101; \
@@ -564,6 +574,11 @@ ifeq ($(CFG_OSTYPE),apple-darwin)
 CTEST_DISABLE_debuginfo-gdb = "gdb on darwin needs root"
 endif
 
+ifeq ($(findstring android, $(CFG_TARGET)), android)
+CTEST_DISABLE_debuginfo-gdb =
+CTEST_DISABLE_debuginfo-lldb = "lldb tests are disabled on android"
+endif
+
 # CTEST_DISABLE_NONSELFHOST_$(TEST_GROUP), if set, will cause that
 # test group to be disabled *unless* the target is able to build a
 # compiler (i.e. when the target triple is in the set of of host
@@ -588,7 +603,7 @@ TEST_SREQ$(1)_T_$(2)_H_$(3) = \
 
 # The tests select when to use debug configuration on their own;
 # remove directive, if present, from CFG_RUSTC_FLAGS (issue #7898).
-CTEST_RUSTC_FLAGS := $$(subst --cfg ndebug,,$$(CFG_RUSTC_FLAGS))
+CTEST_RUSTC_FLAGS := $$(subst -C debug-assertions,,$$(subst -C debug-assertions=on,,$$(CFG_RUSTC_FLAGS)))
 
 # The tests cannot be optimized while the rest of the compiler is optimized, so
 # filter out the optimization (if any) from rustc and then figure out if we need
@@ -690,10 +705,11 @@ $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
                $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
                 $$(CTEST_DEPS_$(4)_$(1)-T-$(2)-H-$(3))
        @$$(call E, run $(4) [$(2)]: $$<)
+       $$(Q)touch $$@.start_time
        $$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \
                $$(CTEST_ARGS$(1)-T-$(2)-H-$(3)-$(4)) \
                --logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \
-                && touch $$@
+                && touch -r $$@.start_time $$@ && rm $$@.start_time
 
 else
 
@@ -750,10 +766,11 @@ $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
                $$(PRETTY_DEPS_$(4)) \
                $$(PRETTY_DEPS$(1)_H_$(3)_$(4))
        @$$(call E, run pretty-rpass [$(2)]: $$<)
+       $$(Q)touch $$@.start_time
        $$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \
                $$(PRETTY_ARGS$(1)-T-$(2)-H-$(3)-$(4)) \
                --logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \
-                && touch $$@
+                && touch -r $$@.start_time $$@ && rm $$@.start_time
 
 endef
 
@@ -799,8 +816,10 @@ endif
 ifeq ($(2),$$(CFG_BUILD))
 $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): $$(DOCTESTDEP_$(1)_$(2)_$(3)_$(4))
        @$$(call E, run doc-$(4) [$(2)])
+       $$(Q)touch $$@.start_time
        $$(Q)$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --cfg dox --test $$< \
-               --test-args "$$(TESTARGS)" && touch $$@
+               --test-args "$$(TESTARGS)" && \
+               touch -r $$@.start_time $$@ && rm $$@.start_time
 else
 $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)):
        touch $$@
@@ -835,9 +854,11 @@ check-stage$(1)-T-$(2)-H-$(3)-doc-crate-$(4)-exec: \
 ifeq ($(2),$$(CFG_BUILD))
 $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-crate-$(4)): $$(CRATEDOCTESTDEP_$(1)_$(2)_$(3)_$(4))
        @$$(call E, run doc-crate-$(4) [$(2)])
+       $$(Q)touch $$@.start_time
        $$(Q)CFG_LLVM_LINKAGE_FILE=$$(LLVM_LINKAGE_PATH_$(3)) \
            $$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --test --cfg dox \
-               $$(CRATEFILE_$(4)) --test-args "$$(TESTARGS)" && touch $$@
+               $$(CRATEFILE_$(4)) --test-args "$$(TESTARGS)" && \
+               touch -r $$@.start_time $$@ && rm $$@.start_time
 else
 $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-crate-$(4)):
        touch $$@
@@ -984,6 +1005,7 @@ $(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \
                $$(CSREQ$(1)_T_$(2)_H_$(3))
        @rm -rf $(3)/test/run-make/$$*
        @mkdir -p $(3)/test/run-make/$$*
+       $$(Q)touch $$@.start_time
        $$(Q)$$(CFG_PYTHON) $(S)src/etc/maketest.py $$(dir $$<) \
         $$(MAKE) \
            $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
@@ -996,7 +1018,7 @@ $(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \
            "$$(LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3))" \
            $(1) \
            $$(S)
-       @touch $$@
+       @touch -r $$@.start_time $$@ && rm $$@.start_time
 else
 # FIXME #11094 - The above rule doesn't work right for multiple targets
 check-stage$(1)-T-$(2)-H-$(3)-rmake-exec:
index 3bbc8f413aec5c04da07138a0c410bda12f368d5..b419c0bbe8ebe4e5f7169fe4d27ab068e6912bab 100644 (file)
@@ -17,4 +17,3 @@ else
 endif
 
 S := $(CFG_SRC_DIR)
-
index 2c046d252799ee02338b399fb4e38a1b1cae75e4..fe556cecef6981eef5b856bb40ccc48d3250c272 100644 (file)
@@ -11,6 +11,7 @@ pub use self::Mode::*;
 
 use std::fmt;
 use std::str::FromStr;
+use std::path::PathBuf;
 
 #[derive(Clone, Copy, PartialEq, Debug)]
 pub enum Mode {
@@ -68,13 +69,13 @@ pub struct Config {
     pub run_lib_path: String,
 
     // The rustc executable
-    pub rustc_path: Path,
+    pub rustc_path: PathBuf,
 
     // The clang executable
-    pub clang_path: Option<Path>,
+    pub clang_path: Option<PathBuf>,
 
     // The llvm binaries path
-    pub llvm_bin_path: Option<Path>,
+    pub llvm_bin_path: Option<PathBuf>,
 
     // The valgrind path
     pub valgrind_path: Option<String>,
@@ -84,13 +85,13 @@ pub struct Config {
     pub force_valgrind: bool,
 
     // The directory containing the tests to run
-    pub src_base: Path,
+    pub src_base: PathBuf,
 
     // The directory where programs should be built
-    pub build_base: Path,
+    pub build_base: PathBuf,
 
     // Directory for auxiliary libraries
-    pub aux_base: Path,
+    pub aux_base: PathBuf,
 
     // The name of the stage being built (stage1, etc)
     pub stage_id: String,
@@ -105,7 +106,7 @@ pub struct Config {
     pub filter: Option<String>,
 
     // Write out a parseable log of tests that were run
-    pub logfile: Option<Path>,
+    pub logfile: Option<PathBuf>,
 
     // A command line to prefix program execution with,
     // for running under valgrind
@@ -133,7 +134,7 @@ pub struct Config {
     pub lldb_version: Option<String>,
 
     // Path to the android tools
-    pub android_cross_path: Path,
+    pub android_cross_path: PathBuf,
 
     // Extra parameter to run adb on arm-linux-androideabi
     pub adb_path: String,
index 278ce5565d9fc38d8ce9bec899e5fcf3109d0ab1..f00ff9bcbe5e5c4bec3ad7fbbd4336a72f1a2c55 100644 (file)
 
 #![feature(box_syntax)]
 #![feature(collections)]
-#![feature(int_uint)]
 #![feature(old_io)]
-#![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(unboxed_closures)]
 #![feature(std_misc)]
 #![feature(test)]
-#![feature(unicode)]
-#![feature(env)]
-#![feature(core)]
+#![feature(path_ext)]
+#![feature(str_char)]
 
 #![deny(warnings)]
 
@@ -32,9 +29,8 @@ extern crate getopts;
 extern crate log;
 
 use std::env;
-use std::old_io;
-use std::old_io::fs;
-use std::thunk::Thunk;
+use std::fs;
+use std::path::{Path, PathBuf};
 use getopts::{optopt, optflag, reqopt};
 use common::Config;
 use common::{Pretty, DebugInfoGdb, DebugInfoLldb, Codegen};
@@ -115,9 +111,9 @@ pub fn parse_config(args: Vec<String> ) -> Config {
         panic!()
     }
 
-    fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
+    fn opt_path(m: &getopts::Matches, nm: &str) -> PathBuf {
         match m.opt_str(nm) {
-            Some(s) => Path::new(s),
+            Some(s) => PathBuf::from(&s),
             None => panic!("no option (=path) found for {}", nm),
         }
     }
@@ -132,10 +128,10 @@ pub fn parse_config(args: Vec<String> ) -> Config {
         compile_lib_path: matches.opt_str("compile-lib-path").unwrap(),
         run_lib_path: matches.opt_str("run-lib-path").unwrap(),
         rustc_path: opt_path(matches, "rustc-path"),
-        clang_path: matches.opt_str("clang-path").map(|s| Path::new(s)),
+        clang_path: matches.opt_str("clang-path").map(|s| PathBuf::from(&s)),
         valgrind_path: matches.opt_str("valgrind-path"),
         force_valgrind: matches.opt_present("force-valgrind"),
-        llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| Path::new(s)),
+        llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| PathBuf::from(&s)),
         src_base: opt_path(matches, "src-base"),
         build_base: opt_path(matches, "build-base"),
         aux_base: opt_path(matches, "aux-base"),
@@ -143,7 +139,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
         mode: matches.opt_str("mode").unwrap().parse().ok().expect("invalid mode"),
         run_ignored: matches.opt_present("ignored"),
         filter: filter,
-        logfile: matches.opt_str("logfile").map(|s| Path::new(s)),
+        logfile: matches.opt_str("logfile").map(|s| PathBuf::from(&s)),
         runtool: matches.opt_str("runtool"),
         host_rustcflags: matches.opt_str("host-rustcflags"),
         target_rustcflags: matches.opt_str("target-rustcflags"),
@@ -226,7 +222,7 @@ pub fn run_tests(config: &Config) {
         // android debug-info test uses remote debugger
         // so, we test 1 task at once.
         // also trying to isolate problems with adb_run_wrapper.sh ilooping
-        env::set_var("RUST_TEST_TASKS","1");
+        env::set_var("RUST_TEST_THREADS","1");
     }
 
     match config.mode {
@@ -234,7 +230,7 @@ pub fn run_tests(config: &Config) {
             // Some older versions of LLDB seem to have problems with multiple
             // instances running in parallel, so only run one test task at a
             // time.
-            env::set_var("RUST_TEST_TASKS", "1");
+            env::set_var("RUST_TEST_THREADS", "1");
         }
         _ => { /* proceed */ }
     }
@@ -244,7 +240,11 @@ pub fn run_tests(config: &Config) {
     // sadly osx needs some file descriptor limits raised for running tests in
     // parallel (especially when we have lots and lots of child processes).
     // For context, see #8904
-    old_io::test::raise_fd_limit();
+    #[allow(deprecated)]
+    fn raise_fd_limit() {
+        std::old_io::test::raise_fd_limit();
+    }
+    raise_fd_limit();
     // Prevent issue #21352 UAC blocking .exe containing 'patch' etc. on Windows
     // If #11207 is resolved (adding manifest to .exe) this becomes unnecessary
     env::set_var("__COMPAT_LAYER", "RunAsInvoker");
@@ -268,7 +268,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
         logfile: config.logfile.clone(),
         run_tests: true,
         run_benchmarks: true,
-        nocapture: false,
+        nocapture: env::var("RUST_TEST_NOCAPTURE").is_ok(),
         color: test::AutoColor,
     }
 }
@@ -277,9 +277,9 @@ pub fn make_tests(config: &Config) -> Vec<test::TestDescAndFn> {
     debug!("making tests from {:?}",
            config.src_base.display());
     let mut tests = Vec::new();
-    let dirs = fs::readdir(&config.src_base).unwrap();
-    for file in &dirs {
-        let file = file.clone();
+    let dirs = fs::read_dir(&config.src_base).unwrap();
+    for file in dirs {
+        let file = file.unwrap().path();
         debug!("inspecting file {:?}", file.display());
         if is_test(config, &file) {
             let t = make_test(config, &file, || {
@@ -302,7 +302,7 @@ pub fn is_test(config: &Config, testfile: &Path) -> bool {
           _ => vec!(".rc".to_string(), ".rs".to_string())
         };
     let invalid_prefixes = vec!(".".to_string(), "#".to_string(), "~".to_string());
-    let name = testfile.filename_str().unwrap();
+    let name = testfile.file_name().unwrap().to_str().unwrap();
 
     let mut valid = false;
 
@@ -328,7 +328,7 @@ pub fn make_test<F>(config: &Config, testfile: &Path, f: F) -> test::TestDescAnd
         desc: test::TestDesc {
             name: make_test_name(config, testfile),
             ignore: header::is_test_ignored(config, testfile),
-            should_fail: test::ShouldFail::No,
+            should_panic: test::ShouldPanic::No,
         },
         testfn: f(),
     }
@@ -338,9 +338,9 @@ pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName {
 
     // Try to elide redundant long paths
     fn shorten(path: &Path) -> String {
-        let filename = path.filename_str();
-        let p = path.dir_path();
-        let dir = p.filename_str();
+        let filename = path.file_name().unwrap().to_str();
+        let p = path.parent().unwrap();
+        let dir = p.file_name().unwrap().to_str();
         format!("{}/{}", dir.unwrap_or(""), filename.unwrap_or(""))
     }
 
@@ -349,19 +349,17 @@ pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName {
 
 pub fn make_test_closure(config: &Config, testfile: &Path) -> test::TestFn {
     let config = (*config).clone();
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    let testfile = testfile.as_str().unwrap().to_string();
-    test::DynTestFn(Thunk::new(move || {
-        runtest::run(config, testfile)
+    let testfile = testfile.to_path_buf();
+    test::DynTestFn(Box::new(move || {
+        runtest::run(config, &testfile)
     }))
 }
 
 pub fn make_metrics_test_closure(config: &Config, testfile: &Path) -> test::TestFn {
     let config = (*config).clone();
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    let testfile = testfile.as_str().unwrap().to_string();
+    let testfile = testfile.to_path_buf();
     test::DynMetricFn(box move |mm: &mut test::MetricMap| {
-        runtest::run_metrics(config, testfile, mm)
+        runtest::run_metrics(config, &testfile, mm)
     })
 }
 
index d8faa53a2de647bc8c82262505ec266572e00daa..4b2a3e0283dc2a54347045890d03e7bffeb29a5e 100644 (file)
@@ -9,16 +9,19 @@
 // except according to those terms.
 use self::WhichLine::*;
 
-use std::old_io::{BufferedReader, File};
+use std::fs::File;
+use std::io::BufReader;
+use std::io::prelude::*;
+use std::path::Path;
 
 pub struct ExpectedError {
-    pub line: uint,
+    pub line: usize,
     pub kind: String,
     pub msg: String,
 }
 
 #[derive(PartialEq, Debug)]
-enum WhichLine { ThisLine, FollowPrevious(uint), AdjustBackward(uint) }
+enum WhichLine { ThisLine, FollowPrevious(usize), AdjustBackward(usize) }
 
 /// Looks for either "//~| KIND MESSAGE" or "//~^^... KIND MESSAGE"
 /// The former is a "follow" that inherits its target from the preceding line;
@@ -29,7 +32,7 @@ enum WhichLine { ThisLine, FollowPrevious(uint), AdjustBackward(uint) }
 ///          //~| ERROR message two for that same line.
 // Load any test directives embedded in the file
 pub fn load_errors(testfile: &Path) -> Vec<ExpectedError> {
-    let mut rdr = BufferedReader::new(File::open(testfile).unwrap());
+    let rdr = BufReader::new(File::open(testfile).unwrap());
 
     // `last_nonfollow_error` tracks the most recently seen
     // line with an error template that did not use the
@@ -55,10 +58,10 @@ pub fn load_errors(testfile: &Path) -> Vec<ExpectedError> {
     }).collect()
 }
 
-fn parse_expected(last_nonfollow_error: Option<uint>,
-                  line_num: uint,
+fn parse_expected(last_nonfollow_error: Option<usize>,
+                  line_num: usize,
                   line: &str) -> Option<(WhichLine, ExpectedError)> {
-    let start = match line.find_str("//~") { Some(i) => i, None => return None };
+    let start = match line.find("//~") { Some(i) => i, None => return None };
     let (follow, adjusts) = if line.char_at(start + 3) == '|' {
         (true, 0)
     } else {
@@ -68,7 +71,7 @@ fn parse_expected(last_nonfollow_error: Option<uint>,
     let letters = line[kind_start..].chars();
     let kind = letters.skip_while(|c| c.is_whitespace())
                       .take_while(|c| !c.is_whitespace())
-                      .map(|c| c.to_lowercase())
+                      .flat_map(|c| c.to_lowercase())
                       .collect::<String>();
     let letters = line[kind_start..].chars();
     let msg = letters.skip_while(|c| c.is_whitespace())
index c2539679643221332b31a32c6caba396dc6f3aee..f5505b6e83a6738dd073b68513a4ef5755a339e4 100644 (file)
@@ -8,6 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::env;
+use std::fs::File;
+use std::io::BufReader;
+use std::io::prelude::*;
+use std::path::{Path, PathBuf};
+
 use common::Config;
 use common;
 use util;
@@ -21,7 +27,7 @@ pub struct TestProps {
     pub run_flags: Option<String>,
     // If present, the name of a file that this test should match when
     // pretty-printed
-    pub pp_exact: Option<Path>,
+    pub pp_exact: Option<PathBuf>,
     // Modules from aux directory that should be compiled
     pub aux_builds: Vec<String> ,
     // Environment settings to use during execution
@@ -34,8 +40,8 @@ pub struct TestProps {
     pub check_stdout: bool,
     // Don't force a --crate-type=dylib flag on the command line
     pub no_prefer_dynamic: bool,
-    // Don't run --pretty expanded when running pretty printing tests
-    pub no_pretty_expanded: bool,
+    // Run --pretty expanded when running pretty printing tests
+    pub pretty_expanded: bool,
     // Which pretty mode are we testing with, default to 'normal'
     pub pretty_mode: String,
     // Only compare pretty output and don't try compiling
@@ -56,11 +62,11 @@ pub fn load_props(testfile: &Path) -> TestProps {
     let mut force_host = false;
     let mut check_stdout = false;
     let mut no_prefer_dynamic = false;
-    let mut no_pretty_expanded = false;
+    let mut pretty_expanded = false;
     let mut pretty_mode = None;
     let mut pretty_compare_only = false;
     let mut forbid_output = Vec::new();
-    iter_header(testfile, |ln| {
+    iter_header(testfile, &mut |ln| {
         match parse_error_pattern(ln) {
           Some(ep) => error_patterns.push(ep),
           None => ()
@@ -90,8 +96,8 @@ pub fn load_props(testfile: &Path) -> TestProps {
             no_prefer_dynamic = parse_no_prefer_dynamic(ln);
         }
 
-        if !no_pretty_expanded {
-            no_pretty_expanded = parse_no_pretty_expanded(ln);
+        if !pretty_expanded {
+            pretty_expanded = parse_pretty_expanded(ln);
         }
 
         if pretty_mode.is_none() {
@@ -125,6 +131,16 @@ pub fn load_props(testfile: &Path) -> TestProps {
         true
     });
 
+    for key in vec!["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
+        match env::var(key) {
+            Ok(val) =>
+                if exec_env.iter().find(|&&(ref x, _)| *x == key.to_string()).is_none() {
+                    exec_env.push((key.to_string(), val))
+                },
+            Err(..) => {}
+        }
+    }
+
     TestProps {
         error_patterns: error_patterns,
         compile_flags: compile_flags,
@@ -136,7 +152,7 @@ pub fn load_props(testfile: &Path) -> TestProps {
         force_host: force_host,
         check_stdout: check_stdout,
         no_prefer_dynamic: no_prefer_dynamic,
-        no_pretty_expanded: no_pretty_expanded,
+        pretty_expanded: pretty_expanded,
         pretty_mode: pretty_mode.unwrap_or("normal".to_string()),
         pretty_compare_only: pretty_compare_only,
         forbid_output: forbid_output,
@@ -147,6 +163,9 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool {
     fn ignore_target(config: &Config) -> String {
         format!("ignore-{}", util::get_os(&config.target))
     }
+    fn ignore_architecture(config: &Config) -> String {
+        format!("ignore-{}", util::get_arch(&config.target))
+    }
     fn ignore_stage(config: &Config) -> String {
         format!("ignore-{}",
                 config.stage_id.split('-').next().unwrap())
@@ -207,9 +226,10 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool {
         }
     }
 
-    let val = iter_header(testfile, |ln| {
+    let val = iter_header(testfile, &mut |ln| {
         !parse_name_directive(ln, "ignore-test") &&
         !parse_name_directive(ln, &ignore_target(config)) &&
+        !parse_name_directive(ln, &ignore_architecture(config)) &&
         !parse_name_directive(ln, &ignore_stage(config)) &&
         !(config.mode == common::Pretty && parse_name_directive(ln, "ignore-pretty")) &&
         !(config.target != config.host && parse_name_directive(ln, "ignore-cross-compile")) &&
@@ -220,12 +240,8 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool {
     !val
 }
 
-fn iter_header<F>(testfile: &Path, mut it: F) -> bool where
-    F: FnMut(&str) -> bool,
-{
-    use std::old_io::{BufferedReader, File};
-
-    let mut rdr = BufferedReader::new(File::open(testfile).unwrap());
+fn iter_header(testfile: &Path, it: &mut FnMut(&str) -> bool) -> bool {
+    let rdr = BufReader::new(File::open(testfile).unwrap());
     for ln in rdr.lines() {
         // Assume that any directives will be found before the first
         // module or function. This doesn't seem to be an optimization
@@ -279,8 +295,8 @@ fn parse_no_prefer_dynamic(line: &str) -> bool {
     parse_name_directive(line, "no-prefer-dynamic")
 }
 
-fn parse_no_pretty_expanded(line: &str) -> bool {
-    parse_name_directive(line, "no-pretty-expanded")
+fn parse_pretty_expanded(line: &str) -> bool {
+    parse_name_directive(line, "pretty-expanded")
 }
 
 fn parse_pretty_mode(line: &str) -> Option<String> {
@@ -295,7 +311,7 @@ fn parse_exec_env(line: &str) -> Option<(String, String)> {
     parse_name_value_directive(line, "exec-env").map(|nv| {
         // nv is either FOO or FOO=BAR
         let mut strs: Vec<String> = nv
-                                      .splitn(1, '=')
+                                      .splitn(2, '=')
                                       .map(|s| s.to_string())
                                       .collect();
 
@@ -310,12 +326,12 @@ fn parse_exec_env(line: &str) -> Option<(String, String)> {
     })
 }
 
-fn parse_pp_exact(line: &str, testfile: &Path) -> Option<Path> {
+fn parse_pp_exact(line: &str, testfile: &Path) -> Option<PathBuf> {
     match parse_name_value_directive(line, "pp-exact") {
-      Some(s) => Some(Path::new(s)),
+      Some(s) => Some(PathBuf::from(&s)),
       None => {
         if parse_name_directive(line, "pp-exact") {
-            testfile.filename().map(|s| Path::new(s))
+            testfile.file_name().map(|s| PathBuf::from(s))
         } else {
             None
         }
@@ -324,13 +340,14 @@ fn parse_pp_exact(line: &str, testfile: &Path) -> Option<Path> {
 }
 
 fn parse_name_directive(line: &str, directive: &str) -> bool {
-    line.contains(directive)
+    // This 'no-' rule is a quick hack to allow pretty-expanded and no-pretty-expanded to coexist
+    line.contains(directive) && !line.contains(&("no-".to_string() + directive))
 }
 
 pub fn parse_name_value_directive(line: &str, directive: &str)
                                   -> Option<String> {
     let keycolon = format!("{}:", directive);
-    match line.find_str(&keycolon) {
+    match line.find(&keycolon) {
         Some(colon) => {
             let value = line[(colon + keycolon.len()) .. line.len()].to_string();
             debug!("{}: {}", directive, value);
@@ -340,7 +357,7 @@ pub fn parse_name_value_directive(line: &str, directive: &str)
     }
 }
 
-pub fn gdb_version_to_int(version_string: &str) -> int {
+pub fn gdb_version_to_int(version_string: &str) -> isize {
     let error_string = format!(
         "Encountered GDB version string with unexpected format: {}",
         version_string);
@@ -352,17 +369,17 @@ pub fn gdb_version_to_int(version_string: &str) -> int {
         panic!("{}", error_string);
     }
 
-    let major: int = components[0].parse().ok().expect(&error_string);
-    let minor: int = components[1].parse().ok().expect(&error_string);
+    let major: isize = components[0].parse().ok().expect(&error_string);
+    let minor: isize = components[1].parse().ok().expect(&error_string);
 
     return major * 1000 + minor;
 }
 
-pub fn lldb_version_to_int(version_string: &str) -> int {
+pub fn lldb_version_to_int(version_string: &str) -> isize {
     let error_string = format!(
         "Encountered LLDB version string with unexpected format: {}",
         version_string);
     let error_string = error_string;
-    let major: int = version_string.parse().ok().expect(&error_string);
+    let major: isize = version_string.parse().ok().expect(&error_string);
     return major;
 }
index 148a43e6c783196555b044efb3e4ec8e1791d4d6..b30efaa6c29d80c73bfef4c4c75c32e7cf393fb0 100644 (file)
@@ -8,27 +8,29 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::old_io::process::{ProcessExit, Command, Process, ProcessOutput};
 use std::dynamic_lib::DynamicLibrary;
+use std::io::prelude::*;
+use std::path::PathBuf;
+use std::process::{ExitStatus, Command, Child, Output, Stdio};
 
 fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
     // Need to be sure to put both the lib_path and the aux path in the dylib
     // search path for the child.
     let mut path = DynamicLibrary::search_path();
     match aux_path {
-        Some(p) => path.insert(0, Path::new(p)),
+        Some(p) => path.insert(0, PathBuf::from(p)),
         None => {}
     }
-    path.insert(0, Path::new(lib_path));
+    path.insert(0, PathBuf::from(lib_path));
 
     // Add the new dylib search path var
     let var = DynamicLibrary::envvar();
     let newpath = DynamicLibrary::create_path(&path);
-    let newpath = String::from_utf8(newpath).unwrap();
-    cmd.env(var.to_string(), newpath);
+    let newpath = newpath.to_str().unwrap().to_string();
+    cmd.env(var, &newpath);
 }
 
-pub struct Result {pub status: ProcessExit, pub out: String, pub err: String}
+pub struct Result {pub status: ExitStatus, pub out: String, pub err: String}
 
 pub fn run(lib_path: &str,
            prog: &str,
@@ -38,10 +40,13 @@ pub fn run(lib_path: &str,
            input: Option<String>) -> Option<Result> {
 
     let mut cmd = Command::new(prog);
-    cmd.args(args);
+    cmd.args(args)
+       .stdin(Stdio::piped())
+       .stdout(Stdio::piped())
+       .stderr(Stdio::piped());
     add_target_env(&mut cmd, lib_path, aux_path);
     for (key, val) in env {
-        cmd.env(key, val);
+        cmd.env(&key, &val);
     }
 
     match cmd.spawn() {
@@ -49,13 +54,13 @@ pub fn run(lib_path: &str,
             if let Some(input) = input {
                 process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
             }
-            let ProcessOutput { status, output, error } =
+            let Output { status, stdout, stderr } =
                 process.wait_with_output().unwrap();
 
             Some(Result {
                 status: status,
-                out: String::from_utf8(output).unwrap(),
-                err: String::from_utf8(error).unwrap()
+                out: String::from_utf8(stdout).unwrap(),
+                err: String::from_utf8(stderr).unwrap()
             })
         },
         Err(..) => None
@@ -67,13 +72,16 @@ pub fn run_background(lib_path: &str,
            aux_path: Option<&str>,
            args: &[String],
            env: Vec<(String, String)> ,
-           input: Option<String>) -> Option<Process> {
+           input: Option<String>) -> Option<Child> {
 
     let mut cmd = Command::new(prog);
-    cmd.args(args);
+    cmd.args(args)
+       .stdin(Stdio::piped())
+       .stdout(Stdio::piped())
+       .stderr(Stdio::piped());
     add_target_env(&mut cmd, lib_path, aux_path);
     for (key, val) in env {
-        cmd.env(key, val);
+        cmd.env(&key, &val);
     }
 
     match cmd.spawn() {
index 1cbb8742bbc5ae511b89c812ecd115d869501c5b..23267c3e93472cb0b4f3faf59fd675594635e13d 100644 (file)
 use self::TargetLocation::*;
 
 use common::Config;
-use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb};
-use common::{Codegen, DebugInfoLldb};
+use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
+use common::{Codegen, DebugInfoLldb, DebugInfoGdb};
 use errors;
 use header::TestProps;
 use header;
 use procsrv;
 use util::logv;
-#[cfg(target_os = "windows")]
-use util;
-
-#[cfg(target_os = "windows")]
-use std::ascii::AsciiExt;
-use std::old_io::File;
-use std::old_io::fs::PathExtensions;
-use std::old_io::fs;
-use std::old_io::net::tcp;
-use std::old_io::process::ProcessExit;
-use std::old_io::process;
-use std::old_io::timer;
-use std::old_io;
+
 use std::env;
+use std::fmt;
+use std::fs::{self, File};
+use std::io::BufReader;
+use std::io::prelude::*;
 use std::iter::repeat;
+use std::net::TcpStream;
+use std::path::{Path, PathBuf};
+use std::process::{Command, Output, ExitStatus};
 use std::str;
-use std::string::String;
-use std::thread;
 use std::time::Duration;
 use test::MetricMap;
 
-pub fn run(config: Config, testfile: String) {
+pub fn run(config: Config, testfile: &Path) {
     match &*config.target {
 
         "arm-linux-androideabi" | "aarch64-linux-android" => {
@@ -55,12 +48,11 @@ pub fn run(config: Config, testfile: String) {
     run_metrics(config, testfile, &mut _mm);
 }
 
-pub fn run_metrics(config: Config, testfile: String, mm: &mut MetricMap) {
+pub fn run_metrics(config: Config, testfile: &Path, mm: &mut MetricMap) {
     if config.verbose {
         // We're going to be dumping a lot of info. Start on a new line.
         print!("\n\n");
     }
-    let testfile = Path::new(testfile);
     debug!("running {:?}", testfile.display());
     let props = header::load_props(&testfile);
     debug!("loaded props");
@@ -89,7 +81,7 @@ fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) {
     let proc_res = compile_test(config, props, testfile);
 
     if proc_res.status.success() {
-        fatal_proc_rec(&format!("{} test compiled successfully!", config.mode)[],
+        fatal_proc_rec(&format!("{} test compiled successfully!", config.mode)[..],
                       &proc_res);
     }
 
@@ -127,8 +119,8 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) {
     };
 
     // The value our Makefile configures valgrind to return on failure
-    static VALGRIND_ERR: int = 100;
-    if proc_res.status.matches_exit_status(VALGRIND_ERR) {
+    const VALGRIND_ERR: i32 = 100;
+    if proc_res.status.code() == Some(VALGRIND_ERR) {
         fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res);
     }
 
@@ -139,10 +131,10 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) {
 
 fn check_correct_failure_status(proc_res: &ProcRes) {
     // The value the rust runtime returns on failure
-    static RUST_ERR: int = 101;
-    if !proc_res.status.matches_exit_status(RUST_ERR) {
+    const RUST_ERR: i32 = 101;
+    if proc_res.status.code() != Some(RUST_ERR) {
         fatal_proc_rec(
-            &format!("failure produced the wrong error: {:?}",
+            &format!("failure produced the wrong error: {}",
                      proc_res.status),
             proc_res);
     }
@@ -201,8 +193,8 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
     let rounds =
         match props.pp_exact { Some(_) => 1, None => 2 };
 
-    let src = File::open(testfile).read_to_end().unwrap();
-    let src = String::from_utf8(src.clone()).unwrap();
+    let mut src = String::new();
+    File::open(testfile).unwrap().read_to_string(&mut src).unwrap();
     let mut srcs = vec!(src);
 
     let mut round = 0;
@@ -226,9 +218,10 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
 
     let mut expected = match props.pp_exact {
         Some(ref file) => {
-            let filepath = testfile.dir_path().join(file);
-            let s = File::open(&filepath).read_to_end().unwrap();
-            String::from_utf8(s).unwrap()
+            let filepath = testfile.parent().unwrap().join(file);
+            let mut s = String::new();
+            File::open(&filepath).unwrap().read_to_string(&mut s).unwrap();
+            s
         }
         None => { srcs[srcs.len() - 2].clone() }
     };
@@ -252,7 +245,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
     if !proc_res.status.success() {
         fatal_proc_rec("pretty-printed source does not typecheck", &proc_res);
     }
-    if props.no_pretty_expanded { return }
+    if !props.pretty_expanded { return }
 
     // additionally, run `--pretty expanded` and try to build it.
     let proc_res = print_source(config, props, testfile, srcs[round].clone(), "expanded");
@@ -283,7 +276,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
                                      pretty_type.to_string()),
                         props.exec_env.clone(),
                         &config.compile_lib_path,
-                        Some(aux_dir.as_str().unwrap()),
+                        Some(aux_dir.to_str().unwrap()),
                         Some(src))
     }
 
@@ -299,11 +292,11 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
                             pretty_type,
                             format!("--target={}", config.target),
                             "-L".to_string(),
-                            aux_dir.as_str().unwrap().to_string());
+                            aux_dir.to_str().unwrap().to_string());
         args.extend(split_maybe_args(&config.target_rustcflags).into_iter());
         args.extend(split_maybe_args(&props.compile_flags).into_iter());
         return ProcArgs {
-            prog: config.rustc_path.as_str().unwrap().to_string(),
+            prog: config.rustc_path.to_str().unwrap().to_string(),
             args: args,
         };
     }
@@ -345,14 +338,14 @@ actual:\n\
                             "--crate-type=lib".to_string(),
                             format!("--target={}", target),
                             "-L".to_string(),
-                            config.build_base.as_str().unwrap().to_string(),
+                            config.build_base.to_str().unwrap().to_string(),
                             "-L".to_string(),
-                            aux_dir.as_str().unwrap().to_string());
+                            aux_dir.to_str().unwrap().to_string());
         args.extend(split_maybe_args(&config.target_rustcflags).into_iter());
         args.extend(split_maybe_args(&props.compile_flags).into_iter());
         // FIXME (#9639): This needs to handle non-utf8 paths
         return ProcArgs {
-            prog: config.rustc_path.as_str().unwrap().to_string(),
+            prog: config.rustc_path.to_str().unwrap().to_string(),
             args: args,
         };
     }
@@ -390,18 +383,19 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
             // write debugger script
             let mut script_str = String::with_capacity(2048);
             script_str.push_str("set charset UTF-8\n");
-            script_str.push_str(&format!("file {}\n", exe_file.as_str().unwrap()));
+            script_str.push_str(&format!("file {}\n", exe_file.to_str().unwrap()));
             script_str.push_str("target remote :5039\n");
             script_str.push_str(&format!("set solib-search-path \
                                          ./{}/stage2/lib/rustlib/{}/lib/\n",
                                          config.host, config.target));
             for line in breakpoint_lines.iter() {
                 script_str.push_str(&format!("break {:?}:{}\n",
-                                             testfile.filename_display(),
-                                             *line)[]);
+                                             testfile.file_name().unwrap()
+                                                     .to_string_lossy(),
+                                             *line)[..]);
             }
             script_str.push_str(&cmds);
-            script_str.push_str("quit\n");
+            script_str.push_str("\nquit\n");
 
             debug!("script_str = {}", script_str);
             dump_output_file(config,
@@ -415,7 +409,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                          None,
                          &[
                             "push".to_string(),
-                            exe_file.as_str().unwrap().to_string(),
+                            exe_file.to_str().unwrap().to_string(),
                             config.adb_test_dir.clone()
                          ],
                          vec!(("".to_string(), "".to_string())),
@@ -440,9 +434,8 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                                   if config.target.contains("aarch64")
                                   {"64"} else {""},
                                   config.adb_test_dir.clone(),
-                                  str::from_utf8(
-                                      exe_file.filename()
-                                      .unwrap()).unwrap());
+                                  exe_file.file_name().unwrap().to_str()
+                                          .unwrap());
 
             let mut process = procsrv::run_background("",
                                                       &config.adb_path
@@ -458,17 +451,17 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                 .expect(&format!("failed to exec `{:?}`", config.adb_path));
             loop {
                 //waiting 1 second for gdbserver start
-                timer::sleep(Duration::milliseconds(1000));
-                let result = thread::spawn(move || {
-                    tcp::TcpStream::connect("127.0.0.1:5039").unwrap();
-                }).join();
-                if result.is_err() {
-                    continue;
+                #[allow(deprecated)]
+                fn sleep() {
+                    ::std::old_io::timer::sleep(Duration::milliseconds(1000));
+                }
+                sleep();
+                if TcpStream::connect("127.0.0.1:5039").is_ok() {
+                    break
                 }
-                break;
             }
 
-            let tool_path = match config.android_cross_path.as_str() {
+            let tool_path = match config.android_cross_path.to_str() {
                 Some(x) => x.to_string(),
                 None => fatal("cannot find android cross path")
             };
@@ -479,7 +472,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                 vec!("-quiet".to_string(),
                      "-batch".to_string(),
                      "-nx".to_string(),
-                     format!("-command={}", debugger_script.as_str().unwrap()));
+                     format!("-command={}", debugger_script.to_str().unwrap()));
 
             let mut gdb_path = tool_path;
             gdb_path.push_str(&format!("/bin/{}-gdb", config.target));
@@ -503,12 +496,12 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
             };
 
             debugger_run_result = ProcRes {
-                status: status,
+                status: Status::Normal(status),
                 stdout: out,
                 stderr: err,
                 cmdline: cmdline
             };
-            if process.signal_kill().is_err() {
+            if process.kill().is_err() {
                 println!("Adb process is already finished.");
             }
         }
@@ -518,7 +511,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                 .expect("Could not find Rust source root");
             let rust_pp_module_rel_path = Path::new("./src/etc");
             let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
-                                                       .as_str()
+                                                       .to_str()
                                                        .unwrap()
                                                        .to_string();
             // write debugger script
@@ -538,7 +531,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                         // GDB's script auto loading safe path
                         script_str.push_str(
                             &format!("add-auto-load-safe-path {}\n",
-                                     rust_pp_module_abs_path.replace("\\", "\\\\"))
+                                     rust_pp_module_abs_path.replace(r"\", r"\\"))
                                 );
                     }
                 }
@@ -553,21 +546,24 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
             script_str.push_str("set print pretty off\n");
 
             // Add the pretty printer directory to GDB's source-file search path
-            script_str.push_str(&format!("directory {}\n", rust_pp_module_abs_path)[]);
+            script_str.push_str(&format!("directory {}\n",
+                                         rust_pp_module_abs_path));
 
             // Load the target executable
             script_str.push_str(&format!("file {}\n",
-                                         exe_file.as_str().unwrap().replace("\\", "\\\\"))[]);
+                                         exe_file.to_str().unwrap()
+                                                 .replace(r"\", r"\\")));
 
             // Add line breakpoints
             for line in &breakpoint_lines {
                 script_str.push_str(&format!("break '{}':{}\n",
-                                             testfile.filename_display(),
-                                             *line)[]);
+                                             testfile.file_name().unwrap()
+                                                     .to_string_lossy(),
+                                             *line));
             }
 
             script_str.push_str(&cmds);
-            script_str.push_str("quit\n");
+            script_str.push_str("\nquit\n");
 
             debug!("script_str = {}", script_str);
             dump_output_file(config,
@@ -576,13 +572,8 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                              "debugger.script");
 
             // run debugger script with gdb
-            #[cfg(windows)]
-            fn debugger() -> String {
-                "gdb.exe".to_string()
-            }
-            #[cfg(unix)]
-            fn debugger() -> String {
-                "gdb".to_string()
+            fn debugger() -> &'static str {
+                if cfg!(windows) {"gdb.exe"} else {"gdb"}
             }
 
             let debugger_script = make_out_name(config, testfile, "debugger.script");
@@ -592,10 +583,10 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
                 vec!("-quiet".to_string(),
                      "-batch".to_string(),
                      "-nx".to_string(),
-                     format!("-command={}", debugger_script.as_str().unwrap()));
+                     format!("-command={}", debugger_script.to_str().unwrap()));
 
             let proc_args = ProcArgs {
-                prog: debugger(),
+                prog: debugger().to_string(),
                 args: debugger_opts,
             };
 
@@ -618,7 +609,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
     check_debugger_output(&debugger_run_result, &check_lines);
 }
 
-fn find_rust_src_root(config: &Config) -> Option<Path> {
+fn find_rust_src_root(config: &Config) -> Option<PathBuf> {
     let mut path = config.src_base.clone();
     let path_postfix = Path::new("src/etc/lldb_batchmode.py");
 
@@ -632,8 +623,6 @@ fn find_rust_src_root(config: &Config) -> Option<Path> {
 }
 
 fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) {
-    use std::old_io::process::{Command, ProcessOutput};
-
     if config.lldb_python_dir.is_none() {
         fatal("Can't run LLDB test because LLDB's python path is not set.");
     }
@@ -685,11 +674,12 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
         .expect("Could not find Rust source root");
     let rust_pp_module_rel_path = Path::new("./src/etc/lldb_rust_formatters.py");
     let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
-                                               .as_str()
+                                               .to_str()
                                                .unwrap()
                                                .to_string();
 
-    script_str.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[..])[]);
+    script_str.push_str(&format!("command script import {}\n",
+                                 &rust_pp_module_abs_path[..])[..]);
     script_str.push_str("type summary add --no-value ");
     script_str.push_str("--python-function lldb_rust_formatters.print_val ");
     script_str.push_str("-x \".*\" --category Rust\n");
@@ -707,7 +697,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
     }
 
     // Finally, quit the debugger
-    script_str.push_str("quit\n");
+    script_str.push_str("\nquit\n");
 
     // Write the script into a file
     debug!("script_str = {}", script_str);
@@ -735,22 +725,19 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
                 rust_src_root: &Path)
                 -> ProcRes {
         // Prepare the lldb_batchmode which executes the debugger script
-        let lldb_script_path = rust_src_root.join(Path::new("./src/etc/lldb_batchmode.py"));
+        let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py");
 
         let mut cmd = Command::new("python");
-        cmd.arg(lldb_script_path)
+        cmd.arg(&lldb_script_path)
            .arg(test_executable)
            .arg(debugger_script)
-           .env_set_all(&[("PYTHONPATH", config.lldb_python_dir.clone().unwrap())]);
-
-        let (status, out, err) = match cmd.spawn() {
-            Ok(process) => {
-                let ProcessOutput { status, output, error } =
-                    process.wait_with_output().unwrap();
+           .env("PYTHONPATH", config.lldb_python_dir.as_ref().unwrap());
 
+        let (status, out, err) = match cmd.output() {
+            Ok(Output { status, stdout, stderr }) => {
                 (status,
-                 String::from_utf8(output).unwrap(),
-                 String::from_utf8(error).unwrap())
+                 String::from_utf8(stdout).unwrap(),
+                 String::from_utf8(stderr).unwrap())
             },
             Err(e) => {
                 fatal(&format!("Failed to setup Python process for \
@@ -760,7 +747,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
 
         dump_output(config, test_executable, &out, &err);
         return ProcRes {
-            status: status,
+            status: Status::Normal(status),
             stdout: out,
             stderr: err,
             cmdline: format!("{:?}", cmd)
@@ -771,13 +758,11 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
 struct DebuggerCommands {
     commands: Vec<String>,
     check_lines: Vec<String>,
-    breakpoint_lines: Vec<uint>,
+    breakpoint_lines: Vec<usize>,
 }
 
 fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
                            -> DebuggerCommands {
-    use std::old_io::{BufferedReader, File};
-
     let command_directive = format!("{}-command", debugger_prefix);
     let check_directive = format!("{}-check", debugger_prefix);
 
@@ -785,7 +770,7 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
     let mut commands = vec!();
     let mut check_lines = vec!();
     let mut counter = 1;
-    let mut reader = BufferedReader::new(File::open(file_path).unwrap());
+    let reader = BufReader::new(File::open(file_path).unwrap());
     for line in reader.lines() {
         match line {
             Ok(line) => {
@@ -847,7 +832,7 @@ fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[String])
             check_lines.iter().map(|s| {
                 s
                  .trim()
-                 .split_str("[...]")
+                 .split("[...]")
                  .map(|x| x.to_string())
                  .collect()
             }).collect();
@@ -866,7 +851,7 @@ fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[String])
                         None
                     }
                 } else {
-                    rest.find_str(frag)
+                    rest.find(frag)
                 };
                 match found {
                     None => {
@@ -963,16 +948,17 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
 
     let prefixes = expected_errors.iter().map(|ee| {
         format!("{}:{}:", testfile.display(), ee.line)
-    }).collect::<Vec<String> >();
-
-    #[cfg(windows)]
-    fn prefix_matches( line : &str, prefix : &str ) -> bool {
-        line.to_ascii_lowercase().starts_with(&prefix.to_ascii_lowercase())
-    }
-
-    #[cfg(unix)]
-    fn prefix_matches( line : &str, prefix : &str ) -> bool {
-        line.starts_with( prefix )
+    }).collect::<Vec<String>>();
+
+    fn prefix_matches(line: &str, prefix: &str) -> bool {
+        use std::ascii::AsciiExt;
+        // On windows just translate all '\' path separators to '/'
+        let line = line.replace(r"\", "/");
+        if cfg!(windows) {
+            line.to_ascii_lowercase().starts_with(&prefix.to_ascii_lowercase())
+        } else {
+            line.starts_with(prefix)
+        }
     }
 
     // A multi-line error will have followup lines which will always
@@ -1050,7 +1036,7 @@ fn is_compiler_error_or_warning(line: &str) -> bool {
          scan_string(line, "warning", &mut i));
 }
 
-fn scan_until_char(haystack: &str, needle: char, idx: &mut uint) -> bool {
+fn scan_until_char(haystack: &str, needle: char, idx: &mut usize) -> bool {
     if *idx >= haystack.len() {
         return false;
     }
@@ -1062,26 +1048,26 @@ fn scan_until_char(haystack: &str, needle: char, idx: &mut uint) -> bool {
     return true;
 }
 
-fn scan_char(haystack: &str, needle: char, idx: &mut uint) -> bool {
+fn scan_char(haystack: &str, needle: char, idx: &mut usize) -> bool {
     if *idx >= haystack.len() {
         return false;
     }
-    let range = haystack.char_range_at(*idx);
-    if range.ch != needle {
+    let ch = haystack.char_at(*idx);
+    if ch != needle {
         return false;
     }
-    *idx = range.next;
+    *idx += ch.len_utf8();
     return true;
 }
 
-fn scan_integer(haystack: &str, idx: &mut uint) -> bool {
+fn scan_integer(haystack: &str, idx: &mut usize) -> bool {
     let mut i = *idx;
     while i < haystack.len() {
-        let range = haystack.char_range_at(i);
-        if range.ch < '0' || '9' < range.ch {
+        let ch = haystack.char_at(i);
+        if ch < '0' || '9' < ch {
             break;
         }
-        i = range.next;
+        i += ch.len_utf8();
     }
     if i == *idx {
         return false;
@@ -1090,16 +1076,16 @@ fn scan_integer(haystack: &str, idx: &mut uint) -> bool {
     return true;
 }
 
-fn scan_string(haystack: &str, needle: &str, idx: &mut uint) -> bool {
+fn scan_string(haystack: &str, needle: &str, idx: &mut usize) -> bool {
     let mut haystack_i = *idx;
     let mut needle_i = 0;
     while needle_i < needle.len() {
         if haystack_i >= haystack.len() {
             return false;
         }
-        let range = haystack.char_range_at(haystack_i);
-        haystack_i = range.next;
-        if !scan_char(needle, range.ch, &mut needle_i) {
+        let ch = haystack.char_at(haystack_i);
+        haystack_i += ch.len_utf8();
+        if !scan_char(needle, ch, &mut needle_i) {
             return false;
         }
     }
@@ -1113,12 +1099,42 @@ struct ProcArgs {
 }
 
 struct ProcRes {
-    status: ProcessExit,
+    status: Status,
     stdout: String,
     stderr: String,
     cmdline: String,
 }
 
+enum Status {
+    Parsed(i32),
+    Normal(ExitStatus),
+}
+
+impl Status {
+    fn code(&self) -> Option<i32> {
+        match *self {
+            Status::Parsed(i) => Some(i),
+            Status::Normal(ref e) => e.code(),
+        }
+    }
+
+    fn success(&self) -> bool {
+        match *self {
+            Status::Parsed(i) => i == 0,
+            Status::Normal(ref e) => e.success(),
+        }
+    }
+}
+
+impl fmt::Display for Status {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Status::Parsed(i) => write!(f, "exit code: {}", i),
+            Status::Normal(ref e) => e.fmt(f),
+        }
+    }
+}
+
 fn compile_test(config: &Config, props: &TestProps,
                 testfile: &Path) -> ProcRes {
     compile_test_(config, props, testfile, &[])
@@ -1133,7 +1149,7 @@ fn compile_test_(config: &Config, props: &TestProps,
     let aux_dir = aux_output_dir_name(config, testfile);
     // FIXME (#9639): This needs to handle non-utf8 paths
     let mut link_args = vec!("-L".to_string(),
-                             aux_dir.as_str().unwrap().to_string());
+                             aux_dir.to_str().unwrap().to_string());
     link_args.extend(extra_args.iter().cloned());
     let args = make_compile_args(config,
                                  props,
@@ -1160,7 +1176,7 @@ fn exec_compiled_test(config: &Config, props: &TestProps,
                             make_run_args(config, props, testfile),
                             env,
                             &config.run_lib_path,
-                            Some(aux_dir.as_str().unwrap()),
+                            Some(aux_dir.to_str().unwrap()),
                             None)
         }
     }
@@ -1179,7 +1195,7 @@ fn compose_and_run_compiler(
 
     let aux_dir = aux_output_dir_name(config, testfile);
     // FIXME (#9639): This needs to handle non-utf8 paths
-    let extra_link_args = vec!("-L".to_string(), aux_dir.as_str().unwrap().to_string());
+    let extra_link_args = vec!("-L".to_string(), aux_dir.to_str().unwrap().to_string());
 
     for rel_ab in &props.aux_builds {
         let abs_ab = config.aux_base.join(rel_ab);
@@ -1196,7 +1212,8 @@ fn compose_and_run_compiler(
                               crate_type,
                               |a,b| {
                                   let f = make_lib_name(a, b, testfile);
-                                  TargetLocation::ThisDirectory(f.dir_path())
+                                  let parent = f.parent().unwrap();
+                                  TargetLocation::ThisDirectory(parent.to_path_buf())
                               },
                               &abs_ab);
         let auxres = compose_and_run(config,
@@ -1204,7 +1221,7 @@ fn compose_and_run_compiler(
                                      aux_args,
                                      Vec::new(),
                                      &config.compile_lib_path,
-                                     Some(aux_dir.as_str().unwrap()),
+                                     Some(aux_dir.to_str().unwrap()),
                                      None);
         if !auxres.status.success() {
             fatal_proc_rec(
@@ -1226,13 +1243,13 @@ fn compose_and_run_compiler(
                     args,
                     Vec::new(),
                     &config.compile_lib_path,
-                    Some(aux_dir.as_str().unwrap()),
+                    Some(aux_dir.to_str().unwrap()),
                     input)
 }
 
 fn ensure_dir(path: &Path) {
     if path.is_dir() { return; }
-    fs::mkdir(path, old_io::USER_RWX).unwrap();
+    fs::create_dir(path).unwrap();
 }
 
 fn compose_and_run(config: &Config, testfile: &Path,
@@ -1246,8 +1263,8 @@ fn compose_and_run(config: &Config, testfile: &Path,
 }
 
 enum TargetLocation {
-    ThisFile(Path),
-    ThisDirectory(Path),
+    ThisFile(PathBuf),
+    ThisDirectory(PathBuf),
 }
 
 fn make_compile_args<F>(config: &Config,
@@ -1265,9 +1282,9 @@ fn make_compile_args<F>(config: &Config,
         &*config.target
     };
     // FIXME (#9639): This needs to handle non-utf8 paths
-    let mut args = vec!(testfile.as_str().unwrap().to_string(),
+    let mut args = vec!(testfile.to_str().unwrap().to_string(),
                         "-L".to_string(),
-                        config.build_base.as_str().unwrap().to_string(),
+                        config.build_base.to_str().unwrap().to_string(),
                         format!("--target={}", target));
     args.push_all(&extras);
     if !props.no_prefer_dynamic {
@@ -1284,7 +1301,7 @@ fn make_compile_args<F>(config: &Config,
             path
         }
     };
-    args.push(path.as_str().unwrap().to_string());
+    args.push(path.to_str().unwrap().to_string());
     if props.force_host {
         args.extend(split_maybe_args(&config.host_rustcflags).into_iter());
     } else {
@@ -1292,24 +1309,24 @@ fn make_compile_args<F>(config: &Config,
     }
     args.extend(split_maybe_args(&props.compile_flags).into_iter());
     return ProcArgs {
-        prog: config.rustc_path.as_str().unwrap().to_string(),
+        prog: config.rustc_path.to_str().unwrap().to_string(),
         args: args,
     };
 }
 
-fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> Path {
+fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> PathBuf {
     // what we return here is not particularly important, as it
     // happens; rustc ignores everything except for the directory.
     let auxname = output_testname(auxfile);
     aux_output_dir_name(config, testfile).join(&auxname)
 }
 
-fn make_exe_name(config: &Config, testfile: &Path) -> Path {
+fn make_exe_name(config: &Config, testfile: &Path) -> PathBuf {
     let mut f = output_base_name(config, testfile);
     if !env::consts::EXE_SUFFIX.is_empty() {
-        let mut fname = f.filename().unwrap().to_vec();
-        fname.extend(env::consts::EXE_SUFFIX.bytes());
-        f.set_filename(fname);
+        let mut fname = f.file_name().unwrap().to_os_string();
+        fname.push(env::consts::EXE_SUFFIX);
+        f.set_file_name(&fname);
     }
     f
 }
@@ -1322,7 +1339,7 @@ fn make_run_args(config: &Config, props: &TestProps, testfile: &Path) ->
     let exe_file = make_exe_name(config, testfile);
 
     // FIXME (#9639): This needs to handle non-utf8 paths
-    args.push(exe_file.as_str().unwrap().to_string());
+    args.push(exe_file.to_str().unwrap().to_string());
 
     // Add the arguments in the run_flags directive
     args.extend(split_maybe_args(&props.run_flags).into_iter());
@@ -1375,29 +1392,28 @@ fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String
                      input).expect(&format!("failed to exec `{}`", prog));
     dump_output(config, testfile, &out, &err);
     return ProcRes {
-        status: status,
+        status: Status::Normal(status),
         stdout: out,
         stderr: err,
         cmdline: cmdline,
     };
 }
 
-// Linux and mac don't require adjusting the library search path
-#[cfg(unix)]
-fn make_cmdline(_libpath: &str, prog: &str, args: &[String]) -> String {
-    format!("{} {}", prog, args.connect(" "))
-}
-
-#[cfg(windows)]
 fn make_cmdline(libpath: &str, prog: &str, args: &[String]) -> String {
+    use util;
 
-    // Build the LD_LIBRARY_PATH variable as it would be seen on the command line
-    // for diagnostic purposes
-    fn lib_path_cmd_prefix(path: &str) -> String {
-        format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
-    }
+    // Linux and mac don't require adjusting the library search path
+    if cfg!(unix) {
+        format!("{} {}", prog, args.connect(" "))
+    } else {
+        // Build the LD_LIBRARY_PATH variable as it would be seen on the command line
+        // for diagnostic purposes
+        fn lib_path_cmd_prefix(path: &str) -> String {
+            format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
+        }
 
-    format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" "))
+        format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" "))
+    }
 }
 
 fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) {
@@ -1409,25 +1425,25 @@ fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) {
 fn dump_output_file(config: &Config, testfile: &Path,
                     out: &str, extension: &str) {
     let outfile = make_out_name(config, testfile, extension);
-    File::create(&outfile).write_all(out.as_bytes()).unwrap();
+    File::create(&outfile).unwrap().write_all(out.as_bytes()).unwrap();
 }
 
-fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> Path {
+fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> PathBuf {
     output_base_name(config, testfile).with_extension(extension)
 }
 
-fn aux_output_dir_name(config: &Config, testfile: &Path) -> Path {
+fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf {
     let f = output_base_name(config, testfile);
-    let mut fname = f.filename().unwrap().to_vec();
-    fname.extend("libaux".bytes());
-    f.with_filename(fname)
+    let mut fname = f.file_name().unwrap().to_os_string();
+    fname.push("libaux");
+    f.with_file_name(&fname)
 }
 
-fn output_testname(testfile: &Path) -> Path {
-    Path::new(testfile.filestem().unwrap())
+fn output_testname(testfile: &Path) -> PathBuf {
+    PathBuf::from(testfile.file_stem().unwrap())
 }
 
-fn output_base_name(config: &Config, testfile: &Path) -> Path {
+fn output_base_name(config: &Config, testfile: &Path) -> PathBuf {
     config.build_base
         .join(&output_testname(testfile))
         .with_extension(&config.stage_id)
@@ -1542,11 +1558,11 @@ fn _arm_exec_compiled_test(config: &Config,
                      Some("".to_string()))
         .expect(&format!("failed to exec `{}`", config.adb_path));
 
-    let mut exitcode: int = 0;
+    let mut exitcode: i32 = 0;
     for c in exitcode_out.chars() {
         if !c.is_numeric() { break; }
         exitcode = exitcode * 10 + match c {
-            '0' ... '9' => c as int - ('0' as int),
+            '0' ... '9' => c as i32 - ('0' as i32),
             _ => 101,
         }
     }
@@ -1587,7 +1603,7 @@ fn _arm_exec_compiled_test(config: &Config,
                 &stderr_out);
 
     ProcRes {
-        status: process::ProcessExit::ExitStatus(exitcode),
+        status: Status::Parsed(exitcode),
         stdout: stdout_out,
         stderr: stderr_out,
         cmdline: cmdline
@@ -1597,16 +1613,17 @@ fn _arm_exec_compiled_test(config: &Config,
 fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
     let tdir = aux_output_dir_name(config, testfile);
 
-    let dirs = fs::readdir(&tdir).unwrap();
-    for file in &dirs {
-        if file.extension_str() == Some("so") {
+    let dirs = fs::read_dir(&tdir).unwrap();
+    for file in dirs {
+        let file = file.unwrap().path();
+        if file.extension().and_then(|s| s.to_str()) == Some("so") {
             // FIXME (#9639): This needs to handle non-utf8 paths
             let copy_result = procsrv::run("",
                                            &config.adb_path,
                                            None,
                                            &[
                                             "push".to_string(),
-                                            file.as_str()
+                                            file.to_str()
                                                 .unwrap()
                                                 .to_string(),
                                             config.adb_test_dir.to_string(),
@@ -1627,14 +1644,14 @@ fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
 
 // codegen tests (vs. clang)
 
-fn append_suffix_to_stem(p: &Path, suffix: &str) -> Path {
+fn append_suffix_to_stem(p: &Path, suffix: &str) -> PathBuf {
     if suffix.len() == 0 {
-        (*p).clone()
+        p.to_path_buf()
     } else {
-        let mut stem = p.filestem().unwrap().to_vec();
-        stem.extend("-".bytes());
-        stem.extend(suffix.bytes());
-        p.with_filename(stem)
+        let mut stem = p.file_stem().unwrap().to_os_string();
+        stem.push("-");
+        stem.push(suffix);
+        p.with_file_name(&stem)
     }
 }
 
@@ -1643,7 +1660,7 @@ fn compile_test_and_save_bitcode(config: &Config, props: &TestProps,
     let aux_dir = aux_output_dir_name(config, testfile);
     // FIXME (#9639): This needs to handle non-utf8 paths
     let mut link_args = vec!("-L".to_string(),
-                             aux_dir.as_str().unwrap().to_string());
+                             aux_dir.to_str().unwrap().to_string());
     let llvm_args = vec!("--emit=llvm-bc,obj".to_string(),
                          "--crate-type=lib".to_string());
     link_args.extend(llvm_args.into_iter());
@@ -1651,7 +1668,8 @@ fn compile_test_and_save_bitcode(config: &Config, props: &TestProps,
                                  props,
                                  link_args,
                                  |a, b| TargetLocation::ThisDirectory(
-                                     output_base_name(a, b).dir_path()),
+                                     output_base_name(a, b).parent()
+                                        .unwrap().to_path_buf()),
                                  testfile);
     compose_and_run_compiler(config, props, testfile, args, None)
 }
@@ -1663,12 +1681,12 @@ fn compile_cc_with_clang_and_save_bitcode(config: &Config, _props: &TestProps,
     let testcc = testfile.with_extension("cc");
     let proc_args = ProcArgs {
         // FIXME (#9639): This needs to handle non-utf8 paths
-        prog: config.clang_path.as_ref().unwrap().as_str().unwrap().to_string(),
+        prog: config.clang_path.as_ref().unwrap().to_str().unwrap().to_string(),
         args: vec!("-c".to_string(),
                    "-emit-llvm".to_string(),
                    "-o".to_string(),
-                   bitcodefile.as_str().unwrap().to_string(),
-                   testcc.as_str().unwrap().to_string())
+                   bitcodefile.to_str().unwrap().to_string(),
+                   testcc.to_str().unwrap().to_string())
     };
     compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
 }
@@ -1682,10 +1700,10 @@ fn extract_function_from_bitcode(config: &Config, _props: &TestProps,
     let prog = config.llvm_bin_path.as_ref().unwrap().join("llvm-extract");
     let proc_args = ProcArgs {
         // FIXME (#9639): This needs to handle non-utf8 paths
-        prog: prog.as_str().unwrap().to_string(),
+        prog: prog.to_str().unwrap().to_string(),
         args: vec!(format!("-func={}", fname),
-                   format!("-o={}", extracted_bc.as_str().unwrap()),
-                   bitcodefile.as_str().unwrap().to_string())
+                   format!("-o={}", extracted_bc.to_str().unwrap()),
+                   bitcodefile.to_str().unwrap().to_string())
     };
     compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
 }
@@ -1699,16 +1717,17 @@ fn disassemble_extract(config: &Config, _props: &TestProps,
     let prog = config.llvm_bin_path.as_ref().unwrap().join("llvm-dis");
     let proc_args = ProcArgs {
         // FIXME (#9639): This needs to handle non-utf8 paths
-        prog: prog.as_str().unwrap().to_string(),
-        args: vec!(format!("-o={}", extracted_ll.as_str().unwrap()),
-                   extracted_bc.as_str().unwrap().to_string())
+        prog: prog.to_str().unwrap().to_string(),
+        args: vec!(format!("-o={}", extracted_ll.to_str().unwrap()),
+                   extracted_bc.to_str().unwrap().to_string())
     };
     compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
 }
 
 
-fn count_extracted_lines(p: &Path) -> uint {
-    let x = File::open(&p.with_extension("ll")).read_to_end().unwrap();
+fn count_extracted_lines(p: &Path) -> usize {
+    let mut x = Vec::new();
+    File::open(&p.with_extension("ll")).unwrap().read_to_end(&mut x).unwrap();
     let x = str::from_utf8(&x).unwrap();
     x.lines().count()
 }
index c046a89cba55ff52c6681c1861c59f4f36fc9f44..a8b26cb3ef76835a5fb498ca76a347eabcfee5e8 100644 (file)
@@ -8,22 +8,39 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use common::Config;
-
-#[cfg(target_os = "windows")]
 use std::env;
+use common::Config;
 
 /// Conversion table from triple OS name to Rust SYSNAME
-static OS_TABLE: &'static [(&'static str, &'static str)] = &[
-    ("mingw32", "windows"),
-    ("win32", "windows"),
-    ("windows", "windows"),
-    ("darwin", "macos"),
+const OS_TABLE: &'static [(&'static str, &'static str)] = &[
     ("android", "android"),
-    ("linux", "linux"),
-    ("freebsd", "freebsd"),
+    ("bitrig", "bitrig"),
+    ("darwin", "macos"),
     ("dragonfly", "dragonfly"),
+    ("freebsd", "freebsd"),
+    ("ios", "ios"),
+    ("linux", "linux"),
+    ("mingw32", "windows"),
     ("openbsd", "openbsd"),
+    ("win32", "windows"),
+    ("windows", "windows"),
+];
+
+const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
+    ("aarch64", "aarch64"),
+    ("amd64", "x86_64"),
+    ("arm", "arm"),
+    ("arm64", "aarch64"),
+    ("hexagon", "hexagon"),
+    ("i386", "x86"),
+    ("i686", "x86"),
+    ("mips", "mips"),
+    ("msp430", "msp430"),
+    ("powerpc", "powerpc"),
+    ("s390x", "systemz"),
+    ("sparc", "sparc"),
+    ("x86_64", "x86_64"),
+    ("xcore", "xcore"),
 ];
 
 pub fn get_os(triple: &str) -> &'static str {
@@ -34,25 +51,29 @@ pub fn get_os(triple: &str) -> &'static str {
     }
     panic!("Cannot determine OS from triple");
 }
+pub fn get_arch(triple: &str) -> &'static str {
+    for &(triple_arch, arch) in ARCH_TABLE {
+        if triple.contains(triple_arch) {
+            return arch
+        }
+    }
+    panic!("Cannot determine Architecture from triple");
+}
 
-#[cfg(target_os = "windows")]
 pub fn make_new_path(path: &str) -> String {
-
+    assert!(cfg!(windows));
     // Windows just uses PATH as the library search path, so we have to
     // maintain the current value while adding our own
     match env::var(lib_path_env_var()) {
-      Ok(curr) => {
-        format!("{}{}{}", path, path_div(), curr)
-      }
-      Err(..) => path.to_string()
+        Ok(curr) => {
+            format!("{}{}{}", path, path_div(), curr)
+        }
+        Err(..) => path.to_string()
     }
 }
 
-#[cfg(target_os = "windows")]
 pub fn lib_path_env_var() -> &'static str { "PATH" }
-
-#[cfg(target_os = "windows")]
-pub fn path_div() -> &'static str { ";" }
+fn path_div() -> &'static str { ";" }
 
 pub fn logv(config: &Config, s: String) {
     debug!("{}", s);
index e57953db3a256fd2463ad6a04d3015dccd830c96..3edbcbe62c51172ea225fa122e62add202f9657b 100644 (file)
@@ -174,3 +174,10 @@ bindings.
 See also [a long thread][alt] on renaming `let mut` to `var`.
 
 [alt]: https://mail.mozilla.org/pipermail/rust-dev/2014-January/008319.html
+
+## Why no `--x` or `x++`?
+
+Preincrement and postincrement, while convenient, are also fairly complex. They
+require knowledge of evaluation order, and often lead to subtle bugs and
+undefined behavior in C and C++. `x = x + 1` or `x += 1` is only slightly
+longer, but unambiguous.
index d7a29ea530952a4f28a934c0834fce2558f7e845..1ea3c7d7bd9d87924cab902b7c69fa34238752e0 100644 (file)
@@ -290,7 +290,7 @@ transcriber : '(' transcriber * ')' | '[' transcriber * ']'
 
 # Items and attributes
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ## Items
 
@@ -301,7 +301,7 @@ item : mod_item | fn_item | type_item | struct_item | enum_item
 
 ### Type Parameters
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Modules
 
@@ -338,35 +338,35 @@ path_item : ident | "mod" ;
 
 ### Functions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Generic functions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Unsafety
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ##### Unsafe functions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ##### Unsafe blocks
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Diverging functions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Type definitions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Structures
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Constant items
 
@@ -382,15 +382,15 @@ static_item : "static" ident ':' type '=' expr ';' ;
 
 #### Mutable statics
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Traits
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Implementations
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### External blocks
 
@@ -401,11 +401,11 @@ extern_block : [ foreign_fn ] * ;
 
 ## Visibility and Privacy
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Re-exporting and Visibility
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ## Attributes
 
@@ -420,11 +420,11 @@ meta_seq : meta_item [ ',' meta_seq ] ? ;
 
 ## Statements
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Declaration statements
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 A _declaration statement_ is one that introduces one or more *names* into the
 enclosing statement block. The declared names may denote new slots or new
@@ -432,7 +432,7 @@ items.
 
 #### Item declarations
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 An _item declaration statement_ has a syntactic form identical to an
 [item](#items) declaration within a module. Declaring an item &mdash; a
@@ -450,35 +450,35 @@ init : [ '=' ] expr ;
 
 ### Expression statements
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ## Expressions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Lvalues, rvalues and temporaries
 
-**FIXME:** grammar?  
+**FIXME:** grammar?
 
 #### Moved and copied types
 
-**FIXME:** Do we want to capture this in the grammar as different productions? 
+**FIXME:** Do we want to capture this in the grammar as different productions?
 
 ### Literal expressions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Path expressions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Tuple expressions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Unit expressions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Structure expressions
 
@@ -514,7 +514,7 @@ field_expr : expr '.' ident ;
 ### Array expressions
 
 ```antlr
-array_expr : '[' "mut" ? vec_elems? ']' ;
+array_expr : '[' "mut" ? array_elems? ']' ;
 
 array_elems : [expr [',' expr]*] | [expr ',' ".." expr] ;
 ```
@@ -527,7 +527,7 @@ idx_expr : expr '[' expr ']' ;
 
 ### Unary operator expressions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Binary operator expressions
 
@@ -537,31 +537,31 @@ binop_expr : expr binop expr ;
 
 #### Arithmetic operators
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Bitwise operators
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Lazy boolean operators
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Comparison operators
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Type cast expressions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Assignment expressions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Compound assignment expressions
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Operator precedence
 
@@ -680,49 +680,49 @@ return_expr : "return" expr ? ;
 
 # Type system
 
-**FIXME:** is this entire chapter relevant here? Or should it all have been covered by some production already? 
+**FIXME:** is this entire chapter relevant here? Or should it all have been covered by some production already?
 
 ## Types
 
 ### Primitive types
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Machine types
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 #### Machine-dependent integer types
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Textual types
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Tuple types
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Array, and Slice types
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Structure types
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Enumerated types
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Pointer types
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Function types
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Closure types
 
@@ -739,15 +739,15 @@ bound := path | lifetime
 
 ### Object types
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Type parameters
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ### Self types
 
-**FIXME:** grammar? 
+**FIXME:** grammar?
 
 ## Type kinds
 
@@ -755,7 +755,7 @@ bound := path | lifetime
 
 # Memory and concurrency models
 
-**FIXME:** is this entire chapter relevant here? Or should it all have been covered by some production already? 
+**FIXME:** is this entire chapter relevant here? Or should it all have been covered by some production already?
 
 ## Memory model
 
index 197559bef0408564d13f90ee1e6cc008d09d5b24..21217bf54d7693e50a4777601536f2fca935edc0 100644 (file)
@@ -1,4 +1,4 @@
 % The (old) Rust Threads and Communication Guide
 
 This content has moved into
-[the Rust Programming Language book](book/tasks.html).
+[the Rust Programming Language book](book/concurrency.html).
index a4f79412220189436fb3ad850210a4a28dcf66d1..f6b0a18824a0253327356b9eeb169b2a1e7f3bf2 100644 (file)
@@ -68,7 +68,7 @@ There are questions that are asked quite often, and so we've made FAQs for them:
 * [Language Design FAQ](complement-design-faq.html)
 * [Language FAQ](complement-lang-faq.html)
 * [Project FAQ](complement-project-faq.html)
-* [How to submit a bug report](complement-bugreport.html)
+* [How to submit a bug report](https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports)
 
 # The standard library
 
index d9bfe71e2e42827d3aaeaa43076a7ce34fab346b..b711085ddbd9c298cd5b641d4d4711617d02224a 100644 (file)
@@ -140,7 +140,7 @@ right at home if you've used tools like [Bundler](http://bundler.io/),
 [npm](https://www.npmjs.org/), or [pip](https://pip.pypa.io/en/latest/).
 There's no `Makefile`s or endless `autotools` output here. (Rust's tooling does
 [play nice with external libraries written in those
-tools](http://crates.io/native-build.html), if you need to.)
+tools](http://doc.crates.io/build-script.html), if you need to.)
 
 Enough about tools, let's talk code!
 
@@ -389,11 +389,11 @@ safe concurrent programs.
 Here's an example of a concurrent Rust program:
 
 ```{rust}
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
     let guards: Vec<_> = (0..10).map(|_| {
-        Thread::scoped(|| {
+        thread::scoped(|| {
             println!("Hello, world!");
         })
     }).collect();
@@ -421,44 +421,41 @@ problem.
 Let's see an example. This Rust code will not compile:
 
 ```{rust,ignore}
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
     let mut numbers = vec![1, 2, 3];
 
-    for i in 0..3 {
-        Thread::spawn(move || {
-            for j in 0..3 { numbers[j] += 1 }
-        });
-    }
+    let guards: Vec<_> = (0..3).map(|i| {
+        thread::scoped(move || {
+            numbers[i] += 1;
+            println!("numbers[{}] is {}", i, numbers[i]);
+        })
+    }).collect();
 }
 ```
 
 It gives us this error:
 
 ```text
-6:71 error: capture of moved value: `numbers`
-    for j in 0..3 { numbers[j] += 1 }
-                    ^~~~~~~
-7:50 note: `numbers` moved into closure environment here
-    spawn(move || {
-        for j in 0..3 { numbers[j] += 1 }
-    });
-6:79 error: cannot assign to immutable dereference (dereference is implicit, due to indexing)
-        for j in 0..3 { numbers[j] += 1 }
-                        ^~~~~~~~~~~~~~~
+7:25: 10:6 error: cannot move out of captured outer variable in an `FnMut` closure
+7     thread::scoped(move || {
+8       numbers[i] += 1;
+9       println!("numbers[{}] is {}", i, numbers[i]);
+10     })
+error: aborting due to previous error
 ```
 
-It mentions that "numbers moved into closure environment". Because we
-declared the closure as a moving closure, and it referred to
-`numbers`, the closure will try to take ownership of the vector. But
-the closure itself is created in a loop, and hence we will actually
-create three closures, one for every iteration of the loop. This means
-that all three of those closures would try to own `numbers`, which is
-impossible -- `numbers` must have just one owner. Rust detects this
-and gives us the error: we claim that `numbers` has ownership, but our
-code tries to make three owners. This may cause a safety problem, so
-Rust disallows it.
+This is a little confusing because there are two closures here: the one passed
+to `map`, and the one passed to `thread::scoped`. In this case, the closure for
+`thread::scoped` is attempting to reference `numbers`, a `Vec<i32>`. This
+closure is a `FnOnce` closure, as that’s what `thread::scoped` takes as an
+argument. `FnOnce` closures take ownership of their environment. That’s fine,
+but there’s one detail: because of `map`, we’re going to make three of these
+closures. And since all three try to take ownership of `numbers`, that would be
+a problem. That’s what it means by ‘cannot move out of captured outer
+variable’: our `thread::scoped` closure wants to take ownership, and it can’t,
+because the closure for `map` won’t let it.
 
 What to do here? Rust has two types that helps us: `Arc<T>` and `Mutex<T>`.
 *Arc* stands for "atomically reference counted". In other words, an Arc will
@@ -474,20 +471,20 @@ mutation doesn't cause a data race.
 Here's what using an Arc with a Mutex looks like:
 
 ```{rust}
-use std::thread::Thread;
+use std::thread;
 use std::sync::{Arc,Mutex};
 
 fn main() {
     let numbers = Arc::new(Mutex::new(vec![1, 2, 3]));
 
-    for i in 0..3 {
+    let guards: Vec<_> = (0..3).map(|i| {
         let number = numbers.clone();
-        Thread::spawn(move || {
+        thread::scoped(move || {
             let mut array = number.lock().unwrap();
             array[i] += 1;
             println!("numbers[{}] is {}", i, array[i]);
-        });
-    }
+        })
+    }).collect();
 }
 ```
 
@@ -516,8 +513,10 @@ numbers[1] is 3
 numbers[0] is 2
 ```
 
-Each time, we get a slightly different output, because each thread works in a
-different order. You may not get the same output as this sample, even.
+Each time, we can get a slightly different output because the threads are not
+guaranteed to run in any set order. If you get the same order every time it is
+because each of these threads are very small and complete too fast for their
+indeterminate behavior to surface.
 
 The important part here is that the Rust compiler was able to use ownership to
 give us assurance _at compile time_ that we weren't doing something incorrect
@@ -536,16 +535,16 @@ As an example, Rust's ownership system is _entirely_ at compile time. The
 safety check that makes this an error about moved values:
 
 ```{rust,ignore}
-use std::thread::Thread;
+use std::thread;
 
 fn main() {
-    let vec = vec![1, 2, 3];
+    let numbers = vec![1, 2, 3];
 
-    for i in 0..3 {
-        Thread::spawn(move || {
-            println!("{}", vec[i]);
-        });
-    }
+    let guards: Vec<_> = (0..3).map(|i| {
+        thread::scoped(move || {
+            println!("{}", numbers[i]);
+        })
+    }).collect();
 }
 ```
 
@@ -569,7 +568,7 @@ while retaining safety. The answer is iterators:
 ```{rust}
 let vec = vec![1, 2, 3];
 
-for x in vec.iter() {
+for x in &vec {
     println!("{}", x);
 }
 ```
index c746c5773dd0907ce8fea7c97a69e47c66de178f..eae2bf1925a99622c2f8b8f2486270da30d96897 100644 (file)
@@ -63,4 +63,3 @@ function populate_rust_search() {
 populate_site_search();
 populate_rust_search();
 </script>
-
index db940947040d48f41c4811bb46c4aca7e8ae1244..cc90a69fd2ae7d2b1f1147565abdddd73f64c0d1 100644 (file)
@@ -229,14 +229,14 @@ cases mentioned in [Number literals](#number-literals) below.
 
 ##### Characters and strings
 
-|   | Example | Number of `#` pairs allowed | Available characters | Escapes | Equivalent to |
-|---|---------|-----------------------------|----------------------|---------|---------------|
-| [Character](#character-literals) | `'H'` | `N/A` | All unicode | `\'` & [Byte escapes](#byte-escapes) & [Unicode escapes](#unicode-escapes) | `N/A` |
-| [String](#string-literals) | `"hello"` | `N/A` | All unicode | `\"` & [Byte escapes](#byte-escapes) & [Unicode escapes](#unicode-escapes) | `N/A` |
-| [Raw](#raw-string-literals) | `r##"hello"##`  | `0...` | All unicode | `N/A` | `N/A` |
-| [Byte](#byte-literals) | `b'H'` | `N/A` | All ASCII | `\'` & [Byte escapes](#byte-escapes) | `u8` |
-| [Byte string](#byte-string-literals) | `b"hello"` | `N/A`  | All ASCII | `\"` & [Byte escapes](#byte-escapes) | `&'static [u8]` |
-| [Raw byte string](#raw-byte-string-literals) | `br##"hello"##` | `0...` | All ASCII | `N/A` | `&'static [u8]` (unsure...not stated) |
+|                                              | Example         | `#` sets   | Characters  | Escapes             |
+|----------------------------------------------|-----------------|------------|-------------|---------------------|
+| [Character](#character-literals)             | `'H'`           | `N/A`      | All Unicode | `\'` & [Byte](#byte-escapes) & [Unicode](#unicode-escapes) |
+| [String](#string-literals)                   | `"hello"`       | `N/A`      | All Unicode | `\"` & [Byte](#byte-escapes) & [Unicode](#unicode-escapes) |
+| [Raw](#raw-string-literals)                  | `r#"hello"#`    | `0...`     | All Unicode | `N/A`                                                      |
+| [Byte](#byte-literals)                       | `b'H'`          | `N/A`      | All ASCII   | `\'` & [Byte](#byte-escapes)                               |
+| [Byte string](#byte-string-literals)         | `b"hello"`      | `N/A`      | All ASCII   | `\"` & [Byte](#byte-escapes)                               |
+| [Raw byte string](#raw-byte-string-literals) | `br#"hello"#`   | `0...`     | All ASCII   | `N/A`                                                      |
 
 ##### Byte escapes
 
@@ -302,7 +302,7 @@ nonzero_dec: '1' | '2' | '3' | '4'
 
 A _character literal_ is a single Unicode character enclosed within two
 `U+0027` (single-quote) characters, with the exception of `U+0027` itself,
-which must be _escaped_ by a preceding U+005C character (`\`).
+which must be _escaped_ by a preceding `U+005C` character (`\`).
 
 ##### String literals
 
@@ -311,6 +311,19 @@ A _string literal_ is a sequence of any Unicode characters enclosed within two
 which must be _escaped_ by a preceding `U+005C` character (`\`), or a _raw
 string literal_.
 
+A multi-line string literal may be defined by terminating each line with a
+`U+005C` character (`\`) immediately before the newline. This causes the
+`U+005C` character, the newline, and all whitespace at the beginning of the
+next line to be ignored.
+
+```rust
+let a = "foobar";
+let b = "foo\
+         bar";
+
+assert_eq!(a,b);
+```
+
 ##### Character escapes
 
 Some additional _escapes_ are available in either character or non-raw string
@@ -515,6 +528,9 @@ 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`.
 
+The representation semantics of floating-point numbers are described in
+["Machine Types"](#machine-types).
+
 #### Boolean literals
 
 The two values of the boolean type are written `true` and `false`.
@@ -629,18 +645,7 @@ fn bar() {
 
 A number of minor features of Rust are not central enough to have their own
 syntax, and yet are not implementable as functions. Instead, they are given
-names, and invoked through a consistent syntax: `name!(...)`. Examples include:
-
-* `format!` : format data into a string
-* `env!` : look up an environment variable's value at compile time
-* `file!`: return the path to the file being compiled
-* `stringify!` : pretty-print the Rust expression given as an argument
-* `include!` : include the Rust expression in the given file
-* `include_str!` : include the contents of the given file as a string
-* `include_bytes!` : include the contents of the given file as a binary blob
-* `error!`, `warn!`, `info!`, `debug!` : provide diagnostic information.
-
-All of the above extensions are expressions with values.
+names, and invoked through a consistent syntax: `some_extension!(...)`.
 
 Users of `rustc` can define new syntax extensions in two ways:
 
@@ -728,23 +733,6 @@ Rust syntax is restricted in two ways:
    pairs when they occur at the beginning of, or immediately after, a `$(...)*`;
    requiring a distinctive token in front can solve the problem.
 
-## Syntax extensions useful for the macro author
-
-* `log_syntax!` : print out the arguments at compile time
-* `trace_macros!` : supply `true` or `false` to enable or disable macro expansion logging
-* `stringify!` : turn the identifier argument into a string literal
-* `concat!` : concatenates a comma-separated list of literals
-* `concat_idents!` : create a new identifier by concatenating the arguments
-
-The following attributes are used for quasiquoting in procedural macros:
-
-* `quote_expr!`
-* `quote_item!`
-* `quote_pat!`
-* `quote_stmt!`
-* `quote_tokens!`
-* `quote_ty!`
-
 # Crates and source files
 
 Rust is a *compiled* language. Its semantics obey a *phase distinction*
@@ -785,8 +773,7 @@ may optionally begin with any number of `attributes` that apply to the
 containing module. Attributes on the anonymous crate module define important
 metadata that influences the behavior of the compiler.
 
-```{.rust}
-# #![allow(unused_attribute)]
+```no_run
 // Crate name
 #![crate_name = "projx"]
 
@@ -950,7 +937,7 @@ extern crate pcre;
 
 extern crate std; // equivalent to: extern crate std as std;
 
-extern crate "std" as ruststd; // linking to 'std' under another name
+extern crate std as ruststd; // linking to 'std' under another name
 ```
 
 ##### Use declarations
@@ -989,7 +976,7 @@ Use declarations support a number of convenient shortcuts:
 An example of `use` declarations:
 
 ```
-use std::iter::range_step;
+# #![feature(core)]
 use std::option::Option::{Some, None};
 use std::collections::hash_map::{self, HashMap};
 
@@ -997,9 +984,6 @@ fn foo<T>(_: T){}
 fn bar(map1: HashMap<String, usize>, map2: hash_map::HashMap<String, usize>){}
 
 fn main() {
-    // Equivalent to 'std::iter::range_step(0, 10, 2);'
-    range_step(0, 10, 2);
-
     // Equivalent to 'foo(vec![std::option::Option::Some(1.0f64),
     // std::option::Option::None]);'
     foo(vec![Some(1.0f64), None]);
@@ -1049,6 +1033,7 @@ declarations.
 An example of what will and will not work for `use` items:
 
 ```
+# #![feature(core)]
 # #![allow(unused_imports)]
 use foo::core::iter;  // good: foo is at the root of the crate
 use foo::baz::foobaz;    // good: foo is at the root of the crate
@@ -1199,12 +1184,15 @@ the guarantee that these issues are never caused by safe code.
 
 * Data races
 * Dereferencing a null/dangling raw pointer
-* Mutating an immutable value/reference without `UnsafeCell`
 * Reads of [undef](http://llvm.org/docs/LangRef.html#undefined-values)
   (uninitialized) memory
 * Breaking the [pointer aliasing
   rules](http://llvm.org/docs/LangRef.html#pointer-aliasing-rules)
   with raw pointers (a subset of the rules used by C)
+* `&mut` and `&` follow LLVM’s scoped [noalias] model, except if the `&T`
+  contains an `UnsafeCell<U>`. Unsafe code must not violate these aliasing
+  guarantees.
+* Mutating an immutable value/reference without `UnsafeCell<U>`
 * Invoking undefined behavior via compiler intrinsics:
   * Indexing outside of the bounds of an object with `std::ptr::offset`
     (`offset` intrinsic), with
@@ -1221,6 +1209,8 @@ the guarantee that these issues are never caused by safe code.
   code. Rust's failure system is not compatible with exception handling in
   other languages. Unwinding must be caught and handled at FFI boundaries.
 
+[noalias]: http://llvm.org/docs/LangRef.html#noalias
+
 ##### Behaviour not considered unsafe
 
 This is a list of behaviour not considered *unsafe* in Rust terms, but that may
@@ -1233,7 +1223,7 @@ be undesired.
 * Sending signals
 * Accessing/modifying the file system
 * Unsigned integer overflow (well-defined as wrapping)
-* Signed integer overflow (well-defined as two's complement representation
+* Signed integer overflow (well-defined as twos complement representation
   wrapping)
 
 #### Diverging functions
@@ -1489,22 +1479,6 @@ statics:
 Constants should in general be preferred over statics, unless large amounts of
 data are being stored, or single-address and mutability properties are required.
 
-```
-use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
-
-// Note that ATOMIC_USIZE_INIT is a *const*, but it may be used to initialize a
-// static. This static can be modified, so it is not placed in read-only memory.
-static COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
-
-// This table is a candidate to be placed in read-only memory.
-static TABLE: &'static [usize] = &[1, 2, 3, /* ... */];
-
-for slot in TABLE.iter() {
-    println!("{}", slot);
-}
-COUNTER.fetch_add(1, Ordering::SeqCst);
-```
-
 #### Mutable statics
 
 If a static item is declared with the `mut` keyword, then it is allowed to
@@ -1674,7 +1648,7 @@ specific type.
 Implementations are defined with the keyword `impl`.
 
 ```
-# #[derive(Copy)]
+# #[derive(Copy, Clone)]
 # struct Point {x: f64, y: f64};
 # type Surface = i32;
 # struct BoundingBox {x: f64, y: f64, width: f64, height: f64};
@@ -1687,6 +1661,10 @@ struct Circle {
 
 impl Copy for Circle {}
 
+impl Clone for Circle {
+    fn clone(&self) -> Circle { *self }
+}
+
 impl Shape for Circle {
     fn draw(&self, s: Surface) { do_draw_circle(s, *self); }
     fn bounding_box(&self) -> BoundingBox {
@@ -1750,6 +1728,7 @@ functions, with the exception that they may not have a body and are instead
 terminated by a semicolon.
 
 ```
+# #![feature(libc)]
 extern crate libc;
 use libc::{c_char, FILE};
 
@@ -1930,16 +1909,18 @@ module through the rules above. It essentially allows public access into the
 re-exported item. For example, this program is valid:
 
 ```
-pub use self::implementation as api;
+pub use self::implementation::api;
 
 mod implementation {
-    pub fn f() {}
+    pub mod api {
+        pub fn f() {}
+    }
 }
 
 # fn main() {}
 ```
 
-This means that any external crate referencing `implementation::f` would
+This means that any external crate referencing `implementation::api::f` would
 receive a privacy violation, while the path `api::f` would be allowed.
 
 When re-exporting a private item, it can be thought of as allowing the "privacy
@@ -1949,7 +1930,7 @@ the namespace hierarchy as it normally would.
 ## Attributes
 
 ```{.ebnf .gram}
-attribute : "#!" ? '[' meta_item ']' ;
+attribute : '#' '!' ? '[' meta_item ']' ;
 meta_item : ident [ '=' literal
                   | '(' meta_seq ')' ] ? ;
 meta_seq : meta_item [ ',' meta_seq ] ? ;
@@ -2035,7 +2016,7 @@ type int8_t = i8;
   item](#language-items) for more details.
 - `test` - indicates that this function is a test function, to only be compiled
   in case of `--test`.
-- `should_fail` - indicates that this test function should panic, inverting the success condition.
+- `should_panic` - indicates that this test function should panic, inverting the success condition.
 - `cold` - The function is unlikely to be executed, so optimize it (and calls
   to it) differently.
 
@@ -2162,7 +2143,7 @@ fn needs_foo_or_bar() {
 
 // This function is only included when compiling for a unixish OS with a 32-bit
 // architecture
-#[cfg(all(unix, target_word_size = "32"))]
+#[cfg(all(unix, target_pointer_width = "32"))]
 fn on_32bit_unix() {
   // ...
 }
@@ -2188,11 +2169,11 @@ The following configurations must be defined by the implementation:
   `"unix"` or `"windows"`. The value of this configuration option is defined
   as a configuration itself, like `unix` or `windows`.
 * `target_os = "..."`. Operating system of the target, examples include
-  `"win32"`, `"macos"`, `"linux"`, `"android"`, `"freebsd"`, `"dragonfly"` or
-  `"openbsd"`.
-* `target_word_size = "..."`. Target word size in bits. This is set to `"32"`
-  for targets with 32-bit pointers, and likewise set to `"64"` for 64-bit
-  pointers.
+  `"win32"`, `"macos"`, `"linux"`, `"android"`, `"freebsd"`, `"dragonfly"`,
+  `"bitrig"` or `"openbsd"`.
+* `target_pointer_width = "..."`. Target pointer width in bits. This is set
+  to `"32"` for targets with 32-bit pointers, and likewise set to `"64"` for
+  64-bit pointers.
 * `unix`. See `target_family`.
 * `windows`. See `target_family`.
 
@@ -2341,18 +2322,6 @@ impl<T: PartialEq> PartialEq for Foo<T> {
 }
 ```
 
-Supported traits for `derive` are:
-
-* Comparison traits: `PartialEq`, `Eq`, `PartialOrd`, `Ord`.
-* Serialization: `Encodable`, `Decodable`. These require `serialize`.
-* `Clone`, to create `T` from `&T` via a copy.
-* `Default`, to create an empty instance of a data type.
-* `FromPrimitive`, to create an instance from a numeric primitive.
-* `Hash`, to iterate over the bytes in a data type.
-* `Rand`, to create a random instance of a data type.
-* `Debug`, to format a value using the `{:?}` formatter.
-* `Copy`, for "Plain Old Data" types which can be copied by simply moving bits.
-
 ### Compiler Features
 
 Certain aspects of Rust may be implemented in the compiler, but they're not
@@ -2373,9 +2342,13 @@ considered off, and using the features will result in a compiler error.
 
 The currently implemented features of the reference compiler are:
 
-* `advanced_slice_patterns` - see the [match expressions](#match-expressions)
+* `advanced_slice_patterns` - See the [match expressions](#match-expressions)
                               section for discussion; the exact semantics of
-                              slice patterns are subject to change.
+                              slice patterns are subject to change, so some types
+                             are still unstable.
+
+* `slice_patterns` - OK, actually, slice patterns are just scary and
+                     completely unstable.
 
 * `asm` - The `asm!` macro provides a means for inline assembly. This is often
           useful, but the exact syntax for this feature along with its
@@ -2398,12 +2371,13 @@ The currently implemented features of the reference compiler are:
                        so that new attributes can be added in a bacwards compatible
                        manner (RFC 572).
 
+* `custom_derive` - Allows the use of `#[derive(Foo,Bar)]` as sugar for
+                    `#[derive_Foo] #[derive_Bar]`, which can be user-defined syntax
+                    extensions.
+
 * `intrinsics` - Allows use of the "rust-intrinsics" ABI. Compiler intrinsics
                  are inherently unstable and no promise about them is made.
 
-* `int_uint` - Allows the use of the `int` and `uint` types, which are deprecated.
-               Use `isize` and `usize` instead.
-
 * `lang_items` - Allows use of the `#[lang]` attribute. Like `intrinsics`,
                  lang items are inherently unstable and no promise about them
                  is made.
@@ -2472,6 +2446,12 @@ The currently implemented features of the reference compiler are:
 
 * `staged_api` - Allows usage of stability markers and `#![staged_api]` in a crate
 
+* `static_assert` - The `#[static_assert]` functionality is experimental and
+                    unstable. The attribute can be attached to a `static` of
+                    type `bool` and the compiler will error if the `bool` is
+                    `false` at compile time. This version of this functionality
+                    is unintuitive and suboptimal.
+
 * `start` - Allows use of the `#[start]` attribute, which changes the entry point
             into a Rust program. This capabiilty, especially the signature for the
             annotated function, is subject to change.
@@ -2518,6 +2498,14 @@ The currently implemented features of the reference compiler are:
                             types, e.g. as the return type of a public function.
                             This capability may be removed in the future.
 
+* `allow_internal_unstable` - Allows `macro_rules!` macros to be tagged with the
+                              `#[allow_internal_unstable]` attribute, designed
+                              to allow `std` macros to call
+                              `#[unstable]`/feature-gated functionality
+                              internally without imposing on callers
+                              (i.e. making them behave like function calls in
+                              terms of encapsulation).
+
 If a feature is promoted to a language feature, then all existing programs will
 start to receive compilation warnings about #[feature] directives which enabled
 the new feature (because the directive is no longer necessary). However, if a
@@ -2706,7 +2694,7 @@ The following are examples of structure expressions:
 ```
 # struct Point { x: f64, y: f64 }
 # struct TuplePoint(f64, f64);
-# mod game { pub struct User<'a> { pub name: &'a str, pub age: u32, pub score: uint } }
+# mod game { pub struct User<'a> { pub name: &'a str, pub age: u32, pub score: usize } }
 # struct Cookie; fn some_fn<T>(t: T) {}
 Point {x: 10.0, y: 20.0};
 TuplePoint(10.0, 20.0);
@@ -2798,7 +2786,7 @@ automatically dereferenced to make the field access possible.
 ### Array expressions
 
 ```{.ebnf .gram}
-array_expr : '[' "mut" ? vec_elems? ']' ;
+array_expr : '[' "mut" ? array_elems? ']' ;
 
 array_elems : [expr [',' expr]*] | [expr ';' expr] ;
 ```
@@ -2908,10 +2896,10 @@ meaning of the operators on standard types is given here.
   : Exclusive or.
     Calls the `bitxor` method of the `std::ops::BitXor` trait.
 * `<<`
-  : Logical left shift.
+  : Left shift.
     Calls the `shl` method of the `std::ops::Shl` trait.
 * `>>`
-  : Logical right shift.
+  : Right shift.
     Calls the `shr` method of the `std::ops::Shr` trait.
 
 #### Lazy boolean operators
@@ -2958,10 +2946,6 @@ A type cast expression is denoted with the binary operator `as`.
 Executing an `as` expression casts the value on the left-hand side to the type
 on the right-hand side.
 
-A numeric value can be cast to any numeric type. A raw pointer value can be
-cast to or from any integral type or raw pointer type. Any other cast is
-unsupported and will fail to compile.
-
 An example of an `as` expression:
 
 ```
@@ -3111,7 +3095,7 @@ ten_times(|j| println!("hello, {}", j));
 ### While loops
 
 ```{.ebnf .gram}
-while_expr : "while" no_struct_literal_expr '{' block '}' ;
+while_expr : [ lifetime ':' ] "while" no_struct_literal_expr '{' block '}' ;
 ```
 
 A `while` loop begins by evaluating the boolean loop conditional expression.
@@ -3176,7 +3160,7 @@ A `continue` expression is only permitted in the body of a loop.
 ### For expressions
 
 ```{.ebnf .gram}
-for_expr : "for" pat "in" no_struct_literal_expr '{' block '}' ;
+for_expr : [ lifetime ':' ] "for" pat "in" no_struct_literal_expr '{' block '}' ;
 ```
 
 A `for` expression is a syntactic construct for looping over elements provided
@@ -3280,7 +3264,7 @@ array, like `[.., 42, ..]`. If preceded by a variable name, it will bind the
 corresponding slice to the variable. Example:
 
 ```
-# #![feature(advanced_slice_patterns)]
+# #![feature(advanced_slice_patterns, slice_patterns)]
 fn is_symmetric(list: &[u32]) -> bool {
     match list {
         [] | [_]                   => true,
@@ -3353,7 +3337,7 @@ subpattern`. For example:
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
-enum List { Nil, Cons(uint, Box<List>) }
+enum List { Nil, Cons(u32, Box<List>) }
 
 fn is_sorted(list: &List) -> bool {
     match *list {
@@ -3554,7 +3538,8 @@ Tuple types and values are denoted by listing the types or values of their
 elements, respectively, in a parenthesized, comma-separated list.
 
 Because tuple elements don't have a name, they can only be accessed by
-pattern-matching.
+pattern-matching or by using `N` directly as a field to access the
+`N`th element.
 
 An example of a tuple type and its use:
 
@@ -3563,6 +3548,7 @@ type Pair<'a> = (i32, &'a str);
 let p: Pair<'static> = (10, "hello");
 let (a, b) = p;
 assert!(b != "world");
+assert!(p.0 == 10);
 ```
 
 ### Array, and Slice types
@@ -3740,9 +3726,9 @@ An example of creating and calling a closure:
 ```rust
 let captured_var = 10;
 
-let closure_no_args = |&:| println!("captured_var={}", captured_var);
+let closure_no_args = || println!("captured_var={}", captured_var);
 
-let closure_args = |&: arg: i32| -> i32 {
+let closure_args = |arg: i32| -> i32 {
   println!("captured_var={}, arg={}", captured_var, arg);
   arg // Note lack of semicolon after 'arg'
 };
@@ -3835,75 +3821,27 @@ impl Printable for String {
 `self` refers to the value of type `String` that is the receiver for a call to
 the method `make_string`.
 
-## Type kinds
-
-Types in Rust are categorized into kinds, based on various properties of the
-components of the type. The kinds are:
-
-* `Send`
-  : Types of this kind can be safely sent between threads.
-    This kind includes scalars, boxes, procs, and
-    structural types containing only other owned types.
-    All `Send` types are `'static`.
-* `Copy`
-  : Types of this kind consist of "Plain Old Data"
-    which can be copied by simply moving bits.
-    All values of this kind can be implicitly copied.
-    This kind includes scalars and immutable references,
-    as well as structural types containing other `Copy` types.
-* `'static`
-  : Types of this kind do not contain any references (except for
-    references with the `static` lifetime, which are allowed).
-    This can be a useful guarantee for code
-    that breaks borrowing assumptions
-    using [`unsafe` operations](#unsafe-functions).
-* `Drop`
-  : This is not strictly a kind,
-    but its presence interacts with kinds:
-    the `Drop` trait provides a single method `drop`
-    that takes no parameters,
-    and is run when values of the type are dropped.
-    Such a method is called a "destructor",
-    and are always executed in "top-down" order:
-    a value is completely destroyed
-    before any of the values it owns run their destructors.
-    Only `Send` types can implement `Drop`.
-
-* _Default_
-  : Types with destructors, closure environments,
-    and various other _non-first-class_ types,
-    are not copyable at all.
-    Such types can usually only be accessed through pointers,
-    or in some cases, moved between mutable locations.
-
-Kinds can be supplied as _bounds_ on type parameters, like traits, in which
-case the parameter is constrained to types satisfying that kind.
-
-By default, type parameters do not carry any assumed kind-bounds at all. When
-instantiating a type parameter, the kind bounds on the parameter are checked to
-be the same or narrower than the kind of the type that it is instantiated with.
-
-Sending operations are not part of the Rust language, but are implemented in
-the library. Generic functions that send values bound the kind of these values
-to sendable.
-
-# Memory and concurrency models
-
-Rust has a memory model centered around concurrently-executing _threads_. Thus
-its memory model and its concurrency model are best discussed simultaneously,
-as parts of each only make sense when considered from the perspective of the
-other.
-
-When reading about the memory model, keep in mind that it is partitioned in
-order to support threads; and when reading about threads, keep in mind that their
-isolation and communication mechanisms are only possible due to the ownership
-and lifetime semantics of the memory model.
-
-## Memory model
-
-A Rust program's memory consists of a static set of *items*, a set of
-[threads](#threads) each with its own *stack*, and a *heap*. Immutable portions of
-the heap may be shared between threads, mutable portions may not.
+# The `Copy` trait
+
+Rust has a special trait, `Copy`, which when implemented changes the semantics
+of a value. Values whose type implements `Copy` are copied rather than moved
+upon assignment.
+
+# The `Sized` trait
+
+`Sized` is a special trait which indicates that the size of this type is known
+at compile-time.
+
+# The `Drop` trait
+
+The `Drop` trait provides a destructor, to be run whenever a value of this type
+is to be destroyed.
+
+# Memory model
+
+A Rust program's memory consists of a static set of *items* and a *heap*.
+Immutable portions of the heap may be shared between threads, mutable portions
+may not.
 
 Allocations in the stack consist of *slots*, and allocations in the heap
 consist of *boxes*.
@@ -3914,10 +3852,6 @@ The _items_ of a program are those functions, modules and types that have their
 value calculated at compile-time and stored uniquely in the memory image of the
 rust process. Items are neither dynamically allocated nor freed.
 
-A thread's _stack_ consists of activation frames automatically allocated on entry
-to each function as the thread executes. A stack allocation is reclaimed when
-control leaves the frame containing it.
-
 The _heap_ is a general term that describes boxes.  The lifetime of an
 allocation in the heap depends on the lifetime of the box values pointing to
 it. Since box values may themselves be passed in and out of frames, or stored
@@ -3925,25 +3859,11 @@ in the heap, heap allocations may outlive the frame they are allocated within.
 
 ### Memory ownership
 
-A thread owns all memory it can *safely* reach through local variables, as well
-as boxes and references.
-
-When a thread sends a value that has the `Send` trait to another thread, it loses
-ownership of the value sent and can no longer refer to it. This is statically
-guaranteed by the combined use of "move semantics", and the compiler-checked
-_meaning_ of the `Send` trait: it is only instantiated for (transitively)
-sendable kinds of data constructor and pointers, never including references.
-
 When a stack frame is exited, its local allocations are all released, and its
 references to boxes are dropped.
 
-When a thread finishes, its stack is necessarily empty and it therefore has no
-references to any boxes; the remainder of its heap is immediately freed.
-
 ### Memory slots
 
-A thread's stack contains slots.
-
 A _slot_ is a component of a stack frame, either a function parameter, a
 [temporary](#lvalues,-rvalues-and-temporaries), or a local variable.
 
@@ -3973,86 +3893,6 @@ state. Subsequent statements within a function may or may not initialize the
 local variables. Local variables can be used only after they have been
 initialized; this is enforced by the compiler.
 
-### Boxes
-
-A _box_ is a reference to a heap allocation holding another value, which is
-constructed by the prefix operator `box`. When the standard library is in use,
-the type of a box is `std::owned::Box<T>`.
-
-An example of a box type and value:
-
-```
-let x: Box<i32> = Box::new(10);
-```
-
-Box values exist in 1:1 correspondence with their heap allocation, copying a
-box value makes a shallow copy of the pointer. Rust will consider a shallow
-copy of a box to move ownership of the value. After a value has been moved,
-the source location cannot be used unless it is reinitialized.
-
-```
-let x: Box<i32> = Box::new(10);
-let y = x;
-// attempting to use `x` will result in an error here
-```
-
-## Threads
-
-Rust's primary concurrency mechanism is called a **thread**.
-
-### Communication between threads
-
-Rust threads are isolated and generally unable to interfere with one another's
-memory directly, except through [`unsafe` code](#unsafe-functions).  All
-contact between threads is mediated by safe forms of ownership transfer, and data
-races on memory are prohibited by the type system.
-
-When you wish to send data between threads, the values are restricted to the
-[`Send` type-kind](#type-kinds). Restricting communication interfaces to this
-kind ensures that no references move between threads. Thus access to an entire
-data structure can be mediated through its owning "root" value; no further
-locking or copying is required to avoid data races within the substructure of
-such a value.
-
-### Thread
-
-The _lifecycle_ of a threads consists of a finite set of states and events that
-cause transitions between the states. The lifecycle states of a thread are:
-
-* running
-* blocked
-* panicked
-* dead
-
-A thread begins its lifecycle &mdash; once it has been spawned &mdash; in the
-*running* state. In this state it executes the statements of its entry
-function, and any functions called by the entry function.
-
-A thread may transition from the *running* state to the *blocked* state any time
-it makes a blocking communication call. When the call can be completed &mdash;
-when a message arrives at a sender, or a buffer opens to receive a message
-&mdash; then the blocked thread will unblock and transition back to *running*.
-
-A thread may transition to the *panicked* state at any time, due being killed by
-some external event or internally, from the evaluation of a `panic!()` macro.
-Once *panicking*, a thread unwinds its stack and transitions to the *dead* state.
-Unwinding the stack of a thread is done by the thread itself, on its own control
-stack. If a value with a destructor is freed during unwinding, the code for the
-destructor is run, also on the thread's control stack. Running the destructor
-code causes a temporary transition to a *running* state, and allows the
-destructor code to cause any subsequent state transitions. The original thread
-of unwinding and panicking thereby may suspend temporarily, and may involve
-(recursive) unwinding of the stack of a failed destructor. Nonetheless, the
-outermost unwinding activity will continue until the stack is unwound and the
-thread transitions to the *dead* state. There is no way to "recover" from thread
-panics. Once a thread has temporarily suspended its unwinding in the *panicking*
-state, a panic occurring from within this destructor results in *hard* panic.
-A hard panic currently results in the process aborting.
-
-A thread in the *dead* state cannot transition to other states; it exists only to
-have its termination status inspected by other threads, and/or to await
-reclamation when the last reference to it drops.
-
 # Runtime services, linkage and debugging
 
 The Rust _runtime_ is a relatively compact collection of Rust code that
index c2a25cd7a584ec39c85978737dc0e3c3770c2339..cd158283180a268381a35370837bd968f7753ed8 100644 (file)
@@ -56,6 +56,7 @@
 /* General structure */
 
 body {
+    background-color: white;
     margin: 0 auto;
     padding: 0 15px;
     font-family: "Source Serif Pro", Georgia, Times, "Times New Roman", serif;
index 33f1e82b187e7ddb6ee68fa2465e131e16a0435e..d2fcf27e93cdf540627bf9e2c2e1255183493882 100644 (file)
@@ -22,9 +22,9 @@ fn write_info(info: &Info) -> Result<(), IoError> {
     let mut file = File::open_mode(&Path::new("my_best_friends.txt"),
                                    Open, Write);
     // Early return on error
-    try!(file.write_line(format!("name: {}", info.name).as_slice()));
-    try!(file.write_line(format!("age: {}", info.age).as_slice()));
-    try!(file.write_line(format!("rating: {}", info.rating).as_slice()));
+    try!(file.write_line(&format!("name: {}", info.name)));
+    try!(file.write_line(&format!("age: {}", info.age)));
+    try!(file.write_line(&format!("rating: {}", info.rating)));
     return Ok(());
 }
 ```
@@ -44,15 +44,15 @@ fn write_info(info: &Info) -> Result<(), IoError> {
     let mut file = File::open_mode(&Path::new("my_best_friends.txt"),
                                    Open, Write);
     // Early return on error
-    match file.write_line(format!("name: {}", info.name).as_slice()) {
+    match file.write_line(&format!("name: {}", info.name)) {
         Ok(_) => (),
         Err(e) => return Err(e)
     }
-    match file.write_line(format!("age: {}", info.age).as_slice()) {
+    match file.write_line(&format!("age: {}", info.age)) {
         Ok(_) => (),
         Err(e) => return Err(e)
     }
-    return file.write_line(format!("rating: {}", info.rating).as_slice());
+    return file.write_line(&format!("rating: {}", info.rating));
 }
 ```
 
index eb9e2b24ac900e0d7f1090cc7697c057111bec19..4a866d6224d5d134b01120deaac0b4ef4abb74d6 100644 (file)
@@ -11,8 +11,7 @@ navigate through the menu on the left.
 <h2 class="section-header"><a href="basic.html">Basics</a></h2>
 
 This section is a linear introduction to the basic syntax and semantics of
-Rust. It has individual sections on each part of Rust's syntax, and culminates
-in a small project: a guessing game.
+Rust. It has individual sections on each part of Rust's syntax.
 
 After reading "Basics," you will have a good foundation to learn more about
 Rust, and can write very simple programs.
@@ -29,7 +28,12 @@ and will be able to understand most Rust code and write more complex programs.
 
 In a similar fashion to "Intermediate," this section is full of individual,
 deep-dive chapters, which stand alone and can be read in any order. These
-chapters focus on the most complex features, as well as some things that
-are only available in upcoming versions of Rust.
+chapters focus on the most complex features,
 
-After reading "Advanced," you'll be a Rust expert!
+<h2 class="section-header"><a href="unstable.html">Unstable</a></h2>
+
+In a similar fashion to "Intermediate," this section is full of individual,
+deep-dive chapters, which stand alone and can be read in any order.
+
+This chapter contains things that are only available on the nightly channel of
+Rust.
index d57aff7f4f411fbc9974666127a02150b324301d..11e62aff42f3fd6132c1d4df5280aaa74a134ba2 100644 (file)
@@ -1,6 +1,6 @@
 # Summary
 
-* [I: The Basics](basic.md)
+* [The Basics](basic.md)
     * [Installing Rust](installing-rust.md)
     * [Hello, world!](hello-world.md)
     * [Hello, Cargo!](hello-cargo.md)
     * [Looping](looping.md)
     * [Strings](strings.md)
     * [Arrays, Vectors, and Slices](arrays-vectors-and-slices.md)
-    * [Standard Input](standard-input.md)
-    * [Guessing Game](guessing-game.md)
-* [II: Intermediate Rust](intermediate.md)
-    * [More Strings](more-strings.md)
+* [Intermediate Rust](intermediate.md)
     * [Crates and Modules](crates-and-modules.md)
     * [Testing](testing.md)
     * [Pointers](pointers.md)
     * [Ownership](ownership.md)
+    * [More Strings](more-strings.md)
     * [Patterns](patterns.md)
     * [Method Syntax](method-syntax.md)
+    * [Associated Types](associated-types.md)
     * [Closures](closures.md)
     * [Iterators](iterators.md)
     * [Generics](generics.md)
     * [Concurrency](concurrency.md)
     * [Error Handling](error-handling.md)
     * [Documentation](documentation.md)
-* [III: Advanced Topics](advanced.md)
+* [Advanced Topics](advanced.md)
     * [FFI](ffi.md)
     * [Unsafe Code](unsafe.md)
     * [Advanced Macros](advanced-macros.md)
+* [Unstable Rust](unstable.md)
     * [Compiler Plugins](plugins.md)
+    * [Inline Assembly](inline-assembly.md)
+    * [No stdlib](no-stdlib.md)
+    * [Intrinsics](intrinsics.md)
+    * [Lang items](lang-items.md)
+    * [Link args](link-args.md)
+    * [Benchmark Tests](benchmark-tests.md)
+    * [Box Syntax and Patterns](box-syntax-and-patterns.md)
 * [Conclusion](conclusion.md)
 * [Glossary](glossary.md)
index aff365051a4eadfc67819f0e9c45487abd1b70ad..fef458caaaf3343a1aa2e198888d005bc2ba8221 100644 (file)
@@ -6,9 +6,11 @@ off.
 # Syntactic requirements
 
 Even when Rust code contains un-expanded macros, it can be parsed as a full
-syntax tree. This property can be very useful for editors and other tools that
-process code. It also has a few consequences for the design of Rust's macro
-system.
+[syntax tree][ast]. This property can be very useful for editors and other
+tools that process code. It also has a few consequences for the design of
+Rust's macro system.
+
+[ast]: glossary.html#abstract-syntax-tree
 
 One consequence is that Rust must determine, when it parses a macro invocation,
 whether the macro stands in for
@@ -192,19 +194,49 @@ To keep this system simple and correct, `#[macro_use] extern crate ...` may
 only appear at the root of your crate, not inside `mod`. This ensures that
 `$crate` is a single identifier.
 
-# A final note
+# The deep end
+
+The introductory chapter mentioned recursive macros, but it did not give the
+full story. Recursive macros are useful for another reason: Each recursive
+invocation gives you another opportunity to pattern-match the macro's
+arguments.
+
+As an extreme example, it is possible, though hardly advisable, to implement
+the [Bitwise Cyclic Tag](http://esolangs.org/wiki/Bitwise_Cyclic_Tag) automaton
+within Rust's macro system.
+
+```rust
+macro_rules! bct {
+    // cmd 0:  d ... => ...
+    (0, $($ps:tt),* ; $_d:tt)
+        => (bct!($($ps),*, 0 ; ));
+    (0, $($ps:tt),* ; $_d:tt, $($ds:tt),*)
+        => (bct!($($ps),*, 0 ; $($ds),*));
+
+    // cmd 1p:  1 ... => 1 ... p
+    (1, $p:tt, $($ps:tt),* ; 1)
+        => (bct!($($ps),*, 1, $p ; 1, $p));
+    (1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*)
+        => (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p));
+
+    // cmd 1p:  0 ... => 0 ...
+    (1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
+        => (bct!($($ps),*, 1, $p ; $($ds),*));
+
+    // halt on empty data string
+    ( $($ps:tt),* ; )
+        => (());
+}
+```
+
+Exercise: use macros to reduce duplication in the above definition of the
+`bct!` macro.
 
-Macros, as currently implemented, are not for the faint of heart. Even
-ordinary syntax errors can be more difficult to debug when they occur inside a
-macro, and errors caused by parse problems in generated code can be very
-tricky. Invoking the `log_syntax!` macro can help elucidate intermediate
-states, invoking `trace_macros!(true)` will automatically print those
-intermediate states out, and passing the flag `--pretty expanded` as a
-command-line argument to the compiler will show the result of expansion.
+# Procedural macros
 
 If Rust's macro system can't do what you need, you may want to write a
 [compiler plugin](plugins.html) instead. Compared to `macro_rules!`
 macros, this is significantly more work, the interfaces are much less stable,
-and the warnings about debugging apply ten-fold. In exchange you get the
+and bugs can be much harder to track down. In exchange you get the
 flexibility of running arbitrary Rust code within the compiler. Syntax
 extension plugins are sometimes called *procedural macros* for this reason.
index d4e2ad5cd5f66fa7973a0214b130afa660a411aa..2916dca2c06b01ac863415456de556f289ca44a5 100644 (file)
@@ -49,7 +49,7 @@ languages.
 
 A *vector* is a dynamic or "growable" array, implemented as the standard
 library type [`Vec<T>`](../std/vec/) (we'll talk about what the `<T>` means
-later). Vectors always allocate their data on the heap. Vectors are to slices 
+later). Vectors always allocate their data on the heap. Vectors are to slices
 what `String` is to `&str`. You can create them with the `vec!` macro:
 
 ```{rust}
@@ -60,6 +60,12 @@ let v = vec![1, 2, 3]; // v: Vec<i32>
 brackets `[]` with `vec!`. Rust allows you to use either in either situation,
 this is just convention.)
 
+There's an alternate form of `vec!` for repeating an initial value:
+
+```
+let v = vec![0; 10]; // ten zeroes
+```
+
 You can get the length of, iterate over, and subscript vectors just like
 arrays. In addition, (mutable) vectors can grow automatically:
 
@@ -93,7 +99,4 @@ You can also take a slice of a vector, `String`, or `&str`, because they are
 backed by arrays. Slices have type `&[T]`, which we'll talk about when we cover
 generics.
 
-We have now learned all of the most basic Rust concepts. We're ready to start
-building ourselves a guessing game, we just need to know one last thing: how to
-get input from the keyboard. You can't have a guessing game without the ability
-to guess!
+We have now learned all of the most basic Rust concepts.
diff --git a/src/doc/trpl/associated-types.md b/src/doc/trpl/associated-types.md
new file mode 100644 (file)
index 0000000..7161cd3
--- /dev/null
@@ -0,0 +1,202 @@
+% Associated Types
+
+Associated types are a powerful part of Rust's type system. They're related to
+the idea of a 'type family', in other words, grouping multiple types together. That
+description is a bit abstract, so let's dive right into an example. If you want
+to write a `Graph` trait, you have two types to be generic over: the node type
+and the edge type. So you might write a trait, `Graph<N, E>`, that looks like
+this:
+
+```rust
+trait Graph<N, E> {
+    fn has_edge(&self, &N, &N) -> bool;
+    fn edges(&self, &N) -> Vec<E>;
+    // etc
+}
+```
+
+While this sort of works, it ends up being awkward. For example, any function
+that wants to take a `Graph` as a parameter now _also_ needs to be generic over
+the `N`ode and `E`dge types too:
+
+```rust,ignore
+fn distance<N, E, G: Graph<N, E>>(graph: &G, start: &N, end: &N) -> u32 { ... }
+```
+
+Our distance calculation works regardless of our `Edge` type, so the `E` stuff in
+this signature is just a distraction.
+
+What we really want to say is that a certain `E`dge and `N`ode type come together
+to form each kind of `Graph`. We can do that with associated types:
+
+```rust
+trait Graph {
+    type N;
+    type E;
+
+    fn has_edge(&self, &Self::N, &Self::N) -> bool;
+    fn edges(&self, &Self::N) -> Vec<Self::E>;
+    // etc
+}
+```
+
+Now, our clients can be abstract over a given `Graph`:
+
+```rust,ignore
+fn distance<G: Graph>(graph: &G, start: &G::N, end: &G::N) -> uint { ... }
+```
+
+No need to deal with the `E`dge type here!
+
+Let's go over all this in more detail.
+
+## Defining associated types
+
+Let's build that `Graph` trait. Here's the definition:
+
+```rust
+trait Graph {
+    type N;
+    type E;
+
+    fn has_edge(&self, &Self::N, &Self::N) -> bool;
+    fn edges(&self, &Self::N) -> Vec<Self::E>;
+}
+```
+
+Simple enough. Associated types use the `type` keyword, and go inside the body
+of the trait, with the functions.
+
+These `type` declarations can have all the same thing as functions do. For example,
+if we wanted our `N` type to implement `Display`, so we can print the nodes out,
+we could do this:
+
+```rust
+use std::fmt;
+
+trait Graph {
+    type N: fmt::Display;
+    type E;
+
+    fn has_edge(&self, &Self::N, &Self::N) -> bool;
+    fn edges(&self, &Self::N) -> Vec<Self::E>;
+}
+```
+
+## Implementing associated types
+
+Just like any trait, traits that use associated types use the `impl` keyword to
+provide implementations. Here's a simple implementation of Graph:
+
+```rust
+# trait Graph {
+#     type N;
+#     type E;
+#     fn has_edge(&self, &Self::N, &Self::N) -> bool;
+#     fn edges(&self, &Self::N) -> Vec<Self::E>;
+# }
+struct Node;
+
+struct Edge;
+
+struct MyGraph;
+
+impl Graph for MyGraph {
+    type N = Node;
+    type E = Edge;
+
+    fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
+        true
+    }
+
+    fn edges(&self, n: &Node) -> Vec<Edge> {
+        Vec::new()
+    }
+}
+```
+
+This silly implementation always returns `true` and an empty `Vec<Edge>`, but it
+gives you an idea of how to implement this kind of thing. We first need three
+`struct`s, one for the graph, one for the node, and one for the edge. If it made
+more sense to use a different type, that would work as well, we're just going to
+use `struct`s for all three here.
+
+Next is the `impl` line, which is just like implementing any other trait.
+
+From here, we use `=` to define our associated types. The name the trait uses
+goes on the left of the `=`, and the concrete type we're `impl`ementing this
+for goes on the right. Finally, we use the concrete types in our function
+declarations.
+
+## Trait objects with associated types
+
+There’s one more bit of syntax we should talk about: trait objects. If you
+try to create a trait object from an associated type, like this:
+
+```rust,ignore
+# trait Graph {
+#     type N;
+#     type E;
+#     fn has_edge(&self, &Self::N, &Self::N) -> bool;
+#     fn edges(&self, &Self::N) -> Vec<Self::E>;
+# }
+# struct Node;
+# struct Edge;
+# struct MyGraph;
+# impl Graph for MyGraph {
+#     type N = Node;
+#     type E = Edge;
+#     fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
+#         true
+#     }
+#     fn edges(&self, n: &Node) -> Vec<Edge> {
+#         Vec::new()
+#     }
+# }
+let graph = MyGraph;
+let obj = Box::new(graph) as Box<Graph>;
+```
+
+You’ll get two errors:
+
+```text
+error: the value of the associated type `E` (from the trait `main::Graph`) must
+be specified [E0191]
+let obj = Box::new(graph) as Box<Graph>;
+          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+24:44 error: the value of the associated type `N` (from the trait
+`main::Graph`) must be specified [E0191]
+let obj = Box::new(graph) as Box<Graph>;
+          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+```
+
+We can’t create a trait object like this, because we don’t know the associated
+types. Instead, we can write this:
+
+```rust
+# trait Graph {
+#     type N;
+#     type E;
+#     fn has_edge(&self, &Self::N, &Self::N) -> bool;
+#     fn edges(&self, &Self::N) -> Vec<Self::E>;
+# }
+# struct Node;
+# struct Edge;
+# struct MyGraph;
+# impl Graph for MyGraph {
+#     type N = Node;
+#     type E = Edge;
+#     fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
+#         true
+#     }
+#     fn edges(&self, n: &Node) -> Vec<Edge> {
+#         Vec::new()
+#     }
+# }
+let graph = MyGraph;
+let obj = Box::new(graph) as Box<Graph<N=Node, E=Edge>>;
+```
+
+The `N=Node` syntax allows us to provide a concrete type, `Node`, for the `N`
+type parameter. Same with `E=Edge`. If we didn’t proide this constraint, we
+couldn’t be sure which `impl` to match this trait object to.
index 087121d0e7dc3d30e35240165ff9090bd7fcd452..c267830e6e0d0c5e0fc700713abb67ad205ef7d4 100644 (file)
@@ -1,8 +1,7 @@
 % Basics
 
 This section is a linear introduction to the basic syntax and semantics of
-Rust. It has individual sections on each part of Rust's syntax, and cumulates
-in a small project: a guessing game.
+Rust. It has individual sections on each part of Rust's syntax.
 
 After reading "Basics," you will have a good foundation to learn more about
 Rust, and can write very simple programs.
diff --git a/src/doc/trpl/benchmark-tests.md b/src/doc/trpl/benchmark-tests.md
new file mode 100644 (file)
index 0000000..8879653
--- /dev/null
@@ -0,0 +1,152 @@
+% Benchmark tests
+
+Rust supports benchmark tests, which can test the performance of your
+code. Let's make our `src/lib.rs` look like this (comments elided):
+
+```{rust,ignore}
+#![feature(test)]
+
+extern crate test;
+
+pub fn add_two(a: i32) -> i32 {
+    a + 2
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use test::Bencher;
+
+    #[test]
+    fn it_works() {
+        assert_eq!(4, add_two(2));
+    }
+
+    #[bench]
+    fn bench_add_two(b: &mut Bencher) {
+        b.iter(|| add_two(2));
+    }
+}
+```
+
+Note the `test` feature gate, which enables this unstable feature.
+
+We've imported the `test` crate, which contains our benchmarking support.
+We have a new function as well, with the `bench` attribute. Unlike regular
+tests, which take no arguments, benchmark tests take a `&mut Bencher`. This
+`Bencher` provides an `iter` method, which takes a closure. This closure
+contains the code we'd like to benchmark.
+
+We can run benchmark tests with `cargo bench`:
+
+```bash
+$ cargo bench
+   Compiling adder v0.0.1 (file:///home/steve/tmp/adder)
+     Running target/release/adder-91b3e234d4ed382a
+
+running 2 tests
+test tests::it_works ... ignored
+test tests::bench_add_two ... bench:         1 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 1 ignored; 1 measured
+```
+
+Our non-benchmark test was ignored. You may have noticed that `cargo bench`
+takes a bit longer than `cargo test`. This is because Rust runs our benchmark
+a number of times, and then takes the average. Because we're doing so little
+work in this example, we have a `1 ns/iter (+/- 0)`, but this would show
+the variance if there was one.
+
+Advice on writing benchmarks:
+
+
+* Move setup code outside the `iter` loop; only put the part you want to measure inside
+* Make the code do "the same thing" on each iteration; do not accumulate or change state
+* Make the outer function idempotent too; the benchmark runner is likely to run
+  it many times
+*  Make the inner `iter` loop short and fast so benchmark runs are fast and the
+   calibrator can adjust the run-length at fine resolution
+* Make the code in the `iter` loop do something simple, to assist in pinpointing
+  performance improvements (or regressions)
+
+## Gotcha: optimizations
+
+There's another tricky part to writing benchmarks: benchmarks compiled with
+optimizations activated can be dramatically changed by the optimizer so that
+the benchmark is no longer benchmarking what one expects. For example, the
+compiler might recognize that some calculation has no external effects and
+remove it entirely.
+
+```{rust,ignore}
+#![feature(test)]
+
+extern crate test;
+use test::Bencher;
+
+#[bench]
+fn bench_xor_1000_ints(b: &mut Bencher) {
+    b.iter(|| {
+        (0..1000).fold(0, |old, new| old ^ new);
+    });
+}
+```
+
+gives the following results
+
+```text
+running 1 test
+test bench_xor_1000_ints ... bench:         0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+```
+
+The benchmarking runner offers two ways to avoid this. Either, the closure that
+the `iter` method receives can return an arbitrary value which forces the
+optimizer to consider the result used and ensures it cannot remove the
+computation entirely. This could be done for the example above by adjusting the
+`b.iter` call to
+
+```rust
+# struct X;
+# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
+b.iter(|| {
+    // note lack of `;` (could also use an explicit `return`).
+    (0..1000).fold(0, |old, new| old ^ new)
+});
+```
+
+Or, the other option is to call the generic `test::black_box` function, which
+is an opaque "black box" to the optimizer and so forces it to consider any
+argument as used.
+
+```rust
+#![feature(test)]
+
+extern crate test;
+
+# fn main() {
+# struct X;
+# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
+b.iter(|| {
+    let n = test::black_box(1000);
+
+    (0..n).fold(0, |a, b| a ^ b)
+})
+# }
+```
+
+Neither of these read or modify the value, and are very cheap for small values.
+Larger values can be passed indirectly to reduce overhead (e.g.
+`black_box(&huge_struct)`).
+
+Performing either of the above changes gives the following benchmarking results
+
+```text
+running 1 test
+test bench_xor_1000_ints ... bench:       131 ns/iter (+/- 3)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+```
+
+However, the optimizer can still modify a testcase in an undesirable manner
+even when using either of the above.
diff --git a/src/doc/trpl/box-syntax-and-patterns.md b/src/doc/trpl/box-syntax-and-patterns.md
new file mode 100644 (file)
index 0000000..839f07d
--- /dev/null
@@ -0,0 +1,100 @@
+%  Box Syntax and Patterns
+
+Currently the only stable way to create a `Box` is via the `Box::new` method.
+Also it is not possible in stable Rust to destructure a `Box` in a match
+pattern. The unstable `box` keyword can be used to both create and destructure
+a `Box`. An example usage would be:
+
+```
+#![feature(box_syntax, box_patterns)]
+
+fn main() {
+    let b = Some(box 5);
+    match b {
+        Some(box n) if n < 0 => {
+            println!("Box contains negative number {}", n);
+        },
+        Some(box n) if n >= 0 => {
+            println!("Box contains non-negative number {}", n);
+        },
+        None => {
+            println!("No box");
+        },
+        _ => unreachable!()
+    }
+}
+```
+
+Note that these features are currently hidden behind the `box_syntax` (box
+creation) and `box_patterns` (destructuring and pattern matching) gates
+because the syntax may still change in the future.
+
+# Returning Pointers
+
+In many languages with pointers, you'd return a pointer from a function
+so as to avoid copying a large data structure. For example:
+
+```{rust}
+struct BigStruct {
+    one: i32,
+    two: i32,
+    // etc
+    one_hundred: i32,
+}
+
+fn foo(x: Box<BigStruct>) -> Box<BigStruct> {
+    Box::new(*x)
+}
+
+fn main() {
+    let x = Box::new(BigStruct {
+        one: 1,
+        two: 2,
+        one_hundred: 100,
+    });
+
+    let y = foo(x);
+}
+```
+
+The idea is that by passing around a box, you're only copying a pointer, rather
+than the hundred `int`s that make up the `BigStruct`.
+
+This is an antipattern in Rust. Instead, write this:
+
+```rust
+#![feature(box_syntax)]
+
+struct BigStruct {
+    one: i32,
+    two: i32,
+    // etc
+    one_hundred: i32,
+}
+
+fn foo(x: Box<BigStruct>) -> BigStruct {
+    *x
+}
+
+fn main() {
+    let x = Box::new(BigStruct {
+        one: 1,
+        two: 2,
+        one_hundred: 100,
+    });
+
+    let y: Box<BigStruct> = box foo(x);
+}
+```
+
+This gives you flexibility without sacrificing performance.
+
+You may think that this gives us terrible performance: return a value and then
+immediately box it up ?! Isn't this pattern the worst of both worlds? Rust is
+smarter than that. There is no copy in this code. `main` allocates enough room
+for the `box`, passes a pointer to that memory into `foo` as `x`, and then
+`foo` writes the value straight into the `Box<T>`.
+
+This is important enough that it bears repeating: pointers are not for
+optimizing returning values from your code. Allow the caller to choose how they
+want to use your output.
index 8cc6be7387ca1ee1e1bc78022d2b9d4ab64abba0..01b8163ffd372b89c75843e419dcc9bc968546e8 100644 (file)
 % Closures
 
-So far, we've made lots of functions in Rust, but we've given them all names.
-Rust also allows us to create anonymous functions. Rust's anonymous
-functions are called *closures*. By themselves, closures aren't all that
-interesting, but when you combine them with functions that take closures as
-arguments, really powerful things are possible.
+Rust not only has named functions, but anonymous functions as well. Anonymous
+functions that have an associated environment are called 'closures', because they
+close over an environment. Rust has a really great implementation of them, as
+we'll see.
 
-Let's make a closure:
+# Syntax
 
-```{rust}
-let add_one = |x| { 1 + x };
+Closures look like this:
 
-println!("The sum of 5 plus 1 is {}.", add_one(5));
+```rust
+let plus_one = |x: i32| x + 1;
+
+assert_eq!(2, plus_one(1));
+```
+
+We create a binding, `plus_one`, and assign it to a closure. The closure's
+arguments go between the pipes (`|`), and the body is an expression, in this
+case, `x + 1`. Remember that `{ }` is an expression, so we can have multi-line
+closures too:
+
+```rust
+let plus_two = |x| {
+    let mut result: i32 = x;
+
+    result += 1;
+    result += 1;
+
+    result
+};
+
+assert_eq!(4, plus_two(2));
+```
+
+You'll notice a few things about closures that are a bit different than regular
+functions defined with `fn`. The first of which is that we did not need to
+annotate the types of arguments the closure takes or the values it returns. We
+can:
+
+```rust
+let plus_one = |x: i32| -> i32 { x + 1 };
+
+assert_eq!(2, plus_one(1));
+```
+
+But we don't have to. Why is this? Basically, it was chosen for ergonomic reasons.
+While specifying the full type for named functions is helpful with things like
+documentation and type inference, the types of closures are rarely documented
+since they’re anonymous, and they don’t cause the kinds of error-at-a-distance
+that inferring named function types can.
+
+The second is that the syntax is similar, but a bit different. I've added spaces
+here to make them look a little closer:
+
+```rust
+fn  plus_one_v1 (  x: i32 ) -> i32 { x + 1 }
+let plus_one_v2 = |x: i32 | -> i32 { x + 1 };
+let plus_one_v3 = |x: i32 |          x + 1  ;
 ```
 
-We create a closure using the `|...| { ... }` syntax, and then we create a
-binding so we can use it later. Note that we call the function using the
-binding name and two parentheses, just like we would for a named function.
+Small differences, but they're similar in ways.
 
-Let's compare syntax. The two are pretty close:
+# Closures and their environment
 
-```{rust}
-let add_one = |x: i32| -> i32 { 1 + x };
-fn  add_one   (x: i32) -> i32 { 1 + x }
+Closures are called such because they 'close over their environment.' It
+looks like this:
+
+```rust
+let num = 5;
+let plus_num = |x: i32| x + num;
+
+assert_eq!(10, plus_num(5));
 ```
 
-As you may have noticed, closures infer their argument and return types, so you
-don't need to declare one. This is different from named functions, which
-default to returning unit (`()`).
+This closure, `plus_num`, refers to a `let` binding in its scope: `num`. More
+specifically, it borrows the binding. If we do something that would conflict
+with that binding, we get an error. Like this one:
+
+```rust,ignore
+let mut num = 5;
+let plus_num = |x: i32| x + num;
 
-There's one big difference between a closure and named functions, and it's in
-the name: a closure "closes over its environment." What does that mean? It means
-this:
+let y = &mut num;
+```
 
-```{rust}
+Which errors with:
+
+```text
+error: cannot borrow `num` as mutable because it is also borrowed as immutable
+    let y = &mut num;
+                 ^~~
+note: previous borrow of `num` occurs here due to use in closure; the immutable
+  borrow prevents subsequent moves or mutable borrows of `num` until the borrow
+  ends
+    let plus_num = |x| x + num;
+                   ^~~~~~~~~~~
+note: previous borrow ends here
 fn main() {
-    let x: i32 = 5;
+    let mut num = 5;
+    let plus_num = |x| x + num;
+    
+    let y = &mut num;
+}
+^
+```
+
+A verbose yet helpful error message! As it says, we can't take a mutable borrow
+on `num` because the closure is already borrowing it. If we let the closure go
+out of scope, we can:
+
+```rust
+let mut num = 5;
+{
+    let plus_num = |x: i32| x + num;
+
+} // plus_num goes out of scope, borrow of num ends
 
-    let printer = || { println!("x is: {}", x); };
+let y = &mut num;
+```
+
+If your closure requires it, however, Rust will take ownership and move
+the environment instead:
+
+```rust,ignore
+let nums = vec![1, 2, 3];
+
+let takes_nums = || nums;
+
+println!("{:?}", nums);
+```
+
+This gives us:
+
+```text
+note: `nums` moved into closure environment here because it has type
+  `[closure(()) -> collections::vec::Vec<i32>]`, which is non-copyable
+let takes_nums = || nums;
+                    ^~~~~~~
+```
+
+`Vec<T>` has ownership over its contents, and therefore, when we refer to it
+in our closure, we have to take ownership of `nums`. It's the same as if we'd
+passed `nums` to a function that took ownership of it.
+
+## `move` closures
+
+We can force our closure to take ownership of its environment with the `move`
+keyword:
 
-    printer(); // prints "x is: 5"
+```rust
+let num = 5;
+
+let owns_num = move |x: i32| x + num;
+```
+
+Now, even though the keyword is `move`, the variables follow normal move semantics.
+In this case, `5` implements `Copy`, and so `owns_num` takes ownership of a copy
+of `num`. So what's the difference?
+
+```rust
+let mut num = 5;
+
+{ 
+    let mut add_num = |x: i32| num += x;
+
+    add_num(5);
 }
+
+assert_eq!(10, num);
 ```
 
-The `||` syntax means this is an anonymous closure that takes no arguments.
-Without it, we'd just have a block of code in `{}`s.
+So in this case, our closure took a mutable reference to `num`, and then when
+we called `add_num`, it mutated the underlying value, as we'd expect. We also
+needed to declare `add_num` as `mut` too, because we’re mutating its
+environment.
 
-In other words, a closure has access to variables in the scope where it's
-defined. The closure borrows any variables it uses, so this will error:
+We also had to declare `add_num` as mut, since we will be modifying its
+environment.
 
-```{rust,ignore}
-fn main() {
-    let mut x: i32 = 5;
+If we change to a `move` closure, it's different:
+
+```rust
+let mut num = 5;
 
-    let printer = || { println!("x is: {}", x); };
+{ 
+    let mut add_num = move |x: i32| num += x;
 
-    x = 6; // error: cannot assign to `x` because it is borrowed
+    add_num(5);
 }
+
+assert_eq!(5, num);
 ```
 
-## Moving closures
+We only get `5`. Rather than taking a mutable borrow out on our `num`, we took
+ownership of a copy.
+
+Another way to think about `move` closures: they give a closure its own stack
+frame.  Without `move`, a closure may be tied to the stack frame that created
+it, while a `move` closure is self-contained. This means that you cannot
+generally return a non-`move` closure from a function, for example.
+
+But before we talk about taking and returning closures, we should talk some more
+about the way that closures are implemented. As a systems language, Rust gives
+you tons of control over what your code does, and closures are no different.
 
-Rust has a second type of closure, called a *moving closure*. Moving
-closures are indicated using the `move` keyword (e.g., `move || x *
-x`). The difference between a moving closure and an ordinary closure
-is that a moving closure always takes ownership of all variables that
-it uses. Ordinary closures, in contrast, just create a reference into
-the enclosing stack frame. Moving closures are most useful with Rust's
-concurrency features, and so we'll just leave it at this for
-now. We'll talk about them more in the "Threads" section of the guide.
+# Closure implementation
 
-## Accepting closures as arguments
+Rust's implementation of closures is a bit different than other languages. They
+are effectively syntax sugar for traits. You'll want to make sure to have read
+the [traits chapter][traits] before this one, as well as the chapter on [static
+and dynamic dispatch][dispatch], which talks about trait objects.
 
-Closures are most useful as an argument to another function. Here's an example:
+[traits]: traits.html
+[dispatch]: static-and-dynamic-dispatch.html
 
-```{rust}
-fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {
-    f(x) + f(x)
+Got all that? Good.
+
+The key to understanding how closures work under the hood is something a bit
+strange: Using `()` to call a function, like `foo()`, is an overloadable
+operator. From this, everything else clicks into place. In Rust, we use the
+trait system to overload operators. Calling functions is no different. We have
+three separate traits to overload with:
+
+```rust
+# mod foo {
+pub trait Fn<Args> : FnMut<Args> {
+    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
 }
 
-fn main() {
-    let square = |x: i32| { x * x };
+pub trait FnMut<Args> : FnOnce<Args> {
+    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+}
+
+pub trait FnOnce<Args> {
+    type Output;
 
-    twice(5, square); // evaluates to 50
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
 }
+# }
 ```
 
-Let's break the example down, starting with `main`:
+You'll notice a few differences between these traits, but a big one is `self`:
+`Fn` takes `&self`, `FnMut` takes `&mut self`, and `FnOnce` takes `self`. This
+covers all three kinds of `self` via the usual method call syntax. But we've
+split them up into three traits, rather than having a single one. This gives us
+a large amount of control over what kind of closures we can take.
 
-```{rust}
-let square = |x: i32| { x * x };
-```
+The `|| {}` syntax for closures is sugar for these three traits. Rust will
+generate a struct for the environment, `impl` the appropriate trait, and then
+use it.
+
+# Taking closures as arguments
+
+Now that we know that closures are traits, we already know how to accept and
+return closures: just like any other trait!
+
+This also means that we can choose static vs dynamic dispatch as well. First,
+let's write a function which takes something callable, calls it, and returns
+the result:
+
+```rust
+fn call_with_one<F>(some_closure: F) -> i32
+    where F : Fn(i32) -> i32 {
+
+    some_closure(1)
+}
 
-We've seen this before. We make a closure that takes an integer, and returns
-its square.
+let answer = call_with_one(|x| x + 2);
 
-```{rust}
-# fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 { f(x) + f(x) }
-# let square = |x: i32| { x * x };
-twice(5, square); // evaluates to 50
+assert_eq!(3, answer);
 ```
 
-This line is more interesting. Here, we call our function, `twice`, and we pass
-it two arguments: an integer, `5`, and our closure, `square`. This is just like
-passing any other two variable bindings to a function, but if you've never
-worked with closures before, it can seem a little complex. Just think: "I'm
-passing two variables: one is an i32, and one is a function."
+We pass our closure, `|x| x + 2`, to `call_with_one`. It just does what it
+suggests: it calls the closure, giving it `1` as an argument.
 
-Next, let's look at how `twice` is defined:
+Let's examine the signature of `call_with_one` in more depth:
 
-```{rust,ignore}
-fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {
+```rust
+fn call_with_one<F>(some_closure: F) -> i32
+#    where F : Fn(i32) -> i32 {
+#    some_closure(1) }
 ```
 
-`twice` takes two arguments, `x` and `f`. That's why we called it with two
-arguments. `x` is an `i32`, we've done that a ton of times. `f` is a function,
-though, and that function takes an `i32` and returns an `i32`. This is
-what the requirement `Fn(i32) -> i32` for the type parameter `F` says.
-Now `F` represents *any* function that takes an `i32` and returns an `i32`.
+We take one parameter, and it has the type `F`. We also return a `i32`. This part
+isn't interesting. The next part is:
 
-This is the most complicated function signature we've seen yet! Give it a read
-a few times until you can see how it works. It takes a teeny bit of practice, and
-then it's easy. The good news is that this kind of passing a closure around
-can be very efficient. With all the type information available at compile-time
-the compiler can do wonders.
+```rust
+# fn call_with_one<F>(some_closure: F) -> i32
+    where F : Fn(i32) -> i32 {
+#   some_closure(1) }
+```
+
+Because `Fn` is a trait, we can bound our generic with it. In this case, our closure
+takes a `i32` as an argument and returns an `i32`, and so the generic bound we use
+is `Fn(i32) -> i32`.
 
-Finally, `twice` returns an `i32` as well.
+There's one other key point here: because we're bounding a generic with a
+trait, this will get monomorphized, and therefore, we'll be doing static
+dispatch into the closure. That's pretty neat. In many langauges, closures are
+inherently heap allocated, and will always involve dynamic dispatch. In Rust,
+we can stack allocate our closure environment, and statically dispatch the
+call. This happens quite often with iterators and their adapters, which often
+take closures as arguments.
 
-Okay, let's look at the body of `twice`:
+Of course, if we want dynamic dispatch, we can get that too. A trait object
+handles this case, as usual:
 
-```{rust}
-fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {
-  f(x) + f(x)
+```rust
+fn call_with_one(some_closure: &Fn(i32) -> i32) -> i32 {
+    some_closure(1)
 }
+
+let answer = call_with_one(&|x| x + 2);
+
+assert_eq!(3, answer);
 ```
 
-Since our closure is named `f`, we can call it just like we called our closures
-before, and we pass in our `x` argument to each one, hence the name `twice`.
+Now we take a trait object, a `&Fn`. And we have to make a reference
+to our closure when we pass it to `call_with_one`, so we use `&||`.
 
-If you do the math, `(5 * 5) + (5 * 5) == 50`, so that's the output we get.
+# Returning closures
 
-Play around with this concept until you're comfortable with it. Rust's standard
-library uses lots of closures where appropriate, so you'll be using
-this technique a lot.
+It’s very common for functional-style code to return closures in various
+situations. If you try to return a closure, you may run into an error. At
+first, it may seem strange, but we'll figure it out. Here's how you'd probably
+try to return a closure from a function:
 
-If we didn't want to give `square` a name, we could just define it inline.
-This example is the same as the previous one:
+```rust,ignore
+fn factory() -> (Fn(i32) -> Vec<i32>) {
+    let vec = vec![1, 2, 3];
 
-```{rust}
-fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {
-    f(x) + f(x)
+    |n| vec.push(n)
 }
 
-fn main() {
-    twice(5, |x: i32| { x * x }); // evaluates to 50
-}
+let f = factory();
+
+let answer = f(4);
+assert_eq!(vec![1, 2, 3, 4], answer);
 ```
 
-A named function's name can be used wherever you'd use a closure. Another
-way of writing the previous example:
+This gives us these long, related errors:
+
+```text
+error: the trait `core::marker::Sized` is not implemented for the type
+`core::ops::Fn(i32) -> collections::vec::Vec<i32>` [E0277]
+f = factory();
+^
+note: `core::ops::Fn(i32) -> collections::vec::Vec<i32>` does not have a
+constant size known at compile-time
+f = factory();
+^
+error: the trait `core::marker::Sized` is not implemented for the type
+`core::ops::Fn(i32) -> collections::vec::Vec<i32>` [E0277]
+factory() -> (Fn(i32) -> Vec<i32>) {
+             ^~~~~~~~~~~~~~~~~~~~~
+note: `core::ops::Fn(i32) -> collections::vec::Vec<i32>` does not have a constant size known at compile-time
+fa ctory() -> (Fn(i32) -> Vec<i32>) {
+              ^~~~~~~~~~~~~~~~~~~~~
 
-```{rust}
-fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {
-    f(x) + f(x)
-}
+```
 
-fn square(x: i32) -> i32 { x * x }
+In order to return something from a function, Rust needs to know what
+size the return type is. But since `Fn` is a trait, it could be various
+things of various sizes: many different types can implement `Fn`. An easy
+way to give something a size is to take a reference to it, as references
+have a known size. So we'd write this:
 
-fn main() {
-    twice(5, square); // evaluates to 50
+```rust,ignore
+fn factory() -> &(Fn(i32) -> Vec<i32>) {
+    let vec = vec![1, 2, 3];
+
+    |n| vec.push(n)
 }
+
+let f = factory();
+
+let answer = f(4);
+assert_eq!(vec![1, 2, 3, 4], answer);
+```
+
+But we get another error:
+
+```text
+error: missing lifetime specifier [E0106]
+fn factory() -> &(Fn(i32) -> i32) {
+                ^~~~~~~~~~~~~~~~~
 ```
 
-Doing this is not particularly common, but it's useful every once in a while.
+Right. Because we have a reference, we need to give it a lifetime. But
+our `factory()` function takes no arguments, so elision doesn't kick in
+here. What lifetime can we choose? `'static`:
 
-Before we move on, let us look at a function that accepts two closures.
+```rust,ignore
+fn factory() -> &'static (Fn(i32) -> i32) {
+    let num = 5;
 
-```{rust}
-fn compose<F, G>(x: i32, f: F, g: G) -> i32
-    where F: Fn(i32) -> i32, G: Fn(i32) -> i32 {
-    g(f(x))
+    |x| x + num
 }
 
-fn main() {
-    compose(5,
-            |n: i32| { n + 42 },
-            |n: i32| { n * 2 }); // evaluates to 94
+let f = factory();
+
+let answer = f(1);
+assert_eq!(6, answer);
+```
+
+But we get another error:
+
+```text
+error: mismatched types:
+ expected `&'static core::ops::Fn(i32) -> i32`,
+    found `[closure <anon>:7:9: 7:20]`
+(expected &-ptr,
+    found closure) [E0308]
+         |x| x + num
+         ^~~~~~~~~~~
+
+```
+
+This error is letting us know that we don't have a `&'static Fn(i32) -> i32`,
+we have a `[closure <anon>:7:9: 7:20]`. Wait, what?
+
+Because each closure generates its own environment `struct` and implementation
+of `Fn` and friends, these types are anonymous. They exist just solely for
+this closure. So Rust shows them as `closure <anon>`, rather than some
+autogenerated name.
+
+But why doesn't our closure implement `&'static Fn`? Well, as we discussed before,
+closures borrow their environment. And in this case, our environment is based
+on a stack-allocated `5`, the `num` variable binding. So the borrow has a lifetime
+of the stack frame. So if we returned this closure, the function call would be
+over, the stack frame would go away, and our closure is capturing an environment
+of garbage memory!
+
+So what to do? This _almost_ works:
+
+```rust,ignore
+fn factory() -> Box<Fn(i32) -> i32> {
+    let num = 5;
+
+    Box::new(|x| x + num)
 }
+# fn main() {
+let f = factory();
+
+let answer = f(1);
+assert_eq!(6, answer);
+# }
 ```
 
-You might ask yourself: why do we need to introduce two type
-parameters `F` and `G` here?  Evidently, both `f` and `g` have the
-same signature: `Fn(i32) -> i32`.
+We use a trait object, by `Box`ing up the `Fn`. There's just one last problem:
 
-That is because in Rust each closure has its own unique type.
-So, not only do closures with different signatures have different types,
-but different closures with the *same* signature have *different*
-types, as well!
+```text
+error: `num` does not live long enough
+Box::new(|x| x + num)
+         ^~~~~~~~~~~
+```
+
+We still have a reference to the parent stack frame. With one last fix, we can
+make this work:
 
-You can think of it this way: the behavior of a closure is part of its
-type.  Therefore, using a single type parameter for both closures
-will accept the first of them, rejecting the second. The distinct
-type of the second closure does not allow it to be represented by the
-same type parameter as that of the first.  We acknowledge this, and
-use two different type parameters `F` and `G`.
+```rust
+fn factory() -> Box<Fn(i32) -> i32> {
+    let num = 5;
 
-This also introduces the `where` clause, which lets us describe type
-parameters in a more flexible manner.
+    Box::new(move |x| x + num)
+}
+# fn main() {
+let f = factory();
+
+let answer = f(1);
+assert_eq!(6, answer);
+# }
+```
 
-That's all you need to get the hang of closures! Closures are a little bit
-strange at first, but once you're used to them, you'll miss them
-in other languages. Passing functions to other functions is
-incredibly powerful, as you will see in the following chapter about iterators.
+By making the inner closure a `move Fn`, we create a new stack frame for our
+closure. By `Box`ing it up, we've given it a known size, and allowing it to
+escape our stack frame.
index 66670c7c631cd972639aab3a174038b8a0871dcb..441496e6a755b7e9590739fdcf44c90f8867d087 100644 (file)
@@ -28,7 +28,7 @@ The other kind of comment is a doc comment. Doc comments use `///` instead of
 ///
 /// * `name` - The name of the person you'd like to greet.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```rust
 /// let name = "Steve";
index 85d67262c4066d9bf78b9d7185b0020fefa23877..e44d2edd667a1ea822cde1798278bbc8b1fe3b55 100644 (file)
@@ -6,8 +6,8 @@ strings, but next, let's talk about some more complicated ways of storing data.
 
 ## Tuples
 
-The first compound data type we're going to talk about are called *tuples*.
-Tuples are an ordered list of a fixed size. Like this:
+The first compound data type we're going to talk about is called the *tuple*.
+A tuple is an ordered list of fixed size. Like this:
 
 ```rust
 let x = (1, "hello");
@@ -47,7 +47,7 @@ This pattern is very powerful, and we'll see it repeated more later.
 
 There are also a few things you can do with a tuple as a whole, without
 destructuring. You can assign one tuple into another, if they have the same
-contained types and arity. Tuples have the same arity when they have the same
+contained types and [arity]. Tuples have the same arity when they have the same
 length.
 
 ```rust
@@ -196,8 +196,9 @@ Now, we have actual names, rather than positions. Good names are important,
 and with a struct, we have actual names.
 
 There _is_ one case when a tuple struct is very useful, though, and that's a
-tuple struct with only one element. We call this a *newtype*, because it lets
-you create a new type that's similar to another one:
+tuple struct with only one element. We call this the *newtype* pattern, because
+it allows you to create a new type, distinct from that of its contained value
+and expressing its own semantic meaning:
 
 ```{rust}
 struct Inches(i32);
@@ -216,7 +217,7 @@ destructuring `let`, as we discussed previously in 'tuples.' In this case, the
 
 Finally, Rust has a "sum type", an *enum*. Enums are an incredibly useful
 feature of Rust, and are used throughout the standard library. An `enum` is
-a type which ties a set of alternates to a specific name. For example, below
+a type which relates a set of alternates to a specific name. For example, below
 we define `Character` to be either a `Digit` or something else. These
 can be used via their fully scoped names: `Character::Other` (more about `::`
 below).
@@ -228,8 +229,8 @@ enum Character {
 }
 ```
 
-An `enum` variant can be defined as most normal types. Below are some example
-types have been listed which also would be allowed in an `enum`.
+Most normal types are allowed as the variant components of an `enum`. Here are
+some examples:
 
 ```rust
 struct Empty;
@@ -239,15 +240,15 @@ struct Status { Health: i32, Mana: i32, Attack: i32, Defense: i32 }
 struct HeightDatabase(Vec<i32>);
 ```
 
-So you see that depending on the sub-datastructure, the `enum` variant, same as
-a struct, may or may not hold data. That is, in `Character`, `Digit` is a name
-tied to an `i32` where `Other` is just a name. However, the fact that they are
-distinct makes this very useful.
+You see that, depending on its type, an `enum` variant may or may not hold data.
+In `Character`, for instance, `Digit` gives a meaningful name for an `i32`
+value, where `Other` is only a name. However, the fact that they represent
+distinct categories of `Character` is a very useful property.
 
-As with structures, enums don't by default have access to operators such as
-compare ( `==` and `!=`), binary operations (`*` and `+`), and order
-(`<` and `>=`). As such, using the previous `Character` type, the
-following code is invalid:
+As with structures, the variants of an enum by default are not comparable with
+equality operators (`==`, `!=`), have no ordering (`<`, `>=`, etc.), and do not
+support other binary operations such as `*` and `+`. As such, the following code
+is invalid for the example `Character` type:
 
 ```{rust,ignore}
 // These assignments both succeed
@@ -265,9 +266,10 @@ let four_equals_ten = four == ten;
 ```
 
 This may seem rather limiting, but it's a limitation which we can overcome.
-There are two ways: by implementing equality ourselves, or by using the
-[`match`][match] keyword. We don't know enough about Rust to implement equality
-yet, but we can use the `Ordering` enum from the standard library, which does:
+There are two ways: by implementing equality ourselves, or by pattern matching
+variants with [`match`][match] expressions, which you'll learn in the next
+chapter. We don't know enough about Rust to implement equality yet, but we can
+use the `Ordering` enum from the standard library, which does:
 
 ```
 enum Ordering {
@@ -277,9 +279,8 @@ enum Ordering {
 }
 ```
 
-Because we did not define `Ordering`, we must import it (from the std
-library) with the `use` keyword. Here's an example of how `Ordering` is
-used:
+Because `Ordering` has already been defined for us, we will import it with the
+`use` keyword. Here's an example of how it is used:
 
 ```{rust}
 use std::cmp::Ordering;
@@ -313,17 +314,17 @@ the standard library if you need them.
 
 Okay, let's talk about the actual code in the example. `cmp` is a function that
 compares two things, and returns an `Ordering`. We return either
-`Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on if
-the two values are less, greater, or equal. Note that each variant of the
-`enum` is namespaced under the `enum` itself: it's `Ordering::Greater` not
-`Greater`.
+`Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on
+whether the first value is less than, greater than, or equal to the second. Note
+that each variant of the `enum` is namespaced under the `enum` itself: it's
+`Ordering::Greater`, not `Greater`.
 
 The `ordering` variable has the type `Ordering`, and so contains one of the
 three values. We then do a bunch of `if`/`else` comparisons to check which
 one it is.
 
-This `Ordering::Greater` notation is too long. Let's use `use` to import the
-`enum` variants instead. This will avoid full scoping:
+This `Ordering::Greater` notation is too long. Let's use another form of `use`
+to import the `enum` variants instead. This will avoid full scoping:
 
 ```{rust}
 use std::cmp::Ordering::{self, Equal, Less, Greater};
@@ -347,16 +348,17 @@ fn main() {
 ```
 
 Importing variants is convenient and compact, but can also cause name conflicts,
-so do this with caution. It's considered good style to rarely import variants
-for this reason.
+so do this with caution. For this reason, it's normally considered better style
+to `use` an enum rather than its variants directly.
 
-As you can see, `enum`s are quite a powerful tool for data representation, and are
-even more useful when they're [generic][generics] across types. Before we
-get to generics, though, let's talk about how to use them with pattern matching, a
-tool that will let us deconstruct this sum type (the type theory term for enums)
-in a very elegant way and avoid all these messy `if`/`else`s.
+As you can see, `enum`s are quite a powerful tool for data representation, and
+are even more useful when they're [generic][generics] across types. Before we
+get to generics, though, let's talk about how to use enums with pattern
+matching, a tool that will let us deconstruct sum types (the type theory term
+for enums) like `Ordering` in a very elegant way that avoids all these messy
+and brittle `if`/`else`s.
 
 
+[arity]: ./glossary.html#arity
 [match]: ./match.html
-[game]: ./guessing-game.html#comparing-guesses
 [generics]: ./generics.html
index 842957bd601c61cd59fc479fce93e4d17659dd1b..6b814a685424ef83220f8ce19f02d036bfe58b70 100644 (file)
@@ -40,14 +40,14 @@ us enforce that it can't leave the current thread.
 
 ### `Sync`
 
-The second of these two trait is called [`Sync`](../std/marker/trait.Sync.html).
+The second of these traits is called [`Sync`](../std/marker/trait.Sync.html).
 When a type `T` implements `Sync`, it indicates to the compiler that something
 of this type has no possibility of introducing memory unsafety when used from
 multiple threads concurrently.
 
 For example, sharing immutable data with an atomic reference count is
 threadsafe. Rust provides a type like this, `Arc<T>`, and it implements `Sync`,
-so that it could be safely shared between threads.
+so it is safe to share between threads.
 
 These two traits allow you to use the type system to make strong guarantees
 about the properties of your code under concurrency. Before we demonstrate
@@ -69,7 +69,7 @@ fn main() {
 }
 ```
 
-The `Thread::scoped()` method accepts a closure, which is executed in a new
+The `thread::scoped()` method accepts a closure, which is executed in a new
 thread. It's called `scoped` because this thread returns a join guard:
 
 ```
@@ -88,6 +88,7 @@ When `guard` goes out of scope, it will block execution until the thread is
 finished. If we didn't want this behaviour, we could use `thread::spawn()`:
 
 ```
+# #![feature(old_io, std_misc)]
 use std::thread;
 use std::old_io::timer;
 use std::time::Duration;
@@ -146,6 +147,7 @@ As an example, here is a Rust program that would have a data race in many
 languages. It will not compile:
 
 ```ignore
+# #![feature(old_io, std_misc)]
 use std::thread;
 use std::old_io::timer;
 use std::time::Duration;
@@ -185,6 +187,7 @@ only one person at a time can mutate what's inside. For that, we can use the
 but for a different reason:
 
 ```ignore
+# #![feature(old_io, std_misc)]
 use std::thread;
 use std::old_io::timer;
 use std::time::Duration;
@@ -208,10 +211,10 @@ Here's the error:
 
 ```text
 <anon>:11:9: 11:22 error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` [E0277]
-<anon>:11         Thread::spawn(move || {
+<anon>:11         thread::spawn(move || {
                   ^~~~~~~~~~~~~
 <anon>:11:9: 11:22 note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` cannot be sent between threads safely
-<anon>:11         Thread::spawn(move || {
+<anon>:11         thread::spawn(move || {
                   ^~~~~~~~~~~~~
 ```
 
@@ -223,19 +226,13 @@ method which has this signature:
 fn lock(&self) -> LockResult<MutexGuard<T>>
 ```
 
-If we [look at the code for MutexGuard](https://github.com/rust-lang/rust/blob/ca4b9674c26c1de07a2042cb68e6a062d7184cef/src/libstd/sync/mutex.rs#L172), we'll see
-this:
-
-```ignore
-__marker: marker::NoSend,
-```
-
-Because our guard is `NoSend`, it's not `Send`. Which means we can't actually
-transfer the guard across thread boundaries, which gives us our error.
+Because `Send` is not implemented for `MutexGuard<T>`, we can't transfer the
+guard across thread boundaries, which gives us our error.
 
 We can use `Arc<T>` to fix this. Here's the working version:
 
 ```
+# #![feature(old_io, std_misc)]
 use std::sync::{Arc, Mutex};
 use std::thread;
 use std::old_io::timer;
@@ -261,6 +258,7 @@ handle is then moved into the new thread. Let's examine the body of the
 thread more closely:
 
 ```
+# #![feature(old_io, std_misc)]
 # use std::sync::{Arc, Mutex};
 # use std::thread;
 # use std::old_io::timer;
@@ -282,13 +280,15 @@ it returns an `Result<T, E>`, and because this is just an example, we `unwrap()`
 it to get a reference to the data. Real code would have more robust error handling
 here. We're then free to mutate it, since we have the lock.
 
-This timer bit is a bit awkward, however. We have picked a reasonable amount of
-time to wait, but it's entirely possible that we've picked too high, and that
-we could be taking less time. It's also possible that we've picked too low,
-and that we aren't actually finishing this computation.
+Lastly, while the threads are running, we wait on a short timer. But
+this is not ideal: we may have picked a reasonable amount of time to
+wait but it's more likely we'll either be waiting longer than
+necessary or not long enough, depending on just how much time the
+threads actually take to finish computing when the program runs.
 
-Rust's standard library provides a few more mechanisms for two threads to
-synchronize with each other. Let's talk about one: channels.
+A more precise alternative to the timer would be to use one of the
+mechanisms provided by the Rust standard library for synchronizing
+threads with each other. Let's talk about one of them: channels.
 
 ## Channels
 
@@ -329,7 +329,6 @@ While this channel is just sending a generic signal, we can send any data that
 is `Send` over the channel!
 
 ```
-use std::sync::{Arc, Mutex};
 use std::thread;
 use std::sync::mpsc;
 
@@ -346,7 +345,7 @@ fn main() {
         });
     }
 
-   rx.recv().ok().expect("Could not recieve answer");
+   rx.recv().ok().expect("Could not receive answer");
 }
 ```
 
index 1f5d3eadae3b9204b7836a838d5f2ce91563cb42..0cc54c9b16598b10eb2e8b945cc6224b6fbea20b 100644 (file)
@@ -1,6 +1,6 @@
 % Crates and Modules
 
-When a project starts getting large, it's considered good software
+When a project starts getting large, it's considered good software
 engineering practice to split it up into a bunch of smaller pieces, and then
 fit them together. It's also important to have a well-defined interface, so
 that some of your functionality is private, and some is public. To facilitate
@@ -12,7 +12,7 @@ Rust has two distinct terms that relate to the module system: *crate* and
 *module*. A crate is synonymous with a *library* or *package* in other
 languages. Hence "Cargo" as the name of Rust's package management tool: you
 ship your crates to others with Cargo. Crates can produce an executable or a
-shared library, depending on the project.
+library, depending on the project.
 
 Each crate has an implicit *root module* that contains the code for that crate.
 You can then define a tree of sub-modules under that root module. Modules allow
@@ -24,23 +24,23 @@ in different languages. To keep things simple, we'll stick to "greetings" and
 two languages for those phrases to be in. We'll use this module layout:
 
 ```text
-                                +-----------+
-                            +---| greetings |
-                            |   +-----------+
-              +---------+   |
-              | english |---+
-              +---------+   |   +-----------+
-              |             +---| farewells |
-+---------+   |                 +-----------+
+                                    +-----------+
+                                +---| greetings |
+                                |   +-----------+
+                  +---------+   |
+              +---| english |---+
+              |   +---------+   |   +-----------+
+              |                 +---| farewells |
++---------+   |                     +-----------+
 | phrases |---+
-+---------+   |                  +-----------+
-              |              +---| greetings |
-              +----------+   |   +-----------+
-              | japanese |---+
-              +----------+   |
-                             |   +-----------+
-                             +---| farewells |
-                                 +-----------+
++---------+   |                     +-----------+
+              |                 +---| greetings |
+              |   +----------+  |   +-----------+
+              +---| japanese |--+
+                  +----------+  |
+                                |   +-----------+
+                                +---| farewells |
+                                    +-----------+
 ```
 
 In this example, `phrases` is the name of our crate. All of the rest are
@@ -76,25 +76,19 @@ To define each of our modules, we use the `mod` keyword. Let's make our
 `src/lib.rs` look like this:
 
 ```
-// in src/lib.rs
-
 mod english {
     mod greetings {
-
     }
 
     mod farewells {
-
     }
 }
 
 mod japanese {
     mod greetings {
-
     }
 
     mod farewells {
-
     }
 }
 ```
@@ -145,11 +139,7 @@ mod english;
 ```
 
 If we do that, Rust will expect to find either a `english.rs` file, or a
-`english/mod.rs` file with the contents of our module:
-
-```{rust,ignore}
-// contents of our module go here
-```
+`english/mod.rs` file with the contents of our module.
 
 Note that in these files, you don't need to re-declare the module: that's
 already been done with the initial `mod` declaration.
@@ -181,10 +171,7 @@ $ tree .
 `src/lib.rs` is our crate root, and looks like this:
 
 ```{rust,ignore}
-// in src/lib.rs
-
 mod english;
-
 mod japanese;
 ```
 
@@ -195,10 +182,7 @@ chosen the second. Both `src/english/mod.rs` and `src/japanese/mod.rs` look
 like this:
 
 ```{rust,ignore}
-// both src/english/mod.rs and src/japanese/mod.rs
-
 mod greetings;
-
 mod farewells;
 ```
 
@@ -214,8 +198,6 @@ both empty at the moment. Let's add some functions.
 Put this in `src/english/greetings.rs`:
 
 ```rust
-// in src/english/greetings.rs
-
 fn hello() -> String {
     "Hello!".to_string()
 }
@@ -224,8 +206,6 @@ fn hello() -> String {
 Put this in `src/english/farewells.rs`:
 
 ```rust
-// in src/english/farewells.rs
-
 fn goodbye() -> String {
     "Goodbye.".to_string()
 }
@@ -248,8 +228,6 @@ about the module system.
 Put this in `src/japanese/farewells.rs`:
 
 ```rust
-// in src/japanese/farewells.rs
-
 fn goodbye() -> String {
     "さようなら".to_string()
 }
@@ -265,11 +243,9 @@ another crate.
 We have a library crate. Let's make an executable crate that imports and uses
 our library.
 
-Make a `src/main.rs` and put this in it: (it won't quite compile yet)
+Make a `src/main.rs` and put this in it (it won't quite compile yet):
 
 ```rust,ignore
-// in src/main.rs
-
 extern crate phrases;
 
 fn main() {
@@ -320,8 +296,6 @@ keyword. Let's focus on the `english` module first, so let's reduce our `src/mai
 to just this:
 
 ```{rust,ignore}
-// in src/main.rs
-
 extern crate phrases;
 
 fn main() {
@@ -333,28 +307,20 @@ fn main() {
 In our `src/lib.rs`, let's add `pub` to the `english` module declaration:
 
 ```{rust,ignore}
-// in src/lib.rs
-
 pub mod english;
-
 mod japanese;
 ```
 
 And in our `src/english/mod.rs`, let's make both `pub`:
 
 ```{rust,ignore}
-// in src/english/mod.rs
-
 pub mod greetings;
-
 pub mod farewells;
 ```
 
 In our `src/english/greetings.rs`, let's add `pub` to our `fn` declaration:
 
 ```{rust,ignore}
-// in src/english/greetings.rs
-
 pub fn hello() -> String {
     "Hello!".to_string()
 }
@@ -363,8 +329,6 @@ pub fn hello() -> String {
 And also in `src/english/farewells.rs`:
 
 ```{rust,ignore}
-// in src/english/farewells.rs
-
 pub fn goodbye() -> String {
     "Goodbye.".to_string()
 }
@@ -400,8 +364,6 @@ Rust has a `use` keyword, which allows us to import names into our local scope.
 Let's change our `src/main.rs` to look like this:
 
 ```{rust,ignore}
-// in src/main.rs
-
 extern crate phrases;
 
 use phrases::english::greetings;
@@ -430,7 +392,7 @@ fn main() {
 }
 ```
 
-But it is not idiomatic. This is significantly more likely to introducing a
+But it is not idiomatic. This is significantly more likely to introduce a
 naming conflict. In our short program, it's not a big deal, but as it grows, it
 becomes a problem. If we have conflicting names, Rust will give a compilation
 error. For example, if we made the `japanese` functions public, and tried to do
@@ -460,21 +422,19 @@ Could not compile `phrases`.
 ```
 
 If we're importing multiple names from the same module, we don't have to type it out
-twice. Rust has a shortcut syntax for writing this:
+twice. Instead of this:
 
 ```{rust,ignore}
 use phrases::english::greetings;
 use phrases::english::farewells;
 ```
 
-You use curly braces:
+We can use this shortcut:
 
 ```{rust,ignore}
 use phrases::english::{greetings, farewells};
 ```
 
-These two declarations are equivalent, but the second is a lot less typing.
-
 ## Re-exporting with `pub use`
 
 You don't just use `use` to shorten identifiers. You can also use it inside of your crate
@@ -484,8 +444,6 @@ interface that may not directly map to your internal code organization.
 Let's look at an example. Modify your `src/main.rs` to read like this:
 
 ```{rust,ignore}
-// in src/main.rs
-
 extern crate phrases;
 
 use phrases::english::{greetings,farewells};
@@ -503,18 +461,13 @@ fn main() {
 Then, modify your `src/lib.rs` to make the `japanese` mod public:
 
 ```{rust,ignore}
-// in src/lib.rs
-
 pub mod english;
-
 pub mod japanese;
 ```
 
 Next, make the two functions public, first in `src/japanese/greetings.rs`:
 
 ```{rust,ignore}
-// in src/japanese/greetings.rs
-
 pub fn hello() -> String {
     "こんにちは".to_string()
 }
@@ -523,8 +476,6 @@ pub fn hello() -> String {
 And then in `src/japanese/farewells.rs`:
 
 ```{rust,ignore}
-// in src/japanese/farewells.rs
-
 pub fn goodbye() -> String {
     "さようなら".to_string()
 }
@@ -533,13 +484,10 @@ pub fn goodbye() -> String {
 Finally, modify your `src/japanese/mod.rs` to read like this:
 
 ```{rust,ignore}
-// in src/japanese/mod.rs
-
 pub use self::greetings::hello;
 pub use self::farewells::goodbye;
 
 mod greetings;
-
 mod farewells;
 ```
 
@@ -551,9 +499,21 @@ module, we now have a `phrases::japanese::hello()` function and a
 `phrases::japanese::farewells::goodbye()`. Our internal organization doesn't
 define our external interface.
 
-Here we have a `pub use` for each function we want to bring into the 
+Here we have a `pub use` for each function we want to bring into the
 `japanese` scope. We could alternatively use the wildcard syntax to include
-everything from `greetings` into the current scope: `pub use self::greetings::*`. 
+everything from `greetings` into the current scope: `pub use self::greetings::*`.
+
+What about the `self`? Well, by default, `use` declarations are absolute paths,
+starting from your crate root. `self` makes that path relative to your current
+place in the hierarchy instead. There's one more special form of `use`: you can
+`use super::` to reach one level up the tree from your current location. Some
+people like to think of `self` as `.` and `super` as `..`, from many shells'
+display for the current directory and the parent directory.
+
+Outside of `use`, paths are relative: `foo::bar()` refers to a function inside
+of `foo` relative to where we are. If that's prefixed with `::`, as in
+`::foo::bar()`, it refers to a different `foo`, an absolute path from your
+crate root.
 
 Also, note that we `pub use`d before we declared our `mod`s. Rust requires that
 `use` declarations go first.
index ded30063ebaf08fbf6a539374a1a978d70699172..06071a8f15fa4e83b564bd27730cc204587b8267 100644 (file)
 % Documentation
 
-`rustdoc` is the built-in tool for generating documentation. It integrates
-with the compiler to provide accurate hyperlinking between usage of types and
-their documentation. Furthermore, by not using a separate parser, it will
-never reject your valid Rust code.
+Documentation is an important part of any software project, and it's
+first-class in Rust. Let's talk about the tooling Rust gives you to
+document your project.
 
-# Creating Documentation
+## About `rustdoc`
 
-Documenting Rust APIs is quite simple. To document a given item, we have "doc
-comments":
+The Rust distribution includes a tool, `rustdoc`, that generates documentation.
+`rustdoc` is also used by Cargo through `cargo doc`.
 
-~~~
-# #![allow(unused_attribute)]
-// the "link" crate attribute is currently required for rustdoc, but normally
-// isn't needed.
-#![crate_id = "universe"]
-#![crate_type= "lib"]
-
-//! Tools for dealing with universes (this is a doc comment, and is shown on
-//! the crate index page. The ! makes it apply to the parent of the comment,
-//! rather than what follows).
-
-# mod workaround_the_outer_function_rustdoc_inserts {
-/// Widgets are very common (this is a doc comment, and will show up on
-/// Widget's documentation).
-pub struct Widget {
-       /// All widgets have a purpose (this is a doc comment, and will show up
-       /// the field's documentation).
-       purpose: String,
-       /// Humans are not allowed to understand some widgets
-       understandable: bool
+Documentation can be generated in two ways: from source code, and from
+standalone Markdown files.
+
+## Documenting source code
+
+The primary way of documenting a Rust project is through annotating the source
+code. You can use documentation comments for this purpose:
+
+```rust,ignore
+/// Constructs a new `Rc<T>`.
+///
+/// # Examples
+///
+/// ```
+/// use std::rc::Rc;
+///
+/// let five = Rc::new(5);
+/// ```
+pub fn new(value: T) -> Rc<T> {
+    // implementation goes here
+}
+```
+
+This code generates documentation that looks [like this][rc-new]. I've left the
+implementation out, with a regular comment in its place. That's the first thing
+to notice about this annotation: it uses `///`, instead of `//`. The triple slash
+indicates a documentation comment.
+
+Documentation comments are written in Markdown.
+
+Rust keeps track of these comments, and uses them when generating
+documentation. This is important when documenting things like enums:
+
+```
+/// The `Option` type. See [the module level documentation](../) for more.
+enum Option<T> {
+    /// No value
+    None,
+    /// Some value `T`
+    Some(T),
 }
+```
+
+The above works, but this does not:
 
-pub fn recalibrate() {
-       //! Recalibrate a pesky universe (this is also a doc comment, like above,
-       //! the documentation will be applied to the *parent* item, so
-       //! `recalibrate`).
-       /* ... */
+```rust,ignore
+/// The `Option` type. See [the module level documentation](../) for more.
+enum Option<T> {
+    None, /// No value
+    Some(T), /// Some value `T`
 }
-# }
-~~~
+```
 
-Documentation can also be controlled via the `doc` attribute on items. This is
-implicitly done by the compiler when using the above form of doc comments
-(converting the slash-based comments to `#[doc]` attributes).
+You'll get an error:
 
-~~~
-#[doc = "
-Calculates the factorial of a number.
+```text
+hello.rs:4:1: 4:2 error: expected ident, found `}`
+hello.rs:4 }
+           ^
+```
 
-Given the input integer `n`, this function will calculate `n!` and return it.
-"]
-pub fn factorial(n: int) -> int { if n < 2 {1} else {n * factorial(n - 1)} }
-# fn main() {}
-~~~
+This [unfortunate error](https://github.com/rust-lang/rust/issues/22547) is
+correct: documentation comments apply to the thing after them, and there's no
+thing after that last comment.
 
-The `doc` attribute can also be used to control how rustdoc emits documentation
-in some cases.
+[rc-new]: http://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new
+
+### Writing documentation comments
+
+Anyway, let's cover each part of this comment in detail:
 
 ```
-// Rustdoc will inline documentation of a `pub use` into this crate when the
-// `pub use` reaches across crates, but this behavior can also be disabled.
-#[doc(no_inline)]
-pub use std::option::Option;
-# fn main() {}
+/// Constructs a new `Rc<T>`.
+# fn foo() {}
 ```
 
-Doc comments are markdown, and are currently parsed with the
-[hoedown][hoedown] library. rustdoc does not yet do any fanciness such as
-referencing other items inline, like javadoc's `@see`. One exception to this
-is that the first paragraph will be used as the "summary" of an item in the
-generated documentation:
+The first line of a documentation comment should be a short summary of its
+functionality. One sentence. Just the basics. High level.
 
-~~~
-/// A whizbang. Does stuff. (this line is the summary)
+```
 ///
-/// Whizbangs are ...
-struct Whizbang;
-~~~
+/// Other details about constructing `Rc<T>`s, maybe describing complicated
+/// semantics, maybe additional options, all kinds of stuff.
+///
+# fn foo() {}
+```
 
-To generate the docs, run `rustdoc universe.rs`. By default, it generates a
-directory called `doc`, with the documentation for `universe` being in
-`doc/universe/index.html`. If you are using other crates with `extern crate`,
-rustdoc will even link to them when you use their types, as long as their
-documentation has already been generated by a previous run of rustdoc, or the
-crate advertises that its documentation is hosted at a given URL.
+Our original example had just a summary line, but if we had more things to say,
+we could have added more explanation in a new paragraph.
 
-The generated output can be controlled with the `doc` crate attribute, which
-is how the above advertisement works. An example from the `libstd`
-documentation:
+#### Special sections
 
-~~~
-#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
-      html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-      html_root_url = "http://doc.rust-lang.org/")];
-~~~
+```
+/// # Examples
+# fn foo() {}
+```
 
-The `html_root_url` is the prefix that rustdoc will apply to any references to
-that crate's types etc.
+Next, are special sections. These are indicated with a header, `#`. There
+are three kinds of headers that are commonly used. They aren't special syntax,
+just convention, for now.
 
-rustdoc can also generate JSON, for consumption by other tools, with
-`rustdoc --output-format json`, and also consume already-generated JSON with
-`rustdoc --input-format json`.
+```
+/// # Panics
+# fn foo() {}
+```
 
-rustdoc also supports personalizing the output from crates' documentation,
-similar to markdown options.
+Unrecoverable misuses of a function (i.e. programming errors) in Rust are
+usually indicated by panics, which kill the whole current thread at the very
+least. If your function has a non-trivial contract like this, that is
+detected/enforced by panics, documenting it is very important.
 
-- `--html-in-header FILE`: includes the contents of `FILE` at the
-  end of the `<head>...</head>` section.
-- `--html-before-content FILE`: includes the contents of `FILE`
-  directly after `<body>`, before the rendered content (including the
-  search bar).
-- `--html-after-content FILE`: includes the contents of `FILE`
-  after all the rendered content.
+```
+/// # Failures
+# fn foo() {}
+```
 
-# Using the Documentation
+If your function or method returns a `Result<T, E>`, then describing the
+conditions under which it returns `Err(E)` is a nice thing to do. This is
+slightly less important than `Panics`, because failure is encoded into the type
+system, but it's still a good thing to do.
 
-The web pages generated by rustdoc present the same logical hierarchy that one
-writes a library with. Every kind of item (function, struct, etc) has its own
-color, and one can always click on a colored type to jump to its
-documentation. There is a search bar at the top, which is powered by some
-JavaScript and a statically-generated search index. No special web server is
-required for the search.
+```
+/// # Safety
+# fn foo() {}
+```
 
-[hoedown]: https://github.com/hoedown/hoedown
+If your function is `unsafe`, you should explain which invariants the caller is
+responsible for upholding.
 
-# Testing the Documentation
+```
+/// # Examples
+///
+/// ```
+/// use std::rc::Rc;
+///
+/// let five = Rc::new(5);
+/// ```
+# fn foo() {}
+```
 
-`rustdoc` has support for testing code examples which appear in the
-documentation. This is helpful for keeping code examples up to date with the
-source code.
+Third, `Examples`. Include one or more examples of using your function or
+method, and your users will love you for it. These examples go inside of
+code block annotations, which we'll talk about in a moment, and can have
+more than one section:
 
-To test documentation, the `--test` argument is passed to rustdoc:
+```
+/// # Examples
+///
+/// Simple `&str` patterns:
+///
+/// ```
+/// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
+/// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
+/// ```
+///
+/// More complex patterns with a lambda:
+///
+/// ```
+/// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
+/// assert_eq!(v, vec!["abc", "def", "ghi"]);
+/// ```
+# fn foo() {}
+```
 
-~~~ {.sh}
-rustdoc --test crate.rs
-~~~
+Let's discuss the details of these code blocks.
 
-## Defining tests
+#### Code block annotations
 
-Rust documentation currently uses the markdown format, and rustdoc treats all
-code blocks as testable-by-default unless they carry a language tag of another
-language. In order to not run a test over a block of code, the `ignore` string
-can be added to the three-backtick form of markdown code block.
+To write some Rust code in a comment, use the triple graves:
 
-~~~md
 ```
-// This is a testable code block
+/// ```
+/// println!("Hello, world");
+/// ```
+# fn foo() {}
 ```
 
-```rust{.example}
-// This is rust and also testable
+If you want something that's not Rust code, you can add an annotation:
+
+```
+/// ```c
+/// printf("Hello, world\n");
+/// ```
+# fn foo() {}
 ```
 
-```ignore
-// This is not a testable code block
+This will highlight according to whatever language you're showing off.
+If you're just showing plain text, choose `text`.
+
+It's important to choose the correct annotation here, because `rustdoc` uses it
+in an interesting way: It can be used to actually test your examples, so that
+they don't get out of date. If you have some C code but `rustdoc` thinks it's
+Rust because you left off the annotation, `rustdoc` will complain when trying to
+generate the documentation.
+
+## Documentation as tests
+
+Let's discuss our sample example documentation:
+
+```
+/// ```
+/// println!("Hello, world");
+/// ```
+# fn foo() {}
 ```
 
-    // This is a testable code block (4-space indent)
+You'll notice that you don't need a `fn main()` or anything here. `rustdoc` will
+automatically add a main() wrapper around your code, and in the right place.
+For example:
 
-```sh
-# this is shell code and not tested
 ```
-~~~
+/// ```
+/// use std::rc::Rc;
+///
+/// let five = Rc::new(5);
+/// ```
+# fn foo() {}
+```
 
-You can specify that the test's execution should fail with the `should_fail`
-directive.
+This will end up testing:
 
-~~~md
-```should_fail
-// This code block is expected to generate a panic when run
 ```
-~~~
+fn main() {
+    use std::rc::Rc;
+    let five = Rc::new(5);
+}
+```
+
+Here's the full algorithm rustdoc uses to postprocess examples:
+
+1. Any leading `#![foo]` attributes are left intact as crate attributes.
+2. Some common `allow` attributes are inserted, including
+   `unused_variables`, `unused_assignments`, `unused_mut`,
+   `unused_attributes`, and `dead_code`. Small examples often trigger
+   these lints.
+3. If the example does not contain `extern crate`, then `extern crate
+   <mycrate>;` is inserted.
+2. Finally, if the example does not contain `fn main`, the remainder of the
+   text is wrapped in `fn main() { your_code }`
 
-You can specify that the code block should be compiled but not run with the
-`no_run` directive.
+Sometimes, this isn't enough, though. For example, all of these code samples
+with `///` we've been talking about? The raw text:
 
-~~~md
-```no_run
-// This code will be compiled but not executed
+```text
+/// Some documentation.
+# fn foo() {}
 ```
-~~~
 
-Lastly, you can specify that a code block be compiled as if `--test`
-were passed to the compiler using the `test_harness` directive.
+looks different than the output:
 
-~~~md
-```test_harness
-#[test]
-fn foo() {
-    panic!("oops! (will run & register as a failed test)")
-}
 ```
-~~~
+/// Some documentation.
+# fn foo() {}
+```
+
+Yes, that's right: you can add lines that start with `# `, and they will
+be hidden from the output, but will be used when compiling your code. You
+can use this to your advantage. In this case, documentation comments need
+to apply to some kind of function, so if I want to show you just a
+documentation comment, I need to add a little function definition below
+it. At the same time, it's just there to satisfy the compiler, so hiding
+it makes the example more clear. You can use this technique to explain
+longer examples in detail, while still preserving the testability of your
+documentation. For example, this code:
+
+```
+let x = 5;
+let y = 6;
+println!("{}", x + y);
+```
+
+Here's an explanation, rendered:
 
-Rustdoc also supplies some extra sugar for helping with some tedious
-documentation examples. If a line is prefixed with `# `, then the line
-will not show up in the HTML documentation, but it will be used when
-testing the code block (NB. the space after the `#` is required, so
-that one can still write things like `#[derive(Eq)]`).
+First, we set `x` to five:
 
-~~~md
 ```
-# /!\ The three following lines are comments, which are usually stripped off by
-# the doc-generating tool.  In order to display them anyway in this particular
-# case, the character following the leading '#' is not a usual space like in
-# these first five lines but a non breakable one.
-# // showing 'fib' in this documentation would just be tedious and detracts from
-# // what's actually being documented.
-# fn fib(n: int) { n + 2 }
+let x = 5;
+# let y = 6;
+# println!("{}", x + y);
+```
+
+Next, we set `y` to six:
 
-spawn(move || { fib(200); })
 ```
-~~~
+# let x = 5;
+let y = 6;
+# println!("{}", x + y);
+```
 
-The documentation online would look like `spawn(move || { fib(200); })`, but when
-testing this code, the `fib` function will be included (so it can compile).
+Finally, we print the sum of `x` and `y`:
 
-Rustdoc will automatically add a `main()` wrapper around your code, and in the right
-place. For example:
+```
+# let x = 5;
+# let y = 6;
+println!("{}", x + y);
+```
+
+Here's the same explanation, in raw text:
+
+> First, we set `x` to five:
+>
+> ```text
+> let x = 5;
+> # let y = 6;
+> # println!("{}", x + y);
+> ```
+>
+> Next, we set `y` to six:
+>
+> ```text
+> # let x = 5;
+> let y = 6;
+> # println!("{}", x + y);
+> ```
+>
+> Finally, we print the sum of `x` and `y`:
+>
+> ```text
+> # let x = 5;
+> # let y = 6;
+> println!("{}", x + y);
+> ```
+
+By repeating all parts of the example, you can ensure that your example still
+compiles, while only showing the parts that are relevant to that part of your
+explanation.
+
+### Documenting macros
+
+Here’s an example of documenting a macro:
 
 ```
+/// Panic with a given message unless an expression evaluates to true.
+///
+/// # Examples
+///
+/// ```
+/// # #[macro_use] extern crate foo;
+/// # fn main() {
+/// panic_unless!(1 + 1 == 2, “Math is broken.”);
+/// # }
 /// ```
-/// use std::rc::Rc;
 ///
-/// let five = Rc::new(5);
+/// ```should_panic
+/// # #[macro_use] extern crate foo;
+/// # fn main() {
+/// panic_unless!(true == false, “I’m broken.”);
+/// # }
+/// ```
+#[macro_export]
+macro_rules! panic_unless {
+    ($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } });
+}
+# fn main() {}
+```
+
+You’ll note three things: we need to add our own `extern crate` line, so that
+we can add the `#[macro_use]` attribute. Second, we’ll need to add our own
+`main()` as well. Finally, a judicious use of `#` to comment out those two
+things, so they don’t show up in the output.
+
+### Running documentation tests
+
+To run the tests, either
+
+```bash
+$ rustdoc --test path/to/my/crate/root.rs
+# or
+$ cargo test
+```
+
+That's right, `cargo test` tests embedded documentation too.
+
+There are a few more annotations that are useful to help `rustdoc` do the right
+thing when testing your code:
+
+```
+/// ```ignore
+/// fn foo() {
 /// ```
 # fn foo() {}
 ```
 
-This will end up testing:
+The `ignore` directive tells Rust to ignore your code. This is almost never
+what you want, as it's the most generic. Instead, consider annotating it
+with `text` if it's not code, or using `#`s to get a working example that
+only shows the part you care about.
 
 ```
-fn main() {
-    use std::rc::Rc;
-    let five = Rc::new(5);
+/// ```should_panic
+/// assert!(false);
+/// ```
+# fn foo() {}
+```
+
+`should_panic` tells `rustdoc` that the code should compile correctly, but
+not actually pass as a test.
+
+```
+/// ```no_run
+/// loop {
+///     println!("Hello, world");
+/// }
+/// ```
+# fn foo() {}
+```
+
+The `no_run` attribute will compile your code, but not run it. This is
+important for examples such as "Here's how to start up a network service,"
+which you would want to make sure compile, but might run in an infinite loop!
+
+### Documenting modules
+
+Rust has another kind of doc comment, `//!`. This comment doesn't document the next item, but the enclosing item. In other words:
+
+```
+mod foo {
+    //! This is documentation for the `foo` module.
+    //!
+    //! # Examples
+
+    // ...
 }
 ```
 
-Here's the full algorithm:
+This is where you'll see `//!` used most often: for module documentation. If
+you have a module in `foo.rs`, you'll often open its code and see this:
+
+```
+//! A module for using `foo`s.
+//!
+//! The `foo` module contains a lot of useful functionality blah blah blah
+```
+
+### Documentation comment style
+
+Check out [RFC 505][rfc505] for full conventions around the style and format of
+documentation.
 
-1. Given a code block, if it does not contain `fn main`, it is wrapped in `fn main() { your_code }`
-2. Given that result, if it contains no `extern crate` directives but it also
-   contains the name of the crate being tested, then `extern crate <name>` is
-   injected at the top.
-3. Some common `allow` attributes are added for documentation examples at the top.
+[rfc505]: https://github.com/rust-lang/rfcs/blob/master/text/0505-api-comment-conventions.md
+
+## Other documentation
+
+All of this behavior works in non-Rust source files too. Because comments
+are written in Markdown, they're often `.md` files.
+
+When you write documentation in Markdown files, you don't need to prefix
+the documentation with comments. For example:
+
+```
+/// # Examples
+///
+/// ```
+/// use std::rc::Rc;
+///
+/// let five = Rc::new(5);
+/// ```
+# fn foo() {}
+```
 
-## Running tests (advanced)
+is just
 
-Running tests often requires some special configuration to filter tests, find
-libraries, or try running ignored examples. The testing framework that rustdoc
-uses is built on crate `test`, which is also used when you compile crates with
-rustc's `--test` flag. Extra arguments can be passed to rustdoc's test harness
-with the `--test-args` flag.
+~~~markdown
+# Examples
 
-~~~console
-# Only run tests containing 'foo' in their name
-$ rustdoc --test lib.rs --test-args 'foo'
+```
+use std::rc::Rc;
 
-# See what's possible when running tests
-$ rustdoc --test lib.rs --test-args '--help'
+let five = Rc::new(5);
+```
 ~~~
 
-When testing a library, code examples will often show how functions are used,
-and this code often requires `use`-ing paths from the crate. To accommodate this,
-rustdoc will implicitly add `extern crate <crate>;` where `<crate>` is the name of
-the crate being tested to the top of each code example. This means that rustdoc
-must be able to find a compiled version of the library crate being tested. Extra
-search paths may be added via the `-L` flag to `rustdoc`.
+when it's in a Markdown file. There is one wrinkle though: Markdown files need
+to have a title like this:
 
-# Standalone Markdown files
+```markdown
+% The title
 
-As well as Rust crates, rustdoc supports rendering pure Markdown files
-into HTML and testing the code snippets from them. A Markdown file is
-detected by a `.md` or `.markdown` extension.
+This is the example documentation.
+```
 
-There are 4 options to modify the output that Rustdoc creates.
+This `%` line needs to be the very first line of the file.
 
-- `--markdown-css PATH`: adds a `<link rel="stylesheet">` tag pointing to `PATH`.
-- `--html-in-header FILE`: includes the contents of `FILE` at the
-  end of the `<head>...</head>` section.
-- `--html-before-content FILE`: includes the contents of `FILE`
-  directly after `<body>`, before the rendered content (including the
-  title).
-- `--html-after-content FILE`: includes the contents of `FILE`
-  directly before `</body>`, after all the rendered content.
+## `doc` attributes
 
-All of these can be specified multiple times, and they are output in
-the order in which they are specified. The first line of the file being rendered must
-be the title, prefixed with `%` (e.g. this page has `% Rust
-Documentation` on the first line).
+At a deeper level, documentation comments are sugar for documentation attributes:
+
+```
+/// this
+# fn foo() {}
 
-Like with a Rust crate, the `--test` argument will run the code
-examples to check they compile, and obeys any `--test-args` flags. The
-tests are named after the last `#` heading.
+#[doc="this"]
+# fn bar() {}
+```
+
+are the same, as are these:
+
+```
+//! this
+
+#![doc="/// this"]
+```
 
-# Re-exports
+You won't often see this attribute used for writing documentation, but it
+can be useful when changing some options, or when writing a macro.
 
-Rustdoc will show the documentation for a publc re-export in both places:
+### Re-exports
 
-```{rust,ignore}
+`rustdoc` will show the documentation for a public re-export in both places:
+
+```ignore
 extern crate foo;
 
 pub use foo::bar;
 ```
 
-This will create documentation for `bar` both inside the documentation for
-the crate `foo`, as well as the documentation for your crate. It will use
-the same documentation in both places.
+This will create documentation for bar both inside the documentation for the
+crate `foo`, as well as the documentation for your crate. It will use the same
+documentation in both places.
 
-This behavior can be supressed with `no_inline`:
+This behavior can be suppressed with `no_inline`:
 
-```{rust,ignore}
+```ignore
 extern crate foo;
 
 #[doc(no_inline)]
 pub use foo::bar;
 ```
+
+### Controlling HTML
+
+You can control a few aspects of the HTML that `rustdoc` generates through the
+`#![doc]` version of the attribute:
+
+```
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+       html_root_url = "http://doc.rust-lang.org/")];
+```
+
+This sets a few different options, with a logo, favicon, and a root URL.
+
+## Generation options
+
+`rustdoc` also contains a few other options on the command line, for further customiziation:
+
+- `--html-in-header FILE`: includes the contents of FILE at the end of the
+  `<head>...</head>` section.
+- `--html-before-content FILE`: includes the contents of FILE directly after
+  `<body>`, before the rendered content (including the search bar).
+- `--html-after-content FILE`: includes the contents of FILE after all the rendered content.
index 68b36e7a4b7ca225573b1accd19cf31c2534cc91..b9e7bd78c5b2fa26dd200d632ce8875b1da846e4 100644 (file)
@@ -200,15 +200,15 @@ Because these kinds of situations are relatively rare, use panics sparingly.
 # Upgrading failures to panics
 
 In certain circumstances, even though a function may fail, we may want to treat
-it as a panic instead. For example, `io::stdin().read_line()` returns an
-`IoResult<String>`, a form of `Result`, when there is an error reading the
-line. This allows us to handle and possibly recover from this sort of error.
+it as a panic instead. For example, `io::stdin().read_line(&mut buffer)` returns
+an `Result<usize>`, when there is an error reading the line. This allows us to
+handle and possibly recover from error.
 
 If we don't want to handle this error, and would rather just abort the program,
 we can use the `unwrap()` method:
 
 ```{rust,ignore}
-io::stdin().read_line().unwrap();
+io::stdin().read_line(&mut buffer).unwrap();
 ```
 
 `unwrap()` will `panic!` if the `Option` is `None`. This basically says "Give
@@ -219,10 +219,83 @@ shorter. Sometimes, just crashing is appropriate.
 There's another way of doing this that's a bit nicer than `unwrap()`:
 
 ```{rust,ignore}
-let input = io::stdin().read_line()
+let mut buffer = String::new();
+let input = io::stdin().read_line(&mut buffer)
                        .ok()
                        .expect("Failed to read line");
 ```
-`ok()` converts the `IoResult` into an `Option`, and `expect()` does the same
+
+`ok()` converts the `Result` into an `Option`, and `expect()` does the same
 thing as `unwrap()`, but takes a message. This message is passed along to the
 underlying `panic!`, providing a better error message if the code errors.
+
+# Using `try!`
+
+When writing code that calls many functions that return the `Result` type, the
+error handling can be tedious. The `try!` macro hides some of the boilerplate
+of propagating errors up the call stack.
+
+It replaces this:
+
+```rust
+use std::fs::File;
+use std::io;
+use std::io::prelude::*;
+
+struct Info {
+    name: String,
+    age: i32,
+    rating: i32,
+}
+
+fn write_info(info: &Info) -> io::Result<()> {
+    let mut file = File::open("my_best_friends.txt").unwrap();
+
+    if let Err(e) = writeln!(&mut file, "name: {}", info.name) {
+        return Err(e)
+    }
+    if let Err(e) = writeln!(&mut file, "age: {}", info.age) {
+        return Err(e)
+    }
+    if let Err(e) = writeln!(&mut file, "rating: {}", info.rating) {
+        return Err(e)
+    }
+
+    return Ok(());
+}
+```
+
+With this:
+
+```rust
+use std::fs::File;
+use std::io;
+use std::io::prelude::*;
+
+struct Info {
+    name: String,
+    age: i32,
+    rating: i32,
+}
+
+fn write_info(info: &Info) -> io::Result<()> {
+    let mut file = try!(File::open("my_best_friends.txt"));
+
+    try!(writeln!(&mut file, "name: {}", info.name));
+    try!(writeln!(&mut file, "age: {}", info.age));
+    try!(writeln!(&mut file, "rating: {}", info.rating));
+
+    return Ok(());
+}
+```
+
+Wrapping an expression in `try!` will result in the unwrapped success (`Ok`)
+value, unless the result is `Err`, in which case `Err` is returned early from
+the enclosing function.
+
+It's worth noting that you can only use `try!` from a function that returns a
+`Result`, which means that you cannot use `try!` inside of `main()`, because
+`main()` doesn't return anything.
+
+`try!` makes use of [`FromError`](../std/error/#the-fromerror-trait) to determine
+what to return in the error case.
index 97e826579fd9bbc473c13c6d2d0bd4c7db0e0ead..23f6e17b860b23a13da61e5e95db73eca0bf370b 100644 (file)
@@ -12,6 +12,7 @@ The following is a minimal example of calling a foreign function which will
 compile if snappy is installed:
 
 ```no_run
+# #![feature(libc)]
 extern crate libc;
 use libc::size_t;
 
@@ -45,6 +46,7 @@ keeping the binding correct at runtime.
 The `extern` block can be extended to cover the entire snappy API:
 
 ```no_run
+# #![feature(libc)]
 extern crate libc;
 use libc::{c_int, size_t};
 
@@ -80,6 +82,7 @@ length is number of elements currently contained, and the capacity is the total
 the allocated memory. The length is less than or equal to the capacity.
 
 ```
+# #![feature(libc)]
 # extern crate libc;
 # use libc::{c_int, size_t};
 # unsafe fn snappy_validate_compressed_buffer(_: *const u8, _: size_t) -> c_int { 0 }
@@ -104,6 +107,7 @@ required capacity to hold the compressed output. The vector can then be passed t
 the true length after compression for setting the length.
 
 ```
+# #![feature(libc)]
 # extern crate libc;
 # use libc::{size_t, c_int};
 # unsafe fn snappy_compress(a: *const u8, b: size_t, c: *mut u8,
@@ -130,6 +134,7 @@ Decompression is similar, because snappy stores the uncompressed size as part of
 format and `snappy_uncompressed_length` will retrieve the exact buffer size required.
 
 ```
+# #![feature(libc)]
 # extern crate libc;
 # use libc::{size_t, c_int};
 # unsafe fn snappy_uncompress(compressed: *const u8,
@@ -170,6 +175,8 @@ Foreign libraries often hand off ownership of resources to the calling code.
 When this occurs, we must use Rust's destructors to provide safety and guarantee
 the release of these resources (especially in the case of panic).
 
+For more about destructors, see the [Drop trait](../std/ops/trait.Drop.html).
+
 # Callbacks from C code to Rust functions
 
 Some external libraries require the usage of callbacks to report back their
@@ -359,31 +366,6 @@ A few examples of how this model can be used are:
 
 On OSX, frameworks behave with the same semantics as a dynamic library.
 
-## The `link_args` attribute
-
-There is one other way to tell rustc how to customize linking, and that is via
-the `link_args` attribute. This attribute is applied to `extern` blocks and
-specifies raw flags which need to get passed to the linker when producing an
-artifact. An example usage would be:
-
-``` no_run
-#![feature(link_args)]
-
-#[link_args = "-foo -bar -baz"]
-extern {}
-# fn main() {}
-```
-
-Note that this feature is currently hidden behind the `feature(link_args)` gate
-because this is not a sanctioned way of performing linking. Right now rustc
-shells out to the system linker, so it makes sense to provide extra command line
-arguments, but this will not always be the case. In the future rustc may use
-LLVM directly to link native libraries in which case `link_args` will have no
-meaning.
-
-It is highly recommended to *not* use this attribute, and rather use the more
-formal `#[link(...)]` attribute on `extern` blocks instead.
-
 # Unsafe blocks
 
 Some operations, like dereferencing unsafe pointers or calling functions that have been marked
@@ -394,7 +376,7 @@ Unsafe functions, on the other hand, advertise it to the world. An unsafe functi
 this:
 
 ```
-unsafe fn kaboom(ptr: *const int) -> int { *ptr }
+unsafe fn kaboom(ptr: *const i32) -> i32 { *ptr }
 ```
 
 This function can only be called from an `unsafe` block or another `unsafe` function.
@@ -406,6 +388,7 @@ global state. In order to access these variables, you declare them in `extern`
 blocks with the `static` keyword:
 
 ```no_run
+# #![feature(libc)]
 extern crate libc;
 
 #[link(name = "readline")]
@@ -415,7 +398,7 @@ extern {
 
 fn main() {
     println!("You have readline version {} installed.",
-             rl_readline_version as int);
+             rl_readline_version as i32);
 }
 ```
 
@@ -424,6 +407,7 @@ interface. To do this, statics can be declared with `mut` so we can mutate
 them.
 
 ```no_run
+# #![feature(libc)]
 extern crate libc;
 
 use std::ffi::CString;
@@ -456,6 +440,7 @@ calling foreign functions. Some foreign functions, most notably the Windows API,
 conventions. Rust provides a way to tell the compiler which convention to use:
 
 ```
+# #![feature(libc)]
 extern crate libc;
 
 #[cfg(all(target_os = "win32", target_arch = "x86"))]
@@ -543,4 +528,3 @@ The `extern` makes this function adhere to the C calling convention, as
 discussed above in "[Foreign Calling
 Conventions](ffi.html#foreign-calling-conventions)". The `no_mangle`
 attribute turns off Rust's name mangling, so that it is easier to link to.
-
index ca1385fde9c74950d8992e3e33646ba540a7a40c..8e8ee8d63d626e6112bf4ef46f86180cf0743e4d 100644 (file)
@@ -179,7 +179,7 @@ Because this function will cause a crash, it will never return, and so it has
 the type '`!`', which is read "diverges." A diverging function can be used
 as any type:
 
-```should_fail
+```should_panic
 # fn diverges() -> ! {
 #    panic!("This function never returns!");
 # }
index 156f33748673b34a5c91b7ffed743143efe108e4..97898324847e4ab770ead3d437b1c48b9f02d446 100644 (file)
@@ -14,3 +14,26 @@ let z = (8, 2, 6);
 ```
 
 In the example above `x` and `y` have arity 2. `z` has arity 3.
+
+### Abstract Syntax Tree
+
+When a compiler is compiling your program, it does a number of different
+things. One of the things that it does is turn the text of your program into an
+'abstract syntax tree,' or 'AST.' This tree is a representation of the
+structure of your program. For example, `2 + 3` can be turned into a tree:
+
+```text
+  +
+ / \
+2   3
+```
+
+And `2 + (3 * 4)` would look like this:
+
+```text
+  +
+ / \
+2   *
+   / \
+  3   4
+```
diff --git a/src/doc/trpl/guessing-game.md b/src/doc/trpl/guessing-game.md
deleted file mode 100644 (file)
index 01f270f..0000000
+++ /dev/null
@@ -1,893 +0,0 @@
-% Guessing Game
-
-Okay! We've got the basics of Rust down. Let's write a bigger program.
-
-For our first project, we'll implement a classic beginner programming problem:
-the guessing game. Here's how it works: Our program will generate a random
-integer between one and a hundred. It will then prompt us to enter a guess.
-Upon entering our guess, it will tell us if we're too low or too high. Once we
-guess correctly, it will congratulate us. Sound good?
-
-## Set up
-
-Let's set up a new project. Go to your projects directory. Remember how we
-had to create our directory structure and a `Cargo.toml` for `hello_world`? Cargo
-has a command that does that for us. Let's give it a shot:
-
-```{bash}
-$ cd ~/projects
-$ cargo new guessing_game --bin
-$ cd guessing_game
-```
-
-We pass the name of our project to `cargo new`, and then the `--bin` flag,
-since we're making a binary, rather than a library.
-
-Check out the generated `Cargo.toml`:
-
-```toml
-[package]
-
-name = "guessing_game"
-version = "0.0.1"
-authors = ["Your Name <you@example.com>"]
-```
-
-Cargo gets this information from your environment. If it's not correct, go ahead
-and fix that.
-
-Finally, Cargo generated a "Hello, world!" for us. Check out `src/main.rs`:
-
-```{rust}
-fn main() {
-    println!("Hello, world!")
-}
-```
-
-Let's try compiling what Cargo gave us:
-
-```{bash}
-$ cargo build
-   Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
-```
-
-Excellent! Open up your `src/main.rs` again. We'll be writing all of
-our code in this file. We'll talk about multiple-file projects later on in the
-guide.
-
-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:
-
-```bash
-$ cargo run
-   Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
-     Running `target/guessing_game`
-Hello, world!
-```
-
-Great! The `run` command comes in handy when you need to rapidly iterate on a project.
-Our game is just such a project, we need to quickly test each iteration before moving on to the next one.
-
-## Processing a Guess
-
-Let's get to it! The first thing we need to do for our guessing game is
-allow our player to input a guess. Put this in your `src/main.rs`:
-
-```{rust,no_run}
-use std::old_io;
-
-fn main() {
-    println!("Guess the number!");
-
-    println!("Please input your guess.");
-
-    let input = old_io::stdin().read_line()
-                           .ok()
-                           .expect("Failed to read line");
-
-    println!("You guessed: {}", input);
-}
-```
-
-You've seen this code before, when we talked about standard input. We
-import the `std::io` module with `use`, and then our `main` function contains
-our program's logic. We print a little message announcing the game, ask the
-user to input a guess, get their input, and then print it out.
-
-Because we talked about this in the section on standard I/O, I won't go into
-more details here. If you need a refresher, go re-read that section.
-
-## Generating a secret number
-
-Next, we need to generate a secret number. To do that, we need to use Rust's
-random number generation, which we haven't talked about yet. Rust includes a
-bunch of interesting functions in its standard library. If you need a bit of
-code, it's possible that it's already been written for you! In this case,
-we do know that Rust has random number generation, but we don't know how to
-use it.
-
-Enter the docs. Rust has a page specifically to document the standard library.
-You can find that page [here](../std/index.html). There's a lot of information on
-that page, but the best part is the search bar. Right up at the top, there's
-a box that you can enter in a search term. The search is pretty primitive
-right now, but is getting better all the time. If you type "random" in that
-box, the page will update to [this one](../std/index.html?search=random). The very
-first result is a link to [`std::rand::random`](../std/rand/fn.random.html). If we
-click on that result, we'll be taken to its documentation page.
-
-This page shows us a few things: the type signature of the function, some
-explanatory text, and then an example. Let's try to modify our code to add in the
-`random` function and see what happens:
-
-```{rust,ignore}
-use std::old_io;
-use std::rand;
-
-fn main() {
-    println!("Guess the number!");
-
-    let secret_number = (rand::random() % 100) + 1; // secret_number: i32
-
-    println!("The secret number is: {}", secret_number);
-
-    println!("Please input your guess.");
-
-    let input = old_io::stdin().read_line()
-                           .ok()
-                           .expect("Failed to read line");
-
-
-    println!("You guessed: {}", input);
-}
-```
-
-The first thing we changed was to `use std::rand`, as the docs
-explained.  We then added in a `let` expression to create a variable binding
-named `secret_number`, and we printed out its result.
-
-Also, you may wonder why we are using `%` on the result of `rand::random()`.
-This operator is called *modulo*, and it returns the remainder of a division.
-By taking the modulo of the result of `rand::random()`, we're limiting the
-values to be between 0 and 99. Then, we add one to the result, making it from 1
-to 100. Using modulo can give you a very, very small bias in the result, but
-for this example, it is not important.
-
-Let's try to compile this using `cargo build`:
-
-```bash
-$ 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
-src/main.rs:7     let secret_number = (rand::random() % 100) + 1;
-                                       ^~~~~~~~
-error: aborting due to previous error
-```
-
-It didn't work! Rust says "the type of this value must be known in this
-context." What's up with that? Well, as it turns out, `rand::random()` can
-generate many kinds of random values, not just integers. And in this case, Rust
-isn't sure what kind of value `random()` should generate. So we have to help
-it. With number literals, we can just add an `i32` onto the end to tell Rust they're
-integers, but that does not work with functions. There's a different syntax,
-and it looks like this:
-
-```{rust,ignore}
-rand::random::<i32>();
-```
-
-This says "please give me a random `i32` value." We can change our code to use
-this hint:
-
-```{rust,no_run}
-use std::old_io;
-use std::rand;
-
-fn main() {
-    println!("Guess the number!");
-
-    let secret_number = (rand::random::<i32>() % 100) + 1;
-
-    println!("The secret number is: {}", secret_number);
-
-    println!("Please input your guess.");
-
-    let input = old_io::stdin().read_line()
-                           .ok()
-                           .expect("Failed to read line");
-
-
-    println!("You guessed: {}", input);
-}
-```
-
-Try running our new program a few times:
-
-```bash
-$ cargo run
-   Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
-     Running `target/guessing_game`
-Guess the number!
-The secret number is: 7
-Please input your guess.
-4
-You guessed: 4
-$ ./target/guessing_game
-Guess the number!
-The secret number is: 83
-Please input your guess.
-5
-You guessed: 5
-$ ./target/guessing_game
-Guess the number!
-The secret number is: -29
-Please input your guess.
-42
-You guessed: 42
-```
-
-Wait. Negative 29? We wanted a number between one and a hundred! We have two
-options here: we can either ask `random()` to generate an unsigned integer, which
-can only be positive, or we can use the `abs()` function. Let's go with the
-unsigned integer approach. If we want a random positive number, we should ask for
-a random positive number. Our code looks like this now:
-
-```{rust,no_run}
-use std::old_io;
-use std::rand;
-
-fn main() {
-    println!("Guess the number!");
-
-    let secret_number = (rand::random::<u32>() % 100) + 1;
-
-    println!("The secret number is: {}", secret_number);
-
-    println!("Please input your guess.");
-
-    let input = old_io::stdin().read_line()
-                           .ok()
-                           .expect("Failed to read line");
-
-
-    println!("You guessed: {}", input);
-}
-```
-
-And trying it out:
-
-```bash
-$ cargo run
-   Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
-     Running `target/guessing_game`
-Guess the number!
-The secret number is: 57
-Please input your guess.
-3
-You guessed: 3
-```
-
-Great! Next up: let's compare our guess to the secret guess.
-
-## Comparing guesses
-
-If you remember, earlier in the guide, we made a `cmp` function that compared
-two numbers. Let's add that in, along with a `match` statement to compare our
-guess to the secret number:
-
-```{rust,ignore}
-use std::old_io;
-use std::rand;
-use std::cmp::Ordering;
-
-fn main() {
-    println!("Guess the number!");
-
-    let secret_number = (rand::random::<u32>() % 100) + 1;
-
-    println!("The secret number is: {}", secret_number);
-
-    println!("Please input your guess.");
-
-    let input = old_io::stdin().read_line()
-                           .ok()
-                           .expect("Failed to read line");
-
-
-    println!("You guessed: {}", input);
-
-    match cmp(input, secret_number) {
-        Ordering::Less => println!("Too small!"),
-        Ordering::Greater => println!("Too big!"),
-        Ordering::Equal => println!("You win!"),
-    }
-}
-
-fn cmp(a: i32, b: i32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-```
-
-If we try to compile, we'll get some errors:
-
-```bash
-$ 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 `i32` but found `collections::string::String` (expected i32 but found struct collections::string::String)
-src/main.rs:20     match cmp(input, secret_number) {
-                             ^~~~~
-src/main.rs:20:22: 20:35 error: mismatched types: expected `i32` but found `u32` (expected i32 but found u32)
-src/main.rs:20     match cmp(input, secret_number) {
-                                    ^~~~~~~~~~~~~
-error: aborting due to 2 previous errors
-```
-
-This often happens when writing Rust programs, and is one of Rust's greatest
-strengths. You try out some code, see if it compiles, and Rust tells you that
-you've done something wrong. In this case, our `cmp` function works on integers,
-but we've given it unsigned integers. In this case, the fix is easy, because
-we wrote the `cmp` function! Let's change it to take `u32`s:
-
-```{rust,ignore}
-use std::old_io;
-use std::rand;
-use std::cmp::Ordering;
-
-fn main() {
-    println!("Guess the number!");
-
-    let secret_number = (rand::random::<u32>() % 100) + 1;
-
-    println!("The secret number is: {}", secret_number);
-
-    println!("Please input your guess.");
-
-    let input = old_io::stdin().read_line()
-                           .ok()
-                           .expect("Failed to read line");
-
-
-    println!("You guessed: {}", input);
-
-    match cmp(input, secret_number) {
-        Ordering::Less => println!("Too small!"),
-        Ordering::Greater => println!("Too big!"),
-        Ordering::Equal => println!("You win!"),
-    }
-}
-
-fn cmp(a: u32, b: u32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-```
-
-And try compiling again:
-
-```bash
-$ 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 `u32` but found `collections::string::String` (expected u32 but found struct collections::string::String)
-src/main.rs:20     match cmp(input, secret_number) {
-                             ^~~~~
-error: aborting due to previous error
-```
-
-This error is similar to the last one: we expected to get a `u32`, 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:
-
-```bash
-$ ./target/guessing_game
-Guess the number!
-The secret number is: 73
-Please input your guess.
-hello
-You guessed: hello
-```
-
-Oops! Also, you'll note that we just ran our program even though it didn't compile.
-This works because the older version we did successfully compile was still lying
-around. Gotta be careful!
-
-Anyway, we have a `String`, but we need a `u32`. What to do? Well, there's
-a function for that:
-
-```{rust,ignore}
-let input = old_io::stdin().read_line()
-                       .ok()
-                       .expect("Failed to read line");
-let input_num: Result<u32, _> = input.parse();
-```
-
-The `parse` function takes in a `&str` value and converts it into something.
-We tell it what kind of something with a type hint. Remember our type hint with
-`random()`? It looked like this:
-
-```{rust,ignore}
-rand::random::<u32>();
-```
-
-There's an alternate way of providing a hint too, and that's declaring the type
-in a `let`:
-
-```{rust,ignore}
-let x: u32 = rand::random();
-```
-
-In this case, we say `x` is a `u32` explicitly, so Rust is able to properly
-tell `random()` what to generate. In a similar fashion, both of these work:
-
-```{rust,ignore}
-let input_num = "5".parse::<u32>(); // input_num: Option<u32>
-let input_num: Result<u32, _> = "5".parse(); // input_num: Result<u32, <u32 as FromStr>::Err>
-```
-
-Here we're converting the `Result` returned by `parse` to an `Option` by using
-the `ok` method as well.  Anyway, with us now converting our input to a number,
-our code looks like this:
-
-```{rust,ignore}
-use std::old_io;
-use std::rand;
-use std::cmp::Ordering;
-
-fn main() {
-    println!("Guess the number!");
-
-    let secret_number = (rand::random::<u32>() % 100) + 1;
-
-    println!("The secret number is: {}", secret_number);
-
-    println!("Please input your guess.");
-
-    let input = old_io::stdin().read_line()
-                           .ok()
-                           .expect("Failed to read line");
-    let input_num: Result<u32, _> = input.parse();
-
-    println!("You guessed: {:?}", input_num);
-
-    match cmp(input_num, secret_number) {
-        Ordering::Less => println!("Too small!"),
-        Ordering::Greater => println!("Too big!"),
-        Ordering::Equal => println!("You win!"),
-    }
-}
-
-fn cmp(a: u32, b: u32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-```
-
-Let's try it out!
-
-```bash
-$ 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 `u32` but found `core::option::Option<u32>` (expected u32 but found enum core::option::Option)
-src/main.rs:22     match cmp(input_num, secret_number) {
-                             ^~~~~~~~~
-error: aborting due to previous error
-```
-
-Oh yeah! Our `input_num` has the type `Option<u32>`, rather than `u32`. We
-need to unwrap the Option. If you remember from before, `match` is a great way
-to do that. Try this code:
-
-```{rust,no_run}
-use std::old_io;
-use std::rand;
-use std::cmp::Ordering;
-
-fn main() {
-    println!("Guess the number!");
-
-    let secret_number = (rand::random::<u32>() % 100) + 1;
-
-    println!("The secret number is: {}", secret_number);
-
-    println!("Please input your guess.");
-
-    let input = old_io::stdin().read_line()
-                           .ok()
-                           .expect("Failed to read line");
-    let input_num: Result<u32, _> = input.parse();
-
-    let num = match input_num {
-        Ok(num) => num,
-        Err(_) => {
-            println!("Please input a number!");
-            return;
-        }
-    };
-
-
-    println!("You guessed: {}", num);
-
-    match cmp(num, secret_number) {
-        Ordering::Less => println!("Too small!"),
-        Ordering::Greater => println!("Too big!"),
-        Ordering::Equal => println!("You win!"),
-    }
-}
-
-fn cmp(a: u32, b: u32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-```
-
-We use a `match` to either give us the `u32` inside of the `Option`, or else
-print an error message and return. Let's give this a shot:
-
-```bash
-$ cargo run
-   Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
-     Running `target/guessing_game`
-Guess the number!
-The secret number is: 17
-Please input your guess.
-5
-Please input a number!
-```
-
-Uh, what? But we did!
-
-... actually, we didn't. See, when you get a line of input from `stdin()`,
-you get all the input. Including the `\n` character from you pressing Enter.
-Therefore, `parse()` sees the string `"5\n"` and says "nope, that's not a
-number; there's non-number stuff in there!" Luckily for us, `&str`s have an easy
-method we can use defined on them: `trim()`. One small modification, and our
-code looks like this:
-
-```{rust,no_run}
-use std::old_io;
-use std::rand;
-use std::cmp::Ordering;
-
-fn main() {
-    println!("Guess the number!");
-
-    let secret_number = (rand::random::<u32>() % 100) + 1;
-
-    println!("The secret number is: {}", secret_number);
-
-    println!("Please input your guess.");
-
-    let input = old_io::stdin().read_line()
-                           .ok()
-                           .expect("Failed to read line");
-    let input_num: Result<u32, _> = input.trim().parse();
-
-    let num = match input_num {
-        Ok(num) => num,
-        Err(_) => {
-            println!("Please input a number!");
-            return;
-        }
-    };
-
-
-    println!("You guessed: {}", num);
-
-    match cmp(num, secret_number) {
-        Ordering::Less => println!("Too small!"),
-        Ordering::Greater => println!("Too big!"),
-        Ordering::Equal => println!("You win!"),
-    }
-}
-
-fn cmp(a: u32, b: u32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-```
-
-Let's try it!
-
-```bash
-$ cargo run
-   Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
-     Running `target/guessing_game`
-Guess the number!
-The secret number is: 58
-Please input your guess.
-  76
-You guessed: 76
-Too big!
-```
-
-Nice! You can see I even added spaces before my guess, and it still figured
-out that I guessed 76. Run the program a few times, and verify that guessing
-the number works, as well as guessing a number too small.
-
-The Rust compiler helped us out quite a bit there! This technique is called
-"leaning on the compiler", and it's often useful when working on some code.
-Let the error messages help guide you towards the correct types.
-
-Now we've got most of the game working, but we can only make one guess. Let's
-change that by adding loops!
-
-## Looping
-
-As we already discussed, the `loop` keyword gives us an infinite loop.
-Let's add that in:
-
-```{rust,no_run}
-use std::old_io;
-use std::rand;
-use std::cmp::Ordering;
-
-fn main() {
-    println!("Guess the number!");
-
-    let secret_number = (rand::random::<u32>() % 100) + 1;
-
-    println!("The secret number is: {}", secret_number);
-
-    loop {
-
-        println!("Please input your guess.");
-
-        let input = old_io::stdin().read_line()
-                               .ok()
-                               .expect("Failed to read line");
-        let input_num: Result<u32, _> = input.trim().parse();
-
-        let num = match input_num {
-            Ok(num) => num,
-            Err(_) => {
-                println!("Please input a number!");
-                return;
-            }
-        };
-
-
-        println!("You guessed: {}", num);
-
-        match cmp(num, secret_number) {
-            Ordering::Less => println!("Too small!"),
-            Ordering::Greater => println!("Too big!"),
-            Ordering::Equal => println!("You win!"),
-        }
-    }
-}
-
-fn cmp(a: u32, b: u32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-```
-
-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:
-
-```bash
-$ cargo run
-   Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
-     Running `target/guessing_game`
-Guess the number!
-The secret number is: 59
-Please input your guess.
-45
-You guessed: 45
-Too small!
-Please input your guess.
-60
-You guessed: 60
-Too big!
-Please input your guess.
-59
-You guessed: 59
-You win!
-Please input your guess.
-quit
-Please input a number!
-```
-
-Ha! `quit` actually quits. As does any other non-number input. Well, this is
-suboptimal to say the least. First, let's actually quit when you win the game:
-
-```{rust,no_run}
-use std::old_io;
-use std::rand;
-use std::cmp::Ordering;
-
-fn main() {
-    println!("Guess the number!");
-
-    let secret_number = (rand::random::<u32>() % 100) + 1;
-
-    println!("The secret number is: {}", secret_number);
-
-    loop {
-
-        println!("Please input your guess.");
-
-        let input = old_io::stdin().read_line()
-                               .ok()
-                               .expect("Failed to read line");
-        let input_num: Result<u32, _> = input.trim().parse();
-
-        let num = match input_num {
-            Ok(num) => num,
-            Err(_) => {
-                println!("Please input a number!");
-                return;
-            }
-        };
-
-
-        println!("You guessed: {}", num);
-
-        match cmp(num, secret_number) {
-            Ordering::Less => println!("Too small!"),
-            Ordering::Greater => println!("Too big!"),
-            Ordering::Equal => {
-                println!("You win!");
-                return;
-            },
-        }
-    }
-}
-
-fn cmp(a: u32, b: u32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-```
-
-By adding the `return` line after the `You win!`, we'll exit the program when
-we win. We have just one more tweak to make: when someone inputs a non-number,
-we don't want to quit, we just want to ignore it. Change that `return` to
-`continue`:
-
-
-```{rust,no_run}
-use std::old_io;
-use std::rand;
-use std::cmp::Ordering;
-
-fn main() {
-    println!("Guess the number!");
-
-    let secret_number = (rand::random::<u32>() % 100) + 1;
-
-    println!("The secret number is: {}", secret_number);
-
-    loop {
-
-        println!("Please input your guess.");
-
-        let input = old_io::stdin().read_line()
-                               .ok()
-                               .expect("Failed to read line");
-        let input_num: Result<u32, _> = input.trim().parse();
-
-        let num = match input_num {
-            Ok(num) => num,
-            Err(_) => {
-                println!("Please input a number!");
-                continue;
-            }
-        };
-
-
-        println!("You guessed: {}", num);
-
-        match cmp(num, secret_number) {
-            Ordering::Less => println!("Too small!"),
-            Ordering::Greater => println!("Too big!"),
-            Ordering::Equal => {
-                println!("You win!");
-                return;
-            },
-        }
-    }
-}
-
-fn cmp(a: u32, b: u32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-```
-
-Now we should be good! Let's try:
-
-```bash
-$ cargo run
-   Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
-     Running `target/guessing_game`
-Guess the number!
-The secret number is: 61
-Please input your guess.
-10
-You guessed: 10
-Too small!
-Please input your guess.
-99
-You guessed: 99
-Too big!
-Please input your guess.
-foo
-Please input a number!
-Please input your guess.
-61
-You guessed: 61
-You win!
-```
-
-Awesome! With one tiny last tweak, we have finished the guessing game. Can you
-think of what it is? That's right, we don't want to print out the secret number.
-It was good for testing, but it kind of ruins the game. Here's our final source:
-
-```{rust,no_run}
-use std::old_io;
-use std::rand;
-use std::cmp::Ordering;
-
-fn main() {
-    println!("Guess the number!");
-
-    let secret_number = (rand::random::<u32>() % 100) + 1;
-
-    loop {
-
-        println!("Please input your guess.");
-
-        let input = old_io::stdin().read_line()
-                               .ok()
-                               .expect("Failed to read line");
-        let input_num: Result<u32, _> = input.trim().parse();
-
-        let num = match input_num {
-            Ok(num) => num,
-            Err(_) => {
-                println!("Please input a number!");
-                continue;
-            }
-        };
-
-
-        println!("You guessed: {}", num);
-
-        match cmp(num, secret_number) {
-            Ordering::Less => println!("Too small!"),
-            Ordering::Greater => println!("Too big!"),
-            Ordering::Equal => {
-                println!("You win!");
-                return;
-            },
-        }
-    }
-}
-
-fn cmp(a: u32, b: u32) -> Ordering {
-    if a < b { Ordering::Less }
-    else if a > b { Ordering::Greater }
-    else { Ordering::Equal }
-}
-```
-
-## Complete!
-
-At this point, you have successfully built the Guessing Game! Congratulations!
-
-You've now learned the basic syntax of Rust. All of this is relatively close to
-various other programming languages you have used in the past. These
-fundamental syntactical and semantic elements will form the foundation for the
-rest of your Rust education.
-
-Now that you're an expert at the basics, it's time to learn about some of
-Rust's more unique features.
index 5eb6cd7c5cd3ae4667d6c54d322bb176ed35037f..b45211e3a0847c198d1f0e47d6dc5a0b424fe84e 100644 (file)
@@ -18,13 +18,15 @@ the Cargo
 README](https://github.com/rust-lang/cargo#installing-cargo-from-nightlies)
 for specific instructions about installing it.
 
+## Converting to Cargo
+
 Let's convert Hello World to Cargo.
 
 To Cargo-ify our project, we need to do two things: Make a `Cargo.toml`
 configuration file, and put our source file in the right place. Let's
 do that part first:
 
-```{bash}
+```bash
 $ mkdir src
 $ mv main.rs src/main.rs
 ```
@@ -36,7 +38,7 @@ place for everything, and everything in its place.
 
 Next, our configuration file:
 
-```{bash}
+```bash
 $ editor Cargo.toml
 ```
 
@@ -73,19 +75,21 @@ well as what it is named.
 
 Once you have this file in place, we should be ready to build! Try this:
 
-```{bash}
+```bash
 $ cargo build
    Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world)
-$ ./target/hello_world
+$ ./target/debug/hello_world
 Hello, world!
 ```
 
 Bam! We build our project with `cargo build`, and run it with
-`./target/hello_world`. This hasn't bought us a whole lot over our simple use
+`./target/debug/hello_world`. This hasn't bought us a whole lot over our simple use
 of `rustc`, but think about the future: when our project has more than one
-file, we would need to call `rustc` more than once, and pass it a bunch of options to
+file, we would need to call `rustc` more than once and pass it a bunch of options to
 tell it to build everything together. With Cargo, as our project grows, we can
-just `cargo build` and it'll work the right way.
+just `cargo build`, and it'll work the right way. When your project is finally
+ready for release, you can use `cargo build --release` to compile your crates with
+optimizations.
 
 You'll also notice that Cargo has created a new file: `Cargo.lock`.
 
@@ -103,6 +107,62 @@ That's it! We've successfully built `hello_world` with Cargo. Even though our
 program is simple, it's using much of the real tooling that you'll use for the
 rest of your Rust career.
 
+## A New Project
+
+You don't have to go through this whole process every time you want to start a new
+project! Cargo has the ability to make a bare-bones project directory in which you
+can start developing right away.
+
+To start a new project with Cargo, use `cargo new`:
+
+```bash
+$ cargo new hello_world --bin
+```
+
+We're passing `--bin` because we're making a binary program: if we
+were making a library, we'd leave it off.
+
+Let's check out what Cargo has generated for us:
+
+```bash
+$ cd hello_world
+$ tree .
+.
+├── Cargo.toml
+└── src
+    └── main.rs
+
+1 directory, 2 files
+```
+
+If you don't have the `tree` command, you can probably get it from your distro's package
+manager. It's not necessary, but it's certainly useful.
+
+This is all we need to get started. First, let's check out `Cargo.toml`:
+
+```toml
+[package]
+
+name = "hello_world"
+version = "0.0.1"
+authors = ["Your Name <you@example.com>"]
+```
+
+Cargo has populated this file with reasonable defaults based off the arguments you gave
+it and your `git` global configuration. You may notice that Cargo has also initialized
+the `hello_world` directory as a `git` repository.
+
+Here's what's in `src/main.rs`:
+
+```rust
+fn main() {
+    println!("Hello, world!");
+}
+```
+
+Cargo has generated a "Hello World!" for us, and you're ready to start coding! A
+much more in-depth guide to Cargo can be found [here](http://doc.crates.io/guide.html).
+
 Now that you've got the tools down, let's actually learn more about the Rust
 language itself. These are the basics that will serve you well through the rest
 of your time with Rust.
index a350df67b1759ebe47afc150dd917d393ce1e4cf..7dac49987d84908ac37dd4ce6cce80fdabfa3c6c 100644 (file)
@@ -34,6 +34,20 @@ if x == 5 {
 }
 ```
 
+If there is more than one case, use an `else if`:
+
+```rust
+let x = 5;
+
+if x == 5 {
+    println!("x is five!");
+} else if x == 6 {
+    println!("x is six!");
+} else {
+    println!("x is not five or six :(");
+}
+```
+
 This is all pretty standard. However, you can also do this:
 
 
diff --git a/src/doc/trpl/inline-assembly.md b/src/doc/trpl/inline-assembly.md
new file mode 100644 (file)
index 0000000..1a4592f
--- /dev/null
@@ -0,0 +1,141 @@
+% Inline Assembly
+
+For extremely low-level manipulations and performance reasons, one
+might wish to control the CPU directly. Rust supports using inline
+assembly to do this via the `asm!` macro. The syntax roughly matches
+that of GCC & Clang:
+
+```ignore
+asm!(assembly template
+   : output operands
+   : input operands
+   : clobbers
+   : options
+   );
+```
+
+Any use of `asm` is feature gated (requires `#![feature(asm)]` on the
+crate to allow) and of course requires an `unsafe` block.
+
+> **Note**: the examples here are given in x86/x86-64 assembly, but
+> all platforms are supported.
+
+## Assembly template
+
+The `assembly template` is the only required parameter and must be a
+literal string (i.e. `""`)
+
+```
+#![feature(asm)]
+
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn foo() {
+    unsafe {
+        asm!("NOP");
+    }
+}
+
+// other platforms
+#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+fn foo() { /* ... */ }
+
+fn main() {
+    // ...
+    foo();
+    // ...
+}
+```
+
+(The `feature(asm)` and `#[cfg]`s are omitted from now on.)
+
+Output operands, input operands, clobbers and options are all optional
+but you must add the right number of `:` if you skip them:
+
+```
+# #![feature(asm)]
+# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+# fn main() { unsafe {
+asm!("xor %eax, %eax"
+    :
+    :
+    : "eax"
+   );
+# } }
+```
+
+Whitespace also doesn't matter:
+
+```
+# #![feature(asm)]
+# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+# fn main() { unsafe {
+asm!("xor %eax, %eax" ::: "eax");
+# } }
+```
+
+## Operands
+
+Input and output operands follow the same format: `:
+"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
+expressions must be mutable lvalues:
+
+```
+# #![feature(asm)]
+# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn add(a: i32, b: i32) -> i32 {
+    let mut c = 0;
+    unsafe {
+        asm!("add $2, $0"
+             : "=r"(c)
+             : "0"(a), "r"(b)
+             );
+    }
+    c
+}
+# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+# fn add(a: i32, b: i32) -> i32 { a + b }
+
+fn main() {
+    assert_eq!(add(3, 14159), 14162)
+}
+```
+
+## Clobbers
+
+Some instructions modify registers which might otherwise have held
+different values so we use the clobbers list to indicate to the
+compiler not to assume any values loaded into those registers will
+stay valid.
+
+```
+# #![feature(asm)]
+# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+# fn main() { unsafe {
+// Put the value 0x200 in eax
+asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
+# } }
+```
+
+Input and output registers need not be listed since that information
+is already communicated by the given constraints. Otherwise, any other
+registers used either implicitly or explicitly should be listed.
+
+If the assembly changes the condition code register `cc` should be
+specified as one of the clobbers. Similarly, if the assembly modifies
+memory, `memory` should also be specified.
+
+## Options
+
+The last section, `options` is specific to Rust. The format is comma
+separated literal strings (i.e. `:"foo", "bar", "baz"`). It's used to
+specify some extra info about the inline assembly:
+
+Current valid options are:
+
+1. *volatile* - specifying this is analogous to
+   `__asm__ __volatile__ (...)` in gcc/clang.
+2. *alignstack* - certain instructions expect the stack to be
+   aligned a certain way (i.e. SSE) and specifying this indicates to
+   the compiler to insert its usual stack alignment code
+3. *intel* - use intel syntax instead of the default AT&T.
+
index 5bc33d0a232eab1d41ecee093f5ce6cb4d75a834..288a4a158fb80d6ab466b0e1f30e5f624cc0f623 100644 (file)
@@ -6,14 +6,14 @@ Linux or a Mac, all you need to do is this (note that you don't need to type
 in the `$`s, they just indicate the start of each command):
 
 ```bash
-$ curl -L https://static.rust-lang.org/rustup.sh | sudo sh
+$ curl -sf -L https://static.rust-lang.org/rustup.sh | sudo sh
 ```
 
 If you're concerned about the [potential insecurity](http://curlpipesh.tumblr.com/) of using `curl | sudo sh`,
 please keep reading and see our disclaimer below. And feel free to use a two-step version of the installation and examine our installation script:
 
 ```bash
-$ curl -L https://static.rust-lang.org/rustup.sh -O
+$ curl -f -L https://static.rust-lang.org/rustup.sh -O
 $ sudo sh rustup.sh
 ```
 
@@ -70,14 +70,19 @@ If you've got Rust installed, you can open up a shell, and type this:
 $ rustc --version
 ```
 
-You should see some output that looks something like this:
+You should see the version number, commit hash, commit date and build date:
 
 ```bash
-rustc 1.0.0-nightly (f11f3e7ba 2015-01-04 20:02:14 +0000)
+rustc 1.0.0-nightly (f11f3e7ba 2015-01-04) (built 2015-01-06)
 ```
 
 If you did, Rust has been installed successfully! Congrats!
 
+This installer also installs a copy of the documentation locally, so you can
+read it offline. On UNIX systems, `/usr/local/share/doc/rust` is the location.
+On Windows, it's in a `share/doc` directory, inside wherever you installed Rust
+to.
+
 If not, there are a number of places where you can get help. The easiest is
 [the #rust IRC channel on irc.mozilla.org](irc://irc.mozilla.org/#rust), which
 you can access through
diff --git a/src/doc/trpl/intrinsics.md b/src/doc/trpl/intrinsics.md
new file mode 100644 (file)
index 0000000..25f7c54
--- /dev/null
@@ -0,0 +1,25 @@
+% Intrinsics
+
+> **Note**: intrinsics will forever have an unstable interface, it is
+> recommended to use the stable interfaces of libcore rather than intrinsics
+> directly.
+
+These are imported as if they were FFI functions, with the special
+`rust-intrinsic` ABI. For example, if one was in a freestanding
+context, but wished to be able to `transmute` between types, and
+perform efficient pointer arithmetic, one would import those functions
+via a declaration like
+
+```
+# #![feature(intrinsics)]
+# fn main() {}
+
+extern "rust-intrinsic" {
+    fn transmute<T, U>(x: T) -> U;
+
+    fn offset<T>(dst: *const T, offset: isize) -> *const T;
+}
+```
+
+As with any other FFI functions, these are always `unsafe` to call.
+
index 45c08af04f8773c6be6469cf0b2b7031ab27c735..55776bee3b585c91e8b0e7bc02b7ca8f5f43571c 100644 (file)
@@ -57,14 +57,13 @@ for i in 0..nums.len() {
 }
 ```
 
-This is strictly worse than using an actual iterator. The `.iter()` method on
-vectors returns an iterator which iterates through a reference to each element
-of the vector in turn. So write this:
+This is strictly worse than using an actual iterator. You can iterate over vectors
+directly, so write this:
 
 ```rust
 let nums = vec![1, 2, 3];
 
-for num in nums.iter() {
+for num in &nums {
     println!("{}", num);
 }
 ```
@@ -86,16 +85,17 @@ see it. This code works fine too:
 ```rust
 let nums = vec![1, 2, 3];
 
-for num in nums.iter() {
+for num in &nums {
     println!("{}", *num);
 }
 ```
 
-Now we're explicitly dereferencing `num`. Why does `iter()` give us references?
-Well, if it gave us the data itself, we would have to be its owner, which would
-involve making a copy of the data and giving us the copy. With references,
-we're just borrowing a reference to the data, and so it's just passing
-a reference, without needing to do the copy.
+Now we're explicitly dereferencing `num`. Why does `&nums` give us
+references?  Firstly, because we explicitly asked it to with
+`&`. Secondly, if it gave us the data itself, we would have to be its
+owner, which would involve making a copy of the data and giving us the
+copy. With references, we're just borrowing a reference to the data,
+and so it's just passing a reference, without needing to do the move.
 
 So, now that we've established that ranges are often not what you want, let's
 talk about what you do want instead.
@@ -230,9 +230,9 @@ let nums = (1..100).collect::<Vec<i32>>();
 Now, `collect()` will require that the range gives it some numbers, and so
 it will do the work of generating the sequence.
 
-Ranges are one of two basic iterators that you'll see. The other is `iter()`,
-which you've used before. `iter()` can turn a vector into a simple iterator
-that gives you each element in turn:
+Ranges are one of two basic iterators that you'll see. The other is `iter()`.
+`iter()` can turn a vector into a simple iterator that gives you each element
+in turn:
 
 ```rust
 let nums = [1, 2, 3];
@@ -243,10 +243,12 @@ for num in nums.iter() {
 ```
 
 These two basic iterators should serve you well. There are some more
-advanced iterators, including ones that are infinite. Like `count`:
+advanced iterators, including ones that are infinite. Like using range syntax
+and `step_by`:
 
 ```rust
-std::iter::count(1, 5);
+# #![feature(step_by)]
+(1..).step_by(5);
 ```
 
 This iterator counts up from one, adding five each time. It will give
@@ -291,10 +293,11 @@ just use `for` instead.
 There are tons of interesting iterator adapters. `take(n)` will return an
 iterator over the next `n` elements of the original iterator, note that this
 has no side effect on the original iterator. Let's try it out with our infinite
-iterator from before, `count()`:
+iterator from before:
 
 ```rust
-for i in std::iter::count(1, 5).take(5) {
+# #![feature(step_by)]
+for i in (1..).step_by(5).take(5) {
     println!("{}", i);
 }
 ```
diff --git a/src/doc/trpl/lang-items.md b/src/doc/trpl/lang-items.md
new file mode 100644 (file)
index 0000000..5c27c03
--- /dev/null
@@ -0,0 +1,79 @@
+% Lang items
+
+> **Note**: lang items are often provided by crates in the Rust distribution,
+> and lang items themselves have an unstable interface. It is recommended to use
+> officially distributed crates instead of defining your own lang items.
+
+The `rustc` compiler has certain pluggable operations, that is,
+functionality that isn't hard-coded into the language, but is
+implemented in libraries, with a special marker to tell the compiler
+it exists. The marker is the attribute `#[lang="..."]` and there are
+various different values of `...`, i.e. various different 'lang
+items'.
+
+For example, `Box` pointers require two lang items, one for allocation
+and one for deallocation. A freestanding program that uses the `Box`
+sugar for dynamic allocations via `malloc` and `free`:
+
+```
+#![feature(lang_items, box_syntax, start, no_std, libc)]
+#![no_std]
+
+extern crate libc;
+
+extern {
+    fn abort() -> !;
+}
+
+#[lang = "owned_box"]
+pub struct Box<T>(*mut T);
+
+#[lang="exchange_malloc"]
+unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
+    let p = libc::malloc(size as libc::size_t) as *mut u8;
+
+    // malloc failed
+    if p as usize == 0 {
+        abort();
+    }
+
+    p
+}
+#[lang="exchange_free"]
+unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
+    libc::free(ptr as *mut libc::c_void)
+}
+
+#[start]
+fn main(argc: isize, argv: *const *const u8) -> isize {
+    let x = box 1;
+
+    0
+}
+
+#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
+#[lang = "eh_personality"] extern fn eh_personality() {}
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+```
+
+Note the use of `abort`: the `exchange_malloc` lang item is assumed to
+return a valid pointer, and so needs to do the check internally.
+
+Other features provided by lang items include:
+
+- overloadable operators via traits: the traits corresponding to the
+  `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
+  marked with lang items; those specific four are `eq`, `ord`,
+  `deref`, and `add` respectively.
+- stack unwinding and general failure; the `eh_personality`, `fail`
+  and `fail_bounds_checks` lang items.
+- the traits in `std::marker` used to indicate types of
+  various kinds; lang items `send`, `sync` and `copy`.
+- the marker types and variance indicators found in
+  `std::marker`; lang items `covariant_type`,
+  `contravariant_lifetime`, etc.
+
+Lang items are loaded lazily by the compiler; e.g. if one never uses
+`Box` then there is no need to define functions for `exchange_malloc`
+and `exchange_free`. `rustc` will emit an error when an item is needed
+but not found in the current crate or any that it depends on.
diff --git a/src/doc/trpl/link-args.md b/src/doc/trpl/link-args.md
new file mode 100644 (file)
index 0000000..ee5159a
--- /dev/null
@@ -0,0 +1,25 @@
+% Link args
+
+There is one other way to tell rustc how to customize linking, and that is via
+the `link_args` attribute. This attribute is applied to `extern` blocks and
+specifies raw flags which need to get passed to the linker when producing an
+artifact. An example usage would be:
+
+``` no_run
+#![feature(link_args)]
+
+#[link_args = "-foo -bar -baz"]
+extern {}
+# fn main() {}
+```
+
+Note that this feature is currently hidden behind the `feature(link_args)` gate
+because this is not a sanctioned way of performing linking. Right now rustc
+shells out to the system linker, so it makes sense to provide extra command line
+arguments, but this will not always be the case. In the future rustc may use
+LLVM directly to link native libraries in which case `link_args` will have no
+meaning.
+
+It is highly recommended to *not* use this attribute, and rather use the more
+formal `#[link(...)]` attribute on `extern` blocks instead.
+
index 4301149d1f8b3d62a26c07ba395f43976c5c3a5c..28f02b1ffe1528239ba2ba798a12dad126dde496 100644 (file)
@@ -123,7 +123,7 @@ We now loop forever with `loop` and use `break` to break out early.
 iteration. This will only print the odd numbers:
 
 ```{rust}
-for x in 0u32..10 {
+for x in 0..10 {
     if x % 2 == 0 { continue; }
 
     println!("{}", x);
index ce6fa3ce949cd7a1f0878ca79bf20358a5127ba1..7e19ec94ee745160e4fe01ecbcb47e056b43b81d 100644 (file)
@@ -37,7 +37,7 @@ number of elements.
 
 ```rust
 let x: Vec<u32> = vec![1, 2, 3];
-# assert_eq!(&[1,2,3], &x);
+# assert_eq!(x, [1, 2, 3]);
 ```
 
 This can't be an ordinary function, because it takes any number of arguments.
@@ -51,7 +51,7 @@ let x: Vec<u32> = {
     temp_vec.push(3);
     temp_vec
 };
-# assert_eq!(&[1,2,3], &x);
+# assert_eq!(x, [1, 2, 3]);
 ```
 
 We can implement this shorthand, using a macro: [^actual]
@@ -73,7 +73,7 @@ macro_rules! vec {
     };
 }
 # fn main() {
-#     assert_eq!(&[1,2,3], &vec![1,2,3]);
+#     assert_eq!(vec![1,2,3], [1, 2, 3]);
 # }
 ```
 
@@ -189,14 +189,12 @@ shorthand for a data type could be valid as either an expression or a pattern.
 
 ## Repetition
 
-The repetition behavior can seem somewhat magical, especially when multiple
-names are bound at multiple nested levels of repetition. The two rules to keep
-in mind are:
+The repetition operator follows two principal rules:
 
-1. the behavior of `$(...)*` is to walk through one "layer" of repetitions, for
-all of the `$name`s it contains, in lockstep, and
+1. `$(...)*` walks through one "layer" of repetitions, for all of the `$name`s
+   it contains, in lockstep, and
 2. each `$name` must be under at least as many `$(...)*`s as it was matched
-against. If it is under more, it'll be duplicated, as appropriate.
+   against. If it is under more, it'll be duplicated, as appropriate.
 
 This baroque macro illustrates the duplication of variables from outer
 repetition levels.
@@ -226,6 +224,10 @@ That's most of the matcher syntax. These examples use `$(...)*`, which is a
 more" match. Both forms optionally include a separator, which can be any token
 except `+` or `*`.
 
+This system is based on
+"[Macro-by-Example](http://www.cs.indiana.edu/ftp/techreports/TR206.pdf)"
+(PDF link).
+
 # Hygiene
 
 Some languages implement macros using simple text substitution, which leads to
@@ -273,19 +275,26 @@ macro, using [a GNU C extension] to emulate Rust's expression blocks.
 })
 ```
 
-This looks reasonable, but watch what happens in this example:
+Here's a simple use case that goes terribly wrong:
 
 ```text
 const char *state = "reticulating splines";
-LOG(state);
+LOG(state)
 ```
 
-The program will likely segfault, after it tries to execute
+This expands to
 
 ```text
-printf("log(%d): %s\n", state, state);
+const char *state = "reticulating splines";
+int state = get_log_state();
+if (state > 0) {
+    printf("log(%d): %s\n", state, state);
+}
 ```
 
+The second variable named `state` shadows the first one.  This is a problem
+because the print statement should refer to both of them.
+
 The equivalent Rust macro has the desired behavior.
 
 ```rust
@@ -357,6 +366,64 @@ fn main() {
 
 [items]: ../reference.html#items
 
+# Recursive macros
+
+A macro's expansion can include more macro invocations, including invocations
+of the very same macro being expanded.  These recursive macros are useful for
+processing tree-structured input, as illustrated by this (simplistic) HTML
+shorthand:
+
+```rust
+# #![allow(unused_must_use)]
+macro_rules! write_html {
+    ($w:expr, ) => (());
+
+    ($w:expr, $e:tt) => (write!($w, "{}", $e));
+
+    ($w:expr, $tag:ident [ $($inner:tt)* ] $($rest:tt)*) => {{
+        write!($w, "<{}>", stringify!($tag));
+        write_html!($w, $($inner)*);
+        write!($w, "</{}>", stringify!($tag));
+        write_html!($w, $($rest)*);
+    }};
+}
+
+fn main() {
+#   // FIXME(#21826)
+    use std::fmt::Write;
+    let mut out = String::new();
+
+    write_html!(&mut out,
+        html[
+            head[title["Macros guide"]]
+            body[h1["Macros are the best!"]]
+        ]);
+
+    assert_eq!(out,
+        "<html><head><title>Macros guide</title></head>\
+         <body><h1>Macros are the best!</h1></body></html>");
+}
+```
+
+# Debugging macro code
+
+To see the results of expanding macros, run `rustc --pretty expanded`. The
+output represents a whole crate, so you can also feed it back in to `rustc`,
+which will sometimes produce better error messages than the original
+compilation. Note that the `--pretty expanded` output may have a different
+meaning if multiple variables of the same name (but different syntax contexts)
+are in play in the same scope. In this case `--pretty expanded,hygiene` will
+tell you about the syntax contexts.
+
+`rustc` provides two syntax extensions that help with macro debugging. For now,
+they are unstable and require feature gates.
+
+* `log_syntax!(...)` will print its arguments to standard output, at compile
+  time, and "expand" to nothing.
+
+* `trace_macros!(true)` will enable a compiler message every time a macro is
+  expanded. Use `trace_macros!(false)` later in expansion to turn it off.
+
 # Further reading
 
 The [advanced macros chapter][] goes into more detail about macro syntax. It
index 64d540582a3998bd7acd97c745379be9d2ba21ba..18542e58bbfd2b878f06d982f8f801f3a6882922 100644 (file)
@@ -23,6 +23,7 @@ the ability to use this *method call syntax* via the `impl` keyword.
 Here's how it works:
 
 ```{rust}
+# #![feature(core)]
 struct Circle {
     x: f64,
     y: f64,
@@ -45,12 +46,35 @@ This will print `12.566371`.
 
 We've made a struct that represents a circle. We then write an `impl` block,
 and inside it, define a method, `area`. Methods take a  special first
-parameter, `&self`. There are three variants: `self`, `&self`, and `&mut self`.
+parameter, of which there are three variants: `self`, `&self`, and `&mut self`.
 You can think of this first parameter as being the `x` in `x.foo()`. The three
 variants correspond to the three kinds of thing `x` could be: `self` if it's
 just a value on the stack, `&self` if it's a reference, and `&mut self` if it's
-a mutable reference. We should default to using `&self`, as it's the most
-common.
+a mutable reference. We should default to using `&self`, as you should prefer
+borrowing over taking ownership, as well as taking immutable references
+over mutable ones. Here's an example of all three variants:
+
+```rust
+struct Circle {
+    x: f64,
+    y: f64,
+    radius: f64,
+}
+
+impl Circle {
+    fn reference(&self) {
+       println!("taking self by reference!");
+    }
+
+    fn mutable_reference(&mut self) {
+       println!("taking self by mutable reference!");
+    }
+
+    fn takes_ownership(self) {
+       println!("taking ownership of self!");
+    }
+}
+```
 
 Finally, as you may remember, the value of the area of a circle is `π*r²`.
 Because we took the `&self` parameter to `area`, we can use it just like any
@@ -65,6 +89,7 @@ original example, `foo.bar().baz()`? This is called 'method chaining', and we
 can do it by returning `self`.
 
 ```
+# #![feature(core)]
 struct Circle {
     x: f64,
     y: f64,
@@ -76,8 +101,8 @@ impl Circle {
         std::f64::consts::PI * (self.radius * self.radius)
     }
 
-    fn grow(&self) -> Circle {
-        Circle { x: self.x, y: self.y, radius: (self.radius * 10.0) }
+    fn grow(&self, increment: f64) -> Circle {
+        Circle { x: self.x, y: self.y, radius: self.radius + increment }
     }
 }
 
@@ -85,7 +110,7 @@ fn main() {
     let c = Circle { x: 0.0, y: 0.0, radius: 2.0 };
     println!("{}", c.area());
 
-    let d = c.grow().area();
+    let d = c.grow(2.0).area();
     println!("{}", d);
 }
 ```
@@ -100,7 +125,7 @@ fn grow(&self) -> Circle {
 ```
 
 We just say we're returning a `Circle`. With this method, we can grow a new
-circle with an area that's 100 times larger than the old one.
+circle to any arbitrary size.
 
 ## Static methods
 
@@ -142,6 +167,7 @@ have method overloading, named arguments, or variable arguments. We employ
 the builder pattern instead. It looks like this:
 
 ```
+# #![feature(core)]
 struct Circle {
     x: f64,
     y: f64,
@@ -155,38 +181,46 @@ impl Circle {
 }
 
 struct CircleBuilder {
-    coordinate: f64,
+    x: f64,
+    y: f64,
     radius: f64,
 }
 
 impl CircleBuilder {
     fn new() -> CircleBuilder {
-        CircleBuilder { coordinate: 0.0, radius: 0.0, }
+        CircleBuilder { x: 0.0, y: 0.0, radius: 0.0, }
     }
 
-    fn coordinate(&mut self, coordinate: f64) -> &mut CircleBuilder {
-       self.coordinate = coordinate;
-       self
+    fn x(&mut self, coordinate: f64) -> &mut CircleBuilder {
+        self.x = coordinate;
+        self
+    }
+
+    fn y(&mut self, coordinate: f64) -> &mut CircleBuilder {
+        self.x = coordinate;
+        self
     }
 
     fn radius(&mut self, radius: f64) -> &mut CircleBuilder {
-       self.radius = radius;
-       self
+        self.radius = radius;
+        self
     }
 
     fn finalize(&self) -> Circle {
-        Circle { x: self.coordinate, y: self.coordinate, radius: self.radius }
+        Circle { x: self.x, y: self.y, radius: self.radius }
     }
 }
 
 fn main() {
     let c = CircleBuilder::new()
-                .coordinate(10.0)
-                .radius(5.0)
+                .x(1.0)
+                .y(2.0)
+                .radius(2.0)
                 .finalize();
 
-
     println!("area: {}", c.area());
+    println!("x: {}", c.x);
+    println!("y: {}", c.y);
 }
 ```
 
index 20f1406aebbabae512dc67639a7b8cfbaab5dfe5..17a463842e71c39fa24c4d9935667a6362b47229 100644 (file)
@@ -12,7 +12,7 @@ Additionally, strings are not null-terminated and can contain null bytes.
 
 Rust has two main types of strings: `&str` and `String`.
 
-# &str
+# `&str`
 
 The first kind is a `&str`. This is pronounced a 'string slice'.
 String literals are of the type `&str`:
@@ -36,10 +36,40 @@ Like vector slices, string slices are simply a pointer plus a length. This
 means that they're a 'view' into an already-allocated string, such as a
 string literal or a `String`.
 
-# String
+## `str`
 
-A `String` is a heap-allocated string. This string is growable, and is also
-guaranteed to be UTF-8.
+You may occasionally see references to a `str` type, without the `&`. While
+this type does exist, it’s not something you want to use yourself. Sometimes,
+people confuse `str` for `String`, and write this:
+
+```rust
+struct S {
+    s: str,
+}
+```
+
+This leads to ugly errors:
+
+```text
+error: the trait `core::marker::Sized` is not implemented for the type `str` [E0277]
+note: `str` does not have a constant size known at compile-time
+```
+
+Instead, this `struct` should be
+
+```rust
+struct S {
+    s: String,
+}
+```
+
+So let’s talk about `String`s.
+
+# `String`
+
+A `String` is a heap-allocated string. This string is growable, and is
+also guaranteed to be UTF-8. `String`s are commonly created by
+converting from a string slice using the `to_string` method.
 
 ```
 let mut s = "Hello".to_string();
@@ -49,7 +79,7 @@ s.push_str(", world.");
 println!("{}", s);
 ```
 
-You can coerce a `String` into a `&str` by dereferencing it:
+A reference to a `String` will automatically coerce to a string slice:
 
 ```
 fn takes_slice(slice: &str) {
@@ -58,7 +88,7 @@ fn takes_slice(slice: &str) {
 
 fn main() {
     let s = "Hello".to_string();
-    takes_slice(&*s);
+    takes_slice(&s);
 }
 ```
 
@@ -99,7 +129,7 @@ need, and it can make your lifetimes more complex.
 To write a function that's generic over types of strings, use `&str`.
 
 ```
-fn some_string_length(x: &str) -> uint {
+fn some_string_length(x: &str) -> usize {
     x.len()
 }
 
@@ -147,6 +177,7 @@ Rust provides iterators for each of these situations:
 Usually, the `graphemes()` method on `&str` is what you want:
 
 ```
+# #![feature(unicode)]
 let s = "u͔n͈̰̎i̙̮͚̦c͚̉o̼̩̰͗d͔̆̓ͥé";
 
 for l in s.graphemes(true) {
@@ -277,7 +308,18 @@ This will print:
 
 Many more bytes than graphemes!
 
-# Other Documentation
+# `Deref` coercions
+
+References to `String`s will automatically coerce into `&str`s. Like this:
 
-* [the `&str` API documentation](../std/str/index.html)
-* [the `String` API documentation](../std/string/index.html)
+```
+fn hello(s: &str) {
+   println!("Hello, {}!", s);
+}
+
+let slice = "Steve";
+let string = "Steve".to_string();
+
+hello(slice);
+hello(&string);
+```
diff --git a/src/doc/trpl/no-stdlib.md b/src/doc/trpl/no-stdlib.md
new file mode 100644 (file)
index 0000000..094c82a
--- /dev/null
@@ -0,0 +1,168 @@
+% No stdlib
+
+By default, `std` is linked to every Rust crate. In some contexts,
+this is undesirable, and can be avoided with the `#![no_std]`
+attribute attached to the crate.
+
+```ignore
+// a minimal library
+#![crate_type="lib"]
+#![feature(no_std)]
+#![no_std]
+# // fn main() {} tricked you, rustdoc!
+```
+
+Obviously there's more to life than just libraries: one can use
+`#[no_std]` with an executable, controlling the entry point is
+possible in two ways: the `#[start]` attribute, or overriding the
+default shim for the C `main` function with your own.
+
+The function marked `#[start]` is passed the command line parameters
+in the same format as C:
+
+```
+#![feature(lang_items, start, no_std, libc)]
+#![no_std]
+
+// Pull in the system libc library for what crt0.o likely requires
+extern crate libc;
+
+// Entry point for this program
+#[start]
+fn start(_argc: isize, _argv: *const *const u8) -> isize {
+    0
+}
+
+// These functions and traits are used by the compiler, but not
+// for a bare-bones hello world. These are normally
+// provided by libstd.
+#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
+#[lang = "eh_personality"] extern fn eh_personality() {}
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+# // fn main() {} tricked you, rustdoc!
+```
+
+To override the compiler-inserted `main` shim, one has to disable it
+with `#![no_main]` and then create the appropriate symbol with the
+correct ABI and the correct name, which requires overriding the
+compiler's name mangling too:
+
+```ignore
+#![feature(no_std)]
+#![no_std]
+#![no_main]
+#![feature(lang_items, start)]
+
+extern crate libc;
+
+#[no_mangle] // ensure that this symbol is called `main` in the output
+pub extern fn main(argc: i32, argv: *const *const u8) -> i32 {
+    0
+}
+
+#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
+#[lang = "eh_personality"] extern fn eh_personality() {}
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+# // fn main() {} tricked you, rustdoc!
+```
+
+
+The compiler currently makes a few assumptions about symbols which are available
+in the executable to call. Normally these functions are provided by the standard
+library, but without it you must define your own.
+
+The first of these three functions, `stack_exhausted`, is invoked whenever stack
+overflow is detected.  This function has a number of restrictions about how it
+can be called and what it must do, but if the stack limit register is not being
+maintained then a thread always has an "infinite stack" and this function
+shouldn't get triggered.
+
+The second of these three functions, `eh_personality`, is used by the
+failure mechanisms of the compiler. This is often mapped to GCC's
+personality function (see the
+[libstd implementation](../std/rt/unwind/index.html) for more
+information), but crates which do not trigger a panic can be assured
+that this function is never called. The final function, `panic_fmt`, is
+also used by the failure mechanisms of the compiler.
+
+## Using libcore
+
+> **Note**: the core library's structure is unstable, and it is recommended to
+> use the standard library instead wherever possible.
+
+With the above techniques, we've got a bare-metal executable running some Rust
+code. There is a good deal of functionality provided by the standard library,
+however, that is necessary to be productive in Rust. If the standard library is
+not sufficient, then [libcore](../core/index.html) is designed to be used
+instead.
+
+The core library has very few dependencies and is much more portable than the
+standard library itself. Additionally, the core library has most of the
+necessary functionality for writing idiomatic and effective Rust code.
+
+As an example, here is a program that will calculate the dot product of two
+vectors provided from C, using idiomatic Rust practices.
+
+```
+#![feature(lang_items, start, no_std, core, libc)]
+#![no_std]
+
+# extern crate libc;
+extern crate core;
+
+use core::prelude::*;
+
+use core::mem;
+
+#[no_mangle]
+pub extern fn dot_product(a: *const u32, a_len: u32,
+                          b: *const u32, b_len: u32) -> u32 {
+    use core::raw::Slice;
+
+    // Convert the provided arrays into Rust slices.
+    // The core::raw module guarantees that the Slice
+    // structure has the same memory layout as a &[T]
+    // slice.
+    //
+    // This is an unsafe operation because the compiler
+    // cannot tell the pointers are valid.
+    let (a_slice, b_slice): (&[u32], &[u32]) = unsafe {
+        mem::transmute((
+            Slice { data: a, len: a_len as usize },
+            Slice { data: b, len: b_len as usize },
+        ))
+    };
+
+    // Iterate over the slices, collecting the result
+    let mut ret = 0;
+    for (i, j) in a_slice.iter().zip(b_slice.iter()) {
+        ret += (*i) * (*j);
+    }
+    return ret;
+}
+
+#[lang = "panic_fmt"]
+extern fn panic_fmt(args: &core::fmt::Arguments,
+                    file: &str,
+                    line: u32) -> ! {
+    loop {}
+}
+
+#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
+#[lang = "eh_personality"] extern fn eh_personality() {}
+# #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 }
+# fn main() {}
+```
+
+Note that there is one extra lang item here which differs from the examples
+above, `panic_fmt`. This must be defined by consumers of libcore because the
+core library declares panics, but it does not define it. The `panic_fmt`
+lang item is this crate's definition of panic, and it must be guaranteed to
+never return.
+
+As can be seen in this example, the core library is intended to provide the
+power of Rust in all circumstances, regardless of platform requirements. Further
+libraries, such as liballoc, add functionality to libcore which make other
+platform-specific assumptions, but continue to be more portable than the
+standard library itself.
+
index 6aced23ede08effc8c9f3f01b5c110cb5e6a421a..223085cc40b8ee50d04258794276363069d4222c 100644 (file)
@@ -472,10 +472,15 @@ thread-safe counterpart of `Rc<T>`.
 
 ## Lifetime Elision
 
-Earlier, we mentioned *lifetime elision*, a feature of Rust which allows you to
-not write lifetime annotations in certain circumstances. All references have a
-lifetime, and so if you elide a lifetime (like `&T` instead of `&'a T`), Rust
-will do three things to determine what those lifetimes should be.
+Rust supports powerful local type inference in function bodies, but it’s
+forbidden in item signatures to allow reasoning about the types just based in
+the item signature alone. However, for ergonomic reasons a very restricted
+secondary inference algorithm called “lifetime elision” applies in function
+signatures. It infers only based on the signature components themselves and not
+based on the body of the function, only infers lifetime parameters, and does
+this with only three easily memorizable and unambiguous rules. This makes
+lifetime elision a shorthand for writing an item signature, while not hiding
+away the actual types involved as full local inference would if applied to it.
 
 When talking about lifetime elision, we use the term *input lifetime* and
 *output lifetime*. An *input lifetime* is a lifetime associated with a parameter
@@ -513,8 +518,8 @@ Otherwise, it is an error to elide an output lifetime.
 
 ### Examples
 
-Here are some examples of functions with elided lifetimes, and the version of
-what the elided lifetimes are expand to:
+Here are some examples of functions with elided lifetimes.  We've paired each
+example of an elided lifetime with its expanded form.
 
 ```{rust,ignore}
 fn print(s: &str); // elided
index 9e82e48fd18b7f1fe829d33e7e1eb1b799226f3c..4ebf696aa57a0b017cd70a063b00c3c7b7143990 100644 (file)
@@ -177,6 +177,7 @@ match origin {
 If you want to match against a slice or array, you can use `&`:
 
 ```{rust}
+# #![feature(slice_patterns)]
 fn main() {
     let v = vec!["match_this", "1"];
 
index 79502f3cd17f755768cabac2c00c36c2f594f03a..9eb22a7f6985a51bb6e026aaf73896f1a630135a 100644 (file)
@@ -1,29 +1,5 @@
 % Compiler Plugins
 
-<div class="unstable-feature">
-
-<p>
-<b>Warning:</b> Plugins are an advanced, unstable feature! For many details,
-the only available documentation is the <a
-href="../syntax/index.html"><code>libsyntax</code></a> and <a
-href="../rustc/index.html"><code>librustc</code></a> API docs, or even the source
-code itself. These internal compiler APIs are also subject to change at any
-time.
-</p>
-
-<p>
-For defining new syntax it is often much easier to use Rust's <a
-href="macros.html">built-in macro system</a>.
-</p>
-
-<p style="margin-bottom: 0">
-The code in this document uses language features not covered in the Rust
-Guide.  See the <a href="../reference.html">Reference Manual</a> for more
-information.
-</p>
-
-</div>
-
 # Introduction
 
 `rustc` can load compiler plugins, which are user-provided libraries that
@@ -63,7 +39,7 @@ that implements Roman numeral integer literals.
 
 ```ignore
 #![crate_type="dylib"]
-#![feature(plugin_registrar)]
+#![feature(plugin_registrar, rustc_private)]
 
 extern crate syntax;
 extern crate rustc;
@@ -71,8 +47,8 @@ extern crate rustc;
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::ast::{TokenTree, TtToken};
-use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacExpr};
-use syntax::ext::build::AstBuilder;  // trait for expr_uint
+use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
+use syntax::ext::build::AstBuilder;  // trait for expr_usize
 use rustc::plugin::Registry;
 
 fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
@@ -92,13 +68,13 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         }
     };
 
-    let mut text = &text;
+    let mut text = &*text;
     let mut total = 0;
     while !text.is_empty() {
         match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
             Some(&(rn, val)) => {
                 total += val;
-                text = text.slice_from(rn.len());
+                text = &text[rn.len()..];
             }
             None => {
                 cx.span_err(sp, "invalid Roman numeral");
@@ -107,7 +83,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         }
     }
 
-    MacExpr::new(cx.expr_uint(sp, total))
+    MacEager::expr(cx.expr_u32(sp, total))
 }
 
 #[plugin_registrar]
@@ -146,14 +122,7 @@ a more involved macro example, see
 
 ## Tips and tricks
 
-To see the results of expanding syntax extensions, run
-`rustc --pretty expanded`. The output represents a whole crate, so you
-can also feed it back in to `rustc`, which will sometimes produce better
-error messages than the original compilation. Note that the
-`--pretty expanded` output may have a different meaning if multiple
-variables of the same name (but different syntax contexts) are in play
-in the same scope. In this case `--pretty expanded,hygiene` will tell
-you about the syntax contexts.
+Some of the [macro debugging tips](macros.html#debugging-macro-code) are applicable.
 
 You can use [`syntax::parse`](../syntax/parse/index.html) to turn token trees into
 higher-level syntax elements like expressions:
@@ -184,8 +153,13 @@ and return
 [`DummyResult`](../syntax/ext/base/struct.DummyResult.html),
 so that the compiler can continue and find further errors.
 
+To print syntax fragments for debugging, you can use
+[`span_note`](../syntax/ext/base/struct.ExtCtxt.html#method.span_note) together
+with
+[`syntax::print::pprust::*_to_string`](http://doc.rust-lang.org/syntax/print/pprust/index.html#functions).
+
 The example above produced an integer literal using
-[`AstBuilder::expr_uint`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_uint).
+[`AstBuilder::expr_usize`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_usize).
 As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of
 [quasiquote macros](../syntax/ext/quote/index.html).  They are undocumented and
 very rough around the edges.  However, the implementation may be a good
index 9c649cd2273f8025117dd58f9f9eedf6f2b8e75d..1b3f2a5b7734cc2dcdc44fd10e678dea53f5817b 100644 (file)
@@ -361,16 +361,16 @@ duration a *lifetime*. Let's try a more complex example:
 
 ```{rust}
 fn main() {
-    let x = &mut 5;
+    let mut x = 5;
 
-    if *x < 10 {
+    if x < 10 {
         let y = &x;
 
         println!("Oh no: {}", y);
         return;
     }
 
-    *x -= 1;
+    x -= 1;
 
     println!("Oh no: {}", x);
 }
@@ -382,17 +382,18 @@ mutated, and therefore, lets us pass. This wouldn't work:
 
 ```{rust,ignore}
 fn main() {
-    let x = &mut 5;
+    let mut x = 5;
 
-    if *x < 10 {
+    if x < 10 {
         let y = &x;
-        *x -= 1;
+
+        x -= 1;
 
         println!("Oh no: {}", y);
         return;
     }
 
-    *x -= 1;
+    x -= 1;
 
     println!("Oh no: {}", x);
 }
@@ -401,12 +402,12 @@ fn main() {
 It gives this error:
 
 ```text
-test.rs:5:8: 5:10 error: cannot assign to `*x` because it is borrowed
-test.rs:5         *x -= 1;
-                  ^~
-test.rs:4:16: 4:18 note: borrow of `*x` occurs here
-test.rs:4         let y = &x;
-                          ^~
+test.rs:7:9: 7:15 error: cannot assign to `x` because it is borrowed
+test.rs:7         x -= 1;
+                  ^~~~~~
+test.rs:5:18: 5:19 note: borrow of `x` occurs here
+test.rs:5         let y = &x;
+                           ^
 ```
 
 As you might guess, this kind of analysis is complex for a human, and therefore
@@ -497,13 +498,10 @@ they go out of scope:
 However, boxes do _not_ use reference counting or garbage collection. Boxes are
 what's called an *affine type*. This means that the Rust compiler, at compile
 time, determines when the box comes into and goes out of scope, and inserts the
-appropriate calls there. Furthermore, boxes are a specific kind of affine type,
-known as a *region*. You can read more about regions [in this paper on the
-Cyclone programming
-language](http://www.cs.umd.edu/projects/cyclone/papers/cyclone-regions.pdf).
+appropriate calls there.
 
-You don't need to fully grok the theory of affine types or regions to grok
-boxes, though. As a rough approximation, you can treat this Rust code:
+You don't need to fully grok the theory of affine types to grok boxes, though.
+As a rough approximation, you can treat this Rust code:
 
 ```{rust}
 {
@@ -560,43 +558,44 @@ fn main() {
 In this case, Rust knows that `x` is being *borrowed* by the `add_one()`
 function, and since it's only reading the value, allows it.
 
-We can borrow `x` multiple times, as long as it's not simultaneous:
+We can borrow `x` as read-only multiple times, even simultaneously:
 
 ```{rust}
-fn add_one(x: &i32) -> i32 {
-    *x + 1
+fn add(x: &i32, y: &i32) -> i32 {
+    *x + *y
 }
 
 fn main() {
     let x = Box::new(5);
 
-    println!("{}", add_one(&*x));
-    println!("{}", add_one(&*x));
-    println!("{}", add_one(&*x));
+    println!("{}", add(&*x, &*x));
+    println!("{}", add(&*x, &*x));
 }
 ```
 
-Or as long as it's not a mutable borrow. This will error:
+We can mutably borrow `x` multiple times, but only if x itself is mutable, and
+it may not be *simultaneously* borrowed:
 
 ```{rust,ignore}
-fn add_one(x: &mut i32) -> i32 {
-    *x + 1
+fn increment(x: &mut i32) {
+    *x += 1;
 }
 
 fn main() {
-    let x = Box::new(5);
+    // If variable x is not "mut", this will not compile
+    let mut x = Box::new(5);
 
-    println!("{}", add_one(&*x)); // error: cannot borrow immutable dereference
-                                  // of `&`-pointer as mutable
+    increment(&mut x);
+    increment(&mut x);
+    println!("{}", x);
 }
 ```
 
-Notice we changed the signature of `add_one()` to request a mutable reference.
+Notice the signature of `increment()` requests a mutable reference.
 
 ## Best practices
 
-Boxes are appropriate to use in two situations: Recursive data structures,
-and occasionally, when returning data.
+Boxes are most appropriate to use when defining recursive data structures.
 
 ### Recursive data structures
 
@@ -630,14 +629,6 @@ we don't know the size, and therefore, we need to heap allocate our list.
 Working with recursive or other unknown-sized data structures is the primary
 use-case for boxes.
 
-### Returning data
-
-This is important enough to have its own section entirely. The TL;DR is this:
-you don't generally want to return pointers, even when you might in a language
-like C or C++.
-
-See [Returning Pointers](#returning-pointers) below for more.
-
 # Rc and Arc
 
 This part is coming soon.
@@ -654,74 +645,6 @@ This part is coming soon.
 
 This part is coming soon.
 
-# Returning Pointers
-
-In many languages with pointers, you'd return a pointer from a function
-so as to avoid copying a large data structure. For example:
-
-```{rust}
-struct BigStruct {
-    one: i32,
-    two: i32,
-    // etc
-    one_hundred: i32,
-}
-
-fn foo(x: Box<BigStruct>) -> Box<BigStruct> {
-    Box::new(*x)
-}
-
-fn main() {
-    let x = Box::new(BigStruct {
-        one: 1,
-        two: 2,
-        one_hundred: 100,
-    });
-
-    let y = foo(x);
-}
-```
-
-The idea is that by passing around a box, you're only copying a pointer, rather
-than the hundred `int`s that make up the `BigStruct`.
-
-This is an antipattern in Rust. Instead, write this:
-
-```{rust}
-struct BigStruct {
-    one: i32,
-    two: i32,
-    // etc
-    one_hundred: i32,
-}
-
-fn foo(x: Box<BigStruct>) -> BigStruct {
-    *x
-}
-
-fn main() {
-    let x = Box::new(BigStruct {
-        one: 1,
-        two: 2,
-        one_hundred: 100,
-    });
-
-    let y = Box::new(foo(x));
-}
-```
-
-This gives you flexibility without sacrificing performance.
-
-You may think that this gives us terrible performance: return a value and then
-immediately box it up ?! Isn't this pattern the worst of both worlds? Rust is
-smarter than that. There is no copy in this code. `main` allocates enough room
-for the `box`, passes a pointer to that memory into `foo` as `x`, and then
-`foo` writes the value straight into the `Box<T>`.
-
-This is important enough that it bears repeating: pointers are not for
-optimizing returning values from your code. Allow the caller to choose how they
-want to use your output.
-
 # Creating your own Pointers
 
 This part is coming soon.
diff --git a/src/doc/trpl/standard-input.md b/src/doc/trpl/standard-input.md
deleted file mode 100644 (file)
index 794b1df..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-% Standard Input
-
-Getting input from the keyboard is pretty easy, but uses some things
-we haven't seen before. Here's a simple program that reads some input,
-and then prints it back out:
-
-```{rust,ignore}
-fn main() {
-    println!("Type something!");
-
-    let input = std::old_io::stdin().read_line().ok().expect("Failed to read line");
-
-    println!("{}", input);
-}
-```
-
-Let's go over these chunks, one by one:
-
-```{rust,ignore}
-std::old_io::stdin();
-```
-
-This calls a function, `stdin()`, that lives inside the `std::old_io` module. As
-you can imagine, everything in `std` is provided by Rust, the 'standard
-library.' We'll talk more about the module system later.
-
-Since writing the fully qualified name all the time is annoying, we can use
-the `use` statement to import it in:
-
-```{rust}
-use std::old_io::stdin;
-
-stdin();
-```
-
-However, it's considered better practice to not import individual functions, but
-to import the module, and only use one level of qualification:
-
-```{rust}
-use std::old_io;
-
-old_io::stdin();
-```
-
-Let's update our example to use this style:
-
-```{rust,ignore}
-use std::old_io;
-
-fn main() {
-    println!("Type something!");
-
-    let input = old_io::stdin().read_line().ok().expect("Failed to read line");
-
-    println!("{}", input);
-}
-```
-
-Next up:
-
-```{rust,ignore}
-.read_line()
-```
-
-The `read_line()` method can be called on the result of `stdin()` to return
-a full line of input. Nice and easy.
-
-```{rust,ignore}
-.ok().expect("Failed to read line");
-```
-
-Do you remember this code?
-
-```{rust}
-enum OptionalInt {
-    Value(i32),
-    Missing,
-}
-
-fn main() {
-    let x = OptionalInt::Value(5);
-    let y = OptionalInt::Missing;
-
-    match x {
-        OptionalInt::Value(n) => println!("x is {}", n),
-        OptionalInt::Missing => println!("x is missing!"),
-    }
-
-    match y {
-        OptionalInt::Value(n) => println!("y is {}", n),
-        OptionalInt::Missing => println!("y is missing!"),
-    }
-}
-```
-
-We had to match each time to see if we had a value or not. In this case,
-though, we _know_ that `x` has a `Value`, but `match` forces us to handle
-the `missing` case. This is what we want 99% of the time, but sometimes, we
-know better than the compiler.
-
-Likewise, `read_line()` does not return a line of input. It _might_ return a
-line of input, though it might also fail to do so. This could happen if our program
-isn't running in a terminal, but as part of a cron job, or some other context
-where there's no standard input. Because of this, `read_line` returns a type
-very similar to our `OptionalInt`: an `IoResult<T>`. We haven't talked about
-`IoResult<T>` yet because it is the *generic* form of our `OptionalInt`.
-Until then, you can think of it as being the same thing, just for any type –
-not just `i32`s.
-
-Rust provides a method on these `IoResult<T>`s called `ok()`, which does the
-same thing as our `match` statement but assumes that we have a valid value.
-We then call `expect()` on the result, which will terminate our program if we
-don't have a valid value. In this case, if we can't get input, our program
-doesn't work, so we're okay with that. In most cases, we would want to handle
-the error case explicitly. `expect()` allows us to give an error message if
-this crash happens.
-
-We will cover the exact details of how all of this works later in the Guide.
-For now, this gives you enough of a basic understanding to work with.
-
-Back to the code we were working on! Here's a refresher:
-
-```{rust,ignore}
-use std::old_io;
-
-fn main() {
-    println!("Type something!");
-
-    let input = old_io::stdin().read_line().ok().expect("Failed to read line");
-
-    println!("{}", input);
-}
-```
-
-With long lines like this, Rust gives you some flexibility with the whitespace.
-We _could_ write the example like this:
-
-```{rust,ignore}
-use std::old_io;
-
-fn main() {
-    println!("Type something!");
-
-    // here, we'll show the types at each step
-
-    let input = old_io::stdin() // std::old_io::stdio::StdinReader
-                  .read_line() // IoResult<String>
-                  .ok() // Option<String>
-                  .expect("Failed to read line"); // String
-
-    println!("{}", input);
-}
-```
-
-Sometimes, this makes things more readable – sometimes, less. Use your judgement
-here.
-
-That's all you need to get basic input from the standard input! It's not too
-complicated, but there are a number of small parts.
index 9421dac7bf65d750a554e9c1f0a17de1bfe6a5c4..a7794814156e63fd330d21713d219cff2d7fd550 100644 (file)
@@ -79,12 +79,13 @@ fn main() {
 }
 ```
 
-This has some upsides: static dispatching of any method calls, allowing for
-inlining and hence usually higher performance. It also has some downsides:
-causing code bloat due to many copies of the same function existing in the
-binary, one for each type.
+This has a great upside: static dispatch allows function calls to be
+inlined because the callee is known at compile time, and inlining is
+the key to good optimization. Static dispatch is fast, but it comes at
+a tradeoff: 'code bloat', due to many copies of the same function
+existing in the binary, one for each type.
 
-Furthermore, compilers aren’t perfect and may “optimise” code to become slower.
+Furthermore, compilers aren’t perfect and may “optimize” code to become slower.
 For example, functions inlined too eagerly will bloat the instruction cache
 (cache rules everything around us). This is part of the reason that `#[inline]`
 and `#[inline(always)]` should be used carefully, and one reason why using a
@@ -92,61 +93,100 @@ dynamic dispatch is sometimes more efficient.
 
 However, the common case is that it is more efficient to use static dispatch,
 and one can always have a thin statically-dispatched wrapper function that does
-a dynamic, but not vice versa, meaning static calls are more flexible. The
-standard library tries to be statically dispatched where possible for this
-reason. 
+a dynamic dispatch, but not vice versa, meaning static calls are more flexible.
+The standard library tries to be statically dispatched where possible for this
+reason.
 
 ## Dynamic dispatch
 
 Rust provides dynamic dispatch through a feature called 'trait objects.' Trait
 objects, like `&Foo` or `Box<Foo>`, are normal values that store a value of
 *any* type that implements the given trait, where the precise type can only be
-known at runtime. The methods of the trait can be called on a trait object via
-a special record of function pointers (created and managed by the compiler).
+known at runtime.
 
-A function that takes a trait object is not specialised to each of the types
-that implements `Foo`: only one copy is generated, often (but not always)
-resulting in less code bloat. However, this comes at the cost of requiring
-slower virtual function calls, and effectively inhibiting any chance of
-inlining and related optimisations from occurring.
+A trait object can be obtained from a pointer to a concrete type that
+implements the trait by *casting* it (e.g. `&x as &Foo`) or *coercing* it
+(e.g. using `&x` as an argument to a function that takes `&Foo`).
 
-Trait objects are both simple and complicated: their core representation and
-layout is quite straight-forward, but there are some curly error messages and
-surprising behaviours to discover.
+These trait object coercions and casts also work for pointers like `&mut T` to
+`&mut Foo` and `Box<T>` to `Box<Foo>`, but that's all at the moment. Coercions
+and casts are identical.
+
+This operation can be seen as "erasing" the compiler's knowledge about the
+specific type of the pointer, and hence trait objects are sometimes referred to
+as "type erasure".
+
+Coming back to the example above, we can use the same trait to perform dynamic
+dispatch with trait objects by casting:
 
-### Obtaining a trait object
+```rust
+# trait Foo { fn method(&self) -> String; }
+# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
+# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
 
-There's two similar ways to get a trait object value: casts and coercions. If
-`T` is a type that implements a trait `Foo` (e.g. `u8` for the `Foo` above),
-then the two ways to get a `Foo` trait object out of a pointer to `T` look
-like:
+fn do_something(x: &Foo) {
+    x.method();
+}
 
-```{rust,ignore}
-let ref_to_t: &T = ...;
+fn main() {
+    let x = 5u8;
+    do_something(&x as &Foo);
+}
+```
+
+or by coercing:
 
-// `as` keyword for casting
-let cast = ref_to_t as &Foo;
+```rust
+# trait Foo { fn method(&self) -> String; }
+# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
+# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
 
-// using a `&T` in a place that has a known type of `&Foo` will implicitly coerce:
-let coerce: &Foo = ref_to_t;
+fn do_something(x: &Foo) {
+    x.method();
+}
 
-fn also_coerce(_unused: &Foo) {}
-also_coerce(ref_to_t);
+fn main() {
+    let x = "Hello".to_string();
+    do_something(&x);
+}
 ```
 
-These trait object coercions and casts also work for pointers like `&mut T` to
-`&mut Foo` and `Box<T>` to `Box<Foo>`, but that's all at the moment. Coercions
-and casts are identical.
+A function that takes a trait object is not specialized to each of the types
+that implements `Foo`: only one copy is generated, often (but not always)
+resulting in less code bloat. However, this comes at the cost of requiring
+slower virtual function calls, and effectively inhibiting any chance of
+inlining and related optimisations from occurring.
 
-This operation can be seen as "erasing" the compiler's knowledge about the
-specific type of the pointer, and hence trait objects are sometimes referred to
-"type erasure".
+### Why pointers?
+
+Rust does not put things behind a pointer by default, unlike many managed
+languages, so types can have different sizes. Knowing the size of the value at
+compile time is important for things like passing it as an argument to a
+function, moving it about on the stack and allocating (and deallocating) space
+on the heap to store it.
+
+For `Foo`, we would need to have a value that could be at least either a
+`String` (24 bytes) or a `u8` (1 byte), as well as any other type for which
+dependent crates may implement `Foo` (any number of bytes at all). There's no
+way to guarantee that this last point can work if the values are stored without
+a pointer, because those other types can be arbitrarily large.
+
+Putting the value behind a pointer means the size of the value is not relevant
+when we are tossing a trait object around, only the size of the pointer itself.
 
 ### Representation
 
+The methods of the trait can be called on a trait object via a special record
+of function pointers traditionally called a 'vtable' (created and managed by
+the compiler).
+
+Trait objects are both simple and complicated: their core representation and
+layout is quite straight-forward, but there are some curly error messages and
+surprising behaviors to discover.
+
 Let's start simple, with the runtime representation of a trait object. The
 `std::raw` module contains structs with layouts that are the same as the
-complicated build-in types, [including trait objects][stdraw]:
+complicated built-in types, [including trait objects][stdraw]:
 
 ```rust
 # mod foo {
@@ -223,14 +263,14 @@ static Foo_for_String_vtable: FooVtable = FooVtable {
 The `destructor` field in each vtable points to a function that will clean up
 any resources of the vtable's type, for `u8` it is trivial, but for `String` it
 will free the memory. This is necessary for owning trait objects like
-`Box<Foo>`, which need to clean-up both the `Box` allocation and as well as the
+`Box<Foo>`, which need to clean-up both the `Box` allocation as well as the
 internal type when they go out of scope. The `size` and `align` fields store
 the size of the erased type, and its alignment requirements; these are
 essentially unused at the moment since the information is embedded in the
-destructor, but will be used in future, as trait objects are progressively made
-more flexible.
+destructor, but will be used in the future, as trait objects are progressively
+made more flexible.
 
-Suppose we've got some values that implement `Foo`, the explicit form of
+Suppose we've got some values that implement `Foo`, then the explicit form of
 construction and use of `Foo` trait objects might look a bit like (ignoring the
 type mismatches: they're all just pointers anyway):
 
@@ -264,23 +304,3 @@ let y = TraitObject {
 If `b` or `y` were owning trait objects (`Box<Foo>`), there would be a
 `(b.vtable.destructor)(b.data)` (respectively `y`) call when they went out of
 scope.
-
-### Why pointers?
-
-The use of language like "fat pointer" implies that a trait object is
-always a pointer of some form, but why?
-
-Rust does not put things behind a pointer by default, unlike many managed
-languages, so types can have different sizes. Knowing the size of the value at
-compile time is important for things like passing it as an argument to a
-function, moving it about on the stack and allocating (and deallocating) space
-on the heap to store it.
-
-For `Foo`, we would need to have a value that could be at least either a
-`String` (24 bytes) or a `u8` (1 byte), as well as any other type for which
-dependent crates may implement `Foo` (any number of bytes at all). There's no
-way to guarantee that this last point can work if the values are stored without
-a pointer, because those other types can be arbitrarily large.
-
-Putting the value behind a pointer means the size of the value is not relevant
-when we are tossing a trait object around, only the size of the pointer itself.
index 8ebebc98baf6b6d6bd4bb1f549e1400d33734d58..2c2e6a8c7c5acdf8079163bf675163a0ea7aff84 100644 (file)
@@ -25,8 +25,10 @@ compiled program, and exists for the entire duration it runs. The `string`
 binding is a reference to this statically allocated string. String slices
 have a fixed size, and cannot be mutated.
 
-A `String`, on the other hand, is an in-memory string.  This string is
-growable, and is also guaranteed to be UTF-8.
+A `String`, on the other hand, is a heap-allocated string. This string
+is growable, and is also guaranteed to be UTF-8. `String`s are
+commonly created by converting from a string slice using the
+`to_string` method.
 
 ```{rust}
 let mut s = "Hello".to_string(); // mut s: String
index 54c74fdd3e2b50e6ecd0f4219b2520c115c20906..fddb4c19031726f51f9dfe0930c40dbb4ff538fb 100644 (file)
@@ -1,7 +1,7 @@
 % Testing
 
 > Program testing can be a very effective way to show the presence of bugs, but
-> it is hopelessly inadequate for showing their absence. 
+> it is hopelessly inadequate for showing their absence.
 >
 > Edsger W. Dijkstra, "The Humble Programmer" (1972)
 
@@ -129,11 +129,11 @@ $ echo $?
 
 This is useful if you want to integrate `cargo test` into other tooling.
 
-We can invert our test's failure with another attribute: `should_fail`:
+We can invert our test's failure with another attribute: `should_panic`:
 
 ```rust
 #[test]
-#[should_fail]
+#[should_panic]
 fn it_works() {
     assert!(false);
 }
@@ -163,13 +163,13 @@ equality:
 
 ```rust
 #[test]
-#[should_fail]
+#[should_panic]
 fn it_works() {
     assert_eq!("Hello", "world");
 }
 ```
 
-Does this test pass or fail? Because of the `should_fail` attribute, it
+Does this test pass or fail? Because of the `should_panic` attribute, it
 passes:
 
 ```bash
@@ -189,15 +189,15 @@ running 0 tests
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 ```
 
-`should_fail` tests can be fragile, as it's hard to guarantee that the test
+`should_panic` 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
+parameter can be added to the `should_panic` 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]
-#[should_fail(expected = "assertion failed")]
+#[should_panic(expected = "assertion failed")]
 fn it_works() {
     assert_eq!("Hello", "world");
 }
@@ -231,7 +231,7 @@ pub fn add_two(a: i32) -> i32 {
 }
 
 #[cfg(test)]
-mod tests {
+mod test {
     use super::add_two;
 
     #[test]
@@ -241,7 +241,7 @@ mod tests {
 }
 ```
 
-There's a few changes here. The first is the introduction of a `mod tests` with
+There's a few changes here. The first is the introduction of a `mod test` with
 a `cfg` attribute. The module allows us to group all of our tests together, and
 to also define helper functions if needed, that don't become a part of the rest
 of our crate. The `cfg` attribute only compiles our test code if we're
@@ -260,7 +260,7 @@ pub fn add_two(a: i32) -> i32 {
 }
 
 #[cfg(test)]
-mod tests {
+mod test {
     use super::*;
 
     #[test]
@@ -308,7 +308,7 @@ extern crate adder;
 #[test]
 fn it_works() {
     assert_eq!(4, adder::add_two(2));
-}   
+}
 ```
 
 This looks similar to our previous tests, but slightly different. We now have
@@ -430,147 +430,3 @@ documentation tests: the `_0` is generated for the module test, and `add_two_0`
 for the function test. These will auto increment with names like `add_two_1` as
 you add more examples.
 
-# Benchmark tests
-
-Rust also supports benchmark tests, which can test the performance of your
-code. Let's make our `src/lib.rs` look like this (comments elided):
-
-```{rust,ignore}
-extern crate test;
-
-pub fn add_two(a: i32) -> i32 {
-    a + 2
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use test::Bencher;
-
-    #[test]
-    fn it_works() {
-        assert_eq!(4, add_two(2));
-    }
-
-    #[bench]
-    fn bench_add_two(b: &mut Bencher) {
-        b.iter(|| add_two(2));
-    }
-}
-```
-
-We've imported the `test` crate, which contains our benchmarking support.
-We have a new function as well, with the `bench` attribute. Unlike regular
-tests, which take no arguments, benchmark tests take a `&mut Bencher`. This
-`Bencher` provides an `iter` method, which takes a closure. This closure
-contains the code we'd like to benchmark.
-
-We can run benchmark tests with `cargo bench`:
-
-```bash
-$ cargo bench
-   Compiling adder v0.0.1 (file:///home/steve/tmp/adder)
-     Running target/release/adder-91b3e234d4ed382a
-
-running 2 tests
-test tests::it_works ... ignored
-test tests::bench_add_two ... bench:         1 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 1 ignored; 1 measured
-```
-
-Our non-benchmark test was ignored. You may have noticed that `cargo bench`
-takes a bit longer than `cargo test`. This is because Rust runs our benchmark
-a number of times, and then takes the average. Because we're doing so little
-work in this example, we have a `1 ns/iter (+/- 0)`, but this would show
-the variance if there was one.
-
-Advice on writing benchmarks:
-
-
-* Move setup code outside the `iter` loop; only put the part you want to measure inside
-* Make the code do "the same thing" on each iteration; do not accumulate or change state
-* Make the outer function idempotent too; the benchmark runner is likely to run
-  it many times
-*  Make the inner `iter` loop short and fast so benchmark runs are fast and the
-   calibrator can adjust the run-length at fine resolution
-* Make the code in the `iter` loop do something simple, to assist in pinpointing
-  performance improvements (or regressions)
-
-## Gotcha: optimizations
-
-There's another tricky part to writing benchmarks: benchmarks compiled with
-optimizations activated can be dramatically changed by the optimizer so that
-the benchmark is no longer benchmarking what one expects. For example, the
-compiler might recognize that some calculation has no external effects and
-remove it entirely.
-
-```{rust,ignore}
-extern crate test;
-use test::Bencher;
-
-#[bench]
-fn bench_xor_1000_ints(b: &mut Bencher) {
-    b.iter(|| {
-        (0..1000).fold(0, |old, new| old ^ new);
-    });
-}
-```
-
-gives the following results
-
-```text
-running 1 test
-test bench_xor_1000_ints ... bench:         0 ns/iter (+/- 0)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-```
-
-The benchmarking runner offers two ways to avoid this. Either, the closure that
-the `iter` method receives can return an arbitrary value which forces the
-optimizer to consider the result used and ensures it cannot remove the
-computation entirely. This could be done for the example above by adjusting the
-`b.iter` call to
-
-```rust
-# struct X;
-# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
-b.iter(|| {
-    // note lack of `;` (could also use an explicit `return`).
-    (0..1000).fold(0, |old, new| old ^ new)
-});
-```
-
-Or, the other option is to call the generic `test::black_box` function, which
-is an opaque "black box" to the optimizer and so forces it to consider any
-argument as used.
-
-```rust
-extern crate test;
-
-# fn main() {
-# struct X;
-# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
-b.iter(|| {
-    let n = test::black_box(1000);
-
-    (0..n).fold(0, |a, b| a ^ b)
-})
-# }
-```
-
-Neither of these read or modify the value, and are very cheap for small values.
-Larger values can be passed indirectly to reduce overhead (e.g.
-`black_box(&huge_struct)`).
-
-Performing either of the above changes gives the following benchmarking results
-
-```text
-running 1 test
-test bench_xor_1000_ints ... bench:       131 ns/iter (+/- 3)
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
-```
-
-However, the optimizer can still modify a testcase in an undesirable manner
-even when using either of the above.
diff --git a/src/doc/trpl/tracing-macros.md b/src/doc/trpl/tracing-macros.md
new file mode 100644 (file)
index 0000000..6226ea9
--- /dev/null
@@ -0,0 +1,91 @@
+% Tracing Macros
+
+The `trace_macros` feature allows you to use a special feature: tracing macro
+invocations.
+
+In the advanced macros chapter, we defined a `bct` macro:
+
+```rust
+macro_rules! bct {
+    // cmd 0:  d ... => ...
+    (0, $($ps:tt),* ; $_d:tt)
+        => (bct!($($ps),*, 0 ; ));
+    (0, $($ps:tt),* ; $_d:tt, $($ds:tt),*)
+        => (bct!($($ps),*, 0 ; $($ds),*));
+
+    // cmd 1p:  1 ... => 1 ... p
+    (1, $p:tt, $($ps:tt),* ; 1)
+        => (bct!($($ps),*, 1, $p ; 1, $p));
+    (1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*)
+        => (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p));
+
+    // cmd 1p:  0 ... => 0 ...
+    (1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
+        => (bct!($($ps),*, 1, $p ; $($ds),*));
+
+    // halt on empty data string
+    ( $($ps:tt),* ; )
+        => (());
+}
+```
+
+This is pretty complex! we can see the output
+
+```rust,ignore
+#![feature(trace_macros)]
+
+macro_rules! bct {
+    // cmd 0:  d ... => ...
+    (0, $($ps:tt),* ; $_d:tt)
+        => (bct!($($ps),*, 0 ; ));
+    (0, $($ps:tt),* ; $_d:tt, $($ds:tt),*)
+        => (bct!($($ps),*, 0 ; $($ds),*));
+
+    // cmd 1p:  1 ... => 1 ... p
+    (1, $p:tt, $($ps:tt),* ; 1)
+        => (bct!($($ps),*, 1, $p ; 1, $p));
+    (1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*)
+        => (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p));
+
+    // cmd 1p:  0 ... => 0 ...
+    (1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
+        => (bct!($($ps),*, 1, $p ; $($ds),*));
+
+    // halt on empty data string
+    ( $($ps:tt),* ; )
+        => (());
+}
+
+fn main() {
+    trace_macros!(true);
+
+    bct!(0, 0, 1, 1, 1 ; 1, 0, 1);
+}
+```
+
+This will print out a wall of text:
+
+```text
+bct! { 0 , 0 , 1 , 1 , 1 ; 1 , 0 , 1 }
+bct! { 0 , 1 , 1 , 1 , 0 ; 0 , 1 }
+bct! { 1 , 1 , 1 , 0 , 0 ; 1 }
+bct! { 1 , 0 , 0 , 1 , 1 ; 1 , 1 }
+bct! { 0 , 1 , 1 , 1 , 0 ; 1 , 1 , 0 }
+bct! { 1 , 1 , 1 , 0 , 0 ; 1 , 0 }
+bct! { 1 , 0 , 0 , 1 , 1 ; 1 , 0 , 1 }
+bct! { 0 , 1 , 1 , 1 , 0 ; 1 , 0 , 1 , 0 }
+bct! { 1 , 1 , 1 , 0 , 0 ; 0 , 1 , 0 }
+bct! { 1 , 0 , 0 , 1 , 1 ; 0 , 1 , 0 }
+bct! { 0 , 1 , 1 , 1 , 0 ; 0 , 1 , 0 }
+```
+
+And eventually, error:
+
+```text
+18:45 error: recursion limit reached while expanding the macro `bct`
+    => (bct!($($ps),*, 1, $p ; $($ds),*));
+        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+```
+
+The `trace_macros!` call is what produces this output, showing how we match
+each time.
index abd9af1af33a097e805f0b64cba83d0ccbbc6cdf..341c90a70877e7cc485e6ac22b645e9e27c02367 100644 (file)
@@ -4,6 +4,7 @@ Do you remember the `impl` keyword, used to call a function with method
 syntax?
 
 ```{rust}
+# #![feature(core)]
 struct Circle {
     x: f64,
     y: f64,
@@ -21,6 +22,7 @@ Traits are similar, except that we define a trait with just the method
 signature, then implement the trait for that struct. Like this:
 
 ```{rust}
+# #![feature(core)]
 struct Circle {
     x: f64,
     y: f64,
@@ -84,6 +86,7 @@ which implements `HasArea` will have an `.area()` method.
 Here's an extended example of how this works:
 
 ```{rust}
+# #![feature(core)]
 trait HasArea {
     fn area(&self) -> f64;
 }
@@ -225,6 +228,7 @@ If we add a `use` line right above `main` and make the right things public,
 everything is fine:
 
 ```{rust}
+# #![feature(core)]
 use shapes::HasArea;
 
 mod shapes {
@@ -273,6 +277,29 @@ One last thing about traits: generic functions with a trait bound use
 dispatched. What's that mean? Check out the chapter on [static and dynamic
 dispatch](static-and-dynamic-dispatch.html) for more.
 
+## Multiple trait bounds
+
+You’ve seen that you can bound a generic type parameter with a trait:
+
+```rust
+fn foo<T: Clone>(x: T) {
+    x.clone();
+}
+```
+
+If you need more than one bound, you can use `+`:
+
+```rust
+use std::fmt::Debug;
+
+fn foo<T: Clone + Debug>(x: T) {
+    x.clone();
+    println!("{:?}", x);
+}
+```
+
+`T` now needs to be both `Clone` as well as `Debug`.
+
 ## Where clause
 
 Writing functions with only a few generic types and a small number of trait
@@ -408,6 +435,7 @@ but instead, we found a floating-point variable. We need a different bound. `Flo
 to the rescue:
 
 ```
+# #![feature(std_misc)]
 use std::num::Float;
 
 fn inverse<T: Float>(x: T) -> Result<T, String> {
@@ -423,6 +451,7 @@ from the `Float` trait. Both `f32` and `f64` implement `Float`, so our function
 works just fine:
 
 ```
+# #![feature(std_misc)]
 # use std::num::Float;
 # fn inverse<T: Float>(x: T) -> Result<T, String> {
 #     if x == Float::zero() { return Err("x cannot be zero!".to_string()) }
@@ -435,3 +464,46 @@ println!("the inverse of {} is {:?}", 2.0f64, inverse(2.0f64));
 println!("the inverse of {} is {:?}", 0.0f32, inverse(0.0f32));
 println!("the inverse of {} is {:?}", 0.0f64, inverse(0.0f64));
 ```
+
+## Default methods
+
+There's one last feature of traits we should cover: default methods. It's
+easiest just to show an example:
+
+```rust
+trait Foo {
+    fn bar(&self);
+
+    fn baz(&self) { println!("We called baz."); }
+}
+```
+
+Implementors of the `Foo` trait need to implement `bar()`, but they don't
+need to implement `baz()`. They'll get this default behavior. They can
+override the default if they so choose:
+
+```rust
+# trait Foo {
+# fn bar(&self);
+# fn baz(&self) { println!("We called baz."); }
+# }
+struct UseDefault;
+
+impl Foo for UseDefault {
+    fn bar(&self) { println!("We called bar."); }
+}
+
+struct OverrideDefault;
+
+impl Foo for OverrideDefault {
+    fn bar(&self) { println!("We called bar."); }
+
+    fn baz(&self) { println!("Override baz!"); }
+}
+
+let default = UseDefault;
+default.baz(); // prints "We called baz."
+
+let over = OverrideDefault;
+over.baz(); // prints "Override baz!"
+```
index 4e14085599b603d3b640d672748c8f41eebce10f..3ca3cfd05886ee8add73eaa419c16f7c3c4c34b5 100644 (file)
@@ -93,10 +93,6 @@ offered by the Rust language and libraries. For example, they
 - are plain-old-data, that is, they don't move ownership, again unlike
   `Box`, hence the Rust compiler cannot protect against bugs like
   use-after-free;
-- are considered sendable (if their contents is considered sendable),
-  so the compiler offers no assistance with ensuring their use is
-  thread-safe; for example, one can concurrently access a `*mut i32`
-  from two threads without synchronization.
 - lack any form of lifetimes, unlike `&`, and so the compiler cannot
   reason about dangling pointers; and
 - have no guarantees about aliasing or mutability other than mutation
@@ -185,533 +181,3 @@ code:
   that clean-up is always run, even when the thread panics.
 - ensure that any data stored behind a raw pointer is destroyed at the
   appropriate time.
-
-As an example, we give a reimplementation of owned boxes by wrapping
-`malloc` and `free`. Rust's move semantics and lifetimes mean this
-reimplementation is as safe as the `Box` type.
-
-```
-#![feature(unsafe_destructor)]
-
-extern crate libc;
-use libc::{c_void, size_t, malloc, free};
-use std::mem;
-use std::ptr;
-
-// Define a wrapper around the handle returned by the foreign code.
-// Unique<T> has the same semantics as Box<T>
-pub struct Unique<T> {
-    // It contains a single raw, mutable pointer to the object in question.
-    ptr: *mut T
-}
-
-// Implement methods for creating and using the values in the box.
-
-// NB: For simplicity and correctness, we require that T has kind Send
-// (owned boxes relax this restriction).
-impl<T: Send> Unique<T> {
-    pub fn new(value: T) -> Unique<T> {
-        unsafe {
-            let ptr = malloc(mem::size_of::<T>() as size_t) as *mut T;
-            // we *need* valid pointer.
-            assert!(!ptr.is_null());
-            // `*ptr` is uninitialized, and `*ptr = value` would
-            // attempt to destroy it `overwrite` moves a value into
-            // this memory without attempting to drop the original
-            // value.
-            ptr::write(&mut *ptr, value);
-            Unique{ptr: ptr}
-        }
-    }
-
-    // the 'r lifetime results in the same semantics as `&*x` with
-    // Box<T>
-    pub fn borrow<'r>(&'r self) -> &'r T {
-        // By construction, self.ptr is valid
-        unsafe { &*self.ptr }
-    }
-
-    // the 'r lifetime results in the same semantics as `&mut *x` with
-    // Box<T>
-    pub fn borrow_mut<'r>(&'r mut self) -> &'r mut T {
-        unsafe { &mut *self.ptr }
-    }
-}
-
-// A key ingredient for safety, we associate a destructor with
-// Unique<T>, making the struct manage the raw pointer: when the
-// struct goes out of scope, it will automatically free the raw pointer.
-//
-// NB: This is an unsafe destructor, because rustc will not normally
-// allow destructors to be associated with parameterized types, due to
-// bad interaction with managed boxes. (With the Send restriction,
-// we don't have this problem.) Note that the `#[unsafe_destructor]`
-// feature gate is required to use unsafe destructors.
-#[unsafe_destructor]
-impl<T: Send> Drop for Unique<T> {
-    fn drop(&mut self) {
-        unsafe {
-            // Copy the object out from the pointer onto the stack,
-            // where it is covered by normal Rust destructor semantics
-            // and cleans itself up, if necessary
-            ptr::read(self.ptr);
-
-            // clean-up our allocation
-            free(self.ptr as *mut c_void)
-        }
-    }
-}
-
-// A comparison between the built-in `Box` and this reimplementation
-fn main() {
-    {
-        let mut x = Box::new(5);
-        *x = 10;
-    } // `x` is freed here
-
-    {
-        let mut y = Unique::new(5);
-        *y.borrow_mut() = 10;
-    } // `y` is freed here
-}
-```
-
-Notably, the only way to construct a `Unique` is via the `new`
-function, and this function ensures that the internal pointer is valid
-and hidden in the private field. The two `borrow` methods are safe
-because the compiler statically guarantees that objects are never used
-before creation or after destruction (unless you use some `unsafe`
-code...).
-
-# Inline assembly
-
-For extremely low-level manipulations and performance reasons, one
-might wish to control the CPU directly. Rust supports using inline
-assembly to do this via the `asm!` macro. The syntax roughly matches
-that of GCC & Clang:
-
-```ignore
-asm!(assembly template
-   : output operands
-   : input operands
-   : clobbers
-   : options
-   );
-```
-
-Any use of `asm` is feature gated (requires `#![feature(asm)]` on the
-crate to allow) and of course requires an `unsafe` block.
-
-> **Note**: the examples here are given in x86/x86-64 assembly, but
-> all platforms are supported.
-
-## Assembly template
-
-The `assembly template` is the only required parameter and must be a
-literal string (i.e. `""`)
-
-```
-#![feature(asm)]
-
-#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-fn foo() {
-    unsafe {
-        asm!("NOP");
-    }
-}
-
-// other platforms
-#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
-fn foo() { /* ... */ }
-
-fn main() {
-    // ...
-    foo();
-    // ...
-}
-```
-
-(The `feature(asm)` and `#[cfg]`s are omitted from now on.)
-
-Output operands, input operands, clobbers and options are all optional
-but you must add the right number of `:` if you skip them:
-
-```
-# #![feature(asm)]
-# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-# fn main() { unsafe {
-asm!("xor %eax, %eax"
-    :
-    :
-    : "eax"
-   );
-# } }
-```
-
-Whitespace also doesn't matter:
-
-```
-# #![feature(asm)]
-# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-# fn main() { unsafe {
-asm!("xor %eax, %eax" ::: "eax");
-# } }
-```
-
-## Operands
-
-Input and output operands follow the same format: `:
-"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
-expressions must be mutable lvalues:
-
-```
-# #![feature(asm)]
-# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-fn add(a: i32, b: i32) -> i32 {
-    let mut c = 0;
-    unsafe {
-        asm!("add $2, $0"
-             : "=r"(c)
-             : "0"(a), "r"(b)
-             );
-    }
-    c
-}
-# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
-# fn add(a: i32, b: i32) -> i32 { a + b }
-
-fn main() {
-    assert_eq!(add(3, 14159), 14162)
-}
-```
-
-## Clobbers
-
-Some instructions modify registers which might otherwise have held
-different values so we use the clobbers list to indicate to the
-compiler not to assume any values loaded into those registers will
-stay valid.
-
-```
-# #![feature(asm)]
-# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-# fn main() { unsafe {
-// Put the value 0x200 in eax
-asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
-# } }
-```
-
-Input and output registers need not be listed since that information
-is already communicated by the given constraints. Otherwise, any other
-registers used either implicitly or explicitly should be listed.
-
-If the assembly changes the condition code register `cc` should be
-specified as one of the clobbers. Similarly, if the assembly modifies
-memory, `memory` should also be specified.
-
-## Options
-
-The last section, `options` is specific to Rust. The format is comma
-separated literal strings (i.e. `:"foo", "bar", "baz"`). It's used to
-specify some extra info about the inline assembly:
-
-Current valid options are:
-
-1. *volatile* - specifying this is analogous to
-   `__asm__ __volatile__ (...)` in gcc/clang.
-2. *alignstack* - certain instructions expect the stack to be
-   aligned a certain way (i.e. SSE) and specifying this indicates to
-   the compiler to insert its usual stack alignment code
-3. *intel* - use intel syntax instead of the default AT&T.
-
-# Avoiding the standard library
-
-By default, `std` is linked to every Rust crate. In some contexts,
-this is undesirable, and can be avoided with the `#![no_std]`
-attribute attached to the crate.
-
-```ignore
-// a minimal library
-#![crate_type="lib"]
-#![feature(no_std)]
-#![no_std]
-# // fn main() {} tricked you, rustdoc!
-```
-
-Obviously there's more to life than just libraries: one can use
-`#[no_std]` with an executable, controlling the entry point is
-possible in two ways: the `#[start]` attribute, or overriding the
-default shim for the C `main` function with your own.
-
-The function marked `#[start]` is passed the command line parameters
-in the same format as C:
-
-```
-#![feature(lang_items, start, no_std)]
-#![no_std]
-
-// Pull in the system libc library for what crt0.o likely requires
-extern crate libc;
-
-// Entry point for this program
-#[start]
-fn start(_argc: isize, _argv: *const *const u8) -> isize {
-    0
-}
-
-// These functions and traits are used by the compiler, but not
-// for a bare-bones hello world. These are normally
-// provided by libstd.
-#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
-#[lang = "eh_personality"] extern fn eh_personality() {}
-#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
-# // fn main() {} tricked you, rustdoc!
-```
-
-To override the compiler-inserted `main` shim, one has to disable it
-with `#![no_main]` and then create the appropriate symbol with the
-correct ABI and the correct name, which requires overriding the
-compiler's name mangling too:
-
-```ignore
-#![feature(no_std)]
-#![no_std]
-#![no_main]
-#![feature(lang_items, start)]
-
-extern crate libc;
-
-#[no_mangle] // ensure that this symbol is called `main` in the output
-pub extern fn main(argc: i32, argv: *const *const u8) -> i32 {
-    0
-}
-
-#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
-#[lang = "eh_personality"] extern fn eh_personality() {}
-#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
-# // fn main() {} tricked you, rustdoc!
-```
-
-
-The compiler currently makes a few assumptions about symbols which are available
-in the executable to call. Normally these functions are provided by the standard
-library, but without it you must define your own.
-
-The first of these three functions, `stack_exhausted`, is invoked whenever stack
-overflow is detected.  This function has a number of restrictions about how it
-can be called and what it must do, but if the stack limit register is not being
-maintained then a thread always has an "infinite stack" and this function
-shouldn't get triggered.
-
-The second of these three functions, `eh_personality`, is used by the
-failure mechanisms of the compiler. This is often mapped to GCC's
-personality function (see the
-[libstd implementation](../std/rt/unwind/index.html) for more
-information), but crates which do not trigger a panic can be assured
-that this function is never called. The final function, `panic_fmt`, is
-also used by the failure mechanisms of the compiler.
-
-## Using libcore
-
-> **Note**: the core library's structure is unstable, and it is recommended to
-> use the standard library instead wherever possible.
-
-With the above techniques, we've got a bare-metal executable running some Rust
-code. There is a good deal of functionality provided by the standard library,
-however, that is necessary to be productive in Rust. If the standard library is
-not sufficient, then [libcore](../core/index.html) is designed to be used
-instead.
-
-The core library has very few dependencies and is much more portable than the
-standard library itself. Additionally, the core library has most of the
-necessary functionality for writing idiomatic and effective Rust code.
-
-As an example, here is a program that will calculate the dot product of two
-vectors provided from C, using idiomatic Rust practices.
-
-```
-#![feature(lang_items, start, no_std)]
-#![no_std]
-
-# extern crate libc;
-extern crate core;
-
-use core::prelude::*;
-
-use core::mem;
-
-#[no_mangle]
-pub extern fn dot_product(a: *const u32, a_len: u32,
-                          b: *const u32, b_len: u32) -> u32 {
-    use core::raw::Slice;
-
-    // Convert the provided arrays into Rust slices.
-    // The core::raw module guarantees that the Slice
-    // structure has the same memory layout as a &[T]
-    // slice.
-    //
-    // This is an unsafe operation because the compiler
-    // cannot tell the pointers are valid.
-    let (a_slice, b_slice): (&[u32], &[u32]) = unsafe {
-        mem::transmute((
-            Slice { data: a, len: a_len as usize },
-            Slice { data: b, len: b_len as usize },
-        ))
-    };
-
-    // Iterate over the slices, collecting the result
-    let mut ret = 0;
-    for (i, j) in a_slice.iter().zip(b_slice.iter()) {
-        ret += (*i) * (*j);
-    }
-    return ret;
-}
-
-#[lang = "panic_fmt"]
-extern fn panic_fmt(args: &core::fmt::Arguments,
-                    file: &str,
-                    line: u32) -> ! {
-    loop {}
-}
-
-#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
-#[lang = "eh_personality"] extern fn eh_personality() {}
-# #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 }
-# fn main() {}
-```
-
-Note that there is one extra lang item here which differs from the examples
-above, `panic_fmt`. This must be defined by consumers of libcore because the
-core library declares panics, but it does not define it. The `panic_fmt`
-lang item is this crate's definition of panic, and it must be guaranteed to
-never return.
-
-As can be seen in this example, the core library is intended to provide the
-power of Rust in all circumstances, regardless of platform requirements. Further
-libraries, such as liballoc, add functionality to libcore which make other
-platform-specific assumptions, but continue to be more portable than the
-standard library itself.
-
-# Interacting with the compiler internals
-
-> **Note**: this section is specific to the `rustc` compiler; these
-> parts of the language may never be fully specified and so details may
-> differ wildly between implementations (and even versions of `rustc`
-> itself).
->
-> Furthermore, this is just an overview; the best form of
-> documentation for specific instances of these features are their
-> definitions and uses in `std`.
-
-The Rust language currently has two orthogonal mechanisms for allowing
-libraries to interact directly with the compiler and vice versa:
-
-- intrinsics, functions built directly into the compiler providing
-  very basic low-level functionality,
-- lang-items, special functions, types and traits in libraries marked
-  with specific `#[lang]` attributes
-
-## Intrinsics
-
-> **Note**: intrinsics will forever have an unstable interface, it is
-> recommended to use the stable interfaces of libcore rather than intrinsics
-> directly.
-
-These are imported as if they were FFI functions, with the special
-`rust-intrinsic` ABI. For example, if one was in a freestanding
-context, but wished to be able to `transmute` between types, and
-perform efficient pointer arithmetic, one would import those functions
-via a declaration like
-
-```
-# #![feature(intrinsics)]
-# fn main() {}
-
-extern "rust-intrinsic" {
-    fn transmute<T, U>(x: T) -> U;
-
-    fn offset<T>(dst: *const T, offset: isize) -> *const T;
-}
-```
-
-As with any other FFI functions, these are always `unsafe` to call.
-
-## Lang items
-
-> **Note**: lang items are often provided by crates in the Rust distribution,
-> and lang items themselves have an unstable interface. It is recommended to use
-> officially distributed crates instead of defining your own lang items.
-
-The `rustc` compiler has certain pluggable operations, that is,
-functionality that isn't hard-coded into the language, but is
-implemented in libraries, with a special marker to tell the compiler
-it exists. The marker is the attribute `#[lang="..."]` and there are
-various different values of `...`, i.e. various different 'lang
-items'.
-
-For example, `Box` pointers require two lang items, one for allocation
-and one for deallocation. A freestanding program that uses the `Box`
-sugar for dynamic allocations via `malloc` and `free`:
-
-```
-#![feature(lang_items, box_syntax, start, no_std)]
-#![no_std]
-
-extern crate libc;
-
-extern {
-    fn abort() -> !;
-}
-
-#[lang = "owned_box"]
-pub struct Box<T>(*mut T);
-
-#[lang="exchange_malloc"]
-unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
-    let p = libc::malloc(size as libc::size_t) as *mut u8;
-
-    // malloc failed
-    if p as usize == 0 {
-        abort();
-    }
-
-    p
-}
-#[lang="exchange_free"]
-unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
-    libc::free(ptr as *mut libc::c_void)
-}
-
-#[start]
-fn main(argc: isize, argv: *const *const u8) -> isize {
-    let x = box 1;
-
-    0
-}
-
-#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
-#[lang = "eh_personality"] extern fn eh_personality() {}
-#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
-```
-
-Note the use of `abort`: the `exchange_malloc` lang item is assumed to
-return a valid pointer, and so needs to do the check internally.
-
-Other features provided by lang items include:
-
-- overloadable operators via traits: the traits corresponding to the
-  `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
-  marked with lang items; those specific four are `eq`, `ord`,
-  `deref`, and `add` respectively.
-- stack unwinding and general failure; the `eh_personality`, `fail`
-  and `fail_bounds_checks` lang items.
-- the traits in `std::marker` used to indicate types of
-  various kinds; lang items `send`, `sync` and `copy`.
-- the marker types and variance indicators found in
-  `std::marker`; lang items `covariant_type`,
-  `contravariant_lifetime`, etc.
-
-Lang items are loaded lazily by the compiler; e.g. if one never uses
-`Box` then there is no need to define functions for `exchange_malloc`
-and `exchange_free`. `rustc` will emit an error when an item is needed
-but not found in the current crate or any that it depends on.
diff --git a/src/doc/trpl/unstable.md b/src/doc/trpl/unstable.md
new file mode 100644 (file)
index 0000000..e8e02cc
--- /dev/null
@@ -0,0 +1 @@
+% Unstable Rust
index 6b56c2b630346ff32c1cf6650917017e0204fc1a..c5c58bb49ac361f34df30451b9badd02450acab9 100644 (file)
@@ -12,9 +12,9 @@
 #![cfg_attr(rustdoc, feature(rustdoc))]
 
 #[cfg(rustdoc)]
-extern crate "rustdoc" as this;
+extern crate rustdoc as this;
 
 #[cfg(rustc)]
-extern crate "rustc_driver" as this;
+extern crate rustc_driver as this;
 
 fn main() { this::main() }
diff --git a/src/etc/check-sanitycheck.py b/src/etc/check-sanitycheck.py
new file mode 100644 (file)
index 0000000..0d9c430
--- /dev/null
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+# 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.
+
+import os
+import sys
+import functools
+import resource
+
+STATUS = 0
+
+
+def error_unless_permitted(env_var, message):
+    global STATUS
+    if not os.getenv(env_var):
+        sys.stderr.write(message)
+        STATUS = 1
+
+
+def only_on(platforms):
+    def decorator(func):
+        @functools.wraps(func)
+        def inner():
+            if any(map(lambda x: sys.platform.startswith(x), platforms)):
+                func()
+        return inner
+    return decorator
+
+
+@only_on(('linux', 'darwin', 'freebsd', 'openbsd'))
+def check_rlimit_core():
+    soft, hard = resource.getrlimit(resource.RLIMIT_CORE)
+    if soft > 0:
+        error_unless_permitted('ALLOW_NONZERO_RLIMIT_CORE', """\
+RLIMIT_CORE is set to a nonzero value (%d). During debuginfo, the test suite
+will segfault many rustc's, creating many potentially large core files.
+set ALLOW_NONZERO_RLIMIT_CORE to ignore this warning
+""" % (soft))
+
+
+def main():
+    check_rlimit_core()
+
+if __name__ == '__main__':
+    main()
+    sys.exit(STATUS)
index ce972c91c8180a41d0cb6fffba7eff5aeadb82de..86fa779cced5fe81f02fb8eb2f417a5c2209955a 100644 (file)
@@ -242,4 +242,3 @@ print
 for line in lines:
     print "* " + line
 print
-
index c5587bb10d1dacf3840b35dc5350055e1b61cbec..4e489df7dd75a76412e4e417751845fbb7f41153 100755 (executable)
@@ -27,9 +27,18 @@ def rust_pretty_printer_lookup_function(val):
     if type_code == gdb.TYPE_CODE_STRUCT:
         struct_kind = classify_struct(val.type)
 
+        if struct_kind == STRUCT_KIND_SLICE:
+            return RustSlicePrinter(val)
+
         if struct_kind == STRUCT_KIND_STR_SLICE:
             return RustStringSlicePrinter(val)
 
+        if struct_kind == STRUCT_KIND_STD_VEC:
+            return RustStdVecPrinter(val)
+
+        if struct_kind == STRUCT_KIND_STD_STRING:
+            return RustStdStringPrinter(val)
+
         if struct_kind == STRUCT_KIND_TUPLE:
             return RustTuplePrinter(val)
 
@@ -172,6 +181,28 @@ class RustTupleStructPrinter:
     def display_hint(self):
         return "array"
 
+class RustSlicePrinter:
+    def __init__(self, val):
+        self.val = val
+
+    def display_hint(self):
+        return "array"
+
+    def to_string(self):
+        length = int(self.val["length"])
+        return self.val.type.tag + ("(len: %i)" % length)
+
+    def children(self):
+        cs = []
+        length = int(self.val["length"])
+        data_ptr = self.val["data_ptr"]
+        assert data_ptr.type.code == gdb.TYPE_CODE_PTR
+        pointee_type = data_ptr.type.target()
+
+        for index in range(0, length):
+            cs.append((str(index), (data_ptr + index).dereference()))
+
+        return cs
 
 class RustStringSlicePrinter:
     def __init__(self, val):
@@ -181,6 +212,35 @@ class RustStringSlicePrinter:
         slice_byte_len = self.val["length"]
         return '"%s"' % self.val["data_ptr"].string(encoding="utf-8", length=slice_byte_len)
 
+class RustStdVecPrinter:
+    def __init__(self, val):
+        self.val = val
+
+    def display_hint(self):
+        return "array"
+
+    def to_string(self):
+        length = int(self.val["len"])
+        cap = int(self.val["cap"])
+        return self.val.type.tag + ("(len: %i, cap: %i)" % (length, cap))
+
+    def children(self):
+        cs = []
+        (length, data_ptr) = extract_length_and_data_ptr_from_std_vec(self.val)
+        pointee_type = data_ptr.type.target()
+
+        for index in range(0, length):
+            cs.append((str(index), (data_ptr + index).dereference()))
+        return cs
+
+class RustStdStringPrinter:
+    def __init__(self, val):
+        self.val = val
+
+    def to_string(self):
+        (length, data_ptr) = extract_length_and_data_ptr_from_std_vec(self.val["vec"])
+        return '"%s"' % data_ptr.string(encoding="utf-8", length=length)
+
 
 class RustCStyleEnumPrinter:
     def __init__(self, val):
@@ -204,19 +264,38 @@ STRUCT_KIND_TUPLE           = 2
 STRUCT_KIND_TUPLE_VARIANT   = 3
 STRUCT_KIND_STRUCT_VARIANT  = 4
 STRUCT_KIND_CSTYLE_VARIANT  = 5
-STRUCT_KIND_STR_SLICE       = 6
+STRUCT_KIND_SLICE           = 6
+STRUCT_KIND_STR_SLICE       = 7
+STRUCT_KIND_STD_VEC         = 8
+STRUCT_KIND_STD_STRING      = 9
 
 
 def classify_struct(type):
+    # print("\nclassify_struct: tag=%s\n" % type.tag)
     if type.tag == "&str":
         return STRUCT_KIND_STR_SLICE
 
+    if type.tag.startswith("&[") and type.tag.endswith("]"):
+        return STRUCT_KIND_SLICE
+
     fields = list(type.fields())
     field_count = len(fields)
 
     if field_count == 0:
         return STRUCT_KIND_REGULAR_STRUCT
 
+    if (field_count == 3 and
+        fields[0].name == "ptr" and
+        fields[1].name == "len" and
+        fields[2].name == "cap" and
+        type.tag.startswith("Vec<")):
+        return STRUCT_KIND_STD_VEC
+
+    if (field_count == 1 and
+        fields[0].name == "vec" and
+        type.tag == "String"):
+        return STRUCT_KIND_STD_STRING
+
     if fields[0].name == "RUST$ENUM$DISR":
         if field_count == 1:
             return STRUCT_KIND_CSTYLE_VARIANT
@@ -254,3 +333,11 @@ def get_field_at_index(val, index):
             return field
         i += 1
     return None
+
+def extract_length_and_data_ptr_from_std_vec(vec_val):
+    length = int(vec_val["len"])
+    vec_ptr_val = vec_val["ptr"]
+    unique_ptr_val = vec_ptr_val[first_field(vec_ptr_val)]
+    data_ptr = unique_ptr_val[first_field(unique_ptr_val)]
+    assert data_ptr.type.code == gdb.TYPE_CODE_PTR
+    return (length, data_ptr)
index 22792ff76355149b4ee8eb006fba37618b094caf..a212e3a04357eccc564097ab90b203d1afc38a8f 100644 (file)
@@ -96,6 +96,9 @@ There are a number of supported commands:
   highlights for example. If you want to simply check the presence of
   given node or attribute, use an empty string (`""`) as a `PATTERN`.
 
+* `@count PATH XPATH COUNT' checks for the occurrence of given XPath
+  in the given file. The number of occurrences must match the given count.
+
 All conditions can be negated with `!`. `@!has foo/type.NoSuch.html`
 checks if the given file does not exist, for example.
 
@@ -333,6 +336,11 @@ def check_tree_text(tree, path, pat, regexp):
     return ret
 
 
+def check_tree_count(tree, path, count):
+    path = normalize_xpath(path)
+    return len(tree.findall(path)) == count
+
+
 def check(target, commands):
     cache = CachedFiles(target)
     for c in commands:
@@ -360,6 +368,13 @@ def check(target, commands):
                 raise RuntimeError('Invalid number of @{} arguments \
                                     at line {}'.format(c.cmd, c.lineno))
 
+        elif c.cmd == 'count': # count test
+            if len(c.args) == 3: # @count <path> <pat> <count> = count test
+                ret = check_tree_count(cache.get_tree(c.args[0]), c.args[1], int(c.args[2]))
+            else:
+                raise RuntimeError('Invalid number of @{} arguments \
+                                    at line {}'.format(c.cmd, c.lineno))
+
         elif c.cmd == 'valid-html':
             raise RuntimeError('Unimplemented @valid-html at line {}'.format(c.lineno))
 
index 2bf919d7e2cce794e2378feb49cda5cfd2c31907..249b5d22b6b23ad763df4d8a586abb33ae82cc79 100644 (file)
@@ -165,6 +165,16 @@ void posix88_consts() {
   put_const(S_IWUSR, int);
   put_const(S_IRUSR, int);
 
+  put_const(S_IRWXG, int);
+  put_const(S_IXGRP, int);
+  put_const(S_IWGRP, int);
+  put_const(S_IRGRP, int);
+
+  put_const(S_IRWXO, int);
+  put_const(S_IXOTH, int);
+  put_const(S_IWOTH, int);
+  put_const(S_IROTH, int);
+
 #ifdef F_OK
   put_const(F_OK, int);
 #endif
index 42c83b6a42ed6f6df6ad7ec765fa5eb5e809b897..20f9b1ce66c967410d07dfce57d3d191803f56b4 100644 (file)
@@ -40,31 +40,12 @@ def print_struct_val(val, internal_dict):
 
     if is_vec_slice(val):
         return print_vec_slice_val(val, internal_dict)
+    elif is_std_vec(val):
+        return print_std_vec_val(val, internal_dict)
     else:
         return print_struct_val_starting_from(0, val, internal_dict)
 
 
-def print_vec_slice_val(val, internal_dict):
-    length = val.GetChildAtIndex(1).GetValueAsUnsigned()
-
-    data_ptr_val = val.GetChildAtIndex(0)
-    data_ptr_type = data_ptr_val.GetType()
-    assert data_ptr_type.IsPointerType()
-
-    element_type = data_ptr_type.GetPointeeType()
-    element_type_size = element_type.GetByteSize()
-
-    start_address = data_ptr_val.GetValueAsUnsigned()
-
-    def render_element(i):
-        address = start_address + i * element_type_size
-        element_val = val.CreateValueFromAddress(val.GetName() +
-                                                 ("[%s]" % i), address, element_type)
-        return print_val(element_val, internal_dict)
-
-    return "&[%s]" % (', '.join([render_element(i) for i in range(length)]))
-
-
 def print_struct_val_starting_from(field_start_index, val, internal_dict):
     '''
     Prints a struct, tuple, or tuple struct value with Rust syntax.
@@ -100,6 +81,16 @@ def print_struct_val_starting_from(field_start_index, val, internal_dict):
             this += field_name + ": "
 
         field_val = val.GetChildAtIndex(child_index)
+
+        if not field_val.IsValid():
+            field = t.GetFieldAtIndex(child_index)
+            # LLDB is not good at handling zero-sized values, so we have to help
+            # it a little
+            if field.GetType().GetByteSize() == 0:
+                return this + extract_type_name(field.GetType().GetName())
+            else:
+                return this + "<invalid value>"
+
         return this + print_val(field_val, internal_dict)
 
     body = separator.join([render_child(idx) for idx in range(field_start_index, num_children)])
@@ -195,6 +186,30 @@ def print_fixed_size_vec_val(val, internal_dict):
     return output
 
 
+def print_vec_slice_val(val, internal_dict):
+    length = val.GetChildAtIndex(1).GetValueAsUnsigned()
+
+    data_ptr_val = val.GetChildAtIndex(0)
+    data_ptr_type = data_ptr_val.GetType()
+
+    return "&[%s]" % print_array_of_values(val.GetName(),
+                                           data_ptr_val,
+                                           length,
+                                           internal_dict)
+
+
+def print_std_vec_val(val, internal_dict):
+    length = val.GetChildAtIndex(1).GetValueAsUnsigned()
+
+    # Vec<> -> Unique<> -> NonZero<> -> *T
+    data_ptr_val = val.GetChildAtIndex(0).GetChildAtIndex(0).GetChildAtIndex(0)
+    data_ptr_type = data_ptr_val.GetType()
+
+    return "vec![%s]" % print_array_of_values(val.GetName(),
+                                              data_ptr_val,
+                                              length,
+                                              internal_dict)
+
 #=--------------------------------------------------------------------------------------------------
 # Helper Functions
 #=--------------------------------------------------------------------------------------------------
@@ -243,3 +258,44 @@ def is_vec_slice(val):
 
     type_name = extract_type_name(ty.GetName()).replace("&'static", "&").replace(" ", "")
     return type_name.startswith("&[") and type_name.endswith("]")
+
+def is_std_vec(val):
+    ty = val.GetType()
+    if ty.GetTypeClass() != lldb.eTypeClassStruct:
+        return False
+
+    if ty.GetNumberOfFields() != 3:
+        return False
+
+    if ty.GetFieldAtIndex(0).GetName() != "ptr":
+        return False
+
+    if ty.GetFieldAtIndex(1).GetName() != "len":
+        return False
+
+    if ty.GetFieldAtIndex(2).GetName() != "cap":
+        return False
+
+    return ty.GetName().startswith("collections::vec::Vec<")
+
+
+def print_array_of_values(array_name, data_ptr_val, length, internal_dict):
+    '''Prints a contigous memory range, interpreting it as values of the
+       pointee-type of data_ptr_val.'''
+
+    data_ptr_type = data_ptr_val.GetType()
+    assert data_ptr_type.IsPointerType()
+
+    element_type = data_ptr_type.GetPointeeType()
+    element_type_size = element_type.GetByteSize()
+
+    start_address = data_ptr_val.GetValueAsUnsigned()
+
+    def render_element(i):
+        address = start_address + i * element_type_size
+        element_val = data_ptr_val.CreateValueFromAddress(array_name + ("[%s]" % i),
+                                                          address,
+                                                          element_type)
+        return print_val(element_val, internal_dict)
+
+    return ', '.join([render_element(i) for i in range(length)])
index b506aff94e7209372ba7197874cef1109fec0a21..ca59b1c7d34a2faeb8f967d73a55355aea9c2a00 100755 (executable)
@@ -18,7 +18,7 @@ LIB_PREFIX=lib
 
 OS=`uname -s`
 case $OS in
-    ("Linux"|"FreeBSD"|"DragonFly"|"OpenBSD")
+    ("Linux"|"FreeBSD"|"DragonFly"|"Bitrig"|"OpenBSD")
     BIN_SUF=
     LIB_SUF=.so
     ;;
index 876db17a248a6fdf360125609a621a432855f4b5..e36e6abde9178dd6b5c1515ff6d4a7a33854f9d1 100644 (file)
@@ -1,6 +1,6 @@
 The purpose of these headers is to fix issues with mingw v4.0, as described in #9246.
 
-This works by adding this directory to GCC include search path before mingw system headers directories, 
+This works by adding this directory to GCC include search path before mingw system headers directories,
 so we can intercept their inclusions and add missing definitions without having to modify files in mingw/include.
 
 Once mingw fixes all 3 issues mentioned in #9246, this directory and all references to it from rust/mk/* may be removed.
index a4234159cb81c9ee624df8b7e4b10aab01aa0788..e5e8c9f11bd82691e823583bfc140d4c46d1664c 100644 (file)
@@ -57,7 +57,16 @@ else:
 args.extend(components)
 out = run(args)
 for lib in out.strip().replace("\n", ' ').split(' '):
-    lib = lib.strip()[2:] # chop of the leading '-l'
+    if len(lib) == 0:
+        continue
+    # in some cases we get extra spaces in between libs so ignore those
+    if len(lib) == 1 and lib == ' ':
+        continue
+    # not all libs strictly follow -lfoo, on Bitrig, there is -pthread
+    if lib[0:2] == '-l':
+        lib = lib.strip()[2:]
+    elif lib[0] == '-':
+        lib = lib.strip()[1:]
     f.write("#[link(name = \"" + lib + "\"")
     # LLVM libraries are all static libraries
     if 'LLVM' in lib:
index d4f1071c724b6a0cd17020514890601005ac1925..918c0c66f76df070b99848c2d53be8a5894ad6db 100755 (executable)
@@ -288,6 +288,7 @@ VAL_OPTIONS=""
 flag uninstall "only uninstall from the installation prefix"
 valopt prefix "" "set installation prefix"
 valopt date "" "use the YYYY-MM-DD nightly instead of the current nightly"
+valopt channel "beta" "use the selected release channel [beta]"
 flag save "save the downloaded nightlies to ~/.rustup"
 
 if [ $HELP -eq 1 ]
@@ -307,7 +308,7 @@ CFG_CPUTYPE=$(uname -m)
 
 if [ $CFG_OSTYPE = Darwin -a $CFG_CPUTYPE = i386 ]
 then
-    # Darwin's `uname -s` lies and always returns i386. We have to use sysctl
+    # Darwin's `uname -m` lies and always returns i386. We have to use sysctl
     # instead.
     if sysctl hw.optional.x86_64 | grep -q ': 1'
     then
@@ -335,7 +336,7 @@ case $CFG_OSTYPE in
     MINGW32*)
         CFG_OSTYPE=pc-mingw32
         ;;
-# Thad's Cygwin identifers below
+# Thad's Cygwin identifiers below
 
 #   Vista 32 bit
     CYGWIN_NT-6.0)
@@ -437,7 +438,7 @@ CFG_TMP_DIR=$(mktemp -d 2>/dev/null \
            || create_tmp_dir)
 
 # If we're saving nightlies and we didn't specify which one, grab the latest
-# verison from the perspective of the server. Buildbot has typically finished
+# version from the perspective of the server. Buildbot has typically finished
 # building and uploading by ~8UTC, but we want to include a little buffer.
 #
 # FIXME It would be better to use the known most recent nightly that has been
@@ -449,18 +450,28 @@ then
 fi
 
 RUST_URL="https://static.rust-lang.org/dist"
-RUST_PACKAGE_NAME=rust-nightly
+case "$CFG_CHANNEL" in
+    nightly)
+        # add a date suffix if we want a particular nightly.
+        if [ -n "${CFG_DATE}" ];
+        then
+            RUST_URL="${RUST_URL}/${CFG_DATE}"
+        fi
+
+        RUST_PACKAGE_NAME=rust-nightly
+        ;;
+    beta)
+        RUST_PACKAGE_NAME=rust-1.0.0-beta
+        ;;
+    *)
+        err "Currently 'beta' and 'nightly' are the only supported channels"
+esac
+
 RUST_PACKAGE_NAME_AND_TRIPLE="${RUST_PACKAGE_NAME}-${HOST_TRIPLE}"
 RUST_TARBALL_NAME="${RUST_PACKAGE_NAME_AND_TRIPLE}.tar.gz"
 RUST_LOCAL_INSTALL_DIR="${CFG_TMP_DIR}/${RUST_PACKAGE_NAME_AND_TRIPLE}"
 RUST_LOCAL_INSTALL_SCRIPT="${RUST_LOCAL_INSTALL_DIR}/install.sh"
 
-# add a date suffix if we want a particular nighly.
-if [ -n "${CFG_DATE}" ];
-then
-    RUST_URL="${RUST_URL}/${CFG_DATE}"
-fi
-
 download_hash() {
     msg "Downloading ${remote_sha256}"
     remote_sha256=`"${CFG_CURL}" -f "${remote_sha256}"`
index 264af5f9854cc81c5ec73306167840aab1187807..0349ccf9b66408bf80833afe3d4b96d68dd6ceef 100644 (file)
@@ -46,13 +46,13 @@ snapshot_files = {
         "winnt": ["bin/rustc.exe"],
         "freebsd": ["bin/rustc"],
         "dragonfly": ["bin/rustc"],
+        "bitrig": ["bin/rustc"],
         "openbsd": ["bin/rustc"],
         }
 
 winnt_runtime_deps_32 = ["libgcc_s_dw2-1.dll", "libstdc++-6.dll"]
 winnt_runtime_deps_64 = ["libgcc_s_seh-1.dll", "libstdc++-6.dll"]
 
-
 def parse_line(n, line):
     global snapshotfile
 
@@ -101,6 +101,8 @@ def get_kernel(triple):
         return "freebsd"
     if os_name == "dragonfly":
         return "dragonfly"
+    if os_name == "bitrig":
+        return "bitrig"
     if os_name == "openbsd":
         return "openbsd"
     return "linux"
index 8c6cf9addc8995d436807763eef12d0e7a59739b..05ba658a918cee76555609ed16aecf423f43a1d3 100644 (file)
Binary files a/src/etc/snapshot.pyc and b/src/etc/snapshot.pyc differ
index e1b3c69c179dfaff5744ea4bf853e6b0d90c9ef9..e86f7fb58a4656330ebdfab5e75d72f86f5e9af9 100644 (file)
@@ -70,4 +70,3 @@ consistent with the licensing of the Independent Modules.
 The availability of this Exception does not imply any general
 presumption that third-party software is unaffected by the copyleft
 requirements of the license of GCC.
-
index fd3309dce12cbd01e1c573e05beeddb096a7c2f1..c524fae7f0a42e6272ce736cd5d54517702baa11 100644 (file)
@@ -13,7 +13,7 @@ import fileinput
 import subprocess
 import re
 import os
-from licenseck import *
+from licenseck import check_license
 import snapshot
 
 err = 0
@@ -22,13 +22,8 @@ cr_flag = "ignore-tidy-cr"
 tab_flag = "ignore-tidy-tab"
 linelength_flag = "ignore-tidy-linelength"
 
-# Be careful to support Python 2.4, 2.6, and 3.x here!
-config_proc = subprocess.Popen(["git", "config", "core.autocrlf"],
-                               stdout=subprocess.PIPE)
-result = config_proc.communicate()[0]
-
-true = "true".encode('utf8')
-autocrlf = result.strip() == true if result is not None else False
+interesting_files = ['.rs', '.py', '.js', '.sh', '.c', '.h']
+uninteresting_files = ['miniz.c', 'jquery', 'rust_android_dummy']
 
 
 def report_error_name_no(name, no, s):
@@ -51,6 +46,34 @@ def do_license_check(name, contents):
     if not check_license(name, contents):
         report_error_name_no(name, 1, "incorrect license")
 
+
+def update_counts(current_name):
+    global file_counts
+    global count_other_linted_files
+
+    _, ext = os.path.splitext(current_name)
+
+    if ext in interesting_files:
+        file_counts[ext] += 1
+    else:
+        count_other_linted_files += 1
+
+
+def interesting_file(f):
+    if any(x in f for x in uninteresting_files):
+        return False
+
+    return any(os.path.splitext(f)[1] == ext for ext in interesting_files)
+
+
+# Be careful to support Python 2.4, 2.6, and 3.x here!
+config_proc = subprocess.Popen(["git", "config", "core.autocrlf"],
+                               stdout=subprocess.PIPE)
+result = config_proc.communicate()[0]
+
+true = "true".encode('utf8')
+autocrlf = result.strip() == true if result is not None else False
+
 current_name = ""
 current_contents = ""
 check_tab = True
@@ -63,28 +86,16 @@ if len(sys.argv) < 2:
 
 src_dir = sys.argv[1]
 
-try:
-    count_lines = 0
-    count_non_blank_lines = 0
+count_lines = 0
+count_non_blank_lines = 0
+count_other_linted_files = 0
 
-    interesting_files = ['.rs', '.py', '.js', '.sh', '.c', '.h']
+file_counts = {ext: 0 for ext in interesting_files}
 
-    file_counts = {ext: 0 for ext in interesting_files}
-    file_counts['other'] = 0
-
-    def update_counts(current_name):
-        global file_counts
-        _, ext = os.path.splitext(current_name)
-
-        if ext in file_counts:
-            file_counts[ext] += 1
-        else:
-            file_counts['other'] += 1
-
-    all_paths = set()
+all_paths = set()
 
+try:
     for (dirpath, dirnames, filenames) in os.walk(src_dir):
-
         # Skip some third-party directories
         skippable_dirs = {
             'src/jemalloc',
@@ -103,14 +114,6 @@ try:
         if any(d in dirpath for d in skippable_dirs):
             continue
 
-        def interesting_file(f):
-            if "miniz.c" in f \
-            or "jquery" in f \
-            or "rust_android_dummy" in f:
-                return False
-
-            return any(os.path.splitext(f)[1] == ext for ext in interesting_files)
-
         file_names = [os.path.join(dirpath, f) for f in filenames
                       if interesting_file(f)
                       and not f.endswith("_gen.rs")
@@ -196,10 +199,11 @@ except UnicodeDecodeError as e:
     report_err("UTF-8 decoding error " + str(e))
 
 print
-for ext in file_counts:
-    print "* linted " + str(file_counts[ext]) + " " + ext + " files"
-print "* total lines of code: " + str(count_lines)
-print "* total non-blank lines of code: " + str(count_non_blank_lines)
+for ext in sorted(file_counts, key=file_counts.get, reverse=True):
+    print "* linted {} {} files".format(file_counts[ext], ext)
+print "* linted {} other files".format(count_other_linted_files)
+print "* total lines of code: {}".format(count_lines)
+print "* total non-blank lines of code: {}".format(count_non_blank_lines)
 print
 
 sys.exit(err)
index dc8716d1378df6ce3296716f204ad70a444f0c88..312076b1b13b2818d43480b32ffea2c96a097ef4 100755 (executable)
@@ -84,8 +84,8 @@ def fetch(f):
         sys.stderr.write("cannot load %s" % f)
         exit(1)
 
-def is_valid_unicode(n):
-    return 0 <= n <= 0xD7FF or 0xE000 <= n <= 0x10FFFF
+def is_surrogate(n):
+    return 0xD800 <= n <= 0xDFFF
 
 def load_unicode_data(f):
     fetch(f)
@@ -96,19 +96,28 @@ def load_unicode_data(f):
     canon_decomp = {}
     compat_decomp = {}
 
+    udict = {};
+    range_start = -1;
     for line in fileinput.input(f):
-        fields = line.split(";")
-        if len(fields) != 15:
+        data = line.split(';');
+        if len(data) != 15:
             continue
-        [code, name, gencat, combine, bidi,
-         decomp, deci, digit, num, mirror,
-         old, iso, upcase, lowcase, titlecase ] = fields
-
-        code_org = code
-        code     = int(code, 16)
-
-        if not is_valid_unicode(code):
+        cp = int(data[0], 16);
+        if is_surrogate(cp):
             continue
+        if range_start >= 0:
+            for i in xrange(range_start, cp):
+                udict[i] = data;
+            range_start = -1;
+        if data[1].endswith(", First>"):
+            range_start = cp;
+            continue;
+        udict[cp] = data;
+
+    for code in udict:
+        [code_org, name, gencat, combine, bidi,
+         decomp, deci, digit, num, mirror,
+         old, iso, upcase, lowcase, titlecase ] = udict[code];
 
         # generate char to char direct common and simple conversions
         # uppercase to lowercase
@@ -290,11 +299,11 @@ def emit_bsearch_range_table(f):
 fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
     use core::cmp::Ordering::{Equal, Less, Greater};
     use core::slice::SliceExt;
-    r.binary_search(|&(lo,hi)| {
+    r.binary_search_by(|&(lo,hi)| {
         if lo <= c && c <= hi { Equal }
         else if hi < c { Less }
         else { Greater }
-    }).found().is_some()
+    }).is_ok()
 }\n
 """)
 
@@ -303,7 +312,7 @@ def emit_table(f, name, t_data, t_type = "&'static [(char, char)]", is_pub=True,
     pub_string = ""
     if is_pub:
         pub_string = "pub "
-    f.write("    %sstatic %s: %s = &[\n" % (pub_string, name, t_type))
+    f.write("    %sconst %s: %s = &[\n" % (pub_string, name, t_type))
     data = ""
     first = True
     for dat in t_data:
@@ -329,14 +338,14 @@ def emit_property_module(f, mod, tbl, emit_fn):
 def emit_regex_module(f, cats, w_data):
     f.write("pub mod regex {\n")
     regex_class = "&'static [(char, char)]"
-    class_table = "&'static [(&'static str, &'static %s)]" % regex_class
+    class_table = "&'static [(&'static str, %s)]" % regex_class
 
     emit_table(f, "UNICODE_CLASSES", cats, class_table,
-        pfun=lambda x: "(\"%s\",&super::%s::%s_table)" % (x[0], x[1], x[0]))
+        pfun=lambda x: "(\"%s\",super::%s::%s_table)" % (x[0], x[1], x[0]))
 
-    f.write("    pub static PERLD: &'static %s = &super::general_category::Nd_table;\n\n"
+    f.write("    pub const PERLD: %s = super::general_category::Nd_table;\n\n"
             % regex_class)
-    f.write("    pub static PERLS: &'static %s = &super::property::White_Space_table;\n\n"
+    f.write("    pub const PERLS: %s = super::property::White_Space_table;\n\n"
             % regex_class)
 
     emit_table(f, "PERLW", w_data, regex_class)
@@ -350,7 +359,7 @@ def emit_conversions_module(f, lowerupper, upperlower):
     use core::slice::SliceExt;
     use core::option::Option;
     use core::option::Option::{Some, None};
-    use core::slice;
+    use core::result::Result::{Ok, Err};
 
     pub fn to_lower(c: char) -> char {
         match bsearch_case_table(c, LuLl_table) {
@@ -367,13 +376,13 @@ def emit_conversions_module(f, lowerupper, upperlower):
     }
 
     fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<usize> {
-        match table.binary_search(|&(key, _)| {
+        match table.binary_search_by(|&(key, _)| {
             if c == key { Equal }
             else if key < c { Less }
             else { Greater }
         }) {
-            slice::BinarySearchResult::Found(i) => Some(i),
-            slice::BinarySearchResult::NotFound(_) => None,
+            Ok(i) => Some(i),
+            Err(_) => None,
         }
     }
 
@@ -386,10 +395,9 @@ def emit_conversions_module(f, lowerupper, upperlower):
 
 def emit_grapheme_module(f, grapheme_table, grapheme_cats):
     f.write("""pub mod grapheme {
-    use core::kinds::Copy;
     use core::slice::SliceExt;
     pub use self::GraphemeCat::*;
-    use core::slice;
+    use core::result::Result::{Ok, Err};
 
     #[allow(non_camel_case_types)]
     #[derive(Clone, Copy)]
@@ -401,16 +409,16 @@ def emit_grapheme_module(f, grapheme_table, grapheme_cats):
 
     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, _)| {
+        match r.binary_search_by(|&(lo, hi, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
             else { Greater }
         }) {
-            slice::BinarySearchResult::Found(idx) => {
+            Ok(idx) => {
                 let (_, _, cat) = r[idx];
                 cat
             }
-            slice::BinarySearchResult::NotFound(_) => GC_Any
+            Err(_) => GC_Any
         }
     }
 
@@ -430,20 +438,20 @@ def emit_charwidth_module(f, width_table):
     f.write("    use core::option::Option;\n")
     f.write("    use core::option::Option::{Some, None};\n")
     f.write("    use core::slice::SliceExt;\n")
-    f.write("    use core::slice;\n")
+    f.write("    use core::result::Result::{Ok, Err};\n")
     f.write("""
     fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 {
         use core::cmp::Ordering::{Equal, Less, Greater};
-        match r.binary_search(|&(lo, hi, _, _)| {
+        match r.binary_search_by(|&(lo, hi, _, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
             else { Greater }
         }) {
-            slice::BinarySearchResult::Found(idx) => {
+            Ok(idx) => {
                 let (_, _, r_ncjk, r_cjk) = r[idx];
                 if is_cjk { r_cjk } else { r_ncjk }
             }
-            slice::BinarySearchResult::NotFound(_) => 1
+            Err(_) => 1
         }
     }
 """)
@@ -530,17 +538,17 @@ def emit_norm_module(f, canon, compat, combine, norm_props):
     fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
         use core::cmp::Ordering::{Equal, Less, Greater};
         use core::slice::SliceExt;
-        use core::slice;
-        match r.binary_search(|&(lo, hi, _)| {
+        use core::result::Result::{Ok, Err};
+        match r.binary_search_by(|&(lo, hi, _)| {
             if lo <= c && c <= hi { Equal }
             else if hi < c { Less }
             else { Greater }
         }) {
-            slice::BinarySearchResult::Found(idx) => {
+            Ok(idx) => {
                 let (_, _, result) = r[idx];
                 result
             }
-            slice::BinarySearchResult::NotFound(_) => 0
+            Err(_) => 0
         }
     }\n
 """)
@@ -609,7 +617,7 @@ if __name__ == "__main__":
             unicode_version = re.search(pattern, readme.read()).groups()
         rf.write("""
 /// The version of [Unicode](http://www.unicode.org/)
-/// that the `UnicodeChar` and `UnicodeStrPrelude` traits are based on.
+/// that the unicode parts of `CharExt` and `UnicodeStrPrelude` traits are based on.
 pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
 """ % unicode_version)
         (canon_decomp, compat_decomp, gencats, combines,
index 2d2a25e9e08e4ca0db81f3f2fd27d5174616f72e..595434747ddc414d71d8ac5543053f9eae33687d 100644 (file)
@@ -1 +1 @@
-0.12.0-5823-g522d09dfecbeca1595f25ac58c6d0178bbd21d7d
+0.12.0-7693-g9854143cba679834bc4ef932858cd5303f015a0e
index b584c44d8a6edb60a7244c93633a720b31e1a193..5a2b1c91754da3fb4f33a15fe6fcb657e0a4463a 100755 (executable)
@@ -4880,6 +4880,12 @@ case "${host}" in
        abi="elf"
        $as_echo "#define JEMALLOC_PURGE_MADVISE_FREE  " >>confdefs.h
 
+       ;;
+  *-*-openbsd*|*-*-bitrig*)
+       CFLAGS="$CFLAGS"
+       abi="elf"
+       $as_echo "#define JEMALLOC_PURGE_MADVISE_FREE  " >>confdefs.h
+
        ;;
   *-*-linux*)
        CFLAGS="$CFLAGS"
index e4afe88906b3301fb0b465db39d81e1dfea24d2d..fd7554d668e94d52e61ab6034dc8066e1be03cea 100644 (file)
@@ -288,6 +288,11 @@ case "${host}" in
        abi="elf"
        AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
        ;;
+  *-*-openbsd*|*-*-bitrig*)
+       CFLAGS="$CFLAGS"
+       abi="elf"
+       AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
+       ;;
   *-*-linux*)
        CFLAGS="$CFLAGS"
        CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
index 934e6ab2159166bd9823779a88670684997731ae..8b884c56505b25ccec7d8ab4083d11adb8192eff 100644 (file)
@@ -33,7 +33,7 @@
 //!
 //! Sharing some immutable data between tasks:
 //!
-//! ```
+//! ```no_run
 //! use std::sync::Arc;
 //! use std::thread;
 //!
@@ -50,7 +50,7 @@
 //!
 //! Sharing mutable data safely between tasks with a `Mutex`:
 //!
-//! ```
+//! ```no_run
 //! use std::sync::{Arc, Mutex};
 //! use std::thread;
 //!
 //! }
 //! ```
 
+use boxed::Box;
+
 use core::prelude::*;
 
 use core::atomic;
 use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
 use core::fmt;
-use core::cmp::{Ordering};
+use core::cmp::Ordering;
 use core::default::Default;
 use core::mem::{min_align_of, size_of};
 use core::mem;
@@ -86,13 +88,17 @@ use heap::deallocate;
 
 /// An atomically reference counted wrapper for shared state.
 ///
-/// # Example
+/// # Examples
 ///
 /// In this example, a large vector of floats is shared between several tasks.
 /// With simple pipes, without `Arc`, a copy would have to be made for each
 /// task.
 ///
-/// ```rust
+/// When you clone an `Arc<T>`, it will create another pointer to the data and
+/// increase the reference counter.
+///
+/// ```
+/// # #![feature(alloc, core)]
 /// use std::sync::Arc;
 /// use std::thread;
 ///
@@ -104,7 +110,7 @@ use heap::deallocate;
 ///         let child_numbers = shared_numbers.clone();
 ///
 ///         thread::spawn(move || {
-///             let local_numbers = child_numbers.as_slice();
+///             let local_numbers = &child_numbers[..];
 ///
 ///             // Work with the local numbers
 ///         });
@@ -125,8 +131,8 @@ unsafe impl<T: Sync + Send> Sync for Arc<T> { }
 
 /// A weak pointer to an `Arc`.
 ///
-/// Weak pointers will not keep the data inside of the `Arc` alive, and can be used to break cycles
-/// between `Arc` pointers.
+/// Weak pointers will not keep the data inside of the `Arc` alive, and can be
+/// used to break cycles between `Arc` pointers.
 #[unsafe_no_drop_flag]
 #[unstable(feature = "alloc",
            reason = "Weak pointers may not belong in this module.")]
@@ -139,6 +145,13 @@ pub struct Weak<T> {
 unsafe impl<T: Sync + Send> Send for Weak<T> { }
 unsafe impl<T: Sync + Send> Sync for Weak<T> { }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: fmt::Debug> fmt::Debug for Weak<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "(Weak)")
+    }
+}
+
 struct ArcInner<T> {
     strong: atomic::AtomicUsize,
     weak: atomic::AtomicUsize,
@@ -163,7 +176,7 @@ impl<T> Arc<T> {
     pub fn new(data: T) -> Arc<T> {
         // Start the weak pointer count as 1 which is the weak pointer that's
         // held by all the strong pointers (kinda), see std/rc.rs for more info
-        let x = box ArcInner {
+        let x: Box<_> = box ArcInner {
             strong: atomic::AtomicUsize::new(1),
             weak: atomic::AtomicUsize::new(1),
             data: data,
@@ -176,6 +189,7 @@ impl<T> Arc<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::sync::Arc;
     ///
     /// let five = Arc::new(5);
@@ -194,12 +208,28 @@ impl<T> Arc<T> {
 impl<T> Arc<T> {
     #[inline]
     fn inner(&self) -> &ArcInner<T> {
-        // This unsafety is ok because while this arc is alive we're guaranteed that the inner
-        // pointer is valid. Furthermore, we know that the `ArcInner` structure itself is `Sync`
-        // because the inner data is `Sync` as well, so we're ok loaning out an immutable pointer
-        // to these contents.
+        // This unsafety is ok because while this arc is alive we're guaranteed
+        // that the inner pointer is valid. Furthermore, we know that the
+        // `ArcInner` structure itself is `Sync` because the inner data is
+        // `Sync` as well, so we're ok loaning out an immutable pointer to these
+        // contents.
         unsafe { &**self._ptr }
     }
+
+    // Non-inlined part of `drop`.
+    #[inline(never)]
+    unsafe fn drop_slow(&mut self) {
+        let ptr = *self._ptr;
+
+        // Destroy the data at this time, even though we may not free the box
+        // allocation itself (there may still be weak pointers lying around).
+        drop(ptr::read(&self.inner().data));
+
+        if self.inner().weak.fetch_sub(1, Release) == 1 {
+            atomic::fence(Acquire);
+            deallocate(ptr as *mut u8, size_of::<ArcInner<T>>(), min_align_of::<ArcInner<T>>())
+        }
+    }
 }
 
 /// Get the number of weak references to this value.
@@ -212,6 +242,41 @@ pub fn weak_count<T>(this: &Arc<T>) -> usize { this.inner().weak.load(SeqCst) -
 #[unstable(feature = "alloc")]
 pub fn strong_count<T>(this: &Arc<T>) -> usize { this.inner().strong.load(SeqCst) }
 
+
+/// Try accessing a mutable reference to the contents behind an unique `Arc<T>`.
+///
+/// The access is granted only if this is the only reference to the object.
+/// Otherwise, `None` is returned.
+///
+/// # Examples
+///
+/// ```
+/// # #![feature(alloc)]
+/// extern crate alloc;
+/// # fn main() {
+/// use alloc::arc;
+///
+/// let mut four = arc::Arc::new(4);
+///
+/// arc::unique(&mut four).map(|num| *num = 5);
+/// # }
+/// ```
+#[inline]
+#[unstable(feature = "alloc")]
+pub fn unique<T>(this: &mut Arc<T>) -> Option<&mut T> {
+    if strong_count(this) == 1 && weak_count(this) == 0 {
+        // This unsafety is ok because we're guaranteed that the pointer
+        // returned is the *only* pointer that will ever be returned to T. Our
+        // reference count is guaranteed to be 1 at this point, and we required
+        // the Arc itself to be `mut`, so we're returning the only possible
+        // reference to the inner data.
+        let inner = unsafe { &mut **this._ptr };
+        Some(&mut inner.data)
+    }else {
+        None
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Clone for Arc<T> {
     /// Makes a clone of the `Arc<T>`.
@@ -221,6 +286,7 @@ impl<T> Clone for Arc<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::sync::Arc;
     ///
     /// let five = Arc::new(5);
@@ -229,13 +295,15 @@ impl<T> Clone for Arc<T> {
     /// ```
     #[inline]
     fn clone(&self) -> Arc<T> {
-        // Using a relaxed ordering is alright here, as knowledge of the original reference
-        // prevents other threads from erroneously deleting the object.
+        // Using a relaxed ordering is alright here, as knowledge of the
+        // original reference prevents other threads from erroneously deleting
+        // the object.
         //
-        // As explained in the [Boost documentation][1], Increasing the reference counter can
-        // always be done with memory_order_relaxed: New references to an object can only be formed
-        // from an existing reference, and passing an existing reference from one thread to another
-        // must already provide any required synchronization.
+        // As explained in the [Boost documentation][1], Increasing the
+        // reference counter can always be done with memory_order_relaxed: New
+        // references to an object can only be formed from an existing
+        // reference, and passing an existing reference from one thread to
+        // another must already provide any required synchronization.
         //
         // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
         self.inner().strong.fetch_add(1, Relaxed);
@@ -253,15 +321,16 @@ impl<T> Deref for Arc<T> {
     }
 }
 
-impl<T: Send + Sync + Clone> Arc<T> {
+impl<T: Clone> Arc<T> {
     /// Make a mutable reference from the given `Arc<T>`.
     ///
-    /// This is also referred to as a copy-on-write operation because the inner data is cloned if
-    /// the reference count is greater than one.
+    /// This is also referred to as a copy-on-write operation because the inner
+    /// data is cloned if the reference count is greater than one.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::sync::Arc;
     ///
     /// let mut five = Arc::new(5);
@@ -271,16 +340,15 @@ impl<T: Send + Sync + Clone> Arc<T> {
     #[inline]
     #[unstable(feature = "alloc")]
     pub fn make_unique(&mut self) -> &mut T {
-        // Note that we hold a strong reference, which also counts as a weak reference, so we only
-        // clone if there is an additional reference of either kind.
+        // Note that we hold a strong reference, which also counts as a weak
+        // reference, so we only clone if there is an additional reference of
+        // either kind.
         if self.inner().strong.load(SeqCst) != 1 ||
            self.inner().weak.load(SeqCst) != 1 {
             *self = Arc::new((**self).clone())
         }
-        // This unsafety is ok because we're guaranteed that the pointer returned is the *only*
-        // pointer that will ever be returned to T. Our reference count is guaranteed to be 1 at
-        // this point, and we required the Arc itself to be `mut`, so we're returning the only
-        // possible reference to the inner data.
+        // As with `unique()`, the unsafety is ok because our reference was
+        // either unique to begin with, or became one upon cloning the contents.
         let inner = unsafe { &mut **self._ptr };
         &mut inner.data
     }
@@ -288,15 +356,17 @@ impl<T: Send + Sync + Clone> Arc<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Sync + Send> Drop for Arc<T> {
+impl<T> Drop for Arc<T> {
     /// Drops the `Arc<T>`.
     ///
-    /// This will decrement the strong reference count. If the strong reference count becomes zero
-    /// and the only other references are `Weak<T>` ones, `drop`s the inner value.
+    /// This will decrement the strong reference count. If the strong reference
+    /// count becomes zero and the only other references are `Weak<T>` ones,
+    /// `drop`s the inner value.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::sync::Arc;
     ///
     /// {
@@ -313,58 +383,59 @@ impl<T: Sync + Send> Drop for Arc<T> {
     ///
     /// } // implicit drop
     /// ```
+    #[inline]
     fn drop(&mut self) {
-        // This structure has #[unsafe_no_drop_flag], so this drop glue may run more than once (but
-        // it is guaranteed to be zeroed after the first if it's run more than once)
+        // This structure has #[unsafe_no_drop_flag], so this drop glue may run
+        // more than once (but it is guaranteed to be zeroed after the first if
+        // it's run more than once)
         let ptr = *self._ptr;
-        if ptr.is_null() { return }
+        // if ptr.is_null() { return }
+        if ptr.is_null() || ptr as usize == mem::POST_DROP_USIZE { return }
 
-        // Because `fetch_sub` is already atomic, we do not need to synchronize with other threads
-        // unless we are going to delete the object. This same logic applies to the below
-        // `fetch_sub` to the `weak` count.
+        // Because `fetch_sub` is already atomic, we do not need to synchronize
+        // with other threads unless we are going to delete the object. This
+        // same logic applies to the below `fetch_sub` to the `weak` count.
         if self.inner().strong.fetch_sub(1, Release) != 1 { return }
 
-        // This fence is needed to prevent reordering of use of the data and deletion of the data.
-        // Because it is marked `Release`, the decreasing of the reference count synchronizes with
-        // this `Acquire` fence. This means that use of the data happens before decreasing the
-        // reference count, which happens before this fence, which happens before the deletion of
-        // the data.
+        // This fence is needed to prevent reordering of use of the data and
+        // deletion of the data.  Because it is marked `Release`, the decreasing
+        // of the reference count synchronizes with this `Acquire` fence. This
+        // means that use of the data happens before decreasing the reference
+        // count, which happens before this fence, which happens before the
+        // deletion of the data.
         //
         // As explained in the [Boost documentation][1],
         //
-        // > It is important to enforce any possible access to the object in one thread (through an
-        // > existing reference) to *happen before* deleting the object in a different thread. This
-        // > is achieved by a "release" operation after dropping a reference (any access to the
-        // > object through this reference must obviously happened before), and an "acquire"
-        // > operation before deleting the object.
+        // > It is important to enforce any possible access to the object in one
+        // > thread (through an existing reference) to *happen before* deleting
+        // > the object in a different thread. This is achieved by a "release"
+        // > operation after dropping a reference (any access to the object
+        // > through this reference must obviously happened before), and an
+        // > "acquire" operation before deleting the object.
         //
         // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
         atomic::fence(Acquire);
 
-        // Destroy the data at this time, even though we may not free the box allocation itself
-        // (there may still be weak pointers lying around).
-        unsafe { drop(ptr::read(&self.inner().data)); }
-
-        if self.inner().weak.fetch_sub(1, Release) == 1 {
-            atomic::fence(Acquire);
-            unsafe { deallocate(ptr as *mut u8, size_of::<ArcInner<T>>(),
-                                min_align_of::<ArcInner<T>>()) }
+        unsafe {
+            self.drop_slow()
         }
     }
 }
 
 #[unstable(feature = "alloc",
            reason = "Weak pointers may not belong in this module.")]
-impl<T: Sync + Send> Weak<T> {
+impl<T> Weak<T> {
     /// Upgrades a weak reference to a strong reference.
     ///
     /// Upgrades the `Weak<T>` reference to an `Arc<T>`, if possible.
     ///
-    /// Returns `None` if there were no strong references and the data was destroyed.
+    /// Returns `None` if there were no strong references and the data was
+    /// destroyed.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::sync::Arc;
     ///
     /// let five = Arc::new(5);
@@ -374,8 +445,8 @@ impl<T: Sync + Send> Weak<T> {
     /// let strong_five: Option<Arc<_>> = weak_five.upgrade();
     /// ```
     pub fn upgrade(&self) -> Option<Arc<T>> {
-        // We use a CAS loop to increment the strong count instead of a fetch_add because once the
-        // count hits 0 is must never be above 0.
+        // We use a CAS loop to increment the strong count instead of a
+        // fetch_add because once the count hits 0 is must never be above 0.
         let inner = self.inner();
         loop {
             let n = inner.strong.load(SeqCst);
@@ -394,7 +465,7 @@ impl<T: Sync + Send> Weak<T> {
 
 #[unstable(feature = "alloc",
            reason = "Weak pointers may not belong in this module.")]
-impl<T: Sync + Send> Clone for Weak<T> {
+impl<T> Clone for Weak<T> {
     /// Makes a clone of the `Weak<T>`.
     ///
     /// This increases the weak reference count.
@@ -402,6 +473,7 @@ impl<T: Sync + Send> Clone for Weak<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::sync::Arc;
     ///
     /// let weak_five = Arc::new(5).downgrade();
@@ -418,7 +490,7 @@ impl<T: Sync + Send> Clone for Weak<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Sync + Send> Drop for Weak<T> {
+impl<T> Drop for Weak<T> {
     /// Drops the `Weak<T>`.
     ///
     /// This will decrement the weak reference count.
@@ -426,6 +498,7 @@ impl<T: Sync + Send> Drop for Weak<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::sync::Arc;
     ///
     /// {
@@ -448,10 +521,11 @@ impl<T: Sync + Send> Drop for Weak<T> {
         let ptr = *self._ptr;
 
         // see comments above for why this check is here
-        if ptr.is_null() { return }
+        if ptr.is_null() || ptr as usize == mem::POST_DROP_USIZE { return }
 
-        // If we find out that we were the last weak pointer, then its time to deallocate the data
-        // entirely. See the discussion in Arc::drop() about the memory orderings
+        // If we find out that we were the last weak pointer, then its time to
+        // deallocate the data entirely. See the discussion in Arc::drop() about
+        // the memory orderings
         if self.inner().weak.fetch_sub(1, Release) == 1 {
             atomic::fence(Acquire);
             unsafe { deallocate(ptr as *mut u8, size_of::<ArcInner<T>>(),
@@ -598,13 +672,6 @@ impl<T: Default + Sync + Send> Default for Arc<T> {
     fn default() -> Arc<T> { Arc::new(Default::default()) }
 }
 
-#[cfg(stage0)]
-impl<H: Hasher, T: Hash<H>> Hash<H> for Arc<T> {
-    fn hash(&self, state: &mut H) {
-        (**self).hash(state)
-    }
-}
-#[cfg(not(stage0))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Hash> Hash for Arc<T> {
     fn hash<H: Hasher>(&self, state: &mut H) {
@@ -624,7 +691,7 @@ mod tests {
     use std::sync::atomic::Ordering::{Acquire, SeqCst};
     use std::thread;
     use std::vec::Vec;
-    use super::{Arc, Weak, weak_count, strong_count};
+    use super::{Arc, Weak, weak_count, strong_count, unique};
     use std::sync::Mutex;
 
     struct Canary(*mut atomic::AtomicUsize);
@@ -660,6 +727,21 @@ mod tests {
         assert_eq!((*arc_v)[4], 5);
     }
 
+    #[test]
+    fn test_arc_unique() {
+        let mut x = Arc::new(10);
+        assert!(unique(&mut x).is_some());
+        {
+            let y = x.clone();
+            assert!(unique(&mut x).is_none());
+        }
+        {
+            let z = x.downgrade();
+            assert!(unique(&mut x).is_none());
+        }
+        assert!(unique(&mut x).is_some());
+    }
+
     #[test]
     fn test_cowarc_clone_make_unique() {
         let mut cow0 = Arc::new(75);
index a3516bd667b7a18cb6e9f0653481511bc5f04779..2801cf38cb75529d94912551a60a5eab51597235 100644 (file)
@@ -42,7 +42,7 @@
 //! }
 //! ```
 //!
-//! This will print `Cons(1i32, Box(Cons(2i32, Box(Nil))))`.
+//! This will print `Cons(1, Box(Cons(2, Box(Nil))))`.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -51,20 +51,20 @@ use core::prelude::*;
 use core::any::Any;
 use core::cmp::Ordering;
 use core::default::Default;
-use core::error::{Error, FromError};
 use core::fmt;
 use core::hash::{self, Hash};
 use core::mem;
 use core::ops::{Deref, DerefMut};
-use core::ptr::Unique;
-use core::raw::TraitObject;
+use core::ptr::{Unique};
+use core::raw::{TraitObject};
 
 /// A value that represents the heap. This is the default place that the `box`
 /// keyword allocates into when no place is supplied.
 ///
 /// The following two examples are equivalent:
 ///
-/// ```rust
+/// ```
+/// # #![feature(alloc)]
 /// #![feature(box_syntax)]
 /// use std::boxed::HEAP;
 ///
@@ -83,6 +83,7 @@ pub static HEAP: () = ();
 /// See the [module-level documentation](../../std/boxed/index.html) for more.
 #[lang = "owned_box"]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[fundamental]
 pub struct Box<T>(Unique<T>);
 
 impl<T> Box<T> {
@@ -94,6 +95,7 @@ impl<T> Box<T> {
     /// let x = Box::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline(always)]
     pub fn new(x: T) -> Box<T> {
         box x
     }
@@ -105,15 +107,16 @@ impl<T : ?Sized> Box<T> {
     /// After this function call, pointer is owned by resulting box.
     /// In particular, it means that `Box` destructor calls destructor
     /// of `T` and releases memory. Since the way `Box` allocates and
-    /// releases memory is unspecified, so the only valid pointer to
-    /// pass to this function is the one taken from another `Box` with
-    /// `box::into_raw` function.
+    /// releases memory is unspecified, the only valid pointer to pass
+    /// to this function is the one taken from another `Box` with
+    /// `boxed::into_raw` function.
     ///
     /// Function is unsafe, because improper use of this function may
     /// lead to memory problems like double-free, for example if the
     /// function is called twice on the same raw pointer.
     #[unstable(feature = "alloc",
                reason = "may be renamed or moved out of Box scope")]
+    #[inline]
     pub unsafe fn from_raw(raw: *mut T) -> Self {
         mem::transmute(raw)
     }
@@ -131,8 +134,9 @@ impl<T : ?Sized> Box<T> {
 /// automatically managed that may lead to memory or other resource
 /// leak.
 ///
-/// # Example
+/// # Examples
 /// ```
+/// # #![feature(alloc)]
 /// use std::boxed;
 ///
 /// let seventeen = Box::new(17u32);
@@ -141,6 +145,7 @@ impl<T : ?Sized> Box<T> {
 /// ```
 #[unstable(feature = "alloc",
            reason = "may be renamed")]
+#[inline]
 pub unsafe fn into_raw<T : ?Sized>(b: Box<T>) -> *mut T {
     mem::transmute(b)
 }
@@ -154,7 +159,7 @@ impl<T: Default> Default for Box<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Default for Box<[T]> {
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn default() -> Box<[T]> { box [] }
+    fn default() -> Box<[T]> { Box::<[T; 0]>::new([]) }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -175,6 +180,7 @@ impl<T: Clone> Clone for Box<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc, core)]
     /// let x = Box::new(5);
     /// let mut y = Box::new(10);
     ///
@@ -220,14 +226,6 @@ impl<T: ?Sized + Ord> Ord for Box<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Eq> Eq for Box<T> {}
 
-#[cfg(stage0)]
-impl<S: hash::Hasher, T: ?Sized + Hash<S>> Hash<S> for Box<T> {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (**self).hash(state);
-    }
-}
-#[cfg(not(stage0))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Hash> Hash for Box<T> {
     fn hash<H: hash::Hasher>(&self, state: &mut H) {
@@ -235,32 +233,19 @@ impl<T: ?Sized + Hash> Hash for Box<T> {
     }
 }
 
-/// Extension methods for an owning `Any` trait object.
-#[unstable(feature = "alloc",
-           reason = "this trait will likely disappear once compiler bugs blocking \
-                     a direct impl on `Box<Any>` have been fixed ")]
-// FIXME(#18737): this should be a direct impl on `Box<Any>`. If you're
-//                removing this please make sure that you can downcase on
-//                `Box<Any + Send>` as well as `Box<Any>`
-pub trait BoxAny {
-    /// Returns the boxed value if it is of type `T`, or
-    /// `Err(Self)` if it isn't.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn downcast<T: 'static>(self) -> Result<Box<T>, Self>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl BoxAny for Box<Any> {
+impl Box<Any> {
     #[inline]
-    fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
         if self.is::<T>() {
             unsafe {
                 // Get the raw representation of the trait object
+                let raw = into_raw(self);
                 let to: TraitObject =
-                    mem::transmute::<Box<Any>, TraitObject>(self);
+                    mem::transmute::<*mut Any, TraitObject>(raw);
 
                 // Extract the data pointer
-                Ok(mem::transmute(to.data))
+                Ok(Box::from_raw(to.data as *mut T))
             }
         } else {
             Err(self)
@@ -268,6 +253,14 @@ impl BoxAny for Box<Any> {
     }
 }
 
+impl Box<Any+Send> {
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any>> {
+        <Box<Any>>::downcast(self)
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: fmt::Display + ?Sized> fmt::Display for Box<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -282,13 +275,6 @@ impl<T: fmt::Debug + ?Sized> fmt::Debug for Box<T> {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for Box<Any> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.pad("Box<Any>")
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Deref for Box<T> {
     type Target = T;
@@ -314,9 +300,74 @@ impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, E: Error + 'a> FromError<E> for Box<Error + 'a> {
-    fn from_error(err: E) -> Box<Error + 'a> {
-        Box::new(err)
+
+/// `FnBox` is a version of the `FnOnce` intended for use with boxed
+/// closure objects. The idea is that where one would normally store a
+/// `Box<FnOnce()>` in a data structure, you should use
+/// `Box<FnBox()>`. The two traits behave essentially the same, except
+/// that a `FnBox` closure can only be called if it is boxed. (Note
+/// that `FnBox` may be deprecated in the future if `Box<FnOnce()>`
+/// closures become directly usable.)
+///
+/// ### Example
+///
+/// Here is a snippet of code which creates a hashmap full of boxed
+/// once closures and then removes them one by one, calling each
+/// closure as it is removed. Note that the type of the closures
+/// stored in the map is `Box<FnBox() -> i32>` and not `Box<FnOnce()
+/// -> i32>`.
+///
+/// ```
+/// #![feature(core)]
+///
+/// use std::boxed::FnBox;
+/// use std::collections::HashMap;
+///
+/// fn make_map() -> HashMap<i32, Box<FnBox() -> i32>> {
+///     let mut map: HashMap<i32, Box<FnBox() -> i32>> = HashMap::new();
+///     map.insert(1, Box::new(|| 22));
+///     map.insert(2, Box::new(|| 44));
+///     map
+/// }
+///
+/// fn main() {
+///     let mut map = make_map();
+///     for i in &[1, 2] {
+///         let f = map.remove(&i).unwrap();
+///         assert_eq!(f(), i * 22);
+///     }
+/// }
+/// ```
+#[rustc_paren_sugar]
+#[unstable(feature = "core", reason = "Newly introduced")]
+pub trait FnBox<A> {
+    type Output;
+
+    fn call_box(self: Box<Self>, args: A) -> Self::Output;
+}
+
+impl<A,F> FnBox<A> for F
+    where F: FnOnce<A>
+{
+    type Output = F::Output;
+
+    fn call_box(self: Box<F>, args: A) -> F::Output {
+        self.call_once(args)
+    }
+}
+
+impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+'a> {
+    type Output = R;
+
+    extern "rust-call" fn call_once(self, args: A) -> R {
+        self.call_box(args)
+    }
+}
+
+impl<'a,A,R> FnOnce<A> for Box<FnBox<A,Output=R>+Send+'a> {
+    type Output = R;
+
+    extern "rust-call" fn call_once(self, args: A) -> R {
+        self.call_box(args)
     }
 }
index b7bacaa0cae2bf074ba3a311da0a34c7a7b256b9..fc44ac4eac628b2eba405276caedb542f5d49bff 100644 (file)
@@ -17,7 +17,6 @@ use core::clone::Clone;
 
 use std::boxed;
 use std::boxed::Box;
-use std::boxed::BoxAny;
 
 #[test]
 fn test_owned_clone() {
@@ -56,29 +55,29 @@ fn test_show() {
     let b = Box::new(Test) as Box<Any>;
     let a_str = format!("{:?}", a);
     let b_str = format!("{:?}", b);
-    assert_eq!(a_str, "Box<Any>");
-    assert_eq!(b_str, "Box<Any>");
+    assert_eq!(a_str, "Any");
+    assert_eq!(b_str, "Any");
 
     static EIGHT: usize = 8;
     static TEST: Test = Test;
     let a = &EIGHT as &Any;
     let b = &TEST as &Any;
     let s = format!("{:?}", a);
-    assert_eq!(s, "&Any");
+    assert_eq!(s, "Any");
     let s = format!("{:?}", b);
-    assert_eq!(s, "&Any");
+    assert_eq!(s, "Any");
 }
 
 #[test]
 fn deref() {
     fn homura<T: Deref<Target=i32>>(_: T) { }
-    homura(Box::new(765i32));
+    homura(Box::new(765));
 }
 
 #[test]
 fn raw_sized() {
     unsafe {
-        let x = Box::new(17i32);
+        let x = Box::new(17);
         let p = boxed::into_raw(x);
         assert_eq!(17, *p);
         *p = 19;
index d3d86270d1e9fdea6a4bb02149f6cfbc2a554c0a..57baa811b9d4740f82be7a272ae0fe2d44eaaad0 100644 (file)
@@ -8,9 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[cfg(not(test))]
-use core::ptr::PtrExt;
-
 // FIXME: #13996: mark the `allocate` and `reallocate` return value as `noalias`
 
 /// Return a pointer to `size` bytes of memory aligned to `align`.
@@ -29,6 +26,9 @@ pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
 ///
 /// On failure, return a null pointer and leave the original allocation intact.
 ///
+/// If the allocation was relocated, the memory at the passed-in pointer is
+/// undefined after the call.
+///
 /// Behavior is undefined if the requested size is 0 or the alignment is not a
 /// power of 2. The alignment must be no larger than the largest supported page
 /// size on the platform.
@@ -189,7 +189,6 @@ mod imp {
     use core::option::Option;
     use core::option::Option::None;
     use core::ptr::{null_mut, null};
-    use core::num::Int;
     use libc::{c_char, c_int, c_void, size_t};
     use super::MIN_ALIGN;
 
@@ -198,6 +197,7 @@ mod imp {
     extern {}
 
     extern {
+        #[allocator]
         fn je_mallocx(size: size_t, flags: c_int) -> *mut c_void;
         fn je_rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
         fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t;
@@ -300,7 +300,7 @@ mod imp {
             libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
         } else {
             let new_ptr = allocate(size, align);
-            ptr::copy_memory(new_ptr, ptr, cmp::min(size, old_size));
+            ptr::copy(ptr, new_ptr, cmp::min(size, old_size));
             deallocate(ptr, old_size, align);
             new_ptr
         }
@@ -386,7 +386,7 @@ mod imp {
 mod test {
     extern crate test;
     use self::test::Bencher;
-    use core::ptr::PtrExt;
+    use boxed::Box;
     use heap;
 
     #[test]
@@ -404,7 +404,7 @@ mod test {
     #[bench]
     fn alloc_owned_small(b: &mut Bencher) {
         b.iter(|| {
-            box 10
+            let _: Box<_> = box 10;
         })
     }
 }
index bc349ebebdeed0a317a30943c9aefa6142a096ff..a8be63d637359beff197d7947b43a037023d8b15 100644 (file)
@@ -56,6 +56,8 @@
 //! The [`heap`](heap/index.html) module defines the low-level interface to the
 //! default global allocator. It is not compatible with the libc allocator API.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "alloc"]
 #![unstable(feature = "alloc")]
 #![feature(staged_api)]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/")]
+#![doc(test(no_crate_inject))]
 
 #![feature(no_std)]
 #![no_std]
+#![feature(allocator)]
+#![feature(custom_attribute)]
+#![feature(fundamental)]
 #![feature(lang_items, unsafe_destructor)]
 #![feature(box_syntax)]
 #![feature(optin_builtin_traits)]
 #![feature(unboxed_closures)]
-#![feature(unsafe_no_drop_flag)]
+#![feature(unsafe_no_drop_flag, filling_drop)]
 #![feature(core)]
+#![feature(unique)]
+#![cfg_attr(test, feature(test, alloc, rustc_private))]
 #![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")),
             feature(libc))]
 
@@ -94,9 +102,15 @@ pub mod heap;
 
 // Primitive types using the heaps above
 
+// Need to conditionally define the mod from `boxed.rs` to avoid
+// duplicating the lang-items when building in test cfg; but also need
+// to allow code to have `use boxed::HEAP;`
+// and `use boxed::Box;` declarations.
 #[cfg(not(test))]
 pub mod boxed;
 #[cfg(test)]
+mod boxed { pub use std::boxed::{Box, HEAP}; }
+#[cfg(test)]
 mod boxed_test;
 pub mod arc;
 pub mod rc;
index 9d39511543188736cd20c9935d80a9f0d3469e78..7cdd48884262182d4c30ee873acc3c082011e863 100644 (file)
@@ -32,6 +32,7 @@
 //! and have the `Owner` remain allocated as long as any `Gadget` points at it.
 //!
 //! ```rust
+//! # #![feature(alloc, collections)]
 //! use std::rc::Rc;
 //!
 //! struct Owner {
 //!
 //!     drop(gadget_owner);
 //!
-//!     // Despite dropping gadget_owner, we're still able to print out the name of
-//!     // the Owner of the Gadgets. This is because we've only dropped the
+//!     // Despite dropping gadget_owner, we're still able to print out the name
+//!     // of the Owner of the Gadgets. This is because we've only dropped the
 //!     // reference count object, not the Owner it wraps. As long as there are
-//!     // other `Rc<T>` objects pointing at the same Owner, it will remain allocated. Notice
-//!     // that the `Rc<T>` wrapper around Gadget.owner gets automatically dereferenced
-//!     // for us.
+//!     // other `Rc<T>` objects pointing at the same Owner, it will remain
+//!     // allocated. Notice that the `Rc<T>` wrapper around Gadget.owner gets
+//!     // automatically dereferenced for us.
 //!     println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name);
 //!     println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name);
 //!
 //! }
 //! ```
 //!
-//! If our requirements change, and we also need to be able to traverse from Owner → Gadget, we
-//! will run into problems: an `Rc<T>` pointer from Owner → Gadget introduces a cycle between the
-//! objects. This means that their reference counts can never reach 0, and the objects will remain
-//! allocated: a memory leak. In order to get around this, we can use `Weak<T>` pointers. These
-//! pointers don't contribute to the total count.
+//! If our requirements change, and we also need to be able to traverse from
+//! Owner → Gadget, we will run into problems: an `Rc<T>` pointer from Owner
+//! → Gadget introduces a cycle between the objects. This means that their
+//! reference counts can never reach 0, and the objects will remain allocated: a
+//! memory leak. In order to get around this, we can use `Weak<T>` pointers.
+//! These pointers don't contribute to the total count.
 //!
-//! Rust actually makes it somewhat difficult to produce this loop in the first place: in order to
-//! end up with two objects that point at each other, one of them needs to be mutable. This is
-//! problematic because `Rc<T>` enforces memory safety by only giving out shared references to the
-//! object it wraps, and these don't allow direct mutation. We need to wrap the part of the object
-//! we wish to mutate in a `RefCell`, which provides *interior mutability*: a method to achieve
-//! mutability through a shared reference. `RefCell` enforces Rust's borrowing rules at runtime.
-//! Read the `Cell` documentation for more details on interior mutability.
+//! Rust actually makes it somewhat difficult to produce this loop in the first
+//! place: in order to end up with two objects that point at each other, one of
+//! them needs to be mutable. This is problematic because `Rc<T>` enforces
+//! memory safety by only giving out shared references to the object it wraps,
+//! and these don't allow direct mutation. We need to wrap the part of the
+//! object we wish to mutate in a `RefCell`, which provides *interior
+//! mutability*: a method to achieve mutability through a shared reference.
+//! `RefCell` enforces Rust's borrowing rules at runtime.  Read the `Cell`
+//! documentation for more details on interior mutability.
 //!
 //! ```rust
+//! # #![feature(alloc)]
 //! use std::rc::Rc;
 //! use std::rc::Weak;
 //! use std::cell::RefCell;
 //!     for gadget_opt in gadget_owner.gadgets.borrow().iter() {
 //!
 //!         // gadget_opt is a Weak<Gadget>. Since weak pointers can't guarantee
-//!         // that their object is still allocated, we need to call upgrade() on them
-//!         // to turn them into a strong reference. This returns an Option, which
-//!         // contains a reference to our object if it still exists.
+//!         // that their object is still allocated, we need to call upgrade()
+//!         // on them to turn them into a strong reference. This returns an
+//!         // Option, which contains a reference to our object if it still
+//!         // exists.
 //!         let gadget = gadget_opt.upgrade().unwrap();
 //!         println!("Gadget {} owned by {}", gadget.id, gadget.owner.name);
 //!     }
 //! ```
 
 #![stable(feature = "rust1", since = "1.0.0")]
-
+#[cfg(not(test))]
+use boxed;
+#[cfg(test)]
+use std::boxed;
 use core::cell::Cell;
 use core::clone::Clone;
 use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
@@ -151,12 +160,12 @@ use core::default::Default;
 use core::fmt;
 use core::hash::{Hasher, Hash};
 use core::marker;
-use core::mem::{transmute, min_align_of, size_of, forget};
+use core::mem::{self, min_align_of, size_of, forget};
 use core::nonzero::NonZero;
 use core::ops::{Deref, Drop};
 use core::option::Option;
 use core::option::Option::{Some, None};
-use core::ptr::{self, PtrExt};
+use core::ptr;
 use core::result::Result;
 use core::result::Result::{Ok, Err};
 use core::intrinsics::assume;
@@ -175,8 +184,8 @@ struct RcBox<T> {
 #[unsafe_no_drop_flag]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Rc<T> {
-    // FIXME #12808: strange names to try to avoid interfering with field accesses of the contained
-    // type via Deref
+    // FIXME #12808: strange names to try to avoid interfering with field
+    // accesses of the contained type via Deref
     _ptr: NonZero<*mut RcBox<T>>,
 }
 
@@ -198,10 +207,11 @@ impl<T> Rc<T> {
     pub fn new(value: T) -> Rc<T> {
         unsafe {
             Rc {
-                // there is an implicit weak pointer owned by all the strong pointers, which
-                // ensures that the weak destructor never frees the allocation while the strong
-                // destructor is running, even if the weak pointer is stored inside the strong one.
-                _ptr: NonZero::new(transmute(box RcBox {
+                // there is an implicit weak pointer owned by all the strong
+                // pointers, which ensures that the weak destructor never frees
+                // the allocation while the strong destructor is running, even
+                // if the weak pointer is stored inside the strong one.
+                _ptr: NonZero::new(boxed::into_raw(box RcBox {
                     value: value,
                     strong: Cell::new(1),
                     weak: Cell::new(1)
@@ -215,6 +225,7 @@ impl<T> Rc<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::rc::Rc;
     ///
     /// let five = Rc::new(5);
@@ -239,11 +250,13 @@ pub fn weak_count<T>(this: &Rc<T>) -> usize { this.weak() - 1 }
 #[unstable(feature = "alloc")]
 pub fn strong_count<T>(this: &Rc<T>) -> usize { this.strong() }
 
-/// Returns true if there are no other `Rc` or `Weak<T>` values that share the same inner value.
+/// Returns true if there are no other `Rc` or `Weak<T>` values that share the
+/// same inner value.
 ///
 /// # Examples
 ///
 /// ```
+/// # #![feature(alloc)]
 /// use std::rc;
 /// use std::rc::Rc;
 ///
@@ -261,9 +274,10 @@ pub fn is_unique<T>(rc: &Rc<T>) -> bool {
 ///
 /// If the `Rc<T>` is not unique, an `Err` is returned with the same `Rc<T>`.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
+/// # #![feature(alloc)]
 /// use std::rc::{self, Rc};
 ///
 /// let x = Rc::new(3);
@@ -295,9 +309,10 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
 ///
 /// Returns `None` if the `Rc<T>` is not unique.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
+/// # #![feature(alloc)]
 /// use std::rc::{self, Rc};
 ///
 /// let mut x = Rc::new(3);
@@ -321,12 +336,13 @@ pub fn get_mut<'a, T>(rc: &'a mut Rc<T>) -> Option<&'a mut T> {
 impl<T: Clone> Rc<T> {
     /// Make a mutable reference from the given `Rc<T>`.
     ///
-    /// This is also referred to as a copy-on-write operation because the inner data is cloned if
-    /// the reference count is greater than one.
+    /// This is also referred to as a copy-on-write operation because the inner
+    /// data is cloned if the reference count is greater than one.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::rc::Rc;
     ///
     /// let mut five = Rc::new(5);
@@ -339,10 +355,11 @@ impl<T: Clone> Rc<T> {
         if !is_unique(self) {
             *self = Rc::new((**self).clone())
         }
-        // This unsafety is ok because we're guaranteed that the pointer returned is the *only*
-        // pointer that will ever be returned to T. Our reference count is guaranteed to be 1 at
-        // this point, and we required the `Rc<T>` itself to be `mut`, so we're returning the only
-        // possible reference to the inner value.
+        // This unsafety is ok because we're guaranteed that the pointer
+        // returned is the *only* pointer that will ever be returned to T. Our
+        // reference count is guaranteed to be 1 at this point, and we required
+        // the `Rc<T>` itself to be `mut`, so we're returning the only possible
+        // reference to the inner value.
         let inner = unsafe { &mut **self._ptr };
         &mut inner.value
     }
@@ -363,12 +380,14 @@ impl<T> Deref for Rc<T> {
 impl<T> Drop for Rc<T> {
     /// Drops the `Rc<T>`.
     ///
-    /// This will decrement the strong reference count. If the strong reference count becomes zero
-    /// and the only other references are `Weak<T>` ones, `drop`s the inner value.
+    /// This will decrement the strong reference count. If the strong reference
+    /// count becomes zero and the only other references are `Weak<T>` ones,
+    /// `drop`s the inner value.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::rc::Rc;
     ///
     /// {
@@ -388,13 +407,13 @@ impl<T> Drop for Rc<T> {
     fn drop(&mut self) {
         unsafe {
             let ptr = *self._ptr;
-            if !ptr.is_null() {
+            if !ptr.is_null() && ptr as usize != mem::POST_DROP_USIZE {
                 self.dec_strong();
                 if self.strong() == 0 {
                     ptr::read(&**self); // destroy the contained object
 
-                    // remove the implicit "strong weak" pointer now that we've destroyed the
-                    // contents.
+                    // remove the implicit "strong weak" pointer now that we've
+                    // destroyed the contents.
                     self.dec_weak();
 
                     if self.weak() == 0 {
@@ -412,11 +431,13 @@ impl<T> Clone for Rc<T> {
 
     /// Makes a clone of the `Rc<T>`.
     ///
-    /// This increases the strong reference count.
+    /// When you clone an `Rc<T>`, it will create another pointer to the data and
+    /// increase the strong reference counter.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::rc::Rc;
     ///
     /// let five = Rc::new(5);
@@ -592,14 +613,6 @@ impl<T: Ord> Ord for Rc<T> {
 }
 
 // FIXME (#18248) Make `T` `Sized?`
-#[cfg(stage0)]
-impl<S: Hasher, T: Hash<S>> Hash<S> for Rc<T> {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (**self).hash(state);
-    }
-}
-#[cfg(not(stage0))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Hash> Hash for Rc<T> {
     fn hash<H: Hasher>(&self, state: &mut H) {
@@ -623,7 +636,8 @@ impl<T: fmt::Debug> fmt::Debug for Rc<T> {
 
 /// A weak version of `Rc<T>`.
 ///
-/// Weak references do not count when determining if the inner value should be dropped.
+/// Weak references do not count when determining if the inner value should be
+/// dropped.
 ///
 /// See the [module level documentation](./index.html) for more.
 #[unsafe_no_drop_flag]
@@ -648,11 +662,13 @@ impl<T> Weak<T> {
     ///
     /// Upgrades the `Weak<T>` reference to an `Rc<T>`, if possible.
     ///
-    /// Returns `None` if there were no strong references and the data was destroyed.
+    /// Returns `None` if there were no strong references and the data was
+    /// destroyed.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::rc::Rc;
     ///
     /// let five = Rc::new(5);
@@ -681,6 +697,7 @@ impl<T> Drop for Weak<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::rc::Rc;
     ///
     /// {
@@ -702,10 +719,10 @@ impl<T> Drop for Weak<T> {
     fn drop(&mut self) {
         unsafe {
             let ptr = *self._ptr;
-            if !ptr.is_null() {
+            if !ptr.is_null() && ptr as usize != mem::POST_DROP_USIZE {
                 self.dec_weak();
-                // the weak count starts at 1, and will only go to zero if all the strong pointers
-                // have disappeared.
+                // the weak count starts at 1, and will only go to zero if all
+                // the strong pointers have disappeared.
                 if self.weak() == 0 {
                     deallocate(ptr as *mut u8, size_of::<RcBox<T>>(),
                                min_align_of::<RcBox<T>>())
@@ -726,6 +743,7 @@ impl<T> Clone for Weak<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(alloc)]
     /// use std::rc::Rc;
     ///
     /// let weak_five = Rc::new(5).downgrade();
@@ -800,6 +818,7 @@ impl<T> RcBoxPtr<T> for Weak<T> {
 #[cfg(test)]
 mod tests {
     use super::{Rc, Weak, weak_count, strong_count};
+    use std::boxed::Box;
     use std::cell::RefCell;
     use std::option::Option;
     use std::option::Option::{Some, None};
@@ -831,7 +850,7 @@ mod tests {
 
     #[test]
     fn test_destructor() {
-        let x = Rc::new(box 5);
+        let x: Rc<Box<_>> = Rc::new(box 5);
         assert_eq!(**x, 5);
     }
 
index b43f9adfb26d92ed9c8f8f4ee8df7bc634c0cb46..7843be0b483ebd8750e7eab20e73ae1014ea04b7 100644 (file)
@@ -19,6 +19,8 @@
 //! arena but can only hold objects of a single type, and `Arena`, which is a
 //! more complex, slower arena which can hold objects of any type.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "arena"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
@@ -40,11 +42,9 @@ extern crate alloc;
 
 use std::cell::{Cell, RefCell};
 use std::cmp;
-use std::intrinsics::{TyDesc, get_tydesc};
 use std::intrinsics;
 use std::marker;
 use std::mem;
-use std::num::{Int, UnsignedInt};
 use std::ptr;
 use std::rc::Rc;
 use std::rt::heap::{allocate, deallocate};
@@ -183,6 +183,25 @@ fn un_bitpack_tydesc_ptr(p: usize) -> (*const TyDesc, bool) {
     ((p & !1) as *const TyDesc, p & 1 == 1)
 }
 
+// HACK(eddyb) TyDesc replacement using a trait object vtable.
+// This could be replaced in the future with a custom DST layout,
+// or `&'static (drop_glue, size, align)` created by a `const fn`.
+struct TyDesc {
+    drop_glue: fn(*const i8),
+    size: usize,
+    align: usize
+}
+
+unsafe fn get_tydesc<T>() -> *const TyDesc {
+    use std::raw::TraitObject;
+
+    let ptr = &*(1 as *const T);
+
+    // Can use any trait that is implemented for all types.
+    let obj = mem::transmute::<&marker::MarkerTrait, TraitObject>(ptr);
+    obj.vtable as *const TyDesc
+}
+
 impl<'longer_than_self> Arena<'longer_than_self> {
     fn chunk_size(&self) -> usize {
         self.copy_head.borrow().capacity()
@@ -321,7 +340,7 @@ fn test_arena_destructors() {
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn test_arena_destructors_fail() {
     let arena = Arena::new();
     // Put some stuff in the arena.
@@ -410,7 +429,8 @@ impl<T> TypedArenaChunk<T> {
         // Destroy the next chunk.
         let next = self.next;
         let size = calculate_size::<T>(self.capacity);
-        deallocate(self as *mut TypedArenaChunk<T> as *mut u8, size,
+        let self_ptr: *mut TypedArenaChunk<T> = self;
+        deallocate(self_ptr as *mut u8, size,
                    mem::min_align_of::<TypedArenaChunk<T>>());
         if !next.is_null() {
             let capacity = (*next).capacity;
@@ -581,11 +601,11 @@ mod tests {
     #[bench]
     pub fn bench_copy_nonarena(b: &mut Bencher) {
         b.iter(|| {
-            box Point {
+            let _: Box<_> = box Point {
                 x: 1,
                 y: 2,
                 z: 3,
-            }
+            };
         })
     }
 
@@ -634,10 +654,10 @@ mod tests {
     #[bench]
     pub fn bench_noncopy_nonarena(b: &mut Bencher) {
         b.iter(|| {
-            box Noncopy {
+            let _: Box<_> = box Noncopy {
                 string: "hello world".to_string(),
                 array: vec!( 1, 2, 3, 4, 5 ),
-            }
+            };
         })
     }
 
index 6add85d7341513eddaa249f477fc51e3799343b7..437289982927dc29c6acec1f4a1e8746afe6c872 100644 (file)
@@ -6,12 +6,12 @@
 # met:
 
 #     (1) Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer. 
+#     notice, this list of conditions and the following disclaimer.
 
 #     (2) Redistributions in binary form must reproduce the above copyright
 #     notice, this list of conditions and the following disclaimer in
 #     the documentation and/or other materials provided with the
-#     distribution.  
+#     distribution.
 
 #     (3) The name of the author may not be used to
 #     endorse or promote products derived from this software without
index 18c1ecaca545fc1274ecdd967035143738ec32ee..93ccec2dbf92f4f6753fa62d75979d62719ef319 100644 (file)
 # met:
 
 #     (1) Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer. 
+#     notice, this list of conditions and the following disclaimer.
 
 #     (2) Redistributions in binary form must reproduce the above copyright
 #     notice, this list of conditions and the following disclaimer in
 #     the documentation and/or other materials provided with the
-#     distribution.  
+#     distribution.
 
 #     (3) The name of the author may not be used to
 #     endorse or promote products derived from this software without
@@ -117,10 +117,10 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
        $(LDFLAGS) -o $@
 SOURCES = $(libbacktrace_la_SOURCES) $(EXTRA_libbacktrace_la_SOURCES) \
        $(btest_SOURCES)
-MULTISRCTOP = 
-MULTIBUILDTOP = 
-MULTIDIRS = 
-MULTISUBDIR = 
+MULTISRCTOP =
+MULTIBUILDTOP =
+MULTIDIRS =
+MULTISUBDIR =
 MULTIDO = true
 MULTICLEAN = true
 ETAGS = etags
@@ -362,7 +362,7 @@ config.h: stamp-h1
 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
        @rm -f stamp-h1
        cd $(top_builddir) && $(SHELL) ./config.status config.h
-$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) 
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
        ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
        rm -f stamp-h1
        touch $@
@@ -380,7 +380,7 @@ clean-noinstLTLIBRARIES:
          echo "rm -f \"$${dir}/so_locations\""; \
          rm -f "$${dir}/so_locations"; \
        done
-libbacktrace.la: $(libbacktrace_la_OBJECTS) $(libbacktrace_la_DEPENDENCIES) 
+libbacktrace.la: $(libbacktrace_la_OBJECTS) $(libbacktrace_la_DEPENDENCIES)
        $(LINK)  $(libbacktrace_la_OBJECTS) $(libbacktrace_la_LIBADD) $(LIBS)
 
 clean-checkPROGRAMS:
@@ -391,7 +391,7 @@ clean-checkPROGRAMS:
        list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
        echo " rm -f" $$list; \
        rm -f $$list
-btest$(EXEEXT): $(btest_OBJECTS) $(btest_DEPENDENCIES) 
+btest$(EXEEXT): $(btest_OBJECTS) $(btest_DEPENDENCIES)
        @rm -f btest$(EXEEXT)
        $(btest_LINK) $(btest_OBJECTS) $(btest_LDADD) $(LIBS)
 
index 37eca65349ee10a409af63e45e8740492cdd3e1a..4aa85d050fd179681c419d9dad91984f7afdb3f4 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index f139d74aa5f373fa54a646792c3a772f9db48b55..b31fa64c798c8e4aae266fd735d5328194168133 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index 901e3f72a431bf732a8dd21dccc4f604ab568b05..28488167c4e2b9f94944eebb1ae73af1c7fdcd16 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index cc3105c06cb19b592641853daa576f9ebe322045..4b90357df5f806f46159ec9a71ae450d4199a156 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index 03b5479081d31e4aecb2a58f76ad3f92b33d1619..3f77093f767edc092cf8e4108f49495fc54c61b6 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index 4b67c3d8bd0c763d3ded1b1dd8ae82a1c509230f..a1818f1ef8311bf602e6cde217e3cac0f1dbd861 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
@@ -460,7 +460,7 @@ f23 (int f1line, int f2line)
                       (unsigned int) bdata.index, j + 1);
              bdata.failed = 1;
            }
-       }      
+       }
 
       check ("test3", 0, all, f3line, "f23", &bdata.failed);
       check ("test3", 1, all, f2line, "f22", &bdata.failed);
index 14a9fd4f452793a1a5ffb1607fc8f00fc3a9aa40..d5e08d93f6c3063f4f7e3937fa0230edd9a5275d 100755 (executable)
@@ -5650,7 +5650,7 @@ else
     lt_cv_sys_max_cmd_len=8192;
     ;;
 
-  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly* | bitrig*)
     # This has been around since 386BSD, at least.  Likely further.
     if test -x /sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -9332,7 +9332,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
       ;;
 
     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
-    freebsd* | dragonfly* | openbsd*)
+    freebsd* | dragonfly* | bitrig* | openbsd*)
       archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
       hardcode_libdir_flag_spec='-R$libdir'
       hardcode_direct=yes
@@ -15153,4 +15153,3 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
 fi
-
index 878bd2c15806c61790f4928e8140bbb041ae301c..d661c7b2560fca6acd60cbc67c804938509004ee 100644 (file)
@@ -6,13 +6,13 @@
 # met:
 
 #     (1) Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer. 
+#     notice, this list of conditions and the following disclaimer.
 
 #     (2) Redistributions in binary form must reproduce the above copyright
 #     notice, this list of conditions and the following disclaimer in
 #     the documentation and/or other materials provided with the
-#     distribution.  
-    
+#     distribution.
+
 #     (3) The name of the author may not be used to
 #     endorse or promote products derived from this software without
 #     specific prior written permission.
index ad52d73b752e51c4be990c17cda0709c42d21fe2..5ecae711792e294d2cb16c686ca163e53b1bbe2c 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
@@ -1241,7 +1241,7 @@ add_unit_ranges (struct backtrace_state *state, uintptr_t base_address,
 
 static int
 find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
-                    struct dwarf_buf *unit_buf, 
+                    struct dwarf_buf *unit_buf,
                     const unsigned char *dwarf_str, size_t dwarf_str_size,
                     const unsigned char *dwarf_ranges,
                     size_t dwarf_ranges_size,
@@ -1599,7 +1599,7 @@ read_line_header (struct backtrace_state *state, struct unit *u,
 
   if (!advance (line_buf, hdrlen))
     return 0;
-  
+
   hdr->min_insn_len = read_byte (&hdr_buf);
   if (hdr->version < 4)
     hdr->max_ops_per_insn = 1;
@@ -1608,7 +1608,7 @@ read_line_header (struct backtrace_state *state, struct unit *u,
 
   /* We don't care about default_is_stmt.  */
   read_byte (&hdr_buf);
-  
+
   hdr->line_base = read_sbyte (&hdr_buf);
   hdr->line_range = read_byte (&hdr_buf);
 
index 6c5b179e90d05596ccb0b0daf6638aaddf64e331..5fc74add05c1814174ffdeb07842df72c9e0b1ba 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index bab5351cab38d9935f336b652e6ba0d29c8b7ec5..f45cccff71306f3926cc50065eeddcf6c0dbefc1 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index 4bb65d6c7a2b4135b8526ca5ec4255987934ed6d..3736622e67739cf97ea710b95a4fdbd66fbb9921 100644 (file)
@@ -1,4 +1,4 @@
-/* An expandable hash tables datatype.  
+/* An expandable hash tables datatype.
    Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Vladimir Makarov (vmakarov@cygnus.com).
@@ -61,7 +61,7 @@ typedef int (*htab_eq) (const void *, const void *);
 /* Cleanup function called whenever a live element is removed from
    the hash table.  */
 typedef void (*htab_del) (void *);
-  
+
 /* Function called by htab_traverse for each live element.  The first
    arg is the slot of the element (which can be passed to htab_clear_slot
    if desired), the second arg is the auxiliary pointer handed to
index dd109db24aed900a6fe66191cd81be6b31500496..a13c775b628737d4ffb60f15cde3b241fa27af8c 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index 9503ec85d709d8f7fdad222ef3c4d8d85fdc6cd1..84f5be9249e7caae28e6c16faccaba9f84096f12 100644 (file)
@@ -4741,7 +4741,7 @@ func_mode_link ()
            # These systems don't actually have a C library (as such)
            test "X$arg" = "X-lc" && continue
            ;;
-         *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+         *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
            # Do not include libc due to us having libc/libc_r.
            test "X$arg" = "X-lc" && continue
            ;;
@@ -8633,4 +8633,3 @@ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
 # sh-indentation:2
 # End:
 # vi:sw=2
-
index b530e38238820084f87949e24111576922810f52..1c691b02e7cfa6db80eedcf817d2d31a1d080c96 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index 72940b403a3d04962436442eb24c2201d43718d9..8b8f124da9a6d729a89116ab5af0d0585c0aa7d1 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index 0097966b422b4165f7028883a103cae399bd429d..f8fdbdc85acb4f6c1cde3144650674cce3760231 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index dba9e525e082611eedcdefd9c26dff7c0c59d14e..7f1c35ab9707d0ce2165a7ba899fea0f3043f83c 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index bd224e6bf4d7db2d396078325392667ce165659c..70e347f62c290fefd8480f4436b28ffd0da1cbfc 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index c618a50b36d3fd6f270e87debf2d83740fd28941..e373b61de2e6c8c7f43c38f595ecd6e0da13fb00 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index efa8b6fc639df802ce99dcdcae58e47959f7bb5e..dd70f831de74a5c5f85e5903ad9320b91de82556 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index a7d4e07d1a5574ea07b7fdc42572724d0c29747a..bef47bd1a0f541494c1d3cdc8237261de97dea73 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
index c1fe8811d477f02608d02e42c5ea8f1d7d4501c4..e5e8421b3a994c0cbfe4a0d6163380bfab23f12d 100644 (file)
@@ -7,13 +7,13 @@ modification, are permitted provided that the following conditions are
 met:
 
     (1) Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer. 
+    notice, this list of conditions and the following disclaimer.
 
     (2) Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
-    distribution.  
-    
+    distribution.
+
     (3) The name of the author may not be used to
     endorse or promote products derived from this software without
     specific prior written permission.
diff --git a/src/libcollections/bench.rs b/src/libcollections/bench.rs
deleted file mode 100644 (file)
index 107f603..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2013-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.
-
-macro_rules! map_insert_rand_bench {
-    ($name: ident, $n: expr, $map: ident) => (
-        #[bench]
-        pub fn $name(b: &mut ::test::Bencher) {
-            use std::rand;
-            use std::rand::Rng;
-            use test::black_box;
-
-            let n: usize = $n;
-            let mut map = $map::new();
-            // setup
-            let mut rng = rand::weak_rng();
-
-            for _ in 0..n {
-                let i = rng.gen() % n;
-                map.insert(i, i);
-            }
-
-            // measure
-            b.iter(|| {
-                let k = rng.gen() % n;
-                map.insert(k, k);
-                map.remove(&k);
-            });
-            black_box(map);
-        }
-    )
-}
-
-macro_rules! map_insert_seq_bench {
-    ($name: ident, $n: expr, $map: ident) => (
-        #[bench]
-        pub fn $name(b: &mut ::test::Bencher) {
-            use test::black_box;
-
-            let mut map = $map::new();
-            let n: usize = $n;
-            // setup
-            for i in 0..n {
-                map.insert(i * 2, i * 2);
-            }
-
-            // measure
-            let mut i = 1;
-            b.iter(|| {
-                map.insert(i, i);
-                map.remove(&i);
-                i = (i + 2) % n;
-            });
-            black_box(map);
-        }
-    )
-}
-
-macro_rules! map_find_rand_bench {
-    ($name: ident, $n: expr, $map: ident) => (
-        #[bench]
-        pub fn $name(b: &mut ::test::Bencher) {
-            use std::rand;
-            use std::iter::IteratorExt;
-            use std::rand::Rng;
-            use test::black_box;
-            use vec::Vec;
-
-            let mut map = $map::new();
-            let n: usize = $n;
-
-            // setup
-            let mut rng = rand::weak_rng();
-            let mut keys: Vec<_> = (0..n).map(|_| rng.gen() % n).collect();
-
-            for &k in &keys {
-                map.insert(k, k);
-            }
-
-            rng.shuffle(&mut keys);
-
-            // measure
-            let mut i = 0;
-            b.iter(|| {
-                let t = map.get(&keys[i]);
-                i = (i + 1) % n;
-                black_box(t);
-            })
-        }
-    )
-}
-
-macro_rules! map_find_seq_bench {
-    ($name: ident, $n: expr, $map: ident) => (
-        #[bench]
-        pub fn $name(b: &mut ::test::Bencher) {
-            use test::black_box;
-
-            let mut map = $map::new();
-            let n: usize = $n;
-
-            // setup
-            for i in 0..n {
-                map.insert(i, i);
-            }
-
-            // measure
-            let mut i = 0;
-            b.iter(|| {
-                let x = map.get(&i);
-                i = (i + 1) % n;
-                black_box(x);
-            })
-        }
-    )
-}
index 9f549fd7237711dce941f7ef0d37e0eec9e8db73..3804874a650f6c065e23c78043bbfc8b1c35a168 100644 (file)
@@ -30,7 +30,7 @@
 //! use std::collections::BinaryHeap;
 //! use std::usize;
 //!
-//! #[derive(Copy, Eq, PartialEq)]
+//! #[derive(Copy, Clone, Eq, PartialEq)]
 //! struct State {
 //!     cost: usize,
 //!     position: usize,
@@ -163,6 +163,11 @@ use vec::{self, Vec};
 /// A priority queue implemented with a binary heap.
 ///
 /// This will be a max-heap.
+///
+/// It is a logic error for an item to be modified in such a way that the
+/// item's ordering relative to any other item, as determined by the `Ord`
+/// trait, changes while it is in the heap. This is normally only possible
+/// through `Cell`, `RefCell`, global state, I/O, or unsafe code.
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BinaryHeap<T> {
@@ -211,6 +216,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BinaryHeap;
     /// let heap = BinaryHeap::from_vec(vec![9, 1, 2, 7, 3, 2]);
     /// ```
@@ -230,6 +236,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BinaryHeap;
     /// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4]);
     ///
@@ -250,6 +257,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BinaryHeap;
     /// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4]);
     ///
@@ -355,6 +363,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BinaryHeap;
     /// let mut heap = BinaryHeap::from_vec(vec![1, 3]);
     ///
@@ -400,6 +409,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BinaryHeap;
     /// let mut heap = BinaryHeap::new();
     /// heap.push(1);
@@ -431,6 +441,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BinaryHeap;
     /// let mut heap = BinaryHeap::new();
     ///
@@ -456,6 +467,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BinaryHeap;
     /// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4, 5, 6, 7]);
     /// let vec = heap.into_vec();
@@ -473,6 +485,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BinaryHeap;
     ///
     /// let mut heap = BinaryHeap::from_vec(vec![1, 2, 4, 5, 7]);
@@ -480,7 +493,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// heap.push(3);
     ///
     /// let vec = heap.into_sorted_vec();
-    /// assert_eq!(vec, vec![1, 2, 3, 4, 5, 6, 7]);
+    /// assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7]);
     /// ```
     pub fn into_sorted_vec(mut self) -> Vec<T> {
         let mut end = self.len();
@@ -550,6 +563,8 @@ impl<T: Ord> BinaryHeap<T> {
     pub fn is_empty(&self) -> bool { self.len() == 0 }
 
     /// Clears the binary heap, returning an iterator over the removed elements.
+    ///
+    /// The elements are removed in arbitrary order.
     #[inline]
     #[unstable(feature = "collections",
                reason = "matches collection reform specification, waiting for dust to settle")]
@@ -688,218 +703,3 @@ impl<T: Ord> Extend<T> for BinaryHeap<T> {
         }
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-
-    use super::BinaryHeap;
-
-    #[test]
-    fn test_iterator() {
-        let data = vec![5, 9, 3];
-        let iterout = [9, 5, 3];
-        let heap = BinaryHeap::from_vec(data);
-        let mut i = 0;
-        for el in &heap {
-            assert_eq!(*el, iterout[i]);
-            i += 1;
-        }
-    }
-
-    #[test]
-    fn test_iterator_reverse() {
-        let data = vec![5, 9, 3];
-        let iterout = vec![3, 5, 9];
-        let pq = BinaryHeap::from_vec(data);
-
-        let v: Vec<_> = pq.iter().rev().cloned().collect();
-        assert_eq!(v, iterout);
-    }
-
-    #[test]
-    fn test_move_iter() {
-        let data = vec![5, 9, 3];
-        let iterout = vec![9, 5, 3];
-        let pq = BinaryHeap::from_vec(data);
-
-        let v: Vec<_> = pq.into_iter().collect();
-        assert_eq!(v, iterout);
-    }
-
-    #[test]
-    fn test_move_iter_size_hint() {
-        let data = vec![5, 9];
-        let pq = BinaryHeap::from_vec(data);
-
-        let mut it = pq.into_iter();
-
-        assert_eq!(it.size_hint(), (2, Some(2)));
-        assert_eq!(it.next(), Some(9));
-
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(it.next(), Some(5));
-
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert_eq!(it.next(), None);
-    }
-
-    #[test]
-    fn test_move_iter_reverse() {
-        let data = vec![5, 9, 3];
-        let iterout = vec![3, 5, 9];
-        let pq = BinaryHeap::from_vec(data);
-
-        let v: Vec<_> = pq.into_iter().rev().collect();
-        assert_eq!(v, iterout);
-    }
-
-    #[test]
-    fn test_peek_and_pop() {
-        let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
-        let mut sorted = data.clone();
-        sorted.sort();
-        let mut heap = BinaryHeap::from_vec(data);
-        while !heap.is_empty() {
-            assert_eq!(heap.peek().unwrap(), sorted.last().unwrap());
-            assert_eq!(heap.pop().unwrap(), sorted.pop().unwrap());
-        }
-    }
-
-    #[test]
-    fn test_push() {
-        let mut heap = BinaryHeap::from_vec(vec![2, 4, 9]);
-        assert_eq!(heap.len(), 3);
-        assert!(*heap.peek().unwrap() == 9);
-        heap.push(11);
-        assert_eq!(heap.len(), 4);
-        assert!(*heap.peek().unwrap() == 11);
-        heap.push(5);
-        assert_eq!(heap.len(), 5);
-        assert!(*heap.peek().unwrap() == 11);
-        heap.push(27);
-        assert_eq!(heap.len(), 6);
-        assert!(*heap.peek().unwrap() == 27);
-        heap.push(3);
-        assert_eq!(heap.len(), 7);
-        assert!(*heap.peek().unwrap() == 27);
-        heap.push(103);
-        assert_eq!(heap.len(), 8);
-        assert!(*heap.peek().unwrap() == 103);
-    }
-
-    #[test]
-    fn test_push_unique() {
-        let mut heap = BinaryHeap::from_vec(vec![box 2, box 4, box 9]);
-        assert_eq!(heap.len(), 3);
-        assert!(*heap.peek().unwrap() == box 9);
-        heap.push(box 11);
-        assert_eq!(heap.len(), 4);
-        assert!(*heap.peek().unwrap() == box 11);
-        heap.push(box 5);
-        assert_eq!(heap.len(), 5);
-        assert!(*heap.peek().unwrap() == box 11);
-        heap.push(box 27);
-        assert_eq!(heap.len(), 6);
-        assert!(*heap.peek().unwrap() == box 27);
-        heap.push(box 3);
-        assert_eq!(heap.len(), 7);
-        assert!(*heap.peek().unwrap() == box 27);
-        heap.push(box 103);
-        assert_eq!(heap.len(), 8);
-        assert!(*heap.peek().unwrap() == box 103);
-    }
-
-    #[test]
-    fn test_push_pop() {
-        let mut heap = BinaryHeap::from_vec(vec![5, 5, 2, 1, 3]);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.push_pop(6), 6);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.push_pop(0), 5);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.push_pop(4), 5);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.push_pop(1), 4);
-        assert_eq!(heap.len(), 5);
-    }
-
-    #[test]
-    fn test_replace() {
-        let mut heap = BinaryHeap::from_vec(vec![5, 5, 2, 1, 3]);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.replace(6).unwrap(), 5);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.replace(0).unwrap(), 6);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.replace(4).unwrap(), 5);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.replace(1).unwrap(), 4);
-        assert_eq!(heap.len(), 5);
-    }
-
-    fn check_to_vec(mut data: Vec<i32>) {
-        let heap = BinaryHeap::from_vec(data.clone());
-        let mut v = heap.clone().into_vec();
-        v.sort();
-        data.sort();
-
-        assert_eq!(v, data);
-        assert_eq!(heap.into_sorted_vec(), data);
-    }
-
-    #[test]
-    fn test_to_vec() {
-        check_to_vec(vec![]);
-        check_to_vec(vec![5]);
-        check_to_vec(vec![3, 2]);
-        check_to_vec(vec![2, 3]);
-        check_to_vec(vec![5, 1, 2]);
-        check_to_vec(vec![1, 100, 2, 3]);
-        check_to_vec(vec![1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
-        check_to_vec(vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
-        check_to_vec(vec![9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
-        check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
-        check_to_vec(vec![10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
-        check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
-        check_to_vec(vec![5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
-    }
-
-    #[test]
-    fn test_empty_pop() {
-        let mut heap = BinaryHeap::<i32>::new();
-        assert!(heap.pop().is_none());
-    }
-
-    #[test]
-    fn test_empty_peek() {
-        let empty = BinaryHeap::<i32>::new();
-        assert!(empty.peek().is_none());
-    }
-
-    #[test]
-    fn test_empty_replace() {
-        let mut heap = BinaryHeap::new();
-        assert!(heap.replace(5).is_none());
-    }
-
-    #[test]
-    fn test_from_iter() {
-        let xs = vec![9, 8, 7, 6, 5, 4, 3, 2, 1];
-
-        let mut q: BinaryHeap<_> = xs.iter().rev().cloned().collect();
-
-        for &x in &xs {
-            assert_eq!(q.pop().unwrap(), x);
-        }
-    }
-
-    #[test]
-    fn test_drain() {
-        let mut q: BinaryHeap<_> = [9, 8, 7, 6, 5, 4, 3, 2, 1].iter().cloned().collect();
-
-        assert_eq!(q.drain().take(5).count(), 5);
-
-        assert!(q.is_empty());
-    }
-}
index 11c576eab152551c274b9036b4ac99a5ee30ae39..8874ac6eb872f020c1d55de74b835dd454d6cd73 100644 (file)
@@ -38,6 +38,7 @@
 //! [sieve]: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
 //!
 //! ```
+//! # #![feature(collections, core, step_by)]
 //! use std::collections::{BitSet, BitVec};
 //! use std::num::Float;
 //! use std::iter;
@@ -59,7 +60,7 @@
 //!         if bv[i] {
 //!             // Mark all multiples of i as non-prime (any multiples below i * i
 //!             // will have been marked as non-prime previously)
-//!             for j in iter::range_step(i * i, max_prime, i) { bv.set(j, false) }
+//!             for j in (i * i..max_prime).step_by(i) { bv.set(j, false) }
 //!         }
 //!     }
 //!     BitSet::from_bit_vec(bv)
@@ -90,7 +91,6 @@ use core::hash;
 use core::iter::RandomAccessIterator;
 use core::iter::{Chain, Enumerate, Repeat, Skip, Take, repeat, Cloned};
 use core::iter::{self, FromIterator, IntoIterator};
-use core::num::Int;
 use core::ops::Index;
 use core::slice;
 use core::{u8, u32, usize};
@@ -110,7 +110,7 @@ fn reverse_bits(byte: u8) -> u8 {
     result
 }
 
-// Take two BitV's, and return iterators of their words, where the shorter one
+// Take two BitVec's, and return iterators of their words, where the shorter one
 // has been padded with 0's
 fn match_words <'a,'b>(a: &'a BitVec, b: &'b BitVec) -> (MatchWords<'a>, MatchWords<'b>) {
     let a_len = a.storage.len();
@@ -118,11 +118,11 @@ fn match_words <'a,'b>(a: &'a BitVec, b: &'b BitVec) -> (MatchWords<'a>, MatchWo
 
     // have to uselessly pretend to pad the longer one for type matching
     if a_len < b_len {
-        (a.blocks().enumerate().chain(iter::repeat(0u32).enumerate().take(b_len).skip(a_len)),
-         b.blocks().enumerate().chain(iter::repeat(0u32).enumerate().take(0).skip(0)))
+        (a.blocks().enumerate().chain(iter::repeat(0).enumerate().take(b_len).skip(a_len)),
+         b.blocks().enumerate().chain(iter::repeat(0).enumerate().take(0).skip(0)))
     } else {
-        (a.blocks().enumerate().chain(iter::repeat(0u32).enumerate().take(0).skip(0)),
-         b.blocks().enumerate().chain(iter::repeat(0u32).enumerate().take(a_len).skip(b_len)))
+        (a.blocks().enumerate().chain(iter::repeat(0).enumerate().take(0).skip(0)),
+         b.blocks().enumerate().chain(iter::repeat(0).enumerate().take(a_len).skip(b_len)))
     }
 }
 
@@ -133,7 +133,8 @@ static FALSE: bool = false;
 ///
 /// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(collections)]
 /// use std::collections::BitVec;
 ///
 /// let mut bv = BitVec::from_elem(10, false);
@@ -170,8 +171,8 @@ impl Index<usize> for BitVec {
     type Output = bool;
 
     #[inline]
-    fn index(&self, i: &usize) -> &bool {
-        if self.get(*i).expect("index out of bounds") {
+    fn index(&self, i: usize) -> &bool {
+        if self.get(i).expect("index out of bounds") {
             &TRUE
         } else {
             &FALSE
@@ -189,17 +190,17 @@ fn blocks_for_bits(bits: usize) -> usize {
     //
     // Note that we can technically avoid this branch with the expression
     // `(nbits + u32::BITS - 1) / 32::BITS`, but if nbits is almost usize::MAX this will overflow.
-    if bits % u32::BITS == 0 {
-        bits / u32::BITS
+    if bits % u32::BITS as usize == 0 {
+        bits / u32::BITS as usize
     } else {
-        bits / u32::BITS + 1
+        bits / u32::BITS as usize + 1
     }
 }
 
 /// Computes the bitmask for the final word of the vector
 fn mask_for_bits(bits: usize) -> u32 {
     // Note especially that a perfect multiple of u32::BITS should mask all 1s.
-    !0u32 >> (u32::BITS - bits % u32::BITS) % u32::BITS
+    !0 >> (u32::BITS as usize - bits % u32::BITS as usize) % u32::BITS as usize
 }
 
 impl BitVec {
@@ -237,7 +238,7 @@ impl BitVec {
     /// An operation might screw up the unused bits in the last block of the
     /// `BitVec`. As per (3), it's assumed to be all 0s. This method fixes it up.
     fn fix_last_block(&mut self) {
-        let extra_bits = self.len() % u32::BITS;
+        let extra_bits = self.len() % u32::BITS as usize;
         if extra_bits > 0 {
             let mask = (1 << extra_bits) - 1;
             let storage_len = self.storage.len();
@@ -250,6 +251,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     /// let mut bv = BitVec::new();
     /// ```
@@ -264,6 +266,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(10, false);
@@ -275,7 +278,7 @@ impl BitVec {
     pub fn from_elem(nbits: usize, bit: bool) -> BitVec {
         let nblocks = blocks_for_bits(nbits);
         let mut bit_vec = BitVec {
-            storage: repeat(if bit { !0u32 } else { 0u32 }).take(nblocks).collect(),
+            storage: repeat(if bit { !0 } else { 0 }).take(nblocks).collect(),
             nbits: nbits
         };
         bit_vec.fix_last_block();
@@ -304,6 +307,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let bv = BitVec::from_bytes(&[0b10100000, 0b00010010]);
@@ -313,7 +317,7 @@ impl BitVec {
     ///                     false, false, true, false]));
     /// ```
     pub fn from_bytes(bytes: &[u8]) -> BitVec {
-        let len = bytes.len().checked_mul(u8::BITS).expect("capacity overflow");
+        let len = bytes.len().checked_mul(u8::BITS as usize).expect("capacity overflow");
         let mut bit_vec = BitVec::with_capacity(len);
         let complete_words = bytes.len() / 4;
         let extra_bytes = bytes.len() % 4;
@@ -330,7 +334,7 @@ impl BitVec {
         }
 
         if extra_bytes > 0 {
-            let mut last_word = 0u32;
+            let mut last_word = 0;
             for (i, &byte) in bytes[complete_words*4..].iter().enumerate() {
                 last_word |= (reverse_bits(byte) as u32) << (i * 8);
             }
@@ -346,6 +350,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let bv = BitVec::from_fn(5, |i| { i % 2 == 0 });
@@ -364,6 +369,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let bv = BitVec::from_bytes(&[0b01100000]);
@@ -380,8 +386,8 @@ impl BitVec {
         if i >= self.nbits {
             return None;
         }
-        let w = i / u32::BITS;
-        let b = i % u32::BITS;
+        let w = i / u32::BITS as usize;
+        let b = i % u32::BITS as usize;
         self.storage.get(w).map(|&block|
             (block & (1 << b)) != 0
         )
@@ -396,6 +402,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(5, false);
@@ -407,8 +414,8 @@ impl BitVec {
                reason = "panic semantics are likely to change in the future")]
     pub fn set(&mut self, i: usize, x: bool) {
         assert!(i < self.nbits);
-        let w = i / u32::BITS;
-        let b = i % u32::BITS;
+        let w = i / u32::BITS as usize;
+        let b = i % u32::BITS as usize;
         let flag = 1 << b;
         let val = if x { self.storage[w] | flag }
                   else { self.storage[w] & !flag };
@@ -420,6 +427,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let before = 0b01100000;
@@ -431,7 +439,7 @@ impl BitVec {
     /// ```
     #[inline]
     pub fn set_all(&mut self) {
-        for w in &mut self.storage { *w = !0u32; }
+        for w in &mut self.storage { *w = !0; }
         self.fix_last_block();
     }
 
@@ -440,6 +448,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let before = 0b01100000;
@@ -468,6 +477,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let a   = 0b01100100;
@@ -498,6 +508,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let a   = 0b01100100;
@@ -528,6 +539,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let a   = 0b01100100;
@@ -557,6 +569,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(5, true);
@@ -566,12 +579,12 @@ impl BitVec {
     /// assert_eq!(bv.all(), false);
     /// ```
     pub fn all(&self) -> bool {
-        let mut last_word = !0u32;
+        let mut last_word = !0;
         // Check that every block but the last is all-ones...
         self.blocks().all(|elem| {
             let tmp = last_word;
             last_word = elem;
-            tmp == !0u32
+            tmp == !0
         // and then check the last one has enough ones
         }) && (last_word == mask_for_bits(self.nbits))
     }
@@ -581,6 +594,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let bv = BitVec::from_bytes(&[0b01110100, 0b10010010]);
@@ -597,6 +611,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(10, false);
@@ -614,6 +629,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(10, false);
@@ -635,18 +651,19 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(3, true);
     /// bv.set(1, false);
     ///
-    /// assert_eq!(bv.to_bytes(), vec!(0b10100000));
+    /// assert_eq!(bv.to_bytes(), [0b10100000]);
     ///
     /// let mut bv = BitVec::from_elem(9, false);
     /// bv.set(2, true);
     /// bv.set(8, true);
     ///
-    /// assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
+    /// assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]);
     /// ```
     pub fn to_bytes(&self) -> Vec<u8> {
         fn bit(bit_vec: &BitVec, byte: usize, bit: usize) -> u8 {
@@ -682,6 +699,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let bv = BitVec::from_bytes(&[0b10100000]);
@@ -702,6 +720,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_bytes(&[0b01001011]);
@@ -728,6 +747,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(3, false);
@@ -758,6 +778,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_elem(3, false);
@@ -780,6 +801,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::new();
@@ -789,7 +811,7 @@ impl BitVec {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn capacity(&self) -> usize {
-        self.storage.capacity().checked_mul(u32::BITS).unwrap_or(usize::MAX)
+        self.storage.capacity().checked_mul(u32::BITS as usize).unwrap_or(usize::MAX)
     }
 
     /// Grows the `BitVec` in-place, adding `n` copies of `value` to the `BitVec`.
@@ -801,12 +823,13 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_bytes(&[0b01001011]);
     /// bv.grow(2, true);
     /// assert_eq!(bv.len(), 10);
-    /// assert_eq!(bv.to_bytes(), vec!(0b01001011, 0b11000000));
+    /// assert_eq!(bv.to_bytes(), [0b01001011, 0b11000000]);
     /// ```
     pub fn grow(&mut self, n: usize, value: bool) {
         // Note: we just bulk set all the bits in the last word in this fn in multiple places
@@ -818,11 +841,11 @@ impl BitVec {
         let full_value = if value { !0 } else { 0 };
 
         // Correct the old tail word, setting or clearing formerly unused bits
-        let old_last_word = blocks_for_bits(self.nbits) - 1;
-        if self.nbits % u32::BITS > 0 {
+        let num_cur_blocks = blocks_for_bits(self.nbits);
+        if self.nbits % u32::BITS as usize > 0 {
             let mask = mask_for_bits(self.nbits);
             if value {
-                self.storage[old_last_word] |= !mask;
+                self.storage[num_cur_blocks - 1] |= !mask;
             } else {
                 // Extra bits are already zero by invariant.
             }
@@ -830,7 +853,7 @@ impl BitVec {
 
         // Fill in words after the old tail word
         let stop_idx = cmp::min(self.storage.len(), new_nblocks);
-        for idx in old_last_word + 1..stop_idx {
+        for idx in num_cur_blocks..stop_idx {
             self.storage[idx] = full_value;
         }
 
@@ -851,6 +874,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::from_bytes(&[0b01001001]);
@@ -868,7 +892,7 @@ impl BitVec {
             // (3)
             self.set(i, false);
             self.nbits = i;
-            if self.nbits % u32::BITS == 0 {
+            if self.nbits % u32::BITS as usize == 0 {
                 // (2)
                 self.storage.pop();
             }
@@ -881,6 +905,7 @@ impl BitVec {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitVec;
     ///
     /// let mut bv = BitVec::new();
@@ -890,7 +915,7 @@ impl BitVec {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn push(&mut self, elem: bool) {
-        if self.nbits % u32::BITS == 0 {
+        if self.nbits % u32::BITS as usize == 0 {
             self.storage.push(0);
         }
         let insert_pos = self.nbits;
@@ -912,7 +937,7 @@ impl BitVec {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn clear(&mut self) {
-        for w in &mut self.storage { *w = 0u32; }
+        for w in &mut self.storage { *w = 0; }
     }
 }
 
@@ -978,24 +1003,13 @@ impl Ord for BitVec {
 impl fmt::Debug for BitVec {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         for bit in self {
-            try!(write!(fmt, "{}", if bit { 1u32 } else { 0u32 }));
+            try!(write!(fmt, "{}", if bit { 1 } else { 0 }));
         }
         Ok(())
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg(stage0)]
-impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for BitVec {
-    fn hash(&self, state: &mut S) {
-        self.nbits.hash(state);
-        for elem in self.blocks() {
-            elem.hash(state);
-        }
-    }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg(not(stage0))]
 impl hash::Hash for BitVec {
     fn hash<H: hash::Hasher>(&self, state: &mut H) {
         self.nbits.hash(state);
@@ -1102,6 +1116,7 @@ impl<'a> IntoIterator for &'a BitVec {
 /// # Examples
 ///
 /// ```
+/// # #![feature(collections)]
 /// use std::collections::{BitSet, BitVec};
 ///
 /// // It's a regular set
@@ -1198,6 +1213,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::new();
@@ -1214,6 +1230,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::with_capacity(100);
@@ -1231,6 +1248,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::{BitVec, BitSet};
     ///
     /// let bv = BitVec::from_bytes(&[0b01100000]);
@@ -1246,20 +1264,13 @@ impl BitSet {
         BitSet { bit_vec: bit_vec }
     }
 
-    /// Deprecated: use `from_bit_vec`.
-    #[inline]
-    #[deprecated(since = "1.0.0", reason = "renamed to from_bit_vec")]
-    #[unstable(feature = "collections")]
-    pub fn from_bitv(bit_vec: BitVec) -> BitSet {
-        BitSet { bit_vec: bit_vec }
-    }
-
     /// Returns the capacity in bits for this bit vector. Inserting any
     /// element less than this amount will not trigger a resizing.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::with_capacity(100);
@@ -1281,6 +1292,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::new();
@@ -1307,6 +1319,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::new();
@@ -1327,6 +1340,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::new();
@@ -1347,6 +1361,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::new();
@@ -1393,6 +1408,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BitSet;
     ///
     /// let mut s = BitSet::new();
@@ -1417,7 +1433,7 @@ impl BitSet {
         // Truncate
         let trunc_len = cmp::max(old_len - n, 1);
         bit_vec.storage.truncate(trunc_len);
-        bit_vec.nbits = trunc_len * u32::BITS;
+        bit_vec.nbits = trunc_len * u32::BITS as usize;
     }
 
     /// Iterator over each u32 stored in the `BitSet`.
@@ -1425,6 +1441,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::{BitVec, BitSet};
     ///
     /// let s = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01001010]));
@@ -1446,6 +1463,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::{BitVec, BitSet};
     ///
     /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
@@ -1476,6 +1494,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::{BitVec, BitSet};
     ///
     /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
@@ -1506,6 +1525,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::{BitSet, BitVec};
     ///
     /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
@@ -1544,6 +1564,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::{BitSet, BitVec};
     ///
     /// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
@@ -1573,6 +1594,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
@@ -1596,6 +1618,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
@@ -1620,6 +1643,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
@@ -1652,6 +1676,7 @@ impl BitSet {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::{BitSet, BitVec};
     ///
     /// let a   = 0b01101000;
@@ -1674,7 +1699,7 @@ impl BitSet {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn len(&self) -> usize  {
-        self.bit_vec.blocks().fold(0, |acc, n| acc + n.count_ones())
+        self.bit_vec.blocks().fold(0, |acc, n| acc + n.count_ones() as usize)
     }
 
     /// Returns whether there are no bits set in this set
@@ -1763,7 +1788,7 @@ impl BitSet {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Debug for BitSet {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(fmt, "BitSet {{"));
+        try!(write!(fmt, "{{"));
         let mut first = true;
         for n in self {
             if !first {
@@ -1776,16 +1801,7 @@ impl fmt::Debug for BitSet {
     }
 }
 
-#[cfg(stage0)]
-impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for BitSet {
-    fn hash(&self, state: &mut S) {
-        for pos in self {
-            pos.hash(state);
-        }
-    }
-}
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg(not(stage0))]
 impl hash::Hash for BitSet {
     fn hash<H: hash::Hasher>(&self, state: &mut H) {
         for pos in self {
@@ -1812,12 +1828,16 @@ struct TwoBitPositions<'a> {
     next_idx: usize
 }
 
+#[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Union<'a>(TwoBitPositions<'a>);
+#[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Intersection<'a>(Take<TwoBitPositions<'a>>);
+#[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Difference<'a>(TwoBitPositions<'a>);
+#[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct SymmetricDifference<'a>(TwoBitPositions<'a>);
 
@@ -1851,13 +1871,13 @@ impl<'a> Iterator for TwoBitPositions<'a> {
     fn next(&mut self) -> Option<usize> {
         while self.next_idx < self.set.bit_vec.len() ||
               self.next_idx < self.other.bit_vec.len() {
-            let bit_idx = self.next_idx % u32::BITS;
+            let bit_idx = self.next_idx % u32::BITS as usize;
             if bit_idx == 0 {
                 let s_bit_vec = &self.set.bit_vec;
                 let o_bit_vec = &self.other.bit_vec;
                 // Merging the two words is a bit of an awkward dance since
                 // one BitVec might be longer than the other
-                let word_idx = self.next_idx / u32::BITS;
+                let word_idx = self.next_idx / u32::BITS as usize;
                 let w1 = if word_idx < s_bit_vec.storage.len() {
                              s_bit_vec.storage[word_idx]
                          } else { 0 };
@@ -1923,1183 +1943,3 @@ impl<'a> IntoIterator for &'a BitSet {
         self.iter()
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use core::u32;
-
-    use super::BitVec;
-
-    #[test]
-    fn test_to_str() {
-        let zerolen = BitVec::new();
-        assert_eq!(format!("{:?}", zerolen), "");
-
-        let eightbits = BitVec::from_elem(8, false);
-        assert_eq!(format!("{:?}", eightbits), "00000000")
-    }
-
-    #[test]
-    fn test_0_elements() {
-        let act = BitVec::new();
-        let exp = Vec::new();
-        assert!(act.eq_vec(&exp));
-        assert!(act.none() && act.all());
-    }
-
-    #[test]
-    fn test_1_element() {
-        let mut act = BitVec::from_elem(1, false);
-        assert!(act.eq_vec(&[false]));
-        assert!(act.none() && !act.all());
-        act = BitVec::from_elem(1, true);
-        assert!(act.eq_vec(&[true]));
-        assert!(!act.none() && act.all());
-    }
-
-    #[test]
-    fn test_2_elements() {
-        let mut b = BitVec::from_elem(2, false);
-        b.set(0, true);
-        b.set(1, false);
-        assert_eq!(format!("{:?}", b), "10");
-        assert!(!b.none() && !b.all());
-    }
-
-    #[test]
-    fn test_10_elements() {
-        let mut act;
-        // all 0
-
-        act = BitVec::from_elem(10, false);
-        assert!((act.eq_vec(
-                    &[false, false, false, false, false, false, false, false, false, false])));
-        assert!(act.none() && !act.all());
-        // all 1
-
-        act = BitVec::from_elem(10, true);
-        assert!((act.eq_vec(&[true, true, true, true, true, true, true, true, true, true])));
-        assert!(!act.none() && act.all());
-        // mixed
-
-        act = BitVec::from_elem(10, false);
-        act.set(0, true);
-        act.set(1, true);
-        act.set(2, true);
-        act.set(3, true);
-        act.set(4, true);
-        assert!((act.eq_vec(&[true, true, true, true, true, false, false, false, false, false])));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(10, false);
-        act.set(5, true);
-        act.set(6, true);
-        act.set(7, true);
-        act.set(8, true);
-        act.set(9, true);
-        assert!((act.eq_vec(&[false, false, false, false, false, true, true, true, true, true])));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(10, false);
-        act.set(0, true);
-        act.set(3, true);
-        act.set(6, true);
-        act.set(9, true);
-        assert!((act.eq_vec(&[true, false, false, true, false, false, true, false, false, true])));
-        assert!(!act.none() && !act.all());
-    }
-
-    #[test]
-    fn test_31_elements() {
-        let mut act;
-        // all 0
-
-        act = BitVec::from_elem(31, false);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false]));
-        assert!(act.none() && !act.all());
-        // all 1
-
-        act = BitVec::from_elem(31, true);
-        assert!(act.eq_vec(
-                &[true, true, true, true, true, true, true, true, true, true, true, true, true,
-                  true, true, true, true, true, true, true, true, true, true, true, true, true,
-                  true, true, true, true, true]));
-        assert!(!act.none() && act.all());
-        // mixed
-
-        act = BitVec::from_elem(31, false);
-        act.set(0, true);
-        act.set(1, true);
-        act.set(2, true);
-        act.set(3, true);
-        act.set(4, true);
-        act.set(5, true);
-        act.set(6, true);
-        act.set(7, true);
-        assert!(act.eq_vec(
-                &[true, true, true, true, true, true, true, true, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(31, false);
-        act.set(16, true);
-        act.set(17, true);
-        act.set(18, true);
-        act.set(19, true);
-        act.set(20, true);
-        act.set(21, true);
-        act.set(22, true);
-        act.set(23, true);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, true, true, true, true, true, true, true, true,
-                  false, false, false, false, false, false, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(31, false);
-        act.set(24, true);
-        act.set(25, true);
-        act.set(26, true);
-        act.set(27, true);
-        act.set(28, true);
-        act.set(29, true);
-        act.set(30, true);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, true, true, true, true, true, true, true]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(31, false);
-        act.set(3, true);
-        act.set(17, true);
-        act.set(30, true);
-        assert!(act.eq_vec(
-                &[false, false, false, true, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, true, false, false, false, false, false, false,
-                  false, false, false, false, false, false, true]));
-        assert!(!act.none() && !act.all());
-    }
-
-    #[test]
-    fn test_32_elements() {
-        let mut act;
-        // all 0
-
-        act = BitVec::from_elem(32, false);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false]));
-        assert!(act.none() && !act.all());
-        // all 1
-
-        act = BitVec::from_elem(32, true);
-        assert!(act.eq_vec(
-                &[true, true, true, true, true, true, true, true, true, true, true, true, true,
-                  true, true, true, true, true, true, true, true, true, true, true, true, true,
-                  true, true, true, true, true, true]));
-        assert!(!act.none() && act.all());
-        // mixed
-
-        act = BitVec::from_elem(32, false);
-        act.set(0, true);
-        act.set(1, true);
-        act.set(2, true);
-        act.set(3, true);
-        act.set(4, true);
-        act.set(5, true);
-        act.set(6, true);
-        act.set(7, true);
-        assert!(act.eq_vec(
-                &[true, true, true, true, true, true, true, true, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(32, false);
-        act.set(16, true);
-        act.set(17, true);
-        act.set(18, true);
-        act.set(19, true);
-        act.set(20, true);
-        act.set(21, true);
-        act.set(22, true);
-        act.set(23, true);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, true, true, true, true, true, true, true, true,
-                  false, false, false, false, false, false, false, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(32, false);
-        act.set(24, true);
-        act.set(25, true);
-        act.set(26, true);
-        act.set(27, true);
-        act.set(28, true);
-        act.set(29, true);
-        act.set(30, true);
-        act.set(31, true);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, true, true, true, true, true, true, true, true]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(32, false);
-        act.set(3, true);
-        act.set(17, true);
-        act.set(30, true);
-        act.set(31, true);
-        assert!(act.eq_vec(
-                &[false, false, false, true, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, true, false, false, false, false, false, false,
-                  false, false, false, false, false, false, true, true]));
-        assert!(!act.none() && !act.all());
-    }
-
-    #[test]
-    fn test_33_elements() {
-        let mut act;
-        // all 0
-
-        act = BitVec::from_elem(33, false);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false]));
-        assert!(act.none() && !act.all());
-        // all 1
-
-        act = BitVec::from_elem(33, true);
-        assert!(act.eq_vec(
-                &[true, true, true, true, true, true, true, true, true, true, true, true, true,
-                  true, true, true, true, true, true, true, true, true, true, true, true, true,
-                  true, true, true, true, true, true, true]));
-        assert!(!act.none() && act.all());
-        // mixed
-
-        act = BitVec::from_elem(33, false);
-        act.set(0, true);
-        act.set(1, true);
-        act.set(2, true);
-        act.set(3, true);
-        act.set(4, true);
-        act.set(5, true);
-        act.set(6, true);
-        act.set(7, true);
-        assert!(act.eq_vec(
-                &[true, true, true, true, true, true, true, true, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(33, false);
-        act.set(16, true);
-        act.set(17, true);
-        act.set(18, true);
-        act.set(19, true);
-        act.set(20, true);
-        act.set(21, true);
-        act.set(22, true);
-        act.set(23, true);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, true, true, true, true, true, true, true, true,
-                  false, false, false, false, false, false, false, false, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(33, false);
-        act.set(24, true);
-        act.set(25, true);
-        act.set(26, true);
-        act.set(27, true);
-        act.set(28, true);
-        act.set(29, true);
-        act.set(30, true);
-        act.set(31, true);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, true, true, true, true, true, true, true, true, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(33, false);
-        act.set(3, true);
-        act.set(17, true);
-        act.set(30, true);
-        act.set(31, true);
-        act.set(32, true);
-        assert!(act.eq_vec(
-                &[false, false, false, true, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, true, false, false, false, false, false, false,
-                  false, false, false, false, false, false, true, true, true]));
-        assert!(!act.none() && !act.all());
-    }
-
-    #[test]
-    fn test_equal_differing_sizes() {
-        let v0 = BitVec::from_elem(10, false);
-        let v1 = BitVec::from_elem(11, false);
-        assert!(v0 != v1);
-    }
-
-    #[test]
-    fn test_equal_greatly_differing_sizes() {
-        let v0 = BitVec::from_elem(10, false);
-        let v1 = BitVec::from_elem(110, false);
-        assert!(v0 != v1);
-    }
-
-    #[test]
-    fn test_equal_sneaky_small() {
-        let mut a = BitVec::from_elem(1, false);
-        a.set(0, true);
-
-        let mut b = BitVec::from_elem(1, true);
-        b.set(0, true);
-
-        assert_eq!(a, b);
-    }
-
-    #[test]
-    fn test_equal_sneaky_big() {
-        let mut a = BitVec::from_elem(100, false);
-        for i in 0..100 {
-            a.set(i, true);
-        }
-
-        let mut b = BitVec::from_elem(100, true);
-        for i in 0..100 {
-            b.set(i, true);
-        }
-
-        assert_eq!(a, b);
-    }
-
-    #[test]
-    fn test_from_bytes() {
-        let bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
-        let str = concat!("10110110", "00000000", "11111111");
-        assert_eq!(format!("{:?}", bit_vec), str);
-    }
-
-    #[test]
-    fn test_to_bytes() {
-        let mut bv = BitVec::from_elem(3, true);
-        bv.set(1, false);
-        assert_eq!(bv.to_bytes(), vec!(0b10100000));
-
-        let mut bv = BitVec::from_elem(9, false);
-        bv.set(2, true);
-        bv.set(8, true);
-        assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
-    }
-
-    #[test]
-    fn test_from_bools() {
-        let bools = vec![true, false, true, true];
-        let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
-        assert_eq!(format!("{:?}", bit_vec), "1011");
-    }
-
-    #[test]
-    fn test_to_bools() {
-        let bools = vec![false, false, true, false, false, true, true, false];
-        assert_eq!(BitVec::from_bytes(&[0b00100110]).iter().collect::<Vec<bool>>(), bools);
-    }
-
-    #[test]
-    fn test_bit_vec_iterator() {
-        let bools = vec![true, false, true, true];
-        let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
-
-        assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), bools);
-
-        let long: Vec<_> = (0i32..10000).map(|i| i % 2 == 0).collect();
-        let bit_vec: BitVec = long.iter().map(|n| *n).collect();
-        assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), long)
-    }
-
-    #[test]
-    fn test_small_difference() {
-        let mut b1 = BitVec::from_elem(3, false);
-        let mut b2 = BitVec::from_elem(3, false);
-        b1.set(0, true);
-        b1.set(1, true);
-        b2.set(1, true);
-        b2.set(2, true);
-        assert!(b1.difference(&b2));
-        assert!(b1[0]);
-        assert!(!b1[1]);
-        assert!(!b1[2]);
-    }
-
-    #[test]
-    fn test_big_difference() {
-        let mut b1 = BitVec::from_elem(100, false);
-        let mut b2 = BitVec::from_elem(100, false);
-        b1.set(0, true);
-        b1.set(40, true);
-        b2.set(40, true);
-        b2.set(80, true);
-        assert!(b1.difference(&b2));
-        assert!(b1[0]);
-        assert!(!b1[40]);
-        assert!(!b1[80]);
-    }
-
-    #[test]
-    fn test_small_clear() {
-        let mut b = BitVec::from_elem(14, true);
-        assert!(!b.none() && b.all());
-        b.clear();
-        assert!(b.none() && !b.all());
-    }
-
-    #[test]
-    fn test_big_clear() {
-        let mut b = BitVec::from_elem(140, true);
-        assert!(!b.none() && b.all());
-        b.clear();
-        assert!(b.none() && !b.all());
-    }
-
-    #[test]
-    fn test_bit_vec_lt() {
-        let mut a = BitVec::from_elem(5, false);
-        let mut b = BitVec::from_elem(5, false);
-
-        assert!(!(a < b) && !(b < a));
-        b.set(2, true);
-        assert!(a < b);
-        a.set(3, true);
-        assert!(a < b);
-        a.set(2, true);
-        assert!(!(a < b) && b < a);
-        b.set(0, true);
-        assert!(a < b);
-    }
-
-    #[test]
-    fn test_ord() {
-        let mut a = BitVec::from_elem(5, false);
-        let mut b = BitVec::from_elem(5, false);
-
-        assert!(a <= b && a >= b);
-        a.set(1, true);
-        assert!(a > b && a >= b);
-        assert!(b < a && b <= a);
-        b.set(1, true);
-        b.set(2, true);
-        assert!(b > a && b >= a);
-        assert!(a < b && a <= b);
-    }
-
-
-    #[test]
-    fn test_small_bit_vec_tests() {
-        let v = BitVec::from_bytes(&[0]);
-        assert!(!v.all());
-        assert!(!v.any());
-        assert!(v.none());
-
-        let v = BitVec::from_bytes(&[0b00010100]);
-        assert!(!v.all());
-        assert!(v.any());
-        assert!(!v.none());
-
-        let v = BitVec::from_bytes(&[0xFF]);
-        assert!(v.all());
-        assert!(v.any());
-        assert!(!v.none());
-    }
-
-    #[test]
-    fn test_big_bit_vec_tests() {
-        let v = BitVec::from_bytes(&[ // 88 bits
-            0, 0, 0, 0,
-            0, 0, 0, 0,
-            0, 0, 0]);
-        assert!(!v.all());
-        assert!(!v.any());
-        assert!(v.none());
-
-        let v = BitVec::from_bytes(&[ // 88 bits
-            0, 0, 0b00010100, 0,
-            0, 0, 0, 0b00110100,
-            0, 0, 0]);
-        assert!(!v.all());
-        assert!(v.any());
-        assert!(!v.none());
-
-        let v = BitVec::from_bytes(&[ // 88 bits
-            0xFF, 0xFF, 0xFF, 0xFF,
-            0xFF, 0xFF, 0xFF, 0xFF,
-            0xFF, 0xFF, 0xFF]);
-        assert!(v.all());
-        assert!(v.any());
-        assert!(!v.none());
-    }
-
-    #[test]
-    fn test_bit_vec_push_pop() {
-        let mut s = BitVec::from_elem(5 * u32::BITS - 2, false);
-        assert_eq!(s.len(), 5 * u32::BITS - 2);
-        assert_eq!(s[5 * u32::BITS - 3], false);
-        s.push(true);
-        s.push(true);
-        assert_eq!(s[5 * u32::BITS - 2], true);
-        assert_eq!(s[5 * u32::BITS - 1], true);
-        // Here the internal vector will need to be extended
-        s.push(false);
-        assert_eq!(s[5 * u32::BITS], false);
-        s.push(false);
-        assert_eq!(s[5 * u32::BITS + 1], false);
-        assert_eq!(s.len(), 5 * u32::BITS + 2);
-        // Pop it all off
-        assert_eq!(s.pop(), Some(false));
-        assert_eq!(s.pop(), Some(false));
-        assert_eq!(s.pop(), Some(true));
-        assert_eq!(s.pop(), Some(true));
-        assert_eq!(s.len(), 5 * u32::BITS - 2);
-    }
-
-    #[test]
-    fn test_bit_vec_truncate() {
-        let mut s = BitVec::from_elem(5 * u32::BITS, true);
-
-        assert_eq!(s, BitVec::from_elem(5 * u32::BITS, true));
-        assert_eq!(s.len(), 5 * u32::BITS);
-        s.truncate(4 * u32::BITS);
-        assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true));
-        assert_eq!(s.len(), 4 * u32::BITS);
-        // Truncating to a size > s.len() should be a noop
-        s.truncate(5 * u32::BITS);
-        assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true));
-        assert_eq!(s.len(), 4 * u32::BITS);
-        s.truncate(3 * u32::BITS - 10);
-        assert_eq!(s, BitVec::from_elem(3 * u32::BITS - 10, true));
-        assert_eq!(s.len(), 3 * u32::BITS - 10);
-        s.truncate(0);
-        assert_eq!(s, BitVec::from_elem(0, true));
-        assert_eq!(s.len(), 0);
-    }
-
-    #[test]
-    fn test_bit_vec_reserve() {
-        let mut s = BitVec::from_elem(5 * u32::BITS, true);
-        // Check capacity
-        assert!(s.capacity() >= 5 * u32::BITS);
-        s.reserve(2 * u32::BITS);
-        assert!(s.capacity() >= 7 * u32::BITS);
-        s.reserve(7 * u32::BITS);
-        assert!(s.capacity() >= 12 * u32::BITS);
-        s.reserve_exact(7 * u32::BITS);
-        assert!(s.capacity() >= 12 * u32::BITS);
-        s.reserve(7 * u32::BITS + 1);
-        assert!(s.capacity() >= 12 * u32::BITS + 1);
-        // Check that length hasn't changed
-        assert_eq!(s.len(), 5 * u32::BITS);
-        s.push(true);
-        s.push(false);
-        s.push(true);
-        assert_eq!(s[5 * u32::BITS - 1], true);
-        assert_eq!(s[5 * u32::BITS - 0], true);
-        assert_eq!(s[5 * u32::BITS + 1], false);
-        assert_eq!(s[5 * u32::BITS + 2], true);
-    }
-
-    #[test]
-    fn test_bit_vec_grow() {
-        let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010]);
-        bit_vec.grow(32, true);
-        assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
-                                     0xFF, 0xFF, 0xFF, 0xFF]));
-        bit_vec.grow(64, false);
-        assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
-                                     0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0]));
-        bit_vec.grow(16, true);
-        assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
-                                     0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]));
-    }
-
-    #[test]
-    fn test_bit_vec_extend() {
-        let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
-        let ext = BitVec::from_bytes(&[0b01001001, 0b10010010, 0b10111101]);
-        bit_vec.extend(ext.iter());
-        assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111,
-                                     0b01001001, 0b10010010, 0b10111101]));
-    }
-}
-
-
-
-
-#[cfg(test)]
-mod bit_vec_bench {
-    use std::prelude::v1::*;
-    use std::rand;
-    use std::rand::Rng;
-    use std::u32;
-    use test::{Bencher, black_box};
-
-    use super::BitVec;
-
-    static BENCH_BITS : usize = 1 << 14;
-
-    fn rng() -> rand::IsaacRng {
-        let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
-        rand::SeedableRng::from_seed(seed)
-    }
-
-    #[bench]
-    fn bench_usize_small(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bit_vec = 0 as usize;
-        b.iter(|| {
-            for _ in 0..100 {
-                bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS);
-            }
-            black_box(&bit_vec);
-        });
-    }
-
-    #[bench]
-    fn bench_bit_set_big_fixed(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
-        b.iter(|| {
-            for _ in 0..100 {
-                bit_vec.set((r.next_u32() as usize) % BENCH_BITS, true);
-            }
-            black_box(&bit_vec);
-        });
-    }
-
-    #[bench]
-    fn bench_bit_set_big_variable(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
-        b.iter(|| {
-            for _ in 0..100 {
-                bit_vec.set((r.next_u32() as usize) % BENCH_BITS, r.gen());
-            }
-            black_box(&bit_vec);
-        });
-    }
-
-    #[bench]
-    fn bench_bit_set_small(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bit_vec = BitVec::from_elem(u32::BITS, false);
-        b.iter(|| {
-            for _ in 0..100 {
-                bit_vec.set((r.next_u32() as usize) % u32::BITS, true);
-            }
-            black_box(&bit_vec);
-        });
-    }
-
-    #[bench]
-    fn bench_bit_vec_big_union(b: &mut Bencher) {
-        let mut b1 = BitVec::from_elem(BENCH_BITS, false);
-        let b2 = BitVec::from_elem(BENCH_BITS, false);
-        b.iter(|| {
-            b1.union(&b2)
-        })
-    }
-
-    #[bench]
-    fn bench_bit_vec_small_iter(b: &mut Bencher) {
-        let bit_vec = BitVec::from_elem(u32::BITS, false);
-        b.iter(|| {
-            let mut sum = 0;
-            for _ in 0..10 {
-                for pres in &bit_vec {
-                    sum += pres as usize;
-                }
-            }
-            sum
-        })
-    }
-
-    #[bench]
-    fn bench_bit_vec_big_iter(b: &mut Bencher) {
-        let bit_vec = BitVec::from_elem(BENCH_BITS, false);
-        b.iter(|| {
-            let mut sum = 0;
-            for pres in &bit_vec {
-                sum += pres as usize;
-            }
-            sum
-        })
-    }
-}
-
-
-
-
-
-
-
-#[cfg(test)]
-mod bit_set_test {
-    use prelude::*;
-    use std::iter::range_step;
-
-    use super::{BitVec, BitSet};
-
-    #[test]
-    fn test_bit_set_show() {
-        let mut s = BitSet::new();
-        s.insert(1);
-        s.insert(10);
-        s.insert(50);
-        s.insert(2);
-        assert_eq!("BitSet {1, 2, 10, 50}", format!("{:?}", s));
-    }
-
-    #[test]
-    fn test_bit_set_from_usizes() {
-        let usizes = vec![0, 2, 2, 3];
-        let a: BitSet = usizes.into_iter().collect();
-        let mut b = BitSet::new();
-        b.insert(0);
-        b.insert(2);
-        b.insert(3);
-        assert_eq!(a, b);
-    }
-
-    #[test]
-    fn test_bit_set_iterator() {
-        let usizes = vec![0, 2, 2, 3];
-        let bit_vec: BitSet = usizes.into_iter().collect();
-
-        let idxs: Vec<_> = bit_vec.iter().collect();
-        assert_eq!(idxs, vec![0, 2, 3]);
-
-        let long: BitSet = (0..10000).filter(|&n| n % 2 == 0).collect();
-        let real: Vec<_> = range_step(0, 10000, 2).collect();
-
-        let idxs: Vec<_> = long.iter().collect();
-        assert_eq!(idxs, real);
-    }
-
-    #[test]
-    fn test_bit_set_frombit_vec_init() {
-        let bools = [true, false];
-        let lengths = [10, 64, 100];
-        for &b in &bools {
-            for &l in &lengths {
-                let bitset = BitSet::from_bit_vec(BitVec::from_elem(l, b));
-                assert_eq!(bitset.contains(&1), b);
-                assert_eq!(bitset.contains(&(l-1)), b);
-                assert!(!bitset.contains(&l));
-            }
-        }
-    }
-
-    #[test]
-    fn test_bit_vec_masking() {
-        let b = BitVec::from_elem(140, true);
-        let mut bs = BitSet::from_bit_vec(b);
-        assert!(bs.contains(&139));
-        assert!(!bs.contains(&140));
-        assert!(bs.insert(150));
-        assert!(!bs.contains(&140));
-        assert!(!bs.contains(&149));
-        assert!(bs.contains(&150));
-        assert!(!bs.contains(&151));
-    }
-
-    #[test]
-    fn test_bit_set_basic() {
-        let mut b = BitSet::new();
-        assert!(b.insert(3));
-        assert!(!b.insert(3));
-        assert!(b.contains(&3));
-        assert!(b.insert(4));
-        assert!(!b.insert(4));
-        assert!(b.contains(&3));
-        assert!(b.insert(400));
-        assert!(!b.insert(400));
-        assert!(b.contains(&400));
-        assert_eq!(b.len(), 3);
-    }
-
-    #[test]
-    fn test_bit_set_intersection() {
-        let mut a = BitSet::new();
-        let mut b = BitSet::new();
-
-        assert!(a.insert(11));
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(77));
-        assert!(a.insert(103));
-        assert!(a.insert(5));
-
-        assert!(b.insert(2));
-        assert!(b.insert(11));
-        assert!(b.insert(77));
-        assert!(b.insert(5));
-        assert!(b.insert(3));
-
-        let expected = [3, 5, 11, 77];
-        let actual: Vec<_> = a.intersection(&b).collect();
-        assert_eq!(actual, expected);
-    }
-
-    #[test]
-    fn test_bit_set_difference() {
-        let mut a = BitSet::new();
-        let mut b = BitSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(200));
-        assert!(a.insert(500));
-
-        assert!(b.insert(3));
-        assert!(b.insert(200));
-
-        let expected = [1, 5, 500];
-        let actual: Vec<_> = a.difference(&b).collect();
-        assert_eq!(actual, expected);
-    }
-
-    #[test]
-    fn test_bit_set_symmetric_difference() {
-        let mut a = BitSet::new();
-        let mut b = BitSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(9));
-        assert!(a.insert(11));
-
-        assert!(b.insert(3));
-        assert!(b.insert(9));
-        assert!(b.insert(14));
-        assert!(b.insert(220));
-
-        let expected = [1, 5, 11, 14, 220];
-        let actual: Vec<_> = a.symmetric_difference(&b).collect();
-        assert_eq!(actual, expected);
-    }
-
-    #[test]
-    fn test_bit_set_union() {
-        let mut a = BitSet::new();
-        let mut b = BitSet::new();
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(9));
-        assert!(a.insert(11));
-        assert!(a.insert(160));
-        assert!(a.insert(19));
-        assert!(a.insert(24));
-        assert!(a.insert(200));
-
-        assert!(b.insert(1));
-        assert!(b.insert(5));
-        assert!(b.insert(9));
-        assert!(b.insert(13));
-        assert!(b.insert(19));
-
-        let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160, 200];
-        let actual: Vec<_> = a.union(&b).collect();
-        assert_eq!(actual, expected);
-    }
-
-    #[test]
-    fn test_bit_set_subset() {
-        let mut set1 = BitSet::new();
-        let mut set2 = BitSet::new();
-
-        assert!(set1.is_subset(&set2)); //  {}  {}
-        set2.insert(100);
-        assert!(set1.is_subset(&set2)); //  {}  { 1 }
-        set2.insert(200);
-        assert!(set1.is_subset(&set2)); //  {}  { 1, 2 }
-        set1.insert(200);
-        assert!(set1.is_subset(&set2)); //  { 2 }  { 1, 2 }
-        set1.insert(300);
-        assert!(!set1.is_subset(&set2)); // { 2, 3 }  { 1, 2 }
-        set2.insert(300);
-        assert!(set1.is_subset(&set2)); // { 2, 3 }  { 1, 2, 3 }
-        set2.insert(400);
-        assert!(set1.is_subset(&set2)); // { 2, 3 }  { 1, 2, 3, 4 }
-        set2.remove(&100);
-        assert!(set1.is_subset(&set2)); // { 2, 3 }  { 2, 3, 4 }
-        set2.remove(&300);
-        assert!(!set1.is_subset(&set2)); // { 2, 3 }  { 2, 4 }
-        set1.remove(&300);
-        assert!(set1.is_subset(&set2)); // { 2 }  { 2, 4 }
-    }
-
-    #[test]
-    fn test_bit_set_is_disjoint() {
-        let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01000000]));
-        let c = BitSet::new();
-        let d = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00110000]));
-
-        assert!(!a.is_disjoint(&d));
-        assert!(!d.is_disjoint(&a));
-
-        assert!(a.is_disjoint(&b));
-        assert!(a.is_disjoint(&c));
-        assert!(b.is_disjoint(&a));
-        assert!(b.is_disjoint(&c));
-        assert!(c.is_disjoint(&a));
-        assert!(c.is_disjoint(&b));
-    }
-
-    #[test]
-    fn test_bit_set_union_with() {
-        //a should grow to include larger elements
-        let mut a = BitSet::new();
-        a.insert(0);
-        let mut b = BitSet::new();
-        b.insert(5);
-        let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
-        a.union_with(&b);
-        assert_eq!(a, expected);
-
-        // Standard
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
-        let c = a.clone();
-        a.union_with(&b);
-        b.union_with(&c);
-        assert_eq!(a.len(), 4);
-        assert_eq!(b.len(), 4);
-    }
-
-    #[test]
-    fn test_bit_set_intersect_with() {
-        // Explicitly 0'ed bits
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
-        let c = a.clone();
-        a.intersect_with(&b);
-        b.intersect_with(&c);
-        assert!(a.is_empty());
-        assert!(b.is_empty());
-
-        // Uninitialized bits should behave like 0's
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let mut b = BitSet::new();
-        let c = a.clone();
-        a.intersect_with(&b);
-        b.intersect_with(&c);
-        assert!(a.is_empty());
-        assert!(b.is_empty());
-
-        // Standard
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
-        let c = a.clone();
-        a.intersect_with(&b);
-        b.intersect_with(&c);
-        assert_eq!(a.len(), 2);
-        assert_eq!(b.len(), 2);
-    }
-
-    #[test]
-    fn test_bit_set_difference_with() {
-        // Explicitly 0'ed bits
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
-        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        a.difference_with(&b);
-        assert!(a.is_empty());
-
-        // Uninitialized bits should behave like 0's
-        let mut a = BitSet::new();
-        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11111111]));
-        a.difference_with(&b);
-        assert!(a.is_empty());
-
-        // Standard
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
-        let c = a.clone();
-        a.difference_with(&b);
-        b.difference_with(&c);
-        assert_eq!(a.len(), 1);
-        assert_eq!(b.len(), 1);
-    }
-
-    #[test]
-    fn test_bit_set_symmetric_difference_with() {
-        //a should grow to include larger elements
-        let mut a = BitSet::new();
-        a.insert(0);
-        a.insert(1);
-        let mut b = BitSet::new();
-        b.insert(1);
-        b.insert(5);
-        let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
-        a.symmetric_difference_with(&b);
-        assert_eq!(a, expected);
-
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let b = BitSet::new();
-        let c = a.clone();
-        a.symmetric_difference_with(&b);
-        assert_eq!(a, c);
-
-        // Standard
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11100010]));
-        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101010]));
-        let c = a.clone();
-        a.symmetric_difference_with(&b);
-        b.symmetric_difference_with(&c);
-        assert_eq!(a.len(), 2);
-        assert_eq!(b.len(), 2);
-    }
-
-    #[test]
-    fn test_bit_set_eq() {
-        let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
-        let c = BitSet::new();
-
-        assert!(a == a);
-        assert!(a != b);
-        assert!(a != c);
-        assert!(b == b);
-        assert!(b == c);
-        assert!(c == c);
-    }
-
-    #[test]
-    fn test_bit_set_cmp() {
-        let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
-        let c = BitSet::new();
-
-        assert_eq!(a.cmp(&b), Greater);
-        assert_eq!(a.cmp(&c), Greater);
-        assert_eq!(b.cmp(&a), Less);
-        assert_eq!(b.cmp(&c), Equal);
-        assert_eq!(c.cmp(&a), Less);
-        assert_eq!(c.cmp(&b), Equal);
-    }
-
-    #[test]
-    fn test_bit_vec_remove() {
-        let mut a = BitSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.remove(&1));
-
-        assert!(a.insert(100));
-        assert!(a.remove(&100));
-
-        assert!(a.insert(1000));
-        assert!(a.remove(&1000));
-        a.shrink_to_fit();
-    }
-
-    #[test]
-    fn test_bit_vec_clone() {
-        let mut a = BitSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(100));
-        assert!(a.insert(1000));
-
-        let mut b = a.clone();
-
-        assert!(a == b);
-
-        assert!(b.remove(&1));
-        assert!(a.contains(&1));
-
-        assert!(a.remove(&1000));
-        assert!(b.contains(&1000));
-    }
-}
-
-
-
-
-
-#[cfg(test)]
-mod bit_set_bench {
-    use std::prelude::v1::*;
-    use std::rand;
-    use std::rand::Rng;
-    use std::u32;
-    use test::{Bencher, black_box};
-
-    use super::{BitVec, BitSet};
-
-    static BENCH_BITS : usize = 1 << 14;
-
-    fn rng() -> rand::IsaacRng {
-        let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
-        rand::SeedableRng::from_seed(seed)
-    }
-
-    #[bench]
-    fn bench_bit_vecset_small(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bit_vec = BitSet::new();
-        b.iter(|| {
-            for _ in 0..100 {
-                bit_vec.insert((r.next_u32() as usize) % u32::BITS);
-            }
-            black_box(&bit_vec);
-        });
-    }
-
-    #[bench]
-    fn bench_bit_vecset_big(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bit_vec = BitSet::new();
-        b.iter(|| {
-            for _ in 0..100 {
-                bit_vec.insert((r.next_u32() as usize) % BENCH_BITS);
-            }
-            black_box(&bit_vec);
-        });
-    }
-
-    #[bench]
-    fn bench_bit_vecset_iter(b: &mut Bencher) {
-        let bit_vec = BitSet::from_bit_vec(BitVec::from_fn(BENCH_BITS,
-                                              |idx| {idx % 3 == 0}));
-        b.iter(|| {
-            let mut sum = 0;
-            for idx in &bit_vec {
-                sum += idx as usize;
-            }
-            sum
-        })
-    }
-}
index 901d7a73b51ed27bbc051ccc09a261fc3b5e3353..2fe769b73f5cc00619e11b0d2f771eb3b05bd717 100644 (file)
@@ -14,6 +14,7 @@
 
 use core::clone::Clone;
 use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::convert::AsRef;
 use core::hash::{Hash, Hasher};
 use core::marker::Sized;
 use core::ops::Deref;
@@ -39,6 +40,24 @@ use self::Cow::*;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Borrow<Borrowed: ?Sized> {
     /// Immutably borrow from an owned value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::borrow::Borrow;
+    ///
+    /// fn check<T: Borrow<str>>(s: T) {
+    ///     assert_eq!("Hello", s.borrow());
+    /// }
+    ///
+    /// let s = "Hello".to_string();
+    ///
+    /// check(s);
+    ///
+    /// let s = "Hello";
+    ///
+    /// check(s);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn borrow(&self) -> &Borrowed;
 }
@@ -49,6 +68,20 @@ pub trait Borrow<Borrowed: ?Sized> {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
     /// Mutably borrow from an owned value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::borrow::BorrowMut;
+    ///
+    /// fn check<T: BorrowMut<[i32]>>(mut v: T) {
+    ///     assert_eq!(&mut [1, 2, 3], v.borrow_mut());
+    /// }
+    ///
+    /// let v = vec![1, 2, 3];
+    ///
+    /// check(v);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn borrow_mut(&mut self) -> &mut Borrowed;
 }
@@ -127,12 +160,12 @@ impl<T> ToOwned for T where T: Clone {
 /// is desired, `to_mut` will obtain a mutable references to an owned
 /// value, cloning if necessary.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::borrow::Cow;
 ///
-/// fn abs_all(input: &mut Cow<[int]>) {
+/// fn abs_all(input: &mut Cow<[i32]>) {
 ///     for i in 0..input.len() {
 ///         let v = input[i];
 ///         if v < 0 {
@@ -170,6 +203,18 @@ impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned {
     /// Acquire a mutable reference to the owned form of the data.
     ///
     /// Copies the data if it is not already owned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::borrow::Cow;
+    ///
+    /// let mut cow: Cow<[_]> = Cow::Owned(vec![1, 2, 3]);
+    ///
+    /// let hello = cow.to_mut();
+    ///
+    /// assert_eq!(hello, &[1, 2, 3]);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
         match *self {
@@ -184,6 +229,18 @@ impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned {
     /// Extract the owned data.
     ///
     /// Copies the data if it is not already owned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::borrow::Cow;
+    ///
+    /// let cow: Cow<[_]> = Cow::Owned(vec![1, 2, 3]);
+    ///
+    /// let hello = cow.into_owned();
+    ///
+    /// assert_eq!(vec![1, 2, 3], hello);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_owned(self) -> <B as ToOwned>::Owned {
         match self {
@@ -191,26 +248,6 @@ impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned {
             Owned(owned) => owned
         }
     }
-
-    /// Returns true if this `Cow` wraps a borrowed value
-    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
-    #[unstable(feature = "std_misc")]
-    pub fn is_borrowed(&self) -> bool {
-        match *self {
-            Borrowed(_) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns true if this `Cow` wraps an owned value
-    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
-    #[unstable(feature = "std_misc")]
-    pub fn is_owned(&self) -> bool {
-        match *self {
-            Owned(_) => true,
-            _ => false,
-        }
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -282,16 +319,6 @@ impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg(stage0)]
-impl<'a, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, B> where B: Hash<S> + ToOwned
-{
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        Hash::hash(&**self, state)
-    }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg(not(stage0))]
 impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned
 {
     #[inline]
@@ -301,10 +328,9 @@ impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned
 }
 
 /// Trait for moving into a `Cow`
-#[stable(feature = "rust1", since = "1.0.0")]
+#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`")]
 pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
     /// Moves `self` into `Cow`
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn into_cow(self) -> Cow<'a, B>;
 }
 
@@ -314,3 +340,10 @@ impl<'a,  B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
         self
     }
 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: Clone> AsRef<T> for Cow<'a, T> {
+    fn as_ref(&self) -> &T {
+        self
+    }
+}
diff --git a/src/libcollections/borrow_stage0.rs b/src/libcollections/borrow_stage0.rs
deleted file mode 100644 (file)
index c1d74b1..0000000
+++ /dev/null
@@ -1,313 +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 module for working with borrowed data.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use core::clone::Clone;
-use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
-use core::hash::{Hash, Hasher};
-use core::marker::Sized;
-use core::ops::Deref;
-use core::option::Option;
-
-use fmt;
-use alloc::{rc, arc};
-
-use self::Cow::*;
-
-/// A trait for borrowing data.
-///
-/// In general, there may be several ways to "borrow" a piece of data.  The
-/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
-/// (a mutable borrow). But types like `Vec<T>` provide additional kinds of
-/// borrows: the borrowed slices `&[T]` and `&mut [T]`.
-///
-/// When writing generic code, it is often desirable to abstract over all ways
-/// of borrowing data from a given type. That is the role of the `Borrow`
-/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`.  A given
-/// type can be borrowed as multiple different types. In particular, `Vec<T>:
-/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait Borrow<Borrowed: ?Sized> {
-    /// Immutably borrow from an owned value.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn borrow(&self) -> &Borrowed;
-}
-
-/// A trait for mutably borrowing data.
-///
-/// Similar to `Borrow`, but for mutable borrows.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
-    /// Mutably borrow from an owned value.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn borrow_mut(&mut self) -> &mut Borrowed;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized> Borrow<T> for T {
-    fn borrow(&self) -> &T { self }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized> BorrowMut<T> for T {
-    fn borrow_mut(&mut self) -> &mut T { self }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: ?Sized> Borrow<T> for &'a T {
-    fn borrow(&self) -> &T { &**self }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: ?Sized> Borrow<T> for &'a mut T {
-    fn borrow(&self) -> &T { &**self }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
-    fn borrow_mut(&mut self) -> &mut T { &mut **self }
-}
-
-impl<T> Borrow<T> for rc::Rc<T> {
-    fn borrow(&self) -> &T { &**self }
-}
-
-impl<T> Borrow<T> for arc::Arc<T> {
-    fn borrow(&self) -> &T { &**self }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
-    fn borrow(&self) -> &B {
-        &**self
-    }
-}
-
-/// A generalization of Clone to borrowed data.
-///
-/// Some types make it possible to go from borrowed to owned, usually by
-/// implementing the `Clone` trait. But `Clone` works only for going from `&T`
-/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
-/// from any borrow of a given type.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait ToOwned {
-    #[stable(feature = "rust1", since = "1.0.0")]
-    type Owned: Borrow<Self>;
-
-    /// Create owned data from borrowed data, usually by copying.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn to_owned(&self) -> Self::Owned;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> ToOwned for T where T: Clone {
-    type Owned = T;
-    fn to_owned(&self) -> T { self.clone() }
-}
-
-/// A clone-on-write smart pointer.
-///
-/// The type `Cow` is a smart pointer providing clone-on-write functionality: it
-/// can enclose and provide immutable access to borrowed data, and clone the
-/// data lazily when mutation or ownership is required. The type is designed to
-/// work with general borrowed data via the `Borrow` trait.
-///
-/// `Cow` implements both `Deref`, which means that you can call
-/// non-mutating methods directly on the data it encloses. If mutation
-/// is desired, `to_mut` will obtain a mutable references to an owned
-/// value, cloning if necessary.
-///
-/// # Example
-///
-/// ```rust
-/// use std::borrow::Cow;
-///
-/// fn abs_all(input: &mut Cow<[int]>) {
-///     for i in 0..input.len() {
-///         let v = input[i];
-///         if v < 0 {
-///             // clones into a vector the first time (if not already owned)
-///             input.to_mut()[i] = -v;
-///         }
-///     }
-/// }
-/// ```
-#[stable(feature = "rust1", since = "1.0.0")]
-pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned {
-    /// Borrowed data.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    Borrowed(&'a B),
-
-    /// Owned data.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    Owned(<B as ToOwned>::Owned)
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned {
-    fn clone(&self) -> Cow<'a, B> {
-        match *self {
-            Borrowed(b) => Borrowed(b),
-            Owned(ref o) => {
-                let b: &B = o.borrow();
-                Owned(b.to_owned())
-            },
-        }
-    }
-}
-
-impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
-    /// Acquire a mutable reference to the owned form of the data.
-    ///
-    /// Copies the data if it is not already owned.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned where <B as ToOwned>::Owned: 'a {
-        match *self {
-            Borrowed(borrowed) => {
-                *self = Owned(borrowed.to_owned());
-                self.to_mut()
-            }
-            Owned(ref mut owned) => owned
-        }
-    }
-
-    /// Extract the owned data.
-    ///
-    /// Copies the data if it is not already owned.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_owned(self) -> <B as ToOwned>::Owned {
-        match self {
-            Borrowed(borrowed) => borrowed.to_owned(),
-            Owned(owned) => owned
-        }
-    }
-
-    /// Returns true if this `Cow` wraps a borrowed value
-    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
-    #[unstable(feature = "std_misc")]
-    pub fn is_borrowed(&self) -> bool {
-        match *self {
-            Borrowed(_) => true,
-            _ => false,
-        }
-    }
-
-    /// Returns true if this `Cow` wraps an owned value
-    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
-    #[unstable(feature = "std_misc")]
-    pub fn is_owned(&self) -> bool {
-        match *self {
-            Owned(_) => true,
-            _ => false,
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, B: ?Sized> Deref for Cow<'a, B> where
-    B: ToOwned, <B as ToOwned>::Owned: 'a
-{
-    type Target = B;
-
-    fn deref(&self) -> &B {
-        match *self {
-            Borrowed(borrowed) => borrowed,
-            Owned(ref owned) => owned.borrow()
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned, <B as ToOwned>::Owned: 'a {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, B: ?Sized> Ord for Cow<'a, B> where
-    B: Ord + ToOwned, <B as ToOwned>::Owned: 'a
-{
-    #[inline]
-    fn cmp(&self, other: &Cow<'a, B>) -> Ordering {
-        Ord::cmp(&**self, &**other)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B> where
-    B: PartialEq<C> + ToOwned, C: ToOwned,
-    <B as ToOwned>::Owned: 'a, <C as ToOwned>::Owned: 'b,
-{
-    #[inline]
-    fn eq(&self, other: &Cow<'b, C>) -> bool {
-        PartialEq::eq(&**self, &**other)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where
-    B: PartialOrd + ToOwned, <B as ToOwned>::Owned: 'a
-{
-    #[inline]
-    fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
-        PartialOrd::partial_cmp(&**self, &**other)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where
-    B: fmt::Debug + ToOwned,
-    <B as ToOwned>::Owned: fmt::Debug,
-{
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            Borrowed(ref b) => fmt::Debug::fmt(b, f),
-            Owned(ref o) => fmt::Debug::fmt(o, f),
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where
-    B: fmt::Display + ToOwned,
-    <B as ToOwned>::Owned: fmt::Display,
-{
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            Borrowed(ref b) => fmt::Display::fmt(b, f),
-            Owned(ref o) => fmt::Display::fmt(o, f),
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, B> where
-    B: Hash<S> + ToOwned, <B as ToOwned>::Owned: 'a
-{
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        Hash::hash(&**self, state)
-    }
-}
-
-/// Trait for moving into a `Cow`
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
-    /// Moves `self` into `Cow`
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn into_cow(self) -> Cow<'a, B>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a,  B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
-    fn into_cow(self) -> Cow<'a, B> {
-        self
-    }
-}
index 7823f536c7a213a8f5f3b2b8e0c7a6a6fad81c73..adfb284dabea73562a31832c15a098fdfd84d849 100644 (file)
@@ -24,8 +24,8 @@ use core::default::Default;
 use core::fmt::Debug;
 use core::hash::{Hash, Hasher};
 use core::iter::{Map, FromIterator, IntoIterator};
-use core::ops::{Index, IndexMut};
-use core::{iter, fmt, mem};
+use core::ops::Index;
+use core::{iter, fmt, mem, usize};
 use Bound::{self, Included, Excluded, Unbounded};
 
 use borrow::Borrow;
@@ -64,6 +64,10 @@ use super::node::{self, Node, Found, GoDown};
 /// and possibly other factors. Using linear search, searching for a random element is expected
 /// to take O(B log<sub>B</sub>n) comparisons, which is generally worse than a BST. In practice,
 /// however, performance is excellent.
+///
+/// It is a logic error for a key to be modified in such a way that the key's ordering relative to
+/// any other key, as determined by the `Ord` trait, changes while it is in the map. This is
+/// normally only possible through `Cell`, `RefCell`, global state, I/O, or unsafe code.
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BTreeMap<K, V> {
@@ -74,6 +78,7 @@ pub struct BTreeMap<K, V> {
 }
 
 /// An abstract base over-which all other BTree iterators are built.
+#[derive(Clone)]
 struct AbsIter<T> {
     traversals: VecDeque<T>,
     size: usize,
@@ -120,26 +125,26 @@ pub struct RangeMut<'a, K: 'a, V: 'a> {
 }
 
 /// A view into a single entry in a map, which may either be vacant or occupied.
-#[unstable(feature = "collections",
-           reason = "precise API still under development")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub enum Entry<'a, K:'a, V:'a> {
     /// A vacant Entry
+    #[stable(feature = "rust1", since = "1.0.0")]
     Vacant(VacantEntry<'a, K, V>),
+
     /// An occupied Entry
+    #[stable(feature = "rust1", since = "1.0.0")]
     Occupied(OccupiedEntry<'a, K, V>),
 }
 
 /// A vacant Entry.
-#[unstable(feature = "collections",
-           reason = "precise API still under development")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct VacantEntry<'a, K:'a, V:'a> {
     key: K,
     stack: stack::SearchStack<'a, K, V, node::handle::Edge, node::handle::Leaf>,
 }
 
 /// An occupied Entry.
-#[unstable(feature = "collections",
-           reason = "precise API still under development")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct OccupiedEntry<'a, K:'a, V:'a> {
     stack: stack::SearchStack<'a, K, V, node::handle::KV, node::handle::LeafOrInternal>,
 }
@@ -260,7 +265,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     ///     Some(x) => *x = "b",
     ///     None => (),
     /// }
-    /// assert_eq!(map[1], "b");
+    /// assert_eq!(map[&1], "b");
     /// ```
     // See `get` for implementation notes, this is basically a copy-paste with mut's added
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -322,7 +327,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     ///
     /// map.insert(37, "b");
     /// assert_eq!(map.insert(37, "c"), Some("b"));
-    /// assert_eq!(map[37], "c");
+    /// assert_eq!(map[&37], "c");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn insert(&mut self, mut key: K, mut value: V) -> Option<V> {
@@ -347,7 +352,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
             let result = stack.with(move |pusher, node| {
                 // Same basic logic as found in `find`, but with PartialSearchStack mediating the
                 // actual nodes for us
-                return match Node::search(node, &key) {
+                match Node::search(node, &key) {
                     Found(mut handle) => {
                         // Perfect match, swap the values and return the old one
                         mem::swap(handle.val_mut(), &mut value);
@@ -372,7 +377,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
                 }
             });
             match result {
-                Finished(ret) => { return ret; },
+                Finished(ret) => return ret,
                 Continue((new_stack, renewed_key, renewed_val)) => {
                     stack = new_stack;
                     key = renewed_key;
@@ -439,7 +444,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
         let mut stack = stack::PartialSearchStack::new(self);
         loop {
             let result = stack.with(move |pusher, node| {
-                return match Node::search(node, key) {
+                match Node::search(node, key) {
                     Found(handle) => {
                         // Perfect match. Terminate the stack here, and remove the entry
                         Finished(Some(pusher.seal(handle).remove()))
@@ -852,16 +857,6 @@ impl<K: Ord, V> Extend<(K, V)> for BTreeMap<K, V> {
     }
 }
 
-#[cfg(stage0)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<S: Hasher, K: Hash<S>, V: Hash<S>> Hash<S> for BTreeMap<K, V> {
-    fn hash(&self, state: &mut S) {
-        for elt in self {
-            elt.hash(state);
-        }
-    }
-}
-#[cfg(not(stage0))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Hash, V: Hash> Hash for BTreeMap<K, V> {
     fn hash<H: Hasher>(&self, state: &mut H) {
@@ -909,37 +904,22 @@ impl<K: Ord, V: Ord> Ord for BTreeMap<K, V> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Debug, V: Debug> Debug for BTreeMap<K, V> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "BTreeMap {{"));
-
-        for (i, (k, v)) in self.iter().enumerate() {
-            if i != 0 { try!(write!(f, ", ")); }
-            try!(write!(f, "{:?}: {:?}", *k, *v));
-        }
-
-        write!(f, "}}")
+        self.iter().fold(f.debug_map(), |b, (k, v)| b.entry(k, v)).finish()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, V>
+impl<'a, K: Ord, Q: ?Sized, V> Index<&'a Q> for BTreeMap<K, V>
     where K: Borrow<Q>, Q: Ord
 {
     type Output = V;
 
+    #[inline]
     fn index(&self, key: &Q) -> &V {
         self.get(key).expect("no entry found for key")
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K: Ord, Q: ?Sized, V> IndexMut<Q> for BTreeMap<K, V>
-    where K: Borrow<Q>, Q: Ord
-{
-    fn index_mut(&mut self, key: &Q) -> &mut V {
-        self.get_mut(key).expect("no entry found for key")
-    }
-}
-
 /// Genericises over how to get the correct type of iterator from the correct type
 /// of Node ownership.
 trait Traverse<N> {
@@ -1040,6 +1020,9 @@ impl<K, V, E, T> DoubleEndedIterator for AbsIter<T> where
     }
 }
 
+impl<'a, K, V> Clone for Iter<'a, K, V> {
+    fn clone(&self) -> Iter<'a, K, V> { Iter { inner: self.inner.clone() } }
+}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, K, V> Iterator for Iter<'a, K, V> {
     type Item = (&'a K, &'a V);
@@ -1082,6 +1065,9 @@ impl<K, V> DoubleEndedIterator for IntoIter<K, V> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K, V> ExactSizeIterator for IntoIter<K, V> {}
 
+impl<'a, K, V> Clone for Keys<'a, K, V> {
+    fn clone(&self) -> Keys<'a, K, V> { Keys { inner: self.inner.clone() } }
+}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, K, V> Iterator for Keys<'a, K, V> {
     type Item = &'a K;
@@ -1097,6 +1083,9 @@ impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> {
 impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {}
 
 
+impl<'a, K, V> Clone for Values<'a, K, V> {
+    fn clone(&self) -> Values<'a, K, V> { Values { inner: self.inner.clone() } }
+}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, K, V> Iterator for Values<'a, K, V> {
     type Item = &'a V;
@@ -1111,6 +1100,9 @@ impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {}
 
+impl<'a, K, V> Clone for Range<'a, K, V> {
+    fn clone(&self) -> Range<'a, K, V> { Range { inner: self.inner.clone() } }
+}
 impl<'a, K, V> Iterator for Range<'a, K, V> {
     type Item = (&'a K, &'a V);
 
@@ -1130,8 +1122,10 @@ impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> {
 }
 
 impl<'a, K: Ord, V> Entry<'a, K, V> {
-    #[unstable(feature = "collections",
-               reason = "matches collection reform v2 specification, waiting for dust to settle")]
+    #[unstable(feature = "std_misc",
+               reason = "will soon be replaced by or_insert")]
+    #[deprecated(since = "1.0",
+                reason = "replaced with more ergonomic `or_insert` and `or_insert_with`")]
     /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
     pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> {
         match self {
@@ -1139,6 +1133,26 @@ impl<'a, K: Ord, V> Entry<'a, K, V> {
             Vacant(entry) => Err(entry),
         }
     }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    /// Ensures a value is in the entry by inserting the default if empty, and returns
+    /// a mutable reference to the value in the entry.
+    pub fn or_insert(self, default: V) -> &'a mut V {
+        match self {
+            Occupied(entry) => entry.into_mut(),
+            Vacant(entry) => entry.insert(default),
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    /// Ensures a value is in the entry by inserting the result of the default function if empty,
+    /// and returns a mutable reference to the value in the entry.
+    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
+        match self {
+            Occupied(entry) => entry.into_mut(),
+            Vacant(entry) => entry.insert(default()),
+        }
+    }
 }
 
 impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
@@ -1187,7 +1201,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
 impl<K, V> BTreeMap<K, V> {
     /// Gets an iterator over the entries of the map.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::BTreeMap;
@@ -1284,6 +1298,7 @@ impl<K, V> BTreeMap<K, V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::BTreeMap;
     ///
     /// let mut a = BTreeMap::new();
@@ -1291,7 +1306,7 @@ impl<K, V> BTreeMap<K, V> {
     /// a.insert(2, "b");
     ///
     /// let keys: Vec<usize> = a.keys().cloned().collect();
-    /// assert_eq!(keys, vec![1,2,]);
+    /// assert_eq!(keys, [1, 2]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
@@ -1306,6 +1321,7 @@ impl<K, V> BTreeMap<K, V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::BTreeMap;
     ///
     /// let mut a = BTreeMap::new();
@@ -1313,7 +1329,7 @@ impl<K, V> BTreeMap<K, V> {
     /// a.insert(2, "b");
     ///
     /// let values: Vec<&str> = a.values().cloned().collect();
-    /// assert_eq!(values, vec!["a","b"]);
+    /// assert_eq!(values, ["a", "b"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn values<'a>(&'a self) -> Values<'a, K, V> {
@@ -1477,7 +1493,7 @@ macro_rules! range_impl {
             $Range {
                 inner: AbsIter {
                     traversals: traversals,
-                    size: 0, // unused
+                    size: usize::MAX, // unused
                 }
             }
         }
@@ -1493,6 +1509,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BTreeMap;
     /// use std::collections::Bound::{Included, Unbounded};
     ///
@@ -1519,6 +1536,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BTreeMap;
     /// use std::collections::Bound::{Included, Excluded};
     ///
@@ -1544,22 +1562,14 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BTreeMap;
-    /// use std::collections::btree_map::Entry;
     ///
     /// let mut count: BTreeMap<&str, usize> = BTreeMap::new();
     ///
     /// // count the number of occurrences of letters in the vec
-    /// for x in vec!["a","b","a","c","a","b"].iter() {
-    ///     match count.entry(*x) {
-    ///         Entry::Vacant(view) => {
-    ///             view.insert(1);
-    ///         },
-    ///         Entry::Occupied(mut view) => {
-    ///             let v = view.get_mut();
-    ///             *v += 1;
-    ///         },
-    ///     }
+    /// for x in vec!["a","b","a","c","a","b"] {
+    ///     *count.entry(x).or_insert(0) += 1;
     /// }
     ///
     /// assert_eq!(count["a"], 3);
@@ -1570,7 +1580,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
         let mut stack = stack::PartialSearchStack::new(self);
         loop {
             let result = stack.with(move |pusher, node| {
-                return match Node::search(node, &key) {
+                match Node::search(node, &key) {
                     Found(handle) => {
                         // Perfect match
                         Finished(Occupied(OccupiedEntry {
@@ -1605,309 +1615,3 @@ impl<K: Ord, V> BTreeMap<K, V> {
         }
     }
 }
-
-
-
-
-
-#[cfg(test)]
-mod test {
-    use prelude::*;
-    use std::iter::range_inclusive;
-
-    use super::BTreeMap;
-    use super::Entry::{Occupied, Vacant};
-    use Bound::{self, Included, Excluded, Unbounded};
-
-    #[test]
-    fn test_basic_large() {
-        let mut map = BTreeMap::new();
-        let size = 10000;
-        assert_eq!(map.len(), 0);
-
-        for i in 0..size {
-            assert_eq!(map.insert(i, 10*i), None);
-            assert_eq!(map.len(), i + 1);
-        }
-
-        for i in 0..size {
-            assert_eq!(map.get(&i).unwrap(), &(i*10));
-        }
-
-        for i in size..size*2 {
-            assert_eq!(map.get(&i), None);
-        }
-
-        for i in 0..size {
-            assert_eq!(map.insert(i, 100*i), Some(10*i));
-            assert_eq!(map.len(), size);
-        }
-
-        for i in 0..size {
-            assert_eq!(map.get(&i).unwrap(), &(i*100));
-        }
-
-        for i in 0..size/2 {
-            assert_eq!(map.remove(&(i*2)), Some(i*200));
-            assert_eq!(map.len(), size - i - 1);
-        }
-
-        for i in 0..size/2 {
-            assert_eq!(map.get(&(2*i)), None);
-            assert_eq!(map.get(&(2*i+1)).unwrap(), &(i*200 + 100));
-        }
-
-        for i in 0..size/2 {
-            assert_eq!(map.remove(&(2*i)), None);
-            assert_eq!(map.remove(&(2*i+1)), Some(i*200 + 100));
-            assert_eq!(map.len(), size/2 - i - 1);
-        }
-    }
-
-    #[test]
-    fn test_basic_small() {
-        let mut map = BTreeMap::new();
-        assert_eq!(map.remove(&1), None);
-        assert_eq!(map.get(&1), None);
-        assert_eq!(map.insert(1, 1), None);
-        assert_eq!(map.get(&1), Some(&1));
-        assert_eq!(map.insert(1, 2), Some(1));
-        assert_eq!(map.get(&1), Some(&2));
-        assert_eq!(map.insert(2, 4), None);
-        assert_eq!(map.get(&2), Some(&4));
-        assert_eq!(map.remove(&1), Some(2));
-        assert_eq!(map.remove(&2), Some(4));
-        assert_eq!(map.remove(&1), None);
-    }
-
-    #[test]
-    fn test_iter() {
-        let size = 10000;
-
-        // Forwards
-        let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-        fn test<T>(size: usize, mut iter: T) where T: Iterator<Item=(usize, usize)> {
-            for i in 0..size {
-                assert_eq!(iter.size_hint(), (size - i, Some(size - i)));
-                assert_eq!(iter.next().unwrap(), (i, i));
-            }
-            assert_eq!(iter.size_hint(), (0, Some(0)));
-            assert_eq!(iter.next(), None);
-        }
-        test(size, map.iter().map(|(&k, &v)| (k, v)));
-        test(size, map.iter_mut().map(|(&k, &mut v)| (k, v)));
-        test(size, map.into_iter());
-    }
-
-    #[test]
-    fn test_iter_rev() {
-        let size = 10000;
-
-        // Forwards
-        let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-        fn test<T>(size: usize, mut iter: T) where T: Iterator<Item=(usize, usize)> {
-            for i in 0..size {
-                assert_eq!(iter.size_hint(), (size - i, Some(size - i)));
-                assert_eq!(iter.next().unwrap(), (size - i - 1, size - i - 1));
-            }
-            assert_eq!(iter.size_hint(), (0, Some(0)));
-            assert_eq!(iter.next(), None);
-        }
-        test(size, map.iter().rev().map(|(&k, &v)| (k, v)));
-        test(size, map.iter_mut().rev().map(|(&k, &mut v)| (k, v)));
-        test(size, map.into_iter().rev());
-    }
-
-    #[test]
-    fn test_iter_mixed() {
-        let size = 10000;
-
-        // Forwards
-        let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-        fn test<T>(size: usize, mut iter: T)
-                where T: Iterator<Item=(usize, usize)> + DoubleEndedIterator {
-            for i in 0..size / 4 {
-                assert_eq!(iter.size_hint(), (size - i * 2, Some(size - i * 2)));
-                assert_eq!(iter.next().unwrap(), (i, i));
-                assert_eq!(iter.next_back().unwrap(), (size - i - 1, size - i - 1));
-            }
-            for i in size / 4..size * 3 / 4 {
-                assert_eq!(iter.size_hint(), (size * 3 / 4 - i, Some(size * 3 / 4 - i)));
-                assert_eq!(iter.next().unwrap(), (i, i));
-            }
-            assert_eq!(iter.size_hint(), (0, Some(0)));
-            assert_eq!(iter.next(), None);
-        }
-        test(size, map.iter().map(|(&k, &v)| (k, v)));
-        test(size, map.iter_mut().map(|(&k, &mut v)| (k, v)));
-        test(size, map.into_iter());
-    }
-
-    #[test]
-    fn test_range_small() {
-        let size = 5;
-
-        // Forwards
-        let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-        let mut j = 0;
-        for ((&k, &v), i) in map.range(Included(&2), Unbounded).zip(2..size) {
-            assert_eq!(k, i);
-            assert_eq!(v, i);
-            j += 1;
-        }
-        assert_eq!(j, size - 2);
-    }
-
-    #[test]
-    fn test_range_1000() {
-        let size = 1000;
-        let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-        fn test(map: &BTreeMap<u32, u32>, size: u32, min: Bound<&u32>, max: Bound<&u32>) {
-            let mut kvs = map.range(min, max).map(|(&k, &v)| (k, v));
-            let mut pairs = (0..size).map(|i| (i, i));
-
-            for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
-                assert_eq!(kv, pair);
-            }
-            assert_eq!(kvs.next(), None);
-            assert_eq!(pairs.next(), None);
-        }
-        test(&map, size, Included(&0), Excluded(&size));
-        test(&map, size, Unbounded, Excluded(&size));
-        test(&map, size, Included(&0), Included(&(size - 1)));
-        test(&map, size, Unbounded, Included(&(size - 1)));
-        test(&map, size, Included(&0), Unbounded);
-        test(&map, size, Unbounded, Unbounded);
-    }
-
-    #[test]
-    fn test_range() {
-        let size = 200;
-        let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-        for i in 0..size {
-            for j in i..size {
-                let mut kvs = map.range(Included(&i), Included(&j)).map(|(&k, &v)| (k, v));
-                let mut pairs = range_inclusive(i, j).map(|i| (i, i));
-
-                for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
-                    assert_eq!(kv, pair);
-                }
-                assert_eq!(kvs.next(), None);
-                assert_eq!(pairs.next(), None);
-            }
-        }
-    }
-
-    #[test]
-    fn test_entry(){
-        let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
-
-        let mut map: BTreeMap<_, _> = xs.iter().cloned().collect();
-
-        // Existing key (insert)
-        match map.entry(1) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                assert_eq!(view.get(), &10);
-                assert_eq!(view.insert(100), 10);
-            }
-        }
-        assert_eq!(map.get(&1).unwrap(), &100);
-        assert_eq!(map.len(), 6);
-
-
-        // Existing key (update)
-        match map.entry(2) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                let v = view.get_mut();
-                *v *= 10;
-            }
-        }
-        assert_eq!(map.get(&2).unwrap(), &200);
-        assert_eq!(map.len(), 6);
-
-        // Existing key (take)
-        match map.entry(3) {
-            Vacant(_) => unreachable!(),
-            Occupied(view) => {
-                assert_eq!(view.remove(), 30);
-            }
-        }
-        assert_eq!(map.get(&3), None);
-        assert_eq!(map.len(), 5);
-
-
-        // Inexistent key (insert)
-        match map.entry(10) {
-            Occupied(_) => unreachable!(),
-            Vacant(view) => {
-                assert_eq!(*view.insert(1000), 1000);
-            }
-        }
-        assert_eq!(map.get(&10).unwrap(), &1000);
-        assert_eq!(map.len(), 6);
-    }
-}
-
-
-
-
-
-
-#[cfg(test)]
-mod bench {
-    use prelude::*;
-    use std::rand::{weak_rng, Rng};
-    use test::{Bencher, black_box};
-
-    use super::BTreeMap;
-
-    map_insert_rand_bench!{insert_rand_100,    100,    BTreeMap}
-    map_insert_rand_bench!{insert_rand_10_000, 10_000, BTreeMap}
-
-    map_insert_seq_bench!{insert_seq_100,    100,    BTreeMap}
-    map_insert_seq_bench!{insert_seq_10_000, 10_000, BTreeMap}
-
-    map_find_rand_bench!{find_rand_100,    100,    BTreeMap}
-    map_find_rand_bench!{find_rand_10_000, 10_000, BTreeMap}
-
-    map_find_seq_bench!{find_seq_100,    100,    BTreeMap}
-    map_find_seq_bench!{find_seq_10_000, 10_000, BTreeMap}
-
-    fn bench_iter(b: &mut Bencher, size: i32) {
-        let mut map = BTreeMap::<i32, i32>::new();
-        let mut rng = weak_rng();
-
-        for _ in 0..size {
-            map.insert(rng.gen(), rng.gen());
-        }
-
-        b.iter(|| {
-            for entry in &map {
-                black_box(entry);
-            }
-        });
-    }
-
-    #[bench]
-    pub fn iter_20(b: &mut Bencher) {
-        bench_iter(b, 20);
-    }
-
-    #[bench]
-    pub fn iter_1000(b: &mut Bencher) {
-        bench_iter(b, 1000);
-    }
-
-    #[bench]
-    pub fn iter_100000(b: &mut Bencher) {
-        bench_iter(b, 100000);
-    }
-}
index f0fc12da7275e000d814d796db75a0f58c2a48f2..26c57256049cb87553ccb5a660893b81c6c8d4b1 100644 (file)
@@ -23,7 +23,7 @@ use core::iter::Zip;
 use core::marker::PhantomData;
 use core::ops::{Deref, DerefMut, Index, IndexMut};
 use core::ptr::Unique;
-use core::{slice, mem, ptr, cmp, num, raw};
+use core::{slice, mem, ptr, cmp, raw};
 use alloc::heap::{self, EMPTY};
 
 use borrow::Borrow;
@@ -105,7 +105,7 @@ struct MutNodeSlice<'a, K: 'a, V: 'a> {
 /// Fails if `target_alignment` is not a power of two.
 #[inline]
 fn round_up_to_next(unrounded: usize, target_alignment: usize) -> usize {
-    assert!(num::UnsignedInt::is_power_of_two(target_alignment));
+    assert!(target_alignment.is_power_of_two());
     (unrounded + target_alignment - 1) & !(target_alignment - 1)
 }
 
@@ -280,9 +280,11 @@ impl<T> Drop for RawItems<T> {
 #[unsafe_destructor]
 impl<K, V> Drop for Node<K, V> {
     fn drop(&mut self) {
-        if self.keys.is_null() {
+        if self.keys.is_null() ||
+            (unsafe { self.keys.get() as *const K as usize == mem::POST_DROP_USIZE })
+        {
             // Since we have #[unsafe_no_drop_flag], we have to watch
-            // out for a null value being stored in self.keys. (Using
+            // out for the sentinel value being stored in self.keys. (Using
             // null is technically a violation of the `Unique`
             // requirements, though.)
             return;
@@ -348,14 +350,8 @@ impl<K, V> Node<K, V> {
     #[inline]
     pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) {
         unsafe {(
-            mem::transmute(raw::Slice {
-                data: *self.keys as *const K,
-                len: self.len()
-            }),
-            mem::transmute(raw::Slice {
-                data: *self.vals as *const V,
-                len: self.len()
-            })
+            slice::from_raw_parts(*self.keys, self.len()),
+            slice::from_raw_parts(*self.vals, self.len()),
         )}
     }
 
@@ -530,7 +526,7 @@ impl<K: Clone, V: Clone> Clone for Node<K, V> {
 ///     println!("Uninitialized memory: {:?}", handle.into_kv());
 /// }
 /// ```
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Handle<NodeRef, Type, NodeType> {
     node: NodeRef,
     index: usize,
@@ -1085,7 +1081,7 @@ impl<K, V> Node<K, V> {
                     vals: RawItems::from_slice(self.vals()),
                     edges: RawItems::from_slice(self.edges()),
 
-                    ptr: *self.keys as *mut u8,
+                    ptr: Unique::new(*self.keys as *mut u8),
                     capacity: self.capacity(),
                     is_leaf: self.is_leaf()
                 },
@@ -1136,14 +1132,14 @@ impl<K, V> Node<K, V> {
     // This must be followed by insert_edge on an internal node.
     #[inline]
     unsafe fn insert_kv(&mut self, index: usize, key: K, val: V) -> &mut V {
-        ptr::copy_memory(
-            self.keys_mut().as_mut_ptr().offset(index as isize + 1),
+        ptr::copy(
             self.keys().as_ptr().offset(index as isize),
+            self.keys_mut().as_mut_ptr().offset(index as isize + 1),
             self.len() - index
         );
-        ptr::copy_memory(
-            self.vals_mut().as_mut_ptr().offset(index as isize + 1),
+        ptr::copy(
             self.vals().as_ptr().offset(index as isize),
+            self.vals_mut().as_mut_ptr().offset(index as isize + 1),
             self.len() - index
         );
 
@@ -1158,9 +1154,9 @@ impl<K, V> Node<K, V> {
     // This can only be called immediately after a call to insert_kv.
     #[inline]
     unsafe fn insert_edge(&mut self, index: usize, edge: Node<K, V>) {
-        ptr::copy_memory(
-            self.edges_mut().as_mut_ptr().offset(index as isize + 1),
+        ptr::copy(
             self.edges().as_ptr().offset(index as isize),
+            self.edges_mut().as_mut_ptr().offset(index as isize + 1),
             self.len() - index
         );
         ptr::write(self.edges_mut().get_unchecked_mut(index), edge);
@@ -1191,14 +1187,14 @@ impl<K, V> Node<K, V> {
         let key = ptr::read(self.keys().get_unchecked(index));
         let val = ptr::read(self.vals().get_unchecked(index));
 
-        ptr::copy_memory(
-            self.keys_mut().as_mut_ptr().offset(index as isize),
+        ptr::copy(
             self.keys().as_ptr().offset(index as isize + 1),
+            self.keys_mut().as_mut_ptr().offset(index as isize),
             self.len() - index - 1
         );
-        ptr::copy_memory(
-            self.vals_mut().as_mut_ptr().offset(index as isize),
+        ptr::copy(
             self.vals().as_ptr().offset(index as isize + 1),
+            self.vals_mut().as_mut_ptr().offset(index as isize),
             self.len() - index - 1
         );
 
@@ -1212,10 +1208,11 @@ impl<K, V> Node<K, V> {
     unsafe fn remove_edge(&mut self, index: usize) -> Node<K, V> {
         let edge = ptr::read(self.edges().get_unchecked(index));
 
-        ptr::copy_memory(
-            self.edges_mut().as_mut_ptr().offset(index as isize),
+        ptr::copy(
             self.edges().as_ptr().offset(index as isize + 1),
-            self.len() - index + 1
+            self.edges_mut().as_mut_ptr().offset(index as isize),
+            // index can be == len+1, so do the +1 first to avoid underflow.
+            (self.len() + 1) - index
         );
 
         edge
@@ -1239,20 +1236,20 @@ impl<K, V> Node<K, V> {
         unsafe {
             right._len = self.len() / 2;
             let right_offset = self.len() - right.len();
-            ptr::copy_nonoverlapping_memory(
-                right.keys_mut().as_mut_ptr(),
+            ptr::copy_nonoverlapping(
                 self.keys().as_ptr().offset(right_offset as isize),
+                right.keys_mut().as_mut_ptr(),
                 right.len()
             );
-            ptr::copy_nonoverlapping_memory(
-                right.vals_mut().as_mut_ptr(),
+            ptr::copy_nonoverlapping(
                 self.vals().as_ptr().offset(right_offset as isize),
+                right.vals_mut().as_mut_ptr(),
                 right.len()
             );
             if !self.is_leaf() {
-                ptr::copy_nonoverlapping_memory(
-                    right.edges_mut().as_mut_ptr(),
+                ptr::copy_nonoverlapping(
                     self.edges().as_ptr().offset(right_offset as isize),
+                    right.edges_mut().as_mut_ptr(),
                     right.len() + 1
                 );
             }
@@ -1280,20 +1277,20 @@ impl<K, V> Node<K, V> {
             ptr::write(self.keys_mut().get_unchecked_mut(old_len), key);
             ptr::write(self.vals_mut().get_unchecked_mut(old_len), val);
 
-            ptr::copy_nonoverlapping_memory(
-                self.keys_mut().as_mut_ptr().offset(old_len as isize + 1),
+            ptr::copy_nonoverlapping(
                 right.keys().as_ptr(),
+                self.keys_mut().as_mut_ptr().offset(old_len as isize + 1),
                 right.len()
             );
-            ptr::copy_nonoverlapping_memory(
-                self.vals_mut().as_mut_ptr().offset(old_len as isize + 1),
+            ptr::copy_nonoverlapping(
                 right.vals().as_ptr(),
+                self.vals_mut().as_mut_ptr().offset(old_len as isize + 1),
                 right.len()
             );
             if !self.is_leaf() {
-                ptr::copy_nonoverlapping_memory(
-                    self.edges_mut().as_mut_ptr().offset(old_len as isize + 1),
+                ptr::copy_nonoverlapping(
                     right.edges().as_ptr(),
+                    self.edges_mut().as_mut_ptr().offset(old_len as isize + 1),
                     right.len() + 1
                 );
             }
@@ -1331,6 +1328,7 @@ trait TraversalImpl {
 
 /// A `TraversalImpl` that actually is backed by two iterators. This works in the non-moving case,
 /// as no deallocation needs to be done.
+#[derive(Clone)]
 struct ElemsAndEdges<Elems, Edges>(Elems, Edges);
 
 impl<K, V, E, Elems: DoubleEndedIterator, Edges: DoubleEndedIterator>
@@ -1354,11 +1352,14 @@ struct MoveTraversalImpl<K, V> {
     edges: RawItems<Node<K, V>>,
 
     // For deallocation when we are done iterating.
-    ptr: *mut u8,
+    ptr: Unique<u8>,
     capacity: usize,
     is_leaf: bool
 }
 
+unsafe impl<K: Sync, V: Sync> Sync for MoveTraversalImpl<K, V> {}
+unsafe impl<K: Send, V: Send> Send for MoveTraversalImpl<K, V> {}
+
 impl<K, V> TraversalImpl for MoveTraversalImpl<K, V> {
     type Item = (K, V);
     type Edge = Node<K, V>;
@@ -1401,11 +1402,12 @@ impl<K, V> Drop for MoveTraversalImpl<K, V> {
 
         let (alignment, size) =
                 calculate_allocation_generic::<K, V>(self.capacity, self.is_leaf);
-        unsafe { heap::deallocate(self.ptr, size, alignment) };
+        unsafe { heap::deallocate(*self.ptr, size, alignment) };
     }
 }
 
 /// An abstraction over all the different kinds of traversals a node supports
+#[derive(Clone)]
 struct AbsTraversal<Impl> {
     inner: Impl,
     head_is_edge: bool,
@@ -1425,12 +1427,12 @@ pub enum TraversalItem<K, V, E> {
 /// A traversal over a node's entries and edges
 pub type Traversal<'a, K, V> = AbsTraversal<ElemsAndEdges<Zip<slice::Iter<'a, K>,
                                                               slice::Iter<'a, V>>,
-                                                              slice::Iter<'a, Node<K, V>>>>;
+                                                          slice::Iter<'a, Node<K, V>>>>;
 
 /// A mutable traversal over a node's entries and edges
 pub type MutTraversal<'a, K, V> = AbsTraversal<ElemsAndEdges<Zip<slice::Iter<'a, K>,
                                                                  slice::IterMut<'a, V>>,
-                                                                 slice::IterMut<'a, Node<K, V>>>>;
+                                                             slice::IterMut<'a, Node<K, V>>>>;
 
 /// An owning traversal over a node's entries and edges
 pub type MoveTraversal<K, V> = AbsTraversal<MoveTraversalImpl<K, V>>;
@@ -1542,10 +1544,10 @@ macro_rules! node_slice_impl {
                     edges: if !self.has_edges {
                         self.edges
                     } else {
-                        self.edges.$index(&(pos ..))
+                        self.edges.$index(pos ..)
                     },
                     keys: &self.keys[pos ..],
-                    vals: self.vals.$index(&(pos ..)),
+                    vals: self.vals.$index(pos ..),
                     head_is_edge: !pos_is_kv,
                     tail_is_edge: self.tail_is_edge,
                 }
@@ -1571,10 +1573,10 @@ macro_rules! node_slice_impl {
                     edges: if !self.has_edges {
                         self.edges
                     } else {
-                        self.edges.$index(&(.. (pos + 1)))
+                        self.edges.$index(.. (pos + 1))
                     },
                     keys: &self.keys[..pos],
-                    vals: self.vals.$index(&(.. pos)),
+                    vals: self.vals.$index(.. pos),
                     head_is_edge: self.head_is_edge,
                     tail_is_edge: !pos_is_kv,
                 }
index 929b2f58043035105097de82e38a1702575f2477..840110b5b276fffc7822d69d345db5e7ed9894d9 100644 (file)
@@ -30,6 +30,10 @@ use Bound;
 ///
 /// See BTreeMap's documentation for a detailed discussion of this collection's performance
 /// benefits and drawbacks.
+///
+/// It is a logic error for an item to be modified in such a way that the item's ordering relative
+/// to any other item, as determined by the `Ord` trait, changes while it is in the set. This is
+/// normally only possible through `Cell`, `RefCell`, global state, I/O, or unsafe code.
 #[derive(Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BTreeSet<T>{
@@ -112,6 +116,7 @@ impl<T> BTreeSet<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::BTreeSet;
     ///
     /// let set: BTreeSet<usize> = [1, 2, 3, 4].iter().cloned().collect();
@@ -121,7 +126,7 @@ impl<T> BTreeSet<T> {
     /// }
     ///
     /// let v: Vec<usize> = set.iter().cloned().collect();
-    /// assert_eq!(v, vec![1,2,3,4]);
+    /// assert_eq!(v, [1, 2, 3, 4]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter(&self) -> Iter<T> {
@@ -133,12 +138,13 @@ impl<T> BTreeSet<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::BTreeSet;
     ///
     /// let set: BTreeSet<usize> = [1, 2, 3, 4].iter().cloned().collect();
     ///
     /// let v: Vec<usize> = set.into_iter().collect();
-    /// assert_eq!(v, vec![1,2,3,4]);
+    /// assert_eq!(v, [1, 2, 3, 4]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_iter(self) -> IntoIter<T> {
@@ -158,6 +164,7 @@ impl<T: Ord> BTreeSet<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::BTreeSet;
     /// use std::collections::Bound::{Included, Unbounded};
     ///
@@ -186,6 +193,7 @@ impl<T: Ord> BTreeSet<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::BTreeSet;
     ///
     /// let mut a = BTreeSet::new();
@@ -197,7 +205,7 @@ impl<T: Ord> BTreeSet<T> {
     /// b.insert(3);
     ///
     /// let diff: Vec<usize> = a.difference(&b).cloned().collect();
-    /// assert_eq!(diff, vec![1]);
+    /// assert_eq!(diff, [1]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn difference<'a>(&'a self, other: &'a BTreeSet<T>) -> Difference<'a, T> {
@@ -209,6 +217,7 @@ impl<T: Ord> BTreeSet<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::BTreeSet;
     ///
     /// let mut a = BTreeSet::new();
@@ -220,7 +229,7 @@ impl<T: Ord> BTreeSet<T> {
     /// b.insert(3);
     ///
     /// let sym_diff: Vec<usize> = a.symmetric_difference(&b).cloned().collect();
-    /// assert_eq!(sym_diff, vec![1,3]);
+    /// assert_eq!(sym_diff, [1, 3]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn symmetric_difference<'a>(&'a self, other: &'a BTreeSet<T>)
@@ -233,6 +242,7 @@ impl<T: Ord> BTreeSet<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::BTreeSet;
     ///
     /// let mut a = BTreeSet::new();
@@ -244,7 +254,7 @@ impl<T: Ord> BTreeSet<T> {
     /// b.insert(3);
     ///
     /// let intersection: Vec<usize> = a.intersection(&b).cloned().collect();
-    /// assert_eq!(intersection, vec![2]);
+    /// assert_eq!(intersection, [2]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn intersection<'a>(&'a self, other: &'a BTreeSet<T>)
@@ -257,6 +267,7 @@ impl<T: Ord> BTreeSet<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::BTreeSet;
     ///
     /// let mut a = BTreeSet::new();
@@ -266,7 +277,7 @@ impl<T: Ord> BTreeSet<T> {
     /// b.insert(2);
     ///
     /// let union: Vec<usize> = a.union(&b).cloned().collect();
-    /// assert_eq!(union, vec![1,2]);
+    /// assert_eq!(union, [1, 2]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn union<'a>(&'a self, other: &'a BTreeSet<T>) -> Union<'a, T> {
@@ -329,6 +340,7 @@ impl<T: Ord> BTreeSet<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::BTreeSet;
     ///
     /// let set: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
@@ -346,6 +358,7 @@ impl<T: Ord> BTreeSet<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::BTreeSet;
     ///
     /// let a: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
@@ -367,6 +380,7 @@ impl<T: Ord> BTreeSet<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::BTreeSet;
     ///
     /// let sup: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
@@ -409,6 +423,7 @@ impl<T: Ord> BTreeSet<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::BTreeSet;
     ///
     /// let sub: BTreeSet<_> = [1, 2].iter().cloned().collect();
@@ -534,7 +549,7 @@ impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet<T>> for &'a BTreeSet<T> {
     ///
     /// let result = &a - &b;
     /// let result_vec: Vec<_> = result.into_iter().collect();
-    /// assert_eq!(result_vec, vec![1, 2]);
+    /// assert_eq!(result_vec, [1, 2]);
     /// ```
     fn sub(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
         self.difference(rhs).cloned().collect()
@@ -557,7 +572,7 @@ impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet<T>> for &'a BTreeSet<T> {
     ///
     /// let result = &a ^ &b;
     /// let result_vec: Vec<_> = result.into_iter().collect();
-    /// assert_eq!(result_vec, vec![1, 4]);
+    /// assert_eq!(result_vec, [1, 4]);
     /// ```
     fn bitxor(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
         self.symmetric_difference(rhs).cloned().collect()
@@ -580,7 +595,7 @@ impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet<T>> for &'a BTreeSet<T> {
     ///
     /// let result = &a & &b;
     /// let result_vec: Vec<_> = result.into_iter().collect();
-    /// assert_eq!(result_vec, vec![2, 3]);
+    /// assert_eq!(result_vec, [2, 3]);
     /// ```
     fn bitand(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
         self.intersection(rhs).cloned().collect()
@@ -603,7 +618,7 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet<T>> for &'a BTreeSet<T> {
     ///
     /// let result = &a | &b;
     /// let result_vec: Vec<_> = result.into_iter().collect();
-    /// assert_eq!(result_vec, vec![1, 2, 3, 4, 5]);
+    /// assert_eq!(result_vec, [1, 2, 3, 4, 5]);
     /// ```
     fn bitor(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
         self.union(rhs).cloned().collect()
@@ -613,17 +628,13 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet<T>> for &'a BTreeSet<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Debug> Debug for BTreeSet<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "BTreeSet {{"));
-
-        for (i, x) in self.iter().enumerate() {
-            if i != 0 { try!(write!(f, ", ")); }
-            try!(write!(f, "{:?}", *x));
-        }
-
-        write!(f, "}}")
+        self.iter().fold(f.debug_set(), |b, e| b.entry(e)).finish()
     }
 }
 
+impl<'a, T> Clone for Iter<'a, T> {
+    fn clone(&self) -> Iter<'a, T> { Iter { iter: self.iter.clone() } }
+}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Iterator for Iter<'a, T> {
     type Item = &'a T;
@@ -654,6 +665,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
 impl<T> ExactSizeIterator for IntoIter<T> {}
 
 
+impl<'a, T> Clone for Range<'a, T> {
+    fn clone(&self) -> Range<'a, T> { Range { iter: self.iter.clone() } }
+}
 impl<'a, T> Iterator for Range<'a, T> {
     type Item = &'a T;
 
@@ -673,6 +687,11 @@ fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>,
     }
 }
 
+impl<'a, T> Clone for Difference<'a, T> {
+    fn clone(&self) -> Difference<'a, T> {
+        Difference { a: self.a.clone(), b: self.b.clone() }
+    }
+}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: Ord> Iterator for Difference<'a, T> {
     type Item = &'a T;
@@ -688,6 +707,11 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> {
     }
 }
 
+impl<'a, T> Clone for SymmetricDifference<'a, T> {
+    fn clone(&self) -> SymmetricDifference<'a, T> {
+        SymmetricDifference { a: self.a.clone(), b: self.b.clone() }
+    }
+}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
     type Item = &'a T;
@@ -703,6 +727,11 @@ impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
     }
 }
 
+impl<'a, T> Clone for Intersection<'a, T> {
+    fn clone(&self) -> Intersection<'a, T> {
+        Intersection { a: self.a.clone(), b: self.b.clone() }
+    }
+}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: Ord> Iterator for Intersection<'a, T> {
     type Item = &'a T;
@@ -724,6 +753,11 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
     }
 }
 
+impl<'a, T> Clone for Union<'a, T> {
+    fn clone(&self) -> Union<'a, T> {
+        Union { a: self.a.clone(), b: self.b.clone() }
+    }
+}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: Ord> Iterator for Union<'a, T> {
     type Item = &'a T;
@@ -738,180 +772,3 @@ impl<'a, T: Ord> Iterator for Union<'a, T> {
         }
     }
 }
-
-
-#[cfg(test)]
-mod test {
-    use prelude::*;
-
-    use super::BTreeSet;
-    use std::hash::{self, SipHasher};
-
-    #[test]
-    fn test_clone_eq() {
-      let mut m = BTreeSet::new();
-
-      m.insert(1);
-      m.insert(2);
-
-      assert!(m.clone() == m);
-    }
-
-    #[test]
-    fn test_hash() {
-      let mut x = BTreeSet::new();
-      let mut y = BTreeSet::new();
-
-      x.insert(1);
-      x.insert(2);
-      x.insert(3);
-
-      y.insert(3);
-      y.insert(2);
-      y.insert(1);
-
-      assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
-    }
-
-    struct Counter<'a, 'b> {
-        i: &'a mut usize,
-        expected: &'b [i32],
-    }
-
-    impl<'a, 'b, 'c> FnMut<(&'c i32,)> for Counter<'a, 'b> {
-        type Output = bool;
-
-        extern "rust-call" fn call_mut(&mut self, (&x,): (&'c i32,)) -> bool {
-            assert_eq!(x, self.expected[*self.i]);
-            *self.i += 1;
-            true
-        }
-    }
-
-    fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) where
-        // FIXME Replace Counter with `Box<FnMut(_) -> _>`
-        F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, Counter) -> bool,
-    {
-        let mut set_a = BTreeSet::new();
-        let mut set_b = BTreeSet::new();
-
-        for x in a { assert!(set_a.insert(*x)) }
-        for y in b { assert!(set_b.insert(*y)) }
-
-        let mut i = 0;
-        f(&set_a, &set_b, Counter { i: &mut i, expected: expected });
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_intersection() {
-        fn check_intersection(a: &[i32], b: &[i32], expected: &[i32]) {
-            check(a, b, expected, |x, y, f| x.intersection(y).all(f))
-        }
-
-        check_intersection(&[], &[], &[]);
-        check_intersection(&[1, 2, 3], &[], &[]);
-        check_intersection(&[], &[1, 2, 3], &[]);
-        check_intersection(&[2], &[1, 2, 3], &[2]);
-        check_intersection(&[1, 2, 3], &[2], &[2]);
-        check_intersection(&[11, 1, 3, 77, 103, 5, -5],
-                           &[2, 11, 77, -9, -42, 5, 3],
-                           &[3, 5, 11, 77]);
-    }
-
-    #[test]
-    fn test_difference() {
-        fn check_difference(a: &[i32], b: &[i32], expected: &[i32]) {
-            check(a, b, expected, |x, y, f| x.difference(y).all(f))
-        }
-
-        check_difference(&[], &[], &[]);
-        check_difference(&[1, 12], &[], &[1, 12]);
-        check_difference(&[], &[1, 2, 3, 9], &[]);
-        check_difference(&[1, 3, 5, 9, 11],
-                         &[3, 9],
-                         &[1, 5, 11]);
-        check_difference(&[-5, 11, 22, 33, 40, 42],
-                         &[-12, -5, 14, 23, 34, 38, 39, 50],
-                         &[11, 22, 33, 40, 42]);
-    }
-
-    #[test]
-    fn test_symmetric_difference() {
-        fn check_symmetric_difference(a: &[i32], b: &[i32], expected: &[i32]) {
-            check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f))
-        }
-
-        check_symmetric_difference(&[], &[], &[]);
-        check_symmetric_difference(&[1, 2, 3], &[2], &[1, 3]);
-        check_symmetric_difference(&[2], &[1, 2, 3], &[1, 3]);
-        check_symmetric_difference(&[1, 3, 5, 9, 11],
-                                   &[-2, 3, 9, 14, 22],
-                                   &[-2, 1, 5, 11, 14, 22]);
-    }
-
-    #[test]
-    fn test_union() {
-        fn check_union(a: &[i32], b: &[i32], expected: &[i32]) {
-            check(a, b, expected, |x, y, f| x.union(y).all(f))
-        }
-
-        check_union(&[], &[], &[]);
-        check_union(&[1, 2, 3], &[2], &[1, 2, 3]);
-        check_union(&[2], &[1, 2, 3], &[1, 2, 3]);
-        check_union(&[1, 3, 5, 9, 11, 16, 19, 24],
-                    &[-2, 1, 5, 9, 13, 19],
-                    &[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
-    }
-
-    #[test]
-    fn test_zip() {
-        let mut x = BTreeSet::new();
-        x.insert(5);
-        x.insert(12);
-        x.insert(11);
-
-        let mut y = BTreeSet::new();
-        y.insert("foo");
-        y.insert("bar");
-
-        let x = x;
-        let y = y;
-        let mut z = x.iter().zip(y.iter());
-
-        // FIXME: #5801: this needs a type hint to compile...
-        let result: Option<(&usize, & &'static str)> = z.next();
-        assert_eq!(result.unwrap(), (&5, &("bar")));
-
-        let result: Option<(&usize, & &'static str)> = z.next();
-        assert_eq!(result.unwrap(), (&11, &("foo")));
-
-        let result: Option<(&usize, & &'static str)> = z.next();
-        assert!(result.is_none());
-    }
-
-    #[test]
-    fn test_from_iter() {
-        let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
-
-        let set: BTreeSet<_> = xs.iter().cloned().collect();
-
-        for x in &xs {
-            assert!(set.contains(x));
-        }
-    }
-
-    #[test]
-    fn test_show() {
-        let mut set = BTreeSet::new();
-        let empty = BTreeSet::<i32>::new();
-
-        set.insert(1);
-        set.insert(2);
-
-        let set_str = format!("{:?}", set);
-
-        assert_eq!(set_str, "BTreeSet {1, 2}");
-        assert_eq!(format!("{:?}", empty), "BTreeSet {}");
-    }
-}
index 0c95742606083fbe33402ca667d840ed620c406c..0b206d381ddacde5216e2d6c99f7033b97b1ce62 100644 (file)
 use core::prelude::*;
 use core::marker;
 use core::fmt;
-use core::num::Int;
 use core::iter::{FromIterator, IntoIterator};
 use core::ops::{Sub, BitOr, BitAnd, BitXor};
 
 // FIXME(contentions): implement union family of methods? (general design may be wrong here)
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
 /// A specialized set implementation to use enum types.
+///
+/// It is a logic error for an item to be modified in such a way that the transformation of the
+/// item to or from a `usize`, as determined by the `CLike` trait, changes while the item is in the
+/// set. This is normally only possible through `Cell`, `RefCell`, global state, I/O, or unsafe
+/// code.
 pub struct EnumSet<E> {
     // We must maintain the invariant that no bits are set
     // for which no variant exists
@@ -33,10 +37,14 @@ pub struct EnumSet<E> {
 
 impl<E> Copy for EnumSet<E> {}
 
+impl<E> Clone for EnumSet<E> {
+    fn clone(&self) -> EnumSet<E> { *self }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<E:CLike + fmt::Debug> fmt::Debug for EnumSet<E> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(fmt, "EnumSet {{"));
+        try!(write!(fmt, "{{"));
         let mut first = true;
         for e in self {
             if !first {
@@ -78,7 +86,7 @@ pub trait CLike {
 fn bit<E:CLike>(e: &E) -> usize {
     use core::usize;
     let value = e.to_usize();
-    assert!(value < usize::BITS,
+    assert!(value < usize::BITS as usize,
             "EnumSet only supports up to {} variants.", usize::BITS - 1);
     1 << value
 }
@@ -95,7 +103,7 @@ impl<E:CLike> EnumSet<E> {
     #[unstable(feature = "collections",
                reason = "matches collection reform specification, waiting for dust to settle")]
     pub fn len(&self) -> usize {
-        self.bits.count_ones()
+        self.bits.count_ones() as usize
     }
 
     /// Returns true if the `EnumSet` is empty.
@@ -250,7 +258,7 @@ impl<E:CLike> Iterator for Iter<E> {
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let exact = self.bits.count_ones();
+        let exact = self.bits.count_ones() as usize;
         (exact, Some(exact))
     }
 }
@@ -280,241 +288,3 @@ impl<E:CLike> Extend<E> for EnumSet<E> {
         }
     }
 }
-
-#[cfg(test)]
-mod test {
-    use self::Foo::*;
-    use prelude::*;
-    use core::mem;
-
-    use super::{EnumSet, CLike};
-
-    #[derive(Copy, PartialEq, Debug)]
-    #[repr(usize)]
-    enum Foo {
-        A, B, C
-    }
-
-    impl CLike for Foo {
-        fn to_usize(&self) -> usize {
-            *self as usize
-        }
-
-        fn from_usize(v: usize) -> Foo {
-            unsafe { mem::transmute(v) }
-        }
-    }
-
-    #[test]
-    fn test_new() {
-        let e: EnumSet<Foo> = EnumSet::new();
-        assert!(e.is_empty());
-    }
-
-    #[test]
-    fn test_show() {
-        let mut e = EnumSet::new();
-        assert!(format!("{:?}", e) == "EnumSet {}");
-        e.insert(A);
-        assert!(format!("{:?}", e) == "EnumSet {A}");
-        e.insert(C);
-        assert!(format!("{:?}", e) == "EnumSet {A, C}");
-    }
-
-    #[test]
-    fn test_len() {
-        let mut e = EnumSet::new();
-        assert_eq!(e.len(), 0);
-        e.insert(A);
-        e.insert(B);
-        e.insert(C);
-        assert_eq!(e.len(), 3);
-        e.remove(&A);
-        assert_eq!(e.len(), 2);
-        e.clear();
-        assert_eq!(e.len(), 0);
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // intersect
-
-    #[test]
-    fn test_two_empties_do_not_intersect() {
-        let e1: EnumSet<Foo> = EnumSet::new();
-        let e2: EnumSet<Foo> = EnumSet::new();
-        assert!(e1.is_disjoint(&e2));
-    }
-
-    #[test]
-    fn test_empty_does_not_intersect_with_full() {
-        let e1: EnumSet<Foo> = EnumSet::new();
-
-        let mut e2: EnumSet<Foo> = EnumSet::new();
-        e2.insert(A);
-        e2.insert(B);
-        e2.insert(C);
-
-        assert!(e1.is_disjoint(&e2));
-    }
-
-    #[test]
-    fn test_disjoint_intersects() {
-        let mut e1: EnumSet<Foo> = EnumSet::new();
-        e1.insert(A);
-
-        let mut e2: EnumSet<Foo> = EnumSet::new();
-        e2.insert(B);
-
-        assert!(e1.is_disjoint(&e2));
-    }
-
-    #[test]
-    fn test_overlapping_intersects() {
-        let mut e1: EnumSet<Foo> = EnumSet::new();
-        e1.insert(A);
-
-        let mut e2: EnumSet<Foo> = EnumSet::new();
-        e2.insert(A);
-        e2.insert(B);
-
-        assert!(!e1.is_disjoint(&e2));
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // contains and contains_elem
-
-    #[test]
-    fn test_superset() {
-        let mut e1: EnumSet<Foo> = EnumSet::new();
-        e1.insert(A);
-
-        let mut e2: EnumSet<Foo> = EnumSet::new();
-        e2.insert(A);
-        e2.insert(B);
-
-        let mut e3: EnumSet<Foo> = EnumSet::new();
-        e3.insert(C);
-
-        assert!(e1.is_subset(&e2));
-        assert!(e2.is_superset(&e1));
-        assert!(!e3.is_superset(&e2));
-        assert!(!e2.is_superset(&e3))
-    }
-
-    #[test]
-    fn test_contains() {
-        let mut e1: EnumSet<Foo> = EnumSet::new();
-        e1.insert(A);
-        assert!(e1.contains(&A));
-        assert!(!e1.contains(&B));
-        assert!(!e1.contains(&C));
-
-        e1.insert(A);
-        e1.insert(B);
-        assert!(e1.contains(&A));
-        assert!(e1.contains(&B));
-        assert!(!e1.contains(&C));
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // iter
-
-    #[test]
-    fn test_iterator() {
-        let mut e1: EnumSet<Foo> = EnumSet::new();
-
-        let elems: ::vec::Vec<Foo> = e1.iter().collect();
-        assert!(elems.is_empty());
-
-        e1.insert(A);
-        let elems: ::vec::Vec<_> = e1.iter().collect();
-        assert_eq!(vec![A], elems);
-
-        e1.insert(C);
-        let elems: ::vec::Vec<_> = e1.iter().collect();
-        assert_eq!(vec![A,C], elems);
-
-        e1.insert(C);
-        let elems: ::vec::Vec<_> = e1.iter().collect();
-        assert_eq!(vec![A,C], elems);
-
-        e1.insert(B);
-        let elems: ::vec::Vec<_> = e1.iter().collect();
-        assert_eq!(vec![A,B,C], elems);
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // operators
-
-    #[test]
-    fn test_operators() {
-        let mut e1: EnumSet<Foo> = EnumSet::new();
-        e1.insert(A);
-        e1.insert(C);
-
-        let mut e2: EnumSet<Foo> = EnumSet::new();
-        e2.insert(B);
-        e2.insert(C);
-
-        let e_union = e1 | e2;
-        let elems: ::vec::Vec<_> = e_union.iter().collect();
-        assert_eq!(vec![A,B,C], elems);
-
-        let e_intersection = e1 & e2;
-        let elems: ::vec::Vec<_> = e_intersection.iter().collect();
-        assert_eq!(vec![C], elems);
-
-        // Another way to express intersection
-        let e_intersection = e1 - (e1 - e2);
-        let elems: ::vec::Vec<_> = e_intersection.iter().collect();
-        assert_eq!(vec![C], elems);
-
-        let e_subtract = e1 - e2;
-        let elems: ::vec::Vec<_> = e_subtract.iter().collect();
-        assert_eq!(vec![A], elems);
-
-        // Bitwise XOR of two sets, aka symmetric difference
-        let e_symmetric_diff = e1 ^ e2;
-        let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
-        assert_eq!(vec![A,B], elems);
-
-        // Another way to express symmetric difference
-        let e_symmetric_diff = (e1 - e2) | (e2 - e1);
-        let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
-        assert_eq!(vec![A,B], elems);
-
-        // Yet another way to express symmetric difference
-        let e_symmetric_diff = (e1 | e2) - (e1 & e2);
-        let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
-        assert_eq!(vec![A,B], elems);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_overflow() {
-        #[allow(dead_code)]
-        #[derive(Copy)]
-        #[repr(usize)]
-        enum Bar {
-            V00, V01, V02, V03, V04, V05, V06, V07, V08, V09,
-            V10, V11, V12, V13, V14, V15, V16, V17, V18, V19,
-            V20, V21, V22, V23, V24, V25, V26, V27, V28, V29,
-            V30, V31, V32, V33, V34, V35, V36, V37, V38, V39,
-            V40, V41, V42, V43, V44, V45, V46, V47, V48, V49,
-            V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
-            V60, V61, V62, V63, V64, V65, V66, V67, V68, V69,
-        }
-
-        impl CLike for Bar {
-            fn to_usize(&self) -> usize {
-                *self as usize
-            }
-
-            fn from_usize(v: usize) -> Bar {
-                unsafe { mem::transmute(v) }
-            }
-        }
-        let mut set = EnumSet::new();
-        set.insert(Bar::V64);
-    }
-}
index 1b5018f4ad73df637c96ec9bd7bdb5ae2262f069..46b1ad2138bd8152a25c6f22cea5898c367abeed 100644 (file)
@@ -16,7 +16,7 @@
 //! This macro is implemented in the compiler to emit calls to this module in
 //! order to format arguments at runtime into strings and streams.
 //!
-//! ## Usage
+//! # Usage
 //!
 //! The `format!` macro is intended to be familiar to those coming from C's
 //! printf/fprintf functions or Python's `str.format` function. In its current
@@ -41,7 +41,7 @@
 //! will then parse the format string and determine if the list of arguments
 //! provided is suitable to pass to this format string.
 //!
-//! ### Positional parameters
+//! ## Positional parameters
 //!
 //! Each formatting argument is allowed to specify which value argument it's
 //! referencing, and if omitted it is assumed to be "the next argument". For
@@ -54,7 +54,7 @@
 //! iterator over the argument. Each time a "next argument" specifier is seen,
 //! the iterator advances. This leads to behavior like this:
 //!
-//! ```rust
+//! ```
 //! format!("{1} {} {0} {}", 1, 2); // => "2 1 1 2"
 //! ```
 //!
@@ -68,7 +68,7 @@
 //! compile-time error. You may refer to the same argument more than once in the
 //! format string, although it must always be referred to with the same type.
 //!
-//! ### Named parameters
+//! ## Named parameters
 //!
 //! Rust itself does not have a Python-like equivalent of named parameters to a
 //! function, but the `format!` macro is a syntax extension which allows it to
@@ -91,7 +91,7 @@
 //! arguments which have names. Like with positional parameters, it is illegal
 //! to provide named parameters that are unused by the format string.
 //!
-//! ### Argument types
+//! ## Argument types
 //!
 //! Each argument's type is dictated by the format string. It is a requirement
 //! that every argument is only ever referred to by one type. For example, this
 //! hexadecimal as well as an
 //! octal.
 //!
-//! There are various parameters which do require a particular type, however.
-//! Namely if the syntax `{:.*}` is used, then the number of characters to print
-//! precedes the actual object being formatted, and the number of characters
-//! must have the type `usize`. Although a `usize` can be printed with `{}`, it is
-//! illegal to reference an argument as such. For example this is another
+//! There are various parameters which do require a particular type, however. Namely, the `{:.*}`
+//! syntax, which sets the number of numbers after the decimal in floating-point types:
+//!
+//! ```
+//! let formatted_number = format!("{:.*}", 2, 1.234567);
+//!
+//! assert_eq!("1.23", formatted_number)
+//! ```
+//!
+//! If this syntax is used, then the number of characters to print precedes the actual object being
+//! formatted, and the number of characters must have the type `usize`. Although a `usize` can be
+//! printed with `{}`, it is illegal to reference an argument as such. For example this is another
 //! invalid format string:
 //!
 //! ```text
 //! {:.*} {0}
 //! ```
 //!
-//! ### Formatting traits
+//! ## Formatting traits
 //!
 //! When requesting that an argument be formatted with a particular type, you
 //! are actually requesting that an argument ascribes to a particular trait.
 //! When implementing a format trait for your own type, you will have to
 //! implement a method of the signature:
 //!
-//! ```rust
+//! ```
 //! # use std::fmt;
 //! # struct Foo; // our custom type
 //! # impl fmt::Display for Foo {
 //! An example of implementing the formatting traits would look
 //! like:
 //!
-//! ```rust
+//! ```
+//! # #![feature(core, std_misc)]
 //! use std::fmt;
 //! use std::f64;
 //! use std::num::Float;
 //!         // for details, and the function `pad` can be used to pad strings.
 //!         let decimals = f.precision().unwrap_or(3);
 //!         let string = f64::to_str_exact(magnitude, decimals);
-//!         f.pad_integral(true, "", string.as_slice())
+//!         f.pad_integral(true, "", &string)
 //!     }
 //! }
 //!
 //! }
 //! ```
 //!
-//! #### fmt::Display vs fmt::Debug
+//! ### fmt::Display vs fmt::Debug
 //!
 //! These two formatting traits have distinct purposes:
 //!
 //! Some examples of the output from both traits:
 //!
 //! ```
-//! assert_eq!(format!("{} {:?}", 3i32, 4i32), "3 4");
+//! assert_eq!(format!("{} {:?}", 3, 4), "3 4");
 //! assert_eq!(format!("{} {:?}", 'a', 'b'), "a 'b'");
 //! assert_eq!(format!("{} {:?}", "foo\n", "bar\n"), "foo\n \"bar\\n\"");
 //! ```
 //!
-//! ### Related macros
+//! ## Related macros
 //!
 //! There are a number of related macros in the `format!` family. The ones that
 //! are currently implemented are:
 //! format_args! // described below.
 //! ```
 //!
-//! #### `write!`
+//! ### `write!`
 //!
 //! This and `writeln` are two macros which are used to emit the format string
 //! to a specified stream. This is used to prevent intermediate allocations of
 //! function is actually invoking the `write` function defined in this module.
 //! Example usage is:
 //!
-//! ```rust
+//! ```
+//! # #![feature(old_io)]
 //! # #![allow(unused_must_use)]
+//! use std::io::Write;
 //! let mut w = Vec::new();
 //! write!(&mut w, "Hello {}!", "world");
 //! ```
 //!
-//! #### `print!`
+//! ### `print!`
 //!
 //! This and `println` emit their output to stdout. Similarly to the `write!`
 //! macro, the goal of these macros is to avoid intermediate allocations when
 //! printing output. Example usage is:
 //!
-//! ```rust
+//! ```
 //! print!("Hello {}!", "world");
 //! println!("I have a newline {}", "character at the end");
 //! ```
 //!
-//! #### `format_args!`
+//! ### `format_args!`
+//!
 //! This is a curious macro which is used to safely pass around
 //! an opaque object describing the format string. This object
 //! does not require any heap allocations to create, and it only
 //! off, some example usage is:
 //!
 //! ```
+//! # #![feature(old_io)]
 //! use std::fmt;
-//! use std::old_io;
+//! use std::io::{self, Write};
 //!
 //! fmt::format(format_args!("this returns {}", "String"));
 //!
-//! let mut some_writer = old_io::stdout();
+//! let mut some_writer = io::stdout();
 //! write!(&mut some_writer, "{}", format_args!("print with a {}", "macro"));
 //!
 //! fn my_fmt_fn(args: fmt::Arguments) {
-//!     write!(&mut old_io::stdout(), "{}", args);
+//!     write!(&mut io::stdout(), "{}", args);
 //! }
 //! my_fmt_fn(format_args!("or a {} too", "function"));
 //! ```
 //! it would internally pass around this structure until it has been determined
 //! where output should go to.
 //!
-//! ## Syntax
+//! # Syntax
 //!
 //! The syntax for the formatting language used is drawn from other languages,
 //! so it should not be too alien. Arguments are formatted with python-like
 //! parameter := integer '$'
 //! ```
 //!
-//! ## Formatting Parameters
+//! # Formatting Parameters
 //!
 //! Each argument being formatted can be transformed by a number of formatting
 //! parameters (corresponding to `format_spec` in the syntax above). These
 //! parameters affect the string representation of what's being formatted. This
 //! syntax draws heavily from Python's, so it may seem a bit familiar.
 //!
-//! ### Fill/Alignment
+//! ## Fill/Alignment
 //!
 //! The fill character is provided normally in conjunction with the `width`
 //! parameter. This indicates that if the value being formatted is smaller than
 //! * `^` - the argument is center-aligned in `width` columns
 //! * `>` - the argument is right-aligned in `width` columns
 //!
-//! ### Sign/#/0
+//! ## Sign/#/0
 //!
 //! These can all be interpreted as flags for a particular formatter.
 //!
 //!         should always be printed.
 //! * '-' - Currently not used
 //! * '#' - This flag is indicates that the "alternate" form of printing should
-//!         be used. By default, this only applies to the integer formatting
-//!         traits and performs like:
-//!     * `x` - precedes the argument with a "0x"
-//!     * `X` - precedes the argument with a "0x"
-//!     * `t` - precedes the argument with a "0b"
-//!     * `o` - precedes the argument with a "0o"
+//!         be used.  For array slices, the alternate form omits the brackets.
+//!         For the integer formatting traits, the alternate forms are:
+//!     * `#x` - precedes the argument with a "0x"
+//!     * `#X` - precedes the argument with a "0x"
+//!     * `#t` - precedes the argument with a "0b"
+//!     * `#o` - precedes the argument with a "0o"
 //! * '0' - This is used to indicate for integer formats that the padding should
 //!         both be done with a `0` character as well as be sign-aware. A format
-//!         like `{:08d}` would yield `00000001` for the integer `1`, while the
+//!         like `{:08}` would yield `00000001` for the integer `1`, while the
 //!         same format would yield `-0000001` for the integer `-1`. Notice that
 //!         the negative version has one fewer zero than the positive version.
 //!
-//! ### Width
+//! ## Width
 //!
 //! This is a parameter for the "minimum width" that the format should take up.
 //! If the value's string does not fill up this many characters, then the
 //! parameters by using the `2$` syntax indicating that the second argument is a
 //! `usize` specifying the width.
 //!
-//! ### Precision
+//! ## Precision
 //!
 //! For non-numeric types, this can be considered a "maximum width". If the
 //! resulting string is longer than this width, then it is truncated down to
 //! For floating-point types, this indicates how many digits after the decimal
 //! point should be printed.
 //!
-//! ## Escaping
+//! # Escaping
 //!
 //! The literal characters `{` and `}` may be included in a string by preceding
 //! them with the same character. For example, the `{` character is escaped with
 #![stable(feature = "rust1", since = "1.0.0")]
 
 pub use core::fmt::{Formatter, Result, Write, rt};
-pub use core::fmt::{Show, String, Octal, Binary};
+pub use core::fmt::{Octal, Binary};
 pub use core::fmt::{Display, Debug};
 pub use core::fmt::{LowerHex, UpperHex, Pointer};
 pub use core::fmt::{LowerExp, UpperExp};
@@ -420,9 +432,9 @@ use string;
 ///
 ///   * args - a structure of arguments generated via the `format_args!` macro.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::fmt;
 ///
 /// let s = fmt::format(format_args!("Hello, {}!", "world"));
@@ -434,15 +446,3 @@ pub fn format(args: Arguments) -> string::String {
     let _ = write!(&mut output, "{}", args);
     output
 }
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use fmt;
-
-    #[test]
-    fn test_format() {
-        let s = fmt::format(format_args!("Hello, {}!", "world"));
-        assert_eq!(s.as_slice(), "Hello, world!");
-    }
-}
index 6569ab9c05acd768f56d4d4d5d9b9ddd32c65943..7658611d809afd6ac23bdd666878c206dc1d3749 100644 (file)
@@ -12,7 +12,8 @@
 //!
 //! See [std::collections](../std/collections) for a detailed discussion of collections in Rust.
 
-
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "collections"]
 #![unstable(feature = "collections")]
 #![staged_api]
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
+#![doc(test(no_crate_inject))]
 
+#![allow(trivial_casts)]
 #![feature(alloc)]
 #![feature(box_syntax)]
 #![feature(box_patterns)]
 #![feature(core)]
+#![feature(lang_items)]
 #![feature(staged_api)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
 #![feature(unsafe_destructor)]
-#![feature(unsafe_no_drop_flag)]
-#![cfg_attr(test, feature(rand, rustc_private, test))]
+#![feature(unique)]
+#![feature(unsafe_no_drop_flag, filling_drop)]
+#![feature(step_by)]
+#![feature(str_char)]
+#![feature(slice_patterns)]
+#![feature(debug_builders)]
+#![cfg_attr(test, feature(rand, rustc_private, test, hash, collections))]
 #![cfg_attr(test, allow(deprecated))] // rand
 
 #![feature(no_std)]
@@ -43,9 +52,8 @@ extern crate core;
 extern crate unicode;
 extern crate alloc;
 
-#[cfg(test)] extern crate test;
 #[cfg(test)] #[macro_use] extern crate std;
-#[cfg(test)] #[macro_use] extern crate log;
+#[cfg(test)] extern crate test;
 
 pub use binary_heap::BinaryHeap;
 pub use bit_vec::BitVec;
@@ -59,58 +67,30 @@ pub use string::String;
 pub use vec::Vec;
 pub use vec_map::VecMap;
 
-#[deprecated(since = "1.0.0", reason = "renamed to vec_deque")]
-#[unstable(feature = "collections")]
-pub use vec_deque as ring_buf;
-
-#[deprecated(since = "1.0.0", reason = "renamed to linked_list")]
-#[unstable(feature = "collections")]
-pub use linked_list as dlist;
-
-#[deprecated(since = "1.0.0", reason = "renamed to bit_vec")]
-#[unstable(feature = "collections")]
-pub use bit_vec as bitv;
-
-#[deprecated(since = "1.0.0", reason = "renamed to bit_set")]
-#[unstable(feature = "collections")]
-pub use bit_set as bitv_set;
-
 // Needed for the vec! macro
 pub use alloc::boxed;
 
 #[macro_use]
 mod macros;
 
-#[cfg(test)] #[macro_use] mod bench;
-
 pub mod binary_heap;
 mod bit;
 mod btree;
-pub mod linked_list;
+pub mod borrow;
 pub mod enum_set;
 pub mod fmt;
-pub mod vec_deque;
+pub mod linked_list;
 pub mod slice;
 pub mod str;
 pub mod string;
 pub mod vec;
+pub mod vec_deque;
 pub mod vec_map;
 
-#[cfg(stage0)]
-#[path = "borrow_stage0.rs"]
-pub mod borrow;
-
-#[cfg(not(stage0))]
-pub mod borrow;
-
 #[unstable(feature = "collections",
            reason = "RFC 509")]
 pub mod bit_vec {
     pub use bit::{BitVec, Iter};
-
-    #[deprecated(since = "1.0.0", reason = "renamed to BitVec")]
-    #[unstable(feature = "collections")]
-    pub use bit::BitVec as Bitv;
 }
 
 #[unstable(feature = "collections",
@@ -118,10 +98,6 @@ pub mod bit_vec {
 pub mod bit_set {
     pub use bit::{BitSet, Union, Intersection, Difference, SymmetricDifference};
     pub use bit::SetIter as Iter;
-
-    #[deprecated(since = "1.0.0", reason = "renamed to BitSet")]
-    #[unstable(feature = "collections")]
-    pub use bit::BitSet as BitvSet;
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -144,41 +120,8 @@ mod std {
     pub use core::ops;      // RangeFull
 }
 
-#[cfg(test)]
-mod prelude {
-    // from core.
-    pub use core::clone::Clone;
-    pub use core::cmp::{PartialEq, Eq, PartialOrd, Ord};
-    pub use core::cmp::Ordering::{Less, Equal, Greater};
-    pub use core::iter::range;
-    pub use core::iter::{FromIterator, Extend, IteratorExt};
-    pub use core::iter::{Iterator, DoubleEndedIterator, RandomAccessIterator};
-    pub use core::iter::{ExactSizeIterator};
-    pub use core::marker::{Copy, Send, Sized, Sync};
-    pub use core::mem::drop;
-    pub use core::ops::{Drop, Fn, FnMut, FnOnce};
-    pub use core::option::Option;
-    pub use core::option::Option::{Some, None};
-    pub use core::ptr::PtrExt;
-    pub use core::result::Result;
-    pub use core::result::Result::{Ok, Err};
-
-    // in core and collections (may differ).
-    pub use slice::{AsSlice, SliceExt};
-    pub use str::{Str, StrExt};
-
-    // from other crates.
-    pub use alloc::boxed::Box;
-    pub use unicode::char::CharExt;
-
-    // from collections.
-    pub use borrow::IntoCow;
-    pub use slice::SliceConcatExt;
-    pub use string::{String, ToString};
-    pub use vec::Vec;
-}
-
 /// An endpoint of a range of keys.
+#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
 pub enum Bound<T> {
     /// An inclusive bound.
     Included(T),
index c142819a5189671bf8400aed0fe5c0fe357a48c6..dbdb79565736cd16a33a13390f5c67b9ef1f6d81 100644 (file)
@@ -28,16 +28,10 @@ use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt;
 use core::hash::{Hasher, Hash};
-#[cfg(stage0)]
-use core::hash::Writer;
 use core::iter::{self, FromIterator, IntoIterator};
 use core::mem;
 use core::ptr;
 
-#[deprecated(since = "1.0.0", reason = "renamed to LinkedList")]
-#[unstable(feature = "collections")]
-pub use LinkedList as DList;
-
 /// A doubly-linked list.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct LinkedList<T> {
@@ -53,8 +47,8 @@ struct Rawlink<T> {
 }
 
 impl<T> Copy for Rawlink<T> {}
-unsafe impl<T:'static+Send> Send for Rawlink<T> {}
-unsafe impl<T:Send+Sync> Sync for Rawlink<T> {}
+unsafe impl<T:Send> Send for Rawlink<T> {}
+unsafe impl<T:Sync> Sync for Rawlink<T> {}
 
 struct Node<T> {
     next: Link<T>,
@@ -237,6 +231,7 @@ impl<T> LinkedList<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::LinkedList;
     ///
     /// let mut a = LinkedList::new();
@@ -253,6 +248,7 @@ impl<T> LinkedList<T> {
     /// }
     /// println!("{}", b.len()); // prints 0
     /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn append(&mut self, other: &mut LinkedList<T>) {
         match self.list_tail.resolve() {
             None => {
@@ -485,6 +481,7 @@ impl<T> LinkedList<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::LinkedList;
     ///
     /// let mut dl = LinkedList::new();
@@ -532,6 +529,7 @@ impl<T> LinkedList<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::LinkedList;
     ///
     /// let mut d = LinkedList::new();
@@ -550,6 +548,7 @@ impl<T> LinkedList<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::LinkedList;
     ///
     /// let mut d = LinkedList::new();
@@ -575,6 +574,7 @@ impl<T> LinkedList<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::LinkedList;
     ///
     /// let mut d = LinkedList::new();
@@ -767,6 +767,7 @@ impl<'a, A> IterMut<'a, A> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::LinkedList;
     ///
     /// let mut list: LinkedList<_> = vec![1, 3, 4].into_iter().collect();
@@ -779,7 +780,7 @@ impl<'a, A> IterMut<'a, A> {
     /// }
     /// {
     ///     let vec: Vec<_> = list.into_iter().collect();
-    ///     assert_eq!(vec, vec![1, 2, 3, 4]);
+    ///     assert_eq!(vec, [1, 2, 3, 4]);
     /// }
     /// ```
     #[inline]
@@ -794,6 +795,7 @@ impl<'a, A> IterMut<'a, A> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::LinkedList;
     ///
     /// let mut list: LinkedList<_> = vec![1, 2, 3].into_iter().collect();
@@ -834,10 +836,12 @@ impl<A> DoubleEndedIterator for IntoIter<A> {
     fn next_back(&mut self) -> Option<A> { self.list.pop_back() }
 }
 
+impl<A> ExactSizeIterator for IntoIter<A> {}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A> FromIterator<A> for LinkedList<A> {
     fn from_iter<T: IntoIterator<Item=A>>(iter: T) -> LinkedList<A> {
-        let mut ret = DList::new();
+        let mut ret = LinkedList::new();
         ret.extend(iter);
         ret
     }
@@ -920,29 +924,11 @@ impl<A: Clone> Clone for LinkedList<A> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A: fmt::Debug> fmt::Debug for LinkedList<A> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "LinkedList ["));
-
-        for (i, e) in self.iter().enumerate() {
-            if i != 0 { try!(write!(f, ", ")); }
-            try!(write!(f, "{:?}", *e));
-        }
-
-        write!(f, "]")
+        self.iter().fold(f.debug_list(), |b, e| b.entry(e)).finish()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg(stage0)]
-impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for LinkedList<A> {
-    fn hash(&self, state: &mut S) {
-        self.len().hash(state);
-        for elt in self {
-            elt.hash(state);
-        }
-    }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg(not(stage0))]
 impl<A: Hash> Hash for LinkedList<A> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         self.len().hash(state);
@@ -953,16 +939,21 @@ impl<A: Hash> Hash for LinkedList<A> {
 }
 
 #[cfg(test)]
-mod tests {
-    use prelude::*;
+mod test {
+    use std::clone::Clone;
+    use std::iter::Iterator;
+    use std::option::Option::{Some, None, self};
     use std::rand;
-    use std::hash::{self, SipHasher};
     use std::thread;
-    use test::Bencher;
-    use test;
+    use std::vec::Vec;
 
     use super::{LinkedList, Node};
 
+    #[cfg(test)]
+    fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
+        v.iter().cloned().collect()
+    }
+
     pub fn check_links<T>(list: &LinkedList<T>) {
         let mut len = 0;
         let mut last_ptr: Option<&Node<T>> = None;
@@ -995,56 +986,6 @@ mod tests {
         assert_eq!(len, list.length);
     }
 
-    #[test]
-    fn test_basic() {
-        let mut m = LinkedList::new();
-        assert_eq!(m.pop_front(), None);
-        assert_eq!(m.pop_back(), None);
-        assert_eq!(m.pop_front(), None);
-        m.push_front(box 1);
-        assert_eq!(m.pop_front(), Some(box 1));
-        m.push_back(box 2);
-        m.push_back(box 3);
-        assert_eq!(m.len(), 2);
-        assert_eq!(m.pop_front(), Some(box 2));
-        assert_eq!(m.pop_front(), Some(box 3));
-        assert_eq!(m.len(), 0);
-        assert_eq!(m.pop_front(), None);
-        m.push_back(box 1);
-        m.push_back(box 3);
-        m.push_back(box 5);
-        m.push_back(box 7);
-        assert_eq!(m.pop_front(), Some(box 1));
-
-        let mut n = LinkedList::new();
-        n.push_front(2);
-        n.push_front(3);
-        {
-            assert_eq!(n.front().unwrap(), &3);
-            let x = n.front_mut().unwrap();
-            assert_eq!(*x, 3);
-            *x = 0;
-        }
-        {
-            assert_eq!(n.back().unwrap(), &2);
-            let y = n.back_mut().unwrap();
-            assert_eq!(*y, 2);
-            *y = 1;
-        }
-        assert_eq!(n.pop_front(), Some(0));
-        assert_eq!(n.pop_front(), Some(1));
-    }
-
-    #[cfg(test)]
-    fn generate_test() -> LinkedList<i32> {
-        list_from(&[0,1,2,3,4,5,6])
-    }
-
-    #[cfg(test)]
-    fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
-        v.iter().cloned().collect()
-    }
-
     #[test]
     fn test_append() {
         // Empty to empty
@@ -1102,166 +1043,6 @@ mod tests {
         check_links(&n);
     }
 
-    #[test]
-    fn test_split_off() {
-        // singleton
-        {
-            let mut m = LinkedList::new();
-            m.push_back(1);
-
-            let p = m.split_off(0);
-            assert_eq!(m.len(), 0);
-            assert_eq!(p.len(), 1);
-            assert_eq!(p.back(), Some(&1));
-            assert_eq!(p.front(), Some(&1));
-        }
-
-        // not singleton, forwards
-        {
-            let u = vec![1,2,3,4,5];
-            let mut m = list_from(&u);
-            let mut n = m.split_off(2);
-            assert_eq!(m.len(), 2);
-            assert_eq!(n.len(), 3);
-            for elt in 1..3 {
-                assert_eq!(m.pop_front(), Some(elt));
-            }
-            for elt in 3..6 {
-                assert_eq!(n.pop_front(), Some(elt));
-            }
-        }
-        // not singleton, backwards
-        {
-            let u = vec![1,2,3,4,5];
-            let mut m = list_from(&u);
-            let mut n = m.split_off(4);
-            assert_eq!(m.len(), 4);
-            assert_eq!(n.len(), 1);
-            for elt in 1..5 {
-                assert_eq!(m.pop_front(), Some(elt));
-            }
-            for elt in 5..6 {
-                assert_eq!(n.pop_front(), Some(elt));
-            }
-        }
-
-        // no-op on the last index
-        {
-            let mut m = LinkedList::new();
-            m.push_back(1);
-
-            let p = m.split_off(1);
-            assert_eq!(m.len(), 1);
-            assert_eq!(p.len(), 0);
-            assert_eq!(m.back(), Some(&1));
-            assert_eq!(m.front(), Some(&1));
-        }
-
-    }
-
-    #[test]
-    fn test_iterator() {
-        let m = generate_test();
-        for (i, elt) in m.iter().enumerate() {
-            assert_eq!(i as i32, *elt);
-        }
-        let mut n = LinkedList::new();
-        assert_eq!(n.iter().next(), None);
-        n.push_front(4);
-        let mut it = n.iter();
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(it.next().unwrap(), &4);
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert_eq!(it.next(), None);
-    }
-
-    #[test]
-    fn test_iterator_clone() {
-        let mut n = LinkedList::new();
-        n.push_back(2);
-        n.push_back(3);
-        n.push_back(4);
-        let mut it = n.iter();
-        it.next();
-        let mut jt = it.clone();
-        assert_eq!(it.next(), jt.next());
-        assert_eq!(it.next_back(), jt.next_back());
-        assert_eq!(it.next(), jt.next());
-    }
-
-    #[test]
-    fn test_iterator_double_end() {
-        let mut n = LinkedList::new();
-        assert_eq!(n.iter().next(), None);
-        n.push_front(4);
-        n.push_front(5);
-        n.push_front(6);
-        let mut it = n.iter();
-        assert_eq!(it.size_hint(), (3, Some(3)));
-        assert_eq!(it.next().unwrap(), &6);
-        assert_eq!(it.size_hint(), (2, Some(2)));
-        assert_eq!(it.next_back().unwrap(), &4);
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(it.next_back().unwrap(), &5);
-        assert_eq!(it.next_back(), None);
-        assert_eq!(it.next(), None);
-    }
-
-    #[test]
-    fn test_rev_iter() {
-        let m = generate_test();
-        for (i, elt) in m.iter().rev().enumerate() {
-            assert_eq!((6 - i) as i32, *elt);
-        }
-        let mut n = LinkedList::new();
-        assert_eq!(n.iter().rev().next(), None);
-        n.push_front(4);
-        let mut it = n.iter().rev();
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(it.next().unwrap(), &4);
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert_eq!(it.next(), None);
-    }
-
-    #[test]
-    fn test_mut_iter() {
-        let mut m = generate_test();
-        let mut len = m.len();
-        for (i, elt) in m.iter_mut().enumerate() {
-            assert_eq!(i as i32, *elt);
-            len -= 1;
-        }
-        assert_eq!(len, 0);
-        let mut n = LinkedList::new();
-        assert!(n.iter_mut().next().is_none());
-        n.push_front(4);
-        n.push_back(5);
-        let mut it = n.iter_mut();
-        assert_eq!(it.size_hint(), (2, Some(2)));
-        assert!(it.next().is_some());
-        assert!(it.next().is_some());
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_iterator_mut_double_end() {
-        let mut n = LinkedList::new();
-        assert!(n.iter_mut().next_back().is_none());
-        n.push_front(4);
-        n.push_front(5);
-        n.push_front(6);
-        let mut it = n.iter_mut();
-        assert_eq!(it.size_hint(), (3, Some(3)));
-        assert_eq!(*it.next().unwrap(), 6);
-        assert_eq!(it.size_hint(), (2, Some(2)));
-        assert_eq!(*it.next_back().unwrap(), 4);
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(*it.next_back().unwrap(), 5);
-        assert!(it.next_back().is_none());
-        assert!(it.next().is_none());
-    }
-
     #[test]
     fn test_insert_prev() {
         let mut m = list_from(&[0,2,4,6,8]);
@@ -1286,21 +1067,7 @@ mod tests {
         }
         check_links(&m);
         assert_eq!(m.len(), 3 + len * 2);
-        assert_eq!(m.into_iter().collect::<Vec<_>>(), vec![-2,0,1,2,3,4,5,6,7,8,9,0,1]);
-    }
-
-    #[test]
-    fn test_mut_rev_iter() {
-        let mut m = generate_test();
-        for (i, elt) in m.iter_mut().rev().enumerate() {
-            assert_eq!((6 - i) as i32, *elt);
-        }
-        let mut n = LinkedList::new();
-        assert!(n.iter_mut().rev().next().is_none());
-        n.push_front(4);
-        let mut it = n.iter_mut().rev();
-        assert!(it.next().is_some());
-        assert!(it.next().is_none());
+        assert_eq!(m.into_iter().collect::<Vec<_>>(), [-2,0,1,2,3,4,5,6,7,8,9,0,1]);
     }
 
     #[test]
@@ -1309,85 +1076,10 @@ mod tests {
         thread::spawn(move || {
             check_links(&n);
             let a: &[_] = &[&1,&2,&3];
-            assert_eq!(a, n.iter().collect::<Vec<_>>());
+            assert_eq!(a, &n.iter().collect::<Vec<_>>()[..]);
         }).join().ok().unwrap();
     }
 
-    #[test]
-    fn test_eq() {
-        let mut n = list_from(&[]);
-        let mut m = list_from(&[]);
-        assert!(n == m);
-        n.push_front(1);
-        assert!(n != m);
-        m.push_back(1);
-        assert!(n == m);
-
-        let n = list_from(&[2,3,4]);
-        let m = list_from(&[1,2,3]);
-        assert!(n != m);
-    }
-
-    #[test]
-    fn test_hash() {
-      let mut x = LinkedList::new();
-      let mut y = LinkedList::new();
-
-      assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
-
-      x.push_back(1);
-      x.push_back(2);
-      x.push_back(3);
-
-      y.push_front(3);
-      y.push_front(2);
-      y.push_front(1);
-
-      assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
-    }
-
-    #[test]
-    fn test_ord() {
-        let n = list_from(&[]);
-        let m = list_from(&[1,2,3]);
-        assert!(n < m);
-        assert!(m > n);
-        assert!(n <= n);
-        assert!(n >= n);
-    }
-
-    #[test]
-    fn test_ord_nan() {
-        let nan = 0.0f64/0.0;
-        let n = list_from(&[nan]);
-        let m = list_from(&[nan]);
-        assert!(!(n < m));
-        assert!(!(n > m));
-        assert!(!(n <= m));
-        assert!(!(n >= m));
-
-        let n = list_from(&[nan]);
-        let one = list_from(&[1.0f64]);
-        assert!(!(n < one));
-        assert!(!(n > one));
-        assert!(!(n <= one));
-        assert!(!(n >= one));
-
-        let u = list_from(&[1.0f64,2.0,nan]);
-        let v = list_from(&[1.0f64,2.0,3.0]);
-        assert!(!(u < v));
-        assert!(!(u > v));
-        assert!(!(u <= v));
-        assert!(!(u >= v));
-
-        let s = list_from(&[1.0f64,2.0,4.0,2.0]);
-        let t = list_from(&[1.0f64,2.0,3.0,2.0]);
-        assert!(!(s < t));
-        assert!(s > one);
-        assert!(!(s <= one));
-        assert!(s >= one);
-    }
-
     #[test]
     fn test_fuzz() {
         for _ in 0..25 {
@@ -1397,15 +1089,6 @@ mod tests {
         }
     }
 
-    #[test]
-    fn test_show() {
-        let list: LinkedList<_> = (0..10).collect();
-        assert_eq!(format!("{:?}", list), "LinkedList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
-
-        let list: LinkedList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect();
-        assert_eq!(format!("{:?}", list), "LinkedList [\"just\", \"one\", \"test\", \"more\"]");
-    }
-
     #[cfg(test)]
     fn fuzz_test(sz: i32) {
         let mut m: LinkedList<_> = LinkedList::new();
@@ -1444,79 +1127,4 @@ mod tests {
         }
         assert_eq!(i, v.len());
     }
-
-    #[bench]
-    fn bench_collect_into(b: &mut test::Bencher) {
-        let v = &[0; 64];
-        b.iter(|| {
-            let _: LinkedList<_> = v.iter().cloned().collect();
-        })
-    }
-
-    #[bench]
-    fn bench_push_front(b: &mut test::Bencher) {
-        let mut m: LinkedList<_> = LinkedList::new();
-        b.iter(|| {
-            m.push_front(0);
-        })
-    }
-
-    #[bench]
-    fn bench_push_back(b: &mut test::Bencher) {
-        let mut m: LinkedList<_> = LinkedList::new();
-        b.iter(|| {
-            m.push_back(0);
-        })
-    }
-
-    #[bench]
-    fn bench_push_back_pop_back(b: &mut test::Bencher) {
-        let mut m: LinkedList<_> = LinkedList::new();
-        b.iter(|| {
-            m.push_back(0);
-            m.pop_back();
-        })
-    }
-
-    #[bench]
-    fn bench_push_front_pop_front(b: &mut test::Bencher) {
-        let mut m: LinkedList<_> = LinkedList::new();
-        b.iter(|| {
-            m.push_front(0);
-            m.pop_front();
-        })
-    }
-
-    #[bench]
-    fn bench_iter(b: &mut test::Bencher) {
-        let v = &[0; 128];
-        let m: LinkedList<_> = v.iter().cloned().collect();
-        b.iter(|| {
-            assert!(m.iter().count() == 128);
-        })
-    }
-    #[bench]
-    fn bench_iter_mut(b: &mut test::Bencher) {
-        let v = &[0; 128];
-        let mut m: LinkedList<_> = v.iter().cloned().collect();
-        b.iter(|| {
-            assert!(m.iter_mut().count() == 128);
-        })
-    }
-    #[bench]
-    fn bench_iter_rev(b: &mut test::Bencher) {
-        let v = &[0; 128];
-        let m: LinkedList<_> = v.iter().cloned().collect();
-        b.iter(|| {
-            assert!(m.iter().rev().count() == 128);
-        })
-    }
-    #[bench]
-    fn bench_iter_mut_rev(b: &mut test::Bencher) {
-        let v = &[0; 128];
-        let mut m: LinkedList<_> = v.iter().cloned().collect();
-        b.iter(|| {
-            assert!(m.iter_mut().rev().count() == 128);
-        })
-    }
 }
index ebcfb8d1cf84e2a4d421e2fc000c2cf767e8e559..5f614f3649ca9fd93f08765b44c46df3002a49ec 100644 (file)
 ///
 /// ```
 /// let v = vec![1; 3];
-/// assert_eq!(v, vec![1, 1, 1]);
+/// assert_eq!(v, [1, 1, 1]);
 /// ```
 ///
 /// Note that unlike array expressions this syntax supports all elements
 /// which implement `Clone` and the number of elements doesn't have to be
 /// a constant.
+#[cfg(not(test))]
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! vec {
@@ -39,8 +40,22 @@ macro_rules! vec {
         $crate::vec::from_elem($elem, $n)
     );
     ($($x:expr),*) => (
-        <[_] as $crate::slice::SliceExt>::into_vec(
-            $crate::boxed::Box::new([$($x),*]))
+        <[_]>::into_vec($crate::boxed::Box::new([$($x),*]))
+    );
+    ($($x:expr,)*) => (vec![$($x),*])
+}
+
+// HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is
+// required for this macro definition, is not available. Instead use the
+// `slice::into_vec`  function which is only available with cfg(test)
+// NB see the slice::hack module in slice.rs for more information
+#[cfg(test)]
+macro_rules! vec {
+    ($elem:expr; $n:expr) => (
+        $crate::vec::from_elem($elem, $n)
+    );
+    ($($x:expr),*) => (
+        $crate::slice::into_vec($crate::boxed::Box::new([$($x),*]))
     );
     ($($x:expr,)*) => (vec![$($x),*])
 }
@@ -48,7 +63,7 @@ macro_rules! vec {
 /// Use the syntax described in `std::fmt` to create a value of type `String`.
 /// See `std::fmt` for more information.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// format!("test");
index 776b8b3af147c262b31fafccd74c9b376f070279..ff923fb19068fb0a8187ea5684d561fac6bfd182 100644 (file)
 //! The `slice` module contains useful code to help work with slice values.
 //! Slices are a view into a block of memory represented as a pointer and a length.
 //!
-//! ```rust
+//! ```
 //! // slicing a Vec
-//! let vec = vec!(1, 2, 3);
-//! let int_slice = vec.as_slice();
+//! let vec = vec![1, 2, 3];
+//! let int_slice = &vec[..];
 //! // coercing an array to a slice
 //! let str_slice: &[&str] = &["one", "two", "three"];
 //! ```
 //!
 //! Slices are either mutable or shared. The shared slice type is `&[T]`,
-//! while the mutable slice type is `&mut[T]`. For example, you can mutate the
-//! block of memory that a mutable slice points to:
+//! while the mutable slice type is `&mut [T]`, where `T` represents the element
+//! type. For example, you can mutate the block of memory that a mutable slice
+//! points to:
 //!
-//! ```rust
-//! let x: &mut[i32] = &mut [1, 2, 3];
+//! ```
+//! let x = &mut [1, 2, 3];
 //! x[1] = 7;
-//! assert_eq!(x[0], 1);
-//! assert_eq!(x[1], 7);
-//! assert_eq!(x[2], 3);
+//! assert_eq!(x, &[1, 7, 3]);
 //! ```
 //!
 //! Here are some of the things this module contains:
 //! There are several structs that are useful for slices, such as `Iter`, which
 //! represents iteration over a slice.
 //!
-//! ## Traits
-//!
-//! A number of traits add methods that allow you to accomplish tasks
-//! with slices, the most important being `SliceExt`. Other traits
-//! apply only to slices of elements satisfying certain bounds (like
-//! `Ord`).
-//!
-//! An example is the `slice` method which enables slicing syntax `[a..b]` that
-//! returns an immutable "view" into a `Vec` or another slice from the index
-//! interval `[a, b)`:
-//!
-//! ```rust
-//! fn main() {
-//!     let numbers = [0, 1, 2];
-//!     let last_numbers = &numbers[1..3];
-//!     // last_numbers is now &[1, 2]
-//! }
-//! ```
-//!
-//! ## Implementations of other traits
+//! ## Trait Implementations
 //!
 //! There are several implementations of common traits for slices. Some examples
 //! include:
 //!
 //! * `Clone`
-//! * `Eq`, `Ord` - for immutable slices whose element type are `Eq` or `Ord`.
+//! * `Eq`, `Ord` - for slices whose element type are `Eq` or `Ord`.
 //! * `Hash` - for slices whose element type is `Hash`
 //!
 //! ## Iteration
 //!
-//! The method `iter()` returns an iteration value for a slice. The iterator
-//! yields references to the slice's elements, so if the element
-//! type of the slice is `isize`, the element type of the iterator is `&isize`.
+//! The slices implement `IntoIterator`. The iterator yields references to the
+//! slice elements.
 //!
-//! ```rust
-//! let numbers = [0, 1, 2];
-//! for &x in numbers.iter() {
-//!     println!("{} is a number!", x);
+//! ```
+//! let numbers = &[0, 1, 2];
+//! for n in numbers {
+//!     println!("{} is a number!", n);
 //! }
 //! ```
 //!
-//! * `.iter_mut()` returns an iterator that allows modifying each value.
-//! * Further iterators exist that split, chunk or permute the slice.
-
+//! The mutable slice yields mutable references to the elements:
+//!
+//! ```
+//! let mut scores = [7, 8, 9];
+//! for score in &mut scores[..] {
+//!     *score += 1;
+//! }
+//! ```
+//!
+//! This iterator yields mutable references to the slice's elements, so while the element
+//! type of the slice is `i32`, the element type of the iterator is `&mut i32`.
+//!
+//! * `.iter()` and `.iter_mut()` are the explicit methods to return the default
+//!   iterators.
+//! * Further methods that return iterators are `.split()`, `.splitn()`,
+//!   `.chunks()`, `.windows()` and more.
 #![doc(primitive = "slice")]
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use alloc::boxed::Box;
+use core::convert::AsRef;
 use core::clone::Clone;
 use core::cmp::Ordering::{self, Greater, Less};
 use core::cmp::{self, Ord, PartialEq};
-use core::iter::{Iterator, IteratorExt};
-use core::iter::{range_step, MultiplicativeIterator};
+use core::iter::Iterator;
+use core::iter::MultiplicativeIterator;
 use core::marker::Sized;
 use core::mem::size_of;
 use core::mem;
 use core::ops::FnMut;
 use core::option::Option::{self, Some, None};
-use core::ptr::PtrExt;
 use core::ptr;
 use core::result::Result;
 use core::slice as core_slice;
@@ -113,18 +105,124 @@ pub use core::slice::{IntSliceExt, SplitMut, ChunksMut, Split};
 pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
 pub use core::slice::{bytes, mut_ref_slice, ref_slice};
 pub use core::slice::{from_raw_parts, from_raw_parts_mut};
-pub use core::slice::{from_raw_buf, from_raw_mut_buf};
 
 ////////////////////////////////////////////////////////////////////////////////
 // Basic slice extension methods
 ////////////////////////////////////////////////////////////////////////////////
 
+// HACK(japaric) needed for the implementation of `vec!` macro during testing
+// NB see the hack module in this file for more details
+#[cfg(test)]
+pub use self::hack::into_vec;
+
+// HACK(japaric) needed for the implementation of `Vec::clone` during testing
+// NB see the hack module in this file for more details
+#[cfg(test)]
+pub use self::hack::to_vec;
+
+// HACK(japaric): With cfg(test) `impl [T]` is not available, these three
+// functions are actually methods that are in `impl [T]` but not in
+// `core::slice::SliceExt` - we need to supply these functions for the
+// `test_permutations` test
+mod hack {
+    use alloc::boxed::Box;
+    use core::clone::Clone;
+    #[cfg(test)]
+    use core::iter::Iterator;
+    use core::mem;
+    #[cfg(test)]
+    use core::option::Option::{Some, None};
+
+    #[cfg(test)]
+    use string::ToString;
+    use vec::Vec;
+
+    use super::{ElementSwaps, Permutations};
+
+    pub fn into_vec<T>(mut b: Box<[T]>) -> Vec<T> {
+        unsafe {
+            let xs = Vec::from_raw_parts(b.as_mut_ptr(), b.len(), b.len());
+            mem::forget(b);
+            xs
+        }
+    }
+
+    pub fn permutations<T>(s: &[T]) -> Permutations<T> where T: Clone {
+        Permutations{
+            swaps: ElementSwaps::new(s.len()),
+            v: to_vec(s),
+        }
+    }
+
+    #[inline]
+    pub fn to_vec<T>(s: &[T]) -> Vec<T> where T: Clone {
+        let mut vector = Vec::with_capacity(s.len());
+        vector.push_all(s);
+        vector
+    }
+
+    // NB we can remove this hack if we move this test to libcollectionstest -
+    // but that can't be done right now because the test needs access to the
+    // private fields of Permutations
+    #[test]
+    fn test_permutations() {
+        {
+            let v: [i32; 0] = [];
+            let mut it = permutations(&v);
+            let (min_size, max_opt) = it.size_hint();
+            assert_eq!(min_size, 1);
+            assert_eq!(max_opt.unwrap(), 1);
+            assert_eq!(it.next(), Some(to_vec(&v)));
+            assert_eq!(it.next(), None);
+        }
+        {
+            let v = ["Hello".to_string()];
+            let mut it = permutations(&v);
+            let (min_size, max_opt) = it.size_hint();
+            assert_eq!(min_size, 1);
+            assert_eq!(max_opt.unwrap(), 1);
+            assert_eq!(it.next(), Some(to_vec(&v)));
+            assert_eq!(it.next(), None);
+        }
+        {
+            let v = [1, 2, 3];
+            let mut it = permutations(&v);
+            let (min_size, max_opt) = it.size_hint();
+            assert_eq!(min_size, 3*2);
+            assert_eq!(max_opt.unwrap(), 3*2);
+            assert_eq!(it.next().unwrap(), [1,2,3]);
+            assert_eq!(it.next().unwrap(), [1,3,2]);
+            assert_eq!(it.next().unwrap(), [3,1,2]);
+            let (min_size, max_opt) = it.size_hint();
+            assert_eq!(min_size, 3);
+            assert_eq!(max_opt.unwrap(), 3);
+            assert_eq!(it.next().unwrap(), [3,2,1]);
+            assert_eq!(it.next().unwrap(), [2,3,1]);
+            assert_eq!(it.next().unwrap(), [2,1,3]);
+            assert_eq!(it.next(), None);
+        }
+        {
+            // check that we have N! permutations
+            let v = ['A', 'B', 'C', 'D', 'E', 'F'];
+            let mut amt = 0;
+            let mut it = permutations(&v);
+            let (min_size, max_opt) = it.size_hint();
+            for _perm in it.by_ref() {
+                amt += 1;
+            }
+            assert_eq!(amt, it.swaps.swaps_made);
+            assert_eq!(amt, min_size);
+            assert_eq!(amt, 2 * 3 * 4 * 5 * 6);
+            assert_eq!(amt, max_opt.unwrap());
+        }
+    }
+}
+
 /// Allocating extension methods for slices.
+#[lang = "slice"]
+#[cfg(not(test))]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub trait SliceExt {
-    #[stable(feature = "rust1", since = "1.0.0")]
-    type Item;
-
+impl<T> [T] {
     /// Sorts the slice, in place, using `compare` to compare
     /// elements.
     ///
@@ -143,7 +241,10 @@ pub trait SliceExt {
     /// assert!(v == [5, 4, 3, 2, 1]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn sort_by<F>(&mut self, compare: F) where F: FnMut(&Self::Item, &Self::Item) -> Ordering;
+    #[inline]
+    pub fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering {
+        merge_sort(self, compare)
+    }
 
     /// Consumes `src` and moves as many elements as it can into `self`
     /// from the range [start,end).
@@ -160,6 +261,7 @@ pub trait SliceExt {
     /// # Examples
     ///
     /// ```rust
+    /// # #![feature(collections)]
     /// let mut a = [1, 2, 3, 4, 5];
     /// let b = vec![6, 7, 8];
     /// let num_moved = a.move_from(b, 0, 3);
@@ -168,25 +270,13 @@ pub trait SliceExt {
     /// ```
     #[unstable(feature = "collections",
                reason = "uncertain about this API approach")]
-    fn move_from(&mut self, src: Vec<Self::Item>, start: usize, end: usize) -> usize;
-
-    /// Deprecated: use `&s[start .. end]` notation instead.
-    #[unstable(feature = "collections",
-               reason = "will be replaced by slice syntax")]
-    #[deprecated(since = "1.0.0", reason = "use &s[start .. end] instead")]
-    fn slice(&self, start: usize, end: usize) -> &[Self::Item];
-
-    /// Deprecated: use `&s[start..]` notation instead.
-    #[unstable(feature = "collections",
-               reason = "will be replaced by slice syntax")]
-    #[deprecated(since = "1.0.0", reason = "use &s[start..] instead")]
-    fn slice_from(&self, start: usize) -> &[Self::Item];
-
-    /// Deprecated: use `&s[..end]` notation instead.
-    #[unstable(feature = "collections",
-               reason = "will be replaced by slice syntax")]
-    #[deprecated(since = "1.0.0", reason = "use &s[..end] instead")]
-    fn slice_to(&self, end: usize) -> &[Self::Item];
+    #[inline]
+    pub fn move_from(&mut self, mut src: Vec<T>, start: usize, end: usize) -> usize {
+        for (a, b) in self.iter_mut().zip(src[start .. end].iter_mut()) {
+            mem::swap(a, b);
+        }
+        cmp::min(self.len(), end-start)
+    }
 
     /// Divides one slice into two at an index.
     ///
@@ -205,11 +295,17 @@ pub trait SliceExt {
     /// assert_eq!([30, 20, 50], v2);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn split_at(&self, mid: usize) -> (&[Self::Item], &[Self::Item]);
+    #[inline]
+    pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
+        core_slice::SliceExt::split_at(self, mid)
+    }
 
     /// Returns an iterator over the slice.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn iter(&self) -> Iter<Self::Item>;
+    #[inline]
+    pub fn iter(&self) -> Iter<T> {
+        core_slice::SliceExt::iter(self)
+    }
 
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`.  The matched element is not contained in the subslices.
@@ -226,13 +322,18 @@ pub trait SliceExt {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn split<F>(&self, pred: F) -> Split<Self::Item, F>
-                where F: FnMut(&Self::Item) -> bool;
+    #[inline]
+    pub fn split<F>(&self, pred: F) -> Split<T, F> where F: FnMut(&T) -> bool {
+        core_slice::SliceExt::split(self, pred)
+    }
 
     /// Returns an iterator over subslices separated by elements that match
-    /// `pred`, limited to splitting at most `n` times.  The matched element is
+    /// `pred`, limited to returning at most `n` items.  The matched element is
     /// not contained in the subslices.
     ///
+    /// The last element returned, if any, will contain the remainder of the
+    /// slice.
+    ///
     /// # Examples
     ///
     /// Print the slice split once by numbers divisible by 3 (i.e. `[10, 40]`,
@@ -240,19 +341,24 @@ pub trait SliceExt {
     ///
     /// ```
     /// let v = [10, 40, 30, 20, 60, 50];
-    /// for group in v.splitn(1, |num| *num % 3 == 0) {
+    /// for group in v.splitn(2, |num| *num % 3 == 0) {
     ///     println!("{:?}", group);
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn splitn<F>(&self, n: usize, pred: F) -> SplitN<Self::Item, F>
-                 where F: FnMut(&Self::Item) -> bool;
+    #[inline]
+    pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<T, F> where F: FnMut(&T) -> bool {
+        core_slice::SliceExt::splitn(self, n, pred)
+    }
 
     /// Returns an iterator over subslices separated by elements that match
-    /// `pred` limited to splitting at most `n` times. This starts at the end of
+    /// `pred` limited to returning at most `n` items. This starts at the end of
     /// the slice and works backwards.  The matched element is not contained in
     /// the subslices.
     ///
+    /// The last element returned, if any, will contain the remainder of the
+    /// slice.
+    ///
     /// # Examples
     ///
     /// Print the slice split once, starting from the end, by numbers divisible
@@ -260,13 +366,15 @@ pub trait SliceExt {
     ///
     /// ```
     /// let v = [10, 40, 30, 20, 60, 50];
-    /// for group in v.rsplitn(1, |num| *num % 3 == 0) {
+    /// for group in v.rsplitn(2, |num| *num % 3 == 0) {
     ///     println!("{:?}", group);
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<Self::Item, F>
-                  where F: FnMut(&Self::Item) -> bool;
+    #[inline]
+    pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<T, F> where F: FnMut(&T) -> bool {
+        core_slice::SliceExt::rsplitn(self, n, pred)
+    }
 
     /// Returns an iterator over all contiguous windows of length
     /// `size`. The windows overlap. If the slice is shorter than
@@ -288,7 +396,10 @@ pub trait SliceExt {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn windows(&self, size: usize) -> Windows<Self::Item>;
+    #[inline]
+    pub fn windows(&self, size: usize) -> Windows<T> {
+        core_slice::SliceExt::windows(self, size)
+    }
 
     /// Returns an iterator over `size` elements of the slice at a
     /// time. The chunks do not overlap. If `size` does not divide the
@@ -311,7 +422,10 @@ pub trait SliceExt {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn chunks(&self, size: usize) -> Chunks<Self::Item>;
+    #[inline]
+    pub fn chunks(&self, size: usize) -> Chunks<T> {
+        core_slice::SliceExt::chunks(self, size)
+    }
 
     /// Returns the element of a slice at the given index, or `None` if the
     /// index is out of bounds.
@@ -324,7 +438,10 @@ pub trait SliceExt {
     /// assert_eq!(None, v.get(3));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn get(&self, index: usize) -> Option<&Self::Item>;
+    #[inline]
+    pub fn get(&self, index: usize) -> Option<&T> {
+        core_slice::SliceExt::get(self, index)
+    }
 
     /// Returns the first element of a slice, or `None` if it is empty.
     ///
@@ -338,15 +455,24 @@ pub trait SliceExt {
     /// assert_eq!(None, w.first());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn first(&self) -> Option<&Self::Item>;
+    #[inline]
+    pub fn first(&self) -> Option<&T> {
+        core_slice::SliceExt::first(self)
+    }
 
     /// Returns all but the first element of a slice.
     #[unstable(feature = "collections", reason = "likely to be renamed")]
-    fn tail(&self) -> &[Self::Item];
+    #[inline]
+    pub fn tail(&self) -> &[T] {
+        core_slice::SliceExt::tail(self)
+    }
 
     /// Returns all but the last element of a slice.
     #[unstable(feature = "collections", reason = "likely to be renamed")]
-    fn init(&self) -> &[Self::Item];
+    #[inline]
+    pub fn init(&self) -> &[T] {
+        core_slice::SliceExt::init(self)
+    }
 
     /// Returns the last element of a slice, or `None` if it is empty.
     ///
@@ -360,12 +486,18 @@ pub trait SliceExt {
     /// assert_eq!(None, w.last());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn last(&self) -> Option<&Self::Item>;
+    #[inline]
+    pub fn last(&self) -> Option<&T> {
+        core_slice::SliceExt::last(self)
+    }
 
     /// Returns a pointer to the element at the given index, without doing
     /// bounds checking.
     #[stable(feature = "rust1", since = "1.0.0")]
-    unsafe fn get_unchecked(&self, index: usize) -> &Self::Item;
+    #[inline]
+    pub unsafe fn get_unchecked(&self, index: usize) -> &T {
+        core_slice::SliceExt::get_unchecked(self, index)
+    }
 
     /// Returns an unsafe pointer to the slice's buffer
     ///
@@ -375,7 +507,10 @@ pub trait SliceExt {
     /// Modifying the slice may cause its buffer to be reallocated, which
     /// would also make any pointers to it invalid.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn as_ptr(&self) -> *const Self::Item;
+    #[inline]
+    pub fn as_ptr(&self) -> *const T {
+        core_slice::SliceExt::as_ptr(self)
+    }
 
     /// Binary search a sorted slice with a comparator function.
     ///
@@ -396,8 +531,8 @@ pub trait SliceExt {
     /// found; the fourth could match any position in `[1,4]`.
     ///
     /// ```rust
+    /// # #![feature(core)]
     /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
-    /// let s = s.as_slice();
     ///
     /// let seek = 13;
     /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
@@ -410,8 +545,10 @@ pub trait SliceExt {
     /// assert!(match r { Ok(1...4) => true, _ => false, });
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn binary_search_by<F>(&self, f: F) -> Result<usize, usize> where
-        F: FnMut(&Self::Item) -> Ordering;
+    #[inline]
+    pub fn binary_search_by<F>(&self, f: F) -> Result<usize, usize> where F: FnMut(&T) -> Ordering {
+        core_slice::SliceExt::binary_search_by(self, f)
+    }
 
     /// Return the number of elements in the slice
     ///
@@ -422,7 +559,10 @@ pub trait SliceExt {
     /// assert_eq!(a.len(), 3);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn len(&self) -> usize;
+    #[inline]
+    pub fn len(&self) -> usize {
+        core_slice::SliceExt::len(self)
+    }
 
     /// Returns true if the slice has a length of 0
     ///
@@ -432,79 +572,91 @@ pub trait SliceExt {
     /// let a = [1, 2, 3];
     /// assert!(!a.is_empty());
     /// ```
-    #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_empty(&self) -> bool { self.len() == 0 }
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        core_slice::SliceExt::is_empty(self)
+    }
+
     /// Returns a mutable reference to the element at the given index,
     /// or `None` if the index is out of bounds
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn get_mut(&mut self, index: usize) -> Option<&mut Self::Item>;
-
-    /// Work with `self` as a mut slice.
-    /// Primarily intended for getting a &mut [T] from a [T; N].
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn as_mut_slice(&mut self) -> &mut [Self::Item];
-
-    /// Deprecated: use `&mut s[start .. end]` instead.
-    #[unstable(feature = "collections",
-               reason = "will be replaced by slice syntax")]
-    #[deprecated(since = "1.0.0", reason = "use &mut s[start .. end] instead")]
-    fn slice_mut(&mut self, start: usize, end: usize) -> &mut [Self::Item];
-
-    /// Deprecated: use `&mut s[start ..]` instead.
-    #[unstable(feature = "collections",
-               reason = "will be replaced by slice syntax")]
-    #[deprecated(since = "1.0.0", reason = "use &mut s[start ..] instead")]
-    fn slice_from_mut(&mut self, start: usize) -> &mut [Self::Item];
-
-    /// Deprecated: use `&mut s[.. end]` instead.
-    #[unstable(feature = "collections",
-               reason = "will be replaced by slice syntax")]
-    #[deprecated(since = "1.0.0", reason = "use &mut s[.. end] instead")]
-    fn slice_to_mut(&mut self, end: usize) -> &mut [Self::Item];
+    #[inline]
+    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
+        core_slice::SliceExt::get_mut(self, index)
+    }
 
     /// Returns an iterator that allows modifying each value
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn iter_mut(&mut self) -> IterMut<Self::Item>;
+    #[inline]
+    pub fn iter_mut(&mut self) -> IterMut<T> {
+        core_slice::SliceExt::iter_mut(self)
+    }
 
     /// Returns a mutable pointer to the first element of a slice, or `None` if it is empty
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn first_mut(&mut self) -> Option<&mut Self::Item>;
+    #[inline]
+    pub fn first_mut(&mut self) -> Option<&mut T> {
+        core_slice::SliceExt::first_mut(self)
+    }
 
     /// Returns all but the first element of a mutable slice
     #[unstable(feature = "collections",
                reason = "likely to be renamed or removed")]
-    fn tail_mut(&mut self) -> &mut [Self::Item];
+    #[inline]
+    pub fn tail_mut(&mut self) -> &mut [T] {
+        core_slice::SliceExt::tail_mut(self)
+    }
 
     /// Returns all but the last element of a mutable slice
     #[unstable(feature = "collections",
                reason = "likely to be renamed or removed")]
-    fn init_mut(&mut self) -> &mut [Self::Item];
+    #[inline]
+    pub fn init_mut(&mut self) -> &mut [T] {
+        core_slice::SliceExt::init_mut(self)
+    }
 
     /// Returns a mutable pointer to the last item in the slice.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn last_mut(&mut self) -> Option<&mut Self::Item>;
+    #[inline]
+    pub fn last_mut(&mut self) -> Option<&mut T> {
+        core_slice::SliceExt::last_mut(self)
+    }
 
     /// Returns an iterator over mutable subslices separated by elements that
     /// match `pred`.  The matched element is not contained in the subslices.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn split_mut<F>(&mut self, pred: F) -> SplitMut<Self::Item, F>
-                    where F: FnMut(&Self::Item) -> bool;
+    #[inline]
+    pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F> where F: FnMut(&T) -> bool {
+        core_slice::SliceExt::split_mut(self, pred)
+    }
 
     /// Returns an iterator over subslices separated by elements that match
-    /// `pred`, limited to splitting at most `n` times.  The matched element is
+    /// `pred`, limited to returning at most `n` items.  The matched element is
     /// not contained in the subslices.
+    ///
+    /// The last element returned, if any, will contain the remainder of the
+    /// slice.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<Self::Item, F>
-                     where F: FnMut(&Self::Item) -> bool;
+    #[inline]
+    pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<T, F>
+                         where F: FnMut(&T) -> bool {
+        core_slice::SliceExt::splitn_mut(self, n, pred)
+    }
 
     /// Returns an iterator over subslices separated by elements that match
-    /// `pred` limited to splitting at most `n` times. This starts at the end of
+    /// `pred` limited to returning at most `n` items. This starts at the end of
     /// the slice and works backwards.  The matched element is not contained in
     /// the subslices.
+    ///
+    /// The last element returned, if any, will contain the remainder of the
+    /// slice.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn rsplitn_mut<F>(&mut self,  n: usize, pred: F) -> RSplitNMut<Self::Item, F>
-                      where F: FnMut(&Self::Item) -> bool;
+    #[inline]
+    pub fn rsplitn_mut<F>(&mut self,  n: usize, pred: F) -> RSplitNMut<T, F>
+                      where F: FnMut(&T) -> bool {
+        core_slice::SliceExt::rsplitn_mut(self, n, pred)
+    }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time.
     /// The chunks are mutable and do not overlap. If `chunk_size` does
@@ -515,7 +667,10 @@ pub trait SliceExt {
     ///
     /// Panics if `chunk_size` is 0.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<Self::Item>;
+    #[inline]
+    pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
+        core_slice::SliceExt::chunks_mut(self, chunk_size)
+    }
 
     /// Swaps two elements in a slice.
     ///
@@ -536,7 +691,10 @@ pub trait SliceExt {
     /// assert!(v == ["a", "d", "c", "b"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn swap(&mut self, a: usize, b: usize);
+    #[inline]
+    pub fn swap(&mut self, a: usize, b: usize) {
+        core_slice::SliceExt::swap(self, a, b)
+    }
 
     /// Divides one `&mut` into two at an index.
     ///
@@ -573,7 +731,10 @@ pub trait SliceExt {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn split_at_mut(&mut self, mid: usize) -> (&mut [Self::Item], &mut [Self::Item]);
+    #[inline]
+    pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
+        core_slice::SliceExt::split_at_mut(self, mid)
+    }
 
     /// Reverse the order of elements in a slice, in place.
     ///
@@ -585,11 +746,17 @@ pub trait SliceExt {
     /// assert!(v == [3, 2, 1]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn reverse(&mut self);
+    #[inline]
+    pub fn reverse(&mut self) {
+        core_slice::SliceExt::reverse(self)
+    }
 
     /// Returns an unsafe mutable pointer to the element in index
     #[stable(feature = "rust1", since = "1.0.0")]
-    unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut Self::Item;
+    #[inline]
+    pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
+        core_slice::SliceExt::get_unchecked_mut(self, index)
+    }
 
     /// Return an unsafe mutable pointer to the slice's buffer.
     ///
@@ -598,13 +765,19 @@ pub trait SliceExt {
     ///
     /// Modifying the slice may cause its buffer to be reallocated, which
     /// would also make any pointers to it invalid.
-    #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn as_mut_ptr(&mut self) -> *mut Self::Item;
+    #[inline]
+    pub fn as_mut_ptr(&mut self) -> *mut T {
+        core_slice::SliceExt::as_mut_ptr(self)
+    }
 
     /// Copies `self` into a new `Vec`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn to_vec(&self) -> Vec<Self::Item> where Self::Item: Clone;
+    #[inline]
+    pub fn to_vec(&self) -> Vec<T> where T: Clone {
+        // NB see hack module in this file
+        hack::to_vec(self)
+    }
 
     /// Creates an iterator that yields every possible permutation of the
     /// vector in succession.
@@ -612,6 +785,7 @@ pub trait SliceExt {
     /// # Examples
     ///
     /// ```rust
+    /// # #![feature(collections)]
     /// let v = [1, 2, 3];
     /// let mut perms = v.permutations();
     ///
@@ -623,6 +797,7 @@ pub trait SliceExt {
     /// Iterating through permutations one by one.
     ///
     /// ```rust
+    /// # #![feature(collections)]
     /// let v = [1, 2, 3];
     /// let mut perms = v.permutations();
     ///
@@ -631,7 +806,11 @@ pub trait SliceExt {
     /// assert_eq!(Some(vec![3, 1, 2]), perms.next());
     /// ```
     #[unstable(feature = "collections")]
-    fn permutations(&self) -> Permutations<Self::Item> where Self::Item: Clone;
+    #[inline]
+    pub fn permutations(&self) -> Permutations<T> where T: Clone {
+        // NB see hack module in this file
+        hack::permutations(self)
+    }
 
     /// Copies as many elements from `src` as it can into `self` (the
     /// shorter of `self.len()` and `src.len()`). Returns the number
@@ -640,6 +819,7 @@ pub trait SliceExt {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(collections)]
     /// let mut dst = [0, 0, 0];
     /// let src = [1, 2];
     ///
@@ -651,7 +831,9 @@ pub trait SliceExt {
     /// assert!(dst == [3, 4, 5]);
     /// ```
     #[unstable(feature = "collections")]
-    fn clone_from_slice(&mut self, &[Self::Item]) -> usize where Self::Item: Clone;
+    pub fn clone_from_slice(&mut self, src: &[T]) -> usize where T: Clone {
+        core_slice::SliceExt::clone_from_slice(self, src)
+    }
 
     /// Sorts the slice, in place.
     ///
@@ -666,7 +848,10 @@ pub trait SliceExt {
     /// assert!(v == [-5, -3, 1, 2, 4]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn sort(&mut self) where Self::Item: Ord;
+    #[inline]
+    pub fn sort(&mut self) where T: Ord {
+        self.sort_by(|a, b| a.cmp(b))
+    }
 
     /// Binary search a sorted slice for a given element.
     ///
@@ -682,8 +867,8 @@ pub trait SliceExt {
     /// found; the fourth could match any position in `[1,4]`.
     ///
     /// ```rust
+    /// # #![feature(core)]
     /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
-    /// let s = s.as_slice();
     ///
     /// assert_eq!(s.binary_search(&13),  Ok(9));
     /// assert_eq!(s.binary_search(&4),   Err(7));
@@ -692,13 +877,8 @@ pub trait SliceExt {
     /// assert!(match r { Ok(1...4) => true, _ => false, });
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn binary_search(&self, x: &Self::Item) -> Result<usize, usize> where Self::Item: Ord;
-
-    /// Deprecated: use `binary_search` instead.
-    #[unstable(feature = "collections")]
-    #[deprecated(since = "1.0.0", reason = "use binary_search instead")]
-    fn binary_search_elem(&self, x: &Self::Item) -> Result<usize, usize> where Self::Item: Ord {
-        self.binary_search(x)
+    pub fn binary_search(&self, x: &T) -> Result<usize, usize> where T: Ord {
+        core_slice::SliceExt::binary_search(self, x)
     }
 
     /// Mutates the slice to the next lexicographic permutation.
@@ -709,6 +889,7 @@ pub trait SliceExt {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(collections)]
     /// let v: &mut [_] = &mut [0, 1, 2];
     /// v.next_permutation();
     /// let b: &mut [_] = &mut [0, 2, 1];
@@ -719,7 +900,9 @@ pub trait SliceExt {
     /// ```
     #[unstable(feature = "collections",
                reason = "uncertain if this merits inclusion in std")]
-    fn next_permutation(&mut self) -> bool where Self::Item: Ord;
+    pub fn next_permutation(&mut self) -> bool where T: Ord {
+        core_slice::SliceExt::next_permutation(self)
+    }
 
     /// Mutates the slice to the previous lexicographic permutation.
     ///
@@ -729,6 +912,7 @@ pub trait SliceExt {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(collections)]
     /// let v: &mut [_] = &mut [1, 0, 2];
     /// v.prev_permutation();
     /// let b: &mut [_] = &mut [0, 2, 1];
@@ -739,15 +923,21 @@ pub trait SliceExt {
     /// ```
     #[unstable(feature = "collections",
                reason = "uncertain if this merits inclusion in std")]
-    fn prev_permutation(&mut self) -> bool where Self::Item: Ord;
+    pub fn prev_permutation(&mut self) -> bool where T: Ord {
+        core_slice::SliceExt::prev_permutation(self)
+    }
 
     /// Find the first index containing a matching value.
     #[unstable(feature = "collections")]
-    fn position_elem(&self, t: &Self::Item) -> Option<usize> where Self::Item: PartialEq;
+    pub fn position_elem(&self, t: &T) -> Option<usize> where T: PartialEq {
+        core_slice::SliceExt::position_elem(self, t)
+    }
 
     /// Find the last index containing a matching value.
     #[unstable(feature = "collections")]
-    fn rposition_elem(&self, t: &Self::Item) -> Option<usize> where Self::Item: PartialEq;
+    pub fn rposition_elem(&self, t: &T) -> Option<usize> where T: PartialEq {
+        core_slice::SliceExt::rposition_elem(self, t)
+    }
 
     /// Returns true if the slice contains an element with the given value.
     ///
@@ -759,7 +949,9 @@ pub trait SliceExt {
     /// assert!(!v.contains(&50));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq;
+    pub fn contains(&self, x: &T) -> bool where T: PartialEq {
+        core_slice::SliceExt::contains(self, x)
+    }
 
     /// Returns true if `needle` is a prefix of the slice.
     ///
@@ -773,7 +965,9 @@ pub trait SliceExt {
     /// assert!(!v.starts_with(&[10, 50]));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
+    pub fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq {
+        core_slice::SliceExt::starts_with(self, needle)
+    }
 
     /// Returns true if `needle` is a suffix of the slice.
     ///
@@ -787,297 +981,18 @@ pub trait SliceExt {
     /// assert!(!v.ends_with(&[50, 30]));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
-
-    /// Convert `self` into a vector without clones or allocation.
-    #[unstable(feature = "collections")]
-    fn into_vec(self: Box<Self>) -> Vec<Self::Item>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> SliceExt for [T] {
-    type Item = T;
-
-    #[inline]
-    fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering {
-        merge_sort(self, compare)
-    }
-
-    #[inline]
-    fn move_from(&mut self, mut src: Vec<T>, start: usize, end: usize) -> usize {
-        for (a, b) in self.iter_mut().zip(src[start .. end].iter_mut()) {
-            mem::swap(a, b);
-        }
-        cmp::min(self.len(), end-start)
-    }
-
-    #[inline]
-    fn slice(&self, start: usize, end: usize) -> &[T] {
-        &self[start .. end]
+    pub fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq {
+        core_slice::SliceExt::ends_with(self, needle)
     }
 
+    /// Convert `self` into a vector without clones or allocation.
+    #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    fn slice_from(&self, start: usize) -> &[T] {
-        &self[start ..]
+    pub fn into_vec(self: Box<Self>) -> Vec<T> {
+        // NB see hack module in this file
+        hack::into_vec(self)
     }
-
-    #[inline]
-    fn slice_to(&self, end: usize) -> &[T] {
-        &self[.. end]
-    }
-
-    #[inline]
-    fn split_at(&self, mid: usize) -> (&[T], &[T]) {
-        core_slice::SliceExt::split_at(self, mid)
-    }
-
-    #[inline]
-    fn iter(&self) -> Iter<T> {
-        core_slice::SliceExt::iter(self)
-    }
-
-    #[inline]
-    fn split<F>(&self, pred: F) -> Split<T, F>
-                where F: FnMut(&T) -> bool {
-        core_slice::SliceExt::split(self, pred)
-    }
-
-    #[inline]
-    fn splitn<F>(&self, n: usize, pred: F) -> SplitN<T, F>
-                 where F: FnMut(&T) -> bool {
-        core_slice::SliceExt::splitn(self, n, pred)
-    }
-
-    #[inline]
-    fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<T, F>
-                  where F: FnMut(&T) -> bool {
-        core_slice::SliceExt::rsplitn(self, n, pred)
-    }
-
-    #[inline]
-    fn windows(&self, size: usize) -> Windows<T> {
-        core_slice::SliceExt::windows(self, size)
-    }
-
-    #[inline]
-    fn chunks(&self, size: usize) -> Chunks<T> {
-        core_slice::SliceExt::chunks(self, size)
-    }
-
-    #[inline]
-    fn get(&self, index: usize) -> Option<&T> {
-        core_slice::SliceExt::get(self, index)
-    }
-
-    #[inline]
-    fn first(&self) -> Option<&T> {
-        core_slice::SliceExt::first(self)
-    }
-
-    #[inline]
-    fn tail(&self) -> &[T] {
-        core_slice::SliceExt::tail(self)
-    }
-
-    #[inline]
-    fn init(&self) -> &[T] {
-        core_slice::SliceExt::init(self)
-    }
-
-    #[inline]
-    fn last(&self) -> Option<&T> {
-        core_slice::SliceExt::last(self)
-    }
-
-    #[inline]
-    unsafe fn get_unchecked(&self, index: usize) -> &T {
-        core_slice::SliceExt::get_unchecked(self, index)
-    }
-
-    #[inline]
-    fn as_ptr(&self) -> *const T {
-        core_slice::SliceExt::as_ptr(self)
-    }
-
-    #[inline]
-    fn binary_search_by<F>(&self, f: F) -> Result<usize, usize>
-                        where F: FnMut(&T) -> Ordering {
-        core_slice::SliceExt::binary_search_by(self, f)
-    }
-
-    #[inline]
-    fn len(&self) -> usize {
-        core_slice::SliceExt::len(self)
-    }
-
-    #[inline]
-    fn is_empty(&self) -> bool {
-        core_slice::SliceExt::is_empty(self)
-    }
-
-    #[inline]
-    fn get_mut(&mut self, index: usize) -> Option<&mut T> {
-        core_slice::SliceExt::get_mut(self, index)
-    }
-
-    #[inline]
-    fn as_mut_slice(&mut self) -> &mut [T] {
-        core_slice::SliceExt::as_mut_slice(self)
-    }
-
-    #[inline]
-    fn slice_mut(&mut self, start: usize, end: usize) -> &mut [T] {
-        &mut self[start .. end]
-    }
-
-    #[inline]
-    fn slice_from_mut(&mut self, start: usize) -> &mut [T] {
-        &mut self[start ..]
-    }
-
-    #[inline]
-    fn slice_to_mut(&mut self, end: usize) -> &mut [T] {
-        &mut self[.. end]
-    }
-
-    #[inline]
-    fn iter_mut(&mut self) -> IterMut<T> {
-        core_slice::SliceExt::iter_mut(self)
-    }
-
-    #[inline]
-    fn first_mut(&mut self) -> Option<&mut T> {
-        core_slice::SliceExt::first_mut(self)
-    }
-
-    #[inline]
-    fn tail_mut(&mut self) -> &mut [T] {
-        core_slice::SliceExt::tail_mut(self)
-    }
-
-    #[inline]
-    fn init_mut(&mut self) -> &mut [T] {
-        core_slice::SliceExt::init_mut(self)
-    }
-
-    #[inline]
-    fn last_mut(&mut self) -> Option<&mut T> {
-        core_slice::SliceExt::last_mut(self)
-    }
-
-    #[inline]
-    fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F>
-                    where F: FnMut(&T) -> bool {
-        core_slice::SliceExt::split_mut(self, pred)
-    }
-
-    #[inline]
-    fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<T, F>
-                     where F: FnMut(&T) -> bool {
-        core_slice::SliceExt::splitn_mut(self, n, pred)
-    }
-
-    #[inline]
-    fn rsplitn_mut<F>(&mut self,  n: usize, pred: F) -> RSplitNMut<T, F>
-                      where F: FnMut(&T) -> bool {
-        core_slice::SliceExt::rsplitn_mut(self, n, pred)
-    }
-
-    #[inline]
-    fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
-        core_slice::SliceExt::chunks_mut(self, chunk_size)
-    }
-
-    #[inline]
-    fn swap(&mut self, a: usize, b: usize) {
-        core_slice::SliceExt::swap(self, a, b)
-    }
-
-    #[inline]
-    fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
-        core_slice::SliceExt::split_at_mut(self, mid)
-    }
-
-    #[inline]
-    fn reverse(&mut self) {
-        core_slice::SliceExt::reverse(self)
-    }
-
-    #[inline]
-    unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
-        core_slice::SliceExt::get_unchecked_mut(self, index)
-    }
-
-    #[inline]
-    fn as_mut_ptr(&mut self) -> *mut T {
-        core_slice::SliceExt::as_mut_ptr(self)
-    }
-
-    /// Returns a copy of `v`.
-    #[inline]
-    fn to_vec(&self) -> Vec<T> where T: Clone {
-        let mut vector = Vec::with_capacity(self.len());
-        vector.push_all(self);
-        vector
-    }
-
-    /// Returns an iterator over all permutations of a vector.
-    fn permutations(&self) -> Permutations<T> where T: Clone {
-        Permutations{
-            swaps: ElementSwaps::new(self.len()),
-            v: self.to_vec(),
-        }
-    }
-
-    fn clone_from_slice(&mut self, src: &[T]) -> usize where T: Clone {
-        core_slice::SliceExt::clone_from_slice(self, src)
-    }
-
-    #[inline]
-    fn sort(&mut self) where T: Ord {
-        self.sort_by(|a, b| a.cmp(b))
-    }
-
-    fn binary_search(&self, x: &T) -> Result<usize, usize> where T: Ord {
-        core_slice::SliceExt::binary_search(self, x)
-    }
-
-    fn next_permutation(&mut self) -> bool where T: Ord {
-        core_slice::SliceExt::next_permutation(self)
-    }
-
-    fn prev_permutation(&mut self) -> bool where T: Ord {
-        core_slice::SliceExt::prev_permutation(self)
-    }
-
-    fn position_elem(&self, t: &T) -> Option<usize> where T: PartialEq {
-        core_slice::SliceExt::position_elem(self, t)
-    }
-
-    fn rposition_elem(&self, t: &T) -> Option<usize> where T: PartialEq {
-        core_slice::SliceExt::rposition_elem(self, t)
-    }
-
-    fn contains(&self, x: &T) -> bool where T: PartialEq {
-        core_slice::SliceExt::contains(self, x)
-    }
-
-    fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq {
-        core_slice::SliceExt::starts_with(self, needle)
-    }
-
-    fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq {
-        core_slice::SliceExt::ends_with(self, needle)
-    }
-
-    fn into_vec(mut self: Box<Self>) -> Vec<T> {
-        unsafe {
-            let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len());
-            mem::forget(self);
-            xs
-        }
-    }
-}
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // Extension traits for slices over specific kinds of data
@@ -1114,23 +1029,23 @@ pub trait SliceConcatExt<T: ?Sized, U> {
     fn connect(&self, sep: &T) -> U;
 }
 
-impl<T: Clone, V: AsSlice<T>> SliceConcatExt<T, Vec<T>> for [V] {
+impl<T: Clone, V: AsRef<[T]>> SliceConcatExt<T, Vec<T>> for [V] {
     fn concat(&self) -> Vec<T> {
-        let size = self.iter().fold(0, |acc, v| acc + v.as_slice().len());
+        let size = self.iter().fold(0, |acc, v| acc + v.as_ref().len());
         let mut result = Vec::with_capacity(size);
         for v in self {
-            result.push_all(v.as_slice())
+            result.push_all(v.as_ref())
         }
         result
     }
 
     fn connect(&self, sep: &T) -> Vec<T> {
-        let size = self.iter().fold(0, |acc, v| acc + v.as_slice().len());
+        let size = self.iter().fold(0, |acc, v| acc + v.as_ref().len());
         let mut result = Vec::with_capacity(size + self.len());
         let mut first = true;
         for v in self {
             if first { first = false } else { result.push(sep.clone()) }
-            result.push_all(v.as_slice())
+            result.push_all(v.as_ref())
         }
         result
     }
@@ -1188,7 +1103,15 @@ impl<T> BorrowMut<[T]> for Vec<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Clone> ToOwned for [T] {
     type Owned = Vec<T>;
+    #[cfg(not(test))]
     fn to_owned(&self) -> Vec<T> { self.to_vec() }
+
+    // HACK(japaric): with cfg(test) the inherent `[T]::to_vec`, which is required for this method
+    // definition, is not available. Since we don't require this method for testing purposes, I'll
+    // just stub it
+    // NB see the slice::hack module in slice.rs for more information
+    #[cfg(test)]
+    fn to_owned(&self) -> Vec<T> { panic!("not available with cfg(test)") }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1209,10 +1132,14 @@ struct SizeDirection {
 impl Iterator for ElementSwaps {
     type Item = (usize, usize);
 
-    #[inline]
+    // #[inline]
     fn next(&mut self) -> Option<(usize, usize)> {
+        fn new_pos_wrapping(i: usize, s: Direction) -> usize {
+            i.wrapping_add(match s { Pos => 1, Neg => !0 /* aka -1 */ })
+        }
+
         fn new_pos(i: usize, s: Direction) -> usize {
-            i + match s { Pos => 1, Neg => -1 }
+            match s { Pos => i + 1, Neg => i - 1 }
         }
 
         // Find the index of the largest mobile element:
@@ -1220,7 +1147,7 @@ impl Iterator for ElementSwaps {
         // swap should be with a smaller `size` element.
         let max = self.sdir.iter().cloned().enumerate()
                            .filter(|&(i, sd)|
-                                new_pos(i, sd.dir) < self.sdir.len() &&
+                                new_pos_wrapping(i, sd.dir) < self.sdir.len() &&
                                 self.sdir[new_pos(i, sd.dir)].size < sd.size)
                            .max_by(|&(_, sd)| sd.size);
         match max {
@@ -1331,12 +1258,10 @@ fn insertion_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> O
 
             if i != j {
                 let tmp = ptr::read(read_ptr);
-                ptr::copy_memory(buf_v.offset(j + 1),
-                                 &*buf_v.offset(j),
-                                 (i - j) as usize);
-                ptr::copy_nonoverlapping_memory(buf_v.offset(j),
-                                                &tmp,
-                                                1);
+                ptr::copy(&*buf_v.offset(j),
+                          buf_v.offset(j + 1),
+                          (i - j) as usize);
+                ptr::copy_nonoverlapping(&tmp, buf_v.offset(j), 1);
                 mem::forget(tmp);
             }
         }
@@ -1345,8 +1270,8 @@ fn insertion_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> O
 
 fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Ordering {
     // warning: this wildly uses unsafe.
-    static BASE_INSERTION: usize = 32;
-    static LARGE_INSERTION: usize = 16;
+    const BASE_INSERTION: usize = 32;
+    const LARGE_INSERTION: usize = 16;
 
     // FIXME #12092: smaller insertion runs seems to make sorting
     // vectors of large elements a little faster on some platforms,
@@ -1384,7 +1309,7 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
     // We could hardcode the sorting comparisons here, and we could
     // manipulate/step the pointers themselves, rather than repeatedly
     // .offset-ing.
-    for start in range_step(0, len, insertion) {
+    for start in (0.. len).step_by(insertion) {
         // start <= i < len;
         for i in start..cmp::min(start + insertion, len) {
             // j satisfies: start <= j <= i;
@@ -1409,10 +1334,10 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
                 // j + 1 could be `len` (for the last `i`), but in
                 // that case, `i == j` so we don't copy. The
                 // `.offset(j)` is always in bounds.
-                ptr::copy_memory(buf_dat.offset(j + 1),
-                                 &*buf_dat.offset(j),
-                                 i - j as usize);
-                ptr::copy_nonoverlapping_memory(buf_dat.offset(j), read_ptr, 1);
+                ptr::copy(&*buf_dat.offset(j),
+                          buf_dat.offset(j + 1),
+                          i - j as usize);
+                ptr::copy_nonoverlapping(read_ptr, buf_dat.offset(j), 1);
             }
         }
     }
@@ -1424,7 +1349,7 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
         // a time, placing the result in `buf_tmp`.
 
         // 0 <= start <= len.
-        for start in range_step(0, len, 2 * width) {
+        for start in (0..len).step_by(2 * width) {
             // manipulate pointers directly for speed (rather than
             // using a `for` loop with `range` and `.offset` inside
             // that loop).
@@ -1460,11 +1385,11 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
                     if left == right_start {
                         // the number remaining in this run.
                         let elems = (right_end as usize - right as usize) / mem::size_of::<T>();
-                        ptr::copy_nonoverlapping_memory(out, &*right, elems);
+                        ptr::copy_nonoverlapping(&*right, out, elems);
                         break;
                     } else if right == right_end {
                         let elems = (right_start as usize - left as usize) / mem::size_of::<T>();
-                        ptr::copy_nonoverlapping_memory(out, &*left, elems);
+                        ptr::copy_nonoverlapping(&*left, out, elems);
                         break;
                     }
 
@@ -1478,7 +1403,7 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
                     } else {
                         step(&mut left)
                     };
-                    ptr::copy_nonoverlapping_memory(out, &*to_copy, 1);
+                    ptr::copy_nonoverlapping(&*to_copy, out, 1);
                     step(&mut out);
                 }
             }
@@ -1492,7 +1417,7 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
     // write the result to `v` in one go, so that there are never two copies
     // of the same object in `v`.
     unsafe {
-        ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), &*buf_dat, len);
+        ptr::copy_nonoverlapping(&*buf_dat, v.as_mut_ptr(), len);
     }
 
     // increment the pointer, returning the old pointer.
@@ -1503,1631 +1428,3 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
         old
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use core::cmp::Ordering::{Greater, Less, Equal};
-    use core::prelude::{Some, None, Clone};
-    use core::prelude::{Iterator, IteratorExt};
-    use core::prelude::{AsSlice};
-    use core::prelude::Ord;
-    use core::default::Default;
-    use core::mem;
-    use std::iter::RandomAccessIterator;
-    use std::rand::{Rng, thread_rng};
-    use std::rc::Rc;
-    use string::ToString;
-    use vec::Vec;
-    use super::{ElementSwaps, SliceConcatExt, SliceExt};
-
-    fn square(n: usize) -> usize { n * n }
-
-    fn is_odd(n: &usize) -> bool { *n % 2 == 1 }
-
-    #[test]
-    fn test_from_fn() {
-        // Test on-stack from_fn.
-        let mut v: Vec<_> = (0..3).map(square).collect();
-        {
-            let v = v;
-            assert_eq!(v.len(), 3);
-            assert_eq!(v[0], 0);
-            assert_eq!(v[1], 1);
-            assert_eq!(v[2], 4);
-        }
-
-        // Test on-heap from_fn.
-        v = (0..5).map(square).collect();
-        {
-            let v = v;
-            assert_eq!(v.len(), 5);
-            assert_eq!(v[0], 0);
-            assert_eq!(v[1], 1);
-            assert_eq!(v[2], 4);
-            assert_eq!(v[3], 9);
-            assert_eq!(v[4], 16);
-        }
-    }
-
-    #[test]
-    fn test_from_elem() {
-        // Test on-stack from_elem.
-        let mut v = vec![10, 10];
-        {
-            let v = v;
-            assert_eq!(v.len(), 2);
-            assert_eq!(v[0], 10);
-            assert_eq!(v[1], 10);
-        }
-
-        // Test on-heap from_elem.
-        v = vec![20; 6];
-        {
-            let v = v.as_slice();
-            assert_eq!(v[0], 20);
-            assert_eq!(v[1], 20);
-            assert_eq!(v[2], 20);
-            assert_eq!(v[3], 20);
-            assert_eq!(v[4], 20);
-            assert_eq!(v[5], 20);
-        }
-    }
-
-    #[test]
-    fn test_is_empty() {
-        let xs: [i32; 0] = [];
-        assert!(xs.is_empty());
-        assert!(![0].is_empty());
-    }
-
-    #[test]
-    fn test_len_divzero() {
-        type Z = [i8; 0];
-        let v0 : &[Z] = &[];
-        let v1 : &[Z] = &[[]];
-        let v2 : &[Z] = &[[], []];
-        assert_eq!(mem::size_of::<Z>(), 0);
-        assert_eq!(v0.len(), 0);
-        assert_eq!(v1.len(), 1);
-        assert_eq!(v2.len(), 2);
-    }
-
-    #[test]
-    fn test_get() {
-        let mut a = vec![11];
-        assert_eq!(a.get(1), None);
-        a = vec![11, 12];
-        assert_eq!(a.get(1).unwrap(), &12);
-        a = vec![11, 12, 13];
-        assert_eq!(a.get(1).unwrap(), &12);
-    }
-
-    #[test]
-    fn test_first() {
-        let mut a = vec![];
-        assert_eq!(a.first(), None);
-        a = vec![11];
-        assert_eq!(a.first().unwrap(), &11);
-        a = vec![11, 12];
-        assert_eq!(a.first().unwrap(), &11);
-    }
-
-    #[test]
-    fn test_first_mut() {
-        let mut a = vec![];
-        assert_eq!(a.first_mut(), None);
-        a = vec![11];
-        assert_eq!(*a.first_mut().unwrap(), 11);
-        a = vec![11, 12];
-        assert_eq!(*a.first_mut().unwrap(), 11);
-    }
-
-    #[test]
-    fn test_tail() {
-        let mut a = vec![11];
-        let b: &[i32] = &[];
-        assert_eq!(a.tail(), b);
-        a = vec![11, 12];
-        let b: &[i32] = &[12];
-        assert_eq!(a.tail(), b);
-    }
-
-    #[test]
-    fn test_tail_mut() {
-        let mut a = vec![11];
-        let b: &mut [i32] = &mut [];
-        assert!(a.tail_mut() == b);
-        a = vec![11, 12];
-        let b: &mut [_] = &mut [12];
-        assert!(a.tail_mut() == b);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_tail_empty() {
-        let a = Vec::<i32>::new();
-        a.tail();
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_tail_mut_empty() {
-        let mut a = Vec::<i32>::new();
-        a.tail_mut();
-    }
-
-    #[test]
-    fn test_init() {
-        let mut a = vec![11];
-        let b: &[i32] = &[];
-        assert_eq!(a.init(), b);
-        a = vec![11, 12];
-        let b: &[_] = &[11];
-        assert_eq!(a.init(), b);
-    }
-
-    #[test]
-    fn test_init_mut() {
-        let mut a = vec![11];
-        let b: &mut [i32] = &mut [];
-        assert!(a.init_mut() == b);
-        a = vec![11, 12];
-        let b: &mut [_] = &mut [11];
-        assert!(a.init_mut() == b);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_init_empty() {
-        let a = Vec::<i32>::new();
-        a.init();
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_init_mut_empty() {
-        let mut a = Vec::<i32>::new();
-        a.init_mut();
-    }
-
-    #[test]
-    fn test_last() {
-        let mut a = vec![];
-        assert_eq!(a.last(), None);
-        a = vec![11];
-        assert_eq!(a.last().unwrap(), &11);
-        a = vec![11, 12];
-        assert_eq!(a.last().unwrap(), &12);
-    }
-
-    #[test]
-    fn test_last_mut() {
-        let mut a = vec![];
-        assert_eq!(a.last_mut(), None);
-        a = vec![11];
-        assert_eq!(*a.last_mut().unwrap(), 11);
-        a = vec![11, 12];
-        assert_eq!(*a.last_mut().unwrap(), 12);
-    }
-
-    #[test]
-    fn test_slice() {
-        // Test fixed length vector.
-        let vec_fixed = [1, 2, 3, 4];
-        let v_a = vec_fixed[1..vec_fixed.len()].to_vec();
-        assert_eq!(v_a.len(), 3);
-
-        assert_eq!(v_a[0], 2);
-        assert_eq!(v_a[1], 3);
-        assert_eq!(v_a[2], 4);
-
-        // Test on stack.
-        let vec_stack: &[_] = &[1, 2, 3];
-        let v_b = vec_stack[1..3].to_vec();
-        assert_eq!(v_b.len(), 2);
-
-        assert_eq!(v_b[0], 2);
-        assert_eq!(v_b[1], 3);
-
-        // Test `Box<[T]>`
-        let vec_unique = vec![1, 2, 3, 4, 5, 6];
-        let v_d = vec_unique[1..6].to_vec();
-        assert_eq!(v_d.len(), 5);
-
-        assert_eq!(v_d[0], 2);
-        assert_eq!(v_d[1], 3);
-        assert_eq!(v_d[2], 4);
-        assert_eq!(v_d[3], 5);
-        assert_eq!(v_d[4], 6);
-    }
-
-    #[test]
-    fn test_slice_from() {
-        let vec: &[_] = &[1, 2, 3, 4];
-        assert_eq!(&vec[..], vec);
-        let b: &[_] = &[3, 4];
-        assert_eq!(&vec[2..], b);
-        let b: &[_] = &[];
-        assert_eq!(&vec[4..], b);
-    }
-
-    #[test]
-    fn test_slice_to() {
-        let vec: &[_] = &[1, 2, 3, 4];
-        assert_eq!(&vec[..4], vec);
-        let b: &[_] = &[1, 2];
-        assert_eq!(&vec[..2], b);
-        let b: &[_] = &[];
-        assert_eq!(&vec[..0], b);
-    }
-
-
-    #[test]
-    fn test_pop() {
-        let mut v = vec![5];
-        let e = v.pop();
-        assert_eq!(v.len(), 0);
-        assert_eq!(e, Some(5));
-        let f = v.pop();
-        assert_eq!(f, None);
-        let g = v.pop();
-        assert_eq!(g, None);
-    }
-
-    #[test]
-    fn test_swap_remove() {
-        let mut v = vec![1, 2, 3, 4, 5];
-        let mut e = v.swap_remove(0);
-        assert_eq!(e, 1);
-        assert_eq!(v, vec![5, 2, 3, 4]);
-        e = v.swap_remove(3);
-        assert_eq!(e, 4);
-        assert_eq!(v, vec![5, 2, 3]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_swap_remove_fail() {
-        let mut v = vec![1];
-        let _ = v.swap_remove(0);
-        let _ = v.swap_remove(0);
-    }
-
-    #[test]
-    fn test_swap_remove_noncopyable() {
-        // Tests that we don't accidentally run destructors twice.
-        let mut v = Vec::new();
-        v.push(box 0u8);
-        v.push(box 0u8);
-        v.push(box 0u8);
-        let mut _e = v.swap_remove(0);
-        assert_eq!(v.len(), 2);
-        _e = v.swap_remove(1);
-        assert_eq!(v.len(), 1);
-        _e = v.swap_remove(0);
-        assert_eq!(v.len(), 0);
-    }
-
-    #[test]
-    fn test_push() {
-        // Test on-stack push().
-        let mut v = vec![];
-        v.push(1);
-        assert_eq!(v.len(), 1);
-        assert_eq!(v[0], 1);
-
-        // Test on-heap push().
-        v.push(2);
-        assert_eq!(v.len(), 2);
-        assert_eq!(v[0], 1);
-        assert_eq!(v[1], 2);
-    }
-
-    #[test]
-    fn test_truncate() {
-        let mut v = vec![box 6,box 5,box 4];
-        v.truncate(1);
-        let v = v;
-        assert_eq!(v.len(), 1);
-        assert_eq!(*(v[0]), 6);
-        // If the unsafe block didn't drop things properly, we blow up here.
-    }
-
-    #[test]
-    fn test_clear() {
-        let mut v = vec![box 6,box 5,box 4];
-        v.clear();
-        assert_eq!(v.len(), 0);
-        // If the unsafe block didn't drop things properly, we blow up here.
-    }
-
-    #[test]
-    fn test_dedup() {
-        fn case(a: Vec<i32>, b: Vec<i32>) {
-            let mut v = a;
-            v.dedup();
-            assert_eq!(v, b);
-        }
-        case(vec![], vec![]);
-        case(vec![1], vec![1]);
-        case(vec![1,1], vec![1]);
-        case(vec![1,2,3], vec![1,2,3]);
-        case(vec![1,1,2,3], vec![1,2,3]);
-        case(vec![1,2,2,3], vec![1,2,3]);
-        case(vec![1,2,3,3], vec![1,2,3]);
-        case(vec![1,1,2,2,2,3,3], vec![1,2,3]);
-    }
-
-    #[test]
-    fn test_dedup_unique() {
-        let mut v0 = vec![box 1, box 1, box 2, box 3];
-        v0.dedup();
-        let mut v1 = vec![box 1, box 2, box 2, box 3];
-        v1.dedup();
-        let mut v2 = vec![box 1, box 2, box 3, box 3];
-        v2.dedup();
-        /*
-         * If the boxed pointers were leaked or otherwise misused, valgrind
-         * and/or rt should raise errors.
-         */
-    }
-
-    #[test]
-    fn test_dedup_shared() {
-        let mut v0 = vec![box 1, box 1, box 2, box 3];
-        v0.dedup();
-        let mut v1 = vec![box 1, box 2, box 2, box 3];
-        v1.dedup();
-        let mut v2 = vec![box 1, box 2, box 3, box 3];
-        v2.dedup();
-        /*
-         * If the pointers were leaked or otherwise misused, valgrind and/or
-         * rt should raise errors.
-         */
-    }
-
-    #[test]
-    fn test_retain() {
-        let mut v = vec![1, 2, 3, 4, 5];
-        v.retain(is_odd);
-        assert_eq!(v, vec![1, 3, 5]);
-    }
-
-    #[test]
-    fn test_element_swaps() {
-        let mut v = [1, 2, 3];
-        for (i, (a, b)) in ElementSwaps::new(v.len()).enumerate() {
-            v.swap(a, b);
-            match i {
-                0 => assert!(v == [1, 3, 2]),
-                1 => assert!(v == [3, 1, 2]),
-                2 => assert!(v == [3, 2, 1]),
-                3 => assert!(v == [2, 3, 1]),
-                4 => assert!(v == [2, 1, 3]),
-                5 => assert!(v == [1, 2, 3]),
-                _ => panic!(),
-            }
-        }
-    }
-
-    #[test]
-    fn test_permutations() {
-        {
-            let v: [i32; 0] = [];
-            let mut it = v.permutations();
-            let (min_size, max_opt) = it.size_hint();
-            assert_eq!(min_size, 1);
-            assert_eq!(max_opt.unwrap(), 1);
-            assert_eq!(it.next(), Some(v.to_vec()));
-            assert_eq!(it.next(), None);
-        }
-        {
-            let v = ["Hello".to_string()];
-            let mut it = v.permutations();
-            let (min_size, max_opt) = it.size_hint();
-            assert_eq!(min_size, 1);
-            assert_eq!(max_opt.unwrap(), 1);
-            assert_eq!(it.next(), Some(v.to_vec()));
-            assert_eq!(it.next(), None);
-        }
-        {
-            let v = [1, 2, 3];
-            let mut it = v.permutations();
-            let (min_size, max_opt) = it.size_hint();
-            assert_eq!(min_size, 3*2);
-            assert_eq!(max_opt.unwrap(), 3*2);
-            assert_eq!(it.next(), Some(vec![1,2,3]));
-            assert_eq!(it.next(), Some(vec![1,3,2]));
-            assert_eq!(it.next(), Some(vec![3,1,2]));
-            let (min_size, max_opt) = it.size_hint();
-            assert_eq!(min_size, 3);
-            assert_eq!(max_opt.unwrap(), 3);
-            assert_eq!(it.next(), Some(vec![3,2,1]));
-            assert_eq!(it.next(), Some(vec![2,3,1]));
-            assert_eq!(it.next(), Some(vec![2,1,3]));
-            assert_eq!(it.next(), None);
-        }
-        {
-            // check that we have N! permutations
-            let v = ['A', 'B', 'C', 'D', 'E', 'F'];
-            let mut amt = 0;
-            let mut it = v.permutations();
-            let (min_size, max_opt) = it.size_hint();
-            for _perm in it.by_ref() {
-                amt += 1;
-            }
-            assert_eq!(amt, it.swaps.swaps_made);
-            assert_eq!(amt, min_size);
-            assert_eq!(amt, 2 * 3 * 4 * 5 * 6);
-            assert_eq!(amt, max_opt.unwrap());
-        }
-    }
-
-    #[test]
-    fn test_lexicographic_permutations() {
-        let v : &mut[_] = &mut[1, 2, 3, 4, 5];
-        assert!(v.prev_permutation() == false);
-        assert!(v.next_permutation());
-        let b: &mut[_] = &mut[1, 2, 3, 5, 4];
-        assert!(v == b);
-        assert!(v.prev_permutation());
-        let b: &mut[_] = &mut[1, 2, 3, 4, 5];
-        assert!(v == b);
-        assert!(v.next_permutation());
-        assert!(v.next_permutation());
-        let b: &mut[_] = &mut[1, 2, 4, 3, 5];
-        assert!(v == b);
-        assert!(v.next_permutation());
-        let b: &mut[_] = &mut[1, 2, 4, 5, 3];
-        assert!(v == b);
-
-        let v : &mut[_] = &mut[1, 0, 0, 0];
-        assert!(v.next_permutation() == false);
-        assert!(v.prev_permutation());
-        let b: &mut[_] = &mut[0, 1, 0, 0];
-        assert!(v == b);
-        assert!(v.prev_permutation());
-        let b: &mut[_] = &mut[0, 0, 1, 0];
-        assert!(v == b);
-        assert!(v.prev_permutation());
-        let b: &mut[_] = &mut[0, 0, 0, 1];
-        assert!(v == b);
-        assert!(v.prev_permutation() == false);
-    }
-
-    #[test]
-    fn test_lexicographic_permutations_empty_and_short() {
-        let empty : &mut[i32] = &mut[];
-        assert!(empty.next_permutation() == false);
-        let b: &mut[i32] = &mut[];
-        assert!(empty == b);
-        assert!(empty.prev_permutation() == false);
-        assert!(empty == b);
-
-        let one_elem : &mut[_] = &mut[4];
-        assert!(one_elem.prev_permutation() == false);
-        let b: &mut[_] = &mut[4];
-        assert!(one_elem == b);
-        assert!(one_elem.next_permutation() == false);
-        assert!(one_elem == b);
-
-        let two_elem : &mut[_] = &mut[1, 2];
-        assert!(two_elem.prev_permutation() == false);
-        let b : &mut[_] = &mut[1, 2];
-        let c : &mut[_] = &mut[2, 1];
-        assert!(two_elem == b);
-        assert!(two_elem.next_permutation());
-        assert!(two_elem == c);
-        assert!(two_elem.next_permutation() == false);
-        assert!(two_elem == c);
-        assert!(two_elem.prev_permutation());
-        assert!(two_elem == b);
-        assert!(two_elem.prev_permutation() == false);
-        assert!(two_elem == b);
-    }
-
-    #[test]
-    fn test_position_elem() {
-        assert!([].position_elem(&1).is_none());
-
-        let v1 = vec![1, 2, 3, 3, 2, 5];
-        assert_eq!(v1.position_elem(&1), Some(0));
-        assert_eq!(v1.position_elem(&2), Some(1));
-        assert_eq!(v1.position_elem(&5), Some(5));
-        assert!(v1.position_elem(&4).is_none());
-    }
-
-    #[test]
-    fn test_binary_search() {
-        assert_eq!([1,2,3,4,5].binary_search(&5).ok(), Some(4));
-        assert_eq!([1,2,3,4,5].binary_search(&4).ok(), Some(3));
-        assert_eq!([1,2,3,4,5].binary_search(&3).ok(), Some(2));
-        assert_eq!([1,2,3,4,5].binary_search(&2).ok(), Some(1));
-        assert_eq!([1,2,3,4,5].binary_search(&1).ok(), Some(0));
-
-        assert_eq!([2,4,6,8,10].binary_search(&1).ok(), None);
-        assert_eq!([2,4,6,8,10].binary_search(&5).ok(), None);
-        assert_eq!([2,4,6,8,10].binary_search(&4).ok(), Some(1));
-        assert_eq!([2,4,6,8,10].binary_search(&10).ok(), Some(4));
-
-        assert_eq!([2,4,6,8].binary_search(&1).ok(), None);
-        assert_eq!([2,4,6,8].binary_search(&5).ok(), None);
-        assert_eq!([2,4,6,8].binary_search(&4).ok(), Some(1));
-        assert_eq!([2,4,6,8].binary_search(&8).ok(), Some(3));
-
-        assert_eq!([2,4,6].binary_search(&1).ok(), None);
-        assert_eq!([2,4,6].binary_search(&5).ok(), None);
-        assert_eq!([2,4,6].binary_search(&4).ok(), Some(1));
-        assert_eq!([2,4,6].binary_search(&6).ok(), Some(2));
-
-        assert_eq!([2,4].binary_search(&1).ok(), None);
-        assert_eq!([2,4].binary_search(&5).ok(), None);
-        assert_eq!([2,4].binary_search(&2).ok(), Some(0));
-        assert_eq!([2,4].binary_search(&4).ok(), Some(1));
-
-        assert_eq!([2].binary_search(&1).ok(), None);
-        assert_eq!([2].binary_search(&5).ok(), None);
-        assert_eq!([2].binary_search(&2).ok(), Some(0));
-
-        assert_eq!([].binary_search(&1).ok(), None);
-        assert_eq!([].binary_search(&5).ok(), None);
-
-        assert!([1,1,1,1,1].binary_search(&1).ok() != None);
-        assert!([1,1,1,1,2].binary_search(&1).ok() != None);
-        assert!([1,1,1,2,2].binary_search(&1).ok() != None);
-        assert!([1,1,2,2,2].binary_search(&1).ok() != None);
-        assert_eq!([1,2,2,2,2].binary_search(&1).ok(), Some(0));
-
-        assert_eq!([1,2,3,4,5].binary_search(&6).ok(), None);
-        assert_eq!([1,2,3,4,5].binary_search(&0).ok(), None);
-    }
-
-    #[test]
-    fn test_reverse() {
-        let mut v = vec![10, 20];
-        assert_eq!(v[0], 10);
-        assert_eq!(v[1], 20);
-        v.reverse();
-        assert_eq!(v[0], 20);
-        assert_eq!(v[1], 10);
-
-        let mut v3 = Vec::<i32>::new();
-        v3.reverse();
-        assert!(v3.is_empty());
-    }
-
-    #[test]
-    fn test_sort() {
-        for len in 4..25 {
-            for _ in 0..100 {
-                let mut v: Vec<_> = thread_rng().gen_iter::<i32>().take(len).collect();
-                let mut v1 = v.clone();
-
-                v.sort();
-                assert!(v.windows(2).all(|w| w[0] <= w[1]));
-
-                v1.sort_by(|a, b| a.cmp(b));
-                assert!(v1.windows(2).all(|w| w[0] <= w[1]));
-
-                v1.sort_by(|a, b| b.cmp(a));
-                assert!(v1.windows(2).all(|w| w[0] >= w[1]));
-            }
-        }
-
-        // shouldn't panic
-        let mut v: [i32; 0] = [];
-        v.sort();
-
-        let mut v = [0xDEADBEEFu64];
-        v.sort();
-        assert!(v == [0xDEADBEEF]);
-    }
-
-    #[test]
-    fn test_sort_stability() {
-        for len in 4..25 {
-            for _ in 0..10 {
-                let mut counts = [0; 10];
-
-                // create a vector like [(6, 1), (5, 1), (6, 2), ...],
-                // where the first item of each tuple is random, but
-                // the second item represents which occurrence of that
-                // number this element is, i.e. the second elements
-                // will occur in sorted order.
-                let mut v: Vec<_> = (0..len).map(|_| {
-                        let n = thread_rng().gen::<usize>() % 10;
-                        counts[n] += 1;
-                        (n, counts[n])
-                    }).collect();
-
-                // only sort on the first element, so an unstable sort
-                // may mix up the counts.
-                v.sort_by(|&(a,_), &(b,_)| a.cmp(&b));
-
-                // this comparison includes the count (the second item
-                // of the tuple), so elements with equal first items
-                // will need to be ordered with increasing
-                // counts... i.e. exactly asserting that this sort is
-                // stable.
-                assert!(v.windows(2).all(|w| w[0] <= w[1]));
-            }
-        }
-    }
-
-    #[test]
-    fn test_concat() {
-        let v: [Vec<i32>; 0] = [];
-        let c = v.concat();
-        assert_eq!(c, []);
-        let d = [vec![1], vec![2,3]].concat();
-        assert_eq!(d, vec![1, 2, 3]);
-
-        let v: &[&[_]] = &[&[1], &[2, 3]];
-        assert_eq!(v.connect(&0), vec![1, 0, 2, 3]);
-        let v: &[&[_]] = &[&[1], &[2], &[3]];
-        assert_eq!(v.connect(&0), vec![1, 0, 2, 0, 3]);
-    }
-
-    #[test]
-    fn test_connect() {
-        let v: [Vec<i32>; 0] = [];
-        assert_eq!(v.connect(&0), vec![]);
-        assert_eq!([vec![1], vec![2, 3]].connect(&0), vec![1, 0, 2, 3]);
-        assert_eq!([vec![1], vec![2], vec![3]].connect(&0), vec![1, 0, 2, 0, 3]);
-
-        let v: [&[_]; 2] = [&[1], &[2, 3]];
-        assert_eq!(v.connect(&0), vec![1, 0, 2, 3]);
-        let v: [&[_]; 3] = [&[1], &[2], &[3]];
-        assert_eq!(v.connect(&0), vec![1, 0, 2, 0, 3]);
-    }
-
-    #[test]
-    fn test_insert() {
-        let mut a = vec![1, 2, 4];
-        a.insert(2, 3);
-        assert_eq!(a, vec![1, 2, 3, 4]);
-
-        let mut a = vec![1, 2, 3];
-        a.insert(0, 0);
-        assert_eq!(a, vec![0, 1, 2, 3]);
-
-        let mut a = vec![1, 2, 3];
-        a.insert(3, 4);
-        assert_eq!(a, vec![1, 2, 3, 4]);
-
-        let mut a = vec![];
-        a.insert(0, 1);
-        assert_eq!(a, vec![1]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_insert_oob() {
-        let mut a = vec![1, 2, 3];
-        a.insert(4, 5);
-    }
-
-    #[test]
-    fn test_remove() {
-        let mut a = vec![1, 2, 3, 4];
-
-        assert_eq!(a.remove(2), 3);
-        assert_eq!(a, vec![1, 2, 4]);
-
-        assert_eq!(a.remove(2), 4);
-        assert_eq!(a, vec![1, 2]);
-
-        assert_eq!(a.remove(0), 1);
-        assert_eq!(a, vec![2]);
-
-        assert_eq!(a.remove(0), 2);
-        assert_eq!(a, vec![]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_remove_fail() {
-        let mut a = vec![1];
-        let _ = a.remove(0);
-        let _ = a.remove(0);
-    }
-
-    #[test]
-    fn test_capacity() {
-        let mut v = vec![0];
-        v.reserve_exact(10);
-        assert!(v.capacity() >= 11);
-    }
-
-    #[test]
-    fn test_slice_2() {
-        let v = vec![1, 2, 3, 4, 5];
-        let v = v.slice(1, 3);
-        assert_eq!(v.len(), 2);
-        assert_eq!(v[0], 2);
-        assert_eq!(v[1], 3);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_permute_fail() {
-        let v = [(box 0, Rc::new(0)), (box 0, Rc::new(0)),
-                 (box 0, Rc::new(0)), (box 0, Rc::new(0))];
-        let mut i = 0;
-        for _ in v.permutations() {
-            if i == 2 {
-                panic!()
-            }
-            i += 1;
-        }
-    }
-
-    #[test]
-    fn test_total_ord() {
-        let c = &[1, 2, 3];
-        [1, 2, 3, 4][..].cmp(c) == Greater;
-        let c = &[1, 2, 3, 4];
-        [1, 2, 3][..].cmp(c) == Less;
-        let c = &[1, 2, 3, 6];
-        [1, 2, 3, 4][..].cmp(c) == Equal;
-        let c = &[1, 2, 3, 4, 5, 6];
-        [1, 2, 3, 4, 5, 5, 5, 5][..].cmp(c) == Less;
-        let c = &[1, 2, 3, 4];
-        [2, 2][..].cmp(c) == Greater;
-    }
-
-    #[test]
-    fn test_iterator() {
-        let xs = [1, 2, 5, 10, 11];
-        let mut it = xs.iter();
-        assert_eq!(it.size_hint(), (5, Some(5)));
-        assert_eq!(it.next().unwrap(), &1);
-        assert_eq!(it.size_hint(), (4, Some(4)));
-        assert_eq!(it.next().unwrap(), &2);
-        assert_eq!(it.size_hint(), (3, Some(3)));
-        assert_eq!(it.next().unwrap(), &5);
-        assert_eq!(it.size_hint(), (2, Some(2)));
-        assert_eq!(it.next().unwrap(), &10);
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(it.next().unwrap(), &11);
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_random_access_iterator() {
-        let xs = [1, 2, 5, 10, 11];
-        let mut it = xs.iter();
-
-        assert_eq!(it.indexable(), 5);
-        assert_eq!(it.idx(0).unwrap(), &1);
-        assert_eq!(it.idx(2).unwrap(), &5);
-        assert_eq!(it.idx(4).unwrap(), &11);
-        assert!(it.idx(5).is_none());
-
-        assert_eq!(it.next().unwrap(), &1);
-        assert_eq!(it.indexable(), 4);
-        assert_eq!(it.idx(0).unwrap(), &2);
-        assert_eq!(it.idx(3).unwrap(), &11);
-        assert!(it.idx(4).is_none());
-
-        assert_eq!(it.next().unwrap(), &2);
-        assert_eq!(it.indexable(), 3);
-        assert_eq!(it.idx(1).unwrap(), &10);
-        assert!(it.idx(3).is_none());
-
-        assert_eq!(it.next().unwrap(), &5);
-        assert_eq!(it.indexable(), 2);
-        assert_eq!(it.idx(1).unwrap(), &11);
-
-        assert_eq!(it.next().unwrap(), &10);
-        assert_eq!(it.indexable(), 1);
-        assert_eq!(it.idx(0).unwrap(), &11);
-        assert!(it.idx(1).is_none());
-
-        assert_eq!(it.next().unwrap(), &11);
-        assert_eq!(it.indexable(), 0);
-        assert!(it.idx(0).is_none());
-
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_iter_size_hints() {
-        let mut xs = [1, 2, 5, 10, 11];
-        assert_eq!(xs.iter().size_hint(), (5, Some(5)));
-        assert_eq!(xs.iter_mut().size_hint(), (5, Some(5)));
-    }
-
-    #[test]
-    fn test_iter_clone() {
-        let xs = [1, 2, 5];
-        let mut it = xs.iter();
-        it.next();
-        let mut jt = it.clone();
-        assert_eq!(it.next(), jt.next());
-        assert_eq!(it.next(), jt.next());
-        assert_eq!(it.next(), jt.next());
-    }
-
-    #[test]
-    fn test_mut_iterator() {
-        let mut xs = [1, 2, 3, 4, 5];
-        for x in &mut xs {
-            *x += 1;
-        }
-        assert!(xs == [2, 3, 4, 5, 6])
-    }
-
-    #[test]
-    fn test_rev_iterator() {
-
-        let xs = [1, 2, 5, 10, 11];
-        let ys = [11, 10, 5, 2, 1];
-        let mut i = 0;
-        for &x in xs.iter().rev() {
-            assert_eq!(x, ys[i]);
-            i += 1;
-        }
-        assert_eq!(i, 5);
-    }
-
-    #[test]
-    fn test_mut_rev_iterator() {
-        let mut xs = [1, 2, 3, 4, 5];
-        for (i,x) in xs.iter_mut().rev().enumerate() {
-            *x += i;
-        }
-        assert!(xs == [5, 5, 5, 5, 5])
-    }
-
-    #[test]
-    fn test_move_iterator() {
-        let xs = vec![1,2,3,4,5];
-        assert_eq!(xs.into_iter().fold(0, |a: usize, b: usize| 10*a + b), 12345);
-    }
-
-    #[test]
-    fn test_move_rev_iterator() {
-        let xs = vec![1,2,3,4,5];
-        assert_eq!(xs.into_iter().rev().fold(0, |a: usize, b: usize| 10*a + b), 54321);
-    }
-
-    #[test]
-    fn test_splitator() {
-        let xs = &[1,2,3,4,5];
-
-        let splits: &[&[_]] = &[&[1], &[3], &[5]];
-        assert_eq!(xs.split(|x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[], &[2,3,4,5]];
-        assert_eq!(xs.split(|x| *x == 1).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[1,2,3,4], &[]];
-        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[1,2,3,4,5]];
-        assert_eq!(xs.split(|x| *x == 10).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[], &[], &[], &[], &[], &[]];
-        assert_eq!(xs.split(|_| true).collect::<Vec<&[i32]>>(),
-                   splits);
-
-        let xs: &[i32] = &[];
-        let splits: &[&[i32]] = &[&[]];
-        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[i32]>>(), splits);
-    }
-
-    #[test]
-    fn test_splitnator() {
-        let xs = &[1,2,3,4,5];
-
-        let splits: &[&[_]] = &[&[1,2,3,4,5]];
-        assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[1], &[3,4,5]];
-        assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[], &[], &[], &[4,5]];
-        assert_eq!(xs.splitn(3, |_| true).collect::<Vec<_>>(),
-                   splits);
-
-        let xs: &[i32] = &[];
-        let splits: &[&[i32]] = &[&[]];
-        assert_eq!(xs.splitn(1, |x| *x == 5).collect::<Vec<_>>(), splits);
-    }
-
-    #[test]
-    fn test_splitnator_mut() {
-        let xs = &mut [1,2,3,4,5];
-
-        let splits: &[&mut[_]] = &[&mut [1,2,3,4,5]];
-        assert_eq!(xs.splitn_mut(0, |x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&mut[_]] = &[&mut [1], &mut [3,4,5]];
-        assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&mut[_]] = &[&mut [], &mut [], &mut [], &mut [4,5]];
-        assert_eq!(xs.splitn_mut(3, |_| true).collect::<Vec<_>>(),
-                   splits);
-
-        let xs: &mut [i32] = &mut [];
-        let splits: &[&mut[i32]] = &[&mut []];
-        assert_eq!(xs.splitn_mut(1, |x| *x == 5).collect::<Vec<_>>(),
-                   splits);
-    }
-
-    #[test]
-    fn test_rsplitator() {
-        let xs = &[1,2,3,4,5];
-
-        let splits: &[&[_]] = &[&[5], &[3], &[1]];
-        assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[2,3,4,5], &[]];
-        assert_eq!(xs.split(|x| *x == 1).rev().collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[], &[1,2,3,4]];
-        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[1,2,3,4,5]];
-        assert_eq!(xs.split(|x| *x == 10).rev().collect::<Vec<_>>(),
-                   splits);
-
-        let xs: &[i32] = &[];
-        let splits: &[&[i32]] = &[&[]];
-        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[i32]>>(), splits);
-    }
-
-    #[test]
-    fn test_rsplitnator() {
-        let xs = &[1,2,3,4,5];
-
-        let splits: &[&[_]] = &[&[1,2,3,4,5]];
-        assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[5], &[1,2,3]];
-        assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[], &[], &[], &[1,2]];
-        assert_eq!(xs.rsplitn(3, |_| true).collect::<Vec<_>>(),
-                   splits);
-
-        let xs: &[i32]  = &[];
-        let splits: &[&[i32]] = &[&[]];
-        assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<Vec<&[i32]>>(), splits);
-    }
-
-    #[test]
-    fn test_windowsator() {
-        let v = &[1,2,3,4];
-
-        let wins: &[&[_]] = &[&[1,2], &[2,3], &[3,4]];
-        assert_eq!(v.windows(2).collect::<Vec<_>>(), wins);
-
-        let wins: &[&[_]] = &[&[1,2,3], &[2,3,4]];
-        assert_eq!(v.windows(3).collect::<Vec<_>>(), wins);
-        assert!(v.windows(6).next().is_none());
-
-        let wins: &[&[_]] = &[&[3,4], &[2,3], &[1,2]];
-        assert_eq!(v.windows(2).rev().collect::<Vec<&[_]>>(), wins);
-        let mut it = v.windows(2);
-        assert_eq!(it.indexable(), 3);
-        let win: &[_] = &[1,2];
-        assert_eq!(it.idx(0).unwrap(), win);
-        let win: &[_] = &[2,3];
-        assert_eq!(it.idx(1).unwrap(), win);
-        let win: &[_] = &[3,4];
-        assert_eq!(it.idx(2).unwrap(), win);
-        assert_eq!(it.idx(3), None);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_windowsator_0() {
-        let v = &[1,2,3,4];
-        let _it = v.windows(0);
-    }
-
-    #[test]
-    fn test_chunksator() {
-        use core::iter::ExactSizeIterator;
-
-        let v = &[1,2,3,4,5];
-
-        assert_eq!(v.chunks(2).len(), 3);
-
-        let chunks: &[&[_]] = &[&[1,2], &[3,4], &[5]];
-        assert_eq!(v.chunks(2).collect::<Vec<_>>(), chunks);
-        let chunks: &[&[_]] = &[&[1,2,3], &[4,5]];
-        assert_eq!(v.chunks(3).collect::<Vec<_>>(), chunks);
-        let chunks: &[&[_]] = &[&[1,2,3,4,5]];
-        assert_eq!(v.chunks(6).collect::<Vec<_>>(), chunks);
-
-        let chunks: &[&[_]] = &[&[5], &[3,4], &[1,2]];
-        assert_eq!(v.chunks(2).rev().collect::<Vec<_>>(), chunks);
-        let mut it = v.chunks(2);
-        assert_eq!(it.indexable(), 3);
-
-        let chunk: &[_] = &[1,2];
-        assert_eq!(it.idx(0).unwrap(), chunk);
-        let chunk: &[_] = &[3,4];
-        assert_eq!(it.idx(1).unwrap(), chunk);
-        let chunk: &[_] = &[5];
-        assert_eq!(it.idx(2).unwrap(), chunk);
-        assert_eq!(it.idx(3), None);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_chunksator_0() {
-        let v = &[1,2,3,4];
-        let _it = v.chunks(0);
-    }
-
-    #[test]
-    fn test_move_from() {
-        let mut a = [1,2,3,4,5];
-        let b = vec![6,7,8];
-        assert_eq!(a.move_from(b, 0, 3), 3);
-        assert!(a == [6,7,8,4,5]);
-        let mut a = [7,2,8,1];
-        let b = vec![3,1,4,1,5,9];
-        assert_eq!(a.move_from(b, 0, 6), 4);
-        assert!(a == [3,1,4,1]);
-        let mut a = [1,2,3,4];
-        let b = vec![5,6,7,8,9,0];
-        assert_eq!(a.move_from(b, 2, 3), 1);
-        assert!(a == [7,2,3,4]);
-        let mut a = [1,2,3,4,5];
-        let b = vec![5,6,7,8,9,0];
-        assert_eq!(a[2..4].move_from(b,1,6), 2);
-        assert!(a == [1,2,6,7,5]);
-    }
-
-    #[test]
-    fn test_reverse_part() {
-        let mut values = [1,2,3,4,5];
-        values[1..4].reverse();
-        assert!(values == [1,4,3,2,5]);
-    }
-
-    #[test]
-    fn test_show() {
-        macro_rules! test_show_vec {
-            ($x:expr, $x_str:expr) => ({
-                let (x, x_str) = ($x, $x_str);
-                assert_eq!(format!("{:?}", x), x_str);
-                assert_eq!(format!("{:?}", x), x_str);
-            })
-        }
-        let empty = Vec::<i32>::new();
-        test_show_vec!(empty, "[]");
-        test_show_vec!(vec![1], "[1]");
-        test_show_vec!(vec![1, 2, 3], "[1, 2, 3]");
-        test_show_vec!(vec![vec![], vec![1], vec![1, 1]],
-                       "[[], [1], [1, 1]]");
-
-        let empty_mut: &mut [i32] = &mut[];
-        test_show_vec!(empty_mut, "[]");
-        let v = &mut[1];
-        test_show_vec!(v, "[1]");
-        let v = &mut[1, 2, 3];
-        test_show_vec!(v, "[1, 2, 3]");
-        let v: &mut[&mut[_]] = &mut[&mut[], &mut[1], &mut[1, 1]];
-        test_show_vec!(v, "[[], [1], [1, 1]]");
-    }
-
-    #[test]
-    fn test_vec_default() {
-        macro_rules! t {
-            ($ty:ty) => {{
-                let v: $ty = Default::default();
-                assert!(v.is_empty());
-            }}
-        }
-
-        t!(&[i32]);
-        t!(Vec<i32>);
-    }
-
-    #[test]
-    fn test_bytes_set_memory() {
-        use slice::bytes::MutableByteVector;
-        let mut values = [1u8,2,3,4,5];
-        values[0..5].set_memory(0xAB);
-        assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
-        values[2..4].set_memory(0xFF);
-        assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_overflow_does_not_cause_segfault() {
-        let mut v = vec![];
-        v.reserve_exact(-1);
-        v.push(1);
-        v.push(2);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_overflow_does_not_cause_segfault_managed() {
-        let mut v = vec![Rc::new(1)];
-        v.reserve_exact(-1);
-        v.push(Rc::new(2));
-    }
-
-    #[test]
-    fn test_mut_split_at() {
-        let mut values = [1u8,2,3,4,5];
-        {
-            let (left, right) = values.split_at_mut(2);
-            {
-                let left: &[_] = left;
-                assert!(left[..left.len()] == [1, 2][]);
-            }
-            for p in left {
-                *p += 1;
-            }
-
-            {
-                let right: &[_] = right;
-                assert!(right[..right.len()] == [3, 4, 5][]);
-            }
-            for p in right {
-                *p += 2;
-            }
-        }
-
-        assert!(values == [2, 3, 5, 6, 7]);
-    }
-
-    #[derive(Clone, PartialEq)]
-    struct Foo;
-
-    #[test]
-    fn test_iter_zero_sized() {
-        let mut v = vec![Foo, Foo, Foo];
-        assert_eq!(v.len(), 3);
-        let mut cnt = 0;
-
-        for f in &v {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 3);
-
-        for f in &v[1..3] {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 5);
-
-        for f in &mut v {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 8);
-
-        for f in v {
-            assert!(f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 11);
-
-        let xs: [Foo; 3] = [Foo, Foo, Foo];
-        cnt = 0;
-        for f in &xs {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert!(cnt == 3);
-    }
-
-    #[test]
-    fn test_shrink_to_fit() {
-        let mut xs = vec![0, 1, 2, 3];
-        for i in 4..100 {
-            xs.push(i)
-        }
-        assert_eq!(xs.capacity(), 128);
-        xs.shrink_to_fit();
-        assert_eq!(xs.capacity(), 100);
-        assert_eq!(xs, (0..100).collect::<Vec<_>>());
-    }
-
-    #[test]
-    fn test_starts_with() {
-        assert!(b"foobar".starts_with(b"foo"));
-        assert!(!b"foobar".starts_with(b"oob"));
-        assert!(!b"foobar".starts_with(b"bar"));
-        assert!(!b"foo".starts_with(b"foobar"));
-        assert!(!b"bar".starts_with(b"foobar"));
-        assert!(b"foobar".starts_with(b"foobar"));
-        let empty: &[u8] = &[];
-        assert!(empty.starts_with(empty));
-        assert!(!empty.starts_with(b"foo"));
-        assert!(b"foobar".starts_with(empty));
-    }
-
-    #[test]
-    fn test_ends_with() {
-        assert!(b"foobar".ends_with(b"bar"));
-        assert!(!b"foobar".ends_with(b"oba"));
-        assert!(!b"foobar".ends_with(b"foo"));
-        assert!(!b"foo".ends_with(b"foobar"));
-        assert!(!b"bar".ends_with(b"foobar"));
-        assert!(b"foobar".ends_with(b"foobar"));
-        let empty: &[u8] = &[];
-        assert!(empty.ends_with(empty));
-        assert!(!empty.ends_with(b"foo"));
-        assert!(b"foobar".ends_with(empty));
-    }
-
-    #[test]
-    fn test_mut_splitator() {
-        let mut xs = [0,1,0,2,3,0,0,4,5,0];
-        assert_eq!(xs.split_mut(|x| *x == 0).count(), 6);
-        for slice in xs.split_mut(|x| *x == 0) {
-            slice.reverse();
-        }
-        assert!(xs == [0,1,0,3,2,0,0,5,4,0]);
-
-        let mut xs = [0,1,0,2,3,0,0,4,5,0,6,7];
-        for slice in xs.split_mut(|x| *x == 0).take(5) {
-            slice.reverse();
-        }
-        assert!(xs == [0,1,0,3,2,0,0,5,4,0,6,7]);
-    }
-
-    #[test]
-    fn test_mut_splitator_rev() {
-        let mut xs = [1,2,0,3,4,0,0,5,6,0];
-        for slice in xs.split_mut(|x| *x == 0).rev().take(4) {
-            slice.reverse();
-        }
-        assert!(xs == [1,2,0,4,3,0,0,6,5,0]);
-    }
-
-    #[test]
-    fn test_get_mut() {
-        let mut v = [0,1,2];
-        assert_eq!(v.get_mut(3), None);
-        v.get_mut(1).map(|e| *e = 7);
-        assert_eq!(v[1], 7);
-        let mut x = 2;
-        assert_eq!(v.get_mut(2), Some(&mut x));
-    }
-
-    #[test]
-    fn test_mut_chunks() {
-        use core::iter::ExactSizeIterator;
-
-        let mut v = [0u8, 1, 2, 3, 4, 5, 6];
-        assert_eq!(v.chunks_mut(2).len(), 4);
-        for (i, chunk) in v.chunks_mut(3).enumerate() {
-            for x in chunk {
-                *x = i as u8;
-            }
-        }
-        let result = [0u8, 0, 0, 1, 1, 1, 2];
-        assert!(v == result);
-    }
-
-    #[test]
-    fn test_mut_chunks_rev() {
-        let mut v = [0u8, 1, 2, 3, 4, 5, 6];
-        for (i, chunk) in v.chunks_mut(3).rev().enumerate() {
-            for x in chunk {
-                *x = i as u8;
-            }
-        }
-        let result = [2u8, 2, 2, 1, 1, 1, 0];
-        assert!(v == result);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_mut_chunks_0() {
-        let mut v = [1, 2, 3, 4];
-        let _it = v.chunks_mut(0);
-    }
-
-    #[test]
-    fn test_mut_last() {
-        let mut x = [1, 2, 3, 4, 5];
-        let h = x.last_mut();
-        assert_eq!(*h.unwrap(), 5);
-
-        let y: &mut [i32] = &mut [];
-        assert!(y.last_mut().is_none());
-    }
-
-    #[test]
-    fn test_to_vec() {
-        let xs = box [1, 2, 3];
-        let ys = xs.to_vec();
-        assert_eq!(ys, [1, 2, 3]);
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    use prelude::*;
-    use core::mem;
-    use core::ptr;
-    use core::iter::repeat;
-    use std::rand::{weak_rng, Rng};
-    use test::{Bencher, black_box};
-
-    #[bench]
-    fn iterator(b: &mut Bencher) {
-        // peculiar numbers to stop LLVM from optimising the summation
-        // out.
-        let v: Vec<_> = (0..100).map(|i| i ^ (i << 1) ^ (i >> 1)).collect();
-
-        b.iter(|| {
-            let mut sum = 0;
-            for x in &v {
-                sum += *x;
-            }
-            // sum == 11806, to stop dead code elimination.
-            if sum == 0 {panic!()}
-        })
-    }
-
-    #[bench]
-    fn mut_iterator(b: &mut Bencher) {
-        let mut v: Vec<_> = repeat(0).take(100).collect();
-
-        b.iter(|| {
-            let mut i = 0;
-            for x in &mut v {
-                *x = i;
-                i += 1;
-            }
-        })
-    }
-
-    #[bench]
-    fn concat(b: &mut Bencher) {
-        let xss: Vec<Vec<i32>> =
-            (0..100).map(|i| (0..i).collect()).collect();
-        b.iter(|| {
-            xss.concat();
-        });
-    }
-
-    #[bench]
-    fn connect(b: &mut Bencher) {
-        let xss: Vec<Vec<i32>> =
-            (0..100).map(|i| (0..i).collect()).collect();
-        b.iter(|| {
-            xss.connect(&0)
-        });
-    }
-
-    #[bench]
-    fn push(b: &mut Bencher) {
-        let mut vec = Vec::<i32>::new();
-        b.iter(|| {
-            vec.push(0);
-            black_box(&vec);
-        });
-    }
-
-    #[bench]
-    fn starts_with_same_vector(b: &mut Bencher) {
-        let vec: Vec<_> = (0..100).collect();
-        b.iter(|| {
-            vec.starts_with(&vec)
-        })
-    }
-
-    #[bench]
-    fn starts_with_single_element(b: &mut Bencher) {
-        let vec: Vec<_> = vec![0];
-        b.iter(|| {
-            vec.starts_with(&vec)
-        })
-    }
-
-    #[bench]
-    fn starts_with_diff_one_element_at_end(b: &mut Bencher) {
-        let vec: Vec<_> = (0..100).collect();
-        let mut match_vec: Vec<_> = (0..99).collect();
-        match_vec.push(0);
-        b.iter(|| {
-            vec.starts_with(&match_vec)
-        })
-    }
-
-    #[bench]
-    fn ends_with_same_vector(b: &mut Bencher) {
-        let vec: Vec<_> = (0..100).collect();
-        b.iter(|| {
-            vec.ends_with(&vec)
-        })
-    }
-
-    #[bench]
-    fn ends_with_single_element(b: &mut Bencher) {
-        let vec: Vec<_> = vec![0];
-        b.iter(|| {
-            vec.ends_with(&vec)
-        })
-    }
-
-    #[bench]
-    fn ends_with_diff_one_element_at_beginning(b: &mut Bencher) {
-        let vec: Vec<_> = (0..100).collect();
-        let mut match_vec: Vec<_> = (0..100).collect();
-        match_vec[0] = 200;
-        b.iter(|| {
-            vec.starts_with(&match_vec)
-        })
-    }
-
-    #[bench]
-    fn contains_last_element(b: &mut Bencher) {
-        let vec: Vec<_> = (0..100).collect();
-        b.iter(|| {
-            vec.contains(&99)
-        })
-    }
-
-    #[bench]
-    fn zero_1kb_from_elem(b: &mut Bencher) {
-        b.iter(|| {
-            repeat(0u8).take(1024).collect::<Vec<_>>()
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_set_memory(b: &mut Bencher) {
-        b.iter(|| {
-            let mut v = Vec::<u8>::with_capacity(1024);
-            unsafe {
-                let vp = v.as_mut_ptr();
-                ptr::set_memory(vp, 0, 1024);
-                v.set_len(1024);
-            }
-            v
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_loop_set(b: &mut Bencher) {
-        b.iter(|| {
-            let mut v = Vec::<u8>::with_capacity(1024);
-            unsafe {
-                v.set_len(1024);
-            }
-            for i in 0..1024 {
-                v[i] = 0;
-            }
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_mut_iter(b: &mut Bencher) {
-        b.iter(|| {
-            let mut v = Vec::<u8>::with_capacity(1024);
-            unsafe {
-                v.set_len(1024);
-            }
-            for x in &mut v {
-                *x = 0;
-            }
-            v
-        });
-    }
-
-    #[bench]
-    fn random_inserts(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v: Vec<_> = repeat((0, 0)).take(30).collect();
-            for _ in 0..100 {
-                let l = v.len();
-                v.insert(rng.gen::<usize>() % (l + 1),
-                         (1, 1));
-            }
-        })
-    }
-    #[bench]
-    fn random_removes(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v: Vec<_> = repeat((0, 0)).take(130).collect();
-            for _ in 0..100 {
-                let l = v.len();
-                v.remove(rng.gen::<usize>() % l);
-            }
-        })
-    }
-
-    #[bench]
-    fn sort_random_small(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v: Vec<_> = rng.gen_iter::<u64>().take(5).collect();
-            v.sort();
-        });
-        b.bytes = 5 * mem::size_of::<u64>() as u64;
-    }
-
-    #[bench]
-    fn sort_random_medium(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v: Vec<_> = rng.gen_iter::<u64>().take(100).collect();
-            v.sort();
-        });
-        b.bytes = 100 * mem::size_of::<u64>() as u64;
-    }
-
-    #[bench]
-    fn sort_random_large(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v: Vec<_> = rng.gen_iter::<u64>().take(10000).collect();
-            v.sort();
-        });
-        b.bytes = 10000 * mem::size_of::<u64>() as u64;
-    }
-
-    #[bench]
-    fn sort_sorted(b: &mut Bencher) {
-        let mut v: Vec<_> = (0..10000).collect();
-        b.iter(|| {
-            v.sort();
-        });
-        b.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
-    }
-
-    type BigSortable = (u64, u64, u64, u64);
-
-    #[bench]
-    fn sort_big_random_small(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v = rng.gen_iter::<BigSortable>().take(5)
-                           .collect::<Vec<BigSortable>>();
-            v.sort();
-        });
-        b.bytes = 5 * mem::size_of::<BigSortable>() as u64;
-    }
-
-    #[bench]
-    fn sort_big_random_medium(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v = rng.gen_iter::<BigSortable>().take(100)
-                           .collect::<Vec<BigSortable>>();
-            v.sort();
-        });
-        b.bytes = 100 * mem::size_of::<BigSortable>() as u64;
-    }
-
-    #[bench]
-    fn sort_big_random_large(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v = rng.gen_iter::<BigSortable>().take(10000)
-                           .collect::<Vec<BigSortable>>();
-            v.sort();
-        });
-        b.bytes = 10000 * mem::size_of::<BigSortable>() as u64;
-    }
-
-    #[bench]
-    fn sort_big_sorted(b: &mut Bencher) {
-        let mut v: Vec<BigSortable> = (0..10000).map(|i| (i, i, i, i)).collect();
-        b.iter(|| {
-            v.sort();
-        });
-        b.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
-    }
-}
index ec0a487acdc77c734c2ae207624c869e95708e25..c22b6fb9286d192382c9dd8c7ec1f112677aaa6b 100644 (file)
 //
 // ignore-lexer-test FIXME #15679
 
-//! Unicode string manipulation (`str` type)
+//! Unicode string manipulation (the `str` type).
 //!
-//! # Basic Usage
+//! Rust's `str` type is one of the core primitive types of the language. `&str`
+//! is the borrowed string type. This type of string can only be created from
+//! other strings, unless it is a `&'static str` (see below). It is not possible
+//! to move out of borrowed strings because they are owned elsewhere.
 //!
-//! Rust's string type is one of the core primitive types of the language. While
-//! represented by the name `str`, the name `str` is not actually a valid type in
-//! Rust. Each string must also be decorated with a pointer. `String` is used
-//! for an owned string, so there is only one commonly-used `str` type in Rust:
-//! `&str`.
+//! # Examples
 //!
-//! `&str` is the borrowed string type. This type of string can only be created
-//! from other strings, unless it is a static string (see below). As the word
-//! "borrowed" implies, this type of string is owned elsewhere, and this string
-//! cannot be moved out of.
+//! Here's some code that uses a `&str`:
 //!
-//! As an example, here's some code that uses a string.
-//!
-//! ```rust
-//! fn main() {
-//!     let borrowed_string = "This string is borrowed with the 'static lifetime";
-//! }
 //! ```
+//! let s = "Hello, world.";
+//! ```
+//!
+//! This `&str` is a `&'static str`, which is the type of string literals.
+//! They're `'static` because literals are available for the entire lifetime of
+//! the program.
+//!
+//! You can get a non-`'static` `&str` by taking a slice of a `String`:
 //!
-//! From the example above, you can guess that Rust's string literals have the
-//! `'static` lifetime. This is akin to C's concept of a static string.
-//! More precisely, string literals are immutable views with a 'static lifetime
-//! (otherwise known as the lifetime of the entire program), and thus have the
-//! type `&'static str`.
+//! ```
+//! # let some_string = "Hello, world.".to_string();
+//! let s = &some_string;
+//! ```
 //!
 //! # Representation
 //!
-//! Rust's string type, `str`, is a sequence of Unicode scalar values encoded as a
-//! stream of UTF-8 bytes. All [strings](../../reference.html#literals) are
+//! Rust's string type, `str`, is a sequence of Unicode scalar values encoded as
+//! stream of UTF-8 bytes. All [strings](../../reference.html#literals) are
 //! guaranteed to be validly encoded UTF-8 sequences. Additionally, strings are
 //! not null-terminated and can thus contain null bytes.
 //!
-//! The actual representation of strings have direct mappings to slices: `&str`
+//! The actual representation of `str`s have direct mappings to slices: `&str`
 //! is the same as `&[u8]`.
 
 #![doc(primitive = "str")]
 use self::RecompositionState::*;
 use self::DecompositionType::*;
 
-use core::char::CharExt;
 use core::clone::Clone;
 use core::iter::AdditiveIterator;
-use core::iter::{Iterator, IteratorExt};
-use core::ops::Index;
-use core::ops::RangeFull;
+use core::iter::{Iterator, Extend};
 use core::option::Option::{self, Some, None};
 use core::result::Result;
-use core::slice::AsSlice;
 use core::str as core_str;
 use unicode::str::{UnicodeStr, Utf16Encoder};
 
+use core::convert::AsRef;
 use vec_deque::VecDeque;
 use borrow::{Borrow, ToOwned};
-use slice::SliceExt;
 use string::String;
 use unicode;
 use vec::Vec;
 use slice::SliceConcatExt;
 
 pub use core::str::{FromStr, Utf8Error, Str};
-pub use core::str::{Lines, LinesAny, MatchIndices, SplitStr, CharRange};
-pub use core::str::{Split, SplitTerminator};
-pub use core::str::{SplitN, RSplitN};
-pub use core::str::{from_utf8, CharEq, Chars, CharIndices, Bytes};
-pub use core::str::{from_utf8_unchecked, from_c_str, ParseBoolError};
+pub use core::str::{Lines, LinesAny, MatchIndices, CharRange};
+pub use core::str::{Split, SplitTerminator, SplitN};
+pub use core::str::{RSplit, RSplitN};
+pub use core::str::{from_utf8, Chars, CharIndices, Bytes};
+pub use core::str::{from_utf8_unchecked, ParseBoolError};
 pub use unicode::str::{Words, Graphemes, GraphemeIndices};
+pub use core::str::Pattern;
+pub use core::str::{Searcher, ReverseSearcher, DoubleEndedSearcher, SearchStep};
 
 /*
 Section: Creating a string
 */
 
-impl<S: Str> SliceConcatExt<str, String> for [S] {
+impl<S: AsRef<str>> SliceConcatExt<str, String> for [S] {
     fn concat(&self) -> String {
-        let s = self.as_slice();
-
-        if s.is_empty() {
+        if self.is_empty() {
             return String::new();
         }
 
         // `len` calculation may overflow but push_str will check boundaries
-        let len = s.iter().map(|s| s.as_slice().len()).sum();
+        let len = self.iter().map(|s| s.as_ref().len()).sum();
         let mut result = String::with_capacity(len);
 
-        for s in s {
-            result.push_str(s.as_slice())
+        for s in self {
+            result.push_str(s.as_ref())
         }
 
         result
     }
 
     fn connect(&self, sep: &str) -> String {
-        let s = self.as_slice();
-
-        if s.is_empty() {
+        if self.is_empty() {
             return String::new();
         }
 
         // concat is faster
         if sep.is_empty() {
-            return s.concat();
+            return self.concat();
         }
 
         // this is wrong without the guarantee that `self` is non-empty
         // `len` calculation may overflow but push_str but will check boundaries
-        let len = sep.len() * (s.len() - 1)
-            + s.iter().map(|s| s.as_slice().len()).sum();
+        let len = sep.len() * (self.len() - 1)
+            + self.iter().map(|s| s.as_ref().len()).sum();
         let mut result = String::with_capacity(len);
         let mut first = true;
 
-        for s in s {
+        for s in self {
             if first {
                 first = false;
             } else {
                 result.push_str(sep);
             }
-            result.push_str(s.as_slice());
+            result.push_str(s.as_ref());
         }
         result
     }
@@ -164,10 +155,13 @@ enum DecompositionType {
     Compatible
 }
 
-/// External iterator for a string's decomposition's characters.
-/// Use with the `std::iter` module.
+/// External iterator for a string decomposition's characters.
+///
+/// For use with the `std::iter` module.
 #[derive(Clone)]
-#[unstable(feature = "collections")]
+#[unstable(feature = "unicode",
+           reason = "this functionality may be replaced with a more generic \
+                     unicode crate on crates.io")]
 pub struct Decompositions<'a> {
     kind: DecompositionType,
     iter: Chars<'a>,
@@ -254,10 +248,13 @@ enum RecompositionState {
     Finished
 }
 
-/// External iterator for a string's recomposition's characters.
-/// Use with the `std::iter` module.
+/// External iterator for a string recomposition's characters.
+///
+/// For use with the `std::iter` module.
 #[derive(Clone)]
-#[unstable(feature = "collections")]
+#[unstable(feature = "unicode",
+           reason = "this functionality may be replaced with a more generic \
+                     unicode crate on crates.io")]
 pub struct Recompositions<'a> {
     iter: Decompositions<'a>,
     state: RecompositionState,
@@ -352,7 +349,8 @@ impl<'a> Iterator for Recompositions<'a> {
 }
 
 /// External iterator for a string's UTF16 codeunits.
-/// Use with the `std::iter` module.
+///
+/// For use with the `std::iter` module.
 #[derive(Clone)]
 #[unstable(feature = "collections")]
 pub struct Utf16Units<'a> {
@@ -383,7 +381,7 @@ macro_rules! utf8_first_byte {
 
 // return the value of $ch updated with continuation byte $byte
 macro_rules! utf8_acc_cont_byte {
-    ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32)
+    ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63) as u32)
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -409,46 +407,47 @@ Section: CowString
 Section: Trait implementations
 */
 
+
 /// Any string that can be represented as a slice.
+#[lang = "str"]
+#[cfg(not(test))]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub trait StrExt: Index<RangeFull, Output = str> {
+impl str {
     /// Escapes each char in `s` with `char::escape_default`.
     #[unstable(feature = "collections",
                reason = "return type may change to be an iterator")]
-    fn escape_default(&self) -> String {
+    pub fn escape_default(&self) -> String {
         self.chars().flat_map(|c| c.escape_default()).collect()
     }
 
     /// Escapes each char in `s` with `char::escape_unicode`.
     #[unstable(feature = "collections",
                reason = "return type may change to be an iterator")]
-    fn escape_unicode(&self) -> String {
+    pub fn escape_unicode(&self) -> String {
         self.chars().flat_map(|c| c.escape_unicode()).collect()
     }
 
     /// Replaces all occurrences of one string with another.
     ///
-    /// # Arguments
-    ///
-    /// * `from` - The string to replace
-    /// * `to` - The replacement string
-    ///
-    /// # Return value
-    ///
-    /// The original string with all occurrences of `from` replaced with `to`.
+    /// `replace` takes two arguments, a sub-`&str` to find in `self`, and a second `&str` to
+    /// replace it with. If the original `&str` isn't found, no change occurs.
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let s = "this is old";
     ///
     /// assert_eq!(s.replace("old", "new"), "this is new");
+    /// ```
+    ///
+    /// When a `&str` isn't found:
     ///
-    /// // not found, so no change.
+    /// ```
+    /// let s = "this is old";
     /// assert_eq!(s.replace("cookie monster", "little lamb"), s);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn replace(&self, from: &str, to: &str) -> String {
+    pub fn replace(&self, from: &str, to: &str) -> String {
         let mut result = String::new();
         let mut last_end = 0;
         for (start, end) in self.match_indices(from) {
@@ -463,9 +462,10 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// Returns an iterator over the string in Unicode Normalization Form D
     /// (canonical decomposition).
     #[inline]
-    #[unstable(feature = "collections",
-               reason = "this functionality may be moved to libunicode")]
-    fn nfd_chars(&self) -> Decompositions {
+    #[unstable(feature = "unicode",
+               reason = "this functionality may be replaced with a more generic \
+                         unicode crate on crates.io")]
+    pub fn nfd_chars(&self) -> Decompositions {
         Decompositions {
             iter: self[..].chars(),
             buffer: Vec::new(),
@@ -477,9 +477,10 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// Returns an iterator over the string in Unicode Normalization Form KD
     /// (compatibility decomposition).
     #[inline]
-    #[unstable(feature = "collections",
-               reason = "this functionality may be moved to libunicode")]
-    fn nfkd_chars(&self) -> Decompositions {
+    #[unstable(feature = "unicode",
+               reason = "this functionality may be replaced with a more generic \
+                         unicode crate on crates.io")]
+    pub fn nfkd_chars(&self) -> Decompositions {
         Decompositions {
             iter: self[..].chars(),
             buffer: Vec::new(),
@@ -491,9 +492,10 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// An Iterator over the string in Unicode Normalization Form C
     /// (canonical decomposition followed by canonical composition).
     #[inline]
-    #[unstable(feature = "collections",
-               reason = "this functionality may be moved to libunicode")]
-    fn nfc_chars(&self) -> Recompositions {
+    #[unstable(feature = "unicode",
+               reason = "this functionality may be replaced with a more generic \
+                         unicode crate on crates.io")]
+    pub fn nfc_chars(&self) -> Recompositions {
         Recompositions {
             iter: self.nfd_chars(),
             state: Composing,
@@ -506,9 +508,10 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// An Iterator over the string in Unicode Normalization Form KC
     /// (compatibility decomposition followed by canonical composition).
     #[inline]
-    #[unstable(feature = "collections",
-               reason = "this functionality may be moved to libunicode")]
-    fn nfkc_chars(&self) -> Recompositions {
+    #[unstable(feature = "unicode",
+               reason = "this functionality may be replaced with a more generic \
+                         unicode crate on crates.io")]
+    pub fn nfkc_chars(&self) -> Recompositions {
         Recompositions {
             iter: self.nfkd_chars(),
             state: Composing,
@@ -518,400 +521,474 @@ pub trait StrExt: Index<RangeFull, Output = str> {
         }
     }
 
-    /// Returns true if a string contains a string pattern.
+    /// Returns `true` if `self` contains another `&str`.
     ///
-    /// # Arguments
-    ///
-    /// - pat - The string pattern to look for
-    ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// assert!("bananas".contains("nana"));
+    ///
+    /// assert!(!"bananas".contains("foobar"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn contains(&self, pat: &str) -> bool {
+    pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
         core_str::StrExt::contains(&self[..], pat)
     }
 
-    /// Returns true if a string contains a char pattern.
-    ///
-    /// # Arguments
+    /// An iterator over the codepoints of `self`.
     ///
-    /// - pat - The char pattern to look for
-    ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
-    /// assert!("hello".contains_char('e'));
     /// ```
-    #[unstable(feature = "collections",
-               reason = "might get removed in favour of a more generic contains()")]
-    fn contains_char<P: CharEq>(&self, pat: P) -> bool {
-        core_str::StrExt::contains_char(&self[..], pat)
-    }
-
-    /// An iterator over the characters of `self`. Note, this iterates
-    /// over Unicode code-points, not Unicode graphemes.
-    ///
-    /// # Example
-    ///
-    /// ```rust
     /// let v: Vec<char> = "abc åäö".chars().collect();
-    /// assert_eq!(v, vec!['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
+    ///
+    /// assert_eq!(v, ['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn chars(&self) -> Chars {
+    pub fn chars(&self) -> Chars {
         core_str::StrExt::chars(&self[..])
     }
 
-    /// An iterator over the bytes of `self`
+    /// An iterator over the bytes of `self`.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let v: Vec<u8> = "bors".bytes().collect();
+    ///
     /// assert_eq!(v, b"bors".to_vec());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn bytes(&self) -> Bytes {
+    pub fn bytes(&self) -> Bytes {
         core_str::StrExt::bytes(&self[..])
     }
 
     /// An iterator over the characters of `self` and their byte offsets.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v: Vec<(usize, char)> = "abc".char_indices().collect();
+    /// let b = vec![(0, 'a'), (1, 'b'), (2, 'c')];
+    ///
+    /// assert_eq!(v, b);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn char_indices(&self) -> CharIndices {
+    pub fn char_indices(&self) -> CharIndices {
         core_str::StrExt::char_indices(&self[..])
     }
 
     /// An iterator over substrings of `self`, separated by characters
-    /// matched by the pattern `pat`.
+    /// matched by a pattern.
     ///
-    /// # Example
+    /// The pattern can be a simple `&str`, or a closure that determines
+    /// the split.
     ///
-    /// ```rust
+    /// # Examples
+    ///
+    /// Simple `&str` patterns:
+    ///
+    /// ```
     /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
-    /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
+    /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
+    ///
+    /// let v: Vec<&str> = "".split('X').collect();
+    /// assert_eq!(v, [""]);
+    /// ```
     ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
     /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
-    /// assert_eq!(v, vec!["abc", "def", "ghi"]);
+    /// assert_eq!(v, ["abc", "def", "ghi"]);
     ///
     /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
-    /// assert_eq!(v, vec!["lion", "", "tiger", "leopard"]);
-    ///
-    /// let v: Vec<&str> = "".split('X').collect();
-    /// assert_eq!(v, vec![""]);
+    /// assert_eq!(v, ["lion", "", "tiger", "leopard"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn split<P: CharEq>(&self, pat: P) -> Split<P> {
+    pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
         core_str::StrExt::split(&self[..], pat)
     }
 
-    /// An iterator over substrings of `self`, separated by characters
-    /// matched by the pattern `pat`, restricted to splitting at most `count`
-    /// times.
+    /// An iterator over substrings of `self`, separated by characters matched
+    /// by a pattern, returning most `count` items.
     ///
-    /// # Example
+    /// The pattern can be a simple `&str`, or a closure that determines
+    /// the split.
     ///
-    /// ```rust
-    /// let v: Vec<&str> = "Mary had a little lambda".splitn(2, ' ').collect();
-    /// assert_eq!(v, vec!["Mary", "had", "a little lambda"]);
+    /// The last element returned, if any, will contain the remainder of the
+    /// string.
+    ///
+    /// # Examples
+    ///
+    /// Simple `&str` patterns:
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".splitn(1, |c: char| c.is_numeric()).collect();
-    /// assert_eq!(v, vec!["abc", "def2ghi"]);
+    /// ```
+    /// let v: Vec<&str> = "Mary had a little lambda".splitn(2, ' ').collect();
+    /// assert_eq!(v, ["Mary", "had a little lambda"]);
     ///
     /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(2, 'X').collect();
-    /// assert_eq!(v, vec!["lion", "", "tigerXleopard"]);
+    /// assert_eq!(v, ["lion", "XtigerXleopard"]);
     ///
-    /// let v: Vec<&str> = "abcXdef".splitn(0, 'X').collect();
-    /// assert_eq!(v, vec!["abcXdef"]);
+    /// let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect();
+    /// assert_eq!(v, ["abcXdef"]);
     ///
     /// let v: Vec<&str> = "".splitn(1, 'X').collect();
-    /// assert_eq!(v, vec![""]);
+    /// assert_eq!(v, [""]);
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// let v: Vec<&str> = "abc1def2ghi".splitn(2, |c: char| c.is_numeric()).collect();
+    /// assert_eq!(v, ["abc", "def2ghi"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn splitn<P: CharEq>(&self, count: usize, pat: P) -> SplitN<P> {
+    pub fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P> {
         core_str::StrExt::splitn(&self[..], count, pat)
     }
 
     /// An iterator over substrings of `self`, separated by characters
-    /// matched by the pattern `pat`.
+    /// matched by a pattern.
     ///
-    /// Equivalent to `split`, except that the trailing substring
-    /// is skipped if empty (terminator semantics).
+    /// Equivalent to `split`, except that the trailing substring is skipped if empty.
     ///
-    /// # Example
+    /// The pattern can be a simple `&str`, or a closure that determines
+    /// the split.
     ///
-    /// ```rust
+    /// # Examples
+    ///
+    /// Simple `&str` patterns:
+    ///
+    /// ```
     /// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
-    /// assert_eq!(v, vec!["A", "B"]);
+    /// assert_eq!(v, ["A", "B"]);
     ///
     /// let v: Vec<&str> = "A..B..".split_terminator('.').collect();
-    /// assert_eq!(v, vec!["A", "", "B", ""]);
-    ///
-    /// let v: Vec<&str> = "Mary had a little lamb".split(' ').rev().collect();
-    /// assert_eq!(v, vec!["lamb", "little", "a", "had", "Mary"]);
+    /// assert_eq!(v, ["A", "", "B", ""]);
+    /// ```
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).rev().collect();
-    /// assert_eq!(v, vec!["ghi", "def", "abc"]);
+    /// More complex patterns with a lambda:
     ///
-    /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').rev().collect();
-    /// assert_eq!(v, vec!["leopard", "tiger", "", "lion"]);
     /// ```
-    #[unstable(feature = "collections", reason = "might get removed")]
-    fn split_terminator<P: CharEq>(&self, pat: P) -> SplitTerminator<P> {
+    /// let v: Vec<&str> = "abc1def2ghi3".split_terminator(|c: char| c.is_numeric()).collect();
+    /// assert_eq!(v, ["abc", "def", "ghi"]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
         core_str::StrExt::split_terminator(&self[..], pat)
     }
 
-    /// An iterator over substrings of `self`, separated by characters
-    /// matched by the pattern `pat`, starting from the end of the string.
-    /// Restricted to splitting at most `count` times.
+    /// An iterator over substrings of `self`, separated by a pattern,
+    /// starting from the end of the string.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
-    /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(2, ' ').collect();
-    /// assert_eq!(v, vec!["lamb", "little", "Mary had a"]);
+    /// Simple patterns:
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |c: char| c.is_numeric()).collect();
-    /// assert_eq!(v, vec!["ghi", "abc1def"]);
+    /// ```
+    /// let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect();
+    /// assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]);
+    ///
+    /// let v: Vec<&str> = "lion::tiger::leopard".rsplit("::").collect();
+    /// assert_eq!(v, ["leopard", "tiger", "lion"]);
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// let v: Vec<&str> = "abc1def2ghi".rsplit(|c: char| c.is_numeric()).collect();
+    /// assert_eq!(v, ["ghi", "def", "abc"]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        core_str::StrExt::rsplit(&self[..], pat)
+    }
+
+    /// An iterator over substrings of `self`, separated by a pattern,
+    /// starting from the end of the string, restricted to returning
+    /// at most `count` items.
+    ///
+    /// The last element returned, if any, will contain the remainder of the
+    /// string.
+    ///
+    /// # Examples
+    ///
+    /// Simple patterns:
+    ///
+    /// ```
+    /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect();
+    /// assert_eq!(v, ["lamb", "little", "Mary had a"]);
+    ///
+    /// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(2, "::").collect();
+    /// assert_eq!(v, ["leopard", "lion::tiger"]);
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
     ///
-    /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect();
-    /// assert_eq!(v, vec!["leopard", "tiger", "lionX"]);
+    /// ```
+    /// let v: Vec<&str> = "abc1def2ghi".rsplitn(2, |c: char| c.is_numeric()).collect();
+    /// assert_eq!(v, ["ghi", "abc1def"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn rsplitn<P: CharEq>(&self, count: usize, pat: P) -> RSplitN<P> {
+    pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
+        where P::Searcher: ReverseSearcher<'a>
+    {
         core_str::StrExt::rsplitn(&self[..], count, pat)
     }
 
-    /// An iterator over the start and end indices of the disjoint
-    /// matches of the pattern `pat` within `self`.
+    /// An iterator over the start and end indices of the disjoint matches of a `&str` within
+    /// `self`.
     ///
-    /// That is, each returned value `(start, end)` satisfies
-    /// `self.slice(start, end) == sep`. For matches of `sep` within
-    /// `self` that overlap, only the indices corresponding to the
-    /// first match are returned.
+    /// That is, each returned value `(start, end)` satisfies `self.slice(start, end) == sep`. For
+    /// matches of `sep` within `self` that overlap, only the indices corresponding to the first
+    /// match are returned.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(collections)]
     /// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".match_indices("abc").collect();
-    /// assert_eq!(v, vec![(0,3), (6,9), (12,15)]);
+    /// assert_eq!(v, [(0,3), (6,9), (12,15)]);
     ///
     /// let v: Vec<(usize, usize)> = "1abcabc2".match_indices("abc").collect();
-    /// assert_eq!(v, vec![(1,4), (4,7)]);
+    /// assert_eq!(v, [(1,4), (4,7)]);
     ///
     /// let v: Vec<(usize, usize)> = "ababa".match_indices("aba").collect();
-    /// assert_eq!(v, vec![(0, 3)]); // only the first `aba`
+    /// assert_eq!(v, [(0, 3)]); // only the first `aba`
     /// ```
     #[unstable(feature = "collections",
                reason = "might have its iterator type changed")]
-    fn match_indices<'a>(&'a self, pat: &'a str) -> MatchIndices<'a> {
+    // NB: Right now MatchIndices yields `(usize, usize)`,
+    // but it would be more consistent and useful to return `(usize, &str)`
+    pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
         core_str::StrExt::match_indices(&self[..], pat)
     }
 
-    /// An iterator over the substrings of `self` separated by the pattern `sep`.
+    /// An iterator over the lines of a string, separated by `\n`.
     ///
-    /// # Example
+    /// This does not include the empty string after a trailing `\n`.
     ///
-    /// ```rust
-    /// let v: Vec<&str> = "abcXXXabcYYYabc".split_str("abc").collect();
-    /// assert_eq!(v, vec!["", "XXX", "YYY", ""]);
+    /// # Examples
     ///
-    /// let v: Vec<&str> = "1abcabc2".split_str("abc").collect();
-    /// assert_eq!(v, vec!["1", "", "2"]);
     /// ```
-    #[unstable(feature = "collections",
-               reason = "might get removed in the future in favor of a more generic split()")]
-    fn split_str<'a>(&'a self, pat: &'a str) -> SplitStr<'a> {
-        core_str::StrExt::split_str(&self[..], pat)
-    }
-
-    /// An iterator over the lines of a string (subsequences separated
-    /// by `\n`). This does not include the empty string after a
-    /// trailing `\n`.
+    /// let four_lines = "foo\nbar\n\nbaz";
+    /// let v: Vec<&str> = four_lines.lines().collect();
     ///
-    /// # Example
+    /// assert_eq!(v, ["foo", "bar", "", "baz"]);
+    /// ```
     ///
-    /// ```rust
+    /// Leaving off the trailing character:
+    ///
+    /// ```
     /// let four_lines = "foo\nbar\n\nbaz\n";
     /// let v: Vec<&str> = four_lines.lines().collect();
-    /// assert_eq!(v, vec!["foo", "bar", "", "baz"]);
+    ///
+    /// assert_eq!(v, ["foo", "bar", "", "baz"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn lines(&self) -> Lines {
+    pub fn lines(&self) -> Lines {
         core_str::StrExt::lines(&self[..])
     }
 
-    /// An iterator over the lines of a string, separated by either
-    /// `\n` or `\r\n`. As with `.lines()`, this does not include an
-    /// empty trailing line.
+    /// An iterator over the lines of a string, separated by either `\n` or `\r\n`.
     ///
-    /// # Example
+    /// As with `.lines()`, this does not include an empty trailing line.
     ///
-    /// ```rust
+    /// # Examples
+    ///
+    /// ```
+    /// let four_lines = "foo\r\nbar\n\r\nbaz";
+    /// let v: Vec<&str> = four_lines.lines_any().collect();
+    ///
+    /// assert_eq!(v, ["foo", "bar", "", "baz"]);
+    /// ```
+    ///
+    /// Leaving off the trailing character:
+    ///
+    /// ```
     /// let four_lines = "foo\r\nbar\n\r\nbaz\n";
     /// let v: Vec<&str> = four_lines.lines_any().collect();
-    /// assert_eq!(v, vec!["foo", "bar", "", "baz"]);
+    ///
+    /// assert_eq!(v, ["foo", "bar", "", "baz"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn lines_any(&self) -> LinesAny {
+    pub fn lines_any(&self) -> LinesAny {
         core_str::StrExt::lines_any(&self[..])
     }
-
-    /// Deprecated: use `s[a .. b]` instead.
-    #[unstable(feature = "collections",
-               reason = "use slice notation [a..b] instead")]
-    #[deprecated(since = "1.0.0", reason = "use slice notation [a..b] instead")]
-    fn slice(&self, begin: usize, end: usize) -> &str;
-
-    /// Deprecated: use `s[a..]` instead.
-    #[unstable(feature = "collections",
-               reason = "use slice notation [a..b] instead")]
-    #[deprecated(since = "1.0.0", reason = "use slice notation [a..] instead")]
-    fn slice_from(&self, begin: usize) -> &str;
-
-    /// Deprecated: use `s[..a]` instead.
-    #[unstable(feature = "collections",
-               reason = "use slice notation [a..b] instead")]
-    #[deprecated(since = "1.0.0", reason = "use slice notation [..a] instead")]
-    fn slice_to(&self, end: usize) -> &str;
-
-    /// Returns a slice of the string from the character range
-    /// [`begin`..`end`).
+    /// Returns a slice of the string from the character range [`begin`..`end`).
     ///
-    /// That is, start at the `begin`-th code point of the string and
-    /// continue to the `end`-th code point. This does not detect or
-    /// handle edge cases such as leaving a combining character as the
-    /// first code point of the string.
+    /// That is, start at the `begin`-th code point of the string and continue
+    /// to the `end`-th code point. This does not detect or handle edge cases
+    /// such as leaving a combining character as the first code point of the
+    /// string.
     ///
-    /// Due to the design of UTF-8, this operation is `O(end)`.
-    /// See `slice`, `slice_to` and `slice_from` for `O(1)`
-    /// variants that use byte indices rather than code point
-    /// indices.
+    /// Due to the design of UTF-8, this operation is `O(end)`. See `slice`,
+    /// `slice_to` and `slice_from` for `O(1)` variants that use byte indices
+    /// rather than code point indices.
     ///
-    /// Panics if `begin` > `end` or the either `begin` or `end` are
-    /// beyond the last character of the string.
+    /// # Panics
     ///
-    /// # Example
+    /// Panics if `begin` > `end` or the either `begin` or `end` are beyond the
+    /// last character of the string.
     ///
-    /// ```rust
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(collections)]
     /// let s = "Löwe 老虎 Léopard";
+    ///
     /// assert_eq!(s.slice_chars(0, 4), "Löwe");
     /// assert_eq!(s.slice_chars(5, 7), "老虎");
     /// ```
     #[unstable(feature = "collections",
                reason = "may have yet to prove its worth")]
-    fn slice_chars(&self, begin: usize, end: usize) -> &str {
+    pub fn slice_chars(&self, begin: usize, end: usize) -> &str {
         core_str::StrExt::slice_chars(&self[..], begin, end)
     }
 
-    /// Takes a bytewise (not UTF-8) slice from a string.
+    /// Takes a bytewise slice from a string.
     ///
     /// Returns the substring from [`begin`..`end`).
     ///
-    /// Caller must check both UTF-8 character boundaries and the boundaries of
-    /// the entire slice as well.
+    /// # Unsafety
+    ///
+    /// Caller must check both UTF-8 character boundaries and the boundaries of the entire slice as
+    /// well.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    ///
+    /// unsafe {
+    ///     assert_eq!(s.slice_unchecked(0, 21), "Löwe 老虎 Léopard");
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
+    pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
         core_str::StrExt::slice_unchecked(&self[..], begin, end)
     }
 
-    /// Returns true if the pattern `pat` is a prefix of the string.
+    /// Returns `true` if the given `&str` is a prefix of the string.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// assert!("banana".starts_with("ba"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn starts_with(&self, pat: &str) -> bool {
+    pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
         core_str::StrExt::starts_with(&self[..], pat)
     }
 
-    /// Returns true if the pattern `pat` is a suffix of the string.
+    /// Returns true if the given `&str` is a suffix of the string.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```rust
     /// assert!("banana".ends_with("nana"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn ends_with(&self, pat: &str) -> bool {
+    pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
+        where P::Searcher: ReverseSearcher<'a>
+    {
         core_str::StrExt::ends_with(&self[..], pat)
     }
 
-    /// Returns a string with all pre- and suffixes that match
-    /// the pattern `pat` repeatedly removed.
+    /// Returns a string with all pre- and suffixes that match a pattern repeatedly removed.
     ///
-    /// # Arguments
+    /// The pattern can be a simple `&str`, or a closure that determines the split.
     ///
-    /// * pat - a string pattern
+    /// # Examples
     ///
-    /// # Example
+    /// Simple `&str` patterns:
     ///
-    /// ```rust
+    /// ```
     /// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
+    ///
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
     /// assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn trim_matches<P: CharEq>(&self, pat: P) -> &str {
+    pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+        where P::Searcher: DoubleEndedSearcher<'a>
+    {
         core_str::StrExt::trim_matches(&self[..], pat)
     }
 
-    /// Returns a string with all prefixes that match
-    /// the pattern `pat` repeatedly removed.
+    /// Returns a string with all prefixes that match a pattern repeatedly removed.
     ///
-    /// # Arguments
+    /// The pattern can be a simple `&str`, or a closure that determines the split.
     ///
-    /// * pat - a string pattern
+    /// # Examples
     ///
-    /// # Example
+    /// Simple `&str` patterns:
     ///
-    /// ```rust
+    /// ```
     /// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
+    ///
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
     /// assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn trim_left_matches<P: CharEq>(&self, pat: P) -> &str {
+    pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
         core_str::StrExt::trim_left_matches(&self[..], pat)
     }
 
-    /// Returns a string with all suffixes that match
-    /// the pattern `pat` repeatedly removed.
+    /// Returns a string with all suffixes that match a pattern repeatedly removed.
     ///
-    /// # Arguments
+    /// The pattern can be a simple `&str`, or a closure that determines the split.
     ///
-    /// * pat - a string pattern
+    /// # Examples
     ///
-    /// # Example
+    /// Simple `&str` patterns:
     ///
-    /// ```rust
+    /// ```
     /// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
     /// assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn trim_right_matches<P: CharEq>(&self, pat: P) -> &str {
+    pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+        where P::Searcher: ReverseSearcher<'a>
+    {
         core_str::StrExt::trim_right_matches(&self[..], pat)
     }
 
-    /// Check that `index`-th byte lies at the start and/or end of a
-    /// UTF-8 code point sequence.
+    /// Check that `index`-th byte lies at the start and/or end of a UTF-8 code point sequence.
     ///
-    /// The start and end of the string (when `index == self.len()`)
-    /// are considered to be boundaries.
+    /// The start and end of the string (when `index == self.len()`) are considered to be
+    /// boundaries.
+    ///
+    /// # Panics
     ///
     /// Panics if `index` is greater than `self.len()`.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(str_char)]
     /// let s = "Löwe 老虎 Léopard";
     /// assert!(s.is_char_boundary(0));
     /// // start of `老`
@@ -924,25 +1001,31 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// // third byte of `老`
     /// assert!(!s.is_char_boundary(8));
     /// ```
-    #[unstable(feature = "collections",
-               reason = "naming is uncertain with container conventions")]
-    fn is_char_boundary(&self, index: usize) -> bool {
+    #[unstable(feature = "str_char",
+               reason = "it is unclear whether this method pulls its weight \
+                         with the existence of the char_indices iterator or \
+                         this method may want to be replaced with checked \
+                         slicing")]
+    pub fn is_char_boundary(&self, index: usize) -> bool {
         core_str::StrExt::is_char_boundary(&self[..], index)
     }
 
-    /// Pluck a character out of a string and return the index of the next
-    /// character.
+    /// Given a byte position, return the next char and its index.
     ///
-    /// This function can be used to iterate over the Unicode characters of a
-    /// string.
+    /// This can be used to iterate over the Unicode characters of a string.
     ///
-    /// # Example
+    /// # Panics
     ///
-    /// This example manually iterates through the characters of a
-    /// string; this should normally be done by `.chars()` or
-    /// `.char_indices`.
+    /// If `i` is greater than or equal to the length of the string.
+    /// If `i` is not the index of the beginning of a valid UTF-8 character.
     ///
-    /// ```rust
+    /// # Examples
+    ///
+    /// This example manually iterates through the characters of a string; this should normally be
+    /// done by `.chars()` or `.char_indices()`.
+    ///
+    /// ```
+    /// # #![feature(str_char, core)]
     /// use std::str::CharRange;
     ///
     /// let s = "中华Việt Nam";
@@ -968,28 +1051,15 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// 14: a
     /// 15: m
     /// ```
-    ///
-    /// # Arguments
-    ///
-    /// * s - The string
-    /// * i - The byte offset of the char to extract
-    ///
-    /// # Return value
-    ///
-    /// A record {ch: char, next: usize} containing the char value and the byte
-    /// index of the next Unicode character.
-    ///
-    /// # Panics
-    ///
-    /// If `i` is greater than or equal to the length of the string.
-    /// If `i` is not the index of the beginning of a valid UTF-8 character.
-    #[unstable(feature = "collections",
-               reason = "naming is uncertain with container conventions")]
-    fn char_range_at(&self, start: usize) -> CharRange {
+    #[unstable(feature = "str_char",
+               reason = "often replaced by char_indices, this method may \
+                         be removed in favor of just char_at() or eventually \
+                         removed altogether")]
+    pub fn char_range_at(&self, start: usize) -> CharRange {
         core_str::StrExt::char_range_at(&self[..], start)
     }
 
-    /// Given a byte position and a str, return the previous char and its position.
+    /// Given a byte position, return the previous `char` and its position.
     ///
     /// This function can be used to iterate over a Unicode string in reverse.
     ///
@@ -999,169 +1069,228 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     ///
     /// If `i` is greater than the length of the string.
     /// If `i` is not an index following a valid UTF-8 character.
-    #[unstable(feature = "collections",
-               reason = "naming is uncertain with container conventions")]
-    fn char_range_at_reverse(&self, start: usize) -> CharRange {
-        core_str::StrExt::char_range_at_reverse(&self[..], start)
-    }
-
-    /// Plucks the character starting at the `i`th byte of a string.
     ///
-    /// # Example
+    /// # Examples
+    ///
+    /// This example manually iterates through the characters of a string; this should normally be
+    /// done by `.chars().rev()` or `.char_indices()`.
     ///
-    /// ```rust
-    /// let s = "abπc";
-    /// assert_eq!(s.char_at(1), 'b');
-    /// assert_eq!(s.char_at(2), 'π');
-    /// assert_eq!(s.char_at(4), 'c');
     /// ```
+    /// # #![feature(str_char, core)]
+    /// use std::str::CharRange;
     ///
-    /// # Panics
+    /// let s = "中华Việt Nam";
+    /// let mut i = s.len();
+    /// while i > 0 {
+    ///     let CharRange {ch, next} = s.char_range_at_reverse(i);
+    ///     println!("{}: {}", i, ch);
+    ///     i = next;
+    /// }
+    /// ```
     ///
-    /// If `i` is greater than or equal to the length of the string.
-    /// If `i` is not the index of the beginning of a valid UTF-8 character.
-    #[unstable(feature = "collections",
-               reason = "naming is uncertain with container conventions")]
-    fn char_at(&self, i: usize) -> char {
-        core_str::StrExt::char_at(&self[..], i)
+    /// This outputs:
+    ///
+    /// ```text
+    /// 16: m
+    /// 15: a
+    /// 14: N
+    /// 13:
+    /// 12: t
+    /// 11: ệ
+    /// 8: i
+    /// 7: V
+    /// 6: 华
+    /// 3: 中
+    /// ```
+    #[unstable(feature = "str_char",
+               reason = "often replaced by char_indices, this method may \
+                         be removed in favor of just char_at_reverse() or \
+                         eventually removed altogether")]
+    pub fn char_range_at_reverse(&self, start: usize) -> CharRange {
+        core_str::StrExt::char_range_at_reverse(&self[..], start)
     }
 
-    /// Plucks the character ending at the `i`th byte of a string.
+    /// Given a byte position, return the `char` at that position.
+    ///
+    /// # Panics
+    ///
+    /// If `i` is greater than or equal to the length of the string.
+    /// If `i` is not the index of the beginning of a valid UTF-8 character.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(str_char)]
+    /// let s = "abπc";
+    /// assert_eq!(s.char_at(1), 'b');
+    /// assert_eq!(s.char_at(2), 'π');
+    /// ```
+    #[unstable(feature = "str_char",
+               reason = "frequently replaced by the chars() iterator, this \
+                         method may be removed or possibly renamed in the \
+                         future; it is normally replaced by chars/char_indices \
+                         iterators or by getting the first char from a \
+                         subslice")]
+    pub fn char_at(&self, i: usize) -> char {
+        core_str::StrExt::char_at(&self[..], i)
+    }
+
+    /// Given a byte position, return the `char` at that position, counting from the end.
     ///
     /// # Panics
     ///
     /// If `i` is greater than the length of the string.
     /// If `i` is not an index following a valid UTF-8 character.
-    #[unstable(feature = "collections",
-               reason = "naming is uncertain with container conventions")]
-    fn char_at_reverse(&self, i: usize) -> char {
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(str_char)]
+    /// let s = "abπc";
+    /// assert_eq!(s.char_at_reverse(1), 'a');
+    /// assert_eq!(s.char_at_reverse(2), 'b');
+    /// ```
+    #[unstable(feature = "str_char",
+               reason = "see char_at for more details, but reverse semantics \
+                         are also somewhat unclear, especially with which \
+                         cases generate panics")]
+    pub fn char_at_reverse(&self, i: usize) -> char {
         core_str::StrExt::char_at_reverse(&self[..], i)
     }
 
-    /// Work with the byte buffer of a string as a byte slice.
+    /// Convert `self` to a byte slice.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// assert_eq!("bors".as_bytes(), b"bors");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn as_bytes(&self) -> &[u8] {
+    pub fn as_bytes(&self) -> &[u8] {
         core_str::StrExt::as_bytes(&self[..])
     }
 
-    /// Returns the byte index of the first character of `self` that
-    /// matches the pattern `pat`.
+    /// Returns the byte index of the first character of `self` that matches the pattern, if it
+    /// exists.
     ///
-    /// # Return value
+    /// Returns `None` if it doesn't exist.
     ///
-    /// `Some` containing the byte index of the last matching character
-    /// or `None` if there is no match
+    /// The pattern can be a simple `&str`, or a closure that determines the split.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// Simple `&str` patterns:
+    ///
+    /// ```
     /// let s = "Löwe 老虎 Léopard";
     ///
     /// assert_eq!(s.find('L'), Some(0));
     /// assert_eq!(s.find('é'), Some(14));
     ///
-    /// // the first space
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    ///
     /// assert_eq!(s.find(|c: char| c.is_whitespace()), Some(5));
+    /// ```
     ///
-    /// // neither are found
+    /// Not finding the pattern:
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
     /// let x: &[_] = &['1', '2'];
+    ///
     /// assert_eq!(s.find(x), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn find<P: CharEq>(&self, pat: P) -> Option<usize> {
+    pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
         core_str::StrExt::find(&self[..], pat)
     }
 
-    /// Returns the byte index of the last character of `self` that
-    /// matches the pattern `pat`.
+    /// Returns the byte index of the last character of `self` that matches the pattern, if it
+    /// exists.
     ///
-    /// # Return value
+    /// Returns `None` if it doesn't exist.
     ///
-    /// `Some` containing the byte index of the last matching character
-    /// or `None` if there is no match.
+    /// The pattern can be a simple `&str`, or a closure that determines the split.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// Simple `&str` patterns:
+    ///
+    /// ```
     /// let s = "Löwe 老虎 Léopard";
     ///
     /// assert_eq!(s.rfind('L'), Some(13));
     /// assert_eq!(s.rfind('é'), Some(14));
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
     ///
-    /// // the second space
     /// assert_eq!(s.rfind(|c: char| c.is_whitespace()), Some(12));
+    /// ```
+    ///
+    /// Not finding the pattern:
     ///
-    /// // searches for an occurrence of either `1` or `2`, but neither are found
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
     /// let x: &[_] = &['1', '2'];
+    ///
     /// assert_eq!(s.rfind(x), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn rfind<P: CharEq>(&self, pat: P) -> Option<usize> {
+    pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
+        where P::Searcher: ReverseSearcher<'a>
+    {
         core_str::StrExt::rfind(&self[..], pat)
     }
 
-    /// Returns the byte index of the first matching substring
-    ///
-    /// # Arguments
+    /// Retrieves the first character from a `&str` and returns it.
     ///
-    /// * `needle` - The string to search for
+    /// This does not allocate a new string; instead, it returns a slice that points one character
+    /// beyond the character that was shifted.
     ///
-    /// # Return value
-    ///
-    /// `Some` containing the byte index of the first matching substring
-    /// or `None` if there is no match.
-    ///
-    /// # Example
+    /// If the slice does not contain any characters, None is returned instead.
     ///
-    /// ```rust
-    /// let s = "Löwe 老虎 Léopard";
+    /// # Examples
     ///
-    /// assert_eq!(s.find_str("老虎 L"), Some(6));
-    /// assert_eq!(s.find_str("muffin man"), None);
     /// ```
-    #[unstable(feature = "collections",
-               reason = "might get removed in favor of a more generic find in the future")]
-    fn find_str(&self, needle: &str) -> Option<usize> {
-        core_str::StrExt::find_str(&self[..], needle)
-    }
-
-    /// Retrieves the first character from a string slice and returns
-    /// it. This does not allocate a new string; instead, it returns a
-    /// slice that point one character beyond the character that was
-    /// shifted. If the string does not contain any characters,
-    /// None is returned instead.
-    ///
-    /// # Example
-    ///
-    /// ```rust
+    /// # #![feature(str_char)]
     /// let s = "Löwe 老虎 Léopard";
     /// let (c, s1) = s.slice_shift_char().unwrap();
+    ///
     /// assert_eq!(c, 'L');
     /// assert_eq!(s1, "öwe 老虎 Léopard");
     ///
     /// let (c, s2) = s1.slice_shift_char().unwrap();
+    ///
     /// assert_eq!(c, 'ö');
     /// assert_eq!(s2, "we 老虎 Léopard");
     /// ```
-    #[unstable(feature = "collections",
-               reason = "awaiting conventions about shifting and slices")]
-    fn slice_shift_char(&self) -> Option<(char, &str)> {
+    #[unstable(feature = "str_char",
+               reason = "awaiting conventions about shifting and slices and \
+                         may not be warranted with the existence of the chars \
+                         and/or char_indices iterators")]
+    pub fn slice_shift_char(&self) -> Option<(char, &str)> {
         core_str::StrExt::slice_shift_char(&self[..])
     }
 
     /// Returns the byte offset of an inner slice relative to an enclosing outer slice.
     ///
+    /// # Panics
+    ///
     /// Panics if `inner` is not a direct slice contained within self.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(collections)]
     /// let string = "a\nb\nc";
     /// let lines: Vec<&str> = string.lines().collect();
     ///
@@ -1171,1870 +1300,228 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// ```
     #[unstable(feature = "collections",
                reason = "awaiting convention about comparability of arbitrary slices")]
-    fn subslice_offset(&self, inner: &str) -> usize {
+    pub fn subslice_offset(&self, inner: &str) -> usize {
         core_str::StrExt::subslice_offset(&self[..], inner)
     }
 
-    /// Return an unsafe pointer to the strings buffer.
+    /// Return an unsafe pointer to the `&str`'s buffer.
+    ///
+    /// The caller must ensure that the string outlives this pointer, and that it is not
+    /// reallocated (e.g. by pushing to the string).
     ///
-    /// The caller must ensure that the string outlives this pointer,
-    /// and that it is not reallocated (e.g. by pushing to the
-    /// string).
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "Hello";
+    /// let p = s.as_ptr();
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    fn as_ptr(&self) -> *const u8 {
+    pub fn as_ptr(&self) -> *const u8 {
         core_str::StrExt::as_ptr(&self[..])
     }
 
     /// Return an iterator of `u16` over the string encoded as UTF-16.
     #[unstable(feature = "collections",
                reason = "this functionality may only be provided by libunicode")]
-    fn utf16_units(&self) -> Utf16Units {
+    pub fn utf16_units(&self) -> Utf16Units {
         Utf16Units { encoder: Utf16Encoder::new(self[..].chars()) }
     }
 
-    /// Return the number of bytes in this string
+    /// Returns the length of `self` in bytes.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// assert_eq!("foo".len(), 3);
-    /// assert_eq!("ƒoo".len(), 4);
+    /// assert_eq!("ƒoo".len(), 4); // fancy f!
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    fn len(&self) -> usize {
+    pub fn len(&self) -> usize {
         core_str::StrExt::len(&self[..])
     }
 
-    /// Returns true if this slice contains no bytes
+    /// Returns true if this slice has a length of zero bytes.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// assert!("".is_empty());
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_empty(&self) -> bool {
+    pub fn is_empty(&self) -> bool {
         core_str::StrExt::is_empty(&self[..])
     }
 
-    /// Parse this string into the specified type.
+    /// Parses `self` into the specified type.
+    ///
+    /// # Failure
+    ///
+    /// Will return `Err` if it's not possible to parse `self` into the type.
     ///
     /// # Example
     ///
     /// ```
     /// assert_eq!("4".parse::<u32>(), Ok(4));
+    /// ```
+    ///
+    /// Failing:
+    ///
+    /// ```
     /// assert!("j".parse::<u32>().is_err());
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
+    pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
         core_str::StrExt::parse(&self[..])
     }
 
-    /// Returns an iterator over the
-    /// [grapheme clusters](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)
-    /// of the string.
+    /// Returns an iterator over the [grapheme clusters][graphemes] of `self`.
+    ///
+    /// [graphemes]: http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
     ///
     /// If `is_extended` is true, the iterator is over the *extended grapheme clusters*;
     /// otherwise, the iterator is over the *legacy grapheme clusters*.
     /// [UAX#29](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)
     /// recommends extended grapheme cluster boundaries for general processing.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(unicode, core)]
     /// let gr1 = "a\u{310}e\u{301}o\u{308}\u{332}".graphemes(true).collect::<Vec<&str>>();
     /// let b: &[_] = &["a\u{310}", "e\u{301}", "o\u{308}\u{332}"];
-    /// assert_eq!(gr1.as_slice(), b);
+    ///
+    /// assert_eq!(&gr1[..], b);
+    ///
     /// let gr2 = "a\r\nb🇷🇺🇸🇹".graphemes(true).collect::<Vec<&str>>();
     /// let b: &[_] = &["a", "\r\n", "b", "🇷🇺🇸🇹"];
-    /// assert_eq!(gr2.as_slice(), b);
+    ///
+    /// assert_eq!(&gr2[..], b);
     /// ```
-    #[unstable(feature = "collections",
+    #[unstable(feature = "unicode",
                reason = "this functionality may only be provided by libunicode")]
-    fn graphemes(&self, is_extended: bool) -> Graphemes {
+    pub fn graphemes(&self, is_extended: bool) -> Graphemes {
         UnicodeStr::graphemes(&self[..], is_extended)
     }
 
-    /// Returns an iterator over the grapheme clusters of self and their byte offsets.
-    /// See `graphemes()` method for more information.
+    /// Returns an iterator over the grapheme clusters of `self` and their byte offsets. See
+    /// `graphemes()` for more information.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(unicode, core)]
     /// let gr_inds = "a̐éö̲\r\n".grapheme_indices(true).collect::<Vec<(usize, &str)>>();
     /// let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
-    /// assert_eq!(gr_inds.as_slice(), b);
+    ///
+    /// assert_eq!(&gr_inds[..], b);
     /// ```
-    #[unstable(feature = "collections",
+    #[unstable(feature = "unicode",
                reason = "this functionality may only be provided by libunicode")]
-    fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
+    pub fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
         UnicodeStr::grapheme_indices(&self[..], is_extended)
     }
 
-    /// An iterator over the words of a string (subsequences separated
-    /// by any sequence of whitespace). Sequences of whitespace are
-    /// collapsed, so empty "words" are not included.
+    /// An iterator over the non-empty words of `self`.
     ///
-    /// # Example
+    /// A 'word' is a subsequence separated by any sequence of whitespace. Sequences of whitespace
+    /// are collapsed, so empty "words" are not included.
     ///
-    /// ```rust
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(str_words)]
     /// let some_words = " Mary   had\ta little  \n\t lamb";
     /// let v: Vec<&str> = some_words.words().collect();
-    /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
+    ///
+    /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
     /// ```
     #[unstable(feature = "str_words",
                reason = "the precise algorithm to use is unclear")]
-    fn words(&self) -> Words {
+    pub fn words(&self) -> Words {
         UnicodeStr::words(&self[..])
     }
 
-    /// Returns a string's displayed width in columns, treating control
-    /// characters as zero-width.
+    /// Returns a string's displayed width in columns.
     ///
-    /// `is_cjk` determines behavior for characters in the Ambiguous category:
-    /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
-    /// In CJK locales, `is_cjk` should be `true`, else it should be `false`.
-    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
-    /// recommends that these characters be treated as 1 column (i.e.,
-    /// `is_cjk` = `false`) if the locale is unknown.
-    #[unstable(feature = "collections",
+    /// Control characters have zero width.
+    ///
+    /// `is_cjk` determines behavior for characters in the Ambiguous category: if `is_cjk` is
+    /// `true`, these are 2 columns wide; otherwise, they are 1. In CJK locales, `is_cjk` should be
+    /// `true`, else it should be `false`.
+    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/) recommends that these
+    /// characters be treated as 1 column (i.e., `is_cjk = false`) if the locale is unknown.
+    #[unstable(feature = "unicode",
                reason = "this functionality may only be provided by libunicode")]
-    fn width(&self, is_cjk: bool) -> usize {
+    pub fn width(&self, is_cjk: bool) -> usize {
         UnicodeStr::width(&self[..], is_cjk)
     }
 
-    /// Returns a string with leading and trailing whitespace removed.
+    /// Returns a `&str` with leading and trailing whitespace removed.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = " Hello\tworld\t";
+    /// assert_eq!(s.trim(), "Hello\tworld");
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn trim(&self) -> &str {
+    pub fn trim(&self) -> &str {
         UnicodeStr::trim(&self[..])
     }
 
-    /// Returns a string with leading whitespace removed.
+    /// Returns a `&str` with leading whitespace removed.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = " Hello\tworld\t";
+    /// assert_eq!(s.trim_left(), "Hello\tworld\t");
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn trim_left(&self) -> &str {
+    pub fn trim_left(&self) -> &str {
         UnicodeStr::trim_left(&self[..])
     }
 
-    /// Returns a string with trailing whitespace removed.
+    /// Returns a `&str` with trailing whitespace removed.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = " Hello\tworld\t";
+    /// assert_eq!(s.trim_right(), " Hello\tworld");
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn trim_right(&self) -> &str {
+    pub fn trim_right(&self) -> &str {
         UnicodeStr::trim_right(&self[..])
     }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl StrExt for str {
-    fn slice(&self, begin: usize, end: usize) -> &str {
-        &self[begin..end]
-    }
-
-    fn slice_from(&self, begin: usize) -> &str {
-        &self[begin..]
-    }
-
-    fn slice_to(&self, end: usize) -> &str {
-        &self[..end]
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-
-    use core::iter::AdditiveIterator;
-    use super::from_utf8;
-    use super::Utf8Error;
-
-    #[test]
-    fn test_le() {
-        assert!("" <= "");
-        assert!("" <= "foo");
-        assert!("foo" <= "foo");
-        assert!("foo" != "bar");
-    }
-
-    #[test]
-    fn test_len() {
-        assert_eq!("".len(), 0);
-        assert_eq!("hello world".len(), 11);
-        assert_eq!("\x63".len(), 1);
-        assert_eq!("\u{a2}".len(), 2);
-        assert_eq!("\u{3c0}".len(), 2);
-        assert_eq!("\u{2620}".len(), 3);
-        assert_eq!("\u{1d11e}".len(), 4);
-
-        assert_eq!("".chars().count(), 0);
-        assert_eq!("hello world".chars().count(), 11);
-        assert_eq!("\x63".chars().count(), 1);
-        assert_eq!("\u{a2}".chars().count(), 1);
-        assert_eq!("\u{3c0}".chars().count(), 1);
-        assert_eq!("\u{2620}".chars().count(), 1);
-        assert_eq!("\u{1d11e}".chars().count(), 1);
-        assert_eq!("ประเทศไทย中华Việt Nam".chars().count(), 19);
-
-        assert_eq!("hello".width(false), 10);
-        assert_eq!("hello".width(true), 10);
-        assert_eq!("\0\0\0\0\0".width(false), 0);
-        assert_eq!("\0\0\0\0\0".width(true), 0);
-        assert_eq!("".width(false), 0);
-        assert_eq!("".width(true), 0);
-        assert_eq!("\u{2081}\u{2082}\u{2083}\u{2084}".width(false), 4);
-        assert_eq!("\u{2081}\u{2082}\u{2083}\u{2084}".width(true), 8);
-    }
-
-    #[test]
-    fn test_find() {
-        assert_eq!("hello".find('l'), Some(2));
-        assert_eq!("hello".find(|c:char| c == 'o'), Some(4));
-        assert!("hello".find('x').is_none());
-        assert!("hello".find(|c:char| c == 'x').is_none());
-        assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30));
-        assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30));
-    }
-
-    #[test]
-    fn test_rfind() {
-        assert_eq!("hello".rfind('l'), Some(3));
-        assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4));
-        assert!("hello".rfind('x').is_none());
-        assert!("hello".rfind(|c:char| c == 'x').is_none());
-        assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30));
-        assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30));
-    }
-
-    #[test]
-    fn test_collect() {
-        let empty = String::from_str("");
-        let s: String = empty.chars().collect();
-        assert_eq!(empty, s);
-        let data = String::from_str("ประเทศไทย中");
-        let s: String = data.chars().collect();
-        assert_eq!(data, s);
-    }
-
-    #[test]
-    fn test_into_bytes() {
-        let data = String::from_str("asdf");
-        let buf = data.into_bytes();
-        assert_eq!(b"asdf", buf);
-    }
-
-    #[test]
-    fn test_find_str() {
-        // byte positions
-        assert_eq!("".find_str(""), Some(0));
-        assert!("banana".find_str("apple pie").is_none());
-
-        let data = "abcabc";
-        assert_eq!(data[0..6].find_str("ab"), Some(0));
-        assert_eq!(data[2..6].find_str("ab"), Some(3 - 2));
-        assert!(data[2..4].find_str("ab").is_none());
-
-        let string = "ประเทศไทย中华Việt Nam";
-        let mut data = String::from_str(string);
-        data.push_str(string);
-        assert!(data.find_str("ไท华").is_none());
-        assert_eq!(data[0..43].find_str(""), Some(0));
-        assert_eq!(data[6..43].find_str(""), Some(6 - 6));
-
-        assert_eq!(data[0..43].find_str("ประ"), Some( 0));
-        assert_eq!(data[0..43].find_str("ทศไ"), Some(12));
-        assert_eq!(data[0..43].find_str("ย中"), Some(24));
-        assert_eq!(data[0..43].find_str("iệt"), Some(34));
-        assert_eq!(data[0..43].find_str("Nam"), Some(40));
-
-        assert_eq!(data[43..86].find_str("ประ"), Some(43 - 43));
-        assert_eq!(data[43..86].find_str("ทศไ"), Some(55 - 43));
-        assert_eq!(data[43..86].find_str("ย中"), Some(67 - 43));
-        assert_eq!(data[43..86].find_str("iệt"), Some(77 - 43));
-        assert_eq!(data[43..86].find_str("Nam"), Some(83 - 43));
-    }
-
-    #[test]
-    fn test_slice_chars() {
-        fn t(a: &str, b: &str, start: usize) {
-            assert_eq!(a.slice_chars(start, start + b.chars().count()), b);
-        }
-        t("", "", 0);
-        t("hello", "llo", 2);
-        t("hello", "el", 1);
-        t("αβλ", "β", 1);
-        t("αβλ", "", 3);
-        assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
-    }
-
-    fn s(x: &str) -> String { x.to_string() }
-
-    macro_rules! test_concat {
-        ($expected: expr, $string: expr) => {
-            {
-                let s: String = $string.concat();
-                assert_eq!($expected, s);
-            }
-        }
-    }
-
-    #[test]
-    fn test_concat_for_different_types() {
-        test_concat!("ab", vec![s("a"), s("b")]);
-        test_concat!("ab", vec!["a", "b"]);
-        test_concat!("ab", vec!["a", "b"]);
-        test_concat!("ab", vec![s("a"), s("b")]);
-    }
-
-    #[test]
-    fn test_concat_for_different_lengths() {
-        let empty: &[&str] = &[];
-        test_concat!("", empty);
-        test_concat!("a", ["a"]);
-        test_concat!("ab", ["a", "b"]);
-        test_concat!("abc", ["", "a", "bc"]);
-    }
-
-    macro_rules! test_connect {
-        ($expected: expr, $string: expr, $delim: expr) => {
-            {
-                let s = $string.connect($delim);
-                assert_eq!($expected, s);
-            }
-        }
-    }
-
-    #[test]
-    fn test_connect_for_different_types() {
-        test_connect!("a-b", ["a", "b"], "-");
-        let hyphen = "-".to_string();
-        test_connect!("a-b", [s("a"), s("b")], &*hyphen);
-        test_connect!("a-b", vec!["a", "b"], &*hyphen);
-        test_connect!("a-b", &*vec!["a", "b"], "-");
-        test_connect!("a-b", vec![s("a"), s("b")], "-");
-    }
-
-    #[test]
-    fn test_connect_for_different_lengths() {
-        let empty: &[&str] = &[];
-        test_connect!("", empty, "-");
-        test_connect!("a", ["a"], "-");
-        test_connect!("a-b", ["a", "b"], "-");
-        test_connect!("-a-bc", ["", "a", "bc"], "-");
-    }
-
-    #[test]
-    fn test_unsafe_slice() {
-        assert_eq!("ab", unsafe {"abc".slice_unchecked(0, 2)});
-        assert_eq!("bc", unsafe {"abc".slice_unchecked(1, 3)});
-        assert_eq!("", unsafe {"abc".slice_unchecked(1, 1)});
-        fn a_million_letter_a() -> String {
-            let mut i = 0;
-            let mut rs = String::new();
-            while i < 100000 {
-                rs.push_str("aaaaaaaaaa");
-                i += 1;
-            }
-            rs
-        }
-        fn half_a_million_letter_a() -> String {
-            let mut i = 0;
-            let mut rs = String::new();
-            while i < 100000 {
-                rs.push_str("aaaaa");
-                i += 1;
-            }
-            rs
-        }
-        let letters = a_million_letter_a();
-        assert!(half_a_million_letter_a() ==
-            unsafe {String::from_str(letters.slice_unchecked(
-                                     0,
-                                     500000))});
-    }
-
-    #[test]
-    fn test_starts_with() {
-        assert!(("".starts_with("")));
-        assert!(("abc".starts_with("")));
-        assert!(("abc".starts_with("a")));
-        assert!((!"a".starts_with("abc")));
-        assert!((!"".starts_with("abc")));
-        assert!((!"ödd".starts_with("-")));
-        assert!(("ödd".starts_with("öd")));
-    }
-
-    #[test]
-    fn test_ends_with() {
-        assert!(("".ends_with("")));
-        assert!(("abc".ends_with("")));
-        assert!(("abc".ends_with("c")));
-        assert!((!"a".ends_with("abc")));
-        assert!((!"".ends_with("abc")));
-        assert!((!"ddö".ends_with("-")));
-        assert!(("ddö".ends_with("dö")));
-    }
-
-    #[test]
-    fn test_is_empty() {
-        assert!("".is_empty());
-        assert!(!"a".is_empty());
-    }
-
-    #[test]
-    fn test_replace() {
-        let a = "a";
-        assert_eq!("".replace(a, "b"), String::from_str(""));
-        assert_eq!("a".replace(a, "b"), String::from_str("b"));
-        assert_eq!("ab".replace(a, "b"), String::from_str("bb"));
-        let test = "test";
-        assert!(" test test ".replace(test, "toast") ==
-            String::from_str(" toast toast "));
-        assert_eq!(" test test ".replace(test, ""), String::from_str("   "));
-    }
-
-    #[test]
-    fn test_replace_2a() {
-        let data = "ประเทศไทย中华";
-        let repl = "دولة الكويت";
-
-        let a = "ประเ";
-        let a2 = "دولة الكويتทศไทย中华";
-        assert_eq!(data.replace(a, repl), a2);
-    }
-
-    #[test]
-    fn test_replace_2b() {
-        let data = "ประเทศไทย中华";
-        let repl = "دولة الكويت";
-
-        let b = "ะเ";
-        let b2 = "ปรدولة الكويتทศไทย中华";
-        assert_eq!(data.replace(b, repl), b2);
-    }
 
-    #[test]
-    fn test_replace_2c() {
-        let data = "ประเทศไทย中华";
-        let repl = "دولة الكويت";
-
-        let c = "中华";
-        let c2 = "ประเทศไทยدولة الكويت";
-        assert_eq!(data.replace(c, repl), c2);
-    }
-
-    #[test]
-    fn test_replace_2d() {
-        let data = "ประเทศไทย中华";
-        let repl = "دولة الكويت";
-
-        let d = "ไท华";
-        assert_eq!(data.replace(d, repl), data);
-    }
-
-    #[test]
-    fn test_slice() {
-        assert_eq!("ab", "abc".slice(0, 2));
-        assert_eq!("bc", "abc".slice(1, 3));
-        assert_eq!("", "abc".slice(1, 1));
-        assert_eq!("\u{65e5}", "\u{65e5}\u{672c}".slice(0, 3));
-
-        let data = "ประเทศไทย中华";
-        assert_eq!("ป", data.slice(0, 3));
-        assert_eq!("ร", data.slice(3, 6));
-        assert_eq!("", data.slice(3, 3));
-        assert_eq!("华", data.slice(30, 33));
-
-        fn a_million_letter_x() -> String {
-            let mut i = 0;
-            let mut rs = String::new();
-            while i < 100000 {
-                rs.push_str("华华华华华华华华华华");
-                i += 1;
-            }
-            rs
-        }
-        fn half_a_million_letter_x() -> String {
-            let mut i = 0;
-            let mut rs = String::new();
-            while i < 100000 {
-                rs.push_str("华华华华华");
-                i += 1;
-            }
-            rs
-        }
-        let letters = a_million_letter_x();
-        assert!(half_a_million_letter_x() ==
-            String::from_str(letters.slice(0, 3 * 500000)));
-    }
-
-    #[test]
-    fn test_slice_2() {
-        let ss = "中华Việt Nam";
-
-        assert_eq!("华", ss.slice(3, 6));
-        assert_eq!("Việt Nam", ss.slice(6, 16));
-
-        assert_eq!("ab", "abc".slice(0, 2));
-        assert_eq!("bc", "abc".slice(1, 3));
-        assert_eq!("", "abc".slice(1, 1));
-
-        assert_eq!("中", ss.slice(0, 3));
-        assert_eq!("华V", ss.slice(3, 7));
-        assert_eq!("", ss.slice(3, 3));
-        /*0: 中
-          3: 华
-          6: V
-          7: i
-          8: ệ
-         11: t
-         12:
-         13: N
-         14: a
-         15: m */
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_slice_fail() {
-        "中华Việt Nam".slice(0, 2);
-    }
-
-    #[test]
-    fn test_slice_from() {
-        assert_eq!("abcd".slice_from(0), "abcd");
-        assert_eq!("abcd".slice_from(2), "cd");
-        assert_eq!("abcd".slice_from(4), "");
-    }
-    #[test]
-    fn test_slice_to() {
-        assert_eq!("abcd".slice_to(0), "");
-        assert_eq!("abcd".slice_to(2), "ab");
-        assert_eq!("abcd".slice_to(4), "abcd");
-    }
-
-    #[test]
-    fn test_trim_left_matches() {
-        let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
-        let chars: &[char] = &['*', ' '];
-        assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
-        assert_eq!(" ***  *** ".trim_left_matches(chars), "");
-        assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
-
-        assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
-        let chars: &[char] = &['1', '2'];
-        assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
-        assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
-    }
-
-    #[test]
-    fn test_trim_right_matches() {
-        let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
-        let chars: &[char] = &['*', ' '];
-        assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
-        assert_eq!(" ***  *** ".trim_right_matches(chars), "");
-        assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
-
-        assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
-        let chars: &[char] = &['1', '2'];
-        assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
-        assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
-    }
-
-    #[test]
-    fn test_trim_matches() {
-        let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
-        let chars: &[char] = &['*', ' '];
-        assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
-        assert_eq!(" ***  *** ".trim_matches(chars), "");
-        assert_eq!("foo".trim_matches(chars), "foo");
-
-        assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
-        let chars: &[char] = &['1', '2'];
-        assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
-        assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
-    }
-
-    #[test]
-    fn test_trim_left() {
-        assert_eq!("".trim_left(), "");
-        assert_eq!("a".trim_left(), "a");
-        assert_eq!("    ".trim_left(), "");
-        assert_eq!("     blah".trim_left(), "blah");
-        assert_eq!("   \u{3000}  wut".trim_left(), "wut");
-        assert_eq!("hey ".trim_left(), "hey ");
-    }
-
-    #[test]
-    fn test_trim_right() {
-        assert_eq!("".trim_right(), "");
-        assert_eq!("a".trim_right(), "a");
-        assert_eq!("    ".trim_right(), "");
-        assert_eq!("blah     ".trim_right(), "blah");
-        assert_eq!("wut   \u{3000}  ".trim_right(), "wut");
-        assert_eq!(" hey".trim_right(), " hey");
-    }
-
-    #[test]
-    fn test_trim() {
-        assert_eq!("".trim(), "");
-        assert_eq!("a".trim(), "a");
-        assert_eq!("    ".trim(), "");
-        assert_eq!("    blah     ".trim(), "blah");
-        assert_eq!("\nwut   \u{3000}  ".trim(), "wut");
-        assert_eq!(" hey dude ".trim(), "hey dude");
-    }
-
-    #[test]
-    fn test_is_whitespace() {
-        assert!("".chars().all(|c| c.is_whitespace()));
-        assert!(" ".chars().all(|c| c.is_whitespace()));
-        assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
-        assert!("  \n\t   ".chars().all(|c| c.is_whitespace()));
-        assert!(!"   _   ".chars().all(|c| c.is_whitespace()));
-    }
-
-    #[test]
-    fn test_slice_shift_char() {
-        let data = "ประเทศไทย中";
-        assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中")));
-    }
-
-    #[test]
-    fn test_slice_shift_char_2() {
-        let empty = "";
-        assert_eq!(empty.slice_shift_char(), None);
-    }
-
-    #[test]
-    fn test_is_utf8() {
-        // deny overlong encodings
-        assert!(from_utf8(&[0xc0, 0x80]).is_err());
-        assert!(from_utf8(&[0xc0, 0xae]).is_err());
-        assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
-        assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
-        assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
-        assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
-        assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
-
-        // deny surrogates
-        assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
-        assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
-
-        assert!(from_utf8(&[0xC2, 0x80]).is_ok());
-        assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
-        assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
-        assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
-        assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
-        assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
-        assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
-        assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
-    }
-
-    #[test]
-    fn test_is_utf16() {
-        use unicode::str::is_utf16;
-        macro_rules! pos {
-            ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } }
-        }
-
-        // non-surrogates
-        pos!(&[0x0000],
-             &[0x0001, 0x0002],
-             &[0xD7FF],
-             &[0xE000]);
-
-        // surrogate pairs (randomly generated with Python 3's
-        // .encode('utf-16be'))
-        pos!(&[0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
-             &[0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
-             &[0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
-
-        // mixtures (also random)
-        pos!(&[0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
-             &[0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
-             &[0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
-
-        // negative tests
-        macro_rules! neg {
-            ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } }
-        }
-
-        neg!(
-            // surrogate + regular unit
-            &[0xdb45, 0x0000],
-            // surrogate + lead surrogate
-            &[0xd900, 0xd900],
-            // unterminated surrogate
-            &[0xd8ff],
-            // trail surrogate without a lead
-            &[0xddb7]);
-
-        // random byte sequences that Python 3's .decode('utf-16be')
-        // failed on
-        neg!(&[0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
-             &[0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
-             &[0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
-             &[0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
-             &[0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
-             &[0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
-             &[0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
-             &[0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
-             &[0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
-             &[0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
-             &[0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
-             &[0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
-             &[0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
-             &[0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
-             &[0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
-             &[0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
-             &[0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
-             &[0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
-             &[0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
-             &[0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
-             &[0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
-    }
-
-    #[test]
-    fn test_as_bytes() {
-        // no null
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let b: &[u8] = &[];
-        assert_eq!("".as_bytes(), b);
-        assert_eq!("abc".as_bytes(), b"abc");
-        assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_as_bytes_fail() {
-        // Don't double free. (I'm not sure if this exercises the
-        // original problem code path anymore.)
-        let s = String::from_str("");
-        let _bytes = s.as_bytes();
-        panic!();
-    }
-
-    #[test]
-    fn test_as_ptr() {
-        let buf = "hello".as_ptr();
-        unsafe {
-            assert_eq!(*buf.offset(0), b'h');
-            assert_eq!(*buf.offset(1), b'e');
-            assert_eq!(*buf.offset(2), b'l');
-            assert_eq!(*buf.offset(3), b'l');
-            assert_eq!(*buf.offset(4), b'o');
-        }
-    }
-
-    #[test]
-    fn test_subslice_offset() {
-        let a = "kernelsprite";
-        let b = &a[7..a.len()];
-        let c = &a[0..a.len() - 6];
-        assert_eq!(a.subslice_offset(b), 7);
-        assert_eq!(a.subslice_offset(c), 0);
-
-        let string = "a\nb\nc";
-        let lines: Vec<&str> = string.lines().collect();
-        assert_eq!(string.subslice_offset(lines[0]), 0);
-        assert_eq!(string.subslice_offset(lines[1]), 2);
-        assert_eq!(string.subslice_offset(lines[2]), 4);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_subslice_offset_2() {
-        let a = "alchemiter";
-        let b = "cruxtruder";
-        a.subslice_offset(b);
-    }
-
-    #[test]
-    fn vec_str_conversions() {
-        let s1: String = String::from_str("All mimsy were the borogoves");
-
-        let v: Vec<u8> = s1.as_bytes().to_vec();
-        let s2: String = String::from_str(from_utf8(&v).unwrap());
-        let mut i = 0;
-        let n1 = s1.len();
-        let n2 = v.len();
-        assert_eq!(n1, n2);
-        while i < n1 {
-            let a: u8 = s1.as_bytes()[i];
-            let b: u8 = s2.as_bytes()[i];
-            debug!("{}", a);
-            debug!("{}", b);
-            assert_eq!(a, b);
-            i += 1;
-        }
-    }
-
-    #[test]
-    fn test_contains() {
-        assert!("abcde".contains("bcd"));
-        assert!("abcde".contains("abcd"));
-        assert!("abcde".contains("bcde"));
-        assert!("abcde".contains(""));
-        assert!("".contains(""));
-        assert!(!"abcde".contains("def"));
-        assert!(!"".contains("a"));
-
-        let data = "ประเทศไทย中华Việt Nam";
-        assert!(data.contains("ประเ"));
-        assert!(data.contains("ะเ"));
-        assert!(data.contains("中华"));
-        assert!(!data.contains("ไท华"));
-    }
-
-    #[test]
-    fn test_contains_char() {
-        assert!("abc".contains_char('b'));
-        assert!("a".contains_char('a'));
-        assert!(!"abc".contains_char('d'));
-        assert!(!"".contains_char('a'));
-    }
-
-    #[test]
-    fn test_char_at() {
-        let s = "ศไทย中华Việt Nam";
-        let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = 0;
-        for ch in &v {
-            assert!(s.char_at(pos) == *ch);
-            pos += ch.to_string().len();
-        }
-    }
-
-    #[test]
-    fn test_char_at_reverse() {
-        let s = "ศไทย中华Việt Nam";
-        let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = s.len();
-        for ch in v.iter().rev() {
-            assert!(s.char_at_reverse(pos) == *ch);
-            pos -= ch.to_string().len();
-        }
-    }
-
-    #[test]
-    fn test_escape_unicode() {
-        assert_eq!("abc".escape_unicode(),
-                   String::from_str("\\u{61}\\u{62}\\u{63}"));
-        assert_eq!("a c".escape_unicode(),
-                   String::from_str("\\u{61}\\u{20}\\u{63}"));
-        assert_eq!("\r\n\t".escape_unicode(),
-                   String::from_str("\\u{d}\\u{a}\\u{9}"));
-        assert_eq!("'\"\\".escape_unicode(),
-                   String::from_str("\\u{27}\\u{22}\\u{5c}"));
-        assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(),
-                   String::from_str("\\u{0}\\u{1}\\u{fe}\\u{ff}"));
-        assert_eq!("\u{100}\u{ffff}".escape_unicode(),
-                   String::from_str("\\u{100}\\u{ffff}"));
-        assert_eq!("\u{10000}\u{10ffff}".escape_unicode(),
-                   String::from_str("\\u{10000}\\u{10ffff}"));
-        assert_eq!("ab\u{fb00}".escape_unicode(),
-                   String::from_str("\\u{61}\\u{62}\\u{fb00}"));
-        assert_eq!("\u{1d4ea}\r".escape_unicode(),
-                   String::from_str("\\u{1d4ea}\\u{d}"));
-    }
-
-    #[test]
-    fn test_escape_default() {
-        assert_eq!("abc".escape_default(), String::from_str("abc"));
-        assert_eq!("a c".escape_default(), String::from_str("a c"));
-        assert_eq!("\r\n\t".escape_default(), String::from_str("\\r\\n\\t"));
-        assert_eq!("'\"\\".escape_default(), String::from_str("\\'\\\"\\\\"));
-        assert_eq!("\u{100}\u{ffff}".escape_default(),
-                   String::from_str("\\u{100}\\u{ffff}"));
-        assert_eq!("\u{10000}\u{10ffff}".escape_default(),
-                   String::from_str("\\u{10000}\\u{10ffff}"));
-        assert_eq!("ab\u{fb00}".escape_default(),
-                   String::from_str("ab\\u{fb00}"));
-        assert_eq!("\u{1d4ea}\r".escape_default(),
-                   String::from_str("\\u{1d4ea}\\r"));
-    }
-
-    #[test]
-    fn test_total_ord() {
-        "1234".cmp("123") == Greater;
-        "123".cmp("1234") == Less;
-        "1234".cmp("1234") == Equal;
-        "12345555".cmp("123456") == Less;
-        "22".cmp("1234") == Greater;
-    }
-
-    #[test]
-    fn test_char_range_at() {
-        let data = "b¢€𤭢𤭢€¢b";
-        assert_eq!('b', data.char_range_at(0).ch);
-        assert_eq!('¢', data.char_range_at(1).ch);
-        assert_eq!('€', data.char_range_at(3).ch);
-        assert_eq!('𤭢', data.char_range_at(6).ch);
-        assert_eq!('𤭢', data.char_range_at(10).ch);
-        assert_eq!('€', data.char_range_at(14).ch);
-        assert_eq!('¢', data.char_range_at(17).ch);
-        assert_eq!('b', data.char_range_at(19).ch);
-    }
-
-    #[test]
-    fn test_char_range_at_reverse_underflow() {
-        assert_eq!("abc".char_range_at_reverse(0).next, 0);
-    }
-
-    #[test]
-    fn test_iterator() {
-        let s = "ศไทย中华Việt Nam";
-        let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-
-        let mut pos = 0;
-        let it = s.chars();
-
-        for c in it {
-            assert_eq!(c, v[pos]);
-            pos += 1;
-        }
-        assert_eq!(pos, v.len());
-    }
-
-    #[test]
-    fn test_rev_iterator() {
-        let s = "ศไทย中华Việt Nam";
-        let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
-
-        let mut pos = 0;
-        let it = s.chars().rev();
-
-        for c in it {
-            assert_eq!(c, v[pos]);
-            pos += 1;
-        }
-        assert_eq!(pos, v.len());
-    }
-
-    #[test]
-    fn test_chars_decoding() {
-        let mut bytes = [0u8; 4];
-        for c in (0u32..0x110000).filter_map(|c| ::core::char::from_u32(c)) {
-            let len = c.encode_utf8(&mut bytes).unwrap_or(0);
-            let s = ::core::str::from_utf8(&bytes[..len]).unwrap();
-            if Some(c) != s.chars().next() {
-                panic!("character {:x}={} does not decode correctly", c as u32, c);
-            }
-        }
-    }
-
-    #[test]
-    fn test_chars_rev_decoding() {
-        let mut bytes = [0u8; 4];
-        for c in (0u32..0x110000).filter_map(|c| ::core::char::from_u32(c)) {
-            let len = c.encode_utf8(&mut bytes).unwrap_or(0);
-            let s = ::core::str::from_utf8(&bytes[..len]).unwrap();
-            if Some(c) != s.chars().rev().next() {
-                panic!("character {:x}={} does not decode correctly", c as u32, c);
-            }
-        }
-    }
-
-    #[test]
-    fn test_iterator_clone() {
-        let s = "ศไทย中华Việt Nam";
-        let mut it = s.chars();
-        it.next();
-        assert!(it.clone().zip(it).all(|(x,y)| x == y));
-    }
-
-    #[test]
-    fn test_bytesator() {
-        let s = "ศไทย中华Việt Nam";
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let mut pos = 0;
-
-        for b in s.bytes() {
-            assert_eq!(b, v[pos]);
-            pos += 1;
-        }
-    }
-
-    #[test]
-    fn test_bytes_revator() {
-        let s = "ศไทย中华Việt Nam";
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let mut pos = v.len();
-
-        for b in s.bytes().rev() {
-            pos -= 1;
-            assert_eq!(b, v[pos]);
-        }
-    }
-
-    #[test]
-    fn test_char_indicesator() {
-        let s = "ศไทย中华Việt Nam";
-        let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
-        let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-
-        let mut pos = 0;
-        let it = s.char_indices();
-
-        for c in it {
-            assert_eq!(c, (p[pos], v[pos]));
-            pos += 1;
-        }
-        assert_eq!(pos, v.len());
-        assert_eq!(pos, p.len());
-    }
-
-    #[test]
-    fn test_char_indices_revator() {
-        let s = "ศไทย中华Việt Nam";
-        let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
-        let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
-
-        let mut pos = 0;
-        let it = s.char_indices().rev();
-
-        for c in it {
-            assert_eq!(c, (p[pos], v[pos]));
-            pos += 1;
-        }
-        assert_eq!(pos, v.len());
-        assert_eq!(pos, p.len());
-    }
-
-    #[test]
-    fn test_splitn_char_iterator() {
-        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-        let split: Vec<&str> = data.splitn(3, ' ').collect();
-        assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
-
-        let split: Vec<&str> = data.splitn(3, |c: char| c == ' ').collect();
-        assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
-
-        // Unicode
-        let split: Vec<&str> = data.splitn(3, 'ä').collect();
-        assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
-
-        let split: Vec<&str> = data.splitn(3, |c: char| c == 'ä').collect();
-        assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
-    }
-
-    #[test]
-    fn test_split_char_iterator_no_trailing() {
-        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-        let split: Vec<&str> = data.split('\n').collect();
-        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]);
-
-        let split: Vec<&str> = data.split_terminator('\n').collect();
-        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]);
-    }
-
-    #[test]
-    fn test_words() {
-        let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
-        let words: Vec<&str> = data.words().collect();
-        assert_eq!(words, vec!["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
-    }
-
-    #[test]
-    fn test_nfd_chars() {
-        macro_rules! t {
-            ($input: expr, $expected: expr) => {
-                assert_eq!($input.nfd_chars().collect::<String>(), $expected);
-            }
-        }
-        t!("abc", "abc");
-        t!("\u{1e0b}\u{1c4}", "d\u{307}\u{1c4}");
-        t!("\u{2026}", "\u{2026}");
-        t!("\u{2126}", "\u{3a9}");
-        t!("\u{1e0b}\u{323}", "d\u{323}\u{307}");
-        t!("\u{1e0d}\u{307}", "d\u{323}\u{307}");
-        t!("a\u{301}", "a\u{301}");
-        t!("\u{301}a", "\u{301}a");
-        t!("\u{d4db}", "\u{1111}\u{1171}\u{11b6}");
-        t!("\u{ac1c}", "\u{1100}\u{1162}");
-    }
-
-    #[test]
-    fn test_nfkd_chars() {
-        macro_rules! t {
-            ($input: expr, $expected: expr) => {
-                assert_eq!($input.nfkd_chars().collect::<String>(), $expected);
-            }
-        }
-        t!("abc", "abc");
-        t!("\u{1e0b}\u{1c4}", "d\u{307}DZ\u{30c}");
-        t!("\u{2026}", "...");
-        t!("\u{2126}", "\u{3a9}");
-        t!("\u{1e0b}\u{323}", "d\u{323}\u{307}");
-        t!("\u{1e0d}\u{307}", "d\u{323}\u{307}");
-        t!("a\u{301}", "a\u{301}");
-        t!("\u{301}a", "\u{301}a");
-        t!("\u{d4db}", "\u{1111}\u{1171}\u{11b6}");
-        t!("\u{ac1c}", "\u{1100}\u{1162}");
-    }
-
-    #[test]
-    fn test_nfc_chars() {
-        macro_rules! t {
-            ($input: expr, $expected: expr) => {
-                assert_eq!($input.nfc_chars().collect::<String>(), $expected);
-            }
-        }
-        t!("abc", "abc");
-        t!("\u{1e0b}\u{1c4}", "\u{1e0b}\u{1c4}");
-        t!("\u{2026}", "\u{2026}");
-        t!("\u{2126}", "\u{3a9}");
-        t!("\u{1e0b}\u{323}", "\u{1e0d}\u{307}");
-        t!("\u{1e0d}\u{307}", "\u{1e0d}\u{307}");
-        t!("a\u{301}", "\u{e1}");
-        t!("\u{301}a", "\u{301}a");
-        t!("\u{d4db}", "\u{d4db}");
-        t!("\u{ac1c}", "\u{ac1c}");
-        t!("a\u{300}\u{305}\u{315}\u{5ae}b", "\u{e0}\u{5ae}\u{305}\u{315}b");
-    }
-
-    #[test]
-    fn test_nfkc_chars() {
-        macro_rules! t {
-            ($input: expr, $expected: expr) => {
-                assert_eq!($input.nfkc_chars().collect::<String>(), $expected);
-            }
-        }
-        t!("abc", "abc");
-        t!("\u{1e0b}\u{1c4}", "\u{1e0b}D\u{17d}");
-        t!("\u{2026}", "...");
-        t!("\u{2126}", "\u{3a9}");
-        t!("\u{1e0b}\u{323}", "\u{1e0d}\u{307}");
-        t!("\u{1e0d}\u{307}", "\u{1e0d}\u{307}");
-        t!("a\u{301}", "\u{e1}");
-        t!("\u{301}a", "\u{301}a");
-        t!("\u{d4db}", "\u{d4db}");
-        t!("\u{ac1c}", "\u{ac1c}");
-        t!("a\u{300}\u{305}\u{315}\u{5ae}b", "\u{e0}\u{5ae}\u{305}\u{315}b");
-    }
-
-    #[test]
-    fn test_lines() {
-        let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
-        let lines: Vec<&str> = data.lines().collect();
-        assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]);
-
-        let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
-        let lines: Vec<&str> = data.lines().collect();
-        assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]);
-    }
-
-    #[test]
-    fn test_graphemes() {
-        use core::iter::order;
-        // official Unicode test data
-        // from http://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt
-        let test_same: [(_, &[_]); 325] = [
-            ("\u{20}\u{20}", &["\u{20}", "\u{20}"]),
-            ("\u{20}\u{308}\u{20}", &["\u{20}\u{308}", "\u{20}"]),
-            ("\u{20}\u{D}", &["\u{20}", "\u{D}"]),
-            ("\u{20}\u{308}\u{D}", &["\u{20}\u{308}", "\u{D}"]),
-            ("\u{20}\u{A}", &["\u{20}", "\u{A}"]),
-            ("\u{20}\u{308}\u{A}", &["\u{20}\u{308}", "\u{A}"]),
-            ("\u{20}\u{1}", &["\u{20}", "\u{1}"]),
-            ("\u{20}\u{308}\u{1}", &["\u{20}\u{308}", "\u{1}"]),
-            ("\u{20}\u{300}", &["\u{20}\u{300}"]),
-            ("\u{20}\u{308}\u{300}", &["\u{20}\u{308}\u{300}"]),
-            ("\u{20}\u{1100}", &["\u{20}", "\u{1100}"]),
-            ("\u{20}\u{308}\u{1100}", &["\u{20}\u{308}", "\u{1100}"]),
-            ("\u{20}\u{1160}", &["\u{20}", "\u{1160}"]),
-            ("\u{20}\u{308}\u{1160}", &["\u{20}\u{308}", "\u{1160}"]),
-            ("\u{20}\u{11A8}", &["\u{20}", "\u{11A8}"]),
-            ("\u{20}\u{308}\u{11A8}", &["\u{20}\u{308}", "\u{11A8}"]),
-            ("\u{20}\u{AC00}", &["\u{20}", "\u{AC00}"]),
-            ("\u{20}\u{308}\u{AC00}", &["\u{20}\u{308}", "\u{AC00}"]),
-            ("\u{20}\u{AC01}", &["\u{20}", "\u{AC01}"]),
-            ("\u{20}\u{308}\u{AC01}", &["\u{20}\u{308}", "\u{AC01}"]),
-            ("\u{20}\u{1F1E6}", &["\u{20}", "\u{1F1E6}"]),
-            ("\u{20}\u{308}\u{1F1E6}", &["\u{20}\u{308}", "\u{1F1E6}"]),
-            ("\u{20}\u{378}", &["\u{20}", "\u{378}"]),
-            ("\u{20}\u{308}\u{378}", &["\u{20}\u{308}", "\u{378}"]),
-            ("\u{D}\u{20}", &["\u{D}", "\u{20}"]),
-            ("\u{D}\u{308}\u{20}", &["\u{D}", "\u{308}", "\u{20}"]),
-            ("\u{D}\u{D}", &["\u{D}", "\u{D}"]),
-            ("\u{D}\u{308}\u{D}", &["\u{D}", "\u{308}", "\u{D}"]),
-            ("\u{D}\u{A}", &["\u{D}\u{A}"]),
-            ("\u{D}\u{308}\u{A}", &["\u{D}", "\u{308}", "\u{A}"]),
-            ("\u{D}\u{1}", &["\u{D}", "\u{1}"]),
-            ("\u{D}\u{308}\u{1}", &["\u{D}", "\u{308}", "\u{1}"]),
-            ("\u{D}\u{300}", &["\u{D}", "\u{300}"]),
-            ("\u{D}\u{308}\u{300}", &["\u{D}", "\u{308}\u{300}"]),
-            ("\u{D}\u{903}", &["\u{D}", "\u{903}"]),
-            ("\u{D}\u{1100}", &["\u{D}", "\u{1100}"]),
-            ("\u{D}\u{308}\u{1100}", &["\u{D}", "\u{308}", "\u{1100}"]),
-            ("\u{D}\u{1160}", &["\u{D}", "\u{1160}"]),
-            ("\u{D}\u{308}\u{1160}", &["\u{D}", "\u{308}", "\u{1160}"]),
-            ("\u{D}\u{11A8}", &["\u{D}", "\u{11A8}"]),
-            ("\u{D}\u{308}\u{11A8}", &["\u{D}", "\u{308}", "\u{11A8}"]),
-            ("\u{D}\u{AC00}", &["\u{D}", "\u{AC00}"]),
-            ("\u{D}\u{308}\u{AC00}", &["\u{D}", "\u{308}", "\u{AC00}"]),
-            ("\u{D}\u{AC01}", &["\u{D}", "\u{AC01}"]),
-            ("\u{D}\u{308}\u{AC01}", &["\u{D}", "\u{308}", "\u{AC01}"]),
-            ("\u{D}\u{1F1E6}", &["\u{D}", "\u{1F1E6}"]),
-            ("\u{D}\u{308}\u{1F1E6}", &["\u{D}", "\u{308}", "\u{1F1E6}"]),
-            ("\u{D}\u{378}", &["\u{D}", "\u{378}"]),
-            ("\u{D}\u{308}\u{378}", &["\u{D}", "\u{308}", "\u{378}"]),
-            ("\u{A}\u{20}", &["\u{A}", "\u{20}"]),
-            ("\u{A}\u{308}\u{20}", &["\u{A}", "\u{308}", "\u{20}"]),
-            ("\u{A}\u{D}", &["\u{A}", "\u{D}"]),
-            ("\u{A}\u{308}\u{D}", &["\u{A}", "\u{308}", "\u{D}"]),
-            ("\u{A}\u{A}", &["\u{A}", "\u{A}"]),
-            ("\u{A}\u{308}\u{A}", &["\u{A}", "\u{308}", "\u{A}"]),
-            ("\u{A}\u{1}", &["\u{A}", "\u{1}"]),
-            ("\u{A}\u{308}\u{1}", &["\u{A}", "\u{308}", "\u{1}"]),
-            ("\u{A}\u{300}", &["\u{A}", "\u{300}"]),
-            ("\u{A}\u{308}\u{300}", &["\u{A}", "\u{308}\u{300}"]),
-            ("\u{A}\u{903}", &["\u{A}", "\u{903}"]),
-            ("\u{A}\u{1100}", &["\u{A}", "\u{1100}"]),
-            ("\u{A}\u{308}\u{1100}", &["\u{A}", "\u{308}", "\u{1100}"]),
-            ("\u{A}\u{1160}", &["\u{A}", "\u{1160}"]),
-            ("\u{A}\u{308}\u{1160}", &["\u{A}", "\u{308}", "\u{1160}"]),
-            ("\u{A}\u{11A8}", &["\u{A}", "\u{11A8}"]),
-            ("\u{A}\u{308}\u{11A8}", &["\u{A}", "\u{308}", "\u{11A8}"]),
-            ("\u{A}\u{AC00}", &["\u{A}", "\u{AC00}"]),
-            ("\u{A}\u{308}\u{AC00}", &["\u{A}", "\u{308}", "\u{AC00}"]),
-            ("\u{A}\u{AC01}", &["\u{A}", "\u{AC01}"]),
-            ("\u{A}\u{308}\u{AC01}", &["\u{A}", "\u{308}", "\u{AC01}"]),
-            ("\u{A}\u{1F1E6}", &["\u{A}", "\u{1F1E6}"]),
-            ("\u{A}\u{308}\u{1F1E6}", &["\u{A}", "\u{308}", "\u{1F1E6}"]),
-            ("\u{A}\u{378}", &["\u{A}", "\u{378}"]),
-            ("\u{A}\u{308}\u{378}", &["\u{A}", "\u{308}", "\u{378}"]),
-            ("\u{1}\u{20}", &["\u{1}", "\u{20}"]),
-            ("\u{1}\u{308}\u{20}", &["\u{1}", "\u{308}", "\u{20}"]),
-            ("\u{1}\u{D}", &["\u{1}", "\u{D}"]),
-            ("\u{1}\u{308}\u{D}", &["\u{1}", "\u{308}", "\u{D}"]),
-            ("\u{1}\u{A}", &["\u{1}", "\u{A}"]),
-            ("\u{1}\u{308}\u{A}", &["\u{1}", "\u{308}", "\u{A}"]),
-            ("\u{1}\u{1}", &["\u{1}", "\u{1}"]),
-            ("\u{1}\u{308}\u{1}", &["\u{1}", "\u{308}", "\u{1}"]),
-            ("\u{1}\u{300}", &["\u{1}", "\u{300}"]),
-            ("\u{1}\u{308}\u{300}", &["\u{1}", "\u{308}\u{300}"]),
-            ("\u{1}\u{903}", &["\u{1}", "\u{903}"]),
-            ("\u{1}\u{1100}", &["\u{1}", "\u{1100}"]),
-            ("\u{1}\u{308}\u{1100}", &["\u{1}", "\u{308}", "\u{1100}"]),
-            ("\u{1}\u{1160}", &["\u{1}", "\u{1160}"]),
-            ("\u{1}\u{308}\u{1160}", &["\u{1}", "\u{308}", "\u{1160}"]),
-            ("\u{1}\u{11A8}", &["\u{1}", "\u{11A8}"]),
-            ("\u{1}\u{308}\u{11A8}", &["\u{1}", "\u{308}", "\u{11A8}"]),
-            ("\u{1}\u{AC00}", &["\u{1}", "\u{AC00}"]),
-            ("\u{1}\u{308}\u{AC00}", &["\u{1}", "\u{308}", "\u{AC00}"]),
-            ("\u{1}\u{AC01}", &["\u{1}", "\u{AC01}"]),
-            ("\u{1}\u{308}\u{AC01}", &["\u{1}", "\u{308}", "\u{AC01}"]),
-            ("\u{1}\u{1F1E6}", &["\u{1}", "\u{1F1E6}"]),
-            ("\u{1}\u{308}\u{1F1E6}", &["\u{1}", "\u{308}", "\u{1F1E6}"]),
-            ("\u{1}\u{378}", &["\u{1}", "\u{378}"]),
-            ("\u{1}\u{308}\u{378}", &["\u{1}", "\u{308}", "\u{378}"]),
-            ("\u{300}\u{20}", &["\u{300}", "\u{20}"]),
-            ("\u{300}\u{308}\u{20}", &["\u{300}\u{308}", "\u{20}"]),
-            ("\u{300}\u{D}", &["\u{300}", "\u{D}"]),
-            ("\u{300}\u{308}\u{D}", &["\u{300}\u{308}", "\u{D}"]),
-            ("\u{300}\u{A}", &["\u{300}", "\u{A}"]),
-            ("\u{300}\u{308}\u{A}", &["\u{300}\u{308}", "\u{A}"]),
-            ("\u{300}\u{1}", &["\u{300}", "\u{1}"]),
-            ("\u{300}\u{308}\u{1}", &["\u{300}\u{308}", "\u{1}"]),
-            ("\u{300}\u{300}", &["\u{300}\u{300}"]),
-            ("\u{300}\u{308}\u{300}", &["\u{300}\u{308}\u{300}"]),
-            ("\u{300}\u{1100}", &["\u{300}", "\u{1100}"]),
-            ("\u{300}\u{308}\u{1100}", &["\u{300}\u{308}", "\u{1100}"]),
-            ("\u{300}\u{1160}", &["\u{300}", "\u{1160}"]),
-            ("\u{300}\u{308}\u{1160}", &["\u{300}\u{308}", "\u{1160}"]),
-            ("\u{300}\u{11A8}", &["\u{300}", "\u{11A8}"]),
-            ("\u{300}\u{308}\u{11A8}", &["\u{300}\u{308}", "\u{11A8}"]),
-            ("\u{300}\u{AC00}", &["\u{300}", "\u{AC00}"]),
-            ("\u{300}\u{308}\u{AC00}", &["\u{300}\u{308}", "\u{AC00}"]),
-            ("\u{300}\u{AC01}", &["\u{300}", "\u{AC01}"]),
-            ("\u{300}\u{308}\u{AC01}", &["\u{300}\u{308}", "\u{AC01}"]),
-            ("\u{300}\u{1F1E6}", &["\u{300}", "\u{1F1E6}"]),
-            ("\u{300}\u{308}\u{1F1E6}", &["\u{300}\u{308}", "\u{1F1E6}"]),
-            ("\u{300}\u{378}", &["\u{300}", "\u{378}"]),
-            ("\u{300}\u{308}\u{378}", &["\u{300}\u{308}", "\u{378}"]),
-            ("\u{903}\u{20}", &["\u{903}", "\u{20}"]),
-            ("\u{903}\u{308}\u{20}", &["\u{903}\u{308}", "\u{20}"]),
-            ("\u{903}\u{D}", &["\u{903}", "\u{D}"]),
-            ("\u{903}\u{308}\u{D}", &["\u{903}\u{308}", "\u{D}"]),
-            ("\u{903}\u{A}", &["\u{903}", "\u{A}"]),
-            ("\u{903}\u{308}\u{A}", &["\u{903}\u{308}", "\u{A}"]),
-            ("\u{903}\u{1}", &["\u{903}", "\u{1}"]),
-            ("\u{903}\u{308}\u{1}", &["\u{903}\u{308}", "\u{1}"]),
-            ("\u{903}\u{300}", &["\u{903}\u{300}"]),
-            ("\u{903}\u{308}\u{300}", &["\u{903}\u{308}\u{300}"]),
-            ("\u{903}\u{1100}", &["\u{903}", "\u{1100}"]),
-            ("\u{903}\u{308}\u{1100}", &["\u{903}\u{308}", "\u{1100}"]),
-            ("\u{903}\u{1160}", &["\u{903}", "\u{1160}"]),
-            ("\u{903}\u{308}\u{1160}", &["\u{903}\u{308}", "\u{1160}"]),
-            ("\u{903}\u{11A8}", &["\u{903}", "\u{11A8}"]),
-            ("\u{903}\u{308}\u{11A8}", &["\u{903}\u{308}", "\u{11A8}"]),
-            ("\u{903}\u{AC00}", &["\u{903}", "\u{AC00}"]),
-            ("\u{903}\u{308}\u{AC00}", &["\u{903}\u{308}", "\u{AC00}"]),
-            ("\u{903}\u{AC01}", &["\u{903}", "\u{AC01}"]),
-            ("\u{903}\u{308}\u{AC01}", &["\u{903}\u{308}", "\u{AC01}"]),
-            ("\u{903}\u{1F1E6}", &["\u{903}", "\u{1F1E6}"]),
-            ("\u{903}\u{308}\u{1F1E6}", &["\u{903}\u{308}", "\u{1F1E6}"]),
-            ("\u{903}\u{378}", &["\u{903}", "\u{378}"]),
-            ("\u{903}\u{308}\u{378}", &["\u{903}\u{308}", "\u{378}"]),
-            ("\u{1100}\u{20}", &["\u{1100}", "\u{20}"]),
-            ("\u{1100}\u{308}\u{20}", &["\u{1100}\u{308}", "\u{20}"]),
-            ("\u{1100}\u{D}", &["\u{1100}", "\u{D}"]),
-            ("\u{1100}\u{308}\u{D}", &["\u{1100}\u{308}", "\u{D}"]),
-            ("\u{1100}\u{A}", &["\u{1100}", "\u{A}"]),
-            ("\u{1100}\u{308}\u{A}", &["\u{1100}\u{308}", "\u{A}"]),
-            ("\u{1100}\u{1}", &["\u{1100}", "\u{1}"]),
-            ("\u{1100}\u{308}\u{1}", &["\u{1100}\u{308}", "\u{1}"]),
-            ("\u{1100}\u{300}", &["\u{1100}\u{300}"]),
-            ("\u{1100}\u{308}\u{300}", &["\u{1100}\u{308}\u{300}"]),
-            ("\u{1100}\u{1100}", &["\u{1100}\u{1100}"]),
-            ("\u{1100}\u{308}\u{1100}", &["\u{1100}\u{308}", "\u{1100}"]),
-            ("\u{1100}\u{1160}", &["\u{1100}\u{1160}"]),
-            ("\u{1100}\u{308}\u{1160}", &["\u{1100}\u{308}", "\u{1160}"]),
-            ("\u{1100}\u{11A8}", &["\u{1100}", "\u{11A8}"]),
-            ("\u{1100}\u{308}\u{11A8}", &["\u{1100}\u{308}", "\u{11A8}"]),
-            ("\u{1100}\u{AC00}", &["\u{1100}\u{AC00}"]),
-            ("\u{1100}\u{308}\u{AC00}", &["\u{1100}\u{308}", "\u{AC00}"]),
-            ("\u{1100}\u{AC01}", &["\u{1100}\u{AC01}"]),
-            ("\u{1100}\u{308}\u{AC01}", &["\u{1100}\u{308}", "\u{AC01}"]),
-            ("\u{1100}\u{1F1E6}", &["\u{1100}", "\u{1F1E6}"]),
-            ("\u{1100}\u{308}\u{1F1E6}", &["\u{1100}\u{308}", "\u{1F1E6}"]),
-            ("\u{1100}\u{378}", &["\u{1100}", "\u{378}"]),
-            ("\u{1100}\u{308}\u{378}", &["\u{1100}\u{308}", "\u{378}"]),
-            ("\u{1160}\u{20}", &["\u{1160}", "\u{20}"]),
-            ("\u{1160}\u{308}\u{20}", &["\u{1160}\u{308}", "\u{20}"]),
-            ("\u{1160}\u{D}", &["\u{1160}", "\u{D}"]),
-            ("\u{1160}\u{308}\u{D}", &["\u{1160}\u{308}", "\u{D}"]),
-            ("\u{1160}\u{A}", &["\u{1160}", "\u{A}"]),
-            ("\u{1160}\u{308}\u{A}", &["\u{1160}\u{308}", "\u{A}"]),
-            ("\u{1160}\u{1}", &["\u{1160}", "\u{1}"]),
-            ("\u{1160}\u{308}\u{1}", &["\u{1160}\u{308}", "\u{1}"]),
-            ("\u{1160}\u{300}", &["\u{1160}\u{300}"]),
-            ("\u{1160}\u{308}\u{300}", &["\u{1160}\u{308}\u{300}"]),
-            ("\u{1160}\u{1100}", &["\u{1160}", "\u{1100}"]),
-            ("\u{1160}\u{308}\u{1100}", &["\u{1160}\u{308}", "\u{1100}"]),
-            ("\u{1160}\u{1160}", &["\u{1160}\u{1160}"]),
-            ("\u{1160}\u{308}\u{1160}", &["\u{1160}\u{308}", "\u{1160}"]),
-            ("\u{1160}\u{11A8}", &["\u{1160}\u{11A8}"]),
-            ("\u{1160}\u{308}\u{11A8}", &["\u{1160}\u{308}", "\u{11A8}"]),
-            ("\u{1160}\u{AC00}", &["\u{1160}", "\u{AC00}"]),
-            ("\u{1160}\u{308}\u{AC00}", &["\u{1160}\u{308}", "\u{AC00}"]),
-            ("\u{1160}\u{AC01}", &["\u{1160}", "\u{AC01}"]),
-            ("\u{1160}\u{308}\u{AC01}", &["\u{1160}\u{308}", "\u{AC01}"]),
-            ("\u{1160}\u{1F1E6}", &["\u{1160}", "\u{1F1E6}"]),
-            ("\u{1160}\u{308}\u{1F1E6}", &["\u{1160}\u{308}", "\u{1F1E6}"]),
-            ("\u{1160}\u{378}", &["\u{1160}", "\u{378}"]),
-            ("\u{1160}\u{308}\u{378}", &["\u{1160}\u{308}", "\u{378}"]),
-            ("\u{11A8}\u{20}", &["\u{11A8}", "\u{20}"]),
-            ("\u{11A8}\u{308}\u{20}", &["\u{11A8}\u{308}", "\u{20}"]),
-            ("\u{11A8}\u{D}", &["\u{11A8}", "\u{D}"]),
-            ("\u{11A8}\u{308}\u{D}", &["\u{11A8}\u{308}", "\u{D}"]),
-            ("\u{11A8}\u{A}", &["\u{11A8}", "\u{A}"]),
-            ("\u{11A8}\u{308}\u{A}", &["\u{11A8}\u{308}", "\u{A}"]),
-            ("\u{11A8}\u{1}", &["\u{11A8}", "\u{1}"]),
-            ("\u{11A8}\u{308}\u{1}", &["\u{11A8}\u{308}", "\u{1}"]),
-            ("\u{11A8}\u{300}", &["\u{11A8}\u{300}"]),
-            ("\u{11A8}\u{308}\u{300}", &["\u{11A8}\u{308}\u{300}"]),
-            ("\u{11A8}\u{1100}", &["\u{11A8}", "\u{1100}"]),
-            ("\u{11A8}\u{308}\u{1100}", &["\u{11A8}\u{308}", "\u{1100}"]),
-            ("\u{11A8}\u{1160}", &["\u{11A8}", "\u{1160}"]),
-            ("\u{11A8}\u{308}\u{1160}", &["\u{11A8}\u{308}", "\u{1160}"]),
-            ("\u{11A8}\u{11A8}", &["\u{11A8}\u{11A8}"]),
-            ("\u{11A8}\u{308}\u{11A8}", &["\u{11A8}\u{308}", "\u{11A8}"]),
-            ("\u{11A8}\u{AC00}", &["\u{11A8}", "\u{AC00}"]),
-            ("\u{11A8}\u{308}\u{AC00}", &["\u{11A8}\u{308}", "\u{AC00}"]),
-            ("\u{11A8}\u{AC01}", &["\u{11A8}", "\u{AC01}"]),
-            ("\u{11A8}\u{308}\u{AC01}", &["\u{11A8}\u{308}", "\u{AC01}"]),
-            ("\u{11A8}\u{1F1E6}", &["\u{11A8}", "\u{1F1E6}"]),
-            ("\u{11A8}\u{308}\u{1F1E6}", &["\u{11A8}\u{308}", "\u{1F1E6}"]),
-            ("\u{11A8}\u{378}", &["\u{11A8}", "\u{378}"]),
-            ("\u{11A8}\u{308}\u{378}", &["\u{11A8}\u{308}", "\u{378}"]),
-            ("\u{AC00}\u{20}", &["\u{AC00}", "\u{20}"]),
-            ("\u{AC00}\u{308}\u{20}", &["\u{AC00}\u{308}", "\u{20}"]),
-            ("\u{AC00}\u{D}", &["\u{AC00}", "\u{D}"]),
-            ("\u{AC00}\u{308}\u{D}", &["\u{AC00}\u{308}", "\u{D}"]),
-            ("\u{AC00}\u{A}", &["\u{AC00}", "\u{A}"]),
-            ("\u{AC00}\u{308}\u{A}", &["\u{AC00}\u{308}", "\u{A}"]),
-            ("\u{AC00}\u{1}", &["\u{AC00}", "\u{1}"]),
-            ("\u{AC00}\u{308}\u{1}", &["\u{AC00}\u{308}", "\u{1}"]),
-            ("\u{AC00}\u{300}", &["\u{AC00}\u{300}"]),
-            ("\u{AC00}\u{308}\u{300}", &["\u{AC00}\u{308}\u{300}"]),
-            ("\u{AC00}\u{1100}", &["\u{AC00}", "\u{1100}"]),
-            ("\u{AC00}\u{308}\u{1100}", &["\u{AC00}\u{308}", "\u{1100}"]),
-            ("\u{AC00}\u{1160}", &["\u{AC00}\u{1160}"]),
-            ("\u{AC00}\u{308}\u{1160}", &["\u{AC00}\u{308}", "\u{1160}"]),
-            ("\u{AC00}\u{11A8}", &["\u{AC00}\u{11A8}"]),
-            ("\u{AC00}\u{308}\u{11A8}", &["\u{AC00}\u{308}", "\u{11A8}"]),
-            ("\u{AC00}\u{AC00}", &["\u{AC00}", "\u{AC00}"]),
-            ("\u{AC00}\u{308}\u{AC00}", &["\u{AC00}\u{308}", "\u{AC00}"]),
-            ("\u{AC00}\u{AC01}", &["\u{AC00}", "\u{AC01}"]),
-            ("\u{AC00}\u{308}\u{AC01}", &["\u{AC00}\u{308}", "\u{AC01}"]),
-            ("\u{AC00}\u{1F1E6}", &["\u{AC00}", "\u{1F1E6}"]),
-            ("\u{AC00}\u{308}\u{1F1E6}", &["\u{AC00}\u{308}", "\u{1F1E6}"]),
-            ("\u{AC00}\u{378}", &["\u{AC00}", "\u{378}"]),
-            ("\u{AC00}\u{308}\u{378}", &["\u{AC00}\u{308}", "\u{378}"]),
-            ("\u{AC01}\u{20}", &["\u{AC01}", "\u{20}"]),
-            ("\u{AC01}\u{308}\u{20}", &["\u{AC01}\u{308}", "\u{20}"]),
-            ("\u{AC01}\u{D}", &["\u{AC01}", "\u{D}"]),
-            ("\u{AC01}\u{308}\u{D}", &["\u{AC01}\u{308}", "\u{D}"]),
-            ("\u{AC01}\u{A}", &["\u{AC01}", "\u{A}"]),
-            ("\u{AC01}\u{308}\u{A}", &["\u{AC01}\u{308}", "\u{A}"]),
-            ("\u{AC01}\u{1}", &["\u{AC01}", "\u{1}"]),
-            ("\u{AC01}\u{308}\u{1}", &["\u{AC01}\u{308}", "\u{1}"]),
-            ("\u{AC01}\u{300}", &["\u{AC01}\u{300}"]),
-            ("\u{AC01}\u{308}\u{300}", &["\u{AC01}\u{308}\u{300}"]),
-            ("\u{AC01}\u{1100}", &["\u{AC01}", "\u{1100}"]),
-            ("\u{AC01}\u{308}\u{1100}", &["\u{AC01}\u{308}", "\u{1100}"]),
-            ("\u{AC01}\u{1160}", &["\u{AC01}", "\u{1160}"]),
-            ("\u{AC01}\u{308}\u{1160}", &["\u{AC01}\u{308}", "\u{1160}"]),
-            ("\u{AC01}\u{11A8}", &["\u{AC01}\u{11A8}"]),
-            ("\u{AC01}\u{308}\u{11A8}", &["\u{AC01}\u{308}", "\u{11A8}"]),
-            ("\u{AC01}\u{AC00}", &["\u{AC01}", "\u{AC00}"]),
-            ("\u{AC01}\u{308}\u{AC00}", &["\u{AC01}\u{308}", "\u{AC00}"]),
-            ("\u{AC01}\u{AC01}", &["\u{AC01}", "\u{AC01}"]),
-            ("\u{AC01}\u{308}\u{AC01}", &["\u{AC01}\u{308}", "\u{AC01}"]),
-            ("\u{AC01}\u{1F1E6}", &["\u{AC01}", "\u{1F1E6}"]),
-            ("\u{AC01}\u{308}\u{1F1E6}", &["\u{AC01}\u{308}", "\u{1F1E6}"]),
-            ("\u{AC01}\u{378}", &["\u{AC01}", "\u{378}"]),
-            ("\u{AC01}\u{308}\u{378}", &["\u{AC01}\u{308}", "\u{378}"]),
-            ("\u{1F1E6}\u{20}", &["\u{1F1E6}", "\u{20}"]),
-            ("\u{1F1E6}\u{308}\u{20}", &["\u{1F1E6}\u{308}", "\u{20}"]),
-            ("\u{1F1E6}\u{D}", &["\u{1F1E6}", "\u{D}"]),
-            ("\u{1F1E6}\u{308}\u{D}", &["\u{1F1E6}\u{308}", "\u{D}"]),
-            ("\u{1F1E6}\u{A}", &["\u{1F1E6}", "\u{A}"]),
-            ("\u{1F1E6}\u{308}\u{A}", &["\u{1F1E6}\u{308}", "\u{A}"]),
-            ("\u{1F1E6}\u{1}", &["\u{1F1E6}", "\u{1}"]),
-            ("\u{1F1E6}\u{308}\u{1}", &["\u{1F1E6}\u{308}", "\u{1}"]),
-            ("\u{1F1E6}\u{300}", &["\u{1F1E6}\u{300}"]),
-            ("\u{1F1E6}\u{308}\u{300}", &["\u{1F1E6}\u{308}\u{300}"]),
-            ("\u{1F1E6}\u{1100}", &["\u{1F1E6}", "\u{1100}"]),
-            ("\u{1F1E6}\u{308}\u{1100}", &["\u{1F1E6}\u{308}", "\u{1100}"]),
-            ("\u{1F1E6}\u{1160}", &["\u{1F1E6}", "\u{1160}"]),
-            ("\u{1F1E6}\u{308}\u{1160}", &["\u{1F1E6}\u{308}", "\u{1160}"]),
-            ("\u{1F1E6}\u{11A8}", &["\u{1F1E6}", "\u{11A8}"]),
-            ("\u{1F1E6}\u{308}\u{11A8}", &["\u{1F1E6}\u{308}", "\u{11A8}"]),
-            ("\u{1F1E6}\u{AC00}", &["\u{1F1E6}", "\u{AC00}"]),
-            ("\u{1F1E6}\u{308}\u{AC00}", &["\u{1F1E6}\u{308}", "\u{AC00}"]),
-            ("\u{1F1E6}\u{AC01}", &["\u{1F1E6}", "\u{AC01}"]),
-            ("\u{1F1E6}\u{308}\u{AC01}", &["\u{1F1E6}\u{308}", "\u{AC01}"]),
-            ("\u{1F1E6}\u{1F1E6}", &["\u{1F1E6}\u{1F1E6}"]),
-            ("\u{1F1E6}\u{308}\u{1F1E6}", &["\u{1F1E6}\u{308}", "\u{1F1E6}"]),
-            ("\u{1F1E6}\u{378}", &["\u{1F1E6}", "\u{378}"]),
-            ("\u{1F1E6}\u{308}\u{378}", &["\u{1F1E6}\u{308}", "\u{378}"]),
-            ("\u{378}\u{20}", &["\u{378}", "\u{20}"]),
-            ("\u{378}\u{308}\u{20}", &["\u{378}\u{308}", "\u{20}"]),
-            ("\u{378}\u{D}", &["\u{378}", "\u{D}"]),
-            ("\u{378}\u{308}\u{D}", &["\u{378}\u{308}", "\u{D}"]),
-            ("\u{378}\u{A}", &["\u{378}", "\u{A}"]),
-            ("\u{378}\u{308}\u{A}", &["\u{378}\u{308}", "\u{A}"]),
-            ("\u{378}\u{1}", &["\u{378}", "\u{1}"]),
-            ("\u{378}\u{308}\u{1}", &["\u{378}\u{308}", "\u{1}"]),
-            ("\u{378}\u{300}", &["\u{378}\u{300}"]),
-            ("\u{378}\u{308}\u{300}", &["\u{378}\u{308}\u{300}"]),
-            ("\u{378}\u{1100}", &["\u{378}", "\u{1100}"]),
-            ("\u{378}\u{308}\u{1100}", &["\u{378}\u{308}", "\u{1100}"]),
-            ("\u{378}\u{1160}", &["\u{378}", "\u{1160}"]),
-            ("\u{378}\u{308}\u{1160}", &["\u{378}\u{308}", "\u{1160}"]),
-            ("\u{378}\u{11A8}", &["\u{378}", "\u{11A8}"]),
-            ("\u{378}\u{308}\u{11A8}", &["\u{378}\u{308}", "\u{11A8}"]),
-            ("\u{378}\u{AC00}", &["\u{378}", "\u{AC00}"]),
-            ("\u{378}\u{308}\u{AC00}", &["\u{378}\u{308}", "\u{AC00}"]),
-            ("\u{378}\u{AC01}", &["\u{378}", "\u{AC01}"]),
-            ("\u{378}\u{308}\u{AC01}", &["\u{378}\u{308}", "\u{AC01}"]),
-            ("\u{378}\u{1F1E6}", &["\u{378}", "\u{1F1E6}"]),
-            ("\u{378}\u{308}\u{1F1E6}", &["\u{378}\u{308}", "\u{1F1E6}"]),
-            ("\u{378}\u{378}", &["\u{378}", "\u{378}"]),
-            ("\u{378}\u{308}\u{378}", &["\u{378}\u{308}", "\u{378}"]),
-            ("\u{61}\u{1F1E6}\u{62}", &["\u{61}", "\u{1F1E6}", "\u{62}"]),
-            ("\u{1F1F7}\u{1F1FA}", &["\u{1F1F7}\u{1F1FA}"]),
-            ("\u{1F1F7}\u{1F1FA}\u{1F1F8}", &["\u{1F1F7}\u{1F1FA}\u{1F1F8}"]),
-            ("\u{1F1F7}\u{1F1FA}\u{1F1F8}\u{1F1EA}",
-            &["\u{1F1F7}\u{1F1FA}\u{1F1F8}\u{1F1EA}"]),
-            ("\u{1F1F7}\u{1F1FA}\u{200B}\u{1F1F8}\u{1F1EA}",
-             &["\u{1F1F7}\u{1F1FA}", "\u{200B}", "\u{1F1F8}\u{1F1EA}"]),
-            ("\u{1F1E6}\u{1F1E7}\u{1F1E8}", &["\u{1F1E6}\u{1F1E7}\u{1F1E8}"]),
-            ("\u{1F1E6}\u{200D}\u{1F1E7}\u{1F1E8}", &["\u{1F1E6}\u{200D}",
-             "\u{1F1E7}\u{1F1E8}"]),
-            ("\u{1F1E6}\u{1F1E7}\u{200D}\u{1F1E8}",
-             &["\u{1F1E6}\u{1F1E7}\u{200D}", "\u{1F1E8}"]),
-            ("\u{20}\u{200D}\u{646}", &["\u{20}\u{200D}", "\u{646}"]),
-            ("\u{646}\u{200D}\u{20}", &["\u{646}\u{200D}", "\u{20}"]),
-        ];
-
-        let test_diff: [(_, &[_], &[_]); 23] = [
-            ("\u{20}\u{903}", &["\u{20}\u{903}"], &["\u{20}", "\u{903}"]), ("\u{20}\u{308}\u{903}",
-            &["\u{20}\u{308}\u{903}"], &["\u{20}\u{308}", "\u{903}"]), ("\u{D}\u{308}\u{903}",
-            &["\u{D}", "\u{308}\u{903}"], &["\u{D}", "\u{308}", "\u{903}"]), ("\u{A}\u{308}\u{903}",
-            &["\u{A}", "\u{308}\u{903}"], &["\u{A}", "\u{308}", "\u{903}"]), ("\u{1}\u{308}\u{903}",
-            &["\u{1}", "\u{308}\u{903}"], &["\u{1}", "\u{308}", "\u{903}"]), ("\u{300}\u{903}",
-            &["\u{300}\u{903}"], &["\u{300}", "\u{903}"]), ("\u{300}\u{308}\u{903}",
-            &["\u{300}\u{308}\u{903}"], &["\u{300}\u{308}", "\u{903}"]), ("\u{903}\u{903}",
-            &["\u{903}\u{903}"], &["\u{903}", "\u{903}"]), ("\u{903}\u{308}\u{903}",
-            &["\u{903}\u{308}\u{903}"], &["\u{903}\u{308}", "\u{903}"]), ("\u{1100}\u{903}",
-            &["\u{1100}\u{903}"], &["\u{1100}", "\u{903}"]), ("\u{1100}\u{308}\u{903}",
-            &["\u{1100}\u{308}\u{903}"], &["\u{1100}\u{308}", "\u{903}"]), ("\u{1160}\u{903}",
-            &["\u{1160}\u{903}"], &["\u{1160}", "\u{903}"]), ("\u{1160}\u{308}\u{903}",
-            &["\u{1160}\u{308}\u{903}"], &["\u{1160}\u{308}", "\u{903}"]), ("\u{11A8}\u{903}",
-            &["\u{11A8}\u{903}"], &["\u{11A8}", "\u{903}"]), ("\u{11A8}\u{308}\u{903}",
-            &["\u{11A8}\u{308}\u{903}"], &["\u{11A8}\u{308}", "\u{903}"]), ("\u{AC00}\u{903}",
-            &["\u{AC00}\u{903}"], &["\u{AC00}", "\u{903}"]), ("\u{AC00}\u{308}\u{903}",
-            &["\u{AC00}\u{308}\u{903}"], &["\u{AC00}\u{308}", "\u{903}"]), ("\u{AC01}\u{903}",
-            &["\u{AC01}\u{903}"], &["\u{AC01}", "\u{903}"]), ("\u{AC01}\u{308}\u{903}",
-            &["\u{AC01}\u{308}\u{903}"], &["\u{AC01}\u{308}", "\u{903}"]), ("\u{1F1E6}\u{903}",
-            &["\u{1F1E6}\u{903}"], &["\u{1F1E6}", "\u{903}"]), ("\u{1F1E6}\u{308}\u{903}",
-            &["\u{1F1E6}\u{308}\u{903}"], &["\u{1F1E6}\u{308}", "\u{903}"]), ("\u{378}\u{903}",
-            &["\u{378}\u{903}"], &["\u{378}", "\u{903}"]), ("\u{378}\u{308}\u{903}",
-            &["\u{378}\u{308}\u{903}"], &["\u{378}\u{308}", "\u{903}"]),
-        ];
-
-        for &(s, g) in &test_same[..] {
-            // test forward iterator
-            assert!(order::equals(s.graphemes(true), g.iter().cloned()));
-            assert!(order::equals(s.graphemes(false), g.iter().cloned()));
-
-            // test reverse iterator
-            assert!(order::equals(s.graphemes(true).rev(), g.iter().rev().cloned()));
-            assert!(order::equals(s.graphemes(false).rev(), g.iter().rev().cloned()));
-        }
-
-        for &(s, gt, gf) in &test_diff {
-            // test forward iterator
-            assert!(order::equals(s.graphemes(true), gt.iter().cloned()));
-            assert!(order::equals(s.graphemes(false), gf.iter().cloned()));
-
-            // test reverse iterator
-            assert!(order::equals(s.graphemes(true).rev(), gt.iter().rev().cloned()));
-            assert!(order::equals(s.graphemes(false).rev(), gf.iter().rev().cloned()));
-        }
-
-        // test the indices iterators
-        let s = "a̐éö̲\r\n";
-        let gr_inds = s.grapheme_indices(true).collect::<Vec<(usize, &str)>>();
-        let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
-        assert_eq!(gr_inds, b);
-        let gr_inds = s.grapheme_indices(true).rev().collect::<Vec<(usize, &str)>>();
-        let b: &[_] = &[(11, "\r\n"), (6, "ö̲"), (3, "é"), (0, "a̐")];
-        assert_eq!(gr_inds, b);
-        let mut gr_inds_iter = s.grapheme_indices(true);
-        {
-            let gr_inds = gr_inds_iter.by_ref();
-            let e1 = gr_inds.size_hint();
-            assert_eq!(e1, (1, Some(13)));
-            let c = gr_inds.count();
-            assert_eq!(c, 4);
-        }
-        let e2 = gr_inds_iter.size_hint();
-        assert_eq!(e2, (0, Some(0)));
-
-        // make sure the reverse iterator does the right thing with "\n" at beginning of string
-        let s = "\n\r\n\r";
-        let gr = s.graphemes(true).rev().collect::<Vec<&str>>();
-        let b: &[_] = &["\r", "\r\n", "\n"];
-        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, u);
-        }
-        t("--1233345--", "12345", &["--1233345--"]);
-        t("abc::hello::there", "::", &["abc", "hello", "there"]);
-        t("::hello::there", "::", &["", "hello", "there"]);
-        t("hello::there::", "::", &["hello", "there", ""]);
-        t("::hello::there::", "::", &["", "hello", "there", ""]);
-        t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
-        t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
-        t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
-        t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
-        t("", ".", &[""]);
-        t("zz", "zz", &["",""]);
-        t("ok", "z", &["ok"]);
-        t("zzz", "zz", &["","z"]);
-        t("zzzzz", "zz", &["","","z"]);
-    }
-
-    #[test]
-    fn test_str_default() {
-        use core::default::Default;
-        fn t<S: Default + Str>() {
-            let s: S = Default::default();
-            assert_eq!(s.as_slice(), "");
-        }
-
-        t::<&str>();
-        t::<String>();
-    }
-
-    #[test]
-    fn test_str_container() {
-        fn sum_len(v: &[&str]) -> usize {
-            v.iter().map(|x| x.len()).sum()
-        }
-
-        let s = String::from_str("01234");
-        assert_eq!(5, sum_len(&["012", "", "34"]));
-        assert_eq!(5, sum_len(&[&String::from_str("01"),
-                                &String::from_str("2"),
-                                &String::from_str("34"),
-                                &String::from_str("")]));
-        assert_eq!(5, sum_len(&[&s]));
-    }
-
-    #[test]
-    fn test_str_from_utf8() {
-        let xs = b"hello";
-        assert_eq!(from_utf8(xs), Ok("hello"));
-
-        let xs = "ศไทย中华Việt Nam".as_bytes();
-        assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
-
-        let xs = b"hello\xFF";
-        assert_eq!(from_utf8(xs), Err(Utf8Error::TooShort));
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    use super::*;
-    use prelude::{SliceExt, IteratorExt, SliceConcatExt};
-    use test::Bencher;
-    use test::black_box;
-
-    #[bench]
-    fn char_iterator(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-
-        b.iter(|| s.chars().count());
-    }
-
-    #[bench]
-    fn char_iterator_for(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-
-        b.iter(|| {
-            for ch in s.chars() { black_box(ch); }
-        });
-    }
-
-    #[bench]
-    fn char_iterator_ascii(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb";
-
-        b.iter(|| s.chars().count());
-    }
-
-    #[bench]
-    fn char_iterator_rev(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-
-        b.iter(|| s.chars().rev().count());
-    }
-
-    #[bench]
-    fn char_iterator_rev_for(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-
-        b.iter(|| {
-            for ch in s.chars().rev() { black_box(ch); }
-        });
-    }
-
-    #[bench]
-    fn char_indicesator(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        let len = s.chars().count();
-
-        b.iter(|| assert_eq!(s.char_indices().count(), len));
-    }
-
-    #[bench]
-    fn char_indicesator_rev(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        let len = s.chars().count();
-
-        b.iter(|| assert_eq!(s.char_indices().rev().count(), len));
-    }
-
-    #[bench]
-    fn split_unicode_ascii(b: &mut Bencher) {
-        let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
-
-        b.iter(|| assert_eq!(s.split('V').count(), 3));
-    }
-
-    #[bench]
-    fn split_unicode_not_ascii(b: &mut Bencher) {
-        struct NotAscii(char);
-        impl CharEq for NotAscii {
-            fn matches(&mut self, c: char) -> bool {
-                let NotAscii(cc) = *self;
-                cc == c
-            }
-            fn only_ascii(&self) -> bool { false }
-        }
-        let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
-
-        b.iter(|| assert_eq!(s.split(NotAscii('V')).count(), 3));
-    }
-
-
-    #[bench]
-    fn split_ascii(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').count();
-
-        b.iter(|| assert_eq!(s.split(' ').count(), len));
-    }
-
-    #[bench]
-    fn split_not_ascii(b: &mut Bencher) {
-        struct NotAscii(char);
-        impl CharEq for NotAscii {
-            #[inline]
-            fn matches(&mut self, c: char) -> bool {
-                let NotAscii(cc) = *self;
-                cc == c
-            }
-            fn only_ascii(&self) -> bool { false }
-        }
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').count();
-
-        b.iter(|| assert_eq!(s.split(NotAscii(' ')).count(), len));
-    }
-
-    #[bench]
-    fn split_extern_fn(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').count();
-        fn pred(c: char) -> bool { c == ' ' }
-
-        b.iter(|| assert_eq!(s.split(pred).count(), len));
-    }
-
-    #[bench]
-    fn split_closure(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').count();
-
-        b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len));
-    }
-
-    #[bench]
-    fn split_slice(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').count();
-
-        let c: &[char] = &[' '];
-        b.iter(|| assert_eq!(s.split(c).count(), len));
-    }
-
-    #[bench]
-    fn bench_connect(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        let sep = "→";
-        let v = vec![s, s, s, s, s, s, s, s, s, s];
-        b.iter(|| {
-            assert_eq!(v.connect(sep).len(), s.len() * 10 + sep.len() * 9);
-        })
-    }
-
-    #[bench]
-    fn bench_contains_short_short(b: &mut Bencher) {
-        let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
-        let needle = "sit";
-
-        b.iter(|| {
-            assert!(haystack.contains(needle));
-        })
-    }
-
-    #[bench]
-    fn bench_contains_short_long(b: &mut Bencher) {
-        let haystack = "\
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
-ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
-eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
-sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
-tempus vel, gravida nec quam.
-
-In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
-sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
-diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
-lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
-eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
-interdum. Curabitur ut nisi justo.
-
-Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
-mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
-lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
-est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
-felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
-ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
-feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
-Aliquam sit amet placerat lorem.
-
-Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
-mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
-Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
-lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
-suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
-cursus accumsan.
-
-Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
-feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
-vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
-leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
-malesuada sollicitudin quam eu fermentum.";
-        let needle = "english";
-
-        b.iter(|| {
-            assert!(!haystack.contains(needle));
-        })
-    }
-
-    #[bench]
-    fn bench_contains_bad_naive(b: &mut Bencher) {
-        let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
-        let needle = "aaaaaaaab";
-
-        b.iter(|| {
-            assert!(!haystack.contains(needle));
-        })
+    /// Returns the lowercase equivalent of this string.
+    ///
+    /// # Examples
+    ///
+    /// let s = "HELLO";
+    /// assert_eq!(s.to_lowercase(), "hello");
+    #[unstable(feature = "collections")]
+    pub fn to_lowercase(&self) -> String {
+        let mut s = String::with_capacity(self.len());
+        s.extend(self[..].chars().flat_map(|c| c.to_lowercase()));
+        return s;
     }
 
-    #[bench]
-    fn bench_contains_equal(b: &mut Bencher) {
-        let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
-        let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
-
-        b.iter(|| {
-            assert!(haystack.contains(needle));
-        })
+    /// Returns the uppercase equivalent of this string.
+    ///
+    /// # Examples
+    ///
+    /// let s = "hello";
+    /// assert_eq!(s.to_uppercase(), "HELLO");
+    #[unstable(feature = "collections")]
+    pub fn to_uppercase(&self) -> String {
+        let mut s = String::with_capacity(self.len());
+        s.extend(self[..].chars().flat_map(|c| c.to_uppercase()));
+        return s;
     }
 }
index 3b179d0b94c97cccddcdef0ddd6c7c070270cfc1..7a7725320914f6fdba19cb1443d0d1e9c2da753b 100644 (file)
 use core::prelude::*;
 
 use core::default::Default;
-use core::error::Error;
 use core::fmt;
 use core::hash;
 use core::iter::{IntoIterator, FromIterator};
 use core::mem;
 use core::ops::{self, Deref, Add, Index};
 use core::ptr;
-use core::raw::Slice as RawSlice;
+use core::slice;
+use core::str::Pattern;
 use unicode::str as unicode_str;
 use unicode::str::Utf16Item;
 
 use borrow::{Cow, IntoCow};
-use str::{self, CharRange, FromStr, Utf8Error};
+use str::{self, FromStr, Utf8Error};
 use vec::{DerefVec, Vec, as_vec};
 
 /// A growable string stored as a UTF-8 encoded buffer.
@@ -90,14 +90,26 @@ impl String {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections, core)]
     /// let s = String::from_str("hello");
-    /// assert_eq!(s.as_slice(), "hello");
+    /// assert_eq!(&s[..], "hello");
     /// ```
     #[inline]
     #[unstable(feature = "collections",
                reason = "needs investigation to see if to_string() can match perf")]
+    #[cfg(not(test))]
     pub fn from_str(string: &str) -> String {
-        String { vec: ::slice::SliceExt::to_vec(string.as_bytes()) }
+        String { vec: <[_]>::to_vec(string.as_bytes()) }
+    }
+
+    // HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is
+    // required for this method definition, is not available. Since we don't
+    // require this method for testing purposes, I'll just stub it
+    // NB see the slice::hack module in slice.rs for more information
+    #[inline]
+    #[cfg(test)]
+    pub fn from_str(_: &str) -> String {
+        panic!("not available with cfg(test)");
     }
 
     /// Returns the vector as a string buffer, if possible, taking care not to
@@ -110,7 +122,8 @@ impl String {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(core)]
     /// use std::str::Utf8Error;
     ///
     /// let hello_vec = vec![104, 101, 108, 108, 111];
@@ -120,7 +133,7 @@ impl String {
     /// let invalid_vec = vec![240, 144, 128];
     /// let s = String::from_utf8(invalid_vec).err().unwrap();
     /// assert_eq!(s.utf8_error(), Utf8Error::TooShort);
-    /// assert_eq!(s.into_bytes(), vec![240, 144, 128]);
+    /// assert_eq!(s.into_bytes(), [240, 144, 128]);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -136,10 +149,10 @@ impl String {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let input = b"Hello \xF0\x90\x80World";
     /// let output = String::from_utf8_lossy(input);
-    /// assert_eq!(output.as_slice(), "Hello \u{FFFD}World");
+    /// assert_eq!(output, "Hello \u{FFFD}World");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> {
@@ -153,8 +166,8 @@ impl String {
             }
         }
 
-        static TAG_CONT_U8: u8 = 128u8;
-        static REPLACEMENT: &'static [u8] = b"\xEF\xBF\xBD"; // U+FFFD in UTF-8
+        const TAG_CONT_U8: u8 = 128;
+        const REPLACEMENT: &'static [u8] = b"\xEF\xBF\xBD"; // U+FFFD in UTF-8
         let total = v.len();
         fn unsafe_get(xs: &[u8], i: usize) -> u8 {
             unsafe { *xs.get_unchecked(i) }
@@ -195,14 +208,14 @@ impl String {
                 }
             })}
 
-            if byte < 128u8 {
+            if byte < 128 {
                 // subseqidx handles this
             } else {
                 let w = unicode_str::utf8_char_width(byte);
 
                 match w {
                     2 => {
-                        if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+                        if safe_get(v, i, total) & 192 != TAG_CONT_U8 {
                             error!();
                             continue;
                         }
@@ -220,7 +233,7 @@ impl String {
                             }
                         }
                         i += 1;
-                        if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+                        if safe_get(v, i, total) & 192 != TAG_CONT_U8 {
                             error!();
                             continue;
                         }
@@ -237,12 +250,12 @@ impl String {
                             }
                         }
                         i += 1;
-                        if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+                        if safe_get(v, i, total) & 192 != TAG_CONT_U8 {
                             error!();
                             continue;
                         }
                         i += 1;
-                        if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+                        if safe_get(v, i, total) & 192 != TAG_CONT_U8 {
                             error!();
                             continue;
                         }
@@ -268,7 +281,7 @@ impl String {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// // 𝄞music
     /// let mut v = &mut [0xD834, 0xDD1E, 0x006d, 0x0075,
     ///                   0x0073, 0x0069, 0x0063];
@@ -296,7 +309,7 @@ impl String {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// // 𝄞mus<invalid>ic<invalid>
     /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
     ///           0x0073, 0xDD1E, 0x0069, 0x0063,
@@ -314,6 +327,7 @@ impl String {
     /// Creates a new `String` from a length, capacity, and pointer.
     ///
     /// This is unsafe because:
+    ///
     /// * We call `Vec::from_raw_parts` to get a `Vec<u8>`;
     /// * We assume that the `Vec` contains valid UTF-8.
     #[inline]
@@ -338,9 +352,10 @@ impl String {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let s = String::from_str("hello");
     /// let bytes = s.into_bytes();
-    /// assert_eq!(bytes, vec![104, 101, 108, 108, 111]);
+    /// assert_eq!(bytes, [104, 101, 108, 108, 111]);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -348,14 +363,23 @@ impl String {
         self.vec
     }
 
+    /// Extract a string slice containing the entire string.
+    #[inline]
+    #[unstable(feature = "convert",
+               reason = "waiting on RFC revision")]
+    pub fn as_str(&self) -> &str {
+        self
+    }
+
     /// Pushes the given string onto this string buffer.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut s = String::from_str("foo");
     /// s.push_str("bar");
-    /// assert_eq!(s.as_slice(), "foobar");
+    /// assert_eq!(s, "foobar");
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -429,6 +453,7 @@ impl String {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut s = String::from_str("foo");
     /// s.reserve(100);
     /// assert!(s.capacity() >= 100);
@@ -446,11 +471,12 @@ impl String {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut s = String::from_str("abc");
     /// s.push('1');
     /// s.push('2');
     /// s.push('3');
-    /// assert_eq!(s.as_slice(), "abc123");
+    /// assert_eq!(s, "abc123");
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -467,11 +493,11 @@ impl String {
         unsafe {
             // Attempt to not use an intermediate buffer by just pushing bytes
             // directly onto this string.
-            let slice = RawSlice {
-                data: self.vec.as_ptr().offset(cur_len as isize),
-                len: 4,
-            };
-            let used = ch.encode_utf8(mem::transmute(slice)).unwrap_or(0);
+            let slice = slice::from_raw_parts_mut (
+                self.vec.as_mut_ptr().offset(cur_len as isize),
+                4
+            );
+            let used = ch.encode_utf8(slice).unwrap_or(0);
             self.vec.set_len(cur_len + used);
         }
     }
@@ -481,6 +507,7 @@ impl String {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let s = String::from_str("hello");
     /// let b: &[_] = &[104, 101, 108, 108, 111];
     /// assert_eq!(s.as_bytes(), b);
@@ -501,9 +528,10 @@ impl String {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut s = String::from_str("hello");
     /// s.truncate(2);
-    /// assert_eq!(s.as_slice(), "he");
+    /// assert_eq!(s, "he");
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -518,6 +546,7 @@ impl String {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut s = String::from_str("foo");
     /// assert_eq!(s.pop(), Some('o'));
     /// assert_eq!(s.pop(), Some('o'));
@@ -532,9 +561,9 @@ impl String {
             return None
         }
 
-        let CharRange {ch, next} = self.char_range_at_reverse(len);
+        let ch = self.char_at_reverse(len);
         unsafe {
-            self.vec.set_len(next);
+            self.vec.set_len(len - ch.len_utf8());
         }
         Some(ch)
     }
@@ -555,6 +584,7 @@ impl String {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut s = String::from_str("foo");
     /// assert_eq!(s.remove(0), 'f');
     /// assert_eq!(s.remove(1), 'o');
@@ -566,11 +596,12 @@ impl String {
         let len = self.len();
         assert!(idx <= len);
 
-        let CharRange { ch, next } = self.char_range_at(idx);
+        let ch = self.char_at(idx);
+        let next = idx + ch.len_utf8();
         unsafe {
-            ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as isize),
-                             self.vec.as_ptr().offset(next as isize),
-                             len - next);
+            ptr::copy(self.vec.as_ptr().offset(next as isize),
+                      self.vec.as_mut_ptr().offset(idx as isize),
+                      len - next);
             self.vec.set_len(len - (next - idx));
         }
         ch
@@ -598,12 +629,12 @@ impl String {
         let amt = ch.encode_utf8(&mut bits).unwrap();
 
         unsafe {
-            ptr::copy_memory(self.vec.as_mut_ptr().offset((idx + amt) as isize),
-                             self.vec.as_ptr().offset(idx as isize),
-                             len - idx);
-            ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as isize),
-                             bits.as_ptr(),
-                             amt);
+            ptr::copy(self.vec.as_ptr().offset(idx as isize),
+                      self.vec.as_mut_ptr().offset((idx + amt) as isize),
+                      len - idx);
+            ptr::copy(bits.as_ptr(),
+                      self.vec.as_mut_ptr().offset(idx as isize),
+                      amt);
             self.vec.set_len(len + amt);
         }
     }
@@ -616,13 +647,14 @@ impl String {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut s = String::from_str("hello");
     /// unsafe {
     ///     let vec = s.as_mut_vec();
-    ///     assert!(vec == &mut vec![104, 101, 108, 108, 111]);
+    ///     assert!(vec == &[104, 101, 108, 108, 111]);
     ///     vec.reverse();
     /// }
-    /// assert_eq!(s.as_slice(), "olleh");
+    /// assert_eq!(s, "olleh");
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -690,11 +722,6 @@ impl fmt::Display for FromUtf8Error {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for FromUtf8Error {
-    fn description(&self) -> &str { "invalid utf-8" }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for FromUtf16Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -702,11 +729,6 @@ impl fmt::Display for FromUtf16Error {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for FromUtf16Error {
-    fn description(&self) -> &str { "invalid utf-16" }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl FromIterator<char> for String {
     fn from_iter<I: IntoIterator<Item=char>>(iter: I) -> String {
@@ -752,6 +774,25 @@ impl<'a> Extend<&'a str> for String {
     }
 }
 
+/// A convenience impl that delegates to the impl for `&str`
+impl<'a, 'b> Pattern<'a> for &'b String {
+    type Searcher = <&'b str as Pattern<'a>>::Searcher;
+
+    fn into_searcher(self, haystack: &'a str) -> <&'b str as Pattern<'a>>::Searcher {
+        self[..].into_searcher(haystack)
+    }
+
+    #[inline]
+    fn is_contained_in(self, haystack: &'a str) -> bool {
+        self[..].is_contained_in(haystack)
+    }
+
+    #[inline]
+    fn is_prefix_of(self, haystack: &'a str) -> bool {
+        self[..].is_prefix_of(haystack)
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq for String {
     #[inline]
@@ -801,9 +842,9 @@ impl<'a, 'b> PartialEq<Cow<'a, str>> for &'b str {
 }
 
 #[unstable(feature = "collections", reason = "waiting on Str stabilization")]
+#[allow(deprecated)]
 impl Str for String {
     #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn as_slice(&self) -> &str {
         unsafe { mem::transmute(&*self.vec) }
     }
@@ -834,16 +875,7 @@ impl fmt::Debug for String {
     }
 }
 
-#[unstable(feature = "collections", reason = "waiting on Hash stabilization")]
-#[cfg(stage0)]
-impl<H: hash::Writer + hash::Hasher> hash::Hash<H> for String {
-    #[inline]
-    fn hash(&self, hasher: &mut H) {
-        (**self).hash(hasher)
-    }
-}
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg(not(stage0))]
 impl hash::Hash for String {
     #[inline]
     fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
@@ -866,32 +898,36 @@ impl<'a> Add<&'a str> for String {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl ops::Index<ops::Range<usize>> for String {
     type Output = str;
+
     #[inline]
-    fn index(&self, index: &ops::Range<usize>) -> &str {
-        &self[..][*index]
+    fn index(&self, index: ops::Range<usize>) -> &str {
+        &self[..][index]
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl ops::Index<ops::RangeTo<usize>> for String {
     type Output = str;
+
     #[inline]
-    fn index(&self, index: &ops::RangeTo<usize>) -> &str {
-        &self[..][*index]
+    fn index(&self, index: ops::RangeTo<usize>) -> &str {
+        &self[..][index]
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl ops::Index<ops::RangeFrom<usize>> for String {
     type Output = str;
+
     #[inline]
-    fn index(&self, index: &ops::RangeFrom<usize>) -> &str {
-        &self[..][*index]
+    fn index(&self, index: ops::RangeFrom<usize>) -> &str {
+        &self[..][index]
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl ops::Index<ops::RangeFull> for String {
     type Output = str;
+
     #[inline]
-    fn index(&self, _index: &ops::RangeFull) -> &str {
+    fn index(&self, _index: ops::RangeFull) -> &str {
         unsafe { mem::transmute(&*self.vec) }
     }
 }
@@ -926,6 +962,7 @@ impl<'a> Deref for DerefString<'a> {
 /// # Examples
 ///
 /// ```
+/// # #![feature(collections)]
 /// use std::string::as_string;
 ///
 /// fn string_consumer(s: String) {
@@ -970,6 +1007,44 @@ impl<T: fmt::Display + ?Sized> ToString for T {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<str> for String {
+    fn as_ref(&self) -> &str {
+        self
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> From<&'a str> for String {
+    #[inline]
+    fn from(s: &'a str) -> String {
+        s.to_string()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> From<&'a str> for Cow<'a, str> {
+    #[inline]
+    fn from(s: &'a str) -> Cow<'a, str> {
+        Cow::Borrowed(s)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> From<String> for Cow<'a, str> {
+    #[inline]
+    fn from(s: String) -> Cow<'a, str> {
+        Cow::Owned(s)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Into<Vec<u8>> for String {
+    fn into(self) -> Vec<u8> {
+        self.into_bytes()
+    }
+}
+
+#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`")]
 impl IntoCow<'static, str> for String {
     #[inline]
     fn into_cow(self) -> Cow<'static, str> {
@@ -977,7 +1052,7 @@ impl IntoCow<'static, str> for String {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
+#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`")]
 impl<'a> IntoCow<'a, str> for &'a str {
     #[inline]
     fn into_cow(self) -> Cow<'a, str> {
@@ -985,6 +1060,7 @@ impl<'a> IntoCow<'a, str> for &'a str {
     }
 }
 
+#[allow(deprecated)]
 impl<'a> Str for Cow<'a, str> {
     #[inline]
     fn as_slice<'b>(&'b self) -> &'b str {
@@ -992,11 +1068,6 @@ impl<'a> Str for Cow<'a, str> {
     }
 }
 
-/// A clone-on-write string
-#[deprecated(since = "1.0.0", reason = "use Cow<'a, str> instead")]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub type CowString<'a> = Cow<'a, str>;
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Write for String {
     #[inline]
@@ -1005,450 +1076,3 @@ impl fmt::Write for String {
         Ok(())
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use test::Bencher;
-
-    use str::Utf8Error;
-    use core::iter::repeat;
-    use super::{as_string, CowString};
-
-    #[test]
-    fn test_as_string() {
-        let x = "foo";
-        assert_eq!(x, &**as_string(x));
-    }
-
-    #[test]
-    fn test_from_str() {
-      let owned: Option<::std::string::String> = "string".parse().ok();
-      assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
-    }
-
-    #[test]
-    fn test_unsized_to_string() {
-        let s: &str = "abc";
-        let _: String = (*s).to_string();
-    }
-
-    #[test]
-    fn test_from_utf8() {
-        let xs = b"hello".to_vec();
-        assert_eq!(String::from_utf8(xs).unwrap(),
-                   String::from_str("hello"));
-
-        let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
-        assert_eq!(String::from_utf8(xs).unwrap(),
-                   String::from_str("ศไทย中华Việt Nam"));
-
-        let xs = b"hello\xFF".to_vec();
-        let err = String::from_utf8(xs).err().unwrap();
-        assert_eq!(err.utf8_error(), Utf8Error::TooShort);
-        assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
-    }
-
-    #[test]
-    fn test_from_utf8_lossy() {
-        let xs = b"hello";
-        let ys: CowString = "hello".into_cow();
-        assert_eq!(String::from_utf8_lossy(xs), ys);
-
-        let xs = "ศไทย中华Việt Nam".as_bytes();
-        let ys: CowString = "ศไทย中华Việt Nam".into_cow();
-        assert_eq!(String::from_utf8_lossy(xs), ys);
-
-        let xs = b"Hello\xC2 There\xFF Goodbye";
-        assert_eq!(String::from_utf8_lossy(xs),
-                   String::from_str("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
-
-        let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
-        assert_eq!(String::from_utf8_lossy(xs),
-                   String::from_str("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
-
-        let xs = b"\xF5foo\xF5\x80bar";
-        assert_eq!(String::from_utf8_lossy(xs),
-                   String::from_str("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
-
-        let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
-        assert_eq!(String::from_utf8_lossy(xs),
-                   String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
-
-        let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
-        assert_eq!(String::from_utf8_lossy(xs),
-                   String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
-
-        let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
-        assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}\
-                                               foo\u{10000}bar").into_cow());
-
-        // surrogates
-        let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
-        assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}foo\
-                                               \u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
-    }
-
-    #[test]
-    fn test_from_utf16() {
-        let pairs =
-            [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
-              vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
-                0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
-                0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
-                0xd800_u16, 0xdf30_u16, 0x000a_u16]),
-
-             (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
-              vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
-                0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
-                0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
-                0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
-                0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
-                0x000a_u16]),
-
-             (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
-              vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
-                0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
-                0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
-                0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
-                0xdf04_u16, 0xd800_u16, 0xdf15_u16, 0xd800_u16,
-                0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
-                0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
-
-             (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
-              vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
-                0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
-                0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
-                0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
-                0xdc93_u16, 0x0020_u16, 0xd801_u16, 0xdc88_u16,
-                0xd801_u16, 0xdc9a_u16, 0xd801_u16, 0xdc8d_u16,
-                0x0020_u16, 0xd801_u16, 0xdc8f_u16, 0xd801_u16,
-                0xdc9c_u16, 0xd801_u16, 0xdc92_u16, 0xd801_u16,
-                0xdc96_u16, 0xd801_u16, 0xdc86_u16, 0x0020_u16,
-                0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
-                0x000a_u16 ]),
-             // Issue #12318, even-numbered non-BMP planes
-             (String::from_str("\u{20000}"),
-              vec![0xD840, 0xDC00])];
-
-        for p in &pairs {
-            let (s, u) = (*p).clone();
-            let s_as_utf16 = s.utf16_units().collect::<Vec<u16>>();
-            let u_as_string = String::from_utf16(&u).unwrap();
-
-            assert!(::unicode::str::is_utf16(&u));
-            assert_eq!(s_as_utf16, u);
-
-            assert_eq!(u_as_string, s);
-            assert_eq!(String::from_utf16_lossy(&u), s);
-
-            assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
-            assert_eq!(u_as_string.utf16_units().collect::<Vec<u16>>(), u);
-        }
-    }
-
-    #[test]
-    fn test_utf16_invalid() {
-        // completely positive cases tested above.
-        // lead + eof
-        assert!(String::from_utf16(&[0xD800]).is_err());
-        // lead + lead
-        assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
-
-        // isolated trail
-        assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
-
-        // general
-        assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
-    }
-
-    #[test]
-    fn test_from_utf16_lossy() {
-        // completely positive cases tested above.
-        // lead + eof
-        assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from_str("\u{FFFD}"));
-        // lead + lead
-        assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
-                   String::from_str("\u{FFFD}\u{FFFD}"));
-
-        // isolated trail
-        assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from_str("a\u{FFFD}"));
-
-        // general
-        assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
-                   String::from_str("\u{FFFD}𐒋\u{FFFD}"));
-    }
-
-    #[test]
-    fn test_push_bytes() {
-        let mut s = String::from_str("ABC");
-        unsafe {
-            let mv = s.as_mut_vec();
-            mv.push_all(&[b'D']);
-        }
-        assert_eq!(s, "ABCD");
-    }
-
-    #[test]
-    fn test_push_str() {
-        let mut s = String::new();
-        s.push_str("");
-        assert_eq!(&s[0..], "");
-        s.push_str("abc");
-        assert_eq!(&s[0..], "abc");
-        s.push_str("ประเทศไทย中华Việt Nam");
-        assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
-    }
-
-    #[test]
-    fn test_push() {
-        let mut data = String::from_str("ประเทศไทย中");
-        data.push('华');
-        data.push('b'); // 1 byte
-        data.push('¢'); // 2 byte
-        data.push('€'); // 3 byte
-        data.push('𤭢'); // 4 byte
-        assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
-    }
-
-    #[test]
-    fn test_pop() {
-        let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
-        assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
-        assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
-        assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
-        assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
-        assert_eq!(data.pop().unwrap(), '华');
-        assert_eq!(data, "ประเทศไทย中");
-    }
-
-    #[test]
-    fn test_str_truncate() {
-        let mut s = String::from_str("12345");
-        s.truncate(5);
-        assert_eq!(s, "12345");
-        s.truncate(3);
-        assert_eq!(s, "123");
-        s.truncate(0);
-        assert_eq!(s, "");
-
-        let mut s = String::from_str("12345");
-        let p = s.as_ptr();
-        s.truncate(3);
-        s.push_str("6");
-        let p_ = s.as_ptr();
-        assert_eq!(p_, p);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_str_truncate_invalid_len() {
-        let mut s = String::from_str("12345");
-        s.truncate(6);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_str_truncate_split_codepoint() {
-        let mut s = String::from_str("\u{FC}"); // ü
-        s.truncate(1);
-    }
-
-    #[test]
-    fn test_str_clear() {
-        let mut s = String::from_str("12345");
-        s.clear();
-        assert_eq!(s.len(), 0);
-        assert_eq!(s, "");
-    }
-
-    #[test]
-    fn test_str_add() {
-        let a = String::from_str("12345");
-        let b = a + "2";
-        let b = b + "2";
-        assert_eq!(b.len(), 7);
-        assert_eq!(b, "1234522");
-    }
-
-    #[test]
-    fn remove() {
-        let mut s = "ศไทย中华Việt Nam; foobar".to_string();;
-        assert_eq!(s.remove(0), 'ศ');
-        assert_eq!(s.len(), 33);
-        assert_eq!(s, "ไทย中华Việt Nam; foobar");
-        assert_eq!(s.remove(17), 'ệ');
-        assert_eq!(s, "ไทย中华Vit Nam; foobar");
-    }
-
-    #[test] #[should_fail]
-    fn remove_bad() {
-        "ศ".to_string().remove(1);
-    }
-
-    #[test]
-    fn insert() {
-        let mut s = "foobar".to_string();
-        s.insert(0, 'ệ');
-        assert_eq!(s, "ệfoobar");
-        s.insert(6, 'ย');
-        assert_eq!(s, "ệfooยbar");
-    }
-
-    #[test] #[should_fail] fn insert_bad1() { "".to_string().insert(1, 't'); }
-    #[test] #[should_fail] fn insert_bad2() { "ệ".to_string().insert(1, 't'); }
-
-    #[test]
-    fn test_slicing() {
-        let s = "foobar".to_string();
-        assert_eq!("foobar", &s[..]);
-        assert_eq!("foo", &s[..3]);
-        assert_eq!("bar", &s[3..]);
-        assert_eq!("oob", &s[1..4]);
-    }
-
-    #[test]
-    fn test_simple_types() {
-        assert_eq!(1.to_string(), "1");
-        assert_eq!((-1).to_string(), "-1");
-        assert_eq!(200.to_string(), "200");
-        assert_eq!(2u8.to_string(), "2");
-        assert_eq!(true.to_string(), "true");
-        assert_eq!(false.to_string(), "false");
-        assert_eq!(("hi".to_string()).to_string(), "hi");
-    }
-
-    #[test]
-    fn test_vectors() {
-        let x: Vec<i32> = vec![];
-        assert_eq!(format!("{:?}", x), "[]");
-        assert_eq!(format!("{:?}", vec![1]), "[1]");
-        assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
-        assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) ==
-               "[[], [1], [1, 1]]");
-    }
-
-    #[test]
-    fn test_from_iterator() {
-        let s = "ศไทย中华Việt Nam".to_string();
-        let t = "ศไทย中华";
-        let u = "Việt Nam";
-
-        let a: String = s.chars().collect();
-        assert_eq!(s, a);
-
-        let mut b = t.to_string();
-        b.extend(u.chars());
-        assert_eq!(s, b);
-
-        let c: String = vec![t, u].into_iter().collect();
-        assert_eq!(s, c);
-
-        let mut d = t.to_string();
-        d.extend(vec![u].into_iter());
-        assert_eq!(s, d);
-    }
-
-    #[bench]
-    fn bench_with_capacity(b: &mut Bencher) {
-        b.iter(|| {
-            String::with_capacity(100)
-        });
-    }
-
-    #[bench]
-    fn bench_push_str(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        b.iter(|| {
-            let mut r = String::new();
-            r.push_str(s);
-        });
-    }
-
-    const REPETITIONS: u64 = 10_000;
-
-    #[bench]
-    fn bench_push_str_one_byte(b: &mut Bencher) {
-        b.bytes = REPETITIONS;
-        b.iter(|| {
-            let mut r = String::new();
-            for _ in 0..REPETITIONS {
-                r.push_str("a")
-            }
-        });
-    }
-
-    #[bench]
-    fn bench_push_char_one_byte(b: &mut Bencher) {
-        b.bytes = REPETITIONS;
-        b.iter(|| {
-            let mut r = String::new();
-            for _ in 0..REPETITIONS {
-                r.push('a')
-            }
-        });
-    }
-
-    #[bench]
-    fn bench_push_char_two_bytes(b: &mut Bencher) {
-        b.bytes = REPETITIONS * 2;
-        b.iter(|| {
-            let mut r = String::new();
-            for _ in 0..REPETITIONS {
-                r.push('â')
-            }
-        });
-    }
-
-    #[bench]
-    fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
-        let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
-                  Lorem ipsum dolor sit amet, consectetur. ";
-
-        assert_eq!(100, s.len());
-        b.iter(|| {
-            let _ = String::from_utf8_lossy(s);
-        });
-    }
-
-    #[bench]
-    fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
-        let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
-        assert_eq!(100, s.len());
-        b.iter(|| {
-            let _ = String::from_utf8_lossy(s);
-        });
-    }
-
-    #[bench]
-    fn from_utf8_lossy_invalid(b: &mut Bencher) {
-        let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
-        b.iter(|| {
-            let _ = String::from_utf8_lossy(s);
-        });
-    }
-
-    #[bench]
-    fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
-        let s = repeat(0xf5u8).take(100).collect::<Vec<_>>();
-        b.iter(|| {
-            let _ = String::from_utf8_lossy(&s);
-        });
-    }
-
-    #[bench]
-    fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
-        let s = "Hello there, the quick brown fox jumped over the lazy dog! \
-                 Lorem ipsum dolor sit amet, consectetur. ";
-        // ensure our operation produces an exact-size string before we benchmark it
-        let mut r = String::with_capacity(s.len());
-        r.push_str(s);
-        assert_eq!(r.len(), r.capacity());
-        b.iter(|| {
-            let mut r = String::with_capacity(s.len());
-            r.push_str(s);
-            r.shrink_to_fit();
-            r
-        });
-    }
-}
index 1cc2a5235abec1a1af6a5cfe6a7361a758d7910c..087b065031f2badba5d3314a147db426e9af508d 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! A growable list type with heap-allocated contents, written `Vec<T>` but pronounced 'vector.'
+//! A growable list type with heap-allocated contents, written `Vec<T>` but
+//! pronounced 'vector.'
 //!
 //! Vectors have `O(1)` indexing, push (to the end) and pop (from the end).
 //!
@@ -51,7 +52,7 @@ use core::prelude::*;
 use alloc::boxed::Box;
 use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
 use core::cmp::max;
-use core::cmp::{Ordering};
+use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt;
 use core::hash::{self, Hash};
@@ -59,12 +60,10 @@ use core::intrinsics::assume;
 use core::iter::{repeat, FromIterator, IntoIterator};
 use core::marker::PhantomData;
 use core::mem;
-use core::num::{Int, UnsignedInt};
 use core::ops::{Index, IndexMut, Deref, Add};
 use core::ops;
 use core::ptr;
 use core::ptr::Unique;
-use core::raw::Slice as RawSlice;
 use core::slice;
 use core::usize;
 
@@ -75,6 +74,7 @@ use borrow::{Cow, IntoCow};
 /// # Examples
 ///
 /// ```
+/// # #![feature(collections)]
 /// let mut vec = Vec::new();
 /// vec.push(1);
 /// vec.push(2);
@@ -93,7 +93,7 @@ use borrow::{Cow, IntoCow};
 /// for x in vec.iter() {
 ///     println!("{}", x);
 /// }
-/// assert_eq!(vec, vec![7, 1, 2, 3]);
+/// assert_eq!(vec, [7, 1, 2, 3]);
 /// ```
 ///
 /// The `vec!` macro is provided to make initialization more convenient:
@@ -101,7 +101,7 @@ use borrow::{Cow, IntoCow};
 /// ```
 /// let mut vec = vec![1, 2, 3];
 /// vec.push(4);
-/// assert_eq!(vec, vec![1, 2, 3, 4]);
+/// assert_eq!(vec, [1, 2, 3, 4]);
 /// ```
 ///
 /// Use a `Vec<T>` as an efficient stack:
@@ -125,17 +125,19 @@ use borrow::{Cow, IntoCow};
 ///
 /// # Capacity and reallocation
 ///
-/// The capacity of a vector is the amount of space allocated for any future elements that will be
-/// added onto the vector. This is not to be confused with the *length* of a vector, which
-/// specifies the number of actual elements within the vector. If a vector's length exceeds its
-/// capacity, its capacity will automatically be increased, but its elements will have to be
+/// The capacity of a vector is the amount of space allocated for any future
+/// elements that will be added onto the vector. This is not to be confused with
+/// the *length* of a vector, which specifies the number of actual elements
+/// within the vector. If a vector's length exceeds its capacity, its capacity
+/// will automatically be increased, but its elements will have to be
 /// reallocated.
 ///
-/// For example, a vector with capacity 10 and length 0 would be an empty vector with space for 10
-/// more elements. Pushing 10 or fewer elements onto the vector will not change its capacity or
-/// cause reallocation to occur. However, if the vector's length is increased to 11, it will have
-/// to reallocate, which can be slow. For this reason, it is recommended to use
-/// `Vec::with_capacity` whenever possible to specify how big the vector is expected to get.
+/// For example, a vector with capacity 10 and length 0 would be an empty vector
+/// with space for 10 more elements. Pushing 10 or fewer elements onto the
+/// vector will not change its capacity or cause reallocation to occur. However,
+/// if the vector's length is increased to 11, it will have to reallocate, which
+/// can be slow. For this reason, it is recommended to use `Vec::with_capacity`
+/// whenever possible to specify how big the vector is expected to get.
 #[unsafe_no_drop_flag]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Vec<T> {
@@ -242,7 +244,7 @@ impl<T> Vec<T> {
     ///
     ///         // Put everything back together into a Vec
     ///         let rebuilt = Vec::from_raw_parts(p, len, cap);
-    ///         assert_eq!(rebuilt, vec![4, 5, 6]);
+    ///         assert_eq!(rebuilt, [4, 5, 6]);
     ///     }
     /// }
     /// ```
@@ -258,16 +260,17 @@ impl<T> Vec<T> {
 
     /// Creates a vector by copying the elements from a raw pointer.
     ///
-    /// This function will copy `elts` contiguous elements starting at `ptr` into a new allocation
-    /// owned by the returned `Vec<T>`. The elements of the buffer are copied into the vector
-    /// without cloning, as if `ptr::read()` were called on them.
+    /// This function will copy `elts` contiguous elements starting at `ptr`
+    /// into a new allocation owned by the returned `Vec<T>`. The elements of
+    /// the buffer are copied into the vector without cloning, as if
+    /// `ptr::read()` were called on them.
     #[inline]
     #[unstable(feature = "collections",
                reason = "may be better expressed via composition")]
     pub unsafe fn from_raw_buf(ptr: *const T, elts: usize) -> Vec<T> {
         let mut dst = Vec::with_capacity(elts);
         dst.set_len(elts);
-        ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts);
+        ptr::copy_nonoverlapping(ptr, dst.as_mut_ptr(), elts);
         dst
     }
 
@@ -286,8 +289,9 @@ impl<T> Vec<T> {
         self.cap
     }
 
-    /// Reserves capacity for at least `additional` more elements to be inserted in the given
-    /// `Vec<T>`. The collection may reserve more space to avoid frequent reallocations.
+    /// Reserves capacity for at least `additional` more elements to be inserted
+    /// in the given `Vec<T>`. The collection may reserve more space to avoid
+    /// frequent reallocations.
     ///
     /// # Panics
     ///
@@ -347,6 +351,7 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut vec = Vec::with_capacity(10);
     /// vec.push_all(&[1, 2, 3]);
     /// assert_eq!(vec.capacity(), 10);
@@ -384,11 +389,11 @@ impl<T> Vec<T> {
     /// Note that this will drop any excess capacity. Calling this and
     /// converting back to a vector with `into_vec()` is equivalent to calling
     /// `shrink_to_fit()`.
-    #[unstable(feature = "collections")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_boxed_slice(mut self) -> Box<[T]> {
         self.shrink_to_fit();
         unsafe {
-            let xs: Box<[T]> = mem::transmute(&mut *self);
+            let xs: Box<[T]> = Box::from_raw(&mut *self);
             mem::forget(self);
             xs
         }
@@ -402,9 +407,10 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut vec = vec![1, 2, 3, 4];
     /// vec.truncate(2);
-    /// assert_eq!(vec, vec![1, 2]);
+    /// assert_eq!(vec, [1, 2]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn truncate(&mut self, len: usize) {
@@ -419,25 +425,20 @@ impl<T> Vec<T> {
         }
     }
 
-    /// Returns a mutable slice of the elements of `self`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// fn foo(slice: &mut [i32]) {}
-    ///
-    /// let mut vec = vec![1, 2];
-    /// foo(vec.as_mut_slice());
-    /// ```
+    /// Extract a slice containing the entire vector.
     #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
+    #[unstable(feature = "convert",
+               reason = "waiting on RFC revision")]
+    pub fn as_slice(&self) -> &[T] {
+        self
+    }
+
+    /// Deprecated: use `&mut s[..]` instead.
+    #[inline]
+    #[unstable(feature = "convert",
+               reason = "waiting on RFC revision")]
     pub fn as_mut_slice(&mut self) -> &mut [T] {
-        unsafe {
-            mem::transmute(RawSlice {
-                data: *self.ptr,
-                len: self.len,
-            })
-        }
+        &mut self[..]
     }
 
     /// Creates a consuming iterator, that is, one that moves each value out of
@@ -458,6 +459,7 @@ impl<T> Vec<T> {
     pub fn into_iter(self) -> IntoIter<T> {
         unsafe {
             let ptr = *self.ptr;
+            assume(!ptr.is_null());
             let cap = self.cap;
             let begin = ptr as *const T;
             let end = if mem::size_of::<T>() == 0 {
@@ -505,10 +507,10 @@ impl<T> Vec<T> {
     /// let mut v = vec!["foo", "bar", "baz", "qux"];
     ///
     /// assert_eq!(v.swap_remove(1), "bar");
-    /// assert_eq!(v, vec!["foo", "qux", "baz"]);
+    /// assert_eq!(v, ["foo", "qux", "baz"]);
     ///
     /// assert_eq!(v.swap_remove(0), "foo");
-    /// assert_eq!(v, vec!["baz", "qux"]);
+    /// assert_eq!(v, ["baz", "qux"]);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -531,9 +533,9 @@ impl<T> Vec<T> {
     /// ```
     /// let mut vec = vec![1, 2, 3];
     /// vec.insert(1, 4);
-    /// assert_eq!(vec, vec![1, 4, 2, 3]);
+    /// assert_eq!(vec, [1, 4, 2, 3]);
     /// vec.insert(4, 5);
-    /// assert_eq!(vec, vec![1, 4, 2, 3, 5]);
+    /// assert_eq!(vec, [1, 4, 2, 3, 5]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn insert(&mut self, index: usize, element: T) {
@@ -548,7 +550,7 @@ impl<T> Vec<T> {
                 let p = self.as_mut_ptr().offset(index as isize);
                 // Shift everything over to make space. (Duplicating the
                 // `index`th element into two consecutive places.)
-                ptr::copy_memory(p.offset(1), &*p, len - index);
+                ptr::copy(&*p, p.offset(1), len - index);
                 // Write it in, overwriting the first copy of the `index`th
                 // element.
                 ptr::write(&mut *p, element);
@@ -567,9 +569,10 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut v = vec![1, 2, 3];
     /// assert_eq!(v.remove(1), 2);
-    /// assert_eq!(v, vec![1, 3]);
+    /// assert_eq!(v, [1, 3]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove(&mut self, index: usize) -> T {
@@ -585,7 +588,7 @@ impl<T> Vec<T> {
                 ret = ptr::read(ptr);
 
                 // Shift everything down to fill in that spot.
-                ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1);
+                ptr::copy(&*ptr.offset(1), ptr, len - index - 1);
             }
             self.set_len(len - 1);
             ret
@@ -603,7 +606,7 @@ impl<T> Vec<T> {
     /// ```
     /// let mut vec = vec![1, 2, 3, 4];
     /// vec.retain(|&x| x%2 == 0);
-    /// assert_eq!(vec, vec![2, 4]);
+    /// assert_eq!(vec, [2, 4]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn retain<F>(&mut self, mut f: F) where F: FnMut(&T) -> bool {
@@ -633,14 +636,28 @@ impl<T> Vec<T> {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let mut vec = vec!(1, 2);
     /// vec.push(3);
-    /// assert_eq!(vec, vec!(1, 2, 3));
+    /// assert_eq!(vec, [1, 2, 3]);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn push(&mut self, value: T) {
+        #[cold]
+        #[inline(never)]
+        fn resize<T>(vec: &mut Vec<T>) {
+            let old_size = vec.cap * mem::size_of::<T>();
+            let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
+            if old_size > size { panic!("capacity overflow") }
+            unsafe {
+                let ptr = alloc_or_realloc(*vec.ptr, old_size, size);
+                if ptr.is_null() { ::alloc::oom() }
+                vec.ptr = Unique::new(ptr);
+            }
+            vec.cap = max(vec.cap, 2) * 2;
+        }
+
         if mem::size_of::<T>() == 0 {
             // zero-size types consume no memory, so we can't rely on the
             // address space running out
@@ -648,16 +665,9 @@ impl<T> Vec<T> {
             unsafe { mem::forget(value); }
             return
         }
+
         if self.len == self.cap {
-            let old_size = self.cap * mem::size_of::<T>();
-            let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
-            if old_size > size { panic!("capacity overflow") }
-            unsafe {
-                let ptr = alloc_or_realloc(*self.ptr, old_size, size);
-                if ptr.is_null() { ::alloc::oom() }
-                self.ptr = Unique::new(ptr);
-            }
-            self.cap = max(self.cap, 2) * 2;
+            resize(self);
         }
 
         unsafe {
@@ -671,10 +681,10 @@ impl<T> Vec<T> {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let mut vec = vec![1, 2, 3];
     /// assert_eq!(vec.pop(), Some(3));
-    /// assert_eq!(vec, vec![1, 2]);
+    /// assert_eq!(vec, [1, 2]);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -698,11 +708,12 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut vec = vec![1, 2, 3];
     /// let mut vec2 = vec![4, 5, 6];
     /// vec.append(&mut vec2);
-    /// assert_eq!(vec, vec![1, 2, 3, 4, 5, 6]);
-    /// assert_eq!(vec2, vec![]);
+    /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+    /// assert_eq!(vec2, []);
     /// ```
     #[inline]
     #[unstable(feature = "collections",
@@ -718,9 +729,9 @@ impl<T> Vec<T> {
         self.reserve(other.len());
         let len = self.len();
         unsafe {
-            ptr::copy_nonoverlapping_memory(
-                self.get_unchecked_mut(len),
+            ptr::copy_nonoverlapping(
                 other.as_ptr(),
+                self.get_unchecked_mut(len),
                 other.len());
         }
 
@@ -734,6 +745,7 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut v = vec!["a".to_string(), "b".to_string()];
     /// for s in v.drain() {
     ///     // s has type String, not &String
@@ -815,15 +827,16 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections, core)]
     /// let v = vec![0, 1, 2];
     /// let w = v.map_in_place(|i| i + 3);
-    /// assert_eq!(w.as_slice(), [3, 4, 5].as_slice());
+    /// assert_eq!(&w[..], &[3, 4, 5]);
     ///
     /// #[derive(PartialEq, Debug)]
     /// struct Newtype(u8);
     /// let bytes = vec![0x11, 0x22];
     /// let newtyped_bytes = bytes.map_in_place(|x| Newtype(x));
-    /// assert_eq!(newtyped_bytes.as_slice(), [Newtype(0x11), Newtype(0x22)].as_slice());
+    /// assert_eq!(&newtyped_bytes[..], &[Newtype(0x11), Newtype(0x22)]);
     /// ```
     #[unstable(feature = "collections",
                reason = "API may change to provide stronger guarantees")]
@@ -1017,10 +1030,11 @@ impl<T> Vec<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut vec = vec![1,2,3];
     /// let vec2 = vec.split_off(1);
-    /// assert_eq!(vec, vec![1]);
-    /// assert_eq!(vec2, vec![2, 3]);
+    /// assert_eq!(vec, [1]);
+    /// assert_eq!(vec2, [2, 3]);
     /// ```
     #[inline]
     #[unstable(feature = "collections",
@@ -1036,9 +1050,9 @@ impl<T> Vec<T> {
             self.set_len(at);
             other.set_len(other_len);
 
-            ptr::copy_nonoverlapping_memory(
-                other.as_mut_ptr(),
+            ptr::copy_nonoverlapping(
                 self.as_ptr().offset(at as isize),
+                other.as_mut_ptr(),
                 other.len());
         }
         other
@@ -1055,13 +1069,14 @@ impl<T: Clone> Vec<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut vec = vec!["hello"];
     /// vec.resize(3, "world");
-    /// assert_eq!(vec, vec!["hello", "world", "world"]);
+    /// assert_eq!(vec, ["hello", "world", "world"]);
     ///
     /// let mut vec = vec![1, 2, 3, 4];
     /// vec.resize(2, 0);
-    /// assert_eq!(vec, vec![1, 2]);
+    /// assert_eq!(vec, [1, 2]);
     /// ```
     #[unstable(feature = "collections",
                reason = "matches collection reform specification; waiting for dust to settle")]
@@ -1083,9 +1098,10 @@ impl<T: Clone> Vec<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// let mut vec = vec![1];
     /// vec.push_all(&[2, 3, 4]);
-    /// assert_eq!(vec, vec![1, 2, 3, 4]);
+    /// assert_eq!(vec, [1, 2, 3, 4]);
     /// ```
     #[inline]
     #[unstable(feature = "collections",
@@ -1121,7 +1137,7 @@ impl<T: PartialEq> Vec<T> {
     ///
     /// vec.dedup();
     ///
-    /// assert_eq!(vec, vec![1, 2, 3, 2]);
+    /// assert_eq!(vec, [1, 2, 3, 2]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn dedup(&mut self) {
@@ -1188,8 +1204,8 @@ impl<T: PartialEq> Vec<T> {
 
             // Avoid bounds checks by using unsafe pointers.
             let p = self.as_mut_ptr();
-            let mut r = 1;
-            let mut w = 1;
+            let mut r: usize = 1;
+            let mut w: usize = 1;
 
             while r < ln {
                 let p_r = p.offset(r as isize);
@@ -1283,7 +1299,17 @@ pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> {
 
 #[unstable(feature = "collections")]
 impl<T:Clone> Clone for Vec<T> {
-    fn clone(&self) -> Vec<T> { ::slice::SliceExt::to_vec(&**self) }
+    #[cfg(not(test))]
+    fn clone(&self) -> Vec<T> { <[T]>::to_vec(&**self) }
+
+    // HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is
+    // required for this method definition, is not available. Instead use the
+    // `slice::to_vec`  function which is only available with cfg(test)
+    // NB see the slice::hack module in slice.rs for more information
+    #[cfg(test)]
+    fn clone(&self) -> Vec<T> {
+        ::slice::to_vec(&**self)
+    }
 
     fn clone_from(&mut self, other: &Vec<T>) {
         // drop anything in self that will not be overwritten
@@ -1303,15 +1329,7 @@ impl<T:Clone> Clone for Vec<T> {
     }
 }
 
-#[cfg(stage0)]
-impl<S: hash::Writer + hash::Hasher, T: Hash<S>> Hash<S> for Vec<T> {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        Hash::hash(&**self, state)
-    }
-}
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg(not(stage0))]
 impl<T: Hash> Hash for Vec<T> {
     #[inline]
     fn hash<H: hash::Hasher>(&self, state: &mut H) {
@@ -1324,18 +1342,18 @@ impl<T> Index<usize> for Vec<T> {
     type Output = T;
 
     #[inline]
-    fn index(&self, index: &usize) -> &T {
+    fn index(&self, index: usize) -> &T {
         // NB built-in indexing via `&[T]`
-        &(**self)[*index]
+        &(**self)[index]
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> IndexMut<usize> for Vec<T> {
     #[inline]
-    fn index_mut(&mut self, index: &usize) -> &mut T {
+    fn index_mut(&mut self, index: usize) -> &mut T {
         // NB built-in indexing via `&mut [T]`
-        &mut (**self)[*index]
+        &mut (**self)[index]
     }
 }
 
@@ -1343,62 +1361,70 @@ impl<T> IndexMut<usize> for Vec<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::Range<usize>> for Vec<T> {
     type Output = [T];
+
     #[inline]
-    fn index(&self, index: &ops::Range<usize>) -> &[T] {
+    fn index(&self, index: ops::Range<usize>) -> &[T] {
         Index::index(&**self, index)
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::RangeTo<usize>> for Vec<T> {
     type Output = [T];
+
     #[inline]
-    fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
+    fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
         Index::index(&**self, index)
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::RangeFrom<usize>> for Vec<T> {
     type Output = [T];
+
     #[inline]
-    fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
+    fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
         Index::index(&**self, index)
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::RangeFull> for Vec<T> {
     type Output = [T];
+
     #[inline]
-    fn index(&self, _index: &ops::RangeFull) -> &[T] {
-        self.as_slice()
+    fn index(&self, _index: ops::RangeFull) -> &[T] {
+        self
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::Range<usize>> for Vec<T> {
+
     #[inline]
-    fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] {
+    fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
         IndexMut::index_mut(&mut **self, index)
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::RangeTo<usize>> for Vec<T> {
+
     #[inline]
-    fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] {
+    fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
         IndexMut::index_mut(&mut **self, index)
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::RangeFrom<usize>> for Vec<T> {
+
     #[inline]
-    fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] {
+    fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
         IndexMut::index_mut(&mut **self, index)
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::RangeFull> for Vec<T> {
+
     #[inline]
-    fn index_mut(&mut self, _index: &ops::RangeFull) -> &mut [T] {
-        self.as_mut_slice()
+    fn index_mut(&mut self, _index: ops::RangeFull) -> &mut [T] {
+        self
     }
 }
 
@@ -1406,12 +1432,24 @@ impl<T> ops::IndexMut<ops::RangeFull> for Vec<T> {
 impl<T> ops::Deref for Vec<T> {
     type Target = [T];
 
-    fn deref(&self) -> &[T] { self.as_slice() }
+    fn deref(&self) -> &[T] {
+        unsafe {
+            let p = *self.ptr;
+            assume(p != 0 as *mut T);
+            slice::from_raw_parts(p, self.len)
+        }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::DerefMut for Vec<T> {
-    fn deref_mut(&mut self) -> &mut [T] { self.as_mut_slice() }
+    fn deref_mut(&mut self) -> &mut [T] {
+        unsafe {
+            let ptr = *self.ptr;
+            assume(!ptr.is_null());
+            slice::from_raw_parts_mut(ptr, self.len)
+        }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1501,69 +1539,34 @@ impl<T> Extend<T> for Vec<T> {
     }
 }
 
-impl<A, B> PartialEq<Vec<B>> for Vec<A> where A: PartialEq<B> {
-    #[inline]
-    fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
-    #[inline]
-    fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
-}
-
-macro_rules! impl_eq {
-    ($lhs:ty, $rhs:ty) => {
-        impl<'b, A, B> PartialEq<$rhs> for $lhs where A: PartialEq<B> {
-            #[inline]
-            fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
-            #[inline]
-            fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
-        }
-
-        impl<'b, A, B> PartialEq<$lhs> for $rhs where B: PartialEq<A> {
-            #[inline]
-            fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
-            #[inline]
-            fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
-        }
+__impl_slice_eq1! { Vec<A>, Vec<B> }
+__impl_slice_eq1! { Vec<A>, &'b [B] }
+__impl_slice_eq1! { Vec<A>, &'b mut [B] }
+__impl_slice_eq1! { Cow<'a, [A]>, &'b [B], Clone }
+__impl_slice_eq1! { Cow<'a, [A]>, &'b mut [B], Clone }
+__impl_slice_eq1! { Cow<'a, [A]>, Vec<B>, Clone }
+
+macro_rules! array_impls {
+    ($($N: expr)+) => {
+        $(
+            // NOTE: some less important impls are omitted to reduce code bloat
+            __impl_slice_eq1! { Vec<A>, [B; $N] }
+            __impl_slice_eq1! { Vec<A>, &'b [B; $N] }
+            // __impl_slice_eq1! { Vec<A>, &'b mut [B; $N] }
+            // __impl_slice_eq1! { Cow<'a, [A]>, [B; $N], Clone }
+            // __impl_slice_eq1! { Cow<'a, [A]>, &'b [B; $N], Clone }
+            // __impl_slice_eq1! { Cow<'a, [A]>, &'b mut [B; $N], Clone }
+        )+
     }
 }
 
-impl_eq! { Vec<A>, &'b [B] }
-impl_eq! { Vec<A>, &'b mut [B] }
-
-impl<'a, A, B> PartialEq<Vec<B>> for Cow<'a, [A]> where A: PartialEq<B> + Clone {
-    #[inline]
-    fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
-    #[inline]
-    fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
-}
-
-impl<'a, A, B> PartialEq<Cow<'a, [A]>> for Vec<B> where A: Clone, B: PartialEq<A> {
-    #[inline]
-    fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) }
-    #[inline]
-    fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) }
-}
-
-macro_rules! impl_eq_for_cowvec {
-    ($rhs:ty) => {
-        impl<'a, 'b, A, B> PartialEq<$rhs> for Cow<'a, [A]> where A: PartialEq<B> + Clone {
-            #[inline]
-            fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
-            #[inline]
-            fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
-        }
-
-        impl<'a, 'b, A, B> PartialEq<Cow<'a, [A]>> for $rhs where A: Clone, B: PartialEq<A> {
-            #[inline]
-            fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) }
-            #[inline]
-            fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) }
-        }
-    }
+array_impls! {
+     0  1  2  3  4  5  6  7  8  9
+    10 11 12 13 14 15 16 17 18 19
+    20 21 22 23 24 25 26 27 28 29
+    30 31 32
 }
 
-impl_eq_for_cowvec! { &'b [B] }
-impl_eq_for_cowvec! { &'b mut [B] }
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: PartialOrd> PartialOrd for Vec<T> {
     #[inline]
@@ -1583,30 +1586,15 @@ impl<T: Ord> Ord for Vec<T> {
     }
 }
 
+#[unstable(feature = "collections",
+           reason = "will be replaced by slice syntax")]
+#[deprecated(since = "1.0.0", reason = "use &mut s[..] instead")]
+#[allow(deprecated)]
 impl<T> AsSlice<T> for Vec<T> {
-    /// Returns a slice into `self`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// fn foo(slice: &[i32]) {}
-    ///
-    /// let vec = vec![1, 2];
-    /// foo(vec.as_slice());
-    /// ```
+    /// Deprecated: use `&mut s[..]` instead.
     #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn as_slice(&self) -> &[T] {
-        unsafe {
-            let p = *self.ptr;
-            if cfg!(not(stage0)) { // NOTE remove cfg after next snapshot
-                assume(p != 0 as *mut T);
-            }
-            mem::transmute(RawSlice {
-                data: p,
-                len: self.len
-            })
-        }
+        self
     }
 }
 
@@ -1628,7 +1616,7 @@ impl<T> Drop for Vec<T> {
     fn drop(&mut self) {
         // This is (and should always remain) a no-op if the fields are
         // zeroed (when moving out, because of #[unsafe_no_drop_flag]).
-        if self.cap != 0 {
+        if self.cap != 0 && self.cap != mem::POST_DROP_USIZE {
             unsafe {
                 for x in &*self {
                     ptr::read(x);
@@ -1654,15 +1642,43 @@ impl<T: fmt::Debug> fmt::Debug for Vec<T> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> AsRef<Vec<T>> for Vec<T> {
+    fn as_ref(&self) -> &Vec<T> {
+        self
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> AsRef<[T]> for Vec<T> {
+    fn as_ref(&self) -> &[T] {
+        self
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: Clone> From<&'a [T]> for Vec<T> {
+    #[cfg(not(test))]
+    fn from(s: &'a [T]) -> Vec<T> {
+        s.to_vec()
+    }
+    #[cfg(test)]
+    fn from(s: &'a [T]) -> Vec<T> {
+        ::slice::to_vec(s)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> From<&'a str> for Vec<u8> {
+    fn from(s: &'a str) -> Vec<u8> {
+        From::from(s.as_bytes())
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Clone-on-write
 ////////////////////////////////////////////////////////////////////////////////
 
-/// A clone-on-write vector
-#[deprecated(since = "1.0.0", reason = "use Cow<'a, [T]> instead")]
-#[unstable(feature = "collections")]
-pub type CowVec<'a, T> = Cow<'a, [T]>;
-
 #[unstable(feature = "collections")]
 impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
     fn from_iter<I: IntoIterator<Item=T>>(it: I) -> Cow<'a, [T]> {
@@ -1800,6 +1816,9 @@ pub struct Drain<'a, T:'a> {
     marker: PhantomData<&'a T>,
 }
 
+unsafe impl<'a, T: Sync> Sync for Drain<'a, T> {}
+unsafe impl<'a, T: Send> Send for Drain<'a, T> {}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Iterator for Drain<'a, T> {
     type Item = T;
@@ -1868,7 +1887,7 @@ impl<'a, T> ExactSizeIterator for Drain<'a, T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Drop for Drain<'a, T> {
     fn drop(&mut self) {
-        // self.ptr == self.end == null if drop has already been called,
+        // self.ptr == self.end == mem::POST_DROP_USIZE if drop has already been called,
         // so we can use #[unsafe_no_drop_flag].
 
         // destroy the remaining elements
@@ -1992,991 +2011,3 @@ impl<T,U> Drop for PartialVecZeroSized<T,U> {
         }
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use core::mem::size_of;
-    use core::iter::repeat;
-    use test::Bencher;
-    use super::as_vec;
-
-    struct DropCounter<'a> {
-        count: &'a mut u32
-    }
-
-    #[unsafe_destructor]
-    impl<'a> Drop for DropCounter<'a> {
-        fn drop(&mut self) {
-            *self.count += 1;
-        }
-    }
-
-    #[test]
-    fn test_as_vec() {
-        let xs = [1u8, 2u8, 3u8];
-        assert_eq!(&**as_vec(&xs), xs);
-    }
-
-    #[test]
-    fn test_as_vec_dtor() {
-        let (mut count_x, mut count_y) = (0, 0);
-        {
-            let xs = &[DropCounter { count: &mut count_x }, DropCounter { count: &mut count_y }];
-            assert_eq!(as_vec(xs).len(), 2);
-        }
-        assert_eq!(count_x, 1);
-        assert_eq!(count_y, 1);
-    }
-
-    #[test]
-    fn test_small_vec_struct() {
-        assert!(size_of::<Vec<u8>>() == size_of::<usize>() * 3);
-    }
-
-    #[test]
-    fn test_double_drop() {
-        struct TwoVec<T> {
-            x: Vec<T>,
-            y: Vec<T>
-        }
-
-        let (mut count_x, mut count_y) = (0, 0);
-        {
-            let mut tv = TwoVec {
-                x: Vec::new(),
-                y: Vec::new()
-            };
-            tv.x.push(DropCounter {count: &mut count_x});
-            tv.y.push(DropCounter {count: &mut count_y});
-
-            // If Vec had a drop flag, here is where it would be zeroed.
-            // Instead, it should rely on its internal state to prevent
-            // doing anything significant when dropped multiple times.
-            drop(tv.x);
-
-            // Here tv goes out of scope, tv.y should be dropped, but not tv.x.
-        }
-
-        assert_eq!(count_x, 1);
-        assert_eq!(count_y, 1);
-    }
-
-    #[test]
-    fn test_reserve() {
-        let mut v = Vec::new();
-        assert_eq!(v.capacity(), 0);
-
-        v.reserve(2);
-        assert!(v.capacity() >= 2);
-
-        for i in 0..16 {
-            v.push(i);
-        }
-
-        assert!(v.capacity() >= 16);
-        v.reserve(16);
-        assert!(v.capacity() >= 32);
-
-        v.push(16);
-
-        v.reserve(16);
-        assert!(v.capacity() >= 33)
-    }
-
-    #[test]
-    fn test_extend() {
-        let mut v = Vec::new();
-        let mut w = Vec::new();
-
-        v.extend(0..3);
-        for i in 0..3 { w.push(i) }
-
-        assert_eq!(v, w);
-
-        v.extend(3..10);
-        for i in 3..10 { w.push(i) }
-
-        assert_eq!(v, w);
-    }
-
-    #[test]
-    fn test_slice_from_mut() {
-        let mut values = vec![1, 2, 3, 4, 5];
-        {
-            let slice = &mut values[2 ..];
-            assert!(slice == [3, 4, 5]);
-            for p in slice {
-                *p += 2;
-            }
-        }
-
-        assert!(values == [1, 2, 5, 6, 7]);
-    }
-
-    #[test]
-    fn test_slice_to_mut() {
-        let mut values = vec![1, 2, 3, 4, 5];
-        {
-            let slice = &mut values[.. 2];
-            assert!(slice == [1, 2]);
-            for p in slice {
-                *p += 1;
-            }
-        }
-
-        assert!(values == [2, 3, 3, 4, 5]);
-    }
-
-    #[test]
-    fn test_split_at_mut() {
-        let mut values = vec![1, 2, 3, 4, 5];
-        {
-            let (left, right) = values.split_at_mut(2);
-            {
-                let left: &[_] = left;
-                assert!(&left[..left.len()] == &[1, 2][]);
-            }
-            for p in left {
-                *p += 1;
-            }
-
-            {
-                let right: &[_] = right;
-                assert!(&right[..right.len()] == &[3, 4, 5][]);
-            }
-            for p in right {
-                *p += 2;
-            }
-        }
-
-        assert!(values == vec![2, 3, 5, 6, 7]);
-    }
-
-    #[test]
-    fn test_clone() {
-        let v: Vec<i32> = vec![];
-        let w = vec!(1, 2, 3);
-
-        assert_eq!(v, v.clone());
-
-        let z = w.clone();
-        assert_eq!(w, z);
-        // they should be disjoint in memory.
-        assert!(w.as_ptr() != z.as_ptr())
-    }
-
-    #[test]
-    fn test_clone_from() {
-        let mut v = vec!();
-        let three = vec!(box 1, box 2, box 3);
-        let two = vec!(box 4, box 5);
-        // zero, long
-        v.clone_from(&three);
-        assert_eq!(v, three);
-
-        // equal
-        v.clone_from(&three);
-        assert_eq!(v, three);
-
-        // long, short
-        v.clone_from(&two);
-        assert_eq!(v, two);
-
-        // short, long
-        v.clone_from(&three);
-        assert_eq!(v, three)
-    }
-
-    #[test]
-    fn test_retain() {
-        let mut vec = vec![1, 2, 3, 4];
-        vec.retain(|&x| x % 2 == 0);
-        assert!(vec == vec![2, 4]);
-    }
-
-    #[test]
-    fn zero_sized_values() {
-        let mut v = Vec::new();
-        assert_eq!(v.len(), 0);
-        v.push(());
-        assert_eq!(v.len(), 1);
-        v.push(());
-        assert_eq!(v.len(), 2);
-        assert_eq!(v.pop(), Some(()));
-        assert_eq!(v.pop(), Some(()));
-        assert_eq!(v.pop(), None);
-
-        assert_eq!(v.iter().count(), 0);
-        v.push(());
-        assert_eq!(v.iter().count(), 1);
-        v.push(());
-        assert_eq!(v.iter().count(), 2);
-
-        for &() in &v {}
-
-        assert_eq!(v.iter_mut().count(), 2);
-        v.push(());
-        assert_eq!(v.iter_mut().count(), 3);
-        v.push(());
-        assert_eq!(v.iter_mut().count(), 4);
-
-        for &mut () in &mut v {}
-        unsafe { v.set_len(0); }
-        assert_eq!(v.iter_mut().count(), 0);
-    }
-
-    #[test]
-    fn test_partition() {
-        assert_eq!(vec![].into_iter().partition(|x: &i32| *x < 3), (vec![], vec![]));
-        assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 4), (vec![1, 2, 3], vec![]));
-        assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 2), (vec![1], vec![2, 3]));
-        assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 0), (vec![], vec![1, 2, 3]));
-    }
-
-    #[test]
-    fn test_zip_unzip() {
-        let z1 = vec![(1, 4), (2, 5), (3, 6)];
-
-        let (left, right): (Vec<_>, Vec<_>) = z1.iter().cloned().unzip();
-
-        assert_eq!((1, 4), (left[0], right[0]));
-        assert_eq!((2, 5), (left[1], right[1]));
-        assert_eq!((3, 6), (left[2], right[2]));
-    }
-
-    #[test]
-    fn test_unsafe_ptrs() {
-        unsafe {
-            // Test on-stack copy-from-buf.
-            let a = [1, 2, 3];
-            let ptr = a.as_ptr();
-            let b = Vec::from_raw_buf(ptr, 3);
-            assert_eq!(b, vec![1, 2, 3]);
-
-            // Test on-heap copy-from-buf.
-            let c = vec![1, 2, 3, 4, 5];
-            let ptr = c.as_ptr();
-            let d = Vec::from_raw_buf(ptr, 5);
-            assert_eq!(d, vec![1, 2, 3, 4, 5]);
-        }
-    }
-
-    #[test]
-    fn test_vec_truncate_drop() {
-        static mut drops: u32 = 0;
-        struct Elem(i32);
-        impl Drop for Elem {
-            fn drop(&mut self) {
-                unsafe { drops += 1; }
-            }
-        }
-
-        let mut v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
-        assert_eq!(unsafe { drops }, 0);
-        v.truncate(3);
-        assert_eq!(unsafe { drops }, 2);
-        v.truncate(0);
-        assert_eq!(unsafe { drops }, 5);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_vec_truncate_fail() {
-        struct BadElem(i32);
-        impl Drop for BadElem {
-            fn drop(&mut self) {
-                let BadElem(ref mut x) = *self;
-                if *x == 0xbadbeef {
-                    panic!("BadElem panic: 0xbadbeef")
-                }
-            }
-        }
-
-        let mut v = vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
-        v.truncate(0);
-    }
-
-    #[test]
-    fn test_index() {
-        let vec = vec![1, 2, 3];
-        assert!(vec[1] == 2);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_index_out_of_bounds() {
-        let vec = vec![1, 2, 3];
-        let _ = vec[3];
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_slice_out_of_bounds_1() {
-        let x = vec![1, 2, 3, 4, 5];
-        &x[-1..];
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_slice_out_of_bounds_2() {
-        let x = vec![1, 2, 3, 4, 5];
-        &x[..6];
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_slice_out_of_bounds_3() {
-        let x = vec![1, 2, 3, 4, 5];
-        &x[-1..4];
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_slice_out_of_bounds_4() {
-        let x = vec![1, 2, 3, 4, 5];
-        &x[1..6];
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_slice_out_of_bounds_5() {
-        let x = vec![1, 2, 3, 4, 5];
-        &x[3..2];
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_swap_remove_empty() {
-        let mut vec= Vec::<i32>::new();
-        vec.swap_remove(0);
-    }
-
-    #[test]
-    fn test_move_iter_unwrap() {
-        let mut vec = Vec::with_capacity(7);
-        vec.push(1);
-        vec.push(2);
-        let ptr = vec.as_ptr();
-        vec = vec.into_iter().into_inner();
-        assert_eq!(vec.as_ptr(), ptr);
-        assert_eq!(vec.capacity(), 7);
-        assert_eq!(vec.len(), 0);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_map_in_place_incompatible_types_fail() {
-        let v = vec![0, 1, 2];
-        v.map_in_place(|_| ());
-    }
-
-    #[test]
-    fn test_map_in_place() {
-        let v = vec![0, 1, 2];
-        assert_eq!(v.map_in_place(|i: u32| i as i32 - 1), [-1, 0, 1]);
-    }
-
-    #[test]
-    fn test_map_in_place_zero_sized() {
-        let v = vec![(), ()];
-        #[derive(PartialEq, Debug)]
-        struct ZeroSized;
-        assert_eq!(v.map_in_place(|_| ZeroSized), [ZeroSized, ZeroSized]);
-    }
-
-    #[test]
-    fn test_map_in_place_zero_drop_count() {
-        use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
-
-        #[derive(Clone, PartialEq, Debug)]
-        struct Nothing;
-        impl Drop for Nothing { fn drop(&mut self) { } }
-
-        #[derive(Clone, PartialEq, Debug)]
-        struct ZeroSized;
-        impl Drop for ZeroSized {
-            fn drop(&mut self) {
-                DROP_COUNTER.fetch_add(1, Ordering::Relaxed);
-            }
-        }
-        const NUM_ELEMENTS: usize = 2;
-        static DROP_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
-
-        let v = repeat(Nothing).take(NUM_ELEMENTS).collect::<Vec<_>>();
-
-        DROP_COUNTER.store(0, Ordering::Relaxed);
-
-        let v = v.map_in_place(|_| ZeroSized);
-        assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
-        drop(v);
-        assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), NUM_ELEMENTS);
-    }
-
-    #[test]
-    fn test_move_items() {
-        let vec = vec![1, 2, 3];
-        let mut vec2 = vec![];
-        for i in vec {
-            vec2.push(i);
-        }
-        assert!(vec2 == vec![1, 2, 3]);
-    }
-
-    #[test]
-    fn test_move_items_reverse() {
-        let vec = vec![1, 2, 3];
-        let mut vec2 = vec![];
-        for i in vec.into_iter().rev() {
-            vec2.push(i);
-        }
-        assert!(vec2 == vec![3, 2, 1]);
-    }
-
-    #[test]
-    fn test_move_items_zero_sized() {
-        let vec = vec![(), (), ()];
-        let mut vec2 = vec![];
-        for i in vec {
-            vec2.push(i);
-        }
-        assert!(vec2 == vec![(), (), ()]);
-    }
-
-    #[test]
-    fn test_drain_items() {
-        let mut vec = vec![1, 2, 3];
-        let mut vec2 = vec![];
-        for i in vec.drain() {
-            vec2.push(i);
-        }
-        assert_eq!(vec, []);
-        assert_eq!(vec2, [ 1, 2, 3 ]);
-    }
-
-    #[test]
-    fn test_drain_items_reverse() {
-        let mut vec = vec![1, 2, 3];
-        let mut vec2 = vec![];
-        for i in vec.drain().rev() {
-            vec2.push(i);
-        }
-        assert_eq!(vec, []);
-        assert_eq!(vec2, [3, 2, 1]);
-    }
-
-    #[test]
-    fn test_drain_items_zero_sized() {
-        let mut vec = vec![(), (), ()];
-        let mut vec2 = vec![];
-        for i in vec.drain() {
-            vec2.push(i);
-        }
-        assert_eq!(vec, []);
-        assert_eq!(vec2, [(), (), ()]);
-    }
-
-    #[test]
-    fn test_into_boxed_slice() {
-        let xs = vec![1, 2, 3];
-        let ys = xs.into_boxed_slice();
-        assert_eq!(ys, [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_append() {
-        let mut vec = vec![1, 2, 3];
-        let mut vec2 = vec![4, 5, 6];
-        vec.append(&mut vec2);
-        assert_eq!(vec, vec![1, 2, 3, 4, 5, 6]);
-        assert_eq!(vec2, vec![]);
-    }
-
-    #[test]
-    fn test_split_off() {
-        let mut vec = vec![1, 2, 3, 4, 5, 6];
-        let vec2 = vec.split_off(4);
-        assert_eq!(vec, vec![1, 2, 3, 4]);
-        assert_eq!(vec2, vec![5, 6]);
-    }
-
-    #[bench]
-    fn bench_new(b: &mut Bencher) {
-        b.iter(|| {
-            let v: Vec<u32> = Vec::new();
-            assert_eq!(v.len(), 0);
-            assert_eq!(v.capacity(), 0);
-        })
-    }
-
-    fn do_bench_with_capacity(b: &mut Bencher, src_len: usize) {
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let v: Vec<u32> = Vec::with_capacity(src_len);
-            assert_eq!(v.len(), 0);
-            assert_eq!(v.capacity(), src_len);
-        })
-    }
-
-    #[bench]
-    fn bench_with_capacity_0000(b: &mut Bencher) {
-        do_bench_with_capacity(b, 0)
-    }
-
-    #[bench]
-    fn bench_with_capacity_0010(b: &mut Bencher) {
-        do_bench_with_capacity(b, 10)
-    }
-
-    #[bench]
-    fn bench_with_capacity_0100(b: &mut Bencher) {
-        do_bench_with_capacity(b, 100)
-    }
-
-    #[bench]
-    fn bench_with_capacity_1000(b: &mut Bencher) {
-        do_bench_with_capacity(b, 1000)
-    }
-
-    fn do_bench_from_fn(b: &mut Bencher, src_len: usize) {
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let dst = (0..src_len).collect::<Vec<_>>();
-            assert_eq!(dst.len(), src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        })
-    }
-
-    #[bench]
-    fn bench_from_fn_0000(b: &mut Bencher) {
-        do_bench_from_fn(b, 0)
-    }
-
-    #[bench]
-    fn bench_from_fn_0010(b: &mut Bencher) {
-        do_bench_from_fn(b, 10)
-    }
-
-    #[bench]
-    fn bench_from_fn_0100(b: &mut Bencher) {
-        do_bench_from_fn(b, 100)
-    }
-
-    #[bench]
-    fn bench_from_fn_1000(b: &mut Bencher) {
-        do_bench_from_fn(b, 1000)
-    }
-
-    fn do_bench_from_elem(b: &mut Bencher, src_len: usize) {
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let dst: Vec<usize> = repeat(5).take(src_len).collect();
-            assert_eq!(dst.len(), src_len);
-            assert!(dst.iter().all(|x| *x == 5));
-        })
-    }
-
-    #[bench]
-    fn bench_from_elem_0000(b: &mut Bencher) {
-        do_bench_from_elem(b, 0)
-    }
-
-    #[bench]
-    fn bench_from_elem_0010(b: &mut Bencher) {
-        do_bench_from_elem(b, 10)
-    }
-
-    #[bench]
-    fn bench_from_elem_0100(b: &mut Bencher) {
-        do_bench_from_elem(b, 100)
-    }
-
-    #[bench]
-    fn bench_from_elem_1000(b: &mut Bencher) {
-        do_bench_from_elem(b, 1000)
-    }
-
-    fn do_bench_from_slice(b: &mut Bencher, src_len: usize) {
-        let src: Vec<_> = FromIterator::from_iter(0..src_len);
-
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let dst = src.clone()[..].to_vec();
-            assert_eq!(dst.len(), src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        });
-    }
-
-    #[bench]
-    fn bench_from_slice_0000(b: &mut Bencher) {
-        do_bench_from_slice(b, 0)
-    }
-
-    #[bench]
-    fn bench_from_slice_0010(b: &mut Bencher) {
-        do_bench_from_slice(b, 10)
-    }
-
-    #[bench]
-    fn bench_from_slice_0100(b: &mut Bencher) {
-        do_bench_from_slice(b, 100)
-    }
-
-    #[bench]
-    fn bench_from_slice_1000(b: &mut Bencher) {
-        do_bench_from_slice(b, 1000)
-    }
-
-    fn do_bench_from_iter(b: &mut Bencher, src_len: usize) {
-        let src: Vec<_> = FromIterator::from_iter(0..src_len);
-
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let dst: Vec<_> = FromIterator::from_iter(src.clone().into_iter());
-            assert_eq!(dst.len(), src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        });
-    }
-
-    #[bench]
-    fn bench_from_iter_0000(b: &mut Bencher) {
-        do_bench_from_iter(b, 0)
-    }
-
-    #[bench]
-    fn bench_from_iter_0010(b: &mut Bencher) {
-        do_bench_from_iter(b, 10)
-    }
-
-    #[bench]
-    fn bench_from_iter_0100(b: &mut Bencher) {
-        do_bench_from_iter(b, 100)
-    }
-
-    #[bench]
-    fn bench_from_iter_1000(b: &mut Bencher) {
-        do_bench_from_iter(b, 1000)
-    }
-
-    fn do_bench_extend(b: &mut Bencher, dst_len: usize, src_len: usize) {
-        let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
-        let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
-
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let mut dst = dst.clone();
-            dst.extend(src.clone().into_iter());
-            assert_eq!(dst.len(), dst_len + src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        });
-    }
-
-    #[bench]
-    fn bench_extend_0000_0000(b: &mut Bencher) {
-        do_bench_extend(b, 0, 0)
-    }
-
-    #[bench]
-    fn bench_extend_0000_0010(b: &mut Bencher) {
-        do_bench_extend(b, 0, 10)
-    }
-
-    #[bench]
-    fn bench_extend_0000_0100(b: &mut Bencher) {
-        do_bench_extend(b, 0, 100)
-    }
-
-    #[bench]
-    fn bench_extend_0000_1000(b: &mut Bencher) {
-        do_bench_extend(b, 0, 1000)
-    }
-
-    #[bench]
-    fn bench_extend_0010_0010(b: &mut Bencher) {
-        do_bench_extend(b, 10, 10)
-    }
-
-    #[bench]
-    fn bench_extend_0100_0100(b: &mut Bencher) {
-        do_bench_extend(b, 100, 100)
-    }
-
-    #[bench]
-    fn bench_extend_1000_1000(b: &mut Bencher) {
-        do_bench_extend(b, 1000, 1000)
-    }
-
-    fn do_bench_push_all(b: &mut Bencher, dst_len: usize, src_len: usize) {
-        let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
-        let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
-
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let mut dst = dst.clone();
-            dst.push_all(&src);
-            assert_eq!(dst.len(), dst_len + src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        });
-    }
-
-    #[bench]
-    fn bench_push_all_0000_0000(b: &mut Bencher) {
-        do_bench_push_all(b, 0, 0)
-    }
-
-    #[bench]
-    fn bench_push_all_0000_0010(b: &mut Bencher) {
-        do_bench_push_all(b, 0, 10)
-    }
-
-    #[bench]
-    fn bench_push_all_0000_0100(b: &mut Bencher) {
-        do_bench_push_all(b, 0, 100)
-    }
-
-    #[bench]
-    fn bench_push_all_0000_1000(b: &mut Bencher) {
-        do_bench_push_all(b, 0, 1000)
-    }
-
-    #[bench]
-    fn bench_push_all_0010_0010(b: &mut Bencher) {
-        do_bench_push_all(b, 10, 10)
-    }
-
-    #[bench]
-    fn bench_push_all_0100_0100(b: &mut Bencher) {
-        do_bench_push_all(b, 100, 100)
-    }
-
-    #[bench]
-    fn bench_push_all_1000_1000(b: &mut Bencher) {
-        do_bench_push_all(b, 1000, 1000)
-    }
-
-    fn do_bench_push_all_move(b: &mut Bencher, dst_len: usize, src_len: usize) {
-        let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
-        let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
-
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let mut dst = dst.clone();
-            dst.extend(src.clone().into_iter());
-            assert_eq!(dst.len(), dst_len + src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        });
-    }
-
-    #[bench]
-    fn bench_push_all_move_0000_0000(b: &mut Bencher) {
-        do_bench_push_all_move(b, 0, 0)
-    }
-
-    #[bench]
-    fn bench_push_all_move_0000_0010(b: &mut Bencher) {
-        do_bench_push_all_move(b, 0, 10)
-    }
-
-    #[bench]
-    fn bench_push_all_move_0000_0100(b: &mut Bencher) {
-        do_bench_push_all_move(b, 0, 100)
-    }
-
-    #[bench]
-    fn bench_push_all_move_0000_1000(b: &mut Bencher) {
-        do_bench_push_all_move(b, 0, 1000)
-    }
-
-    #[bench]
-    fn bench_push_all_move_0010_0010(b: &mut Bencher) {
-        do_bench_push_all_move(b, 10, 10)
-    }
-
-    #[bench]
-    fn bench_push_all_move_0100_0100(b: &mut Bencher) {
-        do_bench_push_all_move(b, 100, 100)
-    }
-
-    #[bench]
-    fn bench_push_all_move_1000_1000(b: &mut Bencher) {
-        do_bench_push_all_move(b, 1000, 1000)
-    }
-
-    fn do_bench_clone(b: &mut Bencher, src_len: usize) {
-        let src: Vec<usize> = FromIterator::from_iter(0..src_len);
-
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let dst = src.clone();
-            assert_eq!(dst.len(), src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        });
-    }
-
-    #[bench]
-    fn bench_clone_0000(b: &mut Bencher) {
-        do_bench_clone(b, 0)
-    }
-
-    #[bench]
-    fn bench_clone_0010(b: &mut Bencher) {
-        do_bench_clone(b, 10)
-    }
-
-    #[bench]
-    fn bench_clone_0100(b: &mut Bencher) {
-        do_bench_clone(b, 100)
-    }
-
-    #[bench]
-    fn bench_clone_1000(b: &mut Bencher) {
-        do_bench_clone(b, 1000)
-    }
-
-    fn do_bench_clone_from(b: &mut Bencher, times: usize, dst_len: usize, src_len: usize) {
-        let dst: Vec<_> = FromIterator::from_iter(0..src_len);
-        let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
-
-        b.bytes = (times * src_len) as u64;
-
-        b.iter(|| {
-            let mut dst = dst.clone();
-
-            for _ in 0..times {
-                dst.clone_from(&src);
-
-                assert_eq!(dst.len(), src_len);
-                assert!(dst.iter().enumerate().all(|(i, x)| dst_len + i == *x));
-            }
-        });
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0000_0000(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 0, 0)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0000_0010(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 0, 10)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0000_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 0, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0000_1000(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 0, 1000)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0010_0010(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 10, 10)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0100_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 100, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_1000_1000(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 1000, 1000)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0010_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 10, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0100_1000(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 100, 1000)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0010_0000(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 10, 0)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0100_0010(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 100, 10)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_1000_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 1000, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0000_0000(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 0, 0)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0000_0010(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 0, 10)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0000_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 0, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0000_1000(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 0, 1000)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0010_0010(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 10, 10)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0100_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 100, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_1000_1000(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 1000, 1000)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0010_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 10, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0100_1000(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 100, 1000)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0010_0000(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 10, 0)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0100_0010(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 100, 10)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_1000_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 1000, 100)
-    }
-}
index 3ba22a41ff74097d73626b926a0bcda8b971486e..49b0c229215bd98ee8842debf19edb21b9d79275 100644 (file)
@@ -24,25 +24,18 @@ use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt;
 use core::iter::{self, repeat, FromIterator, IntoIterator, RandomAccessIterator};
-use core::marker;
 use core::mem;
-use core::num::{Int, UnsignedInt};
 use core::ops::{Index, IndexMut};
 use core::ptr::{self, Unique};
-use core::raw::Slice as RawSlice;
+use core::slice;
 
 use core::hash::{Hash, Hasher};
-#[cfg(stage0)] use core::hash::Writer;
 use core::cmp;
 
 use alloc::heap;
 
-#[deprecated(since = "1.0.0", reason = "renamed to VecDeque")]
-#[unstable(feature = "collections")]
-pub use VecDeque as RingBuf;
-
-static INITIAL_CAPACITY: usize = 7; // 2^3 - 1
-static MINIMUM_CAPACITY: usize = 1; // 2 - 1
+const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
+const MINIMUM_CAPACITY: usize = 1; // 2 - 1
 
 /// `VecDeque` is a growable ring buffer, which can be used as a
 /// double-ended queue efficiently.
@@ -60,12 +53,6 @@ pub struct VecDeque<T> {
     ptr: Unique<T>,
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T: Send> Send for VecDeque<T> {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T: Sync> Sync for VecDeque<T> {}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Clone> Clone for VecDeque<T> {
     fn clone(&self) -> VecDeque<T> {
@@ -98,13 +85,13 @@ impl<T> VecDeque<T> {
     /// Turn ptr into a slice
     #[inline]
     unsafe fn buffer_as_slice(&self) -> &[T] {
-        mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap })
+        slice::from_raw_parts(*self.ptr, self.cap)
     }
 
     /// Turn ptr into a mut slice
     #[inline]
     unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] {
-        mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap })
+        slice::from_raw_parts_mut(*self.ptr, self.cap)
     }
 
     /// Moves an element out of the buffer
@@ -128,6 +115,20 @@ impl<T> VecDeque<T> {
     #[inline]
     fn wrap_index(&self, idx: usize) -> usize { wrap_index(idx, self.cap) }
 
+    /// Returns the index in the underlying buffer for a given logical element
+    /// index + addend.
+    #[inline]
+    fn wrap_add(&self, idx: usize, addend: usize) -> usize {
+        wrap_index(idx.wrapping_add(addend), self.cap)
+    }
+
+    /// Returns the index in the underlying buffer for a given logical element
+    /// index - subtrahend.
+    #[inline]
+    fn wrap_sub(&self, idx: usize, subtrahend: usize) -> usize {
+        wrap_index(idx.wrapping_sub(subtrahend), self.cap)
+    }
+
     /// Copies a contiguous block of memory len long from src to dst
     #[inline]
     unsafe fn copy(&self, dst: usize, src: usize, len: usize) {
@@ -135,9 +136,9 @@ impl<T> VecDeque<T> {
                       self.cap);
         debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
                       self.cap);
-        ptr::copy_memory(
-            self.ptr.offset(dst as isize),
+        ptr::copy(
             self.ptr.offset(src as isize),
+            self.ptr.offset(dst as isize),
             len);
     }
 
@@ -148,9 +149,9 @@ impl<T> VecDeque<T> {
                       self.cap);
         debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
                       self.cap);
-        ptr::copy_nonoverlapping_memory(
-            self.ptr.offset(dst as isize),
+        ptr::copy_nonoverlapping(
             self.ptr.offset(src as isize),
+            self.ptr.offset(dst as isize),
             len);
     }
 }
@@ -193,7 +194,7 @@ impl<T> VecDeque<T> {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -205,7 +206,7 @@ impl<T> VecDeque<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get(&self, i: usize) -> Option<&T> {
         if i < self.len() {
-            let idx = self.wrap_index(self.tail + i);
+            let idx = self.wrap_add(self.tail, i);
             unsafe { Some(&*self.ptr.offset(idx as isize)) }
         } else {
             None
@@ -216,7 +217,7 @@ impl<T> VecDeque<T> {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -235,7 +236,7 @@ impl<T> VecDeque<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self, i: usize) -> Option<&mut T> {
         if i < self.len() {
-            let idx = self.wrap_index(self.tail + i);
+            let idx = self.wrap_add(self.tail, i);
             unsafe { Some(&mut *self.ptr.offset(idx as isize)) }
         } else {
             None
@@ -250,7 +251,8 @@ impl<T> VecDeque<T> {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -265,8 +267,8 @@ impl<T> VecDeque<T> {
     pub fn swap(&mut self, i: usize, j: usize) {
         assert!(i < self.len());
         assert!(j < self.len());
-        let ri = self.wrap_index(self.tail + i);
-        let rj = self.wrap_index(self.tail + j);
+        let ri = self.wrap_add(self.tail, i);
+        let rj = self.wrap_add(self.tail, j);
         unsafe {
             ptr::swap(self.ptr.offset(ri as isize), self.ptr.offset(rj as isize))
         }
@@ -278,6 +280,7 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let buf: VecDeque<i32> = VecDeque::with_capacity(10);
@@ -301,6 +304,7 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
@@ -322,6 +326,7 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
@@ -397,6 +402,7 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::with_capacity(15);
@@ -435,7 +441,7 @@ impl<T> VecDeque<T> {
                 //   [. . . o o o o o o o . . . . . . ]
                 //        H T
                 //   [o o . o o o o o ]
-                let len = self.wrap_index(self.head - target_cap);
+                let len = self.wrap_sub(self.head, target_cap);
                 unsafe {
                     self.copy_nonoverlapping(0, target_cap, len);
                 }
@@ -446,7 +452,7 @@ impl<T> VecDeque<T> {
                 //   [o o o o o . . . . . . . . . o o ]
                 //              H T
                 //   [o o o o o . o o ]
-                debug_assert!(self.wrap_index(self.head - 1) < target_cap);
+                debug_assert!(self.wrap_sub(self.head, 1) < target_cap);
                 let len = self.cap - self.tail;
                 let new_tail = target_cap - len;
                 unsafe {
@@ -483,6 +489,7 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -505,7 +512,8 @@ impl<T> VecDeque<T> {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(core)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -513,7 +521,8 @@ impl<T> VecDeque<T> {
     /// buf.push_back(3);
     /// buf.push_back(4);
     /// let b: &[_] = &[&5, &3, &4];
-    /// assert_eq!(buf.iter().collect::<Vec<&i32>>().as_slice(), b);
+    /// let c: Vec<&i32> = buf.iter().collect();
+    /// assert_eq!(&c[..], b);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter(&self) -> Iter<T> {
@@ -528,7 +537,8 @@ impl<T> VecDeque<T> {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(core)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -539,20 +549,18 @@ impl<T> VecDeque<T> {
     ///     *num = *num - 2;
     /// }
     /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
-    /// assert_eq!(&buf.iter_mut().collect::<Vec<&mut i32>>()[], b);
+    /// assert_eq!(&buf.iter_mut().collect::<Vec<&mut i32>>()[..], b);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter_mut(&mut self) -> IterMut<T> {
         IterMut {
             tail: self.tail,
             head: self.head,
-            cap: self.cap,
-            ptr: *self.ptr,
-            marker: marker::PhantomData,
+            ring: unsafe { self.buffer_as_mut_slice() },
         }
     }
 
-    /// Consumes the list into an iterator yielding elements by value.
+    /// Consumes the list into a front-to-back iterator yielding elements by value.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_iter(self) -> IntoIter<T> {
         IntoIter {
@@ -640,6 +648,7 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let mut v = VecDeque::new();
@@ -785,7 +794,7 @@ impl<T> VecDeque<T> {
             None
         } else {
             let tail = self.tail;
-            self.tail = self.wrap_index(self.tail + 1);
+            self.tail = self.wrap_add(self.tail, 1);
             unsafe { Some(self.buffer_read(tail)) }
         }
     }
@@ -809,7 +818,7 @@ impl<T> VecDeque<T> {
             debug_assert!(!self.is_full());
         }
 
-        self.tail = self.wrap_index(self.tail - 1);
+        self.tail = self.wrap_sub(self.tail, 1);
         let tail = self.tail;
         unsafe { self.buffer_write(tail, t); }
     }
@@ -818,7 +827,7 @@ impl<T> VecDeque<T> {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -834,7 +843,7 @@ impl<T> VecDeque<T> {
         }
 
         let head = self.head;
-        self.head = self.wrap_index(self.head + 1);
+        self.head = self.wrap_add(self.head, 1);
         unsafe { self.buffer_write(head, t) }
     }
 
@@ -843,7 +852,7 @@ impl<T> VecDeque<T> {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -857,7 +866,7 @@ impl<T> VecDeque<T> {
         if self.is_empty() {
             None
         } else {
-            self.head = self.wrap_index(self.head - 1);
+            self.head = self.wrap_sub(self.head, 1);
             let head = self.head;
             unsafe { Some(self.buffer_read(head)) }
         }
@@ -878,6 +887,7 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -911,6 +921,7 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -943,7 +954,8 @@ impl<T> VecDeque<T> {
     /// Panics if `i` is greater than ringbuf's length
     ///
     /// # Examples
-    /// ```rust
+    /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -981,7 +993,7 @@ impl<T> VecDeque<T> {
         //      A - The element that should be after the insertion point
         //      M - Indicates element was moved
 
-        let idx = self.wrap_index(self.tail + i);
+        let idx = self.wrap_add(self.tail, i);
 
         let distance_to_tail = i;
         let distance_to_head = self.len() - i;
@@ -1000,7 +1012,7 @@ impl<T> VecDeque<T> {
                 //      [A o o o o o o o . . . . . I]
                 //
 
-                self.tail = self.wrap_index(self.tail - 1);
+                self.tail = self.wrap_sub(self.tail, 1);
             },
             (true, true, _) => unsafe {
                 // contiguous, insert closer to tail:
@@ -1022,7 +1034,7 @@ impl<T> VecDeque<T> {
                 //      [o I A o o o o o . . . . . . . o]
                 //       M                             M
 
-                let new_tail = self.wrap_index(self.tail - 1);
+                let new_tail = self.wrap_sub(self.tail, 1);
 
                 self.copy(new_tail, self.tail, 1);
                 // Already moved the tail, so we only copy `i - 1` elements.
@@ -1041,7 +1053,7 @@ impl<T> VecDeque<T> {
                 //                       M M M
 
                 self.copy(idx + 1, idx, self.head - idx);
-                self.head = self.wrap_index(self.head + 1);
+                self.head = self.wrap_add(self.head, 1);
             },
             (false, true, true) => unsafe {
                 // discontiguous, insert closer to tail, tail section:
@@ -1133,7 +1145,7 @@ impl<T> VecDeque<T> {
         }
 
         // tail might've been changed so we need to recalculate
-        let new_idx = self.wrap_index(self.tail + i);
+        let new_idx = self.wrap_add(self.tail, i);
         unsafe {
             self.buffer_write(new_idx, t);
         }
@@ -1145,7 +1157,7 @@ impl<T> VecDeque<T> {
     /// Returns `None` if `i` is out of bounds.
     ///
     /// # Examples
-    /// ```rust
+    /// ```
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -1180,7 +1192,7 @@ impl<T> VecDeque<T> {
         //      R - Indicates element that is being removed
         //      M - Indicates element was moved
 
-        let idx = self.wrap_index(self.tail + i);
+        let idx = self.wrap_add(self.tail, i);
 
         let elem = unsafe {
             Some(self.buffer_read(idx))
@@ -1229,7 +1241,7 @@ impl<T> VecDeque<T> {
                 //                               M M
 
                 self.copy(self.tail + 1, self.tail, i);
-                self.tail = self.wrap_index(self.tail + 1);
+                self.tail = self.wrap_add(self.tail, 1);
             },
             (false, false, false) => unsafe {
                 // discontiguous, remove closer to head, head section:
@@ -1275,7 +1287,7 @@ impl<T> VecDeque<T> {
                     self.copy(0, 1, self.head - 1);
                 }
 
-                self.head = self.wrap_index(self.head - 1);
+                self.head = self.wrap_sub(self.head, 1);
             },
             (false, true, false) => unsafe {
                 // discontiguous, remove closer to tail, head section:
@@ -1296,7 +1308,7 @@ impl<T> VecDeque<T> {
                 // move elements from tail to end forward, excluding the last one
                 self.copy(self.tail + 1, self.tail, self.cap - self.tail - 1);
 
-                self.tail = self.wrap_index(self.tail + 1);
+                self.tail = self.wrap_add(self.tail, 1);
             }
         }
 
@@ -1317,6 +1329,7 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf: VecDeque<_> = vec![1,2,3].into_iter().collect();
@@ -1344,27 +1357,27 @@ impl<T> VecDeque<T> {
                 // `at` lies in the first half.
                 let amount_in_first = first_len - at;
 
-                ptr::copy_nonoverlapping_memory(*other.ptr,
-                                                first_half.as_ptr().offset(at as isize),
-                                                amount_in_first);
+                ptr::copy_nonoverlapping(first_half.as_ptr().offset(at as isize),
+                                         *other.ptr,
+                                         amount_in_first);
 
                 // just take all of the second half.
-                ptr::copy_nonoverlapping_memory(other.ptr.offset(amount_in_first as isize),
-                                                second_half.as_ptr(),
-                                                second_len);
+                ptr::copy_nonoverlapping(second_half.as_ptr(),
+                                         other.ptr.offset(amount_in_first as isize),
+                                         second_len);
             } else {
                 // `at` lies in the second half, need to factor in the elements we skipped
                 // in the first half.
                 let offset = at - first_len;
                 let amount_in_second = second_len - offset;
-                ptr::copy_nonoverlapping_memory(*other.ptr,
-                                                second_half.as_ptr().offset(offset as isize),
-                                                amount_in_second);
+                ptr::copy_nonoverlapping(second_half.as_ptr().offset(offset as isize),
+                                         *other.ptr,
+                                         amount_in_second);
             }
         }
 
         // Cleanup where the ends of the buffers are
-        self.head = self.wrap_index(self.head - other_len);
+        self.head = self.wrap_sub(self.head, other_len);
         other.head = other.wrap_index(other_len);
 
         other
@@ -1379,6 +1392,7 @@ impl<T> VecDeque<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
@@ -1403,6 +1417,7 @@ impl<T: Clone> VecDeque<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecDeque;
     ///
     /// let mut buf = VecDeque::new();
@@ -1439,7 +1454,7 @@ fn wrap_index(index: usize, size: usize) -> usize {
 #[inline]
 fn count(tail: usize, head: usize, size: usize) -> usize {
     // size is always a power of 2
-    (head - tail) & (size - 1)
+    (head.wrapping_sub(tail)) & (size - 1)
 }
 
 /// `VecDeque` iterator.
@@ -1471,7 +1486,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
             return None;
         }
         let tail = self.tail;
-        self.tail = wrap_index(self.tail + 1, self.ring.len());
+        self.tail = wrap_index(self.tail.wrapping_add(1), self.ring.len());
         unsafe { Some(self.ring.get_unchecked(tail)) }
     }
 
@@ -1489,7 +1504,7 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
         if self.tail == self.head {
             return None;
         }
-        self.head = wrap_index(self.head - 1, self.ring.len());
+        self.head = wrap_index(self.head.wrapping_sub(1), self.ring.len());
         unsafe { Some(self.ring.get_unchecked(self.head)) }
     }
 }
@@ -1510,23 +1525,18 @@ impl<'a, T> RandomAccessIterator for Iter<'a, T> {
         if j >= self.indexable() {
             None
         } else {
-            let idx = wrap_index(self.tail + j, self.ring.len());
+            let idx = wrap_index(self.tail.wrapping_add(j), self.ring.len());
             unsafe { Some(self.ring.get_unchecked(idx)) }
         }
     }
 }
 
-// FIXME This was implemented differently from Iter because of a problem
-//       with returning the mutable reference. I couldn't find a way to
-//       make the lifetime checker happy so, but there should be a way.
 /// `VecDeque` mutable iterator.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IterMut<'a, T:'a> {
-    ptr: *mut T,
+    ring: &'a mut [T],
     tail: usize,
     head: usize,
-    cap: usize,
-    marker: marker::PhantomData<&'a mut T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1539,16 +1549,17 @@ impl<'a, T> Iterator for IterMut<'a, T> {
             return None;
         }
         let tail = self.tail;
-        self.tail = wrap_index(self.tail + 1, self.cap);
+        self.tail = wrap_index(self.tail.wrapping_add(1), self.ring.len());
 
         unsafe {
-            Some(&mut *self.ptr.offset(tail as isize))
+            let elem = self.ring.get_unchecked_mut(tail);
+            Some(&mut *(elem as *mut _))
         }
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let len = count(self.tail, self.head, self.cap);
+        let len = count(self.tail, self.head, self.ring.len());
         (len, Some(len))
     }
 }
@@ -1560,10 +1571,11 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
         if self.tail == self.head {
             return None;
         }
-        self.head = wrap_index(self.head - 1, self.cap);
+        self.head = wrap_index(self.head.wrapping_sub(1), self.ring.len());
 
         unsafe {
-            Some(&mut *self.ptr.offset(self.head as isize))
+            let elem = self.ring.get_unchecked_mut(self.head);
+            Some(&mut *(elem as *mut _))
         }
     }
 }
@@ -1572,6 +1584,7 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
 impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
 
 /// A by-value VecDeque iterator
+#[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<T> {
     inner: VecDeque<T>,
@@ -1675,17 +1688,6 @@ impl<A: Ord> Ord for VecDeque<A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg(stage0)]
-impl<S: Writer + Hasher, A: Hash<S>> Hash<S> for VecDeque<A> {
-    fn hash(&self, state: &mut S) {
-        self.len().hash(state);
-        for elt in self {
-            elt.hash(state);
-        }
-    }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-#[cfg(not(stage0))]
 impl<A: Hash> Hash for VecDeque<A> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         self.len().hash(state);
@@ -1700,16 +1702,16 @@ impl<A> Index<usize> for VecDeque<A> {
     type Output = A;
 
     #[inline]
-    fn index(&self, i: &usize) -> &A {
-        self.get(*i).expect("Out of bounds access")
+    fn index(&self, i: usize) -> &A {
+        self.get(i).expect("Out of bounds access")
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A> IndexMut<usize> for VecDeque<A> {
     #[inline]
-    fn index_mut(&mut self, i: &usize) -> &mut A {
-        self.get_mut(*i).expect("Out of bounds access")
+    fn index_mut(&mut self, i: usize) -> &mut A {
+        self.get_mut(i).expect("Out of bounds access")
     }
 }
 
@@ -1766,7 +1768,7 @@ impl<A> Extend<A> for VecDeque<A> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "VecDeque ["));
+        try!(write!(f, "["));
 
         for (i, e) in self.iter().enumerate() {
             if i != 0 { try!(write!(f, ", ")); }
@@ -1778,138 +1780,14 @@ impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
 }
 
 #[cfg(test)]
-mod tests {
-    use self::Taggy::*;
-    use self::Taggypar::*;
-    use prelude::*;
-    use core::iter;
-    use std::fmt::Debug;
-    use std::hash::{self, SipHasher};
-    use test::Bencher;
+mod test {
+    use core::iter::{Iterator, self};
+    use core::option::Option::Some;
+
     use test;
 
     use super::VecDeque;
 
-    #[test]
-    #[allow(deprecated)]
-    fn test_simple() {
-        let mut d = VecDeque::new();
-        assert_eq!(d.len(), 0);
-        d.push_front(17);
-        d.push_front(42);
-        d.push_back(137);
-        assert_eq!(d.len(), 3);
-        d.push_back(137);
-        assert_eq!(d.len(), 4);
-        assert_eq!(*d.front().unwrap(), 42);
-        assert_eq!(*d.back().unwrap(), 137);
-        let mut i = d.pop_front();
-        assert_eq!(i, Some(42));
-        i = d.pop_back();
-        assert_eq!(i, Some(137));
-        i = d.pop_back();
-        assert_eq!(i, Some(137));
-        i = d.pop_back();
-        assert_eq!(i, Some(17));
-        assert_eq!(d.len(), 0);
-        d.push_back(3);
-        assert_eq!(d.len(), 1);
-        d.push_front(2);
-        assert_eq!(d.len(), 2);
-        d.push_back(4);
-        assert_eq!(d.len(), 3);
-        d.push_front(1);
-        assert_eq!(d.len(), 4);
-        debug!("{}", d[0]);
-        debug!("{}", d[1]);
-        debug!("{}", d[2]);
-        debug!("{}", d[3]);
-        assert_eq!(d[0], 1);
-        assert_eq!(d[1], 2);
-        assert_eq!(d[2], 3);
-        assert_eq!(d[3], 4);
-    }
-
-    #[cfg(test)]
-    fn test_parameterized<T:Clone + PartialEq + Debug>(a: T, b: T, c: T, d: T) {
-        let mut deq = VecDeque::new();
-        assert_eq!(deq.len(), 0);
-        deq.push_front(a.clone());
-        deq.push_front(b.clone());
-        deq.push_back(c.clone());
-        assert_eq!(deq.len(), 3);
-        deq.push_back(d.clone());
-        assert_eq!(deq.len(), 4);
-        assert_eq!((*deq.front().unwrap()).clone(), b.clone());
-        assert_eq!((*deq.back().unwrap()).clone(), d.clone());
-        assert_eq!(deq.pop_front().unwrap(), b.clone());
-        assert_eq!(deq.pop_back().unwrap(), d.clone());
-        assert_eq!(deq.pop_back().unwrap(), c.clone());
-        assert_eq!(deq.pop_back().unwrap(), a.clone());
-        assert_eq!(deq.len(), 0);
-        deq.push_back(c.clone());
-        assert_eq!(deq.len(), 1);
-        deq.push_front(b.clone());
-        assert_eq!(deq.len(), 2);
-        deq.push_back(d.clone());
-        assert_eq!(deq.len(), 3);
-        deq.push_front(a.clone());
-        assert_eq!(deq.len(), 4);
-        assert_eq!(deq[0].clone(), a.clone());
-        assert_eq!(deq[1].clone(), b.clone());
-        assert_eq!(deq[2].clone(), c.clone());
-        assert_eq!(deq[3].clone(), d.clone());
-    }
-
-    #[test]
-    fn test_push_front_grow() {
-        let mut deq = VecDeque::new();
-        for i in 0..66 {
-            deq.push_front(i);
-        }
-        assert_eq!(deq.len(), 66);
-
-        for i in 0..66 {
-            assert_eq!(deq[i], 65 - i);
-        }
-
-        let mut deq = VecDeque::new();
-        for i in 0..66 {
-            deq.push_back(i);
-        }
-
-        for i in 0..66 {
-            assert_eq!(deq[i], i);
-        }
-    }
-
-    #[test]
-    fn test_index() {
-        let mut deq = VecDeque::new();
-        for i in 1..4 {
-            deq.push_front(i);
-        }
-        assert_eq!(deq[1], 2);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_index_out_of_bounds() {
-        let mut deq = VecDeque::new();
-        for i in 1..4 {
-            deq.push_front(i);
-        }
-        deq[3];
-    }
-
-    #[bench]
-    fn bench_new(b: &mut test::Bencher) {
-        b.iter(|| {
-            let ring: VecDeque<i32> = VecDeque::new();
-            test::black_box(ring);
-        })
-    }
-
     #[bench]
     fn bench_push_back_100(b: &mut test::Bencher) {
         let mut deq = VecDeque::with_capacity(101);
@@ -1960,666 +1838,6 @@ mod tests {
         })
     }
 
-    #[bench]
-    fn bench_grow_1025(b: &mut test::Bencher) {
-        b.iter(|| {
-            let mut deq = VecDeque::new();
-            for i in 0..1025 {
-                deq.push_front(i);
-            }
-            test::black_box(deq);
-        })
-    }
-
-    #[bench]
-    fn bench_iter_1000(b: &mut test::Bencher) {
-        let ring: VecDeque<_> = (0..1000).collect();
-
-        b.iter(|| {
-            let mut sum = 0;
-            for &i in &ring {
-                sum += i;
-            }
-            test::black_box(sum);
-        })
-    }
-
-    #[bench]
-    fn bench_mut_iter_1000(b: &mut test::Bencher) {
-        let mut ring: VecDeque<_> = (0..1000).collect();
-
-        b.iter(|| {
-            let mut sum = 0;
-            for i in &mut ring {
-                sum += *i;
-            }
-            test::black_box(sum);
-        })
-    }
-
-    #[derive(Clone, PartialEq, Debug)]
-    enum Taggy {
-        One(i32),
-        Two(i32, i32),
-        Three(i32, i32, i32),
-    }
-
-    #[derive(Clone, PartialEq, Debug)]
-    enum Taggypar<T> {
-        Onepar(T),
-        Twopar(T, T),
-        Threepar(T, T, T),
-    }
-
-    #[derive(Clone, PartialEq, Debug)]
-    struct RecCy {
-        x: i32,
-        y: i32,
-        t: Taggy
-    }
-
-    #[test]
-    fn test_param_int() {
-        test_parameterized::<i32>(5, 72, 64, 175);
-    }
-
-    #[test]
-    fn test_param_taggy() {
-        test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
-    }
-
-    #[test]
-    fn test_param_taggypar() {
-        test_parameterized::<Taggypar<i32>>(Onepar::<i32>(1),
-                                            Twopar::<i32>(1, 2),
-                                            Threepar::<i32>(1, 2, 3),
-                                            Twopar::<i32>(17, 42));
-    }
-
-    #[test]
-    fn test_param_reccy() {
-        let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
-        let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
-        let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
-        let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
-        test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
-    }
-
-    #[test]
-    fn test_with_capacity() {
-        let mut d = VecDeque::with_capacity(0);
-        d.push_back(1);
-        assert_eq!(d.len(), 1);
-        let mut d = VecDeque::with_capacity(50);
-        d.push_back(1);
-        assert_eq!(d.len(), 1);
-    }
-
-    #[test]
-    fn test_with_capacity_non_power_two() {
-        let mut d3 = VecDeque::with_capacity(3);
-        d3.push_back(1);
-
-        // X = None, | = lo
-        // [|1, X, X]
-        assert_eq!(d3.pop_front(), Some(1));
-        // [X, |X, X]
-        assert_eq!(d3.front(), None);
-
-        // [X, |3, X]
-        d3.push_back(3);
-        // [X, |3, 6]
-        d3.push_back(6);
-        // [X, X, |6]
-        assert_eq!(d3.pop_front(), Some(3));
-
-        // Pushing the lo past half way point to trigger
-        // the 'B' scenario for growth
-        // [9, X, |6]
-        d3.push_back(9);
-        // [9, 12, |6]
-        d3.push_back(12);
-
-        d3.push_back(15);
-        // There used to be a bug here about how the
-        // VecDeque made growth assumptions about the
-        // underlying Vec which didn't hold and lead
-        // to corruption.
-        // (Vec grows to next power of two)
-        //good- [9, 12, 15, X, X, X, X, |6]
-        //bug-  [15, 12, X, X, X, |6, X, X]
-        assert_eq!(d3.pop_front(), Some(6));
-
-        // Which leads us to the following state which
-        // would be a failure case.
-        //bug-  [15, 12, X, X, X, X, |X, X]
-        assert_eq!(d3.front(), Some(&9));
-    }
-
-    #[test]
-    fn test_reserve_exact() {
-        let mut d = VecDeque::new();
-        d.push_back(0);
-        d.reserve_exact(50);
-        assert!(d.capacity() >= 51);
-    }
-
-    #[test]
-    fn test_reserve() {
-        let mut d = VecDeque::new();
-        d.push_back(0);
-        d.reserve(50);
-        assert!(d.capacity() >= 51);
-    }
-
-    #[test]
-    fn test_swap() {
-        let mut d: VecDeque<_> = (0..5).collect();
-        d.pop_front();
-        d.swap(0, 3);
-        assert_eq!(d.iter().cloned().collect::<Vec<_>>(), vec!(4, 2, 3, 1));
-    }
-
-    #[test]
-    fn test_iter() {
-        let mut d = VecDeque::new();
-        assert_eq!(d.iter().next(), None);
-        assert_eq!(d.iter().size_hint(), (0, Some(0)));
-
-        for i in 0..5 {
-            d.push_back(i);
-        }
-        {
-            let b: &[_] = &[&0,&1,&2,&3,&4];
-            assert_eq!(d.iter().collect::<Vec<_>>(), b);
-        }
-
-        for i in 6..9 {
-            d.push_front(i);
-        }
-        {
-            let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
-            assert_eq!(d.iter().collect::<Vec<_>>(), b);
-        }
-
-        let mut it = d.iter();
-        let mut len = d.len();
-        loop {
-            match it.next() {
-                None => break,
-                _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
-            }
-        }
-    }
-
-    #[test]
-    fn test_rev_iter() {
-        let mut d = VecDeque::new();
-        assert_eq!(d.iter().rev().next(), None);
-
-        for i in 0..5 {
-            d.push_back(i);
-        }
-        {
-            let b: &[_] = &[&4,&3,&2,&1,&0];
-            assert_eq!(d.iter().rev().collect::<Vec<_>>(), b);
-        }
-
-        for i in 6..9 {
-            d.push_front(i);
-        }
-        let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
-        assert_eq!(d.iter().rev().collect::<Vec<_>>(), b);
-    }
-
-    #[test]
-    fn test_mut_rev_iter_wrap() {
-        let mut d = VecDeque::with_capacity(3);
-        assert!(d.iter_mut().rev().next().is_none());
-
-        d.push_back(1);
-        d.push_back(2);
-        d.push_back(3);
-        assert_eq!(d.pop_front(), Some(1));
-        d.push_back(4);
-
-        assert_eq!(d.iter_mut().rev().cloned().collect::<Vec<_>>(),
-                   vec![4, 3, 2]);
-    }
-
-    #[test]
-    fn test_mut_iter() {
-        let mut d = VecDeque::new();
-        assert!(d.iter_mut().next().is_none());
-
-        for i in 0..3 {
-            d.push_front(i);
-        }
-
-        for (i, elt) in d.iter_mut().enumerate() {
-            assert_eq!(*elt, 2 - i);
-            *elt = i;
-        }
-
-        {
-            let mut it = d.iter_mut();
-            assert_eq!(*it.next().unwrap(), 0);
-            assert_eq!(*it.next().unwrap(), 1);
-            assert_eq!(*it.next().unwrap(), 2);
-            assert!(it.next().is_none());
-        }
-    }
-
-    #[test]
-    fn test_mut_rev_iter() {
-        let mut d = VecDeque::new();
-        assert!(d.iter_mut().rev().next().is_none());
-
-        for i in 0..3 {
-            d.push_front(i);
-        }
-
-        for (i, elt) in d.iter_mut().rev().enumerate() {
-            assert_eq!(*elt, i);
-            *elt = i;
-        }
-
-        {
-            let mut it = d.iter_mut().rev();
-            assert_eq!(*it.next().unwrap(), 0);
-            assert_eq!(*it.next().unwrap(), 1);
-            assert_eq!(*it.next().unwrap(), 2);
-            assert!(it.next().is_none());
-        }
-    }
-
-    #[test]
-    fn test_into_iter() {
-
-        // Empty iter
-        {
-            let d: VecDeque<i32> = VecDeque::new();
-            let mut iter = d.into_iter();
-
-            assert_eq!(iter.size_hint(), (0, Some(0)));
-            assert_eq!(iter.next(), None);
-            assert_eq!(iter.size_hint(), (0, Some(0)));
-        }
-
-        // simple iter
-        {
-            let mut d = VecDeque::new();
-            for i in 0..5 {
-                d.push_back(i);
-            }
-
-            let b = vec![0,1,2,3,4];
-            assert_eq!(d.into_iter().collect::<Vec<_>>(), b);
-        }
-
-        // wrapped iter
-        {
-            let mut d = VecDeque::new();
-            for i in 0..5 {
-                d.push_back(i);
-            }
-            for i in 6..9 {
-                d.push_front(i);
-            }
-
-            let b = vec![8,7,6,0,1,2,3,4];
-            assert_eq!(d.into_iter().collect::<Vec<_>>(), b);
-        }
-
-        // partially used
-        {
-            let mut d = VecDeque::new();
-            for i in 0..5 {
-                d.push_back(i);
-            }
-            for i in 6..9 {
-                d.push_front(i);
-            }
-
-            let mut it = d.into_iter();
-            assert_eq!(it.size_hint(), (8, Some(8)));
-            assert_eq!(it.next(), Some(8));
-            assert_eq!(it.size_hint(), (7, Some(7)));
-            assert_eq!(it.next_back(), Some(4));
-            assert_eq!(it.size_hint(), (6, Some(6)));
-            assert_eq!(it.next(), Some(7));
-            assert_eq!(it.size_hint(), (5, Some(5)));
-        }
-    }
-
-    #[test]
-    fn test_drain() {
-
-        // Empty iter
-        {
-            let mut d: VecDeque<i32> = VecDeque::new();
-
-            {
-                let mut iter = d.drain();
-
-                assert_eq!(iter.size_hint(), (0, Some(0)));
-                assert_eq!(iter.next(), None);
-                assert_eq!(iter.size_hint(), (0, Some(0)));
-            }
-
-            assert!(d.is_empty());
-        }
-
-        // simple iter
-        {
-            let mut d = VecDeque::new();
-            for i in 0..5 {
-                d.push_back(i);
-            }
-
-            assert_eq!(d.drain().collect::<Vec<_>>(), [0, 1, 2, 3, 4]);
-            assert!(d.is_empty());
-        }
-
-        // wrapped iter
-        {
-            let mut d = VecDeque::new();
-            for i in 0..5 {
-                d.push_back(i);
-            }
-            for i in 6..9 {
-                d.push_front(i);
-            }
-
-            assert_eq!(d.drain().collect::<Vec<_>>(), [8,7,6,0,1,2,3,4]);
-            assert!(d.is_empty());
-        }
-
-        // partially used
-        {
-            let mut d: VecDeque<_> = VecDeque::new();
-            for i in 0..5 {
-                d.push_back(i);
-            }
-            for i in 6..9 {
-                d.push_front(i);
-            }
-
-            {
-                let mut it = d.drain();
-                assert_eq!(it.size_hint(), (8, Some(8)));
-                assert_eq!(it.next(), Some(8));
-                assert_eq!(it.size_hint(), (7, Some(7)));
-                assert_eq!(it.next_back(), Some(4));
-                assert_eq!(it.size_hint(), (6, Some(6)));
-                assert_eq!(it.next(), Some(7));
-                assert_eq!(it.size_hint(), (5, Some(5)));
-            }
-            assert!(d.is_empty());
-        }
-    }
-
-    #[test]
-    fn test_from_iter() {
-        use core::iter;
-        let v = vec!(1,2,3,4,5,6,7);
-        let deq: VecDeque<_> = v.iter().cloned().collect();
-        let u: Vec<_> = deq.iter().cloned().collect();
-        assert_eq!(u, v);
-
-        let seq = iter::count(0, 2).take(256);
-        let deq: VecDeque<_> = seq.collect();
-        for (i, &x) in deq.iter().enumerate() {
-            assert_eq!(2*i, x);
-        }
-        assert_eq!(deq.len(), 256);
-    }
-
-    #[test]
-    fn test_clone() {
-        let mut d = VecDeque::new();
-        d.push_front(17);
-        d.push_front(42);
-        d.push_back(137);
-        d.push_back(137);
-        assert_eq!(d.len(), 4);
-        let mut e = d.clone();
-        assert_eq!(e.len(), 4);
-        while !d.is_empty() {
-            assert_eq!(d.pop_back(), e.pop_back());
-        }
-        assert_eq!(d.len(), 0);
-        assert_eq!(e.len(), 0);
-    }
-
-    #[test]
-    fn test_eq() {
-        let mut d = VecDeque::new();
-        assert!(d == VecDeque::with_capacity(0));
-        d.push_front(137);
-        d.push_front(17);
-        d.push_front(42);
-        d.push_back(137);
-        let mut e = VecDeque::with_capacity(0);
-        e.push_back(42);
-        e.push_back(17);
-        e.push_back(137);
-        e.push_back(137);
-        assert!(&e == &d);
-        e.pop_back();
-        e.push_back(0);
-        assert!(e != d);
-        e.clear();
-        assert!(e == VecDeque::new());
-    }
-
-    #[test]
-    fn test_hash() {
-      let mut x = VecDeque::new();
-      let mut y = VecDeque::new();
-
-      x.push_back(1);
-      x.push_back(2);
-      x.push_back(3);
-
-      y.push_back(0);
-      y.push_back(1);
-      y.pop_front();
-      y.push_back(2);
-      y.push_back(3);
-
-      assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
-    }
-
-    #[test]
-    fn test_ord() {
-        let x = VecDeque::new();
-        let mut y = VecDeque::new();
-        y.push_back(1);
-        y.push_back(2);
-        y.push_back(3);
-        assert!(x < y);
-        assert!(y > x);
-        assert!(x <= x);
-        assert!(x >= x);
-    }
-
-    #[test]
-    fn test_show() {
-        let ringbuf: VecDeque<_> = (0..10).collect();
-        assert_eq!(format!("{:?}", ringbuf), "VecDeque [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
-
-        let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"].iter()
-                                                                        .cloned()
-                                                                        .collect();
-        assert_eq!(format!("{:?}", ringbuf), "VecDeque [\"just\", \"one\", \"test\", \"more\"]");
-    }
-
-    #[test]
-    fn test_drop() {
-        static mut drops: i32 = 0;
-        struct Elem;
-        impl Drop for Elem {
-            fn drop(&mut self) {
-                unsafe { drops += 1; }
-            }
-        }
-
-        let mut ring = VecDeque::new();
-        ring.push_back(Elem);
-        ring.push_front(Elem);
-        ring.push_back(Elem);
-        ring.push_front(Elem);
-        drop(ring);
-
-        assert_eq!(unsafe {drops}, 4);
-    }
-
-    #[test]
-    fn test_drop_with_pop() {
-        static mut drops: i32 = 0;
-        struct Elem;
-        impl Drop for Elem {
-            fn drop(&mut self) {
-                unsafe { drops += 1; }
-            }
-        }
-
-        let mut ring = VecDeque::new();
-        ring.push_back(Elem);
-        ring.push_front(Elem);
-        ring.push_back(Elem);
-        ring.push_front(Elem);
-
-        drop(ring.pop_back());
-        drop(ring.pop_front());
-        assert_eq!(unsafe {drops}, 2);
-
-        drop(ring);
-        assert_eq!(unsafe {drops}, 4);
-    }
-
-    #[test]
-    fn test_drop_clear() {
-        static mut drops: i32 = 0;
-        struct Elem;
-        impl Drop for Elem {
-            fn drop(&mut self) {
-                unsafe { drops += 1; }
-            }
-        }
-
-        let mut ring = VecDeque::new();
-        ring.push_back(Elem);
-        ring.push_front(Elem);
-        ring.push_back(Elem);
-        ring.push_front(Elem);
-        ring.clear();
-        assert_eq!(unsafe {drops}, 4);
-
-        drop(ring);
-        assert_eq!(unsafe {drops}, 4);
-    }
-
-    #[test]
-    fn test_reserve_grow() {
-        // test growth path A
-        // [T o o H] -> [T o o H . . . . ]
-        let mut ring = VecDeque::with_capacity(4);
-        for i in 0..3 {
-            ring.push_back(i);
-        }
-        ring.reserve(7);
-        for i in 0..3 {
-            assert_eq!(ring.pop_front(), Some(i));
-        }
-
-        // test growth path B
-        // [H T o o] -> [. T o o H . . . ]
-        let mut ring = VecDeque::with_capacity(4);
-        for i in 0..1 {
-            ring.push_back(i);
-            assert_eq!(ring.pop_front(), Some(i));
-        }
-        for i in 0..3 {
-            ring.push_back(i);
-        }
-        ring.reserve(7);
-        for i in 0..3 {
-            assert_eq!(ring.pop_front(), Some(i));
-        }
-
-        // test growth path C
-        // [o o H T] -> [o o H . . . . T ]
-        let mut ring = VecDeque::with_capacity(4);
-        for i in 0..3 {
-            ring.push_back(i);
-            assert_eq!(ring.pop_front(), Some(i));
-        }
-        for i in 0..3 {
-            ring.push_back(i);
-        }
-        ring.reserve(7);
-        for i in 0..3 {
-            assert_eq!(ring.pop_front(), Some(i));
-        }
-    }
-
-    #[test]
-    fn test_get() {
-        let mut ring = VecDeque::new();
-        ring.push_back(0);
-        assert_eq!(ring.get(0), Some(&0));
-        assert_eq!(ring.get(1), None);
-
-        ring.push_back(1);
-        assert_eq!(ring.get(0), Some(&0));
-        assert_eq!(ring.get(1), Some(&1));
-        assert_eq!(ring.get(2), None);
-
-        ring.push_back(2);
-        assert_eq!(ring.get(0), Some(&0));
-        assert_eq!(ring.get(1), Some(&1));
-        assert_eq!(ring.get(2), Some(&2));
-        assert_eq!(ring.get(3), None);
-
-        assert_eq!(ring.pop_front(), Some(0));
-        assert_eq!(ring.get(0), Some(&1));
-        assert_eq!(ring.get(1), Some(&2));
-        assert_eq!(ring.get(2), None);
-
-        assert_eq!(ring.pop_front(), Some(1));
-        assert_eq!(ring.get(0), Some(&2));
-        assert_eq!(ring.get(1), None);
-
-        assert_eq!(ring.pop_front(), Some(2));
-        assert_eq!(ring.get(0), None);
-        assert_eq!(ring.get(1), None);
-    }
-
-    #[test]
-    fn test_get_mut() {
-        let mut ring = VecDeque::new();
-        for i in 0..3 {
-            ring.push_back(i);
-        }
-
-        match ring.get_mut(1) {
-            Some(x) => *x = -1,
-            None => ()
-        };
-
-        assert_eq!(ring.get_mut(0), Some(&mut 0));
-        assert_eq!(ring.get_mut(1), Some(&mut -1));
-        assert_eq!(ring.get_mut(2), Some(&mut 2));
-        assert_eq!(ring.get_mut(3), None);
-
-        assert_eq!(ring.pop_front(), Some(0));
-        assert_eq!(ring.get_mut(0), Some(&mut -1));
-        assert_eq!(ring.get_mut(1), Some(&mut 2));
-        assert_eq!(ring.get_mut(2), None);
-    }
-
     #[test]
     fn test_swap_front_back_remove() {
         fn test(back: bool) {
@@ -2679,7 +1897,7 @@ mod tests {
         // len is the length *after* insertion
         for len in 1..cap {
             // 0, 1, 2, .., len - 1
-            let expected = iter::count(0, 1).take(len).collect();
+            let expected = (0..).take(len).collect();
             for tail_pos in 0..cap {
                 for to_insert in 0..len {
                     tester.tail = tail_pos;
@@ -2712,7 +1930,7 @@ mod tests {
         // len is the length *after* removal
         for len in 0..cap - 1 {
             // 0, 1, 2, .., len - 1
-            let expected = iter::count(0, 1).take(len).collect();
+            let expected = (0..).take(len).collect();
             for tail_pos in 0..cap {
                 for to_remove in 0..len + 1 {
                     tester.tail = tail_pos;
@@ -2750,7 +1968,7 @@ mod tests {
 
         for len in 0..cap + 1 {
             // 0, 1, 2, .., len - 1
-            let expected = iter::count(0, 1).take(len).collect();
+            let expected = (0..).take(len).collect();
             for tail_pos in 0..max_cap + 1 {
                 tester.tail = tail_pos;
                 tester.head = tail_pos;
@@ -2767,74 +1985,6 @@ mod tests {
         }
     }
 
-    #[test]
-    fn test_front() {
-        let mut ring = VecDeque::new();
-        ring.push_back(10);
-        ring.push_back(20);
-        assert_eq!(ring.front(), Some(&10));
-        ring.pop_front();
-        assert_eq!(ring.front(), Some(&20));
-        ring.pop_front();
-        assert_eq!(ring.front(), None);
-    }
-
-    #[test]
-    fn test_as_slices() {
-        let mut ring: VecDeque<i32> = VecDeque::with_capacity(127);
-        let cap = ring.capacity() as i32;
-        let first = cap/2;
-        let last  = cap - first;
-        for i in 0..first {
-            ring.push_back(i);
-
-            let (left, right) = ring.as_slices();
-            let expected: Vec<_> = (0..i+1).collect();
-            assert_eq!(left, expected);
-            assert_eq!(right, []);
-        }
-
-        for j in -last..0 {
-            ring.push_front(j);
-            let (left, right) = ring.as_slices();
-            let expected_left: Vec<_> = (-last..j+1).rev().collect();
-            let expected_right: Vec<_> = (0..first).collect();
-            assert_eq!(left, expected_left);
-            assert_eq!(right, expected_right);
-        }
-
-        assert_eq!(ring.len() as i32, cap);
-        assert_eq!(ring.capacity() as i32, cap);
-    }
-
-    #[test]
-    fn test_as_mut_slices() {
-        let mut ring: VecDeque<i32> = VecDeque::with_capacity(127);
-        let cap = ring.capacity() as i32;
-        let first = cap/2;
-        let last  = cap - first;
-        for i in 0..first {
-            ring.push_back(i);
-
-            let (left, right) = ring.as_mut_slices();
-            let expected: Vec<_> = (0..i+1).collect();
-            assert_eq!(left, expected);
-            assert_eq!(right, []);
-        }
-
-        for j in -last..0 {
-            ring.push_front(j);
-            let (left, right) = ring.as_mut_slices();
-            let expected_left: Vec<_> = (-last..j+1).rev().collect();
-            let expected_right: Vec<_> = (0..first).collect();
-            assert_eq!(left, expected_left);
-            assert_eq!(right, expected_right);
-        }
-
-        assert_eq!(ring.len() as i32, cap);
-        assert_eq!(ring.capacity() as i32, cap);
-    }
-
     #[test]
     fn test_split_off() {
         // This test checks that every single combination of tail position, length, and
@@ -2851,9 +2001,9 @@ mod tests {
             // index to split at
             for at in 0..len + 1 {
                 // 0, 1, 2, .., at - 1 (may be empty)
-                let expected_self = iter::count(0, 1).take(at).collect();
+                let expected_self = (0..).take(at).collect();
                 // at, at + 1, .., len - 1 (may be empty)
-                let expected_other = iter::count(at, 1).take(len - at).collect();
+                let expected_other = (at..).take(len - at).collect();
 
                 for tail_pos in 0..cap {
                     tester.tail = tail_pos;
@@ -2872,25 +2022,4 @@ mod tests {
             }
         }
     }
-
-    #[test]
-    fn test_append() {
-        let mut a: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
-        let mut b: VecDeque<_> = vec![4, 5, 6].into_iter().collect();
-
-        // normal append
-        a.append(&mut b);
-        assert_eq!(a.iter().cloned().collect(), vec![1, 2, 3, 4, 5, 6]);
-        assert_eq!(b.iter().cloned().collect(), vec![]);
-
-        // append nothing to something
-        a.append(&mut b);
-        assert_eq!(a.iter().cloned().collect(), vec![1, 2, 3, 4, 5, 6]);
-        assert_eq!(b.iter().cloned().collect(), vec![]);
-
-        // append something to nothing
-        b.append(&mut a);
-        assert_eq!(b.iter().cloned().collect(), vec![1, 2, 3, 4, 5, 6]);
-        assert_eq!(a.iter().cloned().collect(), vec![]);
-    }
 }
index 54589a3142345833b443956f65a17227b35fe915..8900c7950458220f70c12816a5ea1d9995d15b60 100644 (file)
@@ -17,14 +17,13 @@ use self::Entry::*;
 
 use core::prelude::*;
 
-use core::cmp::Ordering;
+use core::cmp::{max, Ordering};
 use core::default::Default;
 use core::fmt;
 use core::hash::{Hash, Hasher};
-#[cfg(stage0)] use core::hash::Writer;
 use core::iter::{Enumerate, FilterMap, Map, FromIterator, IntoIterator};
 use core::iter;
-use core::mem::replace;
+use core::mem::{replace, swap};
 use core::ops::{Index, IndexMut};
 
 use {vec, slice};
@@ -35,6 +34,7 @@ use vec::Vec;
 /// # Examples
 ///
 /// ```
+/// # #![feature(collections)]
 /// use std::collections::VecMap;
 ///
 /// let mut months = VecMap::new();
@@ -68,26 +68,28 @@ pub struct VecMap<V> {
 }
 
 /// A view into a single entry in a map, which may either be vacant or occupied.
-#[unstable(feature = "collections",
-           reason = "precise API still under development")]
+
+#[stable(feature = "rust1", since = "1.0.0")]
 pub enum Entry<'a, V:'a> {
     /// A vacant Entry
+    #[stable(feature = "rust1", since = "1.0.0")]
     Vacant(VacantEntry<'a, V>),
+
     /// An occupied Entry
+    #[stable(feature = "rust1", since = "1.0.0")]
     Occupied(OccupiedEntry<'a, V>),
 }
 
 /// A vacant Entry.
-#[unstable(feature = "collections",
-           reason = "precise API still under development")]
+
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct VacantEntry<'a, V:'a> {
     map: &'a mut VecMap<V>,
     index: usize,
 }
 
 /// An occupied Entry.
-#[unstable(feature = "collections",
-           reason = "precise API still under development")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct OccupiedEntry<'a, V:'a> {
     map: &'a mut VecMap<V>,
     index: usize,
@@ -113,21 +115,7 @@ impl<V:Clone> Clone for VecMap<V> {
     }
 }
 
-#[cfg(stage0)]
-impl<S: Writer + Hasher, V: Hash<S>> Hash<S> for VecMap<V> {
-    fn hash(&self, state: &mut S) {
-        // In order to not traverse the `VecMap` twice, count the elements
-        // during iteration.
-        let mut count: usize = 0;
-        for elt in self {
-            elt.hash(state);
-            count += 1;
-        }
-        count.hash(state);
-    }
-}
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg(not(stage0))]
 impl<V: Hash> Hash for VecMap<V> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         // In order to not traverse the `VecMap` twice, count the elements
@@ -147,6 +135,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     /// let mut map: VecMap<&str> = VecMap::new();
     /// ```
@@ -159,6 +148,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     /// let mut map: VecMap<&str> = VecMap::with_capacity(10);
     /// ```
@@ -173,6 +163,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     /// let map: VecMap<String> = VecMap::with_capacity(10);
     /// assert!(map.capacity() >= 10);
@@ -192,6 +183,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     /// let mut map: VecMap<&str> = VecMap::new();
     /// map.reserve_len(10);
@@ -216,6 +208,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     /// let mut map: VecMap<&str> = VecMap::new();
     /// map.reserve_len_exact(10);
@@ -255,6 +248,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -283,6 +277,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -314,6 +309,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -323,7 +319,7 @@ impl<V> VecMap<V> {
     ///
     /// let vec: Vec<(usize, &str)> = map.into_iter().collect();
     ///
-    /// assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]);
+    /// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_iter(self) -> IntoIter<V> {
@@ -335,6 +331,97 @@ impl<V> VecMap<V> {
         IntoIter { iter: self.v.into_iter().enumerate().filter_map(filter) }
     }
 
+    /// Moves all elements from `other` into the map while overwriting existing keys.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(collections)]
+    /// use std::collections::VecMap;
+    ///
+    /// let mut a = VecMap::new();
+    /// a.insert(1, "a");
+    /// a.insert(2, "b");
+    ///
+    /// let mut b = VecMap::new();
+    /// b.insert(3, "c");
+    /// b.insert(4, "d");
+    ///
+    /// a.append(&mut b);
+    ///
+    /// assert_eq!(a.len(), 4);
+    /// assert_eq!(b.len(), 0);
+    /// assert_eq!(a[1], "a");
+    /// assert_eq!(a[2], "b");
+    /// assert_eq!(a[3], "c");
+    /// assert_eq!(a[4], "d");
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "recently added as part of collections reform 2")]
+    pub fn append(&mut self, other: &mut Self) {
+        self.extend(other.drain());
+    }
+
+    /// Splits the collection into two at the given key.
+    ///
+    /// Returns a newly allocated `Self`. `self` contains elements `[0, at)`,
+    /// and the returned `Self` contains elements `[at, max_key)`.
+    ///
+    /// Note that the capacity of `self` does not change.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(collections)]
+    /// use std::collections::VecMap;
+    ///
+    /// let mut a = VecMap::new();
+    /// a.insert(1, "a");
+    /// a.insert(2, "b");
+    /// a.insert(3, "c");
+    /// a.insert(4, "d");
+    ///
+    /// let b = a.split_off(3);
+    ///
+    /// assert_eq!(a[1], "a");
+    /// assert_eq!(a[2], "b");
+    ///
+    /// assert_eq!(b[3], "c");
+    /// assert_eq!(b[4], "d");
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "recently added as part of collections reform 2")]
+    pub fn split_off(&mut self, at: usize) -> Self {
+        let mut other = VecMap::new();
+
+        if at == 0 {
+            // Move all elements to other
+            swap(self, &mut other);
+            return other
+        } else if at > self.v.len() {
+            // No elements to copy
+            return other;
+        }
+
+        // Look up the index of the first non-None item
+        let first_index = self.v.iter().position(|el| el.is_some());
+        let start_index = match first_index {
+            Some(index) => max(at, index),
+            None => {
+                // self has no elements
+                return other;
+            }
+        };
+
+        // Fill the new VecMap with `None`s until `start_index`
+        other.v.extend((0..start_index).map(|_| None));
+
+        // Move elements beginning with `start_index` from `self` into `other`
+        other.v.extend(self.v[start_index..].iter_mut().map(|el| el.take()));
+
+        other
+    }
+
     /// Returns an iterator visiting all key-value pairs in ascending order of
     /// the keys, emptying (but not consuming) the original `VecMap`.
     /// The iterator's element type is `(usize, &'r V)`. Keeps the allocated memory for reuse.
@@ -342,6 +429,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -351,7 +439,7 @@ impl<V> VecMap<V> {
     ///
     /// let vec: Vec<(usize, &str)> = map.drain().collect();
     ///
-    /// assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]);
+    /// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
     /// ```
     #[unstable(feature = "collections",
                reason = "matches collection reform specification, waiting for dust to settle")]
@@ -369,6 +457,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     ///
     /// let mut a = VecMap::new();
@@ -386,6 +475,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     ///
     /// let mut a = VecMap::new();
@@ -403,6 +493,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     ///
     /// let mut a = VecMap::new();
@@ -418,6 +509,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -442,6 +534,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -460,6 +553,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -488,6 +582,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -513,6 +608,7 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
     ///
     /// let mut map = VecMap::new();
@@ -534,22 +630,14 @@ impl<V> VecMap<V> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(collections)]
     /// use std::collections::VecMap;
-    /// use std::collections::vec_map::Entry;
     ///
     /// let mut count: VecMap<u32> = VecMap::new();
     ///
     /// // count the number of occurrences of numbers in the vec
-    /// for x in vec![1, 2, 1, 2, 3, 4, 1, 2, 4].iter() {
-    ///     match count.entry(*x) {
-    ///         Entry::Vacant(view) => {
-    ///             view.insert(1);
-    ///         },
-    ///         Entry::Occupied(mut view) => {
-    ///             let v = view.get_mut();
-    ///             *v += 1;
-    ///         },
-    ///     }
+    /// for x in vec![1, 2, 1, 2, 3, 4, 1, 2, 4] {
+    ///     *count.entry(x).or_insert(0) += 1;
     /// }
     ///
     /// assert_eq!(count[1], 3);
@@ -577,7 +665,9 @@ impl<V> VecMap<V> {
 
 impl<'a, V> Entry<'a, V> {
     #[unstable(feature = "collections",
-               reason = "matches collection reform v2 specification, waiting for dust to settle")]
+               reason = "will soon be replaced by or_insert")]
+    #[deprecated(since = "1.0",
+                reason = "replaced with more ergonomic `or_insert` and `or_insert_with`")]
     /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
     pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, V>> {
         match self {
@@ -585,6 +675,28 @@ impl<'a, V> Entry<'a, V> {
             Vacant(entry) => Err(entry),
         }
     }
+
+    #[unstable(feature = "collections",
+               reason = "matches entry v3 specification, waiting for dust to settle")]
+    /// Ensures a value is in the entry by inserting the default if empty, and returns
+    /// a mutable reference to the value in the entry.
+    pub fn or_insert(self, default: V) -> &'a mut V {
+        match self {
+            Occupied(entry) => entry.into_mut(),
+            Vacant(entry) => entry.insert(default),
+        }
+    }
+
+    #[unstable(feature = "collections",
+               reason = "matches entry v3 specification, waiting for dust to settle")]
+    /// Ensures a value is in the entry by inserting the result of the default function if empty,
+    /// and returns a mutable reference to the value in the entry.
+    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
+        match self {
+            Occupied(entry) => entry.into_mut(),
+            Vacant(entry) => entry.insert(default()),
+        }
+    }
 }
 
 impl<'a, V> VacantEntry<'a, V> {
@@ -665,7 +777,7 @@ impl<V: Ord> Ord for VecMap<V> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<V: fmt::Debug> fmt::Debug for VecMap<V> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "VecMap {{"));
+        try!(write!(f, "{{"));
 
         for (i, (k, v)) in self.iter().enumerate() {
             if i != 0 { try!(write!(f, ", ")); }
@@ -728,7 +840,16 @@ impl<V> Index<usize> for VecMap<V> {
     type Output = V;
 
     #[inline]
-    fn index<'a>(&'a self, i: &usize) -> &'a V {
+    fn index<'a>(&'a self, i: usize) -> &'a V {
+        self.get(&i).expect("key not present")
+    }
+}
+
+impl<'a,V> Index<&'a usize> for VecMap<V> {
+    type Output = V;
+
+    #[inline]
+    fn index(&self, i: &usize) -> &V {
         self.get(i).expect("key not present")
     }
 }
@@ -736,7 +857,15 @@ impl<V> Index<usize> for VecMap<V> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<V> IndexMut<usize> for VecMap<V> {
     #[inline]
-    fn index_mut<'a>(&'a mut self, i: &usize) -> &'a mut V {
+    fn index_mut(&mut self, i: usize) -> &mut V {
+        self.get_mut(&i).expect("key not present")
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, V> IndexMut<&'a usize> for VecMap<V> {
+    #[inline]
+    fn index_mut(&mut self, i: &usize) -> &mut V {
         self.get_mut(i).expect("key not present")
     }
 }
@@ -930,431 +1059,3 @@ impl<V> Iterator for IntoIter<V> {
 impl<V> DoubleEndedIterator for IntoIter<V> {
     fn next_back(&mut self) -> Option<(usize, V)> { self.iter.next_back() }
 }
-
-#[cfg(test)]
-mod test_map {
-    use prelude::*;
-    use core::hash::{hash, SipHasher};
-
-    use super::VecMap;
-    use super::Entry::{Occupied, Vacant};
-
-    #[test]
-    fn test_get_mut() {
-        let mut m = VecMap::new();
-        assert!(m.insert(1, 12).is_none());
-        assert!(m.insert(2, 8).is_none());
-        assert!(m.insert(5, 14).is_none());
-        let new = 100;
-        match m.get_mut(&5) {
-            None => panic!(), Some(x) => *x = new
-        }
-        assert_eq!(m.get(&5), Some(&new));
-    }
-
-    #[test]
-    fn test_len() {
-        let mut map = VecMap::new();
-        assert_eq!(map.len(), 0);
-        assert!(map.is_empty());
-        assert!(map.insert(5, 20).is_none());
-        assert_eq!(map.len(), 1);
-        assert!(!map.is_empty());
-        assert!(map.insert(11, 12).is_none());
-        assert_eq!(map.len(), 2);
-        assert!(!map.is_empty());
-        assert!(map.insert(14, 22).is_none());
-        assert_eq!(map.len(), 3);
-        assert!(!map.is_empty());
-    }
-
-    #[test]
-    fn test_clear() {
-        let mut map = VecMap::new();
-        assert!(map.insert(5, 20).is_none());
-        assert!(map.insert(11, 12).is_none());
-        assert!(map.insert(14, 22).is_none());
-        map.clear();
-        assert!(map.is_empty());
-        assert!(map.get(&5).is_none());
-        assert!(map.get(&11).is_none());
-        assert!(map.get(&14).is_none());
-    }
-
-    #[test]
-    fn test_insert() {
-        let mut m = VecMap::new();
-        assert_eq!(m.insert(1, 2), None);
-        assert_eq!(m.insert(1, 3), Some(2));
-        assert_eq!(m.insert(1, 4), Some(3));
-    }
-
-    #[test]
-    fn test_remove() {
-        let mut m = VecMap::new();
-        m.insert(1, 2);
-        assert_eq!(m.remove(&1), Some(2));
-        assert_eq!(m.remove(&1), None);
-    }
-
-    #[test]
-    fn test_keys() {
-        let mut map = VecMap::new();
-        map.insert(1, 'a');
-        map.insert(2, 'b');
-        map.insert(3, 'c');
-        let keys: Vec<_> = map.keys().collect();
-        assert_eq!(keys.len(), 3);
-        assert!(keys.contains(&1));
-        assert!(keys.contains(&2));
-        assert!(keys.contains(&3));
-    }
-
-    #[test]
-    fn test_values() {
-        let mut map = VecMap::new();
-        map.insert(1, 'a');
-        map.insert(2, 'b');
-        map.insert(3, 'c');
-        let values: Vec<_> = map.values().cloned().collect();
-        assert_eq!(values.len(), 3);
-        assert!(values.contains(&'a'));
-        assert!(values.contains(&'b'));
-        assert!(values.contains(&'c'));
-    }
-
-    #[test]
-    fn test_iterator() {
-        let mut m = VecMap::new();
-
-        assert!(m.insert(0, 1).is_none());
-        assert!(m.insert(1, 2).is_none());
-        assert!(m.insert(3, 5).is_none());
-        assert!(m.insert(6, 10).is_none());
-        assert!(m.insert(10, 11).is_none());
-
-        let mut it = m.iter();
-        assert_eq!(it.size_hint(), (0, Some(11)));
-        assert_eq!(it.next().unwrap(), (0, &1));
-        assert_eq!(it.size_hint(), (0, Some(10)));
-        assert_eq!(it.next().unwrap(), (1, &2));
-        assert_eq!(it.size_hint(), (0, Some(9)));
-        assert_eq!(it.next().unwrap(), (3, &5));
-        assert_eq!(it.size_hint(), (0, Some(7)));
-        assert_eq!(it.next().unwrap(), (6, &10));
-        assert_eq!(it.size_hint(), (0, Some(4)));
-        assert_eq!(it.next().unwrap(), (10, &11));
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_iterator_size_hints() {
-        let mut m = VecMap::new();
-
-        assert!(m.insert(0, 1).is_none());
-        assert!(m.insert(1, 2).is_none());
-        assert!(m.insert(3, 5).is_none());
-        assert!(m.insert(6, 10).is_none());
-        assert!(m.insert(10, 11).is_none());
-
-        assert_eq!(m.iter().size_hint(), (0, Some(11)));
-        assert_eq!(m.iter().rev().size_hint(), (0, Some(11)));
-        assert_eq!(m.iter_mut().size_hint(), (0, Some(11)));
-        assert_eq!(m.iter_mut().rev().size_hint(), (0, Some(11)));
-    }
-
-    #[test]
-    fn test_mut_iterator() {
-        let mut m = VecMap::new();
-
-        assert!(m.insert(0, 1).is_none());
-        assert!(m.insert(1, 2).is_none());
-        assert!(m.insert(3, 5).is_none());
-        assert!(m.insert(6, 10).is_none());
-        assert!(m.insert(10, 11).is_none());
-
-        for (k, v) in &mut m {
-            *v += k as isize;
-        }
-
-        let mut it = m.iter();
-        assert_eq!(it.next().unwrap(), (0, &1));
-        assert_eq!(it.next().unwrap(), (1, &3));
-        assert_eq!(it.next().unwrap(), (3, &8));
-        assert_eq!(it.next().unwrap(), (6, &16));
-        assert_eq!(it.next().unwrap(), (10, &21));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_rev_iterator() {
-        let mut m = VecMap::new();
-
-        assert!(m.insert(0, 1).is_none());
-        assert!(m.insert(1, 2).is_none());
-        assert!(m.insert(3, 5).is_none());
-        assert!(m.insert(6, 10).is_none());
-        assert!(m.insert(10, 11).is_none());
-
-        let mut it = m.iter().rev();
-        assert_eq!(it.next().unwrap(), (10, &11));
-        assert_eq!(it.next().unwrap(), (6, &10));
-        assert_eq!(it.next().unwrap(), (3, &5));
-        assert_eq!(it.next().unwrap(), (1, &2));
-        assert_eq!(it.next().unwrap(), (0, &1));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_mut_rev_iterator() {
-        let mut m = VecMap::new();
-
-        assert!(m.insert(0, 1).is_none());
-        assert!(m.insert(1, 2).is_none());
-        assert!(m.insert(3, 5).is_none());
-        assert!(m.insert(6, 10).is_none());
-        assert!(m.insert(10, 11).is_none());
-
-        for (k, v) in m.iter_mut().rev() {
-            *v += k as isize;
-        }
-
-        let mut it = m.iter();
-        assert_eq!(it.next().unwrap(), (0, &1));
-        assert_eq!(it.next().unwrap(), (1, &3));
-        assert_eq!(it.next().unwrap(), (3, &8));
-        assert_eq!(it.next().unwrap(), (6, &16));
-        assert_eq!(it.next().unwrap(), (10, &21));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_move_iter() {
-        let mut m = VecMap::new();
-        m.insert(1, box 2);
-        let mut called = false;
-        for (k, v) in m {
-            assert!(!called);
-            called = true;
-            assert_eq!(k, 1);
-            assert_eq!(v, box 2);
-        }
-        assert!(called);
-    }
-
-    #[test]
-    fn test_drain_iterator() {
-        let mut map = VecMap::new();
-        map.insert(1, "a");
-        map.insert(3, "c");
-        map.insert(2, "b");
-
-        let vec: Vec<_> = map.drain().collect();
-
-        assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]);
-        assert_eq!(map.len(), 0);
-    }
-
-    #[test]
-    fn test_show() {
-        let mut map = VecMap::new();
-        let empty = VecMap::<i32>::new();
-
-        map.insert(1, 2);
-        map.insert(3, 4);
-
-        let map_str = format!("{:?}", map);
-        assert!(map_str == "VecMap {1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
-        assert_eq!(format!("{:?}", empty), "VecMap {}");
-    }
-
-    #[test]
-    fn test_clone() {
-        let mut a = VecMap::new();
-
-        a.insert(1, 'x');
-        a.insert(4, 'y');
-        a.insert(6, 'z');
-
-        assert!(a.clone() == a);
-    }
-
-    #[test]
-    fn test_eq() {
-        let mut a = VecMap::new();
-        let mut b = VecMap::new();
-
-        assert!(a == b);
-        assert!(a.insert(0, 5).is_none());
-        assert!(a != b);
-        assert!(b.insert(0, 4).is_none());
-        assert!(a != b);
-        assert!(a.insert(5, 19).is_none());
-        assert!(a != b);
-        assert!(!b.insert(0, 5).is_none());
-        assert!(a != b);
-        assert!(b.insert(5, 19).is_none());
-        assert!(a == b);
-
-        a = VecMap::new();
-        b = VecMap::with_capacity(1);
-        assert!(a == b);
-    }
-
-    #[test]
-    fn test_lt() {
-        let mut a = VecMap::new();
-        let mut b = VecMap::new();
-
-        assert!(!(a < b) && !(b < a));
-        assert!(b.insert(2, 5).is_none());
-        assert!(a < b);
-        assert!(a.insert(2, 7).is_none());
-        assert!(!(a < b) && b < a);
-        assert!(b.insert(1, 0).is_none());
-        assert!(b < a);
-        assert!(a.insert(0, 6).is_none());
-        assert!(a < b);
-        assert!(a.insert(6, 2).is_none());
-        assert!(a < b && !(b < a));
-    }
-
-    #[test]
-    fn test_ord() {
-        let mut a = VecMap::new();
-        let mut b = VecMap::new();
-
-        assert!(a <= b && a >= b);
-        assert!(a.insert(1, 1).is_none());
-        assert!(a > b && a >= b);
-        assert!(b < a && b <= a);
-        assert!(b.insert(2, 2).is_none());
-        assert!(b > a && b >= a);
-        assert!(a < b && a <= b);
-    }
-
-    #[test]
-    fn test_hash() {
-        let mut x = VecMap::new();
-        let mut y = VecMap::new();
-
-        assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
-        x.insert(1, 'a');
-        x.insert(2, 'b');
-        x.insert(3, 'c');
-
-        y.insert(3, 'c');
-        y.insert(2, 'b');
-        y.insert(1, 'a');
-
-        assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
-
-        x.insert(1000, 'd');
-        x.remove(&1000);
-
-        assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
-    }
-
-    #[test]
-    fn test_from_iter() {
-        let xs = vec![(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')];
-
-        let map: VecMap<_> = xs.iter().cloned().collect();
-
-        for &(k, v) in &xs {
-            assert_eq!(map.get(&k), Some(&v));
-        }
-    }
-
-    #[test]
-    fn test_index() {
-        let mut map = VecMap::new();
-
-        map.insert(1, 2);
-        map.insert(2, 1);
-        map.insert(3, 4);
-
-        assert_eq!(map[3], 4);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_index_nonexistent() {
-        let mut map = VecMap::new();
-
-        map.insert(1, 2);
-        map.insert(2, 1);
-        map.insert(3, 4);
-
-        map[4];
-    }
-
-    #[test]
-    fn test_entry(){
-        let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
-
-        let mut map: VecMap<_> = xs.iter().cloned().collect();
-
-        // Existing key (insert)
-        match map.entry(1) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                assert_eq!(view.get(), &10);
-                assert_eq!(view.insert(100), 10);
-            }
-        }
-        assert_eq!(map.get(&1).unwrap(), &100);
-        assert_eq!(map.len(), 6);
-
-
-        // Existing key (update)
-        match map.entry(2) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                let v = view.get_mut();
-                *v *= 10;
-            }
-        }
-        assert_eq!(map.get(&2).unwrap(), &200);
-        assert_eq!(map.len(), 6);
-
-        // Existing key (take)
-        match map.entry(3) {
-            Vacant(_) => unreachable!(),
-            Occupied(view) => {
-                assert_eq!(view.remove(), 30);
-            }
-        }
-        assert_eq!(map.get(&3), None);
-        assert_eq!(map.len(), 5);
-
-
-        // Inexistent key (insert)
-        match map.entry(10) {
-            Occupied(_) => unreachable!(),
-            Vacant(view) => {
-                assert_eq!(*view.insert(1000), 1000);
-            }
-        }
-        assert_eq!(map.get(&10).unwrap(), &1000);
-        assert_eq!(map.len(), 6);
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    use super::VecMap;
-
-    map_insert_rand_bench!{insert_rand_100,    100,    VecMap}
-    map_insert_rand_bench!{insert_rand_10_000, 10_000, VecMap}
-
-    map_insert_seq_bench!{insert_seq_100,    100,    VecMap}
-    map_insert_seq_bench!{insert_seq_10_000, 10_000, VecMap}
-
-    map_find_rand_bench!{find_rand_100,    100,    VecMap}
-    map_find_rand_bench!{find_rand_10_000, 10_000, VecMap}
-
-    map_find_seq_bench!{find_seq_100,    100,    VecMap}
-    map_find_seq_bench!{find_seq_10_000, 10_000, VecMap}
-}
diff --git a/src/libcollectionstest/bench.rs b/src/libcollectionstest/bench.rs
new file mode 100644 (file)
index 0000000..8f2e71b
--- /dev/null
@@ -0,0 +1,122 @@
+// Copyright 2013-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.
+
+macro_rules! map_insert_rand_bench {
+    ($name: ident, $n: expr, $map: ident) => (
+        #[bench]
+        pub fn $name(b: &mut ::test::Bencher) {
+            use std::rand;
+            use std::rand::Rng;
+            use test::black_box;
+
+            let n: usize = $n;
+            let mut map = $map::new();
+            // setup
+            let mut rng = rand::weak_rng();
+
+            for _ in 0..n {
+                let i = rng.gen::<usize>() % n;
+                map.insert(i, i);
+            }
+
+            // measure
+            b.iter(|| {
+                let k = rng.gen::<usize>() % n;
+                map.insert(k, k);
+                map.remove(&k);
+            });
+            black_box(map);
+        }
+    )
+}
+
+macro_rules! map_insert_seq_bench {
+    ($name: ident, $n: expr, $map: ident) => (
+        #[bench]
+        pub fn $name(b: &mut ::test::Bencher) {
+            use test::black_box;
+
+            let mut map = $map::new();
+            let n: usize = $n;
+            // setup
+            for i in 0..n {
+                map.insert(i * 2, i * 2);
+            }
+
+            // measure
+            let mut i = 1;
+            b.iter(|| {
+                map.insert(i, i);
+                map.remove(&i);
+                i = (i + 2) % n;
+            });
+            black_box(map);
+        }
+    )
+}
+
+macro_rules! map_find_rand_bench {
+    ($name: ident, $n: expr, $map: ident) => (
+        #[bench]
+        pub fn $name(b: &mut ::test::Bencher) {
+            use std::iter::Iterator;
+            use std::rand::Rng;
+            use std::rand;
+            use std::vec::Vec;
+            use test::black_box;
+
+            let mut map = $map::new();
+            let n: usize = $n;
+
+            // setup
+            let mut rng = rand::weak_rng();
+            let mut keys: Vec<_> = (0..n).map(|_| rng.gen::<usize>() % n).collect();
+
+            for &k in &keys {
+                map.insert(k, k);
+            }
+
+            rng.shuffle(&mut keys);
+
+            // measure
+            let mut i = 0;
+            b.iter(|| {
+                let t = map.get(&keys[i]);
+                i = (i + 1) % n;
+                black_box(t);
+            })
+        }
+    )
+}
+
+macro_rules! map_find_seq_bench {
+    ($name: ident, $n: expr, $map: ident) => (
+        #[bench]
+        pub fn $name(b: &mut ::test::Bencher) {
+            use test::black_box;
+
+            let mut map = $map::new();
+            let n: usize = $n;
+
+            // setup
+            for i in 0..n {
+                map.insert(i, i);
+            }
+
+            // measure
+            let mut i = 0;
+            b.iter(|| {
+                let x = map.get(&i);
+                i = (i + 1) % n;
+                black_box(x);
+            })
+        }
+    )
+}
diff --git a/src/libcollectionstest/binary_heap.rs b/src/libcollectionstest/binary_heap.rs
new file mode 100644 (file)
index 0000000..47a366b
--- /dev/null
@@ -0,0 +1,219 @@
+// Copyright 2013-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 std::collections::BinaryHeap;
+
+#[test]
+fn test_iterator() {
+    let data = vec![5, 9, 3];
+    let iterout = [9, 5, 3];
+    let heap = BinaryHeap::from_vec(data);
+    let mut i = 0;
+    for el in &heap {
+        assert_eq!(*el, iterout[i]);
+        i += 1;
+    }
+}
+
+#[test]
+fn test_iterator_reverse() {
+    let data = vec![5, 9, 3];
+    let iterout = vec![3, 5, 9];
+    let pq = BinaryHeap::from_vec(data);
+
+    let v: Vec<_> = pq.iter().rev().cloned().collect();
+    assert_eq!(v, iterout);
+}
+
+#[test]
+fn test_move_iter() {
+    let data = vec![5, 9, 3];
+    let iterout = vec![9, 5, 3];
+    let pq = BinaryHeap::from_vec(data);
+
+    let v: Vec<_> = pq.into_iter().collect();
+    assert_eq!(v, iterout);
+}
+
+#[test]
+fn test_move_iter_size_hint() {
+    let data = vec![5, 9];
+    let pq = BinaryHeap::from_vec(data);
+
+    let mut it = pq.into_iter();
+
+    assert_eq!(it.size_hint(), (2, Some(2)));
+    assert_eq!(it.next(), Some(9));
+
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(it.next(), Some(5));
+
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_move_iter_reverse() {
+    let data = vec![5, 9, 3];
+    let iterout = vec![3, 5, 9];
+    let pq = BinaryHeap::from_vec(data);
+
+    let v: Vec<_> = pq.into_iter().rev().collect();
+    assert_eq!(v, iterout);
+}
+
+#[test]
+fn test_peek_and_pop() {
+    let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
+    let mut sorted = data.clone();
+    sorted.sort();
+    let mut heap = BinaryHeap::from_vec(data);
+    while !heap.is_empty() {
+        assert_eq!(heap.peek().unwrap(), sorted.last().unwrap());
+        assert_eq!(heap.pop().unwrap(), sorted.pop().unwrap());
+    }
+}
+
+#[test]
+fn test_push() {
+    let mut heap = BinaryHeap::from_vec(vec![2, 4, 9]);
+    assert_eq!(heap.len(), 3);
+    assert!(*heap.peek().unwrap() == 9);
+    heap.push(11);
+    assert_eq!(heap.len(), 4);
+    assert!(*heap.peek().unwrap() == 11);
+    heap.push(5);
+    assert_eq!(heap.len(), 5);
+    assert!(*heap.peek().unwrap() == 11);
+    heap.push(27);
+    assert_eq!(heap.len(), 6);
+    assert!(*heap.peek().unwrap() == 27);
+    heap.push(3);
+    assert_eq!(heap.len(), 7);
+    assert!(*heap.peek().unwrap() == 27);
+    heap.push(103);
+    assert_eq!(heap.len(), 8);
+    assert!(*heap.peek().unwrap() == 103);
+}
+
+#[test]
+fn test_push_unique() {
+    let mut heap = BinaryHeap::<Box<_>>::from_vec(vec![box 2, box 4, box 9]);
+    assert_eq!(heap.len(), 3);
+    assert!(*heap.peek().unwrap() == box 9);
+    heap.push(box 11);
+    assert_eq!(heap.len(), 4);
+    assert!(*heap.peek().unwrap() == box 11);
+    heap.push(box 5);
+    assert_eq!(heap.len(), 5);
+    assert!(*heap.peek().unwrap() == box 11);
+    heap.push(box 27);
+    assert_eq!(heap.len(), 6);
+    assert!(*heap.peek().unwrap() == box 27);
+    heap.push(box 3);
+    assert_eq!(heap.len(), 7);
+    assert!(*heap.peek().unwrap() == box 27);
+    heap.push(box 103);
+    assert_eq!(heap.len(), 8);
+    assert!(*heap.peek().unwrap() == box 103);
+}
+
+#[test]
+fn test_push_pop() {
+    let mut heap = BinaryHeap::from_vec(vec![5, 5, 2, 1, 3]);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.push_pop(6), 6);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.push_pop(0), 5);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.push_pop(4), 5);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.push_pop(1), 4);
+    assert_eq!(heap.len(), 5);
+}
+
+#[test]
+fn test_replace() {
+    let mut heap = BinaryHeap::from_vec(vec![5, 5, 2, 1, 3]);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.replace(6).unwrap(), 5);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.replace(0).unwrap(), 6);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.replace(4).unwrap(), 5);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.replace(1).unwrap(), 4);
+    assert_eq!(heap.len(), 5);
+}
+
+fn check_to_vec(mut data: Vec<i32>) {
+    let heap = BinaryHeap::from_vec(data.clone());
+    let mut v = heap.clone().into_vec();
+    v.sort();
+    data.sort();
+
+    assert_eq!(v, data);
+    assert_eq!(heap.into_sorted_vec(), data);
+}
+
+#[test]
+fn test_to_vec() {
+    check_to_vec(vec![]);
+    check_to_vec(vec![5]);
+    check_to_vec(vec![3, 2]);
+    check_to_vec(vec![2, 3]);
+    check_to_vec(vec![5, 1, 2]);
+    check_to_vec(vec![1, 100, 2, 3]);
+    check_to_vec(vec![1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
+    check_to_vec(vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
+    check_to_vec(vec![9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
+    check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+    check_to_vec(vec![10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
+    check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
+    check_to_vec(vec![5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
+}
+
+#[test]
+fn test_empty_pop() {
+    let mut heap = BinaryHeap::<i32>::new();
+    assert!(heap.pop().is_none());
+}
+
+#[test]
+fn test_empty_peek() {
+    let empty = BinaryHeap::<i32>::new();
+    assert!(empty.peek().is_none());
+}
+
+#[test]
+fn test_empty_replace() {
+    let mut heap = BinaryHeap::new();
+    assert!(heap.replace(5).is_none());
+}
+
+#[test]
+fn test_from_iter() {
+    let xs = vec![9, 8, 7, 6, 5, 4, 3, 2, 1];
+
+    let mut q: BinaryHeap<_> = xs.iter().rev().cloned().collect();
+
+    for &x in &xs {
+        assert_eq!(q.pop().unwrap(), x);
+    }
+}
+
+#[test]
+fn test_drain() {
+    let mut q: BinaryHeap<_> = [9, 8, 7, 6, 5, 4, 3, 2, 1].iter().cloned().collect();
+
+    assert_eq!(q.drain().take(5).count(), 5);
+
+    assert!(q.is_empty());
+}
diff --git a/src/libcollectionstest/bit/mod.rs b/src/libcollectionstest/bit/mod.rs
new file mode 100644 (file)
index 0000000..8e06524
--- /dev/null
@@ -0,0 +1,12 @@
+// 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.
+//
+// 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.
+
+mod set;
+mod vec;
diff --git a/src/libcollectionstest/bit/set.rs b/src/libcollectionstest/bit/set.rs
new file mode 100644 (file)
index 0000000..19ea25e
--- /dev/null
@@ -0,0 +1,440 @@
+// 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.
+//
+// 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 std::cmp::Ordering::{Equal, Greater, Less};
+use std::collections::{BitSet, BitVec};
+
+#[test]
+fn test_bit_set_show() {
+    let mut s = BitSet::new();
+    s.insert(1);
+    s.insert(10);
+    s.insert(50);
+    s.insert(2);
+    assert_eq!("{1, 2, 10, 50}", format!("{:?}", s));
+}
+
+#[test]
+fn test_bit_set_from_usizes() {
+    let usizes = vec![0, 2, 2, 3];
+    let a: BitSet = usizes.into_iter().collect();
+    let mut b = BitSet::new();
+    b.insert(0);
+    b.insert(2);
+    b.insert(3);
+    assert_eq!(a, b);
+}
+
+#[test]
+fn test_bit_set_iterator() {
+    let usizes = vec![0, 2, 2, 3];
+    let bit_vec: BitSet = usizes.into_iter().collect();
+
+    let idxs: Vec<_> = bit_vec.iter().collect();
+    assert_eq!(idxs, [0, 2, 3]);
+
+    let long: BitSet = (0..10000).filter(|&n| n % 2 == 0).collect();
+    let real: Vec<_> = (0..10000).step_by(2).collect();
+
+    let idxs: Vec<_> = long.iter().collect();
+    assert_eq!(idxs, real);
+}
+
+#[test]
+fn test_bit_set_frombit_vec_init() {
+    let bools = [true, false];
+    let lengths = [10, 64, 100];
+    for &b in &bools {
+        for &l in &lengths {
+            let bitset = BitSet::from_bit_vec(BitVec::from_elem(l, b));
+            assert_eq!(bitset.contains(&1), b);
+            assert_eq!(bitset.contains(&(l-1)), b);
+            assert!(!bitset.contains(&l));
+        }
+    }
+}
+
+#[test]
+fn test_bit_vec_masking() {
+    let b = BitVec::from_elem(140, true);
+    let mut bs = BitSet::from_bit_vec(b);
+    assert!(bs.contains(&139));
+    assert!(!bs.contains(&140));
+    assert!(bs.insert(150));
+    assert!(!bs.contains(&140));
+    assert!(!bs.contains(&149));
+    assert!(bs.contains(&150));
+    assert!(!bs.contains(&151));
+}
+
+#[test]
+fn test_bit_set_basic() {
+    let mut b = BitSet::new();
+    assert!(b.insert(3));
+    assert!(!b.insert(3));
+    assert!(b.contains(&3));
+    assert!(b.insert(4));
+    assert!(!b.insert(4));
+    assert!(b.contains(&3));
+    assert!(b.insert(400));
+    assert!(!b.insert(400));
+    assert!(b.contains(&400));
+    assert_eq!(b.len(), 3);
+}
+
+#[test]
+fn test_bit_set_intersection() {
+    let mut a = BitSet::new();
+    let mut b = BitSet::new();
+
+    assert!(a.insert(11));
+    assert!(a.insert(1));
+    assert!(a.insert(3));
+    assert!(a.insert(77));
+    assert!(a.insert(103));
+    assert!(a.insert(5));
+
+    assert!(b.insert(2));
+    assert!(b.insert(11));
+    assert!(b.insert(77));
+    assert!(b.insert(5));
+    assert!(b.insert(3));
+
+    let expected = [3, 5, 11, 77];
+    let actual: Vec<_> = a.intersection(&b).collect();
+    assert_eq!(actual, expected);
+}
+
+#[test]
+fn test_bit_set_difference() {
+    let mut a = BitSet::new();
+    let mut b = BitSet::new();
+
+    assert!(a.insert(1));
+    assert!(a.insert(3));
+    assert!(a.insert(5));
+    assert!(a.insert(200));
+    assert!(a.insert(500));
+
+    assert!(b.insert(3));
+    assert!(b.insert(200));
+
+    let expected = [1, 5, 500];
+    let actual: Vec<_> = a.difference(&b).collect();
+    assert_eq!(actual, expected);
+}
+
+#[test]
+fn test_bit_set_symmetric_difference() {
+    let mut a = BitSet::new();
+    let mut b = BitSet::new();
+
+    assert!(a.insert(1));
+    assert!(a.insert(3));
+    assert!(a.insert(5));
+    assert!(a.insert(9));
+    assert!(a.insert(11));
+
+    assert!(b.insert(3));
+    assert!(b.insert(9));
+    assert!(b.insert(14));
+    assert!(b.insert(220));
+
+    let expected = [1, 5, 11, 14, 220];
+    let actual: Vec<_> = a.symmetric_difference(&b).collect();
+    assert_eq!(actual, expected);
+}
+
+#[test]
+fn test_bit_set_union() {
+    let mut a = BitSet::new();
+    let mut b = BitSet::new();
+    assert!(a.insert(1));
+    assert!(a.insert(3));
+    assert!(a.insert(5));
+    assert!(a.insert(9));
+    assert!(a.insert(11));
+    assert!(a.insert(160));
+    assert!(a.insert(19));
+    assert!(a.insert(24));
+    assert!(a.insert(200));
+
+    assert!(b.insert(1));
+    assert!(b.insert(5));
+    assert!(b.insert(9));
+    assert!(b.insert(13));
+    assert!(b.insert(19));
+
+    let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160, 200];
+    let actual: Vec<_> = a.union(&b).collect();
+    assert_eq!(actual, expected);
+}
+
+#[test]
+fn test_bit_set_subset() {
+    let mut set1 = BitSet::new();
+    let mut set2 = BitSet::new();
+
+    assert!(set1.is_subset(&set2)); //  {}  {}
+    set2.insert(100);
+    assert!(set1.is_subset(&set2)); //  {}  { 1 }
+    set2.insert(200);
+    assert!(set1.is_subset(&set2)); //  {}  { 1, 2 }
+    set1.insert(200);
+    assert!(set1.is_subset(&set2)); //  { 2 }  { 1, 2 }
+    set1.insert(300);
+    assert!(!set1.is_subset(&set2)); // { 2, 3 }  { 1, 2 }
+    set2.insert(300);
+    assert!(set1.is_subset(&set2)); // { 2, 3 }  { 1, 2, 3 }
+    set2.insert(400);
+    assert!(set1.is_subset(&set2)); // { 2, 3 }  { 1, 2, 3, 4 }
+    set2.remove(&100);
+    assert!(set1.is_subset(&set2)); // { 2, 3 }  { 2, 3, 4 }
+    set2.remove(&300);
+    assert!(!set1.is_subset(&set2)); // { 2, 3 }  { 2, 4 }
+    set1.remove(&300);
+    assert!(set1.is_subset(&set2)); // { 2 }  { 2, 4 }
+}
+
+#[test]
+fn test_bit_set_is_disjoint() {
+    let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01000000]));
+    let c = BitSet::new();
+    let d = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00110000]));
+
+    assert!(!a.is_disjoint(&d));
+    assert!(!d.is_disjoint(&a));
+
+    assert!(a.is_disjoint(&b));
+    assert!(a.is_disjoint(&c));
+    assert!(b.is_disjoint(&a));
+    assert!(b.is_disjoint(&c));
+    assert!(c.is_disjoint(&a));
+    assert!(c.is_disjoint(&b));
+}
+
+#[test]
+fn test_bit_set_union_with() {
+    //a should grow to include larger elements
+    let mut a = BitSet::new();
+    a.insert(0);
+    let mut b = BitSet::new();
+    b.insert(5);
+    let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
+    a.union_with(&b);
+    assert_eq!(a, expected);
+
+    // Standard
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
+    let c = a.clone();
+    a.union_with(&b);
+    b.union_with(&c);
+    assert_eq!(a.len(), 4);
+    assert_eq!(b.len(), 4);
+}
+
+#[test]
+fn test_bit_set_intersect_with() {
+    // Explicitly 0'ed bits
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
+    let c = a.clone();
+    a.intersect_with(&b);
+    b.intersect_with(&c);
+    assert!(a.is_empty());
+    assert!(b.is_empty());
+
+    // Uninitialized bits should behave like 0's
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let mut b = BitSet::new();
+    let c = a.clone();
+    a.intersect_with(&b);
+    b.intersect_with(&c);
+    assert!(a.is_empty());
+    assert!(b.is_empty());
+
+    // Standard
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
+    let c = a.clone();
+    a.intersect_with(&b);
+    b.intersect_with(&c);
+    assert_eq!(a.len(), 2);
+    assert_eq!(b.len(), 2);
+}
+
+#[test]
+fn test_bit_set_difference_with() {
+    // Explicitly 0'ed bits
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
+    let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    a.difference_with(&b);
+    assert!(a.is_empty());
+
+    // Uninitialized bits should behave like 0's
+    let mut a = BitSet::new();
+    let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11111111]));
+    a.difference_with(&b);
+    assert!(a.is_empty());
+
+    // Standard
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
+    let c = a.clone();
+    a.difference_with(&b);
+    b.difference_with(&c);
+    assert_eq!(a.len(), 1);
+    assert_eq!(b.len(), 1);
+}
+
+#[test]
+fn test_bit_set_symmetric_difference_with() {
+    //a should grow to include larger elements
+    let mut a = BitSet::new();
+    a.insert(0);
+    a.insert(1);
+    let mut b = BitSet::new();
+    b.insert(1);
+    b.insert(5);
+    let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
+    a.symmetric_difference_with(&b);
+    assert_eq!(a, expected);
+
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let b = BitSet::new();
+    let c = a.clone();
+    a.symmetric_difference_with(&b);
+    assert_eq!(a, c);
+
+    // Standard
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11100010]));
+    let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101010]));
+    let c = a.clone();
+    a.symmetric_difference_with(&b);
+    b.symmetric_difference_with(&c);
+    assert_eq!(a.len(), 2);
+    assert_eq!(b.len(), 2);
+}
+
+#[test]
+fn test_bit_set_eq() {
+    let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
+    let c = BitSet::new();
+
+    assert!(a == a);
+    assert!(a != b);
+    assert!(a != c);
+    assert!(b == b);
+    assert!(b == c);
+    assert!(c == c);
+}
+
+#[test]
+fn test_bit_set_cmp() {
+    let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
+    let c = BitSet::new();
+
+    assert_eq!(a.cmp(&b), Greater);
+    assert_eq!(a.cmp(&c), Greater);
+    assert_eq!(b.cmp(&a), Less);
+    assert_eq!(b.cmp(&c), Equal);
+    assert_eq!(c.cmp(&a), Less);
+    assert_eq!(c.cmp(&b), Equal);
+}
+
+#[test]
+fn test_bit_vec_remove() {
+    let mut a = BitSet::new();
+
+    assert!(a.insert(1));
+    assert!(a.remove(&1));
+
+    assert!(a.insert(100));
+    assert!(a.remove(&100));
+
+    assert!(a.insert(1000));
+    assert!(a.remove(&1000));
+    a.shrink_to_fit();
+}
+
+#[test]
+fn test_bit_vec_clone() {
+    let mut a = BitSet::new();
+
+    assert!(a.insert(1));
+    assert!(a.insert(100));
+    assert!(a.insert(1000));
+
+    let mut b = a.clone();
+
+    assert!(a == b);
+
+    assert!(b.remove(&1));
+    assert!(a.contains(&1));
+
+    assert!(a.remove(&1000));
+    assert!(b.contains(&1000));
+}
+
+mod bench {
+    use std::collections::{BitSet, BitVec};
+    use std::rand::{Rng, self};
+    use std::u32;
+
+    use test::{Bencher, black_box};
+
+    const BENCH_BITS : usize = 1 << 14;
+
+    fn rng() -> rand::IsaacRng {
+        let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
+        rand::SeedableRng::from_seed(seed)
+    }
+
+    #[bench]
+    fn bench_bit_vecset_small(b: &mut Bencher) {
+        let mut r = rng();
+        let mut bit_vec = BitSet::new();
+        b.iter(|| {
+            for _ in 0..100 {
+                bit_vec.insert((r.next_u32() as usize) % u32::BITS as usize);
+            }
+            black_box(&bit_vec);
+        });
+    }
+
+    #[bench]
+    fn bench_bit_vecset_big(b: &mut Bencher) {
+        let mut r = rng();
+        let mut bit_vec = BitSet::new();
+        b.iter(|| {
+            for _ in 0..100 {
+                bit_vec.insert((r.next_u32() as usize) % BENCH_BITS);
+            }
+            black_box(&bit_vec);
+        });
+    }
+
+    #[bench]
+    fn bench_bit_vecset_iter(b: &mut Bencher) {
+        let bit_vec = BitSet::from_bit_vec(BitVec::from_fn(BENCH_BITS,
+                                              |idx| {idx % 3 == 0}));
+        b.iter(|| {
+            let mut sum = 0;
+            for idx in &bit_vec {
+                sum += idx as usize;
+            }
+            sum
+        })
+    }
+}
diff --git a/src/libcollectionstest/bit/vec.rs b/src/libcollectionstest/bit/vec.rs
new file mode 100644 (file)
index 0000000..3826974
--- /dev/null
@@ -0,0 +1,729 @@
+// 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.
+//
+// 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 std::collections::BitVec;
+use std::u32;
+
+#[test]
+fn test_to_str() {
+    let zerolen = BitVec::new();
+    assert_eq!(format!("{:?}", zerolen), "");
+
+    let eightbits = BitVec::from_elem(8, false);
+    assert_eq!(format!("{:?}", eightbits), "00000000")
+}
+
+#[test]
+fn test_0_elements() {
+    let act = BitVec::new();
+    let exp = Vec::new();
+    assert!(act.eq_vec(&exp));
+    assert!(act.none() && act.all());
+}
+
+#[test]
+fn test_1_element() {
+    let mut act = BitVec::from_elem(1, false);
+    assert!(act.eq_vec(&[false]));
+    assert!(act.none() && !act.all());
+    act = BitVec::from_elem(1, true);
+    assert!(act.eq_vec(&[true]));
+    assert!(!act.none() && act.all());
+}
+
+#[test]
+fn test_2_elements() {
+    let mut b = BitVec::from_elem(2, false);
+    b.set(0, true);
+    b.set(1, false);
+    assert_eq!(format!("{:?}", b), "10");
+    assert!(!b.none() && !b.all());
+}
+
+#[test]
+fn test_10_elements() {
+    let mut act;
+    // all 0
+
+    act = BitVec::from_elem(10, false);
+    assert!((act.eq_vec(
+                &[false, false, false, false, false, false, false, false, false, false])));
+    assert!(act.none() && !act.all());
+    // all 1
+
+    act = BitVec::from_elem(10, true);
+    assert!((act.eq_vec(&[true, true, true, true, true, true, true, true, true, true])));
+    assert!(!act.none() && act.all());
+    // mixed
+
+    act = BitVec::from_elem(10, false);
+    act.set(0, true);
+    act.set(1, true);
+    act.set(2, true);
+    act.set(3, true);
+    act.set(4, true);
+    assert!((act.eq_vec(&[true, true, true, true, true, false, false, false, false, false])));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(10, false);
+    act.set(5, true);
+    act.set(6, true);
+    act.set(7, true);
+    act.set(8, true);
+    act.set(9, true);
+    assert!((act.eq_vec(&[false, false, false, false, false, true, true, true, true, true])));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(10, false);
+    act.set(0, true);
+    act.set(3, true);
+    act.set(6, true);
+    act.set(9, true);
+    assert!((act.eq_vec(&[true, false, false, true, false, false, true, false, false, true])));
+    assert!(!act.none() && !act.all());
+}
+
+#[test]
+fn test_31_elements() {
+    let mut act;
+    // all 0
+
+    act = BitVec::from_elem(31, false);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false]));
+    assert!(act.none() && !act.all());
+    // all 1
+
+    act = BitVec::from_elem(31, true);
+    assert!(act.eq_vec(
+            &[true, true, true, true, true, true, true, true, true, true, true, true, true,
+              true, true, true, true, true, true, true, true, true, true, true, true, true,
+              true, true, true, true, true]));
+    assert!(!act.none() && act.all());
+    // mixed
+
+    act = BitVec::from_elem(31, false);
+    act.set(0, true);
+    act.set(1, true);
+    act.set(2, true);
+    act.set(3, true);
+    act.set(4, true);
+    act.set(5, true);
+    act.set(6, true);
+    act.set(7, true);
+    assert!(act.eq_vec(
+            &[true, true, true, true, true, true, true, true, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(31, false);
+    act.set(16, true);
+    act.set(17, true);
+    act.set(18, true);
+    act.set(19, true);
+    act.set(20, true);
+    act.set(21, true);
+    act.set(22, true);
+    act.set(23, true);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, true, true, true, true, true, true, true, true,
+              false, false, false, false, false, false, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(31, false);
+    act.set(24, true);
+    act.set(25, true);
+    act.set(26, true);
+    act.set(27, true);
+    act.set(28, true);
+    act.set(29, true);
+    act.set(30, true);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, true, true, true, true, true, true, true]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(31, false);
+    act.set(3, true);
+    act.set(17, true);
+    act.set(30, true);
+    assert!(act.eq_vec(
+            &[false, false, false, true, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, true, false, false, false, false, false, false,
+              false, false, false, false, false, false, true]));
+    assert!(!act.none() && !act.all());
+}
+
+#[test]
+fn test_32_elements() {
+    let mut act;
+    // all 0
+
+    act = BitVec::from_elem(32, false);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false]));
+    assert!(act.none() && !act.all());
+    // all 1
+
+    act = BitVec::from_elem(32, true);
+    assert!(act.eq_vec(
+            &[true, true, true, true, true, true, true, true, true, true, true, true, true,
+              true, true, true, true, true, true, true, true, true, true, true, true, true,
+              true, true, true, true, true, true]));
+    assert!(!act.none() && act.all());
+    // mixed
+
+    act = BitVec::from_elem(32, false);
+    act.set(0, true);
+    act.set(1, true);
+    act.set(2, true);
+    act.set(3, true);
+    act.set(4, true);
+    act.set(5, true);
+    act.set(6, true);
+    act.set(7, true);
+    assert!(act.eq_vec(
+            &[true, true, true, true, true, true, true, true, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(32, false);
+    act.set(16, true);
+    act.set(17, true);
+    act.set(18, true);
+    act.set(19, true);
+    act.set(20, true);
+    act.set(21, true);
+    act.set(22, true);
+    act.set(23, true);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, true, true, true, true, true, true, true, true,
+              false, false, false, false, false, false, false, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(32, false);
+    act.set(24, true);
+    act.set(25, true);
+    act.set(26, true);
+    act.set(27, true);
+    act.set(28, true);
+    act.set(29, true);
+    act.set(30, true);
+    act.set(31, true);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, true, true, true, true, true, true, true, true]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(32, false);
+    act.set(3, true);
+    act.set(17, true);
+    act.set(30, true);
+    act.set(31, true);
+    assert!(act.eq_vec(
+            &[false, false, false, true, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, true, false, false, false, false, false, false,
+              false, false, false, false, false, false, true, true]));
+    assert!(!act.none() && !act.all());
+}
+
+#[test]
+fn test_33_elements() {
+    let mut act;
+    // all 0
+
+    act = BitVec::from_elem(33, false);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false]));
+    assert!(act.none() && !act.all());
+    // all 1
+
+    act = BitVec::from_elem(33, true);
+    assert!(act.eq_vec(
+            &[true, true, true, true, true, true, true, true, true, true, true, true, true,
+              true, true, true, true, true, true, true, true, true, true, true, true, true,
+              true, true, true, true, true, true, true]));
+    assert!(!act.none() && act.all());
+    // mixed
+
+    act = BitVec::from_elem(33, false);
+    act.set(0, true);
+    act.set(1, true);
+    act.set(2, true);
+    act.set(3, true);
+    act.set(4, true);
+    act.set(5, true);
+    act.set(6, true);
+    act.set(7, true);
+    assert!(act.eq_vec(
+            &[true, true, true, true, true, true, true, true, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(33, false);
+    act.set(16, true);
+    act.set(17, true);
+    act.set(18, true);
+    act.set(19, true);
+    act.set(20, true);
+    act.set(21, true);
+    act.set(22, true);
+    act.set(23, true);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, true, true, true, true, true, true, true, true,
+              false, false, false, false, false, false, false, false, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(33, false);
+    act.set(24, true);
+    act.set(25, true);
+    act.set(26, true);
+    act.set(27, true);
+    act.set(28, true);
+    act.set(29, true);
+    act.set(30, true);
+    act.set(31, true);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, true, true, true, true, true, true, true, true, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(33, false);
+    act.set(3, true);
+    act.set(17, true);
+    act.set(30, true);
+    act.set(31, true);
+    act.set(32, true);
+    assert!(act.eq_vec(
+            &[false, false, false, true, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, true, false, false, false, false, false, false,
+              false, false, false, false, false, false, true, true, true]));
+    assert!(!act.none() && !act.all());
+}
+
+#[test]
+fn test_equal_differing_sizes() {
+    let v0 = BitVec::from_elem(10, false);
+    let v1 = BitVec::from_elem(11, false);
+    assert!(v0 != v1);
+}
+
+#[test]
+fn test_equal_greatly_differing_sizes() {
+    let v0 = BitVec::from_elem(10, false);
+    let v1 = BitVec::from_elem(110, false);
+    assert!(v0 != v1);
+}
+
+#[test]
+fn test_equal_sneaky_small() {
+    let mut a = BitVec::from_elem(1, false);
+    a.set(0, true);
+
+    let mut b = BitVec::from_elem(1, true);
+    b.set(0, true);
+
+    assert_eq!(a, b);
+}
+
+#[test]
+fn test_equal_sneaky_big() {
+    let mut a = BitVec::from_elem(100, false);
+    for i in 0..100 {
+        a.set(i, true);
+    }
+
+    let mut b = BitVec::from_elem(100, true);
+    for i in 0..100 {
+        b.set(i, true);
+    }
+
+    assert_eq!(a, b);
+}
+
+#[test]
+fn test_from_bytes() {
+    let bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
+    let str = concat!("10110110", "00000000", "11111111");
+    assert_eq!(format!("{:?}", bit_vec), str);
+}
+
+#[test]
+fn test_to_bytes() {
+    let mut bv = BitVec::from_elem(3, true);
+    bv.set(1, false);
+    assert_eq!(bv.to_bytes(), [0b10100000]);
+
+    let mut bv = BitVec::from_elem(9, false);
+    bv.set(2, true);
+    bv.set(8, true);
+    assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]);
+}
+
+#[test]
+fn test_from_bools() {
+    let bools = vec![true, false, true, true];
+    let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
+    assert_eq!(format!("{:?}", bit_vec), "1011");
+}
+
+#[test]
+fn test_to_bools() {
+    let bools = vec![false, false, true, false, false, true, true, false];
+    assert_eq!(BitVec::from_bytes(&[0b00100110]).iter().collect::<Vec<bool>>(), bools);
+}
+
+#[test]
+fn test_bit_vec_iterator() {
+    let bools = vec![true, false, true, true];
+    let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
+
+    assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), bools);
+
+    let long: Vec<_> = (0..10000).map(|i| i % 2 == 0).collect();
+    let bit_vec: BitVec = long.iter().map(|n| *n).collect();
+    assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), long)
+}
+
+#[test]
+fn test_small_difference() {
+    let mut b1 = BitVec::from_elem(3, false);
+    let mut b2 = BitVec::from_elem(3, false);
+    b1.set(0, true);
+    b1.set(1, true);
+    b2.set(1, true);
+    b2.set(2, true);
+    assert!(b1.difference(&b2));
+    assert!(b1[0]);
+    assert!(!b1[1]);
+    assert!(!b1[2]);
+}
+
+#[test]
+fn test_big_difference() {
+    let mut b1 = BitVec::from_elem(100, false);
+    let mut b2 = BitVec::from_elem(100, false);
+    b1.set(0, true);
+    b1.set(40, true);
+    b2.set(40, true);
+    b2.set(80, true);
+    assert!(b1.difference(&b2));
+    assert!(b1[0]);
+    assert!(!b1[40]);
+    assert!(!b1[80]);
+}
+
+#[test]
+fn test_small_clear() {
+    let mut b = BitVec::from_elem(14, true);
+    assert!(!b.none() && b.all());
+    b.clear();
+    assert!(b.none() && !b.all());
+}
+
+#[test]
+fn test_big_clear() {
+    let mut b = BitVec::from_elem(140, true);
+    assert!(!b.none() && b.all());
+    b.clear();
+    assert!(b.none() && !b.all());
+}
+
+#[test]
+fn test_bit_vec_lt() {
+    let mut a = BitVec::from_elem(5, false);
+    let mut b = BitVec::from_elem(5, false);
+
+    assert!(!(a < b) && !(b < a));
+    b.set(2, true);
+    assert!(a < b);
+    a.set(3, true);
+    assert!(a < b);
+    a.set(2, true);
+    assert!(!(a < b) && b < a);
+    b.set(0, true);
+    assert!(a < b);
+}
+
+#[test]
+fn test_ord() {
+    let mut a = BitVec::from_elem(5, false);
+    let mut b = BitVec::from_elem(5, false);
+
+    assert!(a <= b && a >= b);
+    a.set(1, true);
+    assert!(a > b && a >= b);
+    assert!(b < a && b <= a);
+    b.set(1, true);
+    b.set(2, true);
+    assert!(b > a && b >= a);
+    assert!(a < b && a <= b);
+}
+
+
+#[test]
+fn test_small_bit_vec_tests() {
+    let v = BitVec::from_bytes(&[0]);
+    assert!(!v.all());
+    assert!(!v.any());
+    assert!(v.none());
+
+    let v = BitVec::from_bytes(&[0b00010100]);
+    assert!(!v.all());
+    assert!(v.any());
+    assert!(!v.none());
+
+    let v = BitVec::from_bytes(&[0xFF]);
+    assert!(v.all());
+    assert!(v.any());
+    assert!(!v.none());
+}
+
+#[test]
+fn test_big_bit_vec_tests() {
+    let v = BitVec::from_bytes(&[ // 88 bits
+        0, 0, 0, 0,
+        0, 0, 0, 0,
+        0, 0, 0]);
+    assert!(!v.all());
+    assert!(!v.any());
+    assert!(v.none());
+
+    let v = BitVec::from_bytes(&[ // 88 bits
+        0, 0, 0b00010100, 0,
+        0, 0, 0, 0b00110100,
+        0, 0, 0]);
+    assert!(!v.all());
+    assert!(v.any());
+    assert!(!v.none());
+
+    let v = BitVec::from_bytes(&[ // 88 bits
+        0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF]);
+    assert!(v.all());
+    assert!(v.any());
+    assert!(!v.none());
+}
+
+#[test]
+fn test_bit_vec_push_pop() {
+    let mut s = BitVec::from_elem(5 * u32::BITS as usize - 2, false);
+    assert_eq!(s.len(), 5 * u32::BITS as usize - 2);
+    assert_eq!(s[5 * u32::BITS as usize - 3], false);
+    s.push(true);
+    s.push(true);
+    assert_eq!(s[5 * u32::BITS as usize - 2], true);
+    assert_eq!(s[5 * u32::BITS as usize - 1], true);
+    // Here the internal vector will need to be extended
+    s.push(false);
+    assert_eq!(s[5 * u32::BITS as usize], false);
+    s.push(false);
+    assert_eq!(s[5 * u32::BITS as usize + 1], false);
+    assert_eq!(s.len(), 5 * u32::BITS as usize + 2);
+    // Pop it all off
+    assert_eq!(s.pop(), Some(false));
+    assert_eq!(s.pop(), Some(false));
+    assert_eq!(s.pop(), Some(true));
+    assert_eq!(s.pop(), Some(true));
+    assert_eq!(s.len(), 5 * u32::BITS as usize - 2);
+}
+
+#[test]
+fn test_bit_vec_truncate() {
+    let mut s = BitVec::from_elem(5 * u32::BITS as usize, true);
+
+    assert_eq!(s, BitVec::from_elem(5 * u32::BITS as usize, true));
+    assert_eq!(s.len(), 5 * u32::BITS as usize);
+    s.truncate(4 * u32::BITS as usize);
+    assert_eq!(s, BitVec::from_elem(4 * u32::BITS as usize, true));
+    assert_eq!(s.len(), 4 * u32::BITS as usize);
+    // Truncating to a size > s.len() should be a noop
+    s.truncate(5 * u32::BITS as usize);
+    assert_eq!(s, BitVec::from_elem(4 * u32::BITS as usize, true));
+    assert_eq!(s.len(), 4 * u32::BITS as usize);
+    s.truncate(3 * u32::BITS as usize - 10);
+    assert_eq!(s, BitVec::from_elem(3 * u32::BITS as usize - 10, true));
+    assert_eq!(s.len(), 3 * u32::BITS as usize - 10);
+    s.truncate(0);
+    assert_eq!(s, BitVec::from_elem(0, true));
+    assert_eq!(s.len(), 0);
+}
+
+#[test]
+fn test_bit_vec_reserve() {
+    let mut s = BitVec::from_elem(5 * u32::BITS as usize, true);
+    // Check capacity
+    assert!(s.capacity() >= 5 * u32::BITS as usize);
+    s.reserve(2 * u32::BITS as usize);
+    assert!(s.capacity() >= 7 * u32::BITS as usize);
+    s.reserve(7 * u32::BITS as usize);
+    assert!(s.capacity() >= 12 * u32::BITS as usize);
+    s.reserve_exact(7 * u32::BITS as usize);
+    assert!(s.capacity() >= 12 * u32::BITS as usize);
+    s.reserve(7 * u32::BITS as usize + 1);
+    assert!(s.capacity() >= 12 * u32::BITS as usize + 1);
+    // Check that length hasn't changed
+    assert_eq!(s.len(), 5 * u32::BITS as usize);
+    s.push(true);
+    s.push(false);
+    s.push(true);
+    assert_eq!(s[5 * u32::BITS as usize - 1], true);
+    assert_eq!(s[5 * u32::BITS as usize - 0], true);
+    assert_eq!(s[5 * u32::BITS as usize + 1], false);
+    assert_eq!(s[5 * u32::BITS as usize + 2], true);
+}
+
+#[test]
+fn test_bit_vec_grow() {
+    let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010]);
+    bit_vec.grow(32, true);
+    assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
+                                 0xFF, 0xFF, 0xFF, 0xFF]));
+    bit_vec.grow(64, false);
+    assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
+                                 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0]));
+    bit_vec.grow(16, true);
+    assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
+                                 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]));
+}
+
+#[test]
+fn test_bit_vec_extend() {
+    let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
+    let ext = BitVec::from_bytes(&[0b01001001, 0b10010010, 0b10111101]);
+    bit_vec.extend(ext.iter());
+    assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111,
+                                 0b01001001, 0b10010010, 0b10111101]));
+}
+
+mod bench {
+    use std::collections::BitVec;
+    use std::u32;
+    use std::rand::{Rng, self};
+
+    use test::{Bencher, black_box};
+
+    const BENCH_BITS : usize = 1 << 14;
+
+    fn rng() -> rand::IsaacRng {
+        let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
+        rand::SeedableRng::from_seed(seed)
+    }
+
+    #[bench]
+    fn bench_usize_small(b: &mut Bencher) {
+        let mut r = rng();
+        let mut bit_vec = 0 as usize;
+        b.iter(|| {
+            for _ in 0..100 {
+                bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS as usize);
+            }
+            black_box(&bit_vec);
+        });
+    }
+
+    #[bench]
+    fn bench_bit_set_big_fixed(b: &mut Bencher) {
+        let mut r = rng();
+        let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
+        b.iter(|| {
+            for _ in 0..100 {
+                bit_vec.set((r.next_u32() as usize) % BENCH_BITS, true);
+            }
+            black_box(&bit_vec);
+        });
+    }
+
+    #[bench]
+    fn bench_bit_set_big_variable(b: &mut Bencher) {
+        let mut r = rng();
+        let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
+        b.iter(|| {
+            for _ in 0..100 {
+                bit_vec.set((r.next_u32() as usize) % BENCH_BITS, r.gen());
+            }
+            black_box(&bit_vec);
+        });
+    }
+
+    #[bench]
+    fn bench_bit_set_small(b: &mut Bencher) {
+        let mut r = rng();
+        let mut bit_vec = BitVec::from_elem(u32::BITS as usize, false);
+        b.iter(|| {
+            for _ in 0..100 {
+                bit_vec.set((r.next_u32() as usize) % u32::BITS as usize, true);
+            }
+            black_box(&bit_vec);
+        });
+    }
+
+    #[bench]
+    fn bench_bit_vec_big_union(b: &mut Bencher) {
+        let mut b1 = BitVec::from_elem(BENCH_BITS, false);
+        let b2 = BitVec::from_elem(BENCH_BITS, false);
+        b.iter(|| {
+            b1.union(&b2)
+        })
+    }
+
+    #[bench]
+    fn bench_bit_vec_small_iter(b: &mut Bencher) {
+        let bit_vec = BitVec::from_elem(u32::BITS as usize, false);
+        b.iter(|| {
+            let mut sum = 0;
+            for _ in 0..10 {
+                for pres in &bit_vec {
+                    sum += pres as usize;
+                }
+            }
+            sum
+        })
+    }
+
+    #[bench]
+    fn bench_bit_vec_big_iter(b: &mut Bencher) {
+        let bit_vec = BitVec::from_elem(BENCH_BITS, false);
+        b.iter(|| {
+            let mut sum = 0;
+            for pres in &bit_vec {
+                sum += pres as usize;
+            }
+            sum
+        })
+    }
+}
diff --git a/src/libcollectionstest/btree/map.rs b/src/libcollectionstest/btree/map.rs
new file mode 100644 (file)
index 0000000..10d69c9
--- /dev/null
@@ -0,0 +1,299 @@
+// 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 std::collections::BTreeMap;
+use std::collections::Bound::{Excluded, Included, Unbounded, self};
+use std::collections::btree_map::Entry::{Occupied, Vacant};
+use std::iter::range_inclusive;
+
+#[test]
+fn test_basic_large() {
+    let mut map = BTreeMap::new();
+    let size = 10000;
+    assert_eq!(map.len(), 0);
+
+    for i in 0..size {
+        assert_eq!(map.insert(i, 10*i), None);
+        assert_eq!(map.len(), i + 1);
+    }
+
+    for i in 0..size {
+        assert_eq!(map.get(&i).unwrap(), &(i*10));
+    }
+
+    for i in size..size*2 {
+        assert_eq!(map.get(&i), None);
+    }
+
+    for i in 0..size {
+        assert_eq!(map.insert(i, 100*i), Some(10*i));
+        assert_eq!(map.len(), size);
+    }
+
+    for i in 0..size {
+        assert_eq!(map.get(&i).unwrap(), &(i*100));
+    }
+
+    for i in 0..size/2 {
+        assert_eq!(map.remove(&(i*2)), Some(i*200));
+        assert_eq!(map.len(), size - i - 1);
+    }
+
+    for i in 0..size/2 {
+        assert_eq!(map.get(&(2*i)), None);
+        assert_eq!(map.get(&(2*i+1)).unwrap(), &(i*200 + 100));
+    }
+
+    for i in 0..size/2 {
+        assert_eq!(map.remove(&(2*i)), None);
+        assert_eq!(map.remove(&(2*i+1)), Some(i*200 + 100));
+        assert_eq!(map.len(), size/2 - i - 1);
+    }
+}
+
+#[test]
+fn test_basic_small() {
+    let mut map = BTreeMap::new();
+    assert_eq!(map.remove(&1), None);
+    assert_eq!(map.get(&1), None);
+    assert_eq!(map.insert(1, 1), None);
+    assert_eq!(map.get(&1), Some(&1));
+    assert_eq!(map.insert(1, 2), Some(1));
+    assert_eq!(map.get(&1), Some(&2));
+    assert_eq!(map.insert(2, 4), None);
+    assert_eq!(map.get(&2), Some(&4));
+    assert_eq!(map.remove(&1), Some(2));
+    assert_eq!(map.remove(&2), Some(4));
+    assert_eq!(map.remove(&1), None);
+}
+
+#[test]
+fn test_iter() {
+    let size = 10000;
+
+    // Forwards
+    let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    fn test<T>(size: usize, mut iter: T) where T: Iterator<Item=(usize, usize)> {
+        for i in 0..size {
+            assert_eq!(iter.size_hint(), (size - i, Some(size - i)));
+            assert_eq!(iter.next().unwrap(), (i, i));
+        }
+        assert_eq!(iter.size_hint(), (0, Some(0)));
+        assert_eq!(iter.next(), None);
+    }
+    test(size, map.iter().map(|(&k, &v)| (k, v)));
+    test(size, map.iter_mut().map(|(&k, &mut v)| (k, v)));
+    test(size, map.into_iter());
+}
+
+#[test]
+fn test_iter_rev() {
+    let size = 10000;
+
+    // Forwards
+    let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    fn test<T>(size: usize, mut iter: T) where T: Iterator<Item=(usize, usize)> {
+        for i in 0..size {
+            assert_eq!(iter.size_hint(), (size - i, Some(size - i)));
+            assert_eq!(iter.next().unwrap(), (size - i - 1, size - i - 1));
+        }
+        assert_eq!(iter.size_hint(), (0, Some(0)));
+        assert_eq!(iter.next(), None);
+    }
+    test(size, map.iter().rev().map(|(&k, &v)| (k, v)));
+    test(size, map.iter_mut().rev().map(|(&k, &mut v)| (k, v)));
+    test(size, map.into_iter().rev());
+}
+
+#[test]
+fn test_iter_mixed() {
+    let size = 10000;
+
+    // Forwards
+    let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    fn test<T>(size: usize, mut iter: T)
+            where T: Iterator<Item=(usize, usize)> + DoubleEndedIterator {
+        for i in 0..size / 4 {
+            assert_eq!(iter.size_hint(), (size - i * 2, Some(size - i * 2)));
+            assert_eq!(iter.next().unwrap(), (i, i));
+            assert_eq!(iter.next_back().unwrap(), (size - i - 1, size - i - 1));
+        }
+        for i in size / 4..size * 3 / 4 {
+            assert_eq!(iter.size_hint(), (size * 3 / 4 - i, Some(size * 3 / 4 - i)));
+            assert_eq!(iter.next().unwrap(), (i, i));
+        }
+        assert_eq!(iter.size_hint(), (0, Some(0)));
+        assert_eq!(iter.next(), None);
+    }
+    test(size, map.iter().map(|(&k, &v)| (k, v)));
+    test(size, map.iter_mut().map(|(&k, &mut v)| (k, v)));
+    test(size, map.into_iter());
+}
+
+#[test]
+fn test_range_small() {
+    let size = 5;
+
+    // Forwards
+    let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    let mut j = 0;
+    for ((&k, &v), i) in map.range(Included(&2), Unbounded).zip(2..size) {
+        assert_eq!(k, i);
+        assert_eq!(v, i);
+        j += 1;
+    }
+    assert_eq!(j, size - 2);
+}
+
+#[test]
+fn test_range_1000() {
+    let size = 1000;
+    let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    fn test(map: &BTreeMap<u32, u32>, size: u32, min: Bound<&u32>, max: Bound<&u32>) {
+        let mut kvs = map.range(min, max).map(|(&k, &v)| (k, v));
+        let mut pairs = (0..size).map(|i| (i, i));
+
+        for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
+            assert_eq!(kv, pair);
+        }
+        assert_eq!(kvs.next(), None);
+        assert_eq!(pairs.next(), None);
+    }
+    test(&map, size, Included(&0), Excluded(&size));
+    test(&map, size, Unbounded, Excluded(&size));
+    test(&map, size, Included(&0), Included(&(size - 1)));
+    test(&map, size, Unbounded, Included(&(size - 1)));
+    test(&map, size, Included(&0), Unbounded);
+    test(&map, size, Unbounded, Unbounded);
+}
+
+#[test]
+fn test_range() {
+    let size = 200;
+    let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    for i in 0..size {
+        for j in i..size {
+            let mut kvs = map.range(Included(&i), Included(&j)).map(|(&k, &v)| (k, v));
+            let mut pairs = range_inclusive(i, j).map(|i| (i, i));
+
+            for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
+                assert_eq!(kv, pair);
+            }
+            assert_eq!(kvs.next(), None);
+            assert_eq!(pairs.next(), None);
+        }
+    }
+}
+
+#[test]
+fn test_entry(){
+    let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
+
+    let mut map: BTreeMap<_, _> = xs.iter().cloned().collect();
+
+    // Existing key (insert)
+    match map.entry(1) {
+        Vacant(_) => unreachable!(),
+        Occupied(mut view) => {
+            assert_eq!(view.get(), &10);
+            assert_eq!(view.insert(100), 10);
+        }
+    }
+    assert_eq!(map.get(&1).unwrap(), &100);
+    assert_eq!(map.len(), 6);
+
+
+    // Existing key (update)
+    match map.entry(2) {
+        Vacant(_) => unreachable!(),
+        Occupied(mut view) => {
+            let v = view.get_mut();
+            *v *= 10;
+        }
+    }
+    assert_eq!(map.get(&2).unwrap(), &200);
+    assert_eq!(map.len(), 6);
+
+    // Existing key (take)
+    match map.entry(3) {
+        Vacant(_) => unreachable!(),
+        Occupied(view) => {
+            assert_eq!(view.remove(), 30);
+        }
+    }
+    assert_eq!(map.get(&3), None);
+    assert_eq!(map.len(), 5);
+
+
+    // Inexistent key (insert)
+    match map.entry(10) {
+        Occupied(_) => unreachable!(),
+        Vacant(view) => {
+            assert_eq!(*view.insert(1000), 1000);
+        }
+    }
+    assert_eq!(map.get(&10).unwrap(), &1000);
+    assert_eq!(map.len(), 6);
+}
+
+mod bench {
+    use std::collections::BTreeMap;
+    use std::rand::{Rng, weak_rng};
+
+    use test::{Bencher, black_box};
+
+    map_insert_rand_bench!{insert_rand_100,    100,    BTreeMap}
+    map_insert_rand_bench!{insert_rand_10_000, 10_000, BTreeMap}
+
+    map_insert_seq_bench!{insert_seq_100,    100,    BTreeMap}
+    map_insert_seq_bench!{insert_seq_10_000, 10_000, BTreeMap}
+
+    map_find_rand_bench!{find_rand_100,    100,    BTreeMap}
+    map_find_rand_bench!{find_rand_10_000, 10_000, BTreeMap}
+
+    map_find_seq_bench!{find_seq_100,    100,    BTreeMap}
+    map_find_seq_bench!{find_seq_10_000, 10_000, BTreeMap}
+
+    fn bench_iter(b: &mut Bencher, size: i32) {
+        let mut map = BTreeMap::<i32, i32>::new();
+        let mut rng = weak_rng();
+
+        for _ in 0..size {
+            map.insert(rng.gen(), rng.gen());
+        }
+
+        b.iter(|| {
+            for entry in &map {
+                black_box(entry);
+            }
+        });
+    }
+
+    #[bench]
+    pub fn iter_20(b: &mut Bencher) {
+        bench_iter(b, 20);
+    }
+
+    #[bench]
+    pub fn iter_1000(b: &mut Bencher) {
+        bench_iter(b, 1000);
+    }
+
+    #[bench]
+    pub fn iter_100000(b: &mut Bencher) {
+        bench_iter(b, 100000);
+    }
+}
diff --git a/src/libcollectionstest/btree/mod.rs b/src/libcollectionstest/btree/mod.rs
new file mode 100644 (file)
index 0000000..0db48f3
--- /dev/null
@@ -0,0 +1,12 @@
+// 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.
+
+mod map;
+mod set;
diff --git a/src/libcollectionstest/btree/set.rs b/src/libcollectionstest/btree/set.rs
new file mode 100644 (file)
index 0000000..234cd6e
--- /dev/null
@@ -0,0 +1,186 @@
+// 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 std::collections::BTreeSet;
+use std::hash::{SipHasher, self};
+
+#[test]
+fn test_clone_eq() {
+  let mut m = BTreeSet::new();
+
+  m.insert(1);
+  m.insert(2);
+
+  assert!(m.clone() == m);
+}
+
+#[test]
+fn test_hash() {
+  let mut x = BTreeSet::new();
+  let mut y = BTreeSet::new();
+
+  x.insert(1);
+  x.insert(2);
+  x.insert(3);
+
+  y.insert(3);
+  y.insert(2);
+  y.insert(1);
+
+  assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
+}
+
+struct Counter<'a, 'b> {
+    i: &'a mut usize,
+    expected: &'b [i32],
+}
+
+impl<'a, 'b, 'c> FnMut<(&'c i32,)> for Counter<'a, 'b> {
+    extern "rust-call" fn call_mut(&mut self, (&x,): (&'c i32,)) -> bool {
+        assert_eq!(x, self.expected[*self.i]);
+        *self.i += 1;
+        true
+    }
+}
+
+impl<'a, 'b, 'c> FnOnce<(&'c i32,)> for Counter<'a, 'b> {
+    type Output = bool;
+
+    extern "rust-call" fn call_once(mut self, args: (&'c i32,)) -> bool {
+        self.call_mut(args)
+    }
+}
+
+fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) where
+    // FIXME Replace Counter with `Box<FnMut(_) -> _>`
+    F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, Counter) -> bool,
+{
+    let mut set_a = BTreeSet::new();
+    let mut set_b = BTreeSet::new();
+
+    for x in a { assert!(set_a.insert(*x)) }
+    for y in b { assert!(set_b.insert(*y)) }
+
+    let mut i = 0;
+    f(&set_a, &set_b, Counter { i: &mut i, expected: expected });
+    assert_eq!(i, expected.len());
+}
+
+#[test]
+fn test_intersection() {
+    fn check_intersection(a: &[i32], b: &[i32], expected: &[i32]) {
+        check(a, b, expected, |x, y, f| x.intersection(y).all(f))
+    }
+
+    check_intersection(&[], &[], &[]);
+    check_intersection(&[1, 2, 3], &[], &[]);
+    check_intersection(&[], &[1, 2, 3], &[]);
+    check_intersection(&[2], &[1, 2, 3], &[2]);
+    check_intersection(&[1, 2, 3], &[2], &[2]);
+    check_intersection(&[11, 1, 3, 77, 103, 5, -5],
+                       &[2, 11, 77, -9, -42, 5, 3],
+                       &[3, 5, 11, 77]);
+}
+
+#[test]
+fn test_difference() {
+    fn check_difference(a: &[i32], b: &[i32], expected: &[i32]) {
+        check(a, b, expected, |x, y, f| x.difference(y).all(f))
+    }
+
+    check_difference(&[], &[], &[]);
+    check_difference(&[1, 12], &[], &[1, 12]);
+    check_difference(&[], &[1, 2, 3, 9], &[]);
+    check_difference(&[1, 3, 5, 9, 11],
+                     &[3, 9],
+                     &[1, 5, 11]);
+    check_difference(&[-5, 11, 22, 33, 40, 42],
+                     &[-12, -5, 14, 23, 34, 38, 39, 50],
+                     &[11, 22, 33, 40, 42]);
+}
+
+#[test]
+fn test_symmetric_difference() {
+    fn check_symmetric_difference(a: &[i32], b: &[i32], expected: &[i32]) {
+        check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f))
+    }
+
+    check_symmetric_difference(&[], &[], &[]);
+    check_symmetric_difference(&[1, 2, 3], &[2], &[1, 3]);
+    check_symmetric_difference(&[2], &[1, 2, 3], &[1, 3]);
+    check_symmetric_difference(&[1, 3, 5, 9, 11],
+                               &[-2, 3, 9, 14, 22],
+                               &[-2, 1, 5, 11, 14, 22]);
+}
+
+#[test]
+fn test_union() {
+    fn check_union(a: &[i32], b: &[i32], expected: &[i32]) {
+        check(a, b, expected, |x, y, f| x.union(y).all(f))
+    }
+
+    check_union(&[], &[], &[]);
+    check_union(&[1, 2, 3], &[2], &[1, 2, 3]);
+    check_union(&[2], &[1, 2, 3], &[1, 2, 3]);
+    check_union(&[1, 3, 5, 9, 11, 16, 19, 24],
+                &[-2, 1, 5, 9, 13, 19],
+                &[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
+}
+
+#[test]
+fn test_zip() {
+    let mut x = BTreeSet::new();
+    x.insert(5);
+    x.insert(12);
+    x.insert(11);
+
+    let mut y = BTreeSet::new();
+    y.insert("foo");
+    y.insert("bar");
+
+    let x = x;
+    let y = y;
+    let mut z = x.iter().zip(y.iter());
+
+    // FIXME: #5801: this needs a type hint to compile...
+    let result: Option<(&usize, & &'static str)> = z.next();
+    assert_eq!(result.unwrap(), (&5, &("bar")));
+
+    let result: Option<(&usize, & &'static str)> = z.next();
+    assert_eq!(result.unwrap(), (&11, &("foo")));
+
+    let result: Option<(&usize, & &'static str)> = z.next();
+    assert!(result.is_none());
+}
+
+#[test]
+fn test_from_iter() {
+    let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+    let set: BTreeSet<_> = xs.iter().cloned().collect();
+
+    for x in &xs {
+        assert!(set.contains(x));
+    }
+}
+
+#[test]
+fn test_show() {
+    let mut set = BTreeSet::new();
+    let empty = BTreeSet::<i32>::new();
+
+    set.insert(1);
+    set.insert(2);
+
+    let set_str = format!("{:?}", set);
+
+    assert_eq!(set_str, "{1, 2}");
+    assert_eq!(format!("{:?}", empty), "{}");
+}
diff --git a/src/libcollectionstest/enum_set.rs b/src/libcollectionstest/enum_set.rs
new file mode 100644 (file)
index 0000000..0a1eb0b
--- /dev/null
@@ -0,0 +1,244 @@
+// 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.
+
+use std::mem;
+
+use collections::enum_set::{CLike, EnumSet};
+
+use self::Foo::*;
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+#[repr(usize)]
+enum Foo {
+    A, B, C
+}
+
+impl CLike for Foo {
+    fn to_usize(&self) -> usize {
+        *self as usize
+    }
+
+    fn from_usize(v: usize) -> Foo {
+        unsafe { mem::transmute(v) }
+    }
+}
+
+#[test]
+fn test_new() {
+    let e: EnumSet<Foo> = EnumSet::new();
+    assert!(e.is_empty());
+}
+
+#[test]
+fn test_show() {
+    let mut e = EnumSet::new();
+    assert!(format!("{:?}", e) == "{}");
+    e.insert(A);
+    assert!(format!("{:?}", e) == "{A}");
+    e.insert(C);
+    assert!(format!("{:?}", e) == "{A, C}");
+}
+
+#[test]
+fn test_len() {
+    let mut e = EnumSet::new();
+    assert_eq!(e.len(), 0);
+    e.insert(A);
+    e.insert(B);
+    e.insert(C);
+    assert_eq!(e.len(), 3);
+    e.remove(&A);
+    assert_eq!(e.len(), 2);
+    e.clear();
+    assert_eq!(e.len(), 0);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// intersect
+
+#[test]
+fn test_two_empties_do_not_intersect() {
+    let e1: EnumSet<Foo> = EnumSet::new();
+    let e2: EnumSet<Foo> = EnumSet::new();
+    assert!(e1.is_disjoint(&e2));
+}
+
+#[test]
+fn test_empty_does_not_intersect_with_full() {
+    let e1: EnumSet<Foo> = EnumSet::new();
+
+    let mut e2: EnumSet<Foo> = EnumSet::new();
+    e2.insert(A);
+    e2.insert(B);
+    e2.insert(C);
+
+    assert!(e1.is_disjoint(&e2));
+}
+
+#[test]
+fn test_disjoint_intersects() {
+    let mut e1: EnumSet<Foo> = EnumSet::new();
+    e1.insert(A);
+
+    let mut e2: EnumSet<Foo> = EnumSet::new();
+    e2.insert(B);
+
+    assert!(e1.is_disjoint(&e2));
+}
+
+#[test]
+fn test_overlapping_intersects() {
+    let mut e1: EnumSet<Foo> = EnumSet::new();
+    e1.insert(A);
+
+    let mut e2: EnumSet<Foo> = EnumSet::new();
+    e2.insert(A);
+    e2.insert(B);
+
+    assert!(!e1.is_disjoint(&e2));
+}
+
+///////////////////////////////////////////////////////////////////////////
+// contains and contains_elem
+
+#[test]
+fn test_superset() {
+    let mut e1: EnumSet<Foo> = EnumSet::new();
+    e1.insert(A);
+
+    let mut e2: EnumSet<Foo> = EnumSet::new();
+    e2.insert(A);
+    e2.insert(B);
+
+    let mut e3: EnumSet<Foo> = EnumSet::new();
+    e3.insert(C);
+
+    assert!(e1.is_subset(&e2));
+    assert!(e2.is_superset(&e1));
+    assert!(!e3.is_superset(&e2));
+    assert!(!e2.is_superset(&e3))
+}
+
+#[test]
+fn test_contains() {
+    let mut e1: EnumSet<Foo> = EnumSet::new();
+    e1.insert(A);
+    assert!(e1.contains(&A));
+    assert!(!e1.contains(&B));
+    assert!(!e1.contains(&C));
+
+    e1.insert(A);
+    e1.insert(B);
+    assert!(e1.contains(&A));
+    assert!(e1.contains(&B));
+    assert!(!e1.contains(&C));
+}
+
+///////////////////////////////////////////////////////////////////////////
+// iter
+
+#[test]
+fn test_iterator() {
+    let mut e1: EnumSet<Foo> = EnumSet::new();
+
+    let elems: Vec<Foo> = e1.iter().collect();
+    assert!(elems.is_empty());
+
+    e1.insert(A);
+    let elems: Vec<_> = e1.iter().collect();
+    assert_eq!(elems, [A]);
+
+    e1.insert(C);
+    let elems: Vec<_> = e1.iter().collect();
+    assert_eq!(elems, [A,C]);
+
+    e1.insert(C);
+    let elems: Vec<_> = e1.iter().collect();
+    assert_eq!(elems, [A,C]);
+
+    e1.insert(B);
+    let elems: Vec<_> = e1.iter().collect();
+    assert_eq!(elems, [A,B,C]);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// operators
+
+#[test]
+fn test_operators() {
+    let mut e1: EnumSet<Foo> = EnumSet::new();
+    e1.insert(A);
+    e1.insert(C);
+
+    let mut e2: EnumSet<Foo> = EnumSet::new();
+    e2.insert(B);
+    e2.insert(C);
+
+    let e_union = e1 | e2;
+    let elems: Vec<_> = e_union.iter().collect();
+    assert_eq!(elems, [A,B,C]);
+
+    let e_intersection = e1 & e2;
+    let elems: Vec<_> = e_intersection.iter().collect();
+    assert_eq!(elems, [C]);
+
+    // Another way to express intersection
+    let e_intersection = e1 - (e1 - e2);
+    let elems: Vec<_> = e_intersection.iter().collect();
+    assert_eq!(elems, [C]);
+
+    let e_subtract = e1 - e2;
+    let elems: Vec<_> = e_subtract.iter().collect();
+    assert_eq!(elems, [A]);
+
+    // Bitwise XOR of two sets, aka symmetric difference
+    let e_symmetric_diff = e1 ^ e2;
+    let elems: Vec<_> = e_symmetric_diff.iter().collect();
+    assert_eq!(elems, [A,B]);
+
+    // Another way to express symmetric difference
+    let e_symmetric_diff = (e1 - e2) | (e2 - e1);
+    let elems: Vec<_> = e_symmetric_diff.iter().collect();
+    assert_eq!(elems, [A,B]);
+
+    // Yet another way to express symmetric difference
+    let e_symmetric_diff = (e1 | e2) - (e1 & e2);
+    let elems: Vec<_> = e_symmetric_diff.iter().collect();
+    assert_eq!(elems, [A,B]);
+}
+
+#[test]
+#[should_panic]
+fn test_overflow() {
+    #[allow(dead_code)]
+    #[derive(Copy, Clone)]
+    #[repr(usize)]
+    enum Bar {
+        V00, V01, V02, V03, V04, V05, V06, V07, V08, V09,
+        V10, V11, V12, V13, V14, V15, V16, V17, V18, V19,
+        V20, V21, V22, V23, V24, V25, V26, V27, V28, V29,
+        V30, V31, V32, V33, V34, V35, V36, V37, V38, V39,
+        V40, V41, V42, V43, V44, V45, V46, V47, V48, V49,
+        V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
+        V60, V61, V62, V63, V64, V65, V66, V67, V68, V69,
+    }
+
+    impl CLike for Bar {
+        fn to_usize(&self) -> usize {
+            *self as usize
+        }
+
+        fn from_usize(v: usize) -> Bar {
+            unsafe { mem::transmute(v) }
+        }
+    }
+    let mut set = EnumSet::new();
+    set.insert(Bar::V64);
+}
diff --git a/src/libcollectionstest/fmt.rs b/src/libcollectionstest/fmt.rs
new file mode 100644 (file)
index 0000000..70e21c6
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2013-2015 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 std::fmt;
+
+#[test]
+fn test_format() {
+    let s = fmt::format(format_args!("Hello, {}!", "world"));
+    assert_eq!(s, "Hello, world!");
+}
diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs
new file mode 100644 (file)
index 0000000..456c658
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright 2015 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(box_syntax)]
+#![feature(collections)]
+#![feature(core)]
+#![feature(hash)]
+#![feature(rand)]
+#![feature(rustc_private)]
+#![feature(str_words)]
+#![feature(test)]
+#![feature(unboxed_closures)]
+#![feature(unicode)]
+#![feature(unsafe_destructor)]
+#![feature(into_cow)]
+#![feature(step_by)]
+#![cfg_attr(test, feature(str_char))]
+
+#[macro_use] extern crate log;
+
+extern crate collections;
+extern crate test;
+extern crate unicode;
+
+#[cfg(test)] #[macro_use] mod bench;
+
+mod binary_heap;
+mod bit;
+mod btree;
+mod enum_set;
+mod fmt;
+mod linked_list;
+mod slice;
+mod str;
+mod string;
+mod vec_deque;
+mod vec_map;
+mod vec;
diff --git a/src/libcollectionstest/linked_list.rs b/src/libcollectionstest/linked_list.rs
new file mode 100644 (file)
index 0000000..fd73938
--- /dev/null
@@ -0,0 +1,397 @@
+// Copyright 2012-2015 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 std::collections::LinkedList;
+use std::hash::{SipHasher, self};
+
+use test;
+
+#[test]
+fn test_basic() {
+    let mut m = LinkedList::<Box<_>>::new();
+    assert_eq!(m.pop_front(), None);
+    assert_eq!(m.pop_back(), None);
+    assert_eq!(m.pop_front(), None);
+    m.push_front(box 1);
+    assert_eq!(m.pop_front(), Some(box 1));
+    m.push_back(box 2);
+    m.push_back(box 3);
+    assert_eq!(m.len(), 2);
+    assert_eq!(m.pop_front(), Some(box 2));
+    assert_eq!(m.pop_front(), Some(box 3));
+    assert_eq!(m.len(), 0);
+    assert_eq!(m.pop_front(), None);
+    m.push_back(box 1);
+    m.push_back(box 3);
+    m.push_back(box 5);
+    m.push_back(box 7);
+    assert_eq!(m.pop_front(), Some(box 1));
+
+    let mut n = LinkedList::new();
+    n.push_front(2);
+    n.push_front(3);
+    {
+        assert_eq!(n.front().unwrap(), &3);
+        let x = n.front_mut().unwrap();
+        assert_eq!(*x, 3);
+        *x = 0;
+    }
+    {
+        assert_eq!(n.back().unwrap(), &2);
+        let y = n.back_mut().unwrap();
+        assert_eq!(*y, 2);
+        *y = 1;
+    }
+    assert_eq!(n.pop_front(), Some(0));
+    assert_eq!(n.pop_front(), Some(1));
+}
+
+#[cfg(test)]
+fn generate_test() -> LinkedList<i32> {
+    list_from(&[0,1,2,3,4,5,6])
+}
+
+#[cfg(test)]
+fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
+    v.iter().cloned().collect()
+}
+
+#[test]
+fn test_split_off() {
+    // singleton
+    {
+        let mut m = LinkedList::new();
+        m.push_back(1);
+
+        let p = m.split_off(0);
+        assert_eq!(m.len(), 0);
+        assert_eq!(p.len(), 1);
+        assert_eq!(p.back(), Some(&1));
+        assert_eq!(p.front(), Some(&1));
+    }
+
+    // not singleton, forwards
+    {
+        let u = vec![1,2,3,4,5];
+        let mut m = list_from(&u);
+        let mut n = m.split_off(2);
+        assert_eq!(m.len(), 2);
+        assert_eq!(n.len(), 3);
+        for elt in 1..3 {
+            assert_eq!(m.pop_front(), Some(elt));
+        }
+        for elt in 3..6 {
+            assert_eq!(n.pop_front(), Some(elt));
+        }
+    }
+    // not singleton, backwards
+    {
+        let u = vec![1,2,3,4,5];
+        let mut m = list_from(&u);
+        let mut n = m.split_off(4);
+        assert_eq!(m.len(), 4);
+        assert_eq!(n.len(), 1);
+        for elt in 1..5 {
+            assert_eq!(m.pop_front(), Some(elt));
+        }
+        for elt in 5..6 {
+            assert_eq!(n.pop_front(), Some(elt));
+        }
+    }
+
+    // no-op on the last index
+    {
+        let mut m = LinkedList::new();
+        m.push_back(1);
+
+        let p = m.split_off(1);
+        assert_eq!(m.len(), 1);
+        assert_eq!(p.len(), 0);
+        assert_eq!(m.back(), Some(&1));
+        assert_eq!(m.front(), Some(&1));
+    }
+
+}
+
+#[test]
+fn test_iterator() {
+    let m = generate_test();
+    for (i, elt) in m.iter().enumerate() {
+        assert_eq!(i as i32, *elt);
+    }
+    let mut n = LinkedList::new();
+    assert_eq!(n.iter().next(), None);
+    n.push_front(4);
+    let mut it = n.iter();
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(it.next().unwrap(), &4);
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_iterator_clone() {
+    let mut n = LinkedList::new();
+    n.push_back(2);
+    n.push_back(3);
+    n.push_back(4);
+    let mut it = n.iter();
+    it.next();
+    let mut jt = it.clone();
+    assert_eq!(it.next(), jt.next());
+    assert_eq!(it.next_back(), jt.next_back());
+    assert_eq!(it.next(), jt.next());
+}
+
+#[test]
+fn test_iterator_double_end() {
+    let mut n = LinkedList::new();
+    assert_eq!(n.iter().next(), None);
+    n.push_front(4);
+    n.push_front(5);
+    n.push_front(6);
+    let mut it = n.iter();
+    assert_eq!(it.size_hint(), (3, Some(3)));
+    assert_eq!(it.next().unwrap(), &6);
+    assert_eq!(it.size_hint(), (2, Some(2)));
+    assert_eq!(it.next_back().unwrap(), &4);
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(it.next_back().unwrap(), &5);
+    assert_eq!(it.next_back(), None);
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_rev_iter() {
+    let m = generate_test();
+    for (i, elt) in m.iter().rev().enumerate() {
+        assert_eq!((6 - i) as i32, *elt);
+    }
+    let mut n = LinkedList::new();
+    assert_eq!(n.iter().rev().next(), None);
+    n.push_front(4);
+    let mut it = n.iter().rev();
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(it.next().unwrap(), &4);
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_mut_iter() {
+    let mut m = generate_test();
+    let mut len = m.len();
+    for (i, elt) in m.iter_mut().enumerate() {
+        assert_eq!(i as i32, *elt);
+        len -= 1;
+    }
+    assert_eq!(len, 0);
+    let mut n = LinkedList::new();
+    assert!(n.iter_mut().next().is_none());
+    n.push_front(4);
+    n.push_back(5);
+    let mut it = n.iter_mut();
+    assert_eq!(it.size_hint(), (2, Some(2)));
+    assert!(it.next().is_some());
+    assert!(it.next().is_some());
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_iterator_mut_double_end() {
+    let mut n = LinkedList::new();
+    assert!(n.iter_mut().next_back().is_none());
+    n.push_front(4);
+    n.push_front(5);
+    n.push_front(6);
+    let mut it = n.iter_mut();
+    assert_eq!(it.size_hint(), (3, Some(3)));
+    assert_eq!(*it.next().unwrap(), 6);
+    assert_eq!(it.size_hint(), (2, Some(2)));
+    assert_eq!(*it.next_back().unwrap(), 4);
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(*it.next_back().unwrap(), 5);
+    assert!(it.next_back().is_none());
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_mut_rev_iter() {
+    let mut m = generate_test();
+    for (i, elt) in m.iter_mut().rev().enumerate() {
+        assert_eq!((6 - i) as i32, *elt);
+    }
+    let mut n = LinkedList::new();
+    assert!(n.iter_mut().rev().next().is_none());
+    n.push_front(4);
+    let mut it = n.iter_mut().rev();
+    assert!(it.next().is_some());
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_eq() {
+    let mut n = list_from(&[]);
+    let mut m = list_from(&[]);
+    assert!(n == m);
+    n.push_front(1);
+    assert!(n != m);
+    m.push_back(1);
+    assert!(n == m);
+
+    let n = list_from(&[2,3,4]);
+    let m = list_from(&[1,2,3]);
+    assert!(n != m);
+}
+
+#[test]
+fn test_hash() {
+  let mut x = LinkedList::new();
+  let mut y = LinkedList::new();
+
+  assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
+
+  x.push_back(1);
+  x.push_back(2);
+  x.push_back(3);
+
+  y.push_front(3);
+  y.push_front(2);
+  y.push_front(1);
+
+  assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
+}
+
+#[test]
+fn test_ord() {
+    let n = list_from(&[]);
+    let m = list_from(&[1,2,3]);
+    assert!(n < m);
+    assert!(m > n);
+    assert!(n <= n);
+    assert!(n >= n);
+}
+
+#[test]
+fn test_ord_nan() {
+    let nan = 0.0f64/0.0;
+    let n = list_from(&[nan]);
+    let m = list_from(&[nan]);
+    assert!(!(n < m));
+    assert!(!(n > m));
+    assert!(!(n <= m));
+    assert!(!(n >= m));
+
+    let n = list_from(&[nan]);
+    let one = list_from(&[1.0f64]);
+    assert!(!(n < one));
+    assert!(!(n > one));
+    assert!(!(n <= one));
+    assert!(!(n >= one));
+
+    let u = list_from(&[1.0f64,2.0,nan]);
+    let v = list_from(&[1.0f64,2.0,3.0]);
+    assert!(!(u < v));
+    assert!(!(u > v));
+    assert!(!(u <= v));
+    assert!(!(u >= v));
+
+    let s = list_from(&[1.0f64,2.0,4.0,2.0]);
+    let t = list_from(&[1.0f64,2.0,3.0,2.0]);
+    assert!(!(s < t));
+    assert!(s > one);
+    assert!(!(s <= one));
+    assert!(s >= one);
+}
+
+#[test]
+fn test_show() {
+    let list: LinkedList<_> = (0..10).collect();
+    assert_eq!(format!("{:?}", list), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
+
+    let list: LinkedList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect();
+    assert_eq!(format!("{:?}", list), "[\"just\", \"one\", \"test\", \"more\"]");
+}
+
+#[bench]
+fn bench_collect_into(b: &mut test::Bencher) {
+    let v = &[0; 64];
+    b.iter(|| {
+        let _: LinkedList<_> = v.iter().cloned().collect();
+    })
+}
+
+#[bench]
+fn bench_push_front(b: &mut test::Bencher) {
+    let mut m: LinkedList<_> = LinkedList::new();
+    b.iter(|| {
+        m.push_front(0);
+    })
+}
+
+#[bench]
+fn bench_push_back(b: &mut test::Bencher) {
+    let mut m: LinkedList<_> = LinkedList::new();
+    b.iter(|| {
+        m.push_back(0);
+    })
+}
+
+#[bench]
+fn bench_push_back_pop_back(b: &mut test::Bencher) {
+    let mut m: LinkedList<_> = LinkedList::new();
+    b.iter(|| {
+        m.push_back(0);
+        m.pop_back();
+    })
+}
+
+#[bench]
+fn bench_push_front_pop_front(b: &mut test::Bencher) {
+    let mut m: LinkedList<_> = LinkedList::new();
+    b.iter(|| {
+        m.push_front(0);
+        m.pop_front();
+    })
+}
+
+#[bench]
+fn bench_iter(b: &mut test::Bencher) {
+    let v = &[0; 128];
+    let m: LinkedList<_> = v.iter().cloned().collect();
+    b.iter(|| {
+        assert!(m.iter().count() == 128);
+    })
+}
+#[bench]
+fn bench_iter_mut(b: &mut test::Bencher) {
+    let v = &[0; 128];
+    let mut m: LinkedList<_> = v.iter().cloned().collect();
+    b.iter(|| {
+        assert!(m.iter_mut().count() == 128);
+    })
+}
+#[bench]
+fn bench_iter_rev(b: &mut test::Bencher) {
+    let v = &[0; 128];
+    let m: LinkedList<_> = v.iter().cloned().collect();
+    b.iter(|| {
+        assert!(m.iter().rev().count() == 128);
+    })
+}
+#[bench]
+fn bench_iter_mut_rev(b: &mut test::Bencher) {
+    let v = &[0; 128];
+    let mut m: LinkedList<_> = v.iter().cloned().collect();
+    b.iter(|| {
+        assert!(m.iter_mut().rev().count() == 128);
+    })
+}
diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs
new file mode 100644 (file)
index 0000000..5b0aceb
--- /dev/null
@@ -0,0 +1,1572 @@
+// Copyright 2012-2015 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 std::cmp::Ordering::{Equal, Greater, Less};
+use std::default::Default;
+use std::iter::RandomAccessIterator;
+use std::mem;
+use std::rand::{Rng, thread_rng};
+use std::rc::Rc;
+use std::slice::ElementSwaps;
+
+fn square(n: usize) -> usize { n * n }
+
+fn is_odd(n: &usize) -> bool { *n % 2 == 1 }
+
+#[test]
+fn test_from_fn() {
+    // Test on-stack from_fn.
+    let mut v: Vec<_> = (0..3).map(square).collect();
+    {
+        let v = v;
+        assert_eq!(v.len(), 3);
+        assert_eq!(v[0], 0);
+        assert_eq!(v[1], 1);
+        assert_eq!(v[2], 4);
+    }
+
+    // Test on-heap from_fn.
+    v = (0..5).map(square).collect();
+    {
+        let v = v;
+        assert_eq!(v.len(), 5);
+        assert_eq!(v[0], 0);
+        assert_eq!(v[1], 1);
+        assert_eq!(v[2], 4);
+        assert_eq!(v[3], 9);
+        assert_eq!(v[4], 16);
+    }
+}
+
+#[test]
+fn test_from_elem() {
+    // Test on-stack from_elem.
+    let mut v = vec![10, 10];
+    {
+        let v = v;
+        assert_eq!(v.len(), 2);
+        assert_eq!(v[0], 10);
+        assert_eq!(v[1], 10);
+    }
+
+    // Test on-heap from_elem.
+    v = vec![20; 6];
+    {
+        let v = &v[..];
+        assert_eq!(v[0], 20);
+        assert_eq!(v[1], 20);
+        assert_eq!(v[2], 20);
+        assert_eq!(v[3], 20);
+        assert_eq!(v[4], 20);
+        assert_eq!(v[5], 20);
+    }
+}
+
+#[test]
+fn test_is_empty() {
+    let xs: [i32; 0] = [];
+    assert!(xs.is_empty());
+    assert!(![0].is_empty());
+}
+
+#[test]
+fn test_len_divzero() {
+    type Z = [i8; 0];
+    let v0 : &[Z] = &[];
+    let v1 : &[Z] = &[[]];
+    let v2 : &[Z] = &[[], []];
+    assert_eq!(mem::size_of::<Z>(), 0);
+    assert_eq!(v0.len(), 0);
+    assert_eq!(v1.len(), 1);
+    assert_eq!(v2.len(), 2);
+}
+
+#[test]
+fn test_get() {
+    let mut a = vec![11];
+    assert_eq!(a.get(1), None);
+    a = vec![11, 12];
+    assert_eq!(a.get(1).unwrap(), &12);
+    a = vec![11, 12, 13];
+    assert_eq!(a.get(1).unwrap(), &12);
+}
+
+#[test]
+fn test_first() {
+    let mut a = vec![];
+    assert_eq!(a.first(), None);
+    a = vec![11];
+    assert_eq!(a.first().unwrap(), &11);
+    a = vec![11, 12];
+    assert_eq!(a.first().unwrap(), &11);
+}
+
+#[test]
+fn test_first_mut() {
+    let mut a = vec![];
+    assert_eq!(a.first_mut(), None);
+    a = vec![11];
+    assert_eq!(*a.first_mut().unwrap(), 11);
+    a = vec![11, 12];
+    assert_eq!(*a.first_mut().unwrap(), 11);
+}
+
+#[test]
+fn test_tail() {
+    let mut a = vec![11];
+    let b: &[i32] = &[];
+    assert_eq!(a.tail(), b);
+    a = vec![11, 12];
+    let b: &[i32] = &[12];
+    assert_eq!(a.tail(), b);
+}
+
+#[test]
+fn test_tail_mut() {
+    let mut a = vec![11];
+    let b: &mut [i32] = &mut [];
+    assert!(a.tail_mut() == b);
+    a = vec![11, 12];
+    let b: &mut [_] = &mut [12];
+    assert!(a.tail_mut() == b);
+}
+
+#[test]
+#[should_panic]
+fn test_tail_empty() {
+    let a = Vec::<i32>::new();
+    a.tail();
+}
+
+#[test]
+#[should_panic]
+fn test_tail_mut_empty() {
+    let mut a = Vec::<i32>::new();
+    a.tail_mut();
+}
+
+#[test]
+fn test_init() {
+    let mut a = vec![11];
+    let b: &[i32] = &[];
+    assert_eq!(a.init(), b);
+    a = vec![11, 12];
+    let b: &[_] = &[11];
+    assert_eq!(a.init(), b);
+}
+
+#[test]
+fn test_init_mut() {
+    let mut a = vec![11];
+    let b: &mut [i32] = &mut [];
+    assert!(a.init_mut() == b);
+    a = vec![11, 12];
+    let b: &mut [_] = &mut [11];
+    assert!(a.init_mut() == b);
+}
+
+#[test]
+#[should_panic]
+fn test_init_empty() {
+    let a = Vec::<i32>::new();
+    a.init();
+}
+
+#[test]
+#[should_panic]
+fn test_init_mut_empty() {
+    let mut a = Vec::<i32>::new();
+    a.init_mut();
+}
+
+#[test]
+fn test_last() {
+    let mut a = vec![];
+    assert_eq!(a.last(), None);
+    a = vec![11];
+    assert_eq!(a.last().unwrap(), &11);
+    a = vec![11, 12];
+    assert_eq!(a.last().unwrap(), &12);
+}
+
+#[test]
+fn test_last_mut() {
+    let mut a = vec![];
+    assert_eq!(a.last_mut(), None);
+    a = vec![11];
+    assert_eq!(*a.last_mut().unwrap(), 11);
+    a = vec![11, 12];
+    assert_eq!(*a.last_mut().unwrap(), 12);
+}
+
+#[test]
+fn test_slice() {
+    // Test fixed length vector.
+    let vec_fixed = [1, 2, 3, 4];
+    let v_a = vec_fixed[1..vec_fixed.len()].to_vec();
+    assert_eq!(v_a.len(), 3);
+
+    assert_eq!(v_a[0], 2);
+    assert_eq!(v_a[1], 3);
+    assert_eq!(v_a[2], 4);
+
+    // Test on stack.
+    let vec_stack: &[_] = &[1, 2, 3];
+    let v_b = vec_stack[1..3].to_vec();
+    assert_eq!(v_b.len(), 2);
+
+    assert_eq!(v_b[0], 2);
+    assert_eq!(v_b[1], 3);
+
+    // Test `Box<[T]>`
+    let vec_unique = vec![1, 2, 3, 4, 5, 6];
+    let v_d = vec_unique[1..6].to_vec();
+    assert_eq!(v_d.len(), 5);
+
+    assert_eq!(v_d[0], 2);
+    assert_eq!(v_d[1], 3);
+    assert_eq!(v_d[2], 4);
+    assert_eq!(v_d[3], 5);
+    assert_eq!(v_d[4], 6);
+}
+
+#[test]
+fn test_slice_from() {
+    let vec: &[_] = &[1, 2, 3, 4];
+    assert_eq!(&vec[..], vec);
+    let b: &[_] = &[3, 4];
+    assert_eq!(&vec[2..], b);
+    let b: &[_] = &[];
+    assert_eq!(&vec[4..], b);
+}
+
+#[test]
+fn test_slice_to() {
+    let vec: &[_] = &[1, 2, 3, 4];
+    assert_eq!(&vec[..4], vec);
+    let b: &[_] = &[1, 2];
+    assert_eq!(&vec[..2], b);
+    let b: &[_] = &[];
+    assert_eq!(&vec[..0], b);
+}
+
+
+#[test]
+fn test_pop() {
+    let mut v = vec![5];
+    let e = v.pop();
+    assert_eq!(v.len(), 0);
+    assert_eq!(e, Some(5));
+    let f = v.pop();
+    assert_eq!(f, None);
+    let g = v.pop();
+    assert_eq!(g, None);
+}
+
+#[test]
+fn test_swap_remove() {
+    let mut v = vec![1, 2, 3, 4, 5];
+    let mut e = v.swap_remove(0);
+    assert_eq!(e, 1);
+    assert_eq!(v, [5, 2, 3, 4]);
+    e = v.swap_remove(3);
+    assert_eq!(e, 4);
+    assert_eq!(v, [5, 2, 3]);
+}
+
+#[test]
+#[should_panic]
+fn test_swap_remove_fail() {
+    let mut v = vec![1];
+    let _ = v.swap_remove(0);
+    let _ = v.swap_remove(0);
+}
+
+#[test]
+fn test_swap_remove_noncopyable() {
+    // Tests that we don't accidentally run destructors twice.
+    let mut v: Vec<Box<_>> = Vec::new();
+    v.push(box 0u8);
+    v.push(box 0u8);
+    v.push(box 0u8);
+    let mut _e = v.swap_remove(0);
+    assert_eq!(v.len(), 2);
+    _e = v.swap_remove(1);
+    assert_eq!(v.len(), 1);
+    _e = v.swap_remove(0);
+    assert_eq!(v.len(), 0);
+}
+
+#[test]
+fn test_push() {
+    // Test on-stack push().
+    let mut v = vec![];
+    v.push(1);
+    assert_eq!(v.len(), 1);
+    assert_eq!(v[0], 1);
+
+    // Test on-heap push().
+    v.push(2);
+    assert_eq!(v.len(), 2);
+    assert_eq!(v[0], 1);
+    assert_eq!(v[1], 2);
+}
+
+#[test]
+fn test_truncate() {
+    let mut v: Vec<Box<_>> = vec![box 6,box 5,box 4];
+    v.truncate(1);
+    let v = v;
+    assert_eq!(v.len(), 1);
+    assert_eq!(*(v[0]), 6);
+    // If the unsafe block didn't drop things properly, we blow up here.
+}
+
+#[test]
+fn test_clear() {
+    let mut v: Vec<Box<_>> = vec![box 6,box 5,box 4];
+    v.clear();
+    assert_eq!(v.len(), 0);
+    // If the unsafe block didn't drop things properly, we blow up here.
+}
+
+#[test]
+fn test_dedup() {
+    fn case(a: Vec<i32>, b: Vec<i32>) {
+        let mut v = a;
+        v.dedup();
+        assert_eq!(v, b);
+    }
+    case(vec![], vec![]);
+    case(vec![1], vec![1]);
+    case(vec![1,1], vec![1]);
+    case(vec![1,2,3], vec![1,2,3]);
+    case(vec![1,1,2,3], vec![1,2,3]);
+    case(vec![1,2,2,3], vec![1,2,3]);
+    case(vec![1,2,3,3], vec![1,2,3]);
+    case(vec![1,1,2,2,2,3,3], vec![1,2,3]);
+}
+
+#[test]
+fn test_dedup_unique() {
+    let mut v0: Vec<Box<_>> = vec![box 1, box 1, box 2, box 3];
+    v0.dedup();
+    let mut v1: Vec<Box<_>> = vec![box 1, box 2, box 2, box 3];
+    v1.dedup();
+    let mut v2: Vec<Box<_>> = vec![box 1, box 2, box 3, box 3];
+    v2.dedup();
+    /*
+     * If the boxed pointers were leaked or otherwise misused, valgrind
+     * and/or rt should raise errors.
+     */
+}
+
+#[test]
+fn test_dedup_shared() {
+    let mut v0: Vec<Box<_>> = vec![box 1, box 1, box 2, box 3];
+    v0.dedup();
+    let mut v1: Vec<Box<_>> = vec![box 1, box 2, box 2, box 3];
+    v1.dedup();
+    let mut v2: Vec<Box<_>> = vec![box 1, box 2, box 3, box 3];
+    v2.dedup();
+    /*
+     * If the pointers were leaked or otherwise misused, valgrind and/or
+     * rt should raise errors.
+     */
+}
+
+#[test]
+fn test_retain() {
+    let mut v = vec![1, 2, 3, 4, 5];
+    v.retain(is_odd);
+    assert_eq!(v, [1, 3, 5]);
+}
+
+#[test]
+fn test_element_swaps() {
+    let mut v = [1, 2, 3];
+    for (i, (a, b)) in ElementSwaps::new(v.len()).enumerate() {
+        v.swap(a, b);
+        match i {
+            0 => assert!(v == [1, 3, 2]),
+            1 => assert!(v == [3, 1, 2]),
+            2 => assert!(v == [3, 2, 1]),
+            3 => assert!(v == [2, 3, 1]),
+            4 => assert!(v == [2, 1, 3]),
+            5 => assert!(v == [1, 2, 3]),
+            _ => panic!(),
+        }
+    }
+}
+
+#[test]
+fn test_lexicographic_permutations() {
+    let v : &mut[_] = &mut[1, 2, 3, 4, 5];
+    assert!(v.prev_permutation() == false);
+    assert!(v.next_permutation());
+    let b: &mut[_] = &mut[1, 2, 3, 5, 4];
+    assert!(v == b);
+    assert!(v.prev_permutation());
+    let b: &mut[_] = &mut[1, 2, 3, 4, 5];
+    assert!(v == b);
+    assert!(v.next_permutation());
+    assert!(v.next_permutation());
+    let b: &mut[_] = &mut[1, 2, 4, 3, 5];
+    assert!(v == b);
+    assert!(v.next_permutation());
+    let b: &mut[_] = &mut[1, 2, 4, 5, 3];
+    assert!(v == b);
+
+    let v : &mut[_] = &mut[1, 0, 0, 0];
+    assert!(v.next_permutation() == false);
+    assert!(v.prev_permutation());
+    let b: &mut[_] = &mut[0, 1, 0, 0];
+    assert!(v == b);
+    assert!(v.prev_permutation());
+    let b: &mut[_] = &mut[0, 0, 1, 0];
+    assert!(v == b);
+    assert!(v.prev_permutation());
+    let b: &mut[_] = &mut[0, 0, 0, 1];
+    assert!(v == b);
+    assert!(v.prev_permutation() == false);
+}
+
+#[test]
+fn test_lexicographic_permutations_empty_and_short() {
+    let empty : &mut[i32] = &mut[];
+    assert!(empty.next_permutation() == false);
+    let b: &mut[i32] = &mut[];
+    assert!(empty == b);
+    assert!(empty.prev_permutation() == false);
+    assert!(empty == b);
+
+    let one_elem : &mut[_] = &mut[4];
+    assert!(one_elem.prev_permutation() == false);
+    let b: &mut[_] = &mut[4];
+    assert!(one_elem == b);
+    assert!(one_elem.next_permutation() == false);
+    assert!(one_elem == b);
+
+    let two_elem : &mut[_] = &mut[1, 2];
+    assert!(two_elem.prev_permutation() == false);
+    let b : &mut[_] = &mut[1, 2];
+    let c : &mut[_] = &mut[2, 1];
+    assert!(two_elem == b);
+    assert!(two_elem.next_permutation());
+    assert!(two_elem == c);
+    assert!(two_elem.next_permutation() == false);
+    assert!(two_elem == c);
+    assert!(two_elem.prev_permutation());
+    assert!(two_elem == b);
+    assert!(two_elem.prev_permutation() == false);
+    assert!(two_elem == b);
+}
+
+#[test]
+fn test_position_elem() {
+    assert!([].position_elem(&1).is_none());
+
+    let v1 = vec![1, 2, 3, 3, 2, 5];
+    assert_eq!(v1.position_elem(&1), Some(0));
+    assert_eq!(v1.position_elem(&2), Some(1));
+    assert_eq!(v1.position_elem(&5), Some(5));
+    assert!(v1.position_elem(&4).is_none());
+}
+
+#[test]
+fn test_binary_search() {
+    assert_eq!([1,2,3,4,5].binary_search(&5).ok(), Some(4));
+    assert_eq!([1,2,3,4,5].binary_search(&4).ok(), Some(3));
+    assert_eq!([1,2,3,4,5].binary_search(&3).ok(), Some(2));
+    assert_eq!([1,2,3,4,5].binary_search(&2).ok(), Some(1));
+    assert_eq!([1,2,3,4,5].binary_search(&1).ok(), Some(0));
+
+    assert_eq!([2,4,6,8,10].binary_search(&1).ok(), None);
+    assert_eq!([2,4,6,8,10].binary_search(&5).ok(), None);
+    assert_eq!([2,4,6,8,10].binary_search(&4).ok(), Some(1));
+    assert_eq!([2,4,6,8,10].binary_search(&10).ok(), Some(4));
+
+    assert_eq!([2,4,6,8].binary_search(&1).ok(), None);
+    assert_eq!([2,4,6,8].binary_search(&5).ok(), None);
+    assert_eq!([2,4,6,8].binary_search(&4).ok(), Some(1));
+    assert_eq!([2,4,6,8].binary_search(&8).ok(), Some(3));
+
+    assert_eq!([2,4,6].binary_search(&1).ok(), None);
+    assert_eq!([2,4,6].binary_search(&5).ok(), None);
+    assert_eq!([2,4,6].binary_search(&4).ok(), Some(1));
+    assert_eq!([2,4,6].binary_search(&6).ok(), Some(2));
+
+    assert_eq!([2,4].binary_search(&1).ok(), None);
+    assert_eq!([2,4].binary_search(&5).ok(), None);
+    assert_eq!([2,4].binary_search(&2).ok(), Some(0));
+    assert_eq!([2,4].binary_search(&4).ok(), Some(1));
+
+    assert_eq!([2].binary_search(&1).ok(), None);
+    assert_eq!([2].binary_search(&5).ok(), None);
+    assert_eq!([2].binary_search(&2).ok(), Some(0));
+
+    assert_eq!([].binary_search(&1).ok(), None);
+    assert_eq!([].binary_search(&5).ok(), None);
+
+    assert!([1,1,1,1,1].binary_search(&1).ok() != None);
+    assert!([1,1,1,1,2].binary_search(&1).ok() != None);
+    assert!([1,1,1,2,2].binary_search(&1).ok() != None);
+    assert!([1,1,2,2,2].binary_search(&1).ok() != None);
+    assert_eq!([1,2,2,2,2].binary_search(&1).ok(), Some(0));
+
+    assert_eq!([1,2,3,4,5].binary_search(&6).ok(), None);
+    assert_eq!([1,2,3,4,5].binary_search(&0).ok(), None);
+}
+
+#[test]
+fn test_reverse() {
+    let mut v = vec![10, 20];
+    assert_eq!(v[0], 10);
+    assert_eq!(v[1], 20);
+    v.reverse();
+    assert_eq!(v[0], 20);
+    assert_eq!(v[1], 10);
+
+    let mut v3 = Vec::<i32>::new();
+    v3.reverse();
+    assert!(v3.is_empty());
+}
+
+#[test]
+fn test_sort() {
+    for len in 4..25 {
+        for _ in 0..100 {
+            let mut v: Vec<_> = thread_rng().gen_iter::<i32>().take(len).collect();
+            let mut v1 = v.clone();
+
+            v.sort();
+            assert!(v.windows(2).all(|w| w[0] <= w[1]));
+
+            v1.sort_by(|a, b| a.cmp(b));
+            assert!(v1.windows(2).all(|w| w[0] <= w[1]));
+
+            v1.sort_by(|a, b| b.cmp(a));
+            assert!(v1.windows(2).all(|w| w[0] >= w[1]));
+        }
+    }
+
+    // shouldn't panic
+    let mut v: [i32; 0] = [];
+    v.sort();
+
+    let mut v = [0xDEADBEEFu64];
+    v.sort();
+    assert!(v == [0xDEADBEEF]);
+}
+
+#[test]
+fn test_sort_stability() {
+    for len in 4..25 {
+        for _ in 0..10 {
+            let mut counts = [0; 10];
+
+            // create a vector like [(6, 1), (5, 1), (6, 2), ...],
+            // where the first item of each tuple is random, but
+            // the second item represents which occurrence of that
+            // number this element is, i.e. the second elements
+            // will occur in sorted order.
+            let mut v: Vec<_> = (0..len).map(|_| {
+                    let n = thread_rng().gen::<usize>() % 10;
+                    counts[n] += 1;
+                    (n, counts[n])
+                }).collect();
+
+            // only sort on the first element, so an unstable sort
+            // may mix up the counts.
+            v.sort_by(|&(a,_), &(b,_)| a.cmp(&b));
+
+            // this comparison includes the count (the second item
+            // of the tuple), so elements with equal first items
+            // will need to be ordered with increasing
+            // counts... i.e. exactly asserting that this sort is
+            // stable.
+            assert!(v.windows(2).all(|w| w[0] <= w[1]));
+        }
+    }
+}
+
+#[test]
+fn test_concat() {
+    let v: [Vec<i32>; 0] = [];
+    let c = v.concat();
+    assert_eq!(c, []);
+    let d = [vec![1], vec![2, 3]].concat();
+    assert_eq!(d, [1, 2, 3]);
+
+    let v: &[&[_]] = &[&[1], &[2, 3]];
+    assert_eq!(v.connect(&0), [1, 0, 2, 3]);
+    let v: &[&[_]] = &[&[1], &[2], &[3]];
+    assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]);
+}
+
+#[test]
+fn test_connect() {
+    let v: [Vec<i32>; 0] = [];
+    assert_eq!(v.connect(&0), []);
+    assert_eq!([vec![1], vec![2, 3]].connect(&0), [1, 0, 2, 3]);
+    assert_eq!([vec![1], vec![2], vec![3]].connect(&0), [1, 0, 2, 0, 3]);
+
+    let v: [&[_]; 2] = [&[1], &[2, 3]];
+    assert_eq!(v.connect(&0), [1, 0, 2, 3]);
+    let v: [&[_]; 3] = [&[1], &[2], &[3]];
+    assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]);
+}
+
+#[test]
+fn test_insert() {
+    let mut a = vec![1, 2, 4];
+    a.insert(2, 3);
+    assert_eq!(a, [1, 2, 3, 4]);
+
+    let mut a = vec![1, 2, 3];
+    a.insert(0, 0);
+    assert_eq!(a, [0, 1, 2, 3]);
+
+    let mut a = vec![1, 2, 3];
+    a.insert(3, 4);
+    assert_eq!(a, [1, 2, 3, 4]);
+
+    let mut a = vec![];
+    a.insert(0, 1);
+    assert_eq!(a, [1]);
+}
+
+#[test]
+#[should_panic]
+fn test_insert_oob() {
+    let mut a = vec![1, 2, 3];
+    a.insert(4, 5);
+}
+
+#[test]
+fn test_remove() {
+    let mut a = vec![1, 2, 3, 4];
+
+    assert_eq!(a.remove(2), 3);
+    assert_eq!(a, [1, 2, 4]);
+
+    assert_eq!(a.remove(2), 4);
+    assert_eq!(a, [1, 2]);
+
+    assert_eq!(a.remove(0), 1);
+    assert_eq!(a, [2]);
+
+    assert_eq!(a.remove(0), 2);
+    assert_eq!(a, []);
+}
+
+#[test]
+#[should_panic]
+fn test_remove_fail() {
+    let mut a = vec![1];
+    let _ = a.remove(0);
+    let _ = a.remove(0);
+}
+
+#[test]
+fn test_capacity() {
+    let mut v = vec![0];
+    v.reserve_exact(10);
+    assert!(v.capacity() >= 11);
+}
+
+#[test]
+fn test_slice_2() {
+    let v = vec![1, 2, 3, 4, 5];
+    let v = &v[1..3];
+    assert_eq!(v.len(), 2);
+    assert_eq!(v[0], 2);
+    assert_eq!(v[1], 3);
+}
+
+#[test]
+#[should_panic]
+fn test_permute_fail() {
+    let v: [(Box<_>, Rc<_>); 4] =
+        [(box 0, Rc::new(0)), (box 0, Rc::new(0)),
+         (box 0, Rc::new(0)), (box 0, Rc::new(0))];
+    let mut i = 0;
+    for _ in v.permutations() {
+        if i == 2 {
+            panic!()
+        }
+        i += 1;
+    }
+}
+
+#[test]
+fn test_total_ord() {
+    let c = &[1, 2, 3];
+    [1, 2, 3, 4][..].cmp(c) == Greater;
+    let c = &[1, 2, 3, 4];
+    [1, 2, 3][..].cmp(c) == Less;
+    let c = &[1, 2, 3, 6];
+    [1, 2, 3, 4][..].cmp(c) == Equal;
+    let c = &[1, 2, 3, 4, 5, 6];
+    [1, 2, 3, 4, 5, 5, 5, 5][..].cmp(c) == Less;
+    let c = &[1, 2, 3, 4];
+    [2, 2][..].cmp(c) == Greater;
+}
+
+#[test]
+fn test_iterator() {
+    let xs = [1, 2, 5, 10, 11];
+    let mut it = xs.iter();
+    assert_eq!(it.size_hint(), (5, Some(5)));
+    assert_eq!(it.next().unwrap(), &1);
+    assert_eq!(it.size_hint(), (4, Some(4)));
+    assert_eq!(it.next().unwrap(), &2);
+    assert_eq!(it.size_hint(), (3, Some(3)));
+    assert_eq!(it.next().unwrap(), &5);
+    assert_eq!(it.size_hint(), (2, Some(2)));
+    assert_eq!(it.next().unwrap(), &10);
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(it.next().unwrap(), &11);
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_random_access_iterator() {
+    let xs = [1, 2, 5, 10, 11];
+    let mut it = xs.iter();
+
+    assert_eq!(it.indexable(), 5);
+    assert_eq!(it.idx(0).unwrap(), &1);
+    assert_eq!(it.idx(2).unwrap(), &5);
+    assert_eq!(it.idx(4).unwrap(), &11);
+    assert!(it.idx(5).is_none());
+
+    assert_eq!(it.next().unwrap(), &1);
+    assert_eq!(it.indexable(), 4);
+    assert_eq!(it.idx(0).unwrap(), &2);
+    assert_eq!(it.idx(3).unwrap(), &11);
+    assert!(it.idx(4).is_none());
+
+    assert_eq!(it.next().unwrap(), &2);
+    assert_eq!(it.indexable(), 3);
+    assert_eq!(it.idx(1).unwrap(), &10);
+    assert!(it.idx(3).is_none());
+
+    assert_eq!(it.next().unwrap(), &5);
+    assert_eq!(it.indexable(), 2);
+    assert_eq!(it.idx(1).unwrap(), &11);
+
+    assert_eq!(it.next().unwrap(), &10);
+    assert_eq!(it.indexable(), 1);
+    assert_eq!(it.idx(0).unwrap(), &11);
+    assert!(it.idx(1).is_none());
+
+    assert_eq!(it.next().unwrap(), &11);
+    assert_eq!(it.indexable(), 0);
+    assert!(it.idx(0).is_none());
+
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_iter_size_hints() {
+    let mut xs = [1, 2, 5, 10, 11];
+    assert_eq!(xs.iter().size_hint(), (5, Some(5)));
+    assert_eq!(xs.iter_mut().size_hint(), (5, Some(5)));
+}
+
+#[test]
+fn test_iter_clone() {
+    let xs = [1, 2, 5];
+    let mut it = xs.iter();
+    it.next();
+    let mut jt = it.clone();
+    assert_eq!(it.next(), jt.next());
+    assert_eq!(it.next(), jt.next());
+    assert_eq!(it.next(), jt.next());
+}
+
+#[test]
+fn test_mut_iterator() {
+    let mut xs = [1, 2, 3, 4, 5];
+    for x in &mut xs {
+        *x += 1;
+    }
+    assert!(xs == [2, 3, 4, 5, 6])
+}
+
+#[test]
+fn test_rev_iterator() {
+
+    let xs = [1, 2, 5, 10, 11];
+    let ys = [11, 10, 5, 2, 1];
+    let mut i = 0;
+    for &x in xs.iter().rev() {
+        assert_eq!(x, ys[i]);
+        i += 1;
+    }
+    assert_eq!(i, 5);
+}
+
+#[test]
+fn test_mut_rev_iterator() {
+    let mut xs = [1, 2, 3, 4, 5];
+    for (i,x) in xs.iter_mut().rev().enumerate() {
+        *x += i;
+    }
+    assert!(xs == [5, 5, 5, 5, 5])
+}
+
+#[test]
+fn test_move_iterator() {
+    let xs = vec![1,2,3,4,5];
+    assert_eq!(xs.into_iter().fold(0, |a: usize, b: usize| 10*a + b), 12345);
+}
+
+#[test]
+fn test_move_rev_iterator() {
+    let xs = vec![1,2,3,4,5];
+    assert_eq!(xs.into_iter().rev().fold(0, |a: usize, b: usize| 10*a + b), 54321);
+}
+
+#[test]
+fn test_splitator() {
+    let xs = &[1,2,3,4,5];
+
+    let splits: &[&[_]] = &[&[1], &[3], &[5]];
+    assert_eq!(xs.split(|x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[], &[2,3,4,5]];
+    assert_eq!(xs.split(|x| *x == 1).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[1,2,3,4], &[]];
+    assert_eq!(xs.split(|x| *x == 5).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[1,2,3,4,5]];
+    assert_eq!(xs.split(|x| *x == 10).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[], &[], &[], &[], &[], &[]];
+    assert_eq!(xs.split(|_| true).collect::<Vec<&[i32]>>(),
+               splits);
+
+    let xs: &[i32] = &[];
+    let splits: &[&[i32]] = &[&[]];
+    assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[i32]>>(), splits);
+}
+
+#[test]
+fn test_splitnator() {
+    let xs = &[1,2,3,4,5];
+
+    let splits: &[&[_]] = &[&[1,2,3,4,5]];
+    assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[1], &[3,4,5]];
+    assert_eq!(xs.splitn(2, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[], &[], &[], &[4,5]];
+    assert_eq!(xs.splitn(4, |_| true).collect::<Vec<_>>(),
+               splits);
+
+    let xs: &[i32] = &[];
+    let splits: &[&[i32]] = &[&[]];
+    assert_eq!(xs.splitn(2, |x| *x == 5).collect::<Vec<_>>(), splits);
+}
+
+#[test]
+fn test_splitnator_mut() {
+    let xs = &mut [1,2,3,4,5];
+
+    let splits: &[&mut[_]] = &[&mut [1,2,3,4,5]];
+    assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&mut[_]] = &[&mut [1], &mut [3,4,5]];
+    assert_eq!(xs.splitn_mut(2, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&mut[_]] = &[&mut [], &mut [], &mut [], &mut [4,5]];
+    assert_eq!(xs.splitn_mut(4, |_| true).collect::<Vec<_>>(),
+               splits);
+
+    let xs: &mut [i32] = &mut [];
+    let splits: &[&mut[i32]] = &[&mut []];
+    assert_eq!(xs.splitn_mut(2, |x| *x == 5).collect::<Vec<_>>(),
+               splits);
+}
+
+#[test]
+fn test_rsplitator() {
+    let xs = &[1,2,3,4,5];
+
+    let splits: &[&[_]] = &[&[5], &[3], &[1]];
+    assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[2,3,4,5], &[]];
+    assert_eq!(xs.split(|x| *x == 1).rev().collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[], &[1,2,3,4]];
+    assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[1,2,3,4,5]];
+    assert_eq!(xs.split(|x| *x == 10).rev().collect::<Vec<_>>(),
+               splits);
+
+    let xs: &[i32] = &[];
+    let splits: &[&[i32]] = &[&[]];
+    assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[i32]>>(), splits);
+}
+
+#[test]
+fn test_rsplitnator() {
+    let xs = &[1,2,3,4,5];
+
+    let splits: &[&[_]] = &[&[1,2,3,4,5]];
+    assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[5], &[1,2,3]];
+    assert_eq!(xs.rsplitn(2, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[], &[], &[], &[1,2]];
+    assert_eq!(xs.rsplitn(4, |_| true).collect::<Vec<_>>(),
+               splits);
+
+    let xs: &[i32]  = &[];
+    let splits: &[&[i32]] = &[&[]];
+    assert_eq!(xs.rsplitn(2, |x| *x == 5).collect::<Vec<&[i32]>>(), splits);
+    assert!(xs.rsplitn(0, |x| *x % 2 == 0).next().is_none());
+}
+
+#[test]
+fn test_windowsator() {
+    let v = &[1,2,3,4];
+
+    let wins: &[&[_]] = &[&[1,2], &[2,3], &[3,4]];
+    assert_eq!(v.windows(2).collect::<Vec<_>>(), wins);
+
+    let wins: &[&[_]] = &[&[1,2,3], &[2,3,4]];
+    assert_eq!(v.windows(3).collect::<Vec<_>>(), wins);
+    assert!(v.windows(6).next().is_none());
+
+    let wins: &[&[_]] = &[&[3,4], &[2,3], &[1,2]];
+    assert_eq!(v.windows(2).rev().collect::<Vec<&[_]>>(), wins);
+    let mut it = v.windows(2);
+    assert_eq!(it.indexable(), 3);
+    let win: &[_] = &[1,2];
+    assert_eq!(it.idx(0).unwrap(), win);
+    let win: &[_] = &[2,3];
+    assert_eq!(it.idx(1).unwrap(), win);
+    let win: &[_] = &[3,4];
+    assert_eq!(it.idx(2).unwrap(), win);
+    assert_eq!(it.idx(3), None);
+}
+
+#[test]
+#[should_panic]
+fn test_windowsator_0() {
+    let v = &[1,2,3,4];
+    let _it = v.windows(0);
+}
+
+#[test]
+fn test_chunksator() {
+    let v = &[1,2,3,4,5];
+
+    assert_eq!(v.chunks(2).len(), 3);
+
+    let chunks: &[&[_]] = &[&[1,2], &[3,4], &[5]];
+    assert_eq!(v.chunks(2).collect::<Vec<_>>(), chunks);
+    let chunks: &[&[_]] = &[&[1,2,3], &[4,5]];
+    assert_eq!(v.chunks(3).collect::<Vec<_>>(), chunks);
+    let chunks: &[&[_]] = &[&[1,2,3,4,5]];
+    assert_eq!(v.chunks(6).collect::<Vec<_>>(), chunks);
+
+    let chunks: &[&[_]] = &[&[5], &[3,4], &[1,2]];
+    assert_eq!(v.chunks(2).rev().collect::<Vec<_>>(), chunks);
+    let mut it = v.chunks(2);
+    assert_eq!(it.indexable(), 3);
+
+    let chunk: &[_] = &[1,2];
+    assert_eq!(it.idx(0).unwrap(), chunk);
+    let chunk: &[_] = &[3,4];
+    assert_eq!(it.idx(1).unwrap(), chunk);
+    let chunk: &[_] = &[5];
+    assert_eq!(it.idx(2).unwrap(), chunk);
+    assert_eq!(it.idx(3), None);
+}
+
+#[test]
+#[should_panic]
+fn test_chunksator_0() {
+    let v = &[1,2,3,4];
+    let _it = v.chunks(0);
+}
+
+#[test]
+fn test_move_from() {
+    let mut a = [1,2,3,4,5];
+    let b = vec![6,7,8];
+    assert_eq!(a.move_from(b, 0, 3), 3);
+    assert!(a == [6,7,8,4,5]);
+    let mut a = [7,2,8,1];
+    let b = vec![3,1,4,1,5,9];
+    assert_eq!(a.move_from(b, 0, 6), 4);
+    assert!(a == [3,1,4,1]);
+    let mut a = [1,2,3,4];
+    let b = vec![5,6,7,8,9,0];
+    assert_eq!(a.move_from(b, 2, 3), 1);
+    assert!(a == [7,2,3,4]);
+    let mut a = [1,2,3,4,5];
+    let b = vec![5,6,7,8,9,0];
+    assert_eq!(a[2..4].move_from(b,1,6), 2);
+    assert!(a == [1,2,6,7,5]);
+}
+
+#[test]
+fn test_reverse_part() {
+    let mut values = [1,2,3,4,5];
+    values[1..4].reverse();
+    assert!(values == [1,4,3,2,5]);
+}
+
+#[test]
+fn test_show() {
+    macro_rules! test_show_vec {
+        ($x:expr, $x_str:expr) => ({
+            let (x, x_str) = ($x, $x_str);
+            assert_eq!(format!("{:?}", x), x_str);
+            assert_eq!(format!("{:?}", x), x_str);
+        })
+    }
+    let empty = Vec::<i32>::new();
+    test_show_vec!(empty, "[]");
+    test_show_vec!(vec![1], "[1]");
+    test_show_vec!(vec![1, 2, 3], "[1, 2, 3]");
+    test_show_vec!(vec![vec![], vec![1], vec![1, 1]],
+                   "[[], [1], [1, 1]]");
+
+    let empty_mut: &mut [i32] = &mut[];
+    test_show_vec!(empty_mut, "[]");
+    let v = &mut[1];
+    test_show_vec!(v, "[1]");
+    let v = &mut[1, 2, 3];
+    test_show_vec!(v, "[1, 2, 3]");
+    let v: &mut[&mut[_]] = &mut[&mut[], &mut[1], &mut[1, 1]];
+    test_show_vec!(v, "[[], [1], [1, 1]]");
+}
+
+#[test]
+fn test_vec_default() {
+    macro_rules! t {
+        ($ty:ty) => {{
+            let v: $ty = Default::default();
+            assert!(v.is_empty());
+        }}
+    }
+
+    t!(&[i32]);
+    t!(Vec<i32>);
+}
+
+#[test]
+fn test_bytes_set_memory() {
+    use std::slice::bytes::MutableByteVector;
+
+    let mut values = [1,2,3,4,5];
+    values[0..5].set_memory(0xAB);
+    assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
+    values[2..4].set_memory(0xFF);
+    assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
+}
+
+#[test]
+#[should_panic]
+fn test_overflow_does_not_cause_segfault() {
+    let mut v = vec![];
+    v.reserve_exact(!0);
+    v.push(1);
+    v.push(2);
+}
+
+#[test]
+#[should_panic]
+fn test_overflow_does_not_cause_segfault_managed() {
+    let mut v = vec![Rc::new(1)];
+    v.reserve_exact(!0);
+    v.push(Rc::new(2));
+}
+
+#[test]
+fn test_mut_split_at() {
+    let mut values = [1u8,2,3,4,5];
+    {
+        let (left, right) = values.split_at_mut(2);
+        {
+            let left: &[_] = left;
+            assert!(left[..left.len()] == [1, 2]);
+        }
+        for p in left {
+            *p += 1;
+        }
+
+        {
+            let right: &[_] = right;
+            assert!(right[..right.len()] == [3, 4, 5]);
+        }
+        for p in right {
+            *p += 2;
+        }
+    }
+
+    assert!(values == [2, 3, 5, 6, 7]);
+}
+
+#[derive(Clone, PartialEq)]
+struct Foo;
+
+#[test]
+fn test_iter_zero_sized() {
+    let mut v = vec![Foo, Foo, Foo];
+    assert_eq!(v.len(), 3);
+    let mut cnt = 0;
+
+    for f in &v {
+        assert!(*f == Foo);
+        cnt += 1;
+    }
+    assert_eq!(cnt, 3);
+
+    for f in &v[1..3] {
+        assert!(*f == Foo);
+        cnt += 1;
+    }
+    assert_eq!(cnt, 5);
+
+    for f in &mut v {
+        assert!(*f == Foo);
+        cnt += 1;
+    }
+    assert_eq!(cnt, 8);
+
+    for f in v {
+        assert!(f == Foo);
+        cnt += 1;
+    }
+    assert_eq!(cnt, 11);
+
+    let xs: [Foo; 3] = [Foo, Foo, Foo];
+    cnt = 0;
+    for f in &xs {
+        assert!(*f == Foo);
+        cnt += 1;
+    }
+    assert!(cnt == 3);
+}
+
+#[test]
+fn test_shrink_to_fit() {
+    let mut xs = vec![0, 1, 2, 3];
+    for i in 4..100 {
+        xs.push(i)
+    }
+    assert_eq!(xs.capacity(), 128);
+    xs.shrink_to_fit();
+    assert_eq!(xs.capacity(), 100);
+    assert_eq!(xs, (0..100).collect::<Vec<_>>());
+}
+
+#[test]
+fn test_starts_with() {
+    assert!(b"foobar".starts_with(b"foo"));
+    assert!(!b"foobar".starts_with(b"oob"));
+    assert!(!b"foobar".starts_with(b"bar"));
+    assert!(!b"foo".starts_with(b"foobar"));
+    assert!(!b"bar".starts_with(b"foobar"));
+    assert!(b"foobar".starts_with(b"foobar"));
+    let empty: &[u8] = &[];
+    assert!(empty.starts_with(empty));
+    assert!(!empty.starts_with(b"foo"));
+    assert!(b"foobar".starts_with(empty));
+}
+
+#[test]
+fn test_ends_with() {
+    assert!(b"foobar".ends_with(b"bar"));
+    assert!(!b"foobar".ends_with(b"oba"));
+    assert!(!b"foobar".ends_with(b"foo"));
+    assert!(!b"foo".ends_with(b"foobar"));
+    assert!(!b"bar".ends_with(b"foobar"));
+    assert!(b"foobar".ends_with(b"foobar"));
+    let empty: &[u8] = &[];
+    assert!(empty.ends_with(empty));
+    assert!(!empty.ends_with(b"foo"));
+    assert!(b"foobar".ends_with(empty));
+}
+
+#[test]
+fn test_mut_splitator() {
+    let mut xs = [0,1,0,2,3,0,0,4,5,0];
+    assert_eq!(xs.split_mut(|x| *x == 0).count(), 6);
+    for slice in xs.split_mut(|x| *x == 0) {
+        slice.reverse();
+    }
+    assert!(xs == [0,1,0,3,2,0,0,5,4,0]);
+
+    let mut xs = [0,1,0,2,3,0,0,4,5,0,6,7];
+    for slice in xs.split_mut(|x| *x == 0).take(5) {
+        slice.reverse();
+    }
+    assert!(xs == [0,1,0,3,2,0,0,5,4,0,6,7]);
+}
+
+#[test]
+fn test_mut_splitator_rev() {
+    let mut xs = [1,2,0,3,4,0,0,5,6,0];
+    for slice in xs.split_mut(|x| *x == 0).rev().take(4) {
+        slice.reverse();
+    }
+    assert!(xs == [1,2,0,4,3,0,0,6,5,0]);
+}
+
+#[test]
+fn test_get_mut() {
+    let mut v = [0,1,2];
+    assert_eq!(v.get_mut(3), None);
+    v.get_mut(1).map(|e| *e = 7);
+    assert_eq!(v[1], 7);
+    let mut x = 2;
+    assert_eq!(v.get_mut(2), Some(&mut x));
+}
+
+#[test]
+fn test_mut_chunks() {
+    let mut v = [0, 1, 2, 3, 4, 5, 6];
+    assert_eq!(v.chunks_mut(2).len(), 4);
+    for (i, chunk) in v.chunks_mut(3).enumerate() {
+        for x in chunk {
+            *x = i as u8;
+        }
+    }
+    let result = [0, 0, 0, 1, 1, 1, 2];
+    assert!(v == result);
+}
+
+#[test]
+fn test_mut_chunks_rev() {
+    let mut v = [0, 1, 2, 3, 4, 5, 6];
+    for (i, chunk) in v.chunks_mut(3).rev().enumerate() {
+        for x in chunk {
+            *x = i as u8;
+        }
+    }
+    let result = [2, 2, 2, 1, 1, 1, 0];
+    assert!(v == result);
+}
+
+#[test]
+#[should_panic]
+fn test_mut_chunks_0() {
+    let mut v = [1, 2, 3, 4];
+    let _it = v.chunks_mut(0);
+}
+
+#[test]
+fn test_mut_last() {
+    let mut x = [1, 2, 3, 4, 5];
+    let h = x.last_mut();
+    assert_eq!(*h.unwrap(), 5);
+
+    let y: &mut [i32] = &mut [];
+    assert!(y.last_mut().is_none());
+}
+
+#[test]
+fn test_to_vec() {
+    let xs: Box<_> = box [1, 2, 3];
+    let ys = xs.to_vec();
+    assert_eq!(ys, [1, 2, 3]);
+}
+
+mod bench {
+    use std::iter::repeat;
+    use std::{mem, ptr};
+    use std::rand::{Rng, weak_rng};
+
+    use test::{Bencher, black_box};
+
+    #[bench]
+    fn iterator(b: &mut Bencher) {
+        // peculiar numbers to stop LLVM from optimising the summation
+        // out.
+        let v: Vec<_> = (0..100).map(|i| i ^ (i << 1) ^ (i >> 1)).collect();
+
+        b.iter(|| {
+            let mut sum = 0;
+            for x in &v {
+                sum += *x;
+            }
+            // sum == 11806, to stop dead code elimination.
+            if sum == 0 {panic!()}
+        })
+    }
+
+    #[bench]
+    fn mut_iterator(b: &mut Bencher) {
+        let mut v: Vec<_> = repeat(0).take(100).collect();
+
+        b.iter(|| {
+            let mut i = 0;
+            for x in &mut v {
+                *x = i;
+                i += 1;
+            }
+        })
+    }
+
+    #[bench]
+    fn concat(b: &mut Bencher) {
+        let xss: Vec<Vec<i32>> =
+            (0..100).map(|i| (0..i).collect()).collect();
+        b.iter(|| {
+            xss.concat();
+        });
+    }
+
+    #[bench]
+    fn connect(b: &mut Bencher) {
+        let xss: Vec<Vec<i32>> =
+            (0..100).map(|i| (0..i).collect()).collect();
+        b.iter(|| {
+            xss.connect(&0)
+        });
+    }
+
+    #[bench]
+    fn push(b: &mut Bencher) {
+        let mut vec = Vec::<i32>::new();
+        b.iter(|| {
+            vec.push(0);
+            black_box(&vec);
+        });
+    }
+
+    #[bench]
+    fn starts_with_same_vector(b: &mut Bencher) {
+        let vec: Vec<_> = (0..100).collect();
+        b.iter(|| {
+            vec.starts_with(&vec)
+        })
+    }
+
+    #[bench]
+    fn starts_with_single_element(b: &mut Bencher) {
+        let vec: Vec<_> = vec![0];
+        b.iter(|| {
+            vec.starts_with(&vec)
+        })
+    }
+
+    #[bench]
+    fn starts_with_diff_one_element_at_end(b: &mut Bencher) {
+        let vec: Vec<_> = (0..100).collect();
+        let mut match_vec: Vec<_> = (0..99).collect();
+        match_vec.push(0);
+        b.iter(|| {
+            vec.starts_with(&match_vec)
+        })
+    }
+
+    #[bench]
+    fn ends_with_same_vector(b: &mut Bencher) {
+        let vec: Vec<_> = (0..100).collect();
+        b.iter(|| {
+            vec.ends_with(&vec)
+        })
+    }
+
+    #[bench]
+    fn ends_with_single_element(b: &mut Bencher) {
+        let vec: Vec<_> = vec![0];
+        b.iter(|| {
+            vec.ends_with(&vec)
+        })
+    }
+
+    #[bench]
+    fn ends_with_diff_one_element_at_beginning(b: &mut Bencher) {
+        let vec: Vec<_> = (0..100).collect();
+        let mut match_vec: Vec<_> = (0..100).collect();
+        match_vec[0] = 200;
+        b.iter(|| {
+            vec.starts_with(&match_vec)
+        })
+    }
+
+    #[bench]
+    fn contains_last_element(b: &mut Bencher) {
+        let vec: Vec<_> = (0..100).collect();
+        b.iter(|| {
+            vec.contains(&99)
+        })
+    }
+
+    #[bench]
+    fn zero_1kb_from_elem(b: &mut Bencher) {
+        b.iter(|| {
+            repeat(0u8).take(1024).collect::<Vec<_>>()
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_set_memory(b: &mut Bencher) {
+        b.iter(|| {
+            let mut v = Vec::<u8>::with_capacity(1024);
+            unsafe {
+                let vp = v.as_mut_ptr();
+                ptr::write_bytes(vp, 0, 1024);
+                v.set_len(1024);
+            }
+            v
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_loop_set(b: &mut Bencher) {
+        b.iter(|| {
+            let mut v = Vec::<u8>::with_capacity(1024);
+            unsafe {
+                v.set_len(1024);
+            }
+            for i in 0..1024 {
+                v[i] = 0;
+            }
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_mut_iter(b: &mut Bencher) {
+        b.iter(|| {
+            let mut v = Vec::<u8>::with_capacity(1024);
+            unsafe {
+                v.set_len(1024);
+            }
+            for x in &mut v {
+                *x = 0;
+            }
+            v
+        });
+    }
+
+    #[bench]
+    fn random_inserts(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v: Vec<_> = repeat((0, 0)).take(30).collect();
+            for _ in 0..100 {
+                let l = v.len();
+                v.insert(rng.gen::<usize>() % (l + 1),
+                         (1, 1));
+            }
+        })
+    }
+    #[bench]
+    fn random_removes(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v: Vec<_> = repeat((0, 0)).take(130).collect();
+            for _ in 0..100 {
+                let l = v.len();
+                v.remove(rng.gen::<usize>() % l);
+            }
+        })
+    }
+
+    #[bench]
+    fn sort_random_small(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v: Vec<_> = rng.gen_iter::<u64>().take(5).collect();
+            v.sort();
+        });
+        b.bytes = 5 * mem::size_of::<u64>() as u64;
+    }
+
+    #[bench]
+    fn sort_random_medium(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v: Vec<_> = rng.gen_iter::<u64>().take(100).collect();
+            v.sort();
+        });
+        b.bytes = 100 * mem::size_of::<u64>() as u64;
+    }
+
+    #[bench]
+    fn sort_random_large(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v: Vec<_> = rng.gen_iter::<u64>().take(10000).collect();
+            v.sort();
+        });
+        b.bytes = 10000 * mem::size_of::<u64>() as u64;
+    }
+
+    #[bench]
+    fn sort_sorted(b: &mut Bencher) {
+        let mut v: Vec<_> = (0..10000).collect();
+        b.iter(|| {
+            v.sort();
+        });
+        b.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
+    }
+
+    type BigSortable = (u64, u64, u64, u64);
+
+    #[bench]
+    fn sort_big_random_small(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v = rng.gen_iter::<BigSortable>().take(5)
+                           .collect::<Vec<BigSortable>>();
+            v.sort();
+        });
+        b.bytes = 5 * mem::size_of::<BigSortable>() as u64;
+    }
+
+    #[bench]
+    fn sort_big_random_medium(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v = rng.gen_iter::<BigSortable>().take(100)
+                           .collect::<Vec<BigSortable>>();
+            v.sort();
+        });
+        b.bytes = 100 * mem::size_of::<BigSortable>() as u64;
+    }
+
+    #[bench]
+    fn sort_big_random_large(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v = rng.gen_iter::<BigSortable>().take(10000)
+                           .collect::<Vec<BigSortable>>();
+            v.sort();
+        });
+        b.bytes = 10000 * mem::size_of::<BigSortable>() as u64;
+    }
+
+    #[bench]
+    fn sort_big_sorted(b: &mut Bencher) {
+        let mut v: Vec<BigSortable> = (0..10000).map(|i| (i, i, i, i)).collect();
+        b.iter(|| {
+            v.sort();
+        });
+        b.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
+    }
+}
diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs
new file mode 100644 (file)
index 0000000..495a961
--- /dev/null
@@ -0,0 +1,1696 @@
+// 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.
+//
+// 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 std::cmp::Ordering::{Equal, Greater, Less};
+use std::iter::AdditiveIterator;
+use std::str::{Utf8Error, from_utf8};
+
+#[test]
+fn test_le() {
+    assert!("" <= "");
+    assert!("" <= "foo");
+    assert!("foo" <= "foo");
+    assert!("foo" != "bar");
+}
+
+#[test]
+fn test_len() {
+    assert_eq!("".len(), 0);
+    assert_eq!("hello world".len(), 11);
+    assert_eq!("\x63".len(), 1);
+    assert_eq!("\u{a2}".len(), 2);
+    assert_eq!("\u{3c0}".len(), 2);
+    assert_eq!("\u{2620}".len(), 3);
+    assert_eq!("\u{1d11e}".len(), 4);
+
+    assert_eq!("".chars().count(), 0);
+    assert_eq!("hello world".chars().count(), 11);
+    assert_eq!("\x63".chars().count(), 1);
+    assert_eq!("\u{a2}".chars().count(), 1);
+    assert_eq!("\u{3c0}".chars().count(), 1);
+    assert_eq!("\u{2620}".chars().count(), 1);
+    assert_eq!("\u{1d11e}".chars().count(), 1);
+    assert_eq!("ประเทศไทย中华Việt Nam".chars().count(), 19);
+
+    assert_eq!("hello".width(false), 10);
+    assert_eq!("hello".width(true), 10);
+    assert_eq!("\0\0\0\0\0".width(false), 0);
+    assert_eq!("\0\0\0\0\0".width(true), 0);
+    assert_eq!("".width(false), 0);
+    assert_eq!("".width(true), 0);
+    assert_eq!("\u{2081}\u{2082}\u{2083}\u{2084}".width(false), 4);
+    assert_eq!("\u{2081}\u{2082}\u{2083}\u{2084}".width(true), 8);
+}
+
+#[test]
+fn test_find() {
+    assert_eq!("hello".find('l'), Some(2));
+    assert_eq!("hello".find(|c:char| c == 'o'), Some(4));
+    assert!("hello".find('x').is_none());
+    assert!("hello".find(|c:char| c == 'x').is_none());
+    assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30));
+    assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30));
+}
+
+#[test]
+fn test_rfind() {
+    assert_eq!("hello".rfind('l'), Some(3));
+    assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4));
+    assert!("hello".rfind('x').is_none());
+    assert!("hello".rfind(|c:char| c == 'x').is_none());
+    assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30));
+    assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30));
+}
+
+#[test]
+fn test_collect() {
+    let empty = String::from_str("");
+    let s: String = empty.chars().collect();
+    assert_eq!(empty, s);
+    let data = String::from_str("ประเทศไทย中");
+    let s: String = data.chars().collect();
+    assert_eq!(data, s);
+}
+
+#[test]
+fn test_into_bytes() {
+    let data = String::from_str("asdf");
+    let buf = data.into_bytes();
+    assert_eq!(buf, b"asdf");
+}
+
+#[test]
+fn test_find_str() {
+    // byte positions
+    assert_eq!("".find(""), Some(0));
+    assert!("banana".find("apple pie").is_none());
+
+    let data = "abcabc";
+    assert_eq!(data[0..6].find("ab"), Some(0));
+    assert_eq!(data[2..6].find("ab"), Some(3 - 2));
+    assert!(data[2..4].find("ab").is_none());
+
+    let string = "ประเทศไทย中华Việt Nam";
+    let mut data = String::from_str(string);
+    data.push_str(string);
+    assert!(data.find("ไท华").is_none());
+    assert_eq!(data[0..43].find(""), Some(0));
+    assert_eq!(data[6..43].find(""), Some(6 - 6));
+
+    assert_eq!(data[0..43].find("ประ"), Some( 0));
+    assert_eq!(data[0..43].find("ทศไ"), Some(12));
+    assert_eq!(data[0..43].find("ย中"), Some(24));
+    assert_eq!(data[0..43].find("iệt"), Some(34));
+    assert_eq!(data[0..43].find("Nam"), Some(40));
+
+    assert_eq!(data[43..86].find("ประ"), Some(43 - 43));
+    assert_eq!(data[43..86].find("ทศไ"), Some(55 - 43));
+    assert_eq!(data[43..86].find("ย中"), Some(67 - 43));
+    assert_eq!(data[43..86].find("iệt"), Some(77 - 43));
+    assert_eq!(data[43..86].find("Nam"), Some(83 - 43));
+}
+
+#[test]
+fn test_slice_chars() {
+    fn t(a: &str, b: &str, start: usize) {
+        assert_eq!(a.slice_chars(start, start + b.chars().count()), b);
+    }
+    t("", "", 0);
+    t("hello", "llo", 2);
+    t("hello", "el", 1);
+    t("αβλ", "β", 1);
+    t("αβλ", "", 3);
+    assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
+}
+
+fn s(x: &str) -> String { x.to_string() }
+
+macro_rules! test_concat {
+    ($expected: expr, $string: expr) => {
+        {
+            let s: String = $string.concat();
+            assert_eq!($expected, s);
+        }
+    }
+}
+
+#[test]
+fn test_concat_for_different_types() {
+    test_concat!("ab", vec![s("a"), s("b")]);
+    test_concat!("ab", vec!["a", "b"]);
+    test_concat!("ab", vec!["a", "b"]);
+    test_concat!("ab", vec![s("a"), s("b")]);
+}
+
+#[test]
+fn test_concat_for_different_lengths() {
+    let empty: &[&str] = &[];
+    test_concat!("", empty);
+    test_concat!("a", ["a"]);
+    test_concat!("ab", ["a", "b"]);
+    test_concat!("abc", ["", "a", "bc"]);
+}
+
+macro_rules! test_connect {
+    ($expected: expr, $string: expr, $delim: expr) => {
+        {
+            let s = $string.connect($delim);
+            assert_eq!($expected, s);
+        }
+    }
+}
+
+#[test]
+fn test_connect_for_different_types() {
+    test_connect!("a-b", ["a", "b"], "-");
+    let hyphen = "-".to_string();
+    test_connect!("a-b", [s("a"), s("b")], &*hyphen);
+    test_connect!("a-b", vec!["a", "b"], &*hyphen);
+    test_connect!("a-b", &*vec!["a", "b"], "-");
+    test_connect!("a-b", vec![s("a"), s("b")], "-");
+}
+
+#[test]
+fn test_connect_for_different_lengths() {
+    let empty: &[&str] = &[];
+    test_connect!("", empty, "-");
+    test_connect!("a", ["a"], "-");
+    test_connect!("a-b", ["a", "b"], "-");
+    test_connect!("-a-bc", ["", "a", "bc"], "-");
+}
+
+#[test]
+fn test_unsafe_slice() {
+    assert_eq!("ab", unsafe {"abc".slice_unchecked(0, 2)});
+    assert_eq!("bc", unsafe {"abc".slice_unchecked(1, 3)});
+    assert_eq!("", unsafe {"abc".slice_unchecked(1, 1)});
+    fn a_million_letter_a() -> String {
+        let mut i = 0;
+        let mut rs = String::new();
+        while i < 100000 {
+            rs.push_str("aaaaaaaaaa");
+            i += 1;
+        }
+        rs
+    }
+    fn half_a_million_letter_a() -> String {
+        let mut i = 0;
+        let mut rs = String::new();
+        while i < 100000 {
+            rs.push_str("aaaaa");
+            i += 1;
+        }
+        rs
+    }
+    let letters = a_million_letter_a();
+    assert!(half_a_million_letter_a() ==
+        unsafe {String::from_str(letters.slice_unchecked(
+                                 0,
+                                 500000))});
+}
+
+#[test]
+fn test_starts_with() {
+    assert!(("".starts_with("")));
+    assert!(("abc".starts_with("")));
+    assert!(("abc".starts_with("a")));
+    assert!((!"a".starts_with("abc")));
+    assert!((!"".starts_with("abc")));
+    assert!((!"ödd".starts_with("-")));
+    assert!(("ödd".starts_with("öd")));
+}
+
+#[test]
+fn test_ends_with() {
+    assert!(("".ends_with("")));
+    assert!(("abc".ends_with("")));
+    assert!(("abc".ends_with("c")));
+    assert!((!"a".ends_with("abc")));
+    assert!((!"".ends_with("abc")));
+    assert!((!"ddö".ends_with("-")));
+    assert!(("ddö".ends_with("dö")));
+}
+
+#[test]
+fn test_is_empty() {
+    assert!("".is_empty());
+    assert!(!"a".is_empty());
+}
+
+#[test]
+fn test_replace() {
+    let a = "a";
+    assert_eq!("".replace(a, "b"), String::from_str(""));
+    assert_eq!("a".replace(a, "b"), String::from_str("b"));
+    assert_eq!("ab".replace(a, "b"), String::from_str("bb"));
+    let test = "test";
+    assert!(" test test ".replace(test, "toast") ==
+        String::from_str(" toast toast "));
+    assert_eq!(" test test ".replace(test, ""), String::from_str("   "));
+}
+
+#[test]
+fn test_replace_2a() {
+    let data = "ประเทศไทย中华";
+    let repl = "دولة الكويت";
+
+    let a = "ประเ";
+    let a2 = "دولة الكويتทศไทย中华";
+    assert_eq!(data.replace(a, repl), a2);
+}
+
+#[test]
+fn test_replace_2b() {
+    let data = "ประเทศไทย中华";
+    let repl = "دولة الكويت";
+
+    let b = "ะเ";
+    let b2 = "ปรدولة الكويتทศไทย中华";
+    assert_eq!(data.replace(b, repl), b2);
+}
+
+#[test]
+fn test_replace_2c() {
+    let data = "ประเทศไทย中华";
+    let repl = "دولة الكويت";
+
+    let c = "中华";
+    let c2 = "ประเทศไทยدولة الكويت";
+    assert_eq!(data.replace(c, repl), c2);
+}
+
+#[test]
+fn test_replace_2d() {
+    let data = "ประเทศไทย中华";
+    let repl = "دولة الكويت";
+
+    let d = "ไท华";
+    assert_eq!(data.replace(d, repl), data);
+}
+
+#[test]
+fn test_slice() {
+    assert_eq!("ab", &"abc"[0..2]);
+    assert_eq!("bc", &"abc"[1..3]);
+    assert_eq!("", &"abc"[1..1]);
+    assert_eq!("\u{65e5}", &"\u{65e5}\u{672c}"[0..3]);
+
+    let data = "ประเทศไทย中华";
+    assert_eq!("ป", &data[0..3]);
+    assert_eq!("ร", &data[3..6]);
+    assert_eq!("", &data[3..3]);
+    assert_eq!("华", &data[30..33]);
+
+    fn a_million_letter_x() -> String {
+        let mut i = 0;
+        let mut rs = String::new();
+        while i < 100000 {
+            rs.push_str("华华华华华华华华华华");
+            i += 1;
+        }
+        rs
+    }
+    fn half_a_million_letter_x() -> String {
+        let mut i = 0;
+        let mut rs = String::new();
+        while i < 100000 {
+            rs.push_str("华华华华华");
+            i += 1;
+        }
+        rs
+    }
+    let letters = a_million_letter_x();
+    assert!(half_a_million_letter_x() ==
+        String::from_str(&letters[0..3 * 500000]));
+}
+
+#[test]
+fn test_slice_2() {
+    let ss = "中华Việt Nam";
+
+    assert_eq!("华", &ss[3..6]);
+    assert_eq!("Việt Nam", &ss[6..16]);
+
+    assert_eq!("ab", &"abc"[0..2]);
+    assert_eq!("bc", &"abc"[1..3]);
+    assert_eq!("", &"abc"[1..1]);
+
+    assert_eq!("中", &ss[0..3]);
+    assert_eq!("华V", &ss[3..7]);
+    assert_eq!("", &ss[3..3]);
+    /*0: 中
+      3: 华
+      6: V
+      7: i
+      8: ệ
+     11: t
+     12:
+     13: N
+     14: a
+     15: m */
+}
+
+#[test]
+#[should_panic]
+fn test_slice_fail() {
+    &"中华Việt Nam"[0..2];
+}
+
+#[test]
+fn test_slice_from() {
+    assert_eq!(&"abcd"[0..], "abcd");
+    assert_eq!(&"abcd"[2..], "cd");
+    assert_eq!(&"abcd"[4..], "");
+}
+#[test]
+fn test_slice_to() {
+    assert_eq!(&"abcd"[..0], "");
+    assert_eq!(&"abcd"[..2], "ab");
+    assert_eq!(&"abcd"[..4], "abcd");
+}
+
+#[test]
+fn test_trim_left_matches() {
+    let v: &[char] = &[];
+    assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
+    let chars: &[char] = &['*', ' '];
+    assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
+    assert_eq!(" ***  *** ".trim_left_matches(chars), "");
+    assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
+
+    assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
+    let chars: &[char] = &['1', '2'];
+    assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
+    assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
+}
+
+#[test]
+fn test_trim_right_matches() {
+    let v: &[char] = &[];
+    assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
+    let chars: &[char] = &['*', ' '];
+    assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
+    assert_eq!(" ***  *** ".trim_right_matches(chars), "");
+    assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
+
+    assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
+    let chars: &[char] = &['1', '2'];
+    assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
+    assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
+}
+
+#[test]
+fn test_trim_matches() {
+    let v: &[char] = &[];
+    assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
+    let chars: &[char] = &['*', ' '];
+    assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
+    assert_eq!(" ***  *** ".trim_matches(chars), "");
+    assert_eq!("foo".trim_matches(chars), "foo");
+
+    assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
+    let chars: &[char] = &['1', '2'];
+    assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
+    assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
+}
+
+#[test]
+fn test_trim_left() {
+    assert_eq!("".trim_left(), "");
+    assert_eq!("a".trim_left(), "a");
+    assert_eq!("    ".trim_left(), "");
+    assert_eq!("     blah".trim_left(), "blah");
+    assert_eq!("   \u{3000}  wut".trim_left(), "wut");
+    assert_eq!("hey ".trim_left(), "hey ");
+}
+
+#[test]
+fn test_trim_right() {
+    assert_eq!("".trim_right(), "");
+    assert_eq!("a".trim_right(), "a");
+    assert_eq!("    ".trim_right(), "");
+    assert_eq!("blah     ".trim_right(), "blah");
+    assert_eq!("wut   \u{3000}  ".trim_right(), "wut");
+    assert_eq!(" hey".trim_right(), " hey");
+}
+
+#[test]
+fn test_trim() {
+    assert_eq!("".trim(), "");
+    assert_eq!("a".trim(), "a");
+    assert_eq!("    ".trim(), "");
+    assert_eq!("    blah     ".trim(), "blah");
+    assert_eq!("\nwut   \u{3000}  ".trim(), "wut");
+    assert_eq!(" hey dude ".trim(), "hey dude");
+}
+
+#[test]
+fn test_is_whitespace() {
+    assert!("".chars().all(|c| c.is_whitespace()));
+    assert!(" ".chars().all(|c| c.is_whitespace()));
+    assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
+    assert!("  \n\t   ".chars().all(|c| c.is_whitespace()));
+    assert!(!"   _   ".chars().all(|c| c.is_whitespace()));
+}
+
+#[test]
+fn test_slice_shift_char() {
+    let data = "ประเทศไทย中";
+    assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中")));
+}
+
+#[test]
+fn test_slice_shift_char_2() {
+    let empty = "";
+    assert_eq!(empty.slice_shift_char(), None);
+}
+
+#[test]
+fn test_is_utf8() {
+    // deny overlong encodings
+    assert!(from_utf8(&[0xc0, 0x80]).is_err());
+    assert!(from_utf8(&[0xc0, 0xae]).is_err());
+    assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
+    assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
+    assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
+    assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
+    assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
+
+    // deny surrogates
+    assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
+    assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
+
+    assert!(from_utf8(&[0xC2, 0x80]).is_ok());
+    assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
+    assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
+    assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
+    assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
+    assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
+    assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
+    assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
+}
+
+#[test]
+fn test_is_utf16() {
+    use unicode::str::is_utf16;
+
+    macro_rules! pos {
+        ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } }
+    }
+
+    // non-surrogates
+    pos!(&[0x0000],
+         &[0x0001, 0x0002],
+         &[0xD7FF],
+         &[0xE000]);
+
+    // surrogate pairs (randomly generated with Python 3's
+    // .encode('utf-16be'))
+    pos!(&[0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
+         &[0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
+         &[0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
+
+    // mixtures (also random)
+    pos!(&[0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
+         &[0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
+         &[0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
+
+    // negative tests
+    macro_rules! neg {
+        ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } }
+    }
+
+    neg!(
+        // surrogate + regular unit
+        &[0xdb45, 0x0000],
+        // surrogate + lead surrogate
+        &[0xd900, 0xd900],
+        // unterminated surrogate
+        &[0xd8ff],
+        // trail surrogate without a lead
+        &[0xddb7]);
+
+    // random byte sequences that Python 3's .decode('utf-16be')
+    // failed on
+    neg!(&[0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
+         &[0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
+         &[0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
+         &[0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
+         &[0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
+         &[0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
+         &[0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
+         &[0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
+         &[0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
+         &[0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
+         &[0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
+         &[0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
+         &[0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
+         &[0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
+         &[0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
+         &[0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
+         &[0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
+         &[0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
+         &[0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
+         &[0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
+         &[0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
+}
+
+#[test]
+fn test_as_bytes() {
+    // no null
+    let v = [
+        224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+        184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+        109
+    ];
+    let b: &[u8] = &[];
+    assert_eq!("".as_bytes(), b);
+    assert_eq!("abc".as_bytes(), b"abc");
+    assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
+}
+
+#[test]
+#[should_panic]
+fn test_as_bytes_fail() {
+    // Don't double free. (I'm not sure if this exercises the
+    // original problem code path anymore.)
+    let s = String::from_str("");
+    let _bytes = s.as_bytes();
+    panic!();
+}
+
+#[test]
+fn test_as_ptr() {
+    let buf = "hello".as_ptr();
+    unsafe {
+        assert_eq!(*buf.offset(0), b'h');
+        assert_eq!(*buf.offset(1), b'e');
+        assert_eq!(*buf.offset(2), b'l');
+        assert_eq!(*buf.offset(3), b'l');
+        assert_eq!(*buf.offset(4), b'o');
+    }
+}
+
+#[test]
+fn test_subslice_offset() {
+    let a = "kernelsprite";
+    let b = &a[7..a.len()];
+    let c = &a[0..a.len() - 6];
+    assert_eq!(a.subslice_offset(b), 7);
+    assert_eq!(a.subslice_offset(c), 0);
+
+    let string = "a\nb\nc";
+    let lines: Vec<&str> = string.lines().collect();
+    assert_eq!(string.subslice_offset(lines[0]), 0);
+    assert_eq!(string.subslice_offset(lines[1]), 2);
+    assert_eq!(string.subslice_offset(lines[2]), 4);
+}
+
+#[test]
+#[should_panic]
+fn test_subslice_offset_2() {
+    let a = "alchemiter";
+    let b = "cruxtruder";
+    a.subslice_offset(b);
+}
+
+#[test]
+fn vec_str_conversions() {
+    let s1: String = String::from_str("All mimsy were the borogoves");
+
+    let v: Vec<u8> = s1.as_bytes().to_vec();
+    let s2: String = String::from_str(from_utf8(&v).unwrap());
+    let mut i = 0;
+    let n1 = s1.len();
+    let n2 = v.len();
+    assert_eq!(n1, n2);
+    while i < n1 {
+        let a: u8 = s1.as_bytes()[i];
+        let b: u8 = s2.as_bytes()[i];
+        debug!("{}", a);
+        debug!("{}", b);
+        assert_eq!(a, b);
+        i += 1;
+    }
+}
+
+#[test]
+fn test_contains() {
+    assert!("abcde".contains("bcd"));
+    assert!("abcde".contains("abcd"));
+    assert!("abcde".contains("bcde"));
+    assert!("abcde".contains(""));
+    assert!("".contains(""));
+    assert!(!"abcde".contains("def"));
+    assert!(!"".contains("a"));
+
+    let data = "ประเทศไทย中华Việt Nam";
+    assert!(data.contains("ประเ"));
+    assert!(data.contains("ะเ"));
+    assert!(data.contains("中华"));
+    assert!(!data.contains("ไท华"));
+}
+
+#[test]
+fn test_contains_char() {
+    assert!("abc".contains('b'));
+    assert!("a".contains('a'));
+    assert!(!"abc".contains('d'));
+    assert!(!"".contains('a'));
+}
+
+#[test]
+fn test_char_at() {
+    let s = "ศไทย中华Việt Nam";
+    let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+    let mut pos = 0;
+    for ch in &v {
+        assert!(s.char_at(pos) == *ch);
+        pos += ch.to_string().len();
+    }
+}
+
+#[test]
+fn test_char_at_reverse() {
+    let s = "ศไทย中华Việt Nam";
+    let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+    let mut pos = s.len();
+    for ch in v.iter().rev() {
+        assert!(s.char_at_reverse(pos) == *ch);
+        pos -= ch.to_string().len();
+    }
+}
+
+#[test]
+fn test_escape_unicode() {
+    assert_eq!("abc".escape_unicode(),
+               String::from_str("\\u{61}\\u{62}\\u{63}"));
+    assert_eq!("a c".escape_unicode(),
+               String::from_str("\\u{61}\\u{20}\\u{63}"));
+    assert_eq!("\r\n\t".escape_unicode(),
+               String::from_str("\\u{d}\\u{a}\\u{9}"));
+    assert_eq!("'\"\\".escape_unicode(),
+               String::from_str("\\u{27}\\u{22}\\u{5c}"));
+    assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(),
+               String::from_str("\\u{0}\\u{1}\\u{fe}\\u{ff}"));
+    assert_eq!("\u{100}\u{ffff}".escape_unicode(),
+               String::from_str("\\u{100}\\u{ffff}"));
+    assert_eq!("\u{10000}\u{10ffff}".escape_unicode(),
+               String::from_str("\\u{10000}\\u{10ffff}"));
+    assert_eq!("ab\u{fb00}".escape_unicode(),
+               String::from_str("\\u{61}\\u{62}\\u{fb00}"));
+    assert_eq!("\u{1d4ea}\r".escape_unicode(),
+               String::from_str("\\u{1d4ea}\\u{d}"));
+}
+
+#[test]
+fn test_escape_default() {
+    assert_eq!("abc".escape_default(), String::from_str("abc"));
+    assert_eq!("a c".escape_default(), String::from_str("a c"));
+    assert_eq!("\r\n\t".escape_default(), String::from_str("\\r\\n\\t"));
+    assert_eq!("'\"\\".escape_default(), String::from_str("\\'\\\"\\\\"));
+    assert_eq!("\u{100}\u{ffff}".escape_default(),
+               String::from_str("\\u{100}\\u{ffff}"));
+    assert_eq!("\u{10000}\u{10ffff}".escape_default(),
+               String::from_str("\\u{10000}\\u{10ffff}"));
+    assert_eq!("ab\u{fb00}".escape_default(),
+               String::from_str("ab\\u{fb00}"));
+    assert_eq!("\u{1d4ea}\r".escape_default(),
+               String::from_str("\\u{1d4ea}\\r"));
+}
+
+#[test]
+fn test_total_ord() {
+    "1234".cmp("123") == Greater;
+    "123".cmp("1234") == Less;
+    "1234".cmp("1234") == Equal;
+    "12345555".cmp("123456") == Less;
+    "22".cmp("1234") == Greater;
+}
+
+#[test]
+fn test_char_range_at() {
+    let data = "b¢€𤭢𤭢€¢b";
+    assert_eq!('b', data.char_range_at(0).ch);
+    assert_eq!('¢', data.char_range_at(1).ch);
+    assert_eq!('€', data.char_range_at(3).ch);
+    assert_eq!('𤭢', data.char_range_at(6).ch);
+    assert_eq!('𤭢', data.char_range_at(10).ch);
+    assert_eq!('€', data.char_range_at(14).ch);
+    assert_eq!('¢', data.char_range_at(17).ch);
+    assert_eq!('b', data.char_range_at(19).ch);
+}
+
+#[test]
+fn test_char_range_at_reverse_underflow() {
+    assert_eq!("abc".char_range_at_reverse(0).next, 0);
+}
+
+#[test]
+fn test_iterator() {
+    let s = "ศไทย中华Việt Nam";
+    let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+
+    let mut pos = 0;
+    let it = s.chars();
+
+    for c in it {
+        assert_eq!(c, v[pos]);
+        pos += 1;
+    }
+    assert_eq!(pos, v.len());
+}
+
+#[test]
+fn test_rev_iterator() {
+    let s = "ศไทย中华Việt Nam";
+    let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
+
+    let mut pos = 0;
+    let it = s.chars().rev();
+
+    for c in it {
+        assert_eq!(c, v[pos]);
+        pos += 1;
+    }
+    assert_eq!(pos, v.len());
+}
+
+#[test]
+fn test_chars_decoding() {
+    let mut bytes = [0; 4];
+    for c in (0..0x110000).filter_map(::std::char::from_u32) {
+        let len = c.encode_utf8(&mut bytes).unwrap_or(0);
+        let s = ::std::str::from_utf8(&bytes[..len]).unwrap();
+        if Some(c) != s.chars().next() {
+            panic!("character {:x}={} does not decode correctly", c as u32, c);
+        }
+    }
+}
+
+#[test]
+fn test_chars_rev_decoding() {
+    let mut bytes = [0; 4];
+    for c in (0..0x110000).filter_map(::std::char::from_u32) {
+        let len = c.encode_utf8(&mut bytes).unwrap_or(0);
+        let s = ::std::str::from_utf8(&bytes[..len]).unwrap();
+        if Some(c) != s.chars().rev().next() {
+            panic!("character {:x}={} does not decode correctly", c as u32, c);
+        }
+    }
+}
+
+#[test]
+fn test_iterator_clone() {
+    let s = "ศไทย中华Việt Nam";
+    let mut it = s.chars();
+    it.next();
+    assert!(it.clone().zip(it).all(|(x,y)| x == y));
+}
+
+#[test]
+fn test_bytesator() {
+    let s = "ศไทย中华Việt Nam";
+    let v = [
+        224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+        184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+        109
+    ];
+    let mut pos = 0;
+
+    for b in s.bytes() {
+        assert_eq!(b, v[pos]);
+        pos += 1;
+    }
+}
+
+#[test]
+fn test_bytes_revator() {
+    let s = "ศไทย中华Việt Nam";
+    let v = [
+        224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+        184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+        109
+    ];
+    let mut pos = v.len();
+
+    for b in s.bytes().rev() {
+        pos -= 1;
+        assert_eq!(b, v[pos]);
+    }
+}
+
+#[test]
+fn test_char_indicesator() {
+    let s = "ศไทย中华Việt Nam";
+    let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
+    let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+
+    let mut pos = 0;
+    let it = s.char_indices();
+
+    for c in it {
+        assert_eq!(c, (p[pos], v[pos]));
+        pos += 1;
+    }
+    assert_eq!(pos, v.len());
+    assert_eq!(pos, p.len());
+}
+
+#[test]
+fn test_char_indices_revator() {
+    let s = "ศไทย中华Việt Nam";
+    let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
+    let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
+
+    let mut pos = 0;
+    let it = s.char_indices().rev();
+
+    for c in it {
+        assert_eq!(c, (p[pos], v[pos]));
+        pos += 1;
+    }
+    assert_eq!(pos, v.len());
+    assert_eq!(pos, p.len());
+}
+
+#[test]
+fn test_splitn_char_iterator() {
+    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+    let split: Vec<&str> = data.splitn(4, ' ').collect();
+    assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
+
+    let split: Vec<&str> = data.splitn(4, |c: char| c == ' ').collect();
+    assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
+
+    // Unicode
+    let split: Vec<&str> = data.splitn(4, 'ä').collect();
+    assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+
+    let split: Vec<&str> = data.splitn(4, |c: char| c == 'ä').collect();
+    assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+}
+
+#[test]
+fn test_split_char_iterator_no_trailing() {
+    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+    let split: Vec<&str> = data.split('\n').collect();
+    assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
+
+    let split: Vec<&str> = data.split_terminator('\n').collect();
+    assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
+}
+
+#[test]
+fn test_rsplit() {
+    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+    let split: Vec<&str> = data.rsplit(' ').collect();
+    assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
+
+    let split: Vec<&str> = data.rsplit("lämb").collect();
+    assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
+
+    let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
+    assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
+}
+
+#[test]
+fn test_rsplitn() {
+    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+    let split: Vec<&str> = data.rsplitn(2, ' ').collect();
+    assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
+
+    let split: Vec<&str> = data.rsplitn(2, "lämb").collect();
+    assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
+
+    let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect();
+    assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
+}
+
+#[test]
+fn test_words() {
+    let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
+    let words: Vec<&str> = data.words().collect();
+    assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
+}
+
+#[test]
+fn test_nfd_chars() {
+    macro_rules! t {
+        ($input: expr, $expected: expr) => {
+            assert_eq!($input.nfd_chars().collect::<String>(), $expected);
+        }
+    }
+    t!("abc", "abc");
+    t!("\u{1e0b}\u{1c4}", "d\u{307}\u{1c4}");
+    t!("\u{2026}", "\u{2026}");
+    t!("\u{2126}", "\u{3a9}");
+    t!("\u{1e0b}\u{323}", "d\u{323}\u{307}");
+    t!("\u{1e0d}\u{307}", "d\u{323}\u{307}");
+    t!("a\u{301}", "a\u{301}");
+    t!("\u{301}a", "\u{301}a");
+    t!("\u{d4db}", "\u{1111}\u{1171}\u{11b6}");
+    t!("\u{ac1c}", "\u{1100}\u{1162}");
+}
+
+#[test]
+fn test_nfkd_chars() {
+    macro_rules! t {
+        ($input: expr, $expected: expr) => {
+            assert_eq!($input.nfkd_chars().collect::<String>(), $expected);
+        }
+    }
+    t!("abc", "abc");
+    t!("\u{1e0b}\u{1c4}", "d\u{307}DZ\u{30c}");
+    t!("\u{2026}", "...");
+    t!("\u{2126}", "\u{3a9}");
+    t!("\u{1e0b}\u{323}", "d\u{323}\u{307}");
+    t!("\u{1e0d}\u{307}", "d\u{323}\u{307}");
+    t!("a\u{301}", "a\u{301}");
+    t!("\u{301}a", "\u{301}a");
+    t!("\u{d4db}", "\u{1111}\u{1171}\u{11b6}");
+    t!("\u{ac1c}", "\u{1100}\u{1162}");
+}
+
+#[test]
+fn test_nfc_chars() {
+    macro_rules! t {
+        ($input: expr, $expected: expr) => {
+            assert_eq!($input.nfc_chars().collect::<String>(), $expected);
+        }
+    }
+    t!("abc", "abc");
+    t!("\u{1e0b}\u{1c4}", "\u{1e0b}\u{1c4}");
+    t!("\u{2026}", "\u{2026}");
+    t!("\u{2126}", "\u{3a9}");
+    t!("\u{1e0b}\u{323}", "\u{1e0d}\u{307}");
+    t!("\u{1e0d}\u{307}", "\u{1e0d}\u{307}");
+    t!("a\u{301}", "\u{e1}");
+    t!("\u{301}a", "\u{301}a");
+    t!("\u{d4db}", "\u{d4db}");
+    t!("\u{ac1c}", "\u{ac1c}");
+    t!("a\u{300}\u{305}\u{315}\u{5ae}b", "\u{e0}\u{5ae}\u{305}\u{315}b");
+}
+
+#[test]
+fn test_nfkc_chars() {
+    macro_rules! t {
+        ($input: expr, $expected: expr) => {
+            assert_eq!($input.nfkc_chars().collect::<String>(), $expected);
+        }
+    }
+    t!("abc", "abc");
+    t!("\u{1e0b}\u{1c4}", "\u{1e0b}D\u{17d}");
+    t!("\u{2026}", "...");
+    t!("\u{2126}", "\u{3a9}");
+    t!("\u{1e0b}\u{323}", "\u{1e0d}\u{307}");
+    t!("\u{1e0d}\u{307}", "\u{1e0d}\u{307}");
+    t!("a\u{301}", "\u{e1}");
+    t!("\u{301}a", "\u{301}a");
+    t!("\u{d4db}", "\u{d4db}");
+    t!("\u{ac1c}", "\u{ac1c}");
+    t!("a\u{300}\u{305}\u{315}\u{5ae}b", "\u{e0}\u{5ae}\u{305}\u{315}b");
+}
+
+#[test]
+fn test_lines() {
+    let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
+    let lines: Vec<&str> = data.lines().collect();
+    assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
+
+    let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
+    let lines: Vec<&str> = data.lines().collect();
+    assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
+}
+
+#[test]
+fn test_graphemes() {
+    use std::iter::order;
+
+    // official Unicode test data
+    // from http://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt
+    let test_same: [(_, &[_]); 325] = [
+        ("\u{20}\u{20}", &["\u{20}", "\u{20}"]),
+        ("\u{20}\u{308}\u{20}", &["\u{20}\u{308}", "\u{20}"]),
+        ("\u{20}\u{D}", &["\u{20}", "\u{D}"]),
+        ("\u{20}\u{308}\u{D}", &["\u{20}\u{308}", "\u{D}"]),
+        ("\u{20}\u{A}", &["\u{20}", "\u{A}"]),
+        ("\u{20}\u{308}\u{A}", &["\u{20}\u{308}", "\u{A}"]),
+        ("\u{20}\u{1}", &["\u{20}", "\u{1}"]),
+        ("\u{20}\u{308}\u{1}", &["\u{20}\u{308}", "\u{1}"]),
+        ("\u{20}\u{300}", &["\u{20}\u{300}"]),
+        ("\u{20}\u{308}\u{300}", &["\u{20}\u{308}\u{300}"]),
+        ("\u{20}\u{1100}", &["\u{20}", "\u{1100}"]),
+        ("\u{20}\u{308}\u{1100}", &["\u{20}\u{308}", "\u{1100}"]),
+        ("\u{20}\u{1160}", &["\u{20}", "\u{1160}"]),
+        ("\u{20}\u{308}\u{1160}", &["\u{20}\u{308}", "\u{1160}"]),
+        ("\u{20}\u{11A8}", &["\u{20}", "\u{11A8}"]),
+        ("\u{20}\u{308}\u{11A8}", &["\u{20}\u{308}", "\u{11A8}"]),
+        ("\u{20}\u{AC00}", &["\u{20}", "\u{AC00}"]),
+        ("\u{20}\u{308}\u{AC00}", &["\u{20}\u{308}", "\u{AC00}"]),
+        ("\u{20}\u{AC01}", &["\u{20}", "\u{AC01}"]),
+        ("\u{20}\u{308}\u{AC01}", &["\u{20}\u{308}", "\u{AC01}"]),
+        ("\u{20}\u{1F1E6}", &["\u{20}", "\u{1F1E6}"]),
+        ("\u{20}\u{308}\u{1F1E6}", &["\u{20}\u{308}", "\u{1F1E6}"]),
+        ("\u{20}\u{378}", &["\u{20}", "\u{378}"]),
+        ("\u{20}\u{308}\u{378}", &["\u{20}\u{308}", "\u{378}"]),
+        ("\u{D}\u{20}", &["\u{D}", "\u{20}"]),
+        ("\u{D}\u{308}\u{20}", &["\u{D}", "\u{308}", "\u{20}"]),
+        ("\u{D}\u{D}", &["\u{D}", "\u{D}"]),
+        ("\u{D}\u{308}\u{D}", &["\u{D}", "\u{308}", "\u{D}"]),
+        ("\u{D}\u{A}", &["\u{D}\u{A}"]),
+        ("\u{D}\u{308}\u{A}", &["\u{D}", "\u{308}", "\u{A}"]),
+        ("\u{D}\u{1}", &["\u{D}", "\u{1}"]),
+        ("\u{D}\u{308}\u{1}", &["\u{D}", "\u{308}", "\u{1}"]),
+        ("\u{D}\u{300}", &["\u{D}", "\u{300}"]),
+        ("\u{D}\u{308}\u{300}", &["\u{D}", "\u{308}\u{300}"]),
+        ("\u{D}\u{903}", &["\u{D}", "\u{903}"]),
+        ("\u{D}\u{1100}", &["\u{D}", "\u{1100}"]),
+        ("\u{D}\u{308}\u{1100}", &["\u{D}", "\u{308}", "\u{1100}"]),
+        ("\u{D}\u{1160}", &["\u{D}", "\u{1160}"]),
+        ("\u{D}\u{308}\u{1160}", &["\u{D}", "\u{308}", "\u{1160}"]),
+        ("\u{D}\u{11A8}", &["\u{D}", "\u{11A8}"]),
+        ("\u{D}\u{308}\u{11A8}", &["\u{D}", "\u{308}", "\u{11A8}"]),
+        ("\u{D}\u{AC00}", &["\u{D}", "\u{AC00}"]),
+        ("\u{D}\u{308}\u{AC00}", &["\u{D}", "\u{308}", "\u{AC00}"]),
+        ("\u{D}\u{AC01}", &["\u{D}", "\u{AC01}"]),
+        ("\u{D}\u{308}\u{AC01}", &["\u{D}", "\u{308}", "\u{AC01}"]),
+        ("\u{D}\u{1F1E6}", &["\u{D}", "\u{1F1E6}"]),
+        ("\u{D}\u{308}\u{1F1E6}", &["\u{D}", "\u{308}", "\u{1F1E6}"]),
+        ("\u{D}\u{378}", &["\u{D}", "\u{378}"]),
+        ("\u{D}\u{308}\u{378}", &["\u{D}", "\u{308}", "\u{378}"]),
+        ("\u{A}\u{20}", &["\u{A}", "\u{20}"]),
+        ("\u{A}\u{308}\u{20}", &["\u{A}", "\u{308}", "\u{20}"]),
+        ("\u{A}\u{D}", &["\u{A}", "\u{D}"]),
+        ("\u{A}\u{308}\u{D}", &["\u{A}", "\u{308}", "\u{D}"]),
+        ("\u{A}\u{A}", &["\u{A}", "\u{A}"]),
+        ("\u{A}\u{308}\u{A}", &["\u{A}", "\u{308}", "\u{A}"]),
+        ("\u{A}\u{1}", &["\u{A}", "\u{1}"]),
+        ("\u{A}\u{308}\u{1}", &["\u{A}", "\u{308}", "\u{1}"]),
+        ("\u{A}\u{300}", &["\u{A}", "\u{300}"]),
+        ("\u{A}\u{308}\u{300}", &["\u{A}", "\u{308}\u{300}"]),
+        ("\u{A}\u{903}", &["\u{A}", "\u{903}"]),
+        ("\u{A}\u{1100}", &["\u{A}", "\u{1100}"]),
+        ("\u{A}\u{308}\u{1100}", &["\u{A}", "\u{308}", "\u{1100}"]),
+        ("\u{A}\u{1160}", &["\u{A}", "\u{1160}"]),
+        ("\u{A}\u{308}\u{1160}", &["\u{A}", "\u{308}", "\u{1160}"]),
+        ("\u{A}\u{11A8}", &["\u{A}", "\u{11A8}"]),
+        ("\u{A}\u{308}\u{11A8}", &["\u{A}", "\u{308}", "\u{11A8}"]),
+        ("\u{A}\u{AC00}", &["\u{A}", "\u{AC00}"]),
+        ("\u{A}\u{308}\u{AC00}", &["\u{A}", "\u{308}", "\u{AC00}"]),
+        ("\u{A}\u{AC01}", &["\u{A}", "\u{AC01}"]),
+        ("\u{A}\u{308}\u{AC01}", &["\u{A}", "\u{308}", "\u{AC01}"]),
+        ("\u{A}\u{1F1E6}", &["\u{A}", "\u{1F1E6}"]),
+        ("\u{A}\u{308}\u{1F1E6}", &["\u{A}", "\u{308}", "\u{1F1E6}"]),
+        ("\u{A}\u{378}", &["\u{A}", "\u{378}"]),
+        ("\u{A}\u{308}\u{378}", &["\u{A}", "\u{308}", "\u{378}"]),
+        ("\u{1}\u{20}", &["\u{1}", "\u{20}"]),
+        ("\u{1}\u{308}\u{20}", &["\u{1}", "\u{308}", "\u{20}"]),
+        ("\u{1}\u{D}", &["\u{1}", "\u{D}"]),
+        ("\u{1}\u{308}\u{D}", &["\u{1}", "\u{308}", "\u{D}"]),
+        ("\u{1}\u{A}", &["\u{1}", "\u{A}"]),
+        ("\u{1}\u{308}\u{A}", &["\u{1}", "\u{308}", "\u{A}"]),
+        ("\u{1}\u{1}", &["\u{1}", "\u{1}"]),
+        ("\u{1}\u{308}\u{1}", &["\u{1}", "\u{308}", "\u{1}"]),
+        ("\u{1}\u{300}", &["\u{1}", "\u{300}"]),
+        ("\u{1}\u{308}\u{300}", &["\u{1}", "\u{308}\u{300}"]),
+        ("\u{1}\u{903}", &["\u{1}", "\u{903}"]),
+        ("\u{1}\u{1100}", &["\u{1}", "\u{1100}"]),
+        ("\u{1}\u{308}\u{1100}", &["\u{1}", "\u{308}", "\u{1100}"]),
+        ("\u{1}\u{1160}", &["\u{1}", "\u{1160}"]),
+        ("\u{1}\u{308}\u{1160}", &["\u{1}", "\u{308}", "\u{1160}"]),
+        ("\u{1}\u{11A8}", &["\u{1}", "\u{11A8}"]),
+        ("\u{1}\u{308}\u{11A8}", &["\u{1}", "\u{308}", "\u{11A8}"]),
+        ("\u{1}\u{AC00}", &["\u{1}", "\u{AC00}"]),
+        ("\u{1}\u{308}\u{AC00}", &["\u{1}", "\u{308}", "\u{AC00}"]),
+        ("\u{1}\u{AC01}", &["\u{1}", "\u{AC01}"]),
+        ("\u{1}\u{308}\u{AC01}", &["\u{1}", "\u{308}", "\u{AC01}"]),
+        ("\u{1}\u{1F1E6}", &["\u{1}", "\u{1F1E6}"]),
+        ("\u{1}\u{308}\u{1F1E6}", &["\u{1}", "\u{308}", "\u{1F1E6}"]),
+        ("\u{1}\u{378}", &["\u{1}", "\u{378}"]),
+        ("\u{1}\u{308}\u{378}", &["\u{1}", "\u{308}", "\u{378}"]),
+        ("\u{300}\u{20}", &["\u{300}", "\u{20}"]),
+        ("\u{300}\u{308}\u{20}", &["\u{300}\u{308}", "\u{20}"]),
+        ("\u{300}\u{D}", &["\u{300}", "\u{D}"]),
+        ("\u{300}\u{308}\u{D}", &["\u{300}\u{308}", "\u{D}"]),
+        ("\u{300}\u{A}", &["\u{300}", "\u{A}"]),
+        ("\u{300}\u{308}\u{A}", &["\u{300}\u{308}", "\u{A}"]),
+        ("\u{300}\u{1}", &["\u{300}", "\u{1}"]),
+        ("\u{300}\u{308}\u{1}", &["\u{300}\u{308}", "\u{1}"]),
+        ("\u{300}\u{300}", &["\u{300}\u{300}"]),
+        ("\u{300}\u{308}\u{300}", &["\u{300}\u{308}\u{300}"]),
+        ("\u{300}\u{1100}", &["\u{300}", "\u{1100}"]),
+        ("\u{300}\u{308}\u{1100}", &["\u{300}\u{308}", "\u{1100}"]),
+        ("\u{300}\u{1160}", &["\u{300}", "\u{1160}"]),
+        ("\u{300}\u{308}\u{1160}", &["\u{300}\u{308}", "\u{1160}"]),
+        ("\u{300}\u{11A8}", &["\u{300}", "\u{11A8}"]),
+        ("\u{300}\u{308}\u{11A8}", &["\u{300}\u{308}", "\u{11A8}"]),
+        ("\u{300}\u{AC00}", &["\u{300}", "\u{AC00}"]),
+        ("\u{300}\u{308}\u{AC00}", &["\u{300}\u{308}", "\u{AC00}"]),
+        ("\u{300}\u{AC01}", &["\u{300}", "\u{AC01}"]),
+        ("\u{300}\u{308}\u{AC01}", &["\u{300}\u{308}", "\u{AC01}"]),
+        ("\u{300}\u{1F1E6}", &["\u{300}", "\u{1F1E6}"]),
+        ("\u{300}\u{308}\u{1F1E6}", &["\u{300}\u{308}", "\u{1F1E6}"]),
+        ("\u{300}\u{378}", &["\u{300}", "\u{378}"]),
+        ("\u{300}\u{308}\u{378}", &["\u{300}\u{308}", "\u{378}"]),
+        ("\u{903}\u{20}", &["\u{903}", "\u{20}"]),
+        ("\u{903}\u{308}\u{20}", &["\u{903}\u{308}", "\u{20}"]),
+        ("\u{903}\u{D}", &["\u{903}", "\u{D}"]),
+        ("\u{903}\u{308}\u{D}", &["\u{903}\u{308}", "\u{D}"]),
+        ("\u{903}\u{A}", &["\u{903}", "\u{A}"]),
+        ("\u{903}\u{308}\u{A}", &["\u{903}\u{308}", "\u{A}"]),
+        ("\u{903}\u{1}", &["\u{903}", "\u{1}"]),
+        ("\u{903}\u{308}\u{1}", &["\u{903}\u{308}", "\u{1}"]),
+        ("\u{903}\u{300}", &["\u{903}\u{300}"]),
+        ("\u{903}\u{308}\u{300}", &["\u{903}\u{308}\u{300}"]),
+        ("\u{903}\u{1100}", &["\u{903}", "\u{1100}"]),
+        ("\u{903}\u{308}\u{1100}", &["\u{903}\u{308}", "\u{1100}"]),
+        ("\u{903}\u{1160}", &["\u{903}", "\u{1160}"]),
+        ("\u{903}\u{308}\u{1160}", &["\u{903}\u{308}", "\u{1160}"]),
+        ("\u{903}\u{11A8}", &["\u{903}", "\u{11A8}"]),
+        ("\u{903}\u{308}\u{11A8}", &["\u{903}\u{308}", "\u{11A8}"]),
+        ("\u{903}\u{AC00}", &["\u{903}", "\u{AC00}"]),
+        ("\u{903}\u{308}\u{AC00}", &["\u{903}\u{308}", "\u{AC00}"]),
+        ("\u{903}\u{AC01}", &["\u{903}", "\u{AC01}"]),
+        ("\u{903}\u{308}\u{AC01}", &["\u{903}\u{308}", "\u{AC01}"]),
+        ("\u{903}\u{1F1E6}", &["\u{903}", "\u{1F1E6}"]),
+        ("\u{903}\u{308}\u{1F1E6}", &["\u{903}\u{308}", "\u{1F1E6}"]),
+        ("\u{903}\u{378}", &["\u{903}", "\u{378}"]),
+        ("\u{903}\u{308}\u{378}", &["\u{903}\u{308}", "\u{378}"]),
+        ("\u{1100}\u{20}", &["\u{1100}", "\u{20}"]),
+        ("\u{1100}\u{308}\u{20}", &["\u{1100}\u{308}", "\u{20}"]),
+        ("\u{1100}\u{D}", &["\u{1100}", "\u{D}"]),
+        ("\u{1100}\u{308}\u{D}", &["\u{1100}\u{308}", "\u{D}"]),
+        ("\u{1100}\u{A}", &["\u{1100}", "\u{A}"]),
+        ("\u{1100}\u{308}\u{A}", &["\u{1100}\u{308}", "\u{A}"]),
+        ("\u{1100}\u{1}", &["\u{1100}", "\u{1}"]),
+        ("\u{1100}\u{308}\u{1}", &["\u{1100}\u{308}", "\u{1}"]),
+        ("\u{1100}\u{300}", &["\u{1100}\u{300}"]),
+        ("\u{1100}\u{308}\u{300}", &["\u{1100}\u{308}\u{300}"]),
+        ("\u{1100}\u{1100}", &["\u{1100}\u{1100}"]),
+        ("\u{1100}\u{308}\u{1100}", &["\u{1100}\u{308}", "\u{1100}"]),
+        ("\u{1100}\u{1160}", &["\u{1100}\u{1160}"]),
+        ("\u{1100}\u{308}\u{1160}", &["\u{1100}\u{308}", "\u{1160}"]),
+        ("\u{1100}\u{11A8}", &["\u{1100}", "\u{11A8}"]),
+        ("\u{1100}\u{308}\u{11A8}", &["\u{1100}\u{308}", "\u{11A8}"]),
+        ("\u{1100}\u{AC00}", &["\u{1100}\u{AC00}"]),
+        ("\u{1100}\u{308}\u{AC00}", &["\u{1100}\u{308}", "\u{AC00}"]),
+        ("\u{1100}\u{AC01}", &["\u{1100}\u{AC01}"]),
+        ("\u{1100}\u{308}\u{AC01}", &["\u{1100}\u{308}", "\u{AC01}"]),
+        ("\u{1100}\u{1F1E6}", &["\u{1100}", "\u{1F1E6}"]),
+        ("\u{1100}\u{308}\u{1F1E6}", &["\u{1100}\u{308}", "\u{1F1E6}"]),
+        ("\u{1100}\u{378}", &["\u{1100}", "\u{378}"]),
+        ("\u{1100}\u{308}\u{378}", &["\u{1100}\u{308}", "\u{378}"]),
+        ("\u{1160}\u{20}", &["\u{1160}", "\u{20}"]),
+        ("\u{1160}\u{308}\u{20}", &["\u{1160}\u{308}", "\u{20}"]),
+        ("\u{1160}\u{D}", &["\u{1160}", "\u{D}"]),
+        ("\u{1160}\u{308}\u{D}", &["\u{1160}\u{308}", "\u{D}"]),
+        ("\u{1160}\u{A}", &["\u{1160}", "\u{A}"]),
+        ("\u{1160}\u{308}\u{A}", &["\u{1160}\u{308}", "\u{A}"]),
+        ("\u{1160}\u{1}", &["\u{1160}", "\u{1}"]),
+        ("\u{1160}\u{308}\u{1}", &["\u{1160}\u{308}", "\u{1}"]),
+        ("\u{1160}\u{300}", &["\u{1160}\u{300}"]),
+        ("\u{1160}\u{308}\u{300}", &["\u{1160}\u{308}\u{300}"]),
+        ("\u{1160}\u{1100}", &["\u{1160}", "\u{1100}"]),
+        ("\u{1160}\u{308}\u{1100}", &["\u{1160}\u{308}", "\u{1100}"]),
+        ("\u{1160}\u{1160}", &["\u{1160}\u{1160}"]),
+        ("\u{1160}\u{308}\u{1160}", &["\u{1160}\u{308}", "\u{1160}"]),
+        ("\u{1160}\u{11A8}", &["\u{1160}\u{11A8}"]),
+        ("\u{1160}\u{308}\u{11A8}", &["\u{1160}\u{308}", "\u{11A8}"]),
+        ("\u{1160}\u{AC00}", &["\u{1160}", "\u{AC00}"]),
+        ("\u{1160}\u{308}\u{AC00}", &["\u{1160}\u{308}", "\u{AC00}"]),
+        ("\u{1160}\u{AC01}", &["\u{1160}", "\u{AC01}"]),
+        ("\u{1160}\u{308}\u{AC01}", &["\u{1160}\u{308}", "\u{AC01}"]),
+        ("\u{1160}\u{1F1E6}", &["\u{1160}", "\u{1F1E6}"]),
+        ("\u{1160}\u{308}\u{1F1E6}", &["\u{1160}\u{308}", "\u{1F1E6}"]),
+        ("\u{1160}\u{378}", &["\u{1160}", "\u{378}"]),
+        ("\u{1160}\u{308}\u{378}", &["\u{1160}\u{308}", "\u{378}"]),
+        ("\u{11A8}\u{20}", &["\u{11A8}", "\u{20}"]),
+        ("\u{11A8}\u{308}\u{20}", &["\u{11A8}\u{308}", "\u{20}"]),
+        ("\u{11A8}\u{D}", &["\u{11A8}", "\u{D}"]),
+        ("\u{11A8}\u{308}\u{D}", &["\u{11A8}\u{308}", "\u{D}"]),
+        ("\u{11A8}\u{A}", &["\u{11A8}", "\u{A}"]),
+        ("\u{11A8}\u{308}\u{A}", &["\u{11A8}\u{308}", "\u{A}"]),
+        ("\u{11A8}\u{1}", &["\u{11A8}", "\u{1}"]),
+        ("\u{11A8}\u{308}\u{1}", &["\u{11A8}\u{308}", "\u{1}"]),
+        ("\u{11A8}\u{300}", &["\u{11A8}\u{300}"]),
+        ("\u{11A8}\u{308}\u{300}", &["\u{11A8}\u{308}\u{300}"]),
+        ("\u{11A8}\u{1100}", &["\u{11A8}", "\u{1100}"]),
+        ("\u{11A8}\u{308}\u{1100}", &["\u{11A8}\u{308}", "\u{1100}"]),
+        ("\u{11A8}\u{1160}", &["\u{11A8}", "\u{1160}"]),
+        ("\u{11A8}\u{308}\u{1160}", &["\u{11A8}\u{308}", "\u{1160}"]),
+        ("\u{11A8}\u{11A8}", &["\u{11A8}\u{11A8}"]),
+        ("\u{11A8}\u{308}\u{11A8}", &["\u{11A8}\u{308}", "\u{11A8}"]),
+        ("\u{11A8}\u{AC00}", &["\u{11A8}", "\u{AC00}"]),
+        ("\u{11A8}\u{308}\u{AC00}", &["\u{11A8}\u{308}", "\u{AC00}"]),
+        ("\u{11A8}\u{AC01}", &["\u{11A8}", "\u{AC01}"]),
+        ("\u{11A8}\u{308}\u{AC01}", &["\u{11A8}\u{308}", "\u{AC01}"]),
+        ("\u{11A8}\u{1F1E6}", &["\u{11A8}", "\u{1F1E6}"]),
+        ("\u{11A8}\u{308}\u{1F1E6}", &["\u{11A8}\u{308}", "\u{1F1E6}"]),
+        ("\u{11A8}\u{378}", &["\u{11A8}", "\u{378}"]),
+        ("\u{11A8}\u{308}\u{378}", &["\u{11A8}\u{308}", "\u{378}"]),
+        ("\u{AC00}\u{20}", &["\u{AC00}", "\u{20}"]),
+        ("\u{AC00}\u{308}\u{20}", &["\u{AC00}\u{308}", "\u{20}"]),
+        ("\u{AC00}\u{D}", &["\u{AC00}", "\u{D}"]),
+        ("\u{AC00}\u{308}\u{D}", &["\u{AC00}\u{308}", "\u{D}"]),
+        ("\u{AC00}\u{A}", &["\u{AC00}", "\u{A}"]),
+        ("\u{AC00}\u{308}\u{A}", &["\u{AC00}\u{308}", "\u{A}"]),
+        ("\u{AC00}\u{1}", &["\u{AC00}", "\u{1}"]),
+        ("\u{AC00}\u{308}\u{1}", &["\u{AC00}\u{308}", "\u{1}"]),
+        ("\u{AC00}\u{300}", &["\u{AC00}\u{300}"]),
+        ("\u{AC00}\u{308}\u{300}", &["\u{AC00}\u{308}\u{300}"]),
+        ("\u{AC00}\u{1100}", &["\u{AC00}", "\u{1100}"]),
+        ("\u{AC00}\u{308}\u{1100}", &["\u{AC00}\u{308}", "\u{1100}"]),
+        ("\u{AC00}\u{1160}", &["\u{AC00}\u{1160}"]),
+        ("\u{AC00}\u{308}\u{1160}", &["\u{AC00}\u{308}", "\u{1160}"]),
+        ("\u{AC00}\u{11A8}", &["\u{AC00}\u{11A8}"]),
+        ("\u{AC00}\u{308}\u{11A8}", &["\u{AC00}\u{308}", "\u{11A8}"]),
+        ("\u{AC00}\u{AC00}", &["\u{AC00}", "\u{AC00}"]),
+        ("\u{AC00}\u{308}\u{AC00}", &["\u{AC00}\u{308}", "\u{AC00}"]),
+        ("\u{AC00}\u{AC01}", &["\u{AC00}", "\u{AC01}"]),
+        ("\u{AC00}\u{308}\u{AC01}", &["\u{AC00}\u{308}", "\u{AC01}"]),
+        ("\u{AC00}\u{1F1E6}", &["\u{AC00}", "\u{1F1E6}"]),
+        ("\u{AC00}\u{308}\u{1F1E6}", &["\u{AC00}\u{308}", "\u{1F1E6}"]),
+        ("\u{AC00}\u{378}", &["\u{AC00}", "\u{378}"]),
+        ("\u{AC00}\u{308}\u{378}", &["\u{AC00}\u{308}", "\u{378}"]),
+        ("\u{AC01}\u{20}", &["\u{AC01}", "\u{20}"]),
+        ("\u{AC01}\u{308}\u{20}", &["\u{AC01}\u{308}", "\u{20}"]),
+        ("\u{AC01}\u{D}", &["\u{AC01}", "\u{D}"]),
+        ("\u{AC01}\u{308}\u{D}", &["\u{AC01}\u{308}", "\u{D}"]),
+        ("\u{AC01}\u{A}", &["\u{AC01}", "\u{A}"]),
+        ("\u{AC01}\u{308}\u{A}", &["\u{AC01}\u{308}", "\u{A}"]),
+        ("\u{AC01}\u{1}", &["\u{AC01}", "\u{1}"]),
+        ("\u{AC01}\u{308}\u{1}", &["\u{AC01}\u{308}", "\u{1}"]),
+        ("\u{AC01}\u{300}", &["\u{AC01}\u{300}"]),
+        ("\u{AC01}\u{308}\u{300}", &["\u{AC01}\u{308}\u{300}"]),
+        ("\u{AC01}\u{1100}", &["\u{AC01}", "\u{1100}"]),
+        ("\u{AC01}\u{308}\u{1100}", &["\u{AC01}\u{308}", "\u{1100}"]),
+        ("\u{AC01}\u{1160}", &["\u{AC01}", "\u{1160}"]),
+        ("\u{AC01}\u{308}\u{1160}", &["\u{AC01}\u{308}", "\u{1160}"]),
+        ("\u{AC01}\u{11A8}", &["\u{AC01}\u{11A8}"]),
+        ("\u{AC01}\u{308}\u{11A8}", &["\u{AC01}\u{308}", "\u{11A8}"]),
+        ("\u{AC01}\u{AC00}", &["\u{AC01}", "\u{AC00}"]),
+        ("\u{AC01}\u{308}\u{AC00}", &["\u{AC01}\u{308}", "\u{AC00}"]),
+        ("\u{AC01}\u{AC01}", &["\u{AC01}", "\u{AC01}"]),
+        ("\u{AC01}\u{308}\u{AC01}", &["\u{AC01}\u{308}", "\u{AC01}"]),
+        ("\u{AC01}\u{1F1E6}", &["\u{AC01}", "\u{1F1E6}"]),
+        ("\u{AC01}\u{308}\u{1F1E6}", &["\u{AC01}\u{308}", "\u{1F1E6}"]),
+        ("\u{AC01}\u{378}", &["\u{AC01}", "\u{378}"]),
+        ("\u{AC01}\u{308}\u{378}", &["\u{AC01}\u{308}", "\u{378}"]),
+        ("\u{1F1E6}\u{20}", &["\u{1F1E6}", "\u{20}"]),
+        ("\u{1F1E6}\u{308}\u{20}", &["\u{1F1E6}\u{308}", "\u{20}"]),
+        ("\u{1F1E6}\u{D}", &["\u{1F1E6}", "\u{D}"]),
+        ("\u{1F1E6}\u{308}\u{D}", &["\u{1F1E6}\u{308}", "\u{D}"]),
+        ("\u{1F1E6}\u{A}", &["\u{1F1E6}", "\u{A}"]),
+        ("\u{1F1E6}\u{308}\u{A}", &["\u{1F1E6}\u{308}", "\u{A}"]),
+        ("\u{1F1E6}\u{1}", &["\u{1F1E6}", "\u{1}"]),
+        ("\u{1F1E6}\u{308}\u{1}", &["\u{1F1E6}\u{308}", "\u{1}"]),
+        ("\u{1F1E6}\u{300}", &["\u{1F1E6}\u{300}"]),
+        ("\u{1F1E6}\u{308}\u{300}", &["\u{1F1E6}\u{308}\u{300}"]),
+        ("\u{1F1E6}\u{1100}", &["\u{1F1E6}", "\u{1100}"]),
+        ("\u{1F1E6}\u{308}\u{1100}", &["\u{1F1E6}\u{308}", "\u{1100}"]),
+        ("\u{1F1E6}\u{1160}", &["\u{1F1E6}", "\u{1160}"]),
+        ("\u{1F1E6}\u{308}\u{1160}", &["\u{1F1E6}\u{308}", "\u{1160}"]),
+        ("\u{1F1E6}\u{11A8}", &["\u{1F1E6}", "\u{11A8}"]),
+        ("\u{1F1E6}\u{308}\u{11A8}", &["\u{1F1E6}\u{308}", "\u{11A8}"]),
+        ("\u{1F1E6}\u{AC00}", &["\u{1F1E6}", "\u{AC00}"]),
+        ("\u{1F1E6}\u{308}\u{AC00}", &["\u{1F1E6}\u{308}", "\u{AC00}"]),
+        ("\u{1F1E6}\u{AC01}", &["\u{1F1E6}", "\u{AC01}"]),
+        ("\u{1F1E6}\u{308}\u{AC01}", &["\u{1F1E6}\u{308}", "\u{AC01}"]),
+        ("\u{1F1E6}\u{1F1E6}", &["\u{1F1E6}\u{1F1E6}"]),
+        ("\u{1F1E6}\u{308}\u{1F1E6}", &["\u{1F1E6}\u{308}", "\u{1F1E6}"]),
+        ("\u{1F1E6}\u{378}", &["\u{1F1E6}", "\u{378}"]),
+        ("\u{1F1E6}\u{308}\u{378}", &["\u{1F1E6}\u{308}", "\u{378}"]),
+        ("\u{378}\u{20}", &["\u{378}", "\u{20}"]),
+        ("\u{378}\u{308}\u{20}", &["\u{378}\u{308}", "\u{20}"]),
+        ("\u{378}\u{D}", &["\u{378}", "\u{D}"]),
+        ("\u{378}\u{308}\u{D}", &["\u{378}\u{308}", "\u{D}"]),
+        ("\u{378}\u{A}", &["\u{378}", "\u{A}"]),
+        ("\u{378}\u{308}\u{A}", &["\u{378}\u{308}", "\u{A}"]),
+        ("\u{378}\u{1}", &["\u{378}", "\u{1}"]),
+        ("\u{378}\u{308}\u{1}", &["\u{378}\u{308}", "\u{1}"]),
+        ("\u{378}\u{300}", &["\u{378}\u{300}"]),
+        ("\u{378}\u{308}\u{300}", &["\u{378}\u{308}\u{300}"]),
+        ("\u{378}\u{1100}", &["\u{378}", "\u{1100}"]),
+        ("\u{378}\u{308}\u{1100}", &["\u{378}\u{308}", "\u{1100}"]),
+        ("\u{378}\u{1160}", &["\u{378}", "\u{1160}"]),
+        ("\u{378}\u{308}\u{1160}", &["\u{378}\u{308}", "\u{1160}"]),
+        ("\u{378}\u{11A8}", &["\u{378}", "\u{11A8}"]),
+        ("\u{378}\u{308}\u{11A8}", &["\u{378}\u{308}", "\u{11A8}"]),
+        ("\u{378}\u{AC00}", &["\u{378}", "\u{AC00}"]),
+        ("\u{378}\u{308}\u{AC00}", &["\u{378}\u{308}", "\u{AC00}"]),
+        ("\u{378}\u{AC01}", &["\u{378}", "\u{AC01}"]),
+        ("\u{378}\u{308}\u{AC01}", &["\u{378}\u{308}", "\u{AC01}"]),
+        ("\u{378}\u{1F1E6}", &["\u{378}", "\u{1F1E6}"]),
+        ("\u{378}\u{308}\u{1F1E6}", &["\u{378}\u{308}", "\u{1F1E6}"]),
+        ("\u{378}\u{378}", &["\u{378}", "\u{378}"]),
+        ("\u{378}\u{308}\u{378}", &["\u{378}\u{308}", "\u{378}"]),
+        ("\u{61}\u{1F1E6}\u{62}", &["\u{61}", "\u{1F1E6}", "\u{62}"]),
+        ("\u{1F1F7}\u{1F1FA}", &["\u{1F1F7}\u{1F1FA}"]),
+        ("\u{1F1F7}\u{1F1FA}\u{1F1F8}", &["\u{1F1F7}\u{1F1FA}\u{1F1F8}"]),
+        ("\u{1F1F7}\u{1F1FA}\u{1F1F8}\u{1F1EA}",
+        &["\u{1F1F7}\u{1F1FA}\u{1F1F8}\u{1F1EA}"]),
+        ("\u{1F1F7}\u{1F1FA}\u{200B}\u{1F1F8}\u{1F1EA}",
+         &["\u{1F1F7}\u{1F1FA}", "\u{200B}", "\u{1F1F8}\u{1F1EA}"]),
+        ("\u{1F1E6}\u{1F1E7}\u{1F1E8}", &["\u{1F1E6}\u{1F1E7}\u{1F1E8}"]),
+        ("\u{1F1E6}\u{200D}\u{1F1E7}\u{1F1E8}", &["\u{1F1E6}\u{200D}",
+         "\u{1F1E7}\u{1F1E8}"]),
+        ("\u{1F1E6}\u{1F1E7}\u{200D}\u{1F1E8}",
+         &["\u{1F1E6}\u{1F1E7}\u{200D}", "\u{1F1E8}"]),
+        ("\u{20}\u{200D}\u{646}", &["\u{20}\u{200D}", "\u{646}"]),
+        ("\u{646}\u{200D}\u{20}", &["\u{646}\u{200D}", "\u{20}"]),
+    ];
+
+    let test_diff: [(_, &[_], &[_]); 23] = [
+        ("\u{20}\u{903}", &["\u{20}\u{903}"], &["\u{20}", "\u{903}"]), ("\u{20}\u{308}\u{903}",
+        &["\u{20}\u{308}\u{903}"], &["\u{20}\u{308}", "\u{903}"]), ("\u{D}\u{308}\u{903}",
+        &["\u{D}", "\u{308}\u{903}"], &["\u{D}", "\u{308}", "\u{903}"]), ("\u{A}\u{308}\u{903}",
+        &["\u{A}", "\u{308}\u{903}"], &["\u{A}", "\u{308}", "\u{903}"]), ("\u{1}\u{308}\u{903}",
+        &["\u{1}", "\u{308}\u{903}"], &["\u{1}", "\u{308}", "\u{903}"]), ("\u{300}\u{903}",
+        &["\u{300}\u{903}"], &["\u{300}", "\u{903}"]), ("\u{300}\u{308}\u{903}",
+        &["\u{300}\u{308}\u{903}"], &["\u{300}\u{308}", "\u{903}"]), ("\u{903}\u{903}",
+        &["\u{903}\u{903}"], &["\u{903}", "\u{903}"]), ("\u{903}\u{308}\u{903}",
+        &["\u{903}\u{308}\u{903}"], &["\u{903}\u{308}", "\u{903}"]), ("\u{1100}\u{903}",
+        &["\u{1100}\u{903}"], &["\u{1100}", "\u{903}"]), ("\u{1100}\u{308}\u{903}",
+        &["\u{1100}\u{308}\u{903}"], &["\u{1100}\u{308}", "\u{903}"]), ("\u{1160}\u{903}",
+        &["\u{1160}\u{903}"], &["\u{1160}", "\u{903}"]), ("\u{1160}\u{308}\u{903}",
+        &["\u{1160}\u{308}\u{903}"], &["\u{1160}\u{308}", "\u{903}"]), ("\u{11A8}\u{903}",
+        &["\u{11A8}\u{903}"], &["\u{11A8}", "\u{903}"]), ("\u{11A8}\u{308}\u{903}",
+        &["\u{11A8}\u{308}\u{903}"], &["\u{11A8}\u{308}", "\u{903}"]), ("\u{AC00}\u{903}",
+        &["\u{AC00}\u{903}"], &["\u{AC00}", "\u{903}"]), ("\u{AC00}\u{308}\u{903}",
+        &["\u{AC00}\u{308}\u{903}"], &["\u{AC00}\u{308}", "\u{903}"]), ("\u{AC01}\u{903}",
+        &["\u{AC01}\u{903}"], &["\u{AC01}", "\u{903}"]), ("\u{AC01}\u{308}\u{903}",
+        &["\u{AC01}\u{308}\u{903}"], &["\u{AC01}\u{308}", "\u{903}"]), ("\u{1F1E6}\u{903}",
+        &["\u{1F1E6}\u{903}"], &["\u{1F1E6}", "\u{903}"]), ("\u{1F1E6}\u{308}\u{903}",
+        &["\u{1F1E6}\u{308}\u{903}"], &["\u{1F1E6}\u{308}", "\u{903}"]), ("\u{378}\u{903}",
+        &["\u{378}\u{903}"], &["\u{378}", "\u{903}"]), ("\u{378}\u{308}\u{903}",
+        &["\u{378}\u{308}\u{903}"], &["\u{378}\u{308}", "\u{903}"]),
+    ];
+
+    for &(s, g) in &test_same[..] {
+        // test forward iterator
+        assert!(order::equals(s.graphemes(true), g.iter().cloned()));
+        assert!(order::equals(s.graphemes(false), g.iter().cloned()));
+
+        // test reverse iterator
+        assert!(order::equals(s.graphemes(true).rev(), g.iter().rev().cloned()));
+        assert!(order::equals(s.graphemes(false).rev(), g.iter().rev().cloned()));
+    }
+
+    for &(s, gt, gf) in &test_diff {
+        // test forward iterator
+        assert!(order::equals(s.graphemes(true), gt.iter().cloned()));
+        assert!(order::equals(s.graphemes(false), gf.iter().cloned()));
+
+        // test reverse iterator
+        assert!(order::equals(s.graphemes(true).rev(), gt.iter().rev().cloned()));
+        assert!(order::equals(s.graphemes(false).rev(), gf.iter().rev().cloned()));
+    }
+
+    // test the indices iterators
+    let s = "a̐éö̲\r\n";
+    let gr_inds = s.grapheme_indices(true).collect::<Vec<(usize, &str)>>();
+    let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
+    assert_eq!(gr_inds, b);
+    let gr_inds = s.grapheme_indices(true).rev().collect::<Vec<(usize, &str)>>();
+    let b: &[_] = &[(11, "\r\n"), (6, "ö̲"), (3, "é"), (0, "a̐")];
+    assert_eq!(gr_inds, b);
+    let mut gr_inds_iter = s.grapheme_indices(true);
+    {
+        let gr_inds = gr_inds_iter.by_ref();
+        let e1 = gr_inds.size_hint();
+        assert_eq!(e1, (1, Some(13)));
+        let c = gr_inds.count();
+        assert_eq!(c, 4);
+    }
+    let e2 = gr_inds_iter.size_hint();
+    assert_eq!(e2, (0, Some(0)));
+
+    // make sure the reverse iterator does the right thing with "\n" at beginning of string
+    let s = "\n\r\n\r";
+    let gr = s.graphemes(true).rev().collect::<Vec<&str>>();
+    let b: &[_] = &["\r", "\r\n", "\n"];
+    assert_eq!(gr, b);
+}
+
+#[test]
+fn test_splitator() {
+    fn t(s: &str, sep: &str, u: &[&str]) {
+        let v: Vec<&str> = s.split(sep).collect();
+        assert_eq!(v, u);
+    }
+    t("--1233345--", "12345", &["--1233345--"]);
+    t("abc::hello::there", "::", &["abc", "hello", "there"]);
+    t("::hello::there", "::", &["", "hello", "there"]);
+    t("hello::there::", "::", &["hello", "there", ""]);
+    t("::hello::there::", "::", &["", "hello", "there", ""]);
+    t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
+    t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
+    t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
+    t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
+    t("", ".", &[""]);
+    t("zz", "zz", &["",""]);
+    t("ok", "z", &["ok"]);
+    t("zzz", "zz", &["","z"]);
+    t("zzzzz", "zz", &["","","z"]);
+}
+
+#[test]
+fn test_str_default() {
+    use std::default::Default;
+
+    fn t<S: Default + AsRef<str>>() {
+        let s: S = Default::default();
+        assert_eq!(s.as_ref(), "");
+    }
+
+    t::<&str>();
+    t::<String>();
+}
+
+#[test]
+fn test_str_container() {
+    fn sum_len(v: &[&str]) -> usize {
+        v.iter().map(|x| x.len()).sum()
+    }
+
+    let s = String::from_str("01234");
+    assert_eq!(5, sum_len(&["012", "", "34"]));
+    assert_eq!(5, sum_len(&[&String::from_str("01"),
+                            &String::from_str("2"),
+                            &String::from_str("34"),
+                            &String::from_str("")]));
+    assert_eq!(5, sum_len(&[&s]));
+}
+
+#[test]
+fn test_str_from_utf8() {
+    let xs = b"hello";
+    assert_eq!(from_utf8(xs), Ok("hello"));
+
+    let xs = "ศไทย中华Việt Nam".as_bytes();
+    assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
+
+    let xs = b"hello\xFF";
+    assert_eq!(from_utf8(xs), Err(Utf8Error::TooShort));
+}
+
+mod bench {
+    use test::{Bencher, black_box};
+
+    #[bench]
+    fn char_iterator(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+
+        b.iter(|| s.chars().count());
+    }
+
+    #[bench]
+    fn char_iterator_for(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+
+        b.iter(|| {
+            for ch in s.chars() { black_box(ch); }
+        });
+    }
+
+    #[bench]
+    fn char_iterator_ascii(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb";
+
+        b.iter(|| s.chars().count());
+    }
+
+    #[bench]
+    fn char_iterator_rev(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+
+        b.iter(|| s.chars().rev().count());
+    }
+
+    #[bench]
+    fn char_iterator_rev_for(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+
+        b.iter(|| {
+            for ch in s.chars().rev() { black_box(ch); }
+        });
+    }
+
+    #[bench]
+    fn char_indicesator(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let len = s.chars().count();
+
+        b.iter(|| assert_eq!(s.char_indices().count(), len));
+    }
+
+    #[bench]
+    fn char_indicesator_rev(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let len = s.chars().count();
+
+        b.iter(|| assert_eq!(s.char_indices().rev().count(), len));
+    }
+
+    #[bench]
+    fn split_unicode_ascii(b: &mut Bencher) {
+        let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
+
+        b.iter(|| assert_eq!(s.split('V').count(), 3));
+    }
+
+    #[bench]
+    fn split_ascii(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').count();
+
+        b.iter(|| assert_eq!(s.split(' ').count(), len));
+    }
+
+    #[bench]
+    fn split_extern_fn(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').count();
+        fn pred(c: char) -> bool { c == ' ' }
+
+        b.iter(|| assert_eq!(s.split(pred).count(), len));
+    }
+
+    #[bench]
+    fn split_closure(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').count();
+
+        b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len));
+    }
+
+    #[bench]
+    fn split_slice(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').count();
+
+        let c: &[char] = &[' '];
+        b.iter(|| assert_eq!(s.split(c).count(), len));
+    }
+
+    #[bench]
+    fn bench_connect(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let sep = "→";
+        let v = vec![s, s, s, s, s, s, s, s, s, s];
+        b.iter(|| {
+            assert_eq!(v.connect(sep).len(), s.len() * 10 + sep.len() * 9);
+        })
+    }
+
+    #[bench]
+    fn bench_contains_short_short(b: &mut Bencher) {
+        let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+        let needle = "sit";
+
+        b.iter(|| {
+            assert!(haystack.contains(needle));
+        })
+    }
+
+    #[bench]
+    fn bench_contains_short_long(b: &mut Bencher) {
+        let haystack = "\
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
+ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
+eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
+sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
+tempus vel, gravida nec quam.
+
+In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
+sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
+diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
+lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
+eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
+interdum. Curabitur ut nisi justo.
+
+Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
+mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
+lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
+est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
+felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
+ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
+feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
+Aliquam sit amet placerat lorem.
+
+Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
+mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
+Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
+lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
+suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
+cursus accumsan.
+
+Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
+feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
+vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
+leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
+malesuada sollicitudin quam eu fermentum.";
+        let needle = "english";
+
+        b.iter(|| {
+            assert!(!haystack.contains(needle));
+        })
+    }
+
+    #[bench]
+    fn bench_contains_bad_naive(b: &mut Bencher) {
+        let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+        let needle = "aaaaaaaab";
+
+        b.iter(|| {
+            assert!(!haystack.contains(needle));
+        })
+    }
+
+    #[bench]
+    fn bench_contains_equal(b: &mut Bencher) {
+        let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+        let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+
+        b.iter(|| {
+            assert!(haystack.contains(needle));
+        })
+    }
+}
diff --git a/src/libcollectionstest/string.rs b/src/libcollectionstest/string.rs
new file mode 100644 (file)
index 0000000..5d6aa8a
--- /dev/null
@@ -0,0 +1,453 @@
+// 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 std::borrow::{IntoCow, Cow};
+use std::iter::repeat;
+use std::str::Utf8Error;
+use std::string::as_string;
+
+use test::Bencher;
+
+#[test]
+fn test_as_string() {
+    let x = "foo";
+    assert_eq!(x, &**as_string(x));
+}
+
+#[test]
+fn test_from_str() {
+  let owned: Option<::std::string::String> = "string".parse().ok();
+  assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
+}
+
+#[test]
+fn test_unsized_to_string() {
+    let s: &str = "abc";
+    let _: String = (*s).to_string();
+}
+
+#[test]
+fn test_from_utf8() {
+    let xs = b"hello".to_vec();
+    assert_eq!(String::from_utf8(xs).unwrap(),
+               String::from_str("hello"));
+
+    let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
+    assert_eq!(String::from_utf8(xs).unwrap(),
+               String::from_str("ศไทย中华Việt Nam"));
+
+    let xs = b"hello\xFF".to_vec();
+    let err = String::from_utf8(xs).err().unwrap();
+    assert_eq!(err.utf8_error(), Utf8Error::TooShort);
+    assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
+}
+
+#[test]
+fn test_from_utf8_lossy() {
+    let xs = b"hello";
+    let ys: Cow<str> = "hello".into_cow();
+    assert_eq!(String::from_utf8_lossy(xs), ys);
+
+    let xs = "ศไทย中华Việt Nam".as_bytes();
+    let ys: Cow<str> = "ศไทย中华Việt Nam".into_cow();
+    assert_eq!(String::from_utf8_lossy(xs), ys);
+
+    let xs = b"Hello\xC2 There\xFF Goodbye";
+    assert_eq!(String::from_utf8_lossy(xs),
+               String::from_str("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
+
+    let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
+    assert_eq!(String::from_utf8_lossy(xs),
+               String::from_str("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
+
+    let xs = b"\xF5foo\xF5\x80bar";
+    assert_eq!(String::from_utf8_lossy(xs),
+               String::from_str("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
+
+    let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
+    assert_eq!(String::from_utf8_lossy(xs),
+               String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
+
+    let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
+    assert_eq!(String::from_utf8_lossy(xs),
+               String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
+
+    let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
+    assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}\
+                                           foo\u{10000}bar").into_cow());
+
+    // surrogates
+    let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
+    assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}foo\
+                                           \u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
+}
+
+#[test]
+fn test_from_utf16() {
+    let pairs =
+        [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
+          vec![0xd800, 0xdf45, 0xd800, 0xdf3f,
+            0xd800, 0xdf3b, 0xd800, 0xdf46,
+            0xd800, 0xdf39, 0xd800, 0xdf3b,
+            0xd800, 0xdf30, 0x000a]),
+
+         (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
+          vec![0xd801, 0xdc12, 0xd801,
+            0xdc49, 0xd801, 0xdc2e, 0xd801,
+            0xdc40, 0xd801, 0xdc32, 0xd801,
+            0xdc4b, 0x0020, 0xd801, 0xdc0f,
+            0xd801, 0xdc32, 0xd801, 0xdc4d,
+            0x000a]),
+
+         (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
+          vec![0xd800, 0xdf00, 0xd800, 0xdf16,
+            0xd800, 0xdf0b, 0xd800, 0xdf04,
+            0xd800, 0xdf11, 0xd800, 0xdf09,
+            0x00b7, 0xd800, 0xdf0c, 0xd800,
+            0xdf04, 0xd800, 0xdf15, 0xd800,
+            0xdf04, 0xd800, 0xdf0b, 0xd800,
+            0xdf09, 0xd800, 0xdf11, 0x000a ]),
+
+         (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
+          vec![0xd801, 0xdc8b, 0xd801, 0xdc98,
+            0xd801, 0xdc88, 0xd801, 0xdc91,
+            0xd801, 0xdc9b, 0xd801, 0xdc92,
+            0x0020, 0xd801, 0xdc95, 0xd801,
+            0xdc93, 0x0020, 0xd801, 0xdc88,
+            0xd801, 0xdc9a, 0xd801, 0xdc8d,
+            0x0020, 0xd801, 0xdc8f, 0xd801,
+            0xdc9c, 0xd801, 0xdc92, 0xd801,
+            0xdc96, 0xd801, 0xdc86, 0x0020,
+            0xd801, 0xdc95, 0xd801, 0xdc86,
+            0x000a ]),
+         // Issue #12318, even-numbered non-BMP planes
+         (String::from_str("\u{20000}"),
+          vec![0xD840, 0xDC00])];
+
+    for p in &pairs {
+        let (s, u) = (*p).clone();
+        let s_as_utf16 = s.utf16_units().collect::<Vec<u16>>();
+        let u_as_string = String::from_utf16(&u).unwrap();
+
+        assert!(::unicode::str::is_utf16(&u));
+        assert_eq!(s_as_utf16, u);
+
+        assert_eq!(u_as_string, s);
+        assert_eq!(String::from_utf16_lossy(&u), s);
+
+        assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
+        assert_eq!(u_as_string.utf16_units().collect::<Vec<u16>>(), u);
+    }
+}
+
+#[test]
+fn test_utf16_invalid() {
+    // completely positive cases tested above.
+    // lead + eof
+    assert!(String::from_utf16(&[0xD800]).is_err());
+    // lead + lead
+    assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
+
+    // isolated trail
+    assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
+
+    // general
+    assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
+}
+
+#[test]
+fn test_from_utf16_lossy() {
+    // completely positive cases tested above.
+    // lead + eof
+    assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from_str("\u{FFFD}"));
+    // lead + lead
+    assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
+               String::from_str("\u{FFFD}\u{FFFD}"));
+
+    // isolated trail
+    assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from_str("a\u{FFFD}"));
+
+    // general
+    assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
+               String::from_str("\u{FFFD}𐒋\u{FFFD}"));
+}
+
+#[test]
+fn test_push_bytes() {
+    let mut s = String::from_str("ABC");
+    unsafe {
+        let mv = s.as_mut_vec();
+        mv.push_all(&[b'D']);
+    }
+    assert_eq!(s, "ABCD");
+}
+
+#[test]
+fn test_push_str() {
+    let mut s = String::new();
+    s.push_str("");
+    assert_eq!(&s[0..], "");
+    s.push_str("abc");
+    assert_eq!(&s[0..], "abc");
+    s.push_str("ประเทศไทย中华Việt Nam");
+    assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
+}
+
+#[test]
+fn test_push() {
+    let mut data = String::from_str("ประเทศไทย中");
+    data.push('华');
+    data.push('b'); // 1 byte
+    data.push('¢'); // 2 byte
+    data.push('€'); // 3 byte
+    data.push('𤭢'); // 4 byte
+    assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
+}
+
+#[test]
+fn test_pop() {
+    let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
+    assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
+    assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
+    assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
+    assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
+    assert_eq!(data.pop().unwrap(), '华');
+    assert_eq!(data, "ประเทศไทย中");
+}
+
+#[test]
+fn test_str_truncate() {
+    let mut s = String::from_str("12345");
+    s.truncate(5);
+    assert_eq!(s, "12345");
+    s.truncate(3);
+    assert_eq!(s, "123");
+    s.truncate(0);
+    assert_eq!(s, "");
+
+    let mut s = String::from_str("12345");
+    let p = s.as_ptr();
+    s.truncate(3);
+    s.push_str("6");
+    let p_ = s.as_ptr();
+    assert_eq!(p_, p);
+}
+
+#[test]
+#[should_panic]
+fn test_str_truncate_invalid_len() {
+    let mut s = String::from_str("12345");
+    s.truncate(6);
+}
+
+#[test]
+#[should_panic]
+fn test_str_truncate_split_codepoint() {
+    let mut s = String::from_str("\u{FC}"); // ü
+    s.truncate(1);
+}
+
+#[test]
+fn test_str_clear() {
+    let mut s = String::from_str("12345");
+    s.clear();
+    assert_eq!(s.len(), 0);
+    assert_eq!(s, "");
+}
+
+#[test]
+fn test_str_add() {
+    let a = String::from_str("12345");
+    let b = a + "2";
+    let b = b + "2";
+    assert_eq!(b.len(), 7);
+    assert_eq!(b, "1234522");
+}
+
+#[test]
+fn remove() {
+    let mut s = "ศไทย中华Việt Nam; foobar".to_string();;
+    assert_eq!(s.remove(0), 'ศ');
+    assert_eq!(s.len(), 33);
+    assert_eq!(s, "ไทย中华Việt Nam; foobar");
+    assert_eq!(s.remove(17), 'ệ');
+    assert_eq!(s, "ไทย中华Vit Nam; foobar");
+}
+
+#[test] #[should_panic]
+fn remove_bad() {
+    "ศ".to_string().remove(1);
+}
+
+#[test]
+fn insert() {
+    let mut s = "foobar".to_string();
+    s.insert(0, 'ệ');
+    assert_eq!(s, "ệfoobar");
+    s.insert(6, 'ย');
+    assert_eq!(s, "ệfooยbar");
+}
+
+#[test] #[should_panic] fn insert_bad1() { "".to_string().insert(1, 't'); }
+#[test] #[should_panic] fn insert_bad2() { "ệ".to_string().insert(1, 't'); }
+
+#[test]
+fn test_slicing() {
+    let s = "foobar".to_string();
+    assert_eq!("foobar", &s[..]);
+    assert_eq!("foo", &s[..3]);
+    assert_eq!("bar", &s[3..]);
+    assert_eq!("oob", &s[1..4]);
+}
+
+#[test]
+fn test_simple_types() {
+    assert_eq!(1.to_string(), "1");
+    assert_eq!((-1).to_string(), "-1");
+    assert_eq!(200.to_string(), "200");
+    assert_eq!(2.to_string(), "2");
+    assert_eq!(true.to_string(), "true");
+    assert_eq!(false.to_string(), "false");
+    assert_eq!(("hi".to_string()).to_string(), "hi");
+}
+
+#[test]
+fn test_vectors() {
+    let x: Vec<i32> = vec![];
+    assert_eq!(format!("{:?}", x), "[]");
+    assert_eq!(format!("{:?}", vec![1]), "[1]");
+    assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
+    assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) ==
+           "[[], [1], [1, 1]]");
+}
+
+#[test]
+fn test_from_iterator() {
+    let s = "ศไทย中华Việt Nam".to_string();
+    let t = "ศไทย中华";
+    let u = "Việt Nam";
+
+    let a: String = s.chars().collect();
+    assert_eq!(s, a);
+
+    let mut b = t.to_string();
+    b.extend(u.chars());
+    assert_eq!(s, b);
+
+    let c: String = vec![t, u].into_iter().collect();
+    assert_eq!(s, c);
+
+    let mut d = t.to_string();
+    d.extend(vec![u].into_iter());
+    assert_eq!(s, d);
+}
+
+#[bench]
+fn bench_with_capacity(b: &mut Bencher) {
+    b.iter(|| {
+        String::with_capacity(100)
+    });
+}
+
+#[bench]
+fn bench_push_str(b: &mut Bencher) {
+    let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+    b.iter(|| {
+        let mut r = String::new();
+        r.push_str(s);
+    });
+}
+
+const REPETITIONS: u64 = 10_000;
+
+#[bench]
+fn bench_push_str_one_byte(b: &mut Bencher) {
+    b.bytes = REPETITIONS;
+    b.iter(|| {
+        let mut r = String::new();
+        for _ in 0..REPETITIONS {
+            r.push_str("a")
+        }
+    });
+}
+
+#[bench]
+fn bench_push_char_one_byte(b: &mut Bencher) {
+    b.bytes = REPETITIONS;
+    b.iter(|| {
+        let mut r = String::new();
+        for _ in 0..REPETITIONS {
+            r.push('a')
+        }
+    });
+}
+
+#[bench]
+fn bench_push_char_two_bytes(b: &mut Bencher) {
+    b.bytes = REPETITIONS * 2;
+    b.iter(|| {
+        let mut r = String::new();
+        for _ in 0..REPETITIONS {
+            r.push('â')
+        }
+    });
+}
+
+#[bench]
+fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
+    let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
+              Lorem ipsum dolor sit amet, consectetur. ";
+
+    assert_eq!(100, s.len());
+    b.iter(|| {
+        let _ = String::from_utf8_lossy(s);
+    });
+}
+
+#[bench]
+fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
+    let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
+    assert_eq!(100, s.len());
+    b.iter(|| {
+        let _ = String::from_utf8_lossy(s);
+    });
+}
+
+#[bench]
+fn from_utf8_lossy_invalid(b: &mut Bencher) {
+    let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
+    b.iter(|| {
+        let _ = String::from_utf8_lossy(s);
+    });
+}
+
+#[bench]
+fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
+    let s = repeat(0xf5).take(100).collect::<Vec<_>>();
+    b.iter(|| {
+        let _ = String::from_utf8_lossy(&s);
+    });
+}
+
+#[bench]
+fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
+    let s = "Hello there, the quick brown fox jumped over the lazy dog! \
+             Lorem ipsum dolor sit amet, consectetur. ";
+    // ensure our operation produces an exact-size string before we benchmark it
+    let mut r = String::with_capacity(s.len());
+    r.push_str(s);
+    assert_eq!(r.len(), r.capacity());
+    b.iter(|| {
+        let mut r = String::with_capacity(s.len());
+        r.push_str(s);
+        r.shrink_to_fit();
+        r
+    });
+}
diff --git a/src/libcollectionstest/vec.rs b/src/libcollectionstest/vec.rs
new file mode 100644 (file)
index 0000000..2923bea
--- /dev/null
@@ -0,0 +1,994 @@
+// 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 std::iter::{FromIterator, repeat};
+use std::mem::size_of;
+use std::vec::as_vec;
+
+use test::Bencher;
+
+struct DropCounter<'a> {
+    count: &'a mut u32
+}
+
+#[unsafe_destructor]
+impl<'a> Drop for DropCounter<'a> {
+    fn drop(&mut self) {
+        *self.count += 1;
+    }
+}
+
+#[test]
+fn test_as_vec() {
+    let xs = [1u8, 2u8, 3u8];
+    assert_eq!(&**as_vec(&xs), xs);
+}
+
+#[test]
+fn test_as_vec_dtor() {
+    let (mut count_x, mut count_y) = (0, 0);
+    {
+        let xs = &[DropCounter { count: &mut count_x }, DropCounter { count: &mut count_y }];
+        assert_eq!(as_vec(xs).len(), 2);
+    }
+    assert_eq!(count_x, 1);
+    assert_eq!(count_y, 1);
+}
+
+#[test]
+fn test_small_vec_struct() {
+    assert!(size_of::<Vec<u8>>() == size_of::<usize>() * 3);
+}
+
+#[test]
+fn test_double_drop() {
+    struct TwoVec<T> {
+        x: Vec<T>,
+        y: Vec<T>
+    }
+
+    let (mut count_x, mut count_y) = (0, 0);
+    {
+        let mut tv = TwoVec {
+            x: Vec::new(),
+            y: Vec::new()
+        };
+        tv.x.push(DropCounter {count: &mut count_x});
+        tv.y.push(DropCounter {count: &mut count_y});
+
+        // If Vec had a drop flag, here is where it would be zeroed.
+        // Instead, it should rely on its internal state to prevent
+        // doing anything significant when dropped multiple times.
+        drop(tv.x);
+
+        // Here tv goes out of scope, tv.y should be dropped, but not tv.x.
+    }
+
+    assert_eq!(count_x, 1);
+    assert_eq!(count_y, 1);
+}
+
+#[test]
+fn test_reserve() {
+    let mut v = Vec::new();
+    assert_eq!(v.capacity(), 0);
+
+    v.reserve(2);
+    assert!(v.capacity() >= 2);
+
+    for i in 0..16 {
+        v.push(i);
+    }
+
+    assert!(v.capacity() >= 16);
+    v.reserve(16);
+    assert!(v.capacity() >= 32);
+
+    v.push(16);
+
+    v.reserve(16);
+    assert!(v.capacity() >= 33)
+}
+
+#[test]
+fn test_extend() {
+    let mut v = Vec::new();
+    let mut w = Vec::new();
+
+    v.extend(0..3);
+    for i in 0..3 { w.push(i) }
+
+    assert_eq!(v, w);
+
+    v.extend(3..10);
+    for i in 3..10 { w.push(i) }
+
+    assert_eq!(v, w);
+}
+
+#[test]
+fn test_slice_from_mut() {
+    let mut values = vec![1, 2, 3, 4, 5];
+    {
+        let slice = &mut values[2 ..];
+        assert!(slice == [3, 4, 5]);
+        for p in slice {
+            *p += 2;
+        }
+    }
+
+    assert!(values == [1, 2, 5, 6, 7]);
+}
+
+#[test]
+fn test_slice_to_mut() {
+    let mut values = vec![1, 2, 3, 4, 5];
+    {
+        let slice = &mut values[.. 2];
+        assert!(slice == [1, 2]);
+        for p in slice {
+            *p += 1;
+        }
+    }
+
+    assert!(values == [2, 3, 3, 4, 5]);
+}
+
+#[test]
+fn test_split_at_mut() {
+    let mut values = vec![1, 2, 3, 4, 5];
+    {
+        let (left, right) = values.split_at_mut(2);
+        {
+            let left: &[_] = left;
+            assert!(&left[..left.len()] == &[1, 2]);
+        }
+        for p in left {
+            *p += 1;
+        }
+
+        {
+            let right: &[_] = right;
+            assert!(&right[..right.len()] == &[3, 4, 5]);
+        }
+        for p in right {
+            *p += 2;
+        }
+    }
+
+    assert_eq!(values, [2, 3, 5, 6, 7]);
+}
+
+#[test]
+fn test_clone() {
+    let v: Vec<i32> = vec![];
+    let w = vec!(1, 2, 3);
+
+    assert_eq!(v, v.clone());
+
+    let z = w.clone();
+    assert_eq!(w, z);
+    // they should be disjoint in memory.
+    assert!(w.as_ptr() != z.as_ptr())
+}
+
+#[test]
+fn test_clone_from() {
+    let mut v = vec!();
+    let three: Vec<Box<_>> = vec!(box 1, box 2, box 3);
+    let two: Vec<Box<_>> = vec!(box 4, box 5);
+    // zero, long
+    v.clone_from(&three);
+    assert_eq!(v, three);
+
+    // equal
+    v.clone_from(&three);
+    assert_eq!(v, three);
+
+    // long, short
+    v.clone_from(&two);
+    assert_eq!(v, two);
+
+    // short, long
+    v.clone_from(&three);
+    assert_eq!(v, three)
+}
+
+#[test]
+fn test_retain() {
+    let mut vec = vec![1, 2, 3, 4];
+    vec.retain(|&x| x % 2 == 0);
+    assert_eq!(vec, [2, 4]);
+}
+
+#[test]
+fn zero_sized_values() {
+    let mut v = Vec::new();
+    assert_eq!(v.len(), 0);
+    v.push(());
+    assert_eq!(v.len(), 1);
+    v.push(());
+    assert_eq!(v.len(), 2);
+    assert_eq!(v.pop(), Some(()));
+    assert_eq!(v.pop(), Some(()));
+    assert_eq!(v.pop(), None);
+
+    assert_eq!(v.iter().count(), 0);
+    v.push(());
+    assert_eq!(v.iter().count(), 1);
+    v.push(());
+    assert_eq!(v.iter().count(), 2);
+
+    for &() in &v {}
+
+    assert_eq!(v.iter_mut().count(), 2);
+    v.push(());
+    assert_eq!(v.iter_mut().count(), 3);
+    v.push(());
+    assert_eq!(v.iter_mut().count(), 4);
+
+    for &mut () in &mut v {}
+    unsafe { v.set_len(0); }
+    assert_eq!(v.iter_mut().count(), 0);
+}
+
+#[test]
+fn test_partition() {
+    assert_eq!(vec![].into_iter().partition(|x: &i32| *x < 3), (vec![], vec![]));
+    assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 4), (vec![1, 2, 3], vec![]));
+    assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 2), (vec![1], vec![2, 3]));
+    assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 0), (vec![], vec![1, 2, 3]));
+}
+
+#[test]
+fn test_zip_unzip() {
+    let z1 = vec![(1, 4), (2, 5), (3, 6)];
+
+    let (left, right): (Vec<_>, Vec<_>) = z1.iter().cloned().unzip();
+
+    assert_eq!((1, 4), (left[0], right[0]));
+    assert_eq!((2, 5), (left[1], right[1]));
+    assert_eq!((3, 6), (left[2], right[2]));
+}
+
+#[test]
+fn test_unsafe_ptrs() {
+    unsafe {
+        // Test on-stack copy-from-buf.
+        let a = [1, 2, 3];
+        let ptr = a.as_ptr();
+        let b = Vec::from_raw_buf(ptr, 3);
+        assert_eq!(b, [1, 2, 3]);
+
+        // Test on-heap copy-from-buf.
+        let c = vec![1, 2, 3, 4, 5];
+        let ptr = c.as_ptr();
+        let d = Vec::from_raw_buf(ptr, 5);
+        assert_eq!(d, [1, 2, 3, 4, 5]);
+    }
+}
+
+#[test]
+fn test_vec_truncate_drop() {
+    static mut drops: u32 = 0;
+    struct Elem(i32);
+    impl Drop for Elem {
+        fn drop(&mut self) {
+            unsafe { drops += 1; }
+        }
+    }
+
+    let mut v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
+    assert_eq!(unsafe { drops }, 0);
+    v.truncate(3);
+    assert_eq!(unsafe { drops }, 2);
+    v.truncate(0);
+    assert_eq!(unsafe { drops }, 5);
+}
+
+#[test]
+#[should_panic]
+fn test_vec_truncate_fail() {
+    struct BadElem(i32);
+    impl Drop for BadElem {
+        fn drop(&mut self) {
+            let BadElem(ref mut x) = *self;
+            if *x == 0xbadbeef {
+                panic!("BadElem panic: 0xbadbeef")
+            }
+        }
+    }
+
+    let mut v = vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
+    v.truncate(0);
+}
+
+#[test]
+fn test_index() {
+    let vec = vec![1, 2, 3];
+    assert!(vec[1] == 2);
+}
+
+#[test]
+#[should_panic]
+fn test_index_out_of_bounds() {
+    let vec = vec![1, 2, 3];
+    let _ = vec[3];
+}
+
+#[test]
+#[should_panic]
+fn test_slice_out_of_bounds_1() {
+    let x = vec![1, 2, 3, 4, 5];
+    &x[-1..];
+}
+
+#[test]
+#[should_panic]
+fn test_slice_out_of_bounds_2() {
+    let x = vec![1, 2, 3, 4, 5];
+    &x[..6];
+}
+
+#[test]
+#[should_panic]
+fn test_slice_out_of_bounds_3() {
+    let x = vec![1, 2, 3, 4, 5];
+    &x[-1..4];
+}
+
+#[test]
+#[should_panic]
+fn test_slice_out_of_bounds_4() {
+    let x = vec![1, 2, 3, 4, 5];
+    &x[1..6];
+}
+
+#[test]
+#[should_panic]
+fn test_slice_out_of_bounds_5() {
+    let x = vec![1, 2, 3, 4, 5];
+    &x[3..2];
+}
+
+#[test]
+#[should_panic]
+fn test_swap_remove_empty() {
+    let mut vec= Vec::<i32>::new();
+    vec.swap_remove(0);
+}
+
+#[test]
+fn test_move_iter_unwrap() {
+    let mut vec = Vec::with_capacity(7);
+    vec.push(1);
+    vec.push(2);
+    let ptr = vec.as_ptr();
+    vec = vec.into_iter().into_inner();
+    assert_eq!(vec.as_ptr(), ptr);
+    assert_eq!(vec.capacity(), 7);
+    assert_eq!(vec.len(), 0);
+}
+
+#[test]
+#[should_panic]
+fn test_map_in_place_incompatible_types_fail() {
+    let v = vec![0, 1, 2];
+    v.map_in_place(|_| ());
+}
+
+#[test]
+fn test_map_in_place() {
+    let v = vec![0, 1, 2];
+    assert_eq!(v.map_in_place(|i: u32| i as i32 - 1), [-1, 0, 1]);
+}
+
+#[test]
+fn test_map_in_place_zero_sized() {
+    let v = vec![(), ()];
+    #[derive(PartialEq, Debug)]
+    struct ZeroSized;
+    assert_eq!(v.map_in_place(|_| ZeroSized), [ZeroSized, ZeroSized]);
+}
+
+#[test]
+fn test_map_in_place_zero_drop_count() {
+    use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
+
+    #[derive(Clone, PartialEq, Debug)]
+    struct Nothing;
+    impl Drop for Nothing { fn drop(&mut self) { } }
+
+    #[derive(Clone, PartialEq, Debug)]
+    struct ZeroSized;
+    impl Drop for ZeroSized {
+        fn drop(&mut self) {
+            DROP_COUNTER.fetch_add(1, Ordering::Relaxed);
+        }
+    }
+    const NUM_ELEMENTS: usize = 2;
+    static DROP_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
+
+    let v = repeat(Nothing).take(NUM_ELEMENTS).collect::<Vec<_>>();
+
+    DROP_COUNTER.store(0, Ordering::Relaxed);
+
+    let v = v.map_in_place(|_| ZeroSized);
+    assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
+    drop(v);
+    assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), NUM_ELEMENTS);
+}
+
+#[test]
+fn test_move_items() {
+    let vec = vec![1, 2, 3];
+    let mut vec2 = vec![];
+    for i in vec {
+        vec2.push(i);
+    }
+    assert_eq!(vec2, [1, 2, 3]);
+}
+
+#[test]
+fn test_move_items_reverse() {
+    let vec = vec![1, 2, 3];
+    let mut vec2 = vec![];
+    for i in vec.into_iter().rev() {
+        vec2.push(i);
+    }
+    assert_eq!(vec2, [3, 2, 1]);
+}
+
+#[test]
+fn test_move_items_zero_sized() {
+    let vec = vec![(), (), ()];
+    let mut vec2 = vec![];
+    for i in vec {
+        vec2.push(i);
+    }
+    assert_eq!(vec2, [(), (), ()]);
+}
+
+#[test]
+fn test_drain_items() {
+    let mut vec = vec![1, 2, 3];
+    let mut vec2 = vec![];
+    for i in vec.drain() {
+        vec2.push(i);
+    }
+    assert_eq!(vec, []);
+    assert_eq!(vec2, [ 1, 2, 3 ]);
+}
+
+#[test]
+fn test_drain_items_reverse() {
+    let mut vec = vec![1, 2, 3];
+    let mut vec2 = vec![];
+    for i in vec.drain().rev() {
+        vec2.push(i);
+    }
+    assert_eq!(vec, []);
+    assert_eq!(vec2, [3, 2, 1]);
+}
+
+#[test]
+fn test_drain_items_zero_sized() {
+    let mut vec = vec![(), (), ()];
+    let mut vec2 = vec![];
+    for i in vec.drain() {
+        vec2.push(i);
+    }
+    assert_eq!(vec, []);
+    assert_eq!(vec2, [(), (), ()]);
+}
+
+#[test]
+fn test_into_boxed_slice() {
+    let xs = vec![1, 2, 3];
+    let ys = xs.into_boxed_slice();
+    assert_eq!(&*ys, [1, 2, 3]);
+}
+
+#[test]
+fn test_append() {
+    let mut vec = vec![1, 2, 3];
+    let mut vec2 = vec![4, 5, 6];
+    vec.append(&mut vec2);
+    assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(vec2, []);
+}
+
+#[test]
+fn test_split_off() {
+    let mut vec = vec![1, 2, 3, 4, 5, 6];
+    let vec2 = vec.split_off(4);
+    assert_eq!(vec, [1, 2, 3, 4]);
+    assert_eq!(vec2, [5, 6]);
+}
+
+#[bench]
+fn bench_new(b: &mut Bencher) {
+    b.iter(|| {
+        let v: Vec<u32> = Vec::new();
+        assert_eq!(v.len(), 0);
+        assert_eq!(v.capacity(), 0);
+    })
+}
+
+fn do_bench_with_capacity(b: &mut Bencher, src_len: usize) {
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let v: Vec<u32> = Vec::with_capacity(src_len);
+        assert_eq!(v.len(), 0);
+        assert_eq!(v.capacity(), src_len);
+    })
+}
+
+#[bench]
+fn bench_with_capacity_0000(b: &mut Bencher) {
+    do_bench_with_capacity(b, 0)
+}
+
+#[bench]
+fn bench_with_capacity_0010(b: &mut Bencher) {
+    do_bench_with_capacity(b, 10)
+}
+
+#[bench]
+fn bench_with_capacity_0100(b: &mut Bencher) {
+    do_bench_with_capacity(b, 100)
+}
+
+#[bench]
+fn bench_with_capacity_1000(b: &mut Bencher) {
+    do_bench_with_capacity(b, 1000)
+}
+
+fn do_bench_from_fn(b: &mut Bencher, src_len: usize) {
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let dst = (0..src_len).collect::<Vec<_>>();
+        assert_eq!(dst.len(), src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    })
+}
+
+#[bench]
+fn bench_from_fn_0000(b: &mut Bencher) {
+    do_bench_from_fn(b, 0)
+}
+
+#[bench]
+fn bench_from_fn_0010(b: &mut Bencher) {
+    do_bench_from_fn(b, 10)
+}
+
+#[bench]
+fn bench_from_fn_0100(b: &mut Bencher) {
+    do_bench_from_fn(b, 100)
+}
+
+#[bench]
+fn bench_from_fn_1000(b: &mut Bencher) {
+    do_bench_from_fn(b, 1000)
+}
+
+fn do_bench_from_elem(b: &mut Bencher, src_len: usize) {
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let dst: Vec<usize> = repeat(5).take(src_len).collect();
+        assert_eq!(dst.len(), src_len);
+        assert!(dst.iter().all(|x| *x == 5));
+    })
+}
+
+#[bench]
+fn bench_from_elem_0000(b: &mut Bencher) {
+    do_bench_from_elem(b, 0)
+}
+
+#[bench]
+fn bench_from_elem_0010(b: &mut Bencher) {
+    do_bench_from_elem(b, 10)
+}
+
+#[bench]
+fn bench_from_elem_0100(b: &mut Bencher) {
+    do_bench_from_elem(b, 100)
+}
+
+#[bench]
+fn bench_from_elem_1000(b: &mut Bencher) {
+    do_bench_from_elem(b, 1000)
+}
+
+fn do_bench_from_slice(b: &mut Bencher, src_len: usize) {
+    let src: Vec<_> = FromIterator::from_iter(0..src_len);
+
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let dst = src.clone()[..].to_vec();
+        assert_eq!(dst.len(), src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    });
+}
+
+#[bench]
+fn bench_from_slice_0000(b: &mut Bencher) {
+    do_bench_from_slice(b, 0)
+}
+
+#[bench]
+fn bench_from_slice_0010(b: &mut Bencher) {
+    do_bench_from_slice(b, 10)
+}
+
+#[bench]
+fn bench_from_slice_0100(b: &mut Bencher) {
+    do_bench_from_slice(b, 100)
+}
+
+#[bench]
+fn bench_from_slice_1000(b: &mut Bencher) {
+    do_bench_from_slice(b, 1000)
+}
+
+fn do_bench_from_iter(b: &mut Bencher, src_len: usize) {
+    let src: Vec<_> = FromIterator::from_iter(0..src_len);
+
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let dst: Vec<_> = FromIterator::from_iter(src.clone().into_iter());
+        assert_eq!(dst.len(), src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    });
+}
+
+#[bench]
+fn bench_from_iter_0000(b: &mut Bencher) {
+    do_bench_from_iter(b, 0)
+}
+
+#[bench]
+fn bench_from_iter_0010(b: &mut Bencher) {
+    do_bench_from_iter(b, 10)
+}
+
+#[bench]
+fn bench_from_iter_0100(b: &mut Bencher) {
+    do_bench_from_iter(b, 100)
+}
+
+#[bench]
+fn bench_from_iter_1000(b: &mut Bencher) {
+    do_bench_from_iter(b, 1000)
+}
+
+fn do_bench_extend(b: &mut Bencher, dst_len: usize, src_len: usize) {
+    let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
+    let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
+
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let mut dst = dst.clone();
+        dst.extend(src.clone().into_iter());
+        assert_eq!(dst.len(), dst_len + src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    });
+}
+
+#[bench]
+fn bench_extend_0000_0000(b: &mut Bencher) {
+    do_bench_extend(b, 0, 0)
+}
+
+#[bench]
+fn bench_extend_0000_0010(b: &mut Bencher) {
+    do_bench_extend(b, 0, 10)
+}
+
+#[bench]
+fn bench_extend_0000_0100(b: &mut Bencher) {
+    do_bench_extend(b, 0, 100)
+}
+
+#[bench]
+fn bench_extend_0000_1000(b: &mut Bencher) {
+    do_bench_extend(b, 0, 1000)
+}
+
+#[bench]
+fn bench_extend_0010_0010(b: &mut Bencher) {
+    do_bench_extend(b, 10, 10)
+}
+
+#[bench]
+fn bench_extend_0100_0100(b: &mut Bencher) {
+    do_bench_extend(b, 100, 100)
+}
+
+#[bench]
+fn bench_extend_1000_1000(b: &mut Bencher) {
+    do_bench_extend(b, 1000, 1000)
+}
+
+fn do_bench_push_all(b: &mut Bencher, dst_len: usize, src_len: usize) {
+    let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
+    let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
+
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let mut dst = dst.clone();
+        dst.push_all(&src);
+        assert_eq!(dst.len(), dst_len + src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    });
+}
+
+#[bench]
+fn bench_push_all_0000_0000(b: &mut Bencher) {
+    do_bench_push_all(b, 0, 0)
+}
+
+#[bench]
+fn bench_push_all_0000_0010(b: &mut Bencher) {
+    do_bench_push_all(b, 0, 10)
+}
+
+#[bench]
+fn bench_push_all_0000_0100(b: &mut Bencher) {
+    do_bench_push_all(b, 0, 100)
+}
+
+#[bench]
+fn bench_push_all_0000_1000(b: &mut Bencher) {
+    do_bench_push_all(b, 0, 1000)
+}
+
+#[bench]
+fn bench_push_all_0010_0010(b: &mut Bencher) {
+    do_bench_push_all(b, 10, 10)
+}
+
+#[bench]
+fn bench_push_all_0100_0100(b: &mut Bencher) {
+    do_bench_push_all(b, 100, 100)
+}
+
+#[bench]
+fn bench_push_all_1000_1000(b: &mut Bencher) {
+    do_bench_push_all(b, 1000, 1000)
+}
+
+fn do_bench_push_all_move(b: &mut Bencher, dst_len: usize, src_len: usize) {
+    let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
+    let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
+
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let mut dst = dst.clone();
+        dst.extend(src.clone().into_iter());
+        assert_eq!(dst.len(), dst_len + src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    });
+}
+
+#[bench]
+fn bench_push_all_move_0000_0000(b: &mut Bencher) {
+    do_bench_push_all_move(b, 0, 0)
+}
+
+#[bench]
+fn bench_push_all_move_0000_0010(b: &mut Bencher) {
+    do_bench_push_all_move(b, 0, 10)
+}
+
+#[bench]
+fn bench_push_all_move_0000_0100(b: &mut Bencher) {
+    do_bench_push_all_move(b, 0, 100)
+}
+
+#[bench]
+fn bench_push_all_move_0000_1000(b: &mut Bencher) {
+    do_bench_push_all_move(b, 0, 1000)
+}
+
+#[bench]
+fn bench_push_all_move_0010_0010(b: &mut Bencher) {
+    do_bench_push_all_move(b, 10, 10)
+}
+
+#[bench]
+fn bench_push_all_move_0100_0100(b: &mut Bencher) {
+    do_bench_push_all_move(b, 100, 100)
+}
+
+#[bench]
+fn bench_push_all_move_1000_1000(b: &mut Bencher) {
+    do_bench_push_all_move(b, 1000, 1000)
+}
+
+fn do_bench_clone(b: &mut Bencher, src_len: usize) {
+    let src: Vec<usize> = FromIterator::from_iter(0..src_len);
+
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let dst = src.clone();
+        assert_eq!(dst.len(), src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    });
+}
+
+#[bench]
+fn bench_clone_0000(b: &mut Bencher) {
+    do_bench_clone(b, 0)
+}
+
+#[bench]
+fn bench_clone_0010(b: &mut Bencher) {
+    do_bench_clone(b, 10)
+}
+
+#[bench]
+fn bench_clone_0100(b: &mut Bencher) {
+    do_bench_clone(b, 100)
+}
+
+#[bench]
+fn bench_clone_1000(b: &mut Bencher) {
+    do_bench_clone(b, 1000)
+}
+
+fn do_bench_clone_from(b: &mut Bencher, times: usize, dst_len: usize, src_len: usize) {
+    let dst: Vec<_> = FromIterator::from_iter(0..src_len);
+    let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
+
+    b.bytes = (times * src_len) as u64;
+
+    b.iter(|| {
+        let mut dst = dst.clone();
+
+        for _ in 0..times {
+            dst.clone_from(&src);
+
+            assert_eq!(dst.len(), src_len);
+            assert!(dst.iter().enumerate().all(|(i, x)| dst_len + i == *x));
+        }
+    });
+}
+
+#[bench]
+fn bench_clone_from_01_0000_0000(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 0, 0)
+}
+
+#[bench]
+fn bench_clone_from_01_0000_0010(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 0, 10)
+}
+
+#[bench]
+fn bench_clone_from_01_0000_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 0, 100)
+}
+
+#[bench]
+fn bench_clone_from_01_0000_1000(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 0, 1000)
+}
+
+#[bench]
+fn bench_clone_from_01_0010_0010(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 10, 10)
+}
+
+#[bench]
+fn bench_clone_from_01_0100_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 100, 100)
+}
+
+#[bench]
+fn bench_clone_from_01_1000_1000(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 1000, 1000)
+}
+
+#[bench]
+fn bench_clone_from_01_0010_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 10, 100)
+}
+
+#[bench]
+fn bench_clone_from_01_0100_1000(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 100, 1000)
+}
+
+#[bench]
+fn bench_clone_from_01_0010_0000(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 10, 0)
+}
+
+#[bench]
+fn bench_clone_from_01_0100_0010(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 100, 10)
+}
+
+#[bench]
+fn bench_clone_from_01_1000_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 1000, 100)
+}
+
+#[bench]
+fn bench_clone_from_10_0000_0000(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 0, 0)
+}
+
+#[bench]
+fn bench_clone_from_10_0000_0010(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 0, 10)
+}
+
+#[bench]
+fn bench_clone_from_10_0000_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 0, 100)
+}
+
+#[bench]
+fn bench_clone_from_10_0000_1000(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 0, 1000)
+}
+
+#[bench]
+fn bench_clone_from_10_0010_0010(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 10, 10)
+}
+
+#[bench]
+fn bench_clone_from_10_0100_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 100, 100)
+}
+
+#[bench]
+fn bench_clone_from_10_1000_1000(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 1000, 1000)
+}
+
+#[bench]
+fn bench_clone_from_10_0010_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 10, 100)
+}
+
+#[bench]
+fn bench_clone_from_10_0100_1000(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 100, 1000)
+}
+
+#[bench]
+fn bench_clone_from_10_0010_0000(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 10, 0)
+}
+
+#[bench]
+fn bench_clone_from_10_0100_0010(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 100, 10)
+}
+
+#[bench]
+fn bench_clone_from_10_1000_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 1000, 100)
+}
diff --git a/src/libcollectionstest/vec_deque.rs b/src/libcollectionstest/vec_deque.rs
new file mode 100644 (file)
index 0000000..1232328
--- /dev/null
@@ -0,0 +1,887 @@
+// 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.
+//
+// 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 std::collections::VecDeque;
+use std::fmt::Debug;
+use std::hash::{SipHasher, self};
+
+use test;
+
+use self::Taggy::*;
+use self::Taggypar::*;
+
+#[test]
+fn test_simple() {
+    let mut d = VecDeque::new();
+    assert_eq!(d.len(), 0);
+    d.push_front(17);
+    d.push_front(42);
+    d.push_back(137);
+    assert_eq!(d.len(), 3);
+    d.push_back(137);
+    assert_eq!(d.len(), 4);
+    assert_eq!(*d.front().unwrap(), 42);
+    assert_eq!(*d.back().unwrap(), 137);
+    let mut i = d.pop_front();
+    assert_eq!(i, Some(42));
+    i = d.pop_back();
+    assert_eq!(i, Some(137));
+    i = d.pop_back();
+    assert_eq!(i, Some(137));
+    i = d.pop_back();
+    assert_eq!(i, Some(17));
+    assert_eq!(d.len(), 0);
+    d.push_back(3);
+    assert_eq!(d.len(), 1);
+    d.push_front(2);
+    assert_eq!(d.len(), 2);
+    d.push_back(4);
+    assert_eq!(d.len(), 3);
+    d.push_front(1);
+    assert_eq!(d.len(), 4);
+    debug!("{}", d[0]);
+    debug!("{}", d[1]);
+    debug!("{}", d[2]);
+    debug!("{}", d[3]);
+    assert_eq!(d[0], 1);
+    assert_eq!(d[1], 2);
+    assert_eq!(d[2], 3);
+    assert_eq!(d[3], 4);
+}
+
+#[cfg(test)]
+fn test_parameterized<T:Clone + PartialEq + Debug>(a: T, b: T, c: T, d: T) {
+    let mut deq = VecDeque::new();
+    assert_eq!(deq.len(), 0);
+    deq.push_front(a.clone());
+    deq.push_front(b.clone());
+    deq.push_back(c.clone());
+    assert_eq!(deq.len(), 3);
+    deq.push_back(d.clone());
+    assert_eq!(deq.len(), 4);
+    assert_eq!((*deq.front().unwrap()).clone(), b.clone());
+    assert_eq!((*deq.back().unwrap()).clone(), d.clone());
+    assert_eq!(deq.pop_front().unwrap(), b.clone());
+    assert_eq!(deq.pop_back().unwrap(), d.clone());
+    assert_eq!(deq.pop_back().unwrap(), c.clone());
+    assert_eq!(deq.pop_back().unwrap(), a.clone());
+    assert_eq!(deq.len(), 0);
+    deq.push_back(c.clone());
+    assert_eq!(deq.len(), 1);
+    deq.push_front(b.clone());
+    assert_eq!(deq.len(), 2);
+    deq.push_back(d.clone());
+    assert_eq!(deq.len(), 3);
+    deq.push_front(a.clone());
+    assert_eq!(deq.len(), 4);
+    assert_eq!(deq[0].clone(), a.clone());
+    assert_eq!(deq[1].clone(), b.clone());
+    assert_eq!(deq[2].clone(), c.clone());
+    assert_eq!(deq[3].clone(), d.clone());
+}
+
+#[test]
+fn test_push_front_grow() {
+    let mut deq = VecDeque::new();
+    for i in 0..66 {
+        deq.push_front(i);
+    }
+    assert_eq!(deq.len(), 66);
+
+    for i in 0..66 {
+        assert_eq!(deq[i], 65 - i);
+    }
+
+    let mut deq = VecDeque::new();
+    for i in 0..66 {
+        deq.push_back(i);
+    }
+
+    for i in 0..66 {
+        assert_eq!(deq[i], i);
+    }
+}
+
+#[test]
+fn test_index() {
+    let mut deq = VecDeque::new();
+    for i in 1..4 {
+        deq.push_front(i);
+    }
+    assert_eq!(deq[1], 2);
+}
+
+#[test]
+#[should_panic]
+fn test_index_out_of_bounds() {
+    let mut deq = VecDeque::new();
+    for i in 1..4 {
+        deq.push_front(i);
+    }
+    deq[3];
+}
+
+#[bench]
+fn bench_new(b: &mut test::Bencher) {
+    b.iter(|| {
+        let ring: VecDeque<i32> = VecDeque::new();
+        test::black_box(ring);
+    })
+}
+
+#[bench]
+fn bench_grow_1025(b: &mut test::Bencher) {
+    b.iter(|| {
+        let mut deq = VecDeque::new();
+        for i in 0..1025 {
+            deq.push_front(i);
+        }
+        test::black_box(deq);
+    })
+}
+
+#[bench]
+fn bench_iter_1000(b: &mut test::Bencher) {
+    let ring: VecDeque<_> = (0..1000).collect();
+
+    b.iter(|| {
+        let mut sum = 0;
+        for &i in &ring {
+            sum += i;
+        }
+        test::black_box(sum);
+    })
+}
+
+#[bench]
+fn bench_mut_iter_1000(b: &mut test::Bencher) {
+    let mut ring: VecDeque<_> = (0..1000).collect();
+
+    b.iter(|| {
+        let mut sum = 0;
+        for i in &mut ring {
+            sum += *i;
+        }
+        test::black_box(sum);
+    })
+}
+
+#[derive(Clone, PartialEq, Debug)]
+enum Taggy {
+    One(i32),
+    Two(i32, i32),
+    Three(i32, i32, i32),
+}
+
+#[derive(Clone, PartialEq, Debug)]
+enum Taggypar<T> {
+    Onepar(T),
+    Twopar(T, T),
+    Threepar(T, T, T),
+}
+
+#[derive(Clone, PartialEq, Debug)]
+struct RecCy {
+    x: i32,
+    y: i32,
+    t: Taggy
+}
+
+#[test]
+fn test_param_int() {
+    test_parameterized::<i32>(5, 72, 64, 175);
+}
+
+#[test]
+fn test_param_taggy() {
+    test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
+}
+
+#[test]
+fn test_param_taggypar() {
+    test_parameterized::<Taggypar<i32>>(Onepar::<i32>(1),
+                                        Twopar::<i32>(1, 2),
+                                        Threepar::<i32>(1, 2, 3),
+                                        Twopar::<i32>(17, 42));
+}
+
+#[test]
+fn test_param_reccy() {
+    let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
+    let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
+    let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
+    let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
+    test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
+}
+
+#[test]
+fn test_with_capacity() {
+    let mut d = VecDeque::with_capacity(0);
+    d.push_back(1);
+    assert_eq!(d.len(), 1);
+    let mut d = VecDeque::with_capacity(50);
+    d.push_back(1);
+    assert_eq!(d.len(), 1);
+}
+
+#[test]
+fn test_with_capacity_non_power_two() {
+    let mut d3 = VecDeque::with_capacity(3);
+    d3.push_back(1);
+
+    // X = None, | = lo
+    // [|1, X, X]
+    assert_eq!(d3.pop_front(), Some(1));
+    // [X, |X, X]
+    assert_eq!(d3.front(), None);
+
+    // [X, |3, X]
+    d3.push_back(3);
+    // [X, |3, 6]
+    d3.push_back(6);
+    // [X, X, |6]
+    assert_eq!(d3.pop_front(), Some(3));
+
+    // Pushing the lo past half way point to trigger
+    // the 'B' scenario for growth
+    // [9, X, |6]
+    d3.push_back(9);
+    // [9, 12, |6]
+    d3.push_back(12);
+
+    d3.push_back(15);
+    // There used to be a bug here about how the
+    // VecDeque made growth assumptions about the
+    // underlying Vec which didn't hold and lead
+    // to corruption.
+    // (Vec grows to next power of two)
+    //good- [9, 12, 15, X, X, X, X, |6]
+    //bug-  [15, 12, X, X, X, |6, X, X]
+    assert_eq!(d3.pop_front(), Some(6));
+
+    // Which leads us to the following state which
+    // would be a failure case.
+    //bug-  [15, 12, X, X, X, X, |X, X]
+    assert_eq!(d3.front(), Some(&9));
+}
+
+#[test]
+fn test_reserve_exact() {
+    let mut d = VecDeque::new();
+    d.push_back(0);
+    d.reserve_exact(50);
+    assert!(d.capacity() >= 51);
+}
+
+#[test]
+fn test_reserve() {
+    let mut d = VecDeque::new();
+    d.push_back(0);
+    d.reserve(50);
+    assert!(d.capacity() >= 51);
+}
+
+#[test]
+fn test_swap() {
+    let mut d: VecDeque<_> = (0..5).collect();
+    d.pop_front();
+    d.swap(0, 3);
+    assert_eq!(d.iter().cloned().collect::<Vec<_>>(), [4, 2, 3, 1]);
+}
+
+#[test]
+fn test_iter() {
+    let mut d = VecDeque::new();
+    assert_eq!(d.iter().next(), None);
+    assert_eq!(d.iter().size_hint(), (0, Some(0)));
+
+    for i in 0..5 {
+        d.push_back(i);
+    }
+    {
+        let b: &[_] = &[&0,&1,&2,&3,&4];
+        assert_eq!(d.iter().collect::<Vec<_>>(), b);
+    }
+
+    for i in 6..9 {
+        d.push_front(i);
+    }
+    {
+        let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
+        assert_eq!(d.iter().collect::<Vec<_>>(), b);
+    }
+
+    let mut it = d.iter();
+    let mut len = d.len();
+    loop {
+        match it.next() {
+            None => break,
+            _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
+        }
+    }
+}
+
+#[test]
+fn test_rev_iter() {
+    let mut d = VecDeque::new();
+    assert_eq!(d.iter().rev().next(), None);
+
+    for i in 0..5 {
+        d.push_back(i);
+    }
+    {
+        let b: &[_] = &[&4,&3,&2,&1,&0];
+        assert_eq!(d.iter().rev().collect::<Vec<_>>(), b);
+    }
+
+    for i in 6..9 {
+        d.push_front(i);
+    }
+    let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
+    assert_eq!(d.iter().rev().collect::<Vec<_>>(), b);
+}
+
+#[test]
+fn test_mut_rev_iter_wrap() {
+    let mut d = VecDeque::with_capacity(3);
+    assert!(d.iter_mut().rev().next().is_none());
+
+    d.push_back(1);
+    d.push_back(2);
+    d.push_back(3);
+    assert_eq!(d.pop_front(), Some(1));
+    d.push_back(4);
+
+    assert_eq!(d.iter_mut().rev().map(|x| *x).collect::<Vec<_>>(),
+               vec![4, 3, 2]);
+}
+
+#[test]
+fn test_mut_iter() {
+    let mut d = VecDeque::new();
+    assert!(d.iter_mut().next().is_none());
+
+    for i in 0..3 {
+        d.push_front(i);
+    }
+
+    for (i, elt) in d.iter_mut().enumerate() {
+        assert_eq!(*elt, 2 - i);
+        *elt = i;
+    }
+
+    {
+        let mut it = d.iter_mut();
+        assert_eq!(*it.next().unwrap(), 0);
+        assert_eq!(*it.next().unwrap(), 1);
+        assert_eq!(*it.next().unwrap(), 2);
+        assert!(it.next().is_none());
+    }
+}
+
+#[test]
+fn test_mut_rev_iter() {
+    let mut d = VecDeque::new();
+    assert!(d.iter_mut().rev().next().is_none());
+
+    for i in 0..3 {
+        d.push_front(i);
+    }
+
+    for (i, elt) in d.iter_mut().rev().enumerate() {
+        assert_eq!(*elt, i);
+        *elt = i;
+    }
+
+    {
+        let mut it = d.iter_mut().rev();
+        assert_eq!(*it.next().unwrap(), 0);
+        assert_eq!(*it.next().unwrap(), 1);
+        assert_eq!(*it.next().unwrap(), 2);
+        assert!(it.next().is_none());
+    }
+}
+
+#[test]
+fn test_into_iter() {
+
+    // Empty iter
+    {
+        let d: VecDeque<i32> = VecDeque::new();
+        let mut iter = d.into_iter();
+
+        assert_eq!(iter.size_hint(), (0, Some(0)));
+        assert_eq!(iter.next(), None);
+        assert_eq!(iter.size_hint(), (0, Some(0)));
+    }
+
+    // simple iter
+    {
+        let mut d = VecDeque::new();
+        for i in 0..5 {
+            d.push_back(i);
+        }
+
+        let b = vec![0,1,2,3,4];
+        assert_eq!(d.into_iter().collect::<Vec<_>>(), b);
+    }
+
+    // wrapped iter
+    {
+        let mut d = VecDeque::new();
+        for i in 0..5 {
+            d.push_back(i);
+        }
+        for i in 6..9 {
+            d.push_front(i);
+        }
+
+        let b = vec![8,7,6,0,1,2,3,4];
+        assert_eq!(d.into_iter().collect::<Vec<_>>(), b);
+    }
+
+    // partially used
+    {
+        let mut d = VecDeque::new();
+        for i in 0..5 {
+            d.push_back(i);
+        }
+        for i in 6..9 {
+            d.push_front(i);
+        }
+
+        let mut it = d.into_iter();
+        assert_eq!(it.size_hint(), (8, Some(8)));
+        assert_eq!(it.next(), Some(8));
+        assert_eq!(it.size_hint(), (7, Some(7)));
+        assert_eq!(it.next_back(), Some(4));
+        assert_eq!(it.size_hint(), (6, Some(6)));
+        assert_eq!(it.next(), Some(7));
+        assert_eq!(it.size_hint(), (5, Some(5)));
+    }
+}
+
+#[test]
+fn test_drain() {
+
+    // Empty iter
+    {
+        let mut d: VecDeque<i32> = VecDeque::new();
+
+        {
+            let mut iter = d.drain();
+
+            assert_eq!(iter.size_hint(), (0, Some(0)));
+            assert_eq!(iter.next(), None);
+            assert_eq!(iter.size_hint(), (0, Some(0)));
+        }
+
+        assert!(d.is_empty());
+    }
+
+    // simple iter
+    {
+        let mut d = VecDeque::new();
+        for i in 0..5 {
+            d.push_back(i);
+        }
+
+        assert_eq!(d.drain().collect::<Vec<_>>(), [0, 1, 2, 3, 4]);
+        assert!(d.is_empty());
+    }
+
+    // wrapped iter
+    {
+        let mut d = VecDeque::new();
+        for i in 0..5 {
+            d.push_back(i);
+        }
+        for i in 6..9 {
+            d.push_front(i);
+        }
+
+        assert_eq!(d.drain().collect::<Vec<_>>(), [8,7,6,0,1,2,3,4]);
+        assert!(d.is_empty());
+    }
+
+    // partially used
+    {
+        let mut d: VecDeque<_> = VecDeque::new();
+        for i in 0..5 {
+            d.push_back(i);
+        }
+        for i in 6..9 {
+            d.push_front(i);
+        }
+
+        {
+            let mut it = d.drain();
+            assert_eq!(it.size_hint(), (8, Some(8)));
+            assert_eq!(it.next(), Some(8));
+            assert_eq!(it.size_hint(), (7, Some(7)));
+            assert_eq!(it.next_back(), Some(4));
+            assert_eq!(it.size_hint(), (6, Some(6)));
+            assert_eq!(it.next(), Some(7));
+            assert_eq!(it.size_hint(), (5, Some(5)));
+        }
+        assert!(d.is_empty());
+    }
+}
+
+#[test]
+fn test_from_iter() {
+    use std::iter;
+
+    let v = vec!(1,2,3,4,5,6,7);
+    let deq: VecDeque<_> = v.iter().cloned().collect();
+    let u: Vec<_> = deq.iter().cloned().collect();
+    assert_eq!(u, v);
+
+    let seq = (0..).step_by(2).take(256);
+    let deq: VecDeque<_> = seq.collect();
+    for (i, &x) in deq.iter().enumerate() {
+        assert_eq!(2*i, x);
+    }
+    assert_eq!(deq.len(), 256);
+}
+
+#[test]
+fn test_clone() {
+    let mut d = VecDeque::new();
+    d.push_front(17);
+    d.push_front(42);
+    d.push_back(137);
+    d.push_back(137);
+    assert_eq!(d.len(), 4);
+    let mut e = d.clone();
+    assert_eq!(e.len(), 4);
+    while !d.is_empty() {
+        assert_eq!(d.pop_back(), e.pop_back());
+    }
+    assert_eq!(d.len(), 0);
+    assert_eq!(e.len(), 0);
+}
+
+#[test]
+fn test_eq() {
+    let mut d = VecDeque::new();
+    assert!(d == VecDeque::with_capacity(0));
+    d.push_front(137);
+    d.push_front(17);
+    d.push_front(42);
+    d.push_back(137);
+    let mut e = VecDeque::with_capacity(0);
+    e.push_back(42);
+    e.push_back(17);
+    e.push_back(137);
+    e.push_back(137);
+    assert!(&e == &d);
+    e.pop_back();
+    e.push_back(0);
+    assert!(e != d);
+    e.clear();
+    assert!(e == VecDeque::new());
+}
+
+#[test]
+fn test_hash() {
+  let mut x = VecDeque::new();
+  let mut y = VecDeque::new();
+
+  x.push_back(1);
+  x.push_back(2);
+  x.push_back(3);
+
+  y.push_back(0);
+  y.push_back(1);
+  y.pop_front();
+  y.push_back(2);
+  y.push_back(3);
+
+  assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
+}
+
+#[test]
+fn test_ord() {
+    let x = VecDeque::new();
+    let mut y = VecDeque::new();
+    y.push_back(1);
+    y.push_back(2);
+    y.push_back(3);
+    assert!(x < y);
+    assert!(y > x);
+    assert!(x <= x);
+    assert!(x >= x);
+}
+
+#[test]
+fn test_show() {
+    let ringbuf: VecDeque<_> = (0..10).collect();
+    assert_eq!(format!("{:?}", ringbuf), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
+
+    let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"].iter()
+                                                                    .cloned()
+                                                                    .collect();
+    assert_eq!(format!("{:?}", ringbuf), "[\"just\", \"one\", \"test\", \"more\"]");
+}
+
+#[test]
+fn test_drop() {
+    static mut drops: i32 = 0;
+    struct Elem;
+    impl Drop for Elem {
+        fn drop(&mut self) {
+            unsafe { drops += 1; }
+        }
+    }
+
+    let mut ring = VecDeque::new();
+    ring.push_back(Elem);
+    ring.push_front(Elem);
+    ring.push_back(Elem);
+    ring.push_front(Elem);
+    drop(ring);
+
+    assert_eq!(unsafe {drops}, 4);
+}
+
+#[test]
+fn test_drop_with_pop() {
+    static mut drops: i32 = 0;
+    struct Elem;
+    impl Drop for Elem {
+        fn drop(&mut self) {
+            unsafe { drops += 1; }
+        }
+    }
+
+    let mut ring = VecDeque::new();
+    ring.push_back(Elem);
+    ring.push_front(Elem);
+    ring.push_back(Elem);
+    ring.push_front(Elem);
+
+    drop(ring.pop_back());
+    drop(ring.pop_front());
+    assert_eq!(unsafe {drops}, 2);
+
+    drop(ring);
+    assert_eq!(unsafe {drops}, 4);
+}
+
+#[test]
+fn test_drop_clear() {
+    static mut drops: i32 = 0;
+    struct Elem;
+    impl Drop for Elem {
+        fn drop(&mut self) {
+            unsafe { drops += 1; }
+        }
+    }
+
+    let mut ring = VecDeque::new();
+    ring.push_back(Elem);
+    ring.push_front(Elem);
+    ring.push_back(Elem);
+    ring.push_front(Elem);
+    ring.clear();
+    assert_eq!(unsafe {drops}, 4);
+
+    drop(ring);
+    assert_eq!(unsafe {drops}, 4);
+}
+
+#[test]
+fn test_reserve_grow() {
+    // test growth path A
+    // [T o o H] -> [T o o H . . . . ]
+    let mut ring = VecDeque::with_capacity(4);
+    for i in 0..3 {
+        ring.push_back(i);
+    }
+    ring.reserve(7);
+    for i in 0..3 {
+        assert_eq!(ring.pop_front(), Some(i));
+    }
+
+    // test growth path B
+    // [H T o o] -> [. T o o H . . . ]
+    let mut ring = VecDeque::with_capacity(4);
+    for i in 0..1 {
+        ring.push_back(i);
+        assert_eq!(ring.pop_front(), Some(i));
+    }
+    for i in 0..3 {
+        ring.push_back(i);
+    }
+    ring.reserve(7);
+    for i in 0..3 {
+        assert_eq!(ring.pop_front(), Some(i));
+    }
+
+    // test growth path C
+    // [o o H T] -> [o o H . . . . T ]
+    let mut ring = VecDeque::with_capacity(4);
+    for i in 0..3 {
+        ring.push_back(i);
+        assert_eq!(ring.pop_front(), Some(i));
+    }
+    for i in 0..3 {
+        ring.push_back(i);
+    }
+    ring.reserve(7);
+    for i in 0..3 {
+        assert_eq!(ring.pop_front(), Some(i));
+    }
+}
+
+#[test]
+fn test_get() {
+    let mut ring = VecDeque::new();
+    ring.push_back(0);
+    assert_eq!(ring.get(0), Some(&0));
+    assert_eq!(ring.get(1), None);
+
+    ring.push_back(1);
+    assert_eq!(ring.get(0), Some(&0));
+    assert_eq!(ring.get(1), Some(&1));
+    assert_eq!(ring.get(2), None);
+
+    ring.push_back(2);
+    assert_eq!(ring.get(0), Some(&0));
+    assert_eq!(ring.get(1), Some(&1));
+    assert_eq!(ring.get(2), Some(&2));
+    assert_eq!(ring.get(3), None);
+
+    assert_eq!(ring.pop_front(), Some(0));
+    assert_eq!(ring.get(0), Some(&1));
+    assert_eq!(ring.get(1), Some(&2));
+    assert_eq!(ring.get(2), None);
+
+    assert_eq!(ring.pop_front(), Some(1));
+    assert_eq!(ring.get(0), Some(&2));
+    assert_eq!(ring.get(1), None);
+
+    assert_eq!(ring.pop_front(), Some(2));
+    assert_eq!(ring.get(0), None);
+    assert_eq!(ring.get(1), None);
+}
+
+#[test]
+fn test_get_mut() {
+    let mut ring = VecDeque::new();
+    for i in 0..3 {
+        ring.push_back(i);
+    }
+
+    match ring.get_mut(1) {
+        Some(x) => *x = -1,
+        None => ()
+    };
+
+    assert_eq!(ring.get_mut(0), Some(&mut 0));
+    assert_eq!(ring.get_mut(1), Some(&mut -1));
+    assert_eq!(ring.get_mut(2), Some(&mut 2));
+    assert_eq!(ring.get_mut(3), None);
+
+    assert_eq!(ring.pop_front(), Some(0));
+    assert_eq!(ring.get_mut(0), Some(&mut -1));
+    assert_eq!(ring.get_mut(1), Some(&mut 2));
+    assert_eq!(ring.get_mut(2), None);
+}
+
+#[test]
+fn test_front() {
+    let mut ring = VecDeque::new();
+    ring.push_back(10);
+    ring.push_back(20);
+    assert_eq!(ring.front(), Some(&10));
+    ring.pop_front();
+    assert_eq!(ring.front(), Some(&20));
+    ring.pop_front();
+    assert_eq!(ring.front(), None);
+}
+
+#[test]
+fn test_as_slices() {
+    let mut ring: VecDeque<i32> = VecDeque::with_capacity(127);
+    let cap = ring.capacity() as i32;
+    let first = cap/2;
+    let last  = cap - first;
+    for i in 0..first {
+        ring.push_back(i);
+
+        let (left, right) = ring.as_slices();
+        let expected: Vec<_> = (0..i+1).collect();
+        assert_eq!(left, &expected[..]);
+        assert_eq!(right, []);
+    }
+
+    for j in -last..0 {
+        ring.push_front(j);
+        let (left, right) = ring.as_slices();
+        let expected_left: Vec<_> = (-last..j+1).rev().collect();
+        let expected_right: Vec<_> = (0..first).collect();
+        assert_eq!(left, &expected_left[..]);
+        assert_eq!(right, &expected_right[..]);
+    }
+
+    assert_eq!(ring.len() as i32, cap);
+    assert_eq!(ring.capacity() as i32, cap);
+}
+
+#[test]
+fn test_as_mut_slices() {
+    let mut ring: VecDeque<i32> = VecDeque::with_capacity(127);
+    let cap = ring.capacity() as i32;
+    let first = cap/2;
+    let last  = cap - first;
+    for i in 0..first {
+        ring.push_back(i);
+
+        let (left, right) = ring.as_mut_slices();
+        let expected: Vec<_> = (0..i+1).collect();
+        assert_eq!(left, &expected[..]);
+        assert_eq!(right, []);
+    }
+
+    for j in -last..0 {
+        ring.push_front(j);
+        let (left, right) = ring.as_mut_slices();
+        let expected_left: Vec<_> = (-last..j+1).rev().collect();
+        let expected_right: Vec<_> = (0..first).collect();
+        assert_eq!(left, &expected_left[..]);
+        assert_eq!(right, &expected_right[..]);
+    }
+
+    assert_eq!(ring.len() as i32, cap);
+    assert_eq!(ring.capacity() as i32, cap);
+}
+
+#[test]
+fn test_append() {
+    let mut a: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
+    let mut b: VecDeque<_> = vec![4, 5, 6].into_iter().collect();
+
+    // normal append
+    a.append(&mut b);
+    assert_eq!(a.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
+    assert_eq!(b.iter().cloned().collect::<Vec<_>>(), []);
+
+    // append nothing to something
+    a.append(&mut b);
+    assert_eq!(a.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
+    assert_eq!(b.iter().cloned().collect::<Vec<_>>(), []);
+
+    // append something to nothing
+    b.append(&mut a);
+    assert_eq!(b.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
+    assert_eq!(a.iter().cloned().collect::<Vec<_>>(), []);
+}
diff --git a/src/libcollectionstest/vec_map.rs b/src/libcollectionstest/vec_map.rs
new file mode 100644 (file)
index 0000000..112b4c0
--- /dev/null
@@ -0,0 +1,510 @@
+// 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.
+//
+// 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 std::collections::VecMap;
+use std::collections::vec_map::Entry::{Occupied, Vacant};
+use std::hash::{SipHasher, hash};
+
+#[test]
+fn test_get_mut() {
+    let mut m = VecMap::new();
+    assert!(m.insert(1, 12).is_none());
+    assert!(m.insert(2, 8).is_none());
+    assert!(m.insert(5, 14).is_none());
+    let new = 100;
+    match m.get_mut(&5) {
+        None => panic!(), Some(x) => *x = new
+    }
+    assert_eq!(m.get(&5), Some(&new));
+}
+
+#[test]
+fn test_len() {
+    let mut map = VecMap::new();
+    assert_eq!(map.len(), 0);
+    assert!(map.is_empty());
+    assert!(map.insert(5, 20).is_none());
+    assert_eq!(map.len(), 1);
+    assert!(!map.is_empty());
+    assert!(map.insert(11, 12).is_none());
+    assert_eq!(map.len(), 2);
+    assert!(!map.is_empty());
+    assert!(map.insert(14, 22).is_none());
+    assert_eq!(map.len(), 3);
+    assert!(!map.is_empty());
+}
+
+#[test]
+fn test_clear() {
+    let mut map = VecMap::new();
+    assert!(map.insert(5, 20).is_none());
+    assert!(map.insert(11, 12).is_none());
+    assert!(map.insert(14, 22).is_none());
+    map.clear();
+    assert!(map.is_empty());
+    assert!(map.get(&5).is_none());
+    assert!(map.get(&11).is_none());
+    assert!(map.get(&14).is_none());
+}
+
+#[test]
+fn test_insert() {
+    let mut m = VecMap::new();
+    assert_eq!(m.insert(1, 2), None);
+    assert_eq!(m.insert(1, 3), Some(2));
+    assert_eq!(m.insert(1, 4), Some(3));
+}
+
+#[test]
+fn test_remove() {
+    let mut m = VecMap::new();
+    m.insert(1, 2);
+    assert_eq!(m.remove(&1), Some(2));
+    assert_eq!(m.remove(&1), None);
+}
+
+#[test]
+fn test_keys() {
+    let mut map = VecMap::new();
+    map.insert(1, 'a');
+    map.insert(2, 'b');
+    map.insert(3, 'c');
+    let keys: Vec<_> = map.keys().collect();
+    assert_eq!(keys.len(), 3);
+    assert!(keys.contains(&1));
+    assert!(keys.contains(&2));
+    assert!(keys.contains(&3));
+}
+
+#[test]
+fn test_values() {
+    let mut map = VecMap::new();
+    map.insert(1, 'a');
+    map.insert(2, 'b');
+    map.insert(3, 'c');
+    let values: Vec<_> = map.values().cloned().collect();
+    assert_eq!(values.len(), 3);
+    assert!(values.contains(&'a'));
+    assert!(values.contains(&'b'));
+    assert!(values.contains(&'c'));
+}
+
+#[test]
+fn test_iterator() {
+    let mut m = VecMap::new();
+
+    assert!(m.insert(0, 1).is_none());
+    assert!(m.insert(1, 2).is_none());
+    assert!(m.insert(3, 5).is_none());
+    assert!(m.insert(6, 10).is_none());
+    assert!(m.insert(10, 11).is_none());
+
+    let mut it = m.iter();
+    assert_eq!(it.size_hint(), (0, Some(11)));
+    assert_eq!(it.next().unwrap(), (0, &1));
+    assert_eq!(it.size_hint(), (0, Some(10)));
+    assert_eq!(it.next().unwrap(), (1, &2));
+    assert_eq!(it.size_hint(), (0, Some(9)));
+    assert_eq!(it.next().unwrap(), (3, &5));
+    assert_eq!(it.size_hint(), (0, Some(7)));
+    assert_eq!(it.next().unwrap(), (6, &10));
+    assert_eq!(it.size_hint(), (0, Some(4)));
+    assert_eq!(it.next().unwrap(), (10, &11));
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_iterator_size_hints() {
+    let mut m = VecMap::new();
+
+    assert!(m.insert(0, 1).is_none());
+    assert!(m.insert(1, 2).is_none());
+    assert!(m.insert(3, 5).is_none());
+    assert!(m.insert(6, 10).is_none());
+    assert!(m.insert(10, 11).is_none());
+
+    assert_eq!(m.iter().size_hint(), (0, Some(11)));
+    assert_eq!(m.iter().rev().size_hint(), (0, Some(11)));
+    assert_eq!(m.iter_mut().size_hint(), (0, Some(11)));
+    assert_eq!(m.iter_mut().rev().size_hint(), (0, Some(11)));
+}
+
+#[test]
+fn test_mut_iterator() {
+    let mut m = VecMap::new();
+
+    assert!(m.insert(0, 1).is_none());
+    assert!(m.insert(1, 2).is_none());
+    assert!(m.insert(3, 5).is_none());
+    assert!(m.insert(6, 10).is_none());
+    assert!(m.insert(10, 11).is_none());
+
+    for (k, v) in &mut m {
+        *v += k as isize;
+    }
+
+    let mut it = m.iter();
+    assert_eq!(it.next().unwrap(), (0, &1));
+    assert_eq!(it.next().unwrap(), (1, &3));
+    assert_eq!(it.next().unwrap(), (3, &8));
+    assert_eq!(it.next().unwrap(), (6, &16));
+    assert_eq!(it.next().unwrap(), (10, &21));
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_rev_iterator() {
+    let mut m = VecMap::new();
+
+    assert!(m.insert(0, 1).is_none());
+    assert!(m.insert(1, 2).is_none());
+    assert!(m.insert(3, 5).is_none());
+    assert!(m.insert(6, 10).is_none());
+    assert!(m.insert(10, 11).is_none());
+
+    let mut it = m.iter().rev();
+    assert_eq!(it.next().unwrap(), (10, &11));
+    assert_eq!(it.next().unwrap(), (6, &10));
+    assert_eq!(it.next().unwrap(), (3, &5));
+    assert_eq!(it.next().unwrap(), (1, &2));
+    assert_eq!(it.next().unwrap(), (0, &1));
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_mut_rev_iterator() {
+    let mut m = VecMap::new();
+
+    assert!(m.insert(0, 1).is_none());
+    assert!(m.insert(1, 2).is_none());
+    assert!(m.insert(3, 5).is_none());
+    assert!(m.insert(6, 10).is_none());
+    assert!(m.insert(10, 11).is_none());
+
+    for (k, v) in m.iter_mut().rev() {
+        *v += k as isize;
+    }
+
+    let mut it = m.iter();
+    assert_eq!(it.next().unwrap(), (0, &1));
+    assert_eq!(it.next().unwrap(), (1, &3));
+    assert_eq!(it.next().unwrap(), (3, &8));
+    assert_eq!(it.next().unwrap(), (6, &16));
+    assert_eq!(it.next().unwrap(), (10, &21));
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_move_iter() {
+    let mut m: VecMap<Box<_>> = VecMap::new();
+    m.insert(1, box 2);
+    let mut called = false;
+    for (k, v) in m {
+        assert!(!called);
+        called = true;
+        assert_eq!(k, 1);
+        assert_eq!(v, box 2);
+    }
+    assert!(called);
+}
+
+#[test]
+fn test_drain_iterator() {
+    let mut map = VecMap::new();
+    map.insert(1, "a");
+    map.insert(3, "c");
+    map.insert(2, "b");
+
+    let vec: Vec<_> = map.drain().collect();
+
+    assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
+    assert_eq!(map.len(), 0);
+}
+
+#[test]
+fn test_append() {
+    let mut a = VecMap::new();
+    a.insert(1, "a");
+    a.insert(2, "b");
+    a.insert(3, "c");
+
+    let mut b = VecMap::new();
+    b.insert(3, "d");  // Overwrite element from a
+    b.insert(4, "e");
+    b.insert(5, "f");
+
+    a.append(&mut b);
+
+    assert_eq!(a.len(), 5);
+    assert_eq!(b.len(), 0);
+    // Capacity shouldn't change for possible reuse
+    assert!(b.capacity() >= 4);
+
+    assert_eq!(a[1], "a");
+    assert_eq!(a[2], "b");
+    assert_eq!(a[3], "d");
+    assert_eq!(a[4], "e");
+    assert_eq!(a[5], "f");
+}
+
+#[test]
+fn test_split_off() {
+    // Split within the key range
+    let mut a = VecMap::new();
+    a.insert(1, "a");
+    a.insert(2, "b");
+    a.insert(3, "c");
+    a.insert(4, "d");
+
+    let b = a.split_off(3);
+
+    assert_eq!(a.len(), 2);
+    assert_eq!(b.len(), 2);
+
+    assert_eq!(a[1], "a");
+    assert_eq!(a[2], "b");
+
+    assert_eq!(b[3], "c");
+    assert_eq!(b[4], "d");
+
+    // Split at 0
+    a.clear();
+    a.insert(1, "a");
+    a.insert(2, "b");
+    a.insert(3, "c");
+    a.insert(4, "d");
+
+    let b = a.split_off(0);
+
+    assert_eq!(a.len(), 0);
+    assert_eq!(b.len(), 4);
+    assert_eq!(b[1], "a");
+    assert_eq!(b[2], "b");
+    assert_eq!(b[3], "c");
+    assert_eq!(b[4], "d");
+
+    // Split behind max_key
+    a.clear();
+    a.insert(1, "a");
+    a.insert(2, "b");
+    a.insert(3, "c");
+    a.insert(4, "d");
+
+    let b = a.split_off(5);
+
+    assert_eq!(a.len(), 4);
+    assert_eq!(b.len(), 0);
+    assert_eq!(a[1], "a");
+    assert_eq!(a[2], "b");
+    assert_eq!(a[3], "c");
+    assert_eq!(a[4], "d");
+}
+
+#[test]
+fn test_show() {
+    let mut map = VecMap::new();
+    let empty = VecMap::<i32>::new();
+
+    map.insert(1, 2);
+    map.insert(3, 4);
+
+    let map_str = format!("{:?}", map);
+    assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
+    assert_eq!(format!("{:?}", empty), "{}");
+}
+
+#[test]
+fn test_clone() {
+    let mut a = VecMap::new();
+
+    a.insert(1, 'x');
+    a.insert(4, 'y');
+    a.insert(6, 'z');
+
+    assert!(a.clone() == a);
+}
+
+#[test]
+fn test_eq() {
+    let mut a = VecMap::new();
+    let mut b = VecMap::new();
+
+    assert!(a == b);
+    assert!(a.insert(0, 5).is_none());
+    assert!(a != b);
+    assert!(b.insert(0, 4).is_none());
+    assert!(a != b);
+    assert!(a.insert(5, 19).is_none());
+    assert!(a != b);
+    assert!(!b.insert(0, 5).is_none());
+    assert!(a != b);
+    assert!(b.insert(5, 19).is_none());
+    assert!(a == b);
+
+    a = VecMap::new();
+    b = VecMap::with_capacity(1);
+    assert!(a == b);
+}
+
+#[test]
+fn test_lt() {
+    let mut a = VecMap::new();
+    let mut b = VecMap::new();
+
+    assert!(!(a < b) && !(b < a));
+    assert!(b.insert(2, 5).is_none());
+    assert!(a < b);
+    assert!(a.insert(2, 7).is_none());
+    assert!(!(a < b) && b < a);
+    assert!(b.insert(1, 0).is_none());
+    assert!(b < a);
+    assert!(a.insert(0, 6).is_none());
+    assert!(a < b);
+    assert!(a.insert(6, 2).is_none());
+    assert!(a < b && !(b < a));
+}
+
+#[test]
+fn test_ord() {
+    let mut a = VecMap::new();
+    let mut b = VecMap::new();
+
+    assert!(a <= b && a >= b);
+    assert!(a.insert(1, 1).is_none());
+    assert!(a > b && a >= b);
+    assert!(b < a && b <= a);
+    assert!(b.insert(2, 2).is_none());
+    assert!(b > a && b >= a);
+    assert!(a < b && a <= b);
+}
+
+#[test]
+fn test_hash() {
+    let mut x = VecMap::new();
+    let mut y = VecMap::new();
+
+    assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
+    x.insert(1, 'a');
+    x.insert(2, 'b');
+    x.insert(3, 'c');
+
+    y.insert(3, 'c');
+    y.insert(2, 'b');
+    y.insert(1, 'a');
+
+    assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
+
+    x.insert(1000, 'd');
+    x.remove(&1000);
+
+    assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
+}
+
+#[test]
+fn test_from_iter() {
+    let xs = vec![(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')];
+
+    let map: VecMap<_> = xs.iter().cloned().collect();
+
+    for &(k, v) in &xs {
+        assert_eq!(map.get(&k), Some(&v));
+    }
+}
+
+#[test]
+fn test_index() {
+    let mut map = VecMap::new();
+
+    map.insert(1, 2);
+    map.insert(2, 1);
+    map.insert(3, 4);
+
+    assert_eq!(map[3], 4);
+}
+
+#[test]
+#[should_panic]
+fn test_index_nonexistent() {
+    let mut map = VecMap::new();
+
+    map.insert(1, 2);
+    map.insert(2, 1);
+    map.insert(3, 4);
+
+    map[4];
+}
+
+#[test]
+fn test_entry(){
+    let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
+
+    let mut map: VecMap<_> = xs.iter().cloned().collect();
+
+    // Existing key (insert)
+    match map.entry(1) {
+        Vacant(_) => unreachable!(),
+        Occupied(mut view) => {
+            assert_eq!(view.get(), &10);
+            assert_eq!(view.insert(100), 10);
+        }
+    }
+    assert_eq!(map.get(&1).unwrap(), &100);
+    assert_eq!(map.len(), 6);
+
+
+    // Existing key (update)
+    match map.entry(2) {
+        Vacant(_) => unreachable!(),
+        Occupied(mut view) => {
+            let v = view.get_mut();
+            *v *= 10;
+        }
+    }
+    assert_eq!(map.get(&2).unwrap(), &200);
+    assert_eq!(map.len(), 6);
+
+    // Existing key (take)
+    match map.entry(3) {
+        Vacant(_) => unreachable!(),
+        Occupied(view) => {
+            assert_eq!(view.remove(), 30);
+        }
+    }
+    assert_eq!(map.get(&3), None);
+    assert_eq!(map.len(), 5);
+
+
+    // Inexistent key (insert)
+    match map.entry(10) {
+        Occupied(_) => unreachable!(),
+        Vacant(view) => {
+            assert_eq!(*view.insert(1000), 1000);
+        }
+    }
+    assert_eq!(map.get(&10).unwrap(), &1000);
+    assert_eq!(map.len(), 6);
+}
+
+mod bench {
+    use std::collections::VecMap;
+
+    map_insert_rand_bench!{insert_rand_100,    100,    VecMap}
+    map_insert_rand_bench!{insert_rand_10_000, 10_000, VecMap}
+
+    map_insert_seq_bench!{insert_seq_100,    100,    VecMap}
+    map_insert_seq_bench!{insert_seq_10_000, 10_000, VecMap}
+
+    map_find_rand_bench!{find_rand_100,    100,    VecMap}
+    map_find_rand_bench!{find_rand_10_000, 10_000, VecMap}
+
+    map_find_seq_bench!{find_seq_100,    100,    VecMap}
+    map_find_seq_bench!{find_seq_10_000, 10_000, VecMap}
+}
index 462b6771b4a9af77a50d635857475953a445f1e8..320fdd50b3510bd41df790ca167bb72857839f85 100644 (file)
@@ -55,7 +55,7 @@
 //! }
 //!
 //! // This function wants to log its parameter out prior to doing work with it.
-//! fn do_work<T: Debug + 'static>(value: &T) {
+//! fn do_work<T: Any + Debug>(value: &T) {
 //!     log(value);
 //!     // ...do some other work
 //! }
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use fmt;
+use marker::Send;
 use mem::transmute;
 use option::Option::{self, Some, None};
 use raw::TraitObject;
 use intrinsics;
-use marker::Sized;
+use marker::{Reflect, Sized};
 
 ///////////////////////////////////////////////////////////////////////////////
 // Any trait
 ///////////////////////////////////////////////////////////////////////////////
 
-/// The `Any` trait is implemented by all `'static` types, and can be used for
-/// dynamic typing
+/// A type to emulate dynamic typing. See the [module-level documentation][mod] for more details.
 ///
-/// Every type with no non-`'static` references implements `Any`, so `Any` can
-/// be used as a trait object to emulate the effects dynamic typing.
+/// Every type with no non-`'static` references implements `Any`.
+///
+/// [mod]: ../index.html
 #[stable(feature = "rust1", since = "1.0.0")]
-pub trait Any: 'static {
+pub trait Any: Reflect + 'static {
     /// Get the `TypeId` of `self`
     #[unstable(feature = "core",
                reason = "this method will likely be replaced by an associated static")]
     fn get_type_id(&self) -> TypeId;
 }
 
-impl<T: 'static> Any for T {
+impl<T> Any for T
+    where T: Reflect + 'static
+{
     fn get_type_id(&self) -> TypeId { TypeId::of::<T>() }
 }
 
@@ -102,11 +106,18 @@ impl<T: 'static> Any for T {
 // Extension methods for Any trait objects.
 ///////////////////////////////////////////////////////////////////////////////
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Debug for Any {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Any")
+    }
+}
+
 impl Any {
     /// Returns true if the boxed type is the same as `T`
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn is<T: 'static>(&self) -> bool {
+    pub fn is<T: Any>(&self) -> bool {
         // Get TypeId of the type this function is instantiated with
         let t = TypeId::of::<T>();
 
@@ -121,7 +132,7 @@ impl Any {
     /// `None` if it isn't.
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
+    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
         if self.is::<T>() {
             unsafe {
                 // Get the raw representation of the trait object
@@ -139,7 +150,7 @@ impl Any {
     /// `None` if it isn't.
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> {
+    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
         if self.is::<T>() {
             unsafe {
                 // Get the raw representation of the trait object
@@ -154,6 +165,30 @@ impl Any {
     }
 }
 
+impl Any+Send {
+    /// Forwards to the method defined on the type `Any`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is<T: Any>(&self) -> bool {
+        Any::is::<T>(self)
+    }
+
+    /// Forwards to the method defined on the type `Any`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
+        Any::downcast_ref::<T>(self)
+    }
+
+    /// Forwards to the method defined on the type `Any`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
+        Any::downcast_mut::<T>(self)
+    }
+}
+
+
 ///////////////////////////////////////////////////////////////////////////////
 // TypeID and its methods
 ///////////////////////////////////////////////////////////////////////////////
@@ -175,9 +210,8 @@ pub struct TypeId {
 impl TypeId {
     /// Returns the `TypeId` of the type this generic function has been
     /// instantiated with
-    #[unstable(feature = "core",
-               reason = "may grow a `Reflect` bound soon via marker traits")]
-    pub fn of<T: ?Sized + 'static>() -> TypeId {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn of<T: ?Sized + Any>() -> TypeId {
         TypeId {
             t: unsafe { intrinsics::type_id::<T>() },
         }
index afb5d95c9f8d79219b122a529749d35a35ceafab..91301ee558ca566315559f663a6948d11519f2ba 100644 (file)
 
 #![unstable(feature = "core")] // not yet reviewed
 
+#![doc(primitive = "array")]
+
 use clone::Clone;
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
+use convert::{AsRef, AsMut};
 use fmt;
 use hash::{Hash, self};
 use iter::IntoIterator;
-use marker::Copy;
-use ops::Deref;
+use marker::{Copy, Sized};
 use option::Option;
 use slice::{Iter, IterMut, SliceExt};
 
+/// Utility trait implemented only on arrays of fixed size
+///
+/// This trait can be used to implement other traits on fixed-size arrays
+/// without causing much metadata bloat.
+#[unstable(feature = "core")]
+pub trait FixedSizeArray<T> {
+    /// Converts the array to immutable slice
+    fn as_slice(&self) -> &[T];
+    /// Converts the array to mutable slice
+    fn as_mut_slice(&mut self) -> &mut [T];
+}
+
 // macro for implementing n-ary tuple functions and operations
 macro_rules! array_impls {
     ($($N:expr)+) => {
         $(
+            #[unstable(feature = "core")]
+            impl<T> FixedSizeArray<T> for [T; $N] {
+                #[inline]
+                fn as_slice(&self) -> &[T] {
+                    &self[..]
+                }
+                #[inline]
+                fn as_mut_slice(&mut self) -> &mut [T] {
+                    &mut self[..]
+                }
+            }
+
+            #[unstable(feature = "array_as_ref",
+                       reason = "should ideally be implemented for all fixed-sized arrays")]
+            impl<T> AsRef<[T]> for [T; $N] {
+                #[inline]
+                fn as_ref(&self) -> &[T] {
+                    &self[..]
+                }
+            }
+
+            #[unstable(feature = "array_as_ref",
+                       reason = "should ideally be implemented for all fixed-sized arrays")]
+            impl<T> AsMut<[T]> for [T; $N] {
+                #[inline]
+                fn as_mut(&mut self) -> &mut [T] {
+                    &mut self[..]
+                }
+            }
+
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<T:Copy> Clone for [T; $N] {
                 fn clone(&self) -> [T; $N] {
@@ -35,13 +79,6 @@ macro_rules! array_impls {
                 }
             }
 
-            #[cfg(stage0)]
-            impl<S: hash::Writer + hash::Hasher, T: Hash<S>> Hash<S> for [T; $N] {
-                fn hash(&self, state: &mut S) {
-                    Hash::hash(&self[..], state)
-                }
-            }
-            #[cfg(not(stage0))]
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<T: Hash> Hash for [T; $N] {
                 fn hash<H: hash::Hasher>(&self, state: &mut H) {
@@ -76,47 +113,13 @@ macro_rules! array_impls {
                 }
             }
 
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<A, B> PartialEq<[B; $N]> for [A; $N] where A: PartialEq<B> {
-                #[inline]
-                fn eq(&self, other: &[B; $N]) -> bool {
-                    &self[..] == &other[..]
-                }
-                #[inline]
-                fn ne(&self, other: &[B; $N]) -> bool {
-                    &self[..] != &other[..]
-                }
-            }
-
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<'a, A, B, Rhs> PartialEq<Rhs> for [A; $N] where
-                A: PartialEq<B>,
-                Rhs: Deref<Target=[B]>,
-            {
-                #[inline(always)]
-                fn eq(&self, other: &Rhs) -> bool {
-                    PartialEq::eq(&self[..], &**other)
-                }
-                #[inline(always)]
-                fn ne(&self, other: &Rhs) -> bool {
-                    PartialEq::ne(&self[..], &**other)
-                }
-            }
-
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<'a, A, B, Lhs> PartialEq<[B; $N]> for Lhs where
-                A: PartialEq<B>,
-                Lhs: Deref<Target=[A]>
-            {
-                #[inline(always)]
-                fn eq(&self, other: &[B; $N]) -> bool {
-                    PartialEq::eq(&**self, &other[..])
-                }
-                #[inline(always)]
-                fn ne(&self, other: &[B; $N]) -> bool {
-                    PartialEq::ne(&**self, &other[..])
-                }
-            }
+            // NOTE: some less important impls are omitted to reduce code bloat
+            __impl_slice_eq1! { [A; $N], [B; $N] }
+            __impl_slice_eq2! { [A; $N], [B] }
+            __impl_slice_eq2! { [A; $N], &'b [B] }
+            __impl_slice_eq2! { [A; $N], &'b mut [B] }
+            // __impl_slice_eq2! { [A; $N], &'b [B; $N] }
+            // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
 
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<T:Eq> Eq for [T; $N] { }
index 6afe5b2257d279736daa4db1799d48a679f3e53b..ed35e095492178479acf620e9acc579018dbb0a8 100644 (file)
@@ -15,7 +15,7 @@
 //! types.
 //!
 //! This module defines atomic versions of a select number of primitive
-//! types, including `AtomicBool`, `AtomicIsize`, `AtomicUsize`, and `AtomicOption`.
+//! types, including `AtomicBool`, `AtomicIsize`, and `AtomicUsize`.
 //! Atomic types present operations that, when used correctly, synchronize
 //! updates between threads.
 //!
@@ -122,7 +122,7 @@ unsafe impl<T> Sync for AtomicPtr<T> {}
 /// Rust's memory orderings are [the same as
 /// C++'s](http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync).
 #[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum Ordering {
     /// No ordering constraints, only atomic operations.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -161,7 +161,7 @@ pub const ATOMIC_USIZE_INIT: AtomicUsize =
         AtomicUsize { v: UnsafeCell { value: 0, } };
 
 // NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
-const UINT_TRUE: usize = -1;
+const UINT_TRUE: usize = !0;
 
 impl AtomicBool {
     /// Creates a new `AtomicBool`.
@@ -252,7 +252,8 @@ impl AtomicBool {
 
     /// Stores a value into the bool if the current value is the same as the expected value.
     ///
-    /// If the return value is equal to `old` then the value was updated.
+    /// The return value is always the previous value. If it is equal to `old`, then the value was
+    /// updated.
     ///
     /// `swap` also takes an `Ordering` argument which describes the memory ordering of this
     /// operation.
@@ -489,7 +490,8 @@ impl AtomicIsize {
 
     /// Stores a value into the isize if the current value is the same as the expected value.
     ///
-    /// If the return value is equal to `old` then the value was updated.
+    /// The return value is always the previous value. If it is equal to `old`, then the value was
+    /// updated.
     ///
     /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of
     /// this operation.
@@ -676,7 +678,8 @@ impl AtomicUsize {
 
     /// Stores a value into the usize if the current value is the same as the expected value.
     ///
-    /// If the return value is equal to `old` then the value was updated.
+    /// The return value is always the previous value. If it is equal to `old`, then the value was
+    /// updated.
     ///
     /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of
     /// this operation.
@@ -873,7 +876,8 @@ impl<T> AtomicPtr<T> {
 
     /// Stores a value into the pointer if the current value is the same as the expected value.
     ///
-    /// If the return value is equal to `old` then the value was updated.
+    /// The return value is always the previous value. If it is equal to `old`, then the value was
+    /// updated.
     ///
     /// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of
     /// this operation.
@@ -1058,142 +1062,3 @@ pub fn fence(order: Ordering) {
         }
     }
 }
-
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
-             reason = "renamed to AtomicIsize")]
-#[allow(missing_docs)]
-pub struct AtomicInt {
-    v: UnsafeCell<int>,
-}
-
-unsafe impl Sync for AtomicInt {}
-
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
-             reason = "renamed to AtomicUsize")]
-#[allow(missing_docs)]
-pub struct AtomicUint {
-    v: UnsafeCell<uint>,
-}
-
-unsafe impl Sync for AtomicUint {}
-
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
-             reason = "use ATOMIC_ISIZE_INIT instead")]
-#[allow(missing_docs, deprecated)]
-pub const ATOMIC_INT_INIT: AtomicInt =
-        AtomicInt { v: UnsafeCell { value: 0 } };
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
-             reason = "use ATOMIC_USIZE_INIT instead")]
-#[allow(missing_docs, deprecated)]
-pub const ATOMIC_UINT_INIT: AtomicUint =
-        AtomicUint { v: UnsafeCell { value: 0, } };
-
-#[allow(missing_docs, deprecated)]
-impl AtomicInt {
-    #[inline]
-    pub fn new(v: int) -> AtomicInt {
-        AtomicInt {v: UnsafeCell::new(v)}
-    }
-
-    #[inline]
-    pub fn load(&self, order: Ordering) -> int {
-        unsafe { atomic_load(self.v.get(), order) }
-    }
-
-    #[inline]
-    pub fn store(&self, val: int, order: Ordering) {
-        unsafe { atomic_store(self.v.get(), val, order); }
-    }
-
-    #[inline]
-    pub fn swap(&self, val: int, order: Ordering) -> int {
-        unsafe { atomic_swap(self.v.get(), val, order) }
-    }
-
-    #[inline]
-    pub fn compare_and_swap(&self, old: int, new: int, order: Ordering) -> int {
-        unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
-    }
-
-    #[inline]
-    pub fn fetch_add(&self, val: int, order: Ordering) -> int {
-        unsafe { atomic_add(self.v.get(), val, order) }
-    }
-
-    #[inline]
-    pub fn fetch_sub(&self, val: int, order: Ordering) -> int {
-        unsafe { atomic_sub(self.v.get(), val, order) }
-    }
-
-    #[inline]
-    pub fn fetch_and(&self, val: int, order: Ordering) -> int {
-        unsafe { atomic_and(self.v.get(), val, order) }
-    }
-
-    #[inline]
-    pub fn fetch_or(&self, val: int, order: Ordering) -> int {
-        unsafe { atomic_or(self.v.get(), val, order) }
-    }
-
-    #[inline]
-    pub fn fetch_xor(&self, val: int, order: Ordering) -> int {
-        unsafe { atomic_xor(self.v.get(), val, order) }
-    }
-}
-
-#[allow(missing_docs, deprecated)]
-impl AtomicUint {
-    #[inline]
-    pub fn new(v: uint) -> AtomicUint {
-        AtomicUint { v: UnsafeCell::new(v) }
-    }
-
-    #[inline]
-    pub fn load(&self, order: Ordering) -> uint {
-        unsafe { atomic_load(self.v.get(), order) }
-    }
-
-    #[inline]
-    pub fn store(&self, val: uint, order: Ordering) {
-        unsafe { atomic_store(self.v.get(), val, order); }
-    }
-
-    #[inline]
-    pub fn swap(&self, val: uint, order: Ordering) -> uint {
-        unsafe { atomic_swap(self.v.get(), val, order) }
-    }
-
-    #[inline]
-    pub fn compare_and_swap(&self, old: uint, new: uint, order: Ordering) -> uint {
-        unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
-    }
-
-    #[inline]
-    pub fn fetch_add(&self, val: uint, order: Ordering) -> uint {
-        unsafe { atomic_add(self.v.get(), val, order) }
-    }
-
-    #[inline]
-    pub fn fetch_sub(&self, val: uint, order: Ordering) -> uint {
-        unsafe { atomic_sub(self.v.get(), val, order) }
-    }
-
-    #[inline]
-    pub fn fetch_and(&self, val: uint, order: Ordering) -> uint {
-        unsafe { atomic_and(self.v.get(), val, order) }
-    }
-
-    #[inline]
-    pub fn fetch_or(&self, val: uint, order: Ordering) -> uint {
-        unsafe { atomic_or(self.v.get(), val, order) }
-    }
-
-    #[inline]
-    pub fn fetch_xor(&self, val: uint, order: Ordering) -> uint {
-        unsafe { atomic_xor(self.v.get(), val, order) }
-    }
-}
index eb138e6142b80e36e5c4217225ed301dcfcea2d1..76e09eedbdfa574a86f447041d47fed9099613d8 100644 (file)
 use clone::Clone;
 use cmp::PartialEq;
 use default::Default;
-use marker::{Copy, Send};
+use marker::{Copy, Send, Sync};
 use ops::{Deref, DerefMut, Drop};
 use option::Option;
 use option::Option::{None, Some};
@@ -168,6 +168,7 @@ impl<T:Copy> Cell<T> {
     /// let c = Cell::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub fn new(value: T) -> Cell<T> {
         Cell {
             value: UnsafeCell::new(value),
@@ -219,6 +220,7 @@ impl<T:Copy> Cell<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::cell::Cell;
     ///
     /// let c = Cell::new(5);
@@ -237,6 +239,7 @@ unsafe impl<T> Send for Cell<T> where T: Send {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T:Copy> Clone for Cell<T> {
+    #[inline]
     fn clone(&self) -> Cell<T> {
         Cell::new(self.get())
     }
@@ -245,6 +248,7 @@ impl<T:Copy> Clone for Cell<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T:Default + Copy> Default for Cell<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     fn default() -> Cell<T> {
         Cell::new(Default::default())
     }
@@ -252,6 +256,7 @@ impl<T:Default + Copy> Default for Cell<T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T:PartialEq + Copy> PartialEq for Cell<T> {
+    #[inline]
     fn eq(&self, other: &Cell<T>) -> bool {
         self.get() == other.get()
     }
@@ -282,7 +287,7 @@ pub enum BorrowState {
 // (will not outgrow its range since `usize` is the size of the address space)
 type BorrowFlag = usize;
 const UNUSED: BorrowFlag = 0;
-const WRITING: BorrowFlag = -1;
+const WRITING: BorrowFlag = !0;
 
 impl<T> RefCell<T> {
     /// Creates a new `RefCell` containing `value`.
@@ -295,6 +300,7 @@ impl<T> RefCell<T> {
     /// let c = RefCell::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub fn new(value: T) -> RefCell<T> {
         RefCell {
             value: UnsafeCell::new(value),
@@ -314,6 +320,7 @@ impl<T> RefCell<T> {
     /// let five = c.into_inner();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub fn into_inner(self) -> T {
         // Since this function takes `self` (the `RefCell`) by value, the
         // compiler statically verifies that it is not currently borrowed.
@@ -327,6 +334,7 @@ impl<T> RefCell<T> {
     /// The returned value can be dispatched on to determine if a call to
     /// `borrow` or `borrow_mut` would succeed.
     #[unstable(feature = "std_misc")]
+    #[inline]
     pub fn borrow_state(&self) -> BorrowState {
         match self.borrow.get() {
             WRITING => BorrowState::Writing,
@@ -335,22 +343,6 @@ impl<T> RefCell<T> {
         }
     }
 
-    /// Attempts to immutably borrow the wrapped value.
-    ///
-    /// The borrow lasts until the returned `Ref` exits scope. Multiple
-    /// immutable borrows can be taken out at the same time.
-    ///
-    /// Returns `None` if the value is currently mutably borrowed.
-    #[unstable(feature = "core", reason = "may be renamed or removed")]
-    #[deprecated(since = "1.0.0",
-                 reason = "dispatch on `cell.borrow_state()` instead")]
-    pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
-        match BorrowRef::new(&self.borrow) {
-            Some(b) => Some(Ref { _value: unsafe { &*self.value.get() }, _borrow: b }),
-            None => None,
-        }
-    }
-
     /// Immutably borrows the wrapped value.
     ///
     /// The borrow lasts until the returned `Ref` exits scope. Multiple
@@ -387,6 +379,7 @@ impl<T> RefCell<T> {
     /// assert!(result.is_err());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
         match BorrowRef::new(&self.borrow) {
             Some(b) => Ref {
@@ -397,22 +390,6 @@ impl<T> RefCell<T> {
         }
     }
 
-    /// Mutably borrows the wrapped value.
-    ///
-    /// The borrow lasts until the returned `RefMut` exits scope. The value
-    /// cannot be borrowed while this borrow is active.
-    ///
-    /// Returns `None` if the value is currently borrowed.
-    #[unstable(feature = "core", reason = "may be renamed or removed")]
-    #[deprecated(since = "1.0.0",
-                 reason = "dispatch on `cell.borrow_state()` instead")]
-    pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
-        match BorrowRefMut::new(&self.borrow) {
-            Some(b) => Some(RefMut { _value: unsafe { &mut *self.value.get() }, _borrow: b }),
-            None => None,
-        }
-    }
-
     /// Mutably borrows the wrapped value.
     ///
     /// The borrow lasts until the returned `RefMut` exits scope. The value
@@ -448,6 +425,7 @@ impl<T> RefCell<T> {
     /// assert!(result.is_err());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
         match BorrowRefMut::new(&self.borrow) {
             Some(b) => RefMut {
@@ -475,6 +453,7 @@ unsafe impl<T> Send for RefCell<T> where T: Send {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Clone> Clone for RefCell<T> {
+    #[inline]
     fn clone(&self) -> RefCell<T> {
         RefCell::new(self.borrow().clone())
     }
@@ -483,6 +462,7 @@ impl<T: Clone> Clone for RefCell<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T:Default> Default for RefCell<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     fn default() -> RefCell<T> {
         RefCell::new(Default::default())
     }
@@ -490,6 +470,7 @@ impl<T:Default> Default for RefCell<T> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: PartialEq> PartialEq for RefCell<T> {
+    #[inline]
     fn eq(&self, other: &RefCell<T>) -> bool {
         *self.borrow() == *other.borrow()
     }
@@ -500,6 +481,7 @@ struct BorrowRef<'b> {
 }
 
 impl<'b> BorrowRef<'b> {
+    #[inline]
     fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> {
         match borrow.get() {
             WRITING => None,
@@ -513,6 +495,7 @@ impl<'b> BorrowRef<'b> {
 
 #[unsafe_destructor]
 impl<'b> Drop for BorrowRef<'b> {
+    #[inline]
     fn drop(&mut self) {
         let borrow = self._borrow.get();
         debug_assert!(borrow != WRITING && borrow != UNUSED);
@@ -521,6 +504,7 @@ impl<'b> Drop for BorrowRef<'b> {
 }
 
 impl<'b> Clone for BorrowRef<'b> {
+    #[inline]
     fn clone(&self) -> BorrowRef<'b> {
         // Since this Ref exists, we know the borrow flag
         // is not set to WRITING.
@@ -561,6 +545,7 @@ impl<'b, T> Deref for Ref<'b, T> {
 /// use of `r.borrow().clone()` to clone the contents of a `RefCell`.
 #[unstable(feature = "core",
            reason = "likely to be moved to a method, pending language changes")]
+#[inline]
 pub fn clone_ref<'b, T:Clone>(orig: &Ref<'b, T>) -> Ref<'b, T> {
     Ref {
         _value: orig._value,
@@ -574,6 +559,7 @@ struct BorrowRefMut<'b> {
 
 #[unsafe_destructor]
 impl<'b> Drop for BorrowRefMut<'b> {
+    #[inline]
     fn drop(&mut self) {
         let borrow = self._borrow.get();
         debug_assert!(borrow == WRITING);
@@ -582,6 +568,7 @@ impl<'b> Drop for BorrowRefMut<'b> {
 }
 
 impl<'b> BorrowRefMut<'b> {
+    #[inline]
     fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
         match borrow.get() {
             UNUSED => {
@@ -631,9 +618,6 @@ impl<'b, T> DerefMut for RefMut<'b, T> {
 ///
 /// Types like `Cell<T>` and `RefCell<T>` use this type to wrap their internal data.
 ///
-/// `UnsafeCell<T>` doesn't opt-out from any marker traits, instead, types with an `UnsafeCell<T>`
-/// interior are expected to opt-out from those traits themselves.
-///
 /// # Examples
 ///
 /// ```
@@ -660,6 +644,8 @@ pub struct UnsafeCell<T> {
     pub value: T,
 }
 
+impl<T> !Sync for UnsafeCell<T> {}
+
 impl<T> UnsafeCell<T> {
     /// Construct a new instance of `UnsafeCell` which will wrap the specified
     /// value.
@@ -675,6 +661,7 @@ impl<T> UnsafeCell<T> {
     /// let uc = UnsafeCell::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
     pub fn new(value: T) -> UnsafeCell<T> {
         UnsafeCell { value: value }
     }
@@ -692,7 +679,11 @@ impl<T> UnsafeCell<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get(&self) -> *mut T { &self.value as *const T as *mut T }
+    pub fn get(&self) -> *mut T {
+        // FIXME(#23542) Replace with type ascription.
+        #![allow(trivial_casts)]
+        &self.value as *const T as *mut T
+    }
 
     /// Unwraps the value
     ///
index c45fac1bc9490be142f1b9a0e5ac1dc277124628..010415b364aa04a75506c86f7d6d82a83e3d0602 100644 (file)
@@ -22,13 +22,13 @@ use option::Option;
 use slice::SliceExt;
 
 // UTF-8 ranges and tags for encoding characters
-static TAG_CONT: u8    = 0b1000_0000u8;
-static TAG_TWO_B: u8   = 0b1100_0000u8;
-static TAG_THREE_B: u8 = 0b1110_0000u8;
-static TAG_FOUR_B: u8  = 0b1111_0000u8;
-static MAX_ONE_B: u32   =     0x80u32;
-static MAX_TWO_B: u32   =    0x800u32;
-static MAX_THREE_B: u32 =  0x10000u32;
+const TAG_CONT: u8    = 0b1000_0000;
+const TAG_TWO_B: u8   = 0b1100_0000;
+const TAG_THREE_B: u8 = 0b1110_0000;
+const TAG_FOUR_B: u8  = 0b1111_0000;
+const MAX_ONE_B: u32   =     0x80;
+const MAX_TWO_B: u32   =    0x800;
+const MAX_THREE_B: u32 =  0x10000;
 
 /*
     Lu  Uppercase_Letter        an uppercase letter
@@ -118,7 +118,7 @@ pub fn from_u32(i: u32) -> Option<char> {
 /// assert_eq!(c, Some('4'));
 /// ```
 #[inline]
-#[unstable(feature = "core", reason = "pending integer conventions")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn from_digit(num: u32, radix: u32) -> Option<char> {
     if radix > 36 {
         panic!("from_digit: radix is too high (maximum 36)");
@@ -136,230 +136,25 @@ pub fn from_digit(num: u32, radix: u32) -> Option<char> {
     }
 }
 
-/// Basic `char` manipulations.
-#[stable(feature = "rust1", since = "1.0.0")]
+// NB: the stabilization and documentation for this trait is in
+// unicode/char.rs, not here
+#[allow(missing_docs)] // docs in libunicode/u_char.rs
 pub trait CharExt {
-    /// Checks if a `char` parses as a numeric digit in the given radix.
-    ///
-    /// Compared to `is_numeric()`, this function only recognizes the characters
-    /// `0-9`, `a-z` and `A-Z`.
-    ///
-    /// # Return value
-    ///
-    /// Returns `true` if `c` is a valid digit under `radix`, and `false`
-    /// otherwise.
-    ///
-    /// # Panics
-    ///
-    /// Panics if given a radix > 36.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let c = '1';
-    ///
-    /// assert!(c.is_digit(10));
-    ///
-    /// assert!('f'.is_digit(16));
-    /// ```
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
     fn is_digit(self, radix: u32) -> bool;
-
-    /// Converts a character to the corresponding digit.
-    ///
-    /// # Return value
-    ///
-    /// If `c` is between '0' and '9', the corresponding value between 0 and
-    /// 9. If `c` is 'a' or 'A', 10. If `c` is 'b' or 'B', 11, etc. Returns
-    /// none if the character does not refer to a digit in the given radix.
-    ///
-    /// # Panics
-    ///
-    /// Panics if given a radix outside the range [0..36].
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let c = '1';
-    ///
-    /// assert_eq!(c.to_digit(10), Some(1));
-    ///
-    /// assert_eq!('f'.to_digit(16), Some(15));
-    /// ```
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
     fn to_digit(self, radix: u32) -> Option<u32>;
-
-    /// Returns an iterator that yields the hexadecimal Unicode escape of a character, as `char`s.
-    ///
-    /// All characters are escaped with Rust syntax of the form `\\u{NNNN}` where `NNNN` is the
-    /// shortest hexadecimal representation of the code point.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// for i in '❤'.escape_unicode() {
-    ///     println!("{}", i);
-    /// }
-    /// ```
-    ///
-    /// This prints:
-    ///
-    /// ```text
-    /// \
-    /// u
-    /// {
-    /// 2
-    /// 7
-    /// 6
-    /// 4
-    /// }
-    /// ```
-    ///
-    /// Collecting into a `String`:
-    ///
-    /// ```
-    /// let heart: String = '❤'.escape_unicode().collect();
-    ///
-    /// assert_eq!(heart, r"\u{2764}");
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn escape_unicode(self) -> EscapeUnicode;
-
-    /// Returns an iterator that yields the 'default' ASCII and
-    /// C++11-like literal escape of a character, as `char`s.
-    ///
-    /// The default is chosen with a bias toward producing literals that are
-    /// legal in a variety of languages, including C++11 and similar C-family
-    /// languages. The exact rules are:
-    ///
-    /// * Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
-    /// * Single-quote, double-quote and backslash chars are backslash-
-    ///   escaped.
-    /// * Any other chars in the range [0x20,0x7e] are not escaped.
-    /// * Any other chars are given hex Unicode escapes; see `escape_unicode`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// for i in '"'.escape_default() {
-    ///     println!("{}", i);
-    /// }
-    /// ```
-    ///
-    /// This prints:
-    ///
-    /// ```text
-    /// \
-    /// "
-    /// ```
-    ///
-    /// Collecting into a `String`:
-    ///
-    /// ```
-    /// let quote: String = '"'.escape_default().collect();
-    ///
-    /// assert_eq!(quote, "\\\"");
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn escape_default(self) -> EscapeDefault;
-
-    /// Returns the number of bytes this character would need if encoded in UTF-8.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let n = 'ß'.len_utf8();
-    ///
-    /// assert_eq!(n, 2);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn len_utf8(self) -> usize;
-
-    /// Returns the number of bytes this character would need if encoded in UTF-16.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let n = 'ß'.len_utf16();
-    ///
-    /// assert_eq!(n, 1);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn len_utf16(self) -> usize;
-
-    /// Encodes this character as UTF-8 into the provided byte buffer, and then returns the number
-    /// of bytes written.
-    ///
-    /// If the buffer is not large enough, nothing will be written into it and a `None` will be
-    /// returned.
-    ///
-    /// # Examples
-    ///
-    /// In both of these examples, 'ß' takes two bytes to encode.
-    ///
-    /// ```
-    /// let mut b = [0; 2];
-    ///
-    /// let result = 'ß'.encode_utf8(&mut b);
-    ///
-    /// assert_eq!(result, Some(2));
-    /// ```
-    ///
-    /// A buffer that's too small:
-    ///
-    /// ```
-    /// let mut b = [0; 1];
-    ///
-    /// let result = 'ß'.encode_utf8(&mut b);
-    ///
-    /// assert_eq!(result, None);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn encode_utf8(self, dst: &mut [u8]) -> Option<usize>;
-
-    /// Encodes this character as UTF-16 into the provided `u16` buffer, and then returns the
-    /// number of `u16`s written.
-    ///
-    /// If the buffer is not large enough, nothing will be written into it and a `None` will be
-    /// returned.
-    ///
-    /// # Examples
-    ///
-    /// In both of these examples, 'ß' takes one byte to encode.
-    ///
-    /// ```
-    /// let mut b = [0; 1];
-    ///
-    /// let result = 'ß'.encode_utf16(&mut b);
-    ///
-    /// assert_eq!(result, Some(1));
-    /// ```
-    ///
-    /// A buffer that's too small:
-    ///
-    /// ```
-    /// let mut b = [0; 0];
-    ///
-    /// let result = 'ß'.encode_utf8(&mut b);
-    ///
-    /// assert_eq!(result, None);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn encode_utf16(self, dst: &mut [u16]) -> Option<usize>;
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
 impl CharExt for char {
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
     fn is_digit(self, radix: u32) -> bool {
         self.to_digit(radix).is_some()
     }
 
-    #[unstable(feature = "core",
-               reason = "pending integer conventions")]
     fn to_digit(self, radix: u32) -> Option<u32> {
         if radix > 36 {
             panic!("to_digit: radix is too high (maximum 36)");
@@ -374,12 +169,10 @@ impl CharExt for char {
         else { None }
     }
 
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn escape_unicode(self) -> EscapeUnicode {
         EscapeUnicode { c: self, state: EscapeUnicodeState::Backslash }
     }
 
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn escape_default(self) -> EscapeDefault {
         let init_state = match self {
             '\t' => EscapeDefaultState::Backslash('t'),
@@ -395,34 +188,31 @@ impl CharExt for char {
     }
 
     #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn len_utf8(self) -> usize {
         let code = self as u32;
-        match () {
-            _ if code < MAX_ONE_B   => 1,
-            _ if code < MAX_TWO_B   => 2,
-            _ if code < MAX_THREE_B => 3,
-            _  => 4,
+        if code < MAX_ONE_B {
+            1
+        } else if code < MAX_TWO_B {
+            2
+        } else if code < MAX_THREE_B {
+            3
+        } else {
+            4
         }
     }
 
     #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn len_utf16(self) -> usize {
         let ch = self as u32;
-        if (ch & 0xFFFF_u32) == ch { 1 } else { 2 }
+        if (ch & 0xFFFF) == ch { 1 } else { 2 }
     }
 
     #[inline]
-    #[unstable(feature = "core",
-               reason = "pending decision about Iterator/Writer/Reader")]
     fn encode_utf8(self, dst: &mut [u8]) -> Option<usize> {
         encode_utf8_raw(self as u32, dst)
     }
 
     #[inline]
-    #[unstable(feature = "core",
-               reason = "pending decision about Iterator/Writer/Reader")]
     fn encode_utf16(self, dst: &mut [u16]) -> Option<usize> {
         encode_utf16_raw(self as u32, dst)
     }
@@ -434,26 +224,25 @@ impl CharExt for char {
 /// If the buffer is not large enough, nothing will be written into it
 /// and a `None` will be returned.
 #[inline]
-#[unstable(feature = "core")]
 pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> Option<usize> {
     // Marked #[inline] to allow llvm optimizing it away
     if code < MAX_ONE_B && dst.len() >= 1 {
         dst[0] = code as u8;
         Some(1)
     } else if code < MAX_TWO_B && dst.len() >= 2 {
-        dst[0] = (code >> 6 & 0x1F_u32) as u8 | TAG_TWO_B;
-        dst[1] = (code & 0x3F_u32) as u8 | TAG_CONT;
+        dst[0] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
+        dst[1] = (code & 0x3F) as u8 | TAG_CONT;
         Some(2)
     } else if code < MAX_THREE_B && dst.len() >= 3  {
-        dst[0] = (code >> 12 & 0x0F_u32) as u8 | TAG_THREE_B;
-        dst[1] = (code >>  6 & 0x3F_u32) as u8 | TAG_CONT;
-        dst[2] = (code & 0x3F_u32) as u8 | TAG_CONT;
+        dst[0] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
+        dst[1] = (code >>  6 & 0x3F) as u8 | TAG_CONT;
+        dst[2] = (code & 0x3F) as u8 | TAG_CONT;
         Some(3)
     } else if dst.len() >= 4 {
-        dst[0] = (code >> 18 & 0x07_u32) as u8 | TAG_FOUR_B;
-        dst[1] = (code >> 12 & 0x3F_u32) as u8 | TAG_CONT;
-        dst[2] = (code >>  6 & 0x3F_u32) as u8 | TAG_CONT;
-        dst[3] = (code & 0x3F_u32) as u8 | TAG_CONT;
+        dst[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
+        dst[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT;
+        dst[2] = (code >>  6 & 0x3F) as u8 | TAG_CONT;
+        dst[3] = (code & 0x3F) as u8 | TAG_CONT;
         Some(4)
     } else {
         None
@@ -466,18 +255,17 @@ pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> Option<usize> {
 /// If the buffer is not large enough, nothing will be written into it
 /// and a `None` will be returned.
 #[inline]
-#[unstable(feature = "core")]
 pub fn encode_utf16_raw(mut ch: u32, dst: &mut [u16]) -> Option<usize> {
     // Marked #[inline] to allow llvm optimizing it away
-    if (ch & 0xFFFF_u32) == ch  && dst.len() >= 1 {
+    if (ch & 0xFFFF) == ch  && dst.len() >= 1 {
         // The BMP falls through (assuming non-surrogate, as it should)
         dst[0] = ch as u16;
         Some(1)
     } else if dst.len() >= 2 {
         // Supplementary planes break into surrogates.
-        ch -= 0x1_0000_u32;
-        dst[0] = 0xD800_u16 | ((ch >> 10) as u16);
-        dst[1] = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16);
+        ch -= 0x1_0000;
+        dst[0] = 0xD800 | ((ch >> 10) as u16);
+        dst[1] = 0xDC00 | ((ch as u16) & 0x3FF);
         Some(2)
     } else {
         None
@@ -494,7 +282,6 @@ pub struct EscapeUnicode {
 }
 
 #[derive(Clone)]
-#[unstable(feature = "core")]
 enum EscapeUnicodeState {
     Backslash,
     Type,
@@ -556,7 +343,6 @@ pub struct EscapeDefault {
 }
 
 #[derive(Clone)]
-#[unstable(feature = "core")]
 enum EscapeDefaultState {
     Backslash(char),
     Char(char),
index 058eff121e63300daef084435917f9b6131fb130..85e5bde48598eee8bde8ee706fc365e60f19104c 100644 (file)
@@ -27,6 +27,14 @@ use marker::Sized;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Clone : Sized {
     /// Returns a copy of the value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let hello = "Hello"; // &str implements Clone
+    ///
+    /// assert_eq!("Hello", hello.clone());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn clone(&self) -> Self;
 
index b37bad5f7546c21094828cf36e6c54e70593d210..efe1179621de5efde5843896c2aabea9faba2e99 100644 (file)
@@ -19,8 +19,7 @@
 //! could do the following:
 //!
 //! ```
-//! use core::num::SignedInt;
-//!
+//! # #![feature(core)]
 //! struct FuzzyNum {
 //!     num: i32,
 //! }
@@ -65,7 +64,6 @@ use option::Option::{self, Some, None};
 /// inverse of `ne`; that is, `!(a == b)` if and only if `a != b`.
 #[lang="eq"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[old_orphan_check]
 pub trait PartialEq<Rhs: ?Sized = Self> {
     /// This method tests for `self` and `other` values to be equal, and is used by `==`.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -361,6 +359,8 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
 
 /// Compare and return the minimum of two values.
 ///
+/// Returns the first argument if the comparison determines them to be equal.
+///
 /// # Examples
 ///
 /// ```
@@ -372,11 +372,13 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn min<T: Ord>(v1: T, v2: T) -> T {
-    if v1 < v2 { v1 } else { v2 }
+    if v1 <= v2 { v1 } else { v2 }
 }
 
 /// Compare and return the maximum of two values.
 ///
+/// Returns the second argument if the comparison determines them to be equal.
+///
 /// # Examples
 ///
 /// ```
@@ -388,7 +390,7 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn max<T: Ord>(v1: T, v2: T) -> T {
-    if v1 > v2 { v1 } else { v2 }
+    if v2 >= v1 { v2 } else { v1 }
 }
 
 /// Compare and return the minimum of two values if there is one.
@@ -398,6 +400,7 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 /// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::cmp;
 ///
 /// assert_eq!(Some(1), cmp::partial_min(1, 2));
@@ -407,6 +410,7 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 /// When comparison is impossible:
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::cmp;
 ///
 /// let result = cmp::partial_min(std::f64::NAN, 1.0);
@@ -424,11 +428,12 @@ pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
 
 /// Compare and return the maximum of two values if there is one.
 ///
-/// Returns the first argument if the comparison determines them to be equal.
+/// Returns the second argument if the comparison determines them to be equal.
 ///
 /// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::cmp;
 ///
 /// assert_eq!(Some(2), cmp::partial_max(1, 2));
@@ -438,6 +443,7 @@ pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
 /// When comparison is impossible:
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::cmp;
 ///
 /// let result = cmp::partial_max(std::f64::NAN, 1.0);
@@ -447,8 +453,8 @@ pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
 #[unstable(feature = "core")]
 pub fn partial_max<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
     match v1.partial_cmp(&v2) {
-        Some(Less) => Some(v2),
-        Some(Equal) | Some(Greater) => Some(v1),
+        Some(Equal) | Some(Less) => Some(v2),
+        Some(Greater) => Some(v1),
         None => None
     }
 }
diff --git a/src/libcore/cmp_macros.rs b/src/libcore/cmp_macros.rs
new file mode 100644 (file)
index 0000000..95dab3d
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2015 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.
+
+// Utility macros for implementing PartialEq on slice-like types
+
+#![doc(hidden)]
+
+#[macro_export]
+macro_rules! __impl_slice_eq1 {
+    ($Lhs: ty, $Rhs: ty) => {
+        __impl_slice_eq1! { $Lhs, $Rhs, Sized }
+    };
+    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
+            #[inline]
+            fn eq(&self, other: &$Rhs) -> bool { &self[..] == &other[..] }
+            #[inline]
+            fn ne(&self, other: &$Rhs) -> bool { &self[..] != &other[..] }
+        }
+    }
+}
+
+#[macro_export]
+macro_rules! __impl_slice_eq2 {
+    ($Lhs: ty, $Rhs: ty) => {
+        __impl_slice_eq2! { $Lhs, $Rhs, Sized }
+    };
+    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
+        __impl_slice_eq1!($Lhs, $Rhs, $Bound);
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq<A> {
+            #[inline]
+            fn eq(&self, other: &$Lhs) -> bool { &self[..] == &other[..] }
+            #[inline]
+            fn ne(&self, other: &$Lhs) -> bool { &self[..] != &other[..] }
+        }
+    }
+}
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
new file mode 100644 (file)
index 0000000..4a99f1a
--- /dev/null
@@ -0,0 +1,135 @@
+// 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.
+
+//! Traits for conversions between types.
+//!
+//! The traits in this module provide a general way to talk about
+//! conversions from one type to another. They follow the standard
+//! Rust conventions of `as`/`to`/`into`/`from`.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use marker::Sized;
+
+/// A cheap, reference-to-reference conversion.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait AsRef<T: ?Sized> {
+    /// Perform the conversion.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn as_ref(&self) -> &T;
+}
+
+/// A cheap, mutable reference-to-mutable reference conversion.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait AsMut<T: ?Sized> {
+    /// Perform the conversion.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn as_mut(&mut self) -> &mut T;
+}
+
+/// A conversion that consumes `self`, which may or may not be
+/// expensive.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Into<T>: Sized {
+    /// Perform the conversion.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn into(self) -> T;
+}
+
+/// Construct `Self` via a conversion.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait From<T> {
+    /// Perform the conversion.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn from(T) -> Self;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// GENERIC IMPLS
+////////////////////////////////////////////////////////////////////////////////
+
+// As lifts over &
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U> {
+    fn as_ref(&self) -> &U {
+        <T as AsRef<U>>::as_ref(*self)
+    }
+}
+
+// As lifts over &mut
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> {
+    fn as_ref(&self) -> &U {
+        <T as AsRef<U>>::as_ref(*self)
+    }
+}
+
+// FIXME (#23442): replace the above impls for &/&mut with the following more general one:
+// // As lifts over Deref
+// impl<D: ?Sized + Deref, U: ?Sized> AsRef<U> for D where D::Target: AsRef<U> {
+//     fn as_ref(&self) -> &U {
+//         self.deref().as_ref()
+//     }
+// }
+
+// AsMut lifts over &mut
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> {
+    fn as_mut(&mut self) -> &mut U {
+        (*self).as_mut()
+    }
+}
+
+// FIXME (#23442): replace the above impl for &mut with the following more general one:
+// // AsMut lifts over DerefMut
+// impl<D: ?Sized + Deref, U: ?Sized> AsMut<U> for D where D::Target: AsMut<U> {
+//     fn as_mut(&mut self) -> &mut U {
+//         self.deref_mut().as_mut()
+//     }
+// }
+
+// From implies Into
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T, U> Into<U> for T where U: From<T> {
+    fn into(self) -> U {
+        U::from(self)
+    }
+}
+
+// From (and thus Into) is reflexive
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> From<T> for T {
+    fn from(t: T) -> T { t }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CONCRETE IMPLS
+////////////////////////////////////////////////////////////////////////////////
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> AsRef<[T]> for [T] {
+    fn as_ref(&self) -> &[T] {
+        self
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> AsMut<[T]> for [T] {
+    fn as_mut(&mut self) -> &mut [T] {
+        self
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<str> for str {
+    fn as_ref(&self) -> &str {
+        self
+    }
+}
index 7f46d9cbe5021d3da0308e397e8c3418ba8a82c5..910cf805f39985b9bc809a7ad0b2dcdb186bf753 100644 (file)
@@ -164,4 +164,3 @@ default_impl! { i64, 0 }
 
 default_impl! { f32, 0.0f32 }
 default_impl! { f64, 0.0f64 }
-
diff --git a/src/libcore/error.rs b/src/libcore/error.rs
deleted file mode 100644 (file)
index 161f6c7..0000000
+++ /dev/null
@@ -1,112 +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.
-
-//! Traits for working with Errors.
-//!
-//! # The `Error` trait
-//!
-//! `Error` is a trait representing the basic expectations for error values,
-//! i.e. values of type `E` in `Result<T, E>`. At a minimum, errors must provide
-//! a description, but they may optionally provide additional detail (via
-//! `Display`) and cause chain information:
-//!
-//! ```
-//! use std::fmt::Display;
-//!
-//! trait Error: Display {
-//!     fn description(&self) -> &str;
-//!
-//!     fn cause(&self) -> Option<&Error> { None }
-//! }
-//! ```
-//!
-//! The `cause` method is generally used when errors cross "abstraction
-//! boundaries", i.e.  when a one module must report an error that is "caused"
-//! by an error from a lower-level module. This setup makes it possible for the
-//! high-level module to provide its own errors that do not commit to any
-//! particular implementation, but also reveal some of its implementation for
-//! debugging via `cause` chains.
-//!
-//! # The `FromError` trait
-//!
-//! `FromError` is a simple trait that expresses conversions between different
-//! error types. To provide maximum flexibility, it does not require either of
-//! the types to actually implement the `Error` trait, although this will be the
-//! common case.
-//!
-//! The main use of this trait is in the `try!` macro, which uses it to
-//! automatically convert a given error to the error specified in a function's
-//! return type.
-//!
-//! For example,
-//!
-//! ```
-//! use std::error::FromError;
-//! use std::old_io::{File, IoError};
-//! use std::os::{MemoryMap, MapError};
-//! use std::old_path::Path;
-//!
-//! enum MyError {
-//!     Io(IoError),
-//!     Map(MapError)
-//! }
-//!
-//! impl FromError<IoError> for MyError {
-//!     fn from_error(err: IoError) -> MyError {
-//!         MyError::Io(err)
-//!     }
-//! }
-//!
-//! impl FromError<MapError> for MyError {
-//!     fn from_error(err: MapError) -> MyError {
-//!         MyError::Map(err)
-//!     }
-//! }
-//!
-//! #[allow(unused_variables)]
-//! fn open_and_map() -> Result<(), MyError> {
-//!     let f = try!(File::open(&Path::new("foo.txt")));
-//!     let m = try!(MemoryMap::new(0, &[]));
-//!     // do something interesting here...
-//!     Ok(())
-//! }
-//! ```
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use prelude::*;
-use fmt::Display;
-
-/// Base functionality for all errors in Rust.
-#[unstable(feature = "core",
-           reason = "the exact API of this trait may change")]
-pub trait Error: Display {
-    /// A short description of the error; usually a static string.
-    fn description(&self) -> &str;
-
-    /// The lower-level cause of this error, if any.
-    fn cause(&self) -> Option<&Error> { None }
-}
-
-/// A trait for types that can be converted from a given error type `E`.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait FromError<E> {
-    /// Perform the conversion.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn from_error(err: E) -> Self;
-}
-
-// Any type is convertable from itself
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<E> FromError<E> for E {
-    fn from_error(err: E) -> E {
-        err
-    }
-}
diff --git a/src/libcore/finally.rs b/src/libcore/finally.rs
deleted file mode 100644 (file)
index 562a597..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2013 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.
-
-//! The Finally trait provides a method, `finally` on
-//! stack closures that emulates Java-style try/finally blocks.
-//!
-//! Using the `finally` method is sometimes convenient, but the type rules
-//! prohibit any shared, mutable state between the "try" case and the
-//! "finally" case. For advanced cases, the `try_finally` function can
-//! also be used. See that function for more details.
-//!
-//! # Example
-//!
-//! ```
-//! # #![feature(unboxed_closures)]
-//!
-//! use std::finally::Finally;
-//!
-//! (|| {
-//!     // ...
-//! }).finally(|| {
-//!     // this code is always run
-//! })
-//! ```
-
-#![unstable(feature = "core")]
-#![deprecated(since = "1.0.0",
-              reason = "It is unclear if this module is more robust than implementing \
-                        Drop on a custom type, and this module is being removed with no \
-                        replacement. Use a custom Drop implementation to regain existing \
-                        functionality.")]
-#![allow(deprecated)]
-
-use ops::{Drop, FnMut, FnOnce};
-
-/// A trait for executing a destructor unconditionally after a block of code,
-/// regardless of whether the blocked fails.
-pub trait Finally<T> {
-    /// Executes this object, unconditionally running `dtor` after this block of
-    /// code has run.
-    fn finally<F>(&mut self, dtor: F) -> T where F: FnMut();
-}
-
-impl<T, F> Finally<T> for F where F: FnMut() -> T {
-    fn finally<G>(&mut self, mut dtor: G) -> T where G: FnMut() {
-        try_finally(&mut (), self, |_, f| (*f)(), |_| dtor())
-    }
-}
-
-/// The most general form of the `finally` functions. The function
-/// `try_fn` will be invoked first; whether or not it panics, the
-/// function `finally_fn` will be invoked next. The two parameters
-/// `mutate` and `drop` are used to thread state through the two
-/// closures. `mutate` is used for any shared, mutable state that both
-/// closures require access to; `drop` is used for any state that the
-/// `try_fn` requires ownership of.
-///
-/// **WARNING:** While shared, mutable state between the try and finally
-/// function is often necessary, one must be very careful; the `try`
-/// function could have panicked at any point, so the values of the shared
-/// state may be inconsistent.
-///
-/// # Example
-///
-/// ```
-/// use std::finally::try_finally;
-///
-/// struct State<'a> { buffer: &'a mut [u8], len: usize }
-/// # let mut buf = [];
-/// let mut state = State { buffer: &mut buf, len: 0 };
-/// try_finally(
-///     &mut state, (),
-///     |state, ()| {
-///         // use state.buffer, state.len
-///     },
-///     |state| {
-///         // use state.buffer, state.len to cleanup
-///     })
-/// ```
-pub fn try_finally<T, U, R, F, G>(mutate: &mut T, drop: U, try_fn: F, finally_fn: G) -> R where
-    F: FnOnce(&mut T, U) -> R,
-    G: FnMut(&mut T),
-{
-    let f = Finallyalizer {
-        mutate: mutate,
-        dtor: finally_fn,
-    };
-    try_fn(&mut *f.mutate, drop)
-}
-
-struct Finallyalizer<'a, A:'a, F> where F: FnMut(&mut A) {
-    mutate: &'a mut A,
-    dtor: F,
-}
-
-#[unsafe_destructor]
-impl<'a, A, F> Drop for Finallyalizer<'a, A, F> where F: FnMut(&mut A) {
-    #[inline]
-    fn drop(&mut self) {
-        (self.dtor)(self.mutate);
-    }
-}
-
diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs
new file mode 100644 (file)
index 0000000..f61a7f2
--- /dev/null
@@ -0,0 +1,333 @@
+// Copyright 2015 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 prelude::*;
+use fmt::{self, Write, FlagV1};
+
+struct PadAdapter<'a, 'b: 'a> {
+    fmt: &'a mut fmt::Formatter<'b>,
+    on_newline: bool,
+}
+
+impl<'a, 'b: 'a> PadAdapter<'a, 'b> {
+    fn new(fmt: &'a mut fmt::Formatter<'b>) -> PadAdapter<'a, 'b> {
+        PadAdapter {
+            fmt: fmt,
+            on_newline: false,
+        }
+    }
+}
+
+impl<'a, 'b: 'a> fmt::Write for PadAdapter<'a, 'b> {
+    fn write_str(&mut self, mut s: &str) -> fmt::Result {
+        while !s.is_empty() {
+            if self.on_newline {
+                try!(self.fmt.write_str("    "));
+            }
+
+            let split = match s.find('\n') {
+                Some(pos) => {
+                    self.on_newline = true;
+                    pos + 1
+                }
+                None => {
+                    self.on_newline = false;
+                    s.len()
+                }
+            };
+            try!(self.fmt.write_str(&s[..split]));
+            s = &s[split..];
+        }
+
+        Ok(())
+    }
+}
+
+/// A struct to help with `fmt::Debug` implementations.
+///
+/// Constructed by the `Formatter::debug_struct` method.
+#[must_use]
+pub struct DebugStruct<'a, 'b: 'a> {
+    fmt: &'a mut fmt::Formatter<'b>,
+    result: fmt::Result,
+    has_fields: bool,
+}
+
+pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str)
+                                -> DebugStruct<'a, 'b> {
+    let result = fmt.write_str(name);
+    DebugStruct {
+        fmt: fmt,
+        result: result,
+        has_fields: false,
+    }
+}
+
+impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
+    /// Adds a new field to the generated struct output.
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    pub fn field(mut self, name: &str, value: &fmt::Debug) -> DebugStruct<'a, 'b> {
+        self.result = self.result.and_then(|_| {
+            let prefix = if self.has_fields {
+                ","
+            } else {
+                " {"
+            };
+
+            if self.is_pretty() {
+                let mut writer = PadAdapter::new(self.fmt);
+                fmt::write(&mut writer, format_args!("{}\n{}: {:#?}", prefix, name, value))
+            } else {
+                write!(self.fmt, "{} {}: {:?}", prefix, name, value)
+            }
+        });
+
+        self.has_fields = true;
+        self
+    }
+
+    /// Consumes the `DebugStruct`, finishing output and returning any error
+    /// encountered.
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    pub fn finish(mut self) -> fmt::Result {
+        if self.has_fields {
+            self.result = self.result.and_then(|_| {
+                if self.is_pretty() {
+                    self.fmt.write_str("\n}")
+                } else {
+                    self.fmt.write_str(" }")
+                }
+            });
+        }
+        self.result
+    }
+
+    fn is_pretty(&self) -> bool {
+        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
+    }
+}
+
+/// A struct to help with `fmt::Debug` implementations.
+///
+/// Constructed by the `Formatter::debug_tuple` method.
+#[must_use]
+pub struct DebugTuple<'a, 'b: 'a> {
+    fmt: &'a mut fmt::Formatter<'b>,
+    result: fmt::Result,
+    has_fields: bool,
+}
+
+pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> {
+    let result = fmt.write_str(name);
+    DebugTuple {
+        fmt: fmt,
+        result: result,
+        has_fields: false,
+    }
+}
+
+impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
+    /// Adds a new field to the generated tuple struct output.
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    pub fn field(mut self, value: &fmt::Debug) -> DebugTuple<'a, 'b> {
+        self.result = self.result.and_then(|_| {
+            let (prefix, space) = if self.has_fields {
+                (",", " ")
+            } else {
+                ("(", "")
+            };
+
+            if self.is_pretty() {
+                let mut writer = PadAdapter::new(self.fmt);
+                fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, value))
+            } else {
+                write!(self.fmt, "{}{}{:?}", prefix, space, value)
+            }
+        });
+
+        self.has_fields = true;
+        self
+    }
+
+    /// Consumes the `DebugTuple`, finishing output and returning any error
+    /// encountered.
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    pub fn finish(mut self) -> fmt::Result {
+        if self.has_fields {
+            self.result = self.result.and_then(|_| {
+                if self.is_pretty() {
+                    self.fmt.write_str("\n)")
+                } else {
+                    self.fmt.write_str(")")
+                }
+            });
+        }
+        self.result
+    }
+
+    fn is_pretty(&self) -> bool {
+        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
+    }
+}
+
+struct DebugInner<'a, 'b: 'a> {
+    fmt: &'a mut fmt::Formatter<'b>,
+    result: fmt::Result,
+    has_fields: bool,
+}
+
+impl<'a, 'b: 'a> DebugInner<'a, 'b> {
+    fn entry(&mut self, entry: &fmt::Debug) {
+        self.result = self.result.and_then(|_| {
+            if self.is_pretty() {
+                let mut writer = PadAdapter::new(self.fmt);
+                let prefix = if self.has_fields { "," } else { "" };
+                fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
+            } else {
+                let prefix = if self.has_fields { ", " } else { "" };
+                write!(self.fmt, "{}{:?}", prefix, entry)
+            }
+        });
+
+        self.has_fields = true;
+    }
+
+    pub fn finish(&mut self) {
+        let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
+        self.result = self.result.and_then(|_| self.fmt.write_str(prefix));
+    }
+
+    fn is_pretty(&self) -> bool {
+        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
+    }
+}
+
+/// A struct to help with `fmt::Debug` implementations.
+///
+/// Constructed by the `Formatter::debug_set` method.
+#[must_use]
+pub struct DebugSet<'a, 'b: 'a> {
+    inner: DebugInner<'a, 'b>,
+}
+
+pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
+    let result = write!(fmt, "{{");
+    DebugSet {
+        inner: DebugInner {
+            fmt: fmt,
+            result: result,
+            has_fields: false,
+        }
+    }
+}
+
+impl<'a, 'b: 'a> DebugSet<'a, 'b> {
+    /// Adds a new entry to the set output.
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    pub fn entry(mut self, entry: &fmt::Debug) -> DebugSet<'a, 'b> {
+        self.inner.entry(entry);
+        self
+    }
+
+    /// Consumes the `DebugSet`, finishing output and returning any error
+    /// encountered.
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    pub fn finish(mut self) -> fmt::Result {
+        self.inner.finish();
+        self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
+    }
+}
+
+/// A struct to help with `fmt::Debug` implementations.
+///
+/// Constructed by the `Formatter::debug_list` method.
+#[must_use]
+pub struct DebugList<'a, 'b: 'a> {
+    inner: DebugInner<'a, 'b>,
+}
+
+pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
+    let result = write!(fmt, "[");
+    DebugList {
+        inner: DebugInner {
+            fmt: fmt,
+            result: result,
+            has_fields: false,
+        }
+    }
+}
+
+impl<'a, 'b: 'a> DebugList<'a, 'b> {
+    /// Adds a new entry to the set output.
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    pub fn entry(mut self, entry: &fmt::Debug) -> DebugList<'a, 'b> {
+        self.inner.entry(entry);
+        self
+    }
+
+    /// Consumes the `DebugSet`, finishing output and returning any error
+    /// encountered.
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    pub fn finish(mut self) -> fmt::Result {
+        self.inner.finish();
+        self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
+    }
+}
+
+/// A struct to help with `fmt::Debug` implementations.
+///
+/// Constructed by the `Formatter::debug_map` method.
+#[must_use]
+pub struct DebugMap<'a, 'b: 'a> {
+    fmt: &'a mut fmt::Formatter<'b>,
+    result: fmt::Result,
+    has_fields: bool,
+}
+
+pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
+    let result = write!(fmt, "{{");
+    DebugMap {
+        fmt: fmt,
+        result: result,
+        has_fields: false,
+    }
+}
+
+impl<'a, 'b: 'a> DebugMap<'a, 'b> {
+    /// Adds a new entry to the map output.
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    pub fn entry(mut self, key: &fmt::Debug, value: &fmt::Debug) -> DebugMap<'a, 'b> {
+        self.result = self.result.and_then(|_| {
+            if self.is_pretty() {
+                let mut writer = PadAdapter::new(self.fmt);
+                let prefix = if self.has_fields { "," } else { "" };
+                fmt::write(&mut writer, format_args!("{}\n{:#?}: {:#?}", prefix, key, value))
+            } else {
+                let prefix = if self.has_fields { ", " } else { "" };
+                write!(self.fmt, "{}{:?}: {:?}", prefix, key, value)
+            }
+        });
+
+        self.has_fields = true;
+        self
+    }
+
+    /// Consumes the `DebugMap`, finishing output and returning any error
+    /// encountered.
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    pub fn finish(self) -> fmt::Result {
+        let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
+        self.result.and_then(|_| write!(self.fmt, "{}}}", prefix))
+    }
+
+    fn is_pretty(&self) -> bool {
+        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
+    }
+}
index 7f7264a04684b61426996c16ea82fd1683e3b913..6a5943265ca88fee04ccecb1ba986b6d7ab85ad0 100644 (file)
@@ -17,7 +17,7 @@ pub use self::SignFormat::*;
 use char;
 use char::CharExt;
 use fmt;
-use iter::IteratorExt;
+use iter::Iterator;
 use num::{cast, Float, ToPrimitive};
 use num::FpCategory as Fp;
 use ops::FnOnce;
@@ -40,10 +40,10 @@ pub enum ExponentFormat {
 pub enum SignificantDigits {
     /// At most the given number of digits will be printed, truncating any
     /// trailing zeroes.
-    DigMax(uint),
+    DigMax(usize),
 
     /// Precisely the given number of digits will be printed.
-    DigExact(uint)
+    DigExact(usize)
 }
 
 /// How to emit the sign of a number.
@@ -53,7 +53,7 @@ pub enum SignFormat {
     SignNeg
 }
 
-static DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
+const DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
 
 /// Converts a number to its string representation as a byte vector.
 /// This is meant to be a common base implementation for all numeric string
@@ -123,13 +123,13 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
     // For an f64 the exponent is in the range of [-1022, 1023] for base 2, so
     // we may have up to that many digits. Give ourselves some extra wiggle room
     // otherwise as well.
-    let mut buf = [0u8; 1536];
+    let mut buf = [0; 1536];
     let mut end = 0;
-    let radix_gen: T = cast(radix as int).unwrap();
+    let radix_gen: T = cast(radix as isize).unwrap();
 
     let (num, exp) = match exp_format {
-        ExpNone => (num, 0i32),
-        ExpDec if num == _0 => (num, 0i32),
+        ExpNone => (num, 0),
+        ExpDec if num == _0 => (num, 0),
         ExpDec => {
             let (exp, exp_base) = match exp_format {
                 ExpDec => (num.abs().log10().floor(), cast::<f64, T>(10.0f64).unwrap()),
@@ -156,7 +156,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
         deccum = deccum / radix_gen;
         deccum = deccum.trunc();
 
-        let c = char::from_digit(current_digit.to_int().unwrap() as u32, radix);
+        let c = char::from_digit(current_digit.to_isize().unwrap() as u32, radix);
         buf[end] = c.unwrap() as u8;
         end += 1;
 
@@ -211,7 +211,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
             // See note in first loop.
             let current_digit = deccum.trunc().abs();
 
-            let c = char::from_digit(current_digit.to_int().unwrap() as u32,
+            let c = char::from_digit(current_digit.to_isize().unwrap() as u32,
                                      radix);
             buf[end] = c.unwrap() as u8;
             end += 1;
@@ -235,32 +235,32 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
             let extra_digit = ascii2value(buf[end - 1]);
             end -= 1;
             if extra_digit >= radix / 2 { // -> need to round
-                let mut i: int = end as int - 1;
+                let mut i: isize = end as isize - 1;
                 loop {
                     // If reached left end of number, have to
                     // insert additional digit:
                     if i < 0
-                    || buf[i as uint] == b'-'
-                    || buf[i as uint] == b'+' {
-                        for j in (i as uint + 1..end).rev() {
+                    || buf[i as usize] == b'-'
+                    || buf[i as usize] == b'+' {
+                        for j in (i as usize + 1..end).rev() {
                             buf[j + 1] = buf[j];
                         }
-                        buf[(i + 1) as uint] = value2ascii(1);
+                        buf[(i + 1) as usize] = value2ascii(1);
                         end += 1;
                         break;
                     }
 
                     // Skip the '.'
-                    if buf[i as uint] == b'.' { i -= 1; continue; }
+                    if buf[i as usize] == b'.' { i -= 1; continue; }
 
                     // Either increment the digit,
                     // or set to 0 if max and carry the 1.
-                    let current_digit = ascii2value(buf[i as uint]);
+                    let current_digit = ascii2value(buf[i as usize]);
                     if current_digit < (radix - 1) {
-                        buf[i as uint] = value2ascii(current_digit+1);
+                        buf[i as usize] = value2ascii(current_digit+1);
                         break;
                     } else {
-                        buf[i as uint] = value2ascii(0);
+                        buf[i as usize] = value2ascii(0);
                         i -= 1;
                     }
                 }
@@ -311,13 +311,13 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
 
             struct Filler<'a> {
                 buf: &'a mut [u8],
-                end: &'a mut uint,
+                end: &'a mut usize,
             }
 
             impl<'a> fmt::Write for Filler<'a> {
                 fn write_str(&mut self, s: &str) -> fmt::Result {
-                    slice::bytes::copy_memory(&mut self.buf[(*self.end)..],
-                                              s.as_bytes());
+                    slice::bytes::copy_memory(s.as_bytes(),
+                                              &mut self.buf[(*self.end)..]);
                     *self.end += s.len();
                     Ok(())
                 }
index a2c1bbc03317e9da08451e0b2b2d6194d385568b..be804327663e5b058196fd268b5d20d72f5f22eb 100644 (file)
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use any;
 use cell::{Cell, RefCell, Ref, RefMut, BorrowState};
 use char::CharExt;
-use iter::{Iterator, IteratorExt};
+use clone::Clone;
+use iter::Iterator;
 use marker::{Copy, PhantomData, Sized};
 use mem;
 use option::Option;
@@ -32,8 +32,11 @@ pub use self::num::radix;
 pub use self::num::Radix;
 pub use self::num::RadixFmt;
 
+pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugList, DebugMap};
+
 mod num;
 mod float;
+mod builders;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(hidden)]
@@ -51,7 +54,7 @@ pub type Result = result::Result<(), Error>;
 /// occurred. Any extra information must be arranged to be transmitted through
 /// some other means.
 #[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub struct Error;
 
 /// A collection of methods that are required to format a message into a stream.
@@ -110,11 +113,11 @@ pub trait Write {
 /// traits.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Formatter<'a> {
-    flags: uint,
+    flags: u32,
     fill: char,
     align: rt::v1::Alignment,
-    width: Option<uint>,
-    precision: Option<uint>,
+    width: Option<usize>,
+    precision: Option<usize>,
 
     buf: &'a mut (Write+'a),
     curarg: slice::Iter<'a, ArgumentV1<'a>>,
@@ -138,9 +141,15 @@ pub struct ArgumentV1<'a> {
     formatter: fn(&Void, &mut Formatter) -> Result,
 }
 
+impl<'a> Clone for ArgumentV1<'a> {
+    fn clone(&self) -> ArgumentV1<'a> {
+        *self
+    }
+}
+
 impl<'a> ArgumentV1<'a> {
     #[inline(never)]
-    fn show_uint(x: &uint, f: &mut Formatter) -> Result {
+    fn show_usize(x: &usize, f: &mut Formatter) -> Result {
         Display::fmt(x, f)
     }
 
@@ -158,13 +167,13 @@ impl<'a> ArgumentV1<'a> {
 
     #[doc(hidden)]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn from_uint(x: &uint) -> ArgumentV1 {
-        ArgumentV1::new(x, ArgumentV1::show_uint)
+    pub fn from_usize(x: &usize) -> ArgumentV1 {
+        ArgumentV1::new(x, ArgumentV1::show_usize)
     }
 
-    fn as_uint(&self) -> Option<uint> {
-        if self.formatter as uint == ArgumentV1::show_uint as uint {
-            Some(unsafe { *(self.value as *const _ as *const uint) })
+    fn as_usize(&self) -> Option<usize> {
+        if self.formatter as usize == ArgumentV1::show_usize as usize {
+            Some(unsafe { *(self.value as *const _ as *const usize) })
         } else {
             None
         }
@@ -172,7 +181,7 @@ impl<'a> ArgumentV1<'a> {
 }
 
 // flags available in the v1 format of format_args
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 #[allow(dead_code)] // SignMinus isn't currently used
 enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, }
 
@@ -194,7 +203,7 @@ impl<'a> Arguments<'a> {
     /// The `pieces` array must be at least as long as `fmt` to construct
     /// 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
+    /// created with `argumentusize`. However, failing to do so doesn't cause
     /// unsafety, but will ignore invalid .
     #[doc(hidden)] #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -219,7 +228,7 @@ impl<'a> Arguments<'a> {
 /// macro validates the format string at compile-time so usage of the `write`
 /// and `format` functions can be safely performed.
 #[stable(feature = "rust1", since = "1.0.0")]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Arguments<'a> {
     // Format string pieces to print.
     pieces: &'a [&'a str],
@@ -246,16 +255,6 @@ impl<'a> Display for Arguments<'a> {
     }
 }
 
-/// Format trait for the `:?` format. Useful for debugging, all types
-/// should implement this.
-#[deprecated(since = "1.0.0", reason = "renamed to Debug")]
-#[unstable(feature = "old_fmt")]
-pub trait Show {
-    /// Formats the value using the given formatter.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn fmt(&self, &mut Formatter) -> Result;
-}
-
 /// Format trait for the `:?` format. Useful for debugging, all types
 /// should implement this.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -269,22 +268,6 @@ pub trait Debug {
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
-#[allow(deprecated)]
-impl<T: Show + ?Sized> Debug for T {
-    #[allow(deprecated)]
-    fn fmt(&self, f: &mut Formatter) -> Result { Show::fmt(self, f) }
-}
-
-/// When a value can be semantically expressed as a String, this trait may be
-/// used. It corresponds to the default format, `{}`.
-#[deprecated(since = "1.0.0", reason = "renamed to Display")]
-#[unstable(feature = "old_fmt")]
-pub trait String {
-    /// Formats the value using the given formatter.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn fmt(&self, &mut Formatter) -> Result;
-}
-
 /// When a value can be semantically expressed as a String, this trait may be
 /// used. It corresponds to the default format, `{}`.
 #[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default \
@@ -297,12 +280,6 @@ pub trait Display {
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
-#[allow(deprecated)]
-impl<T: String + ?Sized> Display for T {
-    #[allow(deprecated)]
-    fn fmt(&self, f: &mut Formatter) -> Result { String::fmt(self, f) }
-}
-
 /// Format trait for the `o` character
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Octal {
@@ -434,15 +411,15 @@ impl<'a> Formatter<'a> {
         (value.formatter)(value.value, self)
     }
 
-    fn getcount(&mut self, cnt: &rt::v1::Count) -> Option<uint> {
+    fn getcount(&mut self, cnt: &rt::v1::Count) -> Option<usize> {
         match *cnt {
             rt::v1::Count::Is(n) => Some(n),
             rt::v1::Count::Implied => None,
             rt::v1::Count::Param(i) => {
-                self.args[i].as_uint()
+                self.args[i].as_usize()
             }
             rt::v1::Count::NextParam => {
-                self.curarg.next().and_then(|arg| arg.as_uint())
+                self.curarg.next().and_then(|arg| arg.as_usize())
             }
         }
     }
@@ -457,7 +434,7 @@ impl<'a> Formatter<'a> {
     /// # Arguments
     ///
     /// * is_positive - whether the original integer was positive or not.
-    /// * prefix - if the '#' character (FlagAlternate) is provided, this
+    /// * prefix - if the '#' character (Alternate) is provided, this
     ///   is the prefix to put in front of the number.
     /// * buf - the byte array that the number has been formatted into
     ///
@@ -476,12 +453,12 @@ impl<'a> Formatter<'a> {
         let mut sign = None;
         if !is_positive {
             sign = Some('-'); width += 1;
-        } else if self.flags & (1 << (FlagV1::SignPlus as uint)) != 0 {
+        } else if self.flags & (1 << (FlagV1::SignPlus as u32)) != 0 {
             sign = Some('+'); width += 1;
         }
 
         let mut prefixed = false;
-        if self.flags & (1 << (FlagV1::Alternate as uint)) != 0 {
+        if self.flags & (1 << (FlagV1::Alternate as u32)) != 0 {
             prefixed = true; width += prefix.char_len();
         }
 
@@ -511,7 +488,7 @@ impl<'a> Formatter<'a> {
             }
             // The sign and prefix goes before the padding if the fill character
             // is zero
-            Some(min) if self.flags & (1 << (FlagV1::SignAwareZeroPad as uint)) != 0 => {
+            Some(min) if self.flags & (1 << (FlagV1::SignAwareZeroPad as u32)) != 0 => {
                 self.fill = '0';
                 try!(write_prefix(self));
                 self.with_padding(min - width, Alignment::Right, |f| {
@@ -581,7 +558,7 @@ impl<'a> Formatter<'a> {
 
     /// Runs a callback, emitting the correct padding either before or
     /// afterwards depending on whether right or left alignment is requested.
-    fn with_padding<F>(&mut self, padding: uint, default: Alignment,
+    fn with_padding<F>(&mut self, padding: usize, default: Alignment,
                        f: F) -> Result
         where F: FnOnce(&mut Formatter) -> Result,
     {
@@ -597,7 +574,7 @@ impl<'a> Formatter<'a> {
             Alignment::Center => (padding / 2, (padding + 1) / 2),
         };
 
-        let mut fill = [0u8; 4];
+        let mut fill = [0; 4];
         let len = self.fill.encode_utf8(&mut fill).unwrap_or(0);
         let fill = unsafe { str::from_utf8_unchecked(&fill[..len]) };
 
@@ -629,7 +606,7 @@ impl<'a> Formatter<'a> {
 
     /// Flags for formatting (packed version of rt::Flag)
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn flags(&self) -> usize { self.flags }
+    pub fn flags(&self) -> u32 { self.flags }
 
     /// Character used as 'fill' whenever there is alignment
     #[unstable(feature = "core", reason = "method was just created")]
@@ -641,11 +618,150 @@ impl<'a> Formatter<'a> {
 
     /// Optionally specified integer width that the output should be
     #[unstable(feature = "core", reason = "method was just created")]
-    pub fn width(&self) -> Option<uint> { self.width }
+    pub fn width(&self) -> Option<usize> { self.width }
 
     /// Optionally specified precision for numeric types
     #[unstable(feature = "core", reason = "method was just created")]
-    pub fn precision(&self) -> Option<uint> { self.precision }
+    pub fn precision(&self) -> Option<usize> { self.precision }
+
+    /// Creates a `DebugStruct` builder designed to assist with creation of
+    /// `fmt::Debug` implementations for structs.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # #![feature(debug_builders, core)]
+    /// use std::fmt;
+    ///
+    /// struct Foo {
+    ///     bar: i32,
+    ///     baz: String,
+    /// }
+    ///
+    /// impl fmt::Debug for Foo {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    ///         fmt.debug_struct("Foo")
+    ///             .field("bar", &self.bar)
+    ///             .field("baz", &self.baz)
+    ///             .finish()
+    ///     }
+    /// }
+    ///
+    /// // prints "Foo { bar: 10, baz: "Hello World" }"
+    /// println!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() });
+    /// ```
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    #[inline]
+    pub fn debug_struct<'b>(&'b mut self, name: &str) -> DebugStruct<'b, 'a> {
+        builders::debug_struct_new(self, name)
+    }
+
+    /// Creates a `DebugTuple` builder designed to assist with creation of
+    /// `fmt::Debug` implementations for tuple structs.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # #![feature(debug_builders, core)]
+    /// use std::fmt;
+    ///
+    /// struct Foo(i32, String);
+    ///
+    /// impl fmt::Debug for Foo {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    ///         fmt.debug_tuple("Foo")
+    ///             .field(&self.0)
+    ///             .field(&self.1)
+    ///             .finish()
+    ///     }
+    /// }
+    ///
+    /// // prints "Foo(10, "Hello World")"
+    /// println!("{:?}", Foo(10, "Hello World".to_string()));
+    /// ```
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    #[inline]
+    pub fn debug_tuple<'b>(&'b mut self, name: &str) -> DebugTuple<'b, 'a> {
+        builders::debug_tuple_new(self, name)
+    }
+
+    /// Creates a `DebugList` builder designed to assist with creation of
+    /// `fmt::Debug` implementations for list-like structures.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # #![feature(debug_builders, core)]
+    /// use std::fmt;
+    ///
+    /// struct Foo(Vec<i32>);
+    ///
+    /// impl fmt::Debug for Foo {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    ///         self.0.iter().fold(fmt.debug_list(), |b, e| b.entry(e)).finish()
+    ///     }
+    /// }
+    ///
+    /// // prints "[10, 11]"
+    /// println!("{:?}", Foo(vec![10, 11]));
+    /// ```
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    #[inline]
+    pub fn debug_list<'b>(&'b mut self) -> DebugList<'b, 'a> {
+        builders::debug_list_new(self)
+    }
+
+    /// Creates a `DebugSet` builder designed to assist with creation of
+    /// `fmt::Debug` implementations for set-like structures.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # #![feature(debug_builders, core)]
+    /// use std::fmt;
+    ///
+    /// struct Foo(Vec<i32>);
+    ///
+    /// impl fmt::Debug for Foo {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    ///         self.0.iter().fold(fmt.debug_set(), |b, e| b.entry(e)).finish()
+    ///     }
+    /// }
+    ///
+    /// // prints "{10, 11}"
+    /// println!("{:?}", Foo(vec![10, 11]));
+    /// ```
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    #[inline]
+    pub fn debug_set<'b>(&'b mut self) -> DebugSet<'b, 'a> {
+        builders::debug_set_new(self)
+    }
+
+    /// Creates a `DebugMap` builder designed to assist with creation of
+    /// `fmt::Debug` implementations for map-like structures.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # #![feature(debug_builders, core)]
+    /// use std::fmt;
+    ///
+    /// struct Foo(Vec<(String, i32)>);
+    ///
+    /// impl fmt::Debug for Foo {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    ///         self.0.iter().fold(fmt.debug_map(), |b, &(ref k, ref v)| b.entry(k, v)).finish()
+    ///     }
+    /// }
+    ///
+    /// // prints "{"A": 10, "B": 11}"
+    /// println!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)]));
+    /// ```
+    #[unstable(feature = "debug_builders", reason = "method was just created")]
+    #[inline]
+    pub fn debug_map<'b>(&'b mut self) -> DebugMap<'b, 'a> {
+        builders::debug_map_new(self)
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -721,7 +837,7 @@ impl Debug for char {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Display for char {
     fn fmt(&self, f: &mut Formatter) -> Result {
-        let mut utf8 = [0u8; 4];
+        let mut utf8 = [0; 4];
         let amt = self.encode_utf8(&mut utf8).unwrap_or(0);
         let s: &str = unsafe { mem::transmute(&utf8[..amt]) };
         Display::fmt(s, f)
@@ -731,9 +847,9 @@ impl Display for char {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Pointer for *const T {
     fn fmt(&self, f: &mut Formatter) -> Result {
-        f.flags |= 1 << (FlagV1::Alternate as uint);
-        let ret = LowerHex::fmt(&(*self as uint), f);
-        f.flags &= !(1 << (FlagV1::Alternate as uint));
+        f.flags |= 1 << (FlagV1::Alternate as u32);
+        let ret = LowerHex::fmt(&(*self as usize), f);
+        f.flags &= !(1 << (FlagV1::Alternate as u32));
         ret
     }
 }
@@ -741,6 +857,8 @@ impl<T> Pointer for *const T {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Pointer for *mut T {
     fn fmt(&self, f: &mut Formatter) -> Result {
+        // FIXME(#23542) Replace with type ascription.
+        #![allow(trivial_casts)]
         Pointer::fmt(&(*self as *const T), f)
     }
 }
@@ -748,6 +866,8 @@ impl<T> Pointer for *mut T {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Pointer for &'a T {
     fn fmt(&self, f: &mut Formatter) -> Result {
+        // FIXME(#23542) Replace with type ascription.
+        #![allow(trivial_casts)]
         Pointer::fmt(&(*self as *const T), f)
     }
 }
@@ -755,6 +875,8 @@ impl<'a, T> Pointer for &'a T {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Pointer for &'a mut T {
     fn fmt(&self, f: &mut Formatter) -> Result {
+        // FIXME(#23542) Replace with type ascription.
+        #![allow(trivial_casts)]
         Pointer::fmt(&(&**self as *const T), f)
     }
 }
@@ -881,30 +1003,10 @@ macro_rules! tuple {
 
 tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> Debug for &'a (any::Any+'a) {
-    fn fmt(&self, f: &mut Formatter) -> Result { f.pad("&Any") }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Debug> Debug for [T] {
     fn fmt(&self, f: &mut Formatter) -> Result {
-        if f.flags & (1 << (FlagV1::Alternate as uint)) == 0 {
-            try!(write!(f, "["));
-        }
-        let mut is_first = true;
-        for x in self {
-            if is_first {
-                is_first = false;
-            } else {
-                try!(write!(f, ", "));
-            }
-            try!(write!(f, "{:?}", *x))
-        }
-        if f.flags & (1 << (FlagV1::Alternate as uint)) == 0 {
-            try!(write!(f, "]"));
-        }
-        Ok(())
+        self.iter().fold(f.debug_list(), |b, e| b.entry(e)).finish()
     }
 }
 
index 1222126b5e0cdef73c0a3bccc4ce5dff3630c90f..76c975902aabb0df47a9b16b0611517b3e6b9b78 100644 (file)
@@ -15,7 +15,7 @@
 #![allow(unsigned_negation)]
 
 use fmt;
-use iter::IteratorExt;
+use iter::Iterator;
 use num::{Int, cast};
 use slice::SliceExt;
 use str;
@@ -33,12 +33,13 @@ trait GenericRadix {
     fn digit(&self, x: u8) -> u8;
 
     /// Format an integer using the radix using a formatter.
+    #[allow(deprecated)] // Int
     fn fmt_int<T: Int>(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result {
         // The radix can be as low as 2, so we need a buffer of at least 64
         // characters for a base 2 number.
         let zero = Int::zero();
         let is_positive = x >= zero;
-        let mut buf = [0u8; 64];
+        let mut buf = [0; 64];
         let mut curr = buf.len();
         let base = cast(self.base()).unwrap();
         if is_positive {
@@ -84,7 +85,7 @@ struct LowerHex;
 
 /// A hexadecimal (base 16) radix, formatted with upper-case characters
 #[derive(Clone, PartialEq)]
-pub struct UpperHex;
+struct UpperHex;
 
 macro_rules! radix {
     ($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => {
@@ -138,14 +139,15 @@ impl GenericRadix for Radix {
 /// A helper type for formatting radixes.
 #[unstable(feature = "core",
            reason = "may be renamed or move to a different module")]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct RadixFmt<T, R>(T, R);
 
 /// Constructs a radix formatter in the range of `2..36`.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::fmt::radix;
 /// assert_eq!(format!("{}", radix(55, 36)), "1j".to_string());
 /// ```
@@ -156,7 +158,7 @@ pub fn radix<T>(x: T, base: u8) -> RadixFmt<T, Radix> {
 }
 
 macro_rules! radix_fmt {
-    ($T:ty as $U:ty, $fmt:ident, $S:expr) => {
+    ($T:ty as $U:ty, $fmt:ident) => {
         #[stable(feature = "rust1", since = "1.0.0")]
         impl fmt::Debug for RadixFmt<$T, Radix> {
             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -182,8 +184,8 @@ macro_rules! int_base {
     }
 }
 
-macro_rules! show {
-    ($T:ident with $S:expr) => {
+macro_rules! debug {
+    ($T:ident) => {
         #[stable(feature = "rust1", since = "1.0.0")]
         impl fmt::Debug for $T {
             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -194,27 +196,24 @@ macro_rules! show {
 }
 macro_rules! integer {
     ($Int:ident, $Uint:ident) => {
-        integer! { $Int, $Uint, stringify!($Int), stringify!($Uint) }
-    };
-    ($Int:ident, $Uint:ident, $SI:expr, $SU:expr) => {
         int_base! { Display  for $Int as $Int   -> Decimal }
         int_base! { Binary   for $Int as $Uint  -> Binary }
         int_base! { Octal    for $Int as $Uint  -> Octal }
         int_base! { LowerHex for $Int as $Uint  -> LowerHex }
         int_base! { UpperHex for $Int as $Uint  -> UpperHex }
-        radix_fmt! { $Int as $Int, fmt_int, $SI }
-        show! { $Int with $SI }
+        radix_fmt! { $Int as $Int, fmt_int }
+        debug! { $Int }
 
         int_base! { Display  for $Uint as $Uint -> Decimal }
         int_base! { Binary   for $Uint as $Uint -> Binary }
         int_base! { Octal    for $Uint as $Uint -> Octal }
         int_base! { LowerHex for $Uint as $Uint -> LowerHex }
         int_base! { UpperHex for $Uint as $Uint -> UpperHex }
-        radix_fmt! { $Uint as $Uint, fmt_int, $SU }
-        show! { $Uint with $SU }
+        radix_fmt! { $Uint as $Uint, fmt_int }
+        debug! { $Uint }
     }
 }
-integer! { int, uint, "i", "u" }
+integer! { isize, usize }
 integer! { i8, u8 }
 integer! { i16, u16 }
 integer! { i32, u32 }
index 0c9bb6316e0d805ecbcc08a05c1c6bb2fa67bc5e..d56ec6a74d4494b59c7d0fe758784d3f621379f0 100644 (file)
@@ -16,7 +16,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Argument {
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -25,7 +25,7 @@ pub struct Argument {
     pub format: FormatSpec,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct FormatSpec {
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -33,7 +33,7 @@ pub struct FormatSpec {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub align: Alignment,
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub flags: uint,
+    pub flags: u32,
     #[stable(feature = "rust1", since = "1.0.0")]
     pub precision: Count,
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -41,7 +41,7 @@ pub struct FormatSpec {
 }
 
 /// Possible alignments that can be requested as part of a formatting directive.
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Alignment {
     /// Indication that contents should be left-aligned.
@@ -58,7 +58,7 @@ pub enum Alignment {
     Unknown,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Count {
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -71,7 +71,7 @@ pub enum Count {
     Implied,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Position {
     #[stable(feature = "rust1", since = "1.0.0")]
index 2e83334b93732378c960019def28bbef57e2ee77..2375ae896500586799867ef4cd6ab5d23d76380a 100644 (file)
 //! # Examples
 //!
 //! ```rust
+//! # #![feature(hash)]
 //! use std::hash::{hash, Hash, SipHasher};
 //!
 //! #[derive(Hash)]
 //! struct Person {
-//!     id: uint,
+//!     id: u32,
 //!     name: String,
 //!     phone: u64,
 //! }
 //! the trait `Hash`:
 //!
 //! ```rust
+//! # #![feature(hash)]
 //! use std::hash::{hash, Hash, Hasher, SipHasher};
 //!
 //! struct Person {
-//!     id: uint,
+//!     id: u32,
 //!     name: String,
 //!     phone: u64,
 //! }
@@ -70,10 +72,17 @@ mod sip;
 /// A hashable type.
 ///
 /// The `H` type parameter is an abstract hash state that is used by the `Hash`
-/// to compute the hash. Specific implementations of this trait may specialize
-/// for particular instances of `H` in order to be able to optimize the hashing
-/// behavior.
-#[cfg(not(stage0))]
+/// to compute the hash.
+///
+/// If you are also implementing `Eq`, there is an additional property that
+/// is important:
+///
+/// ```text
+/// k1 == k2 -> hash(k1) == hash(k2)
+/// ```
+///
+/// In other words, if two keys are equal, their hashes should also be equal.
+/// `HashMap` and `HashSet` both rely on this behavior.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Hash {
     /// Feeds this value into the state given, updating the hasher as necessary.
@@ -89,72 +98,40 @@ pub trait Hash {
     }
 }
 
-/// A hashable type.
-///
-/// The `H` type parameter is an abstract hash state that is used by the `Hash`
-/// to compute the hash. Specific implementations of this trait may specialize
-/// for particular instances of `H` in order to be able to optimize the hashing
-/// behavior.
-#[cfg(stage0)]
-pub trait Hash<H: Hasher> {
-    /// Feeds this value into the state given, updating the hasher as necessary.
-    fn hash(&self, state: &mut H);
-}
-
 /// A trait which represents the ability to hash an arbitrary stream of bytes.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Hasher {
-    /// Result type of one run of hashing generated by this hasher.
-    #[cfg(stage0)]
-    type Output;
-
-    /// Resets this hasher back to its initial state (as if it were just
-    /// created).
-    #[cfg(stage0)]
-    fn reset(&mut self);
-
-    /// Completes a round of hashing, producing the output hash generated.
-    #[cfg(stage0)]
-    fn finish(&self) -> Self::Output;
-
     /// Completes a round of hashing, producing the output hash generated.
-    #[cfg(not(stage0))]
-    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn finish(&self) -> u64;
 
     /// Writes some data into this `Hasher`
-    #[cfg(not(stage0))]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn write(&mut self, bytes: &[u8]);
 
     /// Write a single `u8` into this hasher
-    #[cfg(not(stage0))]
     #[inline]
     #[unstable(feature = "hash", reason = "module was recently redesigned")]
     fn write_u8(&mut self, i: u8) { self.write(&[i]) }
     /// Write a single `u16` into this hasher.
-    #[cfg(not(stage0))]
     #[inline]
     #[unstable(feature = "hash", reason = "module was recently redesigned")]
     fn write_u16(&mut self, i: u16) {
         self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) })
     }
     /// Write a single `u32` into this hasher.
-    #[cfg(not(stage0))]
     #[inline]
     #[unstable(feature = "hash", reason = "module was recently redesigned")]
     fn write_u32(&mut self, i: u32) {
         self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) })
     }
     /// Write a single `u64` into this hasher.
-    #[cfg(not(stage0))]
     #[inline]
     #[unstable(feature = "hash", reason = "module was recently redesigned")]
     fn write_u64(&mut self, i: u64) {
         self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) })
     }
     /// Write a single `usize` into this hasher.
-    #[cfg(not(stage0))]
     #[inline]
     #[unstable(feature = "hash", reason = "module was recently redesigned")]
     fn write_usize(&mut self, i: usize) {
@@ -166,58 +143,31 @@ pub trait Hasher {
     }
 
     /// Write a single `i8` into this hasher.
-    #[cfg(not(stage0))]
     #[inline]
     #[unstable(feature = "hash", reason = "module was recently redesigned")]
     fn write_i8(&mut self, i: i8) { self.write_u8(i as u8) }
     /// Write a single `i16` into this hasher.
-    #[cfg(not(stage0))]
     #[inline]
     #[unstable(feature = "hash", reason = "module was recently redesigned")]
     fn write_i16(&mut self, i: i16) { self.write_u16(i as u16) }
     /// Write a single `i32` into this hasher.
-    #[cfg(not(stage0))]
     #[inline]
     #[unstable(feature = "hash", reason = "module was recently redesigned")]
     fn write_i32(&mut self, i: i32) { self.write_u32(i as u32) }
     /// Write a single `i64` into this hasher.
-    #[cfg(not(stage0))]
     #[inline]
     #[unstable(feature = "hash", reason = "module was recently redesigned")]
     fn write_i64(&mut self, i: i64) { self.write_u64(i as u64) }
     /// Write a single `isize` into this hasher.
-    #[cfg(not(stage0))]
     #[inline]
     #[unstable(feature = "hash", reason = "module was recently redesigned")]
     fn write_isize(&mut self, i: isize) { self.write_usize(i as usize) }
 }
 
-/// A common bound on the `Hasher` parameter to `Hash` implementations in order
-/// to generically hash an aggregate.
-#[unstable(feature = "hash",
-           reason = "this trait will likely be replaced by io::Writer")]
-#[allow(missing_docs)]
-#[cfg(stage0)]
-pub trait Writer {
-    fn write(&mut self, bytes: &[u8]);
-}
-
-/// Hash a value with the default SipHasher algorithm (two initial keys of 0).
-///
-/// The specified value will be hashed with this hasher and then the resulting
-/// hash will be returned.
-#[cfg(stage0)]
-pub fn hash<T: Hash<H>, H: Hasher + Default>(value: &T) -> H::Output {
-    let mut h: H = Default::default();
-    value.hash(&mut h);
-    h.finish()
-}
-
 /// Hash a value with the default SipHasher algorithm (two initial keys of 0).
 ///
 /// The specified value will be hashed with this hasher and then the resulting
 /// hash will be returned.
-#[cfg(not(stage0))]
 #[unstable(feature = "hash", reason = "module was recently redesigned")]
 pub fn hash<T: Hash, H: Hasher + Default>(value: &T) -> u64 {
     let mut h: H = Default::default();
@@ -227,145 +177,6 @@ pub fn hash<T: Hash, H: Hasher + Default>(value: &T) -> u64 {
 
 //////////////////////////////////////////////////////////////////////////////
 
-#[cfg(stage0)]
-mod impls {
-    use prelude::*;
-
-    use mem;
-    use num::Int;
-    use super::*;
-
-    macro_rules! impl_hash {
-        ($ty:ident, $uty:ident) => {
-            impl<S: Writer + Hasher> Hash<S> for $ty {
-                #[inline]
-                fn hash(&self, state: &mut S) {
-                    let a: [u8; ::$ty::BYTES] = unsafe {
-                        mem::transmute(*self)
-                    };
-                    state.write(&a)
-                }
-            }
-        }
-    }
-
-    impl_hash! { u8, u8 }
-    impl_hash! { u16, u16 }
-    impl_hash! { u32, u32 }
-    impl_hash! { u64, u64 }
-    impl_hash! { uint, uint }
-    impl_hash! { i8, u8 }
-    impl_hash! { i16, u16 }
-    impl_hash! { i32, u32 }
-    impl_hash! { i64, u64 }
-    impl_hash! { int, uint }
-
-    impl<S: Writer + Hasher> Hash<S> for bool {
-        #[inline]
-        fn hash(&self, state: &mut S) {
-            (*self as u8).hash(state);
-        }
-    }
-
-    impl<S: Writer + Hasher> Hash<S> for char {
-        #[inline]
-        fn hash(&self, state: &mut S) {
-            (*self as u32).hash(state);
-        }
-    }
-
-    impl<S: Writer + Hasher> Hash<S> for str {
-        #[inline]
-        fn hash(&self, state: &mut S) {
-            state.write(self.as_bytes());
-            0xffu8.hash(state)
-        }
-    }
-
-    macro_rules! impl_hash_tuple {
-        () => (
-            impl<S: Hasher> Hash<S> for () {
-                #[inline]
-                fn hash(&self, _state: &mut S) {}
-            }
-        );
-
-        ( $($name:ident)+) => (
-            impl<S: Hasher, $($name: Hash<S>),*> Hash<S> for ($($name,)*) {
-                #[inline]
-                #[allow(non_snake_case)]
-                fn hash(&self, state: &mut S) {
-                    match *self {
-                        ($(ref $name,)*) => {
-                            $(
-                                $name.hash(state);
-                            )*
-                        }
-                    }
-                }
-            }
-        );
-    }
-
-    impl_hash_tuple! {}
-    impl_hash_tuple! { A }
-    impl_hash_tuple! { A B }
-    impl_hash_tuple! { A B C }
-    impl_hash_tuple! { A B C D }
-    impl_hash_tuple! { A B C D E }
-    impl_hash_tuple! { A B C D E F }
-    impl_hash_tuple! { A B C D E F G }
-    impl_hash_tuple! { A B C D E F G H }
-    impl_hash_tuple! { A B C D E F G H I }
-    impl_hash_tuple! { A B C D E F G H I J }
-    impl_hash_tuple! { A B C D E F G H I J K }
-    impl_hash_tuple! { A B C D E F G H I J K L }
-
-    impl<S: Writer + Hasher, T: Hash<S>> Hash<S> for [T] {
-        #[inline]
-        fn hash(&self, state: &mut S) {
-            self.len().hash(state);
-            for elt in self {
-                elt.hash(state);
-            }
-        }
-    }
-
-
-    impl<'a, S: Hasher, T: ?Sized + Hash<S>> Hash<S> for &'a T {
-        #[inline]
-        fn hash(&self, state: &mut S) {
-            (**self).hash(state);
-        }
-    }
-
-    impl<'a, S: Hasher, T: ?Sized + Hash<S>> Hash<S> for &'a mut T {
-        #[inline]
-        fn hash(&self, state: &mut S) {
-            (**self).hash(state);
-        }
-    }
-
-    impl<S: Writer + Hasher, T> Hash<S> for *const T {
-        #[inline]
-        fn hash(&self, state: &mut S) {
-            // NB: raw-pointer Hash does _not_ dereference
-            // to the target; it just gives you the pointer-bytes.
-            (*self as uint).hash(state);
-        }
-    }
-
-    impl<S: Writer + Hasher, T> Hash<S> for *mut T {
-        #[inline]
-        fn hash(&self, state: &mut S) {
-            // NB: raw-pointer Hash does _not_ dereference
-            // to the target; it just gives you the pointer-bytes.
-            (*self as uint).hash(state);
-        }
-    }
-}
-
-#[cfg(not(stage0))]
 mod impls {
     use prelude::*;
 
@@ -381,7 +192,9 @@ mod impls {
                 }
 
                 fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
-                    let newlen = data.len() * ::$ty::BYTES;
+                    // FIXME(#23542) Replace with type ascription.
+                    #![allow(trivial_casts)]
+                    let newlen = data.len() * ::$ty::BYTES as usize;
                     let ptr = data.as_ptr() as *const u8;
                     state.write(unsafe { slice::from_raw_parts(ptr, newlen) })
                 }
index ce8917cc20589a93b0edddccc6ede9ed5fe7e329..6820a7025fca6f171cda155752bf60d6e258bf2d 100644 (file)
 
 //! An implementation of SipHash 2-4.
 
+#![allow(deprecated)] // until the next snapshot for inherent wrapping ops
+
 use prelude::*;
 use default::Default;
-
 use super::Hasher;
-#[cfg(stage0)]
-use super::Writer;
 
 /// An implementation of SipHash 2-4.
 ///
@@ -36,13 +35,13 @@ use super::Writer;
 pub struct SipHasher {
     k0: u64,
     k1: u64,
-    length: uint, // how many bytes we've processed
+    length: usize, // how many bytes we've processed
     v0: u64,      // hash state
     v1: u64,
     v2: u64,
     v3: u64,
     tail: u64, // unprocessed bytes le
-    ntail: uint,  // how many bytes in tail are valid
+    ntail: usize,  // how many bytes in tail are valid
 }
 
 // sadly, these macro definitions can't appear later,
@@ -62,7 +61,7 @@ macro_rules! u8to64_le {
     ($buf:expr, $i:expr, $len:expr) =>
     ({
         let mut t = 0;
-        let mut out = 0u64;
+        let mut out = 0;
         while t < $len {
             out |= ($buf[t+$i] as u64) << t*8;
             t += 1;
@@ -73,17 +72,17 @@ macro_rules! u8to64_le {
 
 macro_rules! rotl {
     ($x:expr, $b:expr) =>
-    (($x << $b) | ($x >> (64 - $b)))
+    (($x << $b) | ($x >> (64_i32.wrapping_sub($b))))
 }
 
 macro_rules! compress {
     ($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
     ({
-        $v0 += $v1; $v1 = rotl!($v1, 13); $v1 ^= $v0;
+        $v0 = $v0.wrapping_add($v1); $v1 = rotl!($v1, 13); $v1 ^= $v0;
         $v0 = rotl!($v0, 32);
-        $v2 += $v3; $v3 = rotl!($v3, 16); $v3 ^= $v2;
-        $v0 += $v3; $v3 = rotl!($v3, 21); $v3 ^= $v0;
-        $v2 += $v1; $v1 = rotl!($v1, 17); $v1 ^= $v2;
+        $v2 = $v2.wrapping_add($v3); $v3 = rotl!($v3, 16); $v3 ^= $v2;
+        $v0 = $v0.wrapping_add($v3); $v3 = rotl!($v3, 21); $v3 ^= $v0;
+        $v2 = $v2.wrapping_add($v1); $v1 = rotl!($v1, 17); $v1 ^= $v2;
         $v2 = rotl!($v2, 32);
     })
 }
@@ -115,11 +114,6 @@ impl SipHasher {
         state
     }
 
-    /// Returns the computed hash.
-    #[unstable(feature = "hash")]
-    #[deprecated(since = "1.0.0", reason = "renamed to finish")]
-    pub fn result(&self) -> u64 { self.finish() }
-
     fn reset(&mut self) {
         self.length = 0;
         self.v0 = self.k0 ^ 0x736f6d6570736575;
@@ -175,26 +169,9 @@ impl SipHasher {
     }
 }
 
-#[cfg(stage0)]
-impl Writer for SipHasher {
-    #[inline]
-    fn write(&mut self, msg: &[u8]) {
-        self.write(msg)
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Hasher for SipHasher {
-    #[cfg(stage0)]
-    type Output = u64;
-
-    #[cfg(stage0)]
-    fn reset(&mut self) {
-        self.reset();
-    }
-
     #[inline]
-    #[cfg(not(stage0))]
     fn write(&mut self, msg: &[u8]) {
         self.write(msg)
     }
index b2ee95963878edb13af4a4b99c9cf529377b13f4..0e91eafce187f7b0ed2dd8160c7c4fe365669043 100644 (file)
 
 use marker::Sized;
 
-pub type GlueFn = extern "Rust" fn(*const i8);
-
-#[lang="ty_desc"]
-#[derive(Copy)]
-pub struct TyDesc {
-    // sizeof(T)
-    pub size: usize,
-
-    // alignof(T)
-    pub align: usize,
-
-    // Called when a value of type `T` is no longer needed
-    pub drop_glue: GlueFn,
-
-    // Name corresponding to the type
-    pub name: &'static str,
-}
-
 extern "rust-intrinsic" {
 
     // NB: These intrinsics take unsafe pointers because they mutate aliased
@@ -196,21 +178,42 @@ extern "rust-intrinsic" {
     pub fn min_align_of<T>() -> usize;
     pub fn pref_align_of<T>() -> usize;
 
-    /// Get a static pointer to a type descriptor.
-    pub fn get_tydesc<T: ?Sized>() -> *const TyDesc;
+    /// Gets a static string slice containing the name of a type.
+    pub fn type_name<T: ?Sized>() -> &'static str;
 
     /// Gets an identifier which is globally unique to the specified type. This
     /// function will return the same value for a type regardless of whichever
     /// crate it is invoked in.
     pub fn type_id<T: ?Sized + 'static>() -> u64;
 
+    /// Create a value initialized to so that its drop flag,
+    /// if any, says that it has been dropped.
+    ///
+    /// `init_dropped` is unsafe because it returns a datum with all
+    /// of its bytes set to the drop flag, which generally does not
+    /// correspond to a valid value.
+    ///
+    /// This intrinsic is likely to be deprecated in the future when
+    /// Rust moves to non-zeroing dynamic drop (and thus removes the
+    /// embedded drop flags that are being established by this
+    /// intrinsic).
+    pub fn init_dropped<T>() -> T;
+
     /// Create a value initialized to zero.
     ///
     /// `init` is unsafe because it returns a zeroed-out datum,
-    /// which is unsafe unless T is Copy.
+    /// which is unsafe unless T is `Copy`.  Also, even if T is
+    /// `Copy`, an all-zero value may not correspond to any legitimate
+    /// state for the type in question.
     pub fn init<T>() -> T;
 
     /// Create an uninitialized value.
+    ///
+    /// `uninit` is unsafe because there is no guarantee of what its
+    /// contents are. In particular its drop-flag may be set to any
+    /// state, which means it may claim either dropped or
+    /// undropped. In the general case one must use `ptr::write` to
+    /// initialize memory previous set to the result of `uninit`.
     pub fn uninit<T>() -> T;
 
     /// Move a value out of scope without running drop glue.
@@ -230,7 +233,7 @@ extern "rust-intrinsic" {
     /// use std::mem;
     ///
     /// let v: &[u8] = unsafe { mem::transmute("L") };
-    /// assert!(v == [76u8]);
+    /// assert!(v == [76]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn transmute<T,U>(e: T) -> U;
@@ -241,7 +244,12 @@ extern "rust-intrinsic" {
     /// will trigger a compiler error.
     pub fn return_address() -> *const u8;
 
-    /// Returns `true` if a type requires drop glue.
+    /// Returns `true` if the actual type given as `T` requires drop
+    /// glue; returns `false` if the actual type provided for `T`
+    /// implements `Copy`.
+    ///
+    /// If the actual type neither requires drop glue nor implements
+    /// `Copy`, then may return `true` or `false`.
     pub fn needs_drop<T>() -> bool;
 
     /// Returns `true` if a type is managed (will be allocated on the local heap)
@@ -258,7 +266,7 @@ extern "rust-intrinsic" {
     /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
     /// and destination may *not* overlap.
     ///
-    /// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
+    /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`.
     ///
     /// # Safety
     ///
@@ -274,6 +282,7 @@ extern "rust-intrinsic" {
     /// A safe swap function:
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::mem;
     /// use std::ptr;
     ///
@@ -283,9 +292,9 @@ extern "rust-intrinsic" {
     ///         let mut t: T = mem::uninitialized();
     ///
     ///         // Perform the swap, `&mut` pointers never alias
-    ///         ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
-    ///         ptr::copy_nonoverlapping_memory(x, &*y, 1);
-    ///         ptr::copy_nonoverlapping_memory(y, &t, 1);
+    ///         ptr::copy_nonoverlapping(x, &mut t, 1);
+    ///         ptr::copy_nonoverlapping(y, x, 1);
+    ///         ptr::copy_nonoverlapping(&t, y, 1);
     ///
     ///         // y and t now point to the same thing, but we need to completely forget `tmp`
     ///         // because it's no longer relevant.
@@ -293,13 +302,19 @@ extern "rust-intrinsic" {
     ///     }
     /// }
     /// ```
-    #[unstable(feature = "core")]
-    pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(not(stage0))]
+    pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+
+    /// dox
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(stage0)]
+    pub fn copy_nonoverlapping<T>(dst: *mut T, src: *const T, count: usize);
 
     /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
     /// and destination may overlap.
     ///
-    /// `copy_memory` is semantically equivalent to C's `memmove`.
+    /// `copy` is semantically equivalent to C's `memmove`.
     ///
     /// # Safety
     ///
@@ -313,24 +328,30 @@ extern "rust-intrinsic" {
     /// Efficiently create a Rust vector from an unsafe buffer:
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::ptr;
     ///
-    /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
+    /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
     ///     let mut dst = Vec::with_capacity(elts);
     ///     dst.set_len(elts);
-    ///     ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
+    ///     ptr::copy(ptr, dst.as_mut_ptr(), elts);
     ///     dst
     /// }
     /// ```
     ///
-    #[unstable(feature = "core")]
-    pub fn copy_memory<T>(dst: *mut T, src: *const T, count: usize);
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(not(stage0))]
+    pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
+
+    /// dox
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(stage0)]
+    pub fn copy<T>(dst: *mut T, src: *const T, count: usize);
 
     /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
     /// bytes of memory starting at `dst` to `c`.
-    #[unstable(feature = "core",
-               reason = "uncertain about naming and semantics")]
-    pub fn set_memory<T>(dst: *mut T, val: u8, count: usize);
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
 
     /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
     /// a size of `count` * `size_of::<T>()` and an alignment of
@@ -541,4 +562,11 @@ extern "rust-intrinsic" {
     pub fn u32_mul_with_overflow(x: u32, y: u32) -> (u32, bool);
     /// Performs checked `u64` multiplication.
     pub fn u64_mul_with_overflow(x: u64, y: u64) -> (u64, bool);
+
+    /// Returns (a + b) mod 2^N, where N is the width of N in bits.
+    pub fn overflowing_add<T>(a: T, b: T) -> T;
+    /// Returns (a - b) mod 2^N, where N is the width of N in bits.
+    pub fn overflowing_sub<T>(a: T, b: T) -> T;
+    /// Returns (a * b) mod 2^N, where N is the width of N in bits.
+    pub fn overflowing_mul<T>(a: T, b: T) -> T;
 }
index 8fb10b5b2dc2a53ca3d40709ce7c2abcd46b6e66..42e90ec34db7ce97853ff8a734997604d7f439f4 100644 (file)
 //!
 //! # The `Iterator` trait
 //!
-//! This module defines Rust's core iteration trait. The `Iterator` trait has one
-//! unimplemented method, `next`. All other methods are derived through default
-//! methods to perform operations such as `zip`, `chain`, `enumerate`, and `fold`.
+//! This module defines Rust's core iteration trait. The `Iterator` trait has
+//! one unimplemented method, `next`. All other methods are derived through
+//! default methods to perform operations such as `zip`, `chain`, `enumerate`,
+//! and `fold`.
 //!
 //! The goal of this module is to unify iteration across all containers in Rust.
-//! An iterator can be considered as a state machine which is used to track which
-//! element will be yielded next.
+//! An iterator can be considered as a state machine which is used to track
+//! which element will be yielded next.
 //!
-//! There are various extensions also defined in this module to assist with various
-//! types of iteration, such as the `DoubleEndedIterator` for iterating in reverse,
-//! the `FromIterator` trait for creating a container from an iterator, and much
-//! more.
+//! There are various extensions also defined in this module to assist with
+//! various types of iteration, such as the `DoubleEndedIterator` for iterating
+//! in reverse, the `FromIterator` trait for creating a container from an
+//! iterator, and much more.
 //!
-//! ## Rust's `for` loop
+//! # Rust's `for` loop
 //!
-//! The special syntax used by rust's `for` loop is based around the `Iterator`
-//! trait defined in this module. For loops can be viewed as a syntactical expansion
-//! into a `loop`, for example, the `for` loop in this example is essentially
-//! translated to the `loop` below.
+//! The special syntax used by rust's `for` loop is based around the
+//! `IntoIterator` trait defined in this module. `for` loops can be viewed as a
+//! syntactical expansion into a `loop`, for example, the `for` loop in this
+//! example is essentially translated to the `loop` below.
 //!
 //! ```
 //! let values = vec![1, 2, 3];
 //!
-//! // "Syntactical sugar" taking advantage of an iterator
-//! for &x in values.iter() {
+//! for x in values {
 //!     println!("{}", x);
 //! }
 //!
 //! // Rough translation of the iteration without a `for` iterator.
-//! let mut it = values.iter();
+//! # let values = vec![1, 2, 3];
+//! let mut it = values.into_iter();
 //! loop {
 //!     match it.next() {
-//!         Some(&x) => {
-//!             println!("{}", x);
-//!         }
-//!         None => { break }
+//!         Some(x) => println!("{}", x),
+//!         None => break,
 //!     }
 //! }
 //! ```
 //!
-//! This `for` loop syntax can be applied to any iterator over any type.
+//! Because `Iterator`s implement `IntoIterator`, this `for` loop syntax can be applied to any
+//! iterator over any type.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -64,13 +64,14 @@ use cmp::Ord;
 use default::Default;
 use marker;
 use mem;
-use num::{ToPrimitive, Int};
-use ops::{Add, Deref, FnMut};
-use option::Option;
-use option::Option::{Some, None};
+use num::{Int, Zero, One};
+use ops::{self, Add, Sub, FnMut, RangeFrom};
+use option::Option::{self, Some, None};
 use marker::Sized;
 use usize;
 
+fn _assert_is_object_safe(_: &Iterator) {}
+
 /// An interface for dealing with "external iterators". These types of iterators
 /// can be resumed at any time as all state is stored internally as opposed to
 /// being located on the call stack.
@@ -83,77 +84,26 @@ use usize;
 /// else.
 #[lang="iterator"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling `.iter()` or a similar \
-                            method"]
+#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \
+                            `.iter()` or a similar method"]
 pub trait Iterator {
+    /// The type of the elements being iterated
     #[stable(feature = "rust1", since = "1.0.0")]
     type Item;
 
-    /// Advance the iterator and return the next value. Return `None` when the end is reached.
+    /// Advance the iterator and return the next value. Return `None` when the
+    /// end is reached.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn next(&mut self) -> Option<Self::Item>;
 
     /// Returns a lower and upper bound on the remaining length of the iterator.
     ///
-    /// An upper bound of `None` means either there is no known upper bound, or the upper bound
-    /// does not fit within a `usize`.
+    /// An upper bound of `None` means either there is no known upper bound, or
+    /// the upper bound does not fit within a `usize`.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn size_hint(&self) -> (usize, Option<usize>) { (0, None) }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I {
-    type Item = I::Item;
-    fn next(&mut self) -> Option<I::Item> { (**self).next() }
-    fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() }
-}
-
-/// Conversion from an `Iterator`
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented="a collection of type `{Self}` cannot be \
-                          built from an iterator over elements of type `{A}`"]
-pub trait FromIterator<A> {
-    /// Build a container with elements from something iterable.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn from_iter<T: IntoIterator<Item=A>>(iterator: T) -> Self;
-}
-
-/// Conversion into an `Iterator`
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait IntoIterator {
-    #[stable(feature = "rust1", since = "1.0.0")]
-    type Item;
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    type IntoIter: Iterator<Item=Self::Item>;
-
-    /// Consumes `Self` and returns an iterator over it
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn into_iter(self) -> Self::IntoIter;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator> IntoIterator for I {
-    type Item = I::Item;
-    type IntoIter = I;
-
-    fn into_iter(self) -> I {
-        self
-    }
-}
-
-/// A type growable from an `Iterator` implementation
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait Extend<A> {
-    /// Extend a container with the elements yielded by an arbitrary iterator
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn extend<T: IntoIterator<Item=A>>(&mut self, iterable: T);
-}
 
-/// An extension trait providing numerous methods applicable to all iterators.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait IteratorExt: Iterator + Sized {
     /// Counts the number of elements in this iterator.
     ///
     /// # Examples
@@ -164,12 +114,11 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn count(self) -> usize {
+    fn count(self) -> usize where Self: Sized {
         self.fold(0, |cnt, _x| cnt + 1)
     }
 
-    /// Loops through the entire iterator, returning the last element of the
-    /// iterator.
+    /// Loops through the entire iterator, returning the last element.
     ///
     /// # Examples
     ///
@@ -179,7 +128,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn last(self) -> Option<Self::Item> {
+    fn last(self) -> Option<Self::Item> where Self: Sized {
         let mut last = None;
         for x in self { last = Some(x); }
         last
@@ -198,7 +147,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
+    fn nth(&mut self, mut n: usize) -> Option<Self::Item> where Self: Sized {
         for x in self.by_ref() {
             if n == 0 { return Some(x) }
             n -= 1;
@@ -223,7 +172,7 @@ pub trait IteratorExt: Iterator + Sized {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn chain<U>(self, other: U) -> Chain<Self, U> where
-        U: Iterator<Item=Self::Item>,
+        Self: Sized, U: Iterator<Item=Self::Item>,
     {
         Chain{a: self, b: other, flag: false}
     }
@@ -242,9 +191,23 @@ pub trait IteratorExt: Iterator + Sized {
     /// assert_eq!(it.next().unwrap(), (&0, &1));
     /// assert!(it.next().is_none());
     /// ```
+    ///
+    /// `zip` can provide similar functionality to `enumerate`:
+    ///
+    /// ```
+    /// for pair in "foo".chars().enumerate() {
+    ///     println!("{:?}", pair);
+    /// }
+    ///
+    /// for pair in (0..).zip("foo".chars()) {
+    ///     println!("{:?}", pair);
+    /// }
+    /// ```
+    ///
+    /// both produce the same output.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn zip<U: Iterator>(self, other: U) -> Zip<Self, U> {
+    fn zip<U: Iterator>(self, other: U) -> Zip<Self, U> where Self: Sized {
         Zip{a: self, b: other}
     }
 
@@ -263,7 +226,7 @@ pub trait IteratorExt: Iterator + Sized {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn map<B, F>(self, f: F) -> Map<Self, F> where
-        F: FnMut(Self::Item) -> B,
+        Self: Sized, F: FnMut(Self::Item) -> B,
     {
         Map{iter: self, f: f}
     }
@@ -283,7 +246,7 @@ pub trait IteratorExt: Iterator + Sized {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn filter<P>(self, predicate: P) -> Filter<Self, P> where
-        P: FnMut(&Self::Item) -> bool,
+        Self: Sized, P: FnMut(&Self::Item) -> bool,
     {
         Filter{iter: self, predicate: predicate}
     }
@@ -303,7 +266,7 @@ pub trait IteratorExt: Iterator + Sized {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
-        F: FnMut(Self::Item) -> Option<B>,
+        Self: Sized, F: FnMut(Self::Item) -> Option<B>,
     {
         FilterMap { iter: self, f: f }
     }
@@ -311,6 +274,10 @@ pub trait IteratorExt: Iterator + Sized {
     /// Creates an iterator that yields a pair of the value returned by this
     /// iterator plus the current index of iteration.
     ///
+    /// `enumerate` keeps its count as a `usize`. If you want to count by a
+    /// different sized integer, the `zip` function provides similar
+    /// functionality.
+    ///
     /// # Examples
     ///
     /// ```
@@ -322,7 +289,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn enumerate(self) -> Enumerate<Self> {
+    fn enumerate(self) -> Enumerate<Self> where Self: Sized {
         Enumerate{iter: self, count: 0}
     }
 
@@ -332,6 +299,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let xs = [100, 200, 300];
     /// let mut it = xs.iter().cloned().peekable();
     /// assert_eq!(*it.peek().unwrap(), 100);
@@ -345,7 +313,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn peekable(self) -> Peekable<Self> {
+    fn peekable(self) -> Peekable<Self> where Self: Sized {
         Peekable{iter: self, peeked: None}
     }
 
@@ -366,7 +334,7 @@ pub trait IteratorExt: Iterator + Sized {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
-        P: FnMut(&Self::Item) -> bool,
+        Self: Sized, P: FnMut(&Self::Item) -> bool,
     {
         SkipWhile{iter: self, flag: false, predicate: predicate}
     }
@@ -387,7 +355,7 @@ pub trait IteratorExt: Iterator + Sized {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
-        P: FnMut(&Self::Item) -> bool,
+        Self: Sized, P: FnMut(&Self::Item) -> bool,
     {
         TakeWhile{iter: self, flag: false, predicate: predicate}
     }
@@ -406,7 +374,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn skip(self, n: usize) -> Skip<Self> {
+    fn skip(self, n: usize) -> Skip<Self> where Self: Sized {
         Skip{iter: self, n: n}
     }
 
@@ -425,7 +393,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn take(self, n: usize) -> Take<Self> {
+    fn take(self, n: usize) -> Take<Self> where Self: Sized, {
         Take{iter: self, n: n}
     }
 
@@ -452,7 +420,7 @@ pub trait IteratorExt: Iterator + Sized {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
-        where F: FnMut(&mut St, Self::Item) -> Option<B>,
+        where Self: Sized, F: FnMut(&mut St, Self::Item) -> Option<B>,
     {
         Scan{iter: self, f: f, state: initial_state}
     }
@@ -463,9 +431,10 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let xs = [2, 3];
     /// let ys = [0, 1, 0, 1, 2];
-    /// let it = xs.iter().flat_map(|&x| std::iter::count(0, 1).take(x));
+    /// let it = xs.iter().flat_map(|&x| (0..).take(x));
     /// // Check that `it` has the same elements as `ys`
     /// for (i, x) in it.enumerate() {
     ///     assert_eq!(x, ys[i]);
@@ -474,7 +443,7 @@ pub trait IteratorExt: Iterator + Sized {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
-        where U: Iterator, F: FnMut(Self::Item) -> U,
+        where Self: Sized, U: Iterator, F: FnMut(Self::Item) -> U,
     {
         FlatMap{iter: self, f: f, frontiter: None, backiter: None }
     }
@@ -486,7 +455,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
-    /// fn process<U: Iterator<Item=isize>>(it: U) -> isize {
+    /// fn process<U: Iterator<Item=i32>>(it: U) -> i32 {
     ///     let mut it = it.fuse();
     ///     let mut sum = 0;
     ///     for x in it.by_ref() {
@@ -508,7 +477,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn fuse(self) -> Fuse<Self> {
+    fn fuse(self) -> Fuse<Self> where Self: Sized {
         Fuse{iter: self, done: false}
     }
 
@@ -519,6 +488,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::iter::AdditiveIterator;
     ///
     /// let a = [1, 4, 2, 3, 8, 9, 6];
@@ -533,7 +503,7 @@ pub trait IteratorExt: Iterator + Sized {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn inspect<F>(self, f: F) -> Inspect<Self, F> where
-        F: FnMut(&Self::Item),
+        Self: Sized, F: FnMut(&Self::Item),
     {
         Inspect{iter: self, f: f}
     }
@@ -553,7 +523,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// assert!(it.next() == Some(5));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn by_ref(&mut self) -> &mut Self { self }
+    fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
 
     /// Loops through the entire iterator, collecting all of the elements into
     /// a container implementing `FromIterator`.
@@ -561,13 +531,13 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
-    /// let a = [1, 2, 3, 4, 5];
-    /// let b: Vec<_> = a.iter().cloned().collect();
-    /// assert_eq!(a, b);
+    /// let expected = [1, 2, 3, 4, 5];
+    /// let actual: Vec<_> = expected.iter().cloned().collect();
+    /// assert_eq!(actual, expected);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn collect<B: FromIterator<Self::Item>>(self) -> B {
+    fn collect<B: FromIterator<Self::Item>>(self) -> B where Self: Sized {
         FromIterator::from_iter(self)
     }
 
@@ -577,14 +547,15 @@ pub trait IteratorExt: Iterator + Sized {
     /// do not.
     ///
     /// ```
+    /// # #![feature(core)]
     /// let vec = vec![1, 2, 3, 4];
     /// let (even, odd): (Vec<_>, Vec<_>) = vec.into_iter().partition(|&n| n % 2 == 0);
-    /// assert_eq!(even, vec![2, 4]);
-    /// assert_eq!(odd, vec![1, 3]);
+    /// assert_eq!(even, [2, 4]);
+    /// assert_eq!(odd, [1, 3]);
     /// ```
-    #[unstable(feature = "core",
-               reason = "recently added as part of collections reform")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn partition<B, F>(self, mut f: F) -> (B, B) where
+        Self: Sized,
         B: Default + Extend<Self::Item>,
         F: FnMut(&Self::Item) -> bool
     {
@@ -609,12 +580,12 @@ pub trait IteratorExt: Iterator + Sized {
     ///
     /// ```
     /// let a = [1, 2, 3, 4, 5];
-    /// assert!(a.iter().fold(0, |a, &b| a + b) == 15);
+    /// assert!(a.iter().fold(0, |acc, &item| acc + item) == 15);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn fold<B, F>(self, init: B, mut f: F) -> B where
-        F: FnMut(B, Self::Item) -> B,
+        Self: Sized, F: FnMut(B, Self::Item) -> B,
     {
         let mut accum = init;
         for x in self {
@@ -634,27 +605,34 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn all<F>(self, mut f: F) -> bool where F: FnMut(Self::Item) -> bool {
-        for x in self { if !f(x) { return false; } }
+    fn all<F>(&mut self, mut f: F) -> bool where
+        Self: Sized, F: FnMut(Self::Item) -> bool
+    {
+        for x in self.by_ref() { if !f(x) { return false; } }
         true
     }
 
-    /// Tests whether any element of an iterator satisfies the specified predicate.
+    /// Tests whether any element of an iterator satisfies the specified
+    /// predicate.
     ///
     /// Does not consume the iterator past the first found element.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let a = [1, 2, 3, 4, 5];
     /// let mut it = a.iter();
     /// assert!(it.any(|x| *x == 3));
-    /// assert_eq!(it.as_slice(), [4, 5]);
+    /// assert_eq!(&it[..], [4, 5]);
     ///
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn any<F>(&mut self, mut f: F) -> bool where F: FnMut(Self::Item) -> bool {
+    fn any<F>(&mut self, mut f: F) -> bool where
+        Self: Sized,
+        F: FnMut(Self::Item) -> bool
+    {
         for x in self.by_ref() { if f(x) { return true; } }
         false
     }
@@ -666,13 +644,15 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let a = [1, 2, 3, 4, 5];
     /// let mut it = a.iter();
     /// assert_eq!(it.find(|&x| *x == 3).unwrap(), &3);
-    /// assert_eq!(it.as_slice(), [4, 5]);
+    /// assert_eq!(&it[..], [4, 5]);
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
+        Self: Sized,
         P: FnMut(&Self::Item) -> bool,
     {
         for x in self.by_ref() {
@@ -688,13 +668,15 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let a = [1, 2, 3, 4, 5];
     /// let mut it = a.iter();
     /// assert_eq!(it.position(|x| *x == 3).unwrap(), 2);
-    /// assert_eq!(it.as_slice(), [4, 5]);
+    /// assert_eq!(&it[..], [4, 5]);
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn position<P>(&mut self, mut predicate: P) -> Option<usize> where
+        Self: Sized,
         P: FnMut(Self::Item) -> bool,
     {
         let mut i = 0;
@@ -716,20 +698,22 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let a = [1, 2, 2, 4, 5];
     /// let mut it = a.iter();
     /// assert_eq!(it.rposition(|x| *x == 2).unwrap(), 2);
-    /// assert_eq!(it.as_slice(), [1, 2]);
+    /// assert_eq!(&it[..], [1, 2]);
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn rposition<P>(&mut self, mut predicate: P) -> Option<usize> where
         P: FnMut(Self::Item) -> bool,
-        Self: ExactSizeIterator + DoubleEndedIterator
+        Self: Sized + ExactSizeIterator + DoubleEndedIterator
     {
-        let mut i = self.len() - 1;
+        let mut i = self.len();
+
         while let Some(v) = self.next_back() {
             if predicate(v) {
-                return Some(i);
+                return Some(i - 1);
             }
             i -= 1;
         }
@@ -738,6 +722,9 @@ pub trait IteratorExt: Iterator + Sized {
 
     /// Consumes the entire iterator to return the maximum element.
     ///
+    /// Returns the rightmost element if the comparison determines two elements
+    /// to be equally maximum.
+    ///
     /// # Examples
     ///
     /// ```
@@ -746,18 +733,21 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn max(self) -> Option<Self::Item> where Self::Item: Ord
+    fn max(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord
     {
-        self.fold(None, |max, x| {
+        self.fold(None, |max, y| {
             match max {
-                None    => Some(x),
-                Some(y) => Some(cmp::max(x, y))
+                None    => Some(y),
+                Some(x) => Some(cmp::max(x, y))
             }
         })
     }
 
     /// Consumes the entire iterator to return the minimum element.
     ///
+    /// Returns the leftmost element if the comparison determines two elements
+    /// to be equally minimum.
+    ///
     /// # Examples
     ///
     /// ```
@@ -766,12 +756,12 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn min(self) -> Option<Self::Item> where Self::Item: Ord
+    fn min(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord
     {
-        self.fold(None, |min, x| {
+        self.fold(None, |min, y| {
             match min {
-                None    => Some(x),
-                Some(y) => Some(cmp::min(x, y))
+                None    => Some(y),
+                Some(x) => Some(cmp::min(x, y))
             }
         })
     }
@@ -787,14 +777,16 @@ pub trait IteratorExt: Iterator + Sized {
     ///    element in the iterator and all elements are equal.
     ///
     /// On an iterator of length `n`, `min_max` does `1.5 * n` comparisons,
-    /// and so is faster than calling `min` and `max` separately which does `2 * n` comparisons.
+    /// and so is faster than calling `min` and `max` separately which does `2 *
+    /// n` comparisons.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::iter::MinMaxResult::{NoElements, OneElement, MinMax};
     ///
-    /// let a: [isize; 0] = [];
+    /// let a: [i32; 0] = [];
     /// assert_eq!(a.iter().min_max(), NoElements);
     ///
     /// let a = [1];
@@ -807,23 +799,24 @@ pub trait IteratorExt: Iterator + Sized {
     /// assert!(a.iter().min_max() == MinMax(&1, &1));
     /// ```
     #[unstable(feature = "core", reason = "return type may change")]
-    fn min_max(mut self) -> MinMaxResult<Self::Item> where Self::Item: Ord
+    fn min_max(mut self) -> MinMaxResult<Self::Item> where Self: Sized, Self::Item: Ord
     {
         let (mut min, mut max) = match self.next() {
             None => return NoElements,
             Some(x) => {
                 match self.next() {
                     None => return OneElement(x),
-                    Some(y) => if x < y {(x, y)} else {(y,x)}
+                    Some(y) => if x <= y {(x, y)} else {(y, x)}
                 }
             }
         };
 
         loop {
-            // `first` and `second` are the two next elements we want to look at.
-            // We first compare `first` and `second` (#1). The smaller one is then compared to
-            // current minimum (#2). The larger one is compared to current maximum (#3). This
-            // way we do 3 comparisons for 2 elements.
+            // `first` and `second` are the two next elements we want to look
+            // at.  We first compare `first` and `second` (#1). The smaller one
+            // is then compared to current minimum (#2). The larger one is
+            // compared to current maximum (#3). This way we do 3 comparisons
+            // for 2 elements.
             let first = match self.next() {
                 None => break,
                 Some(x) => x
@@ -832,19 +825,19 @@ pub trait IteratorExt: Iterator + Sized {
                 None => {
                     if first < min {
                         min = first;
-                    } else if first > max {
+                    } else if first >= max {
                         max = first;
                     }
                     break;
                 }
                 Some(x) => x
             };
-            if first < second {
-                if first < min {min = first;}
-                if max < second {max = second;}
+            if first <= second {
+                if first < min { min = first }
+                if second >= max { max = second }
             } else {
-                if second < min {min = second;}
-                if max < first {max = first;}
+                if second < min { min = second }
+                if first >= max { max = first }
             }
         }
 
@@ -854,28 +847,32 @@ pub trait IteratorExt: Iterator + Sized {
     /// Return the element that gives the maximum value from the
     /// specified function.
     ///
+    /// Returns the rightmost element if the comparison determines two elements
+    /// to be equally maximum.
+    ///
     /// # Examples
     ///
     /// ```
-    /// use core::num::SignedInt;
+    /// # #![feature(core)]
     ///
-    /// let a = [-3, 0, 1, 5, -10];
+    /// let a = [-3_i32, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().max_by(|x| x.abs()).unwrap(), -10);
     /// ```
     #[inline]
     #[unstable(feature = "core",
                reason = "may want to produce an Ordering directly; see #15311")]
     fn max_by<B: Ord, F>(self, mut f: F) -> Option<Self::Item> where
+        Self: Sized,
         F: FnMut(&Self::Item) -> B,
     {
-        self.fold(None, |max: Option<(Self::Item, B)>, x| {
-            let x_val = f(&x);
+        self.fold(None, |max: Option<(Self::Item, B)>, y| {
+            let y_val = f(&y);
             match max {
-                None             => Some((x, x_val)),
-                Some((y, y_val)) => if x_val > y_val {
-                    Some((x, x_val))
-                } else {
+                None             => Some((y, y_val)),
+                Some((x, x_val)) => if y_val >= x_val {
                     Some((y, y_val))
+                } else {
+                    Some((x, x_val))
                 }
             }
         }).map(|(x, _)| x)
@@ -884,25 +881,29 @@ pub trait IteratorExt: Iterator + Sized {
     /// Return the element that gives the minimum value from the
     /// specified function.
     ///
+    /// Returns the leftmost element if the comparison determines two elements
+    /// to be equally minimum.
+    ///
     /// # Examples
     ///
     /// ```
-    /// use core::num::SignedInt;
+    /// # #![feature(core)]
     ///
-    /// let a = [-3, 0, 1, 5, -10];
+    /// let a = [-3_i32, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().min_by(|x| x.abs()).unwrap(), 0);
     /// ```
     #[inline]
     #[unstable(feature = "core",
                reason = "may want to produce an Ordering directly; see #15311")]
     fn min_by<B: Ord, F>(self, mut f: F) -> Option<Self::Item> where
+        Self: Sized,
         F: FnMut(&Self::Item) -> B,
     {
-        self.fold(None, |min: Option<(Self::Item, B)>, x| {
-            let x_val = f(&x);
+        self.fold(None, |min: Option<(Self::Item, B)>, y| {
+            let y_val = f(&y);
             match min {
-                None             => Some((x, x_val)),
-                Some((y, y_val)) => if x_val < y_val {
+                None             => Some((y, y_val)),
+                Some((x, x_val)) => if x_val <= y_val {
                     Some((x, x_val))
                 } else {
                     Some((y, y_val))
@@ -925,7 +926,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// `std::usize::MAX` elements of the original iterator.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn rev(self) -> Rev<Self> {
+    fn rev(self) -> Rev<Self> where Self: Sized {
         Rev{iter: self}
     }
 
@@ -937,16 +938,17 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let a = [(1, 2), (3, 4)];
     /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();
-    /// assert_eq!([1, 3], left);
-    /// assert_eq!([2, 4], right);
+    /// assert_eq!(left, [1, 3]);
+    /// assert_eq!(right, [2, 4]);
     /// ```
-    #[unstable(feature = "core", reason = "recent addition")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
         FromA: Default + Extend<A>,
         FromB: Default + Extend<B>,
-        Self: Iterator<Item=(A, B)>,
+        Self: Sized + Iterator<Item=(A, B)>,
     {
         struct SizeHint<A>(usize, Option<usize>, marker::PhantomData<A>);
         impl<A> Iterator for SizeHint<A> {
@@ -973,12 +975,11 @@ pub trait IteratorExt: Iterator + Sized {
         (ts, us)
     }
 
-    /// Creates an iterator that clones the elements it yields. Useful for converting an
-    /// Iterator<&T> to an Iterator<T>.
-    #[unstable(feature = "core", reason = "recent addition")]
-    fn cloned(self) -> Cloned<Self> where
-        Self::Item: Deref,
-        <Self::Item as Deref>::Output: Clone,
+    /// Creates an iterator that clones the elements it yields. Useful for
+    /// converting an Iterator<&T> to an Iterator<T>.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn cloned<'a, T: 'a>(self) -> Cloned<Self>
+        where Self: Sized + Iterator<Item=&'a T>, T: Clone
     {
         Cloned { it: self }
     }
@@ -996,7 +997,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    fn cycle(self) -> Cycle<Self> where Self: Clone {
+    fn cycle(self) -> Cycle<Self> where Self: Sized + Clone {
         Cycle{orig: self.clone(), iter: self}
     }
 
@@ -1004,7 +1005,7 @@ pub trait IteratorExt: Iterator + Sized {
     #[unstable(feature = "core",
                reason = "uncertain about placement or widespread use")]
     fn reverse_in_place<'a, T: 'a>(&mut self) where
-        Self: Iterator<Item=&'a mut T> + DoubleEndedIterator
+        Self: Sized + Iterator<Item=&'a mut T> + DoubleEndedIterator
     {
         loop {
             match (self.next(), self.next_back()) {
@@ -1016,7 +1017,80 @@ pub trait IteratorExt: Iterator + Sized {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I> IteratorExt for I where I: Iterator {}
+impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I {
+    type Item = I::Item;
+    fn next(&mut self) -> Option<I::Item> { (**self).next() }
+    fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() }
+}
+
+/// Conversion from an `Iterator`
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented="a collection of type `{Self}` cannot be \
+                          built from an iterator over elements of type `{A}`"]
+pub trait FromIterator<A> {
+    /// Build a container with elements from something iterable.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    /// use std::iter::FromIterator;
+    ///
+    /// let colors_vec = vec!["red", "red", "yellow", "blue"];
+    /// let colors_set = HashSet::<&str>::from_iter(colors_vec);
+    /// assert_eq!(colors_set.len(), 3);
+    /// ```
+    ///
+    /// `FromIterator` is more commonly used implicitly via the
+    /// `Iterator::collect` method:
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let colors_vec = vec!["red", "red", "yellow", "blue"];
+    /// let colors_set = colors_vec.into_iter().collect::<HashSet<&str>>();
+    /// assert_eq!(colors_set.len(), 3);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn from_iter<T: IntoIterator<Item=A>>(iterator: T) -> Self;
+}
+
+/// Conversion into an `Iterator`
+///
+/// Implementing this trait allows you to use your type with Rust's `for` loop. See
+/// the [module level documentation](../index.html) for more details.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait IntoIterator {
+    /// The type of the elements being iterated
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Item;
+
+    /// A container for iterating over elements of type Item
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type IntoIter: Iterator<Item=Self::Item>;
+
+    /// Consumes `Self` and returns an iterator over it
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn into_iter(self) -> Self::IntoIter;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I: Iterator> IntoIterator for I {
+    type Item = I::Item;
+    type IntoIter = I;
+
+    fn into_iter(self) -> I {
+        self
+    }
+}
+
+/// A type growable from an `Iterator` implementation
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Extend<A> {
+    /// Extend a container with the elements yielded by an arbitrary iterator
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn extend<T: IntoIterator<Item=A>>(&mut self, iterable: T);
+}
 
 /// A range iterator able to yield elements from both ends
 ///
@@ -1038,12 +1112,13 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
 
 /// An object implementing random access indexing by `usize`
 ///
-/// A `RandomAccessIterator` should be either infinite or a `DoubleEndedIterator`.
-/// Calling `next()` or `next_back()` on a `RandomAccessIterator`
-/// reduces the indexable range accordingly. That is, `it.idx(1)` will become `it.idx(0)`
-/// after `it.next()` is called.
+/// A `RandomAccessIterator` should be either infinite or a
+/// `DoubleEndedIterator`.  Calling `next()` or `next_back()` on a
+/// `RandomAccessIterator` reduces the indexable range accordingly. That is,
+/// `it.idx(1)` will become `it.idx(0)` after `it.next()` is called.
 #[unstable(feature = "core",
-           reason = "not widely used, may be better decomposed into Index and ExactSizeIterator")]
+           reason = "not widely used, may be better decomposed into Index \
+                     and ExactSizeIterator")]
 pub trait RandomAccessIterator: Iterator {
     /// Return the number of indexable elements. At most `std::usize::MAX`
     /// elements are indexable, even if the iterator represents a longer range.
@@ -1088,13 +1163,15 @@ impl<I: ExactSizeIterator, F> ExactSizeIterator for Inspect<I, F> where
     F: FnMut(&I::Item),
 {}
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I> ExactSizeIterator for Rev<I> where I: ExactSizeIterator + DoubleEndedIterator {}
+impl<I> ExactSizeIterator for Rev<I>
+    where I: ExactSizeIterator + DoubleEndedIterator {}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<B, I: ExactSizeIterator, F> ExactSizeIterator for Map<I, F> where
     F: FnMut(I::Item) -> B,
 {}
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B> ExactSizeIterator for Zip<A, B> where A: ExactSizeIterator, B: ExactSizeIterator {}
+impl<A, B> ExactSizeIterator for Zip<A, B>
+    where A: ExactSizeIterator, B: ExactSizeIterator {}
 
 /// An double-ended iterator with the direction inverted
 #[derive(Clone)]
@@ -1121,13 +1198,19 @@ impl<I> DoubleEndedIterator for Rev<I> where I: DoubleEndedIterator {
 }
 
 #[unstable(feature = "core", reason = "trait is experimental")]
-impl<I> RandomAccessIterator for Rev<I> where I: DoubleEndedIterator + RandomAccessIterator {
+impl<I> RandomAccessIterator for Rev<I>
+    where I: DoubleEndedIterator + RandomAccessIterator
+{
     #[inline]
     fn indexable(&self) -> usize { self.iter.indexable() }
     #[inline]
     fn idx(&mut self, index: usize) -> Option<<I as Iterator>::Item> {
         let amt = self.indexable();
-        self.iter.idx(amt - index - 1)
+        if amt > index {
+            self.iter.idx(amt - index - 1)
+        } else {
+            None
+        }
     }
 }
 
@@ -1140,9 +1223,10 @@ pub trait AdditiveIterator<A> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::iter::AdditiveIterator;
     ///
-    /// let a = [1i32, 2, 3, 4, 5];
+    /// let a = [1, 2, 3, 4, 5];
     /// let mut it = a.iter().cloned();
     /// assert!(it.sum() == 15);
     /// ```
@@ -1182,10 +1266,11 @@ pub trait MultiplicativeIterator<A> {
     /// # Examples
     ///
     /// ```
-    /// use std::iter::{count, MultiplicativeIterator};
+    /// # #![feature(core)]
+    /// use std::iter::MultiplicativeIterator;
     ///
     /// fn factorial(n: usize) -> usize {
-    ///     count(1, 1).take_while(|&i| i <= n).product()
+    ///     (1..).take_while(|&i| i <= n).product()
     /// }
     /// assert!(factorial(0) == 1);
     /// assert!(factorial(1) == 1);
@@ -1218,7 +1303,8 @@ impl_multiplicative! { usize, 1 }
 impl_multiplicative! { f32,  1.0 }
 impl_multiplicative! { f64,  1.0 }
 
-/// `MinMaxResult` is an enum returned by `min_max`. See `IteratorOrdExt::min_max` for more detail.
+/// `MinMaxResult` is an enum returned by `min_max`. See `Iterator::min_max` for
+/// more detail.
 #[derive(Clone, PartialEq, Debug)]
 #[unstable(feature = "core",
            reason = "unclear whether such a fine-grained result is widely useful")]
@@ -1229,22 +1315,25 @@ pub enum MinMaxResult<T> {
     /// Iterator with one element, so the minimum and maximum are the same
     OneElement(T),
 
-    /// More than one element in the iterator, the first element is not larger than the second
+    /// More than one element in the iterator, the first element is not larger
+    /// than the second
     MinMax(T, T)
 }
 
 impl<T: Clone> MinMaxResult<T> {
-    /// `into_option` creates an `Option` of type `(T,T)`. The returned `Option` has variant
-    /// `None` if and only if the `MinMaxResult` has variant `NoElements`. Otherwise variant
-    /// `Some(x,y)` is returned where `x <= y`. If `MinMaxResult` has variant `OneElement(x)`,
-    /// performing this operation will make one clone of `x`.
+    /// `into_option` creates an `Option` of type `(T,T)`. The returned `Option`
+    /// has variant `None` if and only if the `MinMaxResult` has variant
+    /// `NoElements`. Otherwise variant `Some(x,y)` is returned where `x <= y`.
+    /// If `MinMaxResult` has variant `OneElement(x)`, performing this operation
+    /// will make one clone of `x`.
     ///
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::iter::MinMaxResult::{self, NoElements, OneElement, MinMax};
     ///
-    /// let r: MinMaxResult<isize> = NoElements;
+    /// let r: MinMaxResult<i32> = NoElements;
     /// assert_eq!(r.into_option(), None);
     ///
     /// let r = OneElement(1);
@@ -1272,10 +1361,8 @@ pub struct Cloned<I> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, D, I> Iterator for Cloned<I> where
-    T: Clone,
-    D: Deref<Target=T>,
-    I: Iterator<Item=D>,
+impl<'a, I, T: 'a> Iterator for Cloned<I>
+    where I: Iterator<Item=&'a T>, T: Clone
 {
     type Item = T;
 
@@ -1289,10 +1376,8 @@ impl<T, D, I> Iterator for Cloned<I> where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, D, I> DoubleEndedIterator for Cloned<I> where
-    T: Clone,
-    D: Deref<Target=T>,
-    I: DoubleEndedIterator<Item=D>,
+impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I>
+    where I: DoubleEndedIterator<Item=&'a T>, T: Clone
 {
     fn next_back(&mut self) -> Option<T> {
         self.it.next_back().cloned()
@@ -1300,17 +1385,13 @@ impl<T, D, I> DoubleEndedIterator for Cloned<I> where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, D, I> ExactSizeIterator for Cloned<I> where
-    T: Clone,
-    D: Deref<Target=T>,
-    I: ExactSizeIterator<Item=D>,
+impl<'a, I, T: 'a> ExactSizeIterator for Cloned<I>
+    where I: ExactSizeIterator<Item=&'a T>, T: Clone
 {}
 
 #[unstable(feature = "core", reason = "trait is experimental")]
-impl<T, D, I> RandomAccessIterator for Cloned<I> where
-    T: Clone,
-    D: Deref<Target=T>,
-    I: RandomAccessIterator<Item=D>
+impl<'a, I, T: 'a> RandomAccessIterator for Cloned<I>
+    where I: RandomAccessIterator<Item=&'a T>, T: Clone
 {
     #[inline]
     fn indexable(&self) -> usize {
@@ -1393,11 +1474,14 @@ pub struct Chain<A, B> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, A, B> Iterator for Chain<A, B> where A: Iterator<Item=T>, B: Iterator<Item=T> {
-    type Item = T;
+impl<A, B> Iterator for Chain<A, B> where
+    A: Iterator,
+    B: Iterator<Item = A::Item>
+{
+    type Item = A::Item;
 
     #[inline]
-    fn next(&mut self) -> Option<T> {
+    fn next(&mut self) -> Option<A::Item> {
         if self.flag {
             self.b.next()
         } else {
@@ -1427,12 +1511,12 @@ impl<T, A, B> Iterator for Chain<A, B> where A: Iterator<Item=T>, B: Iterator<It
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, A, B> DoubleEndedIterator for Chain<A, B> where
-    A: DoubleEndedIterator<Item=T>,
-    B: DoubleEndedIterator<Item=T>,
+impl<A, B> DoubleEndedIterator for Chain<A, B> where
+    A: DoubleEndedIterator,
+    B: DoubleEndedIterator<Item=A::Item>,
 {
     #[inline]
-    fn next_back(&mut self) -> Option<T> {
+    fn next_back(&mut self) -> Option<A::Item> {
         match self.b.next_back() {
             Some(x) => Some(x),
             None => self.a.next_back()
@@ -1441,9 +1525,9 @@ impl<T, A, B> DoubleEndedIterator for Chain<A, B> where
 }
 
 #[unstable(feature = "core", reason = "trait is experimental")]
-impl<T, A, B> RandomAccessIterator for Chain<A, B> where
-    A: RandomAccessIterator<Item=T>,
-    B: RandomAccessIterator<Item=T>,
+impl<A, B> RandomAccessIterator for Chain<A, B> where
+    A: RandomAccessIterator,
+    B: RandomAccessIterator<Item = A::Item>,
 {
     #[inline]
     fn indexable(&self) -> usize {
@@ -1452,7 +1536,7 @@ impl<T, A, B> RandomAccessIterator for Chain<A, B> where
     }
 
     #[inline]
-    fn idx(&mut self, index: usize) -> Option<T> {
+    fn idx(&mut self, index: usize) -> Option<A::Item> {
         let len = self.a.indexable();
         if index < len {
             self.a.idx(index)
@@ -1472,14 +1556,12 @@ pub struct Zip<A, B> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, A, B> Iterator for Zip<A, B> where
-    A: Iterator<Item = T>,
-    B: Iterator<Item = U>,
+impl<A, B> Iterator for Zip<A, B> where A: Iterator, B: Iterator
 {
-    type Item = (T, U);
+    type Item = (A::Item, B::Item);
 
     #[inline]
-    fn next(&mut self) -> Option<(T, U)> {
+    fn next(&mut self) -> Option<(A::Item, B::Item)> {
         match self.a.next() {
             None => None,
             Some(x) => match self.b.next() {
@@ -1508,12 +1590,12 @@ impl<T, U, A, B> Iterator for Zip<A, B> where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, A, B> DoubleEndedIterator for Zip<A, B> where
-    A: DoubleEndedIterator + ExactSizeIterator<Item=T>,
-    B: DoubleEndedIterator + ExactSizeIterator<Item=U>,
+impl<A, B> DoubleEndedIterator for Zip<A, B> where
+    A: DoubleEndedIterator + ExactSizeIterator,
+    B: DoubleEndedIterator + ExactSizeIterator,
 {
     #[inline]
-    fn next_back(&mut self) -> Option<(T, U)> {
+    fn next_back(&mut self) -> Option<(A::Item, B::Item)> {
         let a_sz = self.a.len();
         let b_sz = self.b.len();
         if a_sz != b_sz {
@@ -1533,9 +1615,9 @@ impl<T, U, A, B> DoubleEndedIterator for Zip<A, B> where
 }
 
 #[unstable(feature = "core", reason = "trait is experimental")]
-impl<T, U, A, B> RandomAccessIterator for Zip<A, B> where
-    A: RandomAccessIterator<Item=T>,
-    B: RandomAccessIterator<Item=U>,
+impl<A, B> RandomAccessIterator for Zip<A, B> where
+    A: RandomAccessIterator,
+    B: RandomAccessIterator
 {
     #[inline]
     fn indexable(&self) -> usize {
@@ -1543,7 +1625,7 @@ impl<T, U, A, B> RandomAccessIterator for Zip<A, B> where
     }
 
     #[inline]
-    fn idx(&mut self, index: usize) -> Option<(T, U)> {
+    fn idx(&mut self, index: usize) -> Option<(A::Item, B::Item)> {
         match self.a.idx(index) {
             None => None,
             Some(x) => match self.b.idx(index) {
@@ -1563,24 +1645,13 @@ pub struct Map<I, F> {
     f: F,
 }
 
-impl<I: Iterator, F, B> Map<I, F> where F: FnMut(I::Item) -> B {
-    #[inline]
-    fn do_map(&mut self, elt: Option<I::Item>) -> Option<B> {
-        match elt {
-            Some(a) => Some((self.f)(a)),
-            _ => None
-        }
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<B, I: Iterator, F> Iterator for Map<I, F> where F: FnMut(I::Item) -> B {
     type Item = B;
 
     #[inline]
     fn next(&mut self) -> Option<B> {
-        let next = self.iter.next();
-        self.do_map(next)
+        self.iter.next().map(|a| (self.f)(a))
     }
 
     #[inline]
@@ -1595,8 +1666,7 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F> where
 {
     #[inline]
     fn next_back(&mut self) -> Option<B> {
-        let next = self.iter.next_back();
-        self.do_map(next)
+        self.iter.next_back().map(|a| (self.f)(a))
     }
 }
 
@@ -1611,8 +1681,7 @@ impl<B, I: RandomAccessIterator, F> RandomAccessIterator for Map<I, F> where
 
     #[inline]
     fn idx(&mut self, index: usize) -> Option<B> {
-        let elt = self.iter.idx(index);
-        self.do_map(elt)
+        self.iter.idx(index).map(|a| (self.f)(a))
     }
 }
 
@@ -1634,8 +1703,6 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
         for x in self.iter.by_ref() {
             if (self.predicate)(&x) {
                 return Some(x);
-            } else {
-                continue
             }
         }
         None
@@ -2061,12 +2128,14 @@ pub struct Scan<I, St, F> {
     f: F,
 
     /// The current internal state to be passed to the closure next.
+    #[unstable(feature = "core")]
     pub state: St,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B, I: Iterator<Item=A>, St, F> Iterator for Scan<I, St, F> where
-    F: FnMut(&mut St, A) -> Option<B>,
+impl<B, I, St, F> Iterator for Scan<I, St, F> where
+    I: Iterator,
+    F: FnMut(&mut St, I::Item) -> Option<B>,
 {
     type Item = B;
 
@@ -2301,11 +2370,12 @@ impl<I: RandomAccessIterator, F> RandomAccessIterator for Inspect<I, F>
 
 /// An iterator that passes mutable state to a closure and yields the result.
 ///
-/// # Example: The Fibonacci Sequence
+/// # Examples
 ///
 /// An iterator that yields sequential Fibonacci numbers, and stops on overflow.
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::iter::Unfold;
 /// use std::num::Int; // For `.checked_add()`
 ///
@@ -2338,6 +2408,7 @@ impl<I: RandomAccessIterator, F> RandomAccessIterator for Inspect<I, F>
 pub struct Unfold<St, F> {
     f: F,
     /// Internal state that will be passed to the closure on the next iteration
+    #[unstable(feature = "core")]
     pub state: St,
 }
 
@@ -2370,140 +2441,152 @@ impl<A, St, F> Iterator for Unfold<St, F> where F: FnMut(&mut St) -> Option<A> {
     }
 }
 
-/// An infinite iterator starting at `start` and advancing by `step` with each
-/// iteration
-#[derive(Clone)]
-#[unstable(feature = "core",
-           reason = "may be renamed or replaced by range notation adapters")]
-pub struct Counter<A> {
-    /// The current state the counter is at (next value to be yielded)
-    state: A,
-    /// The amount that this iterator is stepping by
-    step: A,
+/// Objects that can be stepped over in both directions.
+///
+/// The `steps_between` function provides a way to efficiently compare
+/// two `Step` objects.
+#[unstable(feature = "step_trait",
+           reason = "likely to be replaced by finer-grained traits")]
+pub trait Step: Ord {
+    /// Steps `self` if possible.
+    fn step(&self, by: &Self) -> Option<Self>;
+
+    /// The number of steps between two step objects.
+    ///
+    /// `start` should always be less than `end`, so the result should never
+    /// be negative.
+    ///
+    /// Return `None` if it is not possible to calculate steps_between
+    /// without overflow.
+    fn steps_between(start: &Self, end: &Self, by: &Self) -> Option<usize>;
 }
 
-/// Creates a new counter with the specified start/step
-#[inline]
-#[unstable(feature = "core",
-           reason = "may be renamed or replaced by range notation adapters")]
-pub fn count<A>(start: A, step: A) -> Counter<A> {
-    Counter{state: start, step: step}
+macro_rules! step_impl {
+    ($($t:ty)*) => ($(
+        impl Step for $t {
+            #[inline]
+            fn step(&self, by: &$t) -> Option<$t> {
+                (*self).checked_add(*by)
+            }
+            #[inline]
+            #[allow(trivial_numeric_casts)]
+            fn steps_between(start: &$t, end: &$t, by: &$t) -> Option<usize> {
+                if *start <= *end {
+                    Some(((*end - *start) / *by) as usize)
+                } else {
+                    Some(0)
+                }
+            }
+        }
+    )*)
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Add<Output=A> + Clone> Iterator for Counter<A> {
-    type Item = A;
+macro_rules! step_impl_no_between {
+    ($($t:ty)*) => ($(
+        impl Step for $t {
+            #[inline]
+            fn step(&self, by: &$t) -> Option<$t> {
+                (*self).checked_add(*by)
+            }
+            #[inline]
+            fn steps_between(_a: &$t, _b: &$t, _by: &$t) -> Option<usize> {
+                None
+            }
+        }
+    )*)
+}
 
-    #[inline]
-    fn next(&mut self) -> Option<A> {
-        let result = self.state.clone();
-        self.state = self.state.clone() + self.step.clone();
-        Some(result)
-    }
+step_impl!(usize u8 u16 u32 isize i8 i16 i32);
+#[cfg(target_pointer_width = "64")]
+step_impl!(u64 i64);
+#[cfg(target_pointer_width = "32")]
+step_impl_no_between!(u64 i64);
 
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (usize::MAX, None) // Too bad we can't specify an infinite lower bound
-    }
+/// An adapter for stepping range iterators by a custom amount.
+///
+/// The resulting iterator handles overflow by stopping. The `A`
+/// parameter is the type being iterated over, while `R` is the range
+/// type (usually one of `std::ops::{Range, RangeFrom}`.
+#[derive(Clone)]
+#[unstable(feature = "step_by", reason = "recent addition")]
+pub struct StepBy<A, R> {
+    step_by: A,
+    range: R,
 }
 
-/// An iterator over the range [start, stop)
-#[derive(Clone)]
-#[unstable(feature = "core",
-           reason = "will be replaced by range notation")]
-pub struct Range<A> {
-    state: A,
-    stop: A,
-    one: A,
+impl<A: Step> RangeFrom<A> {
+    /// Creates an iterator starting at the same point, but stepping by
+    /// the given amount at each iteration.
+    ///
+    /// # Examples
+    ///
+    /// ```ignore
+    /// for i in (0u8..).step_by(2) {
+    ///     println!("{}", i);
+    /// }
+    /// ```
+    ///
+    /// This prints all even `u8` values.
+    #[unstable(feature = "step_by", reason = "recent addition")]
+    pub fn step_by(self, by: A) -> StepBy<A, Self> {
+        StepBy {
+            step_by: by,
+            range: self
+        }
+    }
 }
 
-/// Returns an iterator over the given range [start, stop) (that is, starting
-/// at start (inclusive), and ending at stop (exclusive)).
-///
-/// # Examples
-///
-/// ```
-/// let array = [0, 1, 2, 3, 4];
-///
-/// for i in range(0, 5) {
-///     println!("{}", i);
-///     assert_eq!(i,  array[i]);
-/// }
-/// ```
-#[inline]
-#[unstable(feature = "core",
-           reason = "will be replaced by range notation")]
-pub fn range<A: Int>(start: A, stop: A) -> Range<A> {
-    Range {
-        state: start,
-        stop: stop,
-        one: Int::one(),
+#[allow(deprecated)]
+impl<A: Step> ops::Range<A> {
+    /// Creates an iterator with the same range, but stepping by the
+    /// given amount at each iteration.
+    ///
+    /// The resulting iterator handles overflow by stopping.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(step_by, core)]
+    /// for i in (0..10).step_by(2) {
+    ///     println!("{}", i);
+    /// }
+    /// ```
+    ///
+    /// This prints:
+    ///
+    /// ```text
+    /// 0
+    /// 2
+    /// 4
+    /// 6
+    /// 8
+    /// ```
+    #[unstable(feature = "step_by", reason = "recent addition")]
+    pub fn step_by(self, by: A) -> StepBy<A, Self> {
+        StepBy {
+            step_by: by,
+            range: self
+        }
     }
 }
 
-// FIXME: #10414: Unfortunate type bound
-#[unstable(feature = "core",
-           reason = "will be replaced by range notation")]
-impl<A: Int + ToPrimitive> Iterator for Range<A> {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A> Iterator for StepBy<A, RangeFrom<A>> where
+    A: Clone,
+    for<'a> &'a A: Add<&'a A, Output = A>
+{
     type Item = A;
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        if self.state < self.stop {
-            let result = self.state.clone();
-            self.state = self.state + self.one;
-            Some(result)
-        } else {
-            None
-        }
+        let mut n = &self.range.start + &self.step_by;
+        mem::swap(&mut n, &mut self.range.start);
+        Some(n)
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        // This first checks if the elements are representable as i64. If they aren't, try u64 (to
-        // handle cases like range(huge, huger)). We don't use usize/isize because the difference of
-        // the i64/u64 might lie within their range.
-        let bound = match self.state.to_i64() {
-            Some(a) => {
-                let sz = self.stop.to_i64().map(|b| b.checked_sub(a));
-                match sz {
-                    Some(Some(bound)) => bound.to_uint(),
-                    _ => None,
-                }
-            },
-            None => match self.state.to_u64() {
-                Some(a) => {
-                    let sz = self.stop.to_u64().map(|b| b.checked_sub(a));
-                    match sz {
-                        Some(Some(bound)) => bound.to_uint(),
-                        _ => None
-                    }
-                },
-                None => None
-            }
-        };
-
-        match bound {
-            Some(b) => (b, Some(b)),
-            // Standard fallback for unbounded/unrepresentable bounds
-            None => (0, None)
-        }
-    }
-}
-
-/// `Int` is required to ensure the range will be the same regardless of
-/// the direction it is consumed.
-#[unstable(feature = "core",
-           reason = "will be replaced by range notation")]
-impl<A: Int + ToPrimitive> DoubleEndedIterator for Range<A> {
-    #[inline]
-    fn next_back(&mut self) -> Option<A> {
-        if self.stop > self.state {
-            self.stop = self.stop - self.one;
-            Some(self.stop.clone())
-        } else {
-            None
-        }
+        (usize::MAX, None) // Too bad we can't specify an infinite lower bound
     }
 }
 
@@ -2512,7 +2595,7 @@ impl<A: Int + ToPrimitive> DoubleEndedIterator for Range<A> {
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
 pub struct RangeInclusive<A> {
-    range: Range<A>,
+    range: ops::Range<A>,
     done: bool,
 }
 
@@ -2520,16 +2603,18 @@ pub struct RangeInclusive<A> {
 #[inline]
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
-pub fn range_inclusive<A: Int>(start: A, stop: A) -> RangeInclusive<A> {
+pub fn range_inclusive<A>(start: A, stop: A) -> RangeInclusive<A>
+    where A: Step + One + Clone
+{
     RangeInclusive {
-        range: range(start, stop),
+        range: start..stop,
         done: false,
     }
 }
 
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
-impl<A: Int + ToPrimitive> Iterator for RangeInclusive<A> {
+impl<A: Step + One + Clone> Iterator for RangeInclusive<A> {
     type Item = A;
 
     #[inline]
@@ -2537,9 +2622,9 @@ impl<A: Int + ToPrimitive> Iterator for RangeInclusive<A> {
         match self.range.next() {
             Some(x) => Some(x),
             None => {
-                if !self.done && self.range.state == self.range.stop {
+                if !self.done && self.range.start == self.range.end {
                     self.done = true;
-                    Some(self.range.stop.clone())
+                    Some(self.range.end.clone())
                 } else {
                     None
                 }
@@ -2565,56 +2650,47 @@ impl<A: Int + ToPrimitive> Iterator for RangeInclusive<A> {
 
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
-impl<A: Int + ToPrimitive> DoubleEndedIterator for RangeInclusive<A> {
+impl<A> DoubleEndedIterator for RangeInclusive<A>
+    where A: Step + One + Clone,
+          for<'a> &'a A: Sub<Output=A>
+{
     #[inline]
     fn next_back(&mut self) -> Option<A> {
-        if self.range.stop > self.range.state {
-            let result = self.range.stop.clone();
-            self.range.stop = self.range.stop - self.range.one;
+        if self.range.end > self.range.start {
+            let result = self.range.end.clone();
+            self.range.end = &self.range.end - &A::one();
             Some(result)
-        } else if !self.done && self.range.state == self.range.stop {
+        } else if !self.done && self.range.start == self.range.end {
             self.done = true;
-            Some(self.range.stop.clone())
+            Some(self.range.end.clone())
         } else {
             None
         }
     }
 }
 
-/// An iterator over the range [start, stop) by `step`. It handles overflow by stopping.
-#[derive(Clone)]
-#[unstable(feature = "core",
-           reason = "likely to be replaced by range notation and adapters")]
-pub struct RangeStep<A> {
-    state: A,
-    stop: A,
-    step: A,
-    rev: bool,
-}
-
-/// Return an iterator over the range [start, stop) by `step`. It handles overflow by stopping.
-#[inline]
-#[unstable(feature = "core",
-           reason = "likely to be replaced by range notation and adapters")]
-pub fn range_step<A: Int>(start: A, stop: A, step: A) -> RangeStep<A> {
-    let rev = step < Int::zero();
-    RangeStep{state: start, stop: stop, step: step, rev: rev}
-}
-
-#[unstable(feature = "core",
-           reason = "likely to be replaced by range notation and adapters")]
-impl<A: Int> Iterator for RangeStep<A> {
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
+impl<A: Step + Zero + Clone> Iterator for StepBy<A, ops::Range<A>> {
     type Item = A;
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) {
-            let result = self.state;
-            match self.state.checked_add(self.step) {
-                Some(x) => self.state = x,
-                None => self.state = self.stop.clone()
+        let rev = self.step_by < A::zero();
+        if (rev && self.range.start > self.range.end) ||
+           (!rev && self.range.start < self.range.end)
+        {
+            match self.range.start.step(&self.step_by) {
+                Some(mut n) => {
+                    mem::swap(&mut self.range.start, &mut n);
+                    Some(n)
+                },
+                None => {
+                    let mut n = self.range.end.clone();
+                    mem::swap(&mut self.range.start, &mut n);
+                    Some(n)
+                }
             }
-            Some(result)
         } else {
             None
         }
@@ -2633,10 +2709,35 @@ pub struct RangeStepInclusive<A> {
     done: bool,
 }
 
-/// Return an iterator over the range [start, stop] by `step`. It handles overflow by stopping.
+/// Return an iterator over the range [start, stop] by `step`.
+///
+/// It handles overflow by stopping.
+///
+/// # Examples
+///
+/// ```
+/// # #![feature(core)]
+/// use std::iter::range_step_inclusive;
+///
+/// for i in range_step_inclusive(0, 10, 2) {
+///     println!("{}", i);
+/// }
+/// ```
+///
+/// This prints:
+///
+/// ```text
+/// 0
+/// 2
+/// 4
+/// 6
+/// 8
+/// 10
+/// ```
 #[inline]
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
+#[allow(deprecated)]
 pub fn range_step_inclusive<A: Int>(start: A, stop: A, step: A) -> RangeStepInclusive<A> {
     let rev = step < Int::zero();
     RangeStepInclusive {
@@ -2650,6 +2751,7 @@ pub fn range_step_inclusive<A: Int>(start: A, stop: A, step: A) -> RangeStepIncl
 
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
+#[allow(deprecated)]
 impl<A: Int> Iterator for RangeStepInclusive<A> {
     type Item = A;
 
@@ -2672,20 +2774,30 @@ impl<A: Int> Iterator for RangeStepInclusive<A> {
 macro_rules! range_exact_iter_impl {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl ExactSizeIterator for ::ops::Range<$t> { }
+        impl ExactSizeIterator for ops::Range<$t> { }
     )*)
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Int> Iterator for ::ops::Range<A> {
+#[allow(deprecated)]
+impl<A: Step + One + Clone> Iterator for ops::Range<A> {
     type Item = A;
 
     #[inline]
     fn next(&mut self) -> Option<A> {
         if self.start < self.end {
-            let result = self.start;
-            self.start = self.start + Int::one();
-            Some(result)
+            match self.start.step(&A::one()) {
+                Some(mut n) => {
+                    mem::swap(&mut n, &mut self.start);
+                    Some(n)
+                },
+                None => {
+                    let mut n = self.end.clone();
+                    mem::swap(&mut n, &mut self.start);
+                    Some(n)
+
+                }
+            }
         } else {
             None
         }
@@ -2693,11 +2805,10 @@ impl<A: Int> Iterator for ::ops::Range<A> {
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        if self.start >= self.end {
-            (0, Some(0))
+        if let Some(hint) = Step::steps_between(&self.start, &self.end, &A::one()) {
+            (hint, Some(hint))
         } else {
-            let length = (self.end - self.start).to_uint();
-            (length.unwrap_or(0), length)
+            (0, None)
         }
     }
 }
@@ -2707,12 +2818,15 @@ impl<A: Int> Iterator for ::ops::Range<A> {
 range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Int> DoubleEndedIterator for ::ops::Range<A> {
+#[allow(deprecated)]
+impl<A: Step + One + Clone> DoubleEndedIterator for ops::Range<A> where
+    for<'a> &'a A: Sub<&'a A, Output = A>
+{
     #[inline]
     fn next_back(&mut self) -> Option<A> {
         if self.start < self.end {
-            self.end = self.end - Int::one();
-            Some(self.end)
+            self.end = &self.end - &A::one();
+            Some(self.end.clone())
         } else {
             None
         }
@@ -2720,15 +2834,16 @@ impl<A: Int> DoubleEndedIterator for ::ops::Range<A> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Int> Iterator for ::ops::RangeFrom<A> {
+#[allow(deprecated)]
+impl<A: Step + One> Iterator for ops::RangeFrom<A> {
     type Item = A;
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        let result = self.start;
-        self.start = self.start + Int::one();
-        debug_assert!(result < self.start);
-        Some(result)
+        self.start.step(&A::one()).map(|mut n| {
+            mem::swap(&mut n, &mut self.start);
+            n
+        })
     }
 }
 
@@ -2825,10 +2940,10 @@ pub mod order {
     use super::Iterator;
 
     /// Compare `a` and `b` for equality using `Eq`
-    pub fn equals<A, T, S>(mut a: T, mut b: S) -> bool where
+    pub fn equals<A, L, R>(mut a: L, mut b: R) -> bool where
         A: Eq,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+        L: Iterator<Item=A>,
+        R: Iterator<Item=A>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2840,10 +2955,10 @@ pub mod order {
     }
 
     /// Order `a` and `b` lexicographically using `Ord`
-    pub fn cmp<A, T, S>(mut a: T, mut b: S) -> cmp::Ordering where
+    pub fn cmp<A, L, R>(mut a: L, mut b: R) -> cmp::Ordering where
         A: Ord,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+        L: Iterator<Item=A>,
+        R: Iterator<Item=A>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2859,10 +2974,8 @@ pub mod order {
     }
 
     /// Order `a` and `b` lexicographically using `PartialOrd`
-    pub fn partial_cmp<A, T, S>(mut a: T, mut b: S) -> Option<cmp::Ordering> where
-        A: PartialOrd,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+    pub fn partial_cmp<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> Option<cmp::Ordering> where
+        L::Item: PartialOrd<R::Item>
     {
         loop {
             match (a.next(), b.next()) {
@@ -2878,10 +2991,8 @@ pub mod order {
     }
 
     /// Compare `a` and `b` for equality (Using partial equality, `PartialEq`)
-    pub fn eq<A, B, L, R>(mut a: L, mut b: R) -> bool where
-        A: PartialEq<B>,
-        L: Iterator<Item=A>,
-        R: Iterator<Item=B>,
+    pub fn eq<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
+        L::Item: PartialEq<R::Item>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2893,10 +3004,8 @@ pub mod order {
     }
 
     /// Compare `a` and `b` for nonequality (Using partial equality, `PartialEq`)
-    pub fn ne<A, B, L, R>(mut a: L, mut b: R) -> bool where
-        A: PartialEq<B>,
-        L: Iterator<Item=A>,
-        R: Iterator<Item=B>,
+    pub fn ne<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
+        L::Item: PartialEq<R::Item>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2908,10 +3017,8 @@ pub mod order {
     }
 
     /// Return `a` < `b` lexicographically (Using partial order, `PartialOrd`)
-    pub fn lt<A, T, S>(mut a: T, mut b: S) -> bool where
-        A: PartialOrd,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+    pub fn lt<R: Iterator, L: Iterator>(mut a: L, mut b: R) -> bool where
+        L::Item: PartialOrd<R::Item>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2924,10 +3031,8 @@ pub mod order {
     }
 
     /// Return `a` <= `b` lexicographically (Using partial order, `PartialOrd`)
-    pub fn le<A, T, S>(mut a: T, mut b: S) -> bool where
-        A: PartialOrd,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+    pub fn le<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
+        L::Item: PartialOrd<R::Item>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2940,10 +3045,8 @@ pub mod order {
     }
 
     /// Return `a` > `b` lexicographically (Using partial order, `PartialOrd`)
-    pub fn gt<A, T, S>(mut a: T, mut b: S) -> bool where
-        A: PartialOrd,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+    pub fn gt<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
+        L::Item: PartialOrd<R::Item>,
     {
         loop {
             match (a.next(), b.next()) {
@@ -2956,10 +3059,8 @@ pub mod order {
     }
 
     /// Return `a` >= `b` lexicographically (Using partial order, `PartialOrd`)
-    pub fn ge<A, T, S>(mut a: T, mut b: S) -> bool where
-        A: PartialOrd,
-        T: Iterator<Item=A>,
-        S: Iterator<Item=A>,
+    pub fn ge<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
+        L::Item: PartialOrd<R::Item>,
     {
         loop {
             match (a.next(), b.next()) {
index 3c58480ff0cfa1d70275b9f04bf6931782575468..2189e2c3ad1baca6a42e615d71f4b3c26190f865 100644 (file)
 //!   often generated by LLVM. Additionally, this library can make explicit
 //!   calls to these functions. Their signatures are the same as found in C.
 //!   These functions are often provided by the system libc, but can also be
-//!   provided by `librlibc` which is distributed with the standard rust
-//!   distribution.
+//!   provided by the [rlibc crate](https://crates.io/crates/rlibc).
 //!
 //! * `rust_begin_unwind` - This function takes three arguments, a
-//!   `fmt::Arguments`, a `&str`, and a `uint`. These three arguments dictate
+//!   `fmt::Arguments`, a `&str`, and a `usize`. These three arguments dictate
 //!   the panic message, the file at which panic was invoked, and the line.
 //!   It is up to consumers of this core library to define this panic
 //!   function; it is only required to never return.
@@ -47,6 +46,8 @@
 // Since libcore defines many fundamental lang items, all tests live in a
 // separate crate, libcoretest, to avoid bizarre issues.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "core"]
 #![unstable(feature = "core")]
 #![staged_api]
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
+#![doc(test(no_crate_inject))]
 
 #![feature(no_std)]
 #![no_std]
 #![allow(raw_pointer_derive)]
 #![deny(missing_docs)]
 
-#![feature(int_uint)]
 #![feature(intrinsics, lang_items)]
 #![feature(on_unimplemented)]
 #![feature(simd, unsafe_destructor)]
 #![feature(staged_api)]
 #![feature(unboxed_closures)]
 #![feature(rustc_attrs)]
+#![feature(optin_builtin_traits)]
+#![feature(fundamental)]
+#![feature(concat_idents)]
+#![feature(reflect)]
+#![feature(custom_attribute)]
 
 #[macro_use]
 mod macros;
 
+#[macro_use]
+mod cmp_macros;
+
 #[path = "num/float_macros.rs"]
 #[macro_use]
 mod float_macros;
@@ -84,14 +93,12 @@ mod int_macros;
 #[macro_use]
 mod uint_macros;
 
-#[path = "num/int.rs"]  pub mod int;
 #[path = "num/isize.rs"]  pub mod isize;
 #[path = "num/i8.rs"]   pub mod i8;
 #[path = "num/i16.rs"]  pub mod i16;
 #[path = "num/i32.rs"]  pub mod i32;
 #[path = "num/i64.rs"]  pub mod i64;
 
-#[path = "num/uint.rs"] pub mod uint;
 #[path = "num/usize.rs"] pub mod usize;
 #[path = "num/u8.rs"]   pub mod u8;
 #[path = "num/u16.rs"]  pub mod u16;
@@ -121,15 +128,16 @@ pub mod ops;
 pub mod cmp;
 pub mod clone;
 pub mod default;
+pub mod convert;
 
 /* Core types and methods on primitives */
 
 pub mod any;
+pub mod array;
 pub mod atomic;
 pub mod cell;
 pub mod char;
 pub mod panicking;
-pub mod finally;
 pub mod iter;
 pub mod option;
 pub mod raw;
@@ -139,7 +147,6 @@ pub mod slice;
 pub mod str;
 pub mod hash;
 pub mod fmt;
-pub mod error;
 
 #[doc(primitive = "bool")]
 mod bool {
@@ -147,7 +154,6 @@ mod bool {
 
 // note: does not need to be public
 mod tuple;
-mod array;
 
 #[doc(hidden)]
 mod core {
index 943365d8454d4629ed65a6757aa17ef28817e961..751bd7353e4cbba9d861b22c98c10419239997a4 100644 (file)
@@ -15,7 +15,7 @@ macro_rules! panic {
         panic!("explicit panic")
     );
     ($msg:expr) => ({
-        static _MSG_FILE_LINE: (&'static str, &'static str, usize) = ($msg, file!(), line!());
+        static _MSG_FILE_LINE: (&'static str, &'static str, u32) = ($msg, file!(), line!());
         ::core::panicking::panic(&_MSG_FILE_LINE)
     });
     ($fmt:expr, $($arg:tt)*) => ({
@@ -23,7 +23,7 @@ macro_rules! panic {
         // used inside a dead function. Just `#[allow(dead_code)]` is
         // insufficient, since the user may have
         // `#[forbid(dead_code)]` and which cannot be overridden.
-        static _FILE_LINE: (&'static str, usize) = (file!(), line!());
+        static _FILE_LINE: (&'static str, u32) = (file!(), line!());
         ::core::panicking::panic_fmt(format_args!($fmt, $($arg)*), &_FILE_LINE)
     });
 }
@@ -33,7 +33,7 @@ macro_rules! panic {
 /// This will invoke the `panic!` macro if the provided expression cannot be
 /// evaluated to `true` at runtime.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// // the panic message for these assertions is the stringified value of the
@@ -66,12 +66,12 @@ macro_rules! assert {
     );
 }
 
-/// Asserts that two expressions are equal to each other, testing equality in
-/// both directions.
+/// Asserts that two expressions are equal to each other.
 ///
-/// On panic, this macro will print the values of the expressions.
+/// On panic, this macro will print the values of the expressions with their
+/// debug representations.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// let a = 3;
@@ -84,10 +84,8 @@ macro_rules! assert_eq {
     ($left:expr , $right:expr) => ({
         match (&($left), &($right)) {
             (left_val, right_val) => {
-                // check both directions of equality....
-                if !((*left_val == *right_val) &&
-                     (*right_val == *left_val)) {
-                    panic!("assertion failed: `(left == right) && (right == left)` \
+                if !(*left_val == *right_val) {
+                    panic!("assertion failed: `(left == right)` \
                            (left: `{:?}`, right: `{:?}`)", *left_val, *right_val)
                 }
             }
@@ -100,12 +98,14 @@ macro_rules! assert_eq {
 /// This will invoke the `panic!` macro if the provided expression cannot be
 /// evaluated to `true` at runtime.
 ///
-/// Unlike `assert!`, `debug_assert!` statements can be disabled by passing
-/// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for
-/// checks that are too expensive to be present in a release build but may be
-/// helpful during development.
+/// Unlike `assert!`, `debug_assert!` statements are only enabled in non
+/// optimized builds by default. An optimized build will omit all
+/// `debug_assert!` statements unless `-C debug-assertions` is passed to the
+/// compiler. This makes `debug_assert!` useful for checks that are too
+/// expensive to be present in a release build but may be helpful during
+/// development.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// // the panic message for these assertions is the stringified value of the
@@ -125,7 +125,7 @@ macro_rules! assert_eq {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! debug_assert {
-    ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
+    ($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); })
 }
 
 /// Asserts that two expressions are equal to each other, testing equality in
@@ -133,12 +133,14 @@ macro_rules! debug_assert {
 ///
 /// On panic, this macro will print the values of the expressions.
 ///
-/// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by
-/// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!`
-/// useful for checks that are too expensive to be present in a release build
-/// but may be helpful during development.
+/// Unlike `assert_eq!`, `debug_assert_eq!` statements are only enabled in non
+/// optimized builds by default. An optimized build will omit all
+/// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the
+/// compiler. This makes `debug_assert_eq!` useful for checks that are too
+/// expensive to be present in a release build but may be helpful during
+/// development.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// let a = 3;
@@ -147,12 +149,12 @@ macro_rules! debug_assert {
 /// ```
 #[macro_export]
 macro_rules! debug_assert_eq {
-    ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
+    ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); })
 }
 
 /// Short circuiting evaluation on Err
 ///
-/// `libstd` contains a more general `try!` macro that uses `FromError`.
+/// `libstd` contains a more general `try!` macro that uses `From<E>`.
 #[macro_export]
 macro_rules! try {
     ($e:expr) => ({
@@ -168,10 +170,11 @@ macro_rules! try {
 /// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
 /// See `std::fmt` for more information.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// # #![allow(unused_must_use)]
+/// use std::io::Write;
 ///
 /// let mut w = Vec::new();
 /// write!(&mut w, "test");
@@ -212,8 +215,8 @@ macro_rules! writeln {
 ///
 /// Match arms:
 ///
-/// ```rust
-/// fn foo(x: Option<int>) {
+/// ```
+/// fn foo(x: Option<i32>) {
 ///     match x {
 ///         Some(n) if n >= 0 => println!("Some(Non-negative)"),
 ///         Some(n) if n <  0 => println!("Some(Negative)"),
@@ -225,9 +228,10 @@ macro_rules! writeln {
 ///
 /// Iterators:
 ///
-/// ```rust
+/// ```
+/// # #![feature(core)]
 /// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
-///     for i in std::iter::count(0_u32, 1) {
+///     for i in 0.. {
 ///         if 3*i < i { panic!("u32 overflow"); }
 ///         if x < 3*i { return i-1; }
 ///     }
index d284eb341792b4d363c3cd6896346b7db581a32d..619f983aee07173f3e1deadd9e1abbadc33d105c 100644 (file)
@@ -31,28 +31,25 @@ use option::Option;
 use hash::Hash;
 use hash::Hasher;
 
-/// Types able to be transferred across thread boundaries.
-#[unstable(feature = "core",
-           reason = "will be overhauled with new lifetime rules; see RFC 458")]
-#[lang="send"]
-#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
-#[cfg(stage0)]
-pub unsafe trait Send: 'static {
-    // empty.
-}
 /// Types able to be transferred across thread boundaries.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="send"]
 #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
-#[cfg(not(stage0))]
 pub unsafe trait Send : MarkerTrait {
     // empty.
 }
 
+unsafe impl Send for .. { }
+
+impl<T> !Send for *const T { }
+impl<T> !Send for *mut T { }
+impl !Send for Managed { }
+
 /// Types with a constant size known at compile-time.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="sized"]
 #[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"]
+#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
 pub trait Sized : MarkerTrait {
     // Empty.
 }
@@ -79,7 +76,7 @@ pub trait Sized : MarkerTrait {
 ///
 /// ```
 /// // we can just derive a `Copy` implementation
-/// #[derive(Debug, Copy)]
+/// #[derive(Debug, Copy, Clone)]
 /// struct Foo;
 ///
 /// let x = Foo;
@@ -128,7 +125,7 @@ pub trait Sized : MarkerTrait {
 /// There are two ways to implement `Copy` on your type:
 ///
 /// ```
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct MyStruct;
 /// ```
 ///
@@ -137,6 +134,7 @@ pub trait Sized : MarkerTrait {
 /// ```
 /// struct MyStruct;
 /// impl Copy for MyStruct {}
+/// impl Clone for MyStruct { fn clone(&self) -> MyStruct { *self } }
 /// ```
 ///
 /// There is a small difference between the two: the `derive` strategy will also place a `Copy`
@@ -158,7 +156,7 @@ pub trait Sized : MarkerTrait {
 /// change: that second example would fail to compile if we made `Foo` non-`Copy`.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="copy"]
-pub trait Copy : MarkerTrait {
+pub trait Copy : Clone {
     // Empty.
 }
 
@@ -199,14 +197,9 @@ pub trait Copy : MarkerTrait {
 /// the `sync` crate do ensure that any mutation cannot cause data
 /// races.  Hence these types are `Sync`.
 ///
-/// Users writing their own types with interior mutability (or anything
-/// else that is not thread-safe) should use the `NoSync` marker type
-/// (from `std::marker`) to ensure that the compiler doesn't
-/// consider the user-defined type to be `Sync`.  Any types with
-/// interior mutability must also use the `std::cell::UnsafeCell` wrapper
-/// around the value(s) which can be mutated when behind a `&`
-/// reference; not doing this is undefined behaviour (for example,
-/// `transmute`-ing from `&T` to `&mut T` is illegal).
+/// Any types with interior mutability must also use the `std::cell::UnsafeCell` wrapper around the
+/// value(s) which can be mutated when behind a `&` reference; not doing this is undefined
+/// behaviour (for example, `transmute`-ing from `&T` to `&mut T` is illegal).
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="sync"]
 #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
@@ -214,6 +207,12 @@ pub unsafe trait Sync : MarkerTrait {
     // Empty
 }
 
+unsafe impl Sync for .. { }
+
+impl<T> !Sync for *const T { }
+impl<T> !Sync for *mut T { }
+impl !Sync for Managed { }
+
 /// A type which is considered "not POD", meaning that it is not
 /// implicitly copyable. This is typically embedded in other types to
 /// ensure that they are never copied, even if they lack a destructor.
@@ -233,13 +232,6 @@ pub struct Managed;
 
 macro_rules! impls{
     ($t: ident) => (
-        #[cfg(stage0)]
-        impl<T:?Sized, S: Hasher> Hash<S> for $t<T> {
-            #[inline]
-            fn hash(&self, _: &mut S) {
-            }
-        }
-        #[cfg(not(stage0))]
         impl<T:?Sized> Hash for $t<T> {
             #[inline]
             fn hash<H: Hasher>(&self, _: &mut H) {
@@ -284,7 +276,14 @@ macro_rules! impls{
 /// any methods, but instead is used to gate access to data.
 ///
 /// FIXME. Better documentation needed here!
-pub trait MarkerTrait : PhantomFn<Self> { }
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait MarkerTrait : PhantomFn<Self,Self> { }
+//                                    ~~~~~ <-- FIXME(#22806)?
+//
+// Marker trait has been made invariant so as to avoid inf recursion,
+// but we should ideally solve the underlying problem. That's a bit
+// complicated.
+
 impl<T:?Sized> MarkerTrait for T { }
 
 /// `PhantomFn` is a marker trait for use with traits that contain
@@ -296,7 +295,7 @@ impl<T:?Sized> MarkerTrait for T { }
 /// can extend `MarkerTrait`, which is equivalent to
 /// `PhantomFn<Self>`.
 ///
-/// # Example
+/// # Examples
 ///
 /// As an example, consider a trait with no methods like `Even`, meant
 /// to represent types that are "even":
@@ -318,7 +317,7 @@ impl<T:?Sized> MarkerTrait for T { }
 ///
 /// Therefore, we can model a method like this as follows:
 ///
-/// ```rust
+/// ```
 /// use std::marker::PhantomFn;
 /// trait Even : PhantomFn<Self> { }
 /// ```
@@ -326,7 +325,8 @@ impl<T:?Sized> MarkerTrait for T { }
 /// Another equivalent, but clearer, option would be to use
 /// `MarkerTrait`:
 ///
-/// ```rust
+/// ```
+/// # #![feature(core)]
 /// use std::marker::MarkerTrait;
 /// trait Even : MarkerTrait { }
 /// ```
@@ -348,40 +348,62 @@ impl<T:?Sized> MarkerTrait for T { }
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
 
-#[cfg(stage0)] // built into the trait matching system after stage0
-impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
-
-/// Specific to stage0. You should not be seeing these docs!
-#[cfg(stage0)]
-#[lang="covariant_type"] // only relevant to stage0
-pub struct PhantomData<T:?Sized>;
-
-/// `PhantomData` is a way to tell the compiler about fake fields.
-/// Phantom data is required whenever type parameters are not used.
-/// The idea is that if the compiler encounters a `PhantomData<T>`
-/// instance, it will behave *as if* an instance of the type `T` were
-/// present for the purpose of various automatic analyses.
+/// `PhantomData<T>` allows you to describe that a type acts as if it stores a value of type `T`,
+/// even though it does not. This allows you to inform the compiler about certain safety properties
+/// of your code.
 ///
-/// For example, embedding a `PhantomData<T>` will inform the compiler
+/// Though they both have scary names, `PhantomData<T>` and "phantom types" are unrelated. 👻👻👻
+///
+/// # Examples
+///
+/// When handling external resources over a foreign function interface, `PhantomData<T>` can
+/// prevent mismatches by enforcing types in the method implementations:
+///
+/// ```
+/// # trait ResType { fn foo(&self); };
+/// # struct ParamType;
+/// # mod foreign_lib {
+/// # pub fn new(_: usize) -> *mut () { 42 as *mut () }
+/// # pub fn do_stuff(_: *mut (), _: usize) {}
+/// # }
+/// # fn convert_params(_: ParamType) -> usize { 42 }
+/// use std::marker::PhantomData;
+/// use std::mem;
+///
+/// struct ExternalResource<R> {
+///    resource_handle: *mut (),
+///    resource_type: PhantomData<R>,
+/// }
+///
+/// impl<R: ResType> ExternalResource<R> {
+///     fn new() -> ExternalResource<R> {
+///         let size_of_res = mem::size_of::<R>();
+///         ExternalResource {
+///             resource_handle: foreign_lib::new(size_of_res),
+///             resource_type: PhantomData,
+///         }
+///     }
+///
+///     fn do_stuff(&self, param: ParamType) {
+///         let foreign_params = convert_params(param);
+///         foreign_lib::do_stuff(self.resource_handle, foreign_params);
+///     }
+/// }
+/// ```
+///
+/// Another example: embedding a `PhantomData<T>` will inform the compiler
 /// that one or more instances of the type `T` could be dropped when
 /// instances of the type itself is dropped, though that may not be
 /// apparent from the other structure of the type itself. This is
 /// commonly necessary if the structure is using an unsafe pointer
 /// like `*mut T` whose referent may be dropped when the type is
 /// dropped, as a `*mut T` is otherwise not treated as owned.
-///
-/// FIXME. Better documentation and examples of common patterns needed
-/// here! For now, please see [RFC 738][738] for more information.
-///
-/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md
-#[cfg(not(stage0))]
 #[lang="phantom_data"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct PhantomData<T:?Sized>;
 
 impls! { PhantomData }
 
-#[cfg(not(stage0))]
 mod impls {
     use super::{Send, Sync, Sized};
 
@@ -389,39 +411,41 @@ mod impls {
     unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {}
 }
 
-/// Old-style marker trait. Deprecated.
-#[unstable(feature = "core", reason = "deprecated")]
-#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<&'a ()>`")]
-#[lang="contravariant_lifetime"]
-pub struct ContravariantLifetime<'a>;
-
-/// Old-style marker trait. Deprecated.
-#[unstable(feature = "core", reason = "deprecated")]
-#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<fn(&'a ())>`")]
-#[lang="covariant_lifetime"]
-pub struct CovariantLifetime<'a>;
-
-/// Old-style marker trait. Deprecated.
-#[unstable(feature = "core", reason = "deprecated")]
-#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<Cell<&'a ()>>`")]
-#[lang="invariant_lifetime"]
-pub struct InvariantLifetime<'a>;
-
-/// Old-style marker trait. Deprecated.
-#[unstable(feature = "core", reason = "deprecated")]
-#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<fn(T)>`")]
-#[lang="contravariant_type"]
-pub struct ContravariantType<T>;
+/// A marker trait indicates a type that can be reflected over. This
+/// trait is implemented for all types. Its purpose is to ensure that
+/// when you write a generic function that will employ reflection,
+/// that must be reflected (no pun intended) in the generic bounds of
+/// that function. Here is an example:
+///
+/// ```
+/// #![feature(core)]
+/// use std::marker::Reflect;
+/// use std::any::Any;
+/// fn foo<T:Reflect+'static>(x: &T) {
+///     let any: &Any = x;
+///     if any.is::<u32>() { println!("u32"); }
+/// }
+/// ```
+///
+/// Without the declaration `T:Reflect`, `foo` would not type check
+/// (note: as a matter of style, it would be preferable to to write
+/// `T:Any`, because `T:Any` implies `T:Reflect` and `T:'static`, but
+/// we use `Reflect` here to show how it works). The `Reflect` bound
+/// thus serves to alert `foo`'s caller to the fact that `foo` may
+/// behave differently depending on whether `T=u32` or not. In
+/// particular, thanks to the `Reflect` bound, callers know that a
+/// function declared like `fn bar<T>(...)` will always act in
+/// precisely the same way no matter what type `T` is supplied,
+/// because there are no bounds declared on `T`. (The ability for a
+/// caller to reason about what a function may do based solely on what
+/// generic bounds are declared is often called the ["parametricity
+/// property"][1].)
+///
+/// [1]: http://en.wikipedia.org/wiki/Parametricity
+#[rustc_reflect_like]
+#[unstable(feature = "core", reason = "requires RFC and more experience")]
+pub trait Reflect : MarkerTrait {
+}
 
-/// Old-style marker trait. Deprecated.
-#[unstable(feature = "core", reason = "deprecated")]
-#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<T>`")]
-#[lang="covariant_type"]
-#[cfg(not(stage0))]
-pub struct CovariantType<T>;
+impl Reflect for .. { }
 
-/// Old-style marker trait. Deprecated.
-#[unstable(feature = "core", reason = "deprecated")]
-#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<Cell<T>>`")]
-#[lang="invariant_type"]
-pub struct InvariantType<T>;
index 740997b7a249d5a6fcdf472c2e5c277f472a0327..249beb6295c0733be70e4f74806ee1fbe3c2ea90 100644 (file)
@@ -158,6 +158,27 @@ pub unsafe fn zeroed<T>() -> T {
     intrinsics::init()
 }
 
+/// Create a value initialized to an unspecified series of bytes.
+///
+/// The byte sequence usually indicates that the value at the memory
+/// in question has been dropped. Thus, *if* T carries a drop flag,
+/// any associated destructor will not be run when the value falls out
+/// of scope.
+///
+/// Some code at one time used the `zeroed` function above to
+/// accomplish this goal.
+///
+/// This function is expected to be deprecated with the transition
+/// to non-zeroing drop.
+#[inline]
+#[unstable(feature = "filling_drop")]
+pub unsafe fn dropped<T>() -> T {
+    #[inline(always)]
+    unsafe fn dropped_impl<T>() -> T { intrinsics::init_dropped() }
+
+    dropped_impl()
+}
+
 /// Create an uninitialized value.
 ///
 /// Care must be taken when using this function, if the type `T` has a destructor and the value
@@ -203,9 +224,9 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
         let mut t: T = uninitialized();
 
         // Perform the swap, `&mut` pointers never alias
-        ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
-        ptr::copy_nonoverlapping_memory(x, &*y, 1);
-        ptr::copy_nonoverlapping_memory(y, &t, 1);
+        ptr::copy_nonoverlapping(&*x, &mut t, 1);
+        ptr::copy_nonoverlapping(&*y, x, 1);
+        ptr::copy_nonoverlapping(&t, y, 1);
 
         // y and t now point to the same thing, but we need to completely forget `t`
         // because it's no longer relevant.
@@ -251,7 +272,7 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
 /// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from
 /// `self`, allowing it to be returned:
 ///
-/// ```rust
+/// ```
 /// use std::mem;
 /// # struct Buffer<T> { buf: Vec<T> }
 /// impl<T> Buffer<T> {
@@ -291,15 +312,52 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn drop<T>(_x: T) { }
 
-/// Interprets `src` as `&U`, and then reads `src` without moving the contained value.
+macro_rules! repeat_u8_as_u32 {
+    ($name:expr) => { (($name as u32) << 24 |
+                       ($name as u32) << 16 |
+                       ($name as u32) <<  8 |
+                       ($name as u32)) }
+}
+macro_rules! repeat_u8_as_u64 {
+    ($name:expr) => { ((repeat_u8_as_u32!($name) as u64) << 32 |
+                       (repeat_u8_as_u32!($name) as u64)) }
+}
+
+// NOTE: Keep synchronized with values used in librustc_trans::trans::adt.
+//
+// In particular, the POST_DROP_U8 marker must never equal the
+// DTOR_NEEDED_U8 marker.
+//
+// For a while pnkfelix was using 0xc1 here.
+// But having the sign bit set is a pain, so 0x1d is probably better.
+//
+// And of course, 0x00 brings back the old world of zero'ing on drop.
+#[unstable(feature = "filling_drop")]
+pub const POST_DROP_U8: u8 = 0x1d;
+#[unstable(feature = "filling_drop")]
+pub const POST_DROP_U32: u32 = repeat_u8_as_u32!(POST_DROP_U8);
+#[unstable(feature = "filling_drop")]
+pub const POST_DROP_U64: u64 = repeat_u8_as_u64!(POST_DROP_U8);
+
+#[cfg(target_pointer_width = "32")]
+#[unstable(feature = "filling_drop")]
+pub const POST_DROP_USIZE: usize = POST_DROP_U32 as usize;
+#[cfg(target_pointer_width = "64")]
+#[unstable(feature = "filling_drop")]
+pub const POST_DROP_USIZE: usize = POST_DROP_U64 as usize;
+
+/// Interprets `src` as `&U`, and then reads `src` without moving the contained
+/// value.
 ///
-/// This function will unsafely assume the pointer `src` is valid for `sizeof(U)` bytes by
-/// transmuting `&T` to `&U` and then reading the `&U`. It will also unsafely create a copy of the
-/// contained value instead of moving out of `src`.
+/// This function will unsafely assume the pointer `src` is valid for
+/// `sizeof(U)` bytes by transmuting `&T` to `&U` and then reading the `&U`. It
+/// will also unsafely create a copy of the contained value instead of moving
+/// out of `src`.
 ///
-/// It is not a compile-time error if `T` and `U` have different sizes, but it is highly encouraged
-/// to only invoke this function where `T` and `U` have the same size. This function triggers
-/// undefined behavior if `U` is larger than `T`.
+/// It is not a compile-time error if `T` and `U` have different sizes, but it
+/// is highly encouraged to only invoke this function where `T` and `U` have the
+/// same size. This function triggers undefined behavior if `U` is larger than
+/// `T`.
 ///
 /// # Examples
 ///
@@ -313,6 +371,8 @@ pub fn drop<T>(_x: T) { }
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
+    // FIXME(#23542) Replace with type ascription.
+    #![allow(trivial_casts)]
     ptr::read(src as *const T as *const U)
 }
 
index b542c9d47f7d4a386d9ac5148b7275ae245d008b..12b45a766b63929da94dc01ff5d7d6761451407c 100644 (file)
@@ -22,13 +22,13 @@ use num::Float;
 use num::FpCategory as Fp;
 use option::Option;
 
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const RADIX: uint = 2;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const RADIX: u32 = 2;
 
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MANTISSA_DIGITS: uint = 24;
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const DIGITS: uint = 6;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const MANTISSA_DIGITS: u32 = 24;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const DIGITS: u32 = 6;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const EPSILON: f32 = 1.19209290e-07_f32;
@@ -56,15 +56,15 @@ pub const MIN_POSITIVE: f32 = 1.17549435e-38_f32;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const MAX: f32 = 3.40282347e+38_f32;
 
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MIN_EXP: int = -125;
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MAX_EXP: int = 128;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const MIN_EXP: i32 = -125;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const MAX_EXP: i32 = 128;
 
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MIN_10_EXP: int = -37;
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MAX_10_EXP: int = 38;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const MIN_10_EXP: i32 = -37;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const MAX_10_EXP: i32 = 38;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const NAN: f32 = 0.0_f32/0.0_f32;
@@ -73,61 +73,89 @@ pub const INFINITY: f32 = 1.0_f32/0.0_f32;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const NEG_INFINITY: f32 = -1.0_f32/0.0_f32;
 
-/// Various useful constants.
-#[unstable(feature = "core",
-           reason = "naming scheme needs to be revisited")]
+/// Basic mathematial constants.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub mod consts {
     // FIXME: replace with mathematical constants from cmath.
 
     /// Archimedes' constant
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const PI: f32 = 3.14159265358979323846264338327950288_f32;
 
     /// pi * 2.0
+    #[unstable(feature = "core", reason = "unclear naming convention/usefulness")]
     pub const PI_2: f32 = 6.28318530717958647692528676655900576_f32;
 
     /// pi/2.0
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32;
 
     /// pi/3.0
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_3: f32 = 1.04719755119659774615421446109316763_f32;
 
     /// pi/4.0
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_4: f32 = 0.785398163397448309615660845819875721_f32;
 
     /// pi/6.0
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_6: f32 = 0.52359877559829887307710723054658381_f32;
 
     /// pi/8.0
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_8: f32 = 0.39269908169872415480783042290993786_f32;
 
     /// 1.0/pi
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_1_PI: f32 = 0.318309886183790671537767526745028724_f32;
 
     /// 2.0/pi
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32;
 
     /// 2.0/sqrt(pi)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub const FRAC_2_SQRT_PI: f32 = 1.12837916709551257389615890312154517_f32;
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[deprecated(since = "1.0.0", reason = "renamed to FRAC_2_SQRT_PI")]
     pub const FRAC_2_SQRTPI: f32 = 1.12837916709551257389615890312154517_f32;
 
     /// sqrt(2.0)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub const SQRT_2: f32 = 1.41421356237309504880168872420969808_f32;
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[deprecated(since = "1.0.0", reason = "renamed to SQRT_2")]
     pub const SQRT2: f32 = 1.41421356237309504880168872420969808_f32;
 
     /// 1.0/sqrt(2.0)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub const FRAC_1_SQRT_2: f32 = 0.707106781186547524400844362104849039_f32;
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[deprecated(since = "1.0.0", reason = "renamed to FRAC_1_SQRT_2")]
     pub const FRAC_1_SQRT2: f32 = 0.707106781186547524400844362104849039_f32;
 
     /// Euler's number
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const E: f32 = 2.71828182845904523536028747135266250_f32;
 
     /// log2(e)
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const LOG2_E: f32 = 1.44269504088896340735992468100189214_f32;
 
     /// log10(e)
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const LOG10_E: f32 = 0.434294481903251827651128918916605082_f32;
 
     /// ln(2.0)
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const LN_2: f32 = 0.693147180559945309417232121458176568_f32;
 
     /// ln(10.0)
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const LN_10: f32 = 2.30258509299404568401799145468436421_f32;
 }
 
@@ -193,12 +221,12 @@ impl Float for f32 {
     #[inline]
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0")]
-    fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS }
+    fn mantissa_digits(_: Option<f32>) -> usize { MANTISSA_DIGITS as usize }
 
     #[inline]
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0")]
-    fn digits(_: Option<f32>) -> uint { DIGITS }
+    fn digits(_: Option<f32>) -> usize { DIGITS as usize }
 
     #[inline]
     #[unstable(feature = "core")]
@@ -208,22 +236,22 @@ impl Float for f32 {
     #[inline]
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0")]
-    fn min_exp(_: Option<f32>) -> int { MIN_EXP }
+    fn min_exp(_: Option<f32>) -> isize { MIN_EXP as isize }
 
     #[inline]
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0")]
-    fn max_exp(_: Option<f32>) -> int { MAX_EXP }
+    fn max_exp(_: Option<f32>) -> isize { MAX_EXP as isize }
 
     #[inline]
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0")]
-    fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP }
+    fn min_10_exp(_: Option<f32>) -> isize { MIN_10_EXP as isize }
 
     #[inline]
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0")]
-    fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP }
+    fn max_10_exp(_: Option<f32>) -> isize { MAX_10_EXP as isize }
 
     #[inline]
     #[unstable(feature = "core")]
@@ -281,8 +309,9 @@ impl Float for f32 {
 
     /// The fractional part of the number, satisfying:
     ///
-    /// ```rust
-    /// use core::num::Float;
+    /// ```
+    /// # #![feature(core)]
+    /// use std::num::Float;
     ///
     /// let x = 1.65f32;
     /// assert!(x == x.trunc() + x.fract())
index 2aae7107548c6f3ecab3fa7d632635b7c277933e..058acedd9c98889096926ecc1d1873e611ec6cde 100644 (file)
@@ -22,16 +22,13 @@ use num::Float;
 use num::FpCategory as Fp;
 use option::Option;
 
-// FIXME(#5527): These constants should be deprecated once associated
-// constants are implemented in favour of referencing the respective
-// members of `Bounded` and `Float`.
-
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const RADIX: uint = 2;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const RADIX: u32 = 2;
 
-pub const MANTISSA_DIGITS: uint = 53;
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const DIGITS: uint = 15;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const MANTISSA_DIGITS: u32 = 53;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const DIGITS: u32 = 15;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const EPSILON: f64 = 2.2204460492503131e-16_f64;
@@ -59,15 +56,15 @@ pub const MIN_POSITIVE: f64 = 2.2250738585072014e-308_f64;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const MAX: f64 = 1.7976931348623157e+308_f64;
 
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MIN_EXP: int = -1021;
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MAX_EXP: int = 1024;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const MIN_EXP: i32 = -1021;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const MAX_EXP: i32 = 1024;
 
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MIN_10_EXP: int = -307;
-#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MAX_10_EXP: int = 308;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const MIN_10_EXP: i32 = -307;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub const MAX_10_EXP: i32 = 308;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const NAN: f64 = 0.0_f64/0.0_f64;
@@ -76,65 +73,89 @@ pub const INFINITY: f64 = 1.0_f64/0.0_f64;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const NEG_INFINITY: f64 = -1.0_f64/0.0_f64;
 
-/// Various useful constants.
-#[unstable(feature = "core",
-           reason = "naming scheme needs to be revisited")]
+/// Basic mathematial constants.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub mod consts {
     // FIXME: replace with mathematical constants from cmath.
 
-    // FIXME(#5527): These constants should be deprecated once associated
-    // constants are implemented in favour of referencing the respective members
-    // of `Float`.
-
     /// Archimedes' constant
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const PI: f64 = 3.14159265358979323846264338327950288_f64;
 
     /// pi * 2.0
+    #[unstable(feature = "core", reason = "unclear naming convention/usefulness")]
     pub const PI_2: f64 = 6.28318530717958647692528676655900576_f64;
 
     /// pi/2.0
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64;
 
     /// pi/3.0
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_3: f64 = 1.04719755119659774615421446109316763_f64;
 
     /// pi/4.0
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_4: f64 = 0.785398163397448309615660845819875721_f64;
 
     /// pi/6.0
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_6: f64 = 0.52359877559829887307710723054658381_f64;
 
     /// pi/8.0
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_8: f64 = 0.39269908169872415480783042290993786_f64;
 
     /// 1.0/pi
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_1_PI: f64 = 0.318309886183790671537767526745028724_f64;
 
     /// 2.0/pi
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_2_PI: f64 = 0.636619772367581343075535053490057448_f64;
 
     /// 2.0/sqrt(pi)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub const FRAC_2_SQRT_PI: f64 = 1.12837916709551257389615890312154517_f64;
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[deprecated(since = "1.0.0", reason = "renamed to FRAC_2_SQRT_PI")]
     pub const FRAC_2_SQRTPI: f64 = 1.12837916709551257389615890312154517_f64;
 
     /// sqrt(2.0)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub const SQRT_2: f64 = 1.41421356237309504880168872420969808_f64;
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[deprecated(since = "1.0.0", reason = "renamed to SQRT_2")]
     pub const SQRT2: f64 = 1.41421356237309504880168872420969808_f64;
 
     /// 1.0/sqrt(2.0)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub const FRAC_1_SQRT_2: f64 = 0.707106781186547524400844362104849039_f64;
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[deprecated(since = "1.0.0", reason = "renamed to FRAC_1_SQRT_2")]
     pub const FRAC_1_SQRT2: f64 = 0.707106781186547524400844362104849039_f64;
 
     /// Euler's number
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const E: f64 = 2.71828182845904523536028747135266250_f64;
 
     /// log2(e)
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const LOG2_E: f64 = 1.44269504088896340735992468100189214_f64;
 
     /// log10(e)
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const LOG10_E: f64 = 0.434294481903251827651128918916605082_f64;
 
     /// ln(2.0)
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const LN_2: f64 = 0.693147180559945309417232121458176568_f64;
 
     /// ln(10.0)
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub const LN_10: f64 = 2.30258509299404568401799145468436421_f64;
 }
 
@@ -200,12 +221,12 @@ impl Float for f64 {
     #[inline]
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0")]
-    fn mantissa_digits(_: Option<f64>) -> uint { MANTISSA_DIGITS }
+    fn mantissa_digits(_: Option<f64>) -> usize { MANTISSA_DIGITS as usize }
 
     #[inline]
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0")]
-    fn digits(_: Option<f64>) -> uint { DIGITS }
+    fn digits(_: Option<f64>) -> usize { DIGITS as usize }
 
     #[inline]
     #[unstable(feature = "core")]
@@ -215,22 +236,22 @@ impl Float for f64 {
     #[inline]
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0")]
-    fn min_exp(_: Option<f64>) -> int { MIN_EXP }
+    fn min_exp(_: Option<f64>) -> isize { MIN_EXP as isize }
 
     #[inline]
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0")]
-    fn max_exp(_: Option<f64>) -> int { MAX_EXP }
+    fn max_exp(_: Option<f64>) -> isize { MAX_EXP as isize }
 
     #[inline]
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0")]
-    fn min_10_exp(_: Option<f64>) -> int { MIN_10_EXP }
+    fn min_10_exp(_: Option<f64>) -> isize { MIN_10_EXP as isize }
 
     #[inline]
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0")]
-    fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP }
+    fn max_10_exp(_: Option<f64>) -> isize { MAX_10_EXP as isize }
 
     #[inline]
     #[unstable(feature = "core")]
@@ -288,8 +309,9 @@ impl Float for f64 {
 
     /// The fractional part of the number, satisfying:
     ///
-    /// ```rust
-    /// use core::num::Float;
+    /// ```
+    /// # #![feature(core)]
+    /// use std::num::Float;
     ///
     /// let x = 1.65f64;
     /// assert!(x == x.trunc() + x.fract())
index 20300d29fa0c5f1e66e5d255eb79bc5b1c11ed17..b3adef53dabeebc8a7a03ed478fb691dd7ed28d6 100644 (file)
@@ -18,4 +18,3 @@ macro_rules! assert_approx_eq {
                 "{} is not approximately equal to {}", *a, *b);
     })
 }
-
diff --git a/src/libcore/num/int.rs b/src/libcore/num/int.rs
deleted file mode 100644 (file)
index 2132b95..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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.
-//
-// 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.
-
-//! Deprecated: replaced by `isize`.
-//!
-//! The rollout of the new type will gradually take place over the
-//! alpha cycle along with the development of clearer conventions
-//! around integer types.
-
-#![unstable(feature = "core")]
-#![deprecated(since = "1.0.0", reason = "replaced by isize")]
-
-#[cfg(target_pointer_width = "32")] int_module! { int, 32 }
-#[cfg(target_pointer_width = "64")] int_module! { int, 64 }
index 954c8a08e64d6bafdd15a6ef6c2fe9e6ad29e8c9..fe0d6d13c4c06483649bdbf737fe89c68048cf43 100644 (file)
@@ -15,11 +15,11 @@ macro_rules! int_module { ($T:ty, $bits:expr) => (
 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
 // calling the `mem::size_of` function.
 #[unstable(feature = "core")]
-pub const BITS : uint = $bits;
+pub const BITS : u32 = $bits;
 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
 // calling the `mem::size_of` function.
 #[unstable(feature = "core")]
-pub const BYTES : uint = ($bits / 8);
+pub const BYTES : u32 = ($bits / 8);
 
 // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
 // calling the `Bounded::min_value` function.
index 7612469c8088bbfe3c30579d02e28f48aa4482fd..28e0bcf13dd0911132938784bd5096d264a55a71 100644 (file)
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
+use self::wrapping::{OverflowingOps, WrappingOps};
+
 use char::CharExt;
 use clone::Clone;
 use cmp::{PartialEq, Eq, PartialOrd, Ord};
-use error::Error;
 use fmt;
 use intrinsics;
-use iter::IteratorExt;
+use iter::Iterator;
 use marker::Copy;
 use mem::size_of;
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
@@ -30,8 +31,66 @@ use option::Option::{self, Some, None};
 use result::Result::{self, Ok, Err};
 use str::{FromStr, StrExt};
 
+/// Provides intentionally-wrapped arithmetic on `T`.
+///
+/// Operations like `+` on `u32` values is intended to never overflow,
+/// and in some debug configurations overflow is detected and results
+/// in a panic. While most arithmetic falls into this category, some
+/// code explicitly expects and relies upon modular arithmetic (e.g.,
+/// hashing).
+///
+/// Wrapping arithmetic can be achieved either through methods like
+/// `wrapping_add`, or through the `Wrapping<T>` type, which says that
+/// all standard arithmetic operations on the underlying value are
+/// intended to have wrapping semantics.
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
+pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
+
+#[unstable(feature = "core", reason = "may be removed or relocated")]
+pub mod wrapping;
+
+/// Types that have a "zero" value.
+///
+/// This trait is intended for use in conjunction with `Add`, as an identity:
+/// `x + T::zero() == x`.
+#[unstable(feature = "zero_one",
+           reason = "unsure of placement, wants to use associated constants")]
+pub trait Zero {
+    /// The "zero" (usually, additive identity) for this type.
+    fn zero() -> Self;
+}
+
+/// Types that have a "one" value.
+///
+/// This trait is intended for use in conjunction with `Mul`, as an identity:
+/// `x * T::one() == x`.
+#[unstable(feature = "zero_one",
+           reason = "unsure of placement, wants to use associated constants")]
+pub trait One {
+    /// The "one" (usually, multiplicative identity) for this type.
+    fn one() -> Self;
+}
+
+macro_rules! zero_one_impl {
+    ($($t:ty)*) => ($(
+        impl Zero for $t {
+            #[inline]
+            fn zero() -> $t { 0 }
+        }
+        impl One for $t {
+            #[inline]
+            fn one() -> $t { 1 }
+        }
+    )*)
+}
+zero_one_impl! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
+
 /// A built-in signed or unsigned integer.
 #[stable(feature = "rust1", since = "1.0.0")]
+#[deprecated(since = "1.0.0",
+             reason = "replaced by inherent methods; for generics, use rust-lang/num")]
+#[allow(deprecated)]
 pub trait Int
     : Copy + Clone
     + NumCast
@@ -46,8 +105,10 @@ pub trait Int
     + BitAnd<Output=Self>
     + BitOr<Output=Self>
     + BitXor<Output=Self>
-    + Shl<uint, Output=Self>
-    + Shr<uint, Output=Self>
+    + Shl<usize, Output=Self>
+    + Shr<usize, Output=Self>
+    + WrappingOps
+    + OverflowingOps
 {
     /// Returns the `0` value of this integer type.
     // FIXME (#5527): Should be an associated constant
@@ -75,9 +136,10 @@ pub trait Int
 
     /// Returns the number of ones in the binary representation of `self`.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// let n = 0b01001100u8;
@@ -86,13 +148,14 @@ pub trait Int
     /// ```
     #[unstable(feature = "core",
                reason = "pending integer conventions")]
-    fn count_ones(self) -> uint;
+    fn count_ones(self) -> u32;
 
     /// Returns the number of zeros in the binary representation of `self`.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// let n = 0b01001100u8;
@@ -102,16 +165,17 @@ pub trait Int
     #[unstable(feature = "core",
                reason = "pending integer conventions")]
     #[inline]
-    fn count_zeros(self) -> uint {
+    fn count_zeros(self) -> u32 {
         (!self).count_ones()
     }
 
     /// Returns the number of leading zeros in the binary representation
     /// of `self`.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// let n = 0b0101000u16;
@@ -120,14 +184,15 @@ pub trait Int
     /// ```
     #[unstable(feature = "core",
                reason = "pending integer conventions")]
-    fn leading_zeros(self) -> uint;
+    fn leading_zeros(self) -> u32;
 
     /// Returns the number of trailing zeros in the binary representation
     /// of `self`.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// let n = 0b0101000u16;
@@ -136,14 +201,15 @@ pub trait Int
     /// ```
     #[unstable(feature = "core",
                reason = "pending integer conventions")]
-    fn trailing_zeros(self) -> uint;
+    fn trailing_zeros(self) -> u32;
 
     /// Shifts the bits to the left by a specified amount amount, `n`, wrapping
     /// the truncated bits to the end of the resulting integer.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// let n = 0x0123456789ABCDEFu64;
@@ -153,14 +219,15 @@ pub trait Int
     /// ```
     #[unstable(feature = "core",
                reason = "pending integer conventions")]
-    fn rotate_left(self, n: uint) -> Self;
+    fn rotate_left(self, n: u32) -> Self;
 
     /// Shifts the bits to the right by a specified amount amount, `n`, wrapping
     /// the truncated bits to the beginning of the resulting integer.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// let n = 0x0123456789ABCDEFu64;
@@ -170,13 +237,13 @@ pub trait Int
     /// ```
     #[unstable(feature = "core",
                reason = "pending integer conventions")]
-    fn rotate_right(self, n: uint) -> Self;
+    fn rotate_right(self, n: u32) -> Self;
 
     /// Reverses the byte order of the integer.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::num::Int;
     ///
     /// let n = 0x0123456789ABCDEFu64;
@@ -191,9 +258,9 @@ pub trait Int
     ///
     /// On big endian this is a no-op. On little endian the bytes are swapped.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::num::Int;
     ///
     /// let n = 0x0123456789ABCDEFu64;
@@ -214,9 +281,9 @@ pub trait Int
     ///
     /// On little endian this is a no-op. On big endian the bytes are swapped.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::num::Int;
     ///
     /// let n = 0x0123456789ABCDEFu64;
@@ -237,9 +304,9 @@ pub trait Int
     ///
     /// On big endian this is a no-op. On little endian the bytes are swapped.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::num::Int;
     ///
     /// let n = 0x0123456789ABCDEFu64;
@@ -260,9 +327,9 @@ pub trait Int
     ///
     /// On little endian this is a no-op. On big endian the bytes are swapped.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::num::Int;
     ///
     /// let n = 0x0123456789ABCDEFu64;
@@ -282,9 +349,9 @@ pub trait Int
     /// Checked integer addition. Computes `self + other`, returning `None` if
     /// overflow occurred.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::num::Int;
     ///
     /// assert_eq!(5u16.checked_add(65530), Some(65535));
@@ -296,9 +363,9 @@ pub trait Int
     /// Checked integer subtraction. Computes `self - other`, returning `None`
     /// if underflow occurred.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::num::Int;
     ///
     /// assert_eq!((-127i8).checked_sub(1), Some(-128));
@@ -310,9 +377,9 @@ pub trait Int
     /// Checked integer multiplication. Computes `self * other`, returning
     /// `None` if underflow or overflow occurred.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::num::Int;
     ///
     /// assert_eq!(5u8.checked_mul(51), Some(255));
@@ -324,9 +391,9 @@ pub trait Int
     /// Checked integer division. Computes `self / other`, returning `None` if
     /// `other == 0` or the operation results in underflow or overflow.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::num::Int;
     ///
     /// assert_eq!((-127i8).checked_div(-1), Some(127));
@@ -338,6 +405,16 @@ pub trait Int
 
     /// Saturating integer addition. Computes `self + other`, saturating at
     /// the numeric bounds instead of overflowing.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::num::Int;
+    ///
+    /// assert_eq!(5u16.saturating_add(65534), 65535);
+    /// assert_eq!((-5i16).saturating_add(-32767), -32768);
+    /// assert_eq!(100u32.saturating_add(4294967294), 4294967295);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     fn saturating_add(self, other: Self) -> Self {
@@ -350,6 +427,16 @@ pub trait Int
 
     /// Saturating integer subtraction. Computes `self - other`, saturating at
     /// the numeric bounds instead of overflowing.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::num::Int;
+    ///
+    /// assert_eq!(5u16.saturating_sub(65534), 0);
+    /// assert_eq!(5i16.saturating_sub(-32767), 32767);
+    /// assert_eq!(100u32.saturating_sub(4294967294), 0);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     fn saturating_sub(self, other: Self) -> Self {
@@ -362,9 +449,10 @@ pub trait Int
 
     /// Raises self to the power of `exp`, using exponentiation by squaring.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// assert_eq!(2.pow(4), 16);
@@ -372,14 +460,27 @@ pub trait Int
     #[unstable(feature = "core",
                reason = "pending integer conventions")]
     #[inline]
-    fn pow(self, mut exp: uint) -> Self {
+    fn pow(self, mut exp: u32) -> Self {
         let mut base = self;
         let mut acc: Self = Int::one();
+
+        let mut prev_base = self;
+        let mut base_oflo = false;
         while exp > 0 {
             if (exp & 1) == 1 {
-                acc = acc * base;
+                if base_oflo {
+                    // ensure overflow occurs in the same manner it
+                    // would have otherwise (i.e. signal any exception
+                    // it would have otherwise).
+                    acc = acc * (prev_base * prev_base);
+                } else {
+                    acc = acc * base;
+                }
             }
-            base = base * base;
+            prev_base = base;
+            let (new_base, new_base_oflo) = base.overflowing_mul(base);
+            base = new_base;
+            base_oflo = new_base_oflo;
             exp /= 2;
         }
         acc
@@ -403,6 +504,7 @@ macro_rules! uint_impl {
      $sub_with_overflow:path,
      $mul_with_overflow:path) => {
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[allow(deprecated)]
         impl Int for $T {
             #[inline]
             fn zero() -> $T { 0 }
@@ -414,33 +516,41 @@ macro_rules! uint_impl {
             fn min_value() -> $T { 0 }
 
             #[inline]
-            fn max_value() -> $T { -1 }
+            fn max_value() -> $T { !0 }
 
             #[inline]
-            fn count_ones(self) -> uint { unsafe { $ctpop(self as $ActualT) as uint } }
+            fn count_ones(self) -> u32 {
+                unsafe { $ctpop(self as $ActualT) as u32 }
+            }
 
             #[inline]
-            fn leading_zeros(self) -> uint { unsafe { $ctlz(self as $ActualT) as uint } }
+            fn leading_zeros(self) -> u32 {
+                unsafe { $ctlz(self as $ActualT) as u32 }
+            }
 
             #[inline]
-            fn trailing_zeros(self) -> uint { unsafe { $cttz(self as $ActualT) as uint } }
+            fn trailing_zeros(self) -> u32 {
+                unsafe { $cttz(self as $ActualT) as u32 }
+            }
 
             #[inline]
-            fn rotate_left(self, n: uint) -> $T {
+            fn rotate_left(self, n: u32) -> $T {
                 // Protect against undefined behaviour for over-long bit shifts
                 let n = n % $BITS;
                 (self << n) | (self >> (($BITS - n) % $BITS))
             }
 
             #[inline]
-            fn rotate_right(self, n: uint) -> $T {
+            fn rotate_right(self, n: u32) -> $T {
                 // Protect against undefined behaviour for over-long bit shifts
                 let n = n % $BITS;
                 (self >> n) | (self << (($BITS - n) % $BITS))
             }
 
             #[inline]
-            fn swap_bytes(self) -> $T { unsafe { $bswap(self as $ActualT) as $T } }
+            fn swap_bytes(self) -> $T {
+                unsafe { $bswap(self as $ActualT) as $T }
+            }
 
             #[inline]
             fn checked_add(self, other: $T) -> Option<$T> {
@@ -509,7 +619,7 @@ uint_impl! { u64 = u64, 64,
     intrinsics::u64_mul_with_overflow }
 
 #[cfg(target_pointer_width = "32")]
-uint_impl! { uint = u32, 32,
+uint_impl! { usize = u32, 32,
     intrinsics::ctpop32,
     intrinsics::ctlz32,
     intrinsics::cttz32,
@@ -519,7 +629,7 @@ uint_impl! { uint = u32, 32,
     intrinsics::u32_mul_with_overflow }
 
 #[cfg(target_pointer_width = "64")]
-uint_impl! { uint = u64, 64,
+uint_impl! { usize = u64, 64,
     intrinsics::ctpop64,
     intrinsics::ctlz64,
     intrinsics::cttz64,
@@ -534,6 +644,7 @@ macro_rules! int_impl {
      $sub_with_overflow:path,
      $mul_with_overflow:path) => {
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[allow(deprecated)]
         impl Int for $T {
             #[inline]
             fn zero() -> $T { 0 }
@@ -548,22 +659,32 @@ macro_rules! int_impl {
             fn max_value() -> $T { let min: $T = Int::min_value(); !min }
 
             #[inline]
-            fn count_ones(self) -> uint { (self as $UnsignedT).count_ones() }
+            fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
 
             #[inline]
-            fn leading_zeros(self) -> uint { (self as $UnsignedT).leading_zeros() }
+            fn leading_zeros(self) -> u32 {
+                (self as $UnsignedT).leading_zeros()
+            }
 
             #[inline]
-            fn trailing_zeros(self) -> uint { (self as $UnsignedT).trailing_zeros() }
+            fn trailing_zeros(self) -> u32 {
+                (self as $UnsignedT).trailing_zeros()
+            }
 
             #[inline]
-            fn rotate_left(self, n: uint) -> $T { (self as $UnsignedT).rotate_left(n) as $T }
+            fn rotate_left(self, n: u32) -> $T {
+                (self as $UnsignedT).rotate_left(n) as $T
+            }
 
             #[inline]
-            fn rotate_right(self, n: uint) -> $T { (self as $UnsignedT).rotate_right(n) as $T }
+            fn rotate_right(self, n: u32) -> $T {
+                (self as $UnsignedT).rotate_right(n) as $T
+            }
 
             #[inline]
-            fn swap_bytes(self) -> $T { (self as $UnsignedT).swap_bytes() as $T }
+            fn swap_bytes(self) -> $T {
+                (self as $UnsignedT).swap_bytes() as $T
+            }
 
             #[inline]
             fn checked_add(self, other: $T) -> Option<$T> {
@@ -614,19 +735,22 @@ int_impl! { i64 = i64, u64, 64,
     intrinsics::i64_mul_with_overflow }
 
 #[cfg(target_pointer_width = "32")]
-int_impl! { int = i32, u32, 32,
+int_impl! { isize = i32, u32, 32,
     intrinsics::i32_add_with_overflow,
     intrinsics::i32_sub_with_overflow,
     intrinsics::i32_mul_with_overflow }
 
 #[cfg(target_pointer_width = "64")]
-int_impl! { int = i64, u64, 64,
+int_impl! { isize = i64, u64, 64,
     intrinsics::i64_add_with_overflow,
     intrinsics::i64_sub_with_overflow,
     intrinsics::i64_mul_with_overflow }
 
 /// A built-in two's complement integer.
 #[stable(feature = "rust1", since = "1.0.0")]
+#[deprecated(since = "1.0.0",
+             reason = "replaced by inherent methods; for generics, use rust-lang/num")]
+#[allow(deprecated)]
 pub trait SignedInt
     : Int
     + Neg<Output=Self>
@@ -658,6 +782,7 @@ pub trait SignedInt
 macro_rules! signed_int_impl {
     ($T:ty) => {
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[allow(deprecated)]
         impl SignedInt for $T {
             #[inline]
             fn abs(self) -> $T {
@@ -686,64 +811,1084 @@ signed_int_impl! { i8 }
 signed_int_impl! { i16 }
 signed_int_impl! { i32 }
 signed_int_impl! { i64 }
-signed_int_impl! { int }
+signed_int_impl! { isize }
 
-/// A built-in unsigned integer.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait UnsignedInt: Int {
-    /// Returns `true` iff `self == 2^k` for some `k`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline]
-    fn is_power_of_two(self) -> bool {
-        (self - Int::one()) & self == Int::zero() && !(self == Int::zero())
-    }
+// `Int` + `SignedInt` implemented for signed integers
+macro_rules! int_impl {
+    ($T:ty = $ActualT:ty, $UnsignedT:ty, $BITS:expr,
+     $add_with_overflow:path,
+     $sub_with_overflow:path,
+     $mul_with_overflow:path) => {
+        /// Returns the smallest value that can be represented by this integer type.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub fn min_value() -> $T {
+            (-1 as $T) << ($BITS - 1)
+        }
 
-    /// Returns the smallest power of two greater than or equal to `self`.
-    /// Unspecified behavior on overflow.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline]
-    fn next_power_of_two(self) -> Self {
-        let bits = size_of::<Self>() * 8;
-        let one: Self = Int::one();
-        one << ((bits - (self - one).leading_zeros()) % bits)
+        /// Returns the largest value that can be represented by this integer type.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub fn max_value() -> $T {
+            let min: $T = Int::min_value(); !min
+        }
+
+        /// Convert a string slice in a given base to an integer.
+        ///
+        /// Leading and trailing whitespace represent an error.
+        ///
+        /// # Arguments
+        ///
+        /// * src - A string slice
+        /// * radix - The base to use. Must lie in the range [2 .. 36]
+        ///
+        /// # Return value
+        ///
+        /// `None` if the string did not represent a valid number.
+        /// Otherwise, `Some(n)` where `n` is the integer represented
+        /// by `src`.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[allow(deprecated)]
+        pub fn from_str_radix(src: &str, radix: u32) -> Result<$T, ParseIntError> {
+            <Self as FromStrRadix>::from_str_radix(src, radix)
+        }
+
+        /// Returns the number of ones in the binary representation of `self`.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// let n = 0b01001100u8;
+        ///
+        /// assert_eq!(n.count_ones(), 3);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
+
+        /// Returns the number of zeros in the binary representation of `self`.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// let n = 0b01001100u8;
+        ///
+        /// assert_eq!(n.count_zeros(), 5);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn count_zeros(self) -> u32 {
+            (!self).count_ones()
+        }
+
+        /// Returns the number of leading zeros in the binary representation
+        /// of `self`.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// let n = 0b0101000u16;
+        ///
+        /// assert_eq!(n.leading_zeros(), 10);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn leading_zeros(self) -> u32 {
+            (self as $UnsignedT).leading_zeros()
+        }
+
+        /// Returns the number of trailing zeros in the binary representation
+        /// of `self`.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// let n = 0b0101000u16;
+        ///
+        /// assert_eq!(n.trailing_zeros(), 3);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn trailing_zeros(self) -> u32 {
+            (self as $UnsignedT).trailing_zeros()
+        }
+
+        /// Shifts the bits to the left by a specified amount amount, `n`,
+        /// wrapping the truncated bits to the end of the resulting integer.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        /// let m = 0x3456789ABCDEF012u64;
+        ///
+        /// assert_eq!(n.rotate_left(12), m);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn rotate_left(self, n: u32) -> $T {
+            (self as $UnsignedT).rotate_left(n) as $T
+        }
+
+        /// Shifts the bits to the right by a specified amount amount, `n`,
+        /// wrapping the truncated bits to the beginning of the resulting
+        /// integer.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        /// let m = 0xDEF0123456789ABCu64;
+        ///
+        /// assert_eq!(n.rotate_right(12), m);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn rotate_right(self, n: u32) -> $T {
+            (self as $UnsignedT).rotate_right(n) as $T
+        }
+
+        /// Reverses the byte order of the integer.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        /// let m = 0xEFCDAB8967452301u64;
+        ///
+        /// assert_eq!(n.swap_bytes(), m);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn swap_bytes(self) -> $T {
+            (self as $UnsignedT).swap_bytes() as $T
+        }
+
+        /// Convert an integer from big endian to the target's endianness.
+        ///
+        /// On big endian this is a no-op. On little endian the bytes are
+        /// swapped.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        ///
+        /// if cfg!(target_endian = "big") {
+        ///     assert_eq!(Int::from_be(n), n)
+        /// } else {
+        ///     assert_eq!(Int::from_be(n), n.swap_bytes())
+        /// }
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn from_be(x: $T) -> $T {
+            if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
+        }
+
+        /// Convert an integer from little endian to the target's endianness.
+        ///
+        /// On little endian this is a no-op. On big endian the bytes are
+        /// swapped.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        ///
+        /// if cfg!(target_endian = "little") {
+        ///     assert_eq!(Int::from_le(n), n)
+        /// } else {
+        ///     assert_eq!(Int::from_le(n), n.swap_bytes())
+        /// }
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn from_le(x: $T) -> $T {
+            if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
+        }
+
+        /// Convert `self` to big endian from the target's endianness.
+        ///
+        /// On big endian this is a no-op. On little endian the bytes are
+        /// swapped.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        ///
+        /// if cfg!(target_endian = "big") {
+        ///     assert_eq!(n.to_be(), n)
+        /// } else {
+        ///     assert_eq!(n.to_be(), n.swap_bytes())
+        /// }
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn to_be(self) -> $T { // or not to be?
+            if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
+        }
+
+        /// Convert `self` to little endian from the target's endianness.
+        ///
+        /// On little endian this is a no-op. On big endian the bytes are
+        /// swapped.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        ///
+        /// if cfg!(target_endian = "little") {
+        ///     assert_eq!(n.to_le(), n)
+        /// } else {
+        ///     assert_eq!(n.to_le(), n.swap_bytes())
+        /// }
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn to_le(self) -> $T {
+            if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
+        }
+
+        /// Checked integer addition. Computes `self + other`, returning `None`
+        /// if overflow occurred.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// assert_eq!(5u16.checked_add(65530), Some(65535));
+        /// assert_eq!(6u16.checked_add(65530), None);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn checked_add(self, other: $T) -> Option<$T> {
+            checked_op!($T, $ActualT, $add_with_overflow, self, other)
+        }
+
+        /// Checked integer subtraction. Computes `self - other`, returning
+        /// `None` if underflow occurred.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// assert_eq!((-127i8).checked_sub(1), Some(-128));
+        /// assert_eq!((-128i8).checked_sub(1), None);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn checked_sub(self, other: $T) -> Option<$T> {
+            checked_op!($T, $ActualT, $sub_with_overflow, self, other)
+        }
+
+        /// Checked integer multiplication. Computes `self * other`, returning
+        /// `None` if underflow or overflow occurred.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// assert_eq!(5u8.checked_mul(51), Some(255));
+        /// assert_eq!(5u8.checked_mul(52), None);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn checked_mul(self, other: $T) -> Option<$T> {
+            checked_op!($T, $ActualT, $mul_with_overflow, self, other)
+        }
+
+        /// Checked integer division. Computes `self / other`, returning `None`
+        /// if `other == 0` or the operation results in underflow or overflow.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// assert_eq!((-127i8).checked_div(-1), Some(127));
+        /// assert_eq!((-128i8).checked_div(-1), None);
+        /// assert_eq!((1i8).checked_div(0), None);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn checked_div(self, v: $T) -> Option<$T> {
+            match v {
+                0   => None,
+               -1 if self == <$T>::min_value()
+                    => None,
+                v   => Some(self / v),
+            }
+        }
+
+        /// Saturating integer addition. Computes `self + other`, saturating at
+        /// the numeric bounds instead of overflowing.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn saturating_add(self, other: $T) -> $T {
+            match self.checked_add(other) {
+                Some(x)                       => x,
+                None if other >= <$T as Zero>::zero() => <$T>::max_value(),
+                None => <$T>::min_value(),
+            }
+        }
+
+        /// Saturating integer subtraction. Computes `self - other`, saturating
+        /// at the numeric bounds instead of overflowing.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn saturating_sub(self, other: $T) -> $T {
+            match self.checked_sub(other) {
+                Some(x)                      => x,
+                None if other >= <$T as Zero>::zero() => <$T>::min_value(),
+                None => <$T>::max_value(),
+            }
+        }
+
+        /// Wrapping (modular) addition. Computes `self + other`,
+        /// wrapping around at the boundary of the type.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn wrapping_add(self, rhs: $T) -> $T {
+            unsafe {
+                intrinsics::overflowing_add(self, rhs)
+            }
+        }
+
+        /// Wrapping (modular) subtraction. Computes `self - other`,
+        /// wrapping around at the boundary of the type.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn wrapping_sub(self, rhs: $T) -> $T {
+            unsafe {
+                intrinsics::overflowing_sub(self, rhs)
+            }
+        }
+
+        /// Wrapping (modular) multiplication. Computes `self *
+        /// other`, wrapping around at the boundary of the type.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn wrapping_mul(self, rhs: $T) -> $T {
+            unsafe {
+                intrinsics::overflowing_mul(self, rhs)
+            }
+        }
+
+        /// Raises self to the power of `exp`, using exponentiation by squaring.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// assert_eq!(2.pow(4), 16);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn pow(self, mut exp: u32) -> $T {
+            let mut base = self;
+            let mut acc = <$T as One>::one();
+
+            let mut prev_base = self;
+            let mut base_oflo = false;
+            while exp > 0 {
+                if (exp & 1) == 1 {
+                    if base_oflo {
+                        // ensure overflow occurs in the same manner it
+                        // would have otherwise (i.e. signal any exception
+                        // it would have otherwise).
+                        acc = acc * (prev_base * prev_base);
+                    } else {
+                        acc = acc * base;
+                    }
+                }
+                prev_base = base;
+                let (new_base, new_base_oflo) = base.overflowing_mul(base);
+                base = new_base;
+                base_oflo = new_base_oflo;
+                exp /= 2;
+            }
+            acc
+        }
+
+        /// Computes the absolute value of `self`. `Int::min_value()` will be
+        /// returned if the number is `Int::min_value()`.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn abs(self) -> $T {
+            if self.is_negative() { -self } else { self }
+        }
+
+        /// Returns a number representing sign of `self`.
+        ///
+        /// - `0` if the number is zero
+        /// - `1` if the number is positive
+        /// - `-1` if the number is negative
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn signum(self) -> $T {
+            match self {
+                n if n > 0 =>  1,
+                0          =>  0,
+                _          => -1,
+            }
+        }
+
+        /// Returns `true` if `self` is positive and `false` if the number
+        /// is zero or negative.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn is_positive(self) -> bool { self > 0 }
+
+        /// Returns `true` if `self` is negative and `false` if the number
+        /// is zero or positive.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn is_negative(self) -> bool { self < 0 }
     }
+}
 
-    /// Returns the smallest power of two greater than or equal to `n`. If the
-    /// next power of two is greater than the type's maximum value, `None` is
-    /// returned, otherwise the power of two is wrapped in `Some`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn checked_next_power_of_two(self) -> Option<Self> {
-        let npot = self.next_power_of_two();
-        if npot >= self {
-            Some(npot)
-        } else {
-            None
+#[lang = "i8"]
+impl i8 {
+    int_impl! { i8 = i8, u8, 8,
+        intrinsics::i8_add_with_overflow,
+        intrinsics::i8_sub_with_overflow,
+        intrinsics::i8_mul_with_overflow }
+}
+
+#[lang = "i16"]
+impl i16 {
+    int_impl! { i16 = i16, u16, 16,
+        intrinsics::i16_add_with_overflow,
+        intrinsics::i16_sub_with_overflow,
+        intrinsics::i16_mul_with_overflow }
+}
+
+#[lang = "i32"]
+impl i32 {
+    int_impl! { i32 = i32, u32, 32,
+        intrinsics::i32_add_with_overflow,
+        intrinsics::i32_sub_with_overflow,
+        intrinsics::i32_mul_with_overflow }
+}
+
+#[lang = "i64"]
+impl i64 {
+    int_impl! { i64 = i64, u64, 64,
+        intrinsics::i64_add_with_overflow,
+        intrinsics::i64_sub_with_overflow,
+        intrinsics::i64_mul_with_overflow }
+}
+
+#[cfg(target_pointer_width = "32")]
+#[lang = "isize"]
+impl isize {
+    int_impl! { isize = i32, u32, 32,
+        intrinsics::i32_add_with_overflow,
+        intrinsics::i32_sub_with_overflow,
+        intrinsics::i32_mul_with_overflow }
+}
+
+#[cfg(target_pointer_width = "64")]
+#[lang = "isize"]
+impl isize {
+    int_impl! { isize = i64, u64, 64,
+        intrinsics::i64_add_with_overflow,
+        intrinsics::i64_sub_with_overflow,
+        intrinsics::i64_mul_with_overflow }
+}
+
+// `Int` + `UnsignedInt` implemented for signed integers
+macro_rules! uint_impl {
+    ($T:ty = $ActualT:ty, $BITS:expr,
+     $ctpop:path,
+     $ctlz:path,
+     $cttz:path,
+     $bswap:path,
+     $add_with_overflow:path,
+     $sub_with_overflow:path,
+     $mul_with_overflow:path) => {
+        /// Returns the smallest value that can be represented by this integer type.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub fn min_value() -> $T { 0 }
+
+        /// Returns the largest value that can be represented by this integer type.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub fn max_value() -> $T { !0 }
+
+        /// Convert a string slice in a given base to an integer.
+        ///
+        /// Leading and trailing whitespace represent an error.
+        ///
+        /// # Arguments
+        ///
+        /// * src - A string slice
+        /// * radix - The base to use. Must lie in the range [2 .. 36]
+        ///
+        /// # Return value
+        ///
+        /// `None` if the string did not represent a valid number.
+        /// Otherwise, `Some(n)` where `n` is the integer represented
+        /// by `src`.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[allow(deprecated)]
+        pub fn from_str_radix(src: &str, radix: u32) -> Result<$T, ParseIntError> {
+            <Self as FromStrRadix>::from_str_radix(src, radix)
+        }
+
+        /// Returns the number of ones in the binary representation of `self`.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// let n = 0b01001100u8;
+        ///
+        /// assert_eq!(n.count_ones(), 3);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn count_ones(self) -> u32 {
+            unsafe { $ctpop(self as $ActualT) as u32 }
+        }
+
+        /// Returns the number of zeros in the binary representation of `self`.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// let n = 0b01001100u8;
+        ///
+        /// assert_eq!(n.count_zeros(), 5);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn count_zeros(self) -> u32 {
+            (!self).count_ones()
+        }
+
+        /// Returns the number of leading zeros in the binary representation
+        /// of `self`.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// let n = 0b0101000u16;
+        ///
+        /// assert_eq!(n.leading_zeros(), 10);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn leading_zeros(self) -> u32 {
+            unsafe { $ctlz(self as $ActualT) as u32 }
+        }
+
+        /// Returns the number of trailing zeros in the binary representation
+        /// of `self`.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// let n = 0b0101000u16;
+        ///
+        /// assert_eq!(n.trailing_zeros(), 3);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn trailing_zeros(self) -> u32 {
+            unsafe { $cttz(self as $ActualT) as u32 }
+        }
+
+        /// Shifts the bits to the left by a specified amount amount, `n`,
+        /// wrapping the truncated bits to the end of the resulting integer.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        /// let m = 0x3456789ABCDEF012u64;
+        ///
+        /// assert_eq!(n.rotate_left(12), m);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn rotate_left(self, n: u32) -> $T {
+            // Protect against undefined behaviour for over-long bit shifts
+            let n = n % $BITS;
+            (self << n) | (self >> (($BITS - n) % $BITS))
+        }
+
+        /// Shifts the bits to the right by a specified amount amount, `n`,
+        /// wrapping the truncated bits to the beginning of the resulting
+        /// integer.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        /// let m = 0xDEF0123456789ABCu64;
+        ///
+        /// assert_eq!(n.rotate_right(12), m);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn rotate_right(self, n: u32) -> $T {
+            // Protect against undefined behaviour for over-long bit shifts
+            let n = n % $BITS;
+            (self >> n) | (self << (($BITS - n) % $BITS))
+        }
+
+        /// Reverses the byte order of the integer.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        /// let m = 0xEFCDAB8967452301u64;
+        ///
+        /// assert_eq!(n.swap_bytes(), m);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn swap_bytes(self) -> $T {
+            unsafe { $bswap(self as $ActualT) as $T }
+        }
+
+        /// Convert an integer from big endian to the target's endianness.
+        ///
+        /// On big endian this is a no-op. On little endian the bytes are
+        /// swapped.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        ///
+        /// if cfg!(target_endian = "big") {
+        ///     assert_eq!(Int::from_be(n), n)
+        /// } else {
+        ///     assert_eq!(Int::from_be(n), n.swap_bytes())
+        /// }
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn from_be(x: $T) -> $T {
+            if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
+        }
+
+        /// Convert an integer from little endian to the target's endianness.
+        ///
+        /// On little endian this is a no-op. On big endian the bytes are
+        /// swapped.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        ///
+        /// if cfg!(target_endian = "little") {
+        ///     assert_eq!(Int::from_le(n), n)
+        /// } else {
+        ///     assert_eq!(Int::from_le(n), n.swap_bytes())
+        /// }
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn from_le(x: $T) -> $T {
+            if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
+        }
+
+        /// Convert `self` to big endian from the target's endianness.
+        ///
+        /// On big endian this is a no-op. On little endian the bytes are
+        /// swapped.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        ///
+        /// if cfg!(target_endian = "big") {
+        ///     assert_eq!(n.to_be(), n)
+        /// } else {
+        ///     assert_eq!(n.to_be(), n.swap_bytes())
+        /// }
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn to_be(self) -> $T { // or not to be?
+            if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
+        }
+
+        /// Convert `self` to little endian from the target's endianness.
+        ///
+        /// On little endian this is a no-op. On big endian the bytes are
+        /// swapped.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// let n = 0x0123456789ABCDEFu64;
+        ///
+        /// if cfg!(target_endian = "little") {
+        ///     assert_eq!(n.to_le(), n)
+        /// } else {
+        ///     assert_eq!(n.to_le(), n.swap_bytes())
+        /// }
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn to_le(self) -> $T {
+            if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
+        }
+
+        /// Checked integer addition. Computes `self + other`, returning `None`
+        /// if overflow occurred.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// assert_eq!(5u16.checked_add(65530), Some(65535));
+        /// assert_eq!(6u16.checked_add(65530), None);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn checked_add(self, other: $T) -> Option<$T> {
+            checked_op!($T, $ActualT, $add_with_overflow, self, other)
+        }
+
+        /// Checked integer subtraction. Computes `self - other`, returning
+        /// `None` if underflow occurred.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// assert_eq!((-127i8).checked_sub(1), Some(-128));
+        /// assert_eq!((-128i8).checked_sub(1), None);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn checked_sub(self, other: $T) -> Option<$T> {
+            checked_op!($T, $ActualT, $sub_with_overflow, self, other)
+        }
+
+        /// Checked integer multiplication. Computes `self * other`, returning
+        /// `None` if underflow or overflow occurred.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// assert_eq!(5u8.checked_mul(51), Some(255));
+        /// assert_eq!(5u8.checked_mul(52), None);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn checked_mul(self, other: $T) -> Option<$T> {
+            checked_op!($T, $ActualT, $mul_with_overflow, self, other)
+        }
+
+        /// Checked integer division. Computes `self / other`, returning `None`
+        /// if `other == 0` or the operation results in underflow or overflow.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// use std::num::Int;
+        ///
+        /// assert_eq!((-127i8).checked_div(-1), Some(127));
+        /// assert_eq!((-128i8).checked_div(-1), None);
+        /// assert_eq!((1i8).checked_div(0), None);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn checked_div(self, v: $T) -> Option<$T> {
+            match v {
+                0 => None,
+                v => Some(self / v),
+            }
+        }
+
+        /// Saturating integer addition. Computes `self + other`, saturating at
+        /// the numeric bounds instead of overflowing.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn saturating_add(self, other: $T) -> $T {
+            match self.checked_add(other) {
+                Some(x)                       => x,
+                None if other >= <$T as Zero>::zero() => <$T>::max_value(),
+                None => <$T>::min_value(),
+            }
+        }
+
+        /// Saturating integer subtraction. Computes `self - other`, saturating
+        /// at the numeric bounds instead of overflowing.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn saturating_sub(self, other: $T) -> $T {
+            match self.checked_sub(other) {
+                Some(x)                       => x,
+                None if other >= <$T as Zero>::zero() => <$T>::min_value(),
+                None => <$T>::max_value(),
+            }
+        }
+
+        /// Wrapping (modular) addition. Computes `self + other`,
+        /// wrapping around at the boundary of the type.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn wrapping_add(self, rhs: $T) -> $T {
+            unsafe {
+                intrinsics::overflowing_add(self, rhs)
+            }
+        }
+
+        /// Wrapping (modular) subtraction. Computes `self - other`,
+        /// wrapping around at the boundary of the type.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn wrapping_sub(self, rhs: $T) -> $T {
+            unsafe {
+                intrinsics::overflowing_sub(self, rhs)
+            }
+        }
+
+        /// Wrapping (modular) multiplication. Computes `self *
+        /// other`, wrapping around at the boundary of the type.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn wrapping_mul(self, rhs: $T) -> $T {
+            unsafe {
+                intrinsics::overflowing_mul(self, rhs)
+            }
+        }
+
+        /// Raises self to the power of `exp`, using exponentiation by squaring.
+        ///
+        /// # Examples
+        ///
+        /// ```rust
+        /// # #![feature(core)]
+        /// use std::num::Int;
+        ///
+        /// assert_eq!(2.pow(4), 16);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn pow(self, mut exp: u32) -> $T {
+            let mut base = self;
+            let mut acc = <$T as One>::one();
+
+            let mut prev_base = self;
+            let mut base_oflo = false;
+            while exp > 0 {
+                if (exp & 1) == 1 {
+                    if base_oflo {
+                        // ensure overflow occurs in the same manner it
+                        // would have otherwise (i.e. signal any exception
+                        // it would have otherwise).
+                        acc = acc * (prev_base * prev_base);
+                    } else {
+                        acc = acc * base;
+                    }
+                }
+                prev_base = base;
+                let (new_base, new_base_oflo) = base.overflowing_mul(base);
+                base = new_base;
+                base_oflo = new_base_oflo;
+                exp /= 2;
+            }
+            acc
+        }
+
+        /// Returns `true` iff `self == 2^k` for some `k`.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn is_power_of_two(self) -> bool {
+            (self.wrapping_sub(<$T as One>::one())) & self == <$T as Zero>::zero() &&
+                !(self == <$T as Zero>::zero())
+        }
+
+        /// Returns the smallest power of two greater than or equal to `self`.
+        /// Unspecified behavior on overflow.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[inline]
+        pub fn next_power_of_two(self) -> $T {
+            let bits = size_of::<$T>() * 8;
+            let one: $T = <$T as One>::one();
+            one << ((bits - self.wrapping_sub(one).leading_zeros() as usize) % bits)
+        }
+
+        /// Returns the smallest power of two greater than or equal to `n`. If
+        /// the next power of two is greater than the type's maximum value,
+        /// `None` is returned, otherwise the power of two is wrapped in `Some`.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub fn checked_next_power_of_two(self) -> Option<$T> {
+            let npot = self.next_power_of_two();
+            if npot >= self {
+                Some(npot)
+            } else {
+                None
+            }
         }
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl UnsignedInt for uint {}
+#[lang = "u8"]
+impl u8 {
+    uint_impl! { u8 = u8, 8,
+        intrinsics::ctpop8,
+        intrinsics::ctlz8,
+        intrinsics::cttz8,
+        bswap8,
+        intrinsics::u8_add_with_overflow,
+        intrinsics::u8_sub_with_overflow,
+        intrinsics::u8_mul_with_overflow }
+}
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl UnsignedInt for u8 {}
+#[lang = "u16"]
+impl u16 {
+    uint_impl! { u16 = u16, 16,
+        intrinsics::ctpop16,
+        intrinsics::ctlz16,
+        intrinsics::cttz16,
+        intrinsics::bswap16,
+        intrinsics::u16_add_with_overflow,
+        intrinsics::u16_sub_with_overflow,
+        intrinsics::u16_mul_with_overflow }
+}
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl UnsignedInt for u16 {}
+#[lang = "u32"]
+impl u32 {
+    uint_impl! { u32 = u32, 32,
+        intrinsics::ctpop32,
+        intrinsics::ctlz32,
+        intrinsics::cttz32,
+        intrinsics::bswap32,
+        intrinsics::u32_add_with_overflow,
+        intrinsics::u32_sub_with_overflow,
+        intrinsics::u32_mul_with_overflow }
+}
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl UnsignedInt for u32 {}
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl UnsignedInt for u64 {}
+#[lang = "u64"]
+impl u64 {
+    uint_impl! { u64 = u64, 64,
+        intrinsics::ctpop64,
+        intrinsics::ctlz64,
+        intrinsics::cttz64,
+        intrinsics::bswap64,
+        intrinsics::u64_add_with_overflow,
+        intrinsics::u64_sub_with_overflow,
+        intrinsics::u64_mul_with_overflow }
+}
+
+#[cfg(target_pointer_width = "32")]
+#[lang = "usize"]
+impl usize {
+    uint_impl! { usize = u32, 32,
+        intrinsics::ctpop32,
+        intrinsics::ctlz32,
+        intrinsics::cttz32,
+        intrinsics::bswap32,
+        intrinsics::u32_add_with_overflow,
+        intrinsics::u32_sub_with_overflow,
+        intrinsics::u32_mul_with_overflow }
+}
+
+#[cfg(target_pointer_width = "64")]
+#[lang = "usize"]
+impl usize {
+    uint_impl! { usize = u64, 64,
+        intrinsics::ctpop64,
+        intrinsics::ctlz64,
+        intrinsics::cttz64,
+        intrinsics::bswap64,
+        intrinsics::u64_add_with_overflow,
+        intrinsics::u64_sub_with_overflow,
+        intrinsics::u64_mul_with_overflow }
+}
 
 /// A generic trait for converting a value to a number.
 #[unstable(feature = "core", reason = "trait is likely to be removed")]
 pub trait ToPrimitive {
-    /// Converts the value of `self` to an `int`.
+    /// Converts the value of `self` to an `isize`.
     #[inline]
-    fn to_int(&self) -> Option<int> {
-        self.to_i64().and_then(|x| x.to_int())
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0", reason = "use to_isize")]
+    fn to_int(&self) -> Option<isize> {
+        self.to_i64().and_then(|x| x.to_isize())
+    }
+
+    /// Converts the value of `self` to an `isize`.
+    #[inline]
+    fn to_isize(&self) -> Option<isize> {
+        self.to_i64().and_then(|x| x.to_isize())
     }
 
     /// Converts the value of `self` to an `i8`.
@@ -767,10 +1912,18 @@ pub trait ToPrimitive {
     /// Converts the value of `self` to an `i64`.
     fn to_i64(&self) -> Option<i64>;
 
-    /// Converts the value of `self` to an `uint`.
+    /// Converts the value of `self` to an `usize`.
+    #[inline]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0", reason = "use to_usize")]
+    fn to_uint(&self) -> Option<usize> {
+        self.to_u64().and_then(|x| x.to_usize())
+    }
+
+    /// Converts the value of `self` to a `usize`.
     #[inline]
-    fn to_uint(&self) -> Option<uint> {
-        self.to_u64().and_then(|x| x.to_uint())
+    fn to_usize(&self) -> Option<usize> {
+        self.to_u64().and_then(|x| x.to_usize())
     }
 
     /// Converts the value of `self` to an `u8`.
@@ -845,7 +1998,9 @@ macro_rules! impl_to_primitive_int {
     ($T:ty) => (
         impl ToPrimitive for $T {
             #[inline]
-            fn to_int(&self) -> Option<int> { impl_to_primitive_int_to_int!($T, int, *self) }
+            fn to_int(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
+            #[inline]
+            fn to_isize(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
             #[inline]
             fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8, *self) }
             #[inline]
@@ -856,7 +2011,9 @@ macro_rules! impl_to_primitive_int {
             fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64, *self) }
 
             #[inline]
-            fn to_uint(&self) -> Option<uint> { impl_to_primitive_int_to_uint!($T, uint, *self) }
+            fn to_uint(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
+            #[inline]
+            fn to_usize(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
             #[inline]
             fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8, *self) }
             #[inline]
@@ -874,7 +2031,7 @@ macro_rules! impl_to_primitive_int {
     )
 }
 
-impl_to_primitive_int! { int }
+impl_to_primitive_int! { isize }
 impl_to_primitive_int! { i8 }
 impl_to_primitive_int! { i16 }
 impl_to_primitive_int! { i32 }
@@ -915,7 +2072,9 @@ macro_rules! impl_to_primitive_uint {
     ($T:ty) => (
         impl ToPrimitive for $T {
             #[inline]
-            fn to_int(&self) -> Option<int> { impl_to_primitive_uint_to_int!(int, *self) }
+            fn to_int(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
+            #[inline]
+            fn to_isize(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
             #[inline]
             fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
             #[inline]
@@ -926,7 +2085,11 @@ macro_rules! impl_to_primitive_uint {
             fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64, *self) }
 
             #[inline]
-            fn to_uint(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, uint, *self) }
+            fn to_uint(&self) -> Option<usize> { impl_to_primitive_uint_to_uint!($T, usize, *self) }
+            #[inline]
+            fn to_usize(&self) -> Option<usize> {
+                impl_to_primitive_uint_to_uint!($T, usize, *self)
+            }
             #[inline]
             fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
             #[inline]
@@ -944,7 +2107,7 @@ macro_rules! impl_to_primitive_uint {
     )
 }
 
-impl_to_primitive_uint! { uint }
+impl_to_primitive_uint! { usize }
 impl_to_primitive_uint! { u8 }
 impl_to_primitive_uint! { u16 }
 impl_to_primitive_uint! { u32 }
@@ -970,7 +2133,9 @@ macro_rules! impl_to_primitive_float {
     ($T:ident) => (
         impl ToPrimitive for $T {
             #[inline]
-            fn to_int(&self) -> Option<int> { Some(*self as int) }
+            fn to_int(&self) -> Option<isize> { Some(*self as isize) }
+            #[inline]
+            fn to_isize(&self) -> Option<isize> { Some(*self as isize) }
             #[inline]
             fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
             #[inline]
@@ -981,7 +2146,9 @@ macro_rules! impl_to_primitive_float {
             fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
 
             #[inline]
-            fn to_uint(&self) -> Option<uint> { Some(*self as uint) }
+            fn to_uint(&self) -> Option<usize> { Some(*self as usize) }
+            #[inline]
+            fn to_usize(&self) -> Option<usize> { Some(*self as usize) }
             #[inline]
             fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
             #[inline]
@@ -1005,10 +2172,19 @@ impl_to_primitive_float! { f64 }
 /// A generic trait for converting a number to a value.
 #[unstable(feature = "core", reason = "trait is likely to be removed")]
 pub trait FromPrimitive : ::marker::Sized {
-    /// Convert an `int` to return an optional value of this type. If the
+    /// Convert an `isize` to return an optional value of this type. If the
+    /// value cannot be represented by this value, the `None` is returned.
+    #[inline]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0", reason = "use from_isize")]
+    fn from_int(n: isize) -> Option<Self> {
+        FromPrimitive::from_i64(n as i64)
+    }
+
+    /// Convert an `isize` to return an optional value of this type. If the
     /// value cannot be represented by this value, the `None` is returned.
     #[inline]
-    fn from_int(n: int) -> Option<Self> {
+    fn from_isize(n: isize) -> Option<Self> {
         FromPrimitive::from_i64(n as i64)
     }
 
@@ -1037,10 +2213,19 @@ pub trait FromPrimitive : ::marker::Sized {
     /// type cannot be represented by this value, the `None` is returned.
     fn from_i64(n: i64) -> Option<Self>;
 
-    /// Convert an `uint` to return an optional value of this type. If the
+    /// Convert an `usize` to return an optional value of this type. If the
     /// type cannot be represented by this value, the `None` is returned.
     #[inline]
-    fn from_uint(n: uint) -> Option<Self> {
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0", reason = "use from_usize")]
+    fn from_uint(n: usize) -> Option<Self> {
+        FromPrimitive::from_u64(n as u64)
+    }
+
+    /// Convert a `usize` to return an optional value of this type. If the
+    /// type cannot be represented by this value, the `None` is returned.
+    #[inline]
+    fn from_usize(n: usize) -> Option<Self> {
         FromPrimitive::from_u64(n as u64)
     }
 
@@ -1086,8 +2271,15 @@ pub trait FromPrimitive : ::marker::Sized {
 
 /// A utility function that just calls `FromPrimitive::from_int`.
 #[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_int<A: FromPrimitive>(n: int) -> Option<A> {
-    FromPrimitive::from_int(n)
+#[deprecated(since = "1.0.0", reason = "use from_isize")]
+pub fn from_int<A: FromPrimitive>(n: isize) -> Option<A> {
+    FromPrimitive::from_isize(n)
+}
+
+/// A utility function that just calls `FromPrimitive::from_isize`.
+#[unstable(feature = "core", reason = "likely to be removed")]
+pub fn from_isize<A: FromPrimitive>(n: isize) -> Option<A> {
+    FromPrimitive::from_isize(n)
 }
 
 /// A utility function that just calls `FromPrimitive::from_i8`.
@@ -1116,8 +2308,15 @@ pub fn from_i64<A: FromPrimitive>(n: i64) -> Option<A> {
 
 /// A utility function that just calls `FromPrimitive::from_uint`.
 #[unstable(feature = "core", reason = "likely to be removed")]
-pub fn from_uint<A: FromPrimitive>(n: uint) -> Option<A> {
-    FromPrimitive::from_uint(n)
+#[deprecated(since = "1.0.0", reason = "use from_uint")]
+pub fn from_uint<A: FromPrimitive>(n: usize) -> Option<A> {
+    FromPrimitive::from_usize(n)
+}
+
+/// A utility function that just calls `FromPrimitive::from_usize`.
+#[unstable(feature = "core", reason = "likely to be removed")]
+pub fn from_usize<A: FromPrimitive>(n: usize) -> Option<A> {
+    FromPrimitive::from_usize(n)
 }
 
 /// A utility function that just calls `FromPrimitive::from_u8`.
@@ -1158,14 +2357,15 @@ pub fn from_f64<A: FromPrimitive>(n: f64) -> Option<A> {
 
 macro_rules! impl_from_primitive {
     ($T:ty, $to_ty:ident) => (
+        #[allow(deprecated)]
         impl FromPrimitive for $T {
-            #[inline] fn from_int(n: int) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_int(n: isize) -> Option<$T> { n.$to_ty() }
             #[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
             #[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() }
             #[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() }
             #[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() }
 
-            #[inline] fn from_uint(n: uint) -> Option<$T> { n.$to_ty() }
+            #[inline] fn from_uint(n: usize) -> Option<$T> { n.$to_ty() }
             #[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() }
             #[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() }
             #[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() }
@@ -1177,12 +2377,12 @@ macro_rules! impl_from_primitive {
     )
 }
 
-impl_from_primitive! { int, to_int }
+impl_from_primitive! { isize, to_int }
 impl_from_primitive! { i8, to_i8 }
 impl_from_primitive! { i16, to_i16 }
 impl_from_primitive! { i32, to_i32 }
 impl_from_primitive! { i64, to_i64 }
-impl_from_primitive! { uint, to_uint }
+impl_from_primitive! { usize, to_uint }
 impl_from_primitive! { u8, to_u8 }
 impl_from_primitive! { u16, to_u16 }
 impl_from_primitive! { u32, to_u32 }
@@ -1192,9 +2392,10 @@ impl_from_primitive! { f64, to_f64 }
 
 /// Cast from one machine scalar to another.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::num;
 ///
 /// let twenty: f32 = num::cast(0x14).unwrap();
@@ -1219,6 +2420,7 @@ macro_rules! impl_num_cast {
     ($T:ty, $conv:ident) => (
         impl NumCast for $T {
             #[inline]
+            #[allow(deprecated)]
             fn from<N: ToPrimitive>(n: N) -> Option<$T> {
                 // `$conv` could be generated using `concat_idents!`, but that
                 // macro seems to be broken at the moment
@@ -1232,28 +2434,37 @@ impl_num_cast! { u8,    to_u8 }
 impl_num_cast! { u16,   to_u16 }
 impl_num_cast! { u32,   to_u32 }
 impl_num_cast! { u64,   to_u64 }
-impl_num_cast! { uint,  to_uint }
+impl_num_cast! { usize,  to_uint }
 impl_num_cast! { i8,    to_i8 }
 impl_num_cast! { i16,   to_i16 }
 impl_num_cast! { i32,   to_i32 }
 impl_num_cast! { i64,   to_i64 }
-impl_num_cast! { int,   to_int }
+impl_num_cast! { isize,   to_int }
 impl_num_cast! { f32,   to_f32 }
 impl_num_cast! { f64,   to_f64 }
 
 /// Used for representing the classification of floating point numbers
-#[derive(Copy, PartialEq, Debug)]
-#[unstable(feature = "core", reason = "may be renamed")]
+#[derive(Copy, Clone, PartialEq, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub enum FpCategory {
     /// "Not a Number", often obtained by dividing by zero
+    #[stable(feature = "rust1", since = "1.0.0")]
     Nan,
+
     /// Positive or negative infinity
+    #[stable(feature = "rust1", since = "1.0.0")]
     Infinite ,
+
     /// Positive or negative zero
+    #[stable(feature = "rust1", since = "1.0.0")]
     Zero,
+
     /// De-normalized floating point representation (less precise than `Normal`)
+    #[stable(feature = "rust1", since = "1.0.0")]
     Subnormal,
+
     /// A regular floating point number
+    #[stable(feature = "rust1", since = "1.0.0")]
     Normal,
 }
 
@@ -1297,12 +2508,12 @@ pub trait Float
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MANTISSA_DIGITS` or \
                            `std::f64::MANTISSA_DIGITS` as appropriate")]
-    fn mantissa_digits(unused_self: Option<Self>) -> uint;
+    fn mantissa_digits(unused_self: Option<Self>) -> usize;
     /// Returns the number of base-10 digits of precision that this type supports.
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate")]
-    fn digits(unused_self: Option<Self>) -> uint;
+    fn digits(unused_self: Option<Self>) -> usize;
     /// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0",
@@ -1312,22 +2523,22 @@ pub trait Float
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate")]
-    fn min_exp(unused_self: Option<Self>) -> int;
+    fn min_exp(unused_self: Option<Self>) -> isize;
     /// Returns the maximum binary exponent that this type can represent.
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate")]
-    fn max_exp(unused_self: Option<Self>) -> int;
+    fn max_exp(unused_self: Option<Self>) -> isize;
     /// Returns the minimum base-10 exponent that this type can represent.
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate")]
-    fn min_10_exp(unused_self: Option<Self>) -> int;
+    fn min_10_exp(unused_self: Option<Self>) -> isize;
     /// Returns the maximum base-10 exponent that this type can represent.
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate")]
-    fn max_10_exp(unused_self: Option<Self>) -> int;
+    fn max_10_exp(unused_self: Option<Self>) -> isize;
     /// Returns the smallest finite value that this type can represent.
     #[unstable(feature = "core")]
     #[deprecated(since = "1.0.0",
@@ -1430,13 +2641,24 @@ pub trait Float
 
 /// A generic trait for converting a string with a radix (base) to a value
 #[unstable(feature = "core", reason = "needs reevaluation")]
+#[deprecated(since = "1.0.0",
+             reason = "moved to inherent methods; use e.g. i32::from_str_radix")]
 pub trait FromStrRadix {
+    #[unstable(feature = "core", reason = "needs reevaluation")]
+    #[deprecated(since = "1.0.0", reason = "moved to inherent methods")]
     type Err;
+
+    #[unstable(feature = "core", reason = "needs reevaluation")]
+    #[deprecated(since = "1.0.0",
+                 reason = "moved to inherent methods; use e.g. i32::from_str_radix")]
+    #[allow(deprecated)]
     fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::Err>;
 }
 
-/// A utility function that just calls FromStrRadix::from_str_radix.
+/// A utility function that just calls `FromStrRadix::from_str_radix`.
 #[unstable(feature = "core", reason = "needs reevaluation")]
+#[deprecated(since = "1.0.0", reason = "use e.g. i32::from_str_radix")]
+#[allow(deprecated)]
 pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: u32)
                                        -> Result<T, T::Err> {
     FromStrRadix::from_str_radix(str, radix)
@@ -1474,12 +2696,14 @@ macro_rules! from_str_radix_float_impl {
             /// `None` if the string did not represent a valid number.  Otherwise,
             /// `Some(n)` where `n` is the floating-point number represented by `src`.
             #[inline]
+            #[allow(deprecated)]
             fn from_str(src: &str) -> Result<$T, ParseFloatError> {
                 from_str_radix(src, 10)
             }
         }
 
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[allow(deprecated)]
         impl FromStrRadix for $T {
             type Err = ParseFloatError;
 
@@ -1530,7 +2754,7 @@ macro_rules! from_str_radix_float_impl {
                 let mut prev_sig = sig;
                 let mut cs = src.chars().enumerate();
                 // Exponent prefix and exponent index offset
-                let mut exp_info = None::<(char, uint)>;
+                let mut exp_info = None::<(char, usize)>;
 
                 // Parse the integer part of the significand
                 for (i, c) in cs.by_ref() {
@@ -1541,9 +2765,9 @@ macro_rules! from_str_radix_float_impl {
 
                             // add/subtract current digit depending on sign
                             if is_positive {
-                                sig = sig + ((digit as int) as $T);
+                                sig = sig + ((digit as isize) as $T);
                             } else {
-                                sig = sig - ((digit as int) as $T);
+                                sig = sig - ((digit as isize) as $T);
                             }
 
                             // Detect overflow by comparing to last value, except
@@ -1624,9 +2848,9 @@ macro_rules! from_str_radix_float_impl {
                         // Parse the exponent as decimal integer
                         let src = &src[offset..];
                         let (is_positive, exp) = match src.slice_shift_char() {
-                            Some(('-', src)) => (false, src.parse::<uint>()),
-                            Some(('+', src)) => (true,  src.parse::<uint>()),
-                            Some((_, _))     => (true,  src.parse::<uint>()),
+                            Some(('-', src)) => (false, src.parse::<usize>()),
+                            Some(('+', src)) => (true,  src.parse::<usize>()),
+                            Some((_, _))     => (true,  src.parse::<usize>()),
                             None             => return Err(PFE { kind: Invalid }),
                         };
 
@@ -1650,6 +2874,7 @@ from_str_radix_float_impl! { f64 }
 macro_rules! from_str_radix_int_impl {
     ($T:ty) => {
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[allow(deprecated)]
         impl FromStr for $T {
             type Err = ParseIntError;
             #[inline]
@@ -1659,6 +2884,7 @@ macro_rules! from_str_radix_int_impl {
         }
 
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[allow(deprecated)]
         impl FromStrRadix for $T {
             type Err = ParseIntError;
             fn from_str_radix(src: &str, radix: u32)
@@ -1672,6 +2898,7 @@ macro_rules! from_str_radix_int_impl {
                 let is_signed_ty = (0 as $T) > Int::min_value();
 
                 match src.slice_shift_char() {
+                    Some(('-', "")) => Err(PIE { kind: Empty }),
                     Some(('-', src)) if is_signed_ty => {
                         // The number is negative
                         let mut result = 0;
@@ -1716,12 +2943,12 @@ macro_rules! from_str_radix_int_impl {
         }
     }
 }
-from_str_radix_int_impl! { int }
+from_str_radix_int_impl! { isize }
 from_str_radix_int_impl! { i8 }
 from_str_radix_int_impl! { i16 }
 from_str_radix_int_impl! { i32 }
 from_str_radix_int_impl! { i64 }
-from_str_radix_int_impl! { uint }
+from_str_radix_int_impl! { usize }
 from_str_radix_int_impl! { u8 }
 from_str_radix_int_impl! { u16 }
 from_str_radix_int_impl! { u32 }
@@ -1740,16 +2967,9 @@ enum IntErrorKind {
     Underflow,
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for ParseIntError {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.description().fmt(f)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for ParseIntError {
-    fn description(&self) -> &str {
+impl ParseIntError {
+    #[unstable(feature = "core", reason = "available through Error trait")]
+    pub fn description(&self) -> &str {
         match self.kind {
             IntErrorKind::Empty => "cannot parse integer from empty string",
             IntErrorKind::InvalidDigit => "invalid digit found in string",
@@ -1759,6 +2979,13 @@ impl Error for ParseIntError {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for ParseIntError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.description().fmt(f)
+    }
+}
+
 /// An error which can be returned when parsing a float.
 #[derive(Debug, Clone, PartialEq)]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1770,19 +2997,19 @@ enum FloatErrorKind {
     Invalid,
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for ParseFloatError {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.description().fmt(f)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for ParseFloatError {
-    fn description(&self) -> &str {
+impl ParseFloatError {
+    #[unstable(feature = "core", reason = "available through Error trait")]
+    pub fn description(&self) -> &str {
         match self.kind {
             FloatErrorKind::Empty => "cannot parse float from empty string",
             FloatErrorKind::Invalid => "invalid float literal",
         }
     }
 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for ParseFloatError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.description().fmt(f)
+    }
+}
diff --git a/src/libcore/num/uint.rs b/src/libcore/num/uint.rs
deleted file mode 100644 (file)
index f66a0ee..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// 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.
-//
-// 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.
-
-//! Deprecated: replaced by `usize`.
-//!
-//! The rollout of the new type will gradually take place over the
-//! alpha cycle along with the development of clearer conventions
-//! around integer types.
-
-#![unstable(feature = "core")]
-#![deprecated(since = "1.0.0", reason = "replaced by usize")]
-
-uint_module! { uint, int, ::int::BITS }
index 06502be54aaccded31e2541928248cde27f77407..d0c4885ad00b77ebbfaef418cb230976e6955f21 100644 (file)
 macro_rules! uint_module { ($T:ty, $T_SIGNED:ty, $bits:expr) => (
 
 #[unstable(feature = "core")]
-pub const BITS : uint = $bits;
+pub const BITS : u32 = $bits;
 #[unstable(feature = "core")]
-pub const BYTES : uint = ($bits / 8);
+pub const BYTES : u32 = ($bits / 8);
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const MIN: $T = 0 as $T;
 #[stable(feature = "rust1", since = "1.0.0")]
-pub const MAX: $T = 0 as $T - 1 as $T;
+pub const MAX: $T = !0 as $T;
 
 ) }
diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs
new file mode 100644 (file)
index 0000000..28276d0
--- /dev/null
@@ -0,0 +1,488 @@
+// 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(missing_docs)]
+#![allow(deprecated)]
+
+use super::Wrapping;
+
+use ops::*;
+
+use intrinsics::{overflowing_add, overflowing_sub, overflowing_mul};
+
+use intrinsics::{i8_add_with_overflow, u8_add_with_overflow};
+use intrinsics::{i16_add_with_overflow, u16_add_with_overflow};
+use intrinsics::{i32_add_with_overflow, u32_add_with_overflow};
+use intrinsics::{i64_add_with_overflow, u64_add_with_overflow};
+use intrinsics::{i8_sub_with_overflow, u8_sub_with_overflow};
+use intrinsics::{i16_sub_with_overflow, u16_sub_with_overflow};
+use intrinsics::{i32_sub_with_overflow, u32_sub_with_overflow};
+use intrinsics::{i64_sub_with_overflow, u64_sub_with_overflow};
+use intrinsics::{i8_mul_with_overflow, u8_mul_with_overflow};
+use intrinsics::{i16_mul_with_overflow, u16_mul_with_overflow};
+use intrinsics::{i32_mul_with_overflow, u32_mul_with_overflow};
+use intrinsics::{i64_mul_with_overflow, u64_mul_with_overflow};
+
+use ::{i8,i16,i32,i64};
+
+#[unstable(feature = "core", reason = "may be removed, renamed, or relocated")]
+#[deprecated(since = "1.0.0", reason = "moved to inherent methods")]
+pub trait WrappingOps {
+    fn wrapping_add(self, rhs: Self) -> Self;
+    fn wrapping_sub(self, rhs: Self) -> Self;
+    fn wrapping_mul(self, rhs: Self) -> Self;
+}
+
+#[unstable(feature = "core", reason = "may be removed, renamed, or relocated")]
+pub trait OverflowingOps {
+    fn overflowing_add(self, rhs: Self) -> (Self, bool);
+    fn overflowing_sub(self, rhs: Self) -> (Self, bool);
+    fn overflowing_mul(self, rhs: Self) -> (Self, bool);
+
+    fn overflowing_div(self, rhs: Self) -> (Self, bool);
+    fn overflowing_rem(self, rhs: Self) -> (Self, bool);
+
+    fn overflowing_shl(self, rhs: u32) -> (Self, bool);
+    fn overflowing_shr(self, rhs: u32) -> (Self, bool);
+}
+
+macro_rules! sh_impl {
+    ($t:ty, $f:ty) => (
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Shl<$f> for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn shl(self, other: $f) -> Wrapping<$t> {
+                Wrapping(self.0 << other)
+            }
+        }
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Shr<$f> for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn shr(self, other: $f) -> Wrapping<$t> {
+                Wrapping(self.0 >> other)
+            }
+        }
+    )
+}
+
+// FIXME (#23545): uncomment the remaining impls
+macro_rules! sh_impl_all {
+    ($($t:ty)*) => ($(
+        // sh_impl! { $t, u8 }
+        // sh_impl! { $t, u16 }
+        // sh_impl! { $t, u32 }
+        // sh_impl! { $t, u64 }
+        sh_impl! { $t, usize }
+
+        // sh_impl! { $t, i8 }
+        // sh_impl! { $t, i16 }
+        // sh_impl! { $t, i32 }
+        // sh_impl! { $t, i64 }
+        // sh_impl! { $t, isize }
+    )*)
+}
+
+sh_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
+
+macro_rules! wrapping_impl {
+    ($($t:ty)*) => ($(
+        impl WrappingOps for $t {
+            #[inline(always)]
+            fn wrapping_add(self, rhs: $t) -> $t {
+                unsafe {
+                    overflowing_add(self, rhs)
+                }
+            }
+            #[inline(always)]
+            fn wrapping_sub(self, rhs: $t) -> $t {
+                unsafe {
+                    overflowing_sub(self, rhs)
+                }
+            }
+            #[inline(always)]
+            fn wrapping_mul(self, rhs: $t) -> $t {
+                unsafe {
+                    overflowing_mul(self, rhs)
+                }
+            }
+        }
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Add for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn add(self, other: Wrapping<$t>) -> Wrapping<$t> {
+                Wrapping(self.0.wrapping_add(other.0))
+            }
+        }
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Sub for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn sub(self, other: Wrapping<$t>) -> Wrapping<$t> {
+                Wrapping(self.0.wrapping_sub(other.0))
+            }
+        }
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Mul for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn mul(self, other: Wrapping<$t>) -> Wrapping<$t> {
+                Wrapping(self.0.wrapping_mul(other.0))
+            }
+        }
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Not for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            fn not(self) -> Wrapping<$t> {
+                Wrapping(!self.0)
+            }
+        }
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl BitXor for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn bitxor(self, other: Wrapping<$t>) -> Wrapping<$t> {
+                Wrapping(self.0 ^ other.0)
+            }
+        }
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl BitOr for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn bitor(self, other: Wrapping<$t>) -> Wrapping<$t> {
+                Wrapping(self.0 | other.0)
+            }
+        }
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl BitAnd for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn bitand(self, other: Wrapping<$t>) -> Wrapping<$t> {
+                Wrapping(self.0 & other.0)
+            }
+        }
+    )*)
+}
+
+wrapping_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
+
+mod shift_max {
+    #![allow(non_upper_case_globals)]
+
+    pub const  i8: u32 = (1 << 3) - 1;
+    pub const i16: u32 = (1 << 4) - 1;
+    pub const i32: u32 = (1 << 5) - 1;
+    pub const i64: u32 = (1 << 6) - 1;
+
+    pub const  u8: u32 = i8;
+    pub const u16: u32 = i16;
+    pub const u32: u32 = i32;
+    pub const u64: u32 = i64;
+}
+
+macro_rules! signed_overflowing_impl {
+    ($($t:ident)*) => ($(
+        impl OverflowingOps for $t {
+            #[inline(always)]
+            fn overflowing_add(self, rhs: $t) -> ($t, bool) {
+                unsafe {
+                    concat_idents!($t, _add_with_overflow)(self, rhs)
+                }
+            }
+            #[inline(always)]
+            fn overflowing_sub(self, rhs: $t) -> ($t, bool) {
+                unsafe {
+                    concat_idents!($t, _sub_with_overflow)(self, rhs)
+                }
+            }
+            #[inline(always)]
+            fn overflowing_mul(self, rhs: $t) -> ($t, bool) {
+                unsafe {
+                    concat_idents!($t, _mul_with_overflow)(self, rhs)
+                }
+            }
+
+            #[inline(always)]
+            fn overflowing_div(self, rhs: $t) -> ($t, bool) {
+                if self == $t::MIN && rhs == -1 {
+                    (1, true)
+                } else {
+                    (self/rhs, false)
+                }
+            }
+            #[inline(always)]
+            fn overflowing_rem(self, rhs: $t) -> ($t, bool) {
+                if self == $t::MIN && rhs == -1 {
+                    (0, true)
+                } else {
+                    (self % rhs, false)
+                }
+            }
+
+            #[inline(always)]
+            fn overflowing_shl(self, rhs: u32) -> ($t, bool) {
+                (self << (rhs & self::shift_max::$t),
+                 (rhs > self::shift_max::$t))
+            }
+            #[inline(always)]
+            fn overflowing_shr(self, rhs: u32) -> ($t, bool) {
+                (self >> (rhs & self::shift_max::$t),
+                 (rhs > self::shift_max::$t))
+            }
+        }
+    )*)
+}
+
+macro_rules! unsigned_overflowing_impl {
+    ($($t:ident)*) => ($(
+        impl OverflowingOps for $t {
+            #[inline(always)]
+            fn overflowing_add(self, rhs: $t) -> ($t, bool) {
+                unsafe {
+                    concat_idents!($t, _add_with_overflow)(self, rhs)
+                }
+            }
+            #[inline(always)]
+            fn overflowing_sub(self, rhs: $t) -> ($t, bool) {
+                unsafe {
+                    concat_idents!($t, _sub_with_overflow)(self, rhs)
+                }
+            }
+            #[inline(always)]
+            fn overflowing_mul(self, rhs: $t) -> ($t, bool) {
+                unsafe {
+                    concat_idents!($t, _mul_with_overflow)(self, rhs)
+                }
+            }
+
+            #[inline(always)]
+            fn overflowing_div(self, rhs: $t) -> ($t, bool) {
+                (self/rhs, false)
+            }
+            #[inline(always)]
+            fn overflowing_rem(self, rhs: $t) -> ($t, bool) {
+                (self % rhs, false)
+            }
+
+            #[inline(always)]
+            fn overflowing_shl(self, rhs: u32) -> ($t, bool) {
+                (self << (rhs & self::shift_max::$t),
+                 (rhs > self::shift_max::$t))
+            }
+            #[inline(always)]
+            fn overflowing_shr(self, rhs: u32) -> ($t, bool) {
+                (self >> (rhs & self::shift_max::$t),
+                 (rhs > self::shift_max::$t))
+            }
+        }
+    )*)
+}
+
+signed_overflowing_impl! { i8 i16 i32 i64 }
+unsigned_overflowing_impl! { u8 u16 u32 u64 }
+
+#[cfg(target_pointer_width = "64")]
+impl OverflowingOps for usize {
+    #[inline(always)]
+    fn overflowing_add(self, rhs: usize) -> (usize, bool) {
+        unsafe {
+            let res = u64_add_with_overflow(self as u64, rhs as u64);
+            (res.0 as usize, res.1)
+        }
+    }
+    #[inline(always)]
+    fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
+        unsafe {
+            let res = u64_sub_with_overflow(self as u64, rhs as u64);
+            (res.0 as usize, res.1)
+        }
+    }
+    #[inline(always)]
+    fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
+        unsafe {
+            let res = u64_mul_with_overflow(self as u64, rhs as u64);
+            (res.0 as usize, res.1)
+        }
+    }
+    #[inline(always)]
+    fn overflowing_div(self, rhs: usize) -> (usize, bool) {
+        let (r, f) = (self as u64).overflowing_div(rhs as u64);
+        (r as usize, f)
+    }
+    #[inline(always)]
+    fn overflowing_rem(self, rhs: usize) -> (usize, bool) {
+        let (r, f) = (self as u64).overflowing_rem(rhs as u64);
+        (r as usize, f)
+    }
+    #[inline(always)]
+    fn overflowing_shl(self, rhs: u32) -> (usize, bool) {
+        let (r, f) = (self as u64).overflowing_shl(rhs);
+        (r as usize, f)
+    }
+    #[inline(always)]
+    fn overflowing_shr(self, rhs: u32) -> (usize, bool) {
+        let (r, f) = (self as u64).overflowing_shr(rhs);
+        (r as usize, f)
+    }
+}
+
+#[cfg(target_pointer_width = "32")]
+impl OverflowingOps for usize {
+    #[inline(always)]
+    fn overflowing_add(self, rhs: usize) -> (usize, bool) {
+        unsafe {
+            let res = u32_add_with_overflow(self as u32, rhs as u32);
+            (res.0 as usize, res.1)
+        }
+    }
+    #[inline(always)]
+    fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
+        unsafe {
+            let res = u32_sub_with_overflow(self as u32, rhs as u32);
+            (res.0 as usize, res.1)
+        }
+    }
+    #[inline(always)]
+    fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
+        unsafe {
+            let res = u32_mul_with_overflow(self as u32, rhs as u32);
+            (res.0 as usize, res.1)
+        }
+    }
+    #[inline(always)]
+    fn overflowing_div(self, rhs: usize) -> (usize, bool) {
+        let (r, f) = (self as u32).overflowing_div(rhs as u32);
+        (r as usize, f)
+    }
+    #[inline(always)]
+    fn overflowing_rem(self, rhs: usize) -> (usize, bool) {
+        let (r, f) = (self as u32).overflowing_rem(rhs as u32);
+        (r as usize, f)
+    }
+    #[inline(always)]
+    fn overflowing_shl(self, rhs: u32) -> (usize, bool) {
+        let (r, f) = (self as u32).overflowing_shl(rhs);
+        (r as usize, f)
+    }
+    #[inline(always)]
+    fn overflowing_shr(self, rhs: u32) -> (usize, bool) {
+        let (r, f) = (self as u32).overflowing_shr(rhs);
+        (r as usize, f)
+    }
+}
+
+#[cfg(target_pointer_width = "64")]
+impl OverflowingOps for isize {
+    #[inline(always)]
+    fn overflowing_add(self, rhs: isize) -> (isize, bool) {
+        unsafe {
+            let res = i64_add_with_overflow(self as i64, rhs as i64);
+            (res.0 as isize, res.1)
+        }
+    }
+    #[inline(always)]
+    fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
+        unsafe {
+            let res = i64_sub_with_overflow(self as i64, rhs as i64);
+            (res.0 as isize, res.1)
+        }
+    }
+    #[inline(always)]
+    fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
+        unsafe {
+            let res = i64_mul_with_overflow(self as i64, rhs as i64);
+            (res.0 as isize, res.1)
+        }
+    }
+    #[inline(always)]
+    fn overflowing_div(self, rhs: isize) -> (isize, bool) {
+        let (r, f) = (self as i64).overflowing_div(rhs as i64);
+        (r as isize, f)
+    }
+    #[inline(always)]
+    fn overflowing_rem(self, rhs: isize) -> (isize, bool) {
+        let (r, f) = (self as i64).overflowing_rem(rhs as i64);
+        (r as isize, f)
+    }
+    #[inline(always)]
+    fn overflowing_shl(self, rhs: u32) -> (isize, bool) {
+        let (r, f) = (self as i64).overflowing_shl(rhs);
+        (r as isize, f)
+    }
+    #[inline(always)]
+    fn overflowing_shr(self, rhs: u32) -> (isize, bool) {
+        let (r, f) = (self as i64).overflowing_shr(rhs);
+        (r as isize, f)
+    }
+}
+
+#[cfg(target_pointer_width = "32")]
+impl OverflowingOps for isize {
+    #[inline(always)]
+    fn overflowing_add(self, rhs: isize) -> (isize, bool) {
+        unsafe {
+            let res = i32_add_with_overflow(self as i32, rhs as i32);
+            (res.0 as isize, res.1)
+        }
+    }
+    #[inline(always)]
+    fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
+        unsafe {
+            let res = i32_sub_with_overflow(self as i32, rhs as i32);
+            (res.0 as isize, res.1)
+        }
+    }
+    #[inline(always)]
+    fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
+        unsafe {
+            let res = i32_mul_with_overflow(self as i32, rhs as i32);
+            (res.0 as isize, res.1)
+        }
+    }
+    #[inline(always)]
+    fn overflowing_div(self, rhs: isize) -> (isize, bool) {
+        let (r, f) = (self as i32).overflowing_div(rhs as i32);
+        (r as isize, f)
+    }
+    #[inline(always)]
+    fn overflowing_rem(self, rhs: isize) -> (isize, bool) {
+        let (r, f) = (self as i32).overflowing_rem(rhs as i32);
+        (r as isize, f)
+    }
+    #[inline(always)]
+    fn overflowing_shl(self, rhs: u32) -> (isize, bool) {
+        let (r, f) = (self as i32).overflowing_shl(rhs);
+        (r as isize, f)
+    }
+    #[inline(always)]
+    fn overflowing_shr(self, rhs: u32) -> (isize, bool) {
+        let (r, f) = (self as i32).overflowing_shr(rhs);
+        (r as isize, f)
+    }
+}
index fbd7f840da6e15748e2972899771deaa7b5307d5..faf305c6a13783e6965aaf061d5f46ffb8030790 100644 (file)
@@ -27,7 +27,7 @@
 //! idea to have both `T` and `&T` implement the traits `Add<T>` and `Add<&T>`
 //! so that generic code can be written without unnecessary cloning.
 //!
-//! # Example
+//! # Examples
 //!
 //! This example creates a `Point` struct that implements `Add` and `Sub`, and then
 //! demonstrates adding and subtracting two `Point`s.
@@ -73,12 +73,12 @@ use fmt;
 /// The `Drop` trait is used to run some code when a value goes out of scope. This
 /// is sometimes called a 'destructor'.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Drop`. The `drop` method is called when `_x` goes
 /// out of scope, and therefore `main` prints `Dropping!`.
 ///
-/// ```rust
+/// ```
 /// struct HasDrop;
 ///
 /// impl Drop for HasDrop {
@@ -157,15 +157,15 @@ macro_rules! forward_ref_binop {
 
 /// The `Add` trait is used to specify the functionality of `+`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up
 /// calling `add`, and therefore, `main` prints `Adding!`.
 ///
-/// ```rust
+/// ```
 /// use std::ops::Add;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Add for Foo {
@@ -184,6 +184,7 @@ macro_rules! forward_ref_binop {
 #[lang="add"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Add<RHS=Self> {
+    /// The resulting type after applying the `+` operator
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output;
 
@@ -210,15 +211,15 @@ add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 
 /// The `Sub` trait is used to specify the functionality of `-`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up
 /// calling `sub`, and therefore, `main` prints `Subtracting!`.
 ///
-/// ```rust
+/// ```
 /// use std::ops::Sub;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Sub for Foo {
@@ -237,6 +238,7 @@ add_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 #[lang="sub"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Sub<RHS=Self> {
+    /// The resulting type after applying the `-` operator
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output;
 
@@ -263,15 +265,15 @@ sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 
 /// The `Mul` trait is used to specify the functionality of `*`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
 /// calling `mul`, and therefore, `main` prints `Multiplying!`.
 ///
-/// ```rust
+/// ```
 /// use std::ops::Mul;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Mul for Foo {
@@ -290,6 +292,7 @@ sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 #[lang="mul"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Mul<RHS=Self> {
+    /// The resulting type after applying the `*` operator
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output;
 
@@ -316,7 +319,7 @@ mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 
 /// The `Div` trait is used to specify the functionality of `/`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up
 /// calling `div`, and therefore, `main` prints `Dividing!`.
@@ -324,7 +327,7 @@ mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 /// ```
 /// use std::ops::Div;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Div for Foo {
@@ -343,6 +346,7 @@ mul_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 #[lang="div"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Div<RHS=Self> {
+    /// The resulting type after applying the `/` operator
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output;
 
@@ -369,7 +373,7 @@ div_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 
 /// The `Rem` trait is used to specify the functionality of `%`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
 /// calling `rem`, and therefore, `main` prints `Remainder-ing!`.
@@ -377,7 +381,7 @@ div_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 /// ```
 /// use std::ops::Rem;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Rem for Foo {
@@ -396,6 +400,7 @@ div_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
 #[lang="rem"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Rem<RHS=Self> {
+    /// The resulting type after applying the `%` operator
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output = Self;
 
@@ -441,7 +446,7 @@ rem_float_impl! { f64, fmod }
 
 /// The `Neg` trait is used to specify the functionality of unary `-`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling
 /// `neg`, and therefore, `main` prints `Negating!`.
@@ -449,7 +454,7 @@ rem_float_impl! { f64, fmod }
 /// ```
 /// use std::ops::Neg;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Neg for Foo {
@@ -468,6 +473,7 @@ rem_float_impl! { f64, fmod }
 #[lang="neg"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Neg {
+    /// The resulting type after applying the `-` operator
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output;
 
@@ -476,48 +482,44 @@ pub trait Neg {
     fn neg(self) -> Self::Output;
 }
 
-macro_rules! neg_impl {
-    ($($t:ty)*) => ($(
+
+
+macro_rules! neg_impl_core {
+    ($id:ident => $body:expr, $($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[allow(unsigned_negation)]
         impl Neg for $t {
             #[stable(feature = "rust1", since = "1.0.0")]
             type Output = $t;
 
             #[inline]
             #[stable(feature = "rust1", since = "1.0.0")]
-            fn neg(self) -> $t { -self }
+            fn neg(self) -> $t { let $id = self; $body }
         }
 
         forward_ref_unop! { impl Neg, neg for $t }
     )*)
 }
 
-macro_rules! neg_uint_impl {
-    ($t:ty, $t_signed:ty) => {
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl Neg for $t {
-            type Output = $t;
-
-            #[inline]
-            fn neg(self) -> $t { -(self as $t_signed) as $t }
-        }
-
-        forward_ref_unop! { impl Neg, neg for $t }
-    }
+macro_rules! neg_impl_numeric {
+    ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
 }
 
-neg_impl! { isize i8 i16 i32 i64 f32 f64 }
-
-neg_uint_impl! { usize, isize }
-neg_uint_impl! { u8, i8 }
-neg_uint_impl! { u16, i16 }
-neg_uint_impl! { u32, i32 }
-neg_uint_impl! { u64, i64 }
+macro_rules! neg_impl_unsigned {
+    ($($t:ty)*) => {
+        neg_impl_core!{ x => {
+            #[cfg(stage0)]
+            use ::num::wrapping::WrappingOps;
+            !x.wrapping_add(1)
+        }, $($t)*} }
+}
 
+// neg_impl_unsigned! { usize u8 u16 u32 u64 }
+neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 }
 
 /// The `Not` trait is used to specify the functionality of unary `!`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Not`. When `!Foo` happens, it ends up calling
 /// `not`, and therefore, `main` prints `Not-ing!`.
@@ -525,7 +527,7 @@ neg_uint_impl! { u64, i64 }
 /// ```
 /// use std::ops::Not;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Not for Foo {
@@ -544,6 +546,7 @@ neg_uint_impl! { u64, i64 }
 #[lang="not"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Not {
+    /// The resulting type after applying the `!` operator
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output;
 
@@ -570,7 +573,7 @@ not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 
 /// The `BitAnd` trait is used to specify the functionality of `&`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
 /// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
@@ -578,7 +581,7 @@ not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 /// ```
 /// use std::ops::BitAnd;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl BitAnd for Foo {
@@ -597,6 +600,7 @@ not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 #[lang="bitand"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait BitAnd<RHS=Self> {
+    /// The resulting type after applying the `&` operator
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output;
 
@@ -623,7 +627,7 @@ bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 
 /// The `BitOr` trait is used to specify the functionality of `|`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
 /// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
@@ -631,7 +635,7 @@ bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 /// ```
 /// use std::ops::BitOr;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl BitOr for Foo {
@@ -650,6 +654,7 @@ bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 #[lang="bitor"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait BitOr<RHS=Self> {
+    /// The resulting type after applying the `|` operator
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output;
 
@@ -676,7 +681,7 @@ bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 
 /// The `BitXor` trait is used to specify the functionality of `^`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
 /// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
@@ -684,7 +689,7 @@ bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 /// ```
 /// use std::ops::BitXor;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl BitXor for Foo {
@@ -703,6 +708,7 @@ bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 #[lang="bitxor"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait BitXor<RHS=Self> {
+    /// The resulting type after applying the `^` operator
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output;
 
@@ -729,7 +735,7 @@ bitxor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 
 /// The `Shl` trait is used to specify the functionality of `<<`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up
 /// calling `shl`, and therefore, `main` prints `Shifting left!`.
@@ -737,7 +743,7 @@ bitxor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 /// ```
 /// use std::ops::Shl;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Shl<Foo> for Foo {
@@ -756,6 +762,7 @@ bitxor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 #[lang="shl"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Shl<RHS> {
+    /// The resulting type after applying the `<<` operator
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output;
 
@@ -800,7 +807,7 @@ shl_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 
 /// The `Shr` trait is used to specify the functionality of `>>`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up
 /// calling `shr`, and therefore, `main` prints `Shifting right!`.
@@ -808,7 +815,7 @@ shl_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 /// ```
 /// use std::ops::Shr;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Shr<Foo> for Foo {
@@ -827,6 +834,7 @@ shl_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 #[lang="shr"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Shr<RHS> {
+    /// The resulting type after applying the `>>` operator
     #[stable(feature = "rust1", since = "1.0.0")]
     type Output;
 
@@ -871,7 +879,7 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 /// The `Index` trait is used to specify the functionality of indexing operations
 /// like `arr[idx]` when used in an immutable context.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Index`. When `Foo[Bar]` happens, it ends up
 /// calling `index`, and therefore, `main` prints `Indexing!`.
@@ -879,14 +887,14 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 /// ```
 /// use std::ops::Index;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 /// struct Bar;
 ///
 /// impl Index<Bar> for Foo {
 ///     type Output = Foo;
 ///
-///     fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
+///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
 ///         println!("Indexing!");
 ///         self
 ///     }
@@ -900,17 +908,19 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 #[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Index<Idx: ?Sized> {
+    /// The returned type after indexing
+    #[stable(feature = "rust1", since = "1.0.0")]
     type Output: ?Sized;
 
     /// The method for the indexing (`Foo[Bar]`) operation
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn index<'a>(&'a self, index: &Idx) -> &'a Self::Output;
+    fn index<'a>(&'a self, index: Idx) -> &'a Self::Output;
 }
 
 /// The `IndexMut` trait is used to specify the functionality of indexing
 /// operations like `arr[idx]`, when used in a mutable context.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `IndexMut`. When `Foo[Bar]` happens, it ends up
 /// calling `index_mut`, and therefore, `main` prints `Indexing!`.
@@ -918,20 +928,20 @@ pub trait Index<Idx: ?Sized> {
 /// ```
 /// use std::ops::{Index, IndexMut};
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 /// struct Bar;
 ///
 /// impl Index<Bar> for Foo {
 ///     type Output = Foo;
 ///
-///     fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
+///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
 ///         self
 ///     }
 /// }
 ///
 /// impl IndexMut<Bar> for Foo {
-///     fn index_mut<'a>(&'a mut self, _index: &Bar) -> &'a mut Foo {
+///     fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo {
 ///         println!("Indexing!");
 ///         self
 ///     }
@@ -947,7 +957,7 @@ pub trait Index<Idx: ?Sized> {
 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
     /// The method for the indexing (`Foo[Bar]`) operation
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn index_mut<'a>(&'a mut self, index: &Idx) -> &'a mut Self::Output;
+    fn index_mut<'a>(&'a mut self, index: Idx) -> &'a mut Self::Output;
 }
 
 /// An unbounded range.
@@ -969,8 +979,10 @@ impl fmt::Debug for RangeFull {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Range<Idx> {
     /// The lower bound of the range (inclusive).
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub start: Idx,
     /// The upper bound of the range (exclusive).
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub end: Idx,
 }
 
@@ -987,11 +999,10 @@ impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RangeFrom<Idx> {
     /// The lower bound of the range (inclusive).
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub start: Idx,
 }
 
-
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
@@ -1005,6 +1016,7 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RangeTo<Idx> {
     /// The upper bound of the range (exclusive).
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub end: Idx,
 }
 
@@ -1015,11 +1027,10 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
     }
 }
 
-
 /// The `Deref` trait is used to specify the functionality of dereferencing
 /// operations like `*v`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A struct with a single field which is accessible via dereferencing the
 /// struct.
@@ -1047,6 +1058,7 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
 #[lang="deref"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Deref {
+    /// The resulting type after dereferencing
     #[stable(feature = "rust1", since = "1.0.0")]
     type Target: ?Sized;
 
@@ -1072,7 +1084,7 @@ impl<'a, T: ?Sized> Deref for &'a mut T {
 /// The `DerefMut` trait is used to specify the functionality of dereferencing
 /// mutably like `*v = 1;`
 ///
-/// # Example
+/// # Examples
 ///
 /// A struct with a single field which is modifiable via dereferencing the
 /// struct.
@@ -1121,9 +1133,8 @@ impl<'a, T: ?Sized> DerefMut for &'a mut T {
 #[lang="fn"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_paren_sugar]
-pub trait Fn<Args> {
-    type Output;
-
+#[fundamental] // so that regex can rely that `&str: !FnMut`
+pub trait Fn<Args> : FnMut<Args> {
     /// This is called when the call operator is used.
     extern "rust-call" fn call(&self, args: Args) -> Self::Output;
 }
@@ -1132,9 +1143,8 @@ pub trait Fn<Args> {
 #[lang="fn_mut"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_paren_sugar]
-pub trait FnMut<Args> {
-    type Output;
-
+#[fundamental] // so that regex can rely that `&str: !FnMut`
+pub trait FnMut<Args> : FnOnce<Args> {
     /// This is called when the call operator is used.
     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
 }
@@ -1143,29 +1153,60 @@ pub trait FnMut<Args> {
 #[lang="fn_once"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_paren_sugar]
+#[fundamental] // so that regex can rely that `&str: !FnMut`
 pub trait FnOnce<Args> {
+    /// The returned type after the call operator is used.
     type Output;
 
     /// This is called when the call operator is used.
     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
 }
 
-impl<F: ?Sized, A> FnMut<A> for F
-    where F : Fn<A>
-{
-    type Output = <F as Fn<A>>::Output;
+#[cfg(not(stage0))]
+mod impls {
+    use marker::Sized;
+    use super::{Fn, FnMut, FnOnce};
 
-    extern "rust-call" fn call_mut(&mut self, args: A) -> <F as Fn<A>>::Output {
-        self.call(args)
+    impl<'a,A,F:?Sized> Fn<A> for &'a F
+        where F : Fn<A>
+    {
+        extern "rust-call" fn call(&self, args: A) -> F::Output {
+            (**self).call(args)
+        }
     }
-}
 
-impl<F,A> FnOnce<A> for F
-    where F : FnMut<A>
-{
-    type Output = <F as FnMut<A>>::Output;
+    impl<'a,A,F:?Sized> FnMut<A> for &'a F
+        where F : Fn<A>
+    {
+        extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
+            (**self).call(args)
+        }
+    }
+
+    impl<'a,A,F:?Sized> FnOnce<A> for &'a F
+        where F : Fn<A>
+    {
+        type Output = F::Output;
+
+        extern "rust-call" fn call_once(self, args: A) -> F::Output {
+            (*self).call(args)
+        }
+    }
 
-    extern "rust-call" fn call_once(mut self, args: A) -> <F as FnMut<A>>::Output {
-        self.call_mut(args)
+    impl<'a,A,F:?Sized> FnMut<A> for &'a mut F
+        where F : FnMut<A>
+    {
+        extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
+            (*self).call_mut(args)
+        }
+    }
+
+    impl<'a,A,F:?Sized> FnOnce<A> for &'a mut F
+        where F : FnMut<A>
+    {
+        type Output = F::Output;
+        extern "rust-call" fn call_once(mut self, args: A) -> F::Output {
+            (*self).call_mut(args)
+        }
     }
 }
index abfef72a5dbc33b735a67416a191f2e1b093600c..6db7c9bd99d9b08cb02fa3e12ca5d79e84bd695a 100644 (file)
@@ -148,13 +148,12 @@ use self::Option::*;
 use clone::Clone;
 use cmp::{Eq, Ord};
 use default::Default;
-use iter::{ExactSizeIterator};
-use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, IntoIterator};
+use iter::ExactSizeIterator;
+use iter::{Iterator, DoubleEndedIterator, FromIterator, IntoIterator};
 use mem;
-use ops::{Deref, FnOnce};
+use ops::FnOnce;
 use result::Result::{Ok, Err};
 use result::Result;
-use slice::AsSlice;
 use slice;
 
 // Note that this is not a lang item per se, but it has a hidden dependency on
@@ -185,7 +184,7 @@ impl<T> Option<T> {
 
     /// Returns `true` if the option is a `Some` value
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x: Option<u32> = Some(2);
@@ -205,7 +204,7 @@ impl<T> Option<T> {
 
     /// Returns `true` if the option is a `None` value
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x: Option<u32> = Some(2);
@@ -226,7 +225,7 @@ impl<T> Option<T> {
 
     /// Convert from `Option<T>` to `Option<&T>`
     ///
-    /// # Example
+    /// # Examples
     ///
     /// Convert an `Option<String>` into an `Option<usize>`, preserving the original.
     /// The `map` method takes the `self` argument by value, consuming the original,
@@ -251,7 +250,7 @@ impl<T> Option<T> {
 
     /// Convert from `Option<T>` to `Option<&mut T>`
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let mut x = Some(2);
@@ -272,9 +271,10 @@ impl<T> Option<T> {
 
     /// Convert from `Option<T>` to `&mut [T]` (without copying)
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let mut x = Some("Diamonds");
     /// {
     ///     let v = x.as_mut_slice();
@@ -311,14 +311,14 @@ impl<T> Option<T> {
     /// Panics if the value is a `None` with a custom panic message provided by
     /// `msg`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x = Some("value");
     /// assert_eq!(x.expect("the world is ending"), "value");
     /// ```
     ///
-    /// ```{.should_fail}
+    /// ```{.should_panic}
     /// let x: Option<&str> = None;
     /// x.expect("the world is ending"); // panics with `world is ending`
     /// ```
@@ -331,7 +331,7 @@ impl<T> Option<T> {
         }
     }
 
-    /// Returns the inner `T` of a `Some(T)`.
+    /// Moves the value `v` out of the `Option<T>` if it is `Some(v)`.
     ///
     /// # Panics
     ///
@@ -343,14 +343,14 @@ impl<T> Option<T> {
     /// Instead, prefer to use pattern matching and handle the `None`
     /// case explicitly.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x = Some("air");
     /// assert_eq!(x.unwrap(), "air");
     /// ```
     ///
-    /// ```{.should_fail}
+    /// ```{.should_panic}
     /// let x: Option<&str> = None;
     /// assert_eq!(x.unwrap(), "air"); // fails
     /// ```
@@ -365,7 +365,7 @@ impl<T> Option<T> {
 
     /// Returns the contained value or a default.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// assert_eq!(Some("car").unwrap_or("bike"), "car");
@@ -382,10 +382,10 @@ impl<T> Option<T> {
 
     /// Returns the contained value or computes it from a closure.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
-    /// let k = 10i32;
+    /// let k = 10;
     /// assert_eq!(Some(4).unwrap_or_else(|| 2 * k), 4);
     /// assert_eq!(None.unwrap_or_else(|| 2 * k), 20);
     /// ```
@@ -404,7 +404,7 @@ impl<T> Option<T> {
 
     /// Maps an `Option<T>` to `Option<U>` by applying a function to a contained value
     ///
-    /// # Example
+    /// # Examples
     ///
     /// Convert an `Option<String>` into an `Option<usize>`, consuming the original:
     ///
@@ -424,7 +424,7 @@ impl<T> Option<T> {
 
     /// Applies a function to the contained value or returns a default.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x = Some("foo");
@@ -444,7 +444,7 @@ impl<T> Option<T> {
 
     /// Applies a function to the contained value or computes a default.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let k = 21;
@@ -467,9 +467,10 @@ impl<T> Option<T> {
     /// Transforms the `Option<T>` into a `Result<T, E>`, mapping `Some(v)` to
     /// `Ok(v)` and `None` to `Err(err)`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let x = Some("foo");
     /// assert_eq!(x.ok_or(0), Ok("foo"));
     ///
@@ -477,7 +478,7 @@ impl<T> Option<T> {
     /// assert_eq!(x.ok_or(0), Err(0));
     /// ```
     #[inline]
-    #[unstable(feature = "core")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn ok_or<E>(self, err: E) -> Result<T, E> {
         match self {
             Some(v) => Ok(v),
@@ -488,9 +489,10 @@ impl<T> Option<T> {
     /// Transforms the `Option<T>` into a `Result<T, E>`, mapping `Some(v)` to
     /// `Ok(v)` and `None` to `Err(err())`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let x = Some("foo");
     /// assert_eq!(x.ok_or_else(|| 0), Ok("foo"));
     ///
@@ -498,7 +500,7 @@ impl<T> Option<T> {
     /// assert_eq!(x.ok_or_else(|| 0), Err(0));
     /// ```
     #[inline]
-    #[unstable(feature = "core")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
         match self {
             Some(v) => Ok(v),
@@ -512,7 +514,7 @@ impl<T> Option<T> {
 
     /// Returns an iterator over the possibly contained value.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x = Some(4);
@@ -529,9 +531,10 @@ impl<T> Option<T> {
 
     /// Returns a mutable iterator over the possibly contained value.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let mut x = Some(4);
     /// match x.iter_mut().next() {
     ///     Some(&mut ref mut v) => *v = 42,
@@ -543,20 +546,19 @@ impl<T> Option<T> {
     /// assert_eq!(x.iter_mut().next(), None);
     /// ```
     #[inline]
-    #[unstable(feature = "core",
-               reason = "waiting for iterator conventions")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter_mut(&mut self) -> IterMut<T> {
         IterMut { inner: Item { opt: self.as_mut() } }
     }
 
     /// Returns a consuming iterator over the possibly contained value.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x = Some("string");
     /// let v: Vec<&str> = x.into_iter().collect();
-    /// assert_eq!(v, vec!["string"]);
+    /// assert_eq!(v, ["string"]);
     ///
     /// let x = None;
     /// let v: Vec<&str> = x.into_iter().collect();
@@ -574,7 +576,7 @@ impl<T> Option<T> {
 
     /// Returns `None` if the option is `None`, otherwise returns `optb`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x = Some(2);
@@ -607,7 +609,7 @@ impl<T> Option<T> {
     ///
     /// Some languages call this operation flatmap.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// fn sq(x: u32) -> Option<u32> { Some(x * x) }
@@ -629,7 +631,7 @@ impl<T> Option<T> {
 
     /// Returns the option if it contains a value, otherwise returns `optb`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x = Some(2);
@@ -660,7 +662,7 @@ impl<T> Option<T> {
     /// Returns the option if it contains a value, otherwise calls `f` and
     /// returns the result.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// fn nobody() -> Option<&'static str> { None }
@@ -685,7 +687,7 @@ impl<T> Option<T> {
 
     /// Takes the value out of the option, leaving a `None` in its place.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let mut x = Some(2);
@@ -701,15 +703,26 @@ impl<T> Option<T> {
     pub fn take(&mut self) -> Option<T> {
         mem::replace(self, None)
     }
+
+    /// Convert from `Option<T>` to `&[T]` (without copying)
+    #[inline]
+    #[unstable(feature = "as_slice", since = "unsure of the utility here")]
+    pub fn as_slice<'a>(&'a self) -> &'a [T] {
+        match *self {
+            Some(ref x) => slice::ref_slice(x),
+            None => {
+                let result: &[_] = &[];
+                result
+            }
+        }
+    }
 }
 
-impl<'a, T: Clone, D: Deref<Target=T>> Option<D> {
-    /// Maps an Option<D> to an Option<T> by dereffing and cloning the contents of the Option.
-    /// Useful for converting an Option<&T> to an Option<T>.
-    #[unstable(feature = "core",
-               reason = "recently added as part of collections reform")]
+impl<'a, T: Clone> Option<&'a T> {
+    /// Maps an Option<&T> to an Option<T> by cloning the contents of the Option.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn cloned(self) -> Option<T> {
-        self.map(|t| t.deref().clone())
+        self.map(|t| t.clone())
     }
 }
 
@@ -720,7 +733,7 @@ impl<T: Default> Option<T> {
     /// value, otherwise if `None`, returns the default value for that
     /// type.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// Convert a string to an integer, turning poorly-formed strings
     /// into 0 (the default value for integers). `parse` converts
@@ -750,22 +763,6 @@ impl<T: Default> Option<T> {
 // Trait implementations
 /////////////////////////////////////////////////////////////////////////////
 
-#[unstable(feature = "core",
-           reason = "waiting on the stability of the trait itself")]
-impl<T> AsSlice<T> for Option<T> {
-    /// Convert from `Option<T>` to `&[T]` (without copying)
-    #[inline]
-    fn as_slice<'a>(&'a self) -> &'a [T] {
-        match *self {
-            Some(ref x) => slice::ref_slice(x),
-            None => {
-                let result: &[_] = &[];
-                result
-            }
-        }
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Default for Option<T> {
     #[inline]
@@ -897,7 +894,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
     /// Here is an example which increments every integer in a vector,
     /// checking for overflow:
     ///
-    /// ```rust
+    /// ```
     /// use std::u16;
     ///
     /// let v = vec!(1, 2);
index 61b4284e1dd9c08aa617571da9e4d08356846ed0..d6e00df1fd7955ea88f773bef85ad4f7b80afb1b 100644 (file)
@@ -16,7 +16,7 @@
 //! interface for panicking is:
 //!
 //! ```ignore
-//! fn panic_impl(fmt: fmt::Arguments, &(&'static str, uint)) -> !;
+//! fn panic_impl(fmt: fmt::Arguments, &(&'static str, usize)) -> !;
 //! ```
 //!
 //! This definition allows for panicking with any general message, but it does not
@@ -34,26 +34,32 @@ use fmt;
 
 #[cold] #[inline(never)] // this is the slow path, always
 #[lang="panic"]
-pub fn panic(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
+pub fn panic(expr_file_line: &(&'static str, &'static str, u32)) -> ! {
+    // Use Arguments::new_v1 instead of format_args!("{}", expr) to potentially
+    // reduce size overhead. The format_args! macro uses str's Display trait to
+    // write expr, which calls Formatter::pad, which must accommodate string
+    // truncation and padding (even though none is used here). Using
+    // Arguments::new_v1 may allow the compiler to omit Formatter::pad from the
+    // output binary, saving up to a few kilobytes.
     let (expr, file, line) = *expr_file_line;
-    panic_fmt(format_args!("{}", expr), &(file, line))
+    panic_fmt(fmt::Arguments::new_v1(&[expr], &[]), &(file, line))
 }
 
 #[cold] #[inline(never)]
 #[lang="panic_bounds_check"]
-fn panic_bounds_check(file_line: &(&'static str, uint),
-                     index: uint, len: uint) -> ! {
+fn panic_bounds_check(file_line: &(&'static str, u32),
+                     index: usize, len: usize) -> ! {
     panic_fmt(format_args!("index out of bounds: the len is {} but the index is {}",
                            len, index), file_line)
 }
 
 #[cold] #[inline(never)]
-pub fn panic_fmt(fmt: fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
+pub fn panic_fmt(fmt: fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
     #[allow(improper_ctypes)]
     extern {
         #[lang = "panic_fmt"]
-        fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: uint) -> !;
+        fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: usize) -> !;
     }
     let (file, line) = *file_line;
-    unsafe { panic_impl(fmt, file, line) }
+    unsafe { panic_impl(fmt, file, line as usize) }
 }
index f4b1a0633de5ceecf1d122fdce30ffd0bec80707..e60bc49408195644c331d56e35926db606000bb0 100644 (file)
@@ -29,7 +29,6 @@ pub use marker::{Copy, Send, Sized, Sync};
 pub use ops::{Drop, Fn, FnMut, FnOnce};
 
 // Reexported functions
-pub use iter::range;
 pub use mem::drop;
 
 // Reexported types and traits
@@ -37,11 +36,12 @@ pub use mem::drop;
 pub use char::CharExt;
 pub use clone::Clone;
 pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
-pub use iter::{Extend, IteratorExt};
-pub use iter::{Iterator, DoubleEndedIterator};
-pub use iter::{ExactSizeIterator};
+pub use convert::{AsRef, AsMut, Into, From};
+pub use iter::{Iterator, DoubleEndedIterator, Extend, ExactSizeIterator};
 pub use option::Option::{self, Some, None};
-pub use ptr::{PtrExt, MutPtrExt};
 pub use result::Result::{self, Ok, Err};
-pub use slice::{AsSlice, SliceExt};
-pub use str::{Str, StrExt};
+pub use slice::SliceExt;
+pub use str::StrExt;
+
+#[allow(deprecated)] pub use slice::AsSlice;
+#[allow(deprecated)] pub use str::Str;
index 16b84dcf18e24aed5952b17cfbf1b7f45b1648c0..ff51e25fcbf2535f9cf81a3d0129c7dc7aa556c3 100644 (file)
 //! Working with unsafe pointers in Rust is uncommon,
 //! typically limited to a few patterns.
 //!
-//! Use the [`null` function](fn.null.html) to create null pointers,
-//! the [`is_null`](trait.PtrExt.html#tymethod.is_null)
-//! methods of the [`PtrExt` trait](trait.PtrExt.html) to check for null.
-//! The `PtrExt` trait is imported by the prelude, so `is_null` etc.
-//! work everywhere. The `PtrExt` also defines the `offset` method,
-//! for pointer math.
+//! Use the [`null` function](fn.null.html) to create null pointers, and
+//! the `is_null` method of the `*const T` type  to check for null.
+//! The `*const T` type also defines the `offset` method, for pointer math.
 //!
 //! # Common ways to create unsafe pointers
 //!
 //! let my_speed_ptr: *mut i32 = &mut my_speed;
 //! ```
 //!
+//! To get a pointer to a boxed value, dereference the box:
+//!
+//! ```
+//! let my_num: Box<i32> = Box::new(10);
+//! let my_num_ptr: *const i32 = &*my_num;
+//! let mut my_speed: Box<i32> = Box::new(88);
+//! let my_speed_ptr: *mut i32 = &mut *my_speed;
+//! ```
+//!
 //! This does not take ownership of the original allocation
 //! and requires no resource management later,
 //! but you must not use the pointer after its lifetime.
 //!
-//! ## 2. Transmute an owned box (`Box<T>`).
+//! ## 2. Consume a box (`Box<T>`).
 //!
-//! The `transmute` function takes, by value, whatever it's given
-//! and returns it as whatever type is requested, as long as the
-//! types are the same size. Because `Box<T>` and `*mut T` have the same
-//! representation they can be trivially,
-//! though unsafely, transformed from one type to the other.
+//! The `into_raw` function consumes a box and returns
+//! the raw pointer. It doesn't destroy `T` or deallocate any memory.
 //!
 //! ```
-//! use std::mem;
+//! # #![feature(alloc)]
+//! use std::boxed;
 //!
 //! unsafe {
-//!     let my_num: Box<i32> = Box::new(10);
-//!     let my_num: *const i32 = mem::transmute(my_num);
 //!     let my_speed: Box<i32> = Box::new(88);
-//!     let my_speed: *mut i32 = mem::transmute(my_speed);
+//!     let my_speed: *mut i32 = boxed::into_raw(my_speed);
 //!
 //!     // By taking ownership of the original `Box<T>` though
-//!     // we are obligated to transmute it back later to be destroyed.
-//!     drop(mem::transmute::<_, Box<i32>>(my_speed));
-//!     drop(mem::transmute::<_, Box<i32>>(my_num));
+//!     // we are obligated to put it together later to be destroyed.
+//!     drop(Box::from_raw(my_speed));
 //! }
 //! ```
 //!
@@ -67,6 +68,7 @@
 //! ## 3. Get it from C.
 //!
 //! ```
+//! # #![feature(libc)]
 //! extern crate libc;
 //!
 //! use std::mem;
@@ -101,16 +103,31 @@ use cmp::Ordering::{self, Less, Equal, Greater};
 
 // FIXME #19649: intrinsic docs don't render, so these have no docs :(
 
-#[unstable(feature = "core")]
-pub use intrinsics::copy_nonoverlapping_memory;
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+pub use intrinsics::copy_nonoverlapping;
 
-#[unstable(feature = "core")]
-pub use intrinsics::copy_memory;
+/// dox
+#[cfg(stage0)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
+    intrinsics::copy_nonoverlapping(dst, src, count)
+}
 
-#[unstable(feature = "core",
-           reason = "uncertain about naming and semantics")]
-pub use intrinsics::set_memory;
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+pub use intrinsics::copy;
 
+/// dox
+#[cfg(stage0)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
+    intrinsics::copy(dst, src, count)
+}
+
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use intrinsics::write_bytes;
 
 /// Creates a null raw pointer.
 ///
@@ -140,20 +157,6 @@ pub fn null<T>() -> *const T { 0 as *const T }
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn null_mut<T>() -> *mut T { 0 as *mut T }
 
-/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`. `count` may be
-/// `0`.
-///
-/// # Safety
-///
-/// Beyond accepting a raw pointer, this is unsafe because it will not drop the
-/// contents of `dst`, and may be used to create invalid instances of `T`.
-#[inline]
-#[unstable(feature = "core",
-           reason = "may play a larger role in std::ptr future extensions")]
-pub unsafe fn zero_memory<T>(dst: *mut T, count: usize) {
-    set_memory(dst, 0, count);
-}
-
 /// Swaps the values at two mutable locations of the same type, without
 /// deinitialising either. They may overlap, unlike `mem::swap` which is
 /// otherwise equivalent.
@@ -166,12 +169,11 @@ pub unsafe fn zero_memory<T>(dst: *mut T, count: usize) {
 pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
     // Give ourselves some scratch space to work with
     let mut tmp: T = mem::uninitialized();
-    let t: *mut T = &mut tmp;
 
     // Perform the swap
-    copy_nonoverlapping_memory(t, &*x, 1);
-    copy_memory(x, &*y, 1); // `x` and `y` may overlap
-    copy_nonoverlapping_memory(y, &*t, 1);
+    copy_nonoverlapping(x, &mut tmp, 1);
+    copy(y, x, 1); // `x` and `y` may overlap
+    copy_nonoverlapping(&tmp, y, 1);
 
     // y and t now point to the same thing, but we need to completely forget `tmp`
     // because it's no longer relevant.
@@ -207,7 +209,7 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn read<T>(src: *const T) -> T {
     let mut tmp: T = mem::uninitialized();
-    copy_nonoverlapping_memory(&mut tmp, src, 1);
+    copy_nonoverlapping(src, &mut tmp, 1);
     tmp
 }
 
@@ -224,7 +226,22 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
     let tmp = read(&*dest);
 
     // Now zero out `dest`:
-    zero_memory(dest, 1);
+    write_bytes(dest, 0, 1);
+
+    tmp
+}
+
+/// Variant of read_and_zero that writes the specific drop-flag byte
+/// (which may be more appropriate than zero).
+#[inline(always)]
+#[unstable(feature = "core",
+           reason = "may play a larger role in std::ptr future extensions")]
+pub unsafe fn read_and_drop<T>(dest: *mut T) -> T {
+    // Copy the data out from `dest`:
+    let tmp = read(&*dest);
+
+    // Now mark `dest` as dropped:
+    write_bytes(dest, mem::POST_DROP_U8, 1);
 
     tmp
 }
@@ -246,14 +263,15 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
     intrinsics::move_val_init(&mut *dst, src)
 }
 
-/// Methods on raw pointers
 #[stable(feature = "rust1", since = "1.0.0")]
-pub trait PtrExt: Sized {
-    type Target;
-
+#[lang = "const_ptr"]
+impl<T: ?Sized> *const T {
     /// Returns true if the pointer is null.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_null(self) -> bool;
+    #[inline]
+    pub fn is_null(self) -> bool where T: Sized {
+        self == 0 as *const T
+    }
 
     /// Returns `None` if the pointer is null, or else returns a reference to
     /// the value wrapped in `Some`.
@@ -267,7 +285,14 @@ pub trait PtrExt: Sized {
     #[unstable(feature = "core",
                reason = "Option is not clearly the right return type, and we may want \
                          to tie the return lifetime to a borrow of the raw pointer")]
-    unsafe fn as_ref<'a>(&self) -> Option<&'a Self::Target>;
+    #[inline]
+    pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> where T: Sized {
+        if self.is_null() {
+            None
+        } else {
+            Some(&**self)
+        }
+    }
 
     /// Calculates the offset from a pointer. `count` is in units of T; e.g. a
     /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
@@ -278,90 +303,69 @@ pub trait PtrExt: Sized {
     /// Otherwise `offset` invokes Undefined Behaviour, regardless of whether
     /// the pointer is used.
     #[stable(feature = "rust1", since = "1.0.0")]
-    unsafe fn offset(self, count: isize) -> Self;
+    #[inline]
+    pub unsafe fn offset(self, count: isize) -> *const T where T: Sized {
+        intrinsics::offset(self, count)
+    }
 }
 
-/// Methods on mutable raw pointers
 #[stable(feature = "rust1", since = "1.0.0")]
-pub trait MutPtrExt {
-    type Target;
+#[lang = "mut_ptr"]
+impl<T: ?Sized> *mut T {
+    /// Returns true if the pointer is null.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_null(self) -> bool where T: Sized {
+        self == 0 as *mut T
+    }
 
-    /// Returns `None` if the pointer is null, or else returns a mutable
-    /// reference to the value wrapped in `Some`.
+    /// Returns `None` if the pointer is null, or else returns a reference to
+    /// the value wrapped in `Some`.
     ///
     /// # Safety
     ///
-    /// As with `as_ref`, this is unsafe because it cannot verify the validity
-    /// of the returned pointer.
+    /// While this method and its mutable counterpart are useful for
+    /// null-safety, it is important to note that this is still an unsafe
+    /// operation because the returned value could be pointing to invalid
+    /// memory.
     #[unstable(feature = "core",
                reason = "Option is not clearly the right return type, and we may want \
                          to tie the return lifetime to a borrow of the raw pointer")]
-    unsafe fn as_mut<'a>(&self) -> Option<&'a mut Self::Target>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> PtrExt for *const T {
-    type Target = T;
-
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_null(self) -> bool { self == 0 as *const T }
-
     #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    unsafe fn offset(self, count: isize) -> *const T {
-        intrinsics::offset(self, count)
-    }
-
-    #[inline]
-    #[unstable(feature = "core",
-               reason = "return value does not necessarily convey all possible \
-                         information")]
-    unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
+    pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> where T: Sized {
         if self.is_null() {
             None
         } else {
             Some(&**self)
         }
     }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> PtrExt for *mut T {
-    type Target = T;
 
-    #[inline]
+    /// Calculates the offset from a pointer. `count` is in units of T; e.g. a
+    /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
+    ///
+    /// # Safety
+    ///
+    /// The offset must be in-bounds of the object, or one-byte-past-the-end.
+    /// Otherwise `offset` invokes Undefined Behaviour, regardless of whether
+    /// the pointer is used.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_null(self) -> bool { self == 0 as *mut T }
-
     #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    unsafe fn offset(self, count: isize) -> *mut T {
+    pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
         intrinsics::offset(self, count) as *mut T
     }
 
-    #[inline]
+    /// Returns `None` if the pointer is null, or else returns a mutable
+    /// reference to the value wrapped in `Some`.
+    ///
+    /// # Safety
+    ///
+    /// As with `as_ref`, this is unsafe because it cannot verify the validity
+    /// of the returned pointer.
     #[unstable(feature = "core",
                reason = "return value does not necessarily convey all possible \
                          information")]
-    unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
-        if self.is_null() {
-            None
-        } else {
-            Some(&**self)
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T> MutPtrExt for *mut T {
-    type Target = T;
-
     #[inline]
-    #[unstable(feature = "core",
-               reason = "return value does not necessarily convey all possible \
-                         information")]
-    unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
+    pub unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> where T: Sized {
         if self.is_null() {
             None
         } else {
@@ -372,33 +376,25 @@ impl<T> MutPtrExt for *mut T {
 
 // Equality for pointers
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> PartialEq for *const T {
+impl<T: ?Sized> PartialEq for *const T {
     #[inline]
-    fn eq(&self, other: &*const T) -> bool {
-        *self == *other
-    }
-    #[inline]
-    fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
+    fn eq(&self, other: &*const T) -> bool { *self == *other }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Eq for *const T {}
+impl<T: ?Sized> Eq for *const T {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> PartialEq for *mut T {
-    #[inline]
-    fn eq(&self, other: &*mut T) -> bool {
-        *self == *other
-    }
+impl<T: ?Sized> PartialEq for *mut T {
     #[inline]
-    fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
+    fn eq(&self, other: &*mut T) -> bool { *self == *other }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Eq for *mut T {}
+impl<T: ?Sized> Eq for *mut T {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Clone for *const T {
+impl<T: ?Sized> Clone for *const T {
     #[inline]
     fn clone(&self) -> *const T {
         *self
@@ -406,7 +402,7 @@ impl<T> Clone for *const T {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Clone for *mut T {
+impl<T: ?Sized> Clone for *mut T {
     #[inline]
     fn clone(&self) -> *mut T {
         *self
@@ -450,7 +446,7 @@ mod externfnpointers {
 
 // Comparison for pointers
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Ord for *const T {
+impl<T: ?Sized> Ord for *const T {
     #[inline]
     fn cmp(&self, other: &*const T) -> Ordering {
         if self < other {
@@ -464,7 +460,7 @@ impl<T> Ord for *const T {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> PartialOrd for *const T {
+impl<T: ?Sized> PartialOrd for *const T {
     #[inline]
     fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
         Some(self.cmp(other))
@@ -484,7 +480,7 @@ impl<T> PartialOrd for *const T {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Ord for *mut T {
+impl<T: ?Sized> Ord for *mut T {
     #[inline]
     fn cmp(&self, other: &*mut T) -> Ordering {
         if self < other {
@@ -498,7 +494,7 @@ impl<T> Ord for *mut T {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> PartialOrd for *mut T {
+impl<T: ?Sized> PartialOrd for *mut T {
     #[inline]
     fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
         Some(self.cmp(other))
@@ -525,8 +521,8 @@ impl<T> PartialOrd for *mut T {
 /// modified without a unique path to the `Unique` reference. Useful
 /// for building abstractions like `Vec<T>` or `Box<T>`, which
 /// internally use raw pointers to manage the memory that they own.
-#[unstable(feature = "core", reason = "recently added to this module")]
-pub struct Unique<T:?Sized> {
+#[unstable(feature = "unique")]
+pub struct Unique<T: ?Sized> {
     pointer: NonZero<*const T>,
     _marker: PhantomData<T>,
 }
@@ -535,39 +531,37 @@ pub struct Unique<T:?Sized> {
 /// reference is unaliased. Note that this aliasing invariant is
 /// unenforced by the type system; the abstraction using the
 /// `Unique` must enforce it.
-#[unstable(feature = "core", reason = "recently added to this module")]
+#[unstable(feature = "unique")]
 unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
 
 /// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
 /// reference is unaliased. Note that this aliasing invariant is
 /// unenforced by the type system; the abstraction using the
 /// `Unique` must enforce it.
-#[unstable(feature = "core", reason = "recently added to this module")]
+#[unstable(feature = "unique")]
 unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
 
-impl<T:?Sized> Unique<T> {
+impl<T: ?Sized> Unique<T> {
     /// Create a new `Unique`.
-    #[unstable(feature = "core",
-               reason = "recently added to this module")]
+    #[unstable(feature = "unique")]
     pub unsafe fn new(ptr: *mut T) -> Unique<T> {
-        Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData }
+        Unique { pointer: NonZero::new(ptr), _marker: PhantomData }
     }
 
     /// Dereference the content.
-    #[unstable(feature = "core",
-               reason = "recently added to this module")]
+    #[unstable(feature = "unique")]
     pub unsafe fn get(&self) -> &T {
         &**self.pointer
     }
 
     /// Mutably dereference the content.
-    #[unstable(feature = "core",
-               reason = "recently added to this module")]
+    #[unstable(feature = "unique")]
     pub unsafe fn get_mut(&mut self) -> &mut T {
         &mut ***self
     }
 }
 
+#[unstable(feature = "unique")]
 impl<T:?Sized> Deref for Unique<T> {
     type Target = *mut T;
 
index 5cc210df5b464e5d6581614df4d17a2012a6f323..ded52ff07785ebd100c3c251fda7999db367ed2c 100644 (file)
@@ -18,6 +18,7 @@
 //!
 //! Their definition should always match the ABI defined in `rustc::back::abi`.
 
+use clone::Clone;
 use marker::Copy;
 use mem;
 
@@ -48,6 +49,7 @@ use mem;
 /// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::raw::{self, Repr};
 ///
 /// let slice: &[u16] = &[1, 2, 3, 4];
@@ -62,17 +64,8 @@ pub struct Slice<T> {
 }
 
 impl<T> Copy for Slice<T> {}
-
-/// The representation of an old closure.
-#[repr(C)]
-#[derive(Copy)]
-#[unstable(feature = "core")]
-#[deprecated(reason = "unboxed new closures do not have a universal representation; \
-                       `&Fn` (etc) trait objects should use `TraitObject` instead",
-             since= "1.0.0")]
-pub struct Closure {
-    pub code: *mut (),
-    pub env: *mut (),
+impl<T> Clone for Slice<T> {
+    fn clone(&self) -> Slice<T> { *self }
 }
 
 /// The representation of a trait object like `&SomeTrait`.
@@ -105,6 +98,7 @@ pub struct Closure {
 /// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::mem;
 /// use std::raw;
 ///
@@ -146,7 +140,7 @@ pub struct Closure {
 /// assert_eq!(synthesized.bar(), 457);
 /// ```
 #[repr(C)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct TraitObject {
     pub data: *mut (),
     pub vtable: *mut (),
index 23e936a75d7097e04f972a3da25796a285090711..eff04dd5903936f997ff147a76d39b530349cb63 100644 (file)
 //! that make working with it more succinct.
 //!
 //! ```
-//! let good_result: Result<int, int> = Ok(10);
-//! let bad_result: Result<int, int> = Err(10);
+//! let good_result: Result<i32, i32> = Ok(10);
+//! let bad_result: Result<i32, i32> = Err(10);
 //!
 //! // The `is_ok` and `is_err` methods do what they say.
 //! assert!(good_result.is_ok() && !good_result.is_err());
 //! assert!(bad_result.is_err() && !bad_result.is_ok());
 //!
 //! // `map` consumes the `Result` and produces another.
-//! let good_result: Result<int, int> = good_result.map(|i| i + 1);
-//! let bad_result: Result<int, int> = bad_result.map(|i| i - 1);
+//! let good_result: Result<i32, i32> = good_result.map(|i| i + 1);
+//! let bad_result: Result<i32, i32> = bad_result.map(|i| i - 1);
 //!
 //! // Use `and_then` to continue the computation.
-//! let good_result: Result<bool, int> = good_result.and_then(|i| Ok(i == 11));
+//! let good_result: Result<bool, i32> = good_result.and_then(|i| Ok(i == 11));
 //!
 //! // Use `or_else` to handle the error.
-//! let bad_result: Result<int, int> = bad_result.or_else(|i| Ok(11));
+//! let bad_result: Result<i32, i32> = bad_result.or_else(|i| Ok(11));
 //!
 //! // Consume the result and return the contents with `unwrap`.
-//! let final_awesome_result = good_result.ok().unwrap();
+//! let final_awesome_result = good_result.unwrap();
 //! ```
 //!
 //! # Results must be used
 //! useful value.
 //!
 //! Consider the `write_line` method defined for I/O types
-//! by the [`Writer`](../io/trait.Writer.html) trait:
+//! by the [`Writer`](../old_io/trait.Writer.html) trait:
 //!
 //! ```
+//! # #![feature(old_io)]
 //! use std::old_io::IoError;
 //!
 //! trait Writer {
 //! something like this:
 //!
 //! ```{.ignore}
-//! use std::old_io::{File, Open, Write};
+//! # #![feature(old_io)]
+//! use std::old_io::*;
+//! use std::old_path::Path;
 //!
 //! let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
 //! // If `write_line` errors, then we'll never know, because the return
 //! a marginally useful message indicating why:
 //!
 //! ```{.no_run}
-//! use std::old_io::{File, Open, Write};
+//! # #![feature(old_io, old_path)]
+//! use std::old_io::*;
+//! use std::old_path::Path;
 //!
 //! let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
 //! file.write_line("important message").ok().expect("failed to write message");
 //! You might also simply assert success:
 //!
 //! ```{.no_run}
-//! # use std::old_io::{File, Open, Write};
+//! # #![feature(old_io, old_path)]
+//! # use std::old_io::*;
+//! # use std::old_path::Path;
 //!
 //! # let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
 //! assert!(file.write_line("important message").is_ok());
 //! Or propagate the error up the call stack with `try!`:
 //!
 //! ```
-//! # use std::old_io::{File, Open, Write, IoError};
+//! # #![feature(old_io, old_path)]
+//! # use std::old_io::*;
+//! # use std::old_path::Path;
 //! fn write_message() -> Result<(), IoError> {
 //!     let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
 //!     try!(file.write_line("important message"));
 //! It replaces this:
 //!
 //! ```
-//! use std::old_io::{File, Open, Write, IoError};
+//! # #![feature(old_io, old_path)]
+//! use std::old_io::*;
+//! use std::old_path::Path;
 //!
 //! struct Info {
 //!     name: String,
-//!     age: int,
-//!     rating: int
+//!     age: i32,
+//!     rating: i32,
 //! }
 //!
 //! fn write_info(info: &Info) -> Result<(), IoError> {
 //!     let mut file = File::open_mode(&Path::new("my_best_friends.txt"), Open, Write);
 //!     // Early return on error
-//!     if let Err(e) = file.write_line(format!("name: {}", info.name).as_slice()) {
+//!     if let Err(e) = file.write_line(&format!("name: {}", info.name)) {
 //!         return Err(e)
 //!     }
-//!     if let Err(e) = file.write_line(format!("age: {}", info.age).as_slice()) {
+//!     if let Err(e) = file.write_line(&format!("age: {}", info.age)) {
 //!         return Err(e)
 //!     }
-//!     return file.write_line(format!("rating: {}", info.rating).as_slice());
+//!     return file.write_line(&format!("rating: {}", info.rating));
 //! }
 //! ```
 //!
 //! With this:
 //!
 //! ```
-//! use std::old_io::{File, Open, Write, IoError};
+//! # #![feature(old_io, old_path)]
+//! use std::old_io::*;
+//! use std::old_path::Path;
 //!
 //! struct Info {
 //!     name: String,
-//!     age: int,
-//!     rating: int
+//!     age: i32,
+//!     rating: i32,
 //! }
 //!
 //! fn write_info(info: &Info) -> Result<(), IoError> {
 //!     let mut file = File::open_mode(&Path::new("my_best_friends.txt"), Open, Write);
 //!     // Early return on error
-//!     try!(file.write_line(format!("name: {}", info.name).as_slice()));
-//!     try!(file.write_line(format!("age: {}", info.age).as_slice()));
-//!     try!(file.write_line(format!("rating: {}", info.rating).as_slice()));
+//!     try!(file.write_line(&format!("name: {}", info.name)));
+//!     try!(file.write_line(&format!("age: {}", info.age)));
+//!     try!(file.write_line(&format!("rating: {}", info.rating)));
 //!     return Ok(());
 //! }
 //! ```
@@ -230,10 +243,10 @@ use self::Result::{Ok, Err};
 
 use clone::Clone;
 use fmt;
-use iter::{Iterator, IteratorExt, DoubleEndedIterator,
-           FromIterator, ExactSizeIterator, IntoIterator};
+use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSizeIterator, IntoIterator};
 use ops::{FnMut, FnOnce};
 use option::Option::{self, None, Some};
+#[allow(deprecated)]
 use slice::AsSlice;
 use slice;
 
@@ -265,13 +278,13 @@ impl<T, E> Result<T, E> {
 
     /// Returns true if the result is `Ok`
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
-    /// let x: Result<int, &str> = Ok(-3);
+    /// let x: Result<i32, &str> = Ok(-3);
     /// assert_eq!(x.is_ok(), true);
     ///
-    /// let x: Result<int, &str> = Err("Some error message");
+    /// let x: Result<i32, &str> = Err("Some error message");
     /// assert_eq!(x.is_ok(), false);
     /// ```
     #[inline]
@@ -285,13 +298,13 @@ impl<T, E> Result<T, E> {
 
     /// Returns true if the result is `Err`
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
-    /// let x: Result<int, &str> = Ok(-3);
+    /// let x: Result<i32, &str> = Ok(-3);
     /// assert_eq!(x.is_err(), false);
     ///
-    /// let x: Result<int, &str> = Err("Some error message");
+    /// let x: Result<i32, &str> = Err("Some error message");
     /// assert_eq!(x.is_err(), true);
     /// ```
     #[inline]
@@ -309,7 +322,7 @@ impl<T, E> Result<T, E> {
     /// Converts `self` into an `Option<T>`, consuming `self`,
     /// and discarding the error, if any.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x: Result<u32, &str> = Ok(2);
@@ -330,9 +343,9 @@ impl<T, E> Result<T, E> {
     /// Convert from `Result<T, E>` to `Option<E>`
     ///
     /// Converts `self` into an `Option<E>`, consuming `self`,
-    /// and discarding the value, if any.
+    /// and discarding the success value, if any.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x: Result<u32, &str> = Ok(2);
@@ -378,18 +391,18 @@ impl<T, E> Result<T, E> {
     /// Convert from `Result<T, E>` to `Result<&mut T, &mut E>`
     ///
     /// ```
-    /// fn mutate(r: &mut Result<int, int>) {
+    /// fn mutate(r: &mut Result<i32, i32>) {
     ///     match r.as_mut() {
     ///         Ok(&mut ref mut v) => *v = 42,
     ///         Err(&mut ref mut e) => *e = 0,
     ///     }
     /// }
     ///
-    /// let mut x: Result<int, int> = Ok(2);
+    /// let mut x: Result<i32, i32> = Ok(2);
     /// mutate(&mut x);
     /// assert_eq!(x.unwrap(), 42);
     ///
-    /// let mut x: Result<int, int> = Err(13);
+    /// let mut x: Result<i32, i32> = Err(13);
     /// mutate(&mut x);
     /// assert_eq!(x.unwrap_err(), 0);
     /// ```
@@ -402,9 +415,24 @@ impl<T, E> Result<T, E> {
         }
     }
 
+    /// Convert from `Result<T, E>` to `&[T]` (without copying)
+    #[inline]
+    #[unstable(feature = "as_slice", since = "unsure of the utility here")]
+    pub fn as_slice(&self) -> &[T] {
+        match *self {
+            Ok(ref x) => slice::ref_slice(x),
+            Err(_) => {
+                // work around lack of implicit coercion from fixed-size array to slice
+                let emp: &[_] = &[];
+                emp
+            }
+        }
+    }
+
     /// Convert from `Result<T, E>` to `&mut [T]` (without copying)
     ///
     /// ```
+    /// # #![feature(core)]
     /// let mut x: Result<&str, u32> = Ok("Gold");
     /// {
     ///     let v = x.as_mut_slice();
@@ -440,26 +468,28 @@ impl<T, E> Result<T, E> {
     ///
     /// This function can be used to compose the results of two functions.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// Sum the lines of a buffer by mapping strings to numbers,
     /// ignoring I/O and parse errors:
     ///
     /// ```
-    /// use std::old_io::IoResult;
+    /// # #![feature(old_io)]
+    /// use std::old_io::*;
     ///
-    /// let mut buffer = &mut b"1\n2\n3\n4\n";
+    /// let mut buffer: &[u8] = b"1\n2\n3\n4\n";
+    /// let mut buffer = &mut buffer;
     ///
     /// let mut sum = 0;
     ///
     /// while !buffer.is_empty() {
     ///     let line: IoResult<String> = buffer.read_line();
     ///     // Convert the string line to a number using `map` and `from_str`
-    ///     let val: IoResult<int> = line.map(|line| {
-    ///         line.trim_right().parse::<int>().unwrap_or(0)
+    ///     let val: IoResult<i32> = line.map(|line| {
+    ///         line.trim_right().parse::<i32>().unwrap_or(0)
     ///     });
     ///     // Add the value if there were no errors, otherwise add 0
-    ///     sum += val.ok().unwrap_or(0);
+    ///     sum += val.unwrap_or(0);
     /// }
     ///
     /// assert!(sum == 10);
@@ -479,7 +509,7 @@ impl<T, E> Result<T, E> {
     /// This function can be used to pass through a successful result while handling
     /// an error.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// fn stringify(x: u32) -> String { format!("error code: {}", x) }
@@ -505,7 +535,7 @@ impl<T, E> Result<T, E> {
 
     /// Returns an iterator over the possibly contained value.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x: Result<u32, &str> = Ok(7);
@@ -522,7 +552,7 @@ impl<T, E> Result<T, E> {
 
     /// Returns a mutable iterator over the possibly contained value.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let mut x: Result<u32, &str> = Ok(7);
@@ -543,16 +573,16 @@ impl<T, E> Result<T, E> {
 
     /// Returns a consuming iterator over the possibly contained value.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x: Result<u32, &str> = Ok(5);
     /// let v: Vec<u32> = x.into_iter().collect();
-    /// assert_eq!(v, vec![5]);
+    /// assert_eq!(v, [5]);
     ///
     /// let x: Result<u32, &str> = Err("nothing!");
     /// let v: Vec<u32> = x.into_iter().collect();
-    /// assert_eq!(v, vec![]);
+    /// assert_eq!(v, []);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -566,7 +596,7 @@ impl<T, E> Result<T, E> {
 
     /// Returns `res` if the result is `Ok`, otherwise returns the `Err` value of `self`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x: Result<u32, &str> = Ok(2);
@@ -598,7 +628,7 @@ impl<T, E> Result<T, E> {
     ///
     /// This function can be used for control flow based on result values.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) }
@@ -620,7 +650,7 @@ impl<T, E> Result<T, E> {
 
     /// Returns `res` if the result is `Err`, otherwise returns the `Ok` value of `self`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x: Result<u32, &str> = Ok(2);
@@ -641,9 +671,9 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn or(self, res: Result<T, E>) -> Result<T, E> {
+    pub fn or<F>(self, res: Result<T, F>) -> Result<T, F> {
         match self {
-            Ok(_) => self,
+            Ok(v) => Ok(v),
             Err(_) => res,
         }
     }
@@ -652,7 +682,7 @@ impl<T, E> Result<T, E> {
     ///
     /// This function can be used for control flow based on result values.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) }
@@ -675,7 +705,7 @@ impl<T, E> Result<T, E> {
     /// Unwraps a result, yielding the content of an `Ok`.
     /// Else it returns `optb`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let optb = 2;
@@ -697,7 +727,7 @@ impl<T, E> Result<T, E> {
     /// Unwraps a result, yielding the content of an `Ok`.
     /// If the value is an `Err` then it calls `op` with its value.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// fn count(x: &str) -> usize { x.len() }
@@ -724,14 +754,14 @@ impl<T, E: fmt::Debug> Result<T, E> {
     /// Panics if the value is an `Err`, with a custom panic message provided
     /// by the `Err`'s value.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let x: Result<u32, &str> = Ok(2);
     /// assert_eq!(x.unwrap(), 2);
     /// ```
     ///
-    /// ```{.should_fail}
+    /// ```{.should_panic}
     /// let x: Result<u32, &str> = Err("emergency failure");
     /// x.unwrap(); // panics with `emergency failure`
     /// ```
@@ -755,9 +785,9 @@ impl<T: fmt::Debug, E> Result<T, E> {
     /// Panics if the value is an `Ok`, with a custom panic message provided
     /// by the `Ok`'s value.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```{.should_fail}
+    /// ```{.should_panic}
     /// let x: Result<u32, &str> = Ok(2);
     /// x.unwrap_err(); // panics with `2`
     /// ```
@@ -781,10 +811,14 @@ impl<T: fmt::Debug, E> Result<T, E> {
 // Trait implementations
 /////////////////////////////////////////////////////////////////////////////
 
+#[unstable(feature = "core",
+           reason = "waiting on the stability of the trait itself")]
+#[deprecated(since = "1.0.0",
+             reason = "use inherent method instead")]
+#[allow(deprecated)]
 impl<T, E> AsSlice<T> for Result<T, E> {
     /// Convert from `Result<T, E>` to `&[T]` (without copying)
     #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn as_slice<'a>(&'a self) -> &'a [T] {
         match *self {
             Ok(ref x) => slice::ref_slice(x),
@@ -896,7 +930,7 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
     /// Here is an example which increments every integer in a vector,
     /// checking for overflow:
     ///
-    /// ```rust
+    /// ```
     /// use std::u32;
     ///
     /// let v = vec!(1, 2);
index 0058971faf0796d45727470afdac4e56a734947a..7b55ba49a07f779e83766b417cc4b35861dbdafb 100644 (file)
@@ -19,7 +19,7 @@
 //! provided beyond this module.
 //!
 //! ```rust
-//!
+//! # #![feature(core)]
 //! fn main() {
 //!     use std::simd::f32x4;
 //!     let a = f32x4(40.0, 41.0, 42.0, 43.0);
@@ -38,7 +38,7 @@
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
                  pub i8, pub i8, pub i8, pub i8,
@@ -47,26 +47,26 @@ pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
                  pub i16, pub i16, pub i16, pub i16);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct i64x2(pub i64, pub i64);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
                  pub u8, pub u8, pub u8, pub u8,
@@ -75,31 +75,31 @@ pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
                  pub u16, pub u16, pub u16, pub u16);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct u64x2(pub u64, pub u64);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
 
 #[unstable(feature = "core")]
 #[simd]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 #[repr(C)]
 pub struct f64x2(pub f64, pub f64);
index a86da53b372a9bfc2b14969f445fc7ad1be40465..70e60adf64c2a3649b9d2256a7eadd8a46ff7346 100644 (file)
@@ -40,6 +40,7 @@ use cmp::{Ordering, PartialEq, PartialOrd, Eq, Ord};
 use cmp::Ordering::{Less, Equal, Greater};
 use cmp;
 use default::Default;
+use intrinsics::assume;
 use iter::*;
 use ops::{FnMut, self, Index};
 use ops::RangeFull;
@@ -48,10 +49,9 @@ use option::Option::{None, Some};
 use result::Result;
 use result::Result::{Ok, Err};
 use ptr;
-use ptr::PtrExt;
 use mem;
 use mem::size_of;
-use marker::{Sized, self};
+use marker::{Send, Sized, Sync, self};
 use raw::Repr;
 // Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module.
 use raw::Slice as RawSlice;
@@ -88,7 +88,6 @@ pub trait SliceExt {
     fn len(&self) -> usize;
     fn is_empty(&self) -> bool { self.len() == 0 }
     fn get_mut<'a>(&'a mut self, index: usize) -> Option<&'a mut Self::Item>;
-    fn as_mut_slice<'a>(&'a mut self) -> &'a mut [Self::Item];
     fn iter_mut<'a>(&'a mut self) -> IterMut<'a, Self::Item>;
     fn first_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>;
     fn tail_mut<'a>(&'a mut self) -> &'a mut [Self::Item];
@@ -137,6 +136,7 @@ impl<T> SliceExt for [T] {
     fn iter<'a>(&'a self) -> Iter<'a, T> {
         unsafe {
             let p = self.as_ptr();
+            assume(!p.is_null());
             if mem::size_of::<T>() == 0 {
                 Iter {ptr: p,
                       end: (p as usize + self.len()) as *const T,
@@ -259,16 +259,13 @@ impl<T> SliceExt for [T] {
         if index < self.len() { Some(&mut self[index]) } else { None }
     }
 
-    #[inline]
-    fn as_mut_slice(&mut self) -> &mut [T] { self }
-
     #[inline]
     fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
         unsafe {
             let self2: &mut [T] = mem::transmute_copy(&self);
 
-            (ops::IndexMut::index_mut(self, &ops::RangeTo { end: mid } ),
-             ops::IndexMut::index_mut(self2, &ops::RangeFrom { start: mid } ))
+            (ops::IndexMut::index_mut(self, ops::RangeTo { end: mid } ),
+             ops::IndexMut::index_mut(self2, ops::RangeFrom { start: mid } ))
         }
     }
 
@@ -276,6 +273,7 @@ impl<T> SliceExt for [T] {
     fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> {
         unsafe {
             let p = self.as_mut_ptr();
+            assume(!p.is_null());
             if mem::size_of::<T>() == 0 {
                 IterMut {ptr: p,
                          end: (p as usize + self.len()) as *mut T,
@@ -348,6 +346,7 @@ impl<T> SliceExt for [T] {
         ChunksMut { v: self, chunk_size: chunk_size }
     }
 
+    #[inline]
     fn swap(&mut self, a: usize, b: usize) {
         unsafe {
             // Can't take two mutable loans from one vector, so instead just cast
@@ -492,7 +491,7 @@ impl<T> SliceExt for [T] {
 impl<T> ops::Index<usize> for [T] {
     type Output = T;
 
-    fn index(&self, &index: &usize) -> &T {
+    fn index(&self, index: usize) -> &T {
         assert!(index < self.len());
 
         unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
@@ -501,7 +500,8 @@ impl<T> ops::Index<usize> for [T] {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<usize> for [T] {
-    fn index_mut(&mut self, &index: &usize) -> &mut T {
+    #[inline]
+    fn index_mut(&mut self, index: usize) -> &mut T {
         assert!(index < self.len());
 
         unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
@@ -511,39 +511,43 @@ impl<T> ops::IndexMut<usize> for [T] {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::Range<usize>> for [T] {
     type Output = [T];
+
     #[inline]
-    fn index(&self, index: &ops::Range<usize>) -> &[T] {
+    fn index(&self, index: ops::Range<usize>) -> &[T] {
         assert!(index.start <= index.end);
         assert!(index.end <= self.len());
         unsafe {
-            transmute(RawSlice {
-                    data: self.as_ptr().offset(index.start as isize),
-                    len: index.end - index.start
-                })
+            from_raw_parts (
+                self.as_ptr().offset(index.start as isize),
+                index.end - index.start
+            )
         }
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::RangeTo<usize>> for [T] {
     type Output = [T];
+
     #[inline]
-    fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
-        self.index(&ops::Range{ start: 0, end: index.end })
+    fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
+        self.index(ops::Range{ start: 0, end: index.end })
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::RangeFrom<usize>> for [T] {
     type Output = [T];
+
     #[inline]
-    fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
-        self.index(&ops::Range{ start: index.start, end: self.len() })
+    fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
+        self.index(ops::Range{ start: index.start, end: self.len() })
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<RangeFull> for [T] {
     type Output = [T];
+
     #[inline]
-    fn index(&self, _index: &RangeFull) -> &[T] {
+    fn index(&self, _index: RangeFull) -> &[T] {
         self
     }
 }
@@ -551,36 +555,36 @@ impl<T> ops::Index<RangeFull> for [T] {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
     #[inline]
-    fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] {
+    fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
         assert!(index.start <= index.end);
         assert!(index.end <= self.len());
         unsafe {
-            transmute(RawSlice {
-                    data: self.as_ptr().offset(index.start as isize),
-                    len: index.end - index.start
-                })
+            from_raw_parts_mut(
+                self.as_mut_ptr().offset(index.start as isize),
+                index.end - index.start
+            )
         }
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::RangeTo<usize>> for [T] {
     #[inline]
-    fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] {
-        self.index_mut(&ops::Range{ start: 0, end: index.end })
+    fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
+        self.index_mut(ops::Range{ start: 0, end: index.end })
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::RangeFrom<usize>> for [T] {
     #[inline]
-    fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] {
+    fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
         let len = self.len();
-        self.index_mut(&ops::Range{ start: index.start, end: len })
+        self.index_mut(ops::Range{ start: index.start, end: len })
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<RangeFull> for [T] {
     #[inline]
-    fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
+    fn index_mut(&mut self, _index: RangeFull) -> &mut [T] {
         self
     }
 }
@@ -593,24 +597,29 @@ impl<T> ops::IndexMut<RangeFull> for [T] {
 /// Data that is viewable as a slice.
 #[unstable(feature = "core",
            reason = "will be replaced by slice syntax")]
+#[deprecated(since = "1.0.0",
+             reason = "use std::convert::AsRef<[T]> instead")]
 pub trait AsSlice<T> {
     /// Work with `self` as a slice.
     fn as_slice<'a>(&'a self) -> &'a [T];
 }
 
 #[unstable(feature = "core", reason = "trait is experimental")]
+#[allow(deprecated)]
 impl<T> AsSlice<T> for [T] {
     #[inline(always)]
     fn as_slice<'a>(&'a self) -> &'a [T] { self }
 }
 
 #[unstable(feature = "core", reason = "trait is experimental")]
+#[allow(deprecated)]
 impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a U {
     #[inline(always)]
     fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) }
 }
 
 #[unstable(feature = "core", reason = "trait is experimental")]
+#[allow(deprecated)]
 impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a mut U {
     #[inline(always)]
     fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) }
@@ -657,6 +666,8 @@ macro_rules! iterator {
             fn next(&mut self) -> Option<$elem> {
                 // could be implemented with slices, but this avoids bounds checks
                 unsafe {
+                    ::intrinsics::assume(!self.ptr.is_null());
+                    ::intrinsics::assume(!self.end.is_null());
                     if self.ptr == self.end {
                         None
                     } else {
@@ -693,6 +704,8 @@ macro_rules! iterator {
             fn next_back(&mut self) -> Option<$elem> {
                 // could be implemented with slices, but this avoids bounds checks
                 unsafe {
+                    ::intrinsics::assume(!self.ptr.is_null());
+                    ::intrinsics::assume(!self.end.is_null());
                     if self.end == self.ptr {
                         None
                     } else {
@@ -723,7 +736,21 @@ macro_rules! make_slice {
             diff / mem::size_of::<$t>()
         };
         unsafe {
-            transmute::<_, $result>(RawSlice { data: $start, len: len })
+            from_raw_parts($start, len)
+        }
+    }}
+}
+
+macro_rules! make_mut_slice {
+    ($t: ty => $result: ty: $start: expr, $end: expr) => {{
+        let diff = $end as usize - $start as usize;
+        let len = if mem::size_of::<T>() == 0 {
+            diff
+        } else {
+            diff / mem::size_of::<$t>()
+        };
+        unsafe {
+            from_raw_parts_mut($start, len)
         }
     }}
 }
@@ -736,11 +763,15 @@ pub struct Iter<'a, T: 'a> {
     _marker: marker::PhantomData<&'a T>,
 }
 
+unsafe impl<'a, T: Sync> Sync for Iter<'a, T> {}
+unsafe impl<'a, T: Sync> Send for Iter<'a, T> {}
+
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::Range<usize>> for Iter<'a, T> {
     type Output = [T];
+
     #[inline]
-    fn index(&self, index: &ops::Range<usize>) -> &[T] {
+    fn index(&self, index: ops::Range<usize>) -> &[T] {
         self.as_slice().index(index)
     }
 }
@@ -748,8 +779,9 @@ impl<'a, T> ops::Index<ops::Range<usize>> for Iter<'a, T> {
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::RangeTo<usize>> for Iter<'a, T> {
     type Output = [T];
+
     #[inline]
-    fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
+    fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
         self.as_slice().index(index)
     }
 }
@@ -757,8 +789,9 @@ impl<'a, T> ops::Index<ops::RangeTo<usize>> for Iter<'a, T> {
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::RangeFrom<usize>> for Iter<'a, T> {
     type Output = [T];
+
     #[inline]
-    fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
+    fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
         self.as_slice().index(index)
     }
 }
@@ -766,8 +799,9 @@ impl<'a, T> ops::Index<ops::RangeFrom<usize>> for Iter<'a, T> {
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<RangeFull> for Iter<'a, T> {
     type Output = [T];
+
     #[inline]
-    fn index(&self, _index: &RangeFull) -> &[T] {
+    fn index(&self, _index: RangeFull) -> &[T] {
         self.as_slice()
     }
 }
@@ -826,36 +860,42 @@ pub struct IterMut<'a, T: 'a> {
     _marker: marker::PhantomData<&'a mut T>,
 }
 
+unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {}
+unsafe impl<'a, T: Send> Send for IterMut<'a, T> {}
 
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::Range<usize>> for IterMut<'a, T> {
     type Output = [T];
+
     #[inline]
-    fn index(&self, index: &ops::Range<usize>) -> &[T] {
-        self.index(&RangeFull).index(index)
+    fn index(&self, index: ops::Range<usize>) -> &[T] {
+        self.index(RangeFull).index(index)
     }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::RangeTo<usize>> for IterMut<'a, T> {
     type Output = [T];
+
     #[inline]
-    fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
-        self.index(&RangeFull).index(index)
+    fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
+        self.index(RangeFull).index(index)
     }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::RangeFrom<usize>> for IterMut<'a, T> {
     type Output = [T];
+
     #[inline]
-    fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
-        self.index(&RangeFull).index(index)
+    fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
+        self.index(RangeFull).index(index)
     }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<RangeFull> for IterMut<'a, T> {
     type Output = [T];
+
     #[inline]
-    fn index(&self, _index: &RangeFull) -> &[T] {
+    fn index(&self, _index: RangeFull) -> &[T] {
         make_slice!(T => &[T]: self.ptr, self.end)
     }
 }
@@ -863,29 +903,32 @@ impl<'a, T> ops::Index<RangeFull> for IterMut<'a, T> {
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<ops::Range<usize>> for IterMut<'a, T> {
     #[inline]
-    fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] {
-        self.index_mut(&RangeFull).index_mut(index)
+    fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
+        self.index_mut(RangeFull).index_mut(index)
     }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<ops::RangeTo<usize>> for IterMut<'a, T> {
+
     #[inline]
-    fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] {
-        self.index_mut(&RangeFull).index_mut(index)
+    fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
+        self.index_mut(RangeFull).index_mut(index)
     }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<ops::RangeFrom<usize>> for IterMut<'a, T> {
+
     #[inline]
-    fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] {
-        self.index_mut(&RangeFull).index_mut(index)
+    fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
+        self.index_mut(RangeFull).index_mut(index)
     }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<RangeFull> for IterMut<'a, T> {
+
     #[inline]
-    fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
-        make_slice!(T => &mut [T]: self.ptr, self.end)
+    fn index_mut(&mut self, _index: RangeFull) -> &mut [T] {
+        make_mut_slice!(T => &mut [T]: self.ptr, self.end)
     }
 }
 
@@ -899,7 +942,7 @@ impl<'a, T> IterMut<'a, T> {
     /// restricted lifetimes that do not consume the iterator.
     #[unstable(feature = "core")]
     pub fn into_slice(self) -> &'a mut [T] {
-        make_slice!(T => &'a mut [T]: self.ptr, self.end)
+        make_mut_slice!(T => &'a mut [T]: self.ptr, self.end)
     }
 }
 
@@ -1083,18 +1126,20 @@ impl<T, I: SplitIter<Item=T>> Iterator for GenericSplitN<I> {
 
     #[inline]
     fn next(&mut self) -> Option<T> {
-        if self.count == 0 {
-            self.iter.finish()
-        } else {
-            self.count -= 1;
-            if self.invert { self.iter.next_back() } else { self.iter.next() }
+        match self.count {
+            0 => None,
+            1 => { self.count -= 1; self.iter.finish() }
+            _ => {
+                self.count -= 1;
+                if self.invert {self.iter.next_back()} else {self.iter.next()}
+            }
         }
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         let (lower, upper_opt) = self.iter.size_hint();
-        (lower, upper_opt.map(|upper| cmp::min(self.count + 1, upper)))
+        (lower, upper_opt.map(|upper| cmp::min(self.count, upper)))
     }
 }
 
@@ -1155,13 +1200,23 @@ forward_iterator! { SplitNMut: T, &'a mut [T] }
 forward_iterator! { RSplitNMut: T, &'a mut [T] }
 
 /// An iterator over overlapping subslices of length `size`.
-#[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Windows<'a, T:'a> {
     v: &'a [T],
     size: usize
 }
 
+// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> Clone for Windows<'a, T> {
+    fn clone(&self) -> Windows<'a, T> {
+        Windows {
+            v: self.v,
+            size: self.size,
+        }
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Iterator for Windows<'a, T> {
     type Item = &'a [T];
@@ -1227,13 +1282,23 @@ impl<'a, T> RandomAccessIterator for Windows<'a, T> {
 ///
 /// When the slice len is not evenly divided by the chunk size, the last slice
 /// of the iteration will be the remainder.
-#[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Chunks<'a, T:'a> {
     v: &'a [T],
     size: usize
 }
 
+// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> Clone for Chunks<'a, T> {
+    fn clone(&self) -> Chunks<'a, T> {
+        Chunks {
+            v: self.v,
+            size: self.size,
+        }
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Iterator for Chunks<'a, T> {
     type Item = &'a [T];
@@ -1371,7 +1436,7 @@ impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {}
 #[unstable(feature = "core")]
 pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
     unsafe {
-        transmute(RawSlice { data: s, len: 1 })
+        from_raw_parts(s, 1)
     }
 }
 
@@ -1379,8 +1444,7 @@ pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
 #[unstable(feature = "core")]
 pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
     unsafe {
-        let ptr: *const A = transmute(s);
-        transmute(RawSlice { data: ptr, len: 1 })
+        from_raw_parts_mut(s, 1)
     }
 }
 
@@ -1400,9 +1464,9 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
 /// function taking the lifetime of a host value for the slice, or by explicit
 /// annotation.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::slice;
 ///
 /// // manifest a slice out of thin air!
@@ -1413,7 +1477,7 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
 /// }
 /// ```
 #[inline]
-#[unstable(feature = "core")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: usize) -> &'a [T] {
     transmute(RawSlice { data: p, len: len })
 }
@@ -1425,58 +1489,11 @@ pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: usize) -> &'a [T] {
 /// as not being able to provide a non-aliasing guarantee of the returned
 /// mutable slice.
 #[inline]
-#[unstable(feature = "core")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
     transmute(RawSlice { data: p, len: len })
 }
 
-/// Forms a slice from a pointer and a length.
-///
-/// The pointer given is actually a reference to the base of the slice. This
-/// reference is used to give a concrete lifetime to tie the returned slice to.
-/// Typically this should indicate that the slice is valid for as long as the
-/// pointer itself is valid.
-///
-/// The `len` argument is the number of **elements**, not the number of bytes.
-///
-/// This function is unsafe as there is no guarantee that the given pointer is
-/// valid for `len` elements, nor whether the lifetime provided is a suitable
-/// lifetime for the returned slice.
-///
-/// # Example
-///
-/// ```rust
-/// use std::slice;
-///
-/// // manifest a slice out of thin air!
-/// let ptr = 0x1234 as *const usize;
-/// let amt = 10;
-/// unsafe {
-///     let slice = slice::from_raw_buf(&ptr, amt);
-/// }
-/// ```
-#[inline]
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
-             reason = "use from_raw_parts")]
-pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: usize) -> &'a [T] {
-    transmute(RawSlice { data: *p, len: len })
-}
-
-/// Performs the same functionality as `from_raw_buf`, except that a mutable
-/// slice is returned.
-///
-/// This function is unsafe for the same reasons as `from_raw_buf`, as well as
-/// not being able to provide a non-aliasing guarantee of the returned mutable
-/// slice.
-#[inline]
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
-             reason = "use from_raw_parts_mut")]
-pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: usize) -> &'a mut [T] {
-    transmute(RawSlice { data: *p, len: len })
-}
-
 //
 // Submodules
 //
@@ -1496,7 +1513,7 @@ pub mod bytes {
     impl MutableByteVector for [u8] {
         #[inline]
         fn set_memory(&mut self, value: u8) {
-            unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
+            unsafe { ptr::write_bytes(self.as_mut_ptr(), value, self.len()) };
         }
     }
 
@@ -1504,15 +1521,15 @@ pub mod bytes {
     ///
     /// Panics if the length of `dst` is less than the length of `src`.
     #[inline]
-    pub fn copy_memory(dst: &mut [u8], src: &[u8]) {
+    pub fn copy_memory(src: &[u8], dst: &mut [u8]) {
         let len_src = src.len();
         assert!(dst.len() >= len_src);
         // `dst` is unaliasable, so we know statically it doesn't overlap
         // with `src`.
         unsafe {
-            ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(),
-                                            src.as_ptr(),
-                                            len_src);
+            ptr::copy_nonoverlapping(src.as_ptr(),
+                                     dst.as_mut_ptr(),
+                                     len_src);
         }
     }
 }
index eec997b9f10fc76f3090ae58a4d59b5655c1f2b5..dbb365c4e2357536c4ab7097ed435aedd4f3de9f 100644 (file)
 
 #![doc(primitive = "str")]
 
-use self::Searcher::{Naive, TwoWay, TwoWayLong};
+use self::OldSearcher::{TwoWay, TwoWayLong};
 
+use char::CharExt;
 use clone::Clone;
 use cmp::{self, Eq};
 use default::Default;
-use error::Error;
 use fmt;
 use iter::ExactSizeIterator;
-use iter::{Map, Iterator, IteratorExt, DoubleEndedIterator};
+use iter::{Map, Iterator, DoubleEndedIterator};
 use marker::Sized;
 use mem;
-use num::Int;
-use ops::{Fn, FnMut};
+use ops::{Fn, FnMut, FnOnce};
 use option::Option::{self, None, Some};
-use ptr::PtrExt;
 use raw::{Repr, Slice};
 use result::Result::{self, Ok, Err};
 use slice::{self, SliceExt};
 use usize;
 
+pub use self::pattern::Pattern;
+pub use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher, SearchStep};
+
+mod pattern;
+
 macro_rules! delegate_iter {
     (exact $te:ty : $ti:ty) => {
         delegate_iter!{$te : $ti}
@@ -70,7 +73,7 @@ macro_rules! delegate_iter {
     };
     (pattern $te:ty : $ti:ty) => {
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a, P: CharEq> Iterator for $ti {
+        impl<'a, P: Pattern<'a>> Iterator for $ti {
             type Item = $te;
 
             #[inline]
@@ -83,7 +86,8 @@ macro_rules! delegate_iter {
             }
         }
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a, P: CharEq> DoubleEndedIterator for $ti {
+        impl<'a, P: Pattern<'a>> DoubleEndedIterator for $ti
+        where P::Searcher: DoubleEndedSearcher<'a> {
             #[inline]
             fn next_back(&mut self) -> Option<$te> {
                 self.0.next_back()
@@ -92,7 +96,8 @@ macro_rules! delegate_iter {
     };
     (pattern forward $te:ty : $ti:ty) => {
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a, P: CharEq> Iterator for $ti {
+        impl<'a, P: Pattern<'a>> Iterator for $ti
+        where P::Searcher: DoubleEndedSearcher<'a> {
             type Item = $te;
 
             #[inline]
@@ -104,7 +109,24 @@ macro_rules! delegate_iter {
                 self.0.size_hint()
             }
         }
-    }
+    };
+    (pattern reverse $te:ty : $ti:ty) => {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl<'a, P: Pattern<'a>> Iterator for $ti
+            where P::Searcher: ReverseSearcher<'a>
+        {
+            type Item = $te;
+
+            #[inline]
+            fn next(&mut self) -> Option<$te> {
+                self.0.next()
+            }
+            #[inline]
+            fn size_hint(&self) -> (usize, Option<usize>) {
+                self.0.size_hint()
+            }
+        }
+    };
 }
 
 /// A trait to abstract the idea of creating a new instance of a type from a
@@ -127,12 +149,22 @@ impl FromStr for bool {
 
     /// Parse a `bool` from a string.
     ///
-    /// Yields an `Option<bool>`, because `s` may or may not actually be
-    /// parseable.
+    /// Yields a `Result<bool, ParseBoolError>`, because `s` may or may not
+    /// actually be parseable.
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// use std::str::FromStr;
+    ///
+    /// assert_eq!(FromStr::from_str("true"), Ok(true));
+    /// assert_eq!(FromStr::from_str("false"), Ok(false));
+    /// assert!(<bool as FromStr>::from_str("not even a boolean").is_err());
+    /// ```
+    ///
+    /// Note, in many cases, the `.parse()` method on `str` is more proper.
+    ///
+    /// ```
     /// assert_eq!("true".parse(), Ok(true));
     /// assert_eq!("false".parse(), Ok(false));
     /// assert!("not even a boolean".parse::<bool>().is_err());
@@ -159,11 +191,6 @@ impl fmt::Display for ParseBoolError {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for ParseBoolError {
-    fn description(&self) -> &str { "failed to parse bool" }
-}
-
 /*
 Section: Creating a string
 */
@@ -208,81 +235,6 @@ pub unsafe fn from_utf8_unchecked<'a>(v: &'a [u8]) -> &'a str {
     mem::transmute(v)
 }
 
-/// Constructs a static string slice from a given raw pointer.
-///
-/// This function will read memory starting at `s` until it finds a 0, and then
-/// transmute the memory up to that point as a string slice, returning the
-/// corresponding `&'static str` value.
-///
-/// This function is unsafe because the caller must ensure the C string itself
-/// has the static lifetime and that the memory `s` is valid up to and including
-/// the first null byte.
-///
-/// # Panics
-///
-/// This function will panic if the string pointed to by `s` is not valid UTF-8.
-#[unstable(feature = "core")]
-#[deprecated(since = "1.0.0",
-             reason = "use std::ffi::c_str_to_bytes + str::from_utf8")]
-pub unsafe fn from_c_str(s: *const i8) -> &'static str {
-    let s = s as *const u8;
-    let mut len = 0;
-    while *s.offset(len as isize) != 0 {
-        len += 1;
-    }
-    let v: &'static [u8] = ::mem::transmute(Slice { data: s, len: len });
-    from_utf8(v).ok().expect("from_c_str passed invalid utf-8 data")
-}
-
-/// Something that can be used to compare against a character
-#[unstable(feature = "core",
-           reason = "definition may change as pattern-related methods are stabilized")]
-pub trait CharEq {
-    /// Determine if the splitter should split at the given character
-    fn matches(&mut self, char) -> bool;
-    /// Indicate if this is only concerned about ASCII characters,
-    /// which can allow for a faster implementation.
-    fn only_ascii(&self) -> bool;
-}
-
-impl CharEq for char {
-    #[inline]
-    fn matches(&mut self, c: char) -> bool { *self == c }
-
-    #[inline]
-    fn only_ascii(&self) -> bool { (*self as u32) < 128 }
-}
-
-impl<F> CharEq for F where F: FnMut(char) -> bool {
-    #[inline]
-    fn matches(&mut self, c: char) -> bool { (*self)(c) }
-
-    #[inline]
-    fn only_ascii(&self) -> bool { false }
-}
-
-impl<'a> CharEq for &'a [char] {
-    #[inline]
-    fn matches(&mut self, c: char) -> bool {
-        self.iter().any(|&m| { let mut m = m; m.matches(c) })
-    }
-
-    #[inline]
-    fn only_ascii(&self) -> bool {
-        self.iter().all(|m| m.only_ascii())
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Error for Utf8Error {
-    fn description(&self) -> &str {
-        match *self {
-            Utf8Error::TooShort => "invalid utf-8: not enough bytes",
-            Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents",
-        }
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for Utf8Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -310,21 +262,20 @@ pub struct Chars<'a> {
     iter: slice::Iter<'a, u8>
 }
 
-// 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
-macro_rules! utf8_first_byte {
-    ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as u32)
-}
+/// 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.
+#[inline]
+fn utf8_first_byte(byte: u8, width: u32) -> u32 { (byte & (0x7F >> width)) as u32 }
 
-// return the value of $ch updated with continuation byte $byte
-macro_rules! utf8_acc_cont_byte {
-    ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & CONT_MASK) as u32)
-}
+/// Return the value of `ch` updated with continuation byte `byte`.
+#[inline]
+fn utf8_acc_cont_byte(ch: u32, byte: u8) -> u32 { (ch << 6) | (byte & CONT_MASK) as u32 }
 
-macro_rules! utf8_is_cont_byte {
-    ($byte:expr) => (($byte & !CONT_MASK) == TAG_CONT_U8)
-}
+/// Checks whether the byte is a UTF-8 continuation byte (i.e. starts with the
+/// bits `10`).
+#[inline]
+fn utf8_is_cont_byte(byte: u8) -> bool { (byte & !CONT_MASK) == TAG_CONT_U8 }
 
 #[inline]
 fn unwrap_or_0(opt: Option<&u8>) -> u8 {
@@ -337,6 +288,7 @@ fn unwrap_or_0(opt: Option<&u8>) -> u8 {
 /// Reads the next code point out of a byte iterator (assuming a
 /// UTF-8-like encoding).
 #[unstable(feature = "core")]
+#[inline]
 pub fn next_code_point(bytes: &mut slice::Iter<u8>) -> Option<u32> {
     // Decode UTF-8
     let x = match bytes.next() {
@@ -348,26 +300,58 @@ pub fn next_code_point(bytes: &mut slice::Iter<u8>) -> Option<u32> {
     // Multibyte case follows
     // Decode from a byte combination out of: [[[x y] z] w]
     // NOTE: Performance is sensitive to the exact formulation here
-    let init = utf8_first_byte!(x, 2);
+    let init = utf8_first_byte(x, 2);
     let y = unwrap_or_0(bytes.next());
-    let mut ch = utf8_acc_cont_byte!(init, y);
+    let mut ch = utf8_acc_cont_byte(init, y);
     if x >= 0xE0 {
         // [[x y z] w] case
         // 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid
         let z = unwrap_or_0(bytes.next());
-        let y_z = utf8_acc_cont_byte!((y & CONT_MASK) as u32, z);
+        let y_z = utf8_acc_cont_byte((y & CONT_MASK) as u32, z);
         ch = init << 12 | y_z;
         if x >= 0xF0 {
             // [x y z w] case
             // use only the lower 3 bits of `init`
             let w = unwrap_or_0(bytes.next());
-            ch = (init & 7) << 18 | utf8_acc_cont_byte!(y_z, w);
+            ch = (init & 7) << 18 | utf8_acc_cont_byte(y_z, w);
         }
     }
 
     Some(ch)
 }
 
+/// Reads the last code point out of a byte iterator (assuming a
+/// UTF-8-like encoding).
+#[unstable(feature = "core")]
+#[inline]
+pub fn next_code_point_reverse(bytes: &mut slice::Iter<u8>) -> Option<u32> {
+    // Decode UTF-8
+    let w = match bytes.next_back() {
+        None => return None,
+        Some(&next_byte) if next_byte < 128 => return Some(next_byte as u32),
+        Some(&back_byte) => back_byte,
+    };
+
+    // Multibyte case follows
+    // Decode from a byte combination out of: [x [y [z w]]]
+    let mut ch;
+    let z = unwrap_or_0(bytes.next_back());
+    ch = utf8_first_byte(z, 2);
+    if utf8_is_cont_byte(z) {
+        let y = unwrap_or_0(bytes.next_back());
+        ch = utf8_first_byte(y, 3);
+        if utf8_is_cont_byte(y) {
+            let x = unwrap_or_0(bytes.next_back());
+            ch = utf8_first_byte(x, 4);
+            ch = utf8_acc_cont_byte(ch, y);
+        }
+        ch = utf8_acc_cont_byte(ch, z);
+    }
+    ch = utf8_acc_cont_byte(ch, w);
+
+    Some(ch)
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Iterator for Chars<'a> {
     type Item = char;
@@ -385,7 +369,10 @@ impl<'a> Iterator for Chars<'a> {
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
         let (len, _) = self.iter.size_hint();
-        (len.saturating_add(3) / 4, Some(len))
+        // `(len + 3)` can't overflow, because we know that the `slice::Iter`
+        // belongs to a slice in memory which has a maximum length of
+        // `isize::MAX` (that's well below `usize::MAX`).
+        ((len + 3) / 4, Some(len))
     }
 }
 
@@ -393,33 +380,12 @@ impl<'a> Iterator for Chars<'a> {
 impl<'a> DoubleEndedIterator for Chars<'a> {
     #[inline]
     fn next_back(&mut self) -> Option<char> {
-        let w = match self.iter.next_back() {
-            None => return None,
-            Some(&back_byte) if back_byte < 128 => return Some(back_byte as char),
-            Some(&back_byte) => back_byte,
-        };
-
-        // Multibyte case follows
-        // Decode from a byte combination out of: [x [y [z w]]]
-        let mut ch;
-        let z = unwrap_or_0(self.iter.next_back());
-        ch = utf8_first_byte!(z, 2);
-        if utf8_is_cont_byte!(z) {
-            let y = unwrap_or_0(self.iter.next_back());
-            ch = utf8_first_byte!(y, 3);
-            if utf8_is_cont_byte!(y) {
-                let x = unwrap_or_0(self.iter.next_back());
-                ch = utf8_first_byte!(x, 4);
-                ch = utf8_acc_cont_byte!(ch, y);
+        next_code_point_reverse(&mut self.iter).map(|ch| {
+            // str invariant says `ch` is a valid Unicode Scalar Value
+            unsafe {
+                mem::transmute(ch)
             }
-            ch = utf8_acc_cont_byte!(ch, z);
-        }
-        ch = utf8_acc_cont_byte!(ch, w);
-
-        // str invariant says `ch` is a valid Unicode Scalar Value
-        unsafe {
-            Some(mem::transmute(ch))
-        }
+        })
     }
 }
 
@@ -474,7 +440,7 @@ impl<'a> DoubleEndedIterator for CharIndices<'a> {
 /// External iterator for a string's bytes.
 /// Use with the `std::iter` module.
 ///
-/// Created with `StrExt::bytes`
+/// Created with `str::bytes`
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct Bytes<'a>(Map<slice::Iter<'a, u8>, BytesDeref>);
@@ -486,34 +452,65 @@ delegate_iter!{exact u8 : Bytes<'a>}
 struct BytesDeref;
 
 impl<'a> Fn<(&'a u8,)> for BytesDeref {
-    type Output = u8;
-
     #[inline]
     extern "rust-call" fn call(&self, (ptr,): (&'a u8,)) -> u8 {
         *ptr
     }
 }
 
+impl<'a> FnMut<(&'a u8,)> for BytesDeref {
+    #[inline]
+    extern "rust-call" fn call_mut(&mut self, (ptr,): (&'a u8,)) -> u8 {
+        Fn::call(&*self, (ptr,))
+    }
+}
+
+impl<'a> FnOnce<(&'a u8,)> for BytesDeref {
+    type Output = u8;
+
+    #[inline]
+    extern "rust-call" fn call_once(self, (ptr,): (&'a u8,)) -> u8 {
+        Fn::call(&self, (ptr,))
+    }
+}
+
 /// An iterator over the substrings of a string, separated by `sep`.
-#[derive(Clone)]
-struct CharSplits<'a, Sep> {
+struct CharSplits<'a, P: Pattern<'a>> {
     /// The slice remaining to be iterated
-    string: &'a str,
-    sep: Sep,
+    start: usize,
+    end: usize,
+    matcher: P::Searcher,
     /// Whether an empty string at the end is allowed
     allow_trailing_empty: bool,
-    only_ascii: bool,
     finished: bool,
 }
 
 /// An iterator over the substrings of a string, separated by `sep`,
 /// splitting at most `count` times.
-#[derive(Clone)]
-struct CharSplitsN<'a, Sep> {
-    iter: CharSplits<'a, Sep>,
+struct CharSplitsN<'a, P: Pattern<'a>> {
+    iter: CharSplits<'a, P>,
+    /// The number of items remaining
+    count: usize,
+}
+
+/// An iterator over the substrings of a string, separated by a
+/// pattern, in reverse order.
+struct RCharSplits<'a, P: Pattern<'a>> {
+    /// The slice remaining to be iterated
+    start: usize,
+    end: usize,
+    matcher: P::Searcher,
+    /// Whether an empty string at the end of iteration is allowed
+    allow_final_empty: bool,
+    finished: bool,
+}
+
+/// An iterator over the substrings of a string, separated by a
+/// pattern, splitting at most `count` times, in reverse order.
+struct RCharSplitsN<'a, P: Pattern<'a>> {
+    iter: RCharSplits<'a, P>,
     /// The number of splits remaining
     count: usize,
-    invert: bool,
 }
 
 /// An iterator over the lines of a string, separated by `\n`.
@@ -528,12 +525,15 @@ pub struct LinesAny<'a> {
     inner: Map<Lines<'a>, fn(&str) -> &str>,
 }
 
-impl<'a, Sep> CharSplits<'a, Sep> {
+impl<'a, P: Pattern<'a>> CharSplits<'a, P> {
     #[inline]
     fn get_end(&mut self) -> Option<&'a str> {
-        if !self.finished && (self.allow_trailing_empty || self.string.len() > 0) {
+        if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) {
             self.finished = true;
-            Some(self.string)
+            unsafe {
+                let string = self.matcher.haystack().slice_unchecked(self.start, self.end);
+                Some(string)
+            }
         } else {
             None
         }
@@ -541,33 +541,18 @@ impl<'a, Sep> CharSplits<'a, Sep> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, Sep: CharEq> Iterator for CharSplits<'a, Sep> {
+impl<'a, P: Pattern<'a>> Iterator for CharSplits<'a, P> {
     type Item = &'a str;
 
     #[inline]
     fn next(&mut self) -> Option<&'a str> {
         if self.finished { return None }
 
-        let mut next_split = None;
-        if self.only_ascii {
-            for (idx, byte) in self.string.bytes().enumerate() {
-                if self.sep.matches(byte as char) && byte < 128u8 {
-                    next_split = Some((idx, idx + 1));
-                    break;
-                }
-            }
-        } else {
-            for (idx, ch) in self.string.char_indices() {
-                if self.sep.matches(ch) {
-                    next_split = Some((idx, self.string.char_range_at(idx).next));
-                    break;
-                }
-            }
-        }
-        match next_split {
+        let haystack = self.matcher.haystack();
+        match self.matcher.next_match() {
             Some((a, b)) => unsafe {
-                let elt = self.string.slice_unchecked(0, a);
-                self.string = self.string.slice_unchecked(b, self.string.len());
+                let elt = haystack.slice_unchecked(self.start, a);
+                self.start = b;
                 Some(elt)
             },
             None => self.get_end(),
@@ -576,7 +561,8 @@ impl<'a, Sep: CharEq> Iterator for CharSplits<'a, Sep> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, Sep: CharEq> DoubleEndedIterator for CharSplits<'a, Sep> {
+impl<'a, P: Pattern<'a>> DoubleEndedIterator for CharSplits<'a, P>
+where P::Searcher: DoubleEndedSearcher<'a> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a str> {
         if self.finished { return None }
@@ -588,73 +574,86 @@ impl<'a, Sep: CharEq> DoubleEndedIterator for CharSplits<'a, Sep> {
                 _ => if self.finished { return None }
             }
         }
-        let len = self.string.len();
-        let mut next_split = None;
-
-        if self.only_ascii {
-            for (idx, byte) in self.string.bytes().enumerate().rev() {
-                if self.sep.matches(byte as char) && byte < 128u8 {
-                    next_split = Some((idx, idx + 1));
-                    break;
-                }
-            }
-        } else {
-            for (idx, ch) in self.string.char_indices().rev() {
-                if self.sep.matches(ch) {
-                    next_split = Some((idx, self.string.char_range_at(idx).next));
-                    break;
-                }
-            }
-        }
-        match next_split {
+
+        let haystack = self.matcher.haystack();
+        match self.matcher.next_match_back() {
             Some((a, b)) => unsafe {
-                let elt = self.string.slice_unchecked(b, len);
-                self.string = self.string.slice_unchecked(0, a);
+                let elt = haystack.slice_unchecked(b, self.end);
+                self.end = a;
                 Some(elt)
             },
-            None => { self.finished = true; Some(self.string) }
+            None => unsafe {
+                self.finished = true;
+                Some(haystack.slice_unchecked(self.start, self.end))
+            },
         }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, Sep: CharEq> Iterator for CharSplitsN<'a, Sep> {
+impl<'a, P: Pattern<'a>> Iterator for CharSplitsN<'a, P> {
     type Item = &'a str;
 
     #[inline]
     fn next(&mut self) -> Option<&'a str> {
-        if self.count != 0 {
-            self.count -= 1;
-            if self.invert { self.iter.next_back() } else { self.iter.next() }
-        } else {
-            self.iter.get_end()
+        match self.count {
+            0 => None,
+            1 => { self.count = 0; self.iter.get_end() }
+            _ => { self.count -= 1; self.iter.next() }
         }
     }
 }
 
-/// The internal state of an iterator that searches for matches of a substring
-/// within a larger string using naive search
-#[derive(Clone)]
-struct NaiveSearcher {
-    position: usize
+impl<'a, P: Pattern<'a>> RCharSplits<'a, P> {
+    #[inline]
+    fn get_remainder(&mut self) -> Option<&'a str> {
+        if !self.finished && (self.allow_final_empty || self.end - self.start > 0) {
+            self.finished = true;
+            unsafe {
+                let string = self.matcher.haystack().slice_unchecked(self.start, self.end);
+                Some(string)
+            }
+        } else {
+            None
+        }
+    }
 }
 
-impl NaiveSearcher {
-    fn new() -> NaiveSearcher {
-        NaiveSearcher { position: 0 }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, P: Pattern<'a>> Iterator for RCharSplits<'a, P>
+    where P::Searcher: ReverseSearcher<'a>
+{
+    type Item = &'a str;
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a str> {
+        if self.finished { return None }
+
+        let haystack = self.matcher.haystack();
+        match self.matcher.next_match_back() {
+            Some((a, b)) => unsafe {
+                let elt = haystack.slice_unchecked(b, self.end);
+                self.end = a;
+                Some(elt)
+            },
+            None => self.get_remainder(),
+        }
     }
+}
 
-    fn next(&mut self, haystack: &[u8], needle: &[u8]) -> Option<(usize, usize)> {
-        while self.position + needle.len() <= haystack.len() {
-            if &haystack[self.position .. self.position + needle.len()] == needle {
-                let match_pos = self.position;
-                self.position += needle.len(); // add 1 for all matches
-                return Some((match_pos, match_pos + needle.len()));
-            } else {
-                self.position += 1;
-            }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, P: Pattern<'a>> Iterator for RCharSplitsN<'a, P>
+    where P::Searcher: ReverseSearcher<'a>
+{
+    type Item = &'a str;
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a str> {
+        match self.count {
+            0 => None,
+            1 => { self.count -= 1; self.iter.get_remainder() }
+            _ => { self.count -= 1; self.iter.next() }
         }
-        None
     }
 }
 
@@ -743,6 +742,7 @@ struct TwoWaySearcher {
 
 */
 impl TwoWaySearcher {
+    #[allow(dead_code)]
     fn new(needle: &[u8]) -> TwoWaySearcher {
         let (crit_pos_false, period_false) = TwoWaySearcher::maximal_suffix(needle, false);
         let (crit_pos_true, period_true) = TwoWaySearcher::maximal_suffix(needle, true);
@@ -852,8 +852,10 @@ impl TwoWaySearcher {
     // Specifically, returns (i, p), where i is the starting index of v in some
     // critical factorization (u, v) and p = period(v)
     #[inline]
+    #[allow(dead_code)]
+    #[allow(deprecated)]
     fn maximal_suffix(arr: &[u8], reversed: bool) -> (usize, usize) {
-        let mut left = -1; // Corresponds to i in the paper
+        let mut left: usize = !0; // Corresponds to i in the paper
         let mut right = 0; // Corresponds to j in the paper
         let mut offset = 1; // Corresponds to k in the paper
         let mut period = 1; // Corresponds to p in the paper
@@ -862,17 +864,17 @@ impl TwoWaySearcher {
             let a;
             let b;
             if reversed {
-                a = arr[left + offset];
+                a = arr[left.wrapping_add(offset)];
                 b = arr[right + offset];
             } else {
                 a = arr[right + offset];
-                b = arr[left + offset];
+                b = arr[left.wrapping_add(offset)];
             }
             if a < b {
                 // Suffix is smaller, period is entire prefix so far.
                 right += offset;
                 offset = 1;
-                period = right - left;
+                period = right.wrapping_sub(left);
             } else if a == b {
                 // Advance through repetition of the current period.
                 if offset == period {
@@ -889,27 +891,33 @@ impl TwoWaySearcher {
                 period = 1;
             }
         }
-        (left + 1, period)
+        (left.wrapping_add(1), period)
     }
 }
 
 /// The internal state of an iterator that searches for matches of a substring
 /// within a larger string using a dynamically chosen search algorithm
 #[derive(Clone)]
-enum Searcher {
-    Naive(NaiveSearcher),
+// NB: This is kept around for convenience because
+// it is planned to be used again in the future
+enum OldSearcher {
     TwoWay(TwoWaySearcher),
-    TwoWayLong(TwoWaySearcher)
+    TwoWayLong(TwoWaySearcher),
 }
 
-impl Searcher {
-    fn new(haystack: &[u8], needle: &[u8]) -> Searcher {
+impl OldSearcher {
+    #[allow(dead_code)]
+    fn new(haystack: &[u8], needle: &[u8]) -> OldSearcher {
+        if needle.len() == 0 {
+            // Handle specially
+            unimplemented!()
         // FIXME: Tune this.
         // FIXME(#16715): This unsigned integer addition will probably not
         // overflow because that would mean that the memory almost solely
         // consists of the needle. Needs #16715 to be formally fixed.
-        if needle.len() + 20 > haystack.len() {
-            Naive(NaiveSearcher::new())
+        } else if needle.len() + 20 > haystack.len() {
+            // Use naive searcher
+            unimplemented!()
         } else {
             let searcher = TwoWaySearcher::new(needle);
             if searcher.memory == usize::MAX { // If the period is long
@@ -921,67 +929,45 @@ impl Searcher {
     }
 }
 
-/// An iterator over the start and end indices of the matches of a
-/// substring within a larger string
 #[derive(Clone)]
-#[unstable(feature = "core", reason = "type may be removed")]
-pub struct MatchIndices<'a> {
+// NB: This is kept around for convenience because
+// it is planned to be used again in the future
+struct OldMatchIndices<'a, 'b> {
     // constants
     haystack: &'a str,
-    needle: &'a str,
-    searcher: Searcher
+    needle: &'b str,
+    searcher: OldSearcher
 }
 
-/// An iterator over the substrings of a string separated by a given
-/// search string
-#[derive(Clone)]
+// FIXME: #21637 Prevents a Clone impl
+/// An iterator over the start and end indices of the matches of a
+/// substring within a larger string
 #[unstable(feature = "core", reason = "type may be removed")]
-pub struct SplitStr<'a> {
-    it: MatchIndices<'a>,
-    last_end: usize,
-    finished: bool
-}
+pub struct MatchIndices<'a, P: Pattern<'a>>(P::Searcher);
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> Iterator for MatchIndices<'a> {
+impl<'a, P: Pattern<'a>> Iterator for MatchIndices<'a, P> {
     type Item = (usize, usize);
 
     #[inline]
     fn next(&mut self) -> Option<(usize, usize)> {
-        match self.searcher {
-            Naive(ref mut searcher)
-                => searcher.next(self.haystack.as_bytes(), self.needle.as_bytes()),
-            TwoWay(ref mut searcher)
-                => searcher.next(self.haystack.as_bytes(), self.needle.as_bytes(), false),
-            TwoWayLong(ref mut searcher)
-                => searcher.next(self.haystack.as_bytes(), self.needle.as_bytes(), true)
-        }
+        self.0.next_match()
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a> Iterator for SplitStr<'a> {
-    type Item = &'a str;
-
+impl<'a, 'b>  OldMatchIndices<'a, 'b> {
     #[inline]
-    fn next(&mut self) -> Option<&'a str> {
-        if self.finished { return None; }
-
-        match self.it.next() {
-            Some((from, to)) => {
-                let ret = Some(&self.it.haystack[self.last_end .. from]);
-                self.last_end = to;
-                ret
-            }
-            None => {
-                self.finished = true;
-                Some(&self.it.haystack[self.last_end .. self.it.haystack.len()])
-            }
+    #[allow(dead_code)]
+    fn next(&mut self) -> Option<(usize, usize)> {
+        match self.searcher {
+            TwoWay(ref mut searcher)
+                => searcher.next(self.haystack.as_bytes(), self.needle.as_bytes(), false),
+            TwoWayLong(ref mut searcher)
+                => searcher.next(self.haystack.as_bytes(), self.needle.as_bytes(), true),
         }
     }
 }
 
-
 /*
 Section: Comparing strings
 */
@@ -1051,7 +1037,7 @@ fn run_utf8_validation_iterator(iter: &mut slice::Iter<u8>)
         // ASCII characters are always valid, so only large
         // bytes need more examination.
         if first >= 128 {
-            let w = UTF8_CHAR_WIDTH[first as usize] as usize;
+            let w = UTF8_CHAR_WIDTH[first as usize];
             let second = next!();
             // 2-byte encoding is for codepoints  \u{0080} to  \u{07ff}
             //        first  C2 80        last DF BF
@@ -1119,9 +1105,11 @@ static UTF8_CHAR_WIDTH: [u8; 256] = [
 /// Struct that contains a `char` and the index of the first byte of
 /// the next `char` in a string.  This can be used as a data structure
 /// for iterating over the UTF-8 bytes of a string.
-#[derive(Copy)]
-#[unstable(feature = "core",
-           reason = "naming is uncertain with container conventions")]
+#[derive(Copy, Clone)]
+#[unstable(feature = "str_char",
+           reason = "existence of this struct is uncertain as it is frequently \
+                     able to be replaced with char.len_utf8() and/or \
+                     char/char_indices iterators")]
 pub struct CharRange {
     /// Current `char`
     pub ch: char,
@@ -1130,9 +1118,9 @@ pub struct CharRange {
 }
 
 /// Mask of the value bits of a continuation byte
-const CONT_MASK: u8 = 0b0011_1111u8;
+const CONT_MASK: u8 = 0b0011_1111;
 /// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte
-const TAG_CONT_U8: u8 = 0b1000_0000u8;
+const TAG_CONT_U8: u8 = 0b1000_0000;
 
 /*
 Section: Trait implementations
@@ -1141,7 +1129,7 @@ Section: Trait implementations
 mod traits {
     use cmp::{Ordering, Ord, PartialEq, PartialOrd, Eq};
     use cmp::Ordering::{Less, Equal, Greater};
-    use iter::IteratorExt;
+    use iter::Iterator;
     use option::Option;
     use option::Option::Some;
     use ops;
@@ -1192,9 +1180,9 @@ mod traits {
     /// Panics when `begin` and `end` do not point to valid characters
     /// or point beyond the last character of the string.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let s = "Löwe 老虎 Léopard";
     /// assert_eq!(&s[0 .. 1], "L");
     ///
@@ -1214,7 +1202,7 @@ mod traits {
     impl ops::Index<ops::Range<usize>> for str {
         type Output = str;
         #[inline]
-        fn index(&self, index: &ops::Range<usize>) -> &str {
+        fn index(&self, index: ops::Range<usize>) -> &str {
             // is_char_boundary checks that the index is in [0, .len()]
             if index.start <= index.end &&
                self.is_char_boundary(index.start) &&
@@ -1236,8 +1224,9 @@ mod traits {
     #[stable(feature = "rust1", since = "1.0.0")]
     impl ops::Index<ops::RangeTo<usize>> for str {
         type Output = str;
+
         #[inline]
-        fn index(&self, index: &ops::RangeTo<usize>) -> &str {
+        fn index(&self, index: ops::RangeTo<usize>) -> &str {
             // is_char_boundary checks that the index is in [0, .len()]
             if self.is_char_boundary(index.end) {
                 unsafe { self.slice_unchecked(0, index.end) }
@@ -1256,8 +1245,9 @@ mod traits {
     #[stable(feature = "rust1", since = "1.0.0")]
     impl ops::Index<ops::RangeFrom<usize>> for str {
         type Output = str;
+
         #[inline]
-        fn index(&self, index: &ops::RangeFrom<usize>) -> &str {
+        fn index(&self, index: ops::RangeFrom<usize>) -> &str {
             // is_char_boundary checks that the index is in [0, .len()]
             if self.is_char_boundary(index.start) {
                 unsafe { self.slice_unchecked(index.start, self.len()) }
@@ -1270,8 +1260,9 @@ mod traits {
     #[stable(feature = "rust1", since = "1.0.0")]
     impl ops::Index<ops::RangeFull> for str {
         type Output = str;
+
         #[inline]
-        fn index(&self, _index: &ops::RangeFull) -> &str {
+        fn index(&self, _index: ops::RangeFull) -> &str {
             self
         }
     }
@@ -1282,45 +1273,49 @@ mod traits {
            reason = "Instead of taking this bound generically, this trait will be \
                      replaced with one of slicing syntax (&foo[..]), deref coercions, or \
                      a more generic conversion trait")]
+#[deprecated(since = "1.0.0",
+             reason = "use std::convert::AsRef<str> instead")]
 pub trait Str {
     /// Work with `self` as a slice.
     fn as_slice<'a>(&'a self) -> &'a str;
 }
 
+#[allow(deprecated)]
 impl Str for str {
     #[inline]
     fn as_slice<'a>(&'a self) -> &'a str { self }
 }
 
+#[allow(deprecated)]
 impl<'a, S: ?Sized> Str for &'a S where S: Str {
     #[inline]
     fn as_slice(&self) -> &str { Str::as_slice(*self) }
 }
 
-/// Return type of `StrExt::split`
-#[derive(Clone)]
+/// Return type of `str::split`
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct Split<'a, P>(CharSplits<'a, P>);
+pub struct Split<'a, P: Pattern<'a>>(CharSplits<'a, P>);
 delegate_iter!{pattern &'a str : Split<'a, P>}
 
-/// Return type of `StrExt::split_terminator`
-#[derive(Clone)]
-#[unstable(feature = "core",
-           reason = "might get removed in favour of a constructor method on Split")]
-pub struct SplitTerminator<'a, P>(CharSplits<'a, P>);
+/// Return type of `str::split_terminator`
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct SplitTerminator<'a, P: Pattern<'a>>(CharSplits<'a, P>);
 delegate_iter!{pattern &'a str : SplitTerminator<'a, P>}
 
-/// Return type of `StrExt::splitn`
-#[derive(Clone)]
+/// Return type of `str::splitn`
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct SplitN<'a, P>(CharSplitsN<'a, P>);
+pub struct SplitN<'a, P: Pattern<'a>>(CharSplitsN<'a, P>);
 delegate_iter!{pattern forward &'a str : SplitN<'a, P>}
 
-/// Return type of `StrExt::rsplitn`
-#[derive(Clone)]
+/// Return type of `str::rsplit`
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct RSplitN<'a, P>(CharSplitsN<'a, P>);
-delegate_iter!{pattern forward &'a str : RSplitN<'a, P>}
+pub struct RSplit<'a, P: Pattern<'a>>(RCharSplits<'a, P>);
+delegate_iter!{pattern reverse &'a str : RSplit<'a, P>}
+
+/// Return type of `str::rsplitn`
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct RSplitN<'a, P: Pattern<'a>>(RCharSplitsN<'a, P>);
+delegate_iter!{pattern reverse &'a str : RSplitN<'a, P>}
 
 /// Methods for string slices
 #[allow(missing_docs)]
@@ -1328,36 +1323,42 @@ pub trait StrExt {
     // NB there are no docs here are they're all located on the StrExt trait in
     // libcollections, not here.
 
-    fn contains(&self, pat: &str) -> bool;
-    fn contains_char<P: CharEq>(&self, pat: P) -> bool;
+    fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
+    fn contains_char<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
     fn chars<'a>(&'a self) -> Chars<'a>;
     fn bytes<'a>(&'a self) -> Bytes<'a>;
     fn char_indices<'a>(&'a self) -> CharIndices<'a>;
-    fn split<'a, P: CharEq>(&'a self, pat: P) -> Split<'a, P>;
-    fn splitn<'a, P: CharEq>(&'a self, count: usize, pat: P) -> SplitN<'a, P>;
-    fn split_terminator<'a, P: CharEq>(&'a self, pat: P) -> SplitTerminator<'a, P>;
-    fn rsplitn<'a, P: CharEq>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>;
-    fn match_indices<'a>(&'a self, sep: &'a str) -> MatchIndices<'a>;
-    fn split_str<'a>(&'a self, pat: &'a str) -> SplitStr<'a>;
+    fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P>;
+    fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P>;
+    fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P>;
+    fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
+        where P::Searcher: ReverseSearcher<'a>;
+    fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
+        where P::Searcher: ReverseSearcher<'a>;
+    fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>;
     fn lines<'a>(&'a self) -> Lines<'a>;
     fn lines_any<'a>(&'a self) -> LinesAny<'a>;
     fn char_len(&self) -> usize;
     fn slice_chars<'a>(&'a self, begin: usize, end: usize) -> &'a str;
     unsafe fn slice_unchecked<'a>(&'a self, begin: usize, end: usize) -> &'a str;
-    fn starts_with(&self, pat: &str) -> bool;
-    fn ends_with(&self, pat: &str) -> bool;
-    fn trim_matches<'a, P: CharEq>(&'a self, pat: P) -> &'a str;
-    fn trim_left_matches<'a, P: CharEq>(&'a self, pat: P) -> &'a str;
-    fn trim_right_matches<'a, P: CharEq>(&'a self, pat: P) -> &'a str;
+    fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
+    fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
+        where P::Searcher: ReverseSearcher<'a>;
+    fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+        where P::Searcher: DoubleEndedSearcher<'a>;
+    fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str;
+    fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+        where P::Searcher: ReverseSearcher<'a>;
     fn is_char_boundary(&self, index: usize) -> bool;
     fn char_range_at(&self, start: usize) -> CharRange;
     fn char_range_at_reverse(&self, start: usize) -> CharRange;
     fn char_at(&self, i: usize) -> char;
     fn char_at_reverse(&self, i: usize) -> char;
     fn as_bytes<'a>(&'a self) -> &'a [u8];
-    fn find<P: CharEq>(&self, pat: P) -> Option<usize>;
-    fn rfind<P: CharEq>(&self, pat: P) -> Option<usize>;
-    fn find_str(&self, pat: &str) -> Option<usize>;
+    fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
+    fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
+        where P::Searcher: ReverseSearcher<'a>;
+    fn find_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
     fn slice_shift_char<'a>(&'a self) -> Option<(char, &'a str)>;
     fn subslice_offset(&self, inner: &str) -> usize;
     fn as_ptr(&self) -> *const u8;
@@ -1375,13 +1376,13 @@ fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
 
 impl StrExt for str {
     #[inline]
-    fn contains(&self, needle: &str) -> bool {
-        self.find_str(needle).is_some()
+    fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
+        pat.is_contained_in(self)
     }
 
     #[inline]
-    fn contains_char<P: CharEq>(&self, pat: P) -> bool {
-        self.find(pat).is_some()
+    fn contains_char<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
+        pat.is_contained_in(self)
     }
 
     #[inline]
@@ -1400,27 +1401,26 @@ impl StrExt for str {
     }
 
     #[inline]
-    fn split<P: CharEq>(&self, pat: P) -> Split<P> {
+    fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
         Split(CharSplits {
-            string: self,
-            only_ascii: pat.only_ascii(),
-            sep: pat,
+            start: 0,
+            end: self.len(),
+            matcher: pat.into_searcher(self),
             allow_trailing_empty: true,
             finished: false,
         })
     }
 
     #[inline]
-    fn splitn<P: CharEq>(&self, count: usize, pat: P) -> SplitN<P> {
+    fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P> {
         SplitN(CharSplitsN {
             iter: self.split(pat).0,
             count: count,
-            invert: false,
         })
     }
 
     #[inline]
-    fn split_terminator<P: CharEq>(&self, pat: P) -> SplitTerminator<P> {
+    fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
         SplitTerminator(CharSplits {
             allow_trailing_empty: false,
             ..self.split(pat).0
@@ -1428,31 +1428,31 @@ impl StrExt for str {
     }
 
     #[inline]
-    fn rsplitn<P: CharEq>(&self, count: usize, pat: P) -> RSplitN<P> {
-        RSplitN(CharSplitsN {
-            iter: self.split(pat).0,
-            count: count,
-            invert: true,
+    fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        RSplit(RCharSplits {
+            start: 0,
+            end: self.len(),
+            matcher: pat.into_searcher(self),
+            allow_final_empty: true,
+            finished: false,
         })
     }
 
     #[inline]
-    fn match_indices<'a>(&'a self, sep: &'a str) -> MatchIndices<'a> {
-        assert!(!sep.is_empty());
-        MatchIndices {
-            haystack: self,
-            needle: sep,
-            searcher: Searcher::new(self.as_bytes(), sep.as_bytes())
-        }
+    fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        RSplitN(RCharSplitsN {
+            iter: self.rsplit(pat).0,
+            count: count,
+        })
     }
 
     #[inline]
-    fn split_str<'a>(&'a self, sep: &'a str) -> SplitStr<'a> {
-        SplitStr {
-            it: self.match_indices(sep),
-            last_end: 0,
-            finished: false
-        }
+    fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
+        MatchIndices(pat.into_searcher(self))
     }
 
     #[inline]
@@ -1506,48 +1506,63 @@ impl StrExt for str {
     }
 
     #[inline]
-    fn starts_with(&self, needle: &str) -> bool {
-        let n = needle.len();
-        self.len() >= n && needle.as_bytes() == &self.as_bytes()[..n]
+    fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
+        pat.is_prefix_of(self)
     }
 
     #[inline]
-    fn ends_with(&self, needle: &str) -> bool {
-        let (m, n) = (self.len(), needle.len());
-        m >= n && needle.as_bytes() == &self.as_bytes()[m-n..]
+    fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        pat.is_suffix_of(self)
     }
 
     #[inline]
-    fn trim_matches<P: CharEq>(&self, mut pat: P) -> &str {
-        let cur = match self.find(|c: char| !pat.matches(c)) {
-            None => "",
-            Some(i) => unsafe { self.slice_unchecked(i, self.len()) }
-        };
-        match cur.rfind(|c: char| !pat.matches(c)) {
-            None => "",
-            Some(i) => {
-                let right = cur.char_range_at(i).next;
-                unsafe { cur.slice_unchecked(0, right) }
-            }
+    fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+        where P::Searcher: DoubleEndedSearcher<'a>
+    {
+        let mut i = 0;
+        let mut j = 0;
+        let mut matcher = pat.into_searcher(self);
+        if let Some((a, b)) = matcher.next_reject() {
+            i = a;
+            j = b; // Rember earliest known match, correct it below if
+                   // last match is different
+        }
+        if let Some((_, b)) = matcher.next_reject_back() {
+            j = b;
+        }
+        unsafe {
+            // Searcher is known to return valid indices
+            self.slice_unchecked(i, j)
         }
     }
 
     #[inline]
-    fn trim_left_matches<P: CharEq>(&self, mut pat: P) -> &str {
-        match self.find(|c: char| !pat.matches(c)) {
-            None => "",
-            Some(first) => unsafe { self.slice_unchecked(first, self.len()) }
+    fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
+        let mut i = self.len();
+        let mut matcher = pat.into_searcher(self);
+        if let Some((a, _)) = matcher.next_reject() {
+            i = a;
+        }
+        unsafe {
+            // Searcher is known to return valid indices
+            self.slice_unchecked(i, self.len())
         }
     }
 
     #[inline]
-    fn trim_right_matches<P: CharEq>(&self, mut pat: P) -> &str {
-        match self.rfind(|c: char| !pat.matches(c)) {
-            None => "",
-            Some(last) => {
-                let next = self.char_range_at(last).next;
-                unsafe { self.slice_unchecked(0, next) }
-            }
+    fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        let mut j = 0;
+        let mut matcher = pat.into_searcher(self);
+        if let Some((_, b)) = matcher.next_reject_back() {
+            j = b;
+        }
+        unsafe {
+            // Searcher is known to return valid indices
+            self.slice_unchecked(0, j)
         }
     }
 
@@ -1556,7 +1571,7 @@ impl StrExt for str {
         if index == self.len() { return true; }
         match self.as_bytes().get(index) {
             None => false,
-            Some(&b) => b < 128u8 || b >= 192u8,
+            Some(&b) => b < 128 || b >= 192,
         }
     }
 
@@ -1582,14 +1597,14 @@ impl StrExt for str {
                 i -= 1;
             }
 
-            let mut val = s.as_bytes()[i] as u32;
-            let w = UTF8_CHAR_WIDTH[val as usize] as usize;
-            assert!((w != 0));
+            let first= s.as_bytes()[i];
+            let w = UTF8_CHAR_WIDTH[first as usize];
+            assert!(w != 0);
 
-            val = utf8_first_byte!(val, w);
-            val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 1]);
-            if w > 2 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 2]); }
-            if w > 3 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 3]); }
+            let mut val = utf8_first_byte(first, w as u32);
+            val = utf8_acc_cont_byte(val, s.as_bytes()[i + 1]);
+            if w > 2 { val = utf8_acc_cont_byte(val, s.as_bytes()[i + 2]); }
+            if w > 3 { val = utf8_acc_cont_byte(val, s.as_bytes()[i + 3]); }
 
             return CharRange {ch: unsafe { mem::transmute(val) }, next: i};
         }
@@ -1612,36 +1627,18 @@ impl StrExt for str {
         unsafe { mem::transmute(self) }
     }
 
-    fn find<P: CharEq>(&self, mut pat: P) -> Option<usize> {
-        if pat.only_ascii() {
-            self.bytes().position(|b| pat.matches(b as char))
-        } else {
-            for (index, c) in self.char_indices() {
-                if pat.matches(c) { return Some(index); }
-            }
-            None
-        }
+    fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
+        pat.into_searcher(self).next_match().map(|(i, _)| i)
     }
 
-    fn rfind<P: CharEq>(&self, mut pat: P) -> Option<usize> {
-        if pat.only_ascii() {
-            self.bytes().rposition(|b| pat.matches(b as char))
-        } else {
-            for (index, c) in self.char_indices().rev() {
-                if pat.matches(c) { return Some(index); }
-            }
-            None
-        }
+    fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        pat.into_searcher(self).next_match_back().map(|(i, _)| i)
     }
 
-    fn find_str(&self, needle: &str) -> Option<usize> {
-        if needle.is_empty() {
-            Some(0)
-        } else {
-            self.match_indices(needle)
-                .next()
-                .map(|(start, _end)| start)
-        }
+    fn find_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
+        self.find(pat)
     }
 
     #[inline]
@@ -1649,8 +1646,8 @@ impl StrExt for str {
         if self.is_empty() {
             None
         } else {
-            let CharRange {ch, next} = self.char_range_at(0);
-            let next_s = unsafe { self.slice_unchecked(next, self.len()) };
+            let ch = self.char_at(0);
+            let next_s = unsafe { self.slice_unchecked(ch.len_utf8(), self.len()) };
             Some((ch, next_s))
         }
     }
@@ -1686,22 +1683,22 @@ impl StrExt for str {
 #[inline]
 #[unstable(feature = "core")]
 pub fn char_range_at_raw(bytes: &[u8], i: usize) -> (u32, usize) {
-    if bytes[i] < 128u8 {
+    if bytes[i] < 128 {
         return (bytes[i] as u32, i + 1);
     }
 
     // Multibyte case is a fn to allow char_range_at to inline cleanly
     fn multibyte_char_range_at(bytes: &[u8], i: usize) -> (u32, usize) {
-        let mut val = bytes[i] as u32;
-        let w = UTF8_CHAR_WIDTH[val as usize] as usize;
-        assert!((w != 0));
+        let first = bytes[i];
+        let w = UTF8_CHAR_WIDTH[first as usize];
+        assert!(w != 0);
 
-        val = utf8_first_byte!(val, w);
-        val = utf8_acc_cont_byte!(val, bytes[i + 1]);
-        if w > 2 { val = utf8_acc_cont_byte!(val, bytes[i + 2]); }
-        if w > 3 { val = utf8_acc_cont_byte!(val, bytes[i + 3]); }
+        let mut val = utf8_first_byte(first, w as u32);
+        val = utf8_acc_cont_byte(val, bytes[i + 1]);
+        if w > 2 { val = utf8_acc_cont_byte(val, bytes[i + 2]); }
+        if w > 3 { val = utf8_acc_cont_byte(val, bytes[i + 3]); }
 
-        return (val, i + w);
+        return (val, i + w as usize);
     }
 
     multibyte_char_range_at(bytes, i)
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
new file mode 100644 (file)
index 0000000..922ab2c
--- /dev/null
@@ -0,0 +1,571 @@
+// Copyright 2015 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 prelude::*;
+
+// Pattern
+
+/// A string pattern.
+///
+/// A `Pattern<'a>` expresses that the implementing type
+/// can be used as a string pattern for searching in a `&'a str`.
+///
+/// For example, both `'a'` and `"aa"` are patterns that
+/// would match at index `1` in the string `"baaaab"`.
+///
+/// The trait itself acts as a builder for an associated
+/// `Searcher` type, which does the actual work of finding
+/// occurrences of the pattern in a string.
+pub trait Pattern<'a>: Sized {
+    /// Associated searcher for this pattern
+    type Searcher: Searcher<'a>;
+
+    /// Construct the associated searcher from
+    /// `self` and the `haystack` to search in.
+    fn into_searcher(self, haystack: &'a str) -> Self::Searcher;
+
+    /// Check whether the pattern matches anywhere in the haystack
+    #[inline]
+    fn is_contained_in(self, haystack: &'a str) -> bool {
+        self.into_searcher(haystack).next_match().is_some()
+    }
+
+    /// Check whether the pattern matches at the front of the haystack
+    #[inline]
+    fn is_prefix_of(self, haystack: &'a str) -> bool {
+        match self.into_searcher(haystack).next() {
+            SearchStep::Match(0, _) => true,
+            _ => false,
+        }
+    }
+
+    /// Check whether the pattern matches at the back of the haystack
+    #[inline]
+    fn is_suffix_of(self, haystack: &'a str) -> bool
+        where Self::Searcher: ReverseSearcher<'a>
+    {
+        match self.into_searcher(haystack).next_back() {
+            SearchStep::Match(_, j) if haystack.len() == j => true,
+            _ => false,
+        }
+    }
+}
+
+// Searcher
+
+/// Result of calling `Searcher::next()` or `ReverseSearcher::next_back()`.
+#[derive(Copy, Clone, Eq, PartialEq, Debug)]
+pub enum SearchStep {
+    /// Expresses that a match of the pattern has been found at
+    /// `haystack[a..b]`.
+    Match(usize, usize),
+    /// Expresses that `haystack[a..b]` has been rejected as a possible match
+    /// of the pattern.
+    ///
+    /// Note that there might be more than one `Reject` between two `Match`es,
+    /// there is no requirement for them to be combined into one.
+    Reject(usize, usize),
+    /// Expresses that every byte of the haystack has been visted, ending
+    /// the iteration.
+    Done
+}
+
+/// A searcher for a string pattern.
+///
+/// This trait provides methods for searching for non-overlapping
+/// matches of a pattern starting from the front (left) of a string.
+///
+/// It will be implemented by associated `Searcher`
+/// types of the `Pattern` trait.
+///
+/// The trait is marked unsafe because the indices returned by the
+/// `next()` methods are required to lie on valid utf8 boundaries in
+/// the haystack. This enables consumers of this trait to
+/// slice the haystack without additional runtime checks.
+pub unsafe trait Searcher<'a> {
+    /// Getter for the underlaying string to be searched in
+    ///
+    /// Will always return the same `&str`
+    fn haystack(&self) -> &'a str;
+
+    /// Performs the next search step starting from the front.
+    ///
+    /// - Returns `Match(a, b)` if `haystack[a..b]` matches the pattern.
+    /// - Returns `Reject(a, b)` if `haystack[a..b]` can not match the
+    ///   pattern, even partially.
+    /// - Returns `Done` if every byte of the haystack has been visited
+    ///
+    /// The stream of `Match` and `Reject` values up to a `Done`
+    /// will contain index ranges that are adjacent, non-overlapping,
+    /// covering the whole haystack, and laying on utf8 boundaries.
+    ///
+    /// A `Match` result needs to contain the whole matched pattern,
+    /// however `Reject` results may be split up into arbitrary
+    /// many adjacent fragments. Both ranges may have zero length.
+    ///
+    /// As an example, the pattern `"aaa"` and the haystack `"cbaaaaab"`
+    /// might produce the stream
+    /// `[Reject(0, 1), Reject(1, 2), Match(2, 5), Reject(5, 8)]`
+    fn next(&mut self) -> SearchStep;
+
+    /// Find the next `Match` result. See `next()`
+    #[inline]
+    fn next_match(&mut self) -> Option<(usize, usize)> {
+        loop {
+            match self.next() {
+                SearchStep::Match(a, b) => return Some((a, b)),
+                SearchStep::Done => return None,
+                _ => continue,
+            }
+        }
+    }
+
+    /// Find the next `Reject` result. See `next()`
+    #[inline]
+    fn next_reject(&mut self) -> Option<(usize, usize)> {
+        loop {
+            match self.next() {
+                SearchStep::Reject(a, b) => return Some((a, b)),
+                SearchStep::Done => return None,
+                _ => continue,
+            }
+        }
+    }
+}
+
+/// A reverse searcher for a string pattern.
+///
+/// This trait provides methods for searching for non-overlapping
+/// matches of a pattern starting from the back (right) of a string.
+///
+/// It will be implemented by associated `Searcher`
+/// types of the `Pattern` trait if the pattern supports searching
+/// for it from the back.
+///
+/// The index ranges returned by this trait are not required
+/// to exactly match those of the forward search in reverse.
+///
+/// For the reason why this trait is marked unsafe, see them
+/// parent trait `Searcher`.
+pub unsafe trait ReverseSearcher<'a>: Searcher<'a> {
+    /// Performs the next search step starting from the back.
+    ///
+    /// - Returns `Match(a, b)` if `haystack[a..b]` matches the pattern.
+    /// - Returns `Reject(a, b)` if `haystack[a..b]` can not match the
+    ///   pattern, even partially.
+    /// - Returns `Done` if every byte of the haystack has been visited
+    ///
+    /// The stream of `Match` and `Reject` values up to a `Done`
+    /// will contain index ranges that are adjacent, non-overlapping,
+    /// covering the whole haystack, and laying on utf8 boundaries.
+    ///
+    /// A `Match` result needs to contain the whole matched pattern,
+    /// however `Reject` results may be split up into arbitrary
+    /// many adjacent fragments. Both ranges may have zero length.
+    ///
+    /// As an example, the pattern `"aaa"` and the haystack `"cbaaaaab"`
+    /// might produce the stream
+    /// `[Reject(7, 8), Match(4, 7), Reject(1, 4), Reject(0, 1)]`
+    fn next_back(&mut self) -> SearchStep;
+
+    /// Find the next `Match` result. See `next_back()`
+    #[inline]
+    fn next_match_back(&mut self) -> Option<(usize, usize)>{
+        loop {
+            match self.next_back() {
+                SearchStep::Match(a, b) => return Some((a, b)),
+                SearchStep::Done => return None,
+                _ => continue,
+            }
+        }
+    }
+
+    /// Find the next `Reject` result. See `next_back()`
+    #[inline]
+    fn next_reject_back(&mut self) -> Option<(usize, usize)>{
+        loop {
+            match self.next_back() {
+                SearchStep::Reject(a, b) => return Some((a, b)),
+                SearchStep::Done => return None,
+                _ => continue,
+            }
+        }
+    }
+}
+
+/// A marker trait to express that a `ReverseSearcher`
+/// can be used for a `DoubleEndedIterator` implementation.
+///
+/// For this, the impl of `Searcher` and `ReverseSearcher` need
+/// to follow these conditions:
+///
+/// - All results of `next()` need to be identical
+///   to the results of `next_back()` in reverse order.
+/// - `next()` and `next_back()` need to behave as
+///   the two ends of a range of values, that is they
+///   can not "walk past each other".
+///
+/// # Examples
+///
+/// `char::Searcher` is a `DoubleEndedSearcher` because searching for a
+/// `char` only requires looking at one at a time, which behaves the same
+/// from both ends.
+///
+/// `(&str)::Searcher` is not a `DoubleEndedSearcher` because
+/// the pattern `"aa"` in the haystack `"aaa"` matches as either
+/// `"[aa]a"` or `"a[aa]"`, depending from which side it is searched.
+pub trait DoubleEndedSearcher<'a>: ReverseSearcher<'a> {}
+
+// Impl for a CharEq wrapper
+
+#[doc(hidden)]
+trait CharEq {
+    fn matches(&mut self, char) -> bool;
+    fn only_ascii(&self) -> bool;
+}
+
+impl CharEq for char {
+    #[inline]
+    fn matches(&mut self, c: char) -> bool { *self == c }
+
+    #[inline]
+    fn only_ascii(&self) -> bool { (*self as u32) < 128 }
+}
+
+impl<F> CharEq for F where F: FnMut(char) -> bool {
+    #[inline]
+    fn matches(&mut self, c: char) -> bool { (*self)(c) }
+
+    #[inline]
+    fn only_ascii(&self) -> bool { false }
+}
+
+impl<'a> CharEq for &'a [char] {
+    #[inline]
+    fn matches(&mut self, c: char) -> bool {
+        self.iter().any(|&m| { let mut m = m; m.matches(c) })
+    }
+
+    #[inline]
+    fn only_ascii(&self) -> bool {
+        self.iter().all(|m| m.only_ascii())
+    }
+}
+
+struct CharEqPattern<C: CharEq>(C);
+
+struct CharEqSearcher<'a, C: CharEq> {
+    char_eq: C,
+    haystack: &'a str,
+    char_indices: super::CharIndices<'a>,
+    #[allow(dead_code)]
+    ascii_only: bool,
+}
+
+impl<'a, C: CharEq> Pattern<'a> for CharEqPattern<C> {
+    type Searcher = CharEqSearcher<'a, C>;
+
+    #[inline]
+    fn into_searcher(self, haystack: &'a str) -> CharEqSearcher<'a, C> {
+        CharEqSearcher {
+            ascii_only: self.0.only_ascii(),
+            haystack: haystack,
+            char_eq: self.0,
+            char_indices: haystack.char_indices(),
+        }
+    }
+}
+
+unsafe impl<'a, C: CharEq> Searcher<'a> for CharEqSearcher<'a, C> {
+    #[inline]
+    fn haystack(&self) -> &'a str {
+        self.haystack
+    }
+
+    #[inline]
+    fn next(&mut self) -> SearchStep {
+        let s = &mut self.char_indices;
+        // Compare lengths of the internal byte slice iterator
+        // to find length of current char
+        let (pre_len, _) = s.iter.iter.size_hint();
+        if let Some((i, c)) = s.next() {
+            let (len, _) = s.iter.iter.size_hint();
+            let char_len = pre_len - len;
+            if self.char_eq.matches(c) {
+                return SearchStep::Match(i, i + char_len);
+            } else {
+                return SearchStep::Reject(i, i + char_len);
+            }
+        }
+        SearchStep::Done
+    }
+}
+
+unsafe impl<'a, C: CharEq> ReverseSearcher<'a> for CharEqSearcher<'a, C> {
+    #[inline]
+    fn next_back(&mut self) -> SearchStep {
+        let s = &mut self.char_indices;
+        // Compare lengths of the internal byte slice iterator
+        // to find length of current char
+        let (pre_len, _) = s.iter.iter.size_hint();
+        if let Some((i, c)) = s.next_back() {
+            let (len, _) = s.iter.iter.size_hint();
+            let char_len = pre_len - len;
+            if self.char_eq.matches(c) {
+                return SearchStep::Match(i, i + char_len);
+            } else {
+                return SearchStep::Reject(i, i + char_len);
+            }
+        }
+        SearchStep::Done
+    }
+}
+
+impl<'a, C: CharEq> DoubleEndedSearcher<'a> for CharEqSearcher<'a, C> {}
+
+// Impl for &str
+
+// Todo: Optimize the naive implementation here
+
+#[derive(Clone)]
+struct StrSearcher<'a, 'b> {
+    haystack: &'a str,
+    needle: &'b str,
+    start: usize,
+    end: usize,
+    done: bool,
+}
+
+/// Non-allocating substring search.
+///
+/// Will handle the pattern `""` as returning empty matches at each utf8
+/// boundary.
+impl<'a, 'b> Pattern<'a> for &'b str {
+    type Searcher = StrSearcher<'a, 'b>;
+
+    #[inline]
+    fn into_searcher(self, haystack: &'a str) -> StrSearcher<'a, 'b> {
+        StrSearcher {
+            haystack: haystack,
+            needle: self,
+            start: 0,
+            end: haystack.len(),
+            done: false,
+        }
+    }
+}
+
+unsafe impl<'a, 'b> Searcher<'a> for StrSearcher<'a, 'b>  {
+    #[inline]
+    fn haystack(&self) -> &'a str {
+        self.haystack
+    }
+
+    #[inline]
+    fn next(&mut self) -> SearchStep {
+        str_search_step(self,
+        |m: &mut StrSearcher| {
+            // Forward step for empty needle
+            let current_start = m.start;
+            if !m.done {
+                m.start = m.haystack.char_range_at(current_start).next;
+            }
+            SearchStep::Match(current_start, current_start)
+        },
+        |m: &mut StrSearcher| {
+            // Forward step for nonempty needle
+            let current_start = m.start;
+            // Compare byte window because this might break utf8 boundaries
+            let possible_match = &m.haystack.as_bytes()[m.start .. m.start + m.needle.len()];
+            if possible_match == m.needle.as_bytes() {
+                m.start += m.needle.len();
+                SearchStep::Match(current_start, m.start)
+            } else {
+                // Skip a char
+                let haystack_suffix = &m.haystack[m.start..];
+                m.start += haystack_suffix.chars().next().unwrap().len_utf8();
+                SearchStep::Reject(current_start, m.start)
+            }
+        })
+    }
+}
+
+unsafe impl<'a, 'b> ReverseSearcher<'a> for StrSearcher<'a, 'b>  {
+    #[inline]
+    fn next_back(&mut self) -> SearchStep {
+        str_search_step(self,
+        |m: &mut StrSearcher| {
+            // Backward step for empty needle
+            let current_end = m.end;
+            if !m.done {
+                m.end = m.haystack.char_range_at_reverse(current_end).next;
+            }
+            SearchStep::Match(current_end, current_end)
+        },
+        |m: &mut StrSearcher| {
+            // Backward step for nonempty needle
+            let current_end = m.end;
+            // Compare byte window because this might break utf8 boundaries
+            let possible_match = &m.haystack.as_bytes()[m.end - m.needle.len() .. m.end];
+            if possible_match == m.needle.as_bytes() {
+                m.end -= m.needle.len();
+                SearchStep::Match(m.end, current_end)
+            } else {
+                // Skip a char
+                let haystack_prefix = &m.haystack[..m.end];
+                m.end -= haystack_prefix.chars().rev().next().unwrap().len_utf8();
+                SearchStep::Reject(m.end, current_end)
+            }
+        })
+    }
+}
+
+// Helper function for encapsulating the common control flow
+// of doing a search step from the front or doing a search step from the back
+fn str_search_step<F, G>(mut m: &mut StrSearcher,
+                         empty_needle_step: F,
+                         nonempty_needle_step: G) -> SearchStep
+    where F: FnOnce(&mut StrSearcher) -> SearchStep,
+          G: FnOnce(&mut StrSearcher) -> SearchStep
+{
+    if m.done {
+        SearchStep::Done
+    } else if m.needle.len() == 0 && m.start <= m.end {
+        // Case for needle == ""
+        if m.start == m.end {
+            m.done = true;
+        }
+        empty_needle_step(&mut m)
+    } else if m.start + m.needle.len() <= m.end {
+        // Case for needle != ""
+        nonempty_needle_step(&mut m)
+    } else if m.start < m.end {
+        // Remaining slice shorter than needle, reject it
+        m.done = true;
+        SearchStep::Reject(m.start, m.end)
+    } else {
+        m.done = true;
+        SearchStep::Done
+    }
+}
+
+macro_rules! char_eq_pattern_impl {
+    ($wrapper:ty, $wrapper_ident:ident) => {
+        fn into_searcher(self, haystack: &'a str) -> $wrapper {
+            $wrapper_ident(CharEqPattern(self).into_searcher(haystack))
+        }
+        #[inline]
+        fn is_contained_in(self, haystack: &'a str) -> bool {
+            CharEqPattern(self).is_contained_in(haystack)
+        }
+        #[inline]
+        fn is_prefix_of(self, haystack: &'a str) -> bool {
+            CharEqPattern(self).is_prefix_of(haystack)
+        }
+        #[inline]
+        fn is_suffix_of(self, haystack: &'a str) -> bool
+            where $wrapper: ReverseSearcher<'a>
+        {
+            CharEqPattern(self).is_suffix_of(haystack)
+        }
+    }
+}
+
+// Pattern for char
+
+impl<'a> Pattern<'a> for char {
+    type Searcher = CharSearcher<'a>;
+    char_eq_pattern_impl!(CharSearcher<'a>, CharSearcher);
+}
+
+pub struct CharSearcher<'a>(CharEqSearcher<'a, char>);
+
+unsafe impl<'a> Searcher<'a> for CharSearcher<'a> {
+    #[inline]
+    fn haystack(&self) -> &'a str { self.0.haystack() }
+    #[inline]
+    fn next(&mut self) -> SearchStep { self.0.next() }
+}
+unsafe impl<'a> ReverseSearcher<'a> for CharSearcher<'a> {
+    #[inline]
+    fn next_back(&mut self) -> SearchStep { self.0.next_back() }
+}
+impl<'a> DoubleEndedSearcher<'a> for CharSearcher<'a> {}
+
+// Pattern for &[char]
+
+impl<'a, 'b> Pattern<'a> for &'b [char] {
+    type Searcher = CharSliceSearcher<'a, 'b>;
+    char_eq_pattern_impl!(CharSliceSearcher<'a, 'b>, CharSliceSearcher);
+}
+
+pub struct CharSliceSearcher<'a, 'b>(CharEqSearcher<'a, &'b [char]>);
+
+unsafe impl<'a, 'b> Searcher<'a> for CharSliceSearcher<'a, 'b> {
+    #[inline]
+    fn haystack(&self) -> &'a str { self.0.haystack() }
+    #[inline]
+    fn next(&mut self) -> SearchStep { self.0.next() }
+}
+unsafe impl<'a, 'b> ReverseSearcher<'a> for CharSliceSearcher<'a, 'b> {
+    #[inline]
+    fn next_back(&mut self) -> SearchStep { self.0.next_back() }
+}
+impl<'a, 'b> DoubleEndedSearcher<'a> for CharSliceSearcher<'a, 'b> {}
+
+// Pattern for predicates
+
+impl<'a, F: FnMut(char) -> bool> Pattern<'a> for F {
+    type Searcher = CharPredSearcher<'a, F>;
+    char_eq_pattern_impl!(CharPredSearcher<'a, F>, CharPredSearcher);
+}
+
+pub struct CharPredSearcher<'a, F: FnMut(char) -> bool>(CharEqSearcher<'a, F>);
+
+unsafe impl<'a, F> Searcher<'a> for CharPredSearcher<'a, F>
+    where F: FnMut(char) -> bool
+{
+    #[inline]
+    fn haystack(&self) -> &'a str { self.0.haystack() }
+    #[inline]
+    fn next(&mut self) -> SearchStep { self.0.next() }
+}
+unsafe impl<'a, F> ReverseSearcher<'a> for CharPredSearcher<'a, F>
+    where F: FnMut(char) -> bool
+{
+    #[inline]
+    fn next_back(&mut self) -> SearchStep { self.0.next_back() }
+}
+impl<'a, F> DoubleEndedSearcher<'a> for CharPredSearcher<'a, F>
+    where F: FnMut(char) -> bool
+{}
+
+// Pattern for &&str
+
+impl<'a, 'b> Pattern<'a> for &'b &'b str {
+    type Searcher = <&'b str as Pattern<'a>>::Searcher;
+    #[inline]
+    fn into_searcher(self, haystack: &'a str)
+                     -> <&'b str as Pattern<'a>>::Searcher {
+        (*self).into_searcher(haystack)
+    }
+    #[inline]
+    fn is_contained_in(self, haystack: &'a str) -> bool {
+        (*self).is_contained_in(haystack)
+    }
+    #[inline]
+    fn is_prefix_of(self, haystack: &'a str) -> bool {
+        (*self).is_prefix_of(haystack)
+    }
+    #[inline]
+    fn is_suffix_of(self, haystack: &'a str) -> bool {
+        (*self).is_suffix_of(haystack)
+    }
+}
index 72b2d5dc18882d0e1e5a7f9220758491d1911072..ba6a7c4a5fefa0e476a16064f18959107fb7312a 100644 (file)
 
 //! Operations on tuples
 //!
-//! To access a single element of a tuple one can use the following
-//! methods:
+//! To access a single element of a tuple one can use the `.0`
+//! field access syntax.
 //!
-//! * `valN` - returns a value of _N_-th element
-//! * `refN` - returns a reference to _N_-th element
-//! * `mutN` - returns a mutable reference to _N_-th element
-//!
-//! Indexing starts from zero, so `val0` returns first value, `val1`
-//! returns second value, and so on. In general, a tuple with _S_
-//! elements provides aforementioned methods suffixed with numbers
-//! from `0` to `S-1`. Traits which contain these methods are
-//! implemented for tuples with up to 12 elements.
+//! Indexing starts from zero, so `.0` returns first value, `.1`
+//! returns second value, and so on. In general, a tuple with *N*
+//! elements has field accessors from 0 to *N* - 1.
 //!
 //! If every type inside a tuple implements one of the following
 //! traits, then a tuple itself also implements it.
@@ -52,7 +46,7 @@ macro_rules! e {
 macro_rules! tuple_impls {
     ($(
         $Tuple:ident {
-            $(($valN:ident, $refN:ident, $mutN:ident, $idx:tt) -> $T:ident)+
+            $(($idx:tt) -> $T:ident)+
         }
     )+) => {
         $(
@@ -156,105 +150,105 @@ macro_rules! lexical_cmp {
 
 tuple_impls! {
     Tuple1 {
-        (val0, ref0, mut0, 0) -> A
+        (0) -> A
     }
     Tuple2 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
+        (0) -> A
+        (1) -> B
     }
     Tuple3 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
+        (0) -> A
+        (1) -> B
+        (2) -> C
     }
     Tuple4 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
     }
     Tuple5 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
     }
     Tuple6 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
     }
     Tuple7 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
     }
     Tuple8 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
     }
     Tuple9 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-        (val8, ref8, mut8, 8) -> I
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+        (8) -> I
     }
     Tuple10 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-        (val8, ref8, mut8, 8) -> I
-        (val9, ref9, mut9, 9) -> J
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+        (8) -> I
+        (9) -> J
     }
     Tuple11 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-        (val8, ref8, mut8, 8) -> I
-        (val9, ref9, mut9, 9) -> J
-        (val10, ref10, mut10, 10) -> K
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+        (8) -> I
+        (9) -> J
+        (10) -> K
     }
     Tuple12 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-        (val8, ref8, mut8, 8) -> I
-        (val9, ref9, mut9, 9) -> J
-        (val10, ref10, mut10, 10) -> K
-        (val11, ref11, mut11, 11) -> L
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+        (8) -> I
+        (9) -> J
+        (10) -> K
+        (11) -> L
     }
 }
index 8b5e46f85fa6ac181b1e7968adaa364214c407ad..eeaaa3e217e8f1c80bbb0aca874f3f688c3c42ce 100644 (file)
@@ -37,9 +37,9 @@ fn any_referenced() {
 fn any_owning() {
     let (a, b, c) = (box 5_usize as Box<Any>, box TEST as Box<Any>, box Test as Box<Any>);
 
-    assert!(a.is::<uint>());
-    assert!(!b.is::<uint>());
-    assert!(!c.is::<uint>());
+    assert!(a.is::<usize>());
+    assert!(!b.is::<usize>());
+    assert!(!c.is::<usize>());
 
     assert!(!a.is::<&'static str>());
     assert!(b.is::<&'static str>());
@@ -54,7 +54,7 @@ fn any_owning() {
 fn any_downcast_ref() {
     let a = &5_usize as &Any;
 
-    match a.downcast_ref::<uint>() {
+    match a.downcast_ref::<usize>() {
         Some(&5) => {}
         x => panic!("Unexpected value {:?}", x)
     }
@@ -68,13 +68,13 @@ fn any_downcast_ref() {
 #[test]
 fn any_downcast_mut() {
     let mut a = 5_usize;
-    let mut b = box 7_usize;
+    let mut b: Box<_> = box 7_usize;
 
     let a_r = &mut a as &mut Any;
-    let tmp: &mut uint = &mut *b;
+    let tmp: &mut usize = &mut *b;
     let b_r = tmp as &mut Any;
 
-    match a_r.downcast_mut::<uint>() {
+    match a_r.downcast_mut::<usize>() {
         Some(x) => {
             assert_eq!(*x, 5);
             *x = 612;
@@ -82,7 +82,7 @@ fn any_downcast_mut() {
         x => panic!("Unexpected value {:?}", x)
     }
 
-    match b_r.downcast_mut::<uint>() {
+    match b_r.downcast_mut::<usize>() {
         Some(x) => {
             assert_eq!(*x, 7);
             *x = 413;
@@ -100,12 +100,12 @@ fn any_downcast_mut() {
         x => panic!("Unexpected value {:?}", x)
     }
 
-    match a_r.downcast_mut::<uint>() {
+    match a_r.downcast_mut::<usize>() {
         Some(&mut 612) => {}
         x => panic!("Unexpected value {:?}", x)
     }
 
-    match b_r.downcast_mut::<uint>() {
+    match b_r.downcast_mut::<usize>() {
         Some(&mut 413) => {}
         x => panic!("Unexpected value {:?}", x)
     }
@@ -115,8 +115,8 @@ fn any_downcast_mut() {
 fn any_fixed_vec() {
     let test = [0_usize; 8];
     let test = &test as &Any;
-    assert!(test.is::<[uint; 8]>());
-    assert!(!test.is::<[uint; 10]>());
+    assert!(test.is::<[usize; 8]>());
+    assert!(!test.is::<[usize; 10]>());
 }
 
 
@@ -126,6 +126,6 @@ fn bench_downcast_ref(b: &mut Bencher) {
         let mut x = 0;
         let mut y = &mut x as &mut Any;
         test::black_box(&mut y);
-        test::black_box(y.downcast_ref::<int>() == Some(&0));
+        test::black_box(y.downcast_ref::<isize>() == Some(&0));
     });
 }
index 317ef3a570143e9611f73d3e00047ccbf71c8045..85dd10390038fadc92ac4e3faf3d260d029497d3 100644 (file)
@@ -59,7 +59,6 @@ fn double_imm_borrow() {
 fn no_mut_then_imm_borrow() {
     let x = RefCell::new(0);
     let _b1 = x.borrow_mut();
-    assert!(x.try_borrow().is_none());
     assert_eq!(x.borrow_state(), BorrowState::Writing);
 }
 
@@ -67,7 +66,6 @@ fn no_mut_then_imm_borrow() {
 fn no_imm_then_borrow_mut() {
     let x = RefCell::new(0);
     let _b1 = x.borrow();
-    assert!(x.try_borrow_mut().is_none());
     assert_eq!(x.borrow_state(), BorrowState::Reading);
 }
 
@@ -76,7 +74,6 @@ fn no_double_borrow_mut() {
     let x = RefCell::new(0);
     assert_eq!(x.borrow_state(), BorrowState::Unused);
     let _b1 = x.borrow_mut();
-    assert!(x.try_borrow_mut().is_none());
     assert_eq!(x.borrow_state(), BorrowState::Writing);
 }
 
@@ -105,11 +102,11 @@ fn double_borrow_single_release_no_borrow_mut() {
     {
         let _b2 = x.borrow();
     }
-    assert!(x.try_borrow_mut().is_none());
+    assert_eq!(x.borrow_state(), BorrowState::Reading);
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn discard_doesnt_unborrow() {
     let x = RefCell::new(0);
     let _b = x.borrow();
@@ -122,31 +119,31 @@ fn clone_ref_updates_flag() {
     let x = RefCell::new(0);
     {
         let b1 = x.borrow();
-        assert!(x.try_borrow_mut().is_none());
+        assert_eq!(x.borrow_state(), BorrowState::Reading);
         {
             let _b2 = clone_ref(&b1);
-            assert!(x.try_borrow_mut().is_none());
+            assert_eq!(x.borrow_state(), BorrowState::Reading);
         }
-        assert!(x.try_borrow_mut().is_none());
+        assert_eq!(x.borrow_state(), BorrowState::Reading);
     }
-    assert!(x.try_borrow_mut().is_some());
+    assert_eq!(x.borrow_state(), BorrowState::Unused);
 }
 
 #[test]
 fn as_unsafe_cell() {
-    let c1: Cell<uint> = Cell::new(0);
+    let c1: Cell<usize> = Cell::new(0);
     c1.set(1);
     assert_eq!(1, unsafe { *c1.as_unsafe_cell().get() });
 
-    let c2: Cell<uint> = Cell::new(0);
+    let c2: Cell<usize> = Cell::new(0);
     unsafe { *c2.as_unsafe_cell().get() = 1; }
     assert_eq!(1, c2.get());
 
-    let r1: RefCell<uint> = RefCell::new(0);
+    let r1: RefCell<usize> = RefCell::new(0);
     *r1.borrow_mut() = 1;
     assert_eq!(1, unsafe { *r1.as_unsafe_cell().get() });
 
-    let r2: RefCell<uint> = RefCell::new(0);
+    let r2: RefCell<usize> = RefCell::new(0);
     unsafe { *r2.as_unsafe_cell().get() = 1; }
     assert_eq!(1, *r2.borrow());
 }
index 32dc6440b1326e546c8110da9fbf6ce7b3f7e98c..65e941d160d0453d0fce8e837c2c1dda14f12c41 100644 (file)
@@ -57,35 +57,47 @@ fn test_to_digit() {
 
 #[test]
 fn test_to_lowercase() {
-    assert_eq!('A'.to_lowercase(), 'a');
-    assert_eq!('Ö'.to_lowercase(), 'ö');
-    assert_eq!('ß'.to_lowercase(), 'ß');
-    assert_eq!('Ü'.to_lowercase(), 'ü');
-    assert_eq!('💩'.to_lowercase(), '💩');
-    assert_eq!('Σ'.to_lowercase(), 'σ');
-    assert_eq!('Τ'.to_lowercase(), 'τ');
-    assert_eq!('Ι'.to_lowercase(), 'ι');
-    assert_eq!('Γ'.to_lowercase(), 'γ');
-    assert_eq!('Μ'.to_lowercase(), 'μ');
-    assert_eq!('Α'.to_lowercase(), 'α');
-    assert_eq!('Σ'.to_lowercase(), 'σ');
+    fn lower(c: char) -> char {
+        let mut it = c.to_lowercase();
+        let c = it.next().unwrap();
+        assert!(it.next().is_none());
+        c
+    }
+    assert_eq!(lower('A'), 'a');
+    assert_eq!(lower('Ö'), 'ö');
+    assert_eq!(lower('ß'), 'ß');
+    assert_eq!(lower('Ü'), 'ü');
+    assert_eq!(lower('💩'), '💩');
+    assert_eq!(lower('Σ'), 'σ');
+    assert_eq!(lower('Τ'), 'τ');
+    assert_eq!(lower('Ι'), 'ι');
+    assert_eq!(lower('Γ'), 'γ');
+    assert_eq!(lower('Μ'), 'μ');
+    assert_eq!(lower('Α'), 'α');
+    assert_eq!(lower('Σ'), 'σ');
 }
 
 #[test]
 fn test_to_uppercase() {
-    assert_eq!('a'.to_uppercase(), 'A');
-    assert_eq!('ö'.to_uppercase(), 'Ö');
-    assert_eq!('ß'.to_uppercase(), 'ß'); // not ẞ: Latin capital letter sharp s
-    assert_eq!('ü'.to_uppercase(), 'Ü');
-    assert_eq!('💩'.to_uppercase(), '💩');
-
-    assert_eq!('σ'.to_uppercase(), 'Σ');
-    assert_eq!('τ'.to_uppercase(), 'Τ');
-    assert_eq!('ι'.to_uppercase(), 'Ι');
-    assert_eq!('γ'.to_uppercase(), 'Γ');
-    assert_eq!('μ'.to_uppercase(), 'Μ');
-    assert_eq!('α'.to_uppercase(), 'Α');
-    assert_eq!('ς'.to_uppercase(), 'Σ');
+    fn upper(c: char) -> char {
+        let mut it = c.to_uppercase();
+        let c = it.next().unwrap();
+        assert!(it.next().is_none());
+        c
+    }
+    assert_eq!(upper('a'), 'A');
+    assert_eq!(upper('ö'), 'Ö');
+    assert_eq!(upper('ß'), 'ß'); // not ẞ: Latin capital letter sharp s
+    assert_eq!(upper('ü'), 'Ü');
+    assert_eq!(upper('💩'), '💩');
+
+    assert_eq!(upper('σ'), 'Σ');
+    assert_eq!(upper('τ'), 'Τ');
+    assert_eq!(upper('ι'), 'Ι');
+    assert_eq!(upper('γ'), 'Γ');
+    assert_eq!(upper('μ'), 'Μ');
+    assert_eq!(upper('α'), 'Α');
+    assert_eq!(upper('ς'), 'Σ');
 }
 
 #[test]
@@ -165,7 +177,7 @@ fn test_escape_unicode() {
 #[test]
 fn test_encode_utf8() {
     fn check(input: char, expect: &[u8]) {
-        let mut buf = [0u8; 4];
+        let mut buf = [0; 4];
         let n = input.encode_utf8(&mut buf).unwrap_or(0);
         assert_eq!(&buf[..n], expect);
     }
@@ -179,7 +191,7 @@ fn test_encode_utf8() {
 #[test]
 fn test_encode_utf16() {
     fn check(input: char, expect: &[u16]) {
-        let mut buf = [0u16; 2];
+        let mut buf = [0; 2];
         let n = input.encode_utf16(&mut buf).unwrap_or(0);
         assert_eq!(&buf[..n], expect);
     }
index 2e5c6fe5a2ff7bec0f1f4a3694a85a22957ee061..9ed1508c3eb7877c23b0831682569562ddea5a5f 100644 (file)
@@ -114,7 +114,7 @@ fn test_user_defined_eq() {
 
     // Our type.
     struct SketchyNum {
-        num : int
+        num : isize
     }
 
     // Our implementation of `PartialEq` to support `==` and `!=`.
diff --git a/src/libcoretest/finally.rs b/src/libcoretest/finally.rs
deleted file mode 100644 (file)
index 55fcb84..0000000
+++ /dev/null
@@ -1,62 +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.
-
-#![allow(deprecated)]
-
-use core::finally::{try_finally, Finally};
-use std::thread;
-
-#[test]
-fn test_success() {
-    let mut i = 0;
-    try_finally(
-        &mut i, (),
-        |i, ()| {
-            *i = 10;
-        },
-        |i| {
-            assert!(!thread::panicking());
-            assert_eq!(*i, 10);
-            *i = 20;
-        });
-    assert_eq!(i, 20);
-}
-
-#[test]
-#[should_fail]
-fn test_fail() {
-    let mut i = 0;
-    try_finally(
-        &mut i, (),
-        |i, ()| {
-            *i = 10;
-            panic!();
-        },
-        |i| {
-            assert!(thread::panicking());
-            assert_eq!(*i, 10);
-        })
-}
-
-#[test]
-fn test_retval() {
-    let mut closure = || 10;
-    // FIXME(#16640) `: i32` annotation shouldn't be necessary
-    let i: i32 = closure.finally(|| { });
-    assert_eq!(i, 10);
-}
-
-#[test]
-fn test_compact() {
-    fn do_some_fallible_work() {}
-    fn but_always_run_this_function() { }
-    let mut f = do_some_fallible_work;
-    f.finally(but_always_run_this_function);
-}
diff --git a/src/libcoretest/fmt/builders.rs b/src/libcoretest/fmt/builders.rs
new file mode 100644 (file)
index 0000000..885ee3f
--- /dev/null
@@ -0,0 +1,498 @@
+// Copyright 2015 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.
+
+mod debug_struct {
+    use std::fmt;
+
+    #[test]
+    fn test_empty() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_struct("Foo").finish()
+            }
+        }
+
+        assert_eq!("Foo", format!("{:?}", Foo));
+        assert_eq!("Foo", format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_single() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_struct("Foo")
+                    .field("bar", &true)
+                    .finish()
+            }
+        }
+
+        assert_eq!("Foo { bar: true }", format!("{:?}", Foo));
+        assert_eq!(
+"Foo {
+    bar: true
+}",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_multiple() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_struct("Foo")
+                    .field("bar", &true)
+                    .field("baz", &format_args!("{}/{}", 10i32, 20i32))
+                    .finish()
+            }
+        }
+
+        assert_eq!("Foo { bar: true, baz: 10/20 }", format!("{:?}", Foo));
+        assert_eq!(
+"Foo {
+    bar: true,
+    baz: 10/20
+}",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_nested() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_struct("Foo")
+                    .field("bar", &true)
+                    .field("baz", &format_args!("{}/{}", 10i32, 20i32))
+                    .finish()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_struct("Bar")
+                    .field("foo", &Foo)
+                    .field("hello", &"world")
+                    .finish()
+            }
+        }
+
+        assert_eq!("Bar { foo: Foo { bar: true, baz: 10/20 }, hello: \"world\" }",
+                   format!("{:?}", Bar));
+        assert_eq!(
+"Bar {
+    foo: Foo {
+        bar: true,
+        baz: 10/20
+    },
+    hello: \"world\"
+}",
+                   format!("{:#?}", Bar));
+    }
+}
+
+mod debug_tuple {
+    use std::fmt;
+
+    #[test]
+    fn test_empty() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_tuple("Foo").finish()
+            }
+        }
+
+        assert_eq!("Foo", format!("{:?}", Foo));
+        assert_eq!("Foo", format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_single() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_tuple("Foo")
+                    .field(&true)
+                    .finish()
+            }
+        }
+
+        assert_eq!("Foo(true)", format!("{:?}", Foo));
+        assert_eq!(
+"Foo(
+    true
+)",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_multiple() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_tuple("Foo")
+                    .field(&true)
+                    .field(&format_args!("{}/{}", 10i32, 20i32))
+                    .finish()
+            }
+        }
+
+        assert_eq!("Foo(true, 10/20)", format!("{:?}", Foo));
+        assert_eq!(
+"Foo(
+    true,
+    10/20
+)",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_nested() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_tuple("Foo")
+                    .field(&true)
+                    .field(&format_args!("{}/{}", 10i32, 20i32))
+                    .finish()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_tuple("Bar")
+                    .field(&Foo)
+                    .field(&"world")
+                    .finish()
+            }
+        }
+
+        assert_eq!("Bar(Foo(true, 10/20), \"world\")",
+                   format!("{:?}", Bar));
+        assert_eq!(
+"Bar(
+    Foo(
+        true,
+        10/20
+    ),
+    \"world\"
+)",
+                   format!("{:#?}", Bar));
+    }
+}
+
+mod debug_map {
+    use std::fmt;
+
+    #[test]
+    fn test_empty() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_map().finish()
+            }
+        }
+
+        assert_eq!("{}", format!("{:?}", Foo));
+        assert_eq!("{}", format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_single() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_map()
+                    .entry(&"bar", &true)
+                    .finish()
+            }
+        }
+
+        assert_eq!("{\"bar\": true}", format!("{:?}", Foo));
+        assert_eq!(
+"{
+    \"bar\": true
+}",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_multiple() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_map()
+                    .entry(&"bar", &true)
+                    .entry(&10i32, &format_args!("{}/{}", 10i32, 20i32))
+                    .finish()
+            }
+        }
+
+        assert_eq!("{\"bar\": true, 10: 10/20}", format!("{:?}", Foo));
+        assert_eq!(
+"{
+    \"bar\": true,
+    10: 10/20
+}",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_nested() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_map()
+                    .entry(&"bar", &true)
+                    .entry(&10i32, &format_args!("{}/{}", 10i32, 20i32))
+                    .finish()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_map()
+                    .entry(&"foo", &Foo)
+                    .entry(&Foo, &"world")
+                    .finish()
+            }
+        }
+
+        assert_eq!("{\"foo\": {\"bar\": true, 10: 10/20}, \
+                    {\"bar\": true, 10: 10/20}: \"world\"}",
+                   format!("{:?}", Bar));
+        assert_eq!(
+"{
+    \"foo\": {
+        \"bar\": true,
+        10: 10/20
+    },
+    {
+        \"bar\": true,
+        10: 10/20
+    }: \"world\"
+}",
+                   format!("{:#?}", Bar));
+    }
+}
+
+mod debug_set {
+    use std::fmt;
+
+    #[test]
+    fn test_empty() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_set().finish()
+            }
+        }
+
+        assert_eq!("{}", format!("{:?}", Foo));
+        assert_eq!("{}", format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_single() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_set()
+                    .entry(&true)
+                    .finish()
+            }
+        }
+
+        assert_eq!("{true}", format!("{:?}", Foo));
+        assert_eq!(
+"{
+    true
+}",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_multiple() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_set()
+                    .entry(&true)
+                    .entry(&format_args!("{}/{}", 10i32, 20i32))
+                    .finish()
+            }
+        }
+
+        assert_eq!("{true, 10/20}", format!("{:?}", Foo));
+        assert_eq!(
+"{
+    true,
+    10/20
+}",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_nested() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_set()
+                    .entry(&true)
+                    .entry(&format_args!("{}/{}", 10i32, 20i32))
+                    .finish()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_set()
+                    .entry(&Foo)
+                    .entry(&"world")
+                    .finish()
+            }
+        }
+
+        assert_eq!("{{true, 10/20}, \"world\"}",
+                   format!("{:?}", Bar));
+        assert_eq!(
+"{
+    {
+        true,
+        10/20
+    },
+    \"world\"
+}",
+                   format!("{:#?}", Bar));
+    }
+}
+
+mod debug_list {
+    use std::fmt;
+
+    #[test]
+    fn test_empty() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_list().finish()
+            }
+        }
+
+        assert_eq!("[]", format!("{:?}", Foo));
+        assert_eq!("[]", format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_single() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_list()
+                    .entry(&true)
+                    .finish()
+            }
+        }
+
+        assert_eq!("[true]", format!("{:?}", Foo));
+        assert_eq!(
+"[
+    true
+]",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_multiple() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_list()
+                    .entry(&true)
+                    .entry(&format_args!("{}/{}", 10i32, 20i32))
+                    .finish()
+            }
+        }
+
+        assert_eq!("[true, 10/20]", format!("{:?}", Foo));
+        assert_eq!(
+"[
+    true,
+    10/20
+]",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_nested() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_list()
+                    .entry(&true)
+                    .entry(&format_args!("{}/{}", 10i32, 20i32))
+                    .finish()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_list()
+                    .entry(&Foo)
+                    .entry(&"world")
+                    .finish()
+            }
+        }
+
+        assert_eq!("[[true, 10/20], \"world\"]",
+                   format!("{:?}", Bar));
+        assert_eq!(
+"[
+    [
+        true,
+        10/20
+    ],
+    \"world\"
+]",
+                   format!("{:#?}", Bar));
+    }
+}
index e7792014446816c43fed31dae7cbe1c9ef285af0..cdb9c38f027f729d83c99f7c8d44e1170859c34c 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 mod num;
+mod builders;
 
 #[test]
 fn test_format_flags() {
index bc8461b0b9e09cf9c8c43d8a5d4752be40731959..ba12ff306e9b89dba04c107666553b416f426694 100644 (file)
@@ -125,14 +125,14 @@ fn test_format_int_flags() {
     assert!(format!("{:>8x}", 10) == "       a");
     assert!(format!("{:#08x}", 10) == "0x00000a");
     assert!(format!("{:08}", -10) == "-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");
+    assert!(format!("{:x}", !0u8) == "ff");
+    assert!(format!("{:X}", !0u8) == "FF");
+    assert!(format!("{:b}", !0u8) == "11111111");
+    assert!(format!("{:o}", !0u8) == "377");
+    assert!(format!("{:#x}", !0u8) == "0xff");
+    assert!(format!("{:#X}", !0u8) == "0xFF");
+    assert!(format!("{:#b}", !0u8) == "0b11111111");
+    assert!(format!("{:#o}", !0u8) == "0o377");
 }
 
 #[test]
@@ -161,7 +161,7 @@ fn test_format_radix() {
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn test_radix_base_too_large() {
     let _ = radix(55, 37);
 }
@@ -170,42 +170,42 @@ mod u32 {
     use test::Bencher;
     use core::fmt::radix;
     use std::rand::{weak_rng, Rng};
-    use std::old_io::util::NullWriter;
+    use std::io::{Write, sink};
 
     #[bench]
     fn format_bin(b: &mut Bencher) {
         let mut rng = weak_rng();
-        b.iter(|| { write!(&mut NullWriter, "{:b}", rng.gen::<u32>()) })
+        b.iter(|| { write!(&mut sink(), "{:b}", rng.gen::<u32>()) })
     }
 
     #[bench]
     fn format_oct(b: &mut Bencher) {
         let mut rng = weak_rng();
-        b.iter(|| { write!(&mut NullWriter, "{:o}", rng.gen::<u32>()) })
+        b.iter(|| { write!(&mut sink(), "{:o}", rng.gen::<u32>()) })
     }
 
     #[bench]
     fn format_dec(b: &mut Bencher) {
         let mut rng = weak_rng();
-        b.iter(|| { write!(&mut NullWriter, "{}", rng.gen::<u32>()) })
+        b.iter(|| { write!(&mut sink(), "{}", rng.gen::<u32>()) })
     }
 
     #[bench]
     fn format_hex(b: &mut Bencher) {
         let mut rng = weak_rng();
-        b.iter(|| { write!(&mut NullWriter, "{:x}", rng.gen::<u32>()) })
+        b.iter(|| { write!(&mut sink(), "{:x}", rng.gen::<u32>()) })
     }
 
     #[bench]
     fn format_show(b: &mut Bencher) {
         let mut rng = weak_rng();
-        b.iter(|| { write!(&mut NullWriter, "{:?}", rng.gen::<u32>()) })
+        b.iter(|| { write!(&mut sink(), "{:?}", rng.gen::<u32>()) })
     }
 
     #[bench]
     fn format_base_36(b: &mut Bencher) {
         let mut rng = weak_rng();
-        b.iter(|| { write!(&mut NullWriter, "{}", radix(rng.gen::<u32>(), 36)) })
+        b.iter(|| { write!(&mut sink(), "{}", radix(rng.gen::<u32>(), 36)) })
     }
 }
 
@@ -213,41 +213,41 @@ mod i32 {
     use test::Bencher;
     use core::fmt::radix;
     use std::rand::{weak_rng, Rng};
-    use std::old_io::util::NullWriter;
+    use std::io::{Write, sink};
 
     #[bench]
     fn format_bin(b: &mut Bencher) {
         let mut rng = weak_rng();
-        b.iter(|| { write!(&mut NullWriter, "{:b}", rng.gen::<i32>()) })
+        b.iter(|| { write!(&mut sink(), "{:b}", rng.gen::<i32>()) })
     }
 
     #[bench]
     fn format_oct(b: &mut Bencher) {
         let mut rng = weak_rng();
-        b.iter(|| { write!(&mut NullWriter, "{:o}", rng.gen::<i32>()) })
+        b.iter(|| { write!(&mut sink(), "{:o}", rng.gen::<i32>()) })
     }
 
     #[bench]
     fn format_dec(b: &mut Bencher) {
         let mut rng = weak_rng();
-        b.iter(|| { write!(&mut NullWriter, "{}", rng.gen::<i32>()) })
+        b.iter(|| { write!(&mut sink(), "{}", rng.gen::<i32>()) })
     }
 
     #[bench]
     fn format_hex(b: &mut Bencher) {
         let mut rng = weak_rng();
-        b.iter(|| { write!(&mut NullWriter, "{:x}", rng.gen::<i32>()) })
+        b.iter(|| { write!(&mut sink(), "{:x}", rng.gen::<i32>()) })
     }
 
     #[bench]
     fn format_show(b: &mut Bencher) {
         let mut rng = weak_rng();
-        b.iter(|| { write!(&mut NullWriter, "{:?}", rng.gen::<i32>()) })
+        b.iter(|| { write!(&mut sink(), "{:?}", rng.gen::<i32>()) })
     }
 
     #[bench]
     fn format_base_36(b: &mut Bencher) {
         let mut rng = weak_rng();
-        b.iter(|| { write!(&mut NullWriter, "{}", radix(rng.gen::<i32>(), 36)) })
+        b.iter(|| { write!(&mut sink(), "{}", radix(rng.gen::<i32>(), 36)) })
     }
 }
index 9b6af182f729c291751d2db896acfbc4e5c74200..5c11f0196aeb8d7cdf377fe5d44fb573ac5f642d 100644 (file)
@@ -62,9 +62,10 @@ fn test_writer_hasher() {
     // FIXME (#18283) Enable test
     //let s: Box<str> = box "a";
     //assert_eq!(hasher.hash(& s), 97 + 0xFF);
-    let cs: &[u8] = &[1u8, 2u8, 3u8];
+    let cs: &[u8] = &[1, 2, 3];
     assert_eq!(hash(& cs), 9);
-    let cs: Box<[u8]> = box [1u8, 2u8, 3u8];
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let cs: Box<[u8]> = Box::new([1, 2, 3]);
     assert_eq!(hash(& cs), 9);
 
     // FIXME (#18248) Add tests for hashing Rc<str> and Rc<[T]>
@@ -85,7 +86,7 @@ struct CustomHasher { output: u64 }
 
 impl Hasher for CustomHasher {
     fn finish(&self) -> u64 { self.output }
-    fn write(&mut self, data: &[u8]) { panic!() }
+    fn write(&mut self, _: &[u8]) { panic!() }
     fn write_u64(&mut self, data: u64) { self.output = data; }
 }
 
index 248cad32ef4d24c7af645dc16543d783bf9cf682..8289d06d04c61b2541ac73b79e6063e8d50881c7 100644 (file)
@@ -100,8 +100,8 @@ fn test_siphash() {
         [ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ]
     ];
 
-    let k0 = 0x_07_06_05_04_03_02_01_00_u64;
-    let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08_u64;
+    let k0 = 0x_07_06_05_04_03_02_01_00;
+    let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;
     let mut buf = Vec::new();
     let mut t = 0;
     let mut state_inc = SipState::new_with_keys(k0, k1);
@@ -230,8 +230,8 @@ fn test_hash_no_concat_alias() {
     assert!(s != t && t != u);
     assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u));
 
-    let v: (&[u8], &[u8], &[u8]) = (&[1u8], &[0u8, 0], &[0u8]);
-    let w: (&[u8], &[u8], &[u8]) = (&[1u8, 0, 0, 0], &[], &[]);
+    let v: (&[u8], &[u8], &[u8]) = (&[1], &[0, 0], &[0]);
+    let w: (&[u8], &[u8], &[u8]) = (&[1, 0, 0, 0], &[], &[]);
 
     assert!(v != w);
     assert!(hash(&v) != hash(&w));
index b836f5f3f69f4bf56836d3bef96828383323e084..c99fb8c197d834bb7815910085b729cf2870777f 100644 (file)
@@ -28,4 +28,3 @@ fn test_typeid_unsized_types() {
     assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
     assert!(TypeId::of::<X>() != TypeId::of::<Y>());
 }
-
index 39a590c73074332d91a6de9319df3a52e2e70546..af80d347f028e02b66d4b8c572993c9b4d5edda4 100644 (file)
@@ -12,14 +12,14 @@ use core::iter::*;
 use core::iter::order::*;
 use core::iter::MinMaxResult::*;
 use core::num::SignedInt;
-use core::uint;
+use core::usize;
 use core::cmp;
 
 use test::Bencher;
 
 #[test]
 fn test_lt() {
-    let empty: [int; 0] = [];
+    let empty: [isize; 0] = [];
     let xs = [1,2,3];
     let ys = [1,2,0];
 
@@ -72,9 +72,9 @@ fn test_multi_iter() {
 
 #[test]
 fn test_counter_from_iter() {
-    let it = count(0, 5).take(10);
-    let xs: Vec<int> = FromIterator::from_iter(it);
-    assert!(xs == vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
+    let it = (0..).step_by(5).take(10);
+    let xs: Vec<isize> = FromIterator::from_iter(it);
+    assert_eq!(xs, [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
 }
 
 #[test]
@@ -82,7 +82,7 @@ fn test_iterator_chain() {
     let xs = [0, 1, 2, 3, 4, 5];
     let ys = [30, 40, 50, 60];
     let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
-    let mut it = xs.iter().chain(ys.iter());
+    let it = xs.iter().chain(ys.iter());
     let mut i = 0;
     for &x in it {
         assert_eq!(x, expected[i]);
@@ -90,8 +90,8 @@ fn test_iterator_chain() {
     }
     assert_eq!(i, expected.len());
 
-    let ys = count(30, 10).take(4);
-    let mut it = xs.iter().cloned().chain(ys);
+    let ys = (30..).step_by(10).take(4);
+    let it = xs.iter().cloned().chain(ys);
     let mut i = 0;
     for x in it {
         assert_eq!(x, expected[i]);
@@ -102,15 +102,15 @@ fn test_iterator_chain() {
 
 #[test]
 fn test_filter_map() {
-    let it = count(0, 1).take(10)
+    let it = (0..).step_by(1).take(10)
         .filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None });
-    assert!(it.collect::<Vec<uint>>() == vec![0*0, 2*2, 4*4, 6*6, 8*8]);
+    assert_eq!(it.collect::<Vec<usize>>(), [0*0, 2*2, 4*4, 6*6, 8*8]);
 }
 
 #[test]
 fn test_iterator_enumerate() {
     let xs = [0, 1, 2, 3, 4, 5];
-    let mut it = xs.iter().enumerate();
+    let it = xs.iter().enumerate();
     for (i, &x) in it {
         assert_eq!(i, x);
     }
@@ -152,7 +152,7 @@ fn test_iterator_peekable() {
 fn test_iterator_take_while() {
     let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
     let ys = [0, 1, 2, 3, 5, 13];
-    let mut it = xs.iter().take_while(|&x| *x < 15);
+    let it = xs.iter().take_while(|&x| *x < 15);
     let mut i = 0;
     for x in it {
         assert_eq!(*x, ys[i]);
@@ -165,7 +165,7 @@ fn test_iterator_take_while() {
 fn test_iterator_skip_while() {
     let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
     let ys = [15, 16, 17, 19];
-    let mut it = xs.iter().skip_while(|&x| *x < 15);
+    let it = xs.iter().skip_while(|&x| *x < 15);
     let mut i = 0;
     for x in it {
         assert_eq!(*x, ys[i]);
@@ -224,14 +224,14 @@ fn test_iterator_take_short() {
 #[test]
 fn test_iterator_scan() {
     // test the type inference
-    fn add(old: &mut int, new: &uint) -> Option<f64> {
-        *old += *new as int;
+    fn add(old: &mut isize, new: &usize) -> Option<f64> {
+        *old += *new as isize;
         Some(*old as f64)
     }
     let xs = [0, 1, 2, 3, 4];
     let ys = [0f64, 1.0, 3.0, 6.0, 10.0];
 
-    let mut it = xs.iter().scan(0, add);
+    let it = xs.iter().scan(0, add);
     let mut i = 0;
     for x in it {
         assert_eq!(x, ys[i]);
@@ -244,7 +244,7 @@ fn test_iterator_scan() {
 fn test_iterator_flat_map() {
     let xs = [0, 3, 6];
     let ys = [0, 1, 2, 3, 4, 5, 6, 7, 8];
-    let mut it = xs.iter().flat_map(|&x| count(x, 1).take(3));
+    let it = xs.iter().flat_map(|&x| (x..).step_by(1).take(3));
     let mut i = 0;
     for x in it {
         assert_eq!(x, ys[i]);
@@ -261,7 +261,7 @@ fn test_inspect() {
     let ys = xs.iter()
                .cloned()
                .inspect(|_| n += 1)
-               .collect::<Vec<uint>>();
+               .collect::<Vec<usize>>();
 
     assert_eq!(n, xs.len());
     assert_eq!(&xs[..], &ys[..]);
@@ -269,7 +269,7 @@ fn test_inspect() {
 
 #[test]
 fn test_unfoldr() {
-    fn count(st: &mut uint) -> Option<uint> {
+    fn count(st: &mut usize) -> Option<usize> {
         if *st < 10 {
             let ret = Some(*st);
             *st += 1;
@@ -279,7 +279,7 @@ fn test_unfoldr() {
         }
     }
 
-    let mut it = Unfold::new(0, count);
+    let it = Unfold::new(0, count);
     let mut i = 0;
     for counted in it {
         assert_eq!(counted, i);
@@ -291,13 +291,13 @@ fn test_unfoldr() {
 #[test]
 fn test_cycle() {
     let cycle_len = 3;
-    let it = count(0, 1).take(cycle_len).cycle();
-    assert_eq!(it.size_hint(), (uint::MAX, None));
+    let it = (0..).step_by(1).take(cycle_len).cycle();
+    assert_eq!(it.size_hint(), (usize::MAX, None));
     for (i, x) in it.take(100).enumerate() {
         assert_eq!(i % cycle_len, x);
     }
 
-    let mut it = count(0, 1).take(0).cycle();
+    let mut it = (0..).step_by(1).take(0).cycle();
     assert_eq!(it.size_hint(), (0, Some(0)));
     assert_eq!(it.next(), None);
 }
@@ -360,24 +360,24 @@ fn test_iterator_min() {
 
 #[test]
 fn test_iterator_size_hint() {
-    let c = count(0, 1);
+    let c = (0..).step_by(1);
     let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
     let v2 = &[10, 11, 12];
     let vi = v.iter();
 
-    assert_eq!(c.size_hint(), (uint::MAX, None));
+    assert_eq!(c.size_hint(), (usize::MAX, None));
     assert_eq!(vi.clone().size_hint(), (10, Some(10)));
 
     assert_eq!(c.clone().take(5).size_hint(), (5, Some(5)));
     assert_eq!(c.clone().skip(5).size_hint().1, None);
     assert_eq!(c.clone().take_while(|_| false).size_hint(), (0, None));
     assert_eq!(c.clone().skip_while(|_| false).size_hint(), (0, None));
-    assert_eq!(c.clone().enumerate().size_hint(), (uint::MAX, None));
-    assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (uint::MAX, None));
+    assert_eq!(c.clone().enumerate().size_hint(), (usize::MAX, None));
+    assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (usize::MAX, None));
     assert_eq!(c.clone().zip(vi.clone()).size_hint(), (10, Some(10)));
     assert_eq!(c.clone().scan(0, |_,_| Some(0)).size_hint(), (0, None));
     assert_eq!(c.clone().filter(|_| false).size_hint(), (0, None));
-    assert_eq!(c.clone().map(|_| 0).size_hint(), (uint::MAX, None));
+    assert_eq!(c.clone().map(|_| 0).size_hint(), (usize::MAX, None));
     assert_eq!(c.filter_map(|_| Some(0)).size_hint(), (0, None));
 
     assert_eq!(vi.clone().take(5).size_hint(), (5, Some(5)));
@@ -398,13 +398,14 @@ fn test_iterator_size_hint() {
 #[test]
 fn test_collect() {
     let a = vec![1, 2, 3, 4, 5];
-    let b: Vec<int> = a.iter().cloned().collect();
+    let b: Vec<isize> = a.iter().cloned().collect();
     assert!(a == b);
 }
 
 #[test]
 fn test_all() {
-    let v: Box<[int]> = box [1, 2, 3, 4, 5];
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let v: Box<[isize]> = Box::new([1, 2, 3, 4, 5]);
     assert!(v.iter().all(|&x| x < 10));
     assert!(!v.iter().all(|&x| x % 2 == 0));
     assert!(!v.iter().all(|&x| x > 100));
@@ -413,7 +414,8 @@ fn test_all() {
 
 #[test]
 fn test_any() {
-    let v: Box<[int]> = box [1, 2, 3, 4, 5];
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let v: Box<[isize]> = Box::new([1, 2, 3, 4, 5]);
     assert!(v.iter().any(|&x| x < 10));
     assert!(v.iter().any(|&x| x % 2 == 0));
     assert!(!v.iter().any(|&x| x > 100));
@@ -422,7 +424,7 @@ fn test_any() {
 
 #[test]
 fn test_find() {
-    let v: &[int] = &[1, 3, 9, 27, 103, 14, 11];
+    let v: &[isize] = &[1, 3, 9, 27, 103, 14, 11];
     assert_eq!(*v.iter().find(|&&x| x & 1 == 0).unwrap(), 14);
     assert_eq!(*v.iter().find(|&&x| x % 3 == 0).unwrap(), 3);
     assert!(v.iter().find(|&&x| x % 12 == 0).is_none());
@@ -446,13 +448,13 @@ fn test_count() {
 
 #[test]
 fn test_max_by() {
-    let xs: &[int] = &[-3, 0, 1, 5, -10];
+    let xs: &[isize] = &[-3, 0, 1, 5, -10];
     assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
 }
 
 #[test]
 fn test_min_by() {
-    let xs: &[int] = &[-3, 0, 1, 5, -10];
+    let xs: &[isize] = &[-3, 0, 1, 5, -10];
     assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
 }
 
@@ -471,7 +473,7 @@ fn test_rev() {
     let mut it = xs.iter();
     it.next();
     it.next();
-    assert!(it.rev().cloned().collect::<Vec<int>>() ==
+    assert!(it.rev().cloned().collect::<Vec<isize>>() ==
             vec![16, 14, 12, 10, 8, 6]);
 }
 
@@ -570,8 +572,8 @@ fn test_double_ended_chain() {
 
 #[test]
 fn test_rposition() {
-    fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
-    fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' }
+    fn f(xy: &(isize, char)) -> bool { let (_x, y) = *xy; y == 'b' }
+    fn g(xy: &(isize, char)) -> bool { let (_x, y) = *xy; y == 'd' }
     let v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
 
     assert_eq!(v.iter().rposition(f), Some(3));
@@ -579,10 +581,11 @@ fn test_rposition() {
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn test_rposition_panic() {
-    let v = [(box 0, box 0), (box 0, box 0),
-             (box 0, box 0), (box 0, box 0)];
+    let v: [(Box<_>, Box<_>); 4] =
+        [(box 0, box 0), (box 0, box 0),
+         (box 0, box 0), (box 0, box 0)];
     let mut i = 0;
     v.iter().rposition(|_elt| {
         if i == 2 {
@@ -595,7 +598,7 @@ fn test_rposition_panic() {
 
 
 #[cfg(test)]
-fn check_randacc_iter<A, T>(a: T, len: uint) where
+fn check_randacc_iter<A, T>(a: T, len: usize) where
     A: PartialEq,
     T: Clone + RandomAccessIterator + Iterator<Item=A>,
 {
@@ -681,7 +684,7 @@ fn test_random_access_zip() {
 #[test]
 fn test_random_access_take() {
     let xs = [1, 2, 3, 4, 5];
-    let empty: &[int] = &[];
+    let empty: &[isize] = &[];
     check_randacc_iter(xs.iter().take(3), 3);
     check_randacc_iter(xs.iter().take(20), xs.len());
     check_randacc_iter(xs.iter().take(0), 0);
@@ -691,7 +694,7 @@ fn test_random_access_take() {
 #[test]
 fn test_random_access_skip() {
     let xs = [1, 2, 3, 4, 5];
-    let empty: &[int] = &[];
+    let empty: &[isize] = &[];
     check_randacc_iter(xs.iter().skip(2), xs.len() - 2);
     check_randacc_iter(empty.iter().skip(2), 0);
 }
@@ -723,19 +726,19 @@ fn test_random_access_map() {
 #[test]
 fn test_random_access_cycle() {
     let xs = [1, 2, 3, 4, 5];
-    let empty: &[int] = &[];
+    let empty: &[isize] = &[];
     check_randacc_iter(xs.iter().cycle().take(27), 27);
     check_randacc_iter(empty.iter().cycle(), 0);
 }
 
 #[test]
 fn test_double_ended_range() {
-    assert!((11..14).rev().collect::<Vec<_>>() == vec![13, 12, 11]);
+    assert_eq!((11..14).rev().collect::<Vec<_>>(), [13, 12, 11]);
     for _ in (10..0).rev() {
         panic!("unreachable");
     }
 
-    assert!((11..14).rev().collect::<Vec<_>>() == vec![13, 12, 11]);
+    assert_eq!((11..14).rev().collect::<Vec<_>>(), [13, 12, 11]);
     for _ in (10..0).rev() {
         panic!("unreachable");
     }
@@ -743,62 +746,51 @@ fn test_double_ended_range() {
 
 #[test]
 fn test_range() {
-    assert!((0..5).collect::<Vec<_>>() == vec![0, 1, 2, 3, 4]);
-    assert!((-10..-1).collect::<Vec<_>>() ==
-               vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]);
-    assert!((0..5).rev().collect::<Vec<_>>() == vec![4, 3, 2, 1, 0]);
+    assert_eq!((0..5).collect::<Vec<_>>(), [0, 1, 2, 3, 4]);
+    assert_eq!((-10..-1).collect::<Vec<_>>(), [-10, -9, -8, -7, -6, -5, -4, -3, -2]);
+    assert_eq!((0..5).rev().collect::<Vec<_>>(), [4, 3, 2, 1, 0]);
     assert_eq!((200..-5).count(), 0);
     assert_eq!((200..-5).rev().count(), 0);
     assert_eq!((200..200).count(), 0);
     assert_eq!((200..200).rev().count(), 0);
 
     assert_eq!((0..100).size_hint(), (100, Some(100)));
-    // this test is only meaningful when sizeof uint < sizeof u64
-    assert_eq!((uint::MAX - 1..uint::MAX).size_hint(), (1, Some(1)));
+    // this test is only meaningful when sizeof usize < sizeof u64
+    assert_eq!((usize::MAX - 1..usize::MAX).size_hint(), (1, Some(1)));
     assert_eq!((-10..-1).size_hint(), (9, Some(9)));
     assert_eq!((-1..-10).size_hint(), (0, Some(0)));
 }
 
 #[test]
 fn test_range_inclusive() {
-    assert!(range_inclusive(0, 5).collect::<Vec<int>>() ==
+    assert!(range_inclusive(0, 5).collect::<Vec<isize>>() ==
             vec![0, 1, 2, 3, 4, 5]);
-    assert!(range_inclusive(0, 5).rev().collect::<Vec<int>>() ==
+    assert!(range_inclusive(0, 5).rev().collect::<Vec<isize>>() ==
             vec![5, 4, 3, 2, 1, 0]);
     assert_eq!(range_inclusive(200, -5).count(), 0);
     assert_eq!(range_inclusive(200, -5).rev().count(), 0);
-    assert!(range_inclusive(200, 200).collect::<Vec<int>>() == vec![200]);
-    assert!(range_inclusive(200, 200).rev().collect::<Vec<int>>() == vec![200]);
+    assert_eq!(range_inclusive(200, 200).collect::<Vec<isize>>(), [200]);
+    assert_eq!(range_inclusive(200, 200).rev().collect::<Vec<isize>>(), [200]);
 }
 
 #[test]
 fn test_range_step() {
-    assert!(range_step(0, 20, 5).collect::<Vec<int>>() ==
-            vec![0, 5, 10, 15]);
-    assert!(range_step(20, 0, -5).collect::<Vec<int>>() ==
-            vec![20, 15, 10, 5]);
-    assert!(range_step(20, 0, -6).collect::<Vec<int>>() ==
-            vec![20, 14, 8, 2]);
-    assert!(range_step(200u8, 255, 50).collect::<Vec<u8>>() ==
-            vec![200u8, 250]);
-    assert!(range_step(200, -5, 1).collect::<Vec<int>>() == vec![]);
-    assert!(range_step(200, 200, 1).collect::<Vec<int>>() == vec![]);
+    assert_eq!((0..20).step_by(5).collect::<Vec<isize>>(), [0, 5, 10, 15]);
+    assert_eq!((20..0).step_by(-5).collect::<Vec<isize>>(), [20, 15, 10, 5]);
+    assert_eq!((20..0).step_by(-6).collect::<Vec<isize>>(), [20, 14, 8, 2]);
+    assert_eq!((200..255).step_by(50).collect::<Vec<u8>>(), [200, 250]);
+    assert_eq!((200..-5).step_by(1).collect::<Vec<isize>>(), []);
+    assert_eq!((200..200).step_by(1).collect::<Vec<isize>>(), []);
 }
 
 #[test]
 fn test_range_step_inclusive() {
-    assert!(range_step_inclusive(0, 20, 5).collect::<Vec<int>>() ==
-            vec![0, 5, 10, 15, 20]);
-    assert!(range_step_inclusive(20, 0, -5).collect::<Vec<int>>() ==
-            vec![20, 15, 10, 5, 0]);
-    assert!(range_step_inclusive(20, 0, -6).collect::<Vec<int>>() ==
-            vec![20, 14, 8, 2]);
-    assert!(range_step_inclusive(200u8, 255, 50).collect::<Vec<u8>>() ==
-            vec![200u8, 250]);
-    assert!(range_step_inclusive(200, -5, 1).collect::<Vec<int>>() ==
-            vec![]);
-    assert!(range_step_inclusive(200, 200, 1).collect::<Vec<int>>() ==
-            vec![200]);
+    assert_eq!(range_step_inclusive(0, 20, 5).collect::<Vec<isize>>(), [0, 5, 10, 15, 20]);
+    assert_eq!(range_step_inclusive(20, 0, -5).collect::<Vec<isize>>(), [20, 15, 10, 5, 0]);
+    assert_eq!(range_step_inclusive(20, 0, -6).collect::<Vec<isize>>(), [20, 14, 8, 2]);
+    assert_eq!(range_step_inclusive(200, 255, 50).collect::<Vec<u8>>(), [200, 250]);
+    assert_eq!(range_step_inclusive(200, -5, 1).collect::<Vec<isize>>(), []);
+    assert_eq!(range_step_inclusive(200, 200, 1).collect::<Vec<isize>>(), [200]);
 }
 
 #[test]
@@ -819,7 +811,7 @@ fn test_peekable_is_empty() {
 
 #[test]
 fn test_min_max() {
-    let v: [int; 0] = [];
+    let v: [isize; 0] = [];
     assert_eq!(v.iter().min_max(), NoElements);
 
     let v = [1];
@@ -837,7 +829,7 @@ fn test_min_max() {
 
 #[test]
 fn test_min_max_result() {
-    let r: MinMaxResult<int> = NoElements;
+    let r: MinMaxResult<isize> = NoElements;
     assert_eq!(r.into_option(), None);
 
     let r = OneElement(1);
@@ -884,7 +876,7 @@ fn test_fuse() {
 
 #[bench]
 fn bench_rposition(b: &mut Bencher) {
-    let it: Vec<uint> = (0..300).collect();
+    let it: Vec<usize> = (0..300).collect();
     b.iter(|| {
         it.iter().rposition(|&x| x <= 150);
     });
index 2dfd81f32c2703869f43d32657089860b80ca7db..7ae0dcbb5f9d4b7cae3fda5196908395db025ead 100644 (file)
@@ -8,10 +8,25 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![feature(box_syntax)]
 #![feature(int_uint)]
 #![feature(unboxed_closures)]
 #![feature(unsafe_destructor)]
+#![feature(core)]
+#![feature(test)]
+#![feature(rand)]
+#![feature(unicode)]
+#![feature(std_misc)]
+#![feature(libc)]
+#![feature(hash)]
+#![feature(io)]
+#![feature(collections)]
+#![feature(debug_builders)]
+#![feature(unique)]
+#![feature(step_by)]
+#![feature(slice_patterns)]
 #![allow(deprecated)] // rand
 
 extern crate core;
@@ -24,7 +39,6 @@ mod atomic;
 mod cell;
 mod char;
 mod cmp;
-mod finally;
 mod fmt;
 mod hash;
 mod iter;
index 5aeb330b78b54023ac388d83d22f5eeff636b319..5bc08376d257c5ceff5a7e2b1a722bbcdbc15d45 100644 (file)
@@ -21,15 +21,15 @@ fn size_of_basic() {
 #[test]
 #[cfg(target_pointer_width = "32")]
 fn size_of_32() {
-    assert_eq!(size_of::<uint>(), 4);
-    assert_eq!(size_of::<*const uint>(), 4);
+    assert_eq!(size_of::<usize>(), 4);
+    assert_eq!(size_of::<*const usize>(), 4);
 }
 
 #[test]
 #[cfg(target_pointer_width = "64")]
 fn size_of_64() {
-    assert_eq!(size_of::<uint>(), 8);
-    assert_eq!(size_of::<*const uint>(), 8);
+    assert_eq!(size_of::<usize>(), 8);
+    assert_eq!(size_of::<*const usize>(), 8);
 }
 
 #[test]
@@ -50,15 +50,15 @@ fn align_of_basic() {
 #[test]
 #[cfg(target_pointer_width = "32")]
 fn align_of_32() {
-    assert_eq!(align_of::<uint>(), 4);
-    assert_eq!(align_of::<*const uint>(), 4);
+    assert_eq!(align_of::<usize>(), 4);
+    assert_eq!(align_of::<*const usize>(), 4);
 }
 
 #[test]
 #[cfg(target_pointer_width = "64")]
 fn align_of_64() {
-    assert_eq!(align_of::<uint>(), 8);
-    assert_eq!(align_of::<*const uint>(), 8);
+    assert_eq!(align_of::<usize>(), 8);
+    assert_eq!(align_of::<*const usize>(), 8);
 }
 
 #[test]
@@ -93,17 +93,17 @@ fn test_transmute_copy() {
 #[test]
 fn test_transmute() {
     trait Foo { fn dummy(&self) { } }
-    impl Foo for int {}
+    impl Foo for isize {}
 
-    let a = box 100 as Box<Foo>;
+    let a = box 100isize as Box<Foo>;
     unsafe {
         let x: ::core::raw::TraitObject = transmute(a);
-        assert!(*(x.data as *const int) == 100);
+        assert!(*(x.data as *const isize) == 100);
         let _x: Box<Foo> = transmute(x);
     }
 
     unsafe {
-        assert!(vec![76u8] == transmute::<_, Vec<u8>>("L".to_string()));
+        assert_eq!(transmute::<_, Vec<u8>>("L".to_string()), [76]);
     }
 }
 
@@ -112,15 +112,15 @@ fn test_transmute() {
 // Static/dynamic method dispatch
 
 struct Struct {
-    field: int
+    field: isize
 }
 
 trait Trait {
-    fn method(&self) -> int;
+    fn method(&self) -> isize;
 }
 
 impl Trait for Struct {
-    fn method(&self) -> int {
+    fn method(&self) -> isize {
         self.field
     }
 }
index be4c83d23e8b33796600da56907aa81a3a7a5a11..7a367ddeec8d4599ec8543a712306059061edd91 100644 (file)
@@ -43,7 +43,7 @@ fn test_match_on_nonzero_option() {
 
 #[test]
 fn test_match_option_empty_vec() {
-    let a: Option<Vec<int>> = Some(vec![]);
+    let a: Option<Vec<isize>> = Some(vec![]);
     match a {
         None => panic!("unexpected None while matching on Some(vec![])"),
         _ => {}
@@ -54,7 +54,7 @@ fn test_match_option_empty_vec() {
 fn test_match_option_vec() {
     let a = Some(vec![1, 2, 3, 4]);
     match a {
-        Some(v) => assert_eq!(v, vec![1, 2, 3, 4]),
+        Some(v) => assert_eq!(v, [1, 2, 3, 4]),
         None => panic!("unexpected None while matching on Some(vec![1, 2, 3, 4])")
     }
 }
diff --git a/src/libcoretest/num/int.rs b/src/libcoretest/num/int.rs
deleted file mode 100644 (file)
index be8dfd0..0000000
+++ /dev/null
@@ -1,11 +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.
-
-int_module!(int, int);
index f5657d939b2afccb1258032a88a37251f1809316..fa41167cae8a6dda7742850facc156fa30f3e26d 100644 (file)
@@ -12,7 +12,7 @@ macro_rules! int_module { ($T:ty, $T_i:ident) => (
 #[cfg(test)]
 mod tests {
     use core::$T_i::*;
-    use core::int;
+    use core::isize;
     use core::num::{FromStrRadix, Int, SignedInt};
     use core::ops::{Shl, Shr, Not, BitXor, BitAnd, BitOr};
     use num;
@@ -70,12 +70,12 @@ mod tests {
         assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
     }
 
-    static A: $T = 0b0101100;
-    static B: $T = 0b0100001;
-    static C: $T = 0b1111001;
+    const A: $T = 0b0101100;
+    const B: $T = 0b0100001;
+    const C: $T = 0b1111001;
 
-    static _0: $T = 0;
-    static _1: $T = !0;
+    const _0: $T = 0;
+    const _1: $T = !0;
 
     #[test]
     fn test_count_ones() {
@@ -153,7 +153,7 @@ mod tests {
     fn test_signed_checked_div() {
         assert!(10.checked_div(2) == Some(5));
         assert!(5.checked_div(0) == None);
-        assert!(int::MIN.checked_div(-1) == None);
+        assert!(isize::MIN.checked_div(-1) == None);
     }
 
     #[test]
@@ -201,6 +201,17 @@ mod tests {
         assert_eq!(FromStrRadix::from_str_radix("Z", 35).ok(), None::<$T>);
         assert_eq!(FromStrRadix::from_str_radix("-9", 2).ok(), None::<$T>);
     }
+
+    #[test]
+    fn test_pow() {
+        let mut r = 2 as $T;
+
+        assert_eq!(r.pow(2u32), 4 as $T);
+        assert_eq!(r.pow(0u32), 1 as $T);
+        r = -2 as $T;
+        assert_eq!(r.pow(2u32), 4 as $T);
+        assert_eq!(r.pow(3u32), -8 as $T);
+    }
 }
 
 )}
index 2c6efc0040fae82bb3adb7247ae9506e7ed6b972..9087b87f640cb77519b19df956e97e8f0cc285ea 100644 (file)
@@ -21,7 +21,6 @@ mod i8;
 mod i16;
 mod i32;
 mod i64;
-mod int;
 
 #[macro_use]
 mod uint_macros;
@@ -30,7 +29,6 @@ mod u8;
 mod u16;
 mod u32;
 mod u64;
-mod uint;
 
 /// Helper function for testing numeric operations
 pub fn test_num<T>(ten: T, two: T) where
@@ -90,36 +88,41 @@ mod test {
 
     #[test]
     fn test_int_from_str_overflow() {
-        let mut i8_val: i8 = 127_i8;
+        let mut i8_val: i8 = 127;
         assert_eq!("127".parse::<i8>().ok(), Some(i8_val));
         assert_eq!("128".parse::<i8>().ok(), None);
 
-        i8_val += 1 as i8;
+        i8_val = i8_val.wrapping_add(1);
         assert_eq!("-128".parse::<i8>().ok(), Some(i8_val));
         assert_eq!("-129".parse::<i8>().ok(), None);
 
-        let mut i16_val: i16 = 32_767_i16;
+        let mut i16_val: i16 = 32_767;
         assert_eq!("32767".parse::<i16>().ok(), Some(i16_val));
         assert_eq!("32768".parse::<i16>().ok(), None);
 
-        i16_val += 1 as i16;
+        i16_val = i16_val.wrapping_add(1);
         assert_eq!("-32768".parse::<i16>().ok(), Some(i16_val));
         assert_eq!("-32769".parse::<i16>().ok(), None);
 
-        let mut i32_val: i32 = 2_147_483_647_i32;
+        let mut i32_val: i32 = 2_147_483_647;
         assert_eq!("2147483647".parse::<i32>().ok(), Some(i32_val));
         assert_eq!("2147483648".parse::<i32>().ok(), None);
 
-        i32_val += 1 as i32;
+        i32_val = i32_val.wrapping_add(1);
         assert_eq!("-2147483648".parse::<i32>().ok(), Some(i32_val));
         assert_eq!("-2147483649".parse::<i32>().ok(), None);
 
-        let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
+        let mut i64_val: i64 = 9_223_372_036_854_775_807;
         assert_eq!("9223372036854775807".parse::<i64>().ok(), Some(i64_val));
         assert_eq!("9223372036854775808".parse::<i64>().ok(), None);
 
-        i64_val += 1 as i64;
+        i64_val = i64_val.wrapping_add(1);
         assert_eq!("-9223372036854775808".parse::<i64>().ok(), Some(i64_val));
         assert_eq!("-9223372036854775809".parse::<i64>().ok(), None);
     }
+
+    #[test]
+    fn test_int_from_minus_sign() {
+        assert_eq!("-".parse::<i32>().ok(), None);
+    }
 }
diff --git a/src/libcoretest/num/uint.rs b/src/libcoretest/num/uint.rs
deleted file mode 100644 (file)
index 395e55c..0000000
+++ /dev/null
@@ -1,11 +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.
-
-uint_module!(uint, uint);
index 5c6efc857f1f98fb5d6433543bc0f54124b90994..e3eff6e7512ecf6d3c08167ac809fd5e49ea6552 100644 (file)
@@ -20,7 +20,7 @@ mod tests {
     fn test_overflows() {
         assert!(MAX > 0);
         assert!(MIN <= 0);
-        assert!(MIN + MAX + 1 == 0);
+        assert!((MIN + MAX).wrapping_add(1) == 0);
     }
 
     #[test]
@@ -38,12 +38,12 @@ mod tests {
         assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
     }
 
-    static A: $T = 0b0101100;
-    static B: $T = 0b0100001;
-    static C: $T = 0b1111001;
+    const A: $T = 0b0101100;
+    const B: $T = 0b0100001;
+    const C: $T = 0b1111001;
 
-    static _0: $T = 0;
-    static _1: $T = !0;
+    const _0: $T = 0;
+    const _1: $T = !0;
 
     #[test]
     fn test_count_ones() {
index 0183e6a93cfd07272aab962f2458719f77279b0b..33674a3abd870271fa26c15453367bbfa5ee24df 100644 (file)
@@ -14,7 +14,7 @@ use core::ops::{Range, RangeFull, RangeFrom, RangeTo};
 // Overhead of dtors
 
 struct HasDtor {
-    _x: int
+    _x: isize
 }
 
 impl Drop for HasDtor {
index 860bd40e21eeed7dcda76a520887bd87e4e14818..569142c0d7dc9609d0e1f04d7b837c6fb3bf9458 100644 (file)
@@ -16,11 +16,11 @@ use core::clone::Clone;
 #[test]
 fn test_get_ptr() {
     unsafe {
-        let x = box 0;
-        let addr_x: *const int = mem::transmute(&*x);
+        let x: Box<_> = box 0;
+        let addr_x: *const isize = mem::transmute(&*x);
         let opt = Some(x);
         let y = opt.unwrap();
-        let addr_y: *const int = mem::transmute(&*y);
+        let addr_y: *const isize = mem::transmute(&*y);
         assert_eq!(addr_x, addr_y);
     }
 }
@@ -41,7 +41,7 @@ fn test_get_resource() {
     use core::cell::RefCell;
 
     struct R {
-       i: Rc<RefCell<int>>,
+       i: Rc<RefCell<isize>>,
     }
 
     #[unsafe_destructor]
@@ -53,7 +53,7 @@ fn test_get_resource() {
         }
     }
 
-    fn r(i: Rc<RefCell<int>>) -> R {
+    fn r(i: Rc<RefCell<isize>>) -> R {
         R {
             i: i
         }
@@ -80,7 +80,7 @@ fn test_option_dance() {
     assert!(y.is_none());
 }
 
-#[test] #[should_fail]
+#[test] #[should_panic]
 fn test_option_too_much_dance() {
     let mut y = Some(marker::NoCopy);
     let _y2 = y.take().unwrap();
@@ -89,44 +89,44 @@ fn test_option_too_much_dance() {
 
 #[test]
 fn test_and() {
-    let x: Option<int> = Some(1);
+    let x: Option<isize> = Some(1);
     assert_eq!(x.and(Some(2)), Some(2));
-    assert_eq!(x.and(None::<int>), None);
+    assert_eq!(x.and(None::<isize>), None);
 
-    let x: Option<int> = None;
+    let x: Option<isize> = None;
     assert_eq!(x.and(Some(2)), None);
-    assert_eq!(x.and(None::<int>), None);
+    assert_eq!(x.and(None::<isize>), None);
 }
 
 #[test]
 fn test_and_then() {
-    let x: Option<int> = Some(1);
+    let x: Option<isize> = Some(1);
     assert_eq!(x.and_then(|x| Some(x + 1)), Some(2));
-    assert_eq!(x.and_then(|_| None::<int>), None);
+    assert_eq!(x.and_then(|_| None::<isize>), None);
 
-    let x: Option<int> = None;
+    let x: Option<isize> = None;
     assert_eq!(x.and_then(|x| Some(x + 1)), None);
-    assert_eq!(x.and_then(|_| None::<int>), None);
+    assert_eq!(x.and_then(|_| None::<isize>), None);
 }
 
 #[test]
 fn test_or() {
-    let x: Option<int> = Some(1);
+    let x: Option<isize> = Some(1);
     assert_eq!(x.or(Some(2)), Some(1));
     assert_eq!(x.or(None), Some(1));
 
-    let x: Option<int> = None;
+    let x: Option<isize> = None;
     assert_eq!(x.or(Some(2)), Some(2));
     assert_eq!(x.or(None), None);
 }
 
 #[test]
 fn test_or_else() {
-    let x: Option<int> = Some(1);
+    let x: Option<isize> = Some(1);
     assert_eq!(x.or_else(|| Some(2)), Some(1));
     assert_eq!(x.or_else(|| None), Some(1));
 
-    let x: Option<int> = None;
+    let x: Option<isize> = None;
     assert_eq!(x.or_else(|| Some(2)), Some(2));
     assert_eq!(x.or_else(|| None), None);
 }
@@ -139,14 +139,14 @@ fn test_unwrap() {
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn test_unwrap_panic1() {
-    let x: Option<int> = None;
+    let x: Option<isize> = None;
     x.unwrap();
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 fn test_unwrap_panic2() {
     let x: Option<String> = None;
     x.unwrap();
@@ -154,19 +154,19 @@ fn test_unwrap_panic2() {
 
 #[test]
 fn test_unwrap_or() {
-    let x: Option<int> = Some(1);
+    let x: Option<isize> = Some(1);
     assert_eq!(x.unwrap_or(2), 1);
 
-    let x: Option<int> = None;
+    let x: Option<isize> = None;
     assert_eq!(x.unwrap_or(2), 2);
 }
 
 #[test]
 fn test_unwrap_or_else() {
-    let x: Option<int> = Some(1);
+    let x: Option<isize> = Some(1);
     assert_eq!(x.unwrap_or_else(|| 2), 1);
 
-    let x: Option<int> = None;
+    let x: Option<isize> = None;
     assert_eq!(x.unwrap_or_else(|| 2), 2);
 }
 
@@ -223,13 +223,13 @@ fn test_ord() {
 /* FIXME(#20575)
 #[test]
 fn test_collect() {
-    let v: Option<Vec<int>> = (0..0).map(|_| Some(0)).collect();
+    let v: Option<Vec<isize>> = (0..0).map(|_| Some(0)).collect();
     assert!(v == Some(vec![]));
 
-    let v: Option<Vec<int>> = (0..3).map(|x| Some(x)).collect();
+    let v: Option<Vec<isize>> = (0..3).map(|x| Some(x)).collect();
     assert!(v == Some(vec![0, 1, 2]));
 
-    let v: Option<Vec<int>> = (0..3).map(|x| {
+    let v: Option<Vec<isize>> = (0..3).map(|x| {
         if x > 1 { None } else { Some(x) }
     }).collect();
     assert!(v == None);
@@ -258,9 +258,6 @@ fn test_cloned() {
     assert_eq!(opt_none.clone(), None);
     assert_eq!(opt_none.cloned(), None);
 
-    // Mutable refs work
-    assert_eq!(opt_mut_ref.cloned(), Some(2u32));
-
     // Immutable ref works
     assert_eq!(opt_ref.clone(), Some(&val1));
     assert_eq!(opt_ref.cloned(), Some(1u32));
index 57456bfb1a79ba04ce4b68c77999d37c2b507a90..8f1017c50a39d318b76152ffd7913294cae344d2 100644 (file)
@@ -16,12 +16,12 @@ use std::iter::repeat;
 fn test() {
     unsafe {
         struct Pair {
-            fst: int,
-            snd: int
+            fst: isize,
+            snd: isize
         };
         let mut p = Pair {fst: 10, snd: 20};
         let pptr: *mut Pair = &mut p;
-        let iptr: *mut int = mem::transmute(pptr);
+        let iptr: *mut isize = mem::transmute(pptr);
         assert_eq!(*iptr, 10);
         *iptr = 30;
         assert_eq!(*iptr, 30);
@@ -35,18 +35,15 @@ fn test() {
         let v0 = vec![32000u16, 32001u16, 32002u16];
         let mut v1 = vec![0u16, 0u16, 0u16];
 
-        copy_memory(v1.as_mut_ptr().offset(1),
-                    v0.as_ptr().offset(1), 1);
+        copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
         assert!((v1[0] == 0u16 &&
                  v1[1] == 32001u16 &&
                  v1[2] == 0u16));
-        copy_memory(v1.as_mut_ptr(),
-                    v0.as_ptr().offset(2), 1);
+        copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
         assert!((v1[0] == 32002u16 &&
                  v1[1] == 32001u16 &&
                  v1[2] == 0u16));
-        copy_memory(v1.as_mut_ptr().offset(2),
-                    v0.as_ptr(), 1);
+        copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
         assert!((v1[0] == 32002u16 &&
                  v1[1] == 32001u16 &&
                  v1[2] == 32000u16));
@@ -55,13 +52,13 @@ fn test() {
 
 #[test]
 fn test_is_null() {
-    let p: *const int = null();
+    let p: *const isize = null();
     assert!(p.is_null());
 
     let q = unsafe { p.offset(1) };
     assert!(!q.is_null());
 
-    let mp: *mut int = null_mut();
+    let mp: *mut isize = null_mut();
     assert!(mp.is_null());
 
     let mq = unsafe { mp.offset(1) };
@@ -71,22 +68,22 @@ fn test_is_null() {
 #[test]
 fn test_as_ref() {
     unsafe {
-        let p: *const int = null();
+        let p: *const isize = null();
         assert_eq!(p.as_ref(), None);
 
-        let q: *const int = &2;
+        let q: *const isize = &2;
         assert_eq!(q.as_ref().unwrap(), &2);
 
-        let p: *mut int = null_mut();
+        let p: *mut isize = null_mut();
         assert_eq!(p.as_ref(), None);
 
-        let q: *mut int = &mut 2;
+        let q: *mut isize = &mut 2;
         assert_eq!(q.as_ref().unwrap(), &2);
 
         // Lifetime inference
-        let u = 2;
+        let u = 2isize;
         {
-            let p: *const int = &u as *const _;
+            let p = &u as *const isize;
             assert_eq!(p.as_ref().unwrap(), &2);
         }
     }
@@ -95,16 +92,16 @@ fn test_as_ref() {
 #[test]
 fn test_as_mut() {
     unsafe {
-        let p: *mut int = null_mut();
+        let p: *mut isize = null_mut();
         assert!(p.as_mut() == None);
 
-        let q: *mut int = &mut 2;
+        let q: *mut isize = &mut 2;
         assert!(q.as_mut().unwrap() == &mut 2);
 
         // Lifetime inference
-        let mut u = 2;
+        let mut u = 2isize;
         {
-            let p: *mut int = &mut u as *mut _;
+            let p = &mut u as *mut isize;
             assert!(p.as_mut().unwrap() == &mut 2);
         }
     }
@@ -139,12 +136,12 @@ fn test_ptr_addition() {
 fn test_ptr_subtraction() {
     unsafe {
         let xs = vec![0,1,2,3,4,5,6,7,8,9];
-        let mut idx = 9i8;
+        let mut idx = 9;
         let ptr = xs.as_ptr();
 
-        while idx >= 0i8 {
-            assert_eq!(*(ptr.offset(idx as int)), idx as int);
-            idx = idx - 1i8;
+        while idx >= 0 {
+            assert_eq!(*(ptr.offset(idx as isize)), idx as isize);
+            idx = idx - 1;
         }
 
         let mut xs_mut = xs;
@@ -156,7 +153,7 @@ fn test_ptr_subtraction() {
             m_ptr = m_ptr.offset(-1);
         }
 
-        assert!(xs_mut == vec![0,2,4,6,8,10,12,14,16,18]);
+        assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]);
     }
 }
 
@@ -164,15 +161,15 @@ fn test_ptr_subtraction() {
 fn test_set_memory() {
     let mut xs = [0u8; 20];
     let ptr = xs.as_mut_ptr();
-    unsafe { set_memory(ptr, 5u8, xs.len()); }
+    unsafe { write_bytes(ptr, 5u8, xs.len()); }
     assert!(xs == [5u8; 20]);
 }
 
 #[test]
 fn test_unsized_unique() {
-    let xs: &mut [_] = &mut [1, 2, 3];
-    let ptr = unsafe { Unique::new(xs as *mut [_]) };
+    let xs: &mut [i32] = &mut [1, 2, 3];
+    let ptr = unsafe { Unique::new(xs as *mut [i32]) };
     let ys = unsafe { &mut **ptr };
-    let zs: &mut [_] = &mut [1, 2, 3];
+    let zs: &mut [i32] = &mut [1, 2, 3];
     assert!(ys == zs);
 }
index ab7b5101e726a59f652cad6367e09f8b6c151056..ac8c2b953ae965d185873e429c84a5f547f93e29 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn op1() -> Result<int, &'static str> { Ok(666) }
-pub fn op2() -> Result<int, &'static str> { Err("sadface") }
+pub fn op1() -> Result<isize, &'static str> { Ok(666) }
+pub fn op2() -> Result<isize, &'static str> { Err("sadface") }
 
 #[test]
 pub fn test_and() {
@@ -24,74 +24,74 @@ pub fn test_and() {
 
 #[test]
 pub fn test_and_then() {
-    assert_eq!(op1().and_then(|i| Ok::<int, &'static str>(i + 1)).unwrap(), 667);
-    assert_eq!(op1().and_then(|_| Err::<int, &'static str>("bad")).unwrap_err(),
+    assert_eq!(op1().and_then(|i| Ok::<isize, &'static str>(i + 1)).unwrap(), 667);
+    assert_eq!(op1().and_then(|_| Err::<isize, &'static str>("bad")).unwrap_err(),
                "bad");
 
-    assert_eq!(op2().and_then(|i| Ok::<int, &'static str>(i + 1)).unwrap_err(),
+    assert_eq!(op2().and_then(|i| Ok::<isize, &'static str>(i + 1)).unwrap_err(),
                "sadface");
-    assert_eq!(op2().and_then(|_| Err::<int, &'static str>("bad")).unwrap_err(),
+    assert_eq!(op2().and_then(|_| Err::<isize, &'static str>("bad")).unwrap_err(),
                "sadface");
 }
 
 #[test]
 pub fn test_or() {
-    assert_eq!(op1().or(Ok(667)).unwrap(), 666);
+    assert_eq!(op1().or(Ok::<_, &'static str>(667)).unwrap(), 666);
     assert_eq!(op1().or(Err("bad")).unwrap(), 666);
 
-    assert_eq!(op2().or(Ok(667)).unwrap(), 667);
+    assert_eq!(op2().or(Ok::<_, &'static str>(667)).unwrap(), 667);
     assert_eq!(op2().or(Err("bad")).unwrap_err(), "bad");
 }
 
 #[test]
 pub fn test_or_else() {
-    assert_eq!(op1().or_else(|_| Ok::<int, &'static str>(667)).unwrap(), 666);
-    assert_eq!(op1().or_else(|e| Err::<int, &'static str>(e)).unwrap(), 666);
+    assert_eq!(op1().or_else(|_| Ok::<isize, &'static str>(667)).unwrap(), 666);
+    assert_eq!(op1().or_else(|e| Err::<isize, &'static str>(e)).unwrap(), 666);
 
-    assert_eq!(op2().or_else(|_| Ok::<int, &'static str>(667)).unwrap(), 667);
-    assert_eq!(op2().or_else(|e| Err::<int, &'static str>(e)).unwrap_err(),
+    assert_eq!(op2().or_else(|_| Ok::<isize, &'static str>(667)).unwrap(), 667);
+    assert_eq!(op2().or_else(|e| Err::<isize, &'static str>(e)).unwrap_err(),
                "sadface");
 }
 
 #[test]
 pub fn test_impl_map() {
-    assert!(Ok::<int, int>(1).map(|x| x + 1) == Ok(2));
-    assert!(Err::<int, int>(1).map(|x| x + 1) == Err(1));
+    assert!(Ok::<isize, isize>(1).map(|x| x + 1) == Ok(2));
+    assert!(Err::<isize, isize>(1).map(|x| x + 1) == Err(1));
 }
 
 #[test]
 pub fn test_impl_map_err() {
-    assert!(Ok::<int, int>(1).map_err(|x| x + 1) == Ok(1));
-    assert!(Err::<int, int>(1).map_err(|x| x + 1) == Err(2));
+    assert!(Ok::<isize, isize>(1).map_err(|x| x + 1) == Ok(1));
+    assert!(Err::<isize, isize>(1).map_err(|x| x + 1) == Err(2));
 }
 
 /* FIXME(#20575)
 #[test]
 fn test_collect() {
-    let v: Result<Vec<int>, ()> = (0..0).map(|_| Ok::<int, ()>(0)).collect();
+    let v: Result<Vec<isize>, ()> = (0..0).map(|_| Ok::<isize, ()>(0)).collect();
     assert!(v == Ok(vec![]));
 
-    let v: Result<Vec<int>, ()> = (0..3).map(|x| Ok::<int, ()>(x)).collect();
+    let v: Result<Vec<isize>, ()> = (0..3).map(|x| Ok::<isize, ()>(x)).collect();
     assert!(v == Ok(vec![0, 1, 2]));
 
-    let v: Result<Vec<int>, int> = (0..3).map(|x| {
+    let v: Result<Vec<isize>, isize> = (0..3).map(|x| {
         if x > 1 { Err(x) } else { Ok(x) }
     }).collect();
     assert!(v == Err(2));
 
     // test that it does not take more elements than it needs
-    let mut functions: [Box<Fn() -> Result<(), int>>; 3] =
+    let mut functions: [Box<Fn() -> Result<(), isize>>; 3] =
         [box || Ok(()), box || Err(1), box || panic!()];
 
-    let v: Result<Vec<()>, int> = functions.iter_mut().map(|f| (*f)()).collect();
+    let v: Result<Vec<()>, isize> = functions.iter_mut().map(|f| (*f)()).collect();
     assert!(v == Err(1));
 }
 */
 
 #[test]
 pub fn test_fmt_default() {
-    let ok: Result<int, &'static str> = Ok(100);
-    let err: Result<int, &'static str> = Err("Err");
+    let ok: Result<isize, &'static str> = Ok(100);
+    let err: Result<isize, &'static str> = Err("Err");
 
     let s = format!("{:?}", ok);
     assert_eq!(s, "Ok(100)");
@@ -101,8 +101,8 @@ pub fn test_fmt_default() {
 
 #[test]
 pub fn test_unwrap_or() {
-    let ok: Result<int, &'static str> = Ok(100);
-    let ok_err: Result<int, &'static str> = Err("Err");
+    let ok: Result<isize, &'static str> = Ok(100);
+    let ok_err: Result<isize, &'static str> = Err("Err");
 
     assert_eq!(ok.unwrap_or(50), 100);
     assert_eq!(ok_err.unwrap_or(50), 50);
@@ -110,7 +110,7 @@ pub fn test_unwrap_or() {
 
 #[test]
 pub fn test_unwrap_or_else() {
-    fn handler(msg: &'static str) -> int {
+    fn handler(msg: &'static str) -> isize {
         if msg == "I got this." {
             50
         } else {
@@ -118,17 +118,17 @@ pub fn test_unwrap_or_else() {
         }
     }
 
-    let ok: Result<int, &'static str> = Ok(100);
-    let ok_err: Result<int, &'static str> = Err("I got this.");
+    let ok: Result<isize, &'static str> = Ok(100);
+    let ok_err: Result<isize, &'static str> = Err("I got this.");
 
     assert_eq!(ok.unwrap_or_else(handler), 100);
     assert_eq!(ok_err.unwrap_or_else(handler), 50);
 }
 
 #[test]
-#[should_fail]
+#[should_panic]
 pub fn test_unwrap_or_else_panic() {
-    fn handler(msg: &'static str) -> int {
+    fn handler(msg: &'static str) -> isize {
         if msg == "I got this." {
             50
         } else {
@@ -136,6 +136,6 @@ pub fn test_unwrap_or_else_panic() {
         }
     }
 
-    let bad_err: Result<int, &'static str> = Err("Unrecoverable mess.");
-    let _ : int = bad_err.unwrap_or_else(handler);
+    let bad_err: Result<isize, &'static str> = Err("Unrecoverable mess.");
+    let _ : isize = bad_err.unwrap_or_else(handler);
 }
index 46c7730cc6470aeb852892cb2f1cf3f31506dcb3..fe73b3b44079503544c6dead2a334b86f0877f99 100644 (file)
@@ -59,16 +59,16 @@ fn iterator_to_slice() {
                 let mut iter = data.iter_mut();
                 assert_eq!(&iter[..], &other_data[..]);
                 // mutability:
-                assert!(&mut iter[] == other_data);
+                assert!(&mut iter[..] == other_data);
 
                 iter.next();
                 assert_eq!(&iter[..], &other_data[1..]);
-                assert!(&mut iter[] == &mut other_data[1..]);
+                assert!(&mut iter[..] == &mut other_data[1..]);
 
                 iter.next_back();
 
                 assert_eq!(&iter[..], &other_data[1..2]);
-                assert!(&mut iter[] == &mut other_data[1..2]);
+                assert!(&mut iter[..] == &mut other_data[1..2]);
 
                 let s = iter.into_slice();
                 assert!(s == &mut other_data[1..2]);
index 375564c39bb5b1846f5a4d0f7fd27310ead2cb07..5fce527d9798df979a3183c2d3a433f191d05234 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,6 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[test]
+fn test_pattern_deref_forward() {
+    let data = "aabcdaa";
+    assert!(data.contains("bcd"));
+    assert!(data.contains(&"bcd"));
+    assert!(data.contains(&"bcd".to_string()));
+}
+
+#[test]
+fn test_empty_match_indices() {
+    let data = "aä中!";
+    let vec: Vec<_> = data.match_indices("").collect();
+    assert_eq!(vec, [(0, 0), (1, 1), (3, 3), (6, 6), (7, 7)]);
+}
+
 #[test]
 fn test_bool_from_str() {
     assert_eq!("true".parse().ok(), Some(true));
@@ -18,7 +33,7 @@ fn test_bool_from_str() {
 fn check_contains_all_substrings(s: &str) {
     assert!(s.contains(""));
     for i in 0..s.len() {
-        for j in range(i+1, s.len() + 1) {
+        for j in i+1..s.len() + 1 {
             assert!(s.contains(&s[i..j]));
         }
     }
@@ -50,22 +65,22 @@ fn test_strslice_contains() {
 fn test_rsplitn_char_iterator() {
     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-    let mut split: Vec<&str> = data.rsplitn(3, ' ').collect();
+    let mut split: Vec<&str> = data.rsplitn(4, ' ').collect();
     split.reverse();
-    assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
+    assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
 
-    let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == ' ').collect();
+    let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect();
     split.reverse();
-    assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
+    assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
 
     // Unicode
-    let mut split: Vec<&str> = data.rsplitn(3, 'ä').collect();
+    let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect();
     split.reverse();
-    assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
+    assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
 
-    let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == 'ä').collect();
+    let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect();
     split.reverse();
-    assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
+    assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
 }
 
 #[test]
@@ -73,33 +88,33 @@ fn test_split_char_iterator() {
     let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
     let split: Vec<&str> = data.split(' ').collect();
-    assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+    assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
     let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
     rsplit.reverse();
-    assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+    assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
     let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
-    assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+    assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
     let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
     rsplit.reverse();
-    assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+    assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
     // Unicode
     let split: Vec<&str> = data.split('ä').collect();
-    assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+    assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 
     let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
     rsplit.reverse();
-    assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+    assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 
     let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
-    assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+    assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 
     let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
     rsplit.reverse();
-    assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+    assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 }
 
 #[test]
@@ -108,16 +123,263 @@ fn test_rev_split_char_iterator_no_trailing() {
 
     let mut split: Vec<&str> = data.split('\n').rev().collect();
     split.reverse();
-    assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]);
+    assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
 
     let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
     split.reverse();
-    assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]);
+    assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
 }
 
 #[test]
 fn test_utf16_code_units() {
     use unicode::str::Utf16Encoder;
     assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
-               vec![0xE9, 0xD83D, 0xDCA9])
+               [0xE9, 0xD83D, 0xDCA9])
+}
+
+#[test]
+fn starts_with_in_unicode() {
+    assert!(!"├── Cargo.toml".starts_with("# "));
+}
+
+#[test]
+fn starts_short_long() {
+    assert!(!"".starts_with("##"));
+    assert!(!"##".starts_with("####"));
+    assert!("####".starts_with("##"));
+    assert!(!"##ä".starts_with("####"));
+    assert!("####ä".starts_with("##"));
+    assert!(!"##".starts_with("####ä"));
+    assert!("##ä##".starts_with("##ä"));
+
+    assert!("".starts_with(""));
+    assert!("ä".starts_with(""));
+    assert!("#ä".starts_with(""));
+    assert!("##ä".starts_with(""));
+    assert!("ä###".starts_with(""));
+    assert!("#ä##".starts_with(""));
+    assert!("##ä#".starts_with(""));
+}
+
+#[test]
+fn contains_weird_cases() {
+    assert!("* \t".contains(' '));
+    assert!(!"* \t".contains('?'));
+    assert!(!"* \t".contains('\u{1F4A9}'));
+}
+
+#[test]
+fn trim_ws() {
+    assert_eq!(" \t  a \t  ".trim_left_matches(|c: char| c.is_whitespace()),
+                    "a \t  ");
+    assert_eq!(" \t  a \t  ".trim_right_matches(|c: char| c.is_whitespace()),
+               " \t  a");
+    assert_eq!(" \t  a \t  ".trim_matches(|c: char| c.is_whitespace()),
+                    "a");
+    assert_eq!(" \t   \t  ".trim_left_matches(|c: char| c.is_whitespace()),
+                         "");
+    assert_eq!(" \t   \t  ".trim_right_matches(|c: char| c.is_whitespace()),
+               "");
+    assert_eq!(" \t   \t  ".trim_matches(|c: char| c.is_whitespace()),
+               "");
+}
+
+mod pattern {
+    use std::str::Pattern;
+    use std::str::{Searcher, ReverseSearcher};
+    use std::str::SearchStep::{self, Match, Reject, Done};
+
+    macro_rules! make_test {
+        ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
+            mod $name {
+                use std::str::SearchStep::{Match, Reject};
+                use super::{cmp_search_to_vec};
+                #[test]
+                fn fwd() {
+                    cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
+                }
+                #[test]
+                fn bwd() {
+                    cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
+                }
+            }
+        }
+    }
+
+    fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
+                                             right: Vec<SearchStep>)
+    where P::Searcher: ReverseSearcher<'a>
+    {
+        let mut searcher = pat.into_searcher(haystack);
+        let mut v = vec![];
+        loop {
+            match if !rev {searcher.next()} else {searcher.next_back()} {
+                Match(a, b) => v.push(Match(a, b)),
+                Reject(a, b) => v.push(Reject(a, b)),
+                Done => break,
+            }
+        }
+        if rev {
+            v.reverse();
+        }
+        assert_eq!(v, right);
+    }
+
+    make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
+        Reject(0, 1),
+        Match (1, 3),
+        Reject(3, 4),
+        Match (4, 6),
+        Reject(6, 7),
+    ]);
+    make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
+        Match(0, 0),
+        Match(1, 1),
+        Match(2, 2),
+        Match(3, 3),
+        Match(4, 4),
+        Match(5, 5),
+        Match(6, 6),
+        Match(7, 7),
+    ]);
+    make_test!(str_searcher_mulibyte_haystack, " ", "├──", [
+        Reject(0, 3),
+        Reject(3, 6),
+        Reject(6, 9),
+    ]);
+    make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [
+        Match(0, 0),
+        Match(3, 3),
+        Match(6, 6),
+        Match(9, 9),
+    ]);
+    make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
+        Match(0, 0),
+    ]);
+    make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
+    ]);
+    make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
+        Reject(0, 1),
+        Match (1, 2),
+        Match (2, 3),
+        Reject(3, 4),
+        Match (4, 5),
+        Match (5, 6),
+        Reject(6, 7),
+    ]);
+    make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [
+        Reject(0, 3),
+        Reject(3, 6),
+        Reject(6, 9),
+    ]);
+    make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
+        Reject(0, 1),
+        Reject(1, 2),
+        Reject(2, 3),
+    ]);
+
+}
+
+mod bench {
+    macro_rules! make_test_inner {
+        ($s:ident, $code:expr, $name:ident, $str:expr) => {
+            #[bench]
+            fn $name(bencher: &mut Bencher) {
+                let mut $s = $str;
+                black_box(&mut $s);
+                bencher.iter(|| $code);
+            }
+        }
+    }
+
+    macro_rules! make_test {
+        ($name:ident, $s:ident, $code:expr) => {
+            mod $name {
+                use test::Bencher;
+                use test::black_box;
+
+                // Short strings: 65 bytes each
+                make_test_inner!($s, $code, short_ascii,
+                    "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!");
+                make_test_inner!($s, $code, short_mixed,
+                    "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!");
+                make_test_inner!($s, $code, short_pile_of_poo,
+                    "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!");
+                make_test_inner!($s, $code, long_lorem_ipsum,"\
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
+ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
+eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
+sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
+tempus vel, gravida nec quam.
+
+In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
+sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
+diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
+lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
+eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
+interdum. Curabitur ut nisi justo.
+
+Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
+mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
+lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
+est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
+felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
+ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
+feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
+Aliquam sit amet placerat lorem.
+
+Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
+mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
+Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
+lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
+suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
+cursus accumsan.
+
+Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
+feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
+vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
+leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
+malesuada sollicitudin quam eu fermentum!");
+            }
+        }
+    }
+
+    make_test!(chars_count, s, s.chars().count());
+
+    make_test!(contains_bang_str, s, s.contains("!"));
+    make_test!(contains_bang_char, s, s.contains('!'));
+
+    make_test!(match_indices_a_str, s, s.match_indices("a").count());
+
+    make_test!(split_a_str, s, s.split("a").count());
+
+    make_test!(trim_ascii_char, s, {
+        use std::ascii::AsciiExt;
+        s.trim_matches(|c: char| c.is_ascii())
+    });
+    make_test!(trim_left_ascii_char, s, {
+        use std::ascii::AsciiExt;
+        s.trim_left_matches(|c: char| c.is_ascii())
+    });
+    make_test!(trim_right_ascii_char, s, {
+        use std::ascii::AsciiExt;
+        s.trim_right_matches(|c: char| c.is_ascii())
+    });
+
+    make_test!(find_underscore_char, s, s.find('_'));
+    make_test!(rfind_underscore_char, s, s.rfind('_'));
+    make_test!(find_underscore_str, s, s.find("_"));
+
+    make_test!(find_zzz_char, s, s.find('\u{1F4A4}'));
+    make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}'));
+    make_test!(find_zzz_str, s, s.find("\u{1F4A4}"));
+
+    make_test!(split_space_char, s, s.split(' ').count());
+    make_test!(split_terminator_space_char, s, s.split_terminator(' ').count());
+
+    make_test!(splitn_space_char, s, s.splitn(10, ' ').count());
+    make_test!(rsplitn_space_char, s, s.rsplitn(10, ' ').count());
+
+    make_test!(split_space_str, s, s.split(" ").count());
+    make_test!(split_ad_str, s, s.split("ad").count());
 }
index 24660b3f396c105031903ceb43822ff6b690cb66..63d1fe968fe1b6a0a3aa4c53a0b78f287e1d1d1e 100644 (file)
@@ -14,6 +14,8 @@
 //! [def]: https://en.wikipedia.org/wiki/DEFLATE
 //! [mz]: https://code.google.com/p/miniz/
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "flate"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
-#![feature(core)]
-#![feature(int_uint)]
 #![feature(libc)]
 #![feature(staged_api)]
+#![feature(unique)]
+#![cfg_attr(test, feature(rustc_private, rand, collections))]
 
 #[cfg(test)] #[macro_use] extern crate log;
 
 extern crate libc;
 
 use libc::{c_void, size_t, c_int};
+use std::fmt;
 use std::ops::Deref;
 use std::ptr::Unique;
 use std::slice;
 
+#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub struct Error {
+    _unused: (),
+}
+
+impl Error {
+    fn new() -> Error {
+        Error {
+            _unused: (),
+        }
+    }
+}
+
+impl fmt::Debug for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        "decompression error".fmt(f)
+    }
+}
+
 pub struct Bytes {
     ptr: Unique<u8>,
-    len: uint,
+    len: usize,
 }
 
 impl Deref for Bytes {
@@ -72,59 +94,60 @@ extern {
                                     -> *mut c_void;
 }
 
-static LZ_NORM : c_int = 0x80;  // LZ with 128 probes, "normal"
-static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
-static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum
+const LZ_NORM: c_int = 0x80;  // LZ with 128 probes, "normal"
+const TINFL_FLAG_PARSE_ZLIB_HEADER: c_int = 0x1; // parse zlib header and adler32 checksum
+const TDEFL_WRITE_ZLIB_HEADER: c_int = 0x01000; // write zlib header and adler32 checksum
 
-fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
+fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Bytes {
     unsafe {
-        let mut outsz : size_t = 0;
+        let mut outsz: size_t = 0;
         let res = tdefl_compress_mem_to_heap(bytes.as_ptr() as *const _,
                                              bytes.len() as size_t,
                                              &mut outsz,
                                              flags);
-        if !res.is_null() {
-            let res = Unique::new(res as *mut u8);
-            Some(Bytes { ptr: res, len: outsz as uint })
-        } else {
-            None
+        assert!(!res.is_null());
+        Bytes {
+            ptr: Unique::new(res as *mut u8),
+            len: outsz as usize,
         }
     }
 }
 
 /// Compress a buffer, without writing any sort of header on the output.
-pub fn deflate_bytes(bytes: &[u8]) -> Option<Bytes> {
+pub fn deflate_bytes(bytes: &[u8]) -> Bytes {
     deflate_bytes_internal(bytes, LZ_NORM)
 }
 
 /// Compress a buffer, using a header that zlib can understand.
-pub fn deflate_bytes_zlib(bytes: &[u8]) -> Option<Bytes> {
+pub fn deflate_bytes_zlib(bytes: &[u8]) -> Bytes {
     deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
 }
 
-fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
+fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Result<Bytes,Error> {
     unsafe {
-        let mut outsz : size_t = 0;
+        let mut outsz: size_t = 0;
         let res = tinfl_decompress_mem_to_heap(bytes.as_ptr() as *const _,
                                                bytes.len() as size_t,
                                                &mut outsz,
                                                flags);
         if !res.is_null() {
-            let res = Unique::new(res as *mut u8);
-            Some(Bytes { ptr: res, len: outsz as uint })
+            Ok(Bytes {
+                ptr: Unique::new(res as *mut u8),
+                len: outsz as usize,
+            })
         } else {
-            None
+            Err(Error::new())
         }
     }
 }
 
 /// Decompress a buffer, without parsing any sort of header on the input.
-pub fn inflate_bytes(bytes: &[u8]) -> Option<Bytes> {
+pub fn inflate_bytes(bytes: &[u8]) -> Result<Bytes,Error> {
     inflate_bytes_internal(bytes, 0)
 }
 
 /// Decompress a buffer that starts with a zlib header.
-pub fn inflate_bytes_zlib(bytes: &[u8]) -> Option<Bytes> {
+pub fn inflate_bytes_zlib(bytes: &[u8]) -> Result<Bytes,Error> {
     inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
 }
 
@@ -138,7 +161,7 @@ mod tests {
     #[test]
     fn test_flate_round_trip() {
         let mut r = rand::thread_rng();
-        let mut words = vec!();
+        let mut words = vec![];
         for _ in 0..20 {
             let range = r.gen_range(1, 10);
             let v = r.gen_iter::<u8>().take(range).collect::<Vec<u8>>();
@@ -151,8 +174,8 @@ mod tests {
             }
             debug!("de/inflate of {} bytes of random word-sequences",
                    input.len());
-            let cmp = deflate_bytes(&input).expect("deflation failed");
-            let out = inflate_bytes(&cmp).expect("inflation failed");
+            let cmp = deflate_bytes(&input);
+            let out = inflate_bytes(&cmp).unwrap();
             debug!("{} bytes deflated to {} ({:.1}% size)",
                    input.len(), cmp.len(),
                    100.0 * ((cmp.len() as f64) / (input.len() as f64)));
@@ -162,9 +185,9 @@ mod tests {
 
     #[test]
     fn test_zlib_flate() {
-        let bytes = vec!(1, 2, 3, 4, 5);
-        let deflated = deflate_bytes(&bytes).expect("deflation failed");
-        let inflated = inflate_bytes(&deflated).expect("inflation failed");
+        let bytes = vec![1, 2, 3, 4, 5];
+        let deflated = deflate_bytes(&bytes);
+        let inflated = inflate_bytes(&deflated).unwrap();
         assert_eq!(&*inflated, &*bytes);
     }
 }
index be77622ac1db7c52335525cefd8753423177258f..4cf93ab2645df79a91a9087f9c77c6c9a997925c 100644 (file)
@@ -14,6 +14,8 @@
 //! Parsing does not happen at runtime: structures of `std::fmt::rt` are
 //! generated instead.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "fmt_macros"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
@@ -24,7 +26,6 @@
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
 
-#![feature(int_uint)]
 #![feature(staged_api)]
 #![feature(unicode)]
 
@@ -39,7 +40,7 @@ use std::string;
 
 /// A piece is a portion of the format string which represents the next part
 /// to emit. These are emitted as a stream by the `Parser` class.
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum Piece<'a> {
     /// A literal string which should directly be emitted
     String(&'a str),
@@ -49,7 +50,7 @@ pub enum Piece<'a> {
 }
 
 /// Representation of an argument specification.
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub struct Argument<'a> {
     /// Where to find this argument
     pub position: Position<'a>,
@@ -58,14 +59,14 @@ pub struct Argument<'a> {
 }
 
 /// Specification for the formatting of an argument in the format string.
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub struct FormatSpec<'a> {
     /// Optionally specified character to fill alignment with
     pub fill: Option<char>,
     /// Optionally specified alignment
     pub align: Alignment,
     /// Packed version of various flags provided
-    pub flags: uint,
+    pub flags: u32,
     /// The integer precision to use
     pub precision: Count<'a>,
     /// The string width requested for the resulting format
@@ -77,18 +78,18 @@ pub struct FormatSpec<'a> {
 }
 
 /// Enum describing where an argument for a format can be located.
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum Position<'a> {
     /// The argument will be in the next position. This is the default.
     ArgumentNext,
     /// The argument is located at a specific index.
-    ArgumentIs(uint),
+    ArgumentIs(usize),
     /// The argument has a name.
     ArgumentNamed(&'a str),
 }
 
 /// Enum of alignments which are supported.
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum Alignment {
     /// The value will be aligned to the left.
     AlignLeft,
@@ -102,7 +103,7 @@ pub enum Alignment {
 
 /// Various flags which can be applied to format strings. The meaning of these
 /// flags is defined by the formatters themselves.
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum Flag {
     /// A `+` will be used to denote positive numbers.
     FlagSignPlus,
@@ -118,14 +119,14 @@ pub enum Flag {
 
 /// A count is used for the precision and width parameters of an integer, and
 /// can reference either an argument or a literal integer.
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum Count<'a> {
     /// The count is specified explicitly.
-    CountIs(uint),
+    CountIs(usize),
     /// The count is specified by the argument with the given name.
     CountIsName(&'a str),
     /// The count is specified by the argument at the given index.
-    CountIsParam(uint),
+    CountIsParam(usize),
     /// The count is specified by the next parameter.
     CountIsNextParam,
     /// The count is implied and cannot be explicitly specified.
@@ -237,7 +238,7 @@ impl<'a> Parser<'a> {
 
     /// Parses all of a string which is to be considered a "raw literal" in a
     /// format string. This is everything outside of the braces.
-    fn string(&mut self, start: uint) -> &'a str {
+    fn string(&mut self, start: usize) -> &'a str {
         loop {
             // we may not consume the character, so clone the iterator
             match self.cur.clone().next() {
@@ -314,13 +315,13 @@ impl<'a> Parser<'a> {
         }
         // Sign flags
         if self.consume('+') {
-            spec.flags |= 1 << (FlagSignPlus as uint);
+            spec.flags |= 1 << (FlagSignPlus as u32);
         } else if self.consume('-') {
-            spec.flags |= 1 << (FlagSignMinus as uint);
+            spec.flags |= 1 << (FlagSignMinus as u32);
         }
         // Alternate marker
         if self.consume('#') {
-            spec.flags |= 1 << (FlagAlternate as uint);
+            spec.flags |= 1 << (FlagAlternate as u32);
         }
         // Width and precision
         let mut havewidth = false;
@@ -333,7 +334,7 @@ impl<'a> Parser<'a> {
                 spec.width = CountIsParam(0);
                 havewidth = true;
             } else {
-                spec.flags |= 1 << (FlagSignAwareZeroPad as uint);
+                spec.flags |= 1 << (FlagSignAwareZeroPad as u32);
             }
         }
         if !havewidth {
@@ -413,7 +414,7 @@ impl<'a> Parser<'a> {
 
     /// Optionally parses an integer at the current position. This doesn't deal
     /// with overflow at all, it's just accumulating digits.
-    fn integer(&mut self) -> Option<uint> {
+    fn integer(&mut self) -> Option<usize> {
         let mut cur = 0;
         let mut found = false;
         loop {
@@ -445,7 +446,7 @@ mod tests {
 
     fn same(fmt: &'static str, p: &[Piece<'static>]) {
         let parser = Parser::new(fmt);
-        assert!(p == parser.collect::<Vec<Piece<'static>>>());
+        assert!(parser.collect::<Vec<Piece<'static>>>() == p);
     }
 
     fn fmtdflt() -> FormatSpec<'static> {
@@ -617,7 +618,7 @@ mod tests {
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
-                flags: (1 << FlagSignMinus as uint),
+                flags: (1 << FlagSignMinus as u32),
                 precision: CountImplied,
                 width: CountImplied,
                 ty: "",
@@ -628,7 +629,7 @@ mod tests {
             format: FormatSpec {
                 fill: None,
                 align: AlignUnknown,
-                flags: (1 << FlagSignPlus as uint) | (1 << FlagAlternate as uint),
+                flags: (1 << FlagSignPlus as u32) | (1 << FlagAlternate as u32),
                 precision: CountImplied,
                 width: CountImplied,
                 ty: "",
index fdd7f7395c2b7af5955aa3f52f7cecd52e9cff74..5c10641e8515e288d083bc0f87a2ed56c63d5d4f 100644 (file)
@@ -46,7 +46,7 @@
 //!
 //! fn print_usage(program: &str, opts: &[OptGroup]) {
 //!     let brief = format!("Usage: {} [options]", program);
-//!     print!("{}", usage(brief.as_slice(), opts));
+//!     print!("{}", usage(brief, opts));
 //! }
 //!
 //! fn main() {
 //!         Err(f) => { panic!(f.to_string()) }
 //!     };
 //!     if matches.opt_present("h") {
-//!         print_usage(program.as_slice(), opts);
+//!         print_usage(program, opts);
 //!         return;
 //!     }
 //!     let output = matches.opt_str("o");
 //!     let input = if !matches.free.is_empty() {
 //!         matches.free[0].clone()
 //!     } else {
-//!         print_usage(program.as_slice(), opts);
+//!         print_usage(program, opts);
 //!         return;
 //!     };
-//!     do_work(input.as_slice(), output);
+//!     do_work(input, output);
 //! }
 //! ```
 
+
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "getopts"]
 #![unstable(feature = "rustc_private",
             reason = "use the crates.io `getopts` library instead")]
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![deny(missing_docs)]
-#![feature(collections)]
-#![feature(int_uint)]
 #![feature(staged_api)]
 #![feature(str_words)]
+#![feature(str_char)]
 #![cfg_attr(test, feature(rustc_private))]
 
 #[cfg(test)] #[macro_use] extern crate log;
@@ -211,7 +213,7 @@ pub enum Fail {
 }
 
 /// The type of failure that occurred.
-#[derive(Copy, PartialEq, Eq, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
 #[allow(missing_docs)]
 pub enum FailType {
     ArgumentMissing_,
@@ -308,7 +310,7 @@ impl Matches {
     }
 
     /// Returns the number of times an option was matched.
-    pub fn opt_count(&self, nm: &str) -> uint {
+    pub fn opt_count(&self, nm: &str) -> usize {
         self.opt_vals(nm).len()
     }
 
@@ -386,7 +388,7 @@ fn is_arg(arg: &str) -> bool {
     arg.len() > 1 && arg.as_bytes()[0] == b'-'
 }
 
-fn find_opt(opts: &[Opt], nm: Name) -> Option<uint> {
+fn find_opt(opts: &[Opt], nm: Name) -> Option<usize> {
     // Search main options.
     let pos = opts.iter().position(|opt| opt.name == nm);
     if pos.is_some() {
@@ -584,7 +586,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
     let opts: Vec<Opt> = optgrps.iter().map(|x| x.long_to_short()).collect();
     let n_opts = opts.len();
 
-    fn f(_x: uint) -> Vec<Optval> { return Vec::new(); }
+    fn f(_x: usize) -> Vec<Optval> { return Vec::new(); }
 
     let mut vals: Vec<_> = (0..n_opts).map(f).collect();
     let mut free: Vec<String> = Vec::new();
@@ -616,8 +618,8 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                 let mut j = 1;
                 names = Vec::new();
                 while j < curlen {
-                    let range = cur.char_range_at(j);
-                    let opt = Short(range.ch);
+                    let ch = cur.char_at(j);
+                    let opt = Short(ch);
 
                     /* In a series of potential options (eg. -aheJ), if we
                        see one which takes an argument, we assume all
@@ -638,12 +640,13 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
                         No => false
                     };
 
-                    if arg_follows && range.next < curlen {
-                        i_arg = Some((&cur[range.next..curlen]).to_string());
+                    let next = j + ch.len_utf8();
+                    if arg_follows && next < curlen {
+                        i_arg = Some((&cur[next..curlen]).to_string());
                         break;
                     }
 
-                    j = range.next;
+                    j = next;
                 }
             }
             let mut name_pos = 0;
@@ -784,7 +787,7 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String {
 
         // FIXME: #5516 should be graphemes not codepoints
         // wrapped description
-        row.push_str(&desc_rows.connect(&desc_sep[..])[]);
+        row.push_str(&desc_rows.connect(&desc_sep[..]));
 
         row
     });
@@ -840,18 +843,18 @@ pub fn short_usage(program_name: &str, opts: &[OptGroup]) -> String {
     line
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum SplitWithinState {
     A,  // leading whitespace, initial state
     B,  // words
     C,  // internal and trailing whitespace
 }
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum Whitespace {
     Ws, // current char is whitespace
     Cr  // current char is not whitespace
 }
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum LengthLimit {
     UnderLim, // current char makes current substring still fit in limit
     OverLim   // current char makes current substring no longer fit in limit
@@ -869,7 +872,7 @@ enum LengthLimit {
 ///
 /// Panics during iteration if the string contains a non-whitespace
 /// sequence longer than the limit.
-fn each_split_within<F>(ss: &str, lim: uint, mut it: F) -> bool where
+fn each_split_within<F>(ss: &str, lim: usize, mut it: F) -> bool where
     F: FnMut(&str) -> bool
 {
     // Just for fun, let's write this as a state machine:
@@ -888,7 +891,7 @@ fn each_split_within<F>(ss: &str, lim: uint, mut it: F) -> bool where
         lim = fake_i;
     }
 
-    let mut machine = |cont: &mut bool, (i, c): (uint, char)| -> bool {
+    let mut machine = |cont: &mut bool, (i, c): (usize, char)| -> bool {
         let whitespace = if c.is_whitespace() { Ws }       else { Cr };
         let limit      = if (i - slice_start + 1) <= lim  { UnderLim } else { OverLim };
 
@@ -950,7 +953,7 @@ fn each_split_within<F>(ss: &str, lim: uint, mut it: F) -> bool where
 
 #[test]
 fn test_split_within() {
-    fn t(s: &str, i: uint, u: &[String]) {
+    fn t(s: &str, i: usize, u: &[String]) {
         let mut v = Vec::new();
         each_split_within(s, i, |s| { v.push(s.to_string()); true });
         assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
@@ -963,7 +966,7 @@ fn test_split_within() {
         "little lamb".to_string(),
         "Little lamb".to_string()
     ]);
-    t("\nMary had a little lamb\nLittle lamb\n", ::std::uint::MAX,
+    t("\nMary had a little lamb\nLittle lamb\n", ::std::usize::MAX,
         &["Mary had a little lamb\nLittle lamb".to_string()]);
 }
 
index acd52c752e8aa1b29e79505937f332cc2f311dcb..95b78e1cbfd039a1b4d1e5665a0e4d4b0dd12830 100644 (file)
@@ -37,7 +37,7 @@
 //! Each node label is derived directly from the int representing the node,
 //! while the edge labels are all empty strings.
 //!
-//! This example also illustrates how to use `CowVec` to return
+//! This example also illustrates how to use `Cow<[T]>` to return
 //! an owned vector or a borrowed slice as appropriate: we construct the
 //! node vector from scratch, but borrow the edge list (rather than
 //! constructing a copy of all the edges from scratch).
 //! which is cyclic.
 //!
 //! ```rust
+//! # #![feature(rustc_private, core, into_cow)]
 //! use std::borrow::IntoCow;
+//! use std::io::Write;
 //! use graphviz as dot;
 //!
-//! type Nd = int;
-//! type Ed = (int,int);
+//! type Nd = isize;
+//! type Ed = (isize,isize);
 //! struct Edges(Vec<Ed>);
 //!
-//! pub fn render_to<W:Writer>(output: &mut W) {
+//! pub fn render_to<W: Write>(output: &mut W) {
 //!     let edges = Edges(vec!((0,1), (0,2), (1,3), (2,3), (3,4), (4,4)));
 //!     dot::render(&edges, output).unwrap()
 //! }
@@ -82,7 +84,7 @@
 //!
 //!     fn edges(&'a self) -> dot::Edges<'a,Ed> {
 //!         let &Edges(ref edges) = self;
-//!         edges.as_slice().into_cow()
+//!         (&edges[..]).into_cow()
 //!     }
 //!
 //!     fn source(&self, e: &Ed) -> Nd { let &(s,_) = e; s }
 //! ```
 //!
 //! ```no_run
-//! # pub fn render_to<W:Writer>(output: &mut W) { unimplemented!() }
+//! # pub fn render_to<W:std::io::Write>(output: &mut W) { unimplemented!() }
 //! pub fn main() {
-//!     use std::old_io::File;
-//!     let mut f = File::create(&Path::new("example1.dot"));
+//!     use std::fs::File;
+//!     let mut f = File::create("example1.dot").unwrap();
 //!     render_to(&mut f)
 //! }
 //! ```
 //! direct reference to the `(source,target)` pair stored in the graph's
 //! internal vector (rather than passing around a copy of the pair
 //! itself). Note that this implies that `fn edges(&'a self)` must
-//! construct a fresh `Vec<&'a (uint,uint)>` from the `Vec<(uint,uint)>`
+//! construct a fresh `Vec<&'a (usize,usize)>` from the `Vec<(usize,usize)>`
 //! edges stored in `self`.
 //!
 //! Since both the set of nodes and the set of edges are always
 //! entity `&sube`).
 //!
 //! ```rust
+//! # #![feature(rustc_private, core, into_cow)]
 //! use std::borrow::IntoCow;
+//! use std::io::Write;
 //! use graphviz as dot;
 //!
-//! type Nd = uint;
-//! type Ed<'a> = &'a (uint, uint);
-//! struct Graph { nodes: Vec<&'static str>, edges: Vec<(uint,uint)> }
+//! type Nd = usize;
+//! type Ed<'a> = &'a (usize, usize);
+//! struct Graph { nodes: Vec<&'static str>, edges: Vec<(usize,usize)> }
 //!
-//! pub fn render_to<W:Writer>(output: &mut W) {
+//! pub fn render_to<W: Write>(output: &mut W) {
 //!     let nodes = vec!("{x,y}","{x}","{y}","{}");
 //!     let edges = vec!((0,1), (0,2), (1,3), (2,3));
 //!     let graph = Graph { nodes: nodes, edges: edges };
 //! ```
 //!
 //! ```no_run
-//! # pub fn render_to<W:Writer>(output: &mut W) { unimplemented!() }
+//! # pub fn render_to<W:std::io::Write>(output: &mut W) { unimplemented!() }
 //! pub fn main() {
-//!     use std::old_io::File;
-//!     let mut f = File::create(&Path::new("example2.dot"));
+//!     use std::fs::File;
+//!     let mut f = File::create("example2.dot").unwrap();
 //!     render_to(&mut f)
 //! }
 //! ```
 //! Hasse-diagram for the subsets of the set `{x, y}`.
 //!
 //! ```rust
+//! # #![feature(rustc_private, core, into_cow)]
 //! use std::borrow::IntoCow;
+//! use std::io::Write;
 //! use graphviz as dot;
 //!
-//! type Nd<'a> = (uint, &'a str);
+//! type Nd<'a> = (usize, &'a str);
 //! type Ed<'a> = (Nd<'a>, Nd<'a>);
-//! struct Graph { nodes: Vec<&'static str>, edges: Vec<(uint,uint)> }
+//! struct Graph { nodes: Vec<&'static str>, edges: Vec<(usize,usize)> }
 //!
-//! pub fn render_to<W:Writer>(output: &mut W) {
+//! pub fn render_to<W: Write>(output: &mut W) {
 //!     let nodes = vec!("{x,y}","{x}","{y}","{}");
 //!     let edges = vec!((0,1), (0,2), (1,3), (2,3));
 //!     let graph = Graph { nodes: nodes, edges: edges };
 //!     }
 //!     fn node_label<'b>(&'b self, n: &Nd<'b>) -> dot::LabelText<'b> {
 //!         let &(i, _) = n;
-//!         dot::LabelText::LabelStr(self.nodes[i].as_slice().into_cow())
+//!         dot::LabelText::LabelStr(self.nodes[i].into_cow())
 //!     }
 //!     fn edge_label<'b>(&'b self, _: &Ed<'b>) -> dot::LabelText<'b> {
 //!         dot::LabelText::LabelStr("&sube;".into_cow())
 //!
 //! impl<'a> dot::GraphWalk<'a, Nd<'a>, Ed<'a>> for Graph {
 //!     fn nodes(&'a self) -> dot::Nodes<'a,Nd<'a>> {
-//!         self.nodes.iter().map(|s|s.as_slice()).enumerate().collect()
+//!         self.nodes.iter().map(|s| &s[..]).enumerate().collect()
 //!     }
 //!     fn edges(&'a self) -> dot::Edges<'a,Ed<'a>> {
 //!         self.edges.iter()
-//!             .map(|&(i,j)|((i, self.nodes[i].as_slice()),
-//!                           (j, self.nodes[j].as_slice())))
+//!             .map(|&(i,j)|((i, &self.nodes[i][..]),
+//!                           (j, &self.nodes[j][..])))
 //!             .collect()
 //!     }
 //!     fn source(&self, e: &Ed<'a>) -> Nd<'a> { let &(s,_) = e; s }
 //! ```
 //!
 //! ```no_run
-//! # pub fn render_to<W:Writer>(output: &mut W) { unimplemented!() }
+//! # pub fn render_to<W:std::io::Write>(output: &mut W) { unimplemented!() }
 //! pub fn main() {
-//!     use std::old_io::File;
-//!     let mut f = File::create(&Path::new("example3.dot"));
+//!     use std::fs::File;
+//!     let mut f = File::create("example3.dot").unwrap();
 //!     render_to(&mut f)
 //! }
 //! ```
 //!
 //! * [DOT language](http://www.graphviz.org/doc/info/lang.html)
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "graphviz"]
 #![unstable(feature = "rustc_private")]
 #![feature(staged_api)]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/")]
-#![feature(int_uint)]
 #![feature(collections)]
-#![feature(old_io)]
+#![feature(into_cow)]
 
 use self::LabelText::*;
 
 use std::borrow::{IntoCow, Cow};
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
 
 /// The text for a graphviz label on a node or edge.
 pub enum LabelText<'a> {
@@ -376,7 +384,7 @@ impl<'a> Id<'a> {
             is_letter_or_underscore(c) || in_range('0', c, '9')
         }
         fn in_range(low: char, c: char, high: char) -> bool {
-            low as uint <= c as uint && c as uint <= high as uint
+            low as usize <= c as usize && c as usize <= high as usize
         }
     }
 
@@ -463,7 +471,7 @@ impl<'a> LabelText<'a> {
     fn pre_escaped_content(self) -> Cow<'a, str> {
         match self {
             EscStr(s) => s,
-            LabelStr(s) => if s.contains_char('\\') {
+            LabelStr(s) => if s.contains('\\') {
                 (&*s).escape_default().into_cow()
             } else {
                 s
@@ -502,7 +510,7 @@ pub type Edges<'a,E> = Cow<'a,[E]>;
 /// that is bound by the self lifetime `'a`.
 ///
 /// The `nodes` and `edges` method each return instantiations of
-/// `CowVec` to leave implementers the freedom to create
+/// `Cow<[T]>` to leave implementers the freedom to create
 /// entirely new vectors or to pass back slices into internally owned
 /// vectors.
 pub trait GraphWalk<'a, N, E> {
@@ -516,7 +524,7 @@ pub trait GraphWalk<'a, N, E> {
     fn target(&'a self, edge: &E) -> N;
 }
 
-#[derive(Copy, PartialEq, Eq, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum RenderOption {
     NoEdgeLabels,
     NoNodeLabels,
@@ -527,26 +535,26 @@ pub fn default_options() -> Vec<RenderOption> { vec![] }
 
 /// Renders directed graph `g` into the writer `w` in DOT syntax.
 /// (Simple wrapper around `render_opts` that passes a default set of options.)
-pub fn render<'a, N:Clone+'a, E:Clone+'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Writer>(
+pub fn render<'a, N:Clone+'a, E:Clone+'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Write>(
               g: &'a G,
-              w: &mut W) -> old_io::IoResult<()> {
+              w: &mut W) -> io::Result<()> {
     render_opts(g, w, &[])
 }
 
 /// Renders directed graph `g` into the writer `w` in DOT syntax.
 /// (Main entry point for the library.)
-pub fn render_opts<'a, N:Clone+'a, E:Clone+'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Writer>(
+pub fn render_opts<'a, N:Clone+'a, E:Clone+'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Write>(
               g: &'a G,
               w: &mut W,
-              options: &[RenderOption]) -> old_io::IoResult<()>
+              options: &[RenderOption]) -> io::Result<()>
 {
-    fn writeln<W:Writer>(w: &mut W, arg: &[&str]) -> old_io::IoResult<()> {
-        for &s in arg { try!(w.write_str(s)); }
-        w.write_char('\n')
+    fn writeln<W:Write>(w: &mut W, arg: &[&str]) -> io::Result<()> {
+        for &s in arg { try!(w.write_all(s.as_bytes())); }
+        write!(w, "\n")
     }
 
-    fn indent<W:Writer>(w: &mut W) -> old_io::IoResult<()> {
-        w.write_str("    ")
+    fn indent<W:Write>(w: &mut W) -> io::Result<()> {
+        w.write_all(b"    ")
     }
 
     try!(writeln(w, &["digraph ", g.graph_id().as_slice(), " {"]));
@@ -587,17 +595,18 @@ mod tests {
     use self::NodeLabels::*;
     use super::{Id, Labeller, Nodes, Edges, GraphWalk, render};
     use super::LabelText::{self, LabelStr, EscStr};
-    use std::old_io::IoResult;
+    use std::io;
+    use std::io::prelude::*;
     use std::borrow::IntoCow;
     use std::iter::repeat;
 
     /// each node is an index in a vector in the graph.
-    type Node = uint;
+    type Node = usize;
     struct Edge {
-        from: uint, to: uint, label: &'static str
+        from: usize, to: usize, label: &'static str
     }
 
-    fn edge(from: uint, to: uint, label: &'static str) -> Edge {
+    fn edge(from: usize, to: usize, label: &'static str) -> Edge {
         Edge { from: from, to: to, label: label }
     }
 
@@ -627,7 +636,7 @@ mod tests {
 
     enum NodeLabels<L> {
         AllNodesLabelled(Vec<L>),
-        UnlabelledNodes(uint),
+        UnlabelledNodes(usize),
         SomeNodesLabelled(Vec<Option<L>>),
     }
 
@@ -736,10 +745,12 @@ mod tests {
         }
     }
 
-    fn test_input(g: LabelledGraph) -> IoResult<String> {
+    fn test_input(g: LabelledGraph) -> io::Result<String> {
         let mut writer = Vec::new();
         render(&g, &mut writer).unwrap();
-        (&mut &*writer).read_to_string()
+        let mut s = String::new();
+        try!(Read::read_to_string(&mut &*writer, &mut s));
+        Ok(s)
     }
 
     // All of the tests use raw-strings as the format for the expected outputs,
@@ -851,9 +862,10 @@ r#"digraph hasse_diagram {
                  edge(1, 3, ";"),    edge(2, 3, ";"   )));
 
         render(&g, &mut writer).unwrap();
-        let r = (&mut &*writer).read_to_string();
+        let mut r = String::new();
+        Read::read_to_string(&mut &*writer, &mut r).unwrap();
 
-        assert_eq!(r.unwrap(),
+        assert_eq!(r,
 r#"digraph syntax_tree {
     N0[label="if test {\l    branch1\l} else {\l    branch2\l}\lafterward\l"];
     N1[label="branch1"];
index 383108a3bc0e452656f67bbd8ff24bb38226f71b..44d689059d1cf3b0048fffcadc88733622fa87e9 100644 (file)
@@ -8,15 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "libc"]
 #![crate_type = "rlib"]
-#![cfg_attr(not(feature = "cargo-build"),
-            unstable(feature = "libc"))]
-#![cfg_attr(not(feature = "cargo-build"), feature(staged_api))]
+#![cfg_attr(not(feature = "cargo-build"), unstable(feature = "libc"))]
+#![cfg_attr(not(feature = "cargo-build"), feature(staged_api, core, no_std))]
 #![cfg_attr(not(feature = "cargo-build"), staged_api)]
-#![cfg_attr(not(feature = "cargo-build"), feature(core))]
-#![feature(no_std)]
-#![no_std]
+#![cfg_attr(not(feature = "cargo-build"), no_std)]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/",
@@ -76,7 +75,8 @@
 //! one from Berkeley after the lawsuits died down and the CSRG dissolved.
 
 #![allow(bad_style, raw_pointer_derive)]
-#[cfg(feature = "cargo-build")] extern crate "std" as core;
+#![cfg_attr(target_os = "nacl", allow(unused_imports))]
+#[cfg(feature = "cargo-build")] extern crate std as core;
 #[cfg(not(feature = "cargo-build"))] extern crate core;
 
 #[cfg(test)] extern crate std;
 // you can write more-platform-agnostic code if you stick to just these
 // symbols.
 
-pub use types::common::c95::{FILE, c_void, fpos_t};
-pub use types::common::c99::{int8_t, int16_t, int32_t, int64_t};
-pub use types::common::c99::{uint8_t, uint16_t, uint32_t, uint64_t};
-pub use types::common::posix88::{DIR, dirent_t};
-pub use types::os::common::posix01::{timeval};
-pub use types::os::common::bsd44::{addrinfo, in_addr, in6_addr, sockaddr_storage};
-pub use types::os::common::bsd44::{ip_mreq, ip6_mreq, sockaddr, sockaddr_un};
-pub use types::os::common::bsd44::{sa_family_t, sockaddr_in, sockaddr_in6, socklen_t};
-pub use types::os::arch::c95::{c_char, c_double, c_float, c_int, c_uint};
-pub use types::os::arch::c95::{c_long, c_short, c_uchar, c_ulong, wchar_t};
-pub use types::os::arch::c95::{c_ushort, clock_t, ptrdiff_t, c_schar};
-pub use types::os::arch::c95::{size_t, time_t, suseconds_t};
-pub use types::os::arch::c99::{c_longlong, c_ulonglong};
-pub use types::os::arch::c99::{intptr_t, uintptr_t};
-pub use types::os::arch::c99::{intmax_t, uintmax_t};
-pub use types::os::arch::posix88::{dev_t, ino_t, mode_t};
-pub use types::os::arch::posix88::{off_t, pid_t, ssize_t};
-
-pub use consts::os::c95::{_IOFBF, _IOLBF, _IONBF, BUFSIZ, EOF};
-pub use consts::os::c95::{EXIT_FAILURE, EXIT_SUCCESS};
-pub use consts::os::c95::{FILENAME_MAX, FOPEN_MAX, L_tmpnam};
-pub use consts::os::c95::{RAND_MAX, SEEK_CUR, SEEK_END};
-pub use consts::os::c95::{SEEK_SET, TMP_MAX};
-pub use consts::os::posix88::{F_OK, O_APPEND, O_CREAT, O_EXCL};
-pub use consts::os::posix88::{O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};
-pub use consts::os::posix88::{R_OK, S_IEXEC, S_IFBLK, S_IFCHR};
-pub use consts::os::posix88::{S_IFDIR, S_IFIFO, S_IFMT, S_IFREG, S_IFLNK};
-pub use consts::os::posix88::{S_IREAD, S_IRUSR, S_IRWXU, S_IWUSR};
-pub use consts::os::posix88::{STDERR_FILENO, STDIN_FILENO, S_IXUSR};
-pub use consts::os::posix88::{STDOUT_FILENO, W_OK, X_OK};
-pub use consts::os::bsd44::{AF_INET, AF_INET6, SOCK_STREAM, SOCK_DGRAM, SOCK_RAW};
-pub use consts::os::bsd44::{IPPROTO_IP, IPPROTO_IPV6, IPPROTO_TCP, TCP_NODELAY};
-pub use consts::os::bsd44::{SOL_SOCKET, SO_KEEPALIVE, SO_ERROR};
-pub use consts::os::bsd44::{SO_REUSEADDR, SO_BROADCAST, SHUT_WR, IP_MULTICAST_LOOP};
-pub use consts::os::bsd44::{IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP};
-pub use consts::os::bsd44::{IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP};
-pub use consts::os::bsd44::{IP_MULTICAST_TTL, IP_TTL, IP_HDRINCL, SHUT_RD};
-pub use consts::os::extra::{IPPROTO_RAW};
-
-pub use funcs::c95::ctype::{isalnum, isalpha, iscntrl, isdigit};
-pub use funcs::c95::ctype::{islower, isprint, ispunct, isspace};
-pub use funcs::c95::ctype::{isupper, isxdigit, tolower, toupper};
-
-pub use funcs::c95::stdio::{fclose, feof, ferror, fflush, fgetc};
-pub use funcs::c95::stdio::{fgetpos, fgets, fopen, fputc, fputs};
-pub use funcs::c95::stdio::{fread, freopen, fseek, fsetpos, ftell};
-pub use funcs::c95::stdio::{fwrite, perror, puts, remove, rename, rewind};
-pub use funcs::c95::stdio::{setbuf, setvbuf, tmpfile, ungetc};
-
-pub use funcs::c95::stdlib::{abs, atof, atoi, calloc, exit, _exit, atexit};
-pub use funcs::c95::stdlib::{free, getenv, labs, malloc, rand};
-pub use funcs::c95::stdlib::{realloc, srand, strtod, strtol};
-pub use funcs::c95::stdlib::{strtoul, system};
-
-pub use funcs::c95::string::{memchr, memcmp};
-pub use funcs::c95::string::{strcat, strchr, strcmp};
-pub use funcs::c95::string::{strcoll, strcpy, strcspn, strerror};
-pub use funcs::c95::string::{strlen, strncat, strncmp, strncpy};
-pub use funcs::c95::string::{strpbrk, strrchr, strspn, strstr};
-pub use funcs::c95::string::{strtok, strxfrm};
-
-pub use funcs::posix88::fcntl::{open, creat};
-pub use funcs::posix88::stat_::{chmod, fstat, mkdir, stat};
-pub use funcs::posix88::stdio::{fdopen, fileno, pclose, popen};
-pub use funcs::posix88::unistd::{access, chdir, close, dup, dup2};
-pub use funcs::posix88::unistd::{execv, execve, execvp, getcwd};
-pub use funcs::posix88::unistd::{getpid, isatty, lseek, pipe, read};
-pub use funcs::posix88::unistd::{rmdir, unlink, write};
-
-pub use funcs::bsd43::{socket, setsockopt, bind, send, recv, recvfrom};
-pub use funcs::bsd43::{listen, sendto, accept, connect, getpeername, getsockname};
-pub use funcs::bsd43::{shutdown};
+pub use types::common::c95::*;
+pub use types::common::c99::*;
+pub use types::common::posix88::*;
+pub use types::os::common::posix01::*;
+pub use types::os::common::bsd44::*;
+pub use types::os::arch::c95::*;
+pub use types::os::arch::c99::*;
+pub use types::os::arch::posix88::*;
+pub use types::os::arch::posix01::*;
+pub use types::os::arch::extra::*;
+
+pub use consts::os::c95::*;
+pub use consts::os::posix88::*;
+pub use consts::os::posix01::*;
+pub use consts::os::bsd44::*;
+pub use consts::os::extra::*;
+
+pub use funcs::c95::ctype::*;
+pub use funcs::c95::stdio::*;
+pub use funcs::c95::stdlib::*;
+pub use funcs::c95::string::*;
+pub use funcs::posix88::fcntl::*;
+pub use funcs::posix88::stat_::*;
+pub use funcs::posix88::stdio::*;
+pub use funcs::posix88::unistd::*;
+
+pub use funcs::bsd43::*;
 
 // But we also reexport most everything
 // if you're interested in writing platform-specific code.
@@ -169,148 +124,44 @@ pub use funcs::bsd43::{shutdown};
 //
 // So the following exports don't follow any particular plan.
 
-#[cfg(unix)] pub use consts::os::sysconf::{_SC_PAGESIZE};
-#[cfg(unix)] pub use consts::os::posix88::{PROT_READ, PROT_WRITE, PROT_EXEC};
-#[cfg(unix)] pub use consts::os::posix88::{MAP_FIXED, MAP_FILE, MAP_ANON, MAP_PRIVATE, MAP_FAILED};
-#[cfg(unix)] pub use consts::os::posix88::{EACCES, EBADF, EINVAL, ENODEV, ENOMEM};
-#[cfg(unix)] pub use consts::os::posix88::{ECONNREFUSED, ECONNRESET, EPERM, EPIPE};
-#[cfg(unix)] pub use consts::os::posix88::{ENOTCONN, ECONNABORTED, EADDRNOTAVAIL, EINTR};
-#[cfg(unix)] pub use consts::os::posix88::{EADDRINUSE, ENOENT, EISDIR, EAGAIN, EWOULDBLOCK};
-#[cfg(unix)] pub use consts::os::posix88::{ECANCELED, SIGINT, EINPROGRESS};
-#[cfg(unix)] pub use consts::os::posix88::{ENOSYS, ENOTTY, ETIMEDOUT, EMFILE};
-#[cfg(unix)] pub use consts::os::posix88::{SIGTERM, SIGKILL, SIGPIPE, PROT_NONE};
-#[cfg(unix)] pub use consts::os::posix01::{SIG_IGN, F_GETFL, F_SETFL};
-#[cfg(unix)] pub use consts::os::bsd44::{AF_UNIX};
-#[cfg(unix)] pub use consts::os::extra::{O_NONBLOCK};
-
-#[cfg(unix)] pub use types::os::common::posix01::{pthread_t, timespec, timezone};
-
-#[cfg(unix)] pub use types::os::arch::posix88::{uid_t, gid_t};
-#[cfg(unix)] pub use types::os::arch::posix01::{pthread_attr_t};
-#[cfg(unix)] pub use types::os::arch::posix01::{stat, utimbuf};
-#[cfg(unix)] pub use types::os::common::bsd44::{ifaddrs};
-#[cfg(unix)] pub use funcs::posix88::unistd::{sysconf, setgid, setsid, setuid, pread, pwrite};
-#[cfg(unix)] pub use funcs::posix88::unistd::{getgid, getuid, getsid};
-#[cfg(unix)] pub use funcs::posix88::unistd::{_PC_NAME_MAX, utime, nanosleep, pathconf, link};
-#[cfg(unix)] pub use funcs::posix88::unistd::{chown};
-#[cfg(unix)] pub use funcs::posix88::mman::{mmap, munmap, mprotect};
-#[cfg(unix)] pub use funcs::posix88::dirent::{opendir, readdir_r, closedir};
-#[cfg(unix)] pub use funcs::posix88::fcntl::{fcntl};
-#[cfg(unix)] pub use funcs::posix88::net::{if_nametoindex};
-#[cfg(unix)] pub use funcs::posix01::stat_::{lstat};
-#[cfg(unix)] pub use funcs::posix01::unistd::{fsync, ftruncate};
-#[cfg(unix)] pub use funcs::posix01::unistd::{readlink, symlink};
-#[cfg(unix)] pub use funcs::bsd43::{getifaddrs, freeifaddrs};
-
-#[cfg(windows)] pub use consts::os::c95::{WSAECONNREFUSED, WSAECONNRESET, WSAEACCES};
-#[cfg(windows)] pub use consts::os::c95::{WSAEWOULDBLOCK, WSAENOTCONN, WSAECONNABORTED};
-#[cfg(windows)] pub use consts::os::c95::{WSAEADDRNOTAVAIL, WSAEADDRINUSE, WSAEINTR};
-#[cfg(windows)] pub use consts::os::c95::{WSAEINPROGRESS, WSAEINVAL, WSAEMFILE};
-#[cfg(windows)] pub use consts::os::extra::{ERROR_INSUFFICIENT_BUFFER};
-#[cfg(windows)] pub use consts::os::extra::{O_BINARY, O_NOINHERIT, PAGE_NOACCESS};
-#[cfg(windows)] pub use consts::os::extra::{PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE};
-#[cfg(windows)] pub use consts::os::extra::{PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE};
-#[cfg(windows)] pub use consts::os::extra::{MEM_COMMIT, MEM_RESERVE, MEM_RELEASE};
-#[cfg(windows)] pub use consts::os::extra::{FILE_MAP_READ, FILE_MAP_WRITE, FILE_MAP_EXECUTE};
-#[cfg(windows)] pub use consts::os::extra::{ERROR_ALREADY_EXISTS, ERROR_NO_DATA};
-#[cfg(windows)] pub use consts::os::extra::{ERROR_FILE_NOT_FOUND, ERROR_INVALID_NAME};
-#[cfg(windows)] pub use consts::os::extra::{ERROR_BROKEN_PIPE, ERROR_INVALID_FUNCTION};
-#[cfg(windows)] pub use consts::os::extra::{ERROR_CALL_NOT_IMPLEMENTED};
-#[cfg(windows)] pub use consts::os::extra::{ERROR_NOTHING_TO_TERMINATE};
-#[cfg(windows)] pub use consts::os::extra::{ERROR_INVALID_HANDLE};
-#[cfg(windows)] pub use consts::os::extra::{TRUE, FALSE, INFINITE};
-#[cfg(windows)] pub use consts::os::extra::{PROCESS_TERMINATE, PROCESS_QUERY_INFORMATION};
-#[cfg(windows)] pub use consts::os::extra::{STILL_ACTIVE, DETACHED_PROCESS};
-#[cfg(windows)] pub use consts::os::extra::{CREATE_NEW_PROCESS_GROUP, CREATE_UNICODE_ENVIRONMENT};
-#[cfg(windows)] pub use consts::os::extra::{FILE_BEGIN, FILE_END, FILE_CURRENT};
-#[cfg(windows)] pub use consts::os::extra::{FILE_GENERIC_READ, FILE_GENERIC_WRITE};
-#[cfg(windows)] pub use consts::os::extra::{FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE};
-#[cfg(windows)] pub use consts::os::extra::{TRUNCATE_EXISTING, CREATE_ALWAYS, OPEN_EXISTING};
-#[cfg(windows)] pub use consts::os::extra::{CREATE_NEW, FILE_APPEND_DATA, FILE_WRITE_DATA};
-#[cfg(windows)] pub use consts::os::extra::{OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL};
-#[cfg(windows)] pub use consts::os::extra::{FILE_FLAG_BACKUP_SEMANTICS, INVALID_HANDLE_VALUE};
-#[cfg(windows)] pub use consts::os::extra::{MOVEFILE_REPLACE_EXISTING};
-#[cfg(windows)] pub use consts::os::extra::{GENERIC_READ, GENERIC_WRITE};
-#[cfg(windows)] pub use consts::os::extra::{VOLUME_NAME_DOS};
-#[cfg(windows)] pub use consts::os::extra::{PIPE_ACCESS_DUPLEX, FILE_FLAG_FIRST_PIPE_INSTANCE};
-#[cfg(windows)] pub use consts::os::extra::{FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE};
-#[cfg(windows)] pub use consts::os::extra::{PIPE_READMODE_BYTE, PIPE_WAIT};
-#[cfg(windows)] pub use consts::os::extra::{PIPE_UNLIMITED_INSTANCES, ERROR_ACCESS_DENIED};
-#[cfg(windows)] pub use consts::os::extra::{FILE_WRITE_ATTRIBUTES, FILE_READ_ATTRIBUTES};
-#[cfg(windows)] pub use consts::os::extra::{ERROR_PIPE_BUSY, ERROR_IO_PENDING};
-#[cfg(windows)] pub use consts::os::extra::{ERROR_PIPE_CONNECTED, WAIT_OBJECT_0};
-#[cfg(windows)] pub use consts::os::extra::{ERROR_NOT_FOUND};
-#[cfg(windows)] pub use consts::os::extra::{ERROR_OPERATION_ABORTED};
-#[cfg(windows)] pub use consts::os::extra::{FIONBIO};
-#[cfg(windows)] pub use types::os::common::bsd44::{SOCKET};
-#[cfg(windows)] pub use types::os::common::posix01::{stat, utimbuf};
-#[cfg(windows)] pub use types::os::arch::extra::{HANDLE, BOOL, LPSECURITY_ATTRIBUTES};
-#[cfg(windows)] pub use types::os::arch::extra::{LPCSTR, WORD, DWORD, BYTE, FILETIME};
-#[cfg(windows)] pub use types::os::arch::extra::{LARGE_INTEGER, LPVOID, LONG};
-#[cfg(windows)] pub use types::os::arch::extra::{time64_t, OVERLAPPED, LPCWSTR};
-#[cfg(windows)] pub use types::os::arch::extra::{LPOVERLAPPED, SIZE_T, LPDWORD};
-#[cfg(windows)] pub use types::os::arch::extra::{SECURITY_ATTRIBUTES, WIN32_FIND_DATAW};
-#[cfg(windows)] pub use funcs::c95::string::{wcslen};
-#[cfg(windows)] pub use funcs::posix88::stat_::{wstat, wutime, wchmod, wrmdir};
-#[cfg(windows)] pub use funcs::bsd43::{closesocket};
-#[cfg(windows)] pub use funcs::extra::kernel32::{GetCurrentDirectoryW, GetLastError};
-#[cfg(windows)] pub use funcs::extra::kernel32::{GetEnvironmentVariableW, SetEnvironmentVariableW};
-#[cfg(windows)] pub use funcs::extra::kernel32::{GetModuleFileNameW, SetCurrentDirectoryW};
-#[cfg(windows)] pub use funcs::extra::kernel32::{GetSystemInfo, VirtualAlloc, VirtualFree};
-#[cfg(windows)] pub use funcs::extra::kernel32::{CreateFileMappingW, MapViewOfFile};
-#[cfg(windows)] pub use funcs::extra::kernel32::{UnmapViewOfFile, CloseHandle};
-#[cfg(windows)] pub use funcs::extra::kernel32::{WaitForSingleObject, GetSystemTimeAsFileTime};
-#[cfg(windows)] pub use funcs::extra::kernel32::{QueryPerformanceCounter};
-#[cfg(windows)] pub use funcs::extra::kernel32::{QueryPerformanceFrequency};
-#[cfg(windows)] pub use funcs::extra::kernel32::{GetExitCodeProcess, TerminateProcess};
-#[cfg(windows)] pub use funcs::extra::kernel32::{ReadFile, WriteFile, SetFilePointerEx};
-#[cfg(windows)] pub use funcs::extra::kernel32::{SetEndOfFile, CreateFileW};
-#[cfg(windows)] pub use funcs::extra::kernel32::{CreateDirectoryW, FindFirstFileW};
-#[cfg(windows)] pub use funcs::extra::kernel32::{FindNextFileW, FindClose, DeleteFileW};
-#[cfg(windows)] pub use funcs::extra::kernel32::{CreateHardLinkW, CreateEventW};
-#[cfg(windows)] pub use funcs::extra::kernel32::{FlushFileBuffers, CreateNamedPipeW};
-#[cfg(windows)] pub use funcs::extra::kernel32::{SetNamedPipeHandleState, WaitNamedPipeW};
-#[cfg(windows)] pub use funcs::extra::kernel32::{GetOverlappedResult, ConnectNamedPipe};
-#[cfg(windows)] pub use funcs::extra::kernel32::{DisconnectNamedPipe, OpenProcess};
-#[cfg(windows)] pub use funcs::extra::kernel32::{MoveFileExW, VirtualProtect};
-#[cfg(windows)] pub use funcs::extra::kernel32::{RemoveDirectoryW};
-#[cfg(windows)] pub use funcs::extra::msvcrt::{get_osfhandle, open_osfhandle};
-#[cfg(windows)] pub use funcs::extra::winsock::{ioctlsocket};
-
-#[cfg(any(target_os = "linux",
-          target_os = "android",
-          target_os = "freebsd",
-          target_os = "dragonfly",
-          target_os = "openbsd"))]
-pub use consts::os::posix01::{CLOCK_REALTIME, CLOCK_MONOTONIC};
-
-#[cfg(any(target_os = "linux", target_os = "android"))]
-pub use funcs::posix01::unistd::{fdatasync};
-#[cfg(any(target_os = "linux", target_os = "android"))]
-pub use types::os::arch::extra::{sockaddr_ll};
-#[cfg(any(target_os = "linux", target_os = "android"))]
-pub use consts::os::extra::{AF_PACKET};
-
-#[cfg(all(unix, not(any(target_os = "freebsd", target_os = "openbsd"))))]
-pub use consts::os::extra::{MAP_STACK};
-
-#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
-pub use consts::os::bsd44::{TCP_KEEPIDLE};
-
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-pub use consts::os::bsd44::{TCP_KEEPALIVE};
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-pub use consts::os::extra::{F_FULLFSYNC};
-
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-pub use types::os::arch::extra::{mach_timebase_info};
-
-
-#[cfg(not(windows))]
+#[cfg(unix)] pub use consts::os::sysconf::*;
+
+#[cfg(unix)] pub use funcs::posix88::mman::*;
+#[cfg(unix)] pub use funcs::posix88::dirent::*;
+#[cfg(unix)] pub use funcs::posix88::net::*;
+#[cfg(unix)] pub use funcs::posix01::stat_::*;
+#[cfg(unix)] pub use funcs::posix01::unistd::*;
+#[cfg(unix)] pub use funcs::posix01::resource::*;
+
+
+#[cfg(windows)] pub use funcs::extra::kernel32::*;
+#[cfg(windows)] pub use funcs::extra::winsock::*;
+#[cfg(windows)] pub use funcs::extra::msvcrt::*;
+
+// On NaCl, these libraries are static. Thus it would be a Bad Idea to link them
+// in when creating a test crate.
+#[cfg(not(any(windows, all(target_os = "nacl", test))))]
 #[link(name = "c")]
 #[link(name = "m")]
 extern {}
 
+// libnacl provides functions that require a trip through the IRT to work.
+// ie: _exit, mmap, nanosleep, etc. Anything that would otherwise require a trip
+// to the kernel.
+#[cfg(all(target_os = "nacl", not(feature = "cargo-build"), not(test)))]
+#[link(name = "nacl", kind = "static")]
+extern {}
+
+// pnaclmm provides a number of functions that the toolchain's Clang emits calls
+// to when codegening atomic ops. All the functions within wrap various atomic
+// operations.
+// Yes, it could be linked by rustc explicitly, however by linking it here
+// instead we save a bit of time where bins are involved (by not running the
+// optimizations on the whole pnaclmm foreach binary built).
+#[cfg(all(target_os = "nacl", not(feature = "cargo-build"), not(test)))]
+#[link(name = "pnaclmm", kind = "static")]
+extern {}
+
 pub mod types {
 
     // Types tend to vary *per architecture* so we pull their definitions out
@@ -361,7 +212,7 @@ pub mod types {
 
     // Standard types that are scalar but vary by OS and arch.
 
-    #[cfg(any(target_os = "linux", target_os = "android"))]
+    #[cfg(any(target_os = "linux", target_os = "android", target_os = "nacl"))]
     pub mod os {
         pub mod common {
             pub mod posix01 {
@@ -369,10 +220,14 @@ pub mod types {
                 use types::os::arch::c95::{c_char, c_ulong, size_t,
                                                  time_t, suseconds_t, c_long};
 
+                #[cfg(not(target_os = "nacl"))]
                 pub type pthread_t = c_ulong;
+                #[cfg(target_os = "nacl")]
+                pub type pthread_t = *mut c_void;
+                pub type rlim_t = u64;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct glob_t {
+                #[derive(Copy, Clone)] pub struct glob_t {
                     pub gl_pathc: size_t,
                     pub gl_pathv: *mut *mut c_char,
                     pub gl_offs:  size_t,
@@ -385,21 +240,56 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct timeval {
+                #[derive(Copy, Clone)] pub struct timeval {
                     pub tv_sec: time_t,
                     pub tv_usec: suseconds_t,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct timespec {
+                #[derive(Copy, Clone)] pub struct timespec {
                     pub tv_sec: time_t,
                     pub tv_nsec: c_long,
                 }
 
-                #[derive(Copy)] pub enum timezone {}
+                pub enum timezone {}
 
                 pub type sighandler_t = size_t;
+
+                #[repr(C)]
+                #[derive(Copy, Clone)]
+                pub struct rlimit {
+                    pub rlim_cur: rlim_t,
+                    pub rlim_max: rlim_t,
+                }
+            }
+
+            pub mod bsd43 {
+                use types::os::common::posix01::timeval;
+                use types::os::arch::c95::c_long;
+                // This is also specified in POSIX 2001, but only has two fields. All implementors
+                // implement BSD 4.3 version.
+                #[repr(C)]
+                #[derive(Copy, Clone)]
+                pub struct rusage {
+                    pub ru_utime: timeval,
+                    pub ru_stime: timeval,
+                    pub ru_maxrss: c_long,
+                    pub ru_ixrss: c_long,
+                    pub ru_idrss: c_long,
+                    pub ru_isrss: c_long,
+                    pub ru_minflt: c_long,
+                    pub ru_majflt: c_long,
+                    pub ru_nswap: c_long,
+                    pub ru_inblock: c_long,
+                    pub ru_oublock: c_long,
+                    pub ru_msgsnd: c_long,
+                    pub ru_msgrcv: c_long,
+                    pub ru_nsignals: c_long,
+                    pub ru_nvcsw: c_long,
+                    pub ru_nivcsw: c_long
+                }
             }
+
             pub mod bsd44 {
                 use types::common::c95::{c_void};
                 use types::os::arch::c95::{c_char, c_int, c_uint};
@@ -409,29 +299,35 @@ pub mod types {
                 pub type in_port_t = u16;
                 pub type in_addr_t = u32;
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr {
+                #[derive(Copy, Clone)] pub struct sockaddr {
                     pub sa_family: sa_family_t,
                     pub sa_data: [u8; 14],
                 }
                 #[repr(C)]
                 #[derive(Copy)] pub struct sockaddr_storage {
                     pub ss_family: sa_family_t,
-                    pub __ss_align: i64,
-                    pub __ss_pad2: [u8; 112],
+                    pub __ss_align: isize,
+                    #[cfg(target_pointer_width = "32")]
+                    pub __ss_pad2: [u8; 128 - 2 * 4],
+                    #[cfg(target_pointer_width = "64")]
+                    pub __ss_pad2: [u8; 128 - 2 * 8],
+                }
+                impl ::core::clone::Clone for sockaddr_storage {
+                    fn clone(&self) -> sockaddr_storage { *self }
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_in {
+                #[derive(Copy, Clone)] 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)]
-                #[derive(Copy)] pub struct in_addr {
+                #[derive(Copy, Clone)] pub struct in_addr {
                     pub s_addr: in_addr_t,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_in6 {
+                #[derive(Copy, Clone)] pub struct sockaddr_in6 {
                     pub sin6_family: sa_family_t,
                     pub sin6_port: in_port_t,
                     pub sin6_flowinfo: u32,
@@ -439,21 +335,21 @@ pub mod types {
                     pub sin6_scope_id: u32,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct in6_addr {
+                #[derive(Copy, Clone)] pub struct in6_addr {
                     pub s6_addr: [u16; 8]
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ip_mreq {
+                #[derive(Copy, Clone)] pub struct ip_mreq {
                     pub imr_multiaddr: in_addr,
                     pub imr_interface: in_addr,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ip6_mreq {
+                #[derive(Copy, Clone)] pub struct ip6_mreq {
                     pub ipv6mr_multiaddr: in6_addr,
                     pub ipv6mr_interface: c_uint,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct addrinfo {
+                #[derive(Copy, Clone)] pub struct addrinfo {
                     pub ai_flags: c_int,
                     pub ai_family: c_int,
                     pub ai_socktype: c_int,
@@ -466,10 +362,10 @@ pub mod types {
                     #[cfg(target_os = "linux")]
                     pub ai_canonname: *mut c_char,
 
-                    #[cfg(target_os = "android")]
+                    #[cfg(any(target_os = "android", target_os = "nacl"))]
                     pub ai_canonname: *mut c_char,
 
-                    #[cfg(target_os = "android")]
+                    #[cfg(any(target_os = "android", target_os = "nacl"))]
                     pub ai_addr: *mut sockaddr,
 
                     pub ai_next: *mut addrinfo,
@@ -479,9 +375,12 @@ pub mod types {
                     pub sun_family: sa_family_t,
                     pub sun_path: [c_char; 108]
                 }
+                impl ::core::clone::Clone for sockaddr_un {
+                    fn clone(&self) -> sockaddr_un { *self }
+                }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct ifaddrs {
+                #[derive(Copy, Clone)] pub struct ifaddrs {
                     pub ifa_next: *mut ifaddrs,
                     pub ifa_name: *mut c_char,
                     pub ifa_flags: c_uint,
@@ -498,7 +397,8 @@ pub mod types {
                   target_arch = "arm",
                   target_arch = "mips",
                   target_arch = "mipsel",
-                  target_arch = "powerpc"))]
+                  target_arch = "powerpc",
+                  target_arch = "le32"))]
         pub mod arch {
             pub mod c95 {
                 pub type c_char = i8;
@@ -530,7 +430,9 @@ pub mod types {
             #[cfg(any(target_arch = "x86",
                       target_arch = "mips",
                       target_arch = "mipsel",
-                      target_arch = "powerpc"))]
+                      target_arch = "powerpc",
+                      target_arch = "le32",
+                      all(target_arch = "arm", not(target_os = "android"))))]
             pub mod posix88 {
                 pub type off_t = i32;
                 pub type dev_t = u64;
@@ -542,7 +444,7 @@ pub mod types {
                 pub type mode_t = u32;
                 pub type ssize_t = i32;
             }
-            #[cfg(target_arch = "arm")]
+            #[cfg(all(target_arch = "arm", target_os = "android"))]
             pub mod posix88 {
                 pub type off_t = i32;
                 pub type dev_t = u32;
@@ -555,7 +457,9 @@ pub mod types {
                 pub type ssize_t = i32;
             }
             #[cfg(any(target_arch = "x86",
-                      target_arch = "powerpc"))]
+                      target_arch = "le32",
+                      target_arch = "powerpc",
+                      all(target_arch = "arm", not(target_os = "android"))))]
             pub mod posix01 {
                 use types::os::arch::c95::{c_short, c_long, time_t};
                 use types::os::arch::posix88::{dev_t, gid_t, ino_t};
@@ -567,7 +471,7 @@ pub mod types {
                 pub type blkcnt_t = i32;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct stat {
+                #[derive(Copy, Clone)] pub struct stat {
                     pub st_dev: dev_t,
                     pub __pad1: c_short,
                     pub st_ino: ino_t,
@@ -591,17 +495,17 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct utimbuf {
+                #[derive(Copy, Clone)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct pthread_attr_t {
+                #[derive(Copy, Clone)] pub struct pthread_attr_t {
                     pub __size: [u32; 9]
                 }
             }
-            #[cfg(target_arch = "arm")]
+            #[cfg(all(target_arch = "arm", target_os = "android"))]
             pub mod posix01 {
                 use types::os::arch::c95::{c_uchar, c_uint, c_ulong, time_t};
                 use types::os::arch::c99::{c_longlong, c_ulonglong};
@@ -612,7 +516,7 @@ pub mod types {
                 pub type blkcnt_t = u32;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct stat {
+                #[derive(Copy, Clone)] pub struct stat {
                     pub st_dev: c_ulonglong,
                     pub __pad0: [c_uchar; 4],
                     pub __st_ino: ino_t,
@@ -635,13 +539,13 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct utimbuf {
+                #[derive(Copy, Clone)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct pthread_attr_t {
+                #[derive(Copy, Clone)] pub struct pthread_attr_t {
                     pub __size: [u32; 9]
                 }
             }
@@ -658,7 +562,7 @@ pub mod types {
                 pub type blkcnt_t = i32;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct stat {
+                #[derive(Copy, Clone)] pub struct stat {
                     pub st_dev: c_ulong,
                     pub st_pad1: [c_long; 3],
                     pub st_ino: ino_t,
@@ -682,13 +586,13 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct utimbuf {
+                #[derive(Copy, Clone)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct pthread_attr_t {
+                #[derive(Copy, Clone)] pub struct pthread_attr_t {
                     pub __size: [u32; 9]
                 }
             }
@@ -697,7 +601,7 @@ pub mod types {
             pub mod extra {
                 use types::os::arch::c95::{c_ushort, c_int, c_uchar};
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_ll {
+                #[derive(Copy, Clone)] pub struct sockaddr_ll {
                     pub sll_family: c_ushort,
                     pub sll_protocol: c_ushort,
                     pub sll_ifindex: c_int,
@@ -769,7 +673,7 @@ pub mod types {
                 pub type blkcnt_t = i64;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct stat {
+                #[derive(Copy, Clone)] pub struct stat {
                     pub st_dev: dev_t,
                     pub st_ino: ino_t,
                     pub st_nlink: nlink_t,
@@ -791,13 +695,13 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct utimbuf {
+                #[derive(Copy, Clone)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct pthread_attr_t {
+                #[derive(Copy, Clone)] pub struct pthread_attr_t {
                     pub __size: [u64; 7]
                 }
             }
@@ -813,7 +717,7 @@ pub mod types {
                 pub type blkcnt_t = i64;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct stat {
+                #[derive(Copy, Clone)] pub struct stat {
                     pub st_dev: dev_t,
                     pub st_ino: ino_t,
                     pub st_mode: mode_t,
@@ -836,13 +740,13 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct utimbuf {
+                #[derive(Copy, Clone)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct pthread_attr_t {
+                #[derive(Copy, Clone)] pub struct pthread_attr_t {
                     pub __size: [u64; 8]
                 }
             }
@@ -852,7 +756,7 @@ pub mod types {
             }
             pub mod extra {
                 use types::os::arch::c95::{c_ushort, c_int, c_uchar};
-                #[derive(Copy)] pub struct sockaddr_ll {
+                #[derive(Copy, Clone)] pub struct sockaddr_ll {
                     pub sll_family: c_ushort,
                     pub sll_protocol: c_ushort,
                     pub sll_ifindex: c_int,
@@ -876,9 +780,10 @@ pub mod types {
                 use types::os::arch::c99::{uintptr_t};
 
                 pub type pthread_t = uintptr_t;
+                pub type rlim_t = i64;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct glob_t {
+                #[derive(Copy, Clone)] pub struct glob_t {
                     pub gl_pathc:  size_t,
                     pub __unused1: size_t,
                     pub gl_offs:   size_t,
@@ -895,21 +800,54 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct timeval {
+                #[derive(Copy, Clone)] pub struct timeval {
                     pub tv_sec: time_t,
                     pub tv_usec: suseconds_t,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct timespec {
+                #[derive(Copy, Clone)] pub struct timespec {
                     pub tv_sec: time_t,
                     pub tv_nsec: c_long,
                 }
 
-                #[derive(Copy)] pub enum timezone {}
+                pub enum timezone {}
 
                 pub type sighandler_t = size_t;
+
+                #[repr(C)]
+                #[derive(Copy, Clone)]
+                pub struct rlimit {
+                    pub rlim_cur: rlim_t,
+                    pub rlim_max: rlim_t,
+                }
             }
+
+            pub mod bsd43 {
+                use types::os::common::posix01::timeval;
+                use types::os::arch::c95::c_long;
+                #[repr(C)]
+                #[derive(Copy, Clone)]
+                pub struct rusage {
+                    pub ru_utime: timeval,
+                    pub ru_stime: timeval,
+                    pub ru_maxrss: c_long,
+                    pub ru_ixrss: c_long,
+                    pub ru_idrss: c_long,
+                    pub ru_isrss: c_long,
+                    pub ru_minflt: c_long,
+                    pub ru_majflt: c_long,
+                    pub ru_nswap: c_long,
+                    pub ru_inblock: c_long,
+                    pub ru_oublock: c_long,
+                    pub ru_msgsnd: c_long,
+                    pub ru_msgrcv: c_long,
+                    pub ru_nsignals: c_long,
+                    pub ru_nvcsw: c_long,
+                    pub ru_nivcsw: c_long
+                }
+            }
+
             pub mod bsd44 {
                 use types::common::c95::{c_void};
                 use types::os::arch::c95::{c_char, c_int, c_uint};
@@ -919,13 +857,13 @@ pub mod types {
                 pub type in_port_t = u16;
                 pub type in_addr_t = u32;
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr {
+                #[derive(Copy, Clone)] pub struct sockaddr {
                     pub sa_len: u8,
                     pub sa_family: sa_family_t,
                     pub sa_data: [u8; 14],
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_storage {
+                #[derive(Copy, Clone)] pub struct sockaddr_storage {
                     pub ss_len: u8,
                     pub ss_family: sa_family_t,
                     pub __ss_pad1: [u8; 6],
@@ -933,7 +871,7 @@ pub mod types {
                     pub __ss_pad2: [u8; 112],
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_in {
+                #[derive(Copy, Clone)] pub struct sockaddr_in {
                     pub sin_len: u8,
                     pub sin_family: sa_family_t,
                     pub sin_port: in_port_t,
@@ -941,11 +879,11 @@ pub mod types {
                     pub sin_zero: [u8; 8],
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct in_addr {
+                #[derive(Copy, Clone)] pub struct in_addr {
                     pub s_addr: in_addr_t,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_in6 {
+                #[derive(Copy, Clone)] pub struct sockaddr_in6 {
                     pub sin6_len: u8,
                     pub sin6_family: sa_family_t,
                     pub sin6_port: in_port_t,
@@ -954,21 +892,21 @@ pub mod types {
                     pub sin6_scope_id: u32,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct in6_addr {
+                #[derive(Copy, Clone)] pub struct in6_addr {
                     pub s6_addr: [u16; 8]
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ip_mreq {
+                #[derive(Copy, Clone)] pub struct ip_mreq {
                     pub imr_multiaddr: in_addr,
                     pub imr_interface: in_addr,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ip6_mreq {
+                #[derive(Copy, Clone)] pub struct ip6_mreq {
                     pub ipv6mr_multiaddr: in6_addr,
                     pub ipv6mr_interface: c_uint,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct addrinfo {
+                #[derive(Copy, Clone)] pub struct addrinfo {
                     pub ai_flags: c_int,
                     pub ai_family: c_int,
                     pub ai_socktype: c_int,
@@ -979,13 +917,13 @@ pub mod types {
                     pub ai_next: *mut addrinfo,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_un {
+                #[derive(Copy, Clone)] pub struct sockaddr_un {
                     pub sun_len: u8,
                     pub sun_family: sa_family_t,
                     pub sun_path: [c_char; 104]
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ifaddrs {
+                #[derive(Copy, Clone)] pub struct ifaddrs {
                     pub ifa_next: *mut ifaddrs,
                     pub ifa_name: *mut c_char,
                     pub ifa_flags: c_uint,
@@ -1052,7 +990,7 @@ pub mod types {
                 pub type blkcnt_t = i64;
                 pub type fflags_t = u32;
                 #[repr(C)]
-                #[derive(Copy)] pub struct stat {
+                #[derive(Copy, Clone)] pub struct stat {
                     pub st_dev: dev_t,
                     pub st_ino: ino_t,
                     pub st_mode: mode_t,
@@ -1078,7 +1016,7 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct utimbuf {
+                #[derive(Copy, Clone)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
@@ -1104,9 +1042,10 @@ pub mod types {
                 use types::os::arch::c99::{uintptr_t};
 
                 pub type pthread_t = uintptr_t;
+                pub type rlim_t = i64;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct glob_t {
+                #[derive(Copy, Clone)] pub struct glob_t {
                     pub gl_pathc:  size_t,
                     pub __unused1: size_t,
                     pub gl_offs:   size_t,
@@ -1123,21 +1062,54 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct timeval {
+                #[derive(Copy, Clone)] pub struct timeval {
                     pub tv_sec: time_t,
                     pub tv_usec: suseconds_t,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct timespec {
+                #[derive(Copy, Clone)] pub struct timespec {
                     pub tv_sec: time_t,
                     pub tv_nsec: c_long,
                 }
 
-                #[derive(Copy)] pub enum timezone {}
+                pub enum timezone {}
 
                 pub type sighandler_t = size_t;
+
+                #[repr(C)]
+                #[derive(Copy, Clone)]
+                pub struct rlimit {
+                    pub rlim_cur: rlim_t,
+                    pub rlim_max: rlim_t,
+                }
             }
+
+            pub mod bsd43 {
+                use types::os::common::posix01::timeval;
+                use types::os::arch::c95::c_long;
+                #[repr(C)]
+                #[derive(Copy, Clone)]
+                pub struct rusage {
+                    pub ru_utime: timeval,
+                    pub ru_stime: timeval,
+                    pub ru_maxrss: c_long,
+                    pub ru_ixrss: c_long,
+                    pub ru_idrss: c_long,
+                    pub ru_isrss: c_long,
+                    pub ru_minflt: c_long,
+                    pub ru_majflt: c_long,
+                    pub ru_nswap: c_long,
+                    pub ru_inblock: c_long,
+                    pub ru_oublock: c_long,
+                    pub ru_msgsnd: c_long,
+                    pub ru_msgrcv: c_long,
+                    pub ru_nsignals: c_long,
+                    pub ru_nvcsw: c_long,
+                    pub ru_nivcsw: c_long
+                }
+            }
+
             pub mod bsd44 {
                 use types::common::c95::{c_void};
                 use types::os::arch::c95::{c_char, c_int, c_uint};
@@ -1147,13 +1119,13 @@ pub mod types {
                 pub type in_port_t = u16;
                 pub type in_addr_t = u32;
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr {
+                #[derive(Copy, Clone)] pub struct sockaddr {
                     pub sa_len: u8,
                     pub sa_family: sa_family_t,
                     pub sa_data: [u8; 14],
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_storage {
+                #[derive(Copy, Clone)] pub struct sockaddr_storage {
                     pub ss_len: u8,
                     pub ss_family: sa_family_t,
                     pub __ss_pad1: [u8; 6],
@@ -1161,7 +1133,7 @@ pub mod types {
                     pub __ss_pad2: [u8; 112],
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_in {
+                #[derive(Copy, Clone)] pub struct sockaddr_in {
                     pub sin_len: u8,
                     pub sin_family: sa_family_t,
                     pub sin_port: in_port_t,
@@ -1169,11 +1141,11 @@ pub mod types {
                     pub sin_zero: [u8; 8],
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct in_addr {
+                #[derive(Copy, Clone)] pub struct in_addr {
                     pub s_addr: in_addr_t,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_in6 {
+                #[derive(Copy, Clone)] pub struct sockaddr_in6 {
                     pub sin6_len: u8,
                     pub sin6_family: sa_family_t,
                     pub sin6_port: in_port_t,
@@ -1182,21 +1154,21 @@ pub mod types {
                     pub sin6_scope_id: u32,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct in6_addr {
+                #[derive(Copy, Clone)] pub struct in6_addr {
                     pub s6_addr: [u16; 8]
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ip_mreq {
+                #[derive(Copy, Clone)] pub struct ip_mreq {
                     pub imr_multiaddr: in_addr,
                     pub imr_interface: in_addr,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ip6_mreq {
+                #[derive(Copy, Clone)] pub struct ip6_mreq {
                     pub ipv6mr_multiaddr: in6_addr,
                     pub ipv6mr_interface: c_uint,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct addrinfo {
+                #[derive(Copy, Clone)] pub struct addrinfo {
                     pub ai_flags: c_int,
                     pub ai_family: c_int,
                     pub ai_socktype: c_int,
@@ -1207,13 +1179,13 @@ pub mod types {
                     pub ai_next: *mut addrinfo,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_un {
+                #[derive(Copy, Clone)] pub struct sockaddr_un {
                     pub sun_len: u8,
                     pub sun_family: sa_family_t,
                     pub sun_path: [c_char; 104]
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ifaddrs {
+                #[derive(Copy, Clone)] pub struct ifaddrs {
                     pub ifa_next: *mut ifaddrs,
                     pub ifa_name: *mut c_char,
                     pub ifa_flags: c_uint,
@@ -1258,7 +1230,6 @@ pub mod types {
             pub mod posix88 {
                 pub type off_t = i64;
                 pub type dev_t = u32;
-                pub type ino_t = u32;
                 pub type pid_t = i32;
                 pub type uid_t = u32;
                 pub type gid_t = u32;
@@ -1281,7 +1252,7 @@ pub mod types {
                 pub type fflags_t = u32;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct stat {
+                #[derive(Copy, Clone)] pub struct stat {
                     pub st_ino: ino_t,
                     pub st_nlink: nlink_t,
                     pub st_dev: dev_t,
@@ -1306,7 +1277,7 @@ pub mod types {
                     pub st_qspare2: int64_t,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct utimbuf {
+                #[derive(Copy, Clone)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
@@ -1322,7 +1293,7 @@ pub mod types {
         }
     }
 
-    #[cfg(target_os = "openbsd")]
+    #[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
     pub mod os {
         pub mod common {
             pub mod posix01 {
@@ -1332,9 +1303,28 @@ pub mod types {
                 use types::os::arch::c99::{uintptr_t};
 
                 pub type pthread_t = uintptr_t;
+                pub type rlim_t = u64;
+
+                #[cfg(target_os = "bitrig")]
+                #[repr(C)]
+                #[derive(Copy, Clone)] pub struct glob_t {
+                    pub gl_pathc:  c_int,
+                    pub gl_matchc: c_int,
+                    pub gl_offs:   c_int,
+                    pub gl_flags:  c_int,
+                    pub gl_pathv:  *mut *mut c_char,
+                    pub __unused1: *mut c_void,
+                    pub __unused2: *mut c_void,
+                    pub __unused3: *mut c_void,
+                    pub __unused4: *mut c_void,
+                    pub __unused5: *mut c_void,
+                    pub __unused6: *mut c_void,
+                    pub __unused7: *mut c_void,
+                }
 
+                #[cfg(target_os = "openbsd")]
                 #[repr(C)]
-                #[derive(Copy)] pub struct glob_t {
+                #[derive(Copy, Clone)] pub struct glob_t {
                     pub gl_pathc:  c_int,
                     pub __unused1: c_int,
                     pub gl_offs:   c_int,
@@ -1352,21 +1342,54 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct timeval {
+                #[derive(Copy, Clone)] pub struct timeval {
                     pub tv_sec: time_t,
                     pub tv_usec: suseconds_t,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct timespec {
+                #[derive(Copy, Clone)] pub struct timespec {
                     pub tv_sec: time_t,
                     pub tv_nsec: c_long,
                 }
 
-                #[derive(Copy)] pub enum timezone {}
+                pub enum timezone {}
 
                 pub type sighandler_t = size_t;
+
+                #[repr(C)]
+                #[derive(Copy, Clone)]
+                pub struct rlimit {
+                    pub rlim_cur: rlim_t,
+                    pub rlim_max: rlim_t,
+                }
             }
+
+            pub mod bsd43 {
+                use types::os::common::posix01::timeval;
+                use types::os::arch::c95::c_long;
+                #[repr(C)]
+                #[derive(Copy, Clone)]
+                pub struct rusage {
+                    pub ru_utime: timeval,
+                    pub ru_stime: timeval,
+                    pub ru_maxrss: c_long,
+                    pub ru_ixrss: c_long,
+                    pub ru_idrss: c_long,
+                    pub ru_isrss: c_long,
+                    pub ru_minflt: c_long,
+                    pub ru_majflt: c_long,
+                    pub ru_nswap: c_long,
+                    pub ru_inblock: c_long,
+                    pub ru_oublock: c_long,
+                    pub ru_msgsnd: c_long,
+                    pub ru_msgrcv: c_long,
+                    pub ru_nsignals: c_long,
+                    pub ru_nvcsw: c_long,
+                    pub ru_nivcsw: c_long
+                }
+            }
+
             pub mod bsd44 {
                 use types::common::c95::{c_void};
                 use types::os::arch::c95::{c_char, c_int, c_uint};
@@ -1376,13 +1399,13 @@ pub mod types {
                 pub type in_port_t = u16;
                 pub type in_addr_t = u32;
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr {
+                #[derive(Copy, Clone)] pub struct sockaddr {
                     pub sa_len: u8,
                     pub sa_family: sa_family_t,
                     pub sa_data: [u8; 14],
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_storage {
+                #[derive(Copy, Clone)] pub struct sockaddr_storage {
                     pub ss_len: u8,
                     pub ss_family: sa_family_t,
                     pub __ss_pad1: [u8; 6],
@@ -1390,7 +1413,7 @@ pub mod types {
                     pub __ss_pad3: [u8; 240],
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_in {
+                #[derive(Copy, Clone)] pub struct sockaddr_in {
                     pub sin_len: u8,
                     pub sin_family: sa_family_t,
                     pub sin_port: in_port_t,
@@ -1398,11 +1421,11 @@ pub mod types {
                     pub sin_zero: [u8; 8],
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct in_addr {
+                #[derive(Copy, Clone)] pub struct in_addr {
                     pub s_addr: in_addr_t,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_in6 {
+                #[derive(Copy, Clone)] pub struct sockaddr_in6 {
                     pub sin6_len: u8,
                     pub sin6_family: sa_family_t,
                     pub sin6_port: in_port_t,
@@ -1411,21 +1434,21 @@ pub mod types {
                     pub sin6_scope_id: u32,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct in6_addr {
+                #[derive(Copy, Clone)] pub struct in6_addr {
                     pub s6_addr: [u16; 8]
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ip_mreq {
+                #[derive(Copy, Clone)] pub struct ip_mreq {
                     pub imr_multiaddr: in_addr,
                     pub imr_interface: in_addr,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ip6_mreq {
+                #[derive(Copy, Clone)] pub struct ip6_mreq {
                     pub ipv6mr_multiaddr: in6_addr,
                     pub ipv6mr_interface: c_uint,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct addrinfo {
+                #[derive(Copy, Clone)] pub struct addrinfo {
                     pub ai_flags: c_int,
                     pub ai_family: c_int,
                     pub ai_socktype: c_int,
@@ -1436,13 +1459,13 @@ pub mod types {
                     pub ai_next: *mut addrinfo,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_un {
+                #[derive(Copy, Clone)] pub struct sockaddr_un {
                     pub sun_len: u8,
                     pub sun_family: sa_family_t,
                     pub sun_path: [c_char; 104]
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ifaddrs {
+                #[derive(Copy, Clone)] pub struct ifaddrs {
                     pub ifa_next: *mut ifaddrs,
                     pub ifa_name: *mut c_char,
                     pub ifa_flags: c_uint,
@@ -1451,7 +1474,6 @@ pub mod types {
                     pub ifa_dstaddr: *mut sockaddr,
                     pub ifa_data: *mut c_void
                 }
-
             }
         }
 
@@ -1485,15 +1507,15 @@ pub mod types {
                 pub type uintmax_t = u64;
             }
             pub mod posix88 {
+                use types::os::arch::c95::{c_long};
                 pub type off_t = i64;
-                pub type dev_t = u32;
-                pub type ino_t = u64;
+                pub type dev_t = i32;
                 pub type pid_t = i32;
                 pub type uid_t = u32;
                 pub type gid_t = u32;
                 pub type useconds_t = u32;
                 pub type mode_t = u32;
-                pub type ssize_t = i64;
+                pub type ssize_t = c_long;
             }
             pub mod posix01 {
                 use types::common::c95::{c_void};
@@ -1503,14 +1525,14 @@ pub mod types {
                 use types::os::arch::posix88::{mode_t, off_t};
                 use types::os::arch::posix88::{uid_t};
 
-                pub type nlink_t = u32;
+                pub type nlink_t = uint32_t;
                 pub type blksize_t = uint32_t;
                 pub type ino_t = uint64_t;
                 pub type blkcnt_t = i64;
                 pub type fflags_t = u32; // type not declared, but struct stat have u_int32_t
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct stat {
+                #[derive(Copy, Clone)] pub struct stat {
                     pub st_mode: mode_t,
                     pub st_dev: dev_t,
                     pub st_ino: ino_t,
@@ -1533,7 +1555,7 @@ pub mod types {
                     pub st_birthtime_nsec: c_long,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct utimbuf {
+                #[derive(Copy, Clone)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
@@ -1560,7 +1582,7 @@ pub mod types {
                 // pub Note: this is the struct called stat64 in Windows. Not stat,
                 // nor stati64.
                 #[repr(C)]
-                #[derive(Copy)] pub struct stat {
+                #[derive(Copy, Clone)] pub struct stat {
                     pub st_dev: dev_t,
                     pub st_ino: ino_t,
                     pub st_mode: u16,
@@ -1576,24 +1598,24 @@ pub mod types {
 
                 // note that this is called utimbuf64 in Windows
                 #[repr(C)]
-                #[derive(Copy)] pub struct utimbuf {
+                #[derive(Copy, Clone)] pub struct utimbuf {
                     pub actime: time64_t,
                     pub modtime: time64_t,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct timeval {
+                #[derive(Copy, Clone)] pub struct timeval {
                     pub tv_sec: c_long,
                     pub tv_usec: c_long,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct timespec {
+                #[derive(Copy, Clone)] pub struct timespec {
                     pub tv_sec: time_t,
                     pub tv_nsec: c_long,
                 }
 
-                #[derive(Copy)] pub enum timezone {}
+                pub enum timezone {}
             }
 
             pub mod bsd44 {
@@ -1606,7 +1628,7 @@ pub mod types {
                 pub type in_port_t = u16;
                 pub type in_addr_t = u32;
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr {
+                #[derive(Copy, Clone)] pub struct sockaddr {
                     pub sa_family: sa_family_t,
                     pub sa_data: [u8; 14],
                 }
@@ -1617,19 +1639,22 @@ pub mod types {
                     pub __ss_align: i64,
                     pub __ss_pad2: [u8; 112],
                 }
+                impl ::core::clone::Clone for sockaddr_storage {
+                    fn clone(&self) -> sockaddr_storage { *self }
+                }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_in {
+                #[derive(Copy, Clone)] 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)]
-                #[derive(Copy)] pub struct in_addr {
+                #[derive(Copy, Clone)] pub struct in_addr {
                     pub s_addr: in_addr_t,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_in6 {
+                #[derive(Copy, Clone)] pub struct sockaddr_in6 {
                     pub sin6_family: sa_family_t,
                     pub sin6_port: in_port_t,
                     pub sin6_flowinfo: u32,
@@ -1637,21 +1662,21 @@ pub mod types {
                     pub sin6_scope_id: u32,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct in6_addr {
+                #[derive(Copy, Clone)] pub struct in6_addr {
                     pub s6_addr: [u16; 8]
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ip_mreq {
+                #[derive(Copy, Clone)] pub struct ip_mreq {
                     pub imr_multiaddr: in_addr,
                     pub imr_interface: in_addr,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct ip6_mreq {
+                #[derive(Copy, Clone)] pub struct ip6_mreq {
                     pub ipv6mr_multiaddr: in6_addr,
                     pub ipv6mr_interface: c_uint,
                 }
                 #[repr(C)]
-                #[derive(Copy)] pub struct addrinfo {
+                #[derive(Copy, Clone)] pub struct addrinfo {
                     pub ai_flags: c_int,
                     pub ai_family: c_int,
                     pub ai_socktype: c_int,
@@ -1666,6 +1691,9 @@ pub mod types {
                     pub sun_family: sa_family_t,
                     pub sun_path: [c_char; 108]
                 }
+                impl ::core::clone::Clone for sockaddr_un {
+                    fn clone(&self) -> sockaddr_un { *self }
+                }
             }
         }
 
@@ -1791,7 +1819,7 @@ pub mod types {
                 pub type LPCH = *mut CHAR;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct SECURITY_ATTRIBUTES {
+                #[derive(Copy, Clone)] pub struct SECURITY_ATTRIBUTES {
                     pub nLength: DWORD,
                     pub lpSecurityDescriptor: LPVOID,
                     pub bInheritHandle: BOOL,
@@ -1815,7 +1843,7 @@ pub mod types {
                 pub type int64 = i64;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct STARTUPINFO {
+                #[derive(Copy, Clone)] pub struct STARTUPINFO {
                     pub cb: DWORD,
                     pub lpReserved: LPWSTR,
                     pub lpDesktop: LPWSTR,
@@ -1838,7 +1866,7 @@ pub mod types {
                 pub type LPSTARTUPINFO = *mut STARTUPINFO;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct PROCESS_INFORMATION {
+                #[derive(Copy, Clone)] pub struct PROCESS_INFORMATION {
                     pub hProcess: HANDLE,
                     pub hThread: HANDLE,
                     pub dwProcessId: DWORD,
@@ -1847,7 +1875,7 @@ pub mod types {
                 pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct SYSTEM_INFO {
+                #[derive(Copy, Clone)] pub struct SYSTEM_INFO {
                     pub wProcessorArchitecture: WORD,
                     pub wReserved: WORD,
                     pub dwPageSize: DWORD,
@@ -1863,7 +1891,7 @@ pub mod types {
                 pub type LPSYSTEM_INFO = *mut SYSTEM_INFO;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct MEMORY_BASIC_INFORMATION {
+                #[derive(Copy, Clone)] pub struct MEMORY_BASIC_INFORMATION {
                     pub BaseAddress: LPVOID,
                     pub AllocationBase: LPVOID,
                     pub AllocationProtect: DWORD,
@@ -1875,7 +1903,7 @@ pub mod types {
                 pub type LPMEMORY_BASIC_INFORMATION = *mut MEMORY_BASIC_INFORMATION;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct OVERLAPPED {
+                #[derive(Copy, Clone)] pub struct OVERLAPPED {
                     pub Internal: *mut c_ulong,
                     pub InternalHigh: *mut c_ulong,
                     pub Offset: DWORD,
@@ -1886,7 +1914,7 @@ pub mod types {
                 pub type LPOVERLAPPED = *mut OVERLAPPED;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct FILETIME {
+                #[derive(Copy, Clone)] pub struct FILETIME {
                     pub dwLowDateTime: DWORD,
                     pub dwHighDateTime: DWORD,
                 }
@@ -1894,7 +1922,7 @@ pub mod types {
                 pub type LPFILETIME = *mut FILETIME;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct GUID {
+                #[derive(Copy, Clone)] pub struct GUID {
                     pub Data1: DWORD,
                     pub Data2: WORD,
                     pub Data3: WORD,
@@ -1902,7 +1930,7 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct WSAPROTOCOLCHAIN {
+                #[derive(Copy, Clone)] pub struct WSAPROTOCOLCHAIN {
                     pub ChainLen: c_int,
                     pub ChainEntries: [DWORD; MAX_PROTOCOL_CHAIN as usize],
                 }
@@ -1932,6 +1960,9 @@ pub mod types {
                     pub dwProviderReserved: DWORD,
                     pub szProtocol: [u8; WSAPROTOCOL_LEN as usize + 1],
                 }
+                impl ::core::clone::Clone for WSAPROTOCOL_INFO {
+                    fn clone(&self) -> WSAPROTOCOL_INFO { *self }
+                }
 
                 pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO;
 
@@ -1950,6 +1981,9 @@ pub mod types {
                     pub cFileName: [wchar_t; 260], // #define MAX_PATH 260
                     pub cAlternateFileName: [wchar_t; 14],
                 }
+                impl ::core::clone::Clone for WIN32_FIND_DATAW {
+                    fn clone(&self) -> WIN32_FIND_DATAW { *self }
+                }
 
                 pub type LPWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW;
             }
@@ -1966,9 +2000,10 @@ pub mod types {
                 use types::os::arch::c99::{uintptr_t};
 
                 pub type pthread_t = uintptr_t;
+                pub type rlim_t = u64;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct glob_t {
+                #[derive(Copy, Clone)] pub struct glob_t {
                     pub gl_pathc:  size_t,
                     pub __unused1: c_int,
                     pub gl_offs:   size_t,
@@ -1985,20 +2020,52 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct timeval {
+                #[derive(Copy, Clone)] pub struct timeval {
                     pub tv_sec: time_t,
                     pub tv_usec: suseconds_t,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct timespec {
+                #[derive(Copy, Clone)] pub struct timespec {
                     pub tv_sec: time_t,
                     pub tv_nsec: c_long,
                 }
 
-                #[derive(Copy)] pub enum timezone {}
+                pub enum timezone {}
 
                 pub type sighandler_t = size_t;
+
+                #[repr(C)]
+                #[derive(Copy, Clone)]
+                pub struct rlimit {
+                    pub rlim_cur: rlim_t,
+                    pub rlim_max: rlim_t,
+                }
+            }
+
+            pub mod bsd43 {
+                use types::os::common::posix01::timeval;
+                use types::os::arch::c95::c_long;
+                #[repr(C)]
+                #[derive(Copy, Clone)]
+                pub struct rusage {
+                    pub ru_utime: timeval,
+                    pub ru_stime: timeval,
+                    pub ru_maxrss: c_long,
+                    pub ru_ixrss: c_long,
+                    pub ru_idrss: c_long,
+                    pub ru_isrss: c_long,
+                    pub ru_minflt: c_long,
+                    pub ru_majflt: c_long,
+                    pub ru_nswap: c_long,
+                    pub ru_inblock: c_long,
+                    pub ru_oublock: c_long,
+                    pub ru_msgsnd: c_long,
+                    pub ru_msgrcv: c_long,
+                    pub ru_nsignals: c_long,
+                    pub ru_nvcsw: c_long,
+                    pub ru_nivcsw: c_long
+                }
             }
 
             pub mod bsd44 {
@@ -2010,7 +2077,7 @@ pub mod types {
                 pub type in_port_t = u16;
                 pub type in_addr_t = u32;
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr {
+                #[derive(Copy, Clone)] pub struct sockaddr {
                     pub sa_len: u8,
                     pub sa_family: sa_family_t,
                     pub sa_data: [u8; 14],
@@ -2024,9 +2091,12 @@ pub mod types {
                     pub __ss_align: i64,
                     pub __ss_pad2: [u8; 112],
                 }
+                impl ::core::clone::Clone for sockaddr_storage {
+                    fn clone(&self) -> sockaddr_storage { *self }
+                }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_in {
+                #[derive(Copy, Clone)] pub struct sockaddr_in {
                     pub sin_len: u8,
                     pub sin_family: sa_family_t,
                     pub sin_port: in_port_t,
@@ -2035,12 +2105,12 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct in_addr {
+                #[derive(Copy, Clone)] pub struct in_addr {
                     pub s_addr: in_addr_t,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct sockaddr_in6 {
+                #[derive(Copy, Clone)] pub struct sockaddr_in6 {
                     pub sin6_len: u8,
                     pub sin6_family: sa_family_t,
                     pub sin6_port: in_port_t,
@@ -2050,24 +2120,24 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct in6_addr {
+                #[derive(Copy, Clone)] pub struct in6_addr {
                     pub s6_addr: [u16; 8]
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct ip_mreq {
+                #[derive(Copy, Clone)] pub struct ip_mreq {
                     pub imr_multiaddr: in_addr,
                     pub imr_interface: in_addr,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct ip6_mreq {
+                #[derive(Copy, Clone)] pub struct ip6_mreq {
                     pub ipv6mr_multiaddr: in6_addr,
                     pub ipv6mr_interface: c_uint,
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct addrinfo {
+                #[derive(Copy, Clone)] pub struct addrinfo {
                     pub ai_flags: c_int,
                     pub ai_family: c_int,
                     pub ai_socktype: c_int,
@@ -2084,9 +2154,12 @@ pub mod types {
                     pub sun_family: sa_family_t,
                     pub sun_path: [c_char; 104]
                 }
+                impl ::core::clone::Clone for sockaddr_un {
+                    fn clone(&self) -> sockaddr_un { *self }
+                }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct ifaddrs {
+                #[derive(Copy, Clone)] pub struct ifaddrs {
                     pub ifa_next: *mut ifaddrs,
                     pub ifa_name: *mut c_char,
                     pub ifa_flags: c_uint,
@@ -2151,7 +2224,7 @@ pub mod types {
                 pub type blkcnt_t = i64;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct stat {
+                #[derive(Copy, Clone)] pub struct stat {
                     pub st_dev: dev_t,
                     pub st_mode: mode_t,
                     pub st_nlink: nlink_t,
@@ -2177,7 +2250,7 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct utimbuf {
+                #[derive(Copy, Clone)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
@@ -2187,6 +2260,9 @@ pub mod types {
                     pub __sig: c_long,
                     pub __opaque: [c_char; 36]
                 }
+                impl ::core::clone::Clone for pthread_attr_t {
+                    fn clone(&self) -> pthread_attr_t { *self }
+                }
             }
             pub mod posix08 {
             }
@@ -2194,7 +2270,7 @@ pub mod types {
             }
             pub mod extra {
                 #[repr(C)]
-                #[derive(Copy)] pub struct mach_timebase_info {
+                #[derive(Copy, Clone)] pub struct mach_timebase_info {
                     pub numer: u32,
                     pub denom: u32,
                 }
@@ -2257,7 +2333,7 @@ pub mod types {
                 pub type blkcnt_t = i64;
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct stat {
+                #[derive(Copy, Clone)] pub struct stat {
                     pub st_dev: dev_t,
                     pub st_mode: mode_t,
                     pub st_nlink: nlink_t,
@@ -2283,7 +2359,7 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                #[derive(Copy)] pub struct utimbuf {
+                #[derive(Copy, Clone)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
@@ -2293,6 +2369,9 @@ pub mod types {
                     pub __sig: c_long,
                     pub __opaque: [c_char; 56]
                 }
+                impl ::core::clone::Clone for pthread_attr_t {
+                    fn clone(&self) -> pthread_attr_t { *self }
+                }
             }
             pub mod posix08 {
             }
@@ -2300,7 +2379,7 @@ pub mod types {
             }
             pub mod extra {
                 #[repr(C)]
-                #[derive(Copy)] pub struct mach_timebase_info {
+                #[derive(Copy, Clone)] pub struct mach_timebase_info {
                     pub numer: u32,
                     pub denom: u32,
                 }
@@ -2330,11 +2409,11 @@ pub mod consts {
             pub const _IOFBF : c_int = 0;
             pub const _IONBF : c_int = 4;
             pub const _IOLBF : c_int = 64;
-            pub const BUFSIZ : c_uint = 512_u32;
-            pub const FOPEN_MAX : c_uint = 20_u32;
-            pub const FILENAME_MAX : c_uint = 260_u32;
-            pub const L_tmpnam : c_uint = 16_u32;
-            pub const TMP_MAX : c_uint = 32767_u32;
+            pub const BUFSIZ : c_uint = 512;
+            pub const FOPEN_MAX : c_uint = 20;
+            pub const FILENAME_MAX : c_uint = 260;
+            pub const L_tmpnam : c_uint = 16;
+            pub const TMP_MAX : c_uint = 32767;
 
             pub const WSAEINTR: c_int = 10004;
             pub const WSAEBADF: c_int = 10009;
@@ -2393,6 +2472,7 @@ pub mod consts {
         }
         pub mod posix88 {
             use types::os::arch::c95::c_int;
+            use types::os::arch::posix88::mode_t;
 
             pub const O_RDONLY : c_int = 0;
             pub const O_WRONLY : c_int = 1;
@@ -2415,6 +2495,14 @@ pub mod consts {
             pub const S_IXUSR : c_int = 64;
             pub const S_IWUSR : c_int = 128;
             pub const S_IRUSR : c_int = 256;
+            pub const S_IRWXG : mode_t = 56;
+            pub const S_IXGRP : mode_t = 8;
+            pub const S_IWGRP : mode_t = 16;
+            pub const S_IRGRP : mode_t = 32;
+            pub const S_IRWXO : mode_t = 7;
+            pub const S_IXOTH : mode_t = 1;
+            pub const S_IWOTH : mode_t = 2;
+            pub const S_IROTH : mode_t = 4;
             pub const F_OK : c_int = 0;
             pub const R_OK : c_int = 4;
             pub const W_OK : c_int = 2;
@@ -2449,10 +2537,24 @@ pub mod consts {
 
             pub const TCP_NODELAY: c_int = 0x0001;
             pub const SOL_SOCKET: c_int = 0xffff;
-            pub const SO_KEEPALIVE: c_int = 8;
-            pub const SO_BROADCAST: c_int = 32;
-            pub const SO_REUSEADDR: c_int = 4;
+
+            pub const SO_DEBUG: c_int = 0x0001;
+            pub const SO_ACCEPTCONN: c_int = 0x0002;
+            pub const SO_REUSEADDR: c_int = 0x0004;
+            pub const SO_KEEPALIVE: c_int = 0x0008;
+            pub const SO_DONTROUTE: c_int = 0x0010;
+            pub const SO_BROADCAST: c_int = 0x0020;
+            pub const SO_USELOOPBACK: c_int = 0x0040;
+            pub const SO_LINGER: c_int = 0x0080;
+            pub const SO_OOBINLINE: c_int = 0x0100;
+            pub const SO_SNDBUF: c_int = 0x1001;
+            pub const SO_RCVBUF: c_int = 0x1002;
+            pub const SO_SNDLOWAT: c_int = 0x1003;
+            pub const SO_RCVLOWAT: c_int = 0x1004;
+            pub const SO_SNDTIMEO: c_int = 0x1005;
+            pub const SO_RCVTIMEO: c_int = 0x1006;
             pub const SO_ERROR: c_int = 0x1007;
+            pub const SO_TYPE: c_int = 0x1008;
 
             pub const IFF_LOOPBACK: c_int = 4;
 
@@ -2461,7 +2563,7 @@ pub mod consts {
             pub const SHUT_RDWR: c_int = 2;
         }
         pub mod extra {
-            use SOCKET;
+            use types::os::common::bsd44::SOCKET;
             use types::os::arch::c95::{c_int, c_long};
             use types::os::arch::extra::{WORD, DWORD, BOOL, HANDLE};
 
@@ -2492,7 +2594,7 @@ pub mod consts {
             pub const ERROR_IO_PENDING: c_int = 997;
             pub const ERROR_FILE_INVALID : c_int = 1006;
             pub const ERROR_NOT_FOUND: c_int = 1168;
-            pub const INVALID_HANDLE_VALUE: HANDLE = -1 as HANDLE;
+            pub const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE;
 
             pub const DELETE : DWORD = 0x00010000;
             pub const READ_CONTROL : DWORD = 0x00020000;
@@ -2530,12 +2632,12 @@ pub mod consts {
             pub const WAIT_ABANDONED : DWORD = 0x00000080;
             pub const WAIT_OBJECT_0 : DWORD = 0x00000000;
             pub const WAIT_TIMEOUT : DWORD = 0x00000102;
-            pub const WAIT_FAILED : DWORD = -1;
+            pub const WAIT_FAILED : DWORD = !0;
 
             pub const DUPLICATE_CLOSE_SOURCE : DWORD = 0x00000001;
             pub const DUPLICATE_SAME_ACCESS : DWORD = 0x00000002;
 
-            pub const INFINITE : DWORD = -1;
+            pub const INFINITE : DWORD = !0;
             pub const STILL_ACTIVE : DWORD = 259;
 
             pub const MEM_COMMIT : DWORD = 0x00001000;
@@ -2696,7 +2798,7 @@ pub mod consts {
     }
 
 
-    #[cfg(any(target_os = "linux", target_os = "android"))]
+    #[cfg(any(target_os = "linux", target_os = "android", target_os = "nacl"))]
     pub mod os {
         pub mod c95 {
             use types::os::arch::c95::{c_int, c_uint};
@@ -2711,11 +2813,11 @@ pub mod consts {
             pub const _IOFBF : c_int = 0;
             pub const _IONBF : c_int = 2;
             pub const _IOLBF : c_int = 1;
-            pub const BUFSIZ : c_uint = 8192_u32;
-            pub const FOPEN_MAX : c_uint = 16_u32;
-            pub const FILENAME_MAX : c_uint = 4096_u32;
-            pub const L_tmpnam : c_uint = 20_u32;
-            pub const TMP_MAX : c_uint = 238328_u32;
+            pub const BUFSIZ : c_uint = 8192;
+            pub const FOPEN_MAX : c_uint = 16;
+            pub const FILENAME_MAX : c_uint = 4096;
+            pub const L_tmpnam : c_uint = 20;
+            pub const TMP_MAX : c_uint = 238328;
         }
         pub mod c99 {
         }
@@ -2723,6 +2825,7 @@ pub mod consts {
                   target_arch = "x86_64",
                   target_arch = "arm",
                   target_arch = "aarch64",
+                  target_arch = "le32",
                   target_arch = "powerpc"))]
         pub mod posix88 {
             use types::os::arch::c95::c_int;
@@ -2750,6 +2853,14 @@ pub mod consts {
             pub const S_IXUSR : mode_t = 64;
             pub const S_IWUSR : mode_t = 128;
             pub const S_IRUSR : mode_t = 256;
+            pub const S_IRWXG : mode_t = 56;
+            pub const S_IXGRP : mode_t = 8;
+            pub const S_IWGRP : mode_t = 16;
+            pub const S_IRGRP : mode_t = 32;
+            pub const S_IRWXO : mode_t = 7;
+            pub const S_IXOTH : mode_t = 1;
+            pub const S_IWOTH : mode_t = 2;
+            pub const S_IROTH : mode_t = 4;
             pub const F_OK : c_int = 0;
             pub const R_OK : c_int = 4;
             pub const W_OK : c_int = 2;
@@ -2784,7 +2895,7 @@ pub mod consts {
             pub const MAP_FIXED : c_int = 0x0010;
             pub const MAP_ANON : c_int = 0x0020;
 
-            pub const MAP_FAILED : *mut c_void = -1 as *mut c_void;
+            pub const MAP_FAILED : *mut c_void = !0 as *mut c_void;
 
             pub const MCL_CURRENT : c_int = 0x0001;
             pub const MCL_FUTURE : c_int = 0x0002;
@@ -2963,6 +3074,14 @@ pub mod consts {
             pub const S_IXUSR : mode_t = 64;
             pub const S_IWUSR : mode_t = 128;
             pub const S_IRUSR : mode_t = 256;
+            pub const S_IRWXG : mode_t = 56;
+            pub const S_IXGRP : mode_t = 8;
+            pub const S_IWGRP : mode_t = 16;
+            pub const S_IRGRP : mode_t = 32;
+            pub const S_IRWXO : mode_t = 7;
+            pub const S_IXOTH : mode_t = 1;
+            pub const S_IWOTH : mode_t = 2;
+            pub const S_IROTH : mode_t = 4;
             pub const F_OK : c_int = 0;
             pub const R_OK : c_int = 4;
             pub const W_OK : c_int = 2;
@@ -3146,8 +3265,10 @@ pub mod consts {
 
             pub const EDQUOT: c_int = 1133;
         }
+        #[cfg(not(target_os = "nacl"))]
         pub mod posix01 {
             use types::os::arch::c95::{c_int, size_t};
+            use types::os::common::posix01::rlim_t;
 
             pub const F_DUPFD : c_int = 0;
             pub const F_GETFD : c_int = 1;
@@ -3156,7 +3277,6 @@ pub mod consts {
             pub const F_SETFL : c_int = 4;
 
             pub const SIGTRAP : c_int = 5;
-            pub const SIGPIPE: c_int = 13;
             pub const SIG_IGN: size_t = 1;
 
             pub const GLOB_ERR      : c_int = 1 << 0;
@@ -3227,6 +3347,126 @@ pub mod consts {
 
             pub const CLOCK_REALTIME: c_int = 0;
             pub const CLOCK_MONOTONIC: c_int = 1;
+
+            pub const RLIMIT_CPU: c_int = 0;
+            pub const RLIMIT_FSIZE: c_int = 1;
+            pub const RLIMIT_DATA: c_int = 2;
+            pub const RLIMIT_STACK: c_int = 3;
+            pub const RLIMIT_CORE: c_int = 4;
+            pub const RLIMIT_RSS: c_int = 5;
+            pub const RLIMIT_NOFILE: c_int = 7;
+            pub const RLIMIT_AS: c_int = 9;
+            pub const RLIMIT_NPROC: c_int = 6;
+            pub const RLIMIT_MEMLOCK: c_int = 8;
+            pub const RLIMIT_LOCKS: c_int = 10;
+            pub const RLIMIT_SIGPENDING: c_int = 11;
+            pub const RLIMIT_MSGQUEUE: c_int = 12;
+            pub const RLIMIT_NICE: c_int = 13;
+            pub const RLIMIT_RTPRIO: c_int = 14;
+            pub const RLIMIT_RTTIME: c_int = 15;
+            pub const RLIMIT_NLIMITS: c_int = 16;
+            pub const RLIM_INFINITY: rlim_t = 0xffff_ffff_ffff_ffff;
+            pub const RLIM_SAVED_MAX: rlim_t = RLIM_INFINITY;
+            pub const RLIM_SAVED_CUR: rlim_t = RLIM_INFINITY;
+
+            pub const RUSAGE_SELF: c_int = 0;
+            pub const RUSAGE_CHILDREN: c_int = -1;
+            pub const RUSAGE_THREAD: c_int = 1;
+        }
+        #[cfg(target_os = "nacl")]
+        pub mod posix01 {
+            use types::os::arch::c95::{c_int, size_t};
+            use types::os::common::posix01::rlim_t;
+
+            pub const F_DUPFD : c_int = 0;
+            pub const F_GETFD : c_int = 1;
+            pub const F_SETFD : c_int = 2;
+            pub const F_GETFL : c_int = 3;
+            pub const F_SETFL : c_int = 4;
+
+            pub const SIGTRAP : c_int = 5;
+            pub const SIG_IGN: size_t = 1;
+
+            pub const GLOB_ERR      : c_int = 1 << 0;
+            pub const GLOB_MARK     : c_int = 1 << 1;
+            pub const GLOB_NOSORT   : c_int = 1 << 2;
+            pub const GLOB_DOOFFS   : c_int = 1 << 3;
+            pub const GLOB_NOCHECK  : c_int = 1 << 4;
+            pub const GLOB_APPEND   : c_int = 1 << 5;
+            pub const GLOB_NOESCAPE : c_int = 1 << 6;
+
+            pub const GLOB_NOSPACE  : c_int = 1;
+            pub const GLOB_ABORTED  : c_int = 2;
+            pub const GLOB_NOMATCH  : c_int = 3;
+
+            pub const POSIX_MADV_NORMAL : c_int = 0;
+            pub const POSIX_MADV_RANDOM : c_int = 1;
+            pub const POSIX_MADV_SEQUENTIAL : c_int = 2;
+            pub const POSIX_MADV_WILLNEED : c_int = 3;
+            pub const POSIX_MADV_DONTNEED : c_int = 4;
+
+            pub const _SC_MQ_PRIO_MAX : c_int = 28;
+            pub const _SC_IOV_MAX : c_int = 60;
+            pub const _SC_GETGR_R_SIZE_MAX : c_int = 69;
+            pub const _SC_GETPW_R_SIZE_MAX : c_int = 70;
+            pub const _SC_LOGIN_NAME_MAX : c_int = 71;
+            pub const _SC_TTY_NAME_MAX : c_int = 72;
+            pub const _SC_THREADS : c_int = 67;
+            pub const _SC_THREAD_SAFE_FUNCTIONS : c_int = 68;
+            pub const _SC_THREAD_DESTRUCTOR_ITERATIONS : c_int = 73;
+            pub const _SC_THREAD_KEYS_MAX : c_int = 74;
+            pub const _SC_THREAD_STACK_MIN : c_int = 75;
+            pub const _SC_THREAD_THREADS_MAX : c_int = 76;
+            pub const _SC_THREAD_ATTR_STACKADDR : c_int = 77;
+            pub const _SC_THREAD_ATTR_STACKSIZE : c_int = 78;
+            pub const _SC_THREAD_PRIORITY_SCHEDULING : c_int = 79;
+            pub const _SC_THREAD_PRIO_INHERIT : c_int = 80;
+            pub const _SC_THREAD_PRIO_PROTECT : c_int = 81;
+            pub const _SC_THREAD_PROCESS_SHARED : c_int = 82;
+            pub const _SC_ATEXIT_MAX : c_int = 87;
+            pub const _SC_XOPEN_VERSION : c_int = 89;
+            pub const _SC_XOPEN_XCU_VERSION : c_int = 90;
+            pub const _SC_XOPEN_UNIX : c_int = 91;
+            pub const _SC_XOPEN_CRYPT : c_int = 92;
+            pub const _SC_XOPEN_ENH_I18N : c_int = 93;
+            pub const _SC_XOPEN_SHM : c_int = 94;
+            pub const _SC_XOPEN_LEGACY : c_int = 129;
+            pub const _SC_XOPEN_REALTIME : c_int = 130;
+            pub const _SC_XOPEN_REALTIME_THREADS : c_int = 131;
+
+            pub const PTHREAD_CREATE_JOINABLE: c_int = 1;
+            pub const PTHREAD_CREATE_DETACHED: c_int = 0;
+
+            pub const PTHREAD_STACK_MIN: size_t = 1024;
+
+            pub const CLOCK_REALTIME: c_int = 0;
+            pub const CLOCK_MONOTONIC: c_int = 1;
+
+            pub const RLIMIT_CPU: c_int = 0;
+            pub const RLIMIT_FSIZE: c_int = 1;
+            pub const RLIMIT_DATA: c_int = 2;
+            pub const RLIMIT_STACK: c_int = 3;
+            pub const RLIMIT_CORE: c_int = 4;
+            pub const RLIMIT_RSS: c_int = 5;
+            pub const RLIMIT_NOFILE: c_int = 7;
+            pub const RLIMIT_AS: c_int = 9;
+            pub const RLIMIT_NPROC: c_int = 6;
+            pub const RLIMIT_MEMLOCK: c_int = 8;
+            pub const RLIMIT_LOCKS: c_int = 10;
+            pub const RLIMIT_SIGPENDING: c_int = 11;
+            pub const RLIMIT_MSGQUEUE: c_int = 12;
+            pub const RLIMIT_NICE: c_int = 13;
+            pub const RLIMIT_RTPRIO: c_int = 14;
+            pub const RLIMIT_RTTIME: c_int = 15;
+            pub const RLIMIT_NLIMITS: c_int = 16;
+
+            pub const RLIM_INFINITY: rlim_t = 0xffff_ffff_ffff_ffff;
+            pub const RLIM_SAVED_MAX: rlim_t = RLIM_INFINITY;
+            pub const RLIM_SAVED_CUR: rlim_t = RLIM_INFINITY;
+
+            pub const RUSAGE_SELF: c_int = 0;
+            pub const RUSAGE_CHILDREN: c_int = -1;
+            pub const RUSAGE_THREAD: c_int = 1;
         }
         pub mod posix08 {
         }
@@ -3234,6 +3474,7 @@ pub mod consts {
                   target_arch = "aarch64",
                   target_arch = "x86",
                   target_arch = "x86_64",
+                  target_arch = "le32",
                   target_arch = "powerpc"))]
         pub mod bsd44 {
             use types::os::arch::c95::c_int;
@@ -3272,10 +3513,24 @@ pub mod consts {
 
             pub const TCP_NODELAY: c_int = 1;
             pub const SOL_SOCKET: c_int = 1;
-            pub const SO_KEEPALIVE: c_int = 9;
-            pub const SO_BROADCAST: c_int = 6;
+
+            pub const SO_DEBUG: c_int = 1;
             pub const SO_REUSEADDR: c_int = 2;
+            pub const SO_TYPE: c_int = 3;
             pub const SO_ERROR: c_int = 4;
+            pub const SO_DONTROUTE: c_int = 5;
+            pub const SO_BROADCAST: c_int = 6;
+            pub const SO_SNDBUF: c_int = 7;
+            pub const SO_RCVBUF: c_int = 8;
+            pub const SO_KEEPALIVE: c_int = 9;
+            pub const SO_OOBINLINE: c_int = 10;
+            pub const SO_LINGER: c_int = 13;
+            pub const SO_REUSEPORT: c_int = 15;
+            pub const SO_RCVLOWAT: c_int = 18;
+            pub const SO_SNDLOWAT: c_int = 19;
+            pub const SO_RCVTIMEO: c_int = 20;
+            pub const SO_SNDTIMEO: c_int = 21;
+            pub const SO_ACCEPTCONN: c_int = 30;
 
             pub const SHUT_RD: c_int = 0;
             pub const SHUT_WR: c_int = 1;
@@ -3318,10 +3573,24 @@ pub mod consts {
 
             pub const TCP_NODELAY: c_int = 1;
             pub const SOL_SOCKET: c_int = 65535;
-            pub const SO_KEEPALIVE: c_int = 8;
-            pub const SO_BROADCAST: c_int = 32;
-            pub const SO_REUSEADDR: c_int = 4;
-            pub const SO_ERROR: c_int = 4103;
+
+            pub const SO_DEBUG: c_int = 0x0001;
+            pub const SO_REUSEADDR: c_int = 0x0004;
+            pub const SO_KEEPALIVE: c_int = 0x0008;
+            pub const SO_DONTROUTE: c_int = 0x0010;
+            pub const SO_BROADCAST: c_int = 0x0020;
+            pub const SO_LINGER: c_int = 0x0080;
+            pub const SO_OOBINLINE: c_int = 0x100;
+            pub const SO_REUSEPORT: c_int = 0x0200;
+            pub const SO_SNDBUF: c_int = 0x1001;
+            pub const SO_RCVBUF: c_int = 0x1002;
+            pub const SO_SNDLOWAT: c_int = 0x1003;
+            pub const SO_RCVLOWAT: c_int = 0x1004;
+            pub const SO_SNDTIMEO: c_int = 0x1005;
+            pub const SO_RCVTIMEO: c_int = 0x1006;
+            pub const SO_ERROR: c_int = 0x1007;
+            pub const SO_TYPE: c_int = 0x1008;
+            pub const SO_ACCEPTCONN: c_int = 0x1009;
 
             pub const SHUT_RD: c_int = 0;
             pub const SHUT_WR: c_int = 1;
@@ -3331,6 +3600,7 @@ pub mod consts {
                   target_arch = "x86_64",
                   target_arch = "arm",
                   target_arch = "aarch64",
+                  target_arch = "le32",
                   target_arch = "powerpc"))]
         pub mod extra {
             use types::os::arch::c95::c_int;
@@ -3353,7 +3623,7 @@ pub mod consts {
             pub const MAP_DENYWRITE : c_int = 0x0800;
             pub const MAP_EXECUTABLE : c_int = 0x01000;
             pub const MAP_LOCKED : c_int = 0x02000;
-            pub const MAP_NONRESERVE : c_int = 0x04000;
+            pub const MAP_NORESERVE : c_int = 0x04000;
             pub const MAP_POPULATE : c_int = 0x08000;
             pub const MAP_NONBLOCK : c_int = 0x010000;
             pub const MAP_STACK : c_int = 0x020000;
@@ -3380,7 +3650,7 @@ pub mod consts {
             pub const MAP_DENYWRITE : c_int = 0x02000;
             pub const MAP_EXECUTABLE : c_int = 0x04000;
             pub const MAP_LOCKED : c_int = 0x08000;
-            pub const MAP_NONRESERVE : c_int = 0x0400;
+            pub const MAP_NORESERVE : c_int = 0x0400;
             pub const MAP_POPULATE : c_int = 0x010000;
             pub const MAP_NONBLOCK : c_int = 0x020000;
             pub const MAP_STACK : c_int = 0x040000;
@@ -3446,6 +3716,14 @@ pub mod consts {
             pub const _SC_XBS5_ILP32_OFFBIG : c_int = 126;
             pub const _SC_XBS5_LPBIG_OFFBIG : c_int = 128;
         }
+        #[cfg(target_os = "nacl")]
+        pub mod sysconf {
+            use types::os::arch::c95::c_int;
+
+            pub static _SC_SENDMSG_MAX_SIZE : c_int = 0;
+            pub static _SC_NPROCESSORS_ONLN : c_int = 1;
+            pub static _SC_PAGESIZE : c_int = 2;
+        }
         #[cfg(target_os = "android")]
         pub mod sysconf {
             use types::os::arch::c95::c_int;
@@ -3498,11 +3776,11 @@ pub mod consts {
             pub const _IOFBF : c_int = 0;
             pub const _IONBF : c_int = 2;
             pub const _IOLBF : c_int = 1;
-            pub const BUFSIZ : c_uint = 1024_u32;
-            pub const FOPEN_MAX : c_uint = 20_u32;
-            pub const FILENAME_MAX : c_uint = 1024_u32;
-            pub const L_tmpnam : c_uint = 1024_u32;
-            pub const TMP_MAX : c_uint = 308915776_u32;
+            pub const BUFSIZ : c_uint = 1024;
+            pub const FOPEN_MAX : c_uint = 20;
+            pub const FILENAME_MAX : c_uint = 1024;
+            pub const L_tmpnam : c_uint = 1024;
+            pub const TMP_MAX : c_uint = 308915776;
         }
         pub mod c99 {
         }
@@ -3532,6 +3810,14 @@ pub mod consts {
             pub const S_IXUSR : mode_t = 64;
             pub const S_IWUSR : mode_t = 128;
             pub const S_IRUSR : mode_t = 256;
+            pub const S_IRWXG : mode_t = 56;
+            pub const S_IXGRP : mode_t = 8;
+            pub const S_IWGRP : mode_t = 16;
+            pub const S_IRGRP : mode_t = 32;
+            pub const S_IRWXO : mode_t = 7;
+            pub const S_IXOTH : mode_t = 1;
+            pub const S_IWOTH : mode_t = 2;
+            pub const S_IROTH : mode_t = 4;
             pub const F_OK : c_int = 0;
             pub const R_OK : c_int = 4;
             pub const W_OK : c_int = 2;
@@ -3679,6 +3965,7 @@ pub mod consts {
         }
         pub mod posix01 {
             use types::os::arch::c95::{c_int, size_t};
+            use types::os::common::posix01::rlim_t;
 
             pub const F_DUPFD : c_int = 0;
             pub const F_GETFD : c_int = 1;
@@ -3687,7 +3974,6 @@ pub mod consts {
             pub const F_SETFL : c_int = 4;
 
             pub const SIGTRAP : c_int = 5;
-            pub const SIGPIPE: c_int = 13;
             pub const SIG_IGN: size_t = 1;
 
             pub const GLOB_APPEND   : c_int = 0x0001;
@@ -3755,6 +4041,29 @@ pub mod consts {
 
             pub const CLOCK_REALTIME: c_int = 0;
             pub const CLOCK_MONOTONIC: c_int = 4;
+
+            pub const RLIMIT_CPU: c_int = 0;
+            pub const RLIMIT_FSIZE: c_int = 1;
+            pub const RLIMIT_DATA: c_int = 2;
+            pub const RLIMIT_STACK: c_int = 3;
+            pub const RLIMIT_CORE: c_int = 4;
+            pub const RLIMIT_RSS: c_int = 5;
+            pub const RLIMIT_MEMLOCK: c_int = 6;
+            pub const RLIMIT_NPROC: c_int = 7;
+            pub const RLIMIT_NOFILE: c_int = 8;
+            pub const RLIMIT_SBSIZE: c_int = 9;
+            pub const RLIMIT_VMEM: c_int = 10;
+            pub const RLIMIT_AS: c_int = RLIMIT_VMEM;
+            pub const RLIMIT_NPTS: c_int = 11;
+            pub const RLIMIT_SWAP: c_int = 12;
+            pub const RLIMIT_KQUEUES: c_int = 13;
+
+            pub const RLIM_NLIMITS: rlim_t = 14;
+            pub const RLIM_INFINITY: rlim_t = 0x7fff_ffff_ffff_ffff;
+
+            pub const RUSAGE_SELF: c_int = 0;
+            pub const RUSAGE_CHILDREN: c_int = -1;
+            pub const RUSAGE_THREAD: c_int = 1;
         }
         pub mod posix08 {
         }
@@ -3801,10 +4110,24 @@ pub mod consts {
             pub const TCP_NODELAY: c_int = 1;
             pub const TCP_KEEPIDLE: c_int = 256;
             pub const SOL_SOCKET: c_int = 0xffff;
+            pub const SO_DEBUG: c_int = 0x01;
+            pub const SO_ACCEPTCONN: c_int = 0x0002;
+            pub const SO_REUSEADDR: c_int = 0x0004;
             pub const SO_KEEPALIVE: c_int = 0x0008;
+            pub const SO_DONTROUTE: c_int = 0x0010;
             pub const SO_BROADCAST: c_int = 0x0020;
-            pub const SO_REUSEADDR: c_int = 0x0004;
+            pub const SO_USELOOPBACK: c_int = 0x0040;
+            pub const SO_LINGER: c_int = 0x0080;
+            pub const SO_OOBINLINE: c_int = 0x0100;
+            pub const SO_REUSEPORT: c_int = 0x0200;
+            pub const SO_SNDBUF: c_int = 0x1001;
+            pub const SO_RCVBUF: c_int = 0x1002;
+            pub const SO_SNDLOWAT: c_int = 0x1003;
+            pub const SO_RCVLOWAT: c_int = 0x1004;
+            pub const SO_SNDTIMEO: c_int = 0x1005;
+            pub const SO_RCVTIMEO: c_int = 0x1006;
             pub const SO_ERROR: c_int = 0x1007;
+            pub const SO_TYPE: c_int = 0x1008;
 
             pub const IFF_LOOPBACK: c_int = 0x8;
 
@@ -3892,7 +4215,7 @@ pub mod consts {
         }
     }
 
-    #[cfg(target_os = "openbsd")]
+    #[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
     pub mod os {
         pub mod c95 {
             use types::os::arch::c95::{c_int, c_uint};
@@ -3907,11 +4230,11 @@ pub mod consts {
             pub const _IOFBF : c_int = 0;
             pub const _IONBF : c_int = 2;
             pub const _IOLBF : c_int = 1;
-            pub const BUFSIZ : c_uint = 1024_u32;
-            pub const FOPEN_MAX : c_uint = 20_u32;
-            pub const FILENAME_MAX : c_uint = 1024_u32;
-            pub const L_tmpnam : c_uint = 1024_u32;
-            pub const TMP_MAX : c_uint = 308915776_u32;
+            pub const BUFSIZ : c_uint = 1024;
+            pub const FOPEN_MAX : c_uint = 20;
+            pub const FILENAME_MAX : c_uint = 1024;
+            pub const L_tmpnam : c_uint = 1024;
+            pub const TMP_MAX : c_uint = 308915776;
         }
         pub mod c99 {
         }
@@ -3941,6 +4264,14 @@ pub mod consts {
             pub const S_IXUSR : mode_t = 64;
             pub const S_IWUSR : mode_t = 128;
             pub const S_IRUSR : mode_t = 256;
+            pub const S_IRWXG : mode_t = 56;
+            pub const S_IXGRP : mode_t = 8;
+            pub const S_IWGRP : mode_t = 16;
+            pub const S_IRGRP : mode_t = 32;
+            pub const S_IRWXO : mode_t = 7;
+            pub const S_IXOTH : mode_t = 1;
+            pub const S_IWOTH : mode_t = 2;
+            pub const S_IROTH : mode_t = 4;
             pub const F_OK : c_int = 0;
             pub const R_OK : c_int = 4;
             pub const W_OK : c_int = 2;
@@ -3980,11 +4311,11 @@ pub mod consts {
             pub const MCL_CURRENT : c_int = 0x0001;
             pub const MCL_FUTURE : c_int = 0x0002;
 
-            pub const MS_SYNC : c_int = 0x0002; // changed
             pub const MS_ASYNC : c_int = 0x0001;
-            pub const MS_INVALIDATE : c_int = 0x0004; // changed
+            pub const MS_SYNC : c_int = 0x0002;
+            pub const MS_INVALIDATE : c_int = 0x0004;
 
-            pub const EPERM : c_int = 1; // not checked
+            pub const EPERM : c_int = 1;
             pub const ENOENT : c_int = 2;
             pub const ESRCH : c_int = 3;
             pub const EINTR : c_int = 4;
@@ -4066,37 +4397,35 @@ pub mod consts {
             pub const EFTYPE : c_int = 79;
             pub const EAUTH : c_int = 80;
             pub const ENEEDAUTH : c_int = 81;
-            pub const EIDRM : c_int = 82;
-            pub const ENOMSG : c_int = 83;
-            pub const EOVERFLOW : c_int = 84;
-            pub const ECANCELED : c_int = 85;
-            pub const EILSEQ : c_int = 86;
-            pub const ENOATTR : c_int = 87;
-            pub const EDOOFUS : c_int = 88;
-            pub const EBADMSG : c_int = 89;
-            pub const EMULTIHOP : c_int = 90;
-            pub const ENOLINK : c_int = 91;
-            pub const EPROTO : c_int = 92;
-            pub const ENOMEDIUM : c_int = 93;
-            pub const EUNUSED94 : c_int = 94;
-            pub const EUNUSED95 : c_int = 95;
-            pub const EUNUSED96 : c_int = 96;
-            pub const EUNUSED97 : c_int = 97;
-            pub const EUNUSED98 : c_int = 98;
-            pub const EASYNC : c_int = 99;
-            pub const ELAST : c_int = 99;
+            pub const EIPSEC : c_int = 82;
+            pub const ENOATTR : c_int = 83;
+            pub const EILSEQ : c_int = 84;
+            pub const ENOMEDIUM : c_int = 85;
+            pub const EMEDIUMTYPE : c_int = 86;
+            pub const EOVERFLOW : c_int = 87;
+            pub const ECANCELED : c_int = 88;
+            pub const EIDRM : c_int = 89;
+            pub const ENOMSG : c_int = 90;
+            pub const ENOTSUP : c_int = 91;
+            pub const ELAST : c_int = 91; // must be equal to largest errno
         }
         pub mod posix01 {
             use types::os::arch::c95::{c_int, size_t};
+            use types::os::common::posix01::rlim_t;
 
             pub const F_DUPFD : c_int = 0;
             pub const F_GETFD : c_int = 1;
             pub const F_SETFD : c_int = 2;
             pub const F_GETFL : c_int = 3;
             pub const F_SETFL : c_int = 4;
+            pub const F_GETOWN : c_int = 5;
+            pub const F_SETOWN : c_int = 6;
+            pub const F_GETLK : c_int = 7;
+            pub const F_SETLK : c_int = 8;
+            pub const F_SETLKW : c_int = 9;
+            pub const F_DUPFD_CLOEXEC : c_int = 10;
 
             pub const SIGTRAP : c_int = 5;
-            pub const SIGPIPE: c_int = 13;
             pub const SIG_IGN: size_t = 1;
 
             pub const GLOB_APPEND   : c_int = 0x0001;
@@ -4105,11 +4434,12 @@ pub mod consts {
             pub const GLOB_MARK     : c_int = 0x0008;
             pub const GLOB_NOCHECK  : c_int = 0x0010;
             pub const GLOB_NOSORT   : c_int = 0x0020;
-            pub const GLOB_NOESCAPE : c_int = 0x1000; // changed
+            pub const GLOB_NOESCAPE : c_int = 0x1000;
 
             pub const GLOB_NOSPACE  : c_int = -1;
             pub const GLOB_ABORTED  : c_int = -2;
             pub const GLOB_NOMATCH  : c_int = -3;
+            pub const GLOB_NOSYS : c_int = -4;
 
             pub const POSIX_MADV_NORMAL : c_int = 0;
             pub const POSIX_MADV_RANDOM : c_int = 1;
@@ -4117,7 +4447,7 @@ pub mod consts {
             pub const POSIX_MADV_WILLNEED : c_int = 3;
             pub const POSIX_MADV_DONTNEED : c_int = 4;
 
-            pub const _SC_IOV_MAX : c_int = 51; // all changed...
+            pub const _SC_IOV_MAX : c_int = 51;
             pub const _SC_GETGR_R_SIZE_MAX : c_int = 100;
             pub const _SC_GETPW_R_SIZE_MAX : c_int = 101;
             pub const _SC_LOGIN_NAME_MAX : c_int = 102;
@@ -4144,14 +4474,32 @@ pub mod consts {
             pub const _SC_XOPEN_SHM : c_int = 30;
             pub const _SC_XOPEN_UNIX : c_int = 123;
             pub const _SC_XOPEN_VERSION : c_int = 125;
-            //pub const _SC_XOPEN_XCU_VERSION : c_int = ;
 
-            pub const PTHREAD_CREATE_JOINABLE: c_int = 0;
-            pub const PTHREAD_CREATE_DETACHED: c_int = 1;
-            pub const PTHREAD_STACK_MIN: size_t = 2048;
-
-            pub const CLOCK_REALTIME: c_int = 0;
-            pub const CLOCK_MONOTONIC: c_int = 3;
+            pub const PTHREAD_CREATE_JOINABLE : c_int = 0;
+            pub const PTHREAD_CREATE_DETACHED : c_int = 1;
+            pub const PTHREAD_STACK_MIN : size_t = 2048;
+
+            pub const CLOCK_REALTIME : c_int = 0;
+            pub const CLOCK_MONOTONIC : c_int = 3;
+
+            pub const RLIMIT_CPU: c_int = 0;
+            pub const RLIMIT_FSIZE: c_int = 1;
+            pub const RLIMIT_DATA: c_int = 2;
+            pub const RLIMIT_STACK: c_int = 3;
+            pub const RLIMIT_CORE: c_int = 4;
+            pub const RLIMIT_RSS: c_int = 5;
+            pub const RLIMIT_MEMLOCK: c_int = 6;
+            pub const RLIMIT_NPROC: c_int = 7;
+            pub const RLIMIT_NOFILE: c_int = 8;
+            pub const RLIM_NLIMITS: c_int = 9;
+
+            pub const RLIM_INFINITY: rlim_t = 0x7fff_ffff_ffff_ffff;
+            pub const RLIM_SAVED_MAX: rlim_t = RLIM_INFINITY;
+            pub const RLIM_SAVED_CUR: rlim_t = RLIM_INFINITY;
+
+            pub const RUSAGE_SELF: c_int = 0;
+            pub const RUSAGE_CHILDREN: c_int = -1;
+            pub const RUSAGE_THREAD: c_int = 1;
         }
         pub mod posix08 {
         }
@@ -4163,23 +4511,11 @@ pub mod consts {
             pub const MADV_SEQUENTIAL : c_int = 2;
             pub const MADV_WILLNEED : c_int = 3;
             pub const MADV_DONTNEED : c_int = 4;
-            pub const MADV_FREE : c_int = 6; // changed
-            //pub const MADV_NOSYNC : c_int = ;
-            //pub const MADV_AUTOSYNC : c_int = ;
-            //pub const MADV_NOCORE : c_int = ;
-            //pub const MADV_CORE : c_int = ;
-            //pub const MADV_PROTECT : c_int = ;
-
-            //pub const MINCORE_INCORE : c_int =  ;
-            //pub const MINCORE_REFERENCED : c_int = ;
-            //pub const MINCORE_MODIFIED : c_int = ;
-            //pub const MINCORE_REFERENCED_OTHER : c_int = ;
-            //pub const MINCORE_MODIFIED_OTHER : c_int = ;
-            //pub const MINCORE_SUPER : c_int = ;
+            pub const MADV_FREE : c_int = 6;
 
-            pub const AF_INET: c_int = 2;
-            pub const AF_INET6: c_int = 24; // changed
             pub const AF_UNIX: c_int = 1;
+            pub const AF_INET: c_int = 2;
+            pub const AF_INET6: c_int = 24;
             pub const SOCK_STREAM: c_int = 1;
             pub const SOCK_DGRAM: c_int = 2;
             pub const SOCK_RAW: c_int = 3;
@@ -4192,18 +4528,29 @@ pub mod consts {
             pub const IP_HDRINCL: c_int = 2;
             pub const IP_ADD_MEMBERSHIP: c_int = 12;
             pub const IP_DROP_MEMBERSHIP: c_int = 13;
-            // don't exist, keep same as IP_ADD_MEMBERSHIP
-            pub const IPV6_ADD_MEMBERSHIP: c_int = 12;
-            // don't exist, keep same as IP_DROP_MEMBERSHIP
-            pub const IPV6_DROP_MEMBERSHIP: c_int = 13;
+            pub const IPV6_ADD_MEMBERSHIP: c_int = 12; // don't exist
+            pub const IPV6_DROP_MEMBERSHIP: c_int = 13; // don't exist
 
-            pub const TCP_NODELAY: c_int = 1;
-            //pub const TCP_KEEPIDLE: c_int = ;
+            pub const TCP_NODELAY: c_int = 0x01;
             pub const SOL_SOCKET: c_int = 0xffff;
+            pub const SO_DEBUG: c_int = 0x01;
+            pub const SO_ACCEPTCONN: c_int = 0x0002;
+            pub const SO_REUSEADDR: c_int = 0x0004;
             pub const SO_KEEPALIVE: c_int = 0x0008;
+            pub const SO_DONTROUTE: c_int = 0x0010;
             pub const SO_BROADCAST: c_int = 0x0020;
-            pub const SO_REUSEADDR: c_int = 0x0004;
+            pub const SO_USELOOPBACK: c_int = 0x0040;
+            pub const SO_LINGER: c_int = 0x0080;
+            pub const SO_OOBINLINE: c_int = 0x0100;
+            pub const SO_REUSEPORT: c_int = 0x0200;
+            pub const SO_SNDBUF: c_int = 0x1001;
+            pub const SO_RCVBUF: c_int = 0x1002;
+            pub const SO_SNDLOWAT: c_int = 0x1003;
+            pub const SO_RCVLOWAT: c_int = 0x1004;
+            pub const SO_SNDTIMEO: c_int = 0x1005;
+            pub const SO_RCVTIMEO: c_int = 0x1006;
             pub const SO_ERROR: c_int = 0x1007;
+            pub const SO_TYPE: c_int = 0x1008;
 
             pub const IFF_LOOPBACK: c_int = 0x8;
 
@@ -4214,20 +4561,21 @@ pub mod consts {
         pub mod extra {
             use types::os::arch::c95::c_int;
 
+            pub const O_DSYNC : c_int = 128; // same as SYNC
             pub const O_SYNC : c_int = 128;
             pub const O_NONBLOCK : c_int = 4;
-            pub const CTL_KERN: c_int = 1;
-            pub const KERN_PROC: c_int = 66;
+            pub const CTL_KERN : c_int = 1;
+            pub const KERN_PROC : c_int = 66;
 
             pub const MAP_COPY : c_int = 0x0002;
-            pub const MAP_RENAME : c_int = 0x0000; // changed
-            pub const MAP_NORESERVE : c_int = 0x0000; // changed
-            pub const MAP_HASSEMAPHORE : c_int = 0x0000; // changed
-            //pub const MAP_STACK : c_int = ;
-            //pub const MAP_NOSYNC : c_int = ;
-            //pub const MAP_NOCORE : c_int = ;
+            pub const MAP_RENAME : c_int = 0x0000;
+            pub const MAP_NORESERVE : c_int = 0x0000;
+            pub const MAP_NOEXTEND : c_int = 0x0000;
+            pub const MAP_HASSEMAPHORE : c_int = 0x0000;
 
             pub const IPPROTO_RAW : c_int = 255;
+
+            pub const PATH_MAX: c_int = 1024;
         }
         pub mod sysconf {
             use types::os::arch::c95::c_int;
@@ -4259,31 +4607,31 @@ pub mod consts {
             pub const _SC_2_UPE : c_int = 25;
             pub const _SC_STREAM_MAX : c_int = 26;
             pub const _SC_TZNAME_MAX : c_int = 27;
-            pub const _SC_ASYNCHRONOUS_IO : c_int = 45; // changed...
+            pub const _SC_PAGESIZE : c_int = 28;
+            pub const _SC_FSYNC : c_int = 29;
+            pub const _SC_SEM_NSEMS_MAX : c_int = 31;
+            pub const _SC_SEM_VALUE_MAX : c_int = 32;
+            pub const _SC_AIO_LISTIO_MAX : c_int = 42;
+            pub const _SC_AIO_MAX : c_int = 43;
+            pub const _SC_AIO_PRIO_DELTA_MAX : c_int = 44;
+            pub const _SC_ASYNCHRONOUS_IO : c_int = 45;
+            pub const _SC_DELAYTIMER_MAX : c_int = 50;
             pub const _SC_MAPPED_FILES : c_int = 53;
             pub const _SC_MEMLOCK : c_int = 54;
             pub const _SC_MEMLOCK_RANGE : c_int = 55;
             pub const _SC_MEMORY_PROTECTION : c_int = 56;
             pub const _SC_MESSAGE_PASSING : c_int = 57;
+            pub const _SC_MQ_OPEN_MAX : c_int = 58;
             pub const _SC_PRIORITIZED_IO : c_int = 60;
             pub const _SC_PRIORITY_SCHEDULING : c_int = 61;
             pub const _SC_REALTIME_SIGNALS : c_int = 64;
+            pub const _SC_RTSIG_MAX : c_int = 66;
             pub const _SC_SEMAPHORES : c_int = 67;
-            pub const _SC_FSYNC : c_int = 29;
             pub const _SC_SHARED_MEMORY_OBJECTS : c_int = 68;
-            pub const _SC_SYNCHRONIZED_IO : c_int = 75;
-            pub const _SC_TIMERS : c_int = 94; // ...changed
-            pub const _SC_AIO_LISTIO_MAX : c_int = 42;
-            pub const _SC_AIO_MAX : c_int = 43;
-            pub const _SC_AIO_PRIO_DELTA_MAX : c_int = 44;
-            pub const _SC_DELAYTIMER_MAX : c_int = 50; // changed...
-            pub const _SC_MQ_OPEN_MAX : c_int = 58;
-            pub const _SC_PAGESIZE : c_int = 28;
-            pub const _SC_RTSIG_MAX : c_int = 66;
-            pub const _SC_SEM_NSEMS_MAX : c_int = 31;
-            pub const _SC_SEM_VALUE_MAX : c_int = 32;
             pub const _SC_SIGQUEUE_MAX : c_int = 70;
+            pub const _SC_SYNCHRONIZED_IO : c_int = 75;
             pub const _SC_TIMER_MAX : c_int = 93;
+            pub const _SC_TIMERS : c_int = 94;
         }
     }
 
@@ -4302,11 +4650,11 @@ pub mod consts {
             pub const _IOFBF : c_int = 0;
             pub const _IONBF : c_int = 2;
             pub const _IOLBF : c_int = 1;
-            pub const BUFSIZ : c_uint = 1024_u32;
-            pub const FOPEN_MAX : c_uint = 20_u32;
-            pub const FILENAME_MAX : c_uint = 1024_u32;
-            pub const L_tmpnam : c_uint = 1024_u32;
-            pub const TMP_MAX : c_uint = 308915776_u32;
+            pub const BUFSIZ : c_uint = 1024;
+            pub const FOPEN_MAX : c_uint = 20;
+            pub const FILENAME_MAX : c_uint = 1024;
+            pub const L_tmpnam : c_uint = 1024;
+            pub const TMP_MAX : c_uint = 308915776;
         }
         pub mod c99 {
         }
@@ -4336,6 +4684,14 @@ pub mod consts {
             pub const S_IXUSR : mode_t = 64;
             pub const S_IWUSR : mode_t = 128;
             pub const S_IRUSR : mode_t = 256;
+            pub const S_IRWXG : mode_t = 56;
+            pub const S_IXGRP : mode_t = 8;
+            pub const S_IWGRP : mode_t = 16;
+            pub const S_IRGRP : mode_t = 32;
+            pub const S_IRWXO : mode_t = 7;
+            pub const S_IXOTH : mode_t = 1;
+            pub const S_IWOTH : mode_t = 2;
+            pub const S_IROTH : mode_t = 4;
             pub const F_OK : c_int = 0;
             pub const R_OK : c_int = 4;
             pub const W_OK : c_int = 2;
@@ -4370,7 +4726,7 @@ pub mod consts {
             pub const MAP_FIXED : c_int = 0x0010;
             pub const MAP_ANON : c_int = 0x1000;
 
-            pub const MAP_FAILED : *mut c_void = -1 as *mut c_void;
+            pub const MAP_FAILED : *mut c_void = !0 as *mut c_void;
 
             pub const MCL_CURRENT : c_int = 0x0001;
             pub const MCL_FUTURE : c_int = 0x0002;
@@ -4493,6 +4849,7 @@ pub mod consts {
         }
         pub mod posix01 {
             use types::os::arch::c95::{c_int, size_t};
+            use types::os::common::posix01::rlim_t;
 
             pub const F_DUPFD : c_int = 0;
             pub const F_GETFD : c_int = 1;
@@ -4501,7 +4858,6 @@ pub mod consts {
             pub const F_SETFL : c_int = 4;
 
             pub const SIGTRAP : c_int = 5;
-            pub const SIGPIPE: c_int = 13;
             pub const SIG_IGN: size_t = 1;
 
             pub const GLOB_APPEND   : c_int = 0x0001;
@@ -4554,6 +4910,24 @@ pub mod consts {
             pub const PTHREAD_CREATE_JOINABLE: c_int = 1;
             pub const PTHREAD_CREATE_DETACHED: c_int = 2;
             pub const PTHREAD_STACK_MIN: size_t = 8192;
+
+            pub const RLIMIT_CPU: c_int = 0;
+            pub const RLIMIT_FSIZE: c_int = 1;
+            pub const RLIMIT_DATA: c_int = 2;
+            pub const RLIMIT_STACK: c_int = 3;
+            pub const RLIMIT_CORE: c_int = 4;
+            pub const RLIMIT_AS: c_int = 5;
+            pub const RLIMIT_MEMLOCK: c_int = 6;
+            pub const RLIMIT_NPROC: c_int = 7;
+            pub const RLIMIT_NOFILE: c_int = 8;
+            pub const RLIM_NLIMITS: c_int = 9;
+            pub const _RLIMIT_POSIX_FLAG: c_int = 0x1000;
+
+            pub const RLIM_INFINITY: rlim_t = 0xffff_ffff_ffff_ffff;
+
+            pub const RUSAGE_SELF: c_int = 0;
+            pub const RUSAGE_CHILDREN: c_int = -1;
+            pub const RUSAGE_THREAD: c_int = 1;
         }
         pub mod posix08 {
         }
@@ -4598,10 +4972,25 @@ pub mod consts {
             pub const TCP_NODELAY: c_int = 0x01;
             pub const TCP_KEEPALIVE: c_int = 0x10;
             pub const SOL_SOCKET: c_int = 0xffff;
+
+            pub const SO_DEBUG: c_int = 0x01;
+            pub const SO_ACCEPTCONN: c_int = 0x0002;
+            pub const SO_REUSEADDR: c_int = 0x0004;
             pub const SO_KEEPALIVE: c_int = 0x0008;
+            pub const SO_DONTROUTE: c_int = 0x0010;
             pub const SO_BROADCAST: c_int = 0x0020;
-            pub const SO_REUSEADDR: c_int = 0x0004;
+            pub const SO_USELOOPBACK: c_int = 0x0040;
+            pub const SO_LINGER: c_int = 0x0080;
+            pub const SO_OOBINLINE: c_int = 0x0100;
+            pub const SO_REUSEPORT: c_int = 0x0200;
+            pub const SO_SNDBUF: c_int = 0x1001;
+            pub const SO_RCVBUF: c_int = 0x1002;
+            pub const SO_SNDLOWAT: c_int = 0x1003;
+            pub const SO_RCVLOWAT: c_int = 0x1004;
+            pub const SO_SNDTIMEO: c_int = 0x1005;
+            pub const SO_RCVTIMEO: c_int = 0x1006;
             pub const SO_ERROR: c_int = 0x1007;
+            pub const SO_TYPE: c_int = 0x1008;
 
             pub const IFF_LOOPBACK: c_int = 0x8;
 
@@ -4627,6 +5016,15 @@ pub mod consts {
             pub const MAP_STACK : c_int = 0;
 
             pub const IPPROTO_RAW : c_int = 255;
+
+            pub const SO_NREAD: c_int = 0x1020;
+            pub const SO_NKE: c_int = 0x1021;
+            pub const SO_NOSIGPIPE: c_int = 0x1022;
+            pub const SO_NOADDRERR: c_int = 0x1023;
+            pub const SO_NWRITE: c_int = 0x1024;
+            pub const SO_DONTTRUNC: c_int = 0x2000;
+            pub const SO_WANTMORE: c_int = 0x4000;
+            pub const SO_WANTOOBFLAG: c_int = 0x8000;
         }
         pub mod sysconf {
             use types::os::arch::c95::c_int;
@@ -4809,7 +5207,7 @@ pub mod funcs {
                 ///
                 /// # Examples
                 ///
-                /// ```no_run
+                /// ```no_run,ignore
                 /// extern crate libc;
                 ///
                 /// fn main() {
@@ -5005,7 +5403,9 @@ pub mod funcs {
               target_os = "ios",
               target_os = "freebsd",
               target_os = "dragonfly",
-              target_os = "openbsd"))]
+              target_os = "bitrig",
+              target_os = "openbsd",
+              target_os = "nacl"))]
     pub mod posix88 {
         pub mod stat_ {
             use types::os::arch::c95::{c_char, c_int};
@@ -5019,9 +5419,11 @@ pub mod funcs {
                 #[cfg(any(target_os = "linux",
                           target_os = "freebsd",
                           target_os = "dragonfly",
+                          target_os = "bitrig",
                           target_os = "openbsd",
                           target_os = "android",
-                          target_os = "ios"))]
+                          target_os = "ios",
+                          target_os = "nacl"))]
                 pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
 
                 #[cfg(target_os = "macos")]
@@ -5029,14 +5431,17 @@ pub mod funcs {
                 pub fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
 
                 pub fn mkdir(path: *const c_char, mode: mode_t) -> c_int;
+                #[cfg(not(target_os = "nacl"))]
                 pub fn mkfifo(path: *const c_char, mode: mode_t) -> c_int;
 
                 #[cfg(any(target_os = "linux",
                           target_os = "freebsd",
                           target_os = "dragonfly",
+                          target_os = "bitrig",
                           target_os = "openbsd",
                           target_os = "android",
-                          target_os = "ios"))]
+                          target_os = "ios",
+                          target_os = "nacl"))]
                 pub fn stat(path: *const c_char, buf: *mut stat) -> c_int;
 
                 #[cfg(target_os = "macos")]
@@ -5062,9 +5467,36 @@ pub mod funcs {
             use types::os::arch::c95::{c_char, c_int};
             use types::os::arch::posix88::mode_t;
 
+            mod open_shim {
+                extern {
+                    #[cfg(any(target_os = "macos",
+                              target_os = "ios"))]
+                    pub fn open(path: *const ::c_char, oflag: ::c_int, ...)
+                                -> ::c_int;
+
+                    #[cfg(not(any(target_os = "macos",
+                                  target_os = "ios")))]
+                    pub fn open(path: *const ::c_char, oflag: ::c_int, mode: ::mode_t)
+                                -> ::c_int;
+                }
+            }
+
+            #[cfg(any(target_os = "macos",
+                      target_os = "ios"))]
+            #[inline]
+            pub unsafe extern fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
+                use types::os::arch::c95::c_uint;
+                open_shim::open(path, oflag, mode as c_uint)
+            }
+
+            #[cfg(not(any(target_os = "macos",
+                          target_os = "ios")))]
+            #[inline]
+            pub unsafe extern fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
+                open_shim::open(path, oflag, mode)
+            }
+
             extern {
-                pub fn open(path: *const c_char, oflag: c_int, mode: mode_t)
-                            -> c_int;
                 pub fn creat(path: *const c_char, mode: mode_t) -> c_int;
                 pub fn fcntl(fd: c_int, cmd: c_int, ...) -> c_int;
             }
@@ -5108,6 +5540,7 @@ pub mod funcs {
 
             pub const _PC_NAME_MAX: c_int = 4;
 
+            #[cfg(not(target_os = "nacl"))]
             extern {
                 pub fn access(path: *const c_char, amode: c_int) -> c_int;
                 pub fn alarm(seconds: c_uint) -> c_uint;
@@ -5129,7 +5562,7 @@ pub mod funcs {
                 pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char;
                 pub fn getegid() -> gid_t;
                 pub fn geteuid() -> uid_t;
-                pub fn getgid() -> gid_t ;
+                pub fn getgid() -> gid_t;
                 pub fn getgroups(ngroups_max: c_int, groups: *mut gid_t)
                                  -> c_int;
                 pub fn getlogin() -> *mut c_char;
@@ -5170,6 +5603,57 @@ pub mod funcs {
                               offset: off_t) -> ssize_t;
                 pub fn utime(file: *const c_char, buf: *const utimbuf) -> c_int;
             }
+            #[cfg(target_os = "nacl")]
+            extern {
+                pub fn access(path: *const c_char, amode: c_int) -> c_int;
+                pub fn chdir(dir: *const c_char) -> c_int;
+                pub fn chown(path: *const c_char, uid: uid_t,
+                             gid: gid_t) -> c_int;
+                pub fn close(fd: c_int) -> c_int;
+                pub fn dup(fd: c_int) -> c_int;
+                pub fn dup2(src: c_int, dst: c_int) -> c_int;
+                pub fn execv(prog: *const c_char,
+                             argv: *mut *const c_char) -> c_int;
+                pub fn execve(prog: *const c_char, argv: *mut *const c_char,
+                              envp: *mut *const c_char)
+                              -> c_int;
+                pub fn execvp(c: *const c_char,
+                              argv: *mut *const c_char) -> c_int;
+                pub fn fork() -> pid_t;
+                pub fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char;
+                pub fn getegid() -> gid_t;
+                pub fn geteuid() -> uid_t;
+                pub fn getgid() -> gid_t;
+                pub fn getlogin() -> *mut c_char;
+                pub fn getopt(argc: c_int, argv: *mut *const c_char,
+                              optstr: *const c_char) -> c_int;
+                pub fn getuid() -> uid_t;
+                pub fn getsid(pid: pid_t) -> pid_t;
+                pub fn isatty(fd: c_int) -> c_int;
+                pub fn link(src: *const c_char, dst: *const c_char) -> c_int;
+                pub fn lseek(fd: c_int, offset: off_t, whence: c_int)
+                             -> off_t;
+                pub fn pipe(fds: *mut c_int) -> c_int;
+                pub fn read(fd: c_int, buf: *mut c_void, count: size_t)
+                            -> ssize_t;
+                pub fn rmdir(path: *const c_char) -> c_int;
+                pub fn setgid(gid: gid_t) -> c_int;
+                pub fn setuid(uid: uid_t) -> c_int;
+                pub fn sleep(secs: c_uint) -> c_uint;
+                pub fn usleep(secs: c_uint) -> c_int;
+                pub fn nanosleep(rqtp: *const timespec,
+                                 rmtp: *mut timespec) -> c_int;
+                pub fn sysconf(name: c_int) -> c_long;
+                pub fn ttyname(fd: c_int) -> *mut c_char;
+                pub fn unlink(c: *const c_char) -> c_int;
+                pub fn write(fd: c_int, buf: *const c_void, count: size_t)
+                             -> ssize_t;
+                pub fn pread(fd: c_int, buf: *mut c_void, count: size_t,
+                             offset: off_t) -> ssize_t;
+                pub fn pwrite(fd: c_int, buf: *const c_void, count: size_t,
+                              offset: off_t) -> ssize_t;
+                pub fn utime(file: *const c_char, buf: *const utimbuf) -> c_int;
+            }
         }
 
         pub mod signal {
@@ -5186,12 +5670,24 @@ pub mod funcs {
             use types::os::arch::c95::{size_t, c_int, c_char};
             use types::os::arch::posix88::{mode_t, off_t};
 
+            #[cfg(not(target_os = "nacl"))]
             extern {
                 pub fn mlock(addr: *const c_void, len: size_t) -> c_int;
                 pub fn munlock(addr: *const c_void, len: size_t) -> c_int;
                 pub fn mlockall(flags: c_int) -> c_int;
                 pub fn munlockall() -> c_int;
 
+                pub fn mprotect(addr: *mut c_void, len: size_t, prot: c_int)
+                                -> c_int;
+
+                pub fn msync(addr: *mut c_void, len: size_t, flags: c_int)
+                             -> c_int;
+                pub fn shm_open(name: *const c_char, oflag: c_int, mode: mode_t)
+                                -> c_int;
+                pub fn shm_unlink(name: *const c_char) -> c_int;
+            }
+
+            extern {
                 pub fn mmap(addr: *mut c_void,
                             len: size_t,
                             prot: c_int,
@@ -5201,14 +5697,6 @@ pub mod funcs {
                             -> *mut c_void;
                 pub fn munmap(addr: *mut c_void, len: size_t) -> c_int;
 
-                pub fn mprotect(addr: *mut c_void, len: size_t, prot: c_int)
-                                -> c_int;
-
-                pub fn msync(addr: *mut c_void, len: size_t, flags: c_int)
-                             -> c_int;
-                pub fn shm_open(name: *const c_char, oflag: c_int, mode: mode_t)
-                                -> c_int;
-                pub fn shm_unlink(name: *const c_char) -> c_int;
             }
         }
 
@@ -5228,7 +5716,9 @@ pub mod funcs {
               target_os = "ios",
               target_os = "freebsd",
               target_os = "dragonfly",
-              target_os = "openbsd"))]
+              target_os = "bitrig",
+              target_os = "openbsd",
+              target_os = "nacl"))]
     pub mod posix01 {
         pub mod stat_ {
             use types::os::arch::c95::{c_char, c_int};
@@ -5238,9 +5728,11 @@ pub mod funcs {
                 #[cfg(any(target_os = "linux",
                           target_os = "freebsd",
                           target_os = "dragonfly",
+                          target_os = "bitrig",
                           target_os = "openbsd",
                           target_os = "android",
-                          target_os = "ios"))]
+                          target_os = "ios",
+                          target_os = "nacl"))]
                 pub fn lstat(path: *const c_char, buf: *mut stat) -> c_int;
 
                 #[cfg(target_os = "macos")]
@@ -5312,6 +5804,7 @@ pub mod funcs {
             use types::common::c95::{c_void};
             use types::os::arch::c95::{c_int, size_t};
 
+            #[cfg(not(target_os = "nacl"))]
             extern {
                 pub fn posix_madvise(addr: *mut c_void,
                                      len: size_t,
@@ -5319,6 +5812,18 @@ pub mod funcs {
                                      -> c_int;
             }
         }
+
+        pub mod resource {
+            use types::os::arch::c95::c_int;
+            use types::os::common::posix01::rlimit;
+            use types::os::common::bsd43::rusage;
+            extern {
+                pub fn getrlimit(resource: c_int, rlim: *mut rlimit) -> c_int;
+                pub fn setrlimit(resource: c_int, rlim: *const rlimit) -> c_int;
+                pub fn getrusage(resource: c_int, usage: *mut rusage) -> c_int;
+
+            }
+        }
     }
 
     #[cfg(target_os = "windows")]
@@ -5347,7 +5852,9 @@ pub mod funcs {
               target_os = "ios",
               target_os = "freebsd",
               target_os = "dragonfly",
-              target_os = "openbsd"))]
+              target_os = "bitrig",
+              target_os = "openbsd",
+              target_os = "nacl"))]
     pub mod posix08 {
         pub mod unistd {
         }
@@ -5434,6 +5941,7 @@ pub mod funcs {
               target_os = "ios",
               target_os = "freebsd",
               target_os = "dragonfly",
+              target_os = "bitrig",
               target_os = "openbsd"))]
     pub mod bsd44 {
         use types::common::c95::{c_void};
@@ -5463,10 +5971,11 @@ pub mod funcs {
                            -> c_int;
             pub fn mincore(addr: *mut c_void, len: size_t, vec: *mut c_uchar)
                            -> c_int;
+            pub fn realpath(pathname: *const c_char, resolved: *mut c_char)
+                            -> *mut c_char;
         }
     }
 
-
     #[cfg(any(target_os = "linux", target_os = "android"))]
     pub mod bsd44 {
         use types::common::c95::{c_void};
@@ -5483,6 +5992,13 @@ pub mod funcs {
         }
     }
 
+    #[cfg(target_os = "nacl")]
+    pub mod bsd44 {
+        use types::os::arch::c95::c_int;
+        extern {
+            pub fn getdtablesize() -> c_int;
+        }
+    }
 
     #[cfg(target_os = "windows")]
     pub mod bsd44 {
@@ -5500,11 +6016,12 @@ pub mod funcs {
 
     #[cfg(any(target_os = "freebsd",
               target_os = "dragonfly",
+              target_os = "bitrig",
               target_os = "openbsd"))]
     pub mod extra {
     }
 
-    #[cfg(any(target_os = "linux", target_os = "android"))]
+    #[cfg(any(target_os = "linux", target_os = "android", target_os = "nacl"))]
     pub mod extra {
     }
 
index c2c7f20ce9cdfcff7ead7cf1f79caaf23ff2962e..453d087196b1318c57b95e19c202c2f3e2dc7b56 100644 (file)
 //! they're turned off (just a load and an integer comparison). This also means that
 //! if logging is disabled, none of the components of the log will be executed.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "log"]
 #![unstable(feature = "rustc_private",
             reason = "use the crates.io `log` library instead")]
        html_playground_url = "http://play.rust-lang.org/")]
 #![deny(missing_docs)]
 
+#![feature(alloc)]
 #![feature(staged_api)]
 #![feature(box_syntax)]
-#![feature(int_uint)]
 #![feature(core)]
-#![feature(old_io)]
 #![feature(std_misc)]
-#![feature(env)]
 
+use std::boxed;
 use std::cell::RefCell;
 use std::fmt;
-use std::old_io::LineBufferedWriter;
-use std::old_io;
+use std::io::{self, Stderr};
+use std::io::prelude::*;
 use std::mem;
 use std::env;
-use std::ptr;
 use std::rt;
 use std::slice;
-use std::sync::{Once, ONCE_INIT};
+use std::sync::{Once, ONCE_INIT, StaticMutex, MUTEX_INIT};
 
 use directive::LOG_LEVEL_NAMES;
 
@@ -200,16 +200,18 @@ pub const MAX_LOG_LEVEL: u32 = 255;
 /// The default logging level of a crate if no other is specified.
 const DEFAULT_LOG_LEVEL: u32 = 1;
 
+static LOCK: StaticMutex = MUTEX_INIT;
+
 /// An unsafe constant that is the maximum logging level of any module
 /// specified. This is the first line of defense to determining whether a
 /// logging statement should be run.
 static mut LOG_LEVEL: u32 = MAX_LOG_LEVEL;
 
-static mut DIRECTIVES: *const Vec<directive::LogDirective> =
-    0 as *const Vec<directive::LogDirective>;
+static mut DIRECTIVES: *mut Vec<directive::LogDirective> =
+    0 as *mut Vec<directive::LogDirective>;
 
 /// Optional filter.
-static mut FILTER: *const String = 0 as *const _;
+static mut FILTER: *mut String = 0 as *mut _;
 
 /// Debug log level
 pub const DEBUG: u32 = 4;
@@ -234,18 +236,16 @@ pub trait Logger {
     fn log(&mut self, record: &LogRecord);
 }
 
-struct DefaultLogger {
-    handle: LineBufferedWriter<old_io::stdio::StdWriter>,
-}
+struct DefaultLogger { handle: Stderr }
 
 /// Wraps the log level with fmt implementations.
-#[derive(Copy, PartialEq, PartialOrd, Debug)]
+#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
 pub struct LogLevel(pub u32);
 
 impl fmt::Display for LogLevel {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let LogLevel(level) = *self;
-        match LOG_LEVEL_NAMES.get(level as uint - 1) {
+        match LOG_LEVEL_NAMES.get(level as usize - 1) {
             Some(ref name) => fmt::Display::fmt(name, fmt),
             None => fmt::Display::fmt(&level, fmt)
         }
@@ -286,18 +286,27 @@ impl Drop for DefaultLogger {
 pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
     // Test the literal string from args against the current filter, if there
     // is one.
-    match unsafe { FILTER.as_ref() } {
-        Some(filter) if !args.to_string().contains(&filter[..]) => return,
-        _ => {}
+    unsafe {
+        let _g = LOCK.lock();
+        match FILTER as usize {
+            0 => {}
+            1 => panic!("cannot log after main thread has exited"),
+            n => {
+                let filter = mem::transmute::<_, &String>(n);
+                if !args.to_string().contains(&filter[..]) {
+                    return
+                }
+            }
+        }
     }
 
     // Completely remove the local logger from TLS in case anyone attempts to
     // frob the slot while we're doing the logging. This will destroy any logger
     // set during logging.
-    let mut logger = LOCAL_LOGGER.with(|s| {
+    let mut logger: Box<Logger + Send> = LOCAL_LOGGER.with(|s| {
         s.borrow_mut().take()
     }).unwrap_or_else(|| {
-        box DefaultLogger { handle: old_io::stderr() } as Box<Logger + Send>
+        box DefaultLogger { handle: io::stderr() }
     });
     logger.log(&LogRecord {
         level: LogLevel(level),
@@ -342,15 +351,15 @@ pub struct LogRecord<'a> {
     pub file: &'a str,
 
     /// The line number of where the LogRecord originated.
-    pub line: uint,
+    pub line: u32,
 }
 
 #[doc(hidden)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct LogLocation {
     pub module_path: &'static str,
     pub file: &'static str,
-    pub line: uint,
+    pub line: u32,
 }
 
 /// Tests whether a given module's name is enabled for a particular level of
@@ -370,9 +379,15 @@ pub fn mod_enabled(level: u32, module: &str) -> bool {
 
     // This assertion should never get tripped unless we're in an at_exit
     // handler after logging has been torn down and a logging attempt was made.
-    assert!(unsafe { !DIRECTIVES.is_null() });
 
-    enabled(level, module, unsafe { (*DIRECTIVES).iter() })
+    let _g = LOCK.lock();
+    unsafe {
+        assert!(DIRECTIVES as usize != 0);
+        assert!(DIRECTIVES as usize != 1,
+                "cannot log after the main thread has exited");
+
+        enabled(level, module, (*DIRECTIVES).iter())
+    }
 }
 
 fn enabled(level: u32,
@@ -419,23 +434,23 @@ fn init() {
 
         assert!(FILTER.is_null());
         match filter {
-            Some(f) => FILTER = mem::transmute(box f),
+            Some(f) => FILTER = boxed::into_raw(box f),
             None => {}
         }
 
         assert!(DIRECTIVES.is_null());
-        DIRECTIVES = mem::transmute(box directives);
+        DIRECTIVES = boxed::into_raw(box directives);
 
         // Schedule the cleanup for the globals for when the runtime exits.
-        rt::at_exit(move || {
+        let _ = rt::at_exit(move || {
+            let _g = LOCK.lock();
             assert!(!DIRECTIVES.is_null());
-            let _directives: Box<Vec<directive::LogDirective>> =
-                mem::transmute(DIRECTIVES);
-            DIRECTIVES = ptr::null();
+            let _directives = Box::from_raw(DIRECTIVES);
+            DIRECTIVES = 1 as *mut _;
 
             if !FILTER.is_null() {
-                let _filter: Box<String> = mem::transmute(FILTER);
-                FILTER = 0 as *const _;
+                let _filter = Box::from_raw(FILTER);
+                FILTER = 1 as *mut _;
             }
         });
     }
index 4a9a9bd40600b73d736244b022a68a46cab331fb..80eb1601035a89c20faa3357541a3cd412d5947c 100644 (file)
@@ -16,7 +16,7 @@
 /// format!-based argument list. See documentation in `std::fmt` for details on
 /// how to use the syntax.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// #[macro_use] extern crate log;
@@ -64,7 +64,7 @@ macro_rules! log {
 
 /// A convenience macro for logging at the error log level.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// #[macro_use] extern crate log;
@@ -89,7 +89,7 @@ macro_rules! error {
 
 /// A convenience macro for logging at the warning log level.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// #[macro_use] extern crate log;
@@ -113,7 +113,7 @@ macro_rules! warn {
 
 /// A convenience macro for logging at the info log level.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// #[macro_use] extern crate log;
@@ -139,7 +139,7 @@ macro_rules! info {
 /// be omitted at compile time by passing `--cfg ndebug` to the compiler. If
 /// this option is not passed, then debug statements will be compiled.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// #[macro_use] extern crate log;
@@ -157,12 +157,12 @@ macro_rules! info {
 /// ```
 #[macro_export]
 macro_rules! debug {
-    ($($arg:tt)*) => (if cfg!(not(ndebug)) { log!(::log::DEBUG, $($arg)*) })
+    ($($arg:tt)*) => (if cfg!(debug_assertions) { log!(::log::DEBUG, $($arg)*) })
 }
 
 /// A macro to test whether a log level is enabled for the current module.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// #[macro_use] extern crate log;
@@ -192,9 +192,8 @@ macro_rules! debug {
 macro_rules! log_enabled {
     ($lvl:expr) => ({
         let lvl = $lvl;
-        (lvl != ::log::DEBUG || cfg!(not(ndebug))) &&
+        (lvl != ::log::DEBUG || cfg!(debug_assertions)) &&
         lvl <= ::log::log_level() &&
         ::log::mod_enabled(lvl, module_path!())
     })
 }
-
index 2673649f3440cc9170cff3d79e4d0cd556d418b8..44187a4fc99429002d292e679fb4af77bc5260d7 100644 (file)
 
 use core::prelude::*;
 use core::num::Int;
+use core::num::wrapping::WrappingOps;
 use {Rng, SeedableRng, Rand};
 
-const KEY_WORDS    : uint =  8; // 8 words for the 256-bit key
-const STATE_WORDS  : uint = 16;
-const CHACHA_ROUNDS: uint = 20; // Cryptographically secure from 8 upwards as of this writing
+const KEY_WORDS    : usize =  8; // 8 words for the 256-bit key
+const STATE_WORDS  : usize = 16;
+const CHACHA_ROUNDS: usize = 20; // Cryptographically secure from 8 upwards as of this writing
 
 /// A random number generator that uses the ChaCha20 algorithm [1].
 ///
@@ -31,7 +32,7 @@ const CHACHA_ROUNDS: uint = 20; // Cryptographically secure from 8 upwards as of
 pub struct ChaChaRng {
     buffer:  [u32; STATE_WORDS], // Internal buffer of output
     state:   [u32; STATE_WORDS], // Initial state
-    index:   uint,                 // Index into state
+    index:   usize,                 // Index into state
 }
 
 static EMPTY: ChaChaRng = ChaChaRng {
@@ -43,10 +44,10 @@ static EMPTY: ChaChaRng = ChaChaRng {
 
 macro_rules! quarter_round{
     ($a: expr, $b: expr, $c: expr, $d: expr) => {{
-        $a += $b; $d ^= $a; $d = $d.rotate_left(16);
-        $c += $d; $b ^= $c; $b = $b.rotate_left(12);
-        $a += $b; $d ^= $a; $d = $d.rotate_left( 8);
-        $c += $d; $b ^= $c; $b = $b.rotate_left( 7);
+        $a = $a.wrapping_add($b); $d = $d ^ $a; $d = $d.rotate_left(16);
+        $c = $c.wrapping_add($d); $b = $b ^ $c; $b = $b.rotate_left(12);
+        $a = $a.wrapping_add($b); $d = $d ^ $a; $d = $d.rotate_left( 8);
+        $c = $c.wrapping_add($d); $b = $b ^ $c; $b = $b.rotate_left( 7);
     }}
 }
 
@@ -74,7 +75,7 @@ fn core(output: &mut [u32; STATE_WORDS], input: &[u32; STATE_WORDS]) {
     }
 
     for i in 0..STATE_WORDS {
-        output[i] += input[i];
+        output[i] = output[i].wrapping_add(input[i]);
     }
 }
 
@@ -172,7 +173,7 @@ impl<'a> SeedableRng<&'a [u32]> for ChaChaRng {
 
     fn reseed(&mut self, seed: &'a [u32]) {
         // reset state
-        self.init(&[0u32; KEY_WORDS]);
+        self.init(&[0; KEY_WORDS]);
         // set key in place
         let key = &mut self.state[4 .. 4+KEY_WORDS];
         for (k, s) in key.iter_mut().zip(seed.iter()) {
@@ -197,7 +198,7 @@ impl Rand for ChaChaRng {
         for word in &mut key {
             *word = other.gen();
         }
-        SeedableRng::from_seed(key.as_slice())
+        SeedableRng::from_seed(&key[..])
     }
 }
 
@@ -244,7 +245,7 @@ mod test {
     fn test_rng_true_values() {
         // Test vectors 1 and 2 from
         // http://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
-        let seed : &[_] = &[0u32; 8];
+        let seed : &[_] = &[0; 8];
         let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
 
         let v = (0..16).map(|_| ra.next_u32()).collect::<Vec<_>>();
@@ -284,7 +285,7 @@ mod test {
 
     #[test]
     fn test_rng_clone() {
-        let seed : &[_] = &[0u32; 8];
+        let seed : &[_] = &[0; 8];
         let mut rng: ChaChaRng = SeedableRng::from_seed(seed);
         let mut clone = rng.clone();
         for _ in 0..16 {
index e4927902cb3bb66184ad59f4c360818ee39491af..2ba3164e1b0617125244ad53d3d60baacda3b697 100644 (file)
@@ -29,7 +29,7 @@ use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample};
 /// Generate Normal Random
 /// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
 /// College, Oxford
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Exp1(pub f64);
 
 // This could be done via `-rng.gen::<f64>().ln()` but that is slower.
@@ -57,9 +57,10 @@ impl Rand for Exp1 {
 /// This distribution has density function: `f(x) = lambda *
 /// exp(-lambda * x)` for `x > 0`.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand)]
 /// use std::rand;
 /// use std::rand::distributions::{Exp, IndependentSample};
 ///
@@ -67,7 +68,7 @@ impl Rand for Exp1 {
 /// let v = exp.ind_sample(&mut rand::thread_rng());
 /// println!("{} is from a Exp(2) distribution", v);
 /// ```
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Exp {
     /// `lambda` stored as `1/lambda`, since this is what we scale by.
     lambda_inverse: f64
@@ -109,12 +110,12 @@ mod test {
         }
     }
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_exp_invalid_lambda_zero() {
         Exp::new(0.0);
     }
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_exp_invalid_lambda_neg() {
         Exp::new(-10.0);
     }
index 38eba0cfc712f7221961113775972f80ad76cdc0..d04e83e84f7289e1a8cecbec01d1048bb1503b06 100644 (file)
@@ -37,9 +37,10 @@ use super::{IndependentSample, Sample, Exp};
 /// == 1`, and using the boosting technique described in [1] for
 /// `shape < 1`.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand)]
 /// use std::rand;
 /// use std::rand::distributions::{IndependentSample, Gamma};
 ///
@@ -184,9 +185,10 @@ impl IndependentSample<f64> for GammaLargeShape {
 /// `k`, this uses the equivalent characterisation `χ²(k) = Gamma(k/2,
 /// 2)`.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand)]
 /// use std::rand;
 /// use std::rand::distributions::{ChiSquared, IndependentSample};
 ///
@@ -241,9 +243,10 @@ impl IndependentSample<f64> for ChiSquared {
 /// chi-squared distributions, that is, `F(m,n) = (χ²(m)/m) /
 /// (χ²(n)/n)`.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand)]
 /// use std::rand;
 /// use std::rand::distributions::{FisherF, IndependentSample};
 ///
@@ -285,9 +288,10 @@ impl IndependentSample<f64> for FisherF {
 /// The Student t distribution, `t(nu)`, where `nu` is the degrees of
 /// freedom.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand)]
 /// use std::rand;
 /// use std::rand::distributions::{StudentT, IndependentSample};
 ///
@@ -356,7 +360,7 @@ mod test {
         }
     }
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_chi_squared_invalid_dof() {
         ChiSquared::new(-1.0);
     }
index 5a85552dc384eb10536faa8520621827fe5416cd..432081063c50f7c6e8eba15f781e63c2cc7002e7 100644 (file)
@@ -17,8 +17,6 @@
 //! internally. The `IndependentSample` trait is for generating values
 //! that do not need to record state.
 
-#![unstable(feature = "rand")]
-
 use core::prelude::*;
 use core::num::{Float, Int};
 use core::marker::PhantomData;
@@ -78,7 +76,7 @@ impl<Sup: Rand> IndependentSample<Sup> for RandSample<Sup> {
 /// A value with a particular weight for use with `WeightedChoice`.
 pub struct Weighted<T> {
     /// The numerical weight of this item
-    pub weight: uint,
+    pub weight: usize,
     /// The actual item which is being weighted
     pub item: T,
 }
@@ -90,19 +88,20 @@ pub struct Weighted<T> {
 ///
 /// The `Clone` restriction is a limitation of the `Sample` and
 /// `IndependentSample` traits. Note that `&T` is (cheaply) `Clone` for
-/// all `T`, as is `uint`, so one can store references or indices into
+/// all `T`, as is `usize`, so one can store references or indices into
 /// another vector.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand)]
 /// use std::rand;
 /// use std::rand::distributions::{Weighted, WeightedChoice, IndependentSample};
 ///
 /// let mut items = vec!(Weighted { weight: 2, item: 'a' },
 ///                      Weighted { weight: 4, item: 'b' },
 ///                      Weighted { weight: 1, item: 'c' });
-/// let wc = WeightedChoice::new(items.as_mut_slice());
+/// let wc = WeightedChoice::new(&mut items[..]);
 /// let mut rng = rand::thread_rng();
 /// for _ in 0..16 {
 ///      // on average prints 'a' 4 times, 'b' 8 and 'c' twice.
@@ -111,7 +110,7 @@ pub struct Weighted<T> {
 /// ```
 pub struct WeightedChoice<'a, T:'a> {
     items: &'a mut [Weighted<T>],
-    weight_range: Range<uint>
+    weight_range: Range<usize>
 }
 
 impl<'a, T: Clone> WeightedChoice<'a, T> {
@@ -120,12 +119,12 @@ impl<'a, T: Clone> WeightedChoice<'a, T> {
     /// Panics if:
     /// - `v` is empty
     /// - the total weight is 0
-    /// - the total weight is larger than a `uint` can contain.
+    /// - the total weight is larger than a `usize` can contain.
     pub fn new(items: &'a mut [Weighted<T>]) -> WeightedChoice<'a, T> {
         // strictly speaking, this is subsumed by the total weight == 0 case
         assert!(!items.is_empty(), "WeightedChoice::new called with no items");
 
-        let mut running_total = 0;
+        let mut running_total = 0_usize;
 
         // we convert the list from individual weights to cumulative
         // weights so we can binary search. This *could* drop elements
@@ -134,7 +133,7 @@ impl<'a, T: Clone> WeightedChoice<'a, T> {
             running_total = match running_total.checked_add(item.weight) {
                 Some(n) => n,
                 None => panic!("WeightedChoice::new called with a total weight \
-                               larger than a uint can contain")
+                               larger than a usize can contain")
             };
 
             item.weight = running_total;
@@ -223,7 +222,7 @@ fn ziggurat<R: Rng, P, Z>(
             mut pdf: P,
             mut zero_case: Z)
             -> f64 where P: FnMut(f64) -> f64, Z: FnMut(&mut R, f64) -> f64 {
-    static SCALE: f64 = (1u64 << 53) as f64;
+    const SCALE: f64 = (1u64 << 53) as f64;
     loop {
         // reimplement the f64 generation as an optimisation suggested
         // by the Doornik paper: we have a lot of precision-space
@@ -239,7 +238,7 @@ fn ziggurat<R: Rng, P, Z>(
         // this may be slower than it would be otherwise.)
         // FIXME: investigate/optimise for the above.
         let bits: u64 = rng.gen();
-        let i = (bits & 0xff) as uint;
+        let i = (bits & 0xff) as usize;
         let f = (bits >> 11) as f64 / SCALE;
 
         // u is either U(-1, 1) or U(0, 1) depending on if this is a
@@ -257,7 +256,7 @@ fn ziggurat<R: Rng, P, Z>(
             return zero_case(rng, u);
         }
         // algebraically equivalent to f1 + DRanU()*(f0 - f1) < 1
-        if f_tab[i + 1] + (f_tab[i] - f_tab[i + 1]) * rng.gen() < pdf(x) {
+        if f_tab[i + 1] + (f_tab[i] - f_tab[i + 1]) * rng.gen::<f64>() < pdf(x) {
             return x;
         }
     }
@@ -271,7 +270,7 @@ mod tests {
     use super::{RandSample, WeightedChoice, Weighted, Sample, IndependentSample};
 
     #[derive(PartialEq, Debug)]
-    struct ConstRand(uint);
+    struct ConstRand(usize);
     impl Rand for ConstRand {
         fn rand<R: Rng>(_: &mut R) -> ConstRand {
             ConstRand(0)
@@ -351,18 +350,18 @@ mod tests {
            [50, 51, 52, 53, 54, 55, 56]);
     }
 
-    #[test] #[should_fail]
+    #[test] #[should_panic]
     fn test_weighted_choice_no_items() {
-        WeightedChoice::<int>::new(&mut []);
+        WeightedChoice::<isize>::new(&mut []);
     }
-    #[test] #[should_fail]
+    #[test] #[should_panic]
     fn test_weighted_choice_zero_weight() {
         WeightedChoice::new(&mut [Weighted { weight: 0, item: 0},
                                   Weighted { weight: 0, item: 1}]);
     }
-    #[test] #[should_fail]
+    #[test] #[should_panic]
     fn test_weighted_choice_weight_overflows() {
-        let x = (-1) as uint / 2; // x + x + 2 is the overflow
+        let x = (!0) as usize / 2; // x + x + 2 is the overflow
         WeightedChoice::new(&mut [Weighted { weight: x, item: 0 },
                                   Weighted { weight: 1, item: 1 },
                                   Weighted { weight: x, item: 2 },
index 83f202742d3f33da9dbdf016c32b1cbe541f93ce..fa41c3edfe5ac4e49655f7119ad985c375950ac6 100644 (file)
@@ -28,7 +28,7 @@ use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample};
 /// Generate Normal Random
 /// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
 /// College, Oxford
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct StandardNormal(pub f64);
 
 impl Rand for StandardNormal {
@@ -73,9 +73,10 @@ impl Rand for StandardNormal {
 /// This uses the ZIGNOR variant of the Ziggurat method, see
 /// `StandardNormal` for more details.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand)]
 /// use std::rand;
 /// use std::rand::distributions::{Normal, IndependentSample};
 ///
@@ -84,7 +85,7 @@ impl Rand for StandardNormal {
 /// let v = normal.ind_sample(&mut rand::thread_rng());
 /// println!("{} is from a N(2, 9) distribution", v)
 /// ```
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Normal {
     mean: f64,
     std_dev: f64,
@@ -121,9 +122,10 @@ impl IndependentSample<f64> for Normal {
 /// If `X` is log-normal distributed, then `ln(X)` is `N(mean,
 /// std_dev**2)` distributed.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand)]
 /// use std::rand;
 /// use std::rand::distributions::{LogNormal, IndependentSample};
 ///
@@ -132,7 +134,7 @@ impl IndependentSample<f64> for Normal {
 /// let v = log_normal.ind_sample(&mut rand::thread_rng());
 /// println!("{} is from an ln N(2, 9) distribution", v)
 /// ```
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct LogNormal {
     norm: Normal
 }
@@ -175,7 +177,7 @@ mod tests {
         }
     }
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_normal_invalid_sd() {
         Normal::new(10.0, -1.0);
     }
@@ -191,7 +193,7 @@ mod tests {
         }
     }
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_log_normal_invalid_sd() {
         LogNormal::new(10.0, -1.0);
     }
index 6eb1d68a081aa9d48632a383bfe0315d7f994214..347d494259d08830fbbbf39df99764512ff68bc1 100644 (file)
@@ -12,8 +12,9 @@
 
 // this is surprisingly complicated to be both generic & correct
 
-use core::prelude::{PartialOrd};
+use core::prelude::PartialOrd;
 use core::num::Int;
+use core::num::wrapping::WrappingOps;
 
 use Rng;
 use distributions::{Sample, IndependentSample};
@@ -22,8 +23,8 @@ use distributions::{Sample, IndependentSample};
 ///
 /// This gives a uniform distribution (assuming the RNG used to sample
 /// it is itself uniform & the `SampleRange` implementation for the
-/// given type is correct), even for edge cases like `low = 0u8`,
-/// `high = 170u8`, for which a naive modulo operation would return
+/// given type is correct), even for edge cases like `low = 0`,
+/// `high = 170`, for which a naive modulo operation would return
 /// numbers less than 85 with double the probability to those greater
 /// than 85.
 ///
@@ -32,9 +33,10 @@ use distributions::{Sample, IndependentSample};
 /// primitive integer types satisfy this property, and the float types
 /// normally satisfy it, but rounding may mean `high` can occur.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand)]
 /// use std::rand::distributions::{IndependentSample, Range};
 ///
 /// fn main() {
@@ -97,7 +99,7 @@ macro_rules! integer_impl {
             // bijection.
 
             fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
-                let range = high as $unsigned - low as $unsigned;
+                let range = (high as $unsigned).wrapping_sub(low as $unsigned);
                 let unsigned_max: $unsigned = Int::max_value();
 
                 // this is the largest number that fits into $unsigned
@@ -122,7 +124,7 @@ macro_rules! integer_impl {
                     // be uniformly distributed)
                     if v < r.accept_zone as $unsigned {
                         // and return it, with some adjustments
-                        return r.low + (v % r.range as $unsigned) as $ty;
+                        return r.low.wrapping_add((v % r.range as $unsigned) as $ty);
                     }
                 }
             }
@@ -134,12 +136,12 @@ integer_impl! { i8, u8 }
 integer_impl! { i16, u16 }
 integer_impl! { i32, u32 }
 integer_impl! { i64, u64 }
-integer_impl! { int, uint }
+integer_impl! { isize, usize }
 integer_impl! { u8, u8 }
 integer_impl! { u16, u16 }
 integer_impl! { u32, u32 }
 integer_impl! { u64, u64 }
-integer_impl! { uint, uint }
+integer_impl! { usize, usize }
 
 macro_rules! float_impl {
     ($ty:ty) => {
@@ -152,7 +154,7 @@ macro_rules! float_impl {
                 }
             }
             fn sample_range<R: Rng>(r: &Range<$ty>, rng: &mut R) -> $ty {
-                r.low + r.range * rng.gen()
+                r.low + r.range * rng.gen::<$ty>()
             }
         }
     }
@@ -168,12 +170,12 @@ mod tests {
     use distributions::{Sample, IndependentSample};
     use super::Range as Range;
 
-    #[should_fail]
+    #[should_panic]
     #[test]
     fn test_range_bad_limits_equal() {
         Range::new(10, 10);
     }
-    #[should_fail]
+    #[should_panic]
     #[test]
     fn test_range_bad_limits_flipped() {
         Range::new(10, 5);
@@ -200,8 +202,8 @@ mod tests {
                  )*
             }}
         }
-        t!(i8, i16, i32, i64, int,
-           u8, u16, u32, u64, uint)
+        t!(i8, i16, i32, i64, isize,
+           u8, u16, u32, u64, usize)
     }
 
     #[test]
index 701749ff3443f6e0280ad1308001854ea645cfe2..a7f7889783f70b775d40791d669efb547023a4bb 100644 (file)
 
 //! The ISAAC random number generator.
 
+#![allow(non_camel_case_types)]
+
 use core::prelude::*;
 use core::slice;
-use core::iter::{range_step, repeat};
+use core::iter::repeat;
+use core::num::Wrapping as w;
 
 use {Rng, SeedableRng, Rand};
 
-const RAND_SIZE_LEN: u32 = 8;
-const RAND_SIZE: u32 = 1 << (RAND_SIZE_LEN as uint);
-const RAND_SIZE_UINT: uint = 1 << (RAND_SIZE_LEN as uint);
+type w32 = w<u32>;
+type w64 = w<u64>;
+
+const RAND_SIZE_LEN: usize = 8;
+const RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
+const RAND_SIZE_USIZE: usize = 1 << RAND_SIZE_LEN;
 
 /// A random number generator that uses the ISAAC algorithm[1].
 ///
@@ -32,18 +38,18 @@ const RAND_SIZE_UINT: uint = 1 << (RAND_SIZE_LEN as uint);
 #[derive(Copy)]
 pub struct IsaacRng {
     cnt: u32,
-    rsl: [u32; RAND_SIZE_UINT],
-    mem: [u32; RAND_SIZE_UINT],
-    a: u32,
-    b: u32,
-    c: u32
+    rsl: [w32; RAND_SIZE_USIZE],
+    mem: [w32; RAND_SIZE_USIZE],
+    a: w32,
+    b: w32,
+    c: w32,
 }
 
 static EMPTY: IsaacRng = IsaacRng {
     cnt: 0,
-    rsl: [0; RAND_SIZE_UINT],
-    mem: [0; RAND_SIZE_UINT],
-    a: 0, b: 0, c: 0
+    rsl: [w(0); RAND_SIZE_USIZE],
+    mem: [w(0); RAND_SIZE_USIZE],
+    a: w(0), b: w(0), c: w(0),
 };
 
 impl IsaacRng {
@@ -60,7 +66,7 @@ impl IsaacRng {
     /// of `rsl` as a seed, otherwise construct one algorithmically (not
     /// randomly).
     fn init(&mut self, use_rsl: bool) {
-        let mut a = 0x9e3779b9;
+        let mut a = w(0x9e3779b9);
         let mut b = a;
         let mut c = a;
         let mut d = a;
@@ -71,14 +77,14 @@ impl IsaacRng {
 
         macro_rules! mix {
             () => {{
-                a^=b<<11; d+=a; b+=c;
-                b^=c>>2;  e+=b; c+=d;
-                c^=d<<8;  f+=c; d+=e;
-                d^=e>>16; g+=d; e+=f;
-                e^=f<<10; h+=e; f+=g;
-                f^=g>>4;  a+=f; g+=h;
-                g^=h<<8;  b+=g; h+=a;
-                h^=a>>9;  c+=h; a+=b;
+                a=a^(b<<11); d=d+a; b=b+c;
+                b=b^(c>>2);  e=e+b; c=c+d;
+                c=c^(d<<8);  f=f+c; d=d+e;
+                d=d^(e>>16); g=g+d; e=e+f;
+                e=e^(f<<10); h=h+e; f=f+g;
+                f=f^(g>>4);  a=a+f; g=g+h;
+                g=g^(h<<8);  b=b+g; h=h+a;
+                h=h^(a>>9);  c=c+h; a=a+b;
             }}
         }
 
@@ -89,11 +95,11 @@ impl IsaacRng {
         if use_rsl {
             macro_rules! memloop {
                 ($arr:expr) => {{
-                    for i in range_step(0, RAND_SIZE as uint, 8) {
-                        a+=$arr[i  ]; b+=$arr[i+1];
-                        c+=$arr[i+2]; d+=$arr[i+3];
-                        e+=$arr[i+4]; f+=$arr[i+5];
-                        g+=$arr[i+6]; h+=$arr[i+7];
+                    for i in (0..RAND_SIZE_USIZE).step_by(8) {
+                        a=a+$arr[i  ]; b=b+$arr[i+1];
+                        c=c+$arr[i+2]; d=d+$arr[i+3];
+                        e=e+$arr[i+4]; f=f+$arr[i+5];
+                        g=g+$arr[i+6]; h=h+$arr[i+7];
                         mix!();
                         self.mem[i  ]=a; self.mem[i+1]=b;
                         self.mem[i+2]=c; self.mem[i+3]=d;
@@ -106,7 +112,7 @@ impl IsaacRng {
             memloop!(self.rsl);
             memloop!(self.mem);
         } else {
-            for i in range_step(0, RAND_SIZE as uint, 8) {
+            for i in (0..RAND_SIZE_USIZE).step_by(8) {
                 mix!();
                 self.mem[i  ]=a; self.mem[i+1]=b;
                 self.mem[i+2]=c; self.mem[i+3]=d;
@@ -122,31 +128,31 @@ impl IsaacRng {
     #[inline]
     #[allow(unsigned_negation)]
     fn isaac(&mut self) {
-        self.c += 1;
+        self.c = self.c + w(1);
         // abbreviations
         let mut a = self.a;
         let mut b = self.b + self.c;
 
-        static MIDPOINT: uint = (RAND_SIZE / 2) as uint;
+        const MIDPOINT: usize = RAND_SIZE_USIZE / 2;
 
         macro_rules! ind {
-            ($x:expr) => ( self.mem[(($x >> 2) as uint & ((RAND_SIZE - 1) as uint))] )
+            ($x:expr) => (self.mem[($x >> 2).0 as usize & (RAND_SIZE_USIZE - 1)] )
         }
 
         let r = [(0, MIDPOINT), (MIDPOINT, 0)];
-        for &(mr_offset, m2_offset) in &r {
+        for &(mr_offset, m2_offset) in r.iter() {
 
             macro_rules! rngstepp {
                 ($j:expr, $shift:expr) => {{
                     let base = $j;
-                    let mix = a << $shift as uint;
+                    let mix = a << $shift;
 
                     let x = self.mem[base  + mr_offset];
                     a = (a ^ mix) + self.mem[base + m2_offset];
                     let y = ind!(x) + a + b;
                     self.mem[base + mr_offset] = y;
 
-                    b = ind!(y >> RAND_SIZE_LEN as uint) + x;
+                    b = ind!(y >> RAND_SIZE_LEN) + x;
                     self.rsl[base + mr_offset] = b;
                 }}
             }
@@ -154,19 +160,19 @@ impl IsaacRng {
             macro_rules! rngstepn {
                 ($j:expr, $shift:expr) => {{
                     let base = $j;
-                    let mix = a >> $shift as uint;
+                    let mix = a >> $shift;
 
                     let x = self.mem[base  + mr_offset];
                     a = (a ^ mix) + self.mem[base + m2_offset];
                     let y = ind!(x) + a + b;
                     self.mem[base + mr_offset] = y;
 
-                    b = ind!(y >> RAND_SIZE_LEN as uint) + x;
+                    b = ind!(y >> RAND_SIZE_LEN) + x;
                     self.rsl[base + mr_offset] = b;
                 }}
             }
 
-            for i in range_step(0, MIDPOINT, 4) {
+            for i in (0..MIDPOINT).step_by(4) {
                 rngstepp!(i + 0, 13);
                 rngstepn!(i + 1, 6);
                 rngstepp!(i + 2, 2);
@@ -207,7 +213,7 @@ impl Rng for IsaacRng {
         // (the % is cheaply telling the optimiser that we're always
         // in bounds, without unsafe. NB. this is a power of two, so
         // it optimises to a bitwise mask).
-        self.rsl[(self.cnt % RAND_SIZE) as uint]
+        self.rsl[(self.cnt % RAND_SIZE) as usize].0
     }
 }
 
@@ -215,15 +221,15 @@ impl<'a> SeedableRng<&'a [u32]> for IsaacRng {
     fn reseed(&mut self, seed: &'a [u32]) {
         // make the seed into [seed[0], seed[1], ..., seed[seed.len()
         // - 1], 0, 0, ...], to fill rng.rsl.
-        let seed_iter = seed.iter().cloned().chain(repeat(0u32));
+        let seed_iter = seed.iter().cloned().chain(repeat(0));
 
         for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
-            *rsl_elem = seed_elem;
+            *rsl_elem = w(seed_elem);
         }
         self.cnt = 0;
-        self.a = 0;
-        self.b = 0;
-        self.c = 0;
+        self.a = w(0);
+        self.b = w(0);
+        self.c = w(0);
 
         self.init(true);
     }
@@ -246,21 +252,21 @@ impl Rand for IsaacRng {
         unsafe {
             let ptr = ret.rsl.as_mut_ptr() as *mut u8;
 
-            let slice = slice::from_raw_parts_mut(ptr, (RAND_SIZE * 4) as uint);
+            let slice = slice::from_raw_parts_mut(ptr, RAND_SIZE_USIZE * 4);
             other.fill_bytes(slice);
         }
         ret.cnt = 0;
-        ret.a = 0;
-        ret.b = 0;
-        ret.c = 0;
+        ret.a = w(0);
+        ret.b = w(0);
+        ret.c = w(0);
 
         ret.init(true);
         return ret;
     }
 }
 
-const RAND_SIZE_64_LEN: uint = 8;
-const RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN;
+const RAND_SIZE_64_LEN: usize = 8;
+const RAND_SIZE_64: usize = 1 << RAND_SIZE_64_LEN;
 
 /// A random number generator that uses ISAAC-64[1], the 64-bit
 /// variant of the ISAAC algorithm.
@@ -274,19 +280,19 @@ const RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN;
 /// generator*](http://www.burtleburtle.net/bob/rand/isaacafa.html)
 #[derive(Copy)]
 pub struct Isaac64Rng {
-    cnt: uint,
-    rsl: [u64; RAND_SIZE_64],
-    mem: [u64; RAND_SIZE_64],
-    a: u64,
-    b: u64,
-    c: u64,
+    cnt: usize,
+    rsl: [w64; RAND_SIZE_64],
+    mem: [w64; RAND_SIZE_64],
+    a: w64,
+    b: w64,
+    c: w64,
 }
 
 static EMPTY_64: Isaac64Rng = Isaac64Rng {
     cnt: 0,
-    rsl: [0; RAND_SIZE_64],
-    mem: [0; RAND_SIZE_64],
-    a: 0, b: 0, c: 0,
+    rsl: [w(0); RAND_SIZE_64],
+    mem: [w(0); RAND_SIZE_64],
+    a: w(0), b: w(0), c: w(0),
 };
 
 impl Isaac64Rng {
@@ -304,7 +310,7 @@ impl Isaac64Rng {
     fn init(&mut self, use_rsl: bool) {
         macro_rules! init {
             ($var:ident) => (
-                let mut $var = 0x9e3779b97f4a7c13;
+                let mut $var = w(0x9e3779b97f4a7c13);
             )
         }
         init!(a); init!(b); init!(c); init!(d);
@@ -312,14 +318,14 @@ impl Isaac64Rng {
 
         macro_rules! mix {
             () => {{
-                a-=e; f^=h>>9;  h+=a;
-                b-=f; g^=a<<9;  a+=b;
-                c-=g; h^=b>>23; b+=c;
-                d-=h; a^=c<<15; c+=d;
-                e-=a; b^=d>>14; d+=e;
-                f-=b; c^=e<<20; e+=f;
-                g-=c; d^=f>>17; f+=g;
-                h-=d; e^=g<<14; g+=h;
+                a=a-e; f=f^(h>>9);  h=h+a;
+                b=b-f; g=g^(a<<9);  a=a+b;
+                c=c-g; h=h^(b>>23); b=b+c;
+                d=d-h; a=a^(c<<15); c=c+d;
+                e=e-a; b=b^(d>>14); d=d+e;
+                f=f-b; c=c^(e<<20); e=e+f;
+                g=g-c; d=d^(f>>17); f=f+g;
+                h=h-d; e=e^(g<<14); g=g+h;
             }}
         }
 
@@ -331,10 +337,10 @@ impl Isaac64Rng {
             macro_rules! memloop {
                 ($arr:expr) => {{
                     for i in (0..RAND_SIZE_64 / 8).map(|i| i * 8) {
-                        a+=$arr[i  ]; b+=$arr[i+1];
-                        c+=$arr[i+2]; d+=$arr[i+3];
-                        e+=$arr[i+4]; f+=$arr[i+5];
-                        g+=$arr[i+6]; h+=$arr[i+7];
+                        a=a+$arr[i  ]; b=b+$arr[i+1];
+                        c=c+$arr[i+2]; d=d+$arr[i+3];
+                        e=e+$arr[i+4]; f=f+$arr[i+5];
+                        g=g+$arr[i+6]; h=h+$arr[i+7];
                         mix!();
                         self.mem[i  ]=a; self.mem[i+1]=b;
                         self.mem[i+2]=c; self.mem[i+3]=d;
@@ -361,25 +367,25 @@ impl Isaac64Rng {
 
     /// Refills the output buffer (`self.rsl`)
     fn isaac64(&mut self) {
-        self.c += 1;
+        self.c = self.c + w(1);
         // abbreviations
         let mut a = self.a;
         let mut b = self.b + self.c;
-        const MIDPOINT: uint =  RAND_SIZE_64 / 2;
-        const MP_VEC: [(uint, uint); 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
+        const MIDPOINT: usize =  RAND_SIZE_64 / 2;
+        const MP_VEC: [(usize, usize); 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
         macro_rules! ind {
             ($x:expr) => {
-                *self.mem.get_unchecked(($x as uint >> 3) & (RAND_SIZE_64 - 1))
+                *self.mem.get_unchecked((($x >> 3).0 as usize) & (RAND_SIZE_64 - 1))
             }
         }
 
-        for &(mr_offset, m2_offset) in &MP_VEC {
+        for &(mr_offset, m2_offset) in MP_VEC.iter() {
             for base in (0..MIDPOINT / 4).map(|i| i * 4) {
 
                 macro_rules! rngstepp {
                     ($j:expr, $shift:expr) => {{
                         let base = base + $j;
-                        let mix = a ^ (a << $shift as uint);
+                        let mix = a ^ (a << $shift);
                         let mix = if $j == 0 {!mix} else {mix};
 
                         unsafe {
@@ -397,7 +403,7 @@ impl Isaac64Rng {
                 macro_rules! rngstepn {
                     ($j:expr, $shift:expr) => {{
                         let base = base + $j;
-                        let mix = a ^ (a >> $shift as uint);
+                        let mix = a ^ (a >> $shift);
                         let mix = if $j == 0 {!mix} else {mix};
 
                         unsafe {
@@ -450,7 +456,7 @@ impl Rng for Isaac64Rng {
         // See corresponding location in IsaacRng.next_u32 for
         // explanation.
         debug_assert!(self.cnt < RAND_SIZE_64);
-        self.rsl[(self.cnt % RAND_SIZE_64) as uint]
+        self.rsl[(self.cnt % RAND_SIZE_64) as usize].0
     }
 }
 
@@ -458,15 +464,15 @@ impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng {
     fn reseed(&mut self, seed: &'a [u64]) {
         // make the seed into [seed[0], seed[1], ..., seed[seed.len()
         // - 1], 0, 0, ...], to fill rng.rsl.
-        let seed_iter = seed.iter().cloned().chain(repeat(0u64));
+        let seed_iter = seed.iter().cloned().chain(repeat(0));
 
         for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
-            *rsl_elem = seed_elem;
+            *rsl_elem = w(seed_elem);
         }
         self.cnt = 0;
-        self.a = 0;
-        self.b = 0;
-        self.c = 0;
+        self.a = w(0);
+        self.b = w(0);
+        self.c = w(0);
 
         self.init(true);
     }
@@ -489,13 +495,13 @@ impl Rand for Isaac64Rng {
         unsafe {
             let ptr = ret.rsl.as_mut_ptr() as *mut u8;
 
-            let slice = slice::from_raw_parts_mut(ptr, (RAND_SIZE_64 * 8) as uint);
+            let slice = slice::from_raw_parts_mut(ptr, RAND_SIZE_64 * 8);
             other.fill_bytes(slice);
         }
         ret.cnt = 0;
-        ret.a = 0;
-        ret.b = 0;
-        ret.c = 0;
+        ret.a = w(0);
+        ret.b = w(0);
+        ret.c = w(0);
 
         ret.init(true);
         return ret;
@@ -514,16 +520,16 @@ mod test {
     #[test]
     fn test_rng_32_rand_seeded() {
         let s = ::test::rng().gen_iter::<u32>().take(256).collect::<Vec<u32>>();
-        let mut ra: IsaacRng = SeedableRng::from_seed(&*s);
-        let mut rb: IsaacRng = SeedableRng::from_seed(&*s);
+        let mut ra: IsaacRng = SeedableRng::from_seed(&s[..]);
+        let mut rb: IsaacRng = SeedableRng::from_seed(&s[..]);
         assert!(order::equals(ra.gen_ascii_chars().take(100),
                               rb.gen_ascii_chars().take(100)));
     }
     #[test]
     fn test_rng_64_rand_seeded() {
         let s = ::test::rng().gen_iter::<u64>().take(256).collect::<Vec<u64>>();
-        let mut ra: Isaac64Rng = SeedableRng::from_seed(&*s);
-        let mut rb: Isaac64Rng = SeedableRng::from_seed(&*s);
+        let mut ra: Isaac64Rng = SeedableRng::from_seed(&s[..]);
+        let mut rb: Isaac64Rng = SeedableRng::from_seed(&s[..]);
         assert!(order::equals(ra.gen_ascii_chars().take(100),
                               rb.gen_ascii_chars().take(100)));
     }
@@ -548,7 +554,7 @@ mod test {
     #[test]
     fn test_rng_32_reseed() {
         let s = ::test::rng().gen_iter::<u32>().take(256).collect::<Vec<u32>>();
-        let mut r: IsaacRng = SeedableRng::from_seed(&*s);
+        let mut r: IsaacRng = SeedableRng::from_seed(&s[..]);
         let string1: String = r.gen_ascii_chars().take(100).collect();
 
         r.reseed(&s);
@@ -559,7 +565,7 @@ mod test {
     #[test]
     fn test_rng_64_reseed() {
         let s = ::test::rng().gen_iter::<u64>().take(256).collect::<Vec<u64>>();
-        let mut r: Isaac64Rng = SeedableRng::from_seed(&*s);
+        let mut r: Isaac64Rng = SeedableRng::from_seed(&s[..]);
         let string1: String = r.gen_ascii_chars().take(100).collect();
 
         r.reseed(&s);
index 7588bf7c5158e7f27114784bbe2d025ec8dbfdbe..15d3d981eb5c0c79fd565e7e33ecbcc3aea19c8c 100644 (file)
 //! is not recommended to use this library directly, but rather the official
 //! interface through `std::rand`.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rand"]
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
-#![feature(int_uint)]
 #![feature(no_std)]
 #![no_std]
 #![unstable(feature = "rand")]
 #![feature(staged_api)]
 #![staged_api]
 #![feature(core)]
+#![feature(step_by)]
 #![deprecated(reason = "use the crates.io `rand` library instead",
               since = "1.0.0-alpha")]
 
+#![cfg_attr(test, feature(test, rand, rustc_private))]
+
 #![allow(deprecated)]
 
 #[macro_use]
@@ -50,7 +54,7 @@ use distributions::{Range, IndependentSample};
 use distributions::range::SampleRange;
 
 #[cfg(test)]
-static RAND_BENCH_N: u64 = 100;
+const RAND_BENCH_N: u64 = 100;
 
 pub mod distributions;
 pub mod isaac;
@@ -95,8 +99,8 @@ pub trait Rng : Sized {
     /// See `Closed01` for the closed interval `[0,1]`, and
     /// `Open01` for the open interval `(0,1)`.
     fn next_f32(&mut self) -> f32 {
-        const MANTISSA_BITS: uint = 24;
-        const IGNORED_BITS: uint = 8;
+        const MANTISSA_BITS: usize = 24;
+        const IGNORED_BITS: usize = 8;
         const SCALE: f32 = (1u64 << MANTISSA_BITS) as f32;
 
         // using any more than `MANTISSA_BITS` bits will
@@ -117,8 +121,8 @@ pub trait Rng : Sized {
     /// See `Closed01` for the closed interval `[0,1]`, and
     /// `Open01` for the open interval `(0,1)`.
     fn next_f64(&mut self) -> f64 {
-        const MANTISSA_BITS: uint = 53;
-        const IGNORED_BITS: uint = 11;
+        const MANTISSA_BITS: usize = 53;
+        const IGNORED_BITS: usize = 11;
         const SCALE: f64 = (1u64 << MANTISSA_BITS) as f64;
 
         (self.next_u64() >> IGNORED_BITS) as f64 / SCALE
@@ -142,14 +146,15 @@ pub trait Rng : Sized {
     /// (e.g. reading past the end of a file that is being used as the
     /// source of randomness).
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(rand, core)]
     /// use std::rand::{thread_rng, Rng};
     ///
-    /// let mut v = [0u8; 13579];
+    /// let mut v = [0; 13579];
     /// thread_rng().fill_bytes(&mut v);
-    /// println!("{:?}", v.as_slice());
+    /// println!("{:?}", &v[..]);
     /// ```
     fn fill_bytes(&mut self, dest: &mut [u8]) {
         // this could, in theory, be done by transmuting dest to a
@@ -177,13 +182,14 @@ pub trait Rng : Sized {
 
     /// Return a random value of a `Rand` type.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(rand)]
     /// use std::rand::{thread_rng, Rng};
     ///
     /// let mut rng = thread_rng();
-    /// let x: uint = rng.gen();
+    /// let x: usize = rng.gen();
     /// println!("{}", x);
     /// println!("{:?}", rng.gen::<(f64, bool)>());
     /// ```
@@ -195,13 +201,14 @@ pub trait Rng : Sized {
     /// Return an iterator that will yield an infinite number of randomly
     /// generated items.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(rand)]
     /// use std::rand::{thread_rng, Rng};
     ///
     /// let mut rng = thread_rng();
-    /// let x = rng.gen_iter::<uint>().take(10).collect::<Vec<uint>>();
+    /// let x = rng.gen_iter::<usize>().take(10).collect::<Vec<usize>>();
     /// println!("{:?}", x);
     /// println!("{:?}", rng.gen_iter::<(f64, bool)>().take(5)
     ///                     .collect::<Vec<(f64, bool)>>());
@@ -222,13 +229,14 @@ pub trait Rng : Sized {
     ///
     /// Panics if `low >= high`.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(rand)]
     /// use std::rand::{thread_rng, Rng};
     ///
     /// let mut rng = thread_rng();
-    /// let n: uint = rng.gen_range(0, 10);
+    /// let n: usize = rng.gen_range(0, 10);
     /// println!("{}", n);
     /// let m: f64 = rng.gen_range(-40.0f64, 1.3e5f64);
     /// println!("{}", m);
@@ -240,23 +248,25 @@ pub trait Rng : Sized {
 
     /// Return a bool with a 1 in n chance of true
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(rand)]
     /// use std::rand::{thread_rng, Rng};
     ///
     /// let mut rng = thread_rng();
     /// println!("{}", rng.gen_weighted_bool(3));
     /// ```
-    fn gen_weighted_bool(&mut self, n: uint) -> bool {
+    fn gen_weighted_bool(&mut self, n: usize) -> bool {
         n <= 1 || self.gen_range(0, n) == 0
     }
 
     /// Return an iterator of random characters from the set A-Z,a-z,0-9.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(rand)]
     /// use std::rand::{thread_rng, Rng};
     ///
     /// let s: String = thread_rng().gen_ascii_chars().take(10).collect();
@@ -270,9 +280,10 @@ pub trait Rng : Sized {
     ///
     /// Return `None` if `values` is empty.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(rand)]
     /// use std::rand::{thread_rng, Rng};
     ///
     /// let choices = [1, 2, 4, 8, 16, 32];
@@ -290,17 +301,18 @@ pub trait Rng : Sized {
 
     /// Shuffle a mutable slice in place.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(rand, core)]
     /// use std::rand::{thread_rng, Rng};
     ///
     /// let mut rng = thread_rng();
     /// let mut y = [1, 2, 3];
     /// rng.shuffle(&mut y);
-    /// println!("{:?}", y.as_slice());
+    /// println!("{:?}", y);
     /// rng.shuffle(&mut y);
-    /// println!("{:?}", y.as_slice());
+    /// println!("{:?}", y);
     /// ```
     fn shuffle<T>(&mut self, values: &mut [T]) {
         let mut i = values.len();
@@ -340,7 +352,7 @@ impl<'a, R: Rng> Iterator for AsciiGenerator<'a, R> {
     type Item = char;
 
     fn next(&mut self) -> Option<char> {
-        static GEN_ASCII_STR_CHARSET: &'static [u8] =
+        const GEN_ASCII_STR_CHARSET: &'static [u8] =
             b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
               abcdefghijklmnopqrstuvwxyz\
               0123456789";
@@ -353,9 +365,10 @@ impl<'a, R: Rng> Iterator for AsciiGenerator<'a, R> {
 pub trait SeedableRng<Seed>: Rng {
     /// Reseed an RNG with the given seed.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(rand)]
     /// use std::rand::{Rng, SeedableRng, StdRng};
     ///
     /// let seed: &[_] = &[1, 2, 3, 4];
@@ -368,9 +381,10 @@ pub trait SeedableRng<Seed>: Rng {
 
     /// Create a new RNG with the given seed.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(rand)]
     /// use std::rand::{Rng, SeedableRng, StdRng};
     ///
     /// let seed: &[_] = &[1, 2, 3, 4];
@@ -473,8 +487,10 @@ impl Rand for XorShiftRng {
 /// `Rand` implementation for `f32` and `f64` for the half-open
 /// `[0,1)`.
 ///
-/// # Example
-/// ```rust
+/// # Examples
+///
+/// ```
+/// # #![feature(rand)]
 /// use std::rand::{random, Open01};
 ///
 /// let Open01(val) = random::<Open01<f32>>();
@@ -489,9 +505,10 @@ pub struct Open01<F>(pub F);
 /// `Rand` implementation of `f32` and `f64` for the half-open
 /// `[0,1)`.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand)]
 /// use std::rand::{random, Closed01};
 ///
 /// let Closed01(val) = random::<Closed01<f32>>();
index d5c5d5004657e7facfdee32003e8ef9440d5a073..e2a5276cc78abf8e8782dd8c7e597d58541b9b88 100644 (file)
 
 use core::prelude::*;
 use core::char;
-use core::int;
-use core::uint;
+use core::isize;
+use core::usize;
 
 use {Rand,Rng};
 
-impl Rand for int {
+impl Rand for isize {
     #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> int {
-        if int::BITS == 32 {
-            rng.gen::<i32>() as int
+    fn rand<R: Rng>(rng: &mut R) -> isize {
+        if isize::BITS == 32 {
+            rng.gen::<i32>() as isize
         } else {
-            rng.gen::<i64>() as int
+            rng.gen::<i64>() as isize
         }
     }
 }
@@ -56,13 +56,13 @@ impl Rand for i64 {
     }
 }
 
-impl Rand for uint {
+impl Rand for usize {
     #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> uint {
-        if uint::BITS == 32 {
-            rng.gen::<u32>() as uint
+    fn rand<R: Rng>(rng: &mut R) -> usize {
+        if usize::BITS == 32 {
+            rng.gen::<u32>() as usize
         } else {
-            rng.gen::<u64>() as uint
+            rng.gen::<u64>() as usize
         }
     }
 }
@@ -141,7 +141,7 @@ impl Rand for char {
     #[inline]
     fn rand<R: Rng>(rng: &mut R) -> char {
         // a char is 21 bits
-        static CHAR_MASK: u32 = 0x001f_ffff;
+        const CHAR_MASK: u32 = 0x001f_ffff;
         loop {
             // Rejection sampling. About 0.2% of numbers with at most
             // 21-bits are invalid codepoints (surrogates), so this
@@ -214,7 +214,6 @@ impl<T:Rand> Rand for Option<T> {
 
 #[cfg(test)]
 mod tests {
-    use std::prelude::v1::*;
     use std::rand::{Rng, thread_rng, Open01, Closed01};
 
     struct ConstantRng(u64);
index f4d3e975b75b9e25d187a4fe64e8c86a1608c9eb..98d1bbf5af9da0b54ccdceac90c230fc30722e07 100644 (file)
@@ -18,14 +18,14 @@ use core::default::Default;
 
 /// How many bytes of entropy the underling RNG is allowed to generate
 /// before it is reseeded.
-static DEFAULT_GENERATION_THRESHOLD: uint = 32 * 1024;
+const DEFAULT_GENERATION_THRESHOLD: usize = 32 * 1024;
 
 /// A wrapper around any RNG which reseeds the underlying RNG after it
 /// has generated a certain number of random bytes.
 pub struct ReseedingRng<R, Rsdr> {
     rng: R,
-    generation_threshold: uint,
-    bytes_generated: uint,
+    generation_threshold: usize,
+    bytes_generated: usize,
     /// Controls the behaviour when reseeding the RNG.
     pub reseeder: Rsdr,
 }
@@ -38,7 +38,7 @@ impl<R: Rng, Rsdr: Reseeder<R>> ReseedingRng<R, Rsdr> {
     /// * `rng`: the random number generator to use.
     /// * `generation_threshold`: the number of bytes of entropy at which to reseed the RNG.
     /// * `reseeder`: the reseeding object to use.
-    pub fn new(rng: R, generation_threshold: uint, reseeder: Rsdr) -> ReseedingRng<R,Rsdr> {
+    pub fn new(rng: R, generation_threshold: usize, reseeder: Rsdr) -> ReseedingRng<R,Rsdr> {
         ReseedingRng {
             rng: rng,
             generation_threshold: generation_threshold,
@@ -100,9 +100,10 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R> + Default>
 
 /// Something that can be used to reseed an RNG via `ReseedingRng`.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand)]
 /// use std::rand::{Rng, SeedableRng, StdRng};
 /// use std::rand::reseeding::{Reseeder, ReseedingRng};
 ///
@@ -133,12 +134,8 @@ pub trait Reseeder<R> {
 
 /// Reseed an RNG using a `Default` instance. This reseeds by
 /// replacing the RNG with the result of a `Default::default` call.
-#[derive(Copy)]
-pub struct ReseedWithDefault { __hack: [u8; 0] }
-// FIXME(#21721) used to be an unit struct but that can cause
-// certain LLVM versions to abort during optimizations.
-#[allow(non_upper_case_globals)]
-pub const ReseedWithDefault: ReseedWithDefault = ReseedWithDefault { __hack: [] };
+#[derive(Copy, Clone)]
+pub struct ReseedWithDefault;
 
 impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
     fn reseed(&mut self, rng: &mut R) {
@@ -216,10 +213,10 @@ mod test {
         assert_eq!(string1, string2);
     }
 
-    static FILL_BYTES_V_LEN: uint = 13579;
+    const FILL_BYTES_V_LEN: usize = 13579;
     #[test]
     fn test_rng_fill_bytes() {
-        let mut v = repeat(0u8).take(FILL_BYTES_V_LEN).collect::<Vec<_>>();
+        let mut v = repeat(0).take(FILL_BYTES_V_LEN).collect::<Vec<_>>();
         ::test::rng().fill_bytes(&mut v);
 
         // Sanity test: if we've gotten here, `fill_bytes` has not infinitely
diff --git a/src/librbml/io.rs b/src/librbml/io.rs
deleted file mode 100644 (file)
index 230fda1..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-// 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.
-//
-// 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 std::old_io::{IoError, IoResult, SeekStyle};
-use std::old_io;
-use std::slice;
-use std::iter::repeat;
-
-static BUF_CAPACITY: uint = 128;
-
-fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64> {
-    // compute offset as signed and clamp to prevent overflow
-    let pos = match seek {
-        old_io::SeekSet => 0,
-        old_io::SeekEnd => end,
-        old_io::SeekCur => cur,
-    } as i64;
-
-    if offset + pos < 0 {
-        Err(IoError {
-            kind: old_io::InvalidInput,
-            desc: "invalid seek to a negative offset",
-            detail: None
-        })
-    } else {
-        Ok((offset + pos) as u64)
-    }
-}
-
-/// Writes to an owned, growable byte vector that supports seeking.
-///
-/// # Example
-///
-/// ```rust
-/// # #![allow(unused_must_use)]
-/// use rbml::io::SeekableMemWriter;
-///
-/// let mut w = SeekableMemWriter::new();
-/// w.write(&[0, 1, 2]);
-///
-/// assert_eq!(w.unwrap(), vec!(0, 1, 2));
-/// ```
-pub struct SeekableMemWriter {
-    buf: Vec<u8>,
-    pos: uint,
-}
-
-impl SeekableMemWriter {
-    /// Create a new `SeekableMemWriter`.
-    #[inline]
-    pub fn new() -> SeekableMemWriter {
-        SeekableMemWriter::with_capacity(BUF_CAPACITY)
-    }
-    /// Create a new `SeekableMemWriter`, allocating at least `n` bytes for
-    /// the internal buffer.
-    #[inline]
-    pub fn with_capacity(n: uint) -> SeekableMemWriter {
-        SeekableMemWriter { buf: Vec::with_capacity(n), pos: 0 }
-    }
-
-    /// Acquires an immutable reference to the underlying buffer of this
-    /// `SeekableMemWriter`.
-    ///
-    /// No method is exposed for acquiring a mutable reference to the buffer
-    /// because it could corrupt the state of this `MemWriter`.
-    #[inline]
-    pub fn get_ref<'a>(&'a self) -> &'a [u8] { &self.buf }
-
-    /// Unwraps this `SeekableMemWriter`, returning the underlying buffer
-    #[inline]
-    pub fn unwrap(self) -> Vec<u8> { self.buf }
-}
-
-impl Writer for SeekableMemWriter {
-    #[inline]
-    fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
-        if self.pos == self.buf.len() {
-            self.buf.push_all(buf)
-        } else {
-            // Make sure the internal buffer is as least as big as where we
-            // currently are
-            let difference = self.pos as i64 - self.buf.len() as i64;
-            if difference > 0 {
-                self.buf.extend(repeat(0).take(difference as uint));
-            }
-
-            // Figure out what bytes will be used to overwrite what's currently
-            // there (left), and what will be appended on the end (right)
-            let cap = self.buf.len() - self.pos;
-            let (left, right) = if cap <= buf.len() {
-                (&buf[..cap], &buf[cap..])
-            } else {
-                let result: (_, &[_]) = (buf, &[]);
-                result
-            };
-
-            // Do the necessary writes
-            if left.len() > 0 {
-                slice::bytes::copy_memory(&mut self.buf[self.pos..], left);
-            }
-            if right.len() > 0 {
-                self.buf.push_all(right);
-            }
-        }
-
-        // Bump us forward
-        self.pos += buf.len();
-        Ok(())
-    }
-}
-
-impl Seek for SeekableMemWriter {
-    #[inline]
-    fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
-
-    #[inline]
-    fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
-        let new = try!(combine(style, self.pos, self.buf.len(), pos));
-        self.pos = new as uint;
-        Ok(())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    extern crate test;
-    use super::SeekableMemWriter;
-    use std::old_io;
-    use std::iter::repeat;
-    use test::Bencher;
-
-    #[test]
-    fn test_seekable_mem_writer() {
-        let mut writer = SeekableMemWriter::new();
-        assert_eq!(writer.tell(), Ok(0));
-        writer.write(&[0]).unwrap();
-        assert_eq!(writer.tell(), Ok(1));
-        writer.write(&[1, 2, 3]).unwrap();
-        writer.write(&[4, 5, 6, 7]).unwrap();
-        assert_eq!(writer.tell(), Ok(8));
-        let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
-        assert_eq!(writer.get_ref(), b);
-
-        writer.seek(0, old_io::SeekSet).unwrap();
-        assert_eq!(writer.tell(), Ok(0));
-        writer.write(&[3, 4]).unwrap();
-        let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7];
-        assert_eq!(writer.get_ref(), b);
-
-        writer.seek(1, old_io::SeekCur).unwrap();
-        writer.write(&[0, 1]).unwrap();
-        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7];
-        assert_eq!(writer.get_ref(), b);
-
-        writer.seek(-1, old_io::SeekEnd).unwrap();
-        writer.write(&[1, 2]).unwrap();
-        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2];
-        assert_eq!(writer.get_ref(), b);
-
-        writer.seek(1, old_io::SeekEnd).unwrap();
-        writer.write(&[1]).unwrap();
-        let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1];
-        assert_eq!(writer.get_ref(), b);
-    }
-
-    #[test]
-    fn seek_past_end() {
-        let mut r = SeekableMemWriter::new();
-        r.seek(10, old_io::SeekSet).unwrap();
-        assert!(r.write(&[3]).is_ok());
-    }
-
-    #[test]
-    fn seek_before_0() {
-        let mut r = SeekableMemWriter::new();
-        assert!(r.seek(-1, old_io::SeekSet).is_err());
-    }
-
-    fn do_bench_seekable_mem_writer(b: &mut Bencher, times: uint, len: uint) {
-        let src: Vec<u8> = repeat(5).take(len).collect();
-
-        b.bytes = (times * len) as u64;
-        b.iter(|| {
-            let mut wr = SeekableMemWriter::new();
-            for _ in 0..times {
-                wr.write(&src).unwrap();
-            }
-
-            let v = wr.unwrap();
-            assert_eq!(v.len(), times * len);
-            assert!(v.iter().all(|x| *x == 5));
-        });
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_001_0000(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 1, 0)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_001_0010(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 1, 10)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_001_0100(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 1, 100)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_001_1000(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 1, 1000)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_100_0000(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 100, 0)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_100_0010(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 100, 10)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_100_0100(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 100, 100)
-    }
-
-    #[bench]
-    fn bench_seekable_mem_writer_100_1000(b: &mut Bencher) {
-        do_bench_seekable_mem_writer(b, 100, 1000)
-    }
-}
index 4af322089d53d40d7d3bea7ece5bed39ff48437a..e2875ac8ca529479ab904f06a0c843375c880b6e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Really Bad Markup Language (rbml) is a temporary measure until we migrate
-//! the rust object metadata to a better serialization format. It is not
-//! intended to be used by users.
+//! Really Bad Markup Language (rbml) is an internal serialization format of rustc.
+//! This is not intended to be used by users.
 //!
-//! It is loosely based on the Extensible Binary Markup Language (ebml):
-//!     http://www.matroska.org/technical/specs/rfc/index.html
+//! Originally based on the Extensible Binary Markup Language
+//! (ebml; http://www.matroska.org/technical/specs/rfc/index.html),
+//! it is now a separate format tuned for the rust object metadata.
+//!
+//! # Encoding
+//!
+//! RBML document consists of the tag, length and data.
+//! The encoded data can contain multiple RBML documents concatenated.
+//!
+//! **Tags** are a hint for the following data.
+//! Tags are a number from 0x000 to 0xfff, where 0xf0 through 0xff is reserved.
+//! Tags less than 0xf0 are encoded in one literal byte.
+//! Tags greater than 0xff are encoded in two big-endian bytes,
+//! where the tag number is ORed with 0xf000. (E.g. tag 0x123 = `f1 23`)
+//!
+//! **Lengths** encode the length of the following data.
+//! It is a variable-length unsigned isize, and one of the following forms:
+//!
+//! - `80` through `fe` for lengths up to 0x7e;
+//! - `40 ff` through `7f ff` for lengths up to 0x3fff;
+//! - `20 40 00` through `3f ff ff` for lengths up to 0x1fffff;
+//! - `10 20 00 00` through `1f ff ff ff` for lengths up to 0xfffffff.
+//!
+//! The "overlong" form is allowed so that the length can be encoded
+//! without the prior knowledge of the encoded data.
+//! For example, the length 0 can be represented either by `80`, `40 00`,
+//! `20 00 00` or `10 00 00 00`.
+//! The encoder tries to minimize the length if possible.
+//! Also, some predefined tags listed below are so commonly used that
+//! their lengths are omitted ("implicit length").
+//!
+//! **Data** can be either binary bytes or zero or more nested RBML documents.
+//! Nested documents cannot overflow, and should be entirely contained
+//! within a parent document.
+//!
+//! # Predefined Tags
+//!
+//! Most RBML tags are defined by the application.
+//! (For the rust object metadata, see also `rustc::metadata::common`.)
+//! RBML itself does define a set of predefined tags however,
+//! intended for the auto-serialization implementation.
+//!
+//! Predefined tags with an implicit length:
+//!
+//! - `U8`  (`00`): 1-byte unsigned integer.
+//! - `U16` (`01`): 2-byte big endian unsigned integer.
+//! - `U32` (`02`): 4-byte big endian unsigned integer.
+//! - `U64` (`03`): 8-byte big endian unsigned integer.
+//!   Any of `U*` tags can be used to encode primitive unsigned integer types,
+//!   as long as it is no greater than the actual size.
+//!   For example, `u8` can only be represented via the `U8` tag.
+//!
+//! - `I8`  (`04`): 1-byte signed integer.
+//! - `I16` (`05`): 2-byte big endian signed integer.
+//! - `I32` (`06`): 4-byte big endian signed integer.
+//! - `I64` (`07`): 8-byte big endian signed integer.
+//!   Similar to `U*` tags. Always uses two's complement encoding.
+//!
+//! - `Bool` (`08`): 1-byte boolean value, `00` for false and `01` for true.
+//!
+//! - `Char` (`09`): 4-byte big endian Unicode scalar value.
+//!   Surrogate pairs or out-of-bound values are invalid.
+//!
+//! - `F32` (`0a`): 4-byte big endian unsigned integer representing
+//!   IEEE 754 binary32 floating-point format.
+//! - `F64` (`0b`): 8-byte big endian unsigned integer representing
+//!   IEEE 754 binary64 floating-point format.
+//!
+//! - `Sub8`  (`0c`): 1-byte unsigned integer for supplementary information.
+//! - `Sub32` (`0d`): 4-byte unsigned integer for supplementary information.
+//!   Those two tags normally occur as the first subdocument of certain tags,
+//!   namely `Enum`, `Vec` and `Map`, to provide a variant or size information.
+//!   They can be used interchangeably.
+//!
+//! Predefined tags with an explicit length:
+//!
+//! - `Str` (`10`): A UTF-8-encoded string.
+//!
+//! - `Enum` (`11`): An enum.
+//!   The first subdocument should be `Sub*` tags with a variant ID.
+//!   Subsequent subdocuments, if any, encode variant arguments.
+//!
+//! - `Vec` (`12`): A vector (sequence).
+//! - `VecElt` (`13`): A vector element.
+//!   The first subdocument should be `Sub*` tags with the number of elements.
+//!   Subsequent subdocuments should be `VecElt` tag per each element.
+//!
+//! - `Map` (`14`): A map (associated array).
+//! - `MapKey` (`15`): A key part of the map entry.
+//! - `MapVal` (`16`): A value part of the map entry.
+//!   The first subdocument should be `Sub*` tags with the number of entries.
+//!   Subsequent subdocuments should be an alternating sequence of
+//!   `MapKey` and `MapVal` tags per each entry.
+//!
+//! - `Opaque` (`17`): An opaque, custom-format tag.
+//!   Used to wrap ordinary custom tags or data in the auto-serialized context.
+//!   Rustc typically uses this to encode type informations.
+//!
+//! First 0x20 tags are reserved by RBML; custom tags start at 0x20.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rbml"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
 
-#![feature(collections)]
 #![feature(core)]
-#![feature(int_uint)]
-#![feature(old_io)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 
+#![cfg_attr(test, feature(test))]
+
 extern crate serialize;
 #[macro_use] extern crate log;
 
@@ -43,14 +140,12 @@ pub use self::Error::*;
 use std::str;
 use std::fmt;
 
-pub mod io;
-
 /// Common data structures
 #[derive(Clone, Copy)]
 pub struct Doc<'a> {
     pub data: &'a [u8],
-    pub start: uint,
-    pub end: uint,
+    pub start: usize,
+    pub end: usize,
 }
 
 impl<'doc> Doc<'doc> {
@@ -58,10 +153,14 @@ impl<'doc> Doc<'doc> {
         Doc { data: data, start: 0, end: data.len() }
     }
 
-    pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> {
+    pub fn get<'a>(&'a self, tag: usize) -> Doc<'a> {
         reader::get_doc(*self, tag)
     }
 
+    pub fn is_empty(&self) -> bool {
+        self.start == self.end
+    }
+
     pub fn as_str_slice<'a>(&'a self) -> &'a str {
         str::from_utf8(&self.data[self.start..self.end]).unwrap()
     }
@@ -72,49 +171,59 @@ impl<'doc> Doc<'doc> {
 }
 
 pub struct TaggedDoc<'a> {
-    tag: uint,
+    tag: usize,
     pub doc: Doc<'a>,
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum EbmlEncoderTag {
-    EsUint,     // 0
-    EsU64,      // 1
-    EsU32,      // 2
-    EsU16,      // 3
-    EsU8,       // 4
-    EsInt,      // 5
-    EsI64,      // 6
-    EsI32,      // 7
-    EsI16,      // 8
-    EsI8,       // 9
-    EsBool,     // 10
-    EsChar,     // 11
-    EsStr,      // 12
-    EsF64,      // 13
-    EsF32,      // 14
-    EsFloat,    // 15
-    EsEnum,     // 16
-    EsEnumVid,  // 17
-    EsEnumBody, // 18
-    EsVec,      // 19
-    EsVecLen,   // 20
-    EsVecElt,   // 21
-    EsMap,      // 22
-    EsMapLen,   // 23
-    EsMapKey,   // 24
-    EsMapVal,   // 25
-
-    EsOpaque,
-
-    EsLabel, // Used only when debugging
+    // tags 00..1f are reserved for auto-serialization.
+    // first NUM_IMPLICIT_TAGS tags are implicitly sized and lengths are not encoded.
+
+    EsU8       = 0x00, // + 1 byte
+    EsU16      = 0x01, // + 2 bytes
+    EsU32      = 0x02, // + 4 bytes
+    EsU64      = 0x03, // + 8 bytes
+    EsI8       = 0x04, // + 1 byte
+    EsI16      = 0x05, // + 2 bytes
+    EsI32      = 0x06, // + 4 bytes
+    EsI64      = 0x07, // + 8 bytes
+    EsBool     = 0x08, // + 1 byte
+    EsChar     = 0x09, // + 4 bytes
+    EsF32      = 0x0a, // + 4 bytes
+    EsF64      = 0x0b, // + 8 bytes
+    EsSub8     = 0x0c, // + 1 byte
+    EsSub32    = 0x0d, // + 4 bytes
+    // 0x0e and 0x0f are reserved
+
+    EsStr      = 0x10,
+    EsEnum     = 0x11, // encodes the variant id as the first EsSub*
+    EsVec      = 0x12, // encodes the # of elements as the first EsSub*
+    EsVecElt   = 0x13,
+    EsMap      = 0x14, // encodes the # of pairs as the first EsSub*
+    EsMapKey   = 0x15,
+    EsMapVal   = 0x16,
+    EsOpaque   = 0x17,
 }
 
+const NUM_TAGS: usize = 0x1000;
+const NUM_IMPLICIT_TAGS: usize = 0x0e;
+
+static TAG_IMPLICIT_LEN: [i8; NUM_IMPLICIT_TAGS] = [
+    1, 2, 4, 8, // EsU*
+    1, 2, 4, 8, // ESI*
+    1, // EsBool
+    4, // EsChar
+    4, 8, // EsF*
+    1, 4, // EsSub*
+];
+
 #[derive(Debug)]
 pub enum Error {
-    IntTooBig(uint),
+    IntTooBig(usize),
+    InvalidTag(usize),
     Expected(String),
-    IoError(std::old_io::IoError),
+    IoError(std::io::Error),
     ApplicationError(String)
 }
 
@@ -130,19 +239,16 @@ pub mod reader {
     use std::char;
 
     use std::isize;
-    use std::old_io::extensions::u64_from_be_bytes;
     use std::mem::transmute;
-    use std::num::Int;
-    use std::option::Option;
-    use std::option::Option::{None, Some};
+    use std::slice::bytes;
 
     use serialize;
 
-    use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsVecLen, EsVecElt,
-        EsMapLen, EsMapKey, EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64,
+    use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsSub8, EsSub32,
+        EsVecElt, EsMapKey, EsU64, EsU32, EsU16, EsU8, EsI64,
         EsI32, EsI16, EsI8, EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
-        EsEnumBody, EsUint, EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc,
-        Error, IntTooBig, Expected };
+        EsOpaque, EbmlEncoderTag, Doc, TaggedDoc,
+        Error, IntTooBig, InvalidTag, Expected, NUM_IMPLICIT_TAGS, TAG_IMPLICIT_LEN };
 
     pub type DecodeResult<T> = Result<T, Error>;
     // rbml reading
@@ -159,60 +265,76 @@ pub mod reader {
         )
     }
 
-    #[derive(Copy)]
+    #[derive(Copy, Clone)]
     pub struct Res {
-        pub val: uint,
-        pub next: uint
+        pub val: usize,
+        pub next: usize
+    }
+
+    pub fn tag_at(data: &[u8], start: usize) -> DecodeResult<Res> {
+        let v = data[start] as usize;
+        if v < 0xf0 {
+            Ok(Res { val: v, next: start + 1 })
+        } else if v > 0xf0 {
+            Ok(Res { val: ((v & 0xf) << 8) | data[start + 1] as usize, next: start + 2 })
+        } else {
+            // every tag starting with byte 0xf0 is an overlong form, which is prohibited.
+            Err(InvalidTag(v))
+        }
     }
 
     #[inline(never)]
-    fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
+    fn vuint_at_slow(data: &[u8], start: usize) -> DecodeResult<Res> {
         let a = data[start];
-        if a & 0x80u8 != 0u8 {
-            return Ok(Res {val: (a & 0x7fu8) as uint, next: start + 1});
+        if a & 0x80 != 0 {
+            return Ok(Res {val: (a & 0x7f) as usize, next: start + 1});
         }
-        if a & 0x40u8 != 0u8 {
-            return Ok(Res {val: ((a & 0x3fu8) as uint) << 8 |
-                        (data[start + 1] as uint),
+        if a & 0x40 != 0 {
+            return Ok(Res {val: ((a & 0x3f) as usize) << 8 |
+                        (data[start + 1] as usize),
                     next: start + 2});
         }
-        if a & 0x20u8 != 0u8 {
-            return Ok(Res {val: ((a & 0x1fu8) as uint) << 16 |
-                        (data[start + 1] as uint) << 8 |
-                        (data[start + 2] as uint),
+        if a & 0x20 != 0 {
+            return Ok(Res {val: ((a & 0x1f) as usize) << 16 |
+                        (data[start + 1] as usize) << 8 |
+                        (data[start + 2] as usize),
                     next: start + 3});
         }
-        if a & 0x10u8 != 0u8 {
-            return Ok(Res {val: ((a & 0x0fu8) as uint) << 24 |
-                        (data[start + 1] as uint) << 16 |
-                        (data[start + 2] as uint) << 8 |
-                        (data[start + 3] as uint),
+        if a & 0x10 != 0 {
+            return Ok(Res {val: ((a & 0x0f) as usize) << 24 |
+                        (data[start + 1] as usize) << 16 |
+                        (data[start + 2] as usize) << 8 |
+                        (data[start + 3] as usize),
                     next: start + 4});
         }
-        Err(IntTooBig(a as uint))
+        Err(IntTooBig(a as usize))
     }
 
-    pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
+    pub fn vuint_at(data: &[u8], start: usize) -> DecodeResult<Res> {
         if data.len() - start < 4 {
             return vuint_at_slow(data, start);
         }
 
-        // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
-        // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
-        // Using the four most significant bits of the u32 we lookup in the table below how the
-        // element ID should be derived from it.
+        // Lookup table for parsing EBML Element IDs as per
+        // http://ebml.sourceforge.net/specs/ The Element IDs are parsed by
+        // reading a big endian u32 positioned at data[start].  Using the four
+        // most significant bits of the u32 we lookup in the table below how
+        // the element ID should be derived from it.
         //
-        // The table stores tuples (shift, mask) where shift is the number the u32 should be right
-        // shifted with and mask is the value the right shifted value should be masked with.
-        // If for example the most significant bit is set this means it's a class A ID and the u32
-        // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
-        // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
+        // The table stores tuples (shift, mask) where shift is the number the
+        // u32 should be right shifted with and mask is the value the right
+        // shifted value should be masked with.  If for example the most
+        // significant bit is set this means it's a class A ID and the u32
+        // should be right shifted with 24 and masked with 0x7f. Therefore we
+        // store (24, 0x7f) at index 0x8 - 0xF (four bit numbers where the most
+        // significant bit is set).
         //
-        // By storing the number of shifts and masks in a table instead of checking in order if
-        // the most significant bit is set, the second most significant bit is set etc. we can
-        // replace up to three "and+branch" with a single table lookup which gives us a measured
+        // By storing the number of shifts and masks in a table instead of
+        // checking in order if the most significant bit is set, the second
+        // most significant bit is set etc. we can replace up to three
+        // "and+branch" with a single table lookup which gives us a measured
         // speedup of around 2x on x86_64.
-        static SHIFT_MASK_TABLE: [(uint, u32); 16] = [
+        static SHIFT_MASK_TABLE: [(usize, u32); 16] = [
             (0, 0x0), (0, 0x0fffffff),
             (8, 0x1fffff), (8, 0x1fffff),
             (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff),
@@ -221,21 +343,29 @@ pub mod reader {
         ];
 
         unsafe {
-            let ptr = data.as_ptr().offset(start as int) as *const u32;
-            let val = Int::from_be(*ptr);
+            let ptr = data.as_ptr().offset(start as isize) as *const u32;
+            let val = u32::from_be(*ptr);
 
-            let i = (val >> 28) as uint;
+            let i = (val >> 28) as usize;
             let (shift, mask) = SHIFT_MASK_TABLE[i];
             Ok(Res {
-                val: ((val >> shift) & mask) as uint,
-                next: start + (((32 - shift) >> 3) as uint)
+                val: ((val >> shift) & mask) as usize,
+                next: start + ((32 - shift) >> 3),
             })
         }
     }
 
-    pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
-        let elt_tag = try!(vuint_at(data, start));
-        let elt_size = try!(vuint_at(data, elt_tag.next));
+    pub fn tag_len_at(data: &[u8], tag: Res) -> DecodeResult<Res> {
+        if tag.val < NUM_IMPLICIT_TAGS && TAG_IMPLICIT_LEN[tag.val] >= 0 {
+            Ok(Res { val: TAG_IMPLICIT_LEN[tag.val] as usize, next: tag.next })
+        } else {
+            vuint_at(data, tag.next)
+        }
+    }
+
+    pub fn doc_at<'a>(data: &'a [u8], start: usize) -> DecodeResult<TaggedDoc<'a>> {
+        let elt_tag = try!(tag_at(data, start));
+        let elt_size = try!(tag_len_at(data, elt_tag));
         let end = elt_size.next + elt_size.val;
         Ok(TaggedDoc {
             tag: elt_tag.val,
@@ -243,11 +373,11 @@ pub mod reader {
         })
     }
 
-    pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
+    pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: usize) -> Option<Doc<'a>> {
         let mut pos = d.start;
         while pos < d.end {
-            let elt_tag = try_or!(vuint_at(d.data, pos), None);
-            let elt_size = try_or!(vuint_at(d.data, elt_tag.next), None);
+            let elt_tag = try_or!(tag_at(d.data, pos), None);
+            let elt_size = try_or!(tag_len_at(d.data, elt_tag), None);
             pos = elt_size.next + elt_size.val;
             if elt_tag.val == tg {
                 return Some(Doc { data: d.data, start: elt_size.next,
@@ -257,7 +387,7 @@ pub mod reader {
         None
     }
 
-    pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> {
+    pub fn get_doc<'a>(d: Doc<'a>, tg: usize) -> Doc<'a> {
         match maybe_get_doc(d, tg) {
             Some(d) => d,
             None => {
@@ -268,12 +398,12 @@ pub mod reader {
     }
 
     pub fn docs<F>(d: Doc, mut it: F) -> bool where
-        F: FnMut(uint, Doc) -> bool,
+        F: FnMut(usize, Doc) -> bool,
     {
         let mut pos = d.start;
         while pos < d.end {
-            let elt_tag = try_or!(vuint_at(d.data, pos), false);
-            let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
+            let elt_tag = try_or!(tag_at(d.data, pos), false);
+            let elt_size = try_or!(tag_len_at(d.data, elt_tag), false);
             pos = elt_size.next + elt_size.val;
             let doc = Doc { data: d.data, start: elt_size.next, end: pos };
             if !it(elt_tag.val, doc) {
@@ -283,13 +413,13 @@ pub mod reader {
         return true;
     }
 
-    pub fn tagged_docs<F>(d: Doc, tg: uint, mut it: F) -> bool where
+    pub fn tagged_docs<F>(d: Doc, tg: usize, mut it: F) -> bool where
         F: FnMut(Doc) -> bool,
     {
         let mut pos = d.start;
         while pos < d.end {
-            let elt_tag = try_or!(vuint_at(d.data, pos), false);
-            let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
+            let elt_tag = try_or!(tag_at(d.data, pos), false);
+            let elt_size = try_or!(tag_len_at(d.data, elt_tag), false);
             pos = elt_size.next + elt_size.val;
             if elt_tag.val == tg {
                 let doc = Doc { data: d.data, start: elt_size.next,
@@ -316,17 +446,23 @@ pub mod reader {
 
     pub fn doc_as_u16(d: Doc) -> u16 {
         assert_eq!(d.end, d.start + 2);
-        u64_from_be_bytes(d.data, d.start, 2) as u16
+        let mut b = [0; 2];
+        bytes::copy_memory(&d.data[d.start..d.end], &mut b);
+        unsafe { (*(b.as_ptr() as *const u16)).to_be() }
     }
 
     pub fn doc_as_u32(d: Doc) -> u32 {
         assert_eq!(d.end, d.start + 4);
-        u64_from_be_bytes(d.data, d.start, 4) as u32
+        let mut b = [0; 4];
+        bytes::copy_memory(&d.data[d.start..d.end], &mut b);
+        unsafe { (*(b.as_ptr() as *const u32)).to_be() }
     }
 
     pub fn doc_as_u64(d: Doc) -> u64 {
         assert_eq!(d.end, d.start + 8);
-        u64_from_be_bytes(d.data, d.start, 8)
+        let mut b = [0; 8];
+        bytes::copy_memory(&d.data[d.start..d.end], &mut b);
+        unsafe { (*(b.as_ptr() as *const u64)).to_be() }
     }
 
     pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
@@ -336,7 +472,7 @@ pub mod reader {
 
     pub struct Decoder<'a> {
         parent: Doc<'a>,
-        pos: uint,
+        pos: usize,
     }
 
     impl<'doc> Decoder<'doc> {
@@ -347,23 +483,6 @@ pub mod reader {
             }
         }
 
-        fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
-            if self.pos < self.parent.end {
-                let TaggedDoc { tag: r_tag, doc: r_doc } =
-                    try!(doc_at(self.parent.data, self.pos));
-
-                if r_tag == (EsLabel as uint) {
-                    self.pos = r_doc.end;
-                    let str = r_doc.as_str_slice();
-                    if lbl != str {
-                        return Err(Expected(format!("Expected label {:?} but \
-                                                     found {:?}", lbl, str)));
-                    }
-                }
-            }
-            Ok(())
-        }
-
         fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
             debug!(". next_doc(exp_tag={:?})", exp_tag);
             if self.pos >= self.parent.end {
@@ -379,7 +498,7 @@ pub mod reader {
                    r_tag,
                    r_doc.start,
                    r_doc.end);
-            if r_tag != (exp_tag as uint) {
+            if r_tag != (exp_tag as usize) {
                 return Err(Expected(format!("expected EBML doc with tag {:?} but \
                                              found tag {:?}", exp_tag, r_tag)));
             }
@@ -406,10 +525,66 @@ pub mod reader {
             Ok(r)
         }
 
-        fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
-            let r = doc_as_u32(try!(self.next_doc(exp_tag)));
-            debug!("_next_uint exp_tag={:?} result={:?}", exp_tag, r);
-            Ok(r as uint)
+        fn _next_sub(&mut self) -> DecodeResult<usize> {
+            // empty vector/map optimization
+            if self.parent.is_empty() {
+                return Ok(0);
+            }
+
+            let TaggedDoc { tag: r_tag, doc: r_doc } =
+                try!(doc_at(self.parent.data, self.pos));
+            let r = if r_tag == (EsSub8 as usize) {
+                doc_as_u8(r_doc) as usize
+            } else if r_tag == (EsSub32 as usize) {
+                doc_as_u32(r_doc) as usize
+            } else {
+                return Err(Expected(format!("expected EBML doc with tag {:?} or {:?} but \
+                                             found tag {:?}", EsSub8, EsSub32, r_tag)));
+            };
+            if r_doc.end > self.parent.end {
+                return Err(Expected(format!("invalid EBML, child extends to \
+                                             {:#x}, parent to {:#x}",
+                                            r_doc.end, self.parent.end)));
+            }
+            self.pos = r_doc.end;
+            debug!("_next_sub result={:?}", r);
+            Ok(r)
+        }
+
+        // variable-length unsigned integer with different tags.
+        // `first_tag` should be a tag for u8 or i8.
+        // `last_tag` should be the largest allowed integer tag with the matching signedness.
+        // all tags between them should be valid, in the order of u8, u16, u32 and u64.
+        fn _next_int(&mut self,
+                     first_tag: EbmlEncoderTag,
+                     last_tag: EbmlEncoderTag) -> DecodeResult<u64> {
+            if self.pos >= self.parent.end {
+                return Err(Expected(format!("no more documents in \
+                                             current node!")));
+            }
+
+            let TaggedDoc { tag: r_tag, doc: r_doc } =
+                try!(doc_at(self.parent.data, self.pos));
+            let r = if first_tag as usize <= r_tag && r_tag <= last_tag as usize {
+                match r_tag - first_tag as usize {
+                    0 => doc_as_u8(r_doc) as u64,
+                    1 => doc_as_u16(r_doc) as u64,
+                    2 => doc_as_u32(r_doc) as u64,
+                    3 => doc_as_u64(r_doc),
+                    _ => unreachable!(),
+                }
+            } else {
+                return Err(Expected(format!("expected EBML doc with tag {:?} through {:?} but \
+                                             found tag {:?}", first_tag, last_tag, r_tag)));
+            };
+            if r_doc.end > self.parent.end {
+                return Err(Expected(format!("invalid EBML, child extends to \
+                                             {:#x}, parent to {:#x}",
+                                            r_doc.end, self.parent.end)));
+            }
+            self.pos = r_doc.end;
+            debug!("_next_int({:?}, {:?}) result={:?}", first_tag, last_tag, r);
+            Ok(r)
         }
 
         pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where
@@ -433,38 +608,30 @@ pub mod reader {
         type Error = Error;
         fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
 
-        fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
-        fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
-        fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
-        fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
-        fn read_uint(&mut self) -> DecodeResult<uint> {
-            let v = doc_as_u64(try!(self.next_doc(EsUint)));
+        fn read_u64(&mut self) -> DecodeResult<u64> { self._next_int(EsU8, EsU64) }
+        fn read_u32(&mut self) -> DecodeResult<u32> { Ok(try!(self._next_int(EsU8, EsU32)) as u32) }
+        fn read_u16(&mut self) -> DecodeResult<u16> { Ok(try!(self._next_int(EsU8, EsU16)) as u16) }
+        fn read_u8(&mut self) -> DecodeResult<u8> { Ok(doc_as_u8(try!(self.next_doc(EsU8)))) }
+        fn read_uint(&mut self) -> DecodeResult<usize> {
+            let v = try!(self._next_int(EsU8, EsU64));
             if v > (::std::usize::MAX as u64) {
-                Err(IntTooBig(v as uint))
+                Err(IntTooBig(v as usize))
             } else {
-                Ok(v as uint)
+                Ok(v as usize)
             }
         }
 
-        fn read_i64(&mut self) -> DecodeResult<i64> {
-            Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64)
-        }
-        fn read_i32(&mut self) -> DecodeResult<i32> {
-            Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32)
-        }
-        fn read_i16(&mut self) -> DecodeResult<i16> {
-            Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
-        }
-        fn read_i8 (&mut self) -> DecodeResult<i8> {
-            Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8)
-        }
-        fn read_int(&mut self) -> DecodeResult<int> {
-            let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
+        fn read_i64(&mut self) -> DecodeResult<i64> { Ok(try!(self._next_int(EsI8, EsI64)) as i64) }
+        fn read_i32(&mut self) -> DecodeResult<i32> { Ok(try!(self._next_int(EsI8, EsI32)) as i32) }
+        fn read_i16(&mut self) -> DecodeResult<i16> { Ok(try!(self._next_int(EsI8, EsI16)) as i16) }
+        fn read_i8(&mut self) -> DecodeResult<i8> { Ok(doc_as_u8(try!(self.next_doc(EsI8))) as i8) }
+        fn read_int(&mut self) -> DecodeResult<isize> {
+            let v = try!(self._next_int(EsI8, EsI64)) as i64;
             if v > (isize::MAX as i64) || v < (isize::MIN as i64) {
                 debug!("FIXME \\#6122: Removing this makes this function miscompile");
-                Err(IntTooBig(v as uint))
+                Err(IntTooBig(v as usize))
             } else {
-                Ok(v as int)
+                Ok(v as isize)
             }
         }
 
@@ -492,7 +659,6 @@ pub mod reader {
             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
         {
             debug!("read_enum({})", name);
-            try!(self._check_label(name));
 
             let doc = try!(self.next_doc(EsEnum));
 
@@ -509,26 +675,16 @@ pub mod reader {
 
         fn read_enum_variant<T, F>(&mut self, _: &[&str],
                                    mut f: F) -> DecodeResult<T>
-            where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
+            where F: FnMut(&mut Decoder<'doc>, usize) -> DecodeResult<T>,
         {
             debug!("read_enum_variant()");
-            let idx = try!(self._next_uint(EsEnumVid));
+            let idx = try!(self._next_sub());
             debug!("  idx={}", idx);
 
-            let doc = try!(self.next_doc(EsEnumBody));
-
-            let (old_parent, old_pos) = (self.parent, self.pos);
-            self.parent = doc;
-            self.pos = self.parent.start;
-
-            let result = try!(f(self, idx));
-
-            self.parent = old_parent;
-            self.pos = old_pos;
-            Ok(result)
+            f(self, idx)
         }
 
-        fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+        fn read_enum_variant_arg<T, F>(&mut self, idx: usize, f: F) -> DecodeResult<T> where
             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
         {
             debug!("read_enum_variant_arg(idx={})", idx);
@@ -537,28 +693,18 @@ pub mod reader {
 
         fn read_enum_struct_variant<T, F>(&mut self, _: &[&str],
                                           mut f: F) -> DecodeResult<T>
-            where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
+            where F: FnMut(&mut Decoder<'doc>, usize) -> DecodeResult<T>,
         {
             debug!("read_enum_struct_variant()");
-            let idx = try!(self._next_uint(EsEnumVid));
+            let idx = try!(self._next_sub());
             debug!("  idx={}", idx);
 
-            let doc = try!(self.next_doc(EsEnumBody));
-
-            let (old_parent, old_pos) = (self.parent, self.pos);
-            self.parent = doc;
-            self.pos = self.parent.start;
-
-            let result = try!(f(self, idx));
-
-            self.parent = old_parent;
-            self.pos = old_pos;
-            Ok(result)
+            f(self, idx)
         }
 
         fn read_enum_struct_variant_field<T, F>(&mut self,
                                                 name: &str,
-                                                idx: uint,
+                                                idx: usize,
                                                 f: F)
                                                 -> DecodeResult<T> where
             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
@@ -567,22 +713,21 @@ pub mod reader {
             f(self)
         }
 
-        fn read_struct<T, F>(&mut self, name: &str, _: uint, f: F) -> DecodeResult<T> where
+        fn read_struct<T, F>(&mut self, name: &str, _: usize, f: F) -> DecodeResult<T> where
             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
         {
             debug!("read_struct(name={})", name);
             f(self)
         }
 
-        fn read_struct_field<T, F>(&mut self, name: &str, idx: uint, f: F) -> DecodeResult<T> where
+        fn read_struct_field<T, F>(&mut self, name: &str, idx: usize, f: F) -> DecodeResult<T> where
             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
         {
             debug!("read_struct_field(name={}, idx={})", name, idx);
-            try!(self._check_label(name));
             f(self)
         }
 
-        fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where
+        fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F) -> DecodeResult<T> where
             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
         {
             debug!("read_tuple()");
@@ -596,14 +741,14 @@ pub mod reader {
             })
         }
 
-        fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+        fn read_tuple_arg<T, F>(&mut self, idx: usize, f: F) -> DecodeResult<T> where
             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
         {
             debug!("read_tuple_arg(idx={})", idx);
             self.read_seq_elt(idx, f)
         }
 
-        fn read_tuple_struct<T, F>(&mut self, name: &str, len: uint, f: F) -> DecodeResult<T> where
+        fn read_tuple_struct<T, F>(&mut self, name: &str, len: usize, f: F) -> DecodeResult<T> where
             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
         {
             debug!("read_tuple_struct(name={})", name);
@@ -611,7 +756,7 @@ pub mod reader {
         }
 
         fn read_tuple_struct_arg<T, F>(&mut self,
-                                       idx: uint,
+                                       idx: usize,
                                        f: F)
                                        -> DecodeResult<T> where
             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
@@ -638,17 +783,17 @@ pub mod reader {
         }
 
         fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
-            F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
+            F: FnOnce(&mut Decoder<'doc>, usize) -> DecodeResult<T>,
         {
             debug!("read_seq()");
             self.push_doc(EsVec, move |d| {
-                let len = try!(d._next_uint(EsVecLen));
+                let len = try!(d._next_sub());
                 debug!("  len={}", len);
                 f(d, len)
             })
         }
 
-        fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+        fn read_seq_elt<T, F>(&mut self, idx: usize, f: F) -> DecodeResult<T> where
             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
         {
             debug!("read_seq_elt(idx={})", idx);
@@ -656,24 +801,24 @@ pub mod reader {
         }
 
         fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
-            F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
+            F: FnOnce(&mut Decoder<'doc>, usize) -> DecodeResult<T>,
         {
             debug!("read_map()");
             self.push_doc(EsMap, move |d| {
-                let len = try!(d._next_uint(EsMapLen));
+                let len = try!(d._next_sub());
                 debug!("  len={}", len);
                 f(d, len)
             })
         }
 
-        fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+        fn read_map_elt_key<T, F>(&mut self, idx: usize, f: F) -> DecodeResult<T> where
             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
         {
             debug!("read_map_elt_key(idx={})", idx);
             self.push_doc(EsMapKey, f)
         }
 
-        fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+        fn read_map_elt_val<T, F>(&mut self, idx: usize, f: F) -> DecodeResult<T> where
             F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
         {
             debug!("read_map_elt_val(idx={})", idx);
@@ -687,97 +832,126 @@ pub mod reader {
 }
 
 pub mod writer {
-    use std::clone::Clone;
-    use std::old_io::extensions::u64_to_be_bytes;
-    use std::old_io::{Writer, Seek};
-    use std::old_io;
     use std::mem;
+    use std::io::prelude::*;
+    use std::io::{self, SeekFrom, Cursor};
+    use std::slice::bytes;
+    use std::num::ToPrimitive;
 
-    use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
-        EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
-        EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
-        EsOpaque, EsLabel, EbmlEncoderTag };
+    use super::{ EsVec, EsMap, EsEnum, EsSub8, EsSub32, EsVecElt, EsMapKey,
+        EsU64, EsU32, EsU16, EsU8, EsI64, EsI32, EsI16, EsI8,
+        EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
+        EsOpaque, NUM_IMPLICIT_TAGS, NUM_TAGS };
 
     use serialize;
 
 
-    pub type EncodeResult = old_io::IoResult<()>;
+    pub type EncodeResult = io::Result<()>;
 
     // rbml writing
-    pub struct Encoder<'a, W:'a> {
-        pub writer: &'a mut W,
-        size_positions: Vec<uint>,
+    pub struct Encoder<'a> {
+        pub writer: &'a mut Cursor<Vec<u8>>,
+        size_positions: Vec<u64>,
+        relax_limit: u64, // do not move encoded bytes before this position
     }
 
-    fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
+    fn write_tag<W: Write>(w: &mut W, n: usize) -> EncodeResult {
+        if n < 0xf0 {
+            w.write_all(&[n as u8])
+        } else if 0x100 <= n && n < NUM_TAGS {
+            w.write_all(&[0xf0 | (n >> 8) as u8, n as u8])
+        } else {
+            Err(io::Error::new(io::ErrorKind::Other,
+                               &format!("invalid tag: {}", n)[..]))
+        }
+    }
+
+    fn write_sized_vuint<W: Write>(w: &mut W, n: usize, size: usize) -> EncodeResult {
         match size {
-            1 => w.write_all(&[0x80u8 | (n as u8)]),
-            2 => w.write_all(&[0x40u8 | ((n >> 8) as u8), n as u8]),
-            3 => w.write_all(&[0x20u8 | ((n >> 16) as u8), (n >> 8) as u8,
+            1 => w.write_all(&[0x80 | (n as u8)]),
+            2 => w.write_all(&[0x40 | ((n >> 8) as u8), n as u8]),
+            3 => w.write_all(&[0x20 | ((n >> 16) as u8), (n >> 8) as u8,
                             n as u8]),
-            4 => w.write_all(&[0x10u8 | ((n >> 24) as u8), (n >> 16) as u8,
+            4 => w.write_all(&[0x10 | ((n >> 24) as u8), (n >> 16) as u8,
                             (n >> 8) as u8, n as u8]),
-            _ => Err(old_io::IoError {
-                kind: old_io::OtherIoError,
-                desc: "int too big",
-                detail: Some(format!("{}", n))
-            })
+            _ => Err(io::Error::new(io::ErrorKind::Other,
+                                    &format!("isize too big: {}", n)[..]))
         }
     }
 
-    fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
+    fn write_vuint<W: Write>(w: &mut W, n: usize) -> EncodeResult {
         if n < 0x7f { return write_sized_vuint(w, n, 1); }
         if n < 0x4000 { return write_sized_vuint(w, n, 2); }
         if n < 0x200000 { return write_sized_vuint(w, n, 3); }
         if n < 0x10000000 { return write_sized_vuint(w, n, 4); }
-        Err(old_io::IoError {
-            kind: old_io::OtherIoError,
-            desc: "int too big",
-            detail: Some(format!("{}", n))
-        })
+        Err(io::Error::new(io::ErrorKind::Other,
+                           &format!("isize too big: {}", n)[..]))
     }
 
-    impl<'a, W: Writer + Seek> Encoder<'a, W> {
-        pub fn new(w: &'a mut W) -> Encoder<'a, W> {
+    impl<'a> Encoder<'a> {
+        pub fn new(w: &'a mut Cursor<Vec<u8>>) -> Encoder<'a> {
             Encoder {
                 writer: w,
                 size_positions: vec!(),
+                relax_limit: 0,
             }
         }
 
         /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
-        pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
+        pub unsafe fn unsafe_clone(&self) -> Encoder<'a> {
             Encoder {
                 writer: mem::transmute_copy(&self.writer),
                 size_positions: self.size_positions.clone(),
+                relax_limit: self.relax_limit,
             }
         }
 
-        pub fn start_tag(&mut self, tag_id: uint) -> EncodeResult {
+        pub fn start_tag(&mut self, tag_id: usize) -> EncodeResult {
             debug!("Start tag {:?}", tag_id);
+            assert!(tag_id >= NUM_IMPLICIT_TAGS);
 
             // Write the enum ID:
-            try!(write_vuint(self.writer, tag_id));
+            try!(write_tag(self.writer, tag_id));
 
             // Write a placeholder four-byte size.
-            self.size_positions.push(try!(self.writer.tell()) as uint);
-            let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
+            let cur_pos = try!(self.writer.seek(SeekFrom::Current(0)));
+            self.size_positions.push(cur_pos);
+            let zeroes: &[u8] = &[0, 0, 0, 0];
             self.writer.write_all(zeroes)
         }
 
         pub fn end_tag(&mut self) -> EncodeResult {
             let last_size_pos = self.size_positions.pop().unwrap();
-            let cur_pos = try!(self.writer.tell());
-            try!(self.writer.seek(last_size_pos as i64, old_io::SeekSet));
-            let size = cur_pos as uint - last_size_pos - 4;
-            try!(write_sized_vuint(self.writer, size, 4));
-            let r = try!(self.writer.seek(cur_pos as i64, old_io::SeekSet));
+            let cur_pos = try!(self.writer.seek(SeekFrom::Current(0)));
+            try!(self.writer.seek(SeekFrom::Start(last_size_pos)));
+            let size = (cur_pos - last_size_pos - 4) as usize;
+
+            // relax the size encoding for small tags (bigger tags are costly to move).
+            // we should never try to move the stable positions, however.
+            const RELAX_MAX_SIZE: usize = 0x100;
+            if size <= RELAX_MAX_SIZE && last_size_pos >= self.relax_limit {
+                // we can't alter the buffer in place, so have a temporary buffer
+                let mut buf = [0u8; RELAX_MAX_SIZE];
+                {
+                    let last_size_pos = last_size_pos as usize;
+                    let data = &self.writer.get_ref()[last_size_pos+4..cur_pos as usize];
+                    bytes::copy_memory(data, &mut buf);
+                }
+
+                // overwrite the size and data and continue
+                try!(write_vuint(self.writer, size));
+                try!(self.writer.write_all(&buf[..size]));
+            } else {
+                // overwrite the size with an overlong encoding and skip past the data
+                try!(write_sized_vuint(self.writer, size, 4));
+                try!(self.writer.seek(SeekFrom::Start(cur_pos)));
+            }
 
             debug!("End tag (size = {:?})", size);
-            Ok(r)
+            Ok(())
         }
 
-        pub fn wr_tag<F>(&mut self, tag_id: uint, blk: F) -> EncodeResult where
+        pub fn wr_tag<F>(&mut self, tag_id: usize, blk: F) -> EncodeResult where
             F: FnOnce() -> EncodeResult,
         {
             try!(self.start_tag(tag_id));
@@ -785,60 +959,93 @@ pub mod writer {
             self.end_tag()
         }
 
-        pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
-            try!(write_vuint(self.writer, tag_id));
+        pub fn wr_tagged_bytes(&mut self, tag_id: usize, b: &[u8]) -> EncodeResult {
+            assert!(tag_id >= NUM_IMPLICIT_TAGS);
+            try!(write_tag(self.writer, tag_id));
             try!(write_vuint(self.writer, b.len()));
             self.writer.write_all(b)
         }
 
-        pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
-            u64_to_be_bytes(v, 8, |v| {
-                self.wr_tagged_bytes(tag_id, v)
-            })
+        pub fn wr_tagged_u64(&mut self, tag_id: usize, v: u64) -> EncodeResult {
+            let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) };
+            self.wr_tagged_bytes(tag_id, &bytes)
         }
 
-        pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32)  -> EncodeResult{
-            u64_to_be_bytes(v as u64, 4, |v| {
-                self.wr_tagged_bytes(tag_id, v)
-            })
+        pub fn wr_tagged_u32(&mut self, tag_id: usize, v: u32)  -> EncodeResult{
+            let bytes: [u8; 4] = unsafe { mem::transmute(v.to_be()) };
+            self.wr_tagged_bytes(tag_id, &bytes)
         }
 
-        pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
-            u64_to_be_bytes(v as u64, 2, |v| {
-                self.wr_tagged_bytes(tag_id, v)
-            })
+        pub fn wr_tagged_u16(&mut self, tag_id: usize, v: u16) -> EncodeResult {
+            let bytes: [u8; 2] = unsafe { mem::transmute(v.to_be()) };
+            self.wr_tagged_bytes(tag_id, &bytes)
         }
 
-        pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
+        pub fn wr_tagged_u8(&mut self, tag_id: usize, v: u8) -> EncodeResult {
             self.wr_tagged_bytes(tag_id, &[v])
         }
 
-        pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
-            u64_to_be_bytes(v as u64, 8, |v| {
-                self.wr_tagged_bytes(tag_id, v)
-            })
+        pub fn wr_tagged_i64(&mut self, tag_id: usize, v: i64) -> EncodeResult {
+            self.wr_tagged_u64(tag_id, v as u64)
         }
 
-        pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
-            u64_to_be_bytes(v as u64, 4, |v| {
-                self.wr_tagged_bytes(tag_id, v)
-            })
+        pub fn wr_tagged_i32(&mut self, tag_id: usize, v: i32) -> EncodeResult {
+            self.wr_tagged_u32(tag_id, v as u32)
         }
 
-        pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
-            u64_to_be_bytes(v as u64, 2, |v| {
-                self.wr_tagged_bytes(tag_id, v)
-            })
+        pub fn wr_tagged_i16(&mut self, tag_id: usize, v: i16) -> EncodeResult {
+            self.wr_tagged_u16(tag_id, v as u16)
         }
 
-        pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
+        pub fn wr_tagged_i8(&mut self, tag_id: usize, v: i8) -> EncodeResult {
             self.wr_tagged_bytes(tag_id, &[v as u8])
         }
 
-        pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) -> EncodeResult {
+        pub fn wr_tagged_str(&mut self, tag_id: usize, v: &str) -> EncodeResult {
             self.wr_tagged_bytes(tag_id, v.as_bytes())
         }
 
+        // for auto-serialization
+        fn wr_tagged_raw_bytes(&mut self, tag_id: usize, b: &[u8]) -> EncodeResult {
+            try!(write_tag(self.writer, tag_id));
+            self.writer.write_all(b)
+        }
+
+        fn wr_tagged_raw_u64(&mut self, tag_id: usize, v: u64) -> EncodeResult {
+            let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) };
+            self.wr_tagged_raw_bytes(tag_id, &bytes)
+        }
+
+        fn wr_tagged_raw_u32(&mut self, tag_id: usize, v: u32)  -> EncodeResult{
+            let bytes: [u8; 4] = unsafe { mem::transmute(v.to_be()) };
+            self.wr_tagged_raw_bytes(tag_id, &bytes)
+        }
+
+        fn wr_tagged_raw_u16(&mut self, tag_id: usize, v: u16) -> EncodeResult {
+            let bytes: [u8; 2] = unsafe { mem::transmute(v.to_be()) };
+            self.wr_tagged_raw_bytes(tag_id, &bytes)
+        }
+
+        fn wr_tagged_raw_u8(&mut self, tag_id: usize, v: u8) -> EncodeResult {
+            self.wr_tagged_raw_bytes(tag_id, &[v])
+        }
+
+        fn wr_tagged_raw_i64(&mut self, tag_id: usize, v: i64) -> EncodeResult {
+            self.wr_tagged_raw_u64(tag_id, v as u64)
+        }
+
+        fn wr_tagged_raw_i32(&mut self, tag_id: usize, v: i32) -> EncodeResult {
+            self.wr_tagged_raw_u32(tag_id, v as u32)
+        }
+
+        fn wr_tagged_raw_i16(&mut self, tag_id: usize, v: i16) -> EncodeResult {
+            self.wr_tagged_raw_u16(tag_id, v as u16)
+        }
+
+        fn wr_tagged_raw_i8(&mut self, tag_id: usize, v: i8) -> EncodeResult {
+            self.wr_tagged_raw_bytes(tag_id, &[v as u8])
+        }
+
         pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
             debug!("Write {:?} bytes", b.len());
             self.writer.write_all(b)
@@ -848,188 +1055,198 @@ pub mod writer {
             debug!("Write str: {:?}", s);
             self.writer.write_all(s.as_bytes())
         }
-    }
-
-    // FIXME (#2743): optionally perform "relaxations" on end_tag to more
-    // efficiently encode sizes; this is a fixed point iteration
 
-    // Set to true to generate more debugging in EBML code.
-    // Totally lame approach.
-    #[cfg(not(ndebug))]
-    static DEBUG: bool = true;
-    #[cfg(ndebug)]
-    static DEBUG: bool = false;
-
-    impl<'a, W: Writer + Seek> Encoder<'a, W> {
-        // used internally to emit things like the vector length and so on
-        fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
-            assert!(v <= 0xFFFF_FFFF);
-            self.wr_tagged_u32(t as uint, v as u32)
+        /// Returns the current position while marking it stable, i.e.
+        /// generated bytes so far wouldn't be affected by relaxation.
+        pub fn mark_stable_position(&mut self) -> u64 {
+            let pos = self.writer.seek(SeekFrom::Current(0)).unwrap();
+            if self.relax_limit < pos {
+                self.relax_limit = pos;
+            }
+            pos
         }
+    }
 
-        fn _emit_label(&mut self, label: &str) -> EncodeResult {
-            // There are various strings that we have access to, such as
-            // the name of a record field, which do not actually appear in
-            // the encoded EBML (normally).  This is just for
-            // efficiency.  When debugging, though, we can emit such
-            // labels and then they will be checked by decoder to
-            // try and check panics more quickly.
-            if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
-            else { Ok(()) }
+    impl<'a> Encoder<'a> {
+        // used internally to emit things like the vector length and so on
+        fn _emit_tagged_sub(&mut self, v: usize) -> EncodeResult {
+            if let Some(v) = v.to_u8() {
+                self.wr_tagged_raw_u8(EsSub8 as usize, v)
+            } else if let Some(v) = v.to_u32() {
+                self.wr_tagged_raw_u32(EsSub32 as usize, v)
+            } else {
+                Err(io::Error::new(io::ErrorKind::Other,
+                                   &format!("length or variant id too big: {}",
+                                            v)[..]))
+            }
         }
 
         pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<W>) -> EncodeResult,
+            F: FnOnce(&mut Encoder) -> EncodeResult,
         {
-            try!(self.start_tag(EsOpaque as uint));
+            try!(self.start_tag(EsOpaque as usize));
             try!(f(self));
             self.end_tag()
         }
     }
 
-    impl<'a, W: Writer + Seek> serialize::Encoder for Encoder<'a, W> {
-        type Error = old_io::IoError;
+    impl<'a> serialize::Encoder for Encoder<'a> {
+        type Error = io::Error;
 
         fn emit_nil(&mut self) -> EncodeResult {
             Ok(())
         }
 
-        fn emit_uint(&mut self, v: uint) -> EncodeResult {
-            self.wr_tagged_u64(EsUint as uint, v as u64)
+        fn emit_uint(&mut self, v: usize) -> EncodeResult {
+            self.emit_u64(v as u64)
         }
         fn emit_u64(&mut self, v: u64) -> EncodeResult {
-            self.wr_tagged_u64(EsU64 as uint, v)
+            match v.to_u32() {
+                Some(v) => self.emit_u32(v),
+                None => self.wr_tagged_raw_u64(EsU64 as usize, v)
+            }
         }
         fn emit_u32(&mut self, v: u32) -> EncodeResult {
-            self.wr_tagged_u32(EsU32 as uint, v)
+            match v.to_u16() {
+                Some(v) => self.emit_u16(v),
+                None => self.wr_tagged_raw_u32(EsU32 as usize, v)
+            }
         }
         fn emit_u16(&mut self, v: u16) -> EncodeResult {
-            self.wr_tagged_u16(EsU16 as uint, v)
+            match v.to_u8() {
+                Some(v) => self.emit_u8(v),
+                None => self.wr_tagged_raw_u16(EsU16 as usize, v)
+            }
         }
         fn emit_u8(&mut self, v: u8) -> EncodeResult {
-            self.wr_tagged_u8(EsU8 as uint, v)
+            self.wr_tagged_raw_u8(EsU8 as usize, v)
         }
 
-        fn emit_int(&mut self, v: int) -> EncodeResult {
-            self.wr_tagged_i64(EsInt as uint, v as i64)
+        fn emit_int(&mut self, v: isize) -> EncodeResult {
+            self.emit_i64(v as i64)
         }
         fn emit_i64(&mut self, v: i64) -> EncodeResult {
-            self.wr_tagged_i64(EsI64 as uint, v)
+            match v.to_i32() {
+                Some(v) => self.emit_i32(v),
+                None => self.wr_tagged_raw_i64(EsI64 as usize, v)
+            }
         }
         fn emit_i32(&mut self, v: i32) -> EncodeResult {
-            self.wr_tagged_i32(EsI32 as uint, v)
+            match v.to_i16() {
+                Some(v) => self.emit_i16(v),
+                None => self.wr_tagged_raw_i32(EsI32 as usize, v)
+            }
         }
         fn emit_i16(&mut self, v: i16) -> EncodeResult {
-            self.wr_tagged_i16(EsI16 as uint, v)
+            match v.to_i8() {
+                Some(v) => self.emit_i8(v),
+                None => self.wr_tagged_raw_i16(EsI16 as usize, v)
+            }
         }
         fn emit_i8(&mut self, v: i8) -> EncodeResult {
-            self.wr_tagged_i8(EsI8 as uint, v)
+            self.wr_tagged_raw_i8(EsI8 as usize, v)
         }
 
         fn emit_bool(&mut self, v: bool) -> EncodeResult {
-            self.wr_tagged_u8(EsBool as uint, v as u8)
+            self.wr_tagged_raw_u8(EsBool as usize, v as u8)
         }
 
         fn emit_f64(&mut self, v: f64) -> EncodeResult {
             let bits = unsafe { mem::transmute(v) };
-            self.wr_tagged_u64(EsF64 as uint, bits)
+            self.wr_tagged_raw_u64(EsF64 as usize, bits)
         }
         fn emit_f32(&mut self, v: f32) -> EncodeResult {
             let bits = unsafe { mem::transmute(v) };
-            self.wr_tagged_u32(EsF32 as uint, bits)
+            self.wr_tagged_raw_u32(EsF32 as usize, bits)
         }
         fn emit_char(&mut self, v: char) -> EncodeResult {
-            self.wr_tagged_u32(EsChar as uint, v as u32)
+            self.wr_tagged_raw_u32(EsChar as usize, v as u32)
         }
 
         fn emit_str(&mut self, v: &str) -> EncodeResult {
-            self.wr_tagged_str(EsStr as uint, v)
+            self.wr_tagged_str(EsStr as usize, v)
         }
 
-        fn emit_enum<F>(&mut self, name: &str, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
-            try!(self._emit_label(name));
-            try!(self.start_tag(EsEnum as uint));
+            try!(self.start_tag(EsEnum as usize));
             try!(f(self));
             self.end_tag()
         }
 
         fn emit_enum_variant<F>(&mut self,
                                 _: &str,
-                                v_id: uint,
-                                _: uint,
+                                v_id: usize,
+                                _: usize,
                                 f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
-            try!(self._emit_tagged_uint(EsEnumVid, v_id));
-            try!(self.start_tag(EsEnumBody as uint));
-            try!(f(self));
-            self.end_tag()
+            try!(self._emit_tagged_sub(v_id));
+            f(self)
         }
 
-        fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_enum_variant_arg<F>(&mut self, _: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
             f(self)
         }
 
         fn emit_enum_struct_variant<F>(&mut self,
                                        v_name: &str,
-                                       v_id: uint,
-                                       cnt: uint,
+                                       v_id: usize,
+                                       cnt: usize,
                                        f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
             self.emit_enum_variant(v_name, v_id, cnt, f)
         }
 
         fn emit_enum_struct_variant_field<F>(&mut self,
                                              _: &str,
-                                             idx: uint,
+                                             idx: usize,
                                              f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
             self.emit_enum_variant_arg(idx, f)
         }
 
-        fn emit_struct<F>(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_struct<F>(&mut self, _: &str, _len: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
             f(self)
         }
 
-        fn emit_struct_field<F>(&mut self, name: &str, _: uint, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_struct_field<F>(&mut self, _name: &str, _: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
-            try!(self._emit_label(name));
             f(self)
         }
 
-        fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_tuple<F>(&mut self, len: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
             self.emit_seq(len, f)
         }
-        fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
             self.emit_seq_elt(idx, f)
         }
 
-        fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_tuple_struct<F>(&mut self, _: &str, len: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
             self.emit_seq(len, f)
         }
-        fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_tuple_struct_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
             self.emit_seq_elt(idx, f)
         }
 
         fn emit_option<F>(&mut self, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
             self.emit_enum("Option", f)
         }
@@ -1037,54 +1254,62 @@ pub mod writer {
             self.emit_enum_variant("None", 0, 0, |_| Ok(()))
         }
         fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
 
             self.emit_enum_variant("Some", 1, 1, f)
         }
 
-        fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_seq<F>(&mut self, len: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
+            if len == 0 {
+                // empty vector optimization
+                return self.wr_tagged_bytes(EsVec as usize, &[]);
+            }
 
-            try!(self.start_tag(EsVec as uint));
-            try!(self._emit_tagged_uint(EsVecLen, len));
+            try!(self.start_tag(EsVec as usize));
+            try!(self._emit_tagged_sub(len));
             try!(f(self));
             self.end_tag()
         }
 
-        fn emit_seq_elt<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_seq_elt<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
 
-            try!(self.start_tag(EsVecElt as uint));
+            try!(self.start_tag(EsVecElt as usize));
             try!(f(self));
             self.end_tag()
         }
 
-        fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_map<F>(&mut self, len: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
+            if len == 0 {
+                // empty map optimization
+                return self.wr_tagged_bytes(EsMap as usize, &[]);
+            }
 
-            try!(self.start_tag(EsMap as uint));
-            try!(self._emit_tagged_uint(EsMapLen, len));
+            try!(self.start_tag(EsMap as usize));
+            try!(self._emit_tagged_sub(len));
             try!(f(self));
             self.end_tag()
         }
 
-        fn emit_map_elt_key<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_map_elt_key<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
 
-            try!(self.start_tag(EsMapKey as uint));
+            try!(self.start_tag(EsMapKey as usize));
             try!(f(self));
             self.end_tag()
         }
 
-        fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
-            F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+        fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
+            F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
         {
-            try!(self.start_tag(EsMapVal as uint));
+            try!(self.start_tag(EsMapVal as usize));
             try!(f(self));
             self.end_tag()
         }
@@ -1097,12 +1322,10 @@ pub mod writer {
 #[cfg(test)]
 mod tests {
     use super::{Doc, reader, writer};
-    use super::io::SeekableMemWriter;
 
     use serialize::{Encodable, Decodable};
 
-    use std::option::Option;
-    use std::option::Option::{None, Some};
+    use std::io::Cursor;
 
     #[test]
     fn test_vuint_at() {
@@ -1154,9 +1377,9 @@ mod tests {
 
     #[test]
     fn test_option_int() {
-        fn test_v(v: Option<int>) {
+        fn test_v(v: Option<isize>) {
             debug!("v == {:?}", v);
-            let mut wr = SeekableMemWriter::new();
+            let mut wr = Cursor::new(Vec::new());
             {
                 let mut rbml_w = writer::Encoder::new(&mut wr);
                 let _ = v.encode(&mut rbml_w);
@@ -1182,9 +1405,9 @@ mod bench {
 
     #[bench]
     pub fn vuint_at_A_aligned(b: &mut Bencher) {
-        let data = (0i32..4*100).map(|i| {
+        let data = (0..4*100).map(|i| {
             match i % 2 {
-              0 => 0x80u8,
+              0 => 0x80,
               _ => i as u8,
             }
         }).collect::<Vec<_>>();
@@ -1200,9 +1423,9 @@ mod bench {
 
     #[bench]
     pub fn vuint_at_A_unaligned(b: &mut Bencher) {
-        let data = (0i32..4*100+1).map(|i| {
+        let data = (0..4*100+1).map(|i| {
             match i % 2 {
-              1 => 0x80u8,
+              1 => 0x80,
               _ => i as u8
             }
         }).collect::<Vec<_>>();
@@ -1218,11 +1441,11 @@ mod bench {
 
     #[bench]
     pub fn vuint_at_D_aligned(b: &mut Bencher) {
-        let data = (0i32..4*100).map(|i| {
+        let data = (0..4*100).map(|i| {
             match i % 4 {
-              0 => 0x10u8,
+              0 => 0x10,
               3 => i as u8,
-              _ => 0u8
+              _ => 0
             }
         }).collect::<Vec<_>>();
         let mut sum = 0;
@@ -1237,11 +1460,11 @@ mod bench {
 
     #[bench]
     pub fn vuint_at_D_unaligned(b: &mut Bencher) {
-        let data = (0i32..4*100+1).map(|i| {
+        let data = (0..4*100+1).map(|i| {
             match i % 4 {
-              1 => 0x10u8,
+              1 => 0x10,
               0 => i as u8,
-              _ => 0u8
+              _ => 0
             }
         }).collect::<Vec<_>>();
         let mut sum = 0;
diff --git a/src/librustc/README.md b/src/librustc/README.md
new file mode 100644 (file)
index 0000000..31812e1
--- /dev/null
@@ -0,0 +1,128 @@
+An informal guide to reading and working on the rustc compiler.
+==================================================================
+
+If you wish to expand on this document, or have a more experienced
+Rust contributor add anything else to it, please get in touch:
+
+* http://internals.rust-lang.org/
+* https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
+
+or file a bug:
+
+https://github.com/rust-lang/rust/issues
+
+Your concerns are probably the same as someone else's.
+
+The crates of rustc
+===================
+
+Rustc consists of a number of crates, including `libsyntax`,
+`librustc`, `librustc_back`, `librustc_trans`, and `librustc_driver`
+(the names and divisions are not set in stone and may change;
+in general, a finer-grained division of crates is preferable):
+
+- `libsyntax` contains those things concerned purely with syntax –
+  that is, the AST, parser, pretty-printer, lexer, macro expander, and
+  utilities for traversing ASTs – are in a separate crate called
+  "syntax", whose files are in `./../libsyntax`, where `.` is the
+  current directory (that is, the parent directory of front/, middle/,
+  back/, and so on).
+
+- `librustc` (the current directory) contains the high-level analysis
+  passes, such as the type checker, borrow checker, and so forth.
+  It is the heart of the compiler.
+
+- `librustc_back` contains some very low-level details that are
+  specific to different LLVM targets and so forth.
+
+- `librustc_trans` contains the code to convert from Rust IR into LLVM
+  IR, and then from LLVM IR into machine code, as well as the main
+  driver that orchestrates all the other passes and various other bits
+  of miscellany. In general it contains code that runs towards the
+  end of the compilation process.
+
+- `librustc_driver` invokes the compiler from `libsyntax`, then the
+  analysis phases from `librustc`, and finally the lowering and
+  codegen passes from `librustc_trans`.
+
+Roughly speaking the "order" of the three crates is as follows:
+
+    libsyntax -> librustc -> librustc_trans
+    |                                     |
+    +-----------------+-------------------+
+                      |
+              librustc_driver
+
+
+Modules in the rustc crate
+==========================
+
+The rustc crate itself consists of the following submodules
+(mostly, but not entirely, in their own directories):
+
+- session: options and data that pertain to the compilation session as
+  a whole
+- middle: middle-end: name resolution, typechecking, LLVM code
+  generation
+- metadata: encoder and decoder for data required by separate
+  compilation
+- plugin: infrastructure for compiler plugins
+- lint: infrastructure for compiler warnings
+- util: ubiquitous types and helper functions
+- lib: bindings to LLVM
+
+The entry-point for the compiler is main() in the librustc_trans
+crate.
+
+The 3 central data structures:
+------------------------------
+
+1. `./../libsyntax/ast.rs` defines the AST. The AST is treated as
+   immutable after parsing, but it depends on mutable context data
+   structures (mainly hash maps) to give it meaning.
+
+   - Many – though not all – nodes within this data structure are
+     wrapped in the type `spanned<T>`, meaning that the front-end has
+     marked the input coordinates of that node. The member `node` is
+     the data itself, the member `span` is the input location (file,
+     line, column; both low and high).
+
+   - Many other nodes within this data structure carry a
+     `def_id`. These nodes represent the 'target' of some name
+     reference elsewhere in the tree. When the AST is resolved, by
+     `middle/resolve.rs`, all names wind up acquiring a def that they
+     point to. So anything that can be pointed-to by a name winds
+     up with a `def_id`.
+
+2. `middle/ty.rs` defines the datatype `sty`. This is the type that
+   represents types after they have been resolved and normalized by
+   the middle-end. The typeck phase converts every ast type to a
+   `ty::sty`, and the latter is used to drive later phases of
+   compilation. Most variants in the `ast::ty` tag have a
+   corresponding variant in the `ty::sty` tag.
+
+3. `./../librustc_llvm/lib.rs` defines the exported types
+   `ValueRef`, `TypeRef`, `BasicBlockRef`, and several others.
+   Each of these is an opaque pointer to an LLVM type,
+   manipulated through the `lib::llvm` interface.
+
+
+Control and information flow within the compiler:
+-------------------------------------------------
+
+- main() in lib.rs assumes control on startup. Options are
+  parsed, platform is detected, etc.
+
+- `./../libsyntax/parse/parser.rs` parses the input files and produces
+  an AST that represents the input crate.
+
+- Multiple middle-end passes (`middle/resolve.rs`, `middle/typeck.rs`)
+  analyze the semantics of the resulting AST. Each pass generates new
+  information about the AST and stores it in various environment data
+  structures. The driver passes environments to each compiler pass
+  that needs to refer to them.
+
+- Finally, the `trans` module in `librustc_trans` translates the Rust
+  AST to LLVM bitcode in a type-directed way. When it's finished
+  synthesizing LLVM values, rustc asks LLVM to write them out in some
+  form (`.bc`, `.o`) and possibly run the system linker.
diff --git a/src/librustc/README.txt b/src/librustc/README.txt
deleted file mode 100644 (file)
index 3709776..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-An informal guide to reading and working on the rustc compiler.
-==================================================================
-
-If you wish to expand on this document, or have a more experienced
-Rust contributor add anything else to it, please get in touch:
-
-* http://internals.rust-lang.org/
-* https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
-
-or file a bug:
-
-https://github.com/rust-lang/rust/issues
-
-Your concerns are probably the same as someone else's.
-
-The crates of rustc
-===================
-
-Rustc consists of four crates altogether: `libsyntax`, `librustc`,
-`librustc_back`, and `librustc_trans` (the names and divisions are not
-set in stone and may change; in general, a finer-grained division of
-crates is preferable):
-
-- `libsyntax` contains those things concerned purely with syntax --
-  that is, the AST, parser, pretty-printer, lexer, macro expander, and
-  utilities for traversing ASTs -- are in a separate crate called
-  "syntax", whose files are in ./../libsyntax, where . is the current
-  directory (that is, the parent directory of front/, middle/, back/,
-  and so on).
-
-- `librustc` (the current directory) contains the high-level analysis
-  passes, such as the type checker, borrow checker, and so forth.
-  It is the heart of the compiler.
-
-- `librustc_back` contains some very low-level details that are
-  specific to different LLVM targets and so forth.
-
-- `librustc_trans` contains the code to convert from Rust IR into LLVM
-  IR, and then from LLVM IR into machine code, as well as the main
-  driver that orchestrates all the other passes and various other bits
-  of miscellany. In general it contains code that runs towards the
-  end of the compilation process.
-  
-Roughly speaking the "order" of the three crates is as follows:
-
-    libsyntax -> librustc -> librustc_trans
-    |                                     |
-    +-----------------+-------------------+
-                      |
-             librustc_trans/driver
-
-Here the role of `librustc_trans/driver` is to invoke the compiler
-from libsyntax, then the analysis phases from librustc, and finally
-the lowering and codegen passes from librustc_trans.
-
-Modules in the rustc crate
-==========================
-
-The rustc crate itself consists of the following subdirectories
-(mostly, but not entirely, in their own directories):
-
-session  - options and data that pertain to the compilation session as a whole
-middle   - middle-end: name resolution, typechecking, LLVM code
-                  generation
-metadata - encoder and decoder for data required by
-                    separate compilation
-util     - ubiquitous types and helper functions
-lib      - bindings to LLVM
-
-The entry-point for the compiler is main() in the librustc_trans
-crate.
-
-The 3 central data structures:
-------------------------------
-
-#1: ./../libsyntax/ast.rs defines the AST. The AST is treated as immutable
-    after parsing, but it depends on mutable context data structures
-    (mainly hash maps) to give it meaning.
-
-      - Many -- though not all -- nodes within this data structure are
-        wrapped in the type `spanned<T>`, meaning that the front-end has
-        marked the input coordinates of that node. The member .node is
-        the data itself, the member .span is the input location (file,
-        line, column; both low and high).
-
-      - Many other nodes within this data structure carry a
-        def_id. These nodes represent the 'target' of some name
-        reference elsewhere in the tree. When the AST is resolved, by
-        middle/resolve.rs, all names wind up acquiring a def that they
-        point to. So anything that can be pointed-to by a name winds
-        up with a def_id.
-
-#2: middle/ty.rs defines the datatype sty.  This is the type that
-    represents types after they have been resolved and normalized by
-    the middle-end. The typeck phase converts every ast type to a
-    ty::sty, and the latter is used to drive later phases of
-    compilation.  Most variants in the ast::ty tag have a
-    corresponding variant in the ty::sty tag.
-
-#3: lib/llvm.rs (in librustc_trans) defines the exported types
-    ValueRef, TypeRef, BasicBlockRef, and several others. Each of
-    these is an opaque pointer to an LLVM type, manipulated through
-    the lib::llvm interface.
-
-
-Control and information flow within the compiler:
--------------------------------------------------
-
-- main() in lib.rs assumes control on startup. Options are
-  parsed, platform is detected, etc.
-
-- ./../libsyntax/parse/parser.rs parses the input files and produces an AST
-  that represents the input crate.
-
-- Multiple middle-end passes (middle/resolve.rs, middle/typeck.rs)
-  analyze the semantics of the resulting AST. Each pass generates new
-  information about the AST and stores it in various environment data
-  structures. The driver passes environments to each compiler pass
-  that needs to refer to them.
-
-- Finally, the `trans` module in `librustc_trans` translates the Rust
-  AST to LLVM bitcode in a type-directed way. When it's finished
-  synthesizing LLVM values, rustc asks LLVM to write them out in some
-  form (.bc, .o) and possibly run the system linker.
index 133bef30e4083afba1d8d9f2c7f09895e28b3770..0a29ed90ad46100d863d69a2e799c34000632a69 100644 (file)
@@ -68,6 +68,8 @@ register_diagnostics! {
     E0019,
     E0020,
     E0022,
+    E0079, // enum variant: expected signed integer constant
+    E0080, // enum variant: constant evaluation error
     E0109,
     E0110,
     E0133,
@@ -128,8 +130,8 @@ register_diagnostics! {
     E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
     E0314, // closure outlives stack frame
     E0315, // cannot invoke closure outside of its lifetime
-    E0316 // nested quantification of lifetimes
+    E0316, // nested quantification of lifetimes
+    E0370  // discriminant overflow
 }
 
 __build_diagnostic_array! { DIAGNOSTICS }
-
index fe9a81bb7c984f60d7b2b40e12b9f9106ddfd4ce..a4bb17bc354769d18a2253b7b9a0eb19421aa0f5 100644 (file)
@@ -14,6 +14,8 @@
 //!
 //! This API is completely unstable and subject to change.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rustc"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
 #![feature(collections)]
 #![feature(core)]
 #![feature(hash)]
-#![feature(int_uint)]
-#![feature(old_io)]
 #![feature(libc)]
-#![feature(env)]
-#![feature(old_path)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
 #![feature(unsafe_destructor)]
 #![feature(staged_api)]
 #![feature(std_misc)]
-#![feature(unicode)]
+#![feature(path_ext)]
+#![feature(str_words)]
+#![feature(str_char)]
+#![feature(into_cow)]
+#![feature(slice_patterns)]
 #![cfg_attr(test, feature(test))]
 
+#![allow(trivial_casts)]
+
 extern crate arena;
 extern crate flate;
 extern crate fmt_macros;
@@ -57,7 +61,7 @@ extern crate collections;
 #[macro_use] extern crate syntax;
 #[macro_use] #[no_link] extern crate rustc_bitflags;
 
-extern crate "serialize" as rustc_serialize; // used by deriving
+extern crate serialize as rustc_serialize; // used by deriving
 
 #[cfg(test)]
 extern crate test;
@@ -116,6 +120,8 @@ pub mod middle {
     pub mod traits;
     pub mod ty;
     pub mod ty_fold;
+    pub mod ty_match;
+    pub mod ty_relate;
     pub mod ty_walk;
     pub mod weak_lang_items;
 }
index dc81e89902bb4c093b42d8c65386c7707777510f..495044f9459494f738fa501c229b69de93f22da3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Lints built in to rustc.
+//! Some lints that are built in to the compiler.
 //!
-//! This is a sibling of `lint::context` in order to ensure that
-//! lints implemented here use the same public API as lint plugins.
-//!
-//! To add a new lint to rustc, declare it here using `declare_lint!()`.
-//! Then add code to emit the new lint in the appropriate circumstances.
-//! You can do that in an existing `LintPass` if it makes sense, or in
-//! a new `LintPass`, or using `Session::add_lint` elsewhere in the
-//! compiler. Only do the latter if the check can't be written cleanly
-//! as a `LintPass`.
-//!
-//! If you define a new `LintPass`, you will also need to add it to the
-//! `add_builtin!` or `add_builtin_with_new!` invocation in `context.rs`.
-//! Use the former for unit-like structs and the latter for structs with
-//! a `pub fn new()`.
-use self::MethodContext::*;
-
-use metadata::{csearch, decoder};
-use middle::def::*;
-use middle::subst::Substs;
-use middle::ty::{self, Ty};
-use middle::{def, pat_util, stability};
-use middle::const_eval::{eval_const_expr_partial, const_int, const_uint};
-use middle::cfg;
-use util::ppaux::{ty_to_string};
-use util::nodemap::{FnvHashMap, NodeSet};
-use lint::{Level, Context, LintPass, LintArray, Lint};
-
-use std::collections::BitSet;
-use std::collections::hash_map::Entry::{Occupied, Vacant};
-use std::num::SignedInt;
-use std::{cmp, slice};
-use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
-
-use syntax::{abi, ast, ast_map};
-use syntax::ast_util::is_shift_binop;
-use syntax::attr::{self, AttrMetaMethods};
-use syntax::codemap::{self, Span};
-use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType};
-use syntax::parse::token;
-use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};
-use syntax::ast_util;
-use syntax::ptr::P;
-use syntax::visit::{self, Visitor};
-
-declare_lint! {
-    WHILE_TRUE,
-    Warn,
-    "suggest using `loop { }` instead of `while true { }`"
-}
-
-#[derive(Copy)]
-pub struct WhileTrue;
-
-impl LintPass for WhileTrue {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(WHILE_TRUE)
-    }
-
-    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
-        if let ast::ExprWhile(ref cond, _, _) = e.node {
-            if let ast::ExprLit(ref lit) = cond.node {
-                if let ast::LitBool(true) = lit.node {
-                    cx.span_lint(WHILE_TRUE, e.span,
-                                 "denote infinite loops with loop { ... }");
-                }
-            }
-        }
-    }
-}
-
-declare_lint! {
-    UNUSED_TYPECASTS,
-    Allow,
-    "detects unnecessary type casts that can be removed"
-}
-
-#[derive(Copy)]
-pub struct UnusedCasts;
-
-impl LintPass for UnusedCasts {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNUSED_TYPECASTS)
-    }
-
-    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
-        if let ast::ExprCast(ref expr, ref ty) = e.node {
-            let t_t = ty::expr_ty(cx.tcx, e);
-            if ty::expr_ty(cx.tcx, &**expr) == t_t {
-                cx.span_lint(UNUSED_TYPECASTS, ty.span, "unnecessary type cast");
-            }
-        }
-    }
-}
-
-declare_lint! {
-    UNSIGNED_NEGATION,
-    Warn,
-    "using an unary minus operator on unsigned type"
-}
-
-declare_lint! {
-    UNUSED_COMPARISONS,
-    Warn,
-    "comparisons made useless by limits of the types involved"
-}
-
-declare_lint! {
-    OVERFLOWING_LITERALS,
-    Warn,
-    "literal out of range for its type"
-}
-
-declare_lint! {
-    EXCEEDING_BITSHIFTS,
-    Deny,
-    "shift exceeds the type's number of bits"
-}
-
-#[derive(Copy)]
-pub struct TypeLimits {
-    /// Id of the last visited negated expression
-    negated_expr_id: ast::NodeId,
-}
-
-impl TypeLimits {
-    pub fn new() -> TypeLimits {
-        TypeLimits {
-            negated_expr_id: -1,
-        }
-    }
-}
-
-impl LintPass for TypeLimits {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNSIGNED_NEGATION, UNUSED_COMPARISONS, OVERFLOWING_LITERALS,
-                    EXCEEDING_BITSHIFTS)
-    }
-
-    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
-        match e.node {
-            ast::ExprUnary(ast::UnNeg, ref expr) => {
-                match expr.node  {
-                    ast::ExprLit(ref lit) => {
-                        match lit.node {
-                            ast::LitInt(_, ast::UnsignedIntLit(_)) => {
-                                cx.span_lint(UNSIGNED_NEGATION, e.span,
-                                             "negation of unsigned int literal may \
-                                             be unintentional");
-                            },
-                            _ => ()
-                        }
-                    },
-                    _ => {
-                        let t = ty::expr_ty(cx.tcx, &**expr);
-                        match t.sty {
-                            ty::ty_uint(_) => {
-                                cx.span_lint(UNSIGNED_NEGATION, e.span,
-                                             "negation of unsigned int variable may \
-                                             be unintentional");
-                            },
-                            _ => ()
-                        }
-                    }
-                };
-                // propagate negation, if the negation itself isn't negated
-                if self.negated_expr_id != e.id {
-                    self.negated_expr_id = expr.id;
-                }
-            },
-            ast::ExprParen(ref expr) if self.negated_expr_id == e.id => {
-                self.negated_expr_id = expr.id;
-            },
-            ast::ExprBinary(binop, ref l, ref r) => {
-                if is_comparison(binop) && !check_limits(cx.tcx, binop, &**l, &**r) {
-                    cx.span_lint(UNUSED_COMPARISONS, e.span,
-                                 "comparison is useless due to type limits");
-                }
-
-                if is_shift_binop(binop.node) {
-                    let opt_ty_bits = match ty::expr_ty(cx.tcx, &**l).sty {
-                        ty::ty_int(t) => Some(int_ty_bits(t, cx.sess().target.int_type)),
-                        ty::ty_uint(t) => Some(uint_ty_bits(t, cx.sess().target.uint_type)),
-                        _ => None
-                    };
-
-                    if let Some(bits) = opt_ty_bits {
-                        let exceeding = if let ast::ExprLit(ref lit) = r.node {
-                            if let ast::LitInt(shift, _) = lit.node { shift >= bits }
-                            else { false }
-                        } else {
-                            match eval_const_expr_partial(cx.tcx, &**r, Some(cx.tcx.types.uint)) {
-                                Ok(const_int(shift)) => { shift as u64 >= bits },
-                                Ok(const_uint(shift)) => { shift >= bits },
-                                _ => { false }
-                            }
-                        };
-                        if exceeding {
-                            cx.span_lint(EXCEEDING_BITSHIFTS, e.span,
-                                         "bitshift exceeds the type's number of bits");
-                        }
-                    };
-                }
-            },
-            ast::ExprLit(ref lit) => {
-                match ty::expr_ty(cx.tcx, e).sty {
-                    ty::ty_int(t) => {
-                        match lit.node {
-                            ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
-                            ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
-                                let int_type = if let ast::TyIs(_) = t {
-                                    cx.sess().target.int_type
-                                } else { t };
-                                let (min, max) = int_ty_range(int_type);
-                                let negative = self.negated_expr_id == e.id;
-
-                                if (negative && v > (min.abs() as u64)) ||
-                                   (!negative && v > (max.abs() as u64)) {
-                                    cx.span_lint(OVERFLOWING_LITERALS, e.span,
-                                                 &*format!("literal out of range for {:?}", t));
-                                    return;
-                                }
-                            }
-                            _ => panic!()
-                        };
-                    },
-                    ty::ty_uint(t) => {
-                        let uint_type = if let ast::TyUs(_) = t {
-                            cx.sess().target.uint_type
-                        } else { t };
-                        let (min, max) = uint_ty_range(uint_type);
-                        let lit_val: u64 = match lit.node {
-                            ast::LitByte(_v) => return,  // _v is u8, within range by definition
-                            ast::LitInt(v, _) => v,
-                            _ => panic!()
-                        };
-                        if  lit_val < min || lit_val > max {
-                            cx.span_lint(OVERFLOWING_LITERALS, e.span,
-                                         &*format!("literal out of range for {:?}", t));
-                        }
-                    },
-                    ty::ty_float(t) => {
-                        let (min, max) = float_ty_range(t);
-                        let lit_val: f64 = match lit.node {
-                            ast::LitFloat(ref v, _) |
-                            ast::LitFloatUnsuffixed(ref v) => {
-                                match v.parse().ok() {
-                                    Some(f) => f,
-                                    None => return
-                                }
-                            }
-                            _ => panic!()
-                        };
-                        if lit_val < min || lit_val > max {
-                            cx.span_lint(OVERFLOWING_LITERALS, e.span,
-                                         &*format!("literal out of range for {:?}", t));
-                        }
-                    },
-                    _ => ()
-                };
-            },
-            _ => ()
-        };
-
-        fn is_valid<T:cmp::PartialOrd>(binop: ast::BinOp, v: T,
-                                min: T, max: T) -> bool {
-            match binop.node {
-                ast::BiLt => v >  min && v <= max,
-                ast::BiLe => v >= min && v <  max,
-                ast::BiGt => v >= min && v <  max,
-                ast::BiGe => v >  min && v <= max,
-                ast::BiEq | ast::BiNe => v >= min && v <= max,
-                _ => panic!()
-            }
-        }
-
-        fn rev_binop(binop: ast::BinOp) -> ast::BinOp {
-            codemap::respan(binop.span, match binop.node {
-                ast::BiLt => ast::BiGt,
-                ast::BiLe => ast::BiGe,
-                ast::BiGt => ast::BiLt,
-                ast::BiGe => ast::BiLe,
-                _ => return binop
-            })
-        }
-
-        // for int & uint, be conservative with the warnings, so that the
-        // warnings are consistent between 32- and 64-bit platforms
-        fn int_ty_range(int_ty: ast::IntTy) -> (i64, i64) {
-            match int_ty {
-                ast::TyIs(_) =>    (i64::MIN,        i64::MAX),
-                ast::TyI8 =>   (i8::MIN  as i64, i8::MAX  as i64),
-                ast::TyI16 =>  (i16::MIN as i64, i16::MAX as i64),
-                ast::TyI32 =>  (i32::MIN as i64, i32::MAX as i64),
-                ast::TyI64 =>  (i64::MIN,        i64::MAX)
-            }
-        }
-
-        fn uint_ty_range(uint_ty: ast::UintTy) -> (u64, u64) {
-            match uint_ty {
-                ast::TyUs(_) =>   (u64::MIN,         u64::MAX),
-                ast::TyU8 =>  (u8::MIN   as u64, u8::MAX   as u64),
-                ast::TyU16 => (u16::MIN  as u64, u16::MAX  as u64),
-                ast::TyU32 => (u32::MIN  as u64, u32::MAX  as u64),
-                ast::TyU64 => (u64::MIN,         u64::MAX)
-            }
-        }
-
-        fn float_ty_range(float_ty: ast::FloatTy) -> (f64, f64) {
-            match float_ty {
-                ast::TyF32  => (f32::MIN as f64, f32::MAX as f64),
-                ast::TyF64  => (f64::MIN,        f64::MAX)
-            }
-        }
-
-        fn int_ty_bits(int_ty: ast::IntTy, target_int_ty: ast::IntTy) -> u64 {
-            match int_ty {
-                ast::TyIs(_) =>    int_ty_bits(target_int_ty, target_int_ty),
-                ast::TyI8 =>   i8::BITS  as u64,
-                ast::TyI16 =>  i16::BITS as u64,
-                ast::TyI32 =>  i32::BITS as u64,
-                ast::TyI64 =>  i64::BITS as u64
-            }
-        }
-
-        fn uint_ty_bits(uint_ty: ast::UintTy, target_uint_ty: ast::UintTy) -> u64 {
-            match uint_ty {
-                ast::TyUs(_) =>    uint_ty_bits(target_uint_ty, target_uint_ty),
-                ast::TyU8 =>   u8::BITS  as u64,
-                ast::TyU16 =>  u16::BITS as u64,
-                ast::TyU32 =>  u32::BITS as u64,
-                ast::TyU64 =>  u64::BITS as u64
-            }
-        }
-
-        fn check_limits(tcx: &ty::ctxt, binop: ast::BinOp,
-                        l: &ast::Expr, r: &ast::Expr) -> bool {
-            let (lit, expr, swap) = match (&l.node, &r.node) {
-                (&ast::ExprLit(_), _) => (l, r, true),
-                (_, &ast::ExprLit(_)) => (r, l, false),
-                _ => return true
-            };
-            // Normalize the binop so that the literal is always on the RHS in
-            // the comparison
-            let norm_binop = if swap { rev_binop(binop) } else { binop };
-            match ty::expr_ty(tcx, expr).sty {
-                ty::ty_int(int_ty) => {
-                    let (min, max) = int_ty_range(int_ty);
-                    let lit_val: i64 = match lit.node {
-                        ast::ExprLit(ref li) => match li.node {
-                            ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
-                            ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => v as i64,
-                            ast::LitInt(v, ast::SignedIntLit(_, ast::Minus)) |
-                            ast::LitInt(v, ast::UnsuffixedIntLit(ast::Minus)) => -(v as i64),
-                            _ => return true
-                        },
-                        _ => panic!()
-                    };
-                    is_valid(norm_binop, lit_val, min, max)
-                }
-                ty::ty_uint(uint_ty) => {
-                    let (min, max): (u64, u64) = uint_ty_range(uint_ty);
-                    let lit_val: u64 = match lit.node {
-                        ast::ExprLit(ref li) => match li.node {
-                            ast::LitInt(v, _) => v,
-                            _ => return true
-                        },
-                        _ => panic!()
-                    };
-                    is_valid(norm_binop, lit_val, min, max)
-                }
-                _ => true
-            }
-        }
-
-        fn is_comparison(binop: ast::BinOp) -> bool {
-            match binop.node {
-                ast::BiEq | ast::BiLt | ast::BiLe |
-                ast::BiNe | ast::BiGe | ast::BiGt => true,
-                _ => false
-            }
-        }
-    }
-}
-
-declare_lint! {
-    IMPROPER_CTYPES,
-    Warn,
-    "proper use of libc types in foreign modules"
-}
-
-struct ImproperCTypesVisitor<'a, 'tcx: 'a> {
-    cx: &'a Context<'a, 'tcx>
-}
-
-impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
-    fn check_def(&mut self, sp: Span, ty_id: ast::NodeId, path_id: ast::NodeId) {
-        match self.cx.tcx.def_map.borrow()[path_id].clone() {
-            def::DefPrimTy(ast::TyInt(ast::TyIs(_))) => {
-                self.cx.span_lint(IMPROPER_CTYPES, sp,
-                                  "found rust type `isize` in foreign module, while \
-                                   libc::c_int or libc::c_long should be used");
-            }
-            def::DefPrimTy(ast::TyUint(ast::TyUs(_))) => {
-                self.cx.span_lint(IMPROPER_CTYPES, sp,
-                                  "found rust type `usize` in foreign module, while \
-                                   libc::c_uint or libc::c_ulong should be used");
-            }
-            def::DefTy(..) => {
-                let tty = match self.cx.tcx.ast_ty_to_ty_cache.borrow().get(&ty_id) {
-                    Some(&ty::atttce_resolved(t)) => t,
-                    _ => panic!("ast_ty_to_ty_cache was incomplete after typeck!")
-                };
-
-                if !ty::is_ffi_safe(self.cx.tcx, tty) {
-                    self.cx.span_lint(IMPROPER_CTYPES, sp,
-                                      "found type without foreign-function-safe
-                                      representation annotation in foreign module, consider \
-                                      adding a #[repr(...)] attribute to the type");
-                }
-            }
-            _ => ()
-        }
-    }
-}
-
-impl<'a, 'tcx, 'v> Visitor<'v> for ImproperCTypesVisitor<'a, 'tcx> {
-    fn visit_ty(&mut self, ty: &ast::Ty) {
-        match ty.node {
-            ast::TyPath(_, id) => self.check_def(ty.span, ty.id, id),
-            _ => (),
-        }
-        visit::walk_ty(self, ty);
-    }
-}
-
-#[derive(Copy)]
-pub struct ImproperCTypes;
-
-impl LintPass for ImproperCTypes {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(IMPROPER_CTYPES)
-    }
-
-    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        fn check_ty(cx: &Context, ty: &ast::Ty) {
-            let mut vis = ImproperCTypesVisitor { cx: cx };
-            vis.visit_ty(ty);
-        }
-
-        fn check_foreign_fn(cx: &Context, decl: &ast::FnDecl) {
-            for input in &decl.inputs {
-                check_ty(cx, &*input.ty);
-            }
-            if let ast::Return(ref ret_ty) = decl.output {
-                check_ty(cx, &**ret_ty);
-            }
-        }
-
-        match it.node {
-            ast::ItemForeignMod(ref nmod) if nmod.abi != abi::RustIntrinsic => {
-                for ni in &nmod.items {
-                    match ni.node {
-                        ast::ForeignItemFn(ref decl, _) => check_foreign_fn(cx, &**decl),
-                        ast::ForeignItemStatic(ref t, _) => check_ty(cx, &**t)
-                    }
-                }
-            }
-            _ => (),
-        }
-    }
-}
-
-declare_lint! {
-    BOX_POINTERS,
-    Allow,
-    "use of owned (Box type) heap memory"
-}
-
-#[derive(Copy)]
-pub struct BoxPointers;
-
-impl BoxPointers {
-    fn check_heap_type<'a, 'tcx>(&self, cx: &Context<'a, 'tcx>,
-                                 span: Span, ty: Ty<'tcx>) {
-        let mut n_uniq: usize = 0;
-        ty::fold_ty(cx.tcx, ty, |t| {
-            match t.sty {
-                ty::ty_uniq(_) => {
-                    n_uniq += 1;
-                }
-                _ => ()
-            };
-            t
-        });
-
-        if n_uniq > 0 {
-            let s = ty_to_string(cx.tcx, ty);
-            let m = format!("type uses owned (Box type) pointers: {}", s);
-            cx.span_lint(BOX_POINTERS, span, &m[..]);
-        }
-    }
-}
-
-impl LintPass for BoxPointers {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(BOX_POINTERS)
-    }
-
-    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        match it.node {
-            ast::ItemFn(..) |
-            ast::ItemTy(..) |
-            ast::ItemEnum(..) |
-            ast::ItemStruct(..) =>
-                self.check_heap_type(cx, it.span,
-                                     ty::node_id_to_type(cx.tcx, it.id)),
-            _ => ()
-        }
-
-        // If it's a struct, we also have to check the fields' types
-        match it.node {
-            ast::ItemStruct(ref struct_def, _) => {
-                for struct_field in &struct_def.fields {
-                    self.check_heap_type(cx, struct_field.span,
-                                         ty::node_id_to_type(cx.tcx, struct_field.node.id));
-                }
-            }
-            _ => ()
-        }
-    }
-
-    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
-        let ty = ty::expr_ty(cx.tcx, e);
-        self.check_heap_type(cx, e.span, ty);
-    }
-}
-
-declare_lint! {
-    RAW_POINTER_DERIVE,
-    Warn,
-    "uses of #[derive] with raw pointers are rarely correct"
-}
-
-struct RawPtrDeriveVisitor<'a, 'tcx: 'a> {
-    cx: &'a Context<'a, 'tcx>
-}
-
-impl<'a, 'tcx, 'v> Visitor<'v> for RawPtrDeriveVisitor<'a, 'tcx> {
-    fn visit_ty(&mut self, ty: &ast::Ty) {
-        static MSG: &'static str = "use of `#[derive]` with a raw pointer";
-        if let ast::TyPtr(..) = ty.node {
-            self.cx.span_lint(RAW_POINTER_DERIVE, ty.span, MSG);
-        }
-        visit::walk_ty(self, ty);
-    }
-    // explicit override to a no-op to reduce code bloat
-    fn visit_expr(&mut self, _: &ast::Expr) {}
-    fn visit_block(&mut self, _: &ast::Block) {}
-}
-
-pub struct RawPointerDerive {
-    checked_raw_pointers: NodeSet,
-}
-
-impl RawPointerDerive {
-    pub fn new() -> RawPointerDerive {
-        RawPointerDerive {
-            checked_raw_pointers: NodeSet(),
-        }
-    }
-}
-
-impl LintPass for RawPointerDerive {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(RAW_POINTER_DERIVE)
-    }
-
-    fn check_item(&mut self, cx: &Context, item: &ast::Item) {
-        if !attr::contains_name(&item.attrs[], "automatically_derived") {
-            return
-        }
-        let did = match item.node {
-            ast::ItemImpl(_, _, _, ref t_ref_opt, _, _) => {
-                // Deriving the Copy trait does not cause a warning
-                if let &Some(ref trait_ref) = t_ref_opt {
-                    let def_id = ty::trait_ref_to_def_id(cx.tcx, trait_ref);
-                    if Some(def_id) == cx.tcx.lang_items.copy_trait() {
-                        return
-                    }
-                }
-
-                match ty::node_id_to_type(cx.tcx, item.id).sty {
-                    ty::ty_enum(did, _) => did,
-                    ty::ty_struct(did, _) => did,
-                    _ => return,
-                }
-            }
-            _ => return,
-        };
-        if !ast_util::is_local(did) { return }
-        let item = match cx.tcx.map.find(did.node) {
-            Some(ast_map::NodeItem(item)) => item,
-            _ => return,
-        };
-        if !self.checked_raw_pointers.insert(item.id) { return }
-        match item.node {
-            ast::ItemStruct(..) | ast::ItemEnum(..) => {
-                let mut visitor = RawPtrDeriveVisitor { cx: cx };
-                visit::walk_item(&mut visitor, &*item);
-            }
-            _ => {}
-        }
-    }
-}
-
-declare_lint! {
-    UNUSED_ATTRIBUTES,
-    Warn,
-    "detects attributes that were not used by the compiler"
-}
-
-#[derive(Copy)]
-pub struct UnusedAttributes;
-
-impl LintPass for UnusedAttributes {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNUSED_ATTRIBUTES)
-    }
-
-    fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
-        for &(ref name, ty) in KNOWN_ATTRIBUTES {
-            match ty {
-                AttributeType::Whitelisted
-                | AttributeType::Gated(_, _) if attr.check_name(name) => {
-                    break;
-                },
-                _ => ()
-            }
-        }
-
-        if !attr::is_used(attr) {
-            cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
-            if KNOWN_ATTRIBUTES.contains(&(&attr.name()[], AttributeType::CrateLevel)) {
-                let msg = match attr.node.style {
-                    ast::AttrOuter => "crate-level attribute should be an inner \
-                                       attribute: add an exclamation mark: #![foo]",
-                    ast::AttrInner => "crate-level attribute should be in the \
-                                       root module",
-                };
-                cx.span_lint(UNUSED_ATTRIBUTES, attr.span, msg);
-            }
-        }
-    }
-}
-
-declare_lint! {
-    pub PATH_STATEMENTS,
-    Warn,
-    "path statements with no effect"
-}
-
-#[derive(Copy)]
-pub struct PathStatements;
-
-impl LintPass for PathStatements {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(PATH_STATEMENTS)
-    }
-
-    fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
-        match s.node {
-            ast::StmtSemi(ref expr, _) => {
-                match expr.node {
-                    ast::ExprPath(_) => cx.span_lint(PATH_STATEMENTS, s.span,
-                                                     "path statement with no effect"),
-                    _ => ()
-                }
-            }
-            _ => ()
-        }
-    }
-}
-
-declare_lint! {
-    pub UNUSED_MUST_USE,
-    Warn,
-    "unused result of a type flagged as #[must_use]"
-}
-
-declare_lint! {
-    pub UNUSED_RESULTS,
-    Allow,
-    "unused result of an expression in a statement"
-}
-
-#[derive(Copy)]
-pub struct UnusedResults;
-
-impl LintPass for UnusedResults {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNUSED_MUST_USE, UNUSED_RESULTS)
-    }
-
-    fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
-        let expr = match s.node {
-            ast::StmtSemi(ref expr, _) => &**expr,
-            _ => return
-        };
-
-        if let ast::ExprRet(..) = expr.node {
-            return;
-        }
-
-        let t = ty::expr_ty(cx.tcx, expr);
-        let mut warned = false;
-        match t.sty {
-            ty::ty_tup(ref tys) if tys.is_empty() => return,
-            ty::ty_bool => return,
-            ty::ty_struct(did, _) |
-            ty::ty_enum(did, _) => {
-                if ast_util::is_local(did) {
-                    if let ast_map::NodeItem(it) = cx.tcx.map.get(did.node) {
-                        warned |= check_must_use(cx, &it.attrs[], s.span);
-                    }
-                } else {
-                    let attrs = csearch::get_item_attrs(&cx.sess().cstore, did);
-                    warned |= check_must_use(cx, &attrs[..], s.span);
-                }
-            }
-            _ => {}
-        }
-        if !warned {
-            cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
-        }
-
-        fn check_must_use(cx: &Context, attrs: &[ast::Attribute], sp: Span) -> bool {
-            for attr in attrs {
-                if attr.check_name("must_use") {
-                    let mut msg = "unused result which must be used".to_string();
-                    // check for #[must_use="..."]
-                    match attr.value_str() {
-                        None => {}
-                        Some(s) => {
-                            msg.push_str(": ");
-                            msg.push_str(&s);
-                        }
-                    }
-                    cx.span_lint(UNUSED_MUST_USE, sp, &msg);
-                    return true;
-                }
-            }
-            false
-        }
-    }
-}
-
-declare_lint! {
-    pub NON_CAMEL_CASE_TYPES,
-    Warn,
-    "types, variants, traits and type parameters should have camel case names"
-}
-
-#[derive(Copy)]
-pub struct NonCamelCaseTypes;
-
-impl NonCamelCaseTypes {
-    fn check_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
-        fn is_camel_case(ident: ast::Ident) -> bool {
-            let ident = token::get_ident(ident);
-            if ident.is_empty() { return true; }
-            let ident = ident.trim_matches('_');
-
-            // start with a non-lowercase letter rather than non-uppercase
-            // ones (some scripts don't have a concept of upper/lowercase)
-            ident.len() > 0 && !ident.char_at(0).is_lowercase() && !ident.contains_char('_')
-        }
-
-        fn to_camel_case(s: &str) -> String {
-            s.split('_').flat_map(|word| word.chars().enumerate().map(|(i, c)|
-                if i == 0 { c.to_uppercase() }
-                else { c }
-            )).collect()
-        }
-
-        let s = token::get_ident(ident);
-
-        if !is_camel_case(ident) {
-            let c = to_camel_case(&s);
-            let m = if c.is_empty() {
-                format!("{} `{}` should have a camel case name such as `CamelCase`", sort, s)
-            } else {
-                format!("{} `{}` should have a camel case name such as `{}`", sort, s, c)
-            };
-            cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[..]);
-        }
-    }
-}
-
-impl LintPass for NonCamelCaseTypes {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(NON_CAMEL_CASE_TYPES)
-    }
-
-    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        let has_extern_repr = it.attrs.iter().map(|attr| {
-            attr::find_repr_attrs(cx.tcx.sess.diagnostic(), attr).iter()
-                .any(|r| r == &attr::ReprExtern)
-        }).any(|x| x);
-        if has_extern_repr { return }
-
-        match it.node {
-            ast::ItemTy(..) | ast::ItemStruct(..) => {
-                self.check_case(cx, "type", it.ident, it.span)
-            }
-            ast::ItemTrait(..) => {
-                self.check_case(cx, "trait", it.ident, it.span)
-            }
-            ast::ItemEnum(ref enum_definition, _) => {
-                if has_extern_repr { return }
-                self.check_case(cx, "type", it.ident, it.span);
-                for variant in &enum_definition.variants {
-                    self.check_case(cx, "variant", variant.node.name, variant.span);
-                }
-            }
-            _ => ()
-        }
-    }
-
-    fn check_generics(&mut self, cx: &Context, it: &ast::Generics) {
-        for gen in &*it.ty_params {
-            self.check_case(cx, "type parameter", gen.ident, gen.span);
-        }
-    }
-}
-
-#[derive(PartialEq)]
-enum MethodContext {
-    TraitDefaultImpl,
-    TraitImpl,
-    PlainImpl
-}
-
-fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
-    let did = ast::DefId {
-        krate: ast::LOCAL_CRATE,
-        node: m.id
-    };
-
-    match cx.tcx.impl_or_trait_items.borrow().get(&did).cloned() {
-        None => cx.sess().span_bug(m.span, "missing method descriptor?!"),
-        Some(md) => {
-            match md {
-                ty::MethodTraitItem(md) => {
-                    match md.container {
-                        ty::TraitContainer(..) => TraitDefaultImpl,
-                        ty::ImplContainer(cid) => {
-                            match ty::impl_trait_ref(cx.tcx, cid) {
-                                Some(..) => TraitImpl,
-                                None => PlainImpl
-                            }
-                        }
-                    }
-                }
-                ty::TypeTraitItem(typedef) => {
-                    match typedef.container {
-                        ty::TraitContainer(..) => TraitDefaultImpl,
-                        ty::ImplContainer(cid) => {
-                            match ty::impl_trait_ref(cx.tcx, cid) {
-                                Some(..) => TraitImpl,
-                                None => PlainImpl
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-declare_lint! {
-    pub NON_SNAKE_CASE,
-    Warn,
-    "methods, functions, lifetime parameters and modules should have snake case names"
-}
-
-#[derive(Copy)]
-pub struct NonSnakeCase;
-
-impl NonSnakeCase {
-    fn to_snake_case(mut str: &str) -> String {
-        let mut words = vec![];
-        // Preserve leading underscores
-        str = str.trim_left_matches(|c: char| {
-            if c == '_' {
-                words.push(String::new());
-                true
-            } else { false }
-        });
-        for s in str.split('_') {
-            let mut last_upper = false;
-            let mut buf = String::new();
-            if s.is_empty() { continue; }
-            for ch in s.chars() {
-                if !buf.is_empty() && buf != "'"
-                                   && ch.is_uppercase()
-                                   && !last_upper {
-                    words.push(buf);
-                    buf = String::new();
-                }
-                last_upper = ch.is_uppercase();
-                buf.push(ch.to_lowercase());
-            }
-            words.push(buf);
-        }
-        words.connect("_")
-    }
-
-    fn check_snake_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
-        fn is_snake_case(ident: ast::Ident) -> bool {
-            let ident = token::get_ident(ident);
-            if ident.is_empty() { return true; }
-            let ident = ident.trim_left_matches('\'');
-            let ident = ident.trim_matches('_');
-
-            let mut allow_underscore = true;
-            ident.chars().all(|c| {
-                allow_underscore = match c {
-                    '_' if !allow_underscore => return false,
-                    '_' => false,
-                    c if !c.is_uppercase() => true,
-                    _ => return false,
-                };
-                true
-            })
-        }
-
-        let s = token::get_ident(ident);
-
-        if !is_snake_case(ident) {
-            let sc = NonSnakeCase::to_snake_case(&s);
-            if sc != &s[..] {
-                cx.span_lint(NON_SNAKE_CASE, span,
-                    &*format!("{} `{}` should have a snake case name such as `{}`",
-                            sort, s, sc));
-            } else {
-                cx.span_lint(NON_SNAKE_CASE, span,
-                    &*format!("{} `{}` should have a snake case name",
-                            sort, s));
-            }
-        }
-    }
-}
-
-impl LintPass for NonSnakeCase {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(NON_SNAKE_CASE)
-    }
-
-    fn check_fn(&mut self, cx: &Context,
-                fk: visit::FnKind, _: &ast::FnDecl,
-                _: &ast::Block, span: Span, _: ast::NodeId) {
-        match fk {
-            visit::FkMethod(ident, _, m) => match method_context(cx, m) {
-                PlainImpl
-                    => self.check_snake_case(cx, "method", ident, span),
-                TraitDefaultImpl
-                    => self.check_snake_case(cx, "trait method", ident, span),
-                _ => (),
-            },
-            visit::FkItemFn(ident, _, _, _)
-                => self.check_snake_case(cx, "function", ident, span),
-            _ => (),
-        }
-    }
-
-    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        if let ast::ItemMod(_) = it.node {
-            self.check_snake_case(cx, "module", it.ident, it.span);
-        }
-    }
-
-    fn check_ty_method(&mut self, cx: &Context, t: &ast::TypeMethod) {
-        self.check_snake_case(cx, "trait method", t.ident, t.span);
-    }
-
-    fn check_lifetime_def(&mut self, cx: &Context, t: &ast::LifetimeDef) {
-        self.check_snake_case(cx, "lifetime", t.lifetime.name.ident(), t.lifetime.span);
-    }
-
-    fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
-        if let &ast::PatIdent(_, ref path1, _) = &p.node {
-            if let Some(&def::DefLocal(_)) = cx.tcx.def_map.borrow().get(&p.id) {
-                self.check_snake_case(cx, "variable", path1.node, p.span);
-            }
-        }
-    }
-
-    fn check_struct_def(&mut self, cx: &Context, s: &ast::StructDef,
-            _: ast::Ident, _: &ast::Generics, _: ast::NodeId) {
-        for sf in &s.fields {
-            if let ast::StructField_ { kind: ast::NamedField(ident, _), .. } = sf.node {
-                self.check_snake_case(cx, "structure field", ident, sf.span);
-            }
-        }
-    }
-}
-
-declare_lint! {
-    pub NON_UPPER_CASE_GLOBALS,
-    Warn,
-    "static constants should have uppercase identifiers"
-}
-
-#[derive(Copy)]
-pub struct NonUpperCaseGlobals;
-
-impl NonUpperCaseGlobals {
-    fn check_upper_case(cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
-        let s = token::get_ident(ident);
-
-        if s.chars().any(|c| c.is_lowercase()) {
-            let uc: String = NonSnakeCase::to_snake_case(&s).chars()
-                                           .map(|c| c.to_uppercase()).collect();
-            if uc != &s[..] {
-                cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
-                    &format!("{} `{}` should have an upper case name such as `{}`",
-                             sort, s, uc));
-            } else {
-                cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
-                    &format!("{} `{}` should have an upper case name",
-                             sort, s));
-            }
-        }
-    }
-}
-
-impl LintPass for NonUpperCaseGlobals {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(NON_UPPER_CASE_GLOBALS)
-    }
-
-    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        match it.node {
-            // only check static constants
-            ast::ItemStatic(_, ast::MutImmutable, _) => {
-                NonUpperCaseGlobals::check_upper_case(cx, "static constant", it.ident, it.span);
-            }
-            ast::ItemConst(..) => {
-                NonUpperCaseGlobals::check_upper_case(cx, "constant", it.ident, it.span);
-            }
-            _ => {}
-        }
-    }
-
-    fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
-        // Lint for constants that look like binding identifiers (#7526)
-        match (&p.node, cx.tcx.def_map.borrow().get(&p.id)) {
-            (&ast::PatIdent(_, ref path1, _), Some(&def::DefConst(..))) => {
-                NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
-                                                      path1.node, p.span);
-            }
-            _ => {}
-        }
-    }
-}
-
-declare_lint! {
-    UNUSED_PARENS,
-    Warn,
-    "`if`, `match`, `while` and `return` do not need parentheses"
-}
-
-#[derive(Copy)]
-pub struct UnusedParens;
-
-impl UnusedParens {
-    fn check_unused_parens_core(&self, cx: &Context, value: &ast::Expr, msg: &str,
-                                     struct_lit_needs_parens: bool) {
-        if let ast::ExprParen(ref inner) = value.node {
-            let necessary = struct_lit_needs_parens && contains_exterior_struct_lit(&**inner);
-            if !necessary {
-                cx.span_lint(UNUSED_PARENS, value.span,
-                             &format!("unnecessary parentheses around {}",
-                                     msg)[])
-            }
-        }
-
-        /// Expressions that syntactically contain an "exterior" struct
-        /// literal i.e. not surrounded by any parens or other
-        /// delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo
-        /// == X { y: 1 }` and `X { y: 1 } == foo` all do, but `(X {
-        /// y: 1 }) == foo` does not.
-        fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
-            match value.node {
-                ast::ExprStruct(..) => true,
-
-                ast::ExprAssign(ref lhs, ref rhs) |
-                ast::ExprAssignOp(_, ref lhs, ref rhs) |
-                ast::ExprBinary(_, ref lhs, ref rhs) => {
-                    // X { y: 1 } + X { y: 2 }
-                    contains_exterior_struct_lit(&**lhs) ||
-                        contains_exterior_struct_lit(&**rhs)
-                }
-                ast::ExprUnary(_, ref x) |
-                ast::ExprCast(ref x, _) |
-                ast::ExprField(ref x, _) |
-                ast::ExprTupField(ref x, _) |
-                ast::ExprIndex(ref x, _) => {
-                    // &X { y: 1 }, X { y: 1 }.y
-                    contains_exterior_struct_lit(&**x)
-                }
-
-                ast::ExprMethodCall(_, _, ref exprs) => {
-                    // X { y: 1 }.bar(...)
-                    contains_exterior_struct_lit(&*exprs[0])
-                }
-
-                _ => false
-            }
-        }
-    }
-}
-
-impl LintPass for UnusedParens {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNUSED_PARENS)
-    }
-
-    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
-        let (value, msg, struct_lit_needs_parens) = match e.node {
-            ast::ExprIf(ref cond, _, _) => (cond, "`if` condition", true),
-            ast::ExprWhile(ref cond, _, _) => (cond, "`while` condition", true),
-            ast::ExprMatch(ref head, _, source) => match source {
-                ast::MatchSource::Normal => (head, "`match` head expression", true),
-                ast::MatchSource::IfLetDesugar { .. } => (head, "`if let` head expression", true),
-                ast::MatchSource::WhileLetDesugar => (head, "`while let` head expression", true),
-                ast::MatchSource::ForLoopDesugar => (head, "`for` head expression", true),
-            },
-            ast::ExprRet(Some(ref value)) => (value, "`return` value", false),
-            ast::ExprAssign(_, ref value) => (value, "assigned value", false),
-            ast::ExprAssignOp(_, _, ref value) => (value, "assigned value", false),
-            _ => return
-        };
-        self.check_unused_parens_core(cx, &**value, msg, struct_lit_needs_parens);
-    }
-
-    fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
-        let (value, msg) = match s.node {
-            ast::StmtDecl(ref decl, _) => match decl.node {
-                ast::DeclLocal(ref local) => match local.init {
-                    Some(ref value) => (value, "assigned value"),
-                    None => return
-                },
-                _ => return
-            },
-            _ => return
-        };
-        self.check_unused_parens_core(cx, &**value, msg, false);
-    }
-}
-
-declare_lint! {
-    UNUSED_IMPORT_BRACES,
-    Allow,
-    "unnecessary braces around an imported item"
-}
-
-#[derive(Copy)]
-pub struct UnusedImportBraces;
-
-impl LintPass for UnusedImportBraces {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNUSED_IMPORT_BRACES)
-    }
-
-    fn check_item(&mut self, cx: &Context, item: &ast::Item) {
-        match item.node {
-            ast::ItemUse(ref view_path) => {
-                match view_path.node {
-                    ast::ViewPathList(_, ref items) => {
-                        if items.len() == 1 {
-                            match items[0].node {
-                                ast::PathListIdent {ref name, ..} => {
-                                    let m = format!("braces around {} is unnecessary",
-                                                    &token::get_ident(*name));
-                                    cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
-                                                 &m[..]);
-                                },
-                                _ => ()
-                            }
-                        }
-                    }
-                    _ => ()
-                }
-            },
-            _ => ()
-        }
-    }
-}
-
-declare_lint! {
-    NON_SHORTHAND_FIELD_PATTERNS,
-    Warn,
-    "using `Struct { x: x }` instead of `Struct { x }`"
-}
-
-#[derive(Copy)]
-pub struct NonShorthandFieldPatterns;
-
-impl LintPass for NonShorthandFieldPatterns {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(NON_SHORTHAND_FIELD_PATTERNS)
-    }
-
-    fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
-        let def_map = cx.tcx.def_map.borrow();
-        if let ast::PatStruct(_, ref v, _) = pat.node {
-            for fieldpat in v.iter()
-                             .filter(|fieldpat| !fieldpat.node.is_shorthand)
-                             .filter(|fieldpat| def_map.get(&fieldpat.node.pat.id)
-                                                == Some(&def::DefLocal(fieldpat.node.pat.id))) {
-                if let ast::PatIdent(_, ident, None) = fieldpat.node.pat.node {
-                    if ident.node.as_str() == fieldpat.node.ident.as_str() {
-                        cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
-                                     &format!("the `{}:` in this pattern is redundant and can \
-                                              be removed", ident.node.as_str())[])
-                    }
-                }
-            }
-        }
-    }
-}
-
-declare_lint! {
-    pub UNUSED_UNSAFE,
-    Warn,
-    "unnecessary use of an `unsafe` block"
-}
-
-#[derive(Copy)]
-pub struct UnusedUnsafe;
-
-impl LintPass for UnusedUnsafe {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNUSED_UNSAFE)
-    }
-
-    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
-        if let ast::ExprBlock(ref blk) = e.node {
-            // Don't warn about generated blocks, that'll just pollute the output.
-            if blk.rules == ast::UnsafeBlock(ast::UserProvided) &&
-                !cx.tcx.used_unsafe.borrow().contains(&blk.id) {
-                    cx.span_lint(UNUSED_UNSAFE, blk.span, "unnecessary `unsafe` block");
-            }
-        }
-    }
-}
-
-declare_lint! {
-    UNSAFE_BLOCKS,
-    Allow,
-    "usage of an `unsafe` block"
-}
-
-#[derive(Copy)]
-pub struct UnsafeBlocks;
-
-impl LintPass for UnsafeBlocks {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNSAFE_BLOCKS)
-    }
-
-    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
-        if let ast::ExprBlock(ref blk) = e.node {
-            // Don't warn about generated blocks, that'll just pollute the output.
-            if blk.rules == ast::UnsafeBlock(ast::UserProvided) {
-                cx.span_lint(UNSAFE_BLOCKS, blk.span, "usage of an `unsafe` block");
-            }
-        }
-    }
-}
-
-declare_lint! {
-    pub UNUSED_MUT,
-    Warn,
-    "detect mut variables which don't need to be mutable"
-}
-
-#[derive(Copy)]
-pub struct 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
-        // avoid false warnings in match arms with multiple patterns
-
-        let mut mutables = FnvHashMap();
-        for p in pats {
-            pat_util::pat_bindings(&cx.tcx.def_map, &**p, |mode, id, _, path1| {
-                let ident = path1.node;
-                if let ast::BindByValue(ast::MutMutable) = mode {
-                    if !token::get_ident(ident).starts_with("_") {
-                        match mutables.entry(ident.name.usize()) {
-                            Vacant(entry) => { entry.insert(vec![id]); },
-                            Occupied(mut entry) => { entry.get_mut().push(id); },
-                        }
-                    }
-                }
-            });
-        }
-
-        let used_mutables = cx.tcx.used_mut_nodes.borrow();
-        for (_, v) in &mutables {
-            if !v.iter().any(|e| used_mutables.contains(e)) {
-                cx.span_lint(UNUSED_MUT, cx.tcx.map.span(v[0]),
-                             "variable does not need to be mutable");
-            }
-        }
-    }
-}
-
-impl LintPass for UnusedMut {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNUSED_MUT)
-    }
-
-    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
-        if let ast::ExprMatch(_, ref arms, _) = e.node {
-            for a in arms {
-                self.check_unused_mut_pat(cx, &a.pats[])
-            }
-        }
-    }
-
-    fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
-        if let ast::StmtDecl(ref d, _) = s.node {
-            if let ast::DeclLocal(ref l) = d.node {
-                self.check_unused_mut_pat(cx, slice::ref_slice(&l.pat));
-            }
-        }
-    }
-
-    fn check_fn(&mut self, cx: &Context,
-                _: visit::FnKind, decl: &ast::FnDecl,
-                _: &ast::Block, _: Span, _: ast::NodeId) {
-        for a in &decl.inputs {
-            self.check_unused_mut_pat(cx, slice::ref_slice(&a.pat));
-        }
-    }
-}
-
-declare_lint! {
-    UNUSED_ALLOCATION,
-    Warn,
-    "detects unnecessary allocations that can be eliminated"
-}
-
-#[derive(Copy)]
-pub struct UnusedAllocation;
-
-impl LintPass for UnusedAllocation {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNUSED_ALLOCATION)
-    }
-
-    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
-        match e.node {
-            ast::ExprUnary(ast::UnUniq, _) => (),
-            _ => return
-        }
-
-        if let Some(adjustment) = cx.tcx.adjustments.borrow().get(&e.id) {
-            if let ty::AdjustDerefRef(ty::AutoDerefRef { ref autoref, .. }) = *adjustment {
-                match autoref {
-                    &Some(ty::AutoPtr(_, ast::MutImmutable, None)) => {
-                        cx.span_lint(UNUSED_ALLOCATION, e.span,
-                                     "unnecessary allocation, use & instead");
-                    }
-                    &Some(ty::AutoPtr(_, ast::MutMutable, None)) => {
-                        cx.span_lint(UNUSED_ALLOCATION, e.span,
-                                     "unnecessary allocation, use &mut instead");
-                    }
-                    _ => ()
-                }
-            }
-        }
-    }
-}
-
-declare_lint! {
-    MISSING_DOCS,
-    Allow,
-    "detects missing documentation for public members"
-}
-
-pub struct MissingDoc {
-    /// Stack of IDs of struct definitions.
-    struct_def_stack: Vec<ast::NodeId>,
-
-    /// True if inside variant definition
-    in_variant: bool,
-
-    /// Stack of whether #[doc(hidden)] is set
-    /// at each level which has lint attributes.
-    doc_hidden_stack: Vec<bool>,
-}
-
-impl MissingDoc {
-    pub fn new() -> MissingDoc {
-        MissingDoc {
-            struct_def_stack: vec!(),
-            in_variant: false,
-            doc_hidden_stack: vec!(false),
-        }
-    }
-
-    fn doc_hidden(&self) -> bool {
-        *self.doc_hidden_stack.last().expect("empty doc_hidden_stack")
-    }
-
-    fn check_missing_docs_attrs(&self,
-                               cx: &Context,
-                               id: Option<ast::NodeId>,
-                               attrs: &[ast::Attribute],
-                               sp: Span,
-                               desc: &'static str) {
-        // If we're building a test harness, then warning about
-        // documentation is probably not really relevant right now.
-        if cx.sess().opts.test { return }
-
-        // `#[doc(hidden)]` disables missing_docs check.
-        if self.doc_hidden() { return }
-
-        // Only check publicly-visible items, using the result from the privacy pass.
-        // It's an option so the crate root can also use this function (it doesn't
-        // have a NodeId).
-        if let Some(ref id) = id {
-            if !cx.exported_items.contains(id) {
-                return;
-            }
-        }
-
-        let has_doc = attrs.iter().any(|a| {
-            match a.node.value.node {
-                ast::MetaNameValue(ref name, _) if *name == "doc" => true,
-                _ => false
-            }
-        });
-        if !has_doc {
-            cx.span_lint(MISSING_DOCS, sp,
-                &format!("missing documentation for {}", desc)[]);
-        }
-    }
-}
-
-impl LintPass for MissingDoc {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(MISSING_DOCS)
-    }
-
-    fn enter_lint_attrs(&mut self, _: &Context, attrs: &[ast::Attribute]) {
-        let doc_hidden = self.doc_hidden() || attrs.iter().any(|attr| {
-            attr.check_name("doc") && match attr.meta_item_list() {
-                None => false,
-                Some(l) => attr::contains_name(&l[..], "hidden"),
-            }
-        });
-        self.doc_hidden_stack.push(doc_hidden);
-    }
-
-    fn exit_lint_attrs(&mut self, _: &Context, _: &[ast::Attribute]) {
-        self.doc_hidden_stack.pop().expect("empty doc_hidden_stack");
-    }
-
-    fn check_struct_def(&mut self, _: &Context,
-        _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, id: ast::NodeId) {
-        self.struct_def_stack.push(id);
-    }
-
-    fn check_struct_def_post(&mut self, _: &Context,
-        _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, id: ast::NodeId) {
-        let popped = self.struct_def_stack.pop().expect("empty struct_def_stack");
-        assert!(popped == id);
-    }
-
-    fn check_crate(&mut self, cx: &Context, krate: &ast::Crate) {
-        self.check_missing_docs_attrs(cx, None, &krate.attrs[],
-                                     krate.span, "crate");
-    }
-
-    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        let desc = match it.node {
-            ast::ItemFn(..) => "a function",
-            ast::ItemMod(..) => "a module",
-            ast::ItemEnum(..) => "an enum",
-            ast::ItemStruct(..) => "a struct",
-            ast::ItemTrait(..) => "a trait",
-            ast::ItemTy(..) => "a type alias",
-            _ => return
-        };
-        self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs[],
-                                     it.span, desc);
-    }
-
-    fn check_fn(&mut self, cx: &Context,
-            fk: visit::FnKind, _: &ast::FnDecl,
-            _: &ast::Block, _: Span, _: ast::NodeId) {
-        if let visit::FkMethod(_, _, m) = fk {
-            // If the method is an impl for a trait, don't doc.
-            if method_context(cx, m) == TraitImpl { return; }
-
-            // Otherwise, doc according to privacy. This will also check
-            // doc for default methods defined on traits.
-            self.check_missing_docs_attrs(cx, Some(m.id), &m.attrs[],
-                                          m.span, "a method");
-        }
-    }
-
-    fn check_ty_method(&mut self, cx: &Context, tm: &ast::TypeMethod) {
-        self.check_missing_docs_attrs(cx, Some(tm.id), &tm.attrs[],
-                                     tm.span, "a type method");
-    }
-
-    fn check_struct_field(&mut self, cx: &Context, sf: &ast::StructField) {
-        if let ast::NamedField(_, vis) = sf.node.kind {
-            if vis == ast::Public || self.in_variant {
-                let cur_struct_def = *self.struct_def_stack.last()
-                    .expect("empty struct_def_stack");
-                self.check_missing_docs_attrs(cx, Some(cur_struct_def),
-                                              &sf.node.attrs[], sf.span,
-                                              "a struct field")
-            }
-        }
-    }
-
-    fn check_variant(&mut self, cx: &Context, v: &ast::Variant, _: &ast::Generics) {
-        self.check_missing_docs_attrs(cx, Some(v.node.id), &v.node.attrs[],
-                                     v.span, "a variant");
-        assert!(!self.in_variant);
-        self.in_variant = true;
-    }
-
-    fn check_variant_post(&mut self, _: &Context, _: &ast::Variant, _: &ast::Generics) {
-        assert!(self.in_variant);
-        self.in_variant = false;
-    }
-}
-
-#[derive(Copy)]
-pub struct 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),
-                              cx.tcx.mk_substs(Substs::empty()))
-            }
-            ast::ItemEnum(_, ref ast_generics) => {
-                if ast_generics.is_parameterized() {
-                    return
-                }
-                ty::mk_enum(cx.tcx,
-                            ast_util::local_def(item.id),
-                            cx.tcx.mk_substs(Substs::empty()))
-            }
-            _ => return,
-        };
-        let parameter_environment = ty::empty_parameter_environment(cx.tcx);
-        if !ty::type_moves_by_default(&parameter_environment, item.span, ty) {
-            return
-        }
-        if ty::can_type_implement_copy(&parameter_environment, item.span, ty).is_ok() {
-            cx.span_lint(MISSING_COPY_IMPLEMENTATIONS,
-                         item.span,
-                         "type could implement `Copy`; consider adding `impl \
-                          Copy`")
-        }
-    }
-}
-
-declare_lint! {
-    MISSING_DEBUG_IMPLEMENTATIONS,
-    Allow,
-    "detects missing implementations of fmt::Debug"
-}
-
-pub struct MissingDebugImplementations {
-    impling_types: Option<NodeSet>,
-}
-
-impl MissingDebugImplementations {
-    pub fn new() -> MissingDebugImplementations {
-        MissingDebugImplementations {
-            impling_types: None,
-        }
-    }
-}
-
-impl LintPass for MissingDebugImplementations {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(MISSING_DEBUG_IMPLEMENTATIONS)
-    }
-
-    fn check_item(&mut self, cx: &Context, item: &ast::Item) {
-        if !cx.exported_items.contains(&item.id) {
-            return;
-        }
-
-        match item.node {
-            ast::ItemStruct(..) | ast::ItemEnum(..) => {},
-            _ => return,
-        }
-
-        let debug = match cx.tcx.lang_items.debug_trait() {
-            Some(debug) => debug,
-            None => return,
-        };
-
-        if self.impling_types.is_none() {
-            let impls = cx.tcx.trait_impls.borrow();
-            let impls = match impls.get(&debug) {
-                Some(impls) => {
-                    impls.borrow().iter()
-                        .filter(|d| d.krate == ast::LOCAL_CRATE)
-                        .filter_map(|d| ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)))
-                        .map(|d| d.node)
-                        .collect()
-                }
-                None => NodeSet(),
-            };
-            self.impling_types = Some(impls);
-            debug!("{:?}", self.impling_types);
-        }
-
-        if !self.impling_types.as_ref().unwrap().contains(&item.id) {
-            cx.span_lint(MISSING_DEBUG_IMPLEMENTATIONS,
-                         item.span,
-                         "type does not implement `fmt::Debug`; consider adding #[derive(Debug)] \
-                          or a manual implementation")
-        }
-    }
-}
-
-declare_lint! {
-    DEPRECATED,
-    Warn,
-    "detects use of #[deprecated] items"
-}
-
-/// Checks for use of items with `#[deprecated]` attributes
-#[derive(Copy)]
-pub struct Stability;
-
-impl Stability {
-    fn lint(&self, cx: &Context, _id: ast::DefId, span: Span, stability: &Option<attr::Stability>) {
-
-        // deprecated attributes apply in-crate and cross-crate
-        let (lint, label) = match *stability {
-            Some(attr::Stability { deprecated_since: Some(_), .. }) =>
-                (DEPRECATED, "deprecated"),
-            _ => return
-        };
-
-        output(cx, span, stability, lint, label);
-
-        fn output(cx: &Context, span: Span, stability: &Option<attr::Stability>,
-                  lint: &'static Lint, label: &'static str) {
-            let msg = match *stability {
-                Some(attr::Stability { reason: Some(ref s), .. }) => {
-                    format!("use of {} item: {}", label, *s)
-                }
-                _ => format!("use of {} item", label)
-            };
-
-            cx.span_lint(lint, span, &msg[..]);
-        }
-    }
-}
-
-impl LintPass for Stability {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(DEPRECATED)
-    }
-
-    fn check_item(&mut self, cx: &Context, item: &ast::Item) {
-        stability::check_item(cx.tcx, item, false,
-                              &mut |id, sp, stab| self.lint(cx, id, sp, stab));
-    }
-
-    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
-        stability::check_expr(cx.tcx, e,
-                              &mut |id, sp, stab| self.lint(cx, id, sp, stab));
-    }
-
-    fn check_path(&mut self, cx: &Context, path: &ast::Path, id: ast::NodeId) {
-        stability::check_path(cx.tcx, path, id,
-                              &mut |id, sp, stab| self.lint(cx, id, sp, stab));
-    }
-}
-
-declare_lint! {
-    pub UNCONDITIONAL_RECURSION,
-    Warn,
-    "functions that cannot return without calling themselves"
-}
-
-#[derive(Copy)]
-pub struct UnconditionalRecursion;
-
-
-impl LintPass for UnconditionalRecursion {
-    fn get_lints(&self) -> LintArray {
-        lint_array![UNCONDITIONAL_RECURSION]
-    }
-
-    fn check_fn(&mut self, cx: &Context, fn_kind: visit::FnKind, _: &ast::FnDecl,
-                blk: &ast::Block, sp: Span, id: ast::NodeId) {
-        type F = for<'tcx> fn(&ty::ctxt<'tcx>,
-                              ast::NodeId, ast::NodeId, ast::Ident, ast::NodeId) -> bool;
-
-        let (name, checker) = match fn_kind {
-            visit::FkItemFn(name, _, _, _) => (name, id_refers_to_this_fn as F),
-            visit::FkMethod(name, _, _) => (name, id_refers_to_this_method as F),
-            // closures can't recur, so they don't matter.
-            visit::FkFnBlock => return
-        };
+//! These are the built-in lints that are emitted direct in the main
+//! compiler code, rather than using their own custom pass. Those
+//! lints are all available in `rustc_lint::builtin`.
 
-        let impl_def_id = ty::impl_of_method(cx.tcx, ast_util::local_def(id))
-            .unwrap_or(ast_util::local_def(ast::DUMMY_NODE_ID));
-        assert!(ast_util::is_local(impl_def_id));
-        let impl_node_id = impl_def_id.node;
-
-        // Walk through this function (say `f`) looking to see if
-        // every possible path references itself, i.e. the function is
-        // called recursively unconditionally. This is done by trying
-        // to find a path from the entry node to the exit node that
-        // *doesn't* call `f` by traversing from the entry while
-        // pretending that calls of `f` are sinks (i.e. ignoring any
-        // exit edges from them).
-        //
-        // NB. this has an edge case with non-returning statements,
-        // like `loop {}` or `panic!()`: control flow never reaches
-        // the exit node through these, so one can have a function
-        // that never actually calls itselfs but is still picked up by
-        // this lint:
-        //
-        //     fn f(cond: bool) {
-        //         if !cond { panic!() } // could come from `assert!(cond)`
-        //         f(false)
-        //     }
-        //
-        // In general, functions of that form may be able to call
-        // itself a finite number of times and then diverge. The lint
-        // considers this to be an error for two reasons, (a) it is
-        // easier to implement, and (b) it seems rare to actually want
-        // to have behaviour like the above, rather than
-        // e.g. accidentally recurring after an assert.
-
-        let cfg = cfg::CFG::new(cx.tcx, blk);
-
-        let mut work_queue = vec![cfg.entry];
-        let mut reached_exit_without_self_call = false;
-        let mut self_call_spans = vec![];
-        let mut visited = BitSet::new();
-
-        while let Some(idx) = work_queue.pop() {
-            let cfg_id = idx.node_id();
-            if idx == cfg.exit {
-                // found a path!
-                reached_exit_without_self_call = true;
-                break
-            } else if visited.contains(&cfg_id) {
-                // already done
-                continue
-            }
-            visited.insert(cfg_id);
-            let node_id = cfg.graph.node_data(idx).id;
-
-            // is this a recursive call?
-            if node_id != ast::DUMMY_NODE_ID && checker(cx.tcx, impl_node_id, id, name, node_id) {
-
-                self_call_spans.push(cx.tcx.map.span(node_id));
-                // this is a self call, so we shouldn't explore past
-                // this node in the CFG.
-                continue
-            }
-            // add the successors of this node to explore the graph further.
-            cfg.graph.each_outgoing_edge(idx, |_, edge| {
-                let target_idx = edge.target();
-                let target_cfg_id = target_idx.node_id();
-                if !visited.contains(&target_cfg_id) {
-                    work_queue.push(target_idx)
-                }
-                true
-            });
-        }
-
-        // check the number of sell calls because a function that
-        // doesn't return (e.g. calls a `-> !` function or `loop { /*
-        // no break */ }`) shouldn't be linted unless it actually
-        // recurs.
-        if !reached_exit_without_self_call && self_call_spans.len() > 0 {
-            cx.span_lint(UNCONDITIONAL_RECURSION, sp,
-                         "function cannot return without recurring");
-
-            // FIXME #19668: these could be span_lint_note's instead of this manual guard.
-            if cx.current_level(UNCONDITIONAL_RECURSION) != Level::Allow {
-                let sess = cx.sess();
-                // offer some help to the programmer.
-                for call in &self_call_spans {
-                    sess.span_note(*call, "recursive call site")
-                }
-                sess.span_help(sp, "a `loop` may express intention better if this is on purpose")
-            }
-        }
-
-        // all done
-        return;
-
-        // Functions for identifying if the given NodeId `id`
-        // represents a call to the function `fn_id`/method
-        // `method_id`.
-
-        fn id_refers_to_this_fn<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                      _: ast::NodeId,
-                                      fn_id: ast::NodeId,
-                                      _: ast::Ident,
-                                      id: ast::NodeId) -> bool {
-            tcx.def_map.borrow().get(&id)
-                .map_or(false, |def| {
-                    let did = def.def_id();
-                    ast_util::is_local(did) && did.node == fn_id
-                })
-        }
-
-        // check if the method call `id` refers to method `method_id`
-        // (with name `method_name` contained in impl `impl_id`).
-        fn id_refers_to_this_method<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                          impl_id: ast::NodeId,
-                                          method_id: ast::NodeId,
-                                          method_name: ast::Ident,
-                                          id: ast::NodeId) -> bool {
-            let did = match tcx.method_map.borrow().get(&ty::MethodCall::expr(id)) {
-                None => return false,
-                Some(m) => match m.origin {
-                    // There's no way to know if a method call via a
-                    // vtable is recursion, so we assume it's not.
-                    ty::MethodTraitObject(_) => return false,
-
-                    // This `did` refers directly to the method definition.
-                    ty::MethodStatic(did) | ty::MethodStaticClosure(did) => did,
-
-                    // MethodTypeParam are methods from traits:
-
-                    // The `impl ... for ...` of this method call
-                    // isn't known, e.g. it might be a default method
-                    // in a trait, so we get the def-id of the trait
-                    // method instead.
-                    ty::MethodTypeParam(
-                        ty::MethodParam { ref trait_ref, method_num, impl_def_id: None, }) => {
-                        ty::trait_item(tcx, trait_ref.def_id, method_num).def_id()
-                    }
-
-                    // The `impl` is known, so we check that with a
-                    // special case:
-                    ty::MethodTypeParam(
-                        ty::MethodParam { impl_def_id: Some(impl_def_id), .. }) => {
-
-                        let name = match tcx.map.expect_expr(id).node {
-                            ast::ExprMethodCall(ref sp_ident, _, _) => sp_ident.node,
-                            _ => tcx.sess.span_bug(
-                                tcx.map.span(id),
-                                "non-method call expr behaving like a method call?")
-                        };
-                        // it matches if it comes from the same impl,
-                        // and has the same method name.
-                        return ast_util::is_local(impl_def_id)
-                            && impl_def_id.node == impl_id
-                            && method_name.name == name.name
-                    }
-                }
-            };
-
-            ast_util::is_local(did) && did.node == method_id
-        }
-    }
-}
-
-declare_lint! {
-    PLUGIN_AS_LIBRARY,
-    Warn,
-    "compiler plugin used as ordinary library in non-plugin crate"
-}
-
-#[derive(Copy)]
-pub struct PluginAsLibrary;
-
-impl LintPass for PluginAsLibrary {
-    fn get_lints(&self) -> LintArray {
-        lint_array![PLUGIN_AS_LIBRARY]
-    }
-
-    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        if cx.sess().plugin_registrar_fn.get().is_some() {
-            // We're compiling a plugin; it's fine to link other plugins.
-            return;
-        }
-
-        match it.node {
-            ast::ItemExternCrate(..) => (),
-            _ => return,
-        };
-
-        let md = match cx.sess().cstore.find_extern_mod_stmt_cnum(it.id) {
-            Some(cnum) => cx.sess().cstore.get_crate_data(cnum),
-            None => {
-                // Probably means we aren't linking the crate for some reason.
-                //
-                // Not sure if / when this could happen.
-                return;
-            }
-        };
-
-        if decoder::get_plugin_registrar_fn(md.data()).is_some() {
-            cx.span_lint(PLUGIN_AS_LIBRARY, it.span,
-                "compiler plugin used as an ordinary library");
-        }
-    }
-}
+use lint::{LintPass, LintArray};
 
 declare_lint! {
     pub UNUSED_IMPORTS,
@@ -2043,14 +101,19 @@ declare_lint! {
 }
 
 declare_lint! {
-    pub MISSING_COPY_IMPLEMENTATIONS,
+    pub TRIVIAL_CASTS,
     Allow,
-    "detects potentially-forgotten implementations of `Copy`"
+    "detects trivial casts which could be removed"
 }
 
+declare_lint! {
+    pub TRIVIAL_NUMERIC_CASTS,
+    Allow,
+    "detects trivial casts of numeric types which could be removed"
+}
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// which are used by other parts of the compiler.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct HardwiredLints;
 
 impl LintPass for HardwiredLints {
@@ -2069,86 +132,9 @@ impl LintPass for HardwiredLints {
             STABLE_FEATURES,
             UNKNOWN_CRATE_TYPES,
             VARIANT_SIZE_DIFFERENCES,
-            FAT_PTR_TRANSMUTES
+            FAT_PTR_TRANSMUTES,
+            TRIVIAL_CASTS,
+            TRIVIAL_NUMERIC_CASTS
         )
     }
 }
-
-declare_lint! {
-    PRIVATE_NO_MANGLE_FNS,
-    Warn,
-    "functions marked #[no_mangle] should be exported"
-}
-
-declare_lint! {
-    PRIVATE_NO_MANGLE_STATICS,
-    Warn,
-    "statics marked #[no_mangle] should be exported"
-}
-
-declare_lint! {
-    NO_MANGLE_CONST_ITEMS,
-    Deny,
-    "const items will not have their symbols exported"
-}
-
-#[derive(Copy)]
-pub struct InvalidNoMangleItems;
-
-impl LintPass for InvalidNoMangleItems {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(PRIVATE_NO_MANGLE_FNS,
-                    PRIVATE_NO_MANGLE_STATICS,
-                    NO_MANGLE_CONST_ITEMS)
-    }
-
-    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
-        match it.node {
-            ast::ItemFn(..) => {
-                if attr::contains_name(&it.attrs, "no_mangle") &&
-                       !cx.exported_items.contains(&it.id) {
-                    let msg = format!("function {} is marked #[no_mangle], but not exported",
-                                      it.ident);
-                    cx.span_lint(PRIVATE_NO_MANGLE_FNS, it.span, &msg);
-                }
-            },
-            ast::ItemStatic(..) => {
-                if attr::contains_name(it.attrs.as_slice(), "no_mangle") &&
-                       !cx.exported_items.contains(&it.id) {
-                    let msg = format!("static {} is marked #[no_mangle], but not exported",
-                                      it.ident);
-                    cx.span_lint(PRIVATE_NO_MANGLE_STATICS, it.span, msg.as_slice());
-                }
-            },
-            ast::ItemConst(..) => {
-                if attr::contains_name(it.attrs.as_slice(), "no_mangle") {
-                    // Const items do not refer to a particular location in memory, and therefore
-                    // don't have anything to attach a symbol to
-                    let msg = "const items should never be #[no_mangle], consider instead using \
-                        `pub static`";
-                    cx.span_lint(NO_MANGLE_CONST_ITEMS, it.span, msg);
-                }
-            }
-            _ => {},
-        }
-    }
-}
-
-/// Forbids using the `#[feature(...)]` attribute
-#[derive(Copy)]
-pub struct UnstableFeatures;
-
-declare_lint!(UNSTABLE_FEATURES, Allow,
-              "enabling unstable features");
-
-impl LintPass for UnstableFeatures {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNSTABLE_FEATURES)
-    }
-    fn check_attribute(&mut self, ctx: &Context, attr: &ast::Attribute) {
-        use syntax::attr;
-        if attr::contains_name(&[attr.node.value.clone()], "feature") {
-            ctx.span_lint(UNSTABLE_FEATURES, attr.span, "unstable feature");
-        }
-    }
-}
index 068c179d3431fe7c18087fd92dd1dc7a9a475f54..9688447dc046a50f3f3996333d98c82354d20442 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -105,7 +105,7 @@ impl LintStore {
     }
 
     pub fn get_lints<'t>(&'t self) -> &'t [(&'static Lint, bool)] {
-        &self.lints[]
+        &self.lints
     }
 
     pub fn get_lint_groups<'t>(&'t self) -> Vec<(&'static str, Vec<LintId>, bool)> {
@@ -159,7 +159,7 @@ impl LintStore {
         }
     }
 
-    fn register_renamed(&mut self, old_name: &str, new_name: &str) {
+    pub fn register_renamed(&mut self, old_name: &str, new_name: &str) {
         let target = match self.by_name.get(new_name) {
             Some(&Id(lint_id)) => lint_id.clone(),
             _ => panic!("invalid lint renaming of {} to {}", old_name, new_name)
@@ -167,80 +167,6 @@ impl LintStore {
         self.by_name.insert(old_name.to_string(), Renamed(new_name.to_string(), target));
     }
 
-    pub fn register_builtin(&mut self, sess: Option<&Session>) {
-        macro_rules! add_builtin {
-            ($sess:ident, $($name:ident),*,) => (
-                {$(
-                    self.register_pass($sess, false, box builtin::$name as LintPassObject);
-                )*}
-            )
-        }
-
-        macro_rules! add_builtin_with_new {
-            ($sess:ident, $($name:ident),*,) => (
-                {$(
-                    self.register_pass($sess, false, box builtin::$name::new() as LintPassObject);
-                )*}
-            )
-        }
-
-        macro_rules! add_lint_group {
-            ($sess:ident, $name:expr, $($lint:ident),*) => (
-                self.register_group($sess, false, $name, vec![$(LintId::of(builtin::$lint)),*]);
-            )
-        }
-
-        add_builtin!(sess,
-                     HardwiredLints,
-                     WhileTrue,
-                     UnusedCasts,
-                     ImproperCTypes,
-                     BoxPointers,
-                     UnusedAttributes,
-                     PathStatements,
-                     UnusedResults,
-                     NonCamelCaseTypes,
-                     NonSnakeCase,
-                     NonUpperCaseGlobals,
-                     UnusedParens,
-                     UnusedImportBraces,
-                     NonShorthandFieldPatterns,
-                     UnusedUnsafe,
-                     UnsafeBlocks,
-                     UnusedMut,
-                     UnusedAllocation,
-                     MissingCopyImplementations,
-                     UnstableFeatures,
-                     Stability,
-                     UnconditionalRecursion,
-                     InvalidNoMangleItems,
-                     PluginAsLibrary,
-        );
-
-        add_builtin_with_new!(sess,
-                              TypeLimits,
-                              RawPointerDerive,
-                              MissingDoc,
-                              MissingDebugImplementations,
-        );
-
-        add_lint_group!(sess, "bad_style",
-                        NON_CAMEL_CASE_TYPES, NON_SNAKE_CASE, NON_UPPER_CASE_GLOBALS);
-
-        add_lint_group!(sess, "unused",
-                        UNUSED_IMPORTS, UNUSED_VARIABLES, UNUSED_ASSIGNMENTS, DEAD_CODE,
-                        UNUSED_MUT, UNREACHABLE_CODE, UNUSED_MUST_USE,
-                        UNUSED_UNSAFE, PATH_STATEMENTS);
-
-        // We have one lint pass defined in this module.
-        self.register_pass(sess, false, box GatherNodeLevels as LintPassObject);
-
-        // Insert temporary renamings for a one-time deprecation
-        self.register_renamed("raw_pointer_deriving", "raw_pointer_derive");
-
-        self.register_renamed("unknown_features", "unused_features");
-    }
-
     #[allow(unused_variables)]
     fn find_lint(&self, lint_name: &str, sess: &Session, span: Option<Span>)
                  -> Option<LintId>
@@ -276,7 +202,7 @@ impl LintStore {
                              .collect::<Vec<()>>();
                         }
                         None => sess.err(&format!("unknown {} flag: {}",
-                                                 level.as_str(), lint_name)[]),
+                                                 level.as_str(), lint_name)),
                     }
                 }
             }
@@ -286,7 +212,7 @@ impl LintStore {
     fn maybe_stage_features(&mut self, sess: &Session) {
         let lvl = match sess.opts.unstable_features {
             UnstableFeatures::Default => return,
-            UnstableFeatures::Disallow => Warn,
+            UnstableFeatures::Disallow => Forbid,
             UnstableFeatures::Cheat => Allow
         };
         match self.by_name.get("unstable_features") {
@@ -527,7 +453,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
                     self.tcx.sess.span_err(span,
                                            &format!("{}({}) overruled by outer forbid({})",
                                                    level.as_str(), lint_name,
-                                                   lint_name)[]);
+                                                   lint_name));
                 } else if now != level {
                     let src = self.lints.get_level_source(lint_id).1;
                     self.level_stack.push((lint_id, (now, src)));
@@ -562,7 +488,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
 
 impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
     fn visit_item(&mut self, it: &ast::Item) {
-        self.with_lint_attrs(&it.attrs[], |cx| {
+        self.with_lint_attrs(&it.attrs, |cx| {
             run_lints!(cx, check_item, it);
             cx.visit_ids(|v| v.visit_item(it));
             visit::walk_item(cx, it);
@@ -570,7 +496,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
     }
 
     fn visit_foreign_item(&mut self, it: &ast::ForeignItem) {
-        self.with_lint_attrs(&it.attrs[], |cx| {
+        self.with_lint_attrs(&it.attrs, |cx| {
             run_lints!(cx, check_foreign_item, it);
             visit::walk_foreign_item(cx, it);
         })
@@ -593,28 +519,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
 
     fn visit_fn(&mut self, fk: FnKind<'v>, decl: &'v ast::FnDecl,
                 body: &'v ast::Block, span: Span, id: ast::NodeId) {
-        match fk {
-            visit::FkMethod(_, _, m) => {
-                self.with_lint_attrs(&m.attrs[], |cx| {
-                    run_lints!(cx, check_fn, fk, decl, body, span, id);
-                    cx.visit_ids(|v| {
-                        v.visit_fn(fk, decl, body, span, id);
-                    });
-                    visit::walk_fn(cx, fk, decl, body, span);
-                })
-            },
-            _ => {
-                run_lints!(self, check_fn, fk, decl, body, span, id);
-                visit::walk_fn(self, fk, decl, body, span);
-            }
-        }
-    }
-
-    fn visit_ty_method(&mut self, t: &ast::TypeMethod) {
-        self.with_lint_attrs(&t.attrs[], |cx| {
-            run_lints!(cx, check_ty_method, t);
-            visit::walk_ty_method(cx, t);
-        })
+        run_lints!(self, check_fn, fk, decl, body, span, id);
+        visit::walk_fn(self, fk, decl, body, span);
     }
 
     fn visit_struct_def(&mut self,
@@ -628,23 +534,23 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
     }
 
     fn visit_struct_field(&mut self, s: &ast::StructField) {
-        self.with_lint_attrs(&s.node.attrs[], |cx| {
+        self.with_lint_attrs(&s.node.attrs, |cx| {
             run_lints!(cx, check_struct_field, s);
             visit::walk_struct_field(cx, s);
         })
     }
 
     fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics) {
-        self.with_lint_attrs(&v.node.attrs[], |cx| {
+        self.with_lint_attrs(&v.node.attrs, |cx| {
             run_lints!(cx, check_variant, v, g);
             visit::walk_variant(cx, v, g);
             run_lints!(cx, check_variant_post, v, g);
         })
     }
 
-    // FIXME(#10894) should continue recursing
     fn visit_ty(&mut self, t: &ast::Ty) {
         run_lints!(self, check_ty, t);
+        visit::walk_ty(self, t);
     }
 
     fn visit_ident(&mut self, sp: Span, id: ast::Ident) {
@@ -685,9 +591,20 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
         visit::walk_generics(self, g);
     }
 
-    fn visit_trait_item(&mut self, m: &ast::TraitItem) {
-        run_lints!(self, check_trait_method, m);
-        visit::walk_trait_item(self, m);
+    fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
+        self.with_lint_attrs(&trait_item.attrs, |cx| {
+            run_lints!(cx, check_trait_item, trait_item);
+            cx.visit_ids(|v| v.visit_trait_item(trait_item));
+            visit::walk_trait_item(cx, trait_item);
+        });
+    }
+
+    fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
+        self.with_lint_attrs(&impl_item.attrs, |cx| {
+            run_lints!(cx, check_impl_item, impl_item);
+            cx.visit_ids(|v| v.visit_impl_item(impl_item));
+            visit::walk_impl_item(cx, impl_item);
+        });
     }
 
     fn visit_opt_lifetime_ref(&mut self, sp: Span, lt: &Option<ast::Lifetime>) {
@@ -741,7 +658,7 @@ impl<'a, 'tcx> IdVisitingOperation for Context<'a, 'tcx> {
 // nodes, so that the variant size difference check in trans can call
 // `raw_emit_lint`.
 
-struct GatherNodeLevels;
+pub struct GatherNodeLevels;
 
 impl LintPass for GatherNodeLevels {
     fn get_lints(&self) -> LintArray {
@@ -779,7 +696,7 @@ pub fn check_crate(tcx: &ty::ctxt,
     let mut cx = Context::new(tcx, krate, exported_items);
 
     // Visit the whole crate.
-    cx.with_lint_attrs(&krate.attrs[], |cx| {
+    cx.with_lint_attrs(&krate.attrs, |cx| {
         cx.visit_id(ast::CRATE_NODE_ID);
         cx.visit_ids(|v| {
             v.visited_outermost = true;
index bdcc10ebceca061899bf93a64540a42c37de4253..498b2ce518c16dc6055166053e19ed7ac5cb8b20 100644 (file)
@@ -37,10 +37,11 @@ use syntax::codemap::Span;
 use syntax::visit::FnKind;
 use syntax::ast;
 
-pub use lint::context::{Context, LintStore, raw_emit_lint, check_crate, gather_attrs};
+pub use lint::context::{Context, LintStore, raw_emit_lint, check_crate, gather_attrs,
+                        GatherNodeLevels};
 
 /// Specification of a single lint.
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub struct Lint {
     /// A string identifier for the lint.
     ///
@@ -142,8 +143,8 @@ pub trait LintPass {
     fn check_generics(&mut self, _: &Context, _: &ast::Generics) { }
     fn check_fn(&mut self, _: &Context,
         _: FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
-    fn check_ty_method(&mut self, _: &Context, _: &ast::TypeMethod) { }
-    fn check_trait_method(&mut self, _: &Context, _: &ast::TraitItem) { }
+    fn check_trait_item(&mut self, _: &Context, _: &ast::TraitItem) { }
+    fn check_impl_item(&mut self, _: &Context, _: &ast::ImplItem) { }
     fn check_struct_def(&mut self, _: &Context,
         _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
     fn check_struct_def_post(&mut self, _: &Context,
@@ -185,14 +186,6 @@ impl PartialEq for LintId {
 
 impl Eq for LintId { }
 
-#[cfg(stage0)]
-impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for LintId {
-    fn hash(&self, state: &mut S) {
-        let ptr = self.lint as *const Lint;
-        ptr.hash(state);
-    }
-}
-#[cfg(not(stage0))]
 impl hash::Hash for LintId {
     fn hash<H: hash::Hasher>(&self, state: &mut H) {
         let ptr = self.lint as *const Lint;
index 4930eddb35a53213ebad184791eebf6c9b4d8713..cda0084768644a599a98b438b52539d184758109 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -14,85 +14,89 @@ pub use self::astencode_tag::*;
 
 use back::svh::Svh;
 
-// EBML enum definitions and utils shared by the encoder and decoder
+// RBML enum definitions and utils shared by the encoder and decoder
+//
+// 0x00..0x1f: reserved for RBML generic type tags
+// 0x20..0xef: free for use, preferred for frequent tags
+// 0xf0..0xff: internally used by RBML to encode 0x100..0xfff in two bytes
+// 0x100..0xfff: free for use, preferred for infrequent tags
 
-pub const tag_items: uint = 0x00;
+pub const tag_items: usize = 0x100; // top-level only
 
-pub const tag_paths_data_name: uint = 0x01;
+pub const tag_paths_data_name: usize = 0x20;
 
-pub const tag_def_id: uint = 0x02;
+pub const tag_def_id: usize = 0x21;
 
-pub const tag_items_data: uint = 0x03;
+pub const tag_items_data: usize = 0x22;
 
-pub const tag_items_data_item: uint = 0x04;
+pub const tag_items_data_item: usize = 0x23;
 
-pub const tag_items_data_item_family: uint = 0x05;
+pub const tag_items_data_item_family: usize = 0x24;
 
-pub const tag_items_data_item_type: uint = 0x07;
+pub const tag_items_data_item_type: usize = 0x25;
 
-pub const tag_items_data_item_symbol: uint = 0x08;
+pub const tag_items_data_item_symbol: usize = 0x26;
 
-pub const tag_items_data_item_variant: uint = 0x09;
+pub const tag_items_data_item_variant: usize = 0x27;
 
-pub const tag_items_data_parent_item: uint = 0x0a;
+pub const tag_items_data_parent_item: usize = 0x28;
 
-pub const tag_items_data_item_is_tuple_struct_ctor: uint = 0x0b;
+pub const tag_items_data_item_is_tuple_struct_ctor: usize = 0x29;
 
-pub const tag_index: uint = 0x0c;
+pub const tag_index: usize = 0x2a;
 
-pub const tag_index_buckets: uint = 0x0d;
+pub const tag_index_buckets: usize = 0x2b;
 
-pub const tag_index_buckets_bucket: uint = 0x0e;
+pub const tag_index_buckets_bucket: usize = 0x2c;
 
-pub const tag_index_buckets_bucket_elt: uint = 0x0f;
+pub const tag_index_buckets_bucket_elt: usize = 0x2d;
 
-pub const tag_index_table: uint = 0x10;
+pub const tag_index_table: usize = 0x2e;
 
-pub const tag_meta_item_name_value: uint = 0x11;
+pub const tag_meta_item_name_value: usize = 0x2f;
 
-pub const tag_meta_item_name: uint = 0x12;
+pub const tag_meta_item_name: usize = 0x30;
 
-pub const tag_meta_item_value: uint = 0x13;
+pub const tag_meta_item_value: usize = 0x31;
 
-pub const tag_attributes: uint = 0x14;
+pub const tag_attributes: usize = 0x101; // top-level only
 
-pub const tag_attribute: uint = 0x15;
+pub const tag_attribute: usize = 0x32;
 
-pub const tag_meta_item_word: uint = 0x16;
+pub const tag_meta_item_word: usize = 0x33;
 
-pub const tag_meta_item_list: uint = 0x17;
+pub const tag_meta_item_list: usize = 0x34;
 
 // The list of crates that this crate depends on
-pub const tag_crate_deps: uint = 0x18;
+pub const tag_crate_deps: usize = 0x102; // top-level only
 
 // A single crate dependency
-pub const tag_crate_dep: uint = 0x19;
+pub const tag_crate_dep: usize = 0x35;
 
-pub const tag_crate_hash: uint = 0x1a;
-pub const tag_crate_crate_name: uint = 0x1b;
+pub const tag_crate_hash: usize = 0x103; // top-level only
+pub const tag_crate_crate_name: usize = 0x104; // top-level only
 
-pub const tag_crate_dep_crate_name: uint = 0x1d;
-pub const tag_crate_dep_hash: uint = 0x1e;
+pub const tag_crate_dep_crate_name: usize = 0x36;
+pub const tag_crate_dep_hash: usize = 0x37;
 
-pub const tag_mod_impl: uint = 0x1f;
+pub const tag_mod_impl: usize = 0x38;
 
-pub const tag_item_trait_item: uint = 0x20;
+pub const tag_item_trait_item: usize = 0x39;
 
-pub const tag_item_trait_ref: uint = 0x21;
-pub const tag_item_super_trait_ref: uint = 0x22;
+pub const tag_item_trait_ref: usize = 0x3a;
 
 // discriminator value for variants
-pub const tag_disr_val: uint = 0x23;
+pub const tag_disr_val: usize = 0x3c;
 
 // used to encode ast_map::PathElem
-pub const tag_path: uint = 0x24;
-pub const tag_path_len: uint = 0x25;
-pub const tag_path_elem_mod: uint = 0x26;
-pub const tag_path_elem_name: uint = 0x27;
-pub const tag_item_field: uint = 0x28;
-pub const tag_item_field_origin: uint = 0x29;
-
-pub const tag_item_variances: uint = 0x2a;
+pub const tag_path: usize = 0x3d;
+pub const tag_path_len: usize = 0x3e;
+pub const tag_path_elem_mod: usize = 0x3f;
+pub const tag_path_elem_name: usize = 0x40;
+pub const tag_item_field: usize = 0x41;
+pub const tag_item_field_origin: usize = 0x42;
+
+pub const tag_item_variances: usize = 0x43;
 /*
   trait items contain tag_item_trait_item elements,
   impl items contain tag_item_impl_item elements, and classes
@@ -101,60 +105,59 @@ pub const tag_item_variances: uint = 0x2a;
   both, tag_item_trait_item and tag_item_impl_item have to be two
   different tags.
  */
-pub const tag_item_impl_item: uint = 0x30;
-pub const tag_item_trait_method_explicit_self: uint = 0x31;
+pub const tag_item_impl_item: usize = 0x44;
+pub const tag_item_trait_method_explicit_self: usize = 0x45;
 
 
 // Reexports are found within module tags. Each reexport contains def_ids
 // and names.
-pub const tag_items_data_item_reexport: uint = 0x38;
-pub const tag_items_data_item_reexport_def_id: uint = 0x39;
-pub const tag_items_data_item_reexport_name: uint = 0x3a;
+pub const tag_items_data_item_reexport: usize = 0x46;
+pub const tag_items_data_item_reexport_def_id: usize = 0x47;
+pub const tag_items_data_item_reexport_name: usize = 0x48;
 
 // used to encode crate_ctxt side tables
-#[derive(Copy, PartialEq, FromPrimitive)]
-#[repr(uint)]
-pub enum astencode_tag { // Reserves 0x40 -- 0x5f
-    tag_ast = 0x40,
-
-    tag_tree = 0x41,
-
-    tag_id_range = 0x42,
-
-    tag_table = 0x43,
-    tag_table_id = 0x44,
-    tag_table_val = 0x45,
-    tag_table_def = 0x46,
-    tag_table_node_type = 0x47,
-    tag_table_item_subst = 0x48,
-    tag_table_freevars = 0x49,
-    tag_table_tcache = 0x4a,
-    tag_table_param_defs = 0x4b,
-    tag_table_mutbl = 0x4c,
-    tag_table_last_use = 0x4d,
-    tag_table_spill = 0x4e,
-    tag_table_method_map = 0x4f,
-    tag_table_vtable_map = 0x50,
-    tag_table_adjustments = 0x51,
-    tag_table_moves_map = 0x52,
-    tag_table_capture_map = 0x53,
-    tag_table_closure_tys = 0x54,
-    tag_table_closure_kinds = 0x55,
-    tag_table_upvar_capture_map = 0x56,
-    tag_table_capture_modes = 0x57,
-    tag_table_object_cast_map = 0x58,
-    tag_table_const_qualif = 0x59,
+#[derive(Copy, Clone, PartialEq, FromPrimitive)]
+#[repr(usize)]
+pub enum astencode_tag { // Reserves 0x50 -- 0x6f
+    tag_ast = 0x50,
+
+    tag_tree = 0x51,
+
+    tag_id_range = 0x52,
+
+    tag_table = 0x53,
+    // GAP 0x54, 0x55
+    tag_table_def = 0x56,
+    tag_table_node_type = 0x57,
+    tag_table_item_subst = 0x58,
+    tag_table_freevars = 0x59,
+    tag_table_tcache = 0x5a,
+    tag_table_param_defs = 0x5b,
+    tag_table_mutbl = 0x5c,
+    tag_table_last_use = 0x5d,
+    tag_table_spill = 0x5e,
+    tag_table_method_map = 0x5f,
+    tag_table_vtable_map = 0x60,
+    tag_table_adjustments = 0x61,
+    tag_table_moves_map = 0x62,
+    tag_table_capture_map = 0x63,
+    tag_table_closure_tys = 0x64,
+    tag_table_closure_kinds = 0x65,
+    tag_table_upvar_capture_map = 0x66,
+    tag_table_capture_modes = 0x67,
+    tag_table_object_cast_map = 0x68,
+    tag_table_const_qualif = 0x69,
 }
 
-pub const tag_item_trait_item_sort: uint = 0x60;
+pub const tag_item_trait_item_sort: usize = 0x70;
 
-pub const tag_item_trait_parent_sort: uint = 0x61;
+pub const tag_item_trait_parent_sort: usize = 0x71;
 
-pub const tag_item_impl_type_basename: uint = 0x62;
+pub const tag_item_impl_type_basename: usize = 0x72;
 
-pub const tag_crate_triple: uint = 0x66;
+pub const tag_crate_triple: usize = 0x105; // top-level only
 
-pub const tag_dylib_dependency_formats: uint = 0x67;
+pub const tag_dylib_dependency_formats: usize = 0x106; // top-level only
 
 // Language items are a top-level directory (for speed). Hierarchy:
 //
@@ -163,51 +166,47 @@ pub const tag_dylib_dependency_formats: uint = 0x67;
 //   - tag_lang_items_item_id: u32
 //   - tag_lang_items_item_node_id: u32
 
-pub const tag_lang_items: uint = 0x70;
-pub const tag_lang_items_item: uint = 0x71;
-pub const tag_lang_items_item_id: uint = 0x72;
-pub const tag_lang_items_item_node_id: uint = 0x73;
-pub const tag_lang_items_missing: uint = 0x74;
-
-pub const tag_item_unnamed_field: uint = 0x75;
-pub const tag_items_data_item_visibility: uint = 0x76;
+pub const tag_lang_items: usize = 0x107; // top-level only
+pub const tag_lang_items_item: usize = 0x73;
+pub const tag_lang_items_item_id: usize = 0x74;
+pub const tag_lang_items_item_node_id: usize = 0x75;
+pub const tag_lang_items_missing: usize = 0x76;
 
-pub const tag_item_method_tps: uint = 0x79;
-pub const tag_item_method_fty: uint = 0x7a;
+pub const tag_item_unnamed_field: usize = 0x77;
+pub const tag_items_data_item_visibility: usize = 0x78;
 
-pub const tag_mod_child: uint = 0x7b;
-pub const tag_misc_info: uint = 0x7c;
-pub const tag_misc_info_crate_items: uint = 0x7d;
+pub const tag_item_method_tps: usize = 0x79;
+pub const tag_item_method_fty: usize = 0x7a;
 
-pub const tag_item_method_provided_source: uint = 0x7e;
-pub const tag_item_impl_vtables: uint = 0x7f;
+pub const tag_mod_child: usize = 0x7b;
+pub const tag_misc_info: usize = 0x108; // top-level only
+pub const tag_misc_info_crate_items: usize = 0x7c;
 
-pub const tag_impls: uint = 0x80;
-pub const tag_impls_impl: uint = 0x81;
+pub const tag_item_method_provided_source: usize = 0x7d;
+pub const tag_item_impl_vtables: usize = 0x7e;
 
-pub const tag_items_data_item_inherent_impl: uint = 0x82;
-pub const tag_items_data_item_extension_impl: uint = 0x83;
+pub const tag_impls: usize = 0x109; // top-level only
+pub const tag_impls_impl: usize = 0x7f;
 
-// GAP 0x84, 0x85, 0x86
+pub const tag_items_data_item_inherent_impl: usize = 0x80;
+pub const tag_items_data_item_extension_impl: usize = 0x81;
 
-pub const tag_native_libraries: uint = 0x87;
-pub const tag_native_libraries_lib: uint = 0x88;
-pub const tag_native_libraries_name: uint = 0x89;
-pub const tag_native_libraries_kind: uint = 0x8a;
+pub const tag_native_libraries: usize = 0x10a; // top-level only
+pub const tag_native_libraries_lib: usize = 0x82;
+pub const tag_native_libraries_name: usize = 0x83;
+pub const tag_native_libraries_kind: usize = 0x84;
 
-pub const tag_plugin_registrar_fn: uint = 0x8b;
+pub const tag_plugin_registrar_fn: usize = 0x10b; // top-level only
 
-// GAP 0x8c, 0x8d
+pub const tag_method_argument_names: usize = 0x85;
+pub const tag_method_argument_name: usize = 0x86;
 
-pub const tag_method_argument_names: uint = 0x8e;
-pub const tag_method_argument_name: uint = 0x8f;
+pub const tag_reachable_extern_fns: usize = 0x10c; // top-level only
+pub const tag_reachable_extern_fn_id: usize = 0x87;
 
-pub const tag_reachable_extern_fns: uint = 0x90;
-pub const tag_reachable_extern_fn_id: uint = 0x91;
+pub const tag_items_data_item_stability: usize = 0x88;
 
-pub const tag_items_data_item_stability: uint = 0x92;
-
-pub const tag_items_data_item_repr: uint = 0x93;
+pub const tag_items_data_item_repr: usize = 0x89;
 
 #[derive(Clone, Debug)]
 pub struct LinkMeta {
@@ -215,42 +214,45 @@ pub struct LinkMeta {
     pub crate_hash: Svh,
 }
 
-// GAP 0x94...0x98
+pub const tag_struct_fields: usize = 0x10d; // top-level only
+pub const tag_struct_field: usize = 0x8a;
+pub const tag_struct_field_id: usize = 0x8b;
+
+pub const tag_attribute_is_sugared_doc: usize = 0x8c;
 
-pub const tag_struct_fields: uint = 0x99;
-pub const tag_struct_field: uint = 0x9a;
-pub const tag_struct_field_id: uint = 0x9b;
+pub const tag_items_data_region: usize = 0x8e;
 
-pub const tag_attribute_is_sugared_doc: uint = 0x9c;
+pub const tag_region_param_def: usize = 0x8f;
+pub const tag_region_param_def_ident: usize = 0x90;
+pub const tag_region_param_def_def_id: usize = 0x91;
+pub const tag_region_param_def_space: usize = 0x92;
+pub const tag_region_param_def_index: usize = 0x93;
 
-pub const tag_trait_def_bounds: uint = 0x9d;
+pub const tag_type_param_def: usize = 0x94;
 
-pub const tag_items_data_region: uint = 0x9e;
+pub const tag_item_generics: usize = 0x95;
+pub const tag_method_ty_generics: usize = 0x96;
 
-pub const tag_region_param_def: uint = 0xa0;
-pub const tag_region_param_def_ident: uint = 0xa1;
-pub const tag_region_param_def_def_id: uint = 0xa2;
-pub const tag_region_param_def_space: uint = 0xa3;
-pub const tag_region_param_def_index: uint = 0xa4;
+pub const tag_predicate: usize = 0x97;
+pub const tag_predicate_space: usize = 0x98;
+pub const tag_predicate_data: usize = 0x99;
 
-pub const tag_type_param_def: uint = 0xa5;
+pub const tag_unsafety: usize = 0x9a;
 
-pub const tag_item_generics: uint = 0xa6;
-pub const tag_method_ty_generics: uint = 0xa7;
+pub const tag_associated_type_names: usize = 0x9b;
+pub const tag_associated_type_name: usize = 0x9c;
 
-pub const tag_predicate: uint = 0xa8;
-pub const tag_predicate_space: uint = 0xa9;
-pub const tag_predicate_data: uint = 0xb0;
+pub const tag_polarity: usize = 0x9d;
 
-pub const tag_unsafety: uint = 0xb1;
+pub const tag_macro_defs: usize = 0x10e; // top-level only
+pub const tag_macro_def: usize = 0x9e;
+pub const tag_macro_def_body: usize = 0x9f;
 
-pub const tag_associated_type_names: uint = 0xb2;
-pub const tag_associated_type_name: uint = 0xb3;
+pub const tag_paren_sugar: usize = 0xa0;
 
-pub const tag_polarity: uint = 0xb4;
+pub const tag_codemap: usize = 0xa1;
+pub const tag_codemap_filemap: usize = 0xa2;
 
-pub const tag_macro_defs: uint = 0xb5;
-pub const tag_macro_def: uint = 0xb6;
-pub const tag_macro_def_body: uint = 0xb7;
+pub const tag_item_super_predicates: usize = 0xa3;
 
-pub const tag_paren_sugar: uint = 0xb8;
+pub const tag_defaulted_trait: usize = 0xa4;
index d48a404176ace37d2727925a3fd958ea309f32c4..b6a8525675e456c64afad6b7c8ee895eebb3d948 100644 (file)
@@ -21,12 +21,13 @@ use metadata::decoder;
 use metadata::loader;
 use metadata::loader::CratePaths;
 
+use std::path::{Path, PathBuf};
 use std::rc::Rc;
 use syntax::ast;
 use syntax::abi;
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
-use syntax::codemap::{Span, mk_sp};
+use syntax::codemap::{self, Span, mk_sp, Pos};
 use syntax::parse;
 use syntax::parse::token::InternedString;
 use syntax::parse::token;
@@ -61,7 +62,7 @@ fn dump_crates(cstore: &CStore) {
 }
 
 fn should_link(i: &ast::Item) -> bool {
-    !attr::contains_name(&i.attrs[], "no_link")
+    !attr::contains_name(&i.attrs, "no_link")
 }
 
 struct CrateInfo {
@@ -72,7 +73,7 @@ struct CrateInfo {
 }
 
 pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
-    let err = |s: &str| {
+    let say = |s: &str| {
         match (sp, sess) {
             (_, None) => panic!("{}", s),
             (Some(sp), Some(sess)) => sess.span_err(sp, s),
@@ -80,12 +81,12 @@ pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
         }
     };
     if s.len() == 0 {
-        err("crate name must not be empty");
+        say("crate name must not be empty");
     }
     for c in s.chars() {
         if c.is_alphanumeric() { continue }
-        if c == '_' || c == '-' { continue }
-        err(&format!("invalid character `{}` in crate name: `{}`", c, s)[]);
+        if c == '_'  { continue }
+        say(&format!("invalid character `{}` in crate name: `{}`", c, s));
     }
     match sess {
         Some(sess) => sess.abort_if_errors(),
@@ -124,7 +125,7 @@ fn register_native_lib(sess: &Session,
 // Extra info about a crate loaded for plugins or exported macros.
 struct ExtensionCrate {
     metadata: PMDSource,
-    dylib: Option<Path>,
+    dylib: Option<PathBuf>,
     target_only: bool,
 }
 
@@ -150,8 +151,9 @@ impl<'a> CrateReader<'a> {
         }
     }
 
-    // Traverses an AST, reading all the information about use'd crates and extern
-    // libraries necessary for later resolving, typechecking, linking, etc.
+    // Traverses an AST, reading all the information about use'd crates and
+    // extern libraries necessary for later resolving, typechecking, linking,
+    // etc.
     pub fn read_crates(&mut self, krate: &ast::Crate) {
         self.process_crate(krate);
         visit::walk_crate(self, krate);
@@ -181,11 +183,10 @@ impl<'a> CrateReader<'a> {
                 debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
                        ident, path_opt);
                 let name = match *path_opt {
-                    Some((ref path_str, _)) => {
-                        let name = path_str.to_string();
-                        validate_crate_name(Some(self.sess), &name[..],
+                    Some(name) => {
+                        validate_crate_name(Some(self.sess), name.as_str(),
                                             Some(i.span));
-                        name
+                        name.as_str().to_string()
                     }
                     None => ident.to_string(),
                 };
@@ -210,8 +211,8 @@ impl<'a> CrateReader<'a> {
                 match self.extract_crate_info(i) {
                     Some(info) => {
                         let (cnum, _, _) = self.resolve_crate(&None,
-                                                              &info.ident[],
-                                                              &info.name[],
+                                                              &info.ident,
+                                                              &info.name,
                                                               None,
                                                               i.span,
                                                               PathKind::Crate);
@@ -268,7 +269,7 @@ impl<'a> CrateReader<'a> {
                                     } else {
                                         self.sess.span_err(m.span,
                                             &format!("unknown kind: `{}`",
-                                                    k)[]);
+                                                    k));
                                         cstore::NativeUnknown
                                     }
                                 }
@@ -371,15 +372,17 @@ impl<'a> CrateReader<'a> {
         // Maintain a reference to the top most crate.
         let root = if root.is_some() { root } else { &crate_paths };
 
-        let cnum_map = self.resolve_crate_deps(root, lib.metadata.as_slice(), span);
+        let loader::Library { dylib, rlib, metadata } = lib;
 
-        let loader::Library{ dylib, rlib, metadata } = lib;
+        let cnum_map = self.resolve_crate_deps(root, metadata.as_slice(), span);
+        let codemap_import_info = import_codemap(self.sess.codemap(), &metadata);
 
         let cmeta = Rc::new( cstore::crate_metadata {
             name: name.to_string(),
             data: metadata,
             cnum_map: cnum_map,
             cnum: cnum,
+            codemap_import_info: codemap_import_info,
             span: span,
         });
 
@@ -413,7 +416,7 @@ impl<'a> CrateReader<'a> {
                     hash: hash.map(|a| &*a),
                     filesearch: self.sess.target_filesearch(kind),
                     target: &self.sess.target.target,
-                    triple: &self.sess.opts.target_triple[],
+                    triple: &self.sess.opts.target_triple,
                     root: root,
                     rejected_via_hash: vec!(),
                     rejected_via_triple: vec!(),
@@ -440,8 +443,8 @@ impl<'a> CrateReader<'a> {
         decoder::get_crate_deps(cdata).iter().map(|dep| {
             debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
             let (local_cnum, _, _) = self.resolve_crate(root,
-                                                   &dep.name[],
-                                                   &dep.name[],
+                                                   &dep.name,
+                                                   &dep.name,
                                                    Some(&dep.hash),
                                                    span,
                                                    PathKind::Dependency);
@@ -450,7 +453,7 @@ impl<'a> CrateReader<'a> {
     }
 
     fn read_extension_crate(&mut self, span: Span, info: &CrateInfo) -> ExtensionCrate {
-        let target_triple = &self.sess.opts.target_triple[];
+        let target_triple = &self.sess.opts.target_triple[..];
         let is_cross = target_triple != config::host_triple();
         let mut should_link = info.should_link && !is_cross;
         let mut target_only = false;
@@ -488,13 +491,13 @@ impl<'a> CrateReader<'a> {
         };
 
         let dylib = library.dylib.clone();
-        let register = should_link && self.existing_match(info.name.as_slice(),
+        let register = should_link && self.existing_match(&info.name,
                                                           None,
                                                           PathKind::Crate).is_none();
         let metadata = if register {
             // Register crate now to avoid double-reading metadata
-            let (_, cmd, _) = self.register_crate(&None, &info.ident[],
-                                &info.name[], span, library);
+            let (_, cmd, _) = self.register_crate(&None, &info.ident,
+                                &info.name, span, library);
             PMDSource::Registered(cmd)
         } else {
             // Not registering the crate; just hold on to the metadata
@@ -537,6 +540,7 @@ impl<'a> CrateReader<'a> {
                     // overridden in plugin/load.rs
                     export: false,
                     use_locally: false,
+                    allow_internal_unstable: false,
 
                     body: body,
                 });
@@ -547,7 +551,8 @@ impl<'a> CrateReader<'a> {
     }
 
     /// Look for a plugin registrar. Returns library path and symbol name.
-    pub fn find_plugin_registrar(&mut self, span: Span, name: &str) -> Option<(Path, String)> {
+    pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
+                                 -> Option<(PathBuf, String)> {
         let ekrate = self.read_extension_crate(span, &CrateInfo {
              name: name.to_string(),
              ident: name.to_string(),
@@ -570,7 +575,7 @@ impl<'a> CrateReader<'a> {
             .map(|id| decoder::get_symbol(ekrate.metadata.as_slice(), id));
 
         match (ekrate.dylib.as_ref(), registrar) {
-            (Some(dylib), Some(reg)) => Some((dylib.clone(), reg)),
+            (Some(dylib), Some(reg)) => Some((dylib.to_path_buf(), reg)),
             (None, Some(_)) => {
                 let message = format!("plugin `{}` only found in rlib format, \
                                        but must be available in dylib format",
@@ -584,3 +589,131 @@ impl<'a> CrateReader<'a> {
         }
     }
 }
+
+/// Imports the codemap from an external crate into the codemap of the crate
+/// currently being compiled (the "local crate").
+///
+/// The import algorithm works analogous to how AST items are inlined from an
+/// external crate's metadata:
+/// For every FileMap in the external codemap an 'inline' copy is created in the
+/// local codemap. The correspondence relation between external and local
+/// FileMaps is recorded in the `ImportedFileMap` objects returned from this
+/// function. When an item from an external crate is later inlined into this
+/// crate, this correspondence information is used to translate the span
+/// information of the inlined item so that it refers the correct positions in
+/// the local codemap (see `astencode::DecodeContext::tr_span()`).
+///
+/// The import algorithm in the function below will reuse FileMaps already
+/// existing in the local codemap. For example, even if the FileMap of some
+/// source file of libstd gets imported many times, there will only ever be
+/// one FileMap object for the corresponding file in the local codemap.
+///
+/// Note that imported FileMaps do not actually contain the source code of the
+/// file they represent, just information about length, line breaks, and
+/// multibyte characters. This information is enough to generate valid debuginfo
+/// for items inlined from other crates.
+fn import_codemap(local_codemap: &codemap::CodeMap,
+                  metadata: &MetadataBlob)
+                  -> Vec<cstore::ImportedFileMap> {
+    let external_codemap = decoder::get_imported_filemaps(metadata.as_slice());
+
+    let imported_filemaps = external_codemap.into_iter().map(|filemap_to_import| {
+        // Try to find an existing FileMap that can be reused for the filemap to
+        // be imported. A FileMap is reusable if it is exactly the same, just
+        // positioned at a different offset within the codemap.
+        let reusable_filemap = {
+            local_codemap.files
+                         .borrow()
+                         .iter()
+                         .find(|fm| are_equal_modulo_startpos(&fm, &filemap_to_import))
+                         .map(|rc| rc.clone())
+        };
+
+        match reusable_filemap {
+            Some(fm) => {
+                cstore::ImportedFileMap {
+                    original_start_pos: filemap_to_import.start_pos,
+                    original_end_pos: filemap_to_import.end_pos,
+                    translated_filemap: fm
+                }
+            }
+            None => {
+                // We can't reuse an existing FileMap, so allocate a new one
+                // containing the information we need.
+                let codemap::FileMap {
+                    name,
+                    start_pos,
+                    end_pos,
+                    lines,
+                    multibyte_chars,
+                    ..
+                } = filemap_to_import;
+
+                let source_length = (end_pos - start_pos).to_usize();
+
+                // Translate line-start positions and multibyte character
+                // position into frame of reference local to file.
+                // `CodeMap::new_imported_filemap()` will then translate those
+                // coordinates to their new global frame of reference when the
+                // offset of the FileMap is known.
+                let lines = lines.into_inner().map_in_place(|pos| pos - start_pos);
+                let multibyte_chars = multibyte_chars
+                    .into_inner()
+                    .map_in_place(|mbc|
+                        codemap::MultiByteChar {
+                            pos: mbc.pos + start_pos,
+                            bytes: mbc.bytes
+                        });
+
+                let local_version = local_codemap.new_imported_filemap(name,
+                                                                       source_length,
+                                                                       lines,
+                                                                       multibyte_chars);
+                cstore::ImportedFileMap {
+                    original_start_pos: start_pos,
+                    original_end_pos: end_pos,
+                    translated_filemap: local_version
+                }
+            }
+        }
+    }).collect();
+
+    return imported_filemaps;
+
+    fn are_equal_modulo_startpos(fm1: &codemap::FileMap,
+                                 fm2: &codemap::FileMap)
+                                 -> bool {
+        if fm1.name != fm2.name {
+            return false;
+        }
+
+        let lines1 = fm1.lines.borrow();
+        let lines2 = fm2.lines.borrow();
+
+        if lines1.len() != lines2.len() {
+            return false;
+        }
+
+        for (&line1, &line2) in lines1.iter().zip(lines2.iter()) {
+            if (line1 - fm1.start_pos) != (line2 - fm2.start_pos) {
+                return false;
+            }
+        }
+
+        let multibytes1 = fm1.multibyte_chars.borrow();
+        let multibytes2 = fm2.multibyte_chars.borrow();
+
+        if multibytes1.len() != multibytes2.len() {
+            return false;
+        }
+
+        for (mb1, mb2) in multibytes1.iter().zip(multibytes2.iter()) {
+            if (mb1.bytes != mb2.bytes) ||
+               ((mb1.pos - fm1.start_pos) != (mb2.pos - fm2.start_pos)) {
+                return false;
+            }
+        }
+
+        true
+    }
+}
index 7eeb0589118fbf8dbfd1cc47df80f92a576083b2..d528e38d341cfe099a80acf0f37d039e9bc3c107 100644 (file)
@@ -29,7 +29,7 @@ use syntax::parse::token;
 
 use std::collections::hash_map::HashMap;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct MethodInfo {
     pub name: ast::Name,
     pub def_id: ast::DefId,
@@ -46,7 +46,7 @@ pub fn each_lang_item<F>(cstore: &cstore::CStore,
                          cnum: ast::CrateNum,
                          f: F)
                          -> bool where
-    F: FnMut(ast::NodeId, uint) -> bool,
+    F: FnMut(ast::NodeId, usize) -> bool,
 {
     let crate_data = cstore.get_crate_data(cnum);
     decoder::each_lang_item(&*crate_data, f)
@@ -92,7 +92,7 @@ pub fn get_item_path(tcx: &ty::ctxt, def: ast::DefId) -> Vec<ast_map::PathElem>
 
     // FIXME #1920: This path is not always correct if the crate is not linked
     // into the root namespace.
-    let mut r = vec![ast_map::PathMod(token::intern(&cdata.name[]))];
+    let mut r = vec![ast_map::PathMod(token::intern(&cdata.name))];
     r.push_all(&path);
     r
 }
@@ -150,12 +150,9 @@ pub fn get_trait_name(cstore: &cstore::CStore, def: ast::DefId) -> ast::Name {
                             def.node)
 }
 
-pub fn get_trait_item_name_and_kind(cstore: &cstore::CStore, def: ast::DefId)
-                                    -> (ast::Name, def::TraitItemKind) {
+pub fn is_static_method(cstore: &cstore::CStore, def: ast::DefId) -> bool {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_trait_item_name_and_kind(cstore.intr.clone(),
-                                          &*cdata,
-                                          def.node)
+    decoder::is_static_method(&*cdata, def.node)
 }
 
 pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: ast::DefId)
@@ -178,14 +175,6 @@ pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
     decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.node, tcx)
 }
 
-pub fn get_supertraits<'tcx>(tcx: &ty::ctxt<'tcx>,
-                             def: ast::DefId)
-                             -> Vec<Rc<ty::TraitRef<'tcx>>> {
-    let cstore = &tcx.sess.cstore;
-    let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_supertraits(&*cdata, def.node, tcx)
-}
-
 pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: ast::DefId)
                           -> Option<ast::Name> {
     let cdata = cstore.get_crate_data(def.krate);
@@ -241,6 +230,14 @@ pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
     decoder::get_predicates(&*cdata, def.node, tcx)
 }
 
+pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
+                                  -> ty::GenericPredicates<'tcx>
+{
+    let cstore = &tcx.sess.cstore;
+    let cdata = cstore.get_crate_data(def.krate);
+    decoder::get_super_predicates(&*cdata, def.node, tcx)
+}
+
 pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
                             def: ast::DefId) -> ty::TypeScheme<'tcx> {
     let cstore = &tcx.sess.cstore;
@@ -391,7 +388,7 @@ pub fn is_staged_api(cstore: &cstore::CStore, def: ast::DefId) -> bool {
     let cdata = cstore.get_crate_data(def.krate);
     let attrs = decoder::get_crate_attributes(cdata.data());
     for attr in &attrs {
-        if &attr.name()[] == "staged_api" {
+        if &attr.name()[..] == "staged_api" {
             match attr.node.value.node { ast::MetaWord(_) => return true, _ => (/*pass*/) }
         }
     }
@@ -410,3 +407,12 @@ pub fn is_associated_type(cstore: &cstore::CStore, def: ast::DefId) -> bool {
     decoder::is_associated_type(&*cdata, def.node)
 }
 
+pub fn is_defaulted_trait(cstore: &cstore::CStore, trait_def_id: ast::DefId) -> bool {
+    let cdata = cstore.get_crate_data(trait_def_id.krate);
+    decoder::is_defaulted_trait(&*cdata, trait_def_id.node)
+}
+
+pub fn is_default_impl(cstore: &cstore::CStore, impl_did: ast::DefId) -> bool {
+    let cdata = cstore.get_crate_data(impl_did.krate);
+    decoder::is_default_impl(&*cdata, impl_did.node)
+}
index a3f7d57da67486b39a976a8289743612960ef5b4..811aa21a0b7b986ce8888cf73b83ad0ed2a25184 100644 (file)
@@ -25,9 +25,10 @@ use util::nodemap::{FnvHashMap, NodeMap};
 
 use std::cell::RefCell;
 use std::rc::Rc;
+use std::path::PathBuf;
 use flate::Bytes;
 use syntax::ast;
-use syntax::codemap::Span;
+use syntax::codemap;
 use syntax::parse::token::IdentInterner;
 
 // A map from external crate numbers (as decoded from some crate file) to
@@ -41,12 +42,24 @@ pub enum MetadataBlob {
     MetadataArchive(loader::ArchiveMetadata),
 }
 
+/// Holds information about a codemap::FileMap imported from another crate.
+/// See creader::import_codemap() for more information.
+pub struct ImportedFileMap {
+    /// This FileMap's byte-offset within the codemap of its original crate
+    pub original_start_pos: codemap::BytePos,
+    /// The end of this FileMap within the codemap of its original crate
+    pub original_end_pos: codemap::BytePos,
+    /// The imported FileMap's representation within the local codemap
+    pub translated_filemap: Rc<codemap::FileMap>
+}
+
 pub struct crate_metadata {
     pub name: String,
     pub data: MetadataBlob,
     pub cnum_map: cnum_map,
     pub cnum: ast::CrateNum,
-    pub span: Span,
+    pub codemap_import_info: Vec<ImportedFileMap>,
+    pub span: codemap::Span,
 }
 
 #[derive(Copy, Debug, PartialEq, Clone)]
@@ -66,8 +79,8 @@ pub enum NativeLibraryKind {
 // must be non-None.
 #[derive(PartialEq, Clone)]
 pub struct CrateSource {
-    pub dylib: Option<(Path, PathKind)>,
-    pub rlib: Option<(Path, PathKind)>,
+    pub dylib: Option<(PathBuf, PathKind)>,
+    pub rlib: Option<(PathBuf, PathKind)>,
     pub cnum: ast::CrateNum,
 }
 
@@ -98,7 +111,7 @@ impl CStore {
     }
 
     pub fn get_crate_data(&self, cnum: ast::CrateNum) -> Rc<crate_metadata> {
-        (*self.metas.borrow())[cnum].clone()
+        self.metas.borrow().get(&cnum).unwrap().clone()
     }
 
     pub fn get_crate_hash(&self, cnum: ast::CrateNum) -> Svh {
@@ -160,7 +173,7 @@ impl CStore {
     // topological sort of all crates putting the leaves at the right-most
     // positions.
     pub fn get_used_crates(&self, prefer: LinkagePreference)
-                           -> Vec<(ast::CrateNum, Option<Path>)> {
+                           -> Vec<(ast::CrateNum, Option<PathBuf>)> {
         let mut ordering = Vec::new();
         fn visit(cstore: &CStore, cnum: ast::CrateNum,
                  ordering: &mut Vec<ast::CrateNum>) {
@@ -230,7 +243,7 @@ impl crate_metadata {
 impl MetadataBlob {
     pub fn as_slice<'a>(&'a self) -> &'a [u8] {
         let slice = match *self {
-            MetadataVec(ref vec) => vec.as_slice(),
+            MetadataVec(ref vec) => &vec[..],
             MetadataArchive(ref ar) => ar.as_slice(),
         };
         if slice.len() < 4 {
@@ -239,7 +252,7 @@ impl MetadataBlob {
             let len = (((slice[0] as u32) << 24) |
                        ((slice[1] as u32) << 16) |
                        ((slice[2] as u32) << 8) |
-                       ((slice[3] as u32) << 0)) as uint;
+                       ((slice[3] as u32) << 0)) as usize;
             if len + 4 <= slice.len() {
                 &slice[4.. len + 4]
             } else {
index e5576de6e842442c0de92fc94f2b2c630b08eaca..92810b407f039dde41f2dc16ee97e6878585ed43 100644 (file)
@@ -22,9 +22,8 @@ use metadata::csearch::MethodInfo;
 use metadata::csearch;
 use metadata::cstore;
 use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id,
-                         parse_type_param_def_data, parse_bounds_data,
-                         parse_bare_fn_ty_data, parse_trait_ref_data,
-                         parse_predicate_data};
+                         parse_type_param_def_data, parse_bare_fn_ty_data,
+                         parse_trait_ref_data, parse_predicate_data};
 use middle::def;
 use middle::lang_items;
 use middle::subst;
@@ -34,10 +33,11 @@ use middle::astencode::vtable_decoder_helpers;
 
 use std::collections::HashMap;
 use std::hash::{self, Hash, SipHasher};
-use std::old_io::extensions::u64_from_be_bytes;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
 use std::num::FromPrimitive;
 use std::rc::Rc;
+use std::slice::bytes;
 use std::str;
 
 use rbml::reader;
@@ -60,20 +60,26 @@ pub type Cmd<'a> = &'a crate_metadata;
 // what crate that's in and give us a def_id that makes sense for the current
 // build.
 
+fn u32_from_be_bytes(bytes: &[u8]) -> u32 {
+    let mut b = [0; 4];
+    bytes::copy_memory(&bytes[..4], &mut b);
+    unsafe { (*(b.as_ptr() as *const u32)).to_be() }
+}
+
 fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option<rbml::Doc<'a>> where
     F: FnMut(&[u8]) -> bool,
 {
     let index = reader::get_doc(d, tag_index);
     let table = reader::get_doc(index, tag_index_table);
-    let hash_pos = table.start + (hash % 256 * 4) as uint;
-    let pos = u64_from_be_bytes(d.data, hash_pos, 4) as uint;
+    let hash_pos = table.start + (hash % 256 * 4) as usize;
+    let pos = u32_from_be_bytes(&d.data[hash_pos..]) as usize;
     let tagged_doc = reader::doc_at(d.data, pos).unwrap();
 
     let belt = tag_index_buckets_bucket_elt;
 
     let mut ret = None;
     reader::tagged_docs(tagged_doc.doc, belt, |elt| {
-        let pos = u64_from_be_bytes(elt.data, elt.start, 4) as uint;
+        let pos = u32_from_be_bytes(&elt.data[elt.start..]) as usize;
         if eq_fn(&elt.data[elt.start + 4 .. elt.end]) {
             ret = Some(reader::doc_at(d.data, pos).unwrap().doc);
             false
@@ -87,9 +93,7 @@ fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option<rbml:
 pub fn maybe_find_item<'a>(item_id: ast::NodeId,
                            items: rbml::Doc<'a>) -> Option<rbml::Doc<'a>> {
     fn eq_item(bytes: &[u8], item_id: ast::NodeId) -> bool {
-        return u64_from_be_bytes(
-            &bytes[0..4], 0, 4) as ast::NodeId
-            == item_id;
+        u32_from_be_bytes(bytes) == item_id
     }
     lookup_hash(items,
                 |a| eq_item(a, item_id),
@@ -119,13 +123,13 @@ enum Family {
     StaticMethod,          // F
     Method,                // h
     Type,                  // y
-    ForeignType,           // T
     Mod,                   // m
     ForeignMod,            // n
     Enum,                  // t
     TupleVariant,          // v
     StructVariant,         // V
     Impl,                  // i
+    DefaultImpl,              // d
     Trait,                 // I
     Struct,                // S
     PublicField,           // g
@@ -144,13 +148,13 @@ fn item_family(item: rbml::Doc) -> Family {
       'F' => StaticMethod,
       'h' => Method,
       'y' => Type,
-      'T' => ForeignType,
       'm' => Mod,
       'n' => ForeignMod,
       't' => Enum,
       'v' => TupleVariant,
       'V' => StructVariant,
       'i' => Impl,
+      'd' => DefaultImpl,
       'I' => Trait,
       'S' => Struct,
       'g' => PublicField,
@@ -172,16 +176,13 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
     }
 }
 
-fn item_sort(item: rbml::Doc) -> char {
+fn item_sort(item: rbml::Doc) -> Option<char> {
     let mut ret = None;
     reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
         ret = Some(doc.as_str_slice().as_bytes()[0] as char);
         false
     });
-    match ret {
-        Some(r) => r,
-        None => panic!("No item_sort found")
-    }
+    ret
 }
 
 fn item_symbol(item: rbml::Doc) -> String {
@@ -258,18 +259,6 @@ fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
     doc_trait_ref(tp, tcx, cdata)
 }
 
-fn doc_bounds<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
-                    -> ty::ParamBounds<'tcx> {
-    parse_bounds_data(doc.data, cdata.cnum, doc.start, tcx,
-                      |_, did| translate_def_id(cdata, did))
-}
-
-fn trait_def_bounds<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
-                          -> ty::ParamBounds<'tcx> {
-    let d = reader::get_doc(doc, tag_trait_def_bounds);
-    doc_bounds(d, tcx, cdata)
-}
-
 fn enum_variant_ids(item: rbml::Doc, cdata: Cmd) -> Vec<ast::DefId> {
     let mut ids: Vec<ast::DefId> = Vec::new();
     let v = tag_items_data_item_variant;
@@ -285,7 +274,7 @@ fn item_path(item_doc: rbml::Doc) -> Vec<ast_map::PathElem> {
     let path_doc = reader::get_doc(item_doc, tag_path);
 
     let len_doc = reader::get_doc(path_doc, tag_path_len);
-    let len = reader::doc_as_u32(len_doc) as uint;
+    let len = reader::doc_as_u32(len_doc) as usize;
 
     let mut result = Vec::with_capacity(len);
     reader::docs(path_doc, |tag, elt_doc| {
@@ -337,14 +326,16 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
                 def::FromImpl(item_reqd_and_translated_parent_item(cnum,
                                                                    item))
             };
-            match fam {
-                // We don't bother to get encode/decode the trait id, we don't need it.
-                Method => DlDef(def::DefMethod(did, None, provenance)),
-                StaticMethod => DlDef(def::DefStaticMethod(did, provenance)),
-                _ => panic!()
+            DlDef(def::DefMethod(did, provenance))
+        }
+        Type => {
+            if item_sort(item) == Some('t') {
+                let trait_did = item_reqd_and_translated_parent_item(cnum, item);
+                DlDef(def::DefAssociatedTy(trait_did, did))
+            } else {
+                DlDef(def::DefTy(did, false))
             }
         }
-        Type | ForeignType => DlDef(def::DefTy(did, false)),
         Mod => DlDef(def::DefMod(did)),
         ForeignMod => DlDef(def::DefForeignMod(did)),
         StructVariant => {
@@ -357,7 +348,7 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
         }
         Trait => DlDef(def::DefTrait(did)),
         Enum => DlDef(def::DefTy(did, true)),
-        Impl => DlImpl(did),
+        Impl | DefaultImpl => DlImpl(did),
         PublicField | InheritedField => DlField,
     }
 }
@@ -402,7 +393,6 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
 {
     let item_doc = lookup_item(item_id, cdata.data());
     let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
-    let bounds = trait_def_bounds(item_doc, tcx, cdata);
     let unsafety = parse_unsafety(item_doc);
     let associated_type_names = parse_associated_type_names(item_doc);
     let paren_sugar = parse_paren_sugar(item_doc);
@@ -411,7 +401,6 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
         paren_sugar: paren_sugar,
         unsafety: unsafety,
         generics: generics,
-        bounds: bounds,
         trait_ref: item_trait_ref(item_doc, tcx, cdata),
         associated_type_names: associated_type_names,
     }
@@ -426,6 +415,15 @@ pub fn get_predicates<'tcx>(cdata: Cmd,
     doc_predicates(item_doc, tcx, cdata, tag_item_generics)
 }
 
+pub fn get_super_predicates<'tcx>(cdata: Cmd,
+                                  item_id: ast::NodeId,
+                                  tcx: &ty::ctxt<'tcx>)
+                                  -> ty::GenericPredicates<'tcx>
+{
+    let item_doc = lookup_item(item_id, cdata.data());
+    doc_predicates(item_doc, tcx, cdata, tag_item_super_predicates)
+}
+
 pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
                       -> ty::TypeScheme<'tcx>
 {
@@ -480,7 +478,7 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd,
     let item_doc = lookup_item(id, cdata.data());
     let fam = item_family(item_doc);
     match fam {
-        Family::Impl => {
+        Family::Impl | Family::DefaultImpl => {
             reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
                 doc_trait_ref(tp, tcx, cdata)
             })
@@ -515,13 +513,13 @@ pub enum DefLike {
 
 /// Iterates over the language items in the given crate.
 pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
-    F: FnMut(ast::NodeId, uint) -> bool,
+    F: FnMut(ast::NodeId, usize) -> bool,
 {
     let root = rbml::Doc::new(cdata.data());
     let lang_items = reader::get_doc(root, tag_lang_items);
     reader::tagged_docs(lang_items, tag_lang_items_item, |item_doc| {
         let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
-        let id = reader::doc_as_u32(id_doc) as uint;
+        let id = reader::doc_as_u32(id_doc) as usize;
         let node_id_doc = reader::get_doc(item_doc,
                                           tag_lang_items_item_node_id);
         let node_id = reader::doc_as_u32(node_id_doc) as ast::NodeId;
@@ -779,7 +777,7 @@ pub fn get_enum_variants<'tcx>(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::Nod
             _         => { /* empty */ }
         }
         let old_disr_val = disr_val;
-        disr_val += 1;
+        disr_val = disr_val.wrapping_add(1);
         Rc::new(ty::VariantInfo {
             args: arg_tys,
             arg_names: arg_names,
@@ -829,8 +827,10 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
                         tag_item_impl_item, |doc| {
         let def_id = item_def_id(doc, cdata);
         match item_sort(doc) {
-            'r' | 'p' => impl_items.push(ty::MethodTraitItemId(def_id)),
-            't' => impl_items.push(ty::TypeTraitItemId(def_id)),
+            Some('r') | Some('p') => {
+                impl_items.push(ty::MethodTraitItemId(def_id))
+            }
+            Some('t') => impl_items.push(ty::TypeTraitItemId(def_id)),
             _ => panic!("unknown impl item sort"),
         }
         true
@@ -847,22 +847,13 @@ pub fn get_trait_name(intr: Rc<IdentInterner>,
     item_name(&*intr, doc)
 }
 
-pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
-                                    cdata: Cmd,
-                                    id: ast::NodeId)
-                                    -> (ast::Name, def::TraitItemKind) {
+pub fn is_static_method(cdata: Cmd, id: ast::NodeId) -> bool {
     let doc = lookup_item(id, cdata.data());
-    let name = item_name(&*intr, doc);
     match item_sort(doc) {
-        'r' | 'p' => {
-            let explicit_self = get_explicit_self(doc);
-            (name, def::TraitItemKind::from_explicit_self_category(explicit_self))
-        }
-        't' => (name, def::TypeTraitItemKind),
-        c => {
-            panic!("get_trait_item_name_and_kind(): unknown trait item kind \
-                   in metadata: `{}`", c)
+        Some('r') | Some('p') => {
+            get_explicit_self(doc) == ty::StaticExplicitSelfCategory
         }
+        _ => false
     }
 }
 
@@ -887,7 +878,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
     let vis = item_visibility(method_doc);
 
     match item_sort(method_doc) {
-        'r' | 'p' => {
+        Some('r') | Some('p') => {
             let generics = doc_generics(method_doc, tcx, cdata, tag_method_ty_generics);
             let predicates = doc_predicates(method_doc, tcx, cdata, tag_method_ty_generics);
             let fty = doc_method_fty(method_doc, tcx, cdata);
@@ -904,7 +895,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
                                                         container,
                                                         provided_source)))
         }
-        't' => {
+        Some('t') => {
             ty::TypeTraitItem(Rc::new(ty::AssociatedType {
                 name: name,
                 vis: vis,
@@ -924,8 +915,10 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
     reader::tagged_docs(item, tag_item_trait_item, |mth| {
         let def_id = item_def_id(mth, cdata);
         match item_sort(mth) {
-            'r' | 'p' => result.push(ty::MethodTraitItemId(def_id)),
-            't' => result.push(ty::TypeTraitItemId(def_id)),
+            Some('r') | Some('p') => {
+                result.push(ty::MethodTraitItemId(def_id));
+            }
+            Some('t') => result.push(ty::TypeTraitItemId(def_id)),
             _ => panic!("unknown trait item sort"),
         }
         true
@@ -954,7 +947,7 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
         let did = item_def_id(mth_id, cdata);
         let mth = lookup_item(did.node, data);
 
-        if item_sort(mth) == 'p' {
+        if item_sort(mth) == Some('p') {
             let trait_item = get_impl_or_trait_item(intr.clone(),
                                                     cdata,
                                                     did.node,
@@ -972,24 +965,6 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
     return result;
 }
 
-/// Returns the supertraits of the given trait.
-pub fn get_supertraits<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
-                             -> Vec<Rc<ty::TraitRef<'tcx>>> {
-    let mut results = Vec::new();
-    let item_doc = lookup_item(id, cdata.data());
-    reader::tagged_docs(item_doc, tag_item_super_trait_ref, |trait_doc| {
-        // NB. Only reads the ones that *aren't* builtin-bounds. See also
-        // get_trait_def() for collecting the builtin bounds.
-        // FIXME(#8559): The builtin bounds shouldn't be encoded in the first place.
-        let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
-        if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_none() {
-            results.push(trait_ref);
-        }
-        true
-    });
-    return results;
-}
-
 pub fn get_type_name_if_impl(cdata: Cmd,
                              node_id: ast::NodeId) -> Option<ast::Name> {
     let item = lookup_item(node_id, cdata.data());
@@ -1192,7 +1167,7 @@ fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
 }
 
 fn list_crate_attributes(md: rbml::Doc, hash: &Svh,
-                         out: &mut old_io::Writer) -> old_io::IoResult<()> {
+                         out: &mut io::Write) -> io::Result<()> {
     try!(write!(out, "=Crate Attributes ({})=\n", *hash));
 
     let r = get_attributes(md);
@@ -1219,13 +1194,13 @@ pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> {
     let cratedoc = rbml::Doc::new(data);
     let depsdoc = reader::get_doc(cratedoc, tag_crate_deps);
     let mut crate_num = 1;
-    fn docstr(doc: rbml::Doc, tag_: uint) -> String {
+    fn docstr(doc: rbml::Doc, tag_: usize) -> String {
         let d = reader::get_doc(doc, tag_);
         d.as_str_slice().to_string()
     }
     reader::tagged_docs(depsdoc, tag_crate_dep, |depdoc| {
         let name = docstr(depdoc, tag_crate_dep_crate_name);
-        let hash = Svh::new(&docstr(depdoc, tag_crate_dep_hash)[]);
+        let hash = Svh::new(&docstr(depdoc, tag_crate_dep_hash));
         deps.push(CrateDep {
             cnum: crate_num,
             name: name,
@@ -1237,7 +1212,7 @@ pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> {
     return deps;
 }
 
-fn list_crate_deps(data: &[u8], out: &mut old_io::Writer) -> old_io::IoResult<()> {
+fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> {
     try!(write!(out, "=External Dependencies=\n"));
     for dep in &get_crate_deps(data) {
         try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash));
@@ -1276,7 +1251,7 @@ pub fn get_crate_name(data: &[u8]) -> String {
     maybe_get_crate_name(data).expect("no crate name in crate")
 }
 
-pub fn list_crate_metadata(bytes: &[u8], out: &mut old_io::Writer) -> old_io::IoResult<()> {
+pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()> {
     let hash = get_crate_hash(bytes);
     let md = rbml::Doc::new(bytes);
     try!(list_crate_attributes(md, &hash, out));
@@ -1356,7 +1331,7 @@ pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
     let parent_item_doc = lookup_item(parent_item_id.node, cdata.data());
     match item_family(parent_item_doc) {
         Trait => Some(item_def_id(parent_item_doc, cdata)),
-        Impl => {
+        Impl | DefaultImpl => {
             reader::maybe_get_doc(parent_item_doc, tag_item_trait_ref)
                 .map(|_| item_trait_ref(parent_item_doc, tcx, cdata).def_id)
         }
@@ -1479,7 +1454,7 @@ pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool {
 fn doc_generics<'tcx>(base_doc: rbml::Doc,
                       tcx: &ty::ctxt<'tcx>,
                       cdata: Cmd,
-                      tag: uint)
+                      tag: usize)
                       -> ty::Generics<'tcx>
 {
     let doc = reader::get_doc(base_doc, tag);
@@ -1504,7 +1479,7 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
         let def_id = translate_def_id(cdata, def_id);
 
         let doc = reader::get_doc(rp_doc, tag_region_param_def_space);
-        let space = subst::ParamSpace::from_uint(reader::doc_as_u64(doc) as uint);
+        let space = subst::ParamSpace::from_uint(reader::doc_as_u64(doc) as usize);
 
         let doc = reader::get_doc(rp_doc, tag_region_param_def_index);
         let index = reader::doc_as_u64(doc) as u32;
@@ -1533,7 +1508,7 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
 fn doc_predicates<'tcx>(base_doc: rbml::Doc,
                         tcx: &ty::ctxt<'tcx>,
                         cdata: Cmd,
-                        tag: uint)
+                        tag: usize)
                         -> ty::GenericPredicates<'tcx>
 {
     let doc = reader::get_doc(base_doc, tag);
@@ -1541,7 +1516,7 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc,
     let mut predicates = subst::VecPerParamSpace::empty();
     reader::tagged_docs(doc, tag_predicate, |predicate_doc| {
         let space_doc = reader::get_doc(predicate_doc, tag_predicate_space);
-        let space = subst::ParamSpace::from_uint(reader::doc_as_u8(space_doc) as uint);
+        let space = subst::ParamSpace::from_uint(reader::doc_as_u8(space_doc) as usize);
 
         let data_doc = reader::get_doc(predicate_doc, tag_predicate_data);
         let data = parse_predicate_data(data_doc.data, data_doc.start, cdata.cnum, tcx,
@@ -1558,6 +1533,34 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
     let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
     match maybe_find_item(id, items) {
         None => false,
-        Some(item) => item_sort(item) == 't',
+        Some(item) => item_sort(item) == Some('t'),
     }
 }
+
+pub fn is_defaulted_trait(cdata: Cmd, trait_id: ast::NodeId) -> bool {
+    let trait_doc = lookup_item(trait_id, cdata.data());
+    assert!(item_family(trait_doc) == Family::Trait);
+    let defaulted_doc = reader::get_doc(trait_doc, tag_defaulted_trait);
+    reader::doc_as_u8(defaulted_doc) != 0
+}
+
+pub fn is_default_impl(cdata: Cmd, impl_id: ast::NodeId) -> bool {
+    let impl_doc = lookup_item(impl_id, cdata.data());
+    item_family(impl_doc) == Family::DefaultImpl
+}
+
+pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
+    let crate_doc = rbml::Doc::new(metadata);
+    let cm_doc = reader::get_doc(crate_doc, tag_codemap);
+
+    let mut filemaps = vec![];
+
+    reader::tagged_docs(cm_doc, tag_codemap_filemap, |filemap_doc| {
+        let mut decoder = reader::Decoder::new(filemap_doc);
+        let filemap: codemap::FileMap = Decodable::decode(&mut decoder).unwrap();
+        filemaps.push(filemap);
+        true
+    });
+
+    return filemaps;
+}
index 42a70cec5dfee08903c604b672a124e0e4aef4da..862ced78c082c5056322e6ec8db9e6f4c2777e9f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -22,7 +22,7 @@ use metadata::cstore;
 use metadata::decoder;
 use metadata::tyencode;
 use middle::def;
-use middle::ty::{lookup_item_type};
+use middle::ty::lookup_item_type;
 use middle::ty::{self, Ty};
 use middle::stability;
 use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
@@ -30,10 +30,11 @@ use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
 use serialize::Encodable;
 use std::cell::RefCell;
 use std::hash::{Hash, Hasher, SipHasher};
+use std::io::prelude::*;
+use std::io::{Cursor, SeekFrom};
 use syntax::abi;
 use syntax::ast::{self, DefId, NodeId};
-use syntax::ast_map::{PathElem, PathElems};
-use syntax::ast_map;
+use syntax::ast_map::{self, LinkedPath, PathElem, PathElems};
 use syntax::ast_util::*;
 use syntax::ast_util;
 use syntax::attr;
@@ -46,8 +47,7 @@ use syntax::ptr::P;
 use syntax::visit::Visitor;
 use syntax::visit;
 use syntax;
-use rbml::writer;
-use rbml::io::SeekableMemWriter;
+use rbml::writer::Encoder;
 
 /// A borrowed version of `ast::InlinedItem`.
 pub enum InlinedItemRef<'a> {
@@ -57,8 +57,6 @@ pub enum InlinedItemRef<'a> {
     IIForeignRef(&'a ast::ForeignItem)
 }
 
-pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
-
 pub type EncodeInlinedItem<'a> =
     Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>;
 
@@ -94,7 +92,7 @@ fn encode_impl_type_basename(rbml_w: &mut Encoder, name: ast::Ident) {
 }
 
 pub fn encode_def_id(rbml_w: &mut Encoder, id: DefId) {
-    rbml_w.wr_tagged_str(tag_def_id, &def_to_string(id)[]);
+    rbml_w.wr_tagged_str(tag_def_id, &def_to_string(id));
 }
 
 #[derive(Clone)]
@@ -106,7 +104,7 @@ struct entry<T> {
 fn encode_trait_ref<'a, 'tcx>(rbml_w: &mut Encoder,
                               ecx: &EncodeContext<'a, 'tcx>,
                               trait_ref: &ty::TraitRef<'tcx>,
-                              tag: uint) {
+                              tag: usize) {
     let ty_str_ctxt = &tyencode::ctxt {
         diag: ecx.diag,
         ds: def_to_string,
@@ -115,15 +113,13 @@ fn encode_trait_ref<'a, 'tcx>(rbml_w: &mut Encoder,
     };
 
     rbml_w.start_tag(tag);
-    tyencode::enc_trait_ref(rbml_w.writer, ty_str_ctxt, trait_ref);
+    tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref);
     rbml_w.end_tag();
 }
 
 // Item info table encoding
 fn encode_family(rbml_w: &mut Encoder, c: char) {
-    rbml_w.start_tag(tag_items_data_item_family);
-    rbml_w.writer.write_all(&[c as u8]);
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_u8(tag_items_data_item_family, c as u8);
 }
 
 pub fn def_to_string(did: DefId) -> String {
@@ -157,14 +153,9 @@ fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder,
 }
 
 fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) {
-    rbml_w.start_tag(tag_items_data_item_variant);
     let s = def_to_string(vid);
-    rbml_w.writer.write_all(s.as_bytes());
-    rbml_w.end_tag();
-
-    rbml_w.start_tag(tag_mod_child);
-    rbml_w.wr_str(&s[..]);
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_str(tag_items_data_item_variant, &s[..]);
+    rbml_w.wr_tagged_str(tag_mod_child, &s[..]);
 }
 
 pub fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
@@ -176,7 +167,7 @@ pub fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
-    tyencode::enc_closure_ty(rbml_w.writer, ty_str_ctxt, closure_type);
+    tyencode::enc_closure_ty(rbml_w, ty_str_ctxt, closure_type);
 }
 
 pub fn write_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
@@ -188,7 +179,7 @@ pub fn write_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
-    tyencode::enc_ty(rbml_w.writer, ty_str_ctxt, typ);
+    tyencode::enc_ty(rbml_w, ty_str_ctxt, typ);
 }
 
 pub fn write_trait_ref<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
@@ -200,7 +191,7 @@ pub fn write_trait_ref<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
-    tyencode::enc_trait_ref(rbml_w.writer, ty_str_ctxt, trait_ref);
+    tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref);
 }
 
 pub fn write_region(ecx: &EncodeContext,
@@ -212,22 +203,7 @@ pub fn write_region(ecx: &EncodeContext,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
-    tyencode::enc_region(rbml_w.writer, ty_str_ctxt, r);
-}
-
-fn encode_bounds<'a, 'tcx>(rbml_w: &mut Encoder,
-                           ecx: &EncodeContext<'a, 'tcx>,
-                           bounds: &ty::ParamBounds<'tcx>,
-                           tag: uint) {
-    rbml_w.start_tag(tag);
-
-    let ty_str_ctxt = &tyencode::ctxt { diag: ecx.diag,
-                                        ds: def_to_string,
-                                        tcx: ecx.tcx,
-                                        abbrevs: &ecx.type_abbrevs };
-    tyencode::enc_bounds(rbml_w.writer, ty_str_ctxt, bounds);
-
-    rbml_w.end_tag();
+    tyencode::enc_region(rbml_w, ty_str_ctxt, r);
 }
 
 fn encode_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
@@ -257,7 +233,7 @@ fn encode_method_fty<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
-    tyencode::enc_bare_fn_ty(rbml_w.writer, ty_str_ctxt, typ);
+    tyencode::enc_bare_fn_ty(rbml_w, ty_str_ctxt, typ);
 
     rbml_w.end_tag();
 }
@@ -265,34 +241,26 @@ fn encode_method_fty<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
 fn encode_symbol(ecx: &EncodeContext,
                  rbml_w: &mut Encoder,
                  id: NodeId) {
-    rbml_w.start_tag(tag_items_data_item_symbol);
     match ecx.item_symbols.borrow().get(&id) {
         Some(x) => {
             debug!("encode_symbol(id={}, str={})", id, *x);
-            rbml_w.writer.write_all(x.as_bytes());
+            rbml_w.wr_tagged_str(tag_items_data_item_symbol, x);
         }
         None => {
             ecx.diag.handler().bug(
-                &format!("encode_symbol: id not found {}", id)[]);
+                &format!("encode_symbol: id not found {}", id));
         }
     }
-    rbml_w.end_tag();
 }
 
 fn encode_disr_val(_: &EncodeContext,
                    rbml_w: &mut Encoder,
                    disr_val: ty::Disr) {
-    rbml_w.start_tag(tag_disr_val);
-    let s = disr_val.to_string();
-    rbml_w.writer.write_all(s.as_bytes());
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_str(tag_disr_val, &disr_val.to_string());
 }
 
 fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) {
-    rbml_w.start_tag(tag_items_data_parent_item);
-    let s = def_to_string(id);
-    rbml_w.writer.write_all(s.as_bytes());
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_str(tag_items_data_parent_item, &def_to_string(id));
 }
 
 fn encode_struct_fields(rbml_w: &mut Encoder,
@@ -307,10 +275,7 @@ fn encode_struct_fields(rbml_w: &mut Encoder,
         }
         encode_struct_field_family(rbml_w, f.vis);
         encode_def_id(rbml_w, f.id);
-        rbml_w.start_tag(tag_item_field_origin);
-        let s = def_to_string(origin);
-        rbml_w.writer.write_all(s.as_bytes());
-        rbml_w.end_tag();
+        rbml_w.wr_tagged_str(tag_item_field_origin, &def_to_string(origin));
         rbml_w.end_tag();
     }
 }
@@ -330,7 +295,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
         let def_id = local_def(variant.node.id);
         index.push(entry {
             val: variant.node.id as i64,
-            pos: rbml_w.writer.tell().unwrap(),
+            pos: rbml_w.mark_stable_position(),
         });
         rbml_w.start_tag(tag_items_data_item);
         encode_def_id(rbml_w, def_id);
@@ -341,8 +306,8 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
         encode_name(rbml_w, variant.node.name.name);
         encode_parent_item(rbml_w, local_def(id));
         encode_visibility(rbml_w, variant.node.vis);
-        encode_attributes(rbml_w, &variant.node.attrs[]);
-        encode_repr_attrs(rbml_w, ecx, &variant.node.attrs[]);
+        encode_attributes(rbml_w, &variant.node.attrs);
+        encode_repr_attrs(rbml_w, ecx, &variant.node.attrs);
 
         let stab = stability::lookup(ecx.tcx, ast_util::local_def(variant.node.id));
         encode_stability(rbml_w, stab);
@@ -367,7 +332,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
 
         ecx.tcx.map.with_path(variant.node.id, |path| encode_path(rbml_w, path));
         rbml_w.end_tag();
-        disr_val += 1;
+        disr_val = disr_val.wrapping_add(1);
         i += 1;
     }
 }
@@ -393,14 +358,11 @@ fn encode_reexported_static_method(rbml_w: &mut Encoder,
     debug!("(encode reexported static method) {}::{}",
             exp.name, token::get_name(method_name));
     rbml_w.start_tag(tag_items_data_item_reexport);
-    rbml_w.start_tag(tag_items_data_item_reexport_def_id);
-    rbml_w.wr_str(&def_to_string(method_def_id)[]);
-    rbml_w.end_tag();
-    rbml_w.start_tag(tag_items_data_item_reexport_name);
-    rbml_w.wr_str(&format!("{}::{}",
-                          exp.name,
-                          token::get_name(method_name))[]);
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_str(tag_items_data_item_reexport_def_id,
+                         &def_to_string(method_def_id));
+    rbml_w.wr_tagged_str(tag_items_data_item_reexport_name,
+                         &format!("{}::{}", exp.name,
+                                            token::get_name(method_name)));
     rbml_w.end_tag();
 }
 
@@ -412,7 +374,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
     match ecx.tcx.inherent_impls.borrow().get(&exp.def_id) {
         Some(implementations) => {
             for base_impl_did in &**implementations {
-                for &method_did in &*(*impl_items)[*base_impl_did] {
+                for &method_did in impl_items.get(base_impl_did).unwrap() {
                     let impl_item = ty::impl_or_trait_item(
                         ecx.tcx,
                         method_did.def_id());
@@ -536,12 +498,10 @@ fn encode_reexports(ecx: &EncodeContext,
                        exp.def_id.node,
                        id);
                 rbml_w.start_tag(tag_items_data_item_reexport);
-                rbml_w.start_tag(tag_items_data_item_reexport_def_id);
-                rbml_w.wr_str(&def_to_string(exp.def_id)[]);
-                rbml_w.end_tag();
-                rbml_w.start_tag(tag_items_data_item_reexport_name);
-                rbml_w.wr_str(exp.name.as_str());
-                rbml_w.end_tag();
+                rbml_w.wr_tagged_str(tag_items_data_item_reexport_def_id,
+                                     &def_to_string(exp.def_id));
+                rbml_w.wr_tagged_str(tag_items_data_item_reexport_name,
+                                     exp.name.as_str());
                 rbml_w.end_tag();
                 encode_reexported_static_methods(ecx, rbml_w, path.clone(), exp);
             }
@@ -569,15 +529,12 @@ fn encode_info_for_mod(ecx: &EncodeContext,
 
     // Encode info about all the module children.
     for item in &md.items {
-        rbml_w.start_tag(tag_mod_child);
-        rbml_w.wr_str(&def_to_string(local_def(item.id))[]);
-        rbml_w.end_tag();
+        rbml_w.wr_tagged_str(tag_mod_child,
+                             &def_to_string(local_def(item.id)));
 
         each_auxiliary_node_id(&**item, |auxiliary_node_id| {
-            rbml_w.start_tag(tag_mod_child);
-            rbml_w.wr_str(&def_to_string(local_def(
-                        auxiliary_node_id))[]);
-            rbml_w.end_tag();
+            rbml_w.wr_tagged_str(tag_mod_child,
+                                 &def_to_string(local_def(auxiliary_node_id)));
             true
         });
 
@@ -587,9 +544,8 @@ fn encode_info_for_mod(ecx: &EncodeContext,
                    token::get_ident(ident),
                    did, ecx.tcx.map.node_to_string(did));
 
-            rbml_w.start_tag(tag_mod_impl);
-            rbml_w.wr_str(&def_to_string(local_def(did))[]);
-            rbml_w.end_tag();
+            rbml_w.wr_tagged_str(tag_mod_impl,
+                                 &def_to_string(local_def(did)));
         }
     }
 
@@ -618,67 +574,56 @@ fn encode_struct_field_family(rbml_w: &mut Encoder,
 }
 
 fn encode_visibility(rbml_w: &mut Encoder, visibility: ast::Visibility) {
-    rbml_w.start_tag(tag_items_data_item_visibility);
     let ch = match visibility {
         ast::Public => 'y',
         ast::Inherited => 'i',
     };
-    rbml_w.wr_str(&ch.to_string()[]);
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_u8(tag_items_data_item_visibility, ch as u8);
 }
 
 fn encode_explicit_self(rbml_w: &mut Encoder,
                         explicit_self: &ty::ExplicitSelfCategory) {
-    rbml_w.start_tag(tag_item_trait_method_explicit_self);
+    let tag = tag_item_trait_method_explicit_self;
 
     // Encode the base self type.
     match *explicit_self {
         ty::StaticExplicitSelfCategory => {
-            rbml_w.writer.write_all(&[ 's' as u8 ]);
+            rbml_w.wr_tagged_bytes(tag, &['s' as u8]);
         }
         ty::ByValueExplicitSelfCategory => {
-            rbml_w.writer.write_all(&[ 'v' as u8 ]);
+            rbml_w.wr_tagged_bytes(tag, &['v' as u8]);
         }
         ty::ByBoxExplicitSelfCategory => {
-            rbml_w.writer.write_all(&[ '~' as u8 ]);
+            rbml_w.wr_tagged_bytes(tag, &['~' as u8]);
         }
         ty::ByReferenceExplicitSelfCategory(_, m) => {
             // FIXME(#4846) encode custom lifetime
-            rbml_w.writer.write_all(&['&' as u8]);
-            encode_mutability(rbml_w, m);
+            let ch = encode_mutability(m);
+            rbml_w.wr_tagged_bytes(tag, &['&' as u8, ch]);
         }
     }
 
-    rbml_w.end_tag();
-
-    fn encode_mutability(rbml_w: &mut Encoder,
-                         m: ast::Mutability) {
+    fn encode_mutability(m: ast::Mutability) -> u8 {
         match m {
-            ast::MutImmutable => { rbml_w.writer.write_all(&[ 'i' as u8 ]); }
-            ast::MutMutable => { rbml_w.writer.write_all(&[ 'm' as u8 ]); }
+            ast::MutImmutable => 'i' as u8,
+            ast::MutMutable => 'm' as u8,
         }
     }
 }
 
 fn encode_item_sort(rbml_w: &mut Encoder, sort: char) {
-    rbml_w.start_tag(tag_item_trait_item_sort);
-    rbml_w.writer.write_all(&[ sort as u8 ]);
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_u8(tag_item_trait_item_sort, sort as u8);
 }
 
 fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) {
-    rbml_w.start_tag(tag_item_trait_parent_sort);
-    rbml_w.writer.write_all(&[ sort as u8 ]);
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_u8(tag_item_trait_parent_sort, sort as u8);
 }
 
 fn encode_provided_source(rbml_w: &mut Encoder,
                           source_opt: Option<DefId>) {
     if let Some(source) = source_opt {
-        rbml_w.start_tag(tag_item_method_provided_source);
-        let s = def_to_string(source);
-        rbml_w.writer.write_all(s.as_bytes());
-        rbml_w.end_tag();
+        rbml_w.wr_tagged_str(tag_item_method_provided_source,
+                             &def_to_string(source));
     }
 }
 
@@ -697,10 +642,11 @@ fn encode_info_for_struct(ecx: &EncodeContext,
         let nm = field.name;
         let id = field.id.node;
 
-        index.push(entry {val: id as i64, pos: rbml_w.writer.tell().unwrap()});
+        let pos = rbml_w.mark_stable_position();
+        index.push(entry {val: id as i64, pos: pos});
         global_index.push(entry {
             val: id as i64,
-            pos: rbml_w.writer.tell().unwrap(),
+            pos: pos,
         });
         rbml_w.start_tag(tag_items_data_item);
         debug!("encode_info_for_struct: doing {} {}",
@@ -726,7 +672,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
                                struct_id: NodeId) {
     index.push(entry {
         val: ctor_id as i64,
-        pos: rbml_w.writer.tell().unwrap(),
+        pos: rbml_w.mark_stable_position(),
     });
 
     rbml_w.start_tag(tag_items_data_item);
@@ -747,8 +693,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
     // indicate that this is a tuple struct ctor, because downstream users will normally want
     // the tuple struct definition, but without this there is no way for them to tell that
     // they actually have a ctor rather than a normal function
-    rbml_w.start_tag(tag_items_data_item_is_tuple_struct_ctor);
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]);
 
     rbml_w.end_tag();
 }
@@ -757,7 +702,7 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
                              ecx: &EncodeContext<'a, 'tcx>,
                              generics: &ty::Generics<'tcx>,
                              predicates: &ty::GenericPredicates<'tcx>,
-                             tag: uint)
+                             tag: usize)
 {
     rbml_w.start_tag(tag);
 
@@ -768,9 +713,10 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
         tcx: ecx.tcx,
         abbrevs: &ecx.type_abbrevs
     };
+
     for param in generics.types.iter() {
         rbml_w.start_tag(tag_type_param_def);
-        tyencode::enc_type_param_def(rbml_w.writer, ty_str_ctxt, param);
+        tyencode::enc_type_param_def(rbml_w, ty_str_ctxt, param);
         rbml_w.end_tag();
     }
 
@@ -783,7 +729,7 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
         rbml_w.end_tag();
 
         rbml_w.wr_tagged_str(tag_region_param_def_def_id,
-                             &def_to_string(param.def_id)[]);
+                             &def_to_string(param.def_id));
 
         rbml_w.wr_tagged_u64(tag_region_param_def_space,
                              param.space.to_uint() as u64);
@@ -798,18 +744,42 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
         rbml_w.end_tag();
     }
 
+    encode_predicates_in_current_doc(rbml_w, ecx, predicates);
+
+    rbml_w.end_tag();
+}
+
+fn encode_predicates_in_current_doc<'a,'tcx>(rbml_w: &mut Encoder,
+                                             ecx: &EncodeContext<'a,'tcx>,
+                                             predicates: &ty::GenericPredicates<'tcx>)
+{
+    let ty_str_ctxt = &tyencode::ctxt {
+        diag: ecx.diag,
+        ds: def_to_string,
+        tcx: ecx.tcx,
+        abbrevs: &ecx.type_abbrevs
+    };
+
     for (space, _, predicate) in predicates.predicates.iter_enumerated() {
         rbml_w.start_tag(tag_predicate);
 
         rbml_w.wr_tagged_u8(tag_predicate_space, space as u8);
 
         rbml_w.start_tag(tag_predicate_data);
-        tyencode::enc_predicate(rbml_w.writer, ty_str_ctxt, predicate);
+        tyencode::enc_predicate(rbml_w, ty_str_ctxt, predicate);
         rbml_w.end_tag();
 
         rbml_w.end_tag();
     }
+}
 
+fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder,
+                              ecx: &EncodeContext<'a,'tcx>,
+                              predicates: &ty::GenericPredicates<'tcx>,
+                              tag: usize)
+{
+    rbml_w.start_tag(tag);
+    encode_predicates_in_current_doc(rbml_w, ecx, predicates);
     rbml_w.end_tag();
 }
 
@@ -838,7 +808,7 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                     impl_path: PathElems,
                                     is_default_impl: bool,
                                     parent_id: NodeId,
-                                    ast_item_opt: Option<&ast::ImplItem>) {
+                                    impl_item_opt: Option<&ast::ImplItem>) {
 
     debug!("encode_info_for_method: {:?} {:?}", m.def_id,
            token::get_name(m.name));
@@ -856,21 +826,20 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
 
     let elem = ast_map::PathName(m.name);
     encode_path(rbml_w, impl_path.chain(Some(elem).into_iter()));
-    match ast_item_opt {
-        Some(&ast::MethodImplItem(ref ast_method)) => {
-            encode_attributes(rbml_w, &ast_method.attrs[]);
+    if let Some(impl_item) = impl_item_opt {
+        if let ast::MethodImplItem(ref sig, _) = impl_item.node {
+            encode_attributes(rbml_w, &impl_item.attrs);
             let scheme = ty::lookup_item_type(ecx.tcx, m.def_id);
             let any_types = !scheme.generics.types.is_empty();
-            if any_types || is_default_impl || should_inline(&ast_method.attrs[]) {
+            if any_types || is_default_impl || attr::requests_inline(&impl_item.attrs) {
                 encode_inlined_item(ecx, rbml_w, IIImplItemRef(local_def(parent_id),
-                                                               ast_item_opt.unwrap()));
+                                                               impl_item));
             }
             if !any_types {
                 encode_symbol(ecx, rbml_w, m.def_id.node);
             }
-            encode_method_argument_names(rbml_w, ast_method.pe_fn_decl());
+            encode_method_argument_names(rbml_w, &sig.decl);
         }
-        Some(_) | None => {}
     }
 
     rbml_w.end_tag();
@@ -881,7 +850,7 @@ fn encode_info_for_associated_type(ecx: &EncodeContext,
                                    associated_type: &ty::AssociatedType,
                                    impl_path: PathElems,
                                    parent_id: NodeId,
-                                   typedef_opt: Option<P<ast::Typedef>>) {
+                                   impl_item_opt: Option<&ast::ImplItem>) {
     debug!("encode_info_for_associated_type({:?},{:?})",
            associated_type.def_id,
            token::get_name(associated_type.name));
@@ -903,13 +872,9 @@ fn encode_info_for_associated_type(ecx: &EncodeContext,
     let elem = ast_map::PathName(associated_type.name);
     encode_path(rbml_w, impl_path.chain(Some(elem).into_iter()));
 
-    match typedef_opt {
-        None => {}
-        Some(typedef) => {
-            encode_attributes(rbml_w, &typedef.attrs[]);
-            encode_type(ecx, rbml_w, ty::node_id_to_type(ecx.tcx,
-                                                         typedef.id));
-        }
+    if let Some(ii) = impl_item_opt {
+        encode_attributes(rbml_w, &ii.attrs);
+        encode_type(ecx, rbml_w, ty::node_id_to_type(ecx.tcx, ii.id));
     }
 
     rbml_w.end_tag();
@@ -919,12 +884,13 @@ fn encode_method_argument_names(rbml_w: &mut Encoder,
                                 decl: &ast::FnDecl) {
     rbml_w.start_tag(tag_method_argument_names);
     for arg in &decl.inputs {
-        rbml_w.start_tag(tag_method_argument_name);
+        let tag = tag_method_argument_name;
         if let ast::PatIdent(_, ref path1, _) = arg.pat.node {
             let name = token::get_ident(path1.node);
-            rbml_w.writer.write_all(name.as_bytes());
+            rbml_w.wr_tagged_bytes(tag, name.as_bytes());
+        } else {
+            rbml_w.wr_tagged_bytes(tag, &[]);
         }
-        rbml_w.end_tag();
     }
     rbml_w.end_tag();
 }
@@ -954,14 +920,6 @@ const FN_FAMILY: char = 'f';
 const STATIC_METHOD_FAMILY: char = 'F';
 const METHOD_FAMILY: char = 'h';
 
-fn should_inline(attrs: &[ast::Attribute]) -> bool {
-    use syntax::attr::*;
-    match find_inline_attr(attrs) {
-        InlineNone | InlineNever  => false,
-        InlineHint | InlineAlways => true
-    }
-}
-
 // Encodes the inherent implementations of a structure, enumeration, or trait.
 fn encode_inherent_implementations(ecx: &EncodeContext,
                                    rbml_w: &mut Encoder,
@@ -1010,11 +968,11 @@ fn encode_info_for_item(ecx: &EncodeContext,
                         vis: ast::Visibility) {
     let tcx = ecx.tcx;
 
-    fn add_to_index(item: &ast::Item, rbml_w: &Encoder,
+    fn add_to_index(item: &ast::Item, rbml_w: &mut Encoder,
                     index: &mut Vec<entry<i64>>) {
         index.push(entry {
             val: item.id as i64,
-            pos: rbml_w.writer.tell().unwrap(),
+            pos: rbml_w.mark_stable_position(),
         });
     }
 
@@ -1040,7 +998,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_path(rbml_w, path);
         encode_visibility(rbml_w, vis);
         encode_stability(rbml_w, stab);
-        encode_attributes(rbml_w, &item.attrs[]);
+        encode_attributes(rbml_w, &item.attrs);
         rbml_w.end_tag();
       }
       ast::ItemConst(_, _) => {
@@ -1066,8 +1024,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
         encode_name(rbml_w, item.ident.name);
         encode_path(rbml_w, path);
-        encode_attributes(rbml_w, &item.attrs[]);
-        if tps_len > 0 || should_inline(&item.attrs[]) {
+        encode_attributes(rbml_w, &item.attrs);
+        if tps_len > 0 || attr::requests_inline(&item.attrs) {
             encode_inlined_item(ecx, rbml_w, IIItemRef(item));
         }
         if tps_len == 0 {
@@ -1083,7 +1041,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_info_for_mod(ecx,
                             rbml_w,
                             m,
-                            &item.attrs[],
+                            &item.attrs,
                             item.id,
                             path,
                             item.ident,
@@ -1099,9 +1057,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
 
         // Encode all the items in this module.
         for foreign_item in &fm.items {
-            rbml_w.start_tag(tag_mod_child);
-            rbml_w.wr_str(&def_to_string(local_def(foreign_item.id))[]);
-            rbml_w.end_tag();
+            rbml_w.wr_tagged_str(tag_mod_child,
+                                 &def_to_string(local_def(foreign_item.id)));
         }
         encode_visibility(rbml_w, vis);
         encode_stability(rbml_w, stab);
@@ -1128,8 +1085,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_item_variances(rbml_w, ecx, item.id);
         encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
         encode_name(rbml_w, item.ident.name);
-        encode_attributes(rbml_w, &item.attrs[]);
-        encode_repr_attrs(rbml_w, ecx, &item.attrs[]);
+        encode_attributes(rbml_w, &item.attrs);
+        encode_repr_attrs(rbml_w, ecx, &item.attrs);
         for v in &enum_definition.variants {
             encode_variant_id(rbml_w, local_def(v.node.id));
         }
@@ -1146,7 +1103,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_enum_variant_info(ecx,
                                  rbml_w,
                                  item.id,
-                                 &(*enum_definition).variants[],
+                                 &(*enum_definition).variants,
                                  index);
       }
       ast::ItemStruct(ref struct_def, _) => {
@@ -1172,11 +1129,11 @@ fn encode_info_for_item(ecx: &EncodeContext,
 
         encode_item_variances(rbml_w, ecx, item.id);
         encode_name(rbml_w, item.ident.name);
-        encode_attributes(rbml_w, &item.attrs[]);
+        encode_attributes(rbml_w, &item.attrs);
         encode_path(rbml_w, path.clone());
         encode_stability(rbml_w, stab);
         encode_visibility(rbml_w, vis);
-        encode_repr_attrs(rbml_w, ecx, &item.attrs[]);
+        encode_repr_attrs(rbml_w, ecx, &item.attrs);
 
         /* Encode def_ids for each field and method
          for methods, write all the stuff get_trait_method
@@ -1201,11 +1158,23 @@ fn encode_info_for_item(ecx: &EncodeContext,
             None => {}
         }
       }
+      ast::ItemDefaultImpl(unsafety, _) => {
+          add_to_index(item, rbml_w, index);
+          rbml_w.start_tag(tag_items_data_item);
+          encode_def_id(rbml_w, def_id);
+          encode_family(rbml_w, 'd');
+          encode_name(rbml_w, item.ident.name);
+          encode_unsafety(rbml_w, unsafety);
+
+          let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
+          encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
+          rbml_w.end_tag();
+      }
       ast::ItemImpl(unsafety, polarity, _, ref opt_trait, ref ty, ref ast_items) => {
         // We need to encode information about the default methods we
         // have inherited, so we drive this based on the impl structure.
         let impl_items = tcx.impl_items.borrow();
-        let items = &(*impl_items)[def_id];
+        let items = impl_items.get(&def_id).unwrap();
 
         add_to_index(item, rbml_w, index);
         rbml_w.start_tag(tag_items_data_item);
@@ -1213,11 +1182,11 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_family(rbml_w, 'i');
         encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
         encode_name(rbml_w, item.ident.name);
-        encode_attributes(rbml_w, &item.attrs[]);
+        encode_attributes(rbml_w, &item.attrs);
         encode_unsafety(rbml_w, unsafety);
         encode_polarity(rbml_w, polarity);
         match ty.node {
-            ast::TyPath(ref path, _) if path.segments.len() == 1 => {
+            ast::TyPath(None, ref path) if path.segments.len() == 1 => {
                 let ident = path.segments.last().unwrap().identifier;
                 encode_impl_type_basename(rbml_w, ident);
             }
@@ -1237,9 +1206,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
             }
             rbml_w.end_tag();
         }
-        if let Some(ref ast_trait_ref) = *opt_trait {
-            let trait_ref = ty::node_id_to_trait_ref(
-                tcx, ast_trait_ref.ref_id);
+        if opt_trait.is_some() {
+            let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
             encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
         }
         encode_path(rbml_w, path.clone());
@@ -1253,21 +1221,18 @@ fn encode_info_for_item(ecx: &EncodeContext,
         let num_implemented_methods = ast_items.len();
         for (i, &trait_item_def_id) in items.iter().enumerate() {
             let ast_item = if i < num_implemented_methods {
-                Some(&ast_items[i])
+                Some(&*ast_items[i])
             } else {
                 None
             };
 
             index.push(entry {
                 val: trait_item_def_id.def_id().node as i64,
-                pos: rbml_w.writer.tell().unwrap(),
+                pos: rbml_w.mark_stable_position(),
             });
 
-            let trait_item_type =
-                ty::impl_or_trait_item(tcx, trait_item_def_id.def_id());
-            match (trait_item_type, ast_item) {
-                (ty::MethodTraitItem(ref method_type),
-                 Some(&ast::MethodImplItem(_))) => {
+            match ty::impl_or_trait_item(tcx, trait_item_def_id.def_id()) {
+                ty::MethodTraitItem(ref method_type) => {
                     encode_info_for_method(ecx,
                                            rbml_w,
                                            &**method_type,
@@ -1276,31 +1241,13 @@ fn encode_info_for_item(ecx: &EncodeContext,
                                            item.id,
                                            ast_item)
                 }
-                (ty::MethodTraitItem(ref method_type), _) => {
-                    encode_info_for_method(ecx,
-                                           rbml_w,
-                                           &**method_type,
-                                           path.clone(),
-                                           false,
-                                           item.id,
-                                           None)
-                }
-                (ty::TypeTraitItem(ref associated_type),
-                 Some(&ast::TypeImplItem(ref typedef))) => {
+                ty::TypeTraitItem(ref associated_type) => {
                     encode_info_for_associated_type(ecx,
                                                     rbml_w,
                                                     &**associated_type,
                                                     path.clone(),
                                                     item.id,
-                                                    Some((*typedef).clone()))
-                }
-                (ty::TypeTraitItem(ref associated_type), _) => {
-                    encode_info_for_associated_type(ecx,
-                                                    rbml_w,
-                                                    &**associated_type,
-                                                    path.clone(),
-                                                    item.id,
-                                                    None)
+                                                    ast_item)
                 }
             }
         }
@@ -1315,11 +1262,14 @@ fn encode_info_for_item(ecx: &EncodeContext,
         let trait_predicates = ty::lookup_predicates(tcx, def_id);
         encode_unsafety(rbml_w, trait_def.unsafety);
         encode_paren_sugar(rbml_w, trait_def.paren_sugar);
+        encode_defaulted(rbml_w, ty::trait_has_default_impl(tcx, def_id));
         encode_associated_type_names(rbml_w, &trait_def.associated_type_names);
         encode_generics(rbml_w, ecx, &trait_def.generics, &trait_predicates, tag_item_generics);
+        encode_predicates(rbml_w, ecx, &ty::lookup_super_predicates(tcx, def_id),
+                          tag_item_super_predicates);
         encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
         encode_name(rbml_w, item.ident.name);
-        encode_attributes(rbml_w, &item.attrs[]);
+        encode_attributes(rbml_w, &item.attrs);
         encode_visibility(rbml_w, vis);
         encode_stability(rbml_w, stab);
         for &method_def_id in &*ty::trait_item_def_ids(tcx, def_id) {
@@ -1336,14 +1286,11 @@ fn encode_info_for_item(ecx: &EncodeContext,
             }
             rbml_w.end_tag();
 
-            rbml_w.start_tag(tag_mod_child);
-            rbml_w.wr_str(&def_to_string(method_def_id.def_id())[]);
-            rbml_w.end_tag();
+            rbml_w.wr_tagged_str(tag_mod_child,
+                                 &def_to_string(method_def_id.def_id()));
         }
         encode_path(rbml_w, path.clone());
 
-        encode_bounds(rbml_w, ecx, &trait_def.bounds, tag_trait_def_bounds);
-
         // Encode the implementations of this trait.
         encode_extension_implementations(ecx, rbml_w, def_id);
 
@@ -1359,7 +1306,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
 
             index.push(entry {
                 val: item_def_id.def_id().node as i64,
-                pos: rbml_w.writer.tell().unwrap(),
+                pos: rbml_w.mark_stable_position(),
             });
 
             rbml_w.start_tag(tag_items_data_item);
@@ -1414,35 +1361,29 @@ fn encode_info_for_item(ecx: &EncodeContext,
 
             encode_parent_sort(rbml_w, 't');
 
-            let trait_item = &ms[i];
-            let encode_trait_item = |rbml_w: &mut Encoder| {
-                // If this is a static method, we've already
-                // encoded this.
-                if is_nonstatic_method {
-                    // FIXME: I feel like there is something funny
-                    // going on.
-                    encode_bounds_and_type_for_item(rbml_w, ecx, item_def_id.def_id().local_id());
-                }
-            };
-            match trait_item {
-                &ast::RequiredMethod(ref m) => {
-                    encode_attributes(rbml_w, &m.attrs[]);
-                    encode_trait_item(rbml_w);
-                    encode_item_sort(rbml_w, 'r');
-                    encode_method_argument_names(rbml_w, &*m.decl);
-                }
+            let trait_item = &*ms[i];
+            encode_attributes(rbml_w, &trait_item.attrs);
+            match trait_item.node {
+                ast::MethodTraitItem(ref sig, ref body) => {
+                    // If this is a static method, we've already
+                    // encoded this.
+                    if is_nonstatic_method {
+                        // FIXME: I feel like there is something funny
+                        // going on.
+                        encode_bounds_and_type_for_item(rbml_w, ecx,
+                            item_def_id.def_id().local_id());
+                    }
 
-                &ast::ProvidedMethod(ref m) => {
-                    encode_attributes(rbml_w, &m.attrs[]);
-                    encode_trait_item(rbml_w);
-                    encode_item_sort(rbml_w, 'p');
-                    encode_inlined_item(ecx, rbml_w, IITraitItemRef(def_id, trait_item));
-                    encode_method_argument_names(rbml_w, &*m.pe_fn_decl());
+                    if body.is_some() {
+                        encode_item_sort(rbml_w, 'p');
+                        encode_inlined_item(ecx, rbml_w, IITraitItemRef(def_id, trait_item));
+                    } else {
+                        encode_item_sort(rbml_w, 'r');
+                    }
+                    encode_method_argument_names(rbml_w, &sig.decl);
                 }
 
-                &ast::TypeTraitItem(ref associated_type) => {
-                    encode_attributes(rbml_w,
-                                      &associated_type.attrs[]);
+                ast::TypeTraitItem(..) => {
                     encode_item_sort(rbml_w, 't');
                 }
             }
@@ -1464,7 +1405,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
                                 abi: abi::Abi) {
     index.push(entry {
         val: nitem.id as i64,
-        pos: rbml_w.writer.tell().unwrap(),
+        pos: rbml_w.mark_stable_position(),
     });
 
     rbml_w.start_tag(tag_items_data_item);
@@ -1564,14 +1505,14 @@ fn encode_info_for_items(ecx: &EncodeContext,
     rbml_w.start_tag(tag_items_data);
     index.push(entry {
         val: ast::CRATE_NODE_ID as i64,
-        pos: rbml_w.writer.tell().unwrap(),
+        pos: rbml_w.mark_stable_position(),
     });
     encode_info_for_mod(ecx,
                         rbml_w,
                         &krate.module,
                         &[],
                         ast::CRATE_NODE_ID,
-                        [].iter().cloned().chain(None),
+                        [].iter().cloned().chain(LinkedPath::empty()),
                         syntax::parse::token::special_idents::invalid,
                         ast::Public);
 
@@ -1588,57 +1529,15 @@ fn encode_info_for_items(ecx: &EncodeContext,
 
 // Path and definition ID indexing
 
-#[cfg(stage0)]
 fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn: F) where
-    F: FnMut(&mut SeekableMemWriter, &T),
-    T: Hash<SipHasher>,
-{
-    let mut buckets: Vec<Vec<entry<T>>> = (0..256u16).map(|_| Vec::new()).collect();
-    for elt in index {
-        let mut s = SipHasher::new();
-        elt.val.hash(&mut s);
-        let h = s.finish() as uint;
-        (&mut buckets[h % 256]).push(elt);
-    }
-
-    rbml_w.start_tag(tag_index);
-    let mut bucket_locs = Vec::new();
-    rbml_w.start_tag(tag_index_buckets);
-    for bucket in &buckets {
-        bucket_locs.push(rbml_w.writer.tell().unwrap());
-        rbml_w.start_tag(tag_index_buckets_bucket);
-        for elt in bucket {
-            rbml_w.start_tag(tag_index_buckets_bucket_elt);
-            assert!(elt.pos < 0xffff_ffff);
-            {
-                let wr: &mut SeekableMemWriter = rbml_w.writer;
-                wr.write_be_u32(elt.pos as u32);
-            }
-            write_fn(rbml_w.writer, &elt.val);
-            rbml_w.end_tag();
-        }
-        rbml_w.end_tag();
-    }
-    rbml_w.end_tag();
-    rbml_w.start_tag(tag_index_table);
-    for pos in &bucket_locs {
-        assert!(*pos < 0xffff_ffff);
-        let wr: &mut SeekableMemWriter = rbml_w.writer;
-        wr.write_be_u32(*pos as u32);
-    }
-    rbml_w.end_tag();
-    rbml_w.end_tag();
-}
-#[cfg(not(stage0))]
-fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn: F) where
-    F: FnMut(&mut SeekableMemWriter, &T),
+    F: FnMut(&mut Cursor<Vec<u8>>, &T),
     T: Hash,
 {
     let mut buckets: Vec<Vec<entry<T>>> = (0..256u16).map(|_| Vec::new()).collect();
     for elt in index {
         let mut s = SipHasher::new();
         elt.val.hash(&mut s);
-        let h = s.finish() as uint;
+        let h = s.finish() as usize;
         (&mut buckets[h % 256]).push(elt);
     }
 
@@ -1646,14 +1545,14 @@ fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn:
     let mut bucket_locs = Vec::new();
     rbml_w.start_tag(tag_index_buckets);
     for bucket in &buckets {
-        bucket_locs.push(rbml_w.writer.tell().unwrap());
+        bucket_locs.push(rbml_w.mark_stable_position());
         rbml_w.start_tag(tag_index_buckets_bucket);
         for elt in bucket {
             rbml_w.start_tag(tag_index_buckets_bucket_elt);
             assert!(elt.pos < 0xffff_ffff);
             {
-                let wr: &mut SeekableMemWriter = rbml_w.writer;
-                wr.write_be_u32(elt.pos as u32);
+                let wr: &mut Cursor<Vec<u8>> = rbml_w.writer;
+                write_be_u32(wr, elt.pos as u32);
             }
             write_fn(rbml_w.writer, &elt.val);
             rbml_w.end_tag();
@@ -1664,38 +1563,41 @@ fn encode_index<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, mut write_fn:
     rbml_w.start_tag(tag_index_table);
     for pos in &bucket_locs {
         assert!(*pos < 0xffff_ffff);
-        let wr: &mut SeekableMemWriter = rbml_w.writer;
-        wr.write_be_u32(*pos as u32);
+        let wr: &mut Cursor<Vec<u8>> = rbml_w.writer;
+        write_be_u32(wr, *pos as u32);
     }
     rbml_w.end_tag();
     rbml_w.end_tag();
 }
 
-fn write_i64(writer: &mut SeekableMemWriter, &n: &i64) {
-    let wr: &mut SeekableMemWriter = writer;
+fn write_i64(writer: &mut Cursor<Vec<u8>>, &n: &i64) {
+    let wr: &mut Cursor<Vec<u8>> = writer;
     assert!(n < 0x7fff_ffff);
-    wr.write_be_u32(n as u32);
+    write_be_u32(wr, n as u32);
+}
+
+fn write_be_u32(w: &mut Write, u: u32) {
+    w.write_all(&[
+        (u >> 24) as u8,
+        (u >> 16) as u8,
+        (u >>  8) as u8,
+        (u >>  0) as u8,
+    ]);
 }
 
 fn encode_meta_item(rbml_w: &mut Encoder, mi: &ast::MetaItem) {
     match mi.node {
       ast::MetaWord(ref name) => {
         rbml_w.start_tag(tag_meta_item_word);
-        rbml_w.start_tag(tag_meta_item_name);
-        rbml_w.writer.write_all(name.as_bytes());
-        rbml_w.end_tag();
+        rbml_w.wr_tagged_str(tag_meta_item_name, name);
         rbml_w.end_tag();
       }
       ast::MetaNameValue(ref name, ref value) => {
         match value.node {
           ast::LitStr(ref value, _) => {
             rbml_w.start_tag(tag_meta_item_name_value);
-            rbml_w.start_tag(tag_meta_item_name);
-            rbml_w.writer.write_all(name.as_bytes());
-            rbml_w.end_tag();
-            rbml_w.start_tag(tag_meta_item_value);
-            rbml_w.writer.write_all(value.as_bytes());
-            rbml_w.end_tag();
+            rbml_w.wr_tagged_str(tag_meta_item_name, name);
+            rbml_w.wr_tagged_str(tag_meta_item_value, value);
             rbml_w.end_tag();
           }
           _ => {/* FIXME (#623): encode other variants */ }
@@ -1703,9 +1605,7 @@ fn encode_meta_item(rbml_w: &mut Encoder, mi: &ast::MetaItem) {
       }
       ast::MetaList(ref name, ref items) => {
         rbml_w.start_tag(tag_meta_item_list);
-        rbml_w.start_tag(tag_meta_item_name);
-        rbml_w.writer.write_all(name.as_bytes());
-        rbml_w.end_tag();
+        rbml_w.wr_tagged_str(tag_meta_item_name, name);
         for inner_item in items {
             encode_meta_item(rbml_w, &**inner_item);
         }
@@ -1738,6 +1638,11 @@ fn encode_paren_sugar(rbml_w: &mut Encoder, paren_sugar: bool) {
     rbml_w.wr_tagged_u8(tag_paren_sugar, byte);
 }
 
+fn encode_defaulted(rbml_w: &mut Encoder, is_defaulted: bool) {
+    let byte: u8 = if is_defaulted {1} else {0};
+    rbml_w.wr_tagged_u8(tag_defaulted_trait, byte);
+}
+
 fn encode_associated_type_names(rbml_w: &mut Encoder, names: &[ast::Name]) {
     rbml_w.start_tag(tag_associated_type_names);
     for &name in names {
@@ -1799,22 +1704,9 @@ fn encode_lang_items(ecx: &EncodeContext, rbml_w: &mut Encoder) {
         if let Some(id) = def_id {
             if id.krate == ast::LOCAL_CRATE {
                 rbml_w.start_tag(tag_lang_items_item);
-
-                rbml_w.start_tag(tag_lang_items_item_id);
-                {
-                    let wr: &mut SeekableMemWriter = rbml_w.writer;
-                    wr.write_be_u32(i as u32);
-                }
-                rbml_w.end_tag();   // tag_lang_items_item_id
-
-                rbml_w.start_tag(tag_lang_items_item_node_id);
-                {
-                    let wr: &mut SeekableMemWriter = rbml_w.writer;
-                    wr.write_be_u32(id.node as u32);
-                }
-                rbml_w.end_tag();   // tag_lang_items_item_node_id
-
-                rbml_w.end_tag();   // tag_lang_items_item
+                rbml_w.wr_tagged_u32(tag_lang_items_item_id, i as u32);
+                rbml_w.wr_tagged_u32(tag_lang_items_item_node_id, id.node as u32);
+                rbml_w.end_tag();
             }
         }
     }
@@ -1835,15 +1727,8 @@ fn encode_native_libraries(ecx: &EncodeContext, rbml_w: &mut Encoder) {
             cstore::NativeStatic => {} // these libraries are not propagated
             cstore::NativeFramework | cstore::NativeUnknown => {
                 rbml_w.start_tag(tag_native_libraries_lib);
-
-                rbml_w.start_tag(tag_native_libraries_kind);
-                rbml_w.writer.write_be_u32(kind as u32);
-                rbml_w.end_tag();
-
-                rbml_w.start_tag(tag_native_libraries_name);
-                rbml_w.writer.write_all(lib.as_bytes());
-                rbml_w.end_tag();
-
+                rbml_w.wr_tagged_u32(tag_native_libraries_kind, kind as u32);
+                rbml_w.wr_tagged_str(tag_native_libraries_name, lib);
                 rbml_w.end_tag();
             }
         }
@@ -1859,6 +1744,28 @@ fn encode_plugin_registrar_fn(ecx: &EncodeContext, rbml_w: &mut Encoder) {
     }
 }
 
+fn encode_codemap(ecx: &EncodeContext, rbml_w: &mut Encoder) {
+    rbml_w.start_tag(tag_codemap);
+    let codemap = ecx.tcx.sess.codemap();
+
+    for filemap in &codemap.files.borrow()[..] {
+
+        if filemap.lines.borrow().len() == 0 || filemap.is_imported() {
+            // No need to export empty filemaps, as they can't contain spans
+            // that need translation.
+            // Also no need to re-export imported filemaps, as any downstream
+            // crate will import them from their original source.
+            continue;
+        }
+
+        rbml_w.start_tag(tag_codemap_filemap);
+        filemap.encode(rbml_w);
+        rbml_w.end_tag();
+    }
+
+    rbml_w.end_tag();
+}
+
 /// Serialize the text of the exported macros
 fn encode_macro_defs(rbml_w: &mut Encoder,
                      krate: &ast::Crate) {
@@ -1867,11 +1774,10 @@ fn encode_macro_defs(rbml_w: &mut Encoder,
         rbml_w.start_tag(tag_macro_def);
 
         encode_name(rbml_w, def.ident.name);
-        encode_attributes(rbml_w, &def.attrs[]);
+        encode_attributes(rbml_w, &def.attrs);
 
-        rbml_w.start_tag(tag_macro_def_body);
-        rbml_w.wr_str(&pprust::tts_to_string(&def.body[])[]);
-        rbml_w.end_tag();
+        rbml_w.wr_tagged_str(tag_macro_def_body,
+                             &pprust::tts_to_string(&def.body));
 
         rbml_w.end_tag();
     }
@@ -1887,7 +1793,7 @@ fn encode_struct_field_attrs(rbml_w: &mut Encoder, krate: &ast::Crate) {
         fn visit_struct_field(&mut self, field: &ast::StructField) {
             self.rbml_w.start_tag(tag_struct_field);
             self.rbml_w.wr_tagged_u32(tag_struct_field_id, field.node.id);
-            encode_attributes(self.rbml_w, &field.node.attrs[]);
+            encode_attributes(self.rbml_w, &field.node.attrs);
             self.rbml_w.end_tag();
         }
     }
@@ -1909,9 +1815,7 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
 impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
     fn visit_item(&mut self, item: &ast::Item) {
         if let ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
-            let def_map = &self.ecx.tcx.def_map;
-            let trait_def = def_map.borrow()[trait_ref.ref_id].clone();
-            let def_id = trait_def.def_id();
+            let def_id = self.ecx.tcx.def_map.borrow().get(&trait_ref.ref_id).unwrap().def_id();
 
             // Load eagerly if this is an implementation of the Drop trait
             // or if the trait is not defined in this crate.
@@ -1958,21 +1862,18 @@ fn encode_misc_info(ecx: &EncodeContext,
     rbml_w.start_tag(tag_misc_info);
     rbml_w.start_tag(tag_misc_info_crate_items);
     for item in &krate.module.items {
-        rbml_w.start_tag(tag_mod_child);
-        rbml_w.wr_str(&def_to_string(local_def(item.id))[]);
-        rbml_w.end_tag();
+        rbml_w.wr_tagged_str(tag_mod_child,
+                             &def_to_string(local_def(item.id)));
 
         each_auxiliary_node_id(&**item, |auxiliary_node_id| {
-            rbml_w.start_tag(tag_mod_child);
-            rbml_w.wr_str(&def_to_string(local_def(
-                        auxiliary_node_id))[]);
-            rbml_w.end_tag();
+            rbml_w.wr_tagged_str(tag_mod_child,
+                                 &def_to_string(local_def(auxiliary_node_id)));
             true
         });
     }
 
     // Encode reexports for the root module.
-    encode_reexports(ecx, rbml_w, 0, [].iter().cloned().chain(None));
+    encode_reexports(ecx, rbml_w, 0, [].iter().cloned().chain(LinkedPath::empty()));
 
     rbml_w.end_tag();
     rbml_w.end_tag();
@@ -1997,35 +1898,25 @@ fn encode_reachable_extern_fns(ecx: &EncodeContext, rbml_w: &mut Encoder) {
 fn encode_crate_dep(rbml_w: &mut Encoder,
                     dep: decoder::CrateDep) {
     rbml_w.start_tag(tag_crate_dep);
-    rbml_w.start_tag(tag_crate_dep_crate_name);
-    rbml_w.writer.write_all(dep.name.as_bytes());
-    rbml_w.end_tag();
-    rbml_w.start_tag(tag_crate_dep_hash);
-    rbml_w.writer.write_all(dep.hash.as_str().as_bytes());
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_str(tag_crate_dep_crate_name, &dep.name);
+    rbml_w.wr_tagged_str(tag_crate_dep_hash, dep.hash.as_str());
     rbml_w.end_tag();
 }
 
 fn encode_hash(rbml_w: &mut Encoder, hash: &Svh) {
-    rbml_w.start_tag(tag_crate_hash);
-    rbml_w.writer.write_all(hash.as_str().as_bytes());
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_str(tag_crate_hash, hash.as_str());
 }
 
 fn encode_crate_name(rbml_w: &mut Encoder, crate_name: &str) {
-    rbml_w.start_tag(tag_crate_crate_name);
-    rbml_w.writer.write_all(crate_name.as_bytes());
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_str(tag_crate_crate_name, crate_name);
 }
 
 fn encode_crate_triple(rbml_w: &mut Encoder, triple: &str) {
-    rbml_w.start_tag(tag_crate_triple);
-    rbml_w.writer.write_all(triple.as_bytes());
-    rbml_w.end_tag();
+    rbml_w.wr_tagged_str(tag_crate_triple, triple);
 }
 
 fn encode_dylib_dependency_formats(rbml_w: &mut Encoder, ecx: &EncodeContext) {
-    rbml_w.start_tag(tag_dylib_dependency_formats);
+    let tag = tag_dylib_dependency_formats;
     match ecx.tcx.dependency_formats.borrow().get(&config::CrateTypeDylib) {
         Some(arr) => {
             let s = arr.iter().enumerate().filter_map(|(i, slot)| {
@@ -2034,21 +1925,28 @@ fn encode_dylib_dependency_formats(rbml_w: &mut Encoder, ecx: &EncodeContext) {
                     cstore::RequireStatic => "s",
                 })).to_string())
             }).collect::<Vec<String>>();
-            rbml_w.writer.write_all(s.connect(",").as_bytes());
+            rbml_w.wr_tagged_str(tag, &s.connect(","));
+        }
+        None => {
+            rbml_w.wr_tagged_str(tag, "");
         }
-        None => {}
     }
-    rbml_w.end_tag();
 }
 
 // NB: Increment this as you change the metadata encoding version.
 #[allow(non_upper_case_globals)]
-pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 1 ];
+pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 2 ];
 
 pub fn encode_metadata(parms: EncodeParams, krate: &ast::Crate) -> Vec<u8> {
-    let mut wr = SeekableMemWriter::new();
+    let mut wr = Cursor::new(Vec::new());
     encode_metadata_inner(&mut wr, parms, krate);
-    let mut v = wr.unwrap();
+
+    // RBML compacts the encoded bytes whenever appropriate,
+    // so there are some garbages left after the end of the data.
+    let metalen = wr.seek(SeekFrom::Current(0)).unwrap() as usize;
+    let mut v = wr.into_inner();
+    v.truncate(metalen);
+    assert_eq!(v.len(), metalen);
 
     // 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
@@ -2076,7 +1974,7 @@ pub fn encode_metadata(parms: EncodeParams, krate: &ast::Crate) -> Vec<u8> {
     return v;
 }
 
-fn encode_metadata_inner(wr: &mut SeekableMemWriter,
+fn encode_metadata_inner(wr: &mut Cursor<Vec<u8>>,
                          parms: EncodeParams,
                          krate: &ast::Crate) {
     struct Stats {
@@ -2085,6 +1983,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
         lang_item_bytes: u64,
         native_lib_bytes: u64,
         plugin_registrar_fn_bytes: u64,
+        codemap_bytes: u64,
         macro_defs_bytes: u64,
         impl_bytes: u64,
         misc_bytes: u64,
@@ -2099,6 +1998,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
         lang_item_bytes: 0,
         native_lib_bytes: 0,
         plugin_registrar_fn_bytes: 0,
+        codemap_bytes: 0,
         macro_defs_bytes: 0,
         impl_bytes: 0,
         misc_bytes: 0,
@@ -2130,70 +2030,75 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
         reachable: reachable,
      };
 
-    let mut rbml_w = writer::Encoder::new(wr);
+    let mut rbml_w = Encoder::new(wr);
 
-    encode_crate_name(&mut rbml_w, &ecx.link_meta.crate_name[]);
+    encode_crate_name(&mut rbml_w, &ecx.link_meta.crate_name);
     encode_crate_triple(&mut rbml_w,
                         &tcx.sess
                            .opts
                            .target_triple
-                           []);
+                           );
     encode_hash(&mut rbml_w, &ecx.link_meta.crate_hash);
     encode_dylib_dependency_formats(&mut rbml_w, &ecx);
 
-    let mut i = rbml_w.writer.tell().unwrap();
-    encode_attributes(&mut rbml_w, &krate.attrs[]);
-    stats.attr_bytes = rbml_w.writer.tell().unwrap() - i;
+    let mut i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
+    encode_attributes(&mut rbml_w, &krate.attrs);
+    stats.attr_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_crate_deps(&mut rbml_w, ecx.cstore);
-    stats.dep_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.dep_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode the language items.
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_lang_items(&ecx, &mut rbml_w);
-    stats.lang_item_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.lang_item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode the native libraries used
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_native_libraries(&ecx, &mut rbml_w);
-    stats.native_lib_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.native_lib_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode the plugin registrar function
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_plugin_registrar_fn(&ecx, &mut rbml_w);
-    stats.plugin_registrar_fn_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.plugin_registrar_fn_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
+
+    // Encode codemap
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
+    encode_codemap(&ecx, &mut rbml_w);
+    stats.codemap_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode macro definitions
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_macro_defs(&mut rbml_w, krate);
-    stats.macro_defs_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.macro_defs_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode the def IDs of impls, for coherence checking.
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_impls(&ecx, krate, &mut rbml_w);
-    stats.impl_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.impl_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode miscellaneous info.
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_misc_info(&ecx, krate, &mut rbml_w);
     encode_reachable_extern_fns(&ecx, &mut rbml_w);
-    stats.misc_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.misc_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
     // Encode and index the items.
     rbml_w.start_tag(tag_items);
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     let items_index = encode_info_for_items(&ecx, &mut rbml_w, krate);
-    stats.item_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.item_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
-    i = rbml_w.writer.tell().unwrap();
+    i = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
     encode_index(&mut rbml_w, items_index, write_i64);
-    stats.index_bytes = rbml_w.writer.tell().unwrap() - i;
+    stats.index_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
     rbml_w.end_tag();
 
     encode_struct_field_attrs(&mut rbml_w, krate);
 
-    stats.total_bytes = rbml_w.writer.tell().unwrap();
+    stats.total_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
 
     if tcx.sess.meta_stats() {
         for e in rbml_w.writer.get_ref() {
@@ -2208,6 +2113,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
         println!("       lang item bytes: {}", stats.lang_item_bytes);
         println!("          native bytes: {}", stats.native_lib_bytes);
         println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes);
+        println!("         codemap bytes: {}", stats.codemap_bytes);
         println!("       macro def bytes: {}", stats.macro_defs_bytes);
         println!("            impl bytes: {}", stats.impl_bytes);
         println!("            misc bytes: {}", stats.misc_bytes);
@@ -2220,12 +2126,12 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
 
 // Get the encoded string for a type
 pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> String {
-    let mut wr = SeekableMemWriter::new();
-    tyencode::enc_ty(&mut wr, &tyencode::ctxt {
+    let mut wr = Cursor::new(Vec::new());
+    tyencode::enc_ty(&mut Encoder::new(&mut wr), &tyencode::ctxt {
         diag: tcx.sess.diagnostic(),
         ds: def_to_string,
         tcx: tcx,
         abbrevs: &RefCell::new(FnvHashMap())
     }, t);
-    String::from_utf8(wr.unwrap()).unwrap()
+    String::from_utf8(wr.into_inner()).unwrap()
 }
index 3caa0f5b4db4c97a13722cabc0a5ba1b6d280c3a..1567f4b99475cb1fe345e0f1983f487cb695e12b 100644 (file)
@@ -14,13 +14,14 @@ pub use self::FileMatch::*;
 
 use std::collections::HashSet;
 use std::env;
-use std::old_io::fs::PathExtensions;
-use std::old_io::fs;
+use std::fs;
+use std::io::prelude::*;
+use std::path::{Path, PathBuf};
 
 use util::fs as myfs;
 use session::search_paths::{SearchPaths, PathKind};
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum FileMatch {
     FileMatches,
     FileDoesntMatch,
@@ -49,20 +50,20 @@ impl<'a> FileSearch<'a> {
                 FileMatches => found = true,
                 FileDoesntMatch => ()
             }
-            visited_dirs.insert(path.as_vec().to_vec());
+            visited_dirs.insert(path.to_path_buf());
         }
 
         debug!("filesearch: searching lib path");
         let tlib_path = make_target_lib_path(self.sysroot,
                                              self.triple);
-        if !visited_dirs.contains(tlib_path.as_vec()) {
+        if !visited_dirs.contains(&tlib_path) {
             match f(&tlib_path, PathKind::All) {
                 FileMatches => found = true,
                 FileDoesntMatch => ()
             }
         }
 
-        visited_dirs.insert(tlib_path.as_vec().to_vec());
+        visited_dirs.insert(tlib_path);
         // Try RUST_PATH
         if !found {
             let rustpath = rust_path();
@@ -70,10 +71,10 @@ impl<'a> FileSearch<'a> {
                 let tlib_path = make_rustpkg_lib_path(
                     self.sysroot, path, self.triple);
                 debug!("is {} in visited_dirs? {}", tlib_path.display(),
-                        visited_dirs.contains(&tlib_path.as_vec().to_vec()));
+                        visited_dirs.contains(&tlib_path));
 
-                if !visited_dirs.contains(tlib_path.as_vec()) {
-                    visited_dirs.insert(tlib_path.as_vec().to_vec());
+                if !visited_dirs.contains(&tlib_path) {
+                    visited_dirs.insert(tlib_path.clone());
                     // Don't keep searching the RUST_PATH if one match turns up --
                     // if we did, we'd get a "multiple matching crates" error
                     match f(&tlib_path, PathKind::All) {
@@ -87,7 +88,7 @@ impl<'a> FileSearch<'a> {
         }
     }
 
-    pub fn get_lib_path(&self) -> Path {
+    pub fn get_lib_path(&self) -> PathBuf {
         make_target_lib_path(self.sysroot, self.triple)
     }
 
@@ -96,11 +97,13 @@ impl<'a> FileSearch<'a> {
     {
         self.for_each_lib_search_path(|lib_search_path, kind| {
             debug!("searching {}", lib_search_path.display());
-            match fs::readdir(lib_search_path) {
+            match fs::read_dir(lib_search_path) {
                 Ok(files) => {
+                    let files = files.filter_map(|p| p.ok().map(|s| s.path()))
+                                     .collect::<Vec<_>>();
                     let mut rslt = FileDoesntMatch;
-                    fn is_rlib(p: & &Path) -> bool {
-                        p.extension_str() == Some("rlib")
+                    fn is_rlib(p: &Path) -> bool {
+                        p.extension().and_then(|s| s.to_str()) == Some("rlib")
                     }
                     // Reading metadata out of rlibs is faster, and if we find both
                     // an rlib and a dylib we only read one of the files of
@@ -142,56 +145,57 @@ impl<'a> FileSearch<'a> {
     }
 
     // Returns a list of directories where target-specific dylibs might be located.
-    pub fn get_dylib_search_paths(&self) -> Vec<Path> {
+    pub fn get_dylib_search_paths(&self) -> Vec<PathBuf> {
         let mut paths = Vec::new();
         self.for_each_lib_search_path(|lib_search_path, _| {
-            paths.push(lib_search_path.clone());
+            paths.push(lib_search_path.to_path_buf());
             FileDoesntMatch
         });
         paths
     }
 
     // Returns a list of directories where target-specific tool binaries are located.
-    pub fn get_tools_search_paths(&self) -> Vec<Path> {
-        let mut p = Path::new(self.sysroot);
-        p.push(find_libdir(self.sysroot));
-        p.push(rustlibdir());
-        p.push(self.triple);
+    pub fn get_tools_search_paths(&self) -> Vec<PathBuf> {
+        let mut p = PathBuf::from(self.sysroot);
+        p.push(&find_libdir(self.sysroot));
+        p.push(&rustlibdir());
+        p.push(&self.triple);
         p.push("bin");
         vec![p]
     }
 }
 
-pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> Path {
-    let mut p = Path::new(find_libdir(sysroot));
+pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
+    let mut p = PathBuf::from(&find_libdir(sysroot));
     assert!(p.is_relative());
-    p.push(rustlibdir());
+    p.push(&rustlibdir());
     p.push(target_triple);
     p.push("lib");
     p
 }
 
 fn make_target_lib_path(sysroot: &Path,
-                        target_triple: &str) -> Path {
+                        target_triple: &str) -> PathBuf {
     sysroot.join(&relative_target_lib_path(sysroot, target_triple))
 }
 
 fn make_rustpkg_lib_path(sysroot: &Path,
                          dir: &Path,
-                         triple: &str) -> Path {
-    let mut p = dir.join(find_libdir(sysroot));
+                         triple: &str) -> PathBuf {
+    let mut p = dir.join(&find_libdir(sysroot));
     p.push(triple);
     p
 }
 
-pub fn get_or_default_sysroot() -> Path {
+pub fn get_or_default_sysroot() -> PathBuf {
     // Follow symlinks.  If the resolved path is relative, make it absolute.
-    fn canonicalize(path: Option<Path>) -> Option<Path> {
-        path.and_then(|path|
+    fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {
+        path.and_then(|path| {
             match myfs::realpath(&path) {
                 Ok(canon) => Some(canon),
                 Err(e) => panic!("failed to get realpath: {}", e),
-            })
+            }
+        })
     }
 
     match canonicalize(env::current_exe().ok()) {
@@ -201,9 +205,9 @@ pub fn get_or_default_sysroot() -> Path {
 }
 
 #[cfg(windows)]
-static PATH_ENTRY_SEPARATOR: &'static str = ";";
+const PATH_ENTRY_SEPARATOR: char = ';';
 #[cfg(not(windows))]
-static PATH_ENTRY_SEPARATOR: &'static str = ":";
+const PATH_ENTRY_SEPARATOR: char = ':';
 
 /// Returns RUST_PATH as a string, without default paths added
 pub fn get_rust_path() -> Option<String> {
@@ -215,16 +219,16 @@ pub fn get_rust_path() -> Option<String> {
 /// $HOME/.rust
 /// DIR/.rust for any DIR that's the current working directory
 /// or an ancestor of it
-pub fn rust_path() -> Vec<Path> {
-    let mut env_rust_path: Vec<Path> = match get_rust_path() {
+pub fn rust_path() -> Vec<PathBuf> {
+    let mut env_rust_path: Vec<PathBuf> = match get_rust_path() {
         Some(env_path) => {
             let env_path_components =
-                env_path.split_str(PATH_ENTRY_SEPARATOR);
-            env_path_components.map(|s| Path::new(s)).collect()
+                env_path.split(PATH_ENTRY_SEPARATOR);
+            env_path_components.map(|s| PathBuf::from(s)).collect()
         }
         None => Vec::new()
     };
-    let mut cwd = env::current_dir().unwrap();
+    let cwd = env::current_dir().unwrap();
     // now add in default entries
     let cwd_dot_rust = cwd.join(".rust");
     if !env_rust_path.contains(&cwd_dot_rust) {
@@ -233,15 +237,13 @@ pub fn rust_path() -> Vec<Path> {
     if !env_rust_path.contains(&cwd) {
         env_rust_path.push(cwd.clone());
     }
-    loop {
-        if { let f = cwd.filename(); f.is_none() || f.unwrap() == b".." } {
-            break
-        }
-        cwd.set_filename(".rust");
-        if !env_rust_path.contains(&cwd) && cwd.exists() {
-            env_rust_path.push(cwd.clone());
+    let mut cur = &*cwd;
+    while let Some(parent) = cur.parent() {
+        let candidate = parent.join(".rust");
+        if !env_rust_path.contains(&candidate) && candidate.exists() {
+            env_rust_path.push(candidate.clone());
         }
-        cwd.pop();
+        cur = parent;
     }
     if let Some(h) = env::home_dir() {
         let p = h.join(".rust");
@@ -266,7 +268,7 @@ fn find_libdir(sysroot: &Path) -> String {
 
     match option_env!("CFG_LIBDIR_RELATIVE") {
         Some(libdir) if libdir != "lib" => return libdir.to_string(),
-        _ => if sysroot.join(primary_libdir_name()).join(rustlibdir()).exists() {
+        _ => if sysroot.join(&primary_libdir_name()).join(&rustlibdir()).exists() {
             return primary_libdir_name();
         } else {
             return secondary_libdir_name();
index 01d1f4e7011f8586c7196884fc851e35ee039d1c..7b63e38b585980cce03c4b7839e23f997ec5cc4a 100644 (file)
 //! no means all of the necessary details. Take a look at the rest of
 //! metadata::loader or metadata::creader for all the juicy details!
 
-use back::archive::{METADATA_FILENAME};
+use back::archive::METADATA_FILENAME;
 use back::svh::Svh;
 use session::Session;
 use session::search_paths::PathKind;
@@ -226,13 +226,14 @@ use metadata::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
 use syntax::codemap::Span;
 use syntax::diagnostic::SpanHandler;
 use util::fs;
+use util::common;
 use rustc_back::target::Target;
 
-use std::ffi::CString;
 use std::cmp;
 use std::collections::HashMap;
-use std::old_io::fs::PathExtensions;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
+use std::path::{Path, PathBuf};
 use std::ptr;
 use std::slice;
 use std::time::Duration;
@@ -240,7 +241,7 @@ use std::time::Duration;
 use flate;
 
 pub struct CrateMismatch {
-    path: Path,
+    path: PathBuf,
     got: String,
 }
 
@@ -262,8 +263,8 @@ pub struct Context<'a> {
 }
 
 pub struct Library {
-    pub dylib: Option<(Path, PathKind)>,
-    pub rlib: Option<(Path, PathKind)>,
+    pub dylib: Option<(PathBuf, PathKind)>,
+    pub rlib: Option<(PathBuf, PathKind)>,
     pub metadata: MetadataBlob,
 }
 
@@ -275,12 +276,12 @@ pub struct ArchiveMetadata {
 
 pub struct CratePaths {
     pub ident: String,
-    pub dylib: Option<Path>,
-    pub rlib: Option<Path>
+    pub dylib: Option<PathBuf>,
+    pub rlib: Option<PathBuf>
 }
 
 impl CratePaths {
-    fn paths(&self) -> Vec<Path> {
+    fn paths(&self) -> Vec<PathBuf> {
         match (&self.dylib, &self.rlib) {
             (&None,    &None)              => vec!(),
             (&Some(ref p), &None) |
@@ -329,7 +330,7 @@ impl<'a> Context<'a> {
             for (i, &CrateMismatch{ ref path, ref got }) in mismatches.enumerate() {
                 self.sess.fileline_note(self.span,
                     &format!("crate `{}`, path #{}, triple {}: {}",
-                            self.ident, i+1, got, path.display())[]);
+                            self.ident, i+1, got, path.display()));
             }
         }
         if self.rejected_via_hash.len() > 0 {
@@ -339,7 +340,7 @@ impl<'a> Context<'a> {
             for (i, &CrateMismatch{ ref path, .. }) in mismatches.enumerate() {
                 self.sess.fileline_note(self.span,
                     &format!("crate `{}` path #{}: {}",
-                            self.ident, i+1, path.display())[]);
+                            self.ident, i+1, path.display()));
             }
             match self.root {
                 &None => {}
@@ -347,19 +348,19 @@ impl<'a> Context<'a> {
                     for (i, path) in r.paths().iter().enumerate() {
                         self.sess.fileline_note(self.span,
                             &format!("crate `{}` path #{}: {}",
-                                    r.ident, i+1, path.display())[]);
+                                    r.ident, i+1, path.display()));
                     }
                 }
             }
         }
         if self.rejected_via_kind.len() > 0 {
-            self.sess.span_help(self.span, "please recompile this crate using \
+            self.sess.fileline_help(self.span, "please recompile this crate using \
                                             --crate-type lib");
             let mismatches = self.rejected_via_kind.iter();
             for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() {
                 self.sess.fileline_note(self.span,
                                         &format!("crate `{}` path #{}: {}",
-                                                 self.ident, i+1, path.display())[]);
+                                                 self.ident, i+1, path.display()));
             }
         }
         self.sess.abort_if_errors();
@@ -400,7 +401,7 @@ impl<'a> Context<'a> {
         //
         // The goal of this step is to look at as little metadata as possible.
         self.filesearch.search(|path, kind| {
-            let file = match path.filename_str() {
+            let file = match path.file_name().and_then(|s| s.to_str()) {
                 None => return FileDoesntMatch,
                 Some(file) => file,
             };
@@ -416,7 +417,7 @@ impl<'a> Context<'a> {
                 if file.starts_with(&staticlib_prefix[..]) &&
                    file.ends_with(".a") {
                     staticlibs.push(CrateMismatch {
-                        path: path.clone(),
+                        path: path.to_path_buf(),
                         got: "static".to_string()
                     });
                 }
@@ -425,8 +426,8 @@ impl<'a> Context<'a> {
             info!("lib candidate: {}", path.display());
 
             let hash_str = hash.to_string();
-            let slot = candidates.entry(hash_str).get().unwrap_or_else(
-                |vacant_entry| vacant_entry.insert((HashMap::new(), HashMap::new())));
+            let slot = candidates.entry(hash_str)
+                                 .or_insert_with(|| (HashMap::new(), HashMap::new()));
             let (ref mut rlibs, ref mut dylibs) = *slot;
             if rlib {
                 rlibs.insert(fs::realpath(path).unwrap(), kind);
@@ -472,26 +473,26 @@ impl<'a> Context<'a> {
             _ => {
                 self.sess.span_err(self.span,
                     &format!("multiple matching crates for `{}`",
-                            self.crate_name)[]);
+                            self.crate_name));
                 self.sess.note("candidates:");
                 for lib in &libraries {
                     match lib.dylib {
                         Some((ref p, _)) => {
                             self.sess.note(&format!("path: {}",
-                                                   p.display())[]);
+                                                   p.display()));
                         }
                         None => {}
                     }
                     match lib.rlib {
                         Some((ref p, _)) => {
                             self.sess.note(&format!("path: {}",
-                                                    p.display())[]);
+                                                    p.display()));
                         }
                         None => {}
                     }
                     let data = lib.metadata.as_slice();
                     let name = decoder::get_crate_name(data);
-                    note_crate_name(self.sess.diagnostic(), &name[]);
+                    note_crate_name(self.sess.diagnostic(), &name);
                 }
                 None
             }
@@ -506,9 +507,9 @@ impl<'a> Context<'a> {
     // read the metadata from it if `*slot` is `None`. If the metadata couldn't
     // be read, it is assumed that the file isn't a valid rust library (no
     // errors are emitted).
-    fn extract_one(&mut self, m: HashMap<Path, PathKind>, flavor: &str,
-                   slot: &mut Option<MetadataBlob>) -> Option<(Path, PathKind)> {
-        let mut ret = None::<(Path, PathKind)>;
+    fn extract_one(&mut self, m: HashMap<PathBuf, PathKind>, flavor: &str,
+                   slot: &mut Option<MetadataBlob>) -> Option<(PathBuf, PathKind)> {
+        let mut ret = None::<(PathBuf, PathKind)>;
         let mut error = 0;
 
         if slot.is_some() {
@@ -545,11 +546,11 @@ impl<'a> Context<'a> {
                                    &format!("multiple {} candidates for `{}` \
                                             found",
                                            flavor,
-                                           self.crate_name)[]);
+                                           self.crate_name));
                 self.sess.span_note(self.span,
                                     &format!(r"candidate #1: {}",
                                             ret.as_ref().unwrap().0
-                                               .display())[]);
+                                               .display()));
                 error = 1;
                 ret = None;
             }
@@ -557,7 +558,7 @@ impl<'a> Context<'a> {
                 error += 1;
                 self.sess.span_note(self.span,
                                     &format!(r"candidate #{}: {}", error,
-                                            lib.display())[]);
+                                            lib.display()));
                 continue
             }
             *slot = Some(metadata);
@@ -587,7 +588,7 @@ impl<'a> Context<'a> {
         if triple != self.triple {
             info!("Rejecting via crate triple: expected {} got {}", self.triple, triple);
             self.rejected_via_triple.push(CrateMismatch {
-                path: libpath.clone(),
+                path: libpath.to_path_buf(),
                 got: triple.to_string()
             });
             return false;
@@ -599,7 +600,7 @@ impl<'a> Context<'a> {
                 if *myhash != hash {
                     info!("Rejecting via hash: expected {} got {}", *myhash, hash);
                     self.rejected_via_hash.push(CrateMismatch {
-                        path: libpath.clone(),
+                        path: libpath.to_path_buf(),
                         got: myhash.as_str().to_string()
                     });
                     false
@@ -627,17 +628,17 @@ impl<'a> Context<'a> {
         let mut rlibs = HashMap::new();
         let mut dylibs = HashMap::new();
         {
-            let locs = locs.iter().map(|l| Path::new(&l[..])).filter(|loc| {
+            let locs = locs.iter().map(|l| PathBuf::from(l)).filter(|loc| {
                 if !loc.exists() {
                     sess.err(&format!("extern location for {} does not exist: {}",
-                                     self.crate_name, loc.display())[]);
+                                     self.crate_name, loc.display()));
                     return false;
                 }
-                let file = match loc.filename_str() {
+                let file = match loc.file_name().and_then(|s| s.to_str()) {
                     Some(file) => file,
                     None => {
                         sess.err(&format!("extern location for {} is not a file: {}",
-                                         self.crate_name, loc.display())[]);
+                                         self.crate_name, loc.display()));
                         return false;
                     }
                 };
@@ -651,14 +652,14 @@ impl<'a> Context<'a> {
                     }
                 }
                 sess.err(&format!("extern location for {} is of an unknown type: {}",
-                                 self.crate_name, loc.display())[]);
+                                 self.crate_name, loc.display()));
                 false
             });
 
             // Now that we have an iterator of good candidates, make sure
             // there's at most one rlib and at most one dylib.
             for loc in locs {
-                if loc.filename_str().unwrap().ends_with(".rlib") {
+                if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
                     rlibs.insert(fs::realpath(&loc).unwrap(),
                                  PathKind::ExternFlag);
                 } else {
@@ -686,7 +687,7 @@ impl<'a> Context<'a> {
 }
 
 pub fn note_crate_name(diag: &SpanHandler, name: &str) {
-    diag.handler().note(&format!("crate name: {}", name)[]);
+    diag.handler().note(&format!("crate name: {}", name));
 }
 
 impl ArchiveMetadata {
@@ -714,7 +715,7 @@ fn get_metadata_section(is_osx: bool, filename: &Path) -> Result<MetadataBlob, S
     let dur = Duration::span(|| {
         ret = Some(get_metadata_section_imp(is_osx, filename));
     });
-    info!("reading {} => {}ms", filename.filename_display(),
+    info!("reading {:?} => {}ms", filename.file_name().unwrap(),
           dur.num_milliseconds());
     return ret.unwrap();;
 }
@@ -723,7 +724,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
     if !filename.exists() {
         return Err(format!("no such file: '{}'", filename.display()));
     }
-    if filename.filename_str().unwrap().ends_with(".rlib") {
+    if filename.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
         // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
         // internally to read the file. We also avoid even using a memcpy by
         // just keeping the archive along while the metadata is in use.
@@ -736,17 +737,15 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
             }
         };
         return match ArchiveMetadata::new(archive).map(|ar| MetadataArchive(ar)) {
-            None => {
-                return Err((format!("failed to read rlib metadata: '{}'",
-                                    filename.display())))
-            }
-            Some(blob) => return Ok(blob)
-        }
+            None => Err(format!("failed to read rlib metadata: '{}'",
+                                filename.display())),
+            Some(blob) => Ok(blob)
+        };
     }
     unsafe {
-        let buf = CString::new(filename.as_vec()).unwrap();
+        let buf = common::path2cstr(filename);
         let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
-        if mb as int == 0 {
+        if mb as isize == 0 {
             return Err(format!("error reading library: '{}'",
                                filename.display()))
         }
@@ -762,12 +761,12 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
             let mut name_buf = ptr::null();
             let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
             let name = slice::from_raw_parts(name_buf as *const u8,
-                                             name_len as uint).to_vec();
+                                             name_len as usize).to_vec();
             let name = String::from_utf8(name).unwrap();
             debug!("get_metadata_section: name {}", name);
             if read_meta_section_name(is_osx) == name {
                 let cbuf = llvm::LLVMGetSectionContents(si.llsi);
-                let csz = llvm::LLVMGetSectionSize(si.llsi) as uint;
+                let csz = llvm::LLVMGetSectionSize(si.llsi) as usize;
                 let cvbuf: *const u8 = cbuf as *const u8;
                 let vlen = encoder::metadata_encoding_version.len();
                 debug!("checking {} bytes of metadata-version stamp",
@@ -780,18 +779,18 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
                                         filename.display())));
                 }
 
-                let cvbuf1 = cvbuf.offset(vlen as int);
+                let cvbuf1 = cvbuf.offset(vlen as isize);
                 debug!("inflating {} bytes of compressed metadata",
                        csz - vlen);
                 let bytes = slice::from_raw_parts(cvbuf1, csz - vlen);
                 match flate::inflate_bytes(bytes) {
-                    Some(inflated) => return Ok(MetadataVec(inflated)),
-                    None => {}
+                    Ok(inflated) => return Ok(MetadataVec(inflated)),
+                    Err(_) => {}
                 }
             }
             llvm::LLVMMoveToNextSection(si.llsi);
         }
-        return Err(format!("metadata not found: '{}'", filename.display()));
+        Err(format!("metadata not found: '{}'", filename.display()))
     }
 }
 
@@ -813,7 +812,7 @@ pub fn read_meta_section_name(is_osx: bool) -> &'static str {
 
 // A diagnostic function for dumping crate metadata to an output stream
 pub fn list_file_metadata(is_osx: bool, path: &Path,
-                          out: &mut old_io::Writer) -> old_io::IoResult<()> {
+                          out: &mut io::Write) -> io::Result<()> {
     match get_metadata_section(is_osx, path) {
         Ok(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out),
         Err(msg) => {
index 28c98d455f046dc2e04601c1ce421275b52492af..c2d7911d151fbfb7f3a79e2e4d61776a4e851a59 100644 (file)
@@ -78,16 +78,7 @@ impl<'a, 'v> Visitor<'v> for MacroLoader<'a> {
 
         for attr in &item.attrs {
             let mut used = true;
-            match &attr.name()[] {
-                "phase" => {
-                    self.sess.span_err(attr.span, "#[phase] is deprecated");
-                }
-                "plugin" => {
-                    self.sess.span_err(attr.span, "#[plugin] on `extern crate` is deprecated");
-                    self.sess.span_help(attr.span, &format!("use a crate attribute instead, \
-                                                            i.e. #![plugin({})]",
-                                                            item.ident.as_str())[]);
-                }
+            match &attr.name()[..] {
                 "macro_use" => {
                     let names = attr.meta_item_list();
                     if names.is_none() {
@@ -166,6 +157,9 @@ impl<'a> MacroLoader<'a> {
                 Some(sel) => sel.contains_key(&name),
             };
             def.export = reexport.contains_key(&name);
+            def.allow_internal_unstable = attr::contains_name(&def.attrs,
+                                                              "allow_internal_unstable");
+            debug!("load_macros: loaded: {:?}", def);
             self.macros.push(def);
         }
 
index 5805725a8fc8b7cb6ad2f37651f437f33278182b..3fb128b1881f5b949bed0c91cc9c73b7ba1ba365 100644 (file)
@@ -43,7 +43,7 @@ use syntax::parse::token;
 // def-id will depend on where it originated from.  Therefore, the conversion
 // function is given an indicator of the source of the def-id.  See
 // astencode.rs for more information.
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum DefIdSource {
     // Identifies a struct, trait, enum, etc.
     NominalType,
@@ -66,7 +66,7 @@ pub enum DefIdSource {
 pub struct PState<'a, 'tcx: 'a> {
     data: &'a [u8],
     krate: ast::CrateNum,
-    pos: uint,
+    pos: usize,
     tcx: &'a ty::ctxt<'tcx>
 }
 
@@ -119,7 +119,7 @@ fn parse_name_<F>(st: &mut PState, is_last: F) -> ast::Name where
 }
 
 pub fn parse_state_from_data<'a, 'tcx>(data: &'a [u8], crate_num: ast::CrateNum,
-                                       pos: uint, tcx: &'a ty::ctxt<'tcx>)
+                                       pos: usize, tcx: &'a ty::ctxt<'tcx>)
                                        -> PState<'a, 'tcx> {
     PState {
         data: data,
@@ -129,7 +129,7 @@ pub fn parse_state_from_data<'a, 'tcx>(data: &'a [u8], crate_num: ast::CrateNum,
     }
 }
 
-fn data_log_string(data: &[u8], pos: uint) -> String {
+fn data_log_string(data: &[u8], pos: usize) -> String {
     let mut buf = String::new();
     buf.push_str("<<");
     for i in pos..data.len() {
@@ -146,7 +146,7 @@ fn data_log_string(data: &[u8], pos: uint) -> String {
 
 pub fn parse_ty_closure_data<'tcx, F>(data: &[u8],
                                       crate_num: ast::CrateNum,
-                                      pos: uint,
+                                      pos: usize,
                                       tcx: &ty::ctxt<'tcx>,
                                       conv: F)
                                       -> ty::ClosureTy<'tcx> where
@@ -156,7 +156,7 @@ pub fn parse_ty_closure_data<'tcx, F>(data: &[u8],
     parse_closure_ty(&mut st, conv)
 }
 
-pub fn parse_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
+pub fn parse_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize,
                               tcx: &ty::ctxt<'tcx>, conv: F) -> Ty<'tcx> where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
 {
@@ -165,7 +165,7 @@ pub fn parse_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
     parse_ty(&mut st, conv)
 }
 
-pub fn parse_region_data<F>(data: &[u8], crate_num: ast::CrateNum, pos: uint, tcx: &ty::ctxt,
+pub fn parse_region_data<F>(data: &[u8], crate_num: ast::CrateNum, pos: usize, tcx: &ty::ctxt,
                             conv: F) -> ty::Region where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
 {
@@ -174,7 +174,7 @@ pub fn parse_region_data<F>(data: &[u8], crate_num: ast::CrateNum, pos: uint, tc
     parse_region(&mut st, conv)
 }
 
-pub fn parse_bare_fn_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
+pub fn parse_bare_fn_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize,
                                       tcx: &ty::ctxt<'tcx>, conv: F)
                                       -> ty::BareFnTy<'tcx> where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
@@ -184,7 +184,7 @@ pub fn parse_bare_fn_ty_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos
     parse_bare_fn_ty(&mut st, conv)
 }
 
-pub fn parse_trait_ref_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
+pub fn parse_trait_ref_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize,
                                      tcx: &ty::ctxt<'tcx>, conv: F)
                                      -> Rc<ty::TraitRef<'tcx>> where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
@@ -194,7 +194,7 @@ pub fn parse_trait_ref_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos:
     parse_trait_ref(&mut st, conv)
 }
 
-pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: uint,
+pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: usize,
                                   tcx: &ty::ctxt<'tcx>, conv: F) -> subst::Substs<'tcx> where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
 {
@@ -204,7 +204,7 @@ pub fn parse_substs_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum, pos: ui
 }
 
 pub fn parse_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum,
-                                  pos: uint, tcx: &ty::ctxt<'tcx>, conv: F)
+                                  pos: usize, tcx: &ty::ctxt<'tcx>, conv: F)
                                   -> ty::ParamBounds<'tcx> where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
 {
@@ -213,7 +213,7 @@ pub fn parse_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum,
 }
 
 pub fn parse_existential_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::CrateNum,
-                                              pos: uint, tcx: &ty::ctxt<'tcx>, conv: F)
+                                              pos: usize, tcx: &ty::ctxt<'tcx>, conv: F)
                                               -> ty::ExistentialBounds<'tcx> where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
 {
@@ -222,7 +222,7 @@ pub fn parse_existential_bounds_data<'tcx, F>(data: &[u8], crate_num: ast::Crate
 }
 
 pub fn parse_builtin_bounds_data<F>(data: &[u8], crate_num: ast::CrateNum,
-                                    pos: uint, tcx: &ty::ctxt, conv: F)
+                                    pos: usize, tcx: &ty::ctxt, conv: F)
                                     -> ty::BuiltinBounds where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
 {
@@ -230,7 +230,7 @@ pub fn parse_builtin_bounds_data<F>(data: &[u8], crate_num: ast::CrateNum,
     parse_builtin_bounds(&mut st, conv)
 }
 
-fn parse_size(st: &mut PState) -> Option<uint> {
+fn parse_size(st: &mut PState) -> Option<usize> {
     assert_eq!(next(st), '/');
 
     if peek(st) == '|' {
@@ -305,7 +305,7 @@ fn parse_bound_region_<F>(st: &mut PState, conv: &mut F) -> ty::BoundRegion wher
         }
         '[' => {
             let def = parse_def_(st, RegionParameter, conv);
-            let ident = token::str_to_ident(&parse_str(st, ']')[]);
+            let ident = token::str_to_ident(&parse_str(st, ']'));
             ty::BrNamed(def, ident.name)
         }
         'f' => {
@@ -344,7 +344,7 @@ fn parse_region_<F>(st: &mut PState, conv: &mut F) -> ty::Region where
         assert_eq!(next(st), '|');
         let index = parse_u32(st);
         assert_eq!(next(st), '|');
-        let nm = token::str_to_ident(&parse_str(st, ']')[]);
+        let nm = token::str_to_ident(&parse_str(st, ']'));
         ty::ReEarlyBound(node_id, space, index, nm.name)
       }
       'f' => {
@@ -447,8 +447,8 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w
     let tcx = st.tcx;
     match next(st) {
       'b' => return tcx.types.bool,
-      'i' => { /* eat the s of is */ next(st); return tcx.types.int },
-      'u' => { /* eat the s of us */ next(st); return tcx.types.uint },
+      'i' => { /* eat the s of is */ next(st); return tcx.types.isize },
+      'u' => { /* eat the s of us */ next(st); return tcx.types.usize },
       'M' => {
         match next(st) {
           'b' => return tcx.types.u8,
@@ -485,7 +485,7 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w
         assert_eq!(next(st), '|');
         let space = parse_param_space(st);
         assert_eq!(next(st), '|');
-        let name = token::intern(&parse_str(st, ']')[]);
+        let name = token::intern(&parse_str(st, ']'));
         return ty::mk_param(tcx, space, index, name);
       }
       '~' => return ty::mk_uniq(tcx, parse_ty_(st, conv)),
@@ -555,11 +555,9 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w
       'k' => {
           assert_eq!(next(st), '[');
           let did = parse_def_(st, ClosureSource, conv);
-          let region = parse_region_(st, conv);
           let substs = parse_substs_(st, conv);
           assert_eq!(next(st), ']');
-          return ty::mk_closure(st.tcx, did,
-                  st.tcx.mk_region(region), st.tcx.mk_substs(substs));
+          return ty::mk_closure(st.tcx, did, st.tcx.mk_substs(substs));
       }
       'P' => {
           assert_eq!(next(st), '[');
@@ -594,21 +592,21 @@ fn parse_def_<F>(st: &mut PState, source: DefIdSource, conv: &mut F) -> ast::Def
     return (*conv)(source, scan(st, |c| { c == '|' }, parse_def_id));
 }
 
-fn parse_uint(st: &mut PState) -> uint {
+fn parse_uint(st: &mut PState) -> usize {
     let mut n = 0;
     loop {
         let cur = peek(st);
         if cur < '0' || cur > '9' { return n; }
         st.pos = st.pos + 1;
         n *= 10;
-        n += (cur as uint) - ('0' as uint);
+        n += (cur as usize) - ('0' as usize);
     };
 }
 
 fn parse_u32(st: &mut PState) -> u32 {
     let n = parse_uint(st);
     let m = n as u32;
-    assert_eq!(m as uint, n);
+    assert_eq!(m as usize, n);
     m
 }
 
@@ -616,7 +614,7 @@ fn parse_param_space(st: &mut PState) -> subst::ParamSpace {
     subst::ParamSpace::from_uint(parse_uint(st))
 }
 
-fn parse_hex(st: &mut PState) -> uint {
+fn parse_hex(st: &mut PState) -> usize {
     let mut n = 0;
     loop {
         let cur = peek(st);
@@ -624,8 +622,8 @@ fn parse_hex(st: &mut PState) -> uint {
         st.pos = st.pos + 1;
         n *= 16;
         if '0' <= cur && cur <= '9' {
-            n += (cur as uint) - ('0' as uint);
-        } else { n += 10 + (cur as uint) - ('a' as uint); }
+            n += (cur as usize) - ('0' as usize);
+        } else { n += 10 + (cur as usize) - ('a' as usize); }
     };
 }
 
@@ -727,14 +725,14 @@ pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
     let def_part = &buf[colon_idx + 1..len];
 
     let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| {
-        s.parse::<uint>().ok()
+        s.parse::<usize>().ok()
     }) {
        Some(cn) => cn as ast::CrateNum,
        None => panic!("internal error: parse_def_id: crate number expected, found {:?}",
                      crate_part)
     };
     let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
-        s.parse::<uint>().ok()
+        s.parse::<usize>().ok()
     }) {
        Some(dn) => dn as ast::NodeId,
        None => panic!("internal error: parse_def_id: id expected, found {:?}",
@@ -744,7 +742,7 @@ pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
 }
 
 pub fn parse_predicate_data<'tcx, F>(data: &[u8],
-                                     start: uint,
+                                     start: usize,
                                      crate_num: ast::CrateNum,
                                      tcx: &ty::ctxt<'tcx>,
                                      conv: F)
@@ -796,7 +794,7 @@ fn parse_projection_predicate_<'a,'tcx, F>(
     }
 }
 
-pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: uint,
+pub fn parse_type_param_def_data<'tcx, F>(data: &[u8], start: usize,
                                           crate_num: ast::CrateNum, tcx: &ty::ctxt<'tcx>,
                                           conv: F) -> ty::TypeParameterDef<'tcx> where
     F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
@@ -822,7 +820,6 @@ fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
     assert_eq!(next(st), '|');
     let index = parse_u32(st);
     assert_eq!(next(st), '|');
-    let bounds = parse_bounds_(st, conv);
     let default = parse_opt(st, |st| parse_ty_(st, conv));
     let object_lifetime_default = parse_object_lifetime_default(st, conv);
 
@@ -831,7 +828,6 @@ fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
         def_id: def_id,
         space: space,
         index: index,
-        bounds: bounds,
         default: default,
         object_lifetime_default: object_lifetime_default,
     }
@@ -924,18 +920,18 @@ fn parse_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
 {
     let builtin_bounds = parse_builtin_bounds_(st, conv);
 
+    let region_bounds = parse_region_bounds_(st, conv);
+
     let mut param_bounds = ty::ParamBounds {
-        region_bounds: Vec::new(),
+        region_bounds: region_bounds,
         builtin_bounds: builtin_bounds,
         trait_bounds: Vec::new(),
         projection_bounds: Vec::new(),
     };
+
+
     loop {
         match next(st) {
-            'R' => {
-                param_bounds.region_bounds.push(
-                    parse_region_(st, conv));
-            }
             'I' => {
                 param_bounds.trait_bounds.push(
                     ty::Binder(parse_trait_ref_(st, conv)));
@@ -953,3 +949,17 @@ fn parse_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
         }
     }
 }
+
+fn parse_region_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
+                              -> Vec<ty::Region> where
+    F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
+{
+    let mut region_bounds = Vec::new();
+    loop {
+        match next(st) {
+            'R' => { region_bounds.push(parse_region_(st, conv)); }
+            '.' => { return region_bounds; }
+            c => { panic!("parse_bounds: bad bounds ('{}')", c); }
+        }
+    }
+}
index e1e9d49dd05859d3df5e3ff67b98c2f6d17ef0cf..7a2df4966283a6d7339d3040e2e312fa927a32c5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -14,6 +14,7 @@
 #![allow(non_camel_case_types)]
 
 use std::cell::RefCell;
+use std::io::prelude::*;
 
 use middle::region;
 use middle::subst;
@@ -27,9 +28,9 @@ use syntax::ast;
 use syntax::diagnostic::SpanHandler;
 use syntax::parse::token;
 
-use rbml::io::SeekableMemWriter;
+use rbml::writer::Encoder;
 
-macro_rules! mywrite { ($($arg:tt)*) => ({ write!($($arg)*); }) }
+macro_rules! mywrite { ($w:expr, $($arg:tt)*) => ({ write!($w.writer, $($arg)*); }) }
 
 pub struct ctxt<'a, 'tcx: 'a> {
     pub diag: &'a SpanHandler,
@@ -49,19 +50,21 @@ pub struct ty_abbrev {
 
 pub type abbrev_map<'tcx> = RefCell<FnvHashMap<Ty<'tcx>, ty_abbrev>>;
 
-pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
+pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
     match cx.abbrevs.borrow_mut().get(&t) {
-        Some(a) => { w.write_all(a.s.as_bytes()); return; }
+        Some(a) => { w.writer.write_all(a.s.as_bytes()); return; }
         None => {}
     }
-    let pos = w.tell().unwrap();
+
+    // type abbreviations needs a stable position
+    let pos = w.mark_stable_position();
 
     match t.sty {
         ty::ty_bool => mywrite!(w, "b"),
         ty::ty_char => mywrite!(w, "c"),
         ty::ty_int(t) => {
             match t {
-                ast::TyIs(_) => mywrite!(w, "is"),
+                ast::TyIs => mywrite!(w, "is"),
                 ast::TyI8 => mywrite!(w, "MB"),
                 ast::TyI16 => mywrite!(w, "MW"),
                 ast::TyI32 => mywrite!(w, "ML"),
@@ -70,7 +73,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
         }
         ty::ty_uint(t) => {
             match t {
-                ast::TyUs(_) => mywrite!(w, "us"),
+                ast::TyUs => mywrite!(w, "us"),
                 ast::TyU8 => mywrite!(w, "Mb"),
                 ast::TyU16 => mywrite!(w, "Mw"),
                 ast::TyU32 => mywrite!(w, "Ml"),
@@ -139,9 +142,8 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
             enc_substs(w, cx, substs);
             mywrite!(w, "]");
         }
-        ty::ty_closure(def, region, substs) => {
+        ty::ty_closure(def, substs) => {
             mywrite!(w, "k[{}|", (cx.ds)(def));
-            enc_region(w, cx, *region);
             enc_substs(w, cx, substs);
             mywrite!(w, "]");
         }
@@ -153,12 +155,9 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
         ty::ty_err => {
             mywrite!(w, "e");
         }
-        ty::ty_open(_) => {
-            cx.diag.handler().bug("unexpected type in enc_sty (ty_open)");
-        }
     }
 
-    let end = w.tell().unwrap();
+    let end = w.mark_stable_position();
     let len = end - pos;
     fn estimate_sz(u: u64) -> u64 {
         let mut n = u;
@@ -175,21 +174,21 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
     }
 }
 
-fn enc_mutability(w: &mut SeekableMemWriter, mt: ast::Mutability) {
+fn enc_mutability(w: &mut Encoder, mt: ast::Mutability) {
     match mt {
         ast::MutImmutable => (),
         ast::MutMutable => mywrite!(w, "m"),
     }
 }
 
-fn enc_mt<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+fn enc_mt<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
                     mt: ty::mt<'tcx>) {
     enc_mutability(w, mt.mutbl);
     enc_ty(w, cx, mt.ty);
 }
 
-fn enc_opt<T, F>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: F) where
-    F: FnOnce(&mut SeekableMemWriter, T),
+fn enc_opt<T, F>(w: &mut Encoder, t: Option<T>, enc_f: F) where
+    F: FnOnce(&mut Encoder, T),
 {
     match t {
         None => mywrite!(w, "n"),
@@ -200,11 +199,11 @@ fn enc_opt<T, F>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: F) where
     }
 }
 
-fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut SeekableMemWriter,
+fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut Encoder,
                                            cx: &ctxt<'a, 'tcx>,
                                            v: &VecPerParamSpace<T>,
                                            mut op: F) where
-    F: FnMut(&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T),
+    F: FnMut(&mut Encoder, &ctxt<'a, 'tcx>, &T),
 {
     for &space in &subst::ParamSpace::all() {
         mywrite!(w, "[");
@@ -215,14 +214,14 @@ fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut SeekableMemWriter,
     }
 }
 
-pub fn enc_substs<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_substs<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
                             substs: &subst::Substs<'tcx>) {
     enc_region_substs(w, cx, &substs.regions);
     enc_vec_per_param_space(w, cx, &substs.types,
                             |w, cx, &ty| enc_ty(w, cx, ty));
 }
 
-fn enc_region_substs(w: &mut SeekableMemWriter, cx: &ctxt, substs: &subst::RegionSubsts) {
+fn enc_region_substs(w: &mut Encoder, cx: &ctxt, substs: &subst::RegionSubsts) {
     match *substs {
         subst::ErasedRegions => {
             mywrite!(w, "e");
@@ -235,7 +234,7 @@ fn enc_region_substs(w: &mut SeekableMemWriter, cx: &ctxt, substs: &subst::Regio
     }
 }
 
-pub fn enc_region(w: &mut SeekableMemWriter, cx: &ctxt, r: ty::Region) {
+pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
     match r {
         ty::ReLateBound(id, br) => {
             mywrite!(w, "b[{}|", id.depth);
@@ -274,7 +273,7 @@ pub fn enc_region(w: &mut SeekableMemWriter, cx: &ctxt, r: ty::Region) {
     }
 }
 
-fn enc_scope(w: &mut SeekableMemWriter, _cx: &ctxt, scope: region::CodeExtent) {
+fn enc_scope(w: &mut Encoder, _cx: &ctxt, scope: region::CodeExtent) {
     match scope {
         region::CodeExtent::Misc(node_id) => mywrite!(w, "M{}", node_id),
         region::CodeExtent::Remainder(region::BlockRemainder {
@@ -283,12 +282,12 @@ fn enc_scope(w: &mut SeekableMemWriter, _cx: &ctxt, scope: region::CodeExtent) {
     }
 }
 
-fn enc_destruction_scope_data(w: &mut SeekableMemWriter,
+fn enc_destruction_scope_data(w: &mut Encoder,
                               d: region::DestructionScopeData) {
     mywrite!(w, "{}", d.node_id);
 }
 
-fn enc_bound_region(w: &mut SeekableMemWriter, cx: &ctxt, br: ty::BoundRegion) {
+fn enc_bound_region(w: &mut Encoder, cx: &ctxt, br: ty::BoundRegion) {
     match br {
         ty::BrAnon(idx) => {
             mywrite!(w, "a{}|", idx);
@@ -307,40 +306,40 @@ fn enc_bound_region(w: &mut SeekableMemWriter, cx: &ctxt, br: ty::BoundRegion) {
     }
 }
 
-pub fn enc_trait_ref<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_trait_ref<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
                                s: &ty::TraitRef<'tcx>) {
     mywrite!(w, "{}|", (cx.ds)(s.def_id));
     enc_substs(w, cx, s.substs);
 }
 
-fn enc_unsafety(w: &mut SeekableMemWriter, p: ast::Unsafety) {
+fn enc_unsafety(w: &mut Encoder, p: ast::Unsafety) {
     match p {
         ast::Unsafety::Normal => mywrite!(w, "n"),
         ast::Unsafety::Unsafe => mywrite!(w, "u"),
     }
 }
 
-fn enc_abi(w: &mut SeekableMemWriter, abi: Abi) {
+fn enc_abi(w: &mut Encoder, abi: Abi) {
     mywrite!(w, "[");
     mywrite!(w, "{}", abi.name());
     mywrite!(w, "]")
 }
 
-pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
                                 ft: &ty::BareFnTy<'tcx>) {
     enc_unsafety(w, ft.unsafety);
     enc_abi(w, ft.abi);
     enc_fn_sig(w, cx, &ft.sig);
 }
 
-pub fn enc_closure_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_closure_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
                                 ft: &ty::ClosureTy<'tcx>) {
     enc_unsafety(w, ft.unsafety);
     enc_fn_sig(w, cx, &ft.sig);
     enc_abi(w, ft.abi);
 }
 
-fn enc_fn_sig<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+fn enc_fn_sig<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
                         fsig: &ty::PolyFnSig<'tcx>) {
     mywrite!(w, "[");
     for ty in &fsig.0.inputs {
@@ -362,7 +361,7 @@ fn enc_fn_sig<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
     }
 }
 
-pub fn enc_builtin_bounds(w: &mut SeekableMemWriter, _cx: &ctxt, bs: &ty::BuiltinBounds) {
+pub fn enc_builtin_bounds(w: &mut Encoder, _cx: &ctxt, bs: &ty::BuiltinBounds) {
     for bound in bs {
         match bound {
             ty::BoundSend => mywrite!(w, "S"),
@@ -375,7 +374,7 @@ pub fn enc_builtin_bounds(w: &mut SeekableMemWriter, _cx: &ctxt, bs: &ty::Builti
     mywrite!(w, ".");
 }
 
-pub fn enc_existential_bounds<'a,'tcx>(w: &mut SeekableMemWriter,
+pub fn enc_existential_bounds<'a,'tcx>(w: &mut Encoder,
                                        cx: &ctxt<'a,'tcx>,
                                        bs: &ty::ExistentialBounds<'tcx>) {
     let param_bounds = ty::ParamBounds { trait_bounds: vec!(),
@@ -385,14 +384,11 @@ pub fn enc_existential_bounds<'a,'tcx>(w: &mut SeekableMemWriter,
     enc_bounds(w, cx, &param_bounds);
 }
 
-pub fn enc_bounds<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_bounds<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
                             bs: &ty::ParamBounds<'tcx>) {
     enc_builtin_bounds(w, cx, &bs.builtin_bounds);
 
-    for &r in &bs.region_bounds {
-        mywrite!(w, "R");
-        enc_region(w, cx, r);
-    }
+    enc_region_bounds(w, cx, &bs.region_bounds);
 
     for tp in &bs.trait_bounds {
         mywrite!(w, "I");
@@ -407,17 +403,27 @@ pub fn enc_bounds<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
     mywrite!(w, ".");
 }
 
-pub fn enc_type_param_def<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_region_bounds<'a, 'tcx>(w: &mut Encoder,
+                            cx: &ctxt<'a, 'tcx>,
+                            rs: &[ty::Region]) {
+    for &r in rs {
+        mywrite!(w, "R");
+        enc_region(w, cx, r);
+    }
+
+    mywrite!(w, ".");
+}
+
+pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
                                     v: &ty::TypeParameterDef<'tcx>) {
     mywrite!(w, "{}:{}|{}|{}|",
              token::get_name(v.name), (cx.ds)(v.def_id),
              v.space.to_uint(), v.index);
-    enc_bounds(w, cx, &v.bounds);
     enc_opt(w, v.default, |w, t| enc_ty(w, cx, t));
     enc_object_lifetime_default(w, cx, v.object_lifetime_default);
 }
 
-fn enc_object_lifetime_default<'a, 'tcx>(w: &mut SeekableMemWriter,
+fn enc_object_lifetime_default<'a, 'tcx>(w: &mut Encoder,
                                          cx: &ctxt<'a, 'tcx>,
                                          default: Option<ty::ObjectLifetimeDefault>)
 {
@@ -431,7 +437,7 @@ fn enc_object_lifetime_default<'a, 'tcx>(w: &mut SeekableMemWriter,
     }
 }
 
-pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
+pub fn enc_predicate<'a, 'tcx>(w: &mut Encoder,
                                cx: &ctxt<'a, 'tcx>,
                                p: &ty::Predicate<'tcx>)
 {
@@ -462,7 +468,7 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
     }
 }
 
-fn enc_projection_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
+fn enc_projection_predicate<'a, 'tcx>(w: &mut Encoder,
                                       cx: &ctxt<'a, 'tcx>,
                                       data: &ty::ProjectionPredicate<'tcx>) {
     enc_trait_ref(w, cx, &*data.projection_ty.trait_ref);
index 7143e3caac208f135dda9d44515bbcdd7dcee59c..698cf105ae53c12d6b1a5d4dabec5175f1dc6c63 100644 (file)
@@ -19,71 +19,60 @@ use middle::ty::{self, Ty};
 use syntax::ast;
 use util::ppaux::Repr;
 
-pub const NO_REGIONS: uint = 1;
-pub const NO_TPS: uint = 2;
+pub const NO_REGIONS: usize = 1;
+pub const NO_TPS: usize = 2;
 
-pub fn check_path_args(tcx: &ty::ctxt,
-                       path: &ast::Path,
-                       flags: uint) {
-    if (flags & NO_TPS) != 0 {
-        if path.segments.iter().any(|s| s.parameters.has_types()) {
-            span_err!(tcx.sess, path.span, E0109,
-                "type parameters are not allowed on this type");
+pub fn check_path_args(tcx: &ty::ctxt, segments: &[ast::PathSegment], flags: usize) {
+    for segment in segments {
+        if (flags & NO_TPS) != 0 {
+            for typ in segment.parameters.types() {
+                span_err!(tcx.sess, typ.span, E0109,
+                          "type parameters are not allowed on this type");
+                break;
+            }
         }
-    }
 
-    if (flags & NO_REGIONS) != 0 {
-        if path.segments.iter().any(|s| s.parameters.has_lifetimes()) {
-            span_err!(tcx.sess, path.span, E0110,
-                "region parameters are not allowed on this type");
+        if (flags & NO_REGIONS) != 0 {
+            for lifetime in segment.parameters.lifetimes() {
+                span_err!(tcx.sess, lifetime.span, E0110,
+                          "lifetime parameters are not allowed on this type");
+                break;
+            }
         }
     }
 }
 
+pub fn prim_ty_to_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
+                           segments: &[ast::PathSegment],
+                           nty: ast::PrimTy)
+                           -> Ty<'tcx> {
+    check_path_args(tcx, segments, NO_TPS | NO_REGIONS);
+    match nty {
+        ast::TyBool => tcx.types.bool,
+        ast::TyChar => tcx.types.char,
+        ast::TyInt(it) => ty::mk_mach_int(tcx, it),
+        ast::TyUint(uit) => ty::mk_mach_uint(tcx, uit),
+        ast::TyFloat(ft) => ty::mk_mach_float(tcx, ft),
+        ast::TyStr => ty::mk_str(tcx)
+    }
+}
+
 pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
                                -> Option<Ty<'tcx>> {
-    match ast_ty.node {
-        ast::TyPath(ref path, id) => {
-            let a_def = match tcx.def_map.borrow().get(&id) {
-                None => {
-                    tcx.sess.span_bug(ast_ty.span,
-                                      &format!("unbound path {}",
-                                              path.repr(tcx))[])
-                }
-                Some(&d) => d
-            };
-            match a_def {
-                def::DefPrimTy(nty) => {
-                    match nty {
-                        ast::TyBool => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(tcx.types.bool)
-                        }
-                        ast::TyChar => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(tcx.types.char)
-                        }
-                        ast::TyInt(it) => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_mach_int(tcx, it))
-                        }
-                        ast::TyUint(uit) => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_mach_uint(tcx, uit))
-                        }
-                        ast::TyFloat(ft) => {
-                            check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                            Some(ty::mk_mach_float(tcx, ft))
-                        }
-                        ast::TyStr => {
-                            Some(ty::mk_str(tcx))
-                        }
-                    }
-                }
-                _ => None
+    if let ast::TyPath(None, ref path) = ast_ty.node {
+        let def = match tcx.def_map.borrow().get(&ast_ty.id) {
+            None => {
+                tcx.sess.span_bug(ast_ty.span,
+                                  &format!("unbound path {}", path.repr(tcx)))
             }
+            Some(d) => d.full_def()
+        };
+        if let def::DefPrimTy(nty) = def {
+            Some(prim_ty_to_ty(tcx, &path.segments, nty))
+        } else {
+            None
         }
-        _ => None
+    } else {
+        None
     }
 }
-
index ae10eb686b010244ed71bcdf07de52c2d93616e6..b6061f39233d20b26d2f7a11535223310f67c192 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -25,30 +25,34 @@ use metadata::tydecode::{RegionParameter, ClosureSource};
 use metadata::tyencode;
 use middle::check_const::ConstQualif;
 use middle::mem_categorization::Typer;
+use middle::privacy::{AllPublic, LastMod};
 use middle::subst;
 use middle::subst::VecPerParamSpace;
 use middle::ty::{self, Ty, MethodCall, MethodCallee, MethodOrigin};
 use util::ppaux::ty_to_string;
 
 use syntax::{ast, ast_map, ast_util, codemap, fold};
-use syntax::ast_util::PostExpansionMethod;
 use syntax::codemap::Span;
 use syntax::fold::Folder;
 use syntax::parse::token;
 use syntax::ptr::P;
 use syntax;
 
-use std::old_io::Seek;
+use std::cell::Cell;
+use std::io::SeekFrom;
+use std::io::prelude::*;
 use std::num::FromPrimitive;
 use std::rc::Rc;
+use std::fmt::Debug;
 
-use rbml::io::SeekableMemWriter;
-use rbml::{reader, writer};
+use rbml::reader;
+use rbml::writer::Encoder;
 use rbml;
 use serialize;
 use serialize::{Decodable, Decoder, DecoderHelpers, Encodable};
-use serialize::{EncoderHelpers};
+use serialize::EncoderHelpers;
 
+#[cfg(test)] use std::io::Cursor;
 #[cfg(test)] use syntax::parse;
 #[cfg(test)] use syntax::print::pprust;
 
@@ -56,7 +60,9 @@ struct DecodeContext<'a, 'b, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
     cdata: &'b cstore::crate_metadata,
     from_id_range: ast_util::IdRange,
-    to_id_range: ast_util::IdRange
+    to_id_range: ast_util::IdRange,
+    // Cache the last used filemap for translating spans as an optimization.
+    last_filemap_index: Cell<usize>,
 }
 
 trait tr {
@@ -67,8 +73,6 @@ trait tr_intern {
     fn tr_intern(&self, dcx: &DecodeContext) -> ast::DefId;
 }
 
-pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
-
 // ______________________________________________________________________
 // Top-level methods.
 
@@ -78,21 +82,18 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
     let id = match ii {
         e::IIItemRef(i) => i.id,
         e::IIForeignRef(i) => i.id,
-        e::IITraitItemRef(_, &ast::ProvidedMethod(ref m)) => m.id,
-        e::IITraitItemRef(_, &ast::RequiredMethod(ref m)) => m.id,
-        e::IITraitItemRef(_, &ast::TypeTraitItem(ref ti)) => ti.ty_param.id,
-        e::IIImplItemRef(_, &ast::MethodImplItem(ref m)) => m.id,
-        e::IIImplItemRef(_, &ast::TypeImplItem(ref ti)) => ti.id,
+        e::IITraitItemRef(_, ti) => ti.id,
+        e::IIImplItemRef(_, ii) => ii.id,
     };
     debug!("> Encoding inlined item: {} ({:?})",
            ecx.tcx.map.path_to_string(id),
-           rbml_w.writer.tell());
+           rbml_w.writer.seek(SeekFrom::Current(0)));
 
     // Folding could be avoided with a smarter encoder.
     let ii = simplify_ast(ii);
     let id_range = ast_util::compute_id_range_for_inlined_item(&ii);
 
-    rbml_w.start_tag(c::tag_ast as uint);
+    rbml_w.start_tag(c::tag_ast as usize);
     id_range.encode(rbml_w);
     encode_ast(rbml_w, &ii);
     encode_side_tables_for_ii(ecx, rbml_w, &ii);
@@ -100,7 +101,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
 
     debug!("< Encoded inlined fn: {} ({:?})",
            ecx.tcx.map.path_to_string(id),
-           rbml_w.writer.tell());
+           rbml_w.writer.seek(SeekFrom::Current(0)));
 }
 
 impl<'a, 'b, 'c, 'tcx> ast_map::FoldOps for &'a DecodeContext<'b, 'c, 'tcx> {
@@ -120,6 +121,8 @@ impl<'a, 'b, 'c, 'tcx> ast_map::FoldOps for &'a DecodeContext<'b, 'c, 'tcx> {
     }
 }
 
+/// Decodes an item from its AST in the cdata's metadata and adds it to the
+/// ast-map.
 pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
                                  tcx: &ty::ctxt<'tcx>,
                                  path: Vec<ast_map::PathElem>,
@@ -143,7 +146,8 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
             cdata: cdata,
             tcx: tcx,
             from_id_range: from_id_range,
-            to_id_range: to_id_range
+            to_id_range: to_id_range,
+            last_filemap_index: Cell::new(0)
         };
         let raw_ii = decode_ast(ast_doc);
         let ii = ast_map::map_decoded_item(&dcx.tcx.map, path, raw_ii, dcx);
@@ -151,19 +155,8 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
         let ident = match *ii {
             ast::IIItem(ref i) => i.ident,
             ast::IIForeign(ref i) => i.ident,
-            ast::IITraitItem(_, ref ti) => {
-                match *ti {
-                    ast::ProvidedMethod(ref m) => m.pe_ident(),
-                    ast::RequiredMethod(ref ty_m) => ty_m.ident,
-                    ast::TypeTraitItem(ref ti) => ti.ty_param.ident,
-                }
-            },
-            ast::IIImplItem(_, ref m) => {
-                match *m {
-                    ast::MethodImplItem(ref m) => m.pe_ident(),
-                    ast::TypeImplItem(ref ti) => ti.ident,
-                }
-            }
+            ast::IITraitItem(_, ref ti) => ti.ident,
+            ast::IIImplItem(_, ref ii) => ii.ident
         };
         debug!("Fn named: {}", token::get_ident(ident));
         debug!("< Decoded inlined fn: {}::{}",
@@ -204,7 +197,9 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> {
     pub fn tr_id(&self, id: ast::NodeId) -> ast::NodeId {
         // from_id_range should be non-empty
         assert!(!self.from_id_range.empty());
-        (id - self.from_id_range.min + self.to_id_range.min)
+        // Use wrapping arithmetic because otherwise it introduces control flow.
+        // Maybe we should just have the control flow? -- aatch
+        (id.wrapping_sub(self.from_id_range.min).wrapping_add(self.to_id_range.min))
     }
 
     /// Translates an EXTERNAL def-id, converting the crate number from the one used in the encoded
@@ -232,8 +227,62 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> {
         assert_eq!(did.krate, ast::LOCAL_CRATE);
         ast::DefId { krate: ast::LOCAL_CRATE, node: self.tr_id(did.node) }
     }
-    pub fn tr_span(&self, _span: Span) -> Span {
-        codemap::DUMMY_SP // FIXME (#1972): handle span properly
+
+    /// Translates a `Span` from an extern crate to the corresponding `Span`
+    /// within the local crate's codemap. `creader::import_codemap()` will
+    /// already have allocated any additionally needed FileMaps in the local
+    /// codemap as a side-effect of creating the crate_metadata's
+    /// `codemap_import_info`.
+    pub fn tr_span(&self, span: Span) -> Span {
+        let imported_filemaps = &self.cdata.codemap_import_info[..];
+
+        let span = if span.lo > span.hi {
+            // Currently macro expansion sometimes produces invalid Span values
+            // where lo > hi. In order not to crash the compiler when trying to
+            // translate these values, let's transform them into something we
+            // can handle (and which will produce useful debug locations at
+            // least some of the time).
+            // This workaround is only necessary as long as macro expansion is
+            // not fixed. FIXME(#23480)
+            codemap::mk_sp(span.lo, span.lo)
+        } else {
+            span
+        };
+
+        let filemap_index = {
+            // Optimize for the case that most spans within a translated item
+            // originate from the same filemap.
+            let last_filemap_index = self.last_filemap_index.get();
+
+            if span.lo >= imported_filemaps[last_filemap_index].original_start_pos &&
+               span.lo <= imported_filemaps[last_filemap_index].original_end_pos &&
+               span.hi >= imported_filemaps[last_filemap_index].original_start_pos &&
+               span.hi <= imported_filemaps[last_filemap_index].original_end_pos {
+                last_filemap_index
+            } else {
+                let mut a = 0;
+                let mut b = imported_filemaps.len();
+
+                while b - a > 1 {
+                    let m = (a + b) / 2;
+                    if imported_filemaps[m].original_start_pos > span.lo {
+                        b = m;
+                    } else {
+                        a = m;
+                    }
+                }
+
+                self.last_filemap_index.set(a);
+                a
+            }
+        };
+
+        let lo = (span.lo - imported_filemaps[filemap_index].original_start_pos) +
+                  imported_filemaps[filemap_index].translated_filemap.start_pos;
+        let hi = (span.hi - imported_filemaps[filemap_index].original_start_pos) +
+                  imported_filemaps[filemap_index].translated_filemap.start_pos;
+
+        codemap::mk_sp(lo, hi)
     }
 }
 
@@ -265,9 +314,11 @@ trait def_id_encoder_helpers {
     fn emit_def_id(&mut self, did: ast::DefId);
 }
 
-impl<S:serialize::Encoder> def_id_encoder_helpers for S {
+impl<S:serialize::Encoder> def_id_encoder_helpers for S
+    where <S as serialize::serialize::Encoder>::Error: Debug
+{
     fn emit_def_id(&mut self, did: ast::DefId) {
-        did.encode(self).ok().unwrap()
+        did.encode(self).unwrap()
     }
 }
 
@@ -277,15 +328,18 @@ trait def_id_decoder_helpers {
                          cdata: &cstore::crate_metadata) -> ast::DefId;
 }
 
-impl<D:serialize::Decoder> def_id_decoder_helpers for D {
+impl<D:serialize::Decoder> def_id_decoder_helpers for D
+    where <D as serialize::serialize::Decoder>::Error: Debug
+{
     fn read_def_id(&mut self, dcx: &DecodeContext) -> ast::DefId {
-        let did: ast::DefId = Decodable::decode(self).ok().unwrap();
+        let did: ast::DefId = Decodable::decode(self).unwrap();
         did.tr(dcx)
     }
 
     fn read_def_id_nodcx(&mut self,
-                         cdata: &cstore::crate_metadata) -> ast::DefId {
-        let did: ast::DefId = Decodable::decode(self).ok().unwrap();
+                         cdata: &cstore::crate_metadata)
+                         -> ast::DefId {
+        let did: ast::DefId = Decodable::decode(self).unwrap();
         decoder::translate_def_id(cdata, did)
     }
 }
@@ -306,7 +360,7 @@ impl<D:serialize::Decoder> def_id_decoder_helpers for D {
 // but eventually we should add entries to the local codemap as required.
 
 fn encode_ast(rbml_w: &mut Encoder, item: &ast::InlinedItem) {
-    rbml_w.start_tag(c::tag_tree as uint);
+    rbml_w.start_tag(c::tag_tree as usize);
     item.encode(rbml_w);
     rbml_w.end_tag();
 }
@@ -365,38 +419,16 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem {
                             .expect_one("expected one item"))
         }
         e::IITraitItemRef(d, ti) => {
-            ast::IITraitItem(d, match *ti {
-                ast::ProvidedMethod(ref m) => {
-                    ast::ProvidedMethod(
-                        fold::noop_fold_method(m.clone(), &mut fld)
-                            .expect_one("noop_fold_method must produce \
-                                         exactly one method"))
-                }
-                ast::RequiredMethod(ref ty_m) => {
-                    ast::RequiredMethod(
-                        fold::noop_fold_type_method(ty_m.clone(), &mut fld))
-                }
-                ast::TypeTraitItem(ref associated_type) => {
-                    ast::TypeTraitItem(
-                        P(fold::noop_fold_associated_type(
-                            (**associated_type).clone(),
-                            &mut fld)))
-                }
-            })
+            ast::IITraitItem(d,
+                fold::noop_fold_trait_item(P(ti.clone()), &mut fld)
+                    .expect_one("noop_fold_trait_item must produce \
+                                 exactly one trait item"))
         }
-        e::IIImplItemRef(d, m) => {
-            ast::IIImplItem(d, match *m {
-                ast::MethodImplItem(ref m) => {
-                    ast::MethodImplItem(
-                        fold::noop_fold_method(m.clone(), &mut fld)
-                            .expect_one("noop_fold_method must produce \
-                                         exactly one method"))
-                }
-                ast::TypeImplItem(ref td) => {
-                    ast::TypeImplItem(
-                        P(fold::noop_fold_typedef((**td).clone(), &mut fld)))
-                }
-            })
+        e::IIImplItemRef(d, ii) => {
+            ast::IIImplItem(d,
+                fold::noop_fold_impl_item(P(ii.clone()), &mut fld)
+                    .expect_one("noop_fold_impl_item must produce \
+                                 exactly one impl item"))
         }
         e::IIForeignRef(i) => {
             ast::IIForeign(fold::noop_fold_foreign_item(P(i.clone()), &mut fld))
@@ -405,7 +437,7 @@ fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem {
 }
 
 fn decode_ast(par_doc: rbml::Doc) -> ast::InlinedItem {
-    let chi_doc = par_doc.get(c::tag_tree as uint);
+    let chi_doc = par_doc.get(c::tag_tree as usize);
     let mut d = reader::Decoder::new(chi_doc);
     Decodable::decode(&mut d).unwrap()
 }
@@ -413,9 +445,8 @@ fn decode_ast(par_doc: rbml::Doc) -> ast::InlinedItem {
 // ______________________________________________________________________
 // Encoding and decoding of ast::def
 
-fn decode_def(dcx: &DecodeContext, doc: rbml::Doc) -> def::Def {
-    let mut dsr = reader::Decoder::new(doc);
-    let def: def::Def = Decodable::decode(&mut dsr).unwrap();
+fn decode_def(dcx: &DecodeContext, dsr: &mut reader::Decoder) -> def::Def {
+    let def: def::Def = Decodable::decode(dsr).unwrap();
     def.tr(dcx)
 }
 
@@ -423,13 +454,8 @@ impl tr for def::Def {
     fn tr(&self, dcx: &DecodeContext) -> def::Def {
         match *self {
           def::DefFn(did, is_ctor) => def::DefFn(did.tr(dcx), is_ctor),
-          def::DefStaticMethod(did, p) => {
-            def::DefStaticMethod(did.tr(dcx), p.map(|did2| did2.tr(dcx)))
-          }
-          def::DefMethod(did0, did1, p) => {
-            def::DefMethod(did0.tr(dcx),
-                           did1.map(|did1| did1.tr(dcx)),
-                           p.map(|did2| did2.tr(dcx)))
+          def::DefMethod(did, p) => {
+            def::DefMethod(did.tr(dcx), p.map(|did2| did2.tr(dcx)))
           }
           def::DefSelfTy(nid) => { def::DefSelfTy(dcx.tr_id(nid)) }
           def::DefMod(did) => { def::DefMod(did.tr(dcx)) }
@@ -442,11 +468,8 @@ impl tr for def::Def {
           },
           def::DefTrait(did) => def::DefTrait(did.tr(dcx)),
           def::DefTy(did, is_enum) => def::DefTy(did.tr(dcx), is_enum),
-          def::DefAssociatedTy(did) => def::DefAssociatedTy(did.tr(dcx)),
-          def::DefAssociatedPath(def::TyParamProvenance::FromSelf(did), ident) =>
-              def::DefAssociatedPath(def::TyParamProvenance::FromSelf(did.tr(dcx)), ident),
-          def::DefAssociatedPath(def::TyParamProvenance::FromParam(did), ident) =>
-              def::DefAssociatedPath(def::TyParamProvenance::FromParam(did.tr(dcx)), ident),
+          def::DefAssociatedTy(trait_did, did) =>
+              def::DefAssociatedTy(trait_did.tr(dcx), did.tr(dcx)),
           def::DefPrimTy(p) => def::DefPrimTy(p),
           def::DefTyParam(s, index, def_id, n) => def::DefTyParam(s, index, def_id.tr(dcx), n),
           def::DefUse(did) => def::DefUse(did.tr(dcx)),
@@ -455,9 +478,6 @@ impl tr for def::Def {
           }
           def::DefStruct(did) => def::DefStruct(did.tr(dcx)),
           def::DefRegion(nid) => def::DefRegion(dcx.tr_id(nid)),
-          def::DefTyParamBinder(nid) => {
-            def::DefTyParamBinder(dcx.tr_id(nid))
-          }
           def::DefLabel(nid) => def::DefLabel(dcx.tr_id(nid))
         }
     }
@@ -921,7 +941,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
     fn emit_type_param_def<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
                                type_param_def: &ty::TypeParameterDef<'tcx>) {
         self.emit_opaque(|this| {
-            Ok(tyencode::enc_type_param_def(this.writer,
+            Ok(tyencode::enc_type_param_def(this,
                                          &ecx.ty_str_ctxt(),
                                          type_param_def))
         });
@@ -930,7 +950,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
     fn emit_predicate<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
                           predicate: &ty::Predicate<'tcx>) {
         self.emit_opaque(|this| {
-            Ok(tyencode::enc_predicate(this.writer,
+            Ok(tyencode::enc_predicate(this,
                                        &ecx.ty_str_ctxt(),
                                        predicate))
         });
@@ -964,20 +984,20 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
 
     fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>,
                                    bounds: &ty::ExistentialBounds<'tcx>) {
-        self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this.writer,
+        self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this,
                                                                     &ecx.ty_str_ctxt(),
                                                                     bounds)));
     }
 
     fn emit_builtin_bounds(&mut self, ecx: &e::EncodeContext, bounds: &ty::BuiltinBounds) {
-        self.emit_opaque(|this| Ok(tyencode::enc_builtin_bounds(this.writer,
+        self.emit_opaque(|this| Ok(tyencode::enc_builtin_bounds(this,
                                                                 &ecx.ty_str_ctxt(),
                                                                 bounds)));
     }
 
     fn emit_substs<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
                        substs: &subst::Substs<'tcx>) {
-        self.emit_opaque(|this| Ok(tyencode::enc_substs(this.writer,
+        self.emit_opaque(|this| Ok(tyencode::enc_substs(this,
                                                            &ecx.ty_str_ctxt(),
                                                            substs)));
     }
@@ -994,8 +1014,14 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
                     })
                 }
 
+                ty::AdjustUnsafeFnPointer => {
+                    this.emit_enum_variant("AdjustUnsafeFnPointer", 2, 0, |_| {
+                        Ok(())
+                    })
+                }
+
                 ty::AdjustDerefRef(ref auto_deref_ref) => {
-                    this.emit_enum_variant("AdjustDerefRef", 2, 2, |this| {
+                    this.emit_enum_variant("AdjustDerefRef", 3, 2, |this| {
                         this.emit_enum_variant_arg(0,
                             |this| Ok(this.emit_auto_deref_ref(ecx, auto_deref_ref)))
                     })
@@ -1103,6 +1129,11 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
                         this.emit_enum_variant_arg(1, |this| Ok(this.emit_ty(ecx, self_ty)))
                     })
                 }
+                ty::UnsizeUpcast(target_ty) => {
+                    this.emit_enum_variant("UnsizeUpcast", 3, 1, |this| {
+                        this.emit_enum_variant_arg(0, |this| Ok(this.emit_ty(ecx, target_ty)))
+                    })
+                }
             }
         });
     }
@@ -1119,13 +1150,13 @@ impl<'a> write_tag_and_id for Encoder<'a> {
               f: F) where
         F: FnOnce(&mut Encoder<'a>),
     {
-        self.start_tag(tag_id as uint);
+        self.start_tag(tag_id as usize);
         f(self);
         self.end_tag();
     }
 
     fn id(&mut self, id: ast::NodeId) {
-        self.wr_tagged_u64(c::tag_table_id as uint, id as u64);
+        id.encode(self).unwrap();
     }
 }
 
@@ -1144,7 +1175,7 @@ impl<'a, 'b, 'c, 'tcx> ast_util::IdVisitingOperation for
 fn encode_side_tables_for_ii(ecx: &e::EncodeContext,
                              rbml_w: &mut Encoder,
                              ii: &ast::InlinedItem) {
-    rbml_w.start_tag(c::tag_table as uint);
+    rbml_w.start_tag(c::tag_table as usize);
     ast_util::visit_ids_for_inlined_item(ii, &mut SideTableEncodingIdVisitor {
         ecx: ecx,
         rbml_w: rbml_w
@@ -1159,54 +1190,47 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
 
     debug!("Encoding side tables for id {}", id);
 
-    if let Some(def) = tcx.def_map.borrow().get(&id) {
+    if let Some(def) = tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
         rbml_w.tag(c::tag_table_def, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| (*def).encode(rbml_w).unwrap());
+            def.encode(rbml_w).unwrap();
         })
     }
 
-    if let Some(ty) = tcx.node_types.borrow().get(&id) {
+    if let Some(ty) = tcx.node_types().get(&id) {
         rbml_w.tag(c::tag_table_node_type, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| {
-                rbml_w.emit_ty(ecx, *ty);
-            })
+            rbml_w.emit_ty(ecx, *ty);
         })
     }
 
     if let Some(item_substs) = tcx.item_substs.borrow().get(&id) {
         rbml_w.tag(c::tag_table_item_subst, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| {
-                rbml_w.emit_substs(ecx, &item_substs.substs);
-            })
+            rbml_w.emit_substs(ecx, &item_substs.substs);
         })
     }
 
     if let Some(fv) = tcx.freevars.borrow().get(&id) {
         rbml_w.tag(c::tag_table_freevars, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| {
-                rbml_w.emit_from_vec(fv, |rbml_w, fv_entry| {
-                    Ok(encode_freevar_entry(rbml_w, fv_entry))
-                });
-            })
+            rbml_w.emit_from_vec(fv, |rbml_w, fv_entry| {
+                Ok(encode_freevar_entry(rbml_w, fv_entry))
+            });
         });
 
         for freevar in fv {
             rbml_w.tag(c::tag_table_upvar_capture_map, |rbml_w| {
                 rbml_w.id(id);
-                rbml_w.tag(c::tag_table_val, |rbml_w| {
-                    let var_id = freevar.def.def_id().node;
-                    let upvar_id = ty::UpvarId {
-                        var_id: var_id,
-                        closure_expr_id: id
-                    };
-                    let upvar_capture = tcx.upvar_capture_map.borrow()[upvar_id].clone();
-                    var_id.encode(rbml_w);
-                    upvar_capture.encode(rbml_w);
-                })
+
+                let var_id = freevar.def.def_id().node;
+                let upvar_id = ty::UpvarId {
+                    var_id: var_id,
+                    closure_expr_id: id
+                };
+                let upvar_capture = tcx.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone();
+                var_id.encode(rbml_w);
+                upvar_capture.encode(rbml_w);
             })
         }
     }
@@ -1215,18 +1239,14 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
     if let Some(type_scheme) = tcx.tcache.borrow().get(&lid) {
         rbml_w.tag(c::tag_table_tcache, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| {
-                rbml_w.emit_type_scheme(ecx, type_scheme.clone());
-            })
+            rbml_w.emit_type_scheme(ecx, type_scheme.clone());
         })
     }
 
     if let Some(type_param_def) = tcx.ty_param_defs.borrow().get(&id) {
         rbml_w.tag(c::tag_table_param_defs, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| {
-                rbml_w.emit_type_param_def(ecx, type_param_def)
-            })
+            rbml_w.emit_type_param_def(ecx, type_param_def)
         })
     }
 
@@ -1234,18 +1254,14 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
     if let Some(method) = tcx.method_map.borrow().get(&method_call) {
         rbml_w.tag(c::tag_table_method_map, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| {
-                encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
-            })
+            encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
         })
     }
 
     if let Some(trait_ref) = tcx.object_cast_map.borrow().get(&id) {
         rbml_w.tag(c::tag_table_object_cast_map, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| {
-                rbml_w.emit_trait_ref(ecx, &*trait_ref.0);
-            })
+            rbml_w.emit_trait_ref(ecx, &*trait_ref.0);
         })
     }
 
@@ -1256,9 +1272,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
                 if let Some(method) = tcx.method_map.borrow().get(&method_call) {
                     rbml_w.tag(c::tag_table_method_map, |rbml_w| {
                         rbml_w.id(id);
-                        rbml_w.tag(c::tag_table_val, |rbml_w| {
-                            encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
-                        })
+                        encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
                     })
                 }
             }
@@ -1269,10 +1283,8 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
                     if let Some(method) = tcx.method_map.borrow().get(&method_call) {
                         rbml_w.tag(c::tag_table_method_map, |rbml_w| {
                             rbml_w.id(id);
-                            rbml_w.tag(c::tag_table_val, |rbml_w| {
-                                encode_method_callee(ecx, rbml_w,
-                                                     method_call.adjustment, method)
-                            })
+                            encode_method_callee(ecx, rbml_w,
+                                                 method_call.adjustment, method)
                         })
                     }
                 }
@@ -1284,49 +1296,41 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
 
         rbml_w.tag(c::tag_table_adjustments, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| {
-                rbml_w.emit_auto_adjustment(ecx, adjustment);
-            })
+            rbml_w.emit_auto_adjustment(ecx, adjustment);
         })
     }
 
     if let Some(closure_type) = tcx.closure_tys.borrow().get(&ast_util::local_def(id)) {
         rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| {
-                rbml_w.emit_closure_type(ecx, closure_type);
-            })
+            rbml_w.emit_closure_type(ecx, closure_type);
         })
     }
 
     if let Some(closure_kind) = tcx.closure_kinds.borrow().get(&ast_util::local_def(id)) {
         rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| {
-                encode_closure_kind(rbml_w, *closure_kind)
-            })
+            encode_closure_kind(rbml_w, *closure_kind)
         })
     }
 
     for &qualif in tcx.const_qualif_map.borrow().get(&id).iter() {
         rbml_w.tag(c::tag_table_const_qualif, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| {
-                qualif.encode(rbml_w).unwrap()
-            })
+            qualif.encode(rbml_w).unwrap()
         })
     }
 }
 
 trait doc_decoder_helpers {
-    fn as_int(&self) -> int;
+    fn as_int(&self) -> isize;
     fn opt_child(&self, tag: c::astencode_tag) -> Option<Self>;
 }
 
 impl<'a> doc_decoder_helpers for rbml::Doc<'a> {
-    fn as_int(&self) -> int { reader::doc_as_u64(*self) as int }
+    fn as_int(&self) -> isize { reader::doc_as_u64(*self) as isize }
     fn opt_child(&self, tag: c::astencode_tag) -> Option<rbml::Doc<'a>> {
-        reader::maybe_get_doc(*self, tag as uint)
+        reader::maybe_get_doc(*self, tag as usize)
     }
 }
 
@@ -1642,6 +1646,9 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
                         ty::AdjustReifyFnPointer(def_id)
                     }
                     2 => {
+                        ty::AdjustUnsafeFnPointer
+                    }
+                    3 => {
                         let auto_deref_ref: ty::AutoDerefRef =
                             this.read_enum_variant_arg(0,
                                 |this| Ok(this.read_auto_deref_ref(dcx))).unwrap();
@@ -1735,11 +1742,11 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
     fn read_unsize_kind<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
                                 -> ty::UnsizeKind<'tcx> {
         self.read_enum("UnsizeKind", |this| {
-            let variants = &["UnsizeLength", "UnsizeStruct", "UnsizeVtable"];
+            let variants = &["UnsizeLength", "UnsizeStruct", "UnsizeVtable", "UnsizeUpcast"];
             this.read_enum_variant(variants, |this, i| {
                 Ok(match i {
                     0 => {
-                        let len: uint =
+                        let len: usize =
                             this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap();
 
                         ty::UnsizeLength(len)
@@ -1748,7 +1755,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
                         let uk: ty::UnsizeKind =
                             this.read_enum_variant_arg(0,
                                 |this| Ok(this.read_unsize_kind(dcx))).unwrap();
-                        let idx: uint =
+                        let idx: usize =
                             this.read_enum_variant_arg(1, |this| Decodable::decode(this)).unwrap();
 
                         ty::UnsizeStruct(box uk, idx)
@@ -1769,6 +1776,11 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
                             this.read_enum_variant_arg(1, |this| Ok(this.read_ty(dcx))).unwrap();
                         ty::UnsizeVtable(ty_trait, self_ty)
                     }
+                    3 => {
+                        let target_ty =
+                            this.read_enum_variant_arg(0, |this| Ok(this.read_ty(dcx))).unwrap();
+                        ty::UnsizeUpcast(target_ty)
+                    }
                     _ => panic!("bad enum variant for ty::UnsizeKind")
                 })
             })
@@ -1778,7 +1790,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
     fn read_closure_kind<'b, 'c>(&mut self, _dcx: &DecodeContext<'b, 'c, 'tcx>)
                                  -> ty::ClosureKind
     {
-        Decodable::decode(self).ok().unwrap()
+        Decodable::decode(self).unwrap()
     }
 
     fn read_closure_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
@@ -1839,36 +1851,40 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
 
 fn decode_side_tables(dcx: &DecodeContext,
                       ast_doc: rbml::Doc) {
-    let tbl_doc = ast_doc.get(c::tag_table as uint);
+    let tbl_doc = ast_doc.get(c::tag_table as usize);
     reader::docs(tbl_doc, |tag, entry_doc| {
-        let id0 = entry_doc.get(c::tag_table_id as uint).as_int();
-        let id = dcx.tr_id(id0 as ast::NodeId);
+        let mut entry_dsr = reader::Decoder::new(entry_doc);
+        let id0: ast::NodeId = Decodable::decode(&mut entry_dsr).unwrap();
+        let id = dcx.tr_id(id0);
 
         debug!(">> Side table document with tag 0x{:x} \
                 found for id {} (orig {})",
                tag, id, id0);
-        let decoded_tag: Option<c::astencode_tag> = FromPrimitive::from_uint(tag);
+        let decoded_tag: Option<c::astencode_tag> = FromPrimitive::from_usize(tag);
         match decoded_tag {
             None => {
                 dcx.tcx.sess.bug(
                     &format!("unknown tag found in side tables: {:x}",
-                            tag)[]);
+                            tag));
             }
             Some(value) => {
-                let val_doc = entry_doc.get(c::tag_table_val as uint);
-                let mut val_dsr = reader::Decoder::new(val_doc);
-                let val_dsr = &mut val_dsr;
+                let val_dsr = &mut entry_dsr;
 
                 match value {
                     c::tag_table_def => {
-                        let def = decode_def(dcx, val_doc);
-                        dcx.tcx.def_map.borrow_mut().insert(id, def);
+                        let def = decode_def(dcx, val_dsr);
+                        dcx.tcx.def_map.borrow_mut().insert(id, def::PathResolution {
+                            base_def: def,
+                            // This doesn't matter cross-crate.
+                            last_private: LastMod(AllPublic),
+                            depth: 0
+                        });
                     }
                     c::tag_table_node_type => {
                         let ty = val_dsr.read_ty(dcx);
                         debug!("inserting ty for node {}: {}",
                                id, ty_to_string(dcx.tcx, ty));
-                        dcx.tcx.node_types.borrow_mut().insert(id, ty);
+                        dcx.tcx.node_type_insert(id, ty);
                     }
                     c::tag_table_item_subst => {
                         let item_substs = ty::ItemSubsts {
@@ -1937,7 +1953,7 @@ fn decode_side_tables(dcx: &DecodeContext,
                     _ => {
                         dcx.tcx.sess.bug(
                             &format!("unknown tag found in side tables: {:x}",
-                                    tag)[]);
+                                    tag));
                     }
                 }
             }
@@ -1953,14 +1969,14 @@ fn decode_side_tables(dcx: &DecodeContext,
 
 #[cfg(test)]
 fn encode_item_ast(rbml_w: &mut Encoder, item: &ast::Item) {
-    rbml_w.start_tag(c::tag_tree as uint);
+    rbml_w.start_tag(c::tag_tree as usize);
     (*item).encode(rbml_w);
     rbml_w.end_tag();
 }
 
 #[cfg(test)]
 fn decode_item_ast(par_doc: rbml::Doc) -> ast::Item {
-    let chi_doc = par_doc.get(c::tag_tree as uint);
+    let chi_doc = par_doc.get(c::tag_tree as usize);
     let mut d = reader::Decoder::new(chi_doc);
     Decodable::decode(&mut d).unwrap()
 }
@@ -1999,8 +2015,8 @@ fn mk_ctxt() -> parse::ParseSess {
 #[cfg(test)]
 fn roundtrip(in_item: Option<P<ast::Item>>) {
     let in_item = in_item.unwrap();
-    let mut wr = SeekableMemWriter::new();
-    encode_item_ast(&mut writer::Encoder::new(&mut wr), &*in_item);
+    let mut wr = Cursor::new(Vec::new());
+    encode_item_ast(&mut Encoder::new(&mut wr), &*in_item);
     let rbml_doc = rbml::Doc::new(wr.get_ref());
     let out_item = decode_item_ast(rbml_doc);
 
@@ -2019,7 +2035,7 @@ fn test_basic() {
 fn test_smalltalk() {
     let cx = mk_ctxt();
     roundtrip(quote_item!(&cx,
-        fn foo() -> int { 3 + 4 } // first smalltalk program ever executed.
+        fn foo() -> isize { 3 + 4 } // first smalltalk program ever executed.
     ));
 }
 */
@@ -2028,7 +2044,7 @@ fn test_smalltalk() {
 fn test_more() {
     let cx = mk_ctxt();
     roundtrip(quote_item!(&cx,
-        fn foo(x: uint, y: uint) -> uint {
+        fn foo(x: usize, y: usize) -> usize {
             let z = x + y;
             return z;
         }
@@ -2039,15 +2055,15 @@ fn test_more() {
 fn test_simplification() {
     let cx = mk_ctxt();
     let item = quote_item!(&cx,
-        fn new_int_alist<B>() -> alist<int, B> {
-            fn eq_int(a: int, b: int) -> bool { a == b }
+        fn new_int_alist<B>() -> alist<isize, B> {
+            fn eq_int(a: isize, b: isize) -> bool { a == b }
             return alist {eq_fn: eq_int, data: Vec::new()};
         }
     ).unwrap();
     let item_in = e::IIItemRef(&*item);
     let item_out = simplify_ast(item_in);
     let item_exp = ast::IIItem(quote_item!(&cx,
-        fn new_int_alist<B>() -> alist<int, B> {
+        fn new_int_alist<B>() -> alist<isize, B> {
             return alist {eq_fn: eq_int, data: Vec::new()};
         }
     ).unwrap());
index d39b94a202e4ae1ab12648d14fbbcfaf51928115..cbc2ef1535ea6794b5705bfe15c0d27fbb16dce1 100644 (file)
 use middle::cfg::*;
 use middle::def;
 use middle::graph;
+use middle::pat_util;
 use middle::region::CodeExtent;
 use middle::ty;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::ptr::P;
-use util::nodemap::NodeMap;
 
 struct CFGBuilder<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
-    exit_map: NodeMap<CFGIndex>,
     graph: CFGGraph,
     fn_exit: CFGIndex,
     loop_scopes: Vec<LoopScope>,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct LoopScope {
     loop_id: ast::NodeId,     // id of loop/while node
     continue_index: CFGIndex, // where to go on a `loop`
@@ -36,17 +35,16 @@ struct LoopScope {
 pub fn construct(tcx: &ty::ctxt,
                  blk: &ast::Block) -> CFG {
     let mut graph = graph::Graph::new();
-    let entry = add_initial_dummy_node(&mut graph);
+    let entry = graph.add_node(CFGNodeData::Entry);
 
     // `fn_exit` is target of return exprs, which lies somewhere
     // outside input `blk`. (Distinguishing `fn_exit` and `block_exit`
     // also resolves chicken-and-egg problem that arises if you try to
     // have return exprs jump to `block_exit` during construction.)
-    let fn_exit = add_initial_dummy_node(&mut graph);
+    let fn_exit = graph.add_node(CFGNodeData::Exit);
     let block_exit;
 
     let mut cfg_builder = CFGBuilder {
-        exit_map: NodeMap(),
         graph: graph,
         fn_exit: fn_exit,
         tcx: tcx,
@@ -54,17 +52,12 @@ pub fn construct(tcx: &ty::ctxt,
     };
     block_exit = cfg_builder.block(blk, entry);
     cfg_builder.add_contained_edge(block_exit, fn_exit);
-    let CFGBuilder {exit_map, graph, ..} = cfg_builder;
-    CFG {exit_map: exit_map,
-         graph: graph,
+    let CFGBuilder {graph, ..} = cfg_builder;
+    CFG {graph: graph,
          entry: entry,
          exit: fn_exit}
 }
 
-fn add_initial_dummy_node(g: &mut CFGGraph) -> CFGIndex {
-    g.add_node(CFGNodeData { id: ast::DUMMY_NODE_ID })
-}
-
 impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
     fn block(&mut self, blk: &ast::Block, pred: CFGIndex) -> CFGIndex {
         let mut stmts_exit = pred;
@@ -74,19 +67,19 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
 
         let expr_exit = self.opt_expr(&blk.expr, stmts_exit);
 
-        self.add_node(blk.id, &[expr_exit])
+        self.add_ast_node(blk.id, &[expr_exit])
     }
 
     fn stmt(&mut self, stmt: &ast::Stmt, pred: CFGIndex) -> CFGIndex {
         match stmt.node {
             ast::StmtDecl(ref decl, id) => {
                 let exit = self.decl(&**decl, pred);
-                self.add_node(id, &[exit])
+                self.add_ast_node(id, &[exit])
             }
 
             ast::StmtExpr(ref expr, id) | ast::StmtSemi(ref expr, id) => {
                 let exit = self.expr(&**expr, pred);
-                self.add_node(id, &[exit])
+                self.add_ast_node(id, &[exit])
             }
 
             ast::StmtMac(..) => {
@@ -115,33 +108,33 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
             ast::PatLit(..) |
             ast::PatRange(..) |
             ast::PatWild(_) => {
-                self.add_node(pat.id, &[pred])
+                self.add_ast_node(pat.id, &[pred])
             }
 
             ast::PatBox(ref subpat) |
             ast::PatRegion(ref subpat, _) |
             ast::PatIdent(_, _, Some(ref subpat)) => {
                 let subpat_exit = self.pat(&**subpat, pred);
-                self.add_node(pat.id, &[subpat_exit])
+                self.add_ast_node(pat.id, &[subpat_exit])
             }
 
             ast::PatEnum(_, Some(ref subpats)) |
             ast::PatTup(ref subpats) => {
                 let pats_exit = self.pats_all(subpats.iter(), pred);
-                self.add_node(pat.id, &[pats_exit])
+                self.add_ast_node(pat.id, &[pats_exit])
             }
 
             ast::PatStruct(_, ref subpats, _) => {
                 let pats_exit =
                     self.pats_all(subpats.iter().map(|f| &f.node.pat), pred);
-                self.add_node(pat.id, &[pats_exit])
+                self.add_ast_node(pat.id, &[pats_exit])
             }
 
             ast::PatVec(ref pre, ref vec, ref post) => {
                 let pre_exit = self.pats_all(pre.iter(), pred);
                 let vec_exit = self.pats_all(vec.iter(), pre_exit);
                 let post_exit = self.pats_all(post.iter(), vec_exit);
-                self.add_node(pat.id, &[post_exit])
+                self.add_ast_node(pat.id, &[post_exit])
             }
 
             ast::PatMac(_) => {
@@ -157,28 +150,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         pats.fold(pred, |pred, pat| self.pat(&**pat, pred))
     }
 
-    fn pats_any(&mut self,
-                pats: &[P<ast::Pat>],
-                pred: CFGIndex) -> CFGIndex {
-        //! Handles case where just one of the patterns must match.
-
-        if pats.len() == 1 {
-            self.pat(&*pats[0], pred)
-        } else {
-            let collect = self.add_dummy_node(&[]);
-            for pat in pats {
-                let pat_exit = self.pat(&**pat, pred);
-                self.add_contained_edge(pat_exit, collect);
-            }
-            collect
-        }
-    }
-
     fn expr(&mut self, expr: &ast::Expr, pred: CFGIndex) -> CFGIndex {
         match expr.node {
             ast::ExprBlock(ref blk) => {
                 let blk_exit = self.block(&**blk, pred);
-                self.add_node(expr.id, &[blk_exit])
+                self.add_ast_node(expr.id, &[blk_exit])
             }
 
             ast::ExprIf(ref cond, ref then, None) => {
@@ -198,7 +174,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 //
                 let cond_exit = self.expr(&**cond, pred);                // 1
                 let then_exit = self.block(&**then, cond_exit);          // 2
-                self.add_node(expr.id, &[cond_exit, then_exit])          // 3,4
+                self.add_ast_node(expr.id, &[cond_exit, then_exit])      // 3,4
             }
 
             ast::ExprIf(ref cond, ref then, Some(ref otherwise)) => {
@@ -219,7 +195,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 let cond_exit = self.expr(&**cond, pred);                // 1
                 let then_exit = self.block(&**then, cond_exit);          // 2
                 let else_exit = self.expr(&**otherwise, cond_exit);      // 3
-                self.add_node(expr.id, &[then_exit, else_exit])          // 4, 5
+                self.add_ast_node(expr.id, &[then_exit, else_exit])      // 4, 5
             }
 
             ast::ExprIfLet(..) => {
@@ -247,7 +223,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 // Is the condition considered part of the loop?
                 let loopback = self.add_dummy_node(&[pred]);              // 1
                 let cond_exit = self.expr(&**cond, loopback);             // 2
-                let expr_exit = self.add_node(expr.id, &[cond_exit]);     // 3
+                let expr_exit = self.add_ast_node(expr.id, &[cond_exit]); // 3
                 self.loop_scopes.push(LoopScope {
                     loop_id: expr.id,
                     continue_index: loopback,
@@ -283,7 +259,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 // may cause additional edges.
 
                 let loopback = self.add_dummy_node(&[pred]);              // 1
-                let expr_exit = self.add_node(expr.id, &[]);              // 2
+                let expr_exit = self.add_ast_node(expr.id, &[]);          // 2
                 self.loop_scopes.push(LoopScope {
                     loop_id: expr.id,
                     continue_index: loopback,
@@ -296,45 +272,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
             }
 
             ast::ExprMatch(ref discr, ref arms, _) => {
-                //
-                //     [pred]
-                //       |
-                //       v 1
-                //    [discr]
-                //       |
-                //       v 2
-                //    [cond1]
-                //      /  \
-                //     |    \
-                //     v 3   \
-                //  [pat1]    \
-                //     |       |
-                //     v 4     |
-                //  [guard1]   |
-                //     |       |
-                //     |       |
-                //     v 5     v
-                //  [body1]  [cond2]
-                //     |      /  \
-                //     |    ...  ...
-                //     |     |    |
-                //     v 6   v    v
-                //  [.....expr.....]
-                //
-                let discr_exit = self.expr(&**discr, pred);              // 1
-
-                let expr_exit = self.add_node(expr.id, &[]);
-                let mut cond_exit = discr_exit;
-                for arm in arms {
-                    cond_exit = self.add_dummy_node(&[cond_exit]);        // 2
-                    let pats_exit = self.pats_any(&arm.pats[],
-                                                  cond_exit);            // 3
-                    let guard_exit = self.opt_expr(&arm.guard,
-                                                   pats_exit);           // 4
-                    let body_exit = self.expr(&*arm.body, guard_exit);   // 5
-                    self.add_contained_edge(body_exit, expr_exit);       // 6
-                }
-                expr_exit
+                self.match_(expr.id, &discr, &arms, pred)
             }
 
             ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op.node) => {
@@ -354,30 +292,30 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 //
                 let l_exit = self.expr(&**l, pred);                      // 1
                 let r_exit = self.expr(&**r, l_exit);                    // 2
-                self.add_node(expr.id, &[l_exit, r_exit])                 // 3,4
+                self.add_ast_node(expr.id, &[l_exit, r_exit])            // 3,4
             }
 
             ast::ExprRet(ref v) => {
                 let v_exit = self.opt_expr(v, pred);
-                let b = self.add_node(expr.id, &[v_exit]);
+                let b = self.add_ast_node(expr.id, &[v_exit]);
                 self.add_returning_edge(expr, b);
-                self.add_node(ast::DUMMY_NODE_ID, &[])
+                self.add_unreachable_node()
             }
 
             ast::ExprBreak(label) => {
                 let loop_scope = self.find_scope(expr, label);
-                let b = self.add_node(expr.id, &[pred]);
+                let b = self.add_ast_node(expr.id, &[pred]);
                 self.add_exiting_edge(expr, b,
                                       loop_scope, loop_scope.break_index);
-                self.add_node(ast::DUMMY_NODE_ID, &[])
+                self.add_unreachable_node()
             }
 
             ast::ExprAgain(label) => {
                 let loop_scope = self.find_scope(expr, label);
-                let a = self.add_node(expr.id, &[pred]);
+                let a = self.add_ast_node(expr.id, &[pred]);
                 self.add_exiting_edge(expr, a,
                                       loop_scope, loop_scope.continue_index);
-                self.add_node(ast::DUMMY_NODE_ID, &[])
+                self.add_unreachable_node()
             }
 
             ast::ExprVec(ref elems) => {
@@ -454,14 +392,13 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                     let &(_, ref expr, _) = a;
                     &**expr
                 }), post_inputs);
-                self.add_node(expr.id, &[post_outputs])
+                self.add_ast_node(expr.id, &[post_outputs])
             }
 
             ast::ExprMac(..) |
             ast::ExprClosure(..) |
             ast::ExprLit(..) |
-            ast::ExprPath(..) |
-            ast::ExprQPath(..) => {
+            ast::ExprPath(..) => {
                 self.straightline(expr, pred, None::<ast::Expr>.iter())
             }
         }
@@ -481,7 +418,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
         let ret = self.straightline(call_expr, func_or_rcvr_exit, args);
         if return_ty.diverges() {
-            self.add_node(ast::DUMMY_NODE_ID, &[])
+            self.add_unreachable_node()
         } else {
             ret
         }
@@ -508,20 +445,126 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         //! Handles case of an expression that evaluates `subexprs` in order
 
         let subexprs_exit = self.exprs(subexprs, pred);
-        self.add_node(expr.id, &[subexprs_exit])
+        self.add_ast_node(expr.id, &[subexprs_exit])
+    }
+
+    fn match_(&mut self, id: ast::NodeId, discr: &ast::Expr,
+              arms: &[ast::Arm], pred: CFGIndex) -> CFGIndex {
+        // The CFG for match expression is quite complex, so no ASCII
+        // art for it (yet).
+        //
+        // The CFG generated below matches roughly what trans puts
+        // out. Each pattern and guard is visited in parallel, with
+        // arms containing multiple patterns generating multiple nodes
+        // for the same guard expression. The guard expressions chain
+        // into each other from top to bottom, with a specific
+        // exception to allow some additional valid programs
+        // (explained below). Trans differs slightly in that the
+        // pattern matching may continue after a guard but the visible
+        // behaviour should be the same.
+        //
+        // What is going on is explained in further comments.
+
+        // Visit the discriminant expression
+        let discr_exit = self.expr(discr, pred);
+
+        // Add a node for the exit of the match expression as a whole.
+        let expr_exit = self.add_ast_node(id, &[]);
+
+        // Keep track of the previous guard expressions
+        let mut prev_guards = Vec::new();
+        // Track if the previous pattern contained bindings or wildcards
+        let mut prev_has_bindings = false;
+
+        for arm in arms {
+            // Add an exit node for when we've visited all the
+            // patterns and the guard (if there is one) in the arm.
+            let arm_exit = self.add_dummy_node(&[]);
+
+            for pat in &arm.pats {
+                // Visit the pattern, coming from the discriminant exit
+                let mut pat_exit = self.pat(&**pat, discr_exit);
+
+                // If there is a guard expression, handle it here
+                if let Some(ref guard) = arm.guard {
+                    // Add a dummy node for the previous guard
+                    // expression to target
+                    let guard_start = self.add_dummy_node(&[pat_exit]);
+                    // Visit the guard expression
+                    let guard_exit = self.expr(&**guard, guard_start);
+
+                    let this_has_bindings = pat_util::pat_contains_bindings_or_wild(
+                        &self.tcx.def_map, &**pat);
+
+                    // If both this pattern and the previous pattern
+                    // were free of bindings, they must consist only
+                    // of "constant" patterns. Note we cannot match an
+                    // all-constant pattern, fail the guard, and then
+                    // match *another* all-constant pattern. This is
+                    // because if the previous pattern matches, then
+                    // we *cannot* match this one, unless all the
+                    // constants are the same (which is rejected by
+                    // `check_match`).
+                    //
+                    // We can use this to be smarter about the flow
+                    // along guards. If the previous pattern matched,
+                    // then we know we will not visit the guard in
+                    // this one (whether or not the guard succeeded),
+                    // if the previous pattern failed, then we know
+                    // the guard for that pattern will not have been
+                    // visited. Thus, it is not possible to visit both
+                    // the previous guard and the current one when
+                    // both patterns consist only of constant
+                    // sub-patterns.
+                    //
+                    // However, if the above does not hold, then all
+                    // previous guards need to be wired to visit the
+                    // current guard pattern.
+                    if prev_has_bindings || this_has_bindings {
+                        while let Some(prev) = prev_guards.pop() {
+                            self.add_contained_edge(prev, guard_start);
+                        }
+                    }
+
+                    prev_has_bindings = this_has_bindings;
+
+                    // Push the guard onto the list of previous guards
+                    prev_guards.push(guard_exit);
+
+                    // Update the exit node for the pattern
+                    pat_exit = guard_exit;
+                }
+
+                // Add an edge from the exit of this pattern to the
+                // exit of the arm
+                self.add_contained_edge(pat_exit, arm_exit);
+            }
+
+            // Visit the body of this arm
+            let body_exit = self.expr(&arm.body, arm_exit);
+
+            // Link the body to the exit of the expression
+            self.add_contained_edge(body_exit, expr_exit);
+        }
+
+        expr_exit
     }
 
     fn add_dummy_node(&mut self, preds: &[CFGIndex]) -> CFGIndex {
-        self.add_node(ast::DUMMY_NODE_ID, preds)
+        self.add_node(CFGNodeData::Dummy, preds)
     }
 
-    fn add_node(&mut self, id: ast::NodeId, preds: &[CFGIndex]) -> CFGIndex {
-        assert!(!self.exit_map.contains_key(&id));
-        let node = self.graph.add_node(CFGNodeData {id: id});
-        if id != ast::DUMMY_NODE_ID {
-            assert!(!self.exit_map.contains_key(&id));
-            self.exit_map.insert(id, node);
-        }
+    fn add_ast_node(&mut self, id: ast::NodeId, preds: &[CFGIndex]) -> CFGIndex {
+        assert!(id != ast::DUMMY_NODE_ID);
+        self.add_node(CFGNodeData::AST(id), preds)
+    }
+
+    fn add_unreachable_node(&mut self) -> CFGIndex {
+        self.add_node(CFGNodeData::Unreachable, &[])
+    }
+
+    fn add_node(&mut self, data: CFGNodeData, preds: &[CFGIndex]) -> CFGIndex {
+        let node = self.graph.add_node(data);
         for &pred in preds {
             self.add_contained_edge(pred, node);
         }
@@ -566,32 +609,24 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
     fn find_scope(&self,
                   expr: &ast::Expr,
                   label: Option<ast::Ident>) -> LoopScope {
-        match label {
-            None => {
-                return *self.loop_scopes.last().unwrap();
-            }
-
-            Some(_) => {
-                match self.tcx.def_map.borrow().get(&expr.id) {
-                    Some(&def::DefLabel(loop_id)) => {
-                        for l in &self.loop_scopes {
-                            if l.loop_id == loop_id {
-                                return *l;
-                            }
-                        }
-                        self.tcx.sess.span_bug(
-                            expr.span,
-                            &format!("no loop scope for id {}",
-                                    loop_id)[]);
-                    }
+        if label.is_none() {
+            return *self.loop_scopes.last().unwrap();
+        }
 
-                    r => {
-                        self.tcx.sess.span_bug(
-                            expr.span,
-                            &format!("bad entry `{:?}` in def_map for label",
-                                    r)[]);
+        match self.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
+            Some(def::DefLabel(loop_id)) => {
+                for l in &self.loop_scopes {
+                    if l.loop_id == loop_id {
+                        return *l;
                     }
                 }
+                self.tcx.sess.span_bug(expr.span,
+                    &format!("no loop scope for id {}", loop_id));
+            }
+
+            r => {
+                self.tcx.sess.span_bug(expr.span,
+                    &format!("bad entry `{:?}` in def_map for label", r));
             }
         }
     }
index 46b4a51c9d6fee7b00295727dbd71d600698cf47..3a6966ab112905bee06966be07b48ff0c911175c 100644 (file)
@@ -54,10 +54,10 @@ fn replace_newline_with_backslash_l(s: String) -> String {
 }
 
 impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> {
-    fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new(&self.name[]).ok().unwrap() }
+    fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new(&self.name[..]).unwrap() }
 
     fn node_id(&'a self, &(i,_): &Node<'a>) -> dot::Id<'a> {
-        dot::Id::new(format!("N{}", i.node_id())).ok().unwrap()
+        dot::Id::new(format!("N{}", i.node_id())).unwrap()
     }
 
     fn node_label(&'a self, &(i, n): &Node<'a>) -> dot::LabelText<'a> {
@@ -65,10 +65,10 @@ impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> {
             dot::LabelText::LabelStr("entry".into_cow())
         } else if i == self.cfg.exit {
             dot::LabelText::LabelStr("exit".into_cow())
-        } else if n.data.id == ast::DUMMY_NODE_ID {
+        } else if n.data.id() == ast::DUMMY_NODE_ID {
             dot::LabelText::LabelStr("(dummy_node)".into_cow())
         } else {
-            let s = self.ast_map.node_to_string(n.data.id);
+            let s = self.ast_map.node_to_string(n.data.id());
             // left-aligns the lines
             let s = replace_newline_with_backslash_l(s);
             dot::LabelText::EscStr(s.into_cow())
@@ -92,7 +92,7 @@ impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> {
             let s = replace_newline_with_backslash_l(s);
             label.push_str(&format!("exiting scope_{} {}",
                                    i,
-                                   &s[..])[]);
+                                   &s[..]));
         }
         dot::LabelText::EscStr(label.into_cow())
     }
@@ -124,4 +124,3 @@ impl<'a, 'ast> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast>
     fn source(&'a self, edge: &Edge<'a>) -> Node<'a> { self.cfg.source(edge) }
     fn target(&'a self, edge: &Edge<'a>) -> Node<'a> { self.cfg.target(edge) }
 }
-
index 0ca146a295e139a95712377578205699febcae97..ad4fdcd7b834ef2e5b0bc427820d2ce5f522d9eb 100644 (file)
 use middle::graph;
 use middle::ty;
 use syntax::ast;
-use util::nodemap::NodeMap;
 
 mod construct;
 pub mod graphviz;
 
 pub struct CFG {
-    pub exit_map: NodeMap<CFGIndex>,
     pub graph: CFGGraph,
     pub entry: CFGIndex,
     pub exit: CFGIndex,
 }
 
-#[derive(Copy)]
-pub struct CFGNodeData {
-    pub id: ast::NodeId
+#[derive(Copy, Clone, PartialEq)]
+pub enum CFGNodeData {
+    AST(ast::NodeId),
+    Entry,
+    Exit,
+    Dummy,
+    Unreachable,
+}
+
+impl CFGNodeData {
+    pub fn id(&self) -> ast::NodeId {
+        if let CFGNodeData::AST(id) = *self {
+            id
+        } else {
+            ast::DUMMY_NODE_ID
+        }
+    }
 }
 
 pub struct CFGEdgeData {
@@ -50,6 +62,6 @@ impl CFG {
     }
 
     pub fn node_is_reachable(&self, id: ast::NodeId) -> bool {
-        self.graph.depth_traverse(self.entry).any(|node| node.id == id)
+        self.graph.depth_traverse(self.entry).any(|node| node.id() == id)
     }
 }
index 41d425cd2f6652c54c579f30672dfb4dbf2b734a..ce011f2561b79f661744aa78f613fff58e023a23 100644 (file)
@@ -76,7 +76,7 @@ bitflags! {
     }
 }
 
-#[derive(Copy, Eq, PartialEq)]
+#[derive(Copy, Clone, Eq, PartialEq)]
 enum Mode {
     Const,
     Static,
@@ -176,7 +176,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
         };
 
         self.tcx.sess.span_err(e.span, &format!("mutable statics are not allowed \
-                                                 to have {}", suffix)[]);
+                                                 to have {}", suffix));
     }
 
     fn check_static_type(&self, e: &ast::Expr) {
@@ -307,8 +307,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
                             match const_eval::eval_const_expr_partial(self.tcx, ex, None) {
                                 Ok(_) => {}
                                 Err(msg) => {
-                                    span_err!(self.tcx.sess, ex.span, E0020,
-                                              "{} in a constant expression", msg)
+                                    span_err!(self.tcx.sess, msg.span, E0020,
+                                              "{} in a constant expression",
+                                              msg.description())
                                 }
                             }
                         }
@@ -382,7 +383,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
             if v.mode != Mode::Var {
                 v.tcx.sess.span_err(e.span,
                                     &format!("{}s are not allowed to have destructors",
-                                             v.msg())[]);
+                                             v.msg()));
             }
         }
         _ => {}
@@ -439,8 +440,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                 }
             }
         }
-        ast::ExprPath(_) | ast::ExprQPath(_) => {
-            let def = v.tcx.def_map.borrow().get(&e.id).cloned();
+        ast::ExprPath(..) => {
+            let def = v.tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
             match def {
                 Some(def::DefVariant(_, _, _)) => {
                     // Count the discriminator or function pointer.
@@ -452,8 +453,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                         v.add_qualif(NON_ZERO_SIZED);
                     }
                 }
-                Some(def::DefFn(..)) |
-                Some(def::DefStaticMethod(..)) | Some(def::DefMethod(..)) => {
+                Some(def::DefFn(..)) | Some(def::DefMethod(..)) => {
                     // Count the function pointer.
                     v.add_qualif(NON_ZERO_SIZED);
                 }
@@ -500,7 +500,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                     _ => break
                 };
             }
-            let def = v.tcx.def_map.borrow().get(&callee.id).cloned();
+            let def = v.tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def());
             match def {
                 Some(def::DefStruct(..)) => {}
                 Some(def::DefVariant(..)) => {
index ea584407944abeaa89d657e1cf47953fa62700ef..bf6829d96765058feea270ec09378d460ecfad1a 100644 (file)
@@ -21,7 +21,7 @@ enum Context {
     Normal, Loop, Closure
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct CheckLoopVisitor<'a> {
     sess: &'a Session,
     cx: Context
index 86c59b24e3e933663ed2100f3d5ede07fe3dc82a..79f4d62b45e75fb41740fada747d1a5274163cc4 100644 (file)
@@ -13,11 +13,12 @@ use self::Usefulness::*;
 use self::WitnessPreference::*;
 
 use middle::const_eval::{compare_const_vals, const_bool, const_float, const_val};
-use middle::const_eval::{const_expr_to_pat, eval_const_expr, lookup_const_by_id};
+use middle::const_eval::{eval_const_expr, eval_const_expr_partial};
+use middle::const_eval::{const_expr_to_pat, lookup_const_by_id};
 use middle::def::*;
 use middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, Init};
 use middle::expr_use_visitor::{JustWrite, LoanCause, MutateMode};
-use middle::expr_use_visitor::{WriteAndRead};
+use middle::expr_use_visitor::WriteAndRead;
 use middle::expr_use_visitor as euv;
 use middle::mem_categorization::cmt;
 use middle::pat_util::*;
@@ -26,7 +27,6 @@ use middle::ty;
 use std::cmp::Ordering;
 use std::fmt;
 use std::iter::{range_inclusive, AdditiveIterator, FromIterator, IntoIterator, repeat};
-use std::num::Float;
 use std::slice;
 use syntax::ast::{self, DUMMY_NODE_ID, NodeId, Pat};
 use syntax::ast_util;
@@ -72,7 +72,7 @@ impl<'a> fmt::Debug for Matrix<'a> {
 
         let column_count = m.iter().map(|row| row.len()).max().unwrap_or(0);
         assert!(m.iter().all(|row| row.len() == column_count));
-        let column_widths: Vec<uint> = (0..column_count).map(|col| {
+        let column_widths: Vec<usize> = (0..column_count).map(|col| {
             pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0)
         }).collect();
 
@@ -116,9 +116,9 @@ pub enum Constructor {
     /// Ranges of literal values (2..5).
     ConstantRange(const_val, const_val),
     /// Array patterns of length n.
-    Slice(uint),
+    Slice(usize),
     /// Array patterns with a subslice.
-    SliceWithSubslice(uint, uint)
+    SliceWithSubslice(usize, usize)
 }
 
 #[derive(Clone, PartialEq)]
@@ -128,7 +128,7 @@ enum Usefulness {
     NotUseful
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum WitnessPreference {
     ConstructWitness,
     LeaveOutWitness
@@ -163,7 +163,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
                 // First, check legality of move bindings.
                 check_legality_of_move_bindings(cx,
                                                 arm.guard.is_some(),
-                                                &arm.pats[]);
+                                                &arm.pats);
 
                 // Second, if there is a guard on each arm, make sure it isn't
                 // assigning or borrowing anything mutably.
@@ -229,20 +229,13 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) {
     }
 }
 
-fn is_expr_const_nan(tcx: &ty::ctxt, expr: &ast::Expr) -> bool {
-    match eval_const_expr(tcx, expr) {
-        const_float(f) => f.is_nan(),
-        _ => false
-    }
-}
-
 fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) {
     ast_util::walk_pat(pat, |p| {
         match p.node {
             ast::PatIdent(ast::BindByValue(ast::MutImmutable), ident, None) => {
                 let pat_ty = ty::pat_ty(cx.tcx, p);
                 if let ty::ty_enum(def_id, _) = pat_ty.sty {
-                    let def = cx.tcx.def_map.borrow().get(&p.id).cloned();
+                    let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
                     if let Some(DefLocal(_)) = def {
                         if ty::enum_variants(cx.tcx, def_id).iter().any(|variant|
                             token::get_name(variant.name) == token::get_name(ident.node.name)
@@ -252,7 +245,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
                                 "pattern binding `{}` is named the same as one \
                                  of the variants of the type `{}`",
                                 &token::get_ident(ident.node), ty_to_string(cx.tcx, pat_ty));
-                            span_help!(cx.tcx.sess, p.span,
+                            fileline_help!(cx.tcx.sess, p.span,
                                 "if you meant to match on a variant, \
                                  consider making the path in the pattern qualified: `{}::{}`",
                                 ty_to_string(cx.tcx, pat_ty), &token::get_ident(ident.node));
@@ -269,13 +262,26 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
 // Check that we do not match against a static NaN (#6804)
 fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) {
     ast_util::walk_pat(pat, |p| {
-        match p.node {
-            ast::PatLit(ref expr) if is_expr_const_nan(cx.tcx, &**expr) => {
-                span_warn!(cx.tcx.sess, p.span, E0003,
-                    "unmatchable NaN in pattern, \
-                        use the is_nan method in a guard instead");
+        if let ast::PatLit(ref expr) = p.node {
+            match eval_const_expr_partial(cx.tcx, &**expr, None) {
+                Ok(const_float(f)) if f.is_nan() => {
+                    span_warn!(cx.tcx.sess, p.span, E0003,
+                               "unmatchable NaN in pattern, \
+                                use the is_nan method in a guard instead");
+                }
+                Ok(_) => {}
+
+                Err(err) => {
+                    let subspan = p.span.lo <= err.span.lo && err.span.hi <= p.span.hi;
+                    cx.tcx.sess.span_err(err.span,
+                                         &format!("constant evaluation error: {}",
+                                                  err.description()));
+                    if !subspan {
+                        cx.tcx.sess.span_note(p.span,
+                                              "in pattern here")
+                    }
+                }
             }
-            _ => ()
         }
         true
     });
@@ -434,7 +440,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
     fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
         return match pat.node {
             ast::PatIdent(..) | ast::PatEnum(..) => {
-                let def = self.tcx.def_map.borrow().get(&pat.id).cloned();
+                let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
                 match def {
                     Some(DefConst(did)) => match lookup_const_by_id(self.tcx, did) {
                         Some(const_expr) => {
@@ -492,7 +498,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
 /// left_ty: tuple of 3 elements
 /// pats: [10, 20, _]           => (10, 20, _)
 ///
-/// left_ty: struct X { a: (bool, &'static str), b: uint}
+/// left_ty: struct X { a: (bool, &'static str), b: usize}
 /// pats: [(false, "foo"), 42]  => X { a: (false, "foo"), b: 42 }
 fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
                      pats: Vec<&Pat>, left_ty: Ty) -> P<Pat> {
@@ -574,7 +580,7 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
 }
 
 fn missing_constructor(cx: &MatchCheckCtxt, &Matrix(ref rows): &Matrix,
-                       left_ty: Ty, max_slice_length: uint) -> Option<Constructor> {
+                       left_ty: Ty, max_slice_length: usize) -> Option<Constructor> {
     let used_constructors: Vec<Constructor> = rows.iter()
         .flat_map(|row| pat_constructors(cx, row[0], left_ty, max_slice_length).into_iter())
         .collect();
@@ -588,7 +594,7 @@ fn missing_constructor(cx: &MatchCheckCtxt, &Matrix(ref rows): &Matrix,
 /// but is instead bounded by the maximum fixed length of slice patterns in
 /// the column of patterns being analyzed.
 fn all_constructors(cx: &MatchCheckCtxt, left_ty: Ty,
-                    max_slice_length: uint) -> Vec<Constructor> {
+                    max_slice_length: usize) -> Vec<Constructor> {
     match left_ty.sty {
         ty::ty_bool =>
             [true, false].iter().map(|b| ConstantValue(const_bool(*b))).collect(),
@@ -639,6 +645,7 @@ fn is_useful(cx: &MatchCheckCtxt,
     if rows[0].len() == 0 {
         return NotUseful;
     }
+    assert!(rows.iter().all(|r| r.len() == v.len()));
     let real_pat = match rows.iter().find(|r| (*r)[0].id != DUMMY_NODE_ID) {
         Some(r) => raw_pat(r[0]),
         None if v.len() == 0 => return NotUseful,
@@ -647,7 +654,12 @@ fn is_useful(cx: &MatchCheckCtxt,
     let left_ty = if real_pat.id == DUMMY_NODE_ID {
         ty::mk_nil(cx.tcx)
     } else {
-        ty::pat_ty(cx.tcx, &*real_pat)
+        let left_ty = ty::pat_ty(cx.tcx, &*real_pat);
+
+        match real_pat.node {
+            ast::PatIdent(ast::BindByRef(..), _, _) => ty::deref(left_ty, false).unwrap().ty,
+            _ => left_ty,
+        }
     };
 
     let max_slice_length = rows.iter().filter_map(|row| match row[0].node {
@@ -729,32 +741,32 @@ fn is_useful_specialized(cx: &MatchCheckCtxt, &Matrix(ref m): &Matrix,
 /// On the other hand, a wild pattern and an identifier pattern cannot be
 /// specialized in any way.
 fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
-                    left_ty: Ty, max_slice_length: uint) -> Vec<Constructor> {
+                    left_ty: Ty, max_slice_length: usize) -> Vec<Constructor> {
     let pat = raw_pat(p);
     match pat.node {
         ast::PatIdent(..) =>
-            match cx.tcx.def_map.borrow().get(&pat.id) {
-                Some(&DefConst(..)) =>
+            match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
+                Some(DefConst(..)) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
                                                     been rewritten"),
-                Some(&DefStruct(_)) => vec!(Single),
-                Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
+                Some(DefStruct(_)) => vec!(Single),
+                Some(DefVariant(_, id, _)) => vec!(Variant(id)),
                 _ => vec!()
             },
         ast::PatEnum(..) =>
-            match cx.tcx.def_map.borrow().get(&pat.id) {
-                Some(&DefConst(..)) =>
+            match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
+                Some(DefConst(..)) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
                                                     been rewritten"),
-                Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
+                Some(DefVariant(_, id, _)) => vec!(Variant(id)),
                 _ => vec!(Single)
             },
         ast::PatStruct(..) =>
-            match cx.tcx.def_map.borrow().get(&pat.id) {
-                Some(&DefConst(..)) =>
+            match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
+                Some(DefConst(..)) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
                                                     been rewritten"),
-                Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
+                Some(DefVariant(_, id, _)) => vec!(Variant(id)),
                 _ => vec!(Single)
             },
         ast::PatLit(ref expr) =>
@@ -786,7 +798,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
 ///
 /// For instance, a tuple pattern (_, 42, Some([])) has the arity of 3.
 /// A struct pattern's arity is the number of fields it contains, etc.
-pub fn constructor_arity(cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> uint {
+pub fn constructor_arity(cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usize {
     match ty.sty {
         ty::ty_tup(ref fs) => fs.len(),
         ty::ty_uniq(_) => 1,
@@ -838,7 +850,7 @@ fn range_covered_by_constructor(ctor: &Constructor,
 /// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
 /// fields filled with wild patterns.
 pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
-                      constructor: &Constructor, col: uint, arity: uint) -> Option<Vec<&'a Pat>> {
+                      constructor: &Constructor, col: usize, arity: usize) -> Option<Vec<&'a Pat>> {
     let &Pat {
         id: pat_id, ref node, span: pat_span
     } = raw_pat(r[col]);
@@ -847,7 +859,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
             Some(repeat(DUMMY_WILD_PAT).take(arity).collect()),
 
         ast::PatIdent(_, _, _) => {
-            let opt_def = cx.tcx.def_map.borrow().get(&pat_id).cloned();
+            let opt_def = cx.tcx.def_map.borrow().get(&pat_id).map(|d| d.full_def());
             match opt_def {
                 Some(DefConst(..)) =>
                     cx.tcx.sess.span_bug(pat_span, "const pattern should've \
@@ -862,7 +874,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
         }
 
         ast::PatEnum(_, ref args) => {
-            let def = cx.tcx.def_map.borrow()[pat_id].clone();
+            let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
             match def {
                 DefConst(..) =>
                     cx.tcx.sess.span_bug(pat_span, "const pattern should've \
@@ -880,7 +892,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
 
         ast::PatStruct(_, ref pattern_fields, _) => {
             // Is this a struct or an enum variant?
-            let def = cx.tcx.def_map.borrow()[pat_id].clone();
+            let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
             let class_id = match def {
                 DefConst(..) =>
                     cx.tcx.sess.span_bug(pat_span, "const pattern should've \
@@ -1101,7 +1113,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
                             &format!("binding pattern {} is not an \
                                      identifier: {:?}",
                                     p.id,
-                                    p.node)[]);
+                                    p.node));
                     }
                 }
             }
index 4280b7fe3f09649170a73dc7e37f90873a22fa9f..b97978fc03fff33ae23e04c0cb05595511f2d380 100644 (file)
@@ -93,10 +93,10 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
 
     fn visit_expr(&mut self, e: &ast::Expr) {
         match e.node {
-            ast::ExprPath(_) | ast::ExprQPath(_) => {
-                match self.def_map.borrow().get(&e.id) {
-                    Some(&DefStatic(def_id, _)) |
-                    Some(&DefConst(def_id)) if
+            ast::ExprPath(..) => {
+                match self.def_map.borrow().get(&e.id).map(|d| d.base_def) {
+                    Some(DefStatic(def_id, _)) |
+                    Some(DefConst(def_id)) if
                             ast_util::is_local(def_id) => {
                         match self.ast_map.get(def_id.node) {
                           ast_map::NodeItem(item) =>
index 5bf7422dbc0d41ce7051d5a801238c4d4a28b12f..367bcbbe1d8a972add77a29907999a4cbfaed013 100644 (file)
 
 pub use self::const_val::*;
 
+use self::ErrKind::*;
+
 use metadata::csearch;
 use middle::{astencode, def};
 use middle::pat_util::def_to_path;
 use middle::ty::{self, Ty};
-use middle::astconv_util::{ast_ty_to_prim_ty};
+use middle::astconv_util::ast_ty_to_prim_ty;
 
 use syntax::ast::{self, Expr};
 use syntax::codemap::Span;
+use syntax::feature_gate;
 use syntax::parse::token::InternedString;
 use syntax::ptr::P;
 use syntax::{ast_map, ast_util, codemap};
 
+use std::borrow::{Cow, IntoCow};
+use std::num::wrapping::OverflowingOps;
+use std::num::ToPrimitive;
 use std::cmp::Ordering;
 use std::collections::hash_map::Entry::Vacant;
 use std::{i8, i16, i32, i64};
 use std::rc::Rc;
 
 fn lookup_const<'a>(tcx: &'a ty::ctxt, e: &Expr) -> Option<&'a Expr> {
-    let opt_def = tcx.def_map.borrow().get(&e.id).cloned();
+    let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
     match opt_def {
         Some(def::DefConst(def_id)) => {
             lookup_const_by_id(tcx, def_id)
@@ -77,7 +83,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
             None => {}
         }
         let expr_id = match csearch::maybe_get_item_ast(tcx, enum_def,
-            box |a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
+            Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) {
             csearch::FoundAst::Found(&ast::IIItem(ref item)) => match item.node {
                 ast::ItemEnum(ast::EnumDef { ref variants }, _) => {
                     // NOTE this doesn't do the right thing, it compares inlined
@@ -117,7 +123,7 @@ pub fn lookup_const_by_id<'a>(tcx: &'a ty::ctxt, def_id: ast::DefId)
             None => {}
         }
         let expr_id = match csearch::maybe_get_item_ast(tcx, def_id,
-            box |a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
+            Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) {
             csearch::FoundAst::Found(&ast::IIItem(ref item)) => match item.node {
                 ast::ItemConst(_, ref const_expr) => Some(const_expr.id),
                 _ => None
@@ -130,16 +136,16 @@ pub fn lookup_const_by_id<'a>(tcx: &'a ty::ctxt, def_id: ast::DefId)
     }
 }
 
-// FIXME (#33): this doesn't handle big integer/float literals correctly
-// (nor does the rest of our literal handling).
 #[derive(Clone, PartialEq)]
 pub enum const_val {
     const_float(f64),
     const_int(i64),
     const_uint(u64),
     const_str(InternedString),
-    const_binary(Rc<Vec<u8> >),
-    const_bool(bool)
+    const_binary(Rc<Vec<u8>>),
+    const_bool(bool),
+    Struct(ast::NodeId),
+    Tuple(ast::NodeId)
 }
 
 pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat> {
@@ -148,11 +154,11 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
             ast::PatTup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect()),
 
         ast::ExprCall(ref callee, ref args) => {
-            let def = tcx.def_map.borrow()[callee.id].clone();
+            let def = *tcx.def_map.borrow().get(&callee.id).unwrap();
             if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) {
                entry.insert(def);
             }
-            let path = match def {
+            let path = match def.full_def() {
                 def::DefStruct(def_id) => def_to_path(tcx, def_id),
                 def::DefVariant(_, variant_did, _) => def_to_path(tcx, variant_did),
                 _ => unreachable!()
@@ -178,8 +184,8 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
             ast::PatVec(pats, None, vec![])
         }
 
-        ast::ExprPath(ref path) => {
-            let opt_def = tcx.def_map.borrow().get(&expr.id).cloned();
+        ast::ExprPath(_, ref path) => {
+            let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
             match opt_def {
                 Some(def::DefStruct(..)) =>
                     ast::PatStruct(path.clone(), vec![], false),
@@ -194,13 +200,6 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
             }
         }
 
-        ast::ExprQPath(_) => {
-            match lookup_const(tcx, expr) {
-                Some(actual) => return const_expr_to_pat(tcx, actual, span),
-                _ => unreachable!()
-            }
-        }
-
         _ => ast::PatLit(P(expr.clone()))
     };
     P(ast::Pat { id: expr.id, node: pat, span: span })
@@ -209,106 +208,457 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
 pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> const_val {
     match eval_const_expr_partial(tcx, e, None) {
         Ok(r) => r,
-        Err(s) => tcx.sess.span_fatal(e.span, &s[..])
+        Err(s) => tcx.sess.span_fatal(s.span, &s.description())
+    }
+}
+
+
+#[derive(Clone)]
+pub struct ConstEvalErr {
+    pub span: Span,
+    pub kind: ErrKind,
+}
+
+#[derive(Clone)]
+pub enum ErrKind {
+    CannotCast,
+    CannotCastTo(&'static str),
+    InvalidOpForBools(ast::BinOp_),
+    InvalidOpForFloats(ast::BinOp_),
+    InvalidOpForIntUint(ast::BinOp_),
+    InvalidOpForUintInt(ast::BinOp_),
+    NegateOnString,
+    NegateOnBoolean,
+    NegateOnBinary,
+    NegateOnStruct,
+    NegateOnTuple,
+    NotOnFloat,
+    NotOnString,
+    NotOnBinary,
+    NotOnStruct,
+    NotOnTuple,
+
+    NegateWithOverflow(i64),
+    AddiWithOverflow(i64, i64),
+    SubiWithOverflow(i64, i64),
+    MuliWithOverflow(i64, i64),
+    AdduWithOverflow(u64, u64),
+    SubuWithOverflow(u64, u64),
+    MuluWithOverflow(u64, u64),
+    DivideByZero,
+    DivideWithOverflow,
+    ModuloByZero,
+    ModuloWithOverflow,
+    ShiftLeftWithOverflow,
+    ShiftRightWithOverflow,
+    MissingStructField,
+    NonConstPath,
+    ExpectedConstTuple,
+    ExpectedConstStruct,
+    TupleIndexOutOfBounds,
+
+    MiscBinaryOp,
+    MiscCatchAll,
+}
+
+impl ConstEvalErr {
+    pub fn description(&self) -> Cow<str> {
+        use self::ErrKind::*;
+
+        match self.kind {
+            CannotCast => "can't cast this type".into_cow(),
+            CannotCastTo(s) => format!("can't cast this type to {}", s).into_cow(),
+            InvalidOpForBools(_) =>  "can't do this op on bools".into_cow(),
+            InvalidOpForFloats(_) => "can't do this op on floats".into_cow(),
+            InvalidOpForIntUint(..) => "can't do this op on an isize and usize".into_cow(),
+            InvalidOpForUintInt(..) => "can't do this op on a usize and isize".into_cow(),
+            NegateOnString => "negate on string".into_cow(),
+            NegateOnBoolean => "negate on boolean".into_cow(),
+            NegateOnBinary => "negate on binary literal".into_cow(),
+            NegateOnStruct => "negate on struct".into_cow(),
+            NegateOnTuple => "negate on tuple".into_cow(),
+            NotOnFloat => "not on float or string".into_cow(),
+            NotOnString => "not on float or string".into_cow(),
+            NotOnBinary => "not on binary literal".into_cow(),
+            NotOnStruct => "not on struct".into_cow(),
+            NotOnTuple => "not on tuple".into_cow(),
+
+            NegateWithOverflow(..) => "attempted to negate with overflow".into_cow(),
+            AddiWithOverflow(..) => "attempted to add with overflow".into_cow(),
+            SubiWithOverflow(..) => "attempted to sub with overflow".into_cow(),
+            MuliWithOverflow(..) => "attempted to mul with overflow".into_cow(),
+            AdduWithOverflow(..) => "attempted to add with overflow".into_cow(),
+            SubuWithOverflow(..) => "attempted to sub with overflow".into_cow(),
+            MuluWithOverflow(..) => "attempted to mul with overflow".into_cow(),
+            DivideByZero         => "attempted to divide by zero".into_cow(),
+            DivideWithOverflow   => "attempted to divide with overflow".into_cow(),
+            ModuloByZero         => "attempted remainder with a divisor of zero".into_cow(),
+            ModuloWithOverflow   => "attempted remainder with overflow".into_cow(),
+            ShiftLeftWithOverflow => "attempted left shift with overflow".into_cow(),
+            ShiftRightWithOverflow => "attempted right shift with overflow".into_cow(),
+            MissingStructField  => "nonexistent struct field".into_cow(),
+            NonConstPath        => "non-constant path in constant expr".into_cow(),
+            ExpectedConstTuple => "expected constant tuple".into_cow(),
+            ExpectedConstStruct => "expected constant struct".into_cow(),
+            TupleIndexOutOfBounds => "tuple index out of bounds".into_cow(),
+
+            MiscBinaryOp => "bad operands for binary".into_cow(),
+            MiscCatchAll => "unsupported constant expr".into_cow(),
+        }
+    }
+}
+
+pub type EvalResult = Result<const_val, ConstEvalErr>;
+pub type CastResult = Result<const_val, ErrKind>;
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum IntTy { I8, I16, I32, I64 }
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum UintTy { U8, U16, U32, U64 }
+
+impl IntTy {
+    pub fn from(tcx: &ty::ctxt, t: ast::IntTy) -> IntTy {
+        let t = if let ast::TyIs = t {
+            tcx.sess.target.int_type
+        } else {
+            t
+        };
+        match t {
+            ast::TyIs => unreachable!(),
+            ast::TyI8  => IntTy::I8,
+            ast::TyI16 => IntTy::I16,
+            ast::TyI32 => IntTy::I32,
+            ast::TyI64 => IntTy::I64,
+        }
+    }
+}
+
+impl UintTy {
+    pub fn from(tcx: &ty::ctxt, t: ast::UintTy) -> UintTy {
+        let t = if let ast::TyUs = t {
+            tcx.sess.target.uint_type
+        } else {
+            t
+        };
+        match t {
+            ast::TyUs => unreachable!(),
+            ast::TyU8  => UintTy::U8,
+            ast::TyU16 => UintTy::U16,
+            ast::TyU32 => UintTy::U32,
+            ast::TyU64 => UintTy::U64,
+        }
+    }
+}
+
+macro_rules! signal {
+    ($e:expr, $exn:expr) => {
+        return Err(ConstEvalErr { span: $e.span, kind: $exn })
+    }
+}
+
+// The const_{int,uint}_checked_{neg,add,sub,mul,div,shl,shr} family
+// of functions catch and signal overflow errors during constant
+// evaluation.
+//
+// They all take the operator's arguments (`a` and `b` if binary), the
+// overall expression (`e`) and, if available, whole expression's
+// concrete type (`opt_ety`).
+//
+// If the whole expression's concrete type is None, then this is a
+// constant evaluation happening before type check (e.g. in the check
+// to confirm that a pattern range's left-side is not greater than its
+// right-side). We do not do arithmetic modulo the type's bitwidth in
+// such a case; we just do 64-bit arithmetic and assume that later
+// passes will do it again with the type information, and thus do the
+// overflow checks then.
+
+pub fn const_int_checked_neg<'a>(
+    a: i64, e: &'a Expr, opt_ety: Option<IntTy>) -> EvalResult {
+
+    let (min,max) = match opt_ety {
+        // (-i8::MIN is itself not an i8, etc, but this is an easy way
+        // to allow literals to pass the check. Of course that does
+        // not work for i64::MIN.)
+        Some(IntTy::I8) =>  (-(i8::MAX as i64), -(i8::MIN as i64)),
+        Some(IntTy::I16) => (-(i16::MAX as i64), -(i16::MIN as i64)),
+        Some(IntTy::I32) => (-(i32::MAX as i64), -(i32::MIN as i64)),
+        None | Some(IntTy::I64) => (-i64::MAX, -(i64::MIN+1)),
+    };
+
+    let oflo = a < min || a > max;
+    if oflo {
+        signal!(e, NegateWithOverflow(a));
+    } else {
+        Ok(const_int(-a))
+    }
+}
+
+pub fn const_uint_checked_neg<'a>(
+    a: u64, _e: &'a Expr, _opt_ety: Option<UintTy>) -> EvalResult {
+    // This always succeeds, and by definition, returns `(!a)+1`.
+    Ok(const_uint((!a).wrapping_add(1)))
+}
+
+macro_rules! overflow_checking_body {
+    ($a:ident, $b:ident, $ety:ident, $overflowing_op:ident,
+     lhs: $to_8_lhs:ident $to_16_lhs:ident $to_32_lhs:ident,
+     rhs: $to_8_rhs:ident $to_16_rhs:ident $to_32_rhs:ident $to_64_rhs:ident,
+     $EnumTy:ident $T8: ident $T16: ident $T32: ident $T64: ident,
+     $result_type: ident) => { {
+        let (a,b,opt_ety) = ($a,$b,$ety);
+        match opt_ety {
+            Some($EnumTy::$T8) => match (a.$to_8_lhs(), b.$to_8_rhs()) {
+                (Some(a), Some(b)) => {
+                    let (a, oflo) = a.$overflowing_op(b);
+                    (a as $result_type, oflo)
+                }
+                (None, _) | (_, None) => (0, true)
+            },
+            Some($EnumTy::$T16) => match (a.$to_16_lhs(), b.$to_16_rhs()) {
+                (Some(a), Some(b)) => {
+                    let (a, oflo) = a.$overflowing_op(b);
+                    (a as $result_type, oflo)
+                }
+                (None, _) | (_, None) => (0, true)
+            },
+            Some($EnumTy::$T32) => match (a.$to_32_lhs(), b.$to_32_rhs()) {
+                (Some(a), Some(b)) => {
+                    let (a, oflo) = a.$overflowing_op(b);
+                    (a as $result_type, oflo)
+                }
+                (None, _) | (_, None) => (0, true)
+            },
+            None | Some($EnumTy::$T64) => match b.$to_64_rhs() {
+                Some(b) => a.$overflowing_op(b),
+                None => (0, true),
+            }
+        }
+    } }
+}
+
+macro_rules! int_arith_body {
+    ($a:ident, $b:ident, $ety:ident, $overflowing_op:ident) => {
+        overflow_checking_body!(
+            $a, $b, $ety, $overflowing_op,
+            lhs: to_i8 to_i16 to_i32,
+            rhs: to_i8 to_i16 to_i32 to_i64, IntTy I8 I16 I32 I64, i64)
+    }
+}
+
+macro_rules! uint_arith_body {
+    ($a:ident, $b:ident, $ety:ident, $overflowing_op:ident) => {
+        overflow_checking_body!(
+            $a, $b, $ety, $overflowing_op,
+            lhs: to_u8 to_u16 to_u32,
+            rhs: to_u8 to_u16 to_u32 to_u64, UintTy U8 U16 U32 U64, u64)
+    }
+}
+
+macro_rules! int_shift_body {
+    ($a:ident, $b:ident, $ety:ident, $overflowing_op:ident) => {
+        overflow_checking_body!(
+            $a, $b, $ety, $overflowing_op,
+            lhs: to_i8 to_i16 to_i32,
+            rhs: to_u32 to_u32 to_u32 to_u32, IntTy I8 I16 I32 I64, i64)
+    }
+}
+
+macro_rules! uint_shift_body {
+    ($a:ident, $b:ident, $ety:ident, $overflowing_op:ident) => {
+        overflow_checking_body!(
+            $a, $b, $ety, $overflowing_op,
+            lhs: to_u8 to_u16 to_u32,
+            rhs: to_u32 to_u32 to_u32 to_u32, UintTy U8 U16 U32 U64, u64)
+    }
+}
+
+macro_rules! pub_fn_checked_op {
+    {$fn_name:ident ($a:ident : $a_ty:ty, $b:ident : $b_ty:ty,.. $WhichTy:ident) {
+        $ret_oflo_body:ident $overflowing_op:ident
+            $const_ty:ident $signal_exn:expr
+    }} => {
+        pub fn $fn_name<'a>($a: $a_ty,
+                            $b: $b_ty,
+                            e: &'a Expr,
+                            opt_ety: Option<$WhichTy>) -> EvalResult {
+            let (ret, oflo) = $ret_oflo_body!($a, $b, opt_ety, $overflowing_op);
+            if !oflo { Ok($const_ty(ret)) } else { signal!(e, $signal_exn) }
+        }
     }
 }
 
+pub_fn_checked_op!{ const_int_checked_add(a: i64, b: i64,.. IntTy) {
+           int_arith_body overflowing_add const_int AddiWithOverflow(a, b)
+}}
+
+pub_fn_checked_op!{ const_int_checked_sub(a: i64, b: i64,.. IntTy) {
+           int_arith_body overflowing_sub const_int SubiWithOverflow(a, b)
+}}
+
+pub_fn_checked_op!{ const_int_checked_mul(a: i64, b: i64,.. IntTy) {
+           int_arith_body overflowing_mul const_int MuliWithOverflow(a, b)
+}}
+
+pub fn const_int_checked_div<'a>(
+    a: i64, b: i64, e: &'a Expr, opt_ety: Option<IntTy>) -> EvalResult {
+    if b == 0 { signal!(e, DivideByZero); }
+    let (ret, oflo) = int_arith_body!(a, b, opt_ety, overflowing_div);
+    if !oflo { Ok(const_int(ret)) } else { signal!(e, DivideWithOverflow) }
+}
+
+pub fn const_int_checked_rem<'a>(
+    a: i64, b: i64, e: &'a Expr, opt_ety: Option<IntTy>) -> EvalResult {
+    if b == 0 { signal!(e, ModuloByZero); }
+    let (ret, oflo) = int_arith_body!(a, b, opt_ety, overflowing_rem);
+    if !oflo { Ok(const_int(ret)) } else { signal!(e, ModuloWithOverflow) }
+}
+
+pub_fn_checked_op!{ const_int_checked_shl(a: i64, b: i64,.. IntTy) {
+           int_shift_body overflowing_shl const_int ShiftLeftWithOverflow
+}}
+
+pub_fn_checked_op!{ const_int_checked_shl_via_uint(a: i64, b: u64,.. IntTy) {
+           int_shift_body overflowing_shl const_int ShiftLeftWithOverflow
+}}
+
+pub_fn_checked_op!{ const_int_checked_shr(a: i64, b: i64,.. IntTy) {
+           int_shift_body overflowing_shr const_int ShiftRightWithOverflow
+}}
+
+pub_fn_checked_op!{ const_int_checked_shr_via_uint(a: i64, b: u64,.. IntTy) {
+           int_shift_body overflowing_shr const_int ShiftRightWithOverflow
+}}
+
+pub_fn_checked_op!{ const_uint_checked_add(a: u64, b: u64,.. UintTy) {
+           uint_arith_body overflowing_add const_uint AdduWithOverflow(a, b)
+}}
+
+pub_fn_checked_op!{ const_uint_checked_sub(a: u64, b: u64,.. UintTy) {
+           uint_arith_body overflowing_sub const_uint SubuWithOverflow(a, b)
+}}
+
+pub_fn_checked_op!{ const_uint_checked_mul(a: u64, b: u64,.. UintTy) {
+           uint_arith_body overflowing_mul const_uint MuluWithOverflow(a, b)
+}}
+
+pub fn const_uint_checked_div<'a>(
+    a: u64, b: u64, e: &'a Expr, opt_ety: Option<UintTy>) -> EvalResult {
+    if b == 0 { signal!(e, DivideByZero); }
+    let (ret, oflo) = uint_arith_body!(a, b, opt_ety, overflowing_div);
+    if !oflo { Ok(const_uint(ret)) } else { signal!(e, DivideWithOverflow) }
+}
+
+pub fn const_uint_checked_rem<'a>(
+    a: u64, b: u64, e: &'a Expr, opt_ety: Option<UintTy>) -> EvalResult {
+    if b == 0 { signal!(e, ModuloByZero); }
+    let (ret, oflo) = uint_arith_body!(a, b, opt_ety, overflowing_rem);
+    if !oflo { Ok(const_uint(ret)) } else { signal!(e, ModuloWithOverflow) }
+}
+
+pub_fn_checked_op!{ const_uint_checked_shl(a: u64, b: u64,.. UintTy) {
+           uint_shift_body overflowing_shl const_uint ShiftLeftWithOverflow
+}}
+
+pub_fn_checked_op!{ const_uint_checked_shl_via_int(a: u64, b: i64,.. UintTy) {
+           uint_shift_body overflowing_shl const_uint ShiftLeftWithOverflow
+}}
+
+pub_fn_checked_op!{ const_uint_checked_shr(a: u64, b: u64,.. UintTy) {
+           uint_shift_body overflowing_shr const_uint ShiftRightWithOverflow
+}}
+
+pub_fn_checked_op!{ const_uint_checked_shr_via_int(a: u64, b: i64,.. UintTy) {
+           uint_shift_body overflowing_shr const_uint ShiftRightWithOverflow
+}}
+
 pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
                                      e: &Expr,
-                                     ty_hint: Option<Ty<'tcx>>)
-                                     -> Result<const_val, String> {
-    fn fromb(b: bool) -> Result<const_val, String> { Ok(const_int(b as i64)) }
+                                     ty_hint: Option<Ty<'tcx>>) -> EvalResult {
+    fn fromb(b: bool) -> const_val { const_int(b as i64) }
 
     let ety = ty_hint.or_else(|| ty::expr_ty_opt(tcx, e));
 
-    match e.node {
+    // If type of expression itself is int or uint, normalize in these
+    // bindings so that isize/usize is mapped to a type with an
+    // inherently known bitwidth.
+    let expr_int_type = ety.and_then(|ty| {
+        if let ty::ty_int(t) = ty.sty {
+            Some(IntTy::from(tcx, t)) } else { None }
+    });
+    let expr_uint_type = ety.and_then(|ty| {
+        if let ty::ty_uint(t) = ty.sty {
+            Some(UintTy::from(tcx, t)) } else { None }
+    });
+
+    let result = match e.node {
       ast::ExprUnary(ast::UnNeg, ref inner) => {
-        match eval_const_expr_partial(tcx, &**inner, ety) {
-          Ok(const_float(f)) => Ok(const_float(-f)),
-          Ok(const_int(i)) => Ok(const_int(-i)),
-          Ok(const_uint(i)) => Ok(const_uint(-i)),
-          Ok(const_str(_)) => Err("negate on string".to_string()),
-          Ok(const_bool(_)) => Err("negate on boolean".to_string()),
-          ref err => ((*err).clone())
+        match try!(eval_const_expr_partial(tcx, &**inner, ety)) {
+          const_float(f) => const_float(-f),
+          const_int(n) =>  try!(const_int_checked_neg(n, e, expr_int_type)),
+          const_uint(i) => {
+              if !tcx.sess.features.borrow().negate_unsigned {
+                  feature_gate::emit_feature_err(
+                      &tcx.sess.parse_sess.span_diagnostic,
+                      "negate_unsigned",
+                      e.span,
+                      "unary negation of unsigned integers may be removed in the future");
+              }
+              try!(const_uint_checked_neg(i, e, expr_uint_type))
+          }
+          const_str(_) => signal!(e, NegateOnString),
+          const_bool(_) => signal!(e, NegateOnBoolean),
+          const_binary(_) => signal!(e, NegateOnBinary),
+          const_val::Tuple(_) => signal!(e, NegateOnTuple),
+          const_val::Struct(..) => signal!(e, NegateOnStruct),
         }
       }
       ast::ExprUnary(ast::UnNot, ref inner) => {
-        match eval_const_expr_partial(tcx, &**inner, ety) {
-          Ok(const_int(i)) => Ok(const_int(!i)),
-          Ok(const_uint(i)) => Ok(const_uint(!i)),
-          Ok(const_bool(b)) => Ok(const_bool(!b)),
-          _ => Err("not on float or string".to_string())
+        match try!(eval_const_expr_partial(tcx, &**inner, ety)) {
+          const_int(i) => const_int(!i),
+          const_uint(i) => const_uint(!i),
+          const_bool(b) => const_bool(!b),
+          const_str(_) => signal!(e, NotOnString),
+          const_float(_) => signal!(e, NotOnFloat),
+          const_binary(_) => signal!(e, NotOnBinary),
+          const_val::Tuple(_) => signal!(e, NotOnTuple),
+          const_val::Struct(..) => signal!(e, NotOnStruct),
         }
       }
       ast::ExprBinary(op, ref a, ref b) => {
         let b_ty = match op.node {
-            ast::BiShl | ast::BiShr => Some(tcx.types.uint),
+            ast::BiShl | ast::BiShr => Some(tcx.types.usize),
             _ => ety
         };
-        match (eval_const_expr_partial(tcx, &**a, ety),
-               eval_const_expr_partial(tcx, &**b, b_ty)) {
-          (Ok(const_float(a)), Ok(const_float(b))) => {
+        match (try!(eval_const_expr_partial(tcx, &**a, ety)),
+               try!(eval_const_expr_partial(tcx, &**b, b_ty))) {
+          (const_float(a), const_float(b)) => {
             match op.node {
-              ast::BiAdd => Ok(const_float(a + b)),
-              ast::BiSub => Ok(const_float(a - b)),
-              ast::BiMul => Ok(const_float(a * b)),
-              ast::BiDiv => Ok(const_float(a / b)),
-              ast::BiRem => Ok(const_float(a % b)),
+              ast::BiAdd => const_float(a + b),
+              ast::BiSub => const_float(a - b),
+              ast::BiMul => const_float(a * b),
+              ast::BiDiv => const_float(a / b),
+              ast::BiRem => const_float(a % b),
               ast::BiEq => fromb(a == b),
               ast::BiLt => fromb(a < b),
               ast::BiLe => fromb(a <= b),
               ast::BiNe => fromb(a != b),
               ast::BiGe => fromb(a >= b),
               ast::BiGt => fromb(a > b),
-              _ => Err("can't do this op on floats".to_string())
+              _ => signal!(e, InvalidOpForFloats(op.node))
             }
           }
-          (Ok(const_int(a)), Ok(const_int(b))) => {
-            let is_a_min_value = |&:| {
-                let int_ty = match ty::expr_ty_opt(tcx, e).map(|ty| &ty.sty) {
-                    Some(&ty::ty_int(int_ty)) => int_ty,
-                    _ => return false
-                };
-                let int_ty = if let ast::TyIs(_) = int_ty {
-                    tcx.sess.target.int_type
-                } else {
-                    int_ty
-                };
-                match int_ty {
-                    ast::TyI8 => (a as i8) == i8::MIN,
-                    ast::TyI16 =>  (a as i16) == i16::MIN,
-                    ast::TyI32 =>  (a as i32) == i32::MIN,
-                    ast::TyI64 =>  (a as i64) == i64::MIN,
-                    ast::TyIs(_) => unreachable!()
-                }
-            };
+          (const_int(a), const_int(b)) => {
             match op.node {
-              ast::BiAdd => Ok(const_int(a + b)),
-              ast::BiSub => Ok(const_int(a - b)),
-              ast::BiMul => Ok(const_int(a * b)),
-              ast::BiDiv => {
-                  if b == 0 {
-                      Err("attempted to divide by zero".to_string())
-                  } else if b == -1 && is_a_min_value() {
-                      Err("attempted to divide with overflow".to_string())
-                  } else {
-                      Ok(const_int(a / b))
-                  }
-              }
-              ast::BiRem => {
-                  if b == 0 {
-                      Err("attempted remainder with a divisor of zero".to_string())
-                  } else if b == -1 && is_a_min_value() {
-                      Err("attempted remainder with overflow".to_string())
-                  } else {
-                      Ok(const_int(a % b))
-                  }
-              }
-              ast::BiAnd | ast::BiBitAnd => Ok(const_int(a & b)),
-              ast::BiOr | ast::BiBitOr => Ok(const_int(a | b)),
-              ast::BiBitXor => Ok(const_int(a ^ b)),
-              ast::BiShl => Ok(const_int(a << b as uint)),
-              ast::BiShr => Ok(const_int(a >> b as uint)),
+              ast::BiAdd => try!(const_int_checked_add(a,b,e,expr_int_type)),
+              ast::BiSub => try!(const_int_checked_sub(a,b,e,expr_int_type)),
+              ast::BiMul => try!(const_int_checked_mul(a,b,e,expr_int_type)),
+              ast::BiDiv => try!(const_int_checked_div(a,b,e,expr_int_type)),
+              ast::BiRem => try!(const_int_checked_rem(a,b,e,expr_int_type)),
+              ast::BiAnd | ast::BiBitAnd => const_int(a & b),
+              ast::BiOr | ast::BiBitOr => const_int(a | b),
+              ast::BiBitXor => const_int(a ^ b),
+              ast::BiShl => try!(const_int_checked_shl(a,b,e,expr_int_type)),
+              ast::BiShr => try!(const_int_checked_shr(a,b,e,expr_int_type)),
               ast::BiEq => fromb(a == b),
               ast::BiLt => fromb(a < b),
               ast::BiLe => fromb(a <= b),
@@ -317,25 +667,18 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
               ast::BiGt => fromb(a > b)
             }
           }
-          (Ok(const_uint(a)), Ok(const_uint(b))) => {
+          (const_uint(a), const_uint(b)) => {
             match op.node {
-              ast::BiAdd => Ok(const_uint(a + b)),
-              ast::BiSub => Ok(const_uint(a - b)),
-              ast::BiMul => Ok(const_uint(a * b)),
-              ast::BiDiv if b == 0 => {
-                  Err("attempted to divide by zero".to_string())
-              }
-              ast::BiDiv => Ok(const_uint(a / b)),
-              ast::BiRem if b == 0 => {
-                  Err("attempted remainder with a divisor of \
-                       zero".to_string())
-              }
-              ast::BiRem => Ok(const_uint(a % b)),
-              ast::BiAnd | ast::BiBitAnd => Ok(const_uint(a & b)),
-              ast::BiOr | ast::BiBitOr => Ok(const_uint(a | b)),
-              ast::BiBitXor => Ok(const_uint(a ^ b)),
-              ast::BiShl => Ok(const_uint(a << b as uint)),
-              ast::BiShr => Ok(const_uint(a >> b as uint)),
+              ast::BiAdd => try!(const_uint_checked_add(a,b,e,expr_uint_type)),
+              ast::BiSub => try!(const_uint_checked_sub(a,b,e,expr_uint_type)),
+              ast::BiMul => try!(const_uint_checked_mul(a,b,e,expr_uint_type)),
+              ast::BiDiv => try!(const_uint_checked_div(a,b,e,expr_uint_type)),
+              ast::BiRem => try!(const_uint_checked_rem(a,b,e,expr_uint_type)),
+              ast::BiAnd | ast::BiBitAnd => const_uint(a & b),
+              ast::BiOr | ast::BiBitOr => const_uint(a | b),
+              ast::BiBitXor => const_uint(a ^ b),
+              ast::BiShl => try!(const_uint_checked_shl(a,b,e,expr_uint_type)),
+              ast::BiShr => try!(const_uint_checked_shr(a,b,e,expr_uint_type)),
               ast::BiEq => fromb(a == b),
               ast::BiLt => fromb(a < b),
               ast::BiLe => fromb(a <= b),
@@ -345,22 +688,22 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
             }
           }
           // shifts can have any integral type as their rhs
-          (Ok(const_int(a)), Ok(const_uint(b))) => {
+          (const_int(a), const_uint(b)) => {
             match op.node {
-              ast::BiShl => Ok(const_int(a << b as uint)),
-              ast::BiShr => Ok(const_int(a >> b as uint)),
-              _ => Err("can't do this op on an int and uint".to_string())
+              ast::BiShl => try!(const_int_checked_shl_via_uint(a,b,e,expr_int_type)),
+              ast::BiShr => try!(const_int_checked_shr_via_uint(a,b,e,expr_int_type)),
+              _ => signal!(e, InvalidOpForIntUint(op.node)),
             }
           }
-          (Ok(const_uint(a)), Ok(const_int(b))) => {
+          (const_uint(a), const_int(b)) => {
             match op.node {
-              ast::BiShl => Ok(const_uint(a << b as uint)),
-              ast::BiShr => Ok(const_uint(a >> b as uint)),
-              _ => Err("can't do this op on a uint and int".to_string())
+              ast::BiShl => try!(const_uint_checked_shl_via_int(a,b,e,expr_uint_type)),
+              ast::BiShr => try!(const_uint_checked_shr_via_int(a,b,e,expr_uint_type)),
+              _ => signal!(e, InvalidOpForUintInt(op.node)),
             }
           }
-          (Ok(const_bool(a)), Ok(const_bool(b))) => {
-            Ok(const_bool(match op.node {
+          (const_bool(a), const_bool(b)) => {
+            const_bool(match op.node {
               ast::BiAnd => a && b,
               ast::BiOr => a || b,
               ast::BiBitXor => a ^ b,
@@ -368,10 +711,11 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
               ast::BiBitOr => a | b,
               ast::BiEq => a == b,
               ast::BiNe => a != b,
-              _ => return Err("can't do this op on bools".to_string())
-             }))
+              _ => signal!(e, InvalidOpForBools(op.node)),
+             })
           }
-          _ => Err("bad operands for binary".to_string())
+
+          _ => signal!(e, MiscBinaryOp),
         }
       }
       ast::ExprCast(ref base, ref target_ty) => {
@@ -383,13 +727,21 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
                     tcx.sess.span_fatal(target_ty.span,
                                         "target type not found for const cast")
                 });
+
         // Prefer known type to noop, but always have a type hint.
+        //
+        // FIXME (#23833): the type-hint can cause problems,
+        // e.g. `(i8::MAX + 1_i8) as u32` feeds in `u32` as result
+        // type to the sum, and thus no overflow is signaled.
         let base_hint = ty::expr_ty_opt(tcx, &**base).unwrap_or(ety);
         let val = try!(eval_const_expr_partial(tcx, &**base, Some(base_hint)));
-        cast_const(val, ety)
+        match cast_const(tcx, val, ety) {
+            Ok(val) => val,
+            Err(kind) => return Err(ConstEvalErr { span: e.span, kind: kind }),
+        }
       }
-      ast::ExprPath(_) | ast::ExprQPath(_) => {
-          let opt_def = tcx.def_map.borrow().get(&e.id).cloned();
+      ast::ExprPath(..) => {
+          let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
           let (const_expr, const_ty) = match opt_def {
               Some(def::DefConst(def_id)) => {
                   if ast_util::is_local(def_id) {
@@ -413,87 +765,117 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
           };
           let const_expr = match const_expr {
               Some(actual_e) => actual_e,
-              None => return Err("non-constant path in constant expr".to_string())
+              None => signal!(e, NonConstPath)
           };
           let ety = ety.or_else(|| const_ty.and_then(|ty| ast_ty_to_prim_ty(tcx, ty)));
-          eval_const_expr_partial(tcx, const_expr, ety)
+          try!(eval_const_expr_partial(tcx, const_expr, ety))
       }
       ast::ExprLit(ref lit) => {
-          Ok(lit_to_const(&**lit, ety))
+          lit_to_const(&**lit, ety)
       }
-      ast::ExprParen(ref e)     => eval_const_expr_partial(tcx, &**e, ety),
+      ast::ExprParen(ref e) => try!(eval_const_expr_partial(tcx, &**e, ety)),
       ast::ExprBlock(ref block) => {
         match block.expr {
-            Some(ref expr) => eval_const_expr_partial(tcx, &**expr, ety),
-            None => Ok(const_int(0i64))
+            Some(ref expr) => try!(eval_const_expr_partial(tcx, &**expr, ety)),
+            None => const_int(0)
         }
       }
+      ast::ExprTup(_) => {
+        const_val::Tuple(e.id)
+      }
+      ast::ExprStruct(..) => {
+        const_val::Struct(e.id)
+      }
       ast::ExprTupField(ref base, index) => {
-        // Get the base tuple if it is constant
-        if let Some(&ast::ExprTup(ref fields)) = lookup_const(tcx, &**base).map(|s| &s.node) {
-            // Check that the given index is within bounds and evaluate its value
-            if fields.len() > index.node {
-                return eval_const_expr_partial(tcx, &*fields[index.node], None)
+        if let Ok(c) = eval_const_expr_partial(tcx, base, None) {
+            if let const_val::Tuple(tup_id) = c {
+                if let ast::ExprTup(ref fields) = tcx.map.expect_expr(tup_id).node {
+                    if index.node < fields.len() {
+                        return eval_const_expr_partial(tcx, &fields[index.node], None)
+                    } else {
+                        signal!(e, TupleIndexOutOfBounds);
+                    }
+                } else {
+                    unreachable!()
+                }
             } else {
-                return Err("tuple index out of bounds".to_string())
+                signal!(base, ExpectedConstTuple);
             }
+        } else {
+            signal!(base, NonConstPath)
         }
-
-        Err("non-constant struct in constant expr".to_string())
       }
       ast::ExprField(ref base, field_name) => {
         // Get the base expression if it is a struct and it is constant
-        if let Some(&ast::ExprStruct(_, ref fields, _)) = lookup_const(tcx, &**base)
-                                                            .map(|s| &s.node) {
-            // Check that the given field exists and evaluate it
-            if let Some(f) = fields.iter().find(|f|
-                                           f.ident.node.as_str() == field_name.node.as_str()) {
-                return eval_const_expr_partial(tcx, &*f.expr, None)
+        if let Ok(c) = eval_const_expr_partial(tcx, base, None) {
+            if let const_val::Struct(struct_id) = c {
+                if let ast::ExprStruct(_, ref fields, _) = tcx.map.expect_expr(struct_id).node {
+                    // Check that the given field exists and evaluate it
+                    if let Some(f) = fields.iter().find(|f| f.ident.node.as_str()
+                                                         == field_name.node.as_str()) {
+                        return eval_const_expr_partial(tcx, &*f.expr, None)
+                    } else {
+                        signal!(e, MissingStructField);
+                    }
+                } else {
+                    unreachable!()
+                }
             } else {
-                return Err("nonexistent struct field".to_string())
+                signal!(base, ExpectedConstStruct);
             }
+        } else {
+            signal!(base, NonConstPath);
         }
-
-        Err("non-constant struct in constant expr".to_string())
       }
-      _ => Err("unsupported constant expr".to_string())
-    }
+      _ => signal!(e, MiscCatchAll)
+    };
+
+    Ok(result)
 }
 
-fn cast_const(val: const_val, ty: Ty) -> Result<const_val, String> {
-    macro_rules! define_casts {
-        ($($ty_pat:pat => (
-            $intermediate_ty:ty,
-            $const_type:ident,
-            $target_ty:ty
-        )),*) => (match ty.sty {
-            $($ty_pat => {
-                match val {
-                    const_bool(b) => Ok($const_type(b as $intermediate_ty as $target_ty)),
-                    const_uint(u) => Ok($const_type(u as $intermediate_ty as $target_ty)),
-                    const_int(i) => Ok($const_type(i as $intermediate_ty as $target_ty)),
-                    const_float(f) => Ok($const_type(f as $intermediate_ty as $target_ty)),
-                    _ => Err(concat!("can't cast this type to ",
-                                     stringify!($const_type)).to_string())
-                }
-            },)*
-            _ => Err("can't cast this type".to_string())
-        })
+fn cast_const<'tcx>(tcx: &ty::ctxt<'tcx>, val: const_val, ty: Ty) -> CastResult {
+    macro_rules! convert_val {
+        ($intermediate_ty:ty, $const_type:ident, $target_ty:ty) => {
+            match val {
+                const_bool(b) => Ok($const_type(b as $intermediate_ty as $target_ty)),
+                const_uint(u) => Ok($const_type(u as $intermediate_ty as $target_ty)),
+                const_int(i) => Ok($const_type(i as $intermediate_ty as $target_ty)),
+                const_float(f) => Ok($const_type(f as $intermediate_ty as $target_ty)),
+                _ => Err(ErrKind::CannotCastTo(stringify!($const_type))),
+            }
+        }
+    }
+
+    // Issue #23890: If isize/usize, then dispatch to appropriate target representation type
+    match (&ty.sty, tcx.sess.target.int_type, tcx.sess.target.uint_type) {
+        (&ty::ty_int(ast::TyIs), ast::TyI32, _) => return convert_val!(i32, const_int, i64),
+        (&ty::ty_int(ast::TyIs), ast::TyI64, _) => return convert_val!(i64, const_int, i64),
+        (&ty::ty_int(ast::TyIs), _, _) => panic!("unexpected target.int_type"),
+
+        (&ty::ty_uint(ast::TyUs), _, ast::TyU32) => return convert_val!(u32, const_uint, u64),
+        (&ty::ty_uint(ast::TyUs), _, ast::TyU64) => return convert_val!(u64, const_uint, u64),
+        (&ty::ty_uint(ast::TyUs), _, _) => panic!("unexpected target.uint_type"),
+
+        _ => {}
     }
 
-    define_casts!{
-        ty::ty_int(ast::TyIs(_)) => (int, const_int, i64),
-        ty::ty_int(ast::TyI8) => (i8, const_int, i64),
-        ty::ty_int(ast::TyI16) => (i16, const_int, i64),
-        ty::ty_int(ast::TyI32) => (i32, const_int, i64),
-        ty::ty_int(ast::TyI64) => (i64, const_int, i64),
-        ty::ty_uint(ast::TyUs(_)) => (uint, const_uint, u64),
-        ty::ty_uint(ast::TyU8) => (u8, const_uint, u64),
-        ty::ty_uint(ast::TyU16) => (u16, const_uint, u64),
-        ty::ty_uint(ast::TyU32) => (u32, const_uint, u64),
-        ty::ty_uint(ast::TyU64) => (u64, const_uint, u64),
-        ty::ty_float(ast::TyF32) => (f32, const_float, f64),
-        ty::ty_float(ast::TyF64) => (f64, const_float, f64)
+    match ty.sty {
+        ty::ty_int(ast::TyIs) => unreachable!(),
+        ty::ty_uint(ast::TyUs) => unreachable!(),
+
+        ty::ty_int(ast::TyI8) => convert_val!(i8, const_int, i64),
+        ty::ty_int(ast::TyI16) => convert_val!(i16, const_int, i64),
+        ty::ty_int(ast::TyI32) => convert_val!(i32, const_int, i64),
+        ty::ty_int(ast::TyI64) => convert_val!(i64, const_int, i64),
+
+        ty::ty_uint(ast::TyU8) => convert_val!(u8, const_uint, u64),
+        ty::ty_uint(ast::TyU16) => convert_val!(u16, const_uint, u64),
+        ty::ty_uint(ast::TyU32) => convert_val!(u32, const_uint, u64),
+        ty::ty_uint(ast::TyU64) => convert_val!(u64, const_uint, u64),
+
+        ty::ty_float(ast::TyF32) => convert_val!(f32, const_float, f64),
+        ty::ty_float(ast::TyF64) => convert_val!(f64, const_float, f64),
+        _ => Err(ErrKind::CannotCast),
     }
 }
 
@@ -551,15 +933,15 @@ pub fn compare_lit_exprs<'tcx>(tcx: &ty::ctxt<'tcx>,
                                -> Option<Ordering> {
     let a = match eval_const_expr_partial(tcx, a, ty_hint) {
         Ok(a) => a,
-        Err(s) => {
-            tcx.sess.span_err(a.span, &s[..]);
+        Err(e) => {
+            tcx.sess.span_err(a.span, &e.description());
             return None;
         }
     };
     let b = match eval_const_expr_partial(tcx, b, ty_hint) {
         Ok(b) => b,
-        Err(s) => {
-            tcx.sess.span_err(b.span, &s[..]);
+        Err(e) => {
+            tcx.sess.span_err(b.span, &e.description());
             return None;
         }
     };
index 085d5cbc347e5b015801586b7756c1f2acce7b67..f69ac030520922a471d9212d1c90922c9daf25c6 100644 (file)
@@ -19,7 +19,7 @@ pub use self::EntryOrExit::*;
 use middle::cfg;
 use middle::cfg::CFGIndex;
 use middle::ty;
-use std::old_io;
+use std::io;
 use std::usize;
 use std::iter::repeat;
 use syntax::ast;
@@ -28,7 +28,7 @@ use syntax::visit;
 use syntax::print::{pp, pprust};
 use util::nodemap::NodeMap;
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum EntryOrExit {
     Entry,
     Exit,
@@ -45,15 +45,15 @@ pub struct DataFlowContext<'a, 'tcx: 'a, O> {
     oper: O,
 
     /// number of bits to propagate per id
-    bits_per_id: uint,
+    bits_per_id: usize,
 
     /// number of words we will use to store bits_per_id.
     /// equal to bits_per_id/usize::BITS rounded up.
-    words_per_id: uint,
+    words_per_id: usize,
 
     // mapping from node to cfg node index
     // FIXME (#6298): Shouldn't this go with CFG?
-    nodeid_to_index: NodeMap<CFGIndex>,
+    nodeid_to_index: NodeMap<Vec<CFGIndex>>,
 
     // Bit sets per cfg node.  The following three fields (`gens`, `kills`,
     // and `on_entry`) all have the same structure. For each id in
@@ -62,19 +62,19 @@ pub struct DataFlowContext<'a, 'tcx: 'a, O> {
     // the full vector (see the method `compute_id_range()`).
 
     /// bits generated as we exit the cfg node. Updated by `add_gen()`.
-    gens: Vec<uint>,
+    gens: Vec<usize>,
 
     /// bits killed as we exit the cfg node. Updated by `add_kill()`.
-    kills: Vec<uint>,
+    kills: Vec<usize>,
 
     /// bits that are valid on entry to the cfg node. Updated by
     /// `propagate()`.
-    on_entry: Vec<uint>,
+    on_entry: Vec<usize>,
 }
 
 pub trait BitwiseOperator {
     /// Joins two predecessor bits together, typically either `|` or `&`
-    fn join(&self, succ: uint, pred: uint) -> uint;
+    fn join(&self, succ: usize, pred: usize) -> usize;
 }
 
 /// Parameterization for the precise form of data flow that is used.
@@ -88,11 +88,9 @@ struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O: 'a> {
     changed: bool
 }
 
-fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap<CFGIndex>) -> CFGIndex {
-    let opt_cfgindex = index.get(&id).cloned();
-    opt_cfgindex.unwrap_or_else(|| {
-        panic!("nodeid_to_index does not have entry for NodeId {}", id);
-    })
+fn get_cfg_indices<'a>(id: ast::NodeId, index: &'a NodeMap<Vec<CFGIndex>>) -> &'a [CFGIndex] {
+    let opt_indices = index.get(&id);
+    opt_indices.map(|v| &v[..]).unwrap_or(&[])
 }
 
 impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
@@ -105,18 +103,22 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
 impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O> {
     fn pre(&self,
            ps: &mut pprust::State,
-           node: pprust::AnnNode) -> old_io::IoResult<()> {
+           node: pprust::AnnNode) -> io::Result<()> {
         let id = match node {
             pprust::NodeIdent(_) | pprust::NodeName(_) => 0,
             pprust::NodeExpr(expr) => expr.id,
             pprust::NodeBlock(blk) => blk.id,
-            pprust::NodeItem(_) => 0,
+            pprust::NodeItem(_) | pprust::NodeSubItem(_) => 0,
             pprust::NodePat(pat) => pat.id
         };
 
-        if self.has_bitset_for_nodeid(id) {
-            assert!(self.bits_per_id > 0);
-            let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
+        if !self.has_bitset_for_nodeid(id) {
+            return Ok(());
+        }
+
+        assert!(self.bits_per_id > 0);
+        let indices = get_cfg_indices(id, &self.nodeid_to_index);
+        for &cfgidx in indices {
             let (start, end) = self.compute_id_range(cfgidx);
             let on_entry = &self.on_entry[start.. end];
             let entry_str = bits_to_string(on_entry);
@@ -144,7 +146,7 @@ impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O
 }
 
 fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
-                         cfg: &cfg::CFG) -> NodeMap<CFGIndex> {
+                         cfg: &cfg::CFG) -> NodeMap<Vec<CFGIndex>> {
     let mut index = NodeMap();
 
     // FIXME (#6298): Would it be better to fold formals from decl
@@ -157,28 +159,28 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
     }
 
     cfg.graph.each_node(|node_idx, node| {
-        if node.data.id != ast::DUMMY_NODE_ID {
-            index.insert(node.data.id, node_idx);
+        if let cfg::CFGNodeData::AST(id) = node.data {
+            index.entry(id).or_insert(vec![]).push(node_idx);
         }
         true
     });
 
     return index;
 
-    fn add_entries_from_fn_decl(index: &mut NodeMap<CFGIndex>,
+    fn add_entries_from_fn_decl(index: &mut NodeMap<Vec<CFGIndex>>,
                                 decl: &ast::FnDecl,
                                 entry: CFGIndex) {
         //! add mappings from the ast nodes for the formal bindings to
         //! the entry-node in the graph.
         struct Formals<'a> {
             entry: CFGIndex,
-            index: &'a mut NodeMap<CFGIndex>,
+            index: &'a mut NodeMap<Vec<CFGIndex>>,
         }
         let mut formals = Formals { entry: entry, index: index };
         visit::walk_fn_decl(&mut formals, decl);
         impl<'a, 'v> visit::Visitor<'v> for Formals<'a> {
             fn visit_pat(&mut self, p: &ast::Pat) {
-                self.index.insert(p.id, self.entry);
+                self.index.entry(p.id).or_insert(vec![]).push(self.entry);
                 visit::walk_pat(self, p)
             }
         }
@@ -192,8 +194,8 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
                cfg: &cfg::CFG,
                oper: O,
                id_range: IdRange,
-               bits_per_id: uint) -> DataFlowContext<'a, 'tcx, O> {
-        let words_per_id = (bits_per_id + usize::BITS - 1) / usize::BITS;
+               bits_per_id: usize) -> DataFlowContext<'a, 'tcx, O> {
+        let words_per_id = (bits_per_id + usize::BITS as usize - 1) / usize::BITS as usize;
         let num_nodes = cfg.graph.all_nodes().len();
 
         debug!("DataFlowContext::new(analysis_name: {}, id_range={:?}, \
@@ -223,33 +225,37 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
         }
     }
 
-    pub fn add_gen(&mut self, id: ast::NodeId, bit: uint) {
+    pub fn add_gen(&mut self, id: ast::NodeId, bit: usize) {
         //! Indicates that `id` generates `bit`
         debug!("{} add_gen(id={}, bit={})",
                self.analysis_name, id, bit);
         assert!(self.nodeid_to_index.contains_key(&id));
         assert!(self.bits_per_id > 0);
 
-        let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
-        let (start, end) = self.compute_id_range(cfgidx);
-        let gens = &mut self.gens[start.. end];
-        set_bit(gens, bit);
+        let indices = get_cfg_indices(id, &self.nodeid_to_index);
+        for &cfgidx in indices {
+            let (start, end) = self.compute_id_range(cfgidx);
+            let gens = &mut self.gens[start.. end];
+            set_bit(gens, bit);
+        }
     }
 
-    pub fn add_kill(&mut self, id: ast::NodeId, bit: uint) {
+    pub fn add_kill(&mut self, id: ast::NodeId, bit: usize) {
         //! Indicates that `id` kills `bit`
         debug!("{} add_kill(id={}, bit={})",
                self.analysis_name, id, bit);
         assert!(self.nodeid_to_index.contains_key(&id));
         assert!(self.bits_per_id > 0);
 
-        let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
-        let (start, end) = self.compute_id_range(cfgidx);
-        let kills = &mut self.kills[start.. end];
-        set_bit(kills, bit);
+        let indices = get_cfg_indices(id, &self.nodeid_to_index);
+        for &cfgidx in indices {
+            let (start, end) = self.compute_id_range(cfgidx);
+            let kills = &mut self.kills[start.. end];
+            set_bit(kills, bit);
+        }
     }
 
-    fn apply_gen_kill(&self, cfgidx: CFGIndex, bits: &mut [uint]) {
+    fn apply_gen_kill(&self, cfgidx: CFGIndex, bits: &mut [usize]) {
         //! Applies the gen and kill sets for `cfgidx` to `bits`
         debug!("{} apply_gen_kill(cfgidx={:?}, bits={}) [before]",
                self.analysis_name, cfgidx, mut_bits_to_string(bits));
@@ -265,7 +271,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
                self.analysis_name, cfgidx, mut_bits_to_string(bits));
     }
 
-    fn compute_id_range(&self, cfgidx: CFGIndex) -> (uint, uint) {
+    fn compute_id_range(&self, cfgidx: CFGIndex) -> (usize, usize) {
         let n = cfgidx.node_id();
         let start = n * self.words_per_id;
         let end = start + self.words_per_id;
@@ -279,20 +285,25 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
     }
 
 
-    pub fn each_bit_on_entry<F>(&self, id: ast::NodeId, f: F) -> bool where
-        F: FnMut(uint) -> bool,
+    pub fn each_bit_on_entry<F>(&self, id: ast::NodeId, mut f: F) -> bool where
+        F: FnMut(usize) -> bool,
     {
         //! Iterates through each bit that is set on entry to `id`.
         //! Only useful after `propagate()` has been called.
         if !self.has_bitset_for_nodeid(id) {
             return true;
         }
-        let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
-        self.each_bit_for_node(Entry, cfgidx, f)
+        let indices = get_cfg_indices(id, &self.nodeid_to_index);
+        for &cfgidx in indices {
+            if !self.each_bit_for_node(Entry, cfgidx, |i| f(i)) {
+                return false;
+            }
+        }
+        return true;
     }
 
     pub fn each_bit_for_node<F>(&self, e: EntryOrExit, cfgidx: CFGIndex, f: F) -> bool where
-        F: FnMut(uint) -> bool,
+        F: FnMut(usize) -> bool,
     {
         //! Iterates through each bit that is set on entry/exit to `cfgidx`.
         //! Only useful after `propagate()` has been called.
@@ -320,8 +331,8 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
         self.each_bit(slice, f)
     }
 
-    pub fn each_gen_bit<F>(&self, id: ast::NodeId, f: F) -> bool where
-        F: FnMut(uint) -> bool,
+    pub fn each_gen_bit<F>(&self, id: ast::NodeId, mut f: F) -> bool where
+        F: FnMut(usize) -> bool,
     {
         //! Iterates through each bit in the gen set for `id`.
         if !self.has_bitset_for_nodeid(id) {
@@ -334,16 +345,21 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
             return true;
         }
 
-        let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
-        let (start, end) = self.compute_id_range(cfgidx);
-        let gens = &self.gens[start.. end];
-        debug!("{} each_gen_bit(id={}, gens={})",
-               self.analysis_name, id, bits_to_string(gens));
-        self.each_bit(gens, f)
+        let indices = get_cfg_indices(id, &self.nodeid_to_index);
+        for &cfgidx in indices {
+            let (start, end) = self.compute_id_range(cfgidx);
+            let gens = &self.gens[start.. end];
+            debug!("{} each_gen_bit(id={}, gens={})",
+                   self.analysis_name, id, bits_to_string(gens));
+            if !self.each_bit(gens, |i| f(i)) {
+                return false;
+            }
+        }
+        return true;
     }
 
-    fn each_bit<F>(&self, words: &[uint], mut f: F) -> bool where
-        F: FnMut(uint) -> bool,
+    fn each_bit<F>(&self, words: &[usize], mut f: F) -> bool where
+        F: FnMut(usize) -> bool,
     {
         //! Helper for iterating over the bits in a bit set.
         //! Returns false on the first call to `f` that returns false;
@@ -351,7 +367,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
 
         for (word_index, &word) in words.iter().enumerate() {
             if word != 0 {
-                let base_index = word_index * usize::BITS;
+                let base_index = word_index * usize::BITS as usize;
                 for offset in 0..usize::BITS {
                     let bit = 1 << offset;
                     if (word & bit) != 0 {
@@ -364,7 +380,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
                         // whether the bit_index is greater than the
                         // actual value the user specified and stop
                         // iterating if so.
-                        let bit_index = base_index + offset;
+                        let bit_index = base_index + offset as usize;
                         if bit_index >= self.bits_per_id {
                             return true;
                         } else if !f(bit_index) {
@@ -400,13 +416,15 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
 
             let mut changed = false;
             for &node_id in &edge.data.exiting_scopes {
-                let opt_cfg_idx = self.nodeid_to_index.get(&node_id).cloned();
+                let opt_cfg_idx = self.nodeid_to_index.get(&node_id);
                 match opt_cfg_idx {
-                    Some(cfg_idx) => {
-                        let (start, end) = self.compute_id_range(cfg_idx);
-                        let kills = &self.kills[start.. end];
-                        if bitwise(&mut orig_kills, kills, &Union) {
-                            changed = true;
+                    Some(indices) => {
+                        for &cfg_idx in indices {
+                            let (start, end) = self.compute_id_range(cfg_idx);
+                            let kills = &self.kills[start.. end];
+                            if bitwise(&mut orig_kills, kills, &Union) {
+                                changed = true;
+                            }
                         }
                     }
                     None => {
@@ -457,13 +475,15 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> {
 
         debug!("Dataflow result for {}:", self.analysis_name);
         debug!("{}", {
-            self.pretty_print_to(box old_io::stderr(), blk).unwrap();
+            let mut v = Vec::new();
+            self.pretty_print_to(box &mut v, blk).unwrap();
+            println!("{}", String::from_utf8(v).unwrap());
             ""
         });
     }
 
-    fn pretty_print_to(&self, wr: Box<old_io::Writer+'static>,
-                       blk: &ast::Block) -> old_io::IoResult<()> {
+    fn pretty_print_to<'b>(&self, wr: Box<io::Write + 'b>,
+                           blk: &ast::Block) -> io::Result<()> {
         let mut ps = pprust::rust_printer_annotated(wr, self);
         try!(ps.cbox(pprust::indent_unit));
         try!(ps.ibox(0));
@@ -475,14 +495,14 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> {
 impl<'a, 'b, 'tcx, O:DataFlowOperator> PropagationContext<'a, 'b, 'tcx, O> {
     fn walk_cfg(&mut self,
                 cfg: &cfg::CFG,
-                in_out: &mut [uint]) {
+                in_out: &mut [usize]) {
         debug!("DataFlowContext::walk_cfg(in_out={}) {}",
                bits_to_string(in_out), self.dfcx.analysis_name);
         assert!(self.dfcx.bits_per_id > 0);
 
         cfg.graph.each_node(|node_index, node| {
             debug!("DataFlowContext::walk_cfg idx={:?} id={} begin in_out={}",
-                   node_index, node.data.id, bits_to_string(in_out));
+                   node_index, node.data.id(), bits_to_string(in_out));
 
             let (start, end) = self.dfcx.compute_id_range(node_index);
 
@@ -499,7 +519,7 @@ impl<'a, 'b, 'tcx, O:DataFlowOperator> PropagationContext<'a, 'b, 'tcx, O> {
         });
     }
 
-    fn reset(&mut self, bits: &mut [uint]) {
+    fn reset(&mut self, bits: &mut [usize]) {
         let e = if self.dfcx.oper.initial_value() {usize::MAX} else {0};
         for b in bits {
             *b = e;
@@ -507,7 +527,7 @@ impl<'a, 'b, 'tcx, O:DataFlowOperator> PropagationContext<'a, 'b, 'tcx, O> {
     }
 
     fn propagate_bits_into_graph_successors_of(&mut self,
-                                               pred_bits: &[uint],
+                                               pred_bits: &[usize],
                                                cfg: &cfg::CFG,
                                                cfgidx: CFGIndex) {
         cfg.graph.each_outgoing_edge(cfgidx, |_e_idx, edge| {
@@ -517,7 +537,7 @@ impl<'a, 'b, 'tcx, O:DataFlowOperator> PropagationContext<'a, 'b, 'tcx, O> {
     }
 
     fn propagate_bits_into_entry_set_for(&mut self,
-                                         pred_bits: &[uint],
+                                         pred_bits: &[usize],
                                          edge: &cfg::CFGEdge) {
         let source = edge.source();
         let cfgidx = edge.target();
@@ -540,11 +560,11 @@ impl<'a, 'b, 'tcx, O:DataFlowOperator> PropagationContext<'a, 'b, 'tcx, O> {
     }
 }
 
-fn mut_bits_to_string(words: &mut [uint]) -> String {
+fn mut_bits_to_string(words: &mut [usize]) -> String {
     bits_to_string(words)
 }
 
-fn bits_to_string(words: &[uint]) -> String {
+fn bits_to_string(words: &[usize]) -> String {
     let mut result = String::new();
     let mut sep = '[';
 
@@ -554,7 +574,7 @@ fn bits_to_string(words: &[uint]) -> String {
         let mut v = word;
         for _ in 0..usize::BYTES {
             result.push(sep);
-            result.push_str(&format!("{:02x}", v & 0xFF)[]);
+            result.push_str(&format!("{:02x}", v & 0xFF));
             v >>= 8;
             sep = '-';
         }
@@ -564,8 +584,8 @@ fn bits_to_string(words: &[uint]) -> String {
 }
 
 #[inline]
-fn bitwise<Op:BitwiseOperator>(out_vec: &mut [uint],
-                               in_vec: &[uint],
+fn bitwise<Op:BitwiseOperator>(out_vec: &mut [usize],
+                               in_vec: &[usize],
                                op: &Op) -> bool {
     assert_eq!(out_vec.len(), in_vec.len());
     let mut changed = false;
@@ -578,11 +598,11 @@ fn bitwise<Op:BitwiseOperator>(out_vec: &mut [uint],
     changed
 }
 
-fn set_bit(words: &mut [uint], bit: uint) -> bool {
+fn set_bit(words: &mut [usize], bit: usize) -> bool {
     debug!("set_bit: words={} bit={}",
            mut_bits_to_string(words), bit_str(bit));
-    let word = bit / usize::BITS;
-    let bit_in_word = bit % usize::BITS;
+    let word = bit / usize::BITS as usize;
+    let bit_in_word = bit % usize::BITS as usize;
     let bit_mask = 1 << bit_in_word;
     debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, word);
     let oldv = words[word];
@@ -591,7 +611,7 @@ fn set_bit(words: &mut [uint], bit: uint) -> bool {
     oldv != newv
 }
 
-fn bit_str(bit: uint) -> String {
+fn bit_str(bit: usize) -> String {
     let byte = bit >> 8;
     let lobits = 1 << (bit & 0xFF);
     format!("[{}:{}-{:02x}]", bit, byte, lobits)
@@ -599,9 +619,9 @@ fn bit_str(bit: uint) -> String {
 
 struct Union;
 impl BitwiseOperator for Union {
-    fn join(&self, a: uint, b: uint) -> uint { a | b }
+    fn join(&self, a: usize, b: usize) -> usize { a | b }
 }
 struct Subtract;
 impl BitwiseOperator for Subtract {
-    fn join(&self, a: uint, b: uint) -> uint { a & !b }
+    fn join(&self, a: usize, b: usize) -> usize { a & !b }
 }
index ff78deb8d12ea6ba945531b6c34f0762b38a2ee6..568375597c0de1bfd9f1d2dd9db2ee5a9a2fa108 100644 (file)
@@ -18,7 +18,7 @@ use util::nodemap::NodeSet;
 
 use std::collections::HashSet;
 use syntax::{ast, ast_map, codemap};
-use syntax::ast_util::{local_def, is_local, PostExpansionMethod};
+use syntax::ast_util::{local_def, is_local};
 use syntax::attr::{self, AttrMetaMethods};
 use syntax::visit::{self, Visitor};
 
@@ -71,13 +71,13 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
 
     fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
         self.tcx.def_map.borrow().get(id).map(|def| {
-            match def {
-                &def::DefConst(_) => {
+            match def.full_def() {
+                def::DefConst(_) => {
                     self.check_def_id(def.def_id())
                 }
                 _ if self.ignore_non_const_paths => (),
-                &def::DefPrimTy(_) => (),
-                &def::DefVariant(enum_id, variant_id, _) => {
+                def::DefPrimTy(_) => (),
+                def::DefVariant(enum_id, variant_id, _) => {
                     self.check_def_id(enum_id);
                     self.check_def_id(variant_id);
                 }
@@ -145,7 +145,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
         }
     }
 
-    fn handle_tup_field_access(&mut self, lhs: &ast::Expr, idx: uint) {
+    fn handle_tup_field_access(&mut self, lhs: &ast::Expr, idx: usize) {
         match ty::expr_ty_adjusted(self.tcx, lhs).sty {
             ty::ty_struct(id, _) => {
                 let fields = ty::lookup_struct_fields(self.tcx, id);
@@ -158,7 +158,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
 
     fn handle_field_pattern_match(&mut self, lhs: &ast::Pat,
                                   pats: &[codemap::Spanned<ast::FieldPat>]) {
-        let id = match (*self.tcx.def_map.borrow())[lhs.id] {
+        let id = match self.tcx.def_map.borrow().get(&lhs.id).unwrap().full_def() {
             def::DefVariant(_, id, _) => id,
             _ => {
                 match ty::ty_to_def_id(ty::node_id_to_type(self.tcx,
@@ -228,16 +228,11 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                     _ => ()
                 }
             }
-            ast_map::NodeTraitItem(trait_method) => {
-                visit::walk_trait_item(self, trait_method);
+            ast_map::NodeTraitItem(trait_item) => {
+                visit::walk_trait_item(self, trait_item);
             }
             ast_map::NodeImplItem(impl_item) => {
-                match *impl_item {
-                    ast::MethodImplItem(ref method) => {
-                        visit::walk_method_helper(self, method);
-                    }
-                    ast::TypeImplItem(_) => {}
-                }
+                visit::walk_impl_item(self, impl_item);
             }
             ast_map::NodeForeignItem(foreign_item) => {
                 visit::walk_foreign_item(self, &*foreign_item);
@@ -355,13 +350,29 @@ impl<'v> Visitor<'v> for LifeSeeder {
             ast::ItemEnum(ref enum_def, _) if allow_dead_code => {
                 self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id));
             }
-            ast::ItemImpl(_, _, _, Some(ref _trait_ref), _, ref impl_items) => {
+            ast::ItemTrait(_, _, _, ref trait_items) => {
+                for trait_item in trait_items {
+                    match trait_item.node {
+                        ast::MethodTraitItem(_, Some(_)) => {
+                            if has_allow_dead_code_or_lang_attr(&trait_item.attrs) {
+                                self.worklist.push(trait_item.id);
+                            }
+                        }
+                        _ => {}
+                    }
+                }
+            }
+            ast::ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
                 for impl_item in impl_items {
-                    match *impl_item {
-                        ast::MethodImplItem(ref method) => {
-                            self.worklist.push(method.id);
+                    match impl_item.node {
+                        ast::MethodImplItem(..) => {
+                            if opt_trait.is_some() ||
+                                    has_allow_dead_code_or_lang_attr(&impl_item.attrs) {
+                                self.worklist.push(impl_item.id);
+                            }
                         }
                         ast::TypeImplItem(_) => {}
+                        ast::MacImplItem(_) => panic!("unexpanded macro")
                     }
                 }
             }
@@ -369,21 +380,6 @@ impl<'v> Visitor<'v> for LifeSeeder {
         }
         visit::walk_item(self, item);
     }
-
-    fn visit_fn(&mut self, fk: visit::FnKind<'v>,
-                _: &'v ast::FnDecl, block: &'v ast::Block,
-                _: codemap::Span, id: ast::NodeId) {
-        // Check for method here because methods are not ast::Item
-        match fk {
-            visit::FkMethod(_, _, method) => {
-                if has_allow_dead_code_or_lang_attr(&method.attrs) {
-                    self.worklist.push(id);
-                }
-            }
-            _ => ()
-        }
-        visit::walk_block(self, block);
-    }
 }
 
 fn create_and_seed_worklist(tcx: &ty::ctxt,
@@ -500,7 +496,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
             None => (),
             Some(impl_list) => {
                 for impl_did in &**impl_list {
-                    for item_did in &(*impl_items)[*impl_did] {
+                    for item_did in &*impl_items.get(impl_did).unwrap() {
                         if self.live_symbols.contains(&item_did.def_id()
                                                                .node) {
                             return true;
@@ -561,7 +557,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
                 span: codemap::Span, id: ast::NodeId) {
         // Have to warn method here because methods are not ast::Item
         match fk {
-            visit::FkMethod(name, _, _) => {
+            visit::FkMethod(name, _) => {
                 if !self.symbol_is_live(id, None) {
                     self.warn_dead_code(id, span, name, "method");
                 }
@@ -582,12 +578,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
 
     // Overwrite so that we don't warn the trait method itself.
     fn visit_trait_item(&mut self, trait_method: &ast::TraitItem) {
-        match *trait_method {
-            ast::ProvidedMethod(ref method) => {
-                visit::walk_block(self, &*method.pe_body())
+        match trait_method.node {
+            ast::MethodTraitItem(_, Some(ref body)) => {
+                visit::walk_block(self, body)
             }
-            ast::RequiredMethod(_) => {}
-            ast::TypeTraitItem(_) => {}
+            ast::MethodTraitItem(_, None) |
+            ast::TypeTraitItem(..) => {}
         }
     }
 }
index 7857bcad8135d8dc6628c80aaf7e792221a07d84..6707a4d3fd775454ca0d9a109469a08c6cf3c9a9 100644 (file)
 
 pub use self::Def::*;
 pub use self::MethodProvenance::*;
-pub use self::TraitItemKind::*;
 
+use middle::privacy::LastPrivate;
 use middle::subst::ParamSpace;
-use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
 use util::nodemap::NodeMap;
 use syntax::ast;
 use syntax::ast_util::local_def;
@@ -23,7 +22,6 @@ use std::cell::RefCell;
 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Def {
     DefFn(ast::DefId, bool /* is_ctor */),
-    DefStaticMethod(/* method */ ast::DefId, MethodProvenance),
     DefSelfTy(/* trait id */ ast::NodeId),
     DefMod(ast::DefId),
     DefForeignMod(ast::DefId),
@@ -32,12 +30,7 @@ pub enum Def {
     DefLocal(ast::NodeId),
     DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */),
     DefTy(ast::DefId, bool /* is_enum */),
-    DefAssociatedTy(ast::DefId),
-    // A partially resolved path to an associated type `T::U` where `T` is a concrete
-    // type (indicated by the DefId) which implements a trait which has an associated
-    // type `U` (indicated by the Ident).
-    // FIXME(#20301) -- should use Name
-    DefAssociatedPath(TyParamProvenance, ast::Ident),
+    DefAssociatedTy(ast::DefId /* trait */, ast::DefId),
     DefTrait(ast::DefId),
     DefPrimTy(ast::PrimTy),
     DefTyParam(ParamSpace, u32, ast::DefId, ast::Name),
@@ -54,19 +47,64 @@ pub enum Def {
     /// - If it's an ExprPath referring to some tuple struct, then DefMap maps
     ///   it to a def whose id is the StructDef.ctor_id.
     DefStruct(ast::DefId),
-    DefTyParamBinder(ast::NodeId), /* struct, impl or trait with ty params */
     DefRegion(ast::NodeId),
     DefLabel(ast::NodeId),
-    DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */, MethodProvenance),
+    DefMethod(ast::DefId /* method */, MethodProvenance),
+}
+
+/// The result of resolving a path.
+/// Before type checking completes, `depth` represents the number of
+/// trailing segments which are yet unresolved. Afterwards, if there
+/// were no errors, all paths should be fully resolved, with `depth`
+/// set to `0` and `base_def` representing the final resolution.
+///
+///     module::Type::AssocX::AssocY::MethodOrAssocType
+///     ^~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///     base_def      depth = 3
+///
+///     <T as Trait>::AssocX::AssocY::MethodOrAssocType
+///           ^~~~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~
+///           base_def        depth = 2
+#[derive(Copy, Clone, Debug)]
+pub struct PathResolution {
+    pub base_def: Def,
+    pub last_private: LastPrivate,
+    pub depth: usize
+}
+
+impl PathResolution {
+    /// Get the definition, if fully resolved, otherwise panic.
+    pub fn full_def(&self) -> Def {
+        if self.depth != 0 {
+            panic!("path not fully resolved: {:?}", self);
+        }
+        self.base_def
+    }
+
+    /// Get the DefId, if fully resolved, otherwise panic.
+    pub fn def_id(&self) -> ast::DefId {
+        self.full_def().def_id()
+    }
+
+    pub fn new(base_def: Def,
+               last_private: LastPrivate,
+               depth: usize)
+               -> PathResolution {
+        PathResolution {
+            base_def: base_def,
+            last_private: last_private,
+            depth: depth,
+        }
+    }
 }
 
 // Definition mapping
-pub type DefMap = RefCell<NodeMap<Def>>;
+pub type DefMap = RefCell<NodeMap<PathResolution>>;
 // This is the replacement export map. It maps a module to all of the exports
 // within.
 pub type ExportMap = NodeMap<Vec<Export>>;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Export {
     pub name: ast::Name,    // The name of the target.
     pub def_id: ast::DefId, // The definition of the target.
@@ -78,12 +116,6 @@ pub enum MethodProvenance {
     FromImpl(ast::DefId),
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TyParamProvenance {
-    FromSelf(ast::DefId),
-    FromParam(ast::DefId),
-}
-
 impl MethodProvenance {
     pub fn map<F>(self, f: F) -> MethodProvenance where
         F: FnOnce(ast::DefId) -> ast::DefId,
@@ -95,34 +127,6 @@ impl MethodProvenance {
     }
 }
 
-impl TyParamProvenance {
-    pub fn def_id(&self) -> ast::DefId {
-        match *self {
-            TyParamProvenance::FromSelf(ref did) => did.clone(),
-            TyParamProvenance::FromParam(ref did) => did.clone(),
-        }
-    }
-}
-
-#[derive(Clone, Copy, Eq, PartialEq)]
-pub enum TraitItemKind {
-    NonstaticMethodTraitItemKind,
-    StaticMethodTraitItemKind,
-    TypeTraitItemKind,
-}
-
-impl TraitItemKind {
-    pub fn from_explicit_self_category(explicit_self_category:
-                                       ExplicitSelfCategory)
-                                       -> TraitItemKind {
-        if explicit_self_category == StaticExplicitSelfCategory {
-            StaticMethodTraitItemKind
-        } else {
-            NonstaticMethodTraitItemKind
-        }
-    }
-}
-
 impl Def {
     pub fn local_node_id(&self) -> ast::NodeId {
         let def_id = self.def_id();
@@ -132,25 +136,21 @@ impl Def {
 
     pub fn def_id(&self) -> ast::DefId {
         match *self {
-            DefFn(id, _) | DefStaticMethod(id, _) | DefMod(id) |
-            DefForeignMod(id) | DefStatic(id, _) |
-            DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
+            DefFn(id, _) | DefMod(id) | DefForeignMod(id) | DefStatic(id, _) |
+            DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(_, id) |
             DefTyParam(_, _, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
-            DefMethod(id, _, _) | DefConst(id) |
-            DefAssociatedPath(TyParamProvenance::FromSelf(id), _) |
-            DefAssociatedPath(TyParamProvenance::FromParam(id), _) => {
+            DefMethod(id, _) | DefConst(id) => {
                 id
             }
             DefLocal(id) |
             DefSelfTy(id) |
             DefUpvar(id, _) |
             DefRegion(id) |
-            DefTyParamBinder(id) |
             DefLabel(id) => {
                 local_def(id)
             }
 
-            DefPrimTy(_) => panic!()
+            DefPrimTy(_) => panic!("attempted .def_id() on DefPrimTy")
         }
     }
 
index ad9f4eade5c90d25538240080640f300aace049a..0b688e1e08a2e3eabdc7a7324b3eb2cf05c0784c 100644 (file)
@@ -118,7 +118,7 @@ fn calculate_type(sess: &session::Session,
                 let src = sess.cstore.get_used_crate_source(cnum).unwrap();
                 if src.rlib.is_some() { return }
                 sess.err(&format!("dependency `{}` not found in rlib format",
-                                 data.name)[]);
+                                 data.name));
             });
             return Vec::new();
         }
@@ -172,7 +172,7 @@ fn calculate_type(sess: &session::Session,
             assert!(src.rlib.is_some());
             debug!("adding staticlib: {}", data.name);
             add_library(sess, cnum, cstore::RequireStatic, &mut formats);
-            ret[cnum as uint - 1] = Some(cstore::RequireStatic);
+            ret[cnum as usize - 1] = Some(cstore::RequireStatic);
         }
     });
 
@@ -197,7 +197,7 @@ fn calculate_type(sess: &session::Session,
                                  match kind {
                                      cstore::RequireStatic => "rlib",
                                      cstore::RequireDynamic => "dylib",
-                                 })[]);
+                                 }));
             }
         }
     }
@@ -222,7 +222,7 @@ fn add_library(sess: &session::Session,
                 let data = sess.cstore.get_crate_data(cnum);
                 sess.err(&format!("cannot satisfy dependencies so `{}` only \
                                   shows up once",
-                                 data.name)[]);
+                                 data.name));
                 sess.help("having upstream crates all available in one format \
                            will likely make this go away");
             }
index abb8f35f662b5e07604f03d873a7d0861a8b9c99..814492cbef1dd3fca1dd8d3d92d3f7c46fcd2303 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 //! Enforces the Rust effect system. Currently there is just one effect,
-/// `unsafe`.
+//! `unsafe`.
 use self::UnsafeContext::*;
 
 use middle::def;
@@ -18,12 +18,11 @@ use middle::ty::MethodCall;
 use util::ppaux;
 
 use syntax::ast;
-use syntax::ast_util::PostExpansionMethod;
 use syntax::codemap::Span;
 use syntax::visit;
 use syntax::visit::Visitor;
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 enum UnsafeContext {
     SafeContext,
     UnsafeFn,
@@ -90,8 +89,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
         let (is_item_fn, is_unsafe_fn) = match fn_kind {
             visit::FkItemFn(_, _, fn_style, _) =>
                 (true, fn_style == ast::Unsafety::Unsafe),
-            visit::FkMethod(_, _, method) =>
-                (true, method.pe_unsafety() == ast::Unsafety::Unsafe),
+            visit::FkMethod(_, sig) =>
+                (true, sig.unsafety == ast::Unsafety::Unsafe),
             _ => (false, false),
         };
 
@@ -142,7 +141,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
         match expr.node {
             ast::ExprMethodCall(_, _, _) => {
                 let method_call = MethodCall::expr(expr.id);
-                let base_type = (*self.tcx.method_map.borrow())[method_call].ty;
+                let base_type = self.tcx.method_map.borrow().get(&method_call).unwrap().ty;
                 debug!("effect: method call case, base type is {}",
                        ppaux::ty_to_string(self.tcx, base_type));
                 if type_is_unsafe_function(base_type) {
@@ -175,7 +174,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
             ast::ExprInlineAsm(..) => {
                 self.require_unsafe(expr.span, "use of inline assembly");
             }
-            ast::ExprPath(_) | ast::ExprQPath(_) => {
+            ast::ExprPath(..) => {
                 if let def::DefStatic(_, true) = ty::resolve_expr(self.tcx, expr) {
                     self.require_unsafe(expr.span, "use of mutable static");
                 }
index e99d214742a0b668b40becf51bccafc8c387022b..2fa9c7c8fbebb0a7e8ceb794b5926ace6f818259 100644 (file)
@@ -94,7 +94,7 @@ pub trait Delegate<'tcx> {
               mode: MutateMode);
 }
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum LoanCause {
     ClosureCapture(Span),
     AddrOf,
@@ -106,20 +106,20 @@ pub enum LoanCause {
     MatchDiscriminant
 }
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 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
 }
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum MoveReason {
     DirectRefMove,
     PatBindingMove,
     CaptureMove,
 }
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum MatchMode {
     NonBindingMatch,
     BorrowingMatch,
@@ -127,7 +127,7 @@ pub enum MatchMode {
     MovingMatch,
 }
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 enum TrackMatchMode {
     Unknown,
     Definite(MatchMode),
@@ -194,14 +194,14 @@ impl TrackMatchMode {
     }
 }
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum MutateMode {
     Init,
     JustWrite,    // x = y
     WriteAndRead, // x += y
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum OverloadedCallType {
     FnOverloadedCall,
     FnMutOverloadedCall,
@@ -422,7 +422,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                 self.walk_expr(&**subexpr)
             }
 
-            ast::ExprPath(_) | ast::ExprQPath(_) => { }
+            ast::ExprPath(..) => { }
 
             ast::ExprUnary(ast::UnDeref, ref base) => {      // *base
                 if !self.walk_overloaded_operator(expr, &**base, Vec::new(), PassArgs::ByRef) {
@@ -442,7 +442,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                 if !self.walk_overloaded_operator(expr,
                                                   &**lhs,
                                                   vec![&**rhs],
-                                                  PassArgs::ByRef) {
+                                                  PassArgs::ByValue) {
                     self.select_from_expr(&**lhs);
                     self.consume_expr(&**rhs);
                 }
@@ -790,7 +790,8 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
             None => { }
             Some(adjustment) => {
                 match *adjustment {
-                    ty::AdjustReifyFnPointer(..) => {
+                    ty::AdjustReifyFnPointer(..) |
+                    ty::AdjustUnsafeFnPointer(..) => {
                         // Creating a closure/fn-pointer consumes the
                         // input and stores it into the resulting
                         // rvalue.
@@ -822,7 +823,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
     /// `deref()` is declared with `&self`, this is an autoref of `x`.
     fn walk_autoderefs(&mut self,
                        expr: &ast::Expr,
-                       autoderefs: uint) {
+                       autoderefs: usize) {
         debug!("walk_autoderefs expr={} autoderefs={}", expr.repr(self.tcx()), autoderefs);
 
         for i in 0..autoderefs {
@@ -841,7 +842,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                         ty::ty_rptr(r, ref m) => (m.mutbl, r),
                         _ => self.tcx().sess.span_bug(expr.span,
                                 &format!("bad overloaded deref type {}",
-                                    method_ty.repr(self.tcx()))[])
+                                    method_ty.repr(self.tcx())))
                     };
                     let bk = ty::BorrowKind::from_mutbl(m);
                     self.delegate.borrow(expr.id, expr.span, cmt,
@@ -854,31 +855,16 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
     fn walk_autoref(&mut self,
                     expr: &ast::Expr,
                     autoref: &ty::AutoRef,
-                    n: uint) {
+                    n: usize) {
         debug!("walk_autoref expr={}", expr.repr(self.tcx()));
 
-        // Match for unique trait coercions first, since we don't need the
-        // call to cat_expr_autoderefd.
-        match *autoref {
-            ty::AutoUnsizeUniq(ty::UnsizeVtable(..)) |
-            ty::AutoUnsize(ty::UnsizeVtable(..)) => {
-                assert!(n == 1, format!("Expected exactly 1 deref with Uniq \
-                                         AutoRefs, found: {}", n));
-                let cmt_unadjusted =
-                    return_if_err!(self.mc.cat_expr_unadjusted(expr));
-                self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
-                return;
-            }
-            _ => {}
-        }
-
-        let cmt_derefd = return_if_err!(
-            self.mc.cat_expr_autoderefd(expr, n));
-        debug!("walk_adjustment: cmt_derefd={}",
-               cmt_derefd.repr(self.tcx()));
-
         match *autoref {
             ty::AutoPtr(r, m, _) => {
+                let cmt_derefd = return_if_err!(
+                    self.mc.cat_expr_autoderefd(expr, n));
+                debug!("walk_adjustment: cmt_derefd={}",
+                       cmt_derefd.repr(self.tcx()));
+
                 self.delegate.borrow(expr.id,
                                      expr.span,
                                      cmt_derefd,
@@ -886,10 +872,24 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                                      ty::BorrowKind::from_mutbl(m),
                                      AutoRef);
             }
-            ty::AutoUnsizeUniq(_) | ty::AutoUnsize(_) | ty::AutoUnsafe(..) => {}
+            ty::AutoUnsize(_) |
+            ty::AutoUnsizeUniq(_) => {
+                assert!(n == 1, format!("Expected exactly 1 deref with Uniq \
+                                         AutoRefs, found: {}", n));
+                let cmt_unadjusted =
+                    return_if_err!(self.mc.cat_expr_unadjusted(expr));
+                self.delegate_consume(expr.id, expr.span, cmt_unadjusted);
+            }
+            ty::AutoUnsafe(..) => {
+            }
         }
     }
 
+    // When this returns true, it means that the expression *is* a
+    // method-call (i.e. via the operator-overload).  This true result
+    // also implies that walk_overloaded_operator already took care of
+    // recursively processing the input arguments, and thus the caller
+    // should not do so.
     fn walk_overloaded_operator(&mut self,
                                 expr: &ast::Expr,
                                 receiver: &ast::Expr,
@@ -1017,7 +1017,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
 
                 // Each match binding is effectively an assignment to the
                 // binding being produced.
-                let def = def_map.borrow()[pat.id].clone();
+                let def = def_map.borrow().get(&pat.id).unwrap().full_def();
                 match mc.cat_def(pat.id, pat.span, pat_ty, def) {
                     Ok(binding_cmt) => {
                         delegate.mutate(pat.id, pat.span, binding_cmt, Init);
@@ -1097,13 +1097,13 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
 
             match pat.node {
                 ast::PatEnum(_, _) | ast::PatIdent(_, _, None) | ast::PatStruct(..) => {
-                    match def_map.get(&pat.id) {
+                    match def_map.get(&pat.id).map(|d| d.full_def()) {
                         None => {
                             // no definition found: pat is not a
                             // struct or enum pattern.
                         }
 
-                        Some(&def::DefVariant(enum_did, variant_did, _is_struct)) => {
+                        Some(def::DefVariant(enum_did, variant_did, _is_struct)) => {
                             let downcast_cmt =
                                 if ty::enum_is_univariant(tcx, enum_did) {
                                     cmt_pat
@@ -1119,7 +1119,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                             delegate.matched_pat(pat, downcast_cmt, match_mode);
                         }
 
-                        Some(&def::DefStruct(..)) | Some(&def::DefTy(_, false)) => {
+                        Some(def::DefStruct(..)) | Some(def::DefTy(_, false)) => {
                             // A struct (in either the value or type
                             // namespace; we encounter the former on
                             // e.g. patterns for unit structs).
@@ -1131,14 +1131,14 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                             delegate.matched_pat(pat, cmt_pat, match_mode);
                         }
 
-                        Some(&def::DefConst(..)) |
-                        Some(&def::DefLocal(..)) => {
+                        Some(def::DefConst(..)) |
+                        Some(def::DefLocal(..)) => {
                             // This is a leaf (i.e. identifier binding
                             // or constant value to match); thus no
                             // `matched_pat` call.
                         }
 
-                        Some(def @ &def::DefTy(_, true)) => {
+                        Some(def @ def::DefTy(_, true)) => {
                             // An enum's type -- should never be in a
                             // pattern.
 
index b33e5a802f1582f6a639431938abaf3c026d8709..36065aaca57f33b4708d7ce721d95cc54238b6fa 100644 (file)
@@ -25,11 +25,11 @@ pub enum SimplifiedType {
     StrSimplifiedType,
     VecSimplifiedType,
     PtrSimplifiedType,
-    TupleSimplifiedType(uint),
+    TupleSimplifiedType(usize),
     TraitSimplifiedType(ast::DefId),
     StructSimplifiedType(ast::DefId),
     ClosureSimplifiedType(ast::DefId),
-    FunctionSimplifiedType(uint),
+    FunctionSimplifiedType(usize),
     ParameterSimplifiedType,
 }
 
@@ -74,7 +74,7 @@ pub fn simplify_type(tcx: &ty::ctxt,
             let def_id = tcx.lang_items.owned_box().unwrap();
             Some(StructSimplifiedType(def_id))
         }
-        ty::ty_closure(def_id, _, _) => {
+        ty::ty_closure(def_id, _) => {
             Some(ClosureSimplifiedType(def_id))
         }
         ty::ty_tup(ref tys) => {
@@ -93,7 +93,6 @@ pub fn simplify_type(tcx: &ty::ctxt,
                 None
             }
         }
-        ty::ty_open(_) | ty::ty_infer(_) | ty::ty_err => None,
+        ty::ty_infer(_) | ty::ty_err => None,
     }
 }
-
index 436f04fc9e9cf9744f7d484757c9022146e47883..a9ac61b49eca8bd247ffd8a7ce06e0275db5521b 100644 (file)
@@ -62,33 +62,33 @@ impl<E: Debug> Debug for Edge<E> {
 }
 
 #[derive(Clone, Copy, PartialEq, Debug)]
-pub struct NodeIndex(pub uint);
+pub struct NodeIndex(pub usize);
 #[allow(non_upper_case_globals)]
 pub const InvalidNodeIndex: NodeIndex = NodeIndex(usize::MAX);
 
-#[derive(Copy, PartialEq, Debug)]
-pub struct EdgeIndex(pub uint);
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub struct EdgeIndex(pub usize);
 #[allow(non_upper_case_globals)]
 pub const InvalidEdgeIndex: EdgeIndex = EdgeIndex(usize::MAX);
 
 // Use a private field here to guarantee no more instances are created:
-#[derive(Copy, Debug)]
-pub struct Direction { repr: uint }
+#[derive(Copy, Clone, Debug)]
+pub struct Direction { repr: usize }
 #[allow(non_upper_case_globals)]
 pub const Outgoing: Direction = Direction { repr: 0 };
 #[allow(non_upper_case_globals)]
 pub const Incoming: Direction = Direction { repr: 1 };
 
 impl NodeIndex {
-    fn get(&self) -> uint { let NodeIndex(v) = *self; v }
+    fn get(&self) -> usize { let NodeIndex(v) = *self; v }
     /// Returns unique id (unique with respect to the graph holding associated node).
-    pub fn node_id(&self) -> uint { self.get() }
+    pub fn node_id(&self) -> usize { self.get() }
 }
 
 impl EdgeIndex {
-    fn get(&self) -> uint { let EdgeIndex(v) = *self; v }
+    fn get(&self) -> usize { let EdgeIndex(v) = *self; v }
     /// Returns unique id (unique with respect to the graph holding associated edge).
-    pub fn edge_id(&self) -> uint { self.get() }
+    pub fn edge_id(&self) -> usize { self.get() }
 }
 
 impl<N,E> Graph<N,E> {
@@ -99,8 +99,8 @@ impl<N,E> Graph<N,E> {
         }
     }
 
-    pub fn with_capacity(num_nodes: uint,
-                         num_edges: uint) -> Graph<N,E> {
+    pub fn with_capacity(num_nodes: usize,
+                         num_edges: usize) -> Graph<N,E> {
         Graph {
             nodes: Vec::with_capacity(num_nodes),
             edges: Vec::with_capacity(num_edges),
@@ -275,7 +275,7 @@ impl<N,E> Graph<N,E> {
     // computation.
 
     pub fn iterate_until_fixed_point<'a, F>(&'a self, mut op: F) where
-        F: FnMut(uint, EdgeIndex, &'a Edge<E>) -> bool,
+        F: FnMut(usize, EdgeIndex, &'a Edge<E>) -> bool,
     {
         let mut iteration = 0;
         let mut changed = true;
index 93c80fb754f71f8d83db96d9c1b058b326926d22..940dc75271c22f0a33d1585ab2af2a0eee1aede9 100644 (file)
 //! In particular, it might be enough to say (A,B) are bivariant for
 //! all (A,B).
 
-use middle::ty::{BuiltinBounds};
+use super::combine::{self, CombineFields};
+use super::type_variable::{BiTo};
+
 use middle::ty::{self, Ty};
 use middle::ty::TyVar;
-use middle::infer::combine::*;
-use middle::infer::{cres};
-use middle::infer::type_variable::{BiTo};
+use middle::ty_relate::{Relate, RelateResult, TypeRelation};
 use util::ppaux::{Repr};
 
-use syntax::ast::{Unsafety};
-
-pub struct Bivariate<'f, 'tcx: 'f> {
-    fields: CombineFields<'f, 'tcx>
-}
-
-#[allow(non_snake_case)]
-pub fn Bivariate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Bivariate<'f, 'tcx> {
-    Bivariate { fields: cf }
+pub struct Bivariate<'a, 'tcx: 'a> {
+    fields: CombineFields<'a, 'tcx>
 }
 
-impl<'f, 'tcx> Combine<'tcx> for Bivariate<'f, 'tcx> {
-    fn tag(&self) -> String { "Bivariate".to_string() }
-    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
-
-    fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
-                         -> cres<'tcx, Ty<'tcx>>
-    {
-        match v {
-            ty::Invariant => self.equate().tys(a, b),
-            ty::Covariant => self.tys(a, b),
-            ty::Contravariant => self.tys(a, b),
-            ty::Bivariant => self.tys(a, b),
-        }
-    }
-
-    fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
-                             -> cres<'tcx, ty::Region>
-    {
-        match v {
-            ty::Invariant => self.equate().regions(a, b),
-            ty::Covariant => self.regions(a, b),
-            ty::Contravariant => self.regions(a, b),
-            ty::Bivariant => self.regions(a, b),
-        }
-    }
-
-    fn regions(&self, a: ty::Region, _: ty::Region) -> cres<'tcx, ty::Region> {
-        Ok(a)
+impl<'a, 'tcx> Bivariate<'a, 'tcx> {
+    pub fn new(fields: CombineFields<'a, 'tcx>) -> Bivariate<'a, 'tcx> {
+        Bivariate { fields: fields }
     }
+}
 
-    fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
-        debug!("mts({} <: {})",
-               a.repr(self.fields.infcx.tcx),
-               b.repr(self.fields.infcx.tcx));
+impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Bivariate<'a, 'tcx> {
+    fn tag(&self) -> &'static str { "Bivariate" }
 
-        if a.mutbl != b.mutbl { return Err(ty::terr_mutability); }
-        let t = try!(self.tys(a.ty, b.ty));
-        Ok(ty::mt { mutbl: a.mutbl, ty: t })
-    }
+    fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.fields.tcx() }
 
-    fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
-        if a != b {
-            Err(ty::terr_unsafety_mismatch(expected_found(self, a, b)))
-        } else {
-            Ok(a)
-        }
-    }
+    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
 
-    fn builtin_bounds(&self,
-                      a: BuiltinBounds,
-                      b: BuiltinBounds)
-                      -> cres<'tcx, BuiltinBounds>
+    fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
+                                               variance: ty::Variance,
+                                               a: &T,
+                                               b: &T)
+                                               -> RelateResult<'tcx, T>
     {
-        if a != b {
-            Err(ty::terr_builtin_bounds(expected_found(self, a, b)))
-        } else {
-            Ok(a)
+        match variance {
+            // If we have Foo<A> and Foo is invariant w/r/t A,
+            // and we want to assert that
+            //
+            //     Foo<A> <: Foo<B> ||
+            //     Foo<B> <: Foo<A>
+            //
+            // then still A must equal B.
+            ty::Invariant => self.relate(a, b),
+
+            ty::Covariant => self.relate(a, b),
+            ty::Bivariant => self.relate(a, b),
+            ty::Contravariant => self.relate(a, b),
         }
     }
 
-    fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
+    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         debug!("{}.tys({}, {})", self.tag(),
                a.repr(self.fields.infcx.tcx), b.repr(self.fields.infcx.tcx));
         if a == b { return Ok(a); }
@@ -129,17 +97,22 @@ impl<'f, 'tcx> Combine<'tcx> for Bivariate<'f, 'tcx> {
             }
 
             _ => {
-                super_tys(self, a, b)
+                combine::super_combine_tys(self.fields.infcx, self, a, b)
             }
         }
     }
 
-    fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
-        where T : Combineable<'tcx>
+    fn regions(&mut self, a: ty::Region, _: ty::Region) -> RelateResult<'tcx, ty::Region> {
+        Ok(a)
+    }
+
+    fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
+                  -> RelateResult<'tcx, ty::Binder<T>>
+        where T: Relate<'a,'tcx>
     {
         let a1 = ty::erase_late_bound_regions(self.tcx(), a);
         let b1 = ty::erase_late_bound_regions(self.tcx(), b);
-        let c = try!(Combineable::combine(self, &a1, &b1));
+        let c = try!(self.relate(&a1, &b1));
         Ok(ty::Binder(c))
     }
 }
index 0eeafb767d8a625d2792a3c393f4888aec8cf68c..86f12b669b35ebe42f714835d26cb2c5cb7a74dd 100644 (file)
@@ -37,369 +37,21 @@ use super::equate::Equate;
 use super::glb::Glb;
 use super::lub::Lub;
 use super::sub::Sub;
-use super::unify::InferCtxtMethodsForSimplyUnifiableTypes;
-use super::{InferCtxt, cres};
+use super::{InferCtxt};
 use super::{MiscVariable, TypeTrace};
 use super::type_variable::{RelationDir, BiTo, EqTo, SubtypeOf, SupertypeOf};
 
-use middle::subst;
-use middle::subst::{ErasedRegions, NonerasedRegions, Substs};
-use middle::ty::{FloatVar, FnSig, IntVar, TyVar};
+use middle::ty::{TyVar};
 use middle::ty::{IntType, UintType};
-use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
 use middle::ty_fold;
 use middle::ty_fold::{TypeFolder, TypeFoldable};
+use middle::ty_relate::{self, Relate, RelateResult, TypeRelation};
 use util::ppaux::Repr;
 
-use std::rc::Rc;
-use syntax::ast::Unsafety;
 use syntax::ast;
-use syntax::abi;
 use syntax::codemap::Span;
 
-pub trait Combine<'tcx> : Sized {
-    fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.infcx().tcx }
-    fn tag(&self) -> String;
-
-    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx>;
-
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields().infcx }
-    fn a_is_expected(&self) -> bool { self.fields().a_is_expected }
-    fn trace(&self) -> TypeTrace<'tcx> { self.fields().trace.clone() }
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { self.fields().equate() }
-    fn bivariate<'a>(&'a self) -> Bivariate<'a, 'tcx> { self.fields().bivariate() }
-
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { self.fields().sub() }
-    fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields().clone()) }
-    fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields().clone()) }
-
-    fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>>;
-
-    fn tys_with_variance(&self, variance: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
-                         -> cres<'tcx, Ty<'tcx>>;
-
-    fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>>;
-
-    fn regions_with_variance(&self, variance: ty::Variance, a: ty::Region, b: ty::Region)
-                             -> cres<'tcx, ty::Region>;
-
-    fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>;
-
-    fn substs(&self,
-              item_def_id: ast::DefId,
-              a_subst: &subst::Substs<'tcx>,
-              b_subst: &subst::Substs<'tcx>)
-              -> cres<'tcx, subst::Substs<'tcx>>
-    {
-        debug!("substs: item_def_id={} a_subst={} b_subst={}",
-               item_def_id.repr(self.infcx().tcx),
-               a_subst.repr(self.infcx().tcx),
-               b_subst.repr(self.infcx().tcx));
-
-        let variances = if self.infcx().tcx.variance_computed.get() {
-            Some(ty::item_variances(self.infcx().tcx, item_def_id))
-        } else {
-            None
-        };
-        self.substs_variances(variances.as_ref().map(|v| &**v), a_subst, b_subst)
-    }
-
-    fn substs_variances(&self,
-                        variances: Option<&ty::ItemVariances>,
-                        a_subst: &subst::Substs<'tcx>,
-                        b_subst: &subst::Substs<'tcx>)
-                        -> cres<'tcx, subst::Substs<'tcx>>
-    {
-        let mut substs = subst::Substs::empty();
-
-        for &space in &subst::ParamSpace::all() {
-            let a_tps = a_subst.types.get_slice(space);
-            let b_tps = b_subst.types.get_slice(space);
-            let t_variances = variances.map(|v| v.types.get_slice(space));
-            let tps = try!(relate_type_params(self, t_variances, a_tps, b_tps));
-            substs.types.replace(space, tps);
-        }
-
-        match (&a_subst.regions, &b_subst.regions) {
-            (&ErasedRegions, _) | (_, &ErasedRegions) => {
-                substs.regions = ErasedRegions;
-            }
-
-            (&NonerasedRegions(ref a), &NonerasedRegions(ref b)) => {
-                for &space in &subst::ParamSpace::all() {
-                    let a_regions = a.get_slice(space);
-                    let b_regions = b.get_slice(space);
-                    let r_variances = variances.map(|v| v.regions.get_slice(space));
-                    let regions = try!(relate_region_params(self,
-                                                            r_variances,
-                                                            a_regions,
-                                                            b_regions));
-                    substs.mut_regions().replace(space, regions);
-                }
-            }
-        }
-
-        return Ok(substs);
-
-        fn relate_type_params<'tcx, C: Combine<'tcx>>(this: &C,
-                                                      variances: Option<&[ty::Variance]>,
-                                                      a_tys: &[Ty<'tcx>],
-                                                      b_tys: &[Ty<'tcx>])
-                                                      -> cres<'tcx, Vec<Ty<'tcx>>>
-        {
-            if a_tys.len() != b_tys.len() {
-                return Err(ty::terr_ty_param_size(expected_found(this,
-                                                                 a_tys.len(),
-                                                                 b_tys.len())));
-            }
-
-            range(0, a_tys.len()).map(|i| {
-                let a_ty = a_tys[i];
-                let b_ty = b_tys[i];
-                let v = variances.map_or(ty::Invariant, |v| v[i]);
-                this.tys_with_variance(v, a_ty, b_ty)
-            }).collect()
-        }
-
-        fn relate_region_params<'tcx, C: Combine<'tcx>>(this: &C,
-                                                        variances: Option<&[ty::Variance]>,
-                                                        a_rs: &[ty::Region],
-                                                        b_rs: &[ty::Region])
-                                                        -> cres<'tcx, Vec<ty::Region>>
-        {
-            let tcx = this.infcx().tcx;
-            let num_region_params = a_rs.len();
-
-            debug!("relate_region_params(\
-                   a_rs={}, \
-                   b_rs={},
-                   variances={})",
-                   a_rs.repr(tcx),
-                   b_rs.repr(tcx),
-                   variances.repr(tcx));
-
-            assert_eq!(num_region_params,
-                       variances.map_or(num_region_params,
-                                        |v| v.len()));
-
-            assert_eq!(num_region_params, b_rs.len());
-
-            (0..a_rs.len()).map(|i| {
-                let a_r = a_rs[i];
-                let b_r = b_rs[i];
-                let variance = variances.map_or(ty::Invariant, |v| v[i]);
-                this.regions_with_variance(variance, a_r, b_r)
-            }).collect()
-        }
-    }
-
-    fn bare_fn_tys(&self, a: &ty::BareFnTy<'tcx>,
-                   b: &ty::BareFnTy<'tcx>) -> cres<'tcx, ty::BareFnTy<'tcx>> {
-        let unsafety = try!(self.unsafeties(a.unsafety, b.unsafety));
-        let abi = try!(self.abi(a.abi, b.abi));
-        let sig = try!(self.binders(&a.sig, &b.sig));
-        Ok(ty::BareFnTy {unsafety: unsafety,
-                         abi: abi,
-                         sig: sig})
-    }
-
-    fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>) -> cres<'tcx, ty::FnSig<'tcx>> {
-        if a.variadic != b.variadic {
-            return Err(ty::terr_variadic_mismatch(expected_found(self, a.variadic, b.variadic)));
-        }
-
-        let inputs = try!(argvecs(self,
-                                  &a.inputs,
-                                  &b.inputs));
-
-        let output = try!(match (a.output, b.output) {
-            (ty::FnConverging(a_ty), ty::FnConverging(b_ty)) =>
-                Ok(ty::FnConverging(try!(self.tys(a_ty, b_ty)))),
-            (ty::FnDiverging, ty::FnDiverging) =>
-                Ok(ty::FnDiverging),
-            (a, b) =>
-                Err(ty::terr_convergence_mismatch(
-                    expected_found(self, a != ty::FnDiverging, b != ty::FnDiverging))),
-        });
-
-        return Ok(ty::FnSig {inputs: inputs,
-                             output: output,
-                             variadic: a.variadic});
-
-
-        fn argvecs<'tcx, C: Combine<'tcx>>(combiner: &C,
-                                           a_args: &[Ty<'tcx>],
-                                           b_args: &[Ty<'tcx>])
-                                           -> cres<'tcx, Vec<Ty<'tcx>>>
-        {
-            if a_args.len() == b_args.len() {
-                a_args.iter().zip(b_args.iter())
-                    .map(|(a, b)| combiner.args(*a, *b)).collect()
-            } else {
-                Err(ty::terr_arg_count)
-            }
-        }
-    }
-
-    fn args(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        self.tys_with_variance(ty::Contravariant, a, b).and_then(|t| Ok(t))
-    }
-
-    fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety>;
-
-    fn abi(&self, a: abi::Abi, b: abi::Abi) -> cres<'tcx, abi::Abi> {
-        if a == b {
-            Ok(a)
-        } else {
-            Err(ty::terr_abi_mismatch(expected_found(self, a, b)))
-        }
-    }
-
-    fn projection_tys(&self,
-                      a: &ty::ProjectionTy<'tcx>,
-                      b: &ty::ProjectionTy<'tcx>)
-                      -> cres<'tcx, ty::ProjectionTy<'tcx>>
-    {
-        if a.item_name != b.item_name {
-            Err(ty::terr_projection_name_mismatched(
-                expected_found(self, a.item_name, b.item_name)))
-        } else {
-            // Note that the trait refs for the projection must be
-            // *equal*. This is because there is no inherent
-            // relationship between `<T as Foo>::Bar` and `<U as
-            // Foo>::Bar` that we can derive based on how `T` relates
-            // to `U`. Issue #21726 contains further discussion and
-            // in-depth examples.
-            let trait_ref = try!(self.equate().trait_refs(&*a.trait_ref, &*b.trait_ref));
-            Ok(ty::ProjectionTy { trait_ref: Rc::new(trait_ref), item_name: a.item_name })
-        }
-    }
-
-    fn projection_predicates(&self,
-                             a: &ty::ProjectionPredicate<'tcx>,
-                             b: &ty::ProjectionPredicate<'tcx>)
-                             -> cres<'tcx, ty::ProjectionPredicate<'tcx>>
-    {
-        let projection_ty = try!(self.projection_tys(&a.projection_ty, &b.projection_ty));
-        let ty = try!(self.tys(a.ty, b.ty));
-        Ok(ty::ProjectionPredicate { projection_ty: projection_ty, ty: ty })
-    }
-
-    fn projection_bounds(&self,
-                         a: &Vec<ty::PolyProjectionPredicate<'tcx>>,
-                         b: &Vec<ty::PolyProjectionPredicate<'tcx>>)
-                         -> cres<'tcx, Vec<ty::PolyProjectionPredicate<'tcx>>>
-    {
-        // To be compatible, `a` and `b` must be for precisely the
-        // same set of traits and item names. We always require that
-        // projection bounds lists are sorted by trait-def-id and item-name,
-        // so we can just iterate through the lists pairwise, so long as they are the
-        // same length.
-        if a.len() != b.len() {
-            Err(ty::terr_projection_bounds_length(expected_found(self, a.len(), b.len())))
-        } else {
-            a.iter()
-                .zip(b.iter())
-                .map(|(a, b)| self.binders(a, b))
-                .collect()
-        }
-    }
-
-    fn existential_bounds(&self,
-                          a: &ty::ExistentialBounds<'tcx>,
-                          b: &ty::ExistentialBounds<'tcx>)
-                          -> cres<'tcx, ty::ExistentialBounds<'tcx>>
-    {
-        let r = try!(self.regions_with_variance(ty::Contravariant, a.region_bound, b.region_bound));
-        let nb = try!(self.builtin_bounds(a.builtin_bounds, b.builtin_bounds));
-        let pb = try!(self.projection_bounds(&a.projection_bounds, &b.projection_bounds));
-        Ok(ty::ExistentialBounds { region_bound: r,
-                                   builtin_bounds: nb,
-                                   projection_bounds: pb })
-    }
-
-    fn builtin_bounds(&self,
-                      a: ty::BuiltinBounds,
-                      b: ty::BuiltinBounds)
-                      -> cres<'tcx, ty::BuiltinBounds>;
-
-    fn trait_refs(&self,
-                  a: &ty::TraitRef<'tcx>,
-                  b: &ty::TraitRef<'tcx>)
-                  -> cres<'tcx, ty::TraitRef<'tcx>>
-    {
-        // Different traits cannot be related
-        if a.def_id != b.def_id {
-            Err(ty::terr_traits(expected_found(self, a.def_id, b.def_id)))
-        } else {
-            let substs = try!(self.substs(a.def_id, a.substs, b.substs));
-            Ok(ty::TraitRef { def_id: a.def_id, substs: self.tcx().mk_substs(substs) })
-        }
-    }
-
-    fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
-        where T : Combineable<'tcx>;
-    // this must be overridden to do correctly, so as to account for higher-ranked
-    // behavior
-}
-
-pub trait Combineable<'tcx> : Repr<'tcx> + TypeFoldable<'tcx> {
-    fn combine<C:Combine<'tcx>>(combiner: &C, a: &Self, b: &Self) -> cres<'tcx, Self>;
-}
-
-impl<'tcx,T> Combineable<'tcx> for Rc<T>
-    where T : Combineable<'tcx>
-{
-    fn combine<C:Combine<'tcx>>(combiner: &C,
-                                a: &Rc<T>,
-                                b: &Rc<T>)
-                                -> cres<'tcx, Rc<T>>
-    {
-        Ok(Rc::new(try!(Combineable::combine(combiner, &**a, &**b))))
-    }
-}
-
-impl<'tcx> Combineable<'tcx> for ty::TraitRef<'tcx> {
-    fn combine<C:Combine<'tcx>>(combiner: &C,
-                                a: &ty::TraitRef<'tcx>,
-                                b: &ty::TraitRef<'tcx>)
-                                -> cres<'tcx, ty::TraitRef<'tcx>>
-    {
-        combiner.trait_refs(a, b)
-    }
-}
-
-impl<'tcx> Combineable<'tcx> for Ty<'tcx> {
-    fn combine<C:Combine<'tcx>>(combiner: &C,
-                                a: &Ty<'tcx>,
-                                b: &Ty<'tcx>)
-                                -> cres<'tcx, Ty<'tcx>>
-    {
-        combiner.tys(*a, *b)
-    }
-}
-
-impl<'tcx> Combineable<'tcx> for ty::ProjectionPredicate<'tcx> {
-    fn combine<C:Combine<'tcx>>(combiner: &C,
-                                a: &ty::ProjectionPredicate<'tcx>,
-                                b: &ty::ProjectionPredicate<'tcx>)
-                                -> cres<'tcx, ty::ProjectionPredicate<'tcx>>
-    {
-        combiner.projection_predicates(a, b)
-    }
-}
-
-impl<'tcx> Combineable<'tcx> for ty::FnSig<'tcx> {
-    fn combine<C:Combine<'tcx>>(combiner: &C,
-                                a: &ty::FnSig<'tcx>,
-                                b: &ty::FnSig<'tcx>)
-                                -> cres<'tcx, ty::FnSig<'tcx>>
-    {
-        combiner.fn_sigs(a, b)
-    }
-}
-
 #[derive(Clone)]
 pub struct CombineFields<'a, 'tcx: 'a> {
     pub infcx: &'a InferCtxt<'a, 'tcx>,
@@ -407,254 +59,133 @@ pub struct CombineFields<'a, 'tcx: 'a> {
     pub trace: TypeTrace<'tcx>,
 }
 
-pub fn expected_found<'tcx, C: Combine<'tcx>, T>(
-        this: &C, a: T, b: T) -> ty::expected_found<T> {
-    if this.a_is_expected() {
-        ty::expected_found {expected: a, found: b}
-    } else {
-        ty::expected_found {expected: b, found: a}
-    }
-}
-
-pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
-                                         a: Ty<'tcx>,
-                                         b: Ty<'tcx>)
-                                         -> cres<'tcx, Ty<'tcx>>
+pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,
+                                       relation: &mut R,
+                                       a: Ty<'tcx>,
+                                       b: Ty<'tcx>)
+                                       -> RelateResult<'tcx, Ty<'tcx>>
+    where R: TypeRelation<'a,'tcx>
 {
-    let tcx = this.infcx().tcx;
-    let a_sty = &a.sty;
-    let b_sty = &b.sty;
-    debug!("super_tys: a_sty={:?} b_sty={:?}", a_sty, b_sty);
-    return match (a_sty, b_sty) {
-      // The "subtype" ought to be handling cases involving var:
-      (&ty::ty_infer(TyVar(_)), _) |
-      (_, &ty::ty_infer(TyVar(_))) => {
-        tcx.sess.bug(
-            &format!("{}: bot and var types should have been handled ({},{})",
-                    this.tag(),
-                    a.repr(this.infcx().tcx),
-                    b.repr(this.infcx().tcx))[]);
-      }
-
-      (&ty::ty_err, _) | (_, &ty::ty_err) => {
-          Ok(tcx.types.err)
-      }
+    let a_is_expected = relation.a_is_expected();
 
+    match (&a.sty, &b.sty) {
         // Relate integral variables to other types
-        (&ty::ty_infer(IntVar(a_id)), &ty::ty_infer(IntVar(b_id))) => {
-            try!(this.infcx().simple_vars(this.a_is_expected(),
-                                            a_id, b_id));
+        (&ty::ty_infer(ty::IntVar(a_id)), &ty::ty_infer(ty::IntVar(b_id))) => {
+            try!(infcx.int_unification_table
+                      .borrow_mut()
+                      .unify_var_var(a_id, b_id)
+                      .map_err(|e| int_unification_error(a_is_expected, e)));
             Ok(a)
         }
-        (&ty::ty_infer(IntVar(v_id)), &ty::ty_int(v)) => {
-            unify_integral_variable(this, this.a_is_expected(),
-                                    v_id, IntType(v))
+        (&ty::ty_infer(ty::IntVar(v_id)), &ty::ty_int(v)) => {
+            unify_integral_variable(infcx, a_is_expected, v_id, IntType(v))
         }
-        (&ty::ty_int(v), &ty::ty_infer(IntVar(v_id))) => {
-            unify_integral_variable(this, !this.a_is_expected(),
-                                    v_id, IntType(v))
+        (&ty::ty_int(v), &ty::ty_infer(ty::IntVar(v_id))) => {
+            unify_integral_variable(infcx, !a_is_expected, v_id, IntType(v))
         }
-        (&ty::ty_infer(IntVar(v_id)), &ty::ty_uint(v)) => {
-            unify_integral_variable(this, this.a_is_expected(),
-                                    v_id, UintType(v))
+        (&ty::ty_infer(ty::IntVar(v_id)), &ty::ty_uint(v)) => {
+            unify_integral_variable(infcx, a_is_expected, v_id, UintType(v))
         }
-        (&ty::ty_uint(v), &ty::ty_infer(IntVar(v_id))) => {
-            unify_integral_variable(this, !this.a_is_expected(),
-                                    v_id, UintType(v))
+        (&ty::ty_uint(v), &ty::ty_infer(ty::IntVar(v_id))) => {
+            unify_integral_variable(infcx, !a_is_expected, v_id, UintType(v))
         }
 
         // Relate floating-point variables to other types
-        (&ty::ty_infer(FloatVar(a_id)), &ty::ty_infer(FloatVar(b_id))) => {
-            try!(this.infcx().simple_vars(this.a_is_expected(), a_id, b_id));
+        (&ty::ty_infer(ty::FloatVar(a_id)), &ty::ty_infer(ty::FloatVar(b_id))) => {
+            try!(infcx.float_unification_table
+                      .borrow_mut()
+                      .unify_var_var(a_id, b_id)
+                      .map_err(|e| float_unification_error(relation.a_is_expected(), e)));
             Ok(a)
         }
-        (&ty::ty_infer(FloatVar(v_id)), &ty::ty_float(v)) => {
-            unify_float_variable(this, this.a_is_expected(), v_id, v)
+        (&ty::ty_infer(ty::FloatVar(v_id)), &ty::ty_float(v)) => {
+            unify_float_variable(infcx, a_is_expected, v_id, v)
         }
-        (&ty::ty_float(v), &ty::ty_infer(FloatVar(v_id))) => {
-            unify_float_variable(this, !this.a_is_expected(), v_id, v)
+        (&ty::ty_float(v), &ty::ty_infer(ty::FloatVar(v_id))) => {
+            unify_float_variable(infcx, !a_is_expected, v_id, v)
         }
 
-      (&ty::ty_char, _) |
-      (&ty::ty_bool, _) |
-      (&ty::ty_int(_), _) |
-      (&ty::ty_uint(_), _) |
-      (&ty::ty_float(_), _) => {
-        if a == b {
-            Ok(a)
-        } else {
-            Err(ty::terr_sorts(expected_found(this, a, b)))
+        // All other cases of inference are errors
+        (&ty::ty_infer(_), _) |
+        (_, &ty::ty_infer(_)) => {
+            Err(ty::terr_sorts(ty_relate::expected_found(relation, &a, &b)))
         }
-      }
-
-      (&ty::ty_param(ref a_p), &ty::ty_param(ref b_p)) if
-          a_p.idx == b_p.idx && a_p.space == b_p.space => {
-        Ok(a)
-      }
-
-      (&ty::ty_enum(a_id, a_substs),
-       &ty::ty_enum(b_id, b_substs))
-      if a_id == b_id => {
-          let substs = try!(this.substs(a_id,
-                                          a_substs,
-                                          b_substs));
-          Ok(ty::mk_enum(tcx, a_id, tcx.mk_substs(substs)))
-      }
-
-      (&ty::ty_trait(ref a_),
-       &ty::ty_trait(ref b_)) => {
-          debug!("Trying to match traits {:?} and {:?}", a, b);
-          let principal = try!(this.binders(&a_.principal, &b_.principal));
-          let bounds = try!(this.existential_bounds(&a_.bounds, &b_.bounds));
-          Ok(ty::mk_trait(tcx, principal, bounds))
-      }
-
-      (&ty::ty_struct(a_id, a_substs), &ty::ty_struct(b_id, b_substs))
-      if a_id == b_id => {
-            let substs = try!(this.substs(a_id, a_substs, b_substs));
-            Ok(ty::mk_struct(tcx, a_id, tcx.mk_substs(substs)))
-      }
-
-      (&ty::ty_closure(a_id, a_region, a_substs),
-       &ty::ty_closure(b_id, b_region, b_substs))
-      if a_id == b_id => {
-          // All ty_closure types with the same id represent
-          // the (anonymous) type of the same closure expression. So
-          // all of their regions should be equated.
-          let region = try!(this.equate().regions(*a_region, *b_region));
-          let substs = try!(this.substs_variances(None, a_substs, b_substs));
-          Ok(ty::mk_closure(tcx, a_id, tcx.mk_region(region), tcx.mk_substs(substs)))
-      }
-
-      (&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => {
-          let typ = try!(this.tys(a_inner, b_inner));
-          Ok(ty::mk_uniq(tcx, typ))
-      }
-
-      (&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_mt)) => {
-          let mt = try!(this.mts(a_mt, b_mt));
-          Ok(ty::mk_ptr(tcx, mt))
-      }
-
-      (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => {
-            let r = try!(this.regions_with_variance(ty::Contravariant, *a_r, *b_r));
-
-            // FIXME(14985)  If we have mutable references to trait objects, we
-            // used to use covariant subtyping. I have preserved this behaviour,
-            // even though it is probably incorrect. So don't go down the usual
-            // path which would require invariance.
-            let mt = match (&a_mt.ty.sty, &b_mt.ty.sty) {
-                (&ty::ty_trait(..), &ty::ty_trait(..)) if a_mt.mutbl == b_mt.mutbl => {
-                    let ty = try!(this.tys(a_mt.ty, b_mt.ty));
-                    ty::mt { ty: ty, mutbl: a_mt.mutbl }
-                }
-                _ => try!(this.mts(a_mt, b_mt))
-            };
-            Ok(ty::mk_rptr(tcx, tcx.mk_region(r), mt))
-      }
-
-      (&ty::ty_vec(a_t, Some(sz_a)), &ty::ty_vec(b_t, Some(sz_b))) => {
-        this.tys(a_t, b_t).and_then(|t| {
-            if sz_a == sz_b {
-                Ok(ty::mk_vec(tcx, t, Some(sz_a)))
-            } else {
-                Err(ty::terr_fixed_array_size(expected_found(this, sz_a, sz_b)))
-            }
-        })
-      }
-
-      (&ty::ty_vec(a_t, sz_a), &ty::ty_vec(b_t, sz_b)) => {
-        this.tys(a_t, b_t).and_then(|t| {
-            if sz_a == sz_b {
-                Ok(ty::mk_vec(tcx, t, sz_a))
-            } else {
-                Err(ty::terr_sorts(expected_found(this, a, b)))
-            }
-        })
-      }
-
-      (&ty::ty_str, &ty::ty_str) => {
-            Ok(ty::mk_str(tcx))
-      }
-
-      (&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) => {
-        if as_.len() == bs.len() {
-            as_.iter().zip(bs.iter())
-               .map(|(a, b)| this.tys(*a, *b))
-               .collect::<Result<_, _>>()
-               .map(|ts| ty::mk_tup(tcx, ts))
-        } else if as_.len() != 0 && bs.len() != 0 {
-            Err(ty::terr_tuple_size(
-                expected_found(this, as_.len(), bs.len())))
-        } else {
-            Err(ty::terr_sorts(expected_found(this, a, b)))
-        }
-      }
-
-        (&ty::ty_bare_fn(a_opt_def_id, a_fty), &ty::ty_bare_fn(b_opt_def_id, b_fty))
-            if a_opt_def_id == b_opt_def_id =>
-        {
-            let fty = try!(this.bare_fn_tys(a_fty, b_fty));
-            Ok(ty::mk_bare_fn(tcx, a_opt_def_id, tcx.mk_bare_fn(fty)))
-        }
-
-      (&ty::ty_projection(ref a_data), &ty::ty_projection(ref b_data)) => {
-          let projection_ty = try!(this.projection_tys(a_data, b_data));
-          Ok(ty::mk_projection(tcx, projection_ty.trait_ref, projection_ty.item_name))
-      }
 
-      _ => Err(ty::terr_sorts(expected_found(this, a, b)))
-    };
 
-    fn unify_integral_variable<'tcx, C: Combine<'tcx>>(
-        this: &C,
-        vid_is_expected: bool,
-        vid: ty::IntVid,
-        val: ty::IntVarValue) -> cres<'tcx, Ty<'tcx>>
-    {
-        try!(this.infcx().simple_var_t(vid_is_expected, vid, val));
-        match val {
-            IntType(v) => Ok(ty::mk_mach_int(this.tcx(), v)),
-            UintType(v) => Ok(ty::mk_mach_uint(this.tcx(), v))
+        _ => {
+            ty_relate::super_relate_tys(relation, a, b)
         }
     }
+}
 
-    fn unify_float_variable<'tcx, C: Combine<'tcx>>(
-        this: &C,
-        vid_is_expected: bool,
-        vid: ty::FloatVid,
-        val: ast::FloatTy) -> cres<'tcx, Ty<'tcx>>
-    {
-        try!(this.infcx().simple_var_t(vid_is_expected, vid, val));
-        Ok(ty::mk_mach_float(this.tcx(), val))
+fn unify_integral_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
+                                    vid_is_expected: bool,
+                                    vid: ty::IntVid,
+                                    val: ty::IntVarValue)
+                                    -> RelateResult<'tcx, Ty<'tcx>>
+{
+    try!(infcx
+         .int_unification_table
+         .borrow_mut()
+         .unify_var_value(vid, val)
+         .map_err(|e| int_unification_error(vid_is_expected, e)));
+    match val {
+        IntType(v) => Ok(ty::mk_mach_int(infcx.tcx, v)),
+        UintType(v) => Ok(ty::mk_mach_uint(infcx.tcx, v)),
     }
 }
 
-impl<'f, 'tcx> CombineFields<'f, 'tcx> {
-    pub fn switch_expected(&self) -> CombineFields<'f, 'tcx> {
+fn unify_float_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
+                                 vid_is_expected: bool,
+                                 vid: ty::FloatVid,
+                                 val: ast::FloatTy)
+                                 -> RelateResult<'tcx, Ty<'tcx>>
+{
+    try!(infcx
+         .float_unification_table
+         .borrow_mut()
+         .unify_var_value(vid, val)
+         .map_err(|e| float_unification_error(vid_is_expected, e)));
+    Ok(ty::mk_mach_float(infcx.tcx, val))
+}
+
+impl<'a, 'tcx> CombineFields<'a, 'tcx> {
+    pub fn tcx(&self) -> &'a ty::ctxt<'tcx> {
+        self.infcx.tcx
+    }
+
+    pub fn switch_expected(&self) -> CombineFields<'a, 'tcx> {
         CombineFields {
             a_is_expected: !self.a_is_expected,
             ..(*self).clone()
         }
     }
 
-    fn equate(&self) -> Equate<'f, 'tcx> {
-        Equate((*self).clone())
+    pub fn equate(&self) -> Equate<'a, 'tcx> {
+        Equate::new(self.clone())
     }
 
-    fn bivariate(&self) -> Bivariate<'f, 'tcx> {
-        Bivariate((*self).clone())
+    pub fn bivariate(&self) -> Bivariate<'a, 'tcx> {
+        Bivariate::new(self.clone())
     }
 
-    fn sub(&self) -> Sub<'f, 'tcx> {
-        Sub((*self).clone())
+    pub fn sub(&self) -> Sub<'a, 'tcx> {
+        Sub::new(self.clone())
+    }
+
+    pub fn lub(&self) -> Lub<'a, 'tcx> {
+        Lub::new(self.clone())
+    }
+
+    pub fn glb(&self) -> Glb<'a, 'tcx> {
+        Glb::new(self.clone())
     }
 
     pub fn instantiate(&self,
                        a_ty: Ty<'tcx>,
                        dir: RelationDir,
                        b_vid: ty::TyVid)
-                       -> cres<'tcx, ()>
+                       -> RelateResult<'tcx, ()>
     {
         let tcx = self.infcx.tcx;
         let mut stack = Vec::new();
@@ -696,12 +227,8 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
                 None => {     // ...not yet instantiated:
                     // Generalize type if necessary.
                     let generalized_ty = try!(match dir {
-                        EqTo => {
-                            self.generalize(a_ty, b_vid, false)
-                        }
-                        BiTo | SupertypeOf | SubtypeOf => {
-                            self.generalize(a_ty, b_vid, true)
-                        }
+                        EqTo => self.generalize(a_ty, b_vid, false),
+                        BiTo | SupertypeOf | SubtypeOf => self.generalize(a_ty, b_vid, true),
                     });
                     debug!("instantiate(a_ty={}, dir={:?}, \
                                         b_vid={}, generalized_ty={})",
@@ -722,23 +249,12 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
             // relations wind up attributed to the same spans. We need
             // to associate causes/spans with each of the relations in
             // the stack to get this right.
-            match dir {
-                BiTo => {
-                    try!(self.bivariate().tys(a_ty, b_ty));
-                }
-
-                EqTo => {
-                    try!(self.equate().tys(a_ty, b_ty));
-                }
-
-                SubtypeOf => {
-                    try!(self.sub().tys(a_ty, b_ty));
-                }
-
-                SupertypeOf => {
-                    try!(self.sub().tys_with_variance(ty::Contravariant, a_ty, b_ty));
-                }
-            }
+            try!(match dir {
+                BiTo => self.bivariate().relate(&a_ty, &b_ty),
+                EqTo => self.equate().relate(&a_ty, &b_ty),
+                SubtypeOf => self.sub().relate(&a_ty, &b_ty),
+                SupertypeOf => self.sub().relate_with_variance(ty::Contravariant, &a_ty, &b_ty),
+            });
         }
 
         Ok(())
@@ -752,13 +268,15 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
                   ty: Ty<'tcx>,
                   for_vid: ty::TyVid,
                   make_region_vars: bool)
-                  -> cres<'tcx, Ty<'tcx>>
+                  -> RelateResult<'tcx, Ty<'tcx>>
     {
-        let mut generalize = Generalizer { infcx: self.infcx,
-                                           span: self.trace.origin.span(),
-                                           for_vid: for_vid,
-                                           make_region_vars: make_region_vars,
-                                           cycle_detected: false };
+        let mut generalize = Generalizer {
+            infcx: self.infcx,
+            span: self.trace.origin.span(),
+            for_vid: for_vid,
+            make_region_vars: make_region_vars,
+            cycle_detected: false
+        };
         let u = ty.fold_with(&mut generalize);
         if generalize.cycle_detected {
             Err(ty::terr_cyclic_ty)
@@ -818,7 +336,7 @@ impl<'cx, 'tcx> ty_fold::TypeFolder<'tcx> for Generalizer<'cx, 'tcx> {
                 self.tcx().sess.span_bug(
                     self.span,
                     &format!("Encountered early bound region when generalizing: {}",
-                            r.repr(self.tcx()))[]);
+                            r.repr(self.tcx())));
             }
 
             // Always make a fresh region variable for skolemized regions;
@@ -843,3 +361,37 @@ impl<'cx, 'tcx> ty_fold::TypeFolder<'tcx> for Generalizer<'cx, 'tcx> {
         self.infcx.next_region_var(MiscVariable(self.span))
     }
 }
+
+pub trait RelateResultCompare<'tcx, T> {
+    fn compare<F>(&self, t: T, f: F) -> RelateResult<'tcx, T> where
+        F: FnOnce() -> ty::type_err<'tcx>;
+}
+
+impl<'tcx, T:Clone + PartialEq> RelateResultCompare<'tcx, T> for RelateResult<'tcx, T> {
+    fn compare<F>(&self, t: T, f: F) -> RelateResult<'tcx, T> where
+        F: FnOnce() -> ty::type_err<'tcx>,
+    {
+        self.clone().and_then(|s| {
+            if s == t {
+                self.clone()
+            } else {
+                Err(f())
+            }
+        })
+    }
+}
+
+fn int_unification_error<'tcx>(a_is_expected: bool, v: (ty::IntVarValue, ty::IntVarValue))
+                               -> ty::type_err<'tcx>
+{
+    let (a, b) = v;
+    ty::terr_int_mismatch(ty_relate::expected_found_bool(a_is_expected, &a, &b))
+}
+
+fn float_unification_error<'tcx>(a_is_expected: bool,
+                                 v: (ast::FloatTy, ast::FloatTy))
+                                 -> ty::type_err<'tcx>
+{
+    let (a, b) = v;
+    ty::terr_float_mismatch(ty_relate::expected_found_bool(a_is_expected, &a, &b))
+}
index 7194e20b0cf655224c08530e4f569c158d197cab..2003f459d89b42cb895625da636b8d3e74ecb04f 100644 (file)
@@ -8,89 +8,43 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use middle::ty::{BuiltinBounds};
+use super::combine::{self, CombineFields};
+use super::higher_ranked::HigherRankedRelations;
+use super::{Subtype};
+use super::type_variable::{EqTo};
+
 use middle::ty::{self, Ty};
 use middle::ty::TyVar;
-use middle::infer::combine::*;
-use middle::infer::{cres};
-use middle::infer::{Subtype};
-use middle::infer::type_variable::{EqTo};
+use middle::ty_relate::{Relate, RelateResult, TypeRelation};
 use util::ppaux::{Repr};
 
-use syntax::ast::Unsafety;
-
-pub struct Equate<'f, 'tcx: 'f> {
-    fields: CombineFields<'f, 'tcx>
-}
-
-#[allow(non_snake_case)]
-pub fn Equate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Equate<'f, 'tcx> {
-    Equate { fields: cf }
+pub struct Equate<'a, 'tcx: 'a> {
+    fields: CombineFields<'a, 'tcx>
 }
 
-impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
-    fn tag(&self) -> String { "Equate".to_string() }
-    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
-
-    fn tys_with_variance(&self, _: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
-                         -> cres<'tcx, Ty<'tcx>>
-    {
-        // Once we're equating, it doesn't matter what the variance is.
-        self.tys(a, b)
-    }
-
-    fn regions_with_variance(&self, _: ty::Variance, a: ty::Region, b: ty::Region)
-                             -> cres<'tcx, ty::Region>
-    {
-        // Once we're equating, it doesn't matter what the variance is.
-        self.regions(a, b)
-    }
-
-    fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
-        debug!("{}.regions({}, {})",
-               self.tag(),
-               a.repr(self.fields.infcx.tcx),
-               b.repr(self.fields.infcx.tcx));
-        self.infcx().region_vars.make_eqregion(Subtype(self.trace()), a, b);
-        Ok(a)
+impl<'a, 'tcx> Equate<'a, 'tcx> {
+    pub fn new(fields: CombineFields<'a, 'tcx>) -> Equate<'a, 'tcx> {
+        Equate { fields: fields }
     }
+}
 
-    fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
-        debug!("mts({} <: {})",
-               a.repr(self.fields.infcx.tcx),
-               b.repr(self.fields.infcx.tcx));
+impl<'a, 'tcx> TypeRelation<'a,'tcx> for Equate<'a, 'tcx> {
+    fn tag(&self) -> &'static str { "Equate" }
 
-        if a.mutbl != b.mutbl { return Err(ty::terr_mutability); }
-        let t = try!(self.tys(a.ty, b.ty));
-        Ok(ty::mt { mutbl: a.mutbl, ty: t })
-    }
+    fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.fields.tcx() }
 
-    fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
-        if a != b {
-            Err(ty::terr_unsafety_mismatch(expected_found(self, a, b)))
-        } else {
-            Ok(a)
-        }
-    }
+    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
 
-    fn builtin_bounds(&self,
-                      a: BuiltinBounds,
-                      b: BuiltinBounds)
-                      -> cres<'tcx, BuiltinBounds>
+    fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
+                                               _: ty::Variance,
+                                               a: &T,
+                                               b: &T)
+                                               -> RelateResult<'tcx, T>
     {
-        // More bounds is a subtype of fewer bounds.
-        //
-        // e.g., fn:Copy() <: fn(), because the former is a function
-        // that only closes over copyable things, but the latter is
-        // any function at all.
-        if a != b {
-            Err(ty::terr_builtin_bounds(expected_found(self, a, b)))
-        } else {
-            Ok(a)
-        }
+        self.relate(a, b)
     }
 
-    fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
+    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         debug!("{}.tys({}, {})", self.tag(),
                a.repr(self.fields.infcx.tcx), b.repr(self.fields.infcx.tcx));
         if a == b { return Ok(a); }
@@ -115,15 +69,26 @@ impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
             }
 
             _ => {
-                super_tys(self, a, b)
+                combine::super_combine_tys(self.fields.infcx, self, a, b)
             }
         }
     }
 
-    fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
-        where T : Combineable<'tcx>
+    fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
+        debug!("{}.regions({}, {})",
+               self.tag(),
+               a.repr(self.fields.infcx.tcx),
+               b.repr(self.fields.infcx.tcx));
+        let origin = Subtype(self.fields.trace.clone());
+        self.fields.infcx.region_vars.make_eqregion(origin, a, b);
+        Ok(a)
+    }
+
+    fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
+                  -> RelateResult<'tcx, ty::Binder<T>>
+        where T: Relate<'a, 'tcx>
     {
-        try!(self.sub().binders(a, b));
-        self.sub().binders(b, a)
+        try!(self.fields.higher_ranked_sub(a, b));
+        self.fields.higher_ranked_sub(b, a)
     }
 }
index 53032f9b9ac64ac512d673d0faece23d2bee32a9..36229a558e95585756eeff466e5ef13af245575c 100644 (file)
@@ -83,7 +83,7 @@ use std::rc::Rc;
 use std::string::String;
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{name_to_dummy_lifetime, PostExpansionMethod};
+use syntax::ast_util::name_to_dummy_lifetime;
 use syntax::owned_slice::OwnedSlice;
 use syntax::codemap;
 use syntax::parse::token;
@@ -357,23 +357,9 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
             }
         };
 
-        let message_root_str = match trace.origin {
-            infer::Misc(_) => "mismatched types",
-            infer::MethodCompatCheck(_) => "method not compatible with trait",
-            infer::ExprAssignable(_) => "mismatched types",
-            infer::RelateTraitRefs(_) => "mismatched traits",
-            infer::RelateSelfType(_) => "mismatched types",
-            infer::RelateOutputImplTypes(_) => "mismatched types",
-            infer::MatchExpressionArm(_, _) => "match arms have incompatible types",
-            infer::IfExpression(_) => "if and else have incompatible types",
-            infer::IfExpressionWithNoElse(_) => "if may be missing an else clause",
-            infer::RangeExpression(_) => "start and end of range have incompatible types",
-            infer::EquatePredicate(_) => "equality predicate not satisfied",
-        };
-
         span_err!(self.tcx.sess, trace.origin.span(), E0308,
             "{}: {} ({})",
-                 message_root_str,
+                 trace.origin,
                  expected_found_str,
                  ty::type_err_to_str(self.tcx, terr));
 
@@ -444,23 +430,23 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                 // Does the required lifetime have a nice name we can print?
                 span_err!(self.tcx.sess, origin.span(), E0309,
                     "{} may not live long enough", labeled_user_string);
-                self.tcx.sess.span_help(
+                self.tcx.sess.fileline_help(
                     origin.span(),
                     &format!(
                         "consider adding an explicit lifetime bound `{}: {}`...",
                         bound_kind.user_string(self.tcx),
-                        sub.user_string(self.tcx))[]);
+                        sub.user_string(self.tcx)));
             }
 
             ty::ReStatic => {
                 // Does the required lifetime have a nice name we can print?
                 span_err!(self.tcx.sess, origin.span(), E0310,
                     "{} may not live long enough", labeled_user_string);
-                self.tcx.sess.span_help(
+                self.tcx.sess.fileline_help(
                     origin.span(),
                     &format!(
                         "consider adding an explicit lifetime bound `{}: 'static`...",
-                        bound_kind.user_string(self.tcx))[]);
+                        bound_kind.user_string(self.tcx)));
             }
 
             _ => {
@@ -468,14 +454,14 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                 span_err!(self.tcx.sess, origin.span(), E0311,
                         "{} may not live long enough",
                         labeled_user_string);
-                self.tcx.sess.span_help(
+                self.tcx.sess.fileline_help(
                     origin.span(),
                     &format!(
                         "consider adding an explicit lifetime bound for `{}`",
-                        bound_kind.user_string(self.tcx))[]);
+                        bound_kind.user_string(self.tcx)));
                 note_and_explain_region(
                     self.tcx,
-                    &format!("{} must be valid for ", labeled_user_string)[],
+                    &format!("{} must be valid for ", labeled_user_string),
                     sub,
                     "...");
             }
@@ -525,7 +511,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                     &format!("...but `{}` is only valid for ",
                             ty::local_var_name_str(self.tcx,
                                                    upvar_id.var_id)
-                                .to_string())[],
+                                .to_string()),
                     sup,
                     "");
             }
@@ -568,7 +554,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                     &format!("captured variable `{}` does not \
                             outlive the enclosing closure",
                             ty::local_var_name_str(self.tcx,
-                                                   id).to_string())[]);
+                                                   id).to_string()));
                 note_and_explain_region(
                     self.tcx,
                     "captured variable is valid for ",
@@ -610,7 +596,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                     span,
                     &format!("the type `{}` does not fulfill the \
                              required lifetime",
-                            self.ty_to_string(ty))[]);
+                            self.ty_to_string(ty)));
                 note_and_explain_region(self.tcx,
                                         "type must outlive ",
                                         sub,
@@ -636,7 +622,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                     span,
                     &format!("the type `{}` (provided as the value of \
                              a type parameter) is not valid at this point",
-                            self.ty_to_string(ty))[]);
+                            self.ty_to_string(ty)));
                 note_and_explain_region(self.tcx,
                                         "type must outlive ",
                                         sub,
@@ -713,7 +699,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                     span,
                     &format!("type of expression contains references \
                              that are not valid during the expression: `{}`",
-                            self.ty_to_string(t))[]);
+                            self.ty_to_string(t)));
                 note_and_explain_region(
                     self.tcx,
                     "type is only valid for ",
@@ -752,7 +738,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                     span,
                     &format!("in type `{}`, reference has a longer lifetime \
                              than the data it references",
-                            self.ty_to_string(ty))[]);
+                            self.ty_to_string(ty)));
                 note_and_explain_region(
                     self.tcx,
                     "the pointer is valid for ",
@@ -841,33 +827,34 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                 ast_map::NodeItem(ref item) => {
                     match item.node {
                         ast::ItemFn(ref fn_decl, pur, _, ref gen, _) => {
-                            Some((&**fn_decl, gen, pur, item.ident, None, item.span))
+                            Some((fn_decl, gen, pur, item.ident, None, item.span))
                         },
                         _ => None
                     }
                 }
-                ast_map::NodeImplItem(ref item) => {
-                    match **item {
-                        ast::MethodImplItem(ref m) => {
-                            Some((m.pe_fn_decl(),
-                                  m.pe_generics(),
-                                  m.pe_unsafety(),
-                                  m.pe_ident(),
-                                  Some(&m.pe_explicit_self().node),
-                                  m.span))
+                ast_map::NodeImplItem(item) => {
+                    match item.node {
+                        ast::MethodImplItem(ref sig, _) => {
+                            Some((&sig.decl,
+                                  &sig.generics,
+                                  sig.unsafety,
+                                  item.ident,
+                                  Some(&sig.explicit_self.node),
+                                  item.span))
                         }
                         ast::TypeImplItem(_) => None,
+                        ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
                     }
                 },
-                ast_map::NodeTraitItem(ref item) => {
-                    match **item {
-                        ast::ProvidedMethod(ref m) => {
-                            Some((m.pe_fn_decl(),
-                                  m.pe_generics(),
-                                  m.pe_unsafety(),
-                                  m.pe_ident(),
-                                  Some(&m.pe_explicit_self().node),
-                                  m.span))
+                ast_map::NodeTraitItem(item) => {
+                    match item.node {
+                        ast::MethodTraitItem(ref sig, Some(_)) => {
+                            Some((&sig.decl,
+                                  &sig.generics,
+                                  sig.unsafety,
+                                  item.ident,
+                                  Some(&sig.explicit_self.node),
+                                  item.span))
                         }
                         _ => None
                     }
@@ -988,7 +975,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
                 names.push(lt_name);
             }
             names.sort();
-            let name = token::str_to_ident(&names[0][]).name;
+            let name = token::str_to_ident(&names[0]).name;
             return (name_to_dummy_lifetime(name), Kept);
         }
         return (self.life_giver.give_lifetime(), Fresh);
@@ -1233,16 +1220,16 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
                     }
                     ty_queue.push(&*mut_ty.ty);
                 }
-                ast::TyPath(ref path, id) => {
-                    let a_def = match self.tcx.def_map.borrow().get(&id) {
+                ast::TyPath(ref maybe_qself, ref path) => {
+                    let a_def = match self.tcx.def_map.borrow().get(&cur_ty.id) {
                         None => {
                             self.tcx
                                 .sess
                                 .fatal(&format!(
                                         "unbound path {}",
-                                        pprust::path_to_string(path))[])
+                                        pprust::path_to_string(path)))
                         }
-                        Some(&d) => d
+                        Some(d) => d.full_def()
                     };
                     match a_def {
                         def::DefTy(did, _) | def::DefStruct(did) => {
@@ -1277,9 +1264,16 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
                                 region_names: region_names
                             };
                             let new_path = self.rebuild_path(rebuild_info, lifetime);
+                            let qself = maybe_qself.as_ref().map(|qself| {
+                                ast::QSelf {
+                                    ty: self.rebuild_arg_ty_or_output(&qself.ty, lifetime,
+                                                                      anon_nums, region_names),
+                                    position: qself.position
+                                }
+                            });
                             let to = ast::Ty {
                                 id: cur_ty.id,
-                                node: ast::TyPath(new_path, id),
+                                node: ast::TyPath(qself, new_path),
                                 span: cur_ty.span
                             };
                             new_ty = self.rebuild_ty(new_ty, P(to));
@@ -1479,7 +1473,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
             var_origin.span(),
             &format!("cannot infer an appropriate lifetime{} \
                     due to conflicting requirements",
-                    var_description)[]);
+                    var_description));
     }
 
     fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) {
@@ -1487,38 +1481,38 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
             infer::Subtype(ref trace) => {
                 let desc = match trace.origin {
                     infer::Misc(_) => {
-                        format!("types are compatible")
+                        "types are compatible"
                     }
                     infer::MethodCompatCheck(_) => {
-                        format!("method type is compatible with trait")
+                        "method type is compatible with trait"
                     }
                     infer::ExprAssignable(_) => {
-                        format!("expression is assignable")
+                        "expression is assignable"
                     }
                     infer::RelateTraitRefs(_) => {
-                        format!("traits are compatible")
+                        "traits are compatible"
                     }
                     infer::RelateSelfType(_) => {
-                        format!("self type matches impl self type")
+                        "self type matches impl self type"
                     }
                     infer::RelateOutputImplTypes(_) => {
-                        format!("trait type parameters matches those \
-                                 specified on the impl")
+                        "trait type parameters matches those \
+                                 specified on the impl"
                     }
                     infer::MatchExpressionArm(_, _) => {
-                        format!("match arms have compatible types")
+                        "match arms have compatible types"
                     }
                     infer::IfExpression(_) => {
-                        format!("if and else have compatible types")
+                        "if and else have compatible types"
                     }
                     infer::IfExpressionWithNoElse(_) => {
-                        format!("if may be missing an else clause")
+                        "if may be missing an else clause"
                     }
                     infer::RangeExpression(_) => {
-                        format!("start and end of range have compatible types")
+                        "start and end of range have compatible types"
                     }
                     infer::EquatePredicate(_) => {
-                        format!("equality where clause is satisfied")
+                        "equality where clause is satisfied"
                     }
                 };
 
@@ -1527,7 +1521,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
                         self.tcx.sess.span_note(
                             trace.origin.span(),
                             &format!("...so that {} ({})",
-                                    desc, values_str)[]);
+                                    desc, values_str));
                     }
                     None => {
                         // Really should avoid printing this error at
@@ -1536,7 +1530,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
                         // doing right now. - nmatsakis
                         self.tcx.sess.span_note(
                             trace.origin.span(),
-                            &format!("...so that {}", desc)[]);
+                            &format!("...so that {}", desc));
                     }
                 }
             }
@@ -1552,7 +1546,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
                     &format!(
                         "...so that closure can access `{}`",
                         ty::local_var_name_str(self.tcx, upvar_id.var_id)
-                            .to_string())[])
+                            .to_string()))
             }
             infer::InfStackClosure(span) => {
                 self.tcx.sess.span_note(
@@ -1577,7 +1571,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
                             does not outlive the enclosing closure",
                             ty::local_var_name_str(
                                 self.tcx,
-                                id).to_string())[]);
+                                id).to_string()));
             }
             infer::IndexSlice(span) => {
                 self.tcx.sess.span_note(
@@ -1626,7 +1620,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
                     span,
                     &format!("...so type `{}` of expression is valid during the \
                              expression",
-                            self.ty_to_string(t))[]);
+                            self.ty_to_string(t)));
             }
             infer::BindingTypeIsNotValidAtDecl(span) => {
                 self.tcx.sess.span_note(
@@ -1638,14 +1632,14 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
                     span,
                     &format!("...so that the reference type `{}` \
                              does not outlive the data it points at",
-                            self.ty_to_string(ty))[]);
+                            self.ty_to_string(ty)));
             }
             infer::RelateParamBound(span, t) => {
                 self.tcx.sess.span_note(
                     span,
                     &format!("...so that the type `{}` \
                              will meet its required lifetime bounds",
-                            self.ty_to_string(t))[]);
+                            self.ty_to_string(t)));
             }
             infer::RelateDefaultParamBound(span, t) => {
                 self.tcx.sess.span_note(
@@ -1653,13 +1647,13 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
                     &format!("...so that type parameter \
                              instantiated with `{}`, \
                              will meet its declared lifetime bounds",
-                            self.ty_to_string(t))[]);
+                            self.ty_to_string(t)));
             }
             infer::RelateRegionParamBound(span) => {
                 self.tcx.sess.span_note(
                     span,
-                    &format!("...so that the declared lifetime parameter bounds \
-                                are satisfied")[]);
+                    "...so that the declared lifetime parameter bounds \
+                                are satisfied");
             }
             infer::SafeDestructor(span) => {
                 self.tcx.sess.span_note(
@@ -1717,18 +1711,19 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
         Some(node) => match node {
             ast_map::NodeItem(item) => match item.node {
                 ast::ItemFn(_, _, _, ref gen, _) => {
-                    taken.push_all(&gen.lifetimes[]);
+                    taken.push_all(&gen.lifetimes);
                     None
                 },
                 _ => None
             },
             ast_map::NodeImplItem(ii) => {
-                match *ii {
-                    ast::MethodImplItem(ref m) => {
-                        taken.push_all(&m.pe_generics().lifetimes[]);
-                        Some(m.id)
+                match ii.node {
+                    ast::MethodImplItem(ref sig, _) => {
+                        taken.push_all(&sig.generics.lifetimes);
+                        Some(ii.id)
                     }
                     ast::TypeImplItem(_) => None,
+                    ast::MacImplItem(_) => tcx.sess.bug("unexpanded macro")
                 }
             }
             _ => None
@@ -1757,7 +1752,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
 // LifeGiver is responsible for generating fresh lifetime names
 struct LifeGiver {
     taken: HashSet<String>,
-    counter: Cell<uint>,
+    counter: Cell<usize>,
     generated: RefCell<Vec<ast::Lifetime>>,
 }
 
@@ -1784,7 +1779,7 @@ impl LifeGiver {
         let mut lifetime;
         loop {
             let mut s = String::from_str("'");
-            s.push_str(&num_to_string(self.counter.get())[]);
+            s.push_str(&num_to_string(self.counter.get()));
             if !self.taken.contains(&s) {
                 lifetime = name_to_dummy_lifetime(
                                     token::str_to_ident(&s[..]).name);
@@ -1797,7 +1792,7 @@ impl LifeGiver {
         return lifetime;
 
         // 0 .. 25 generates a .. z, 26 .. 51 generates aa .. zz, and so on
-        fn num_to_string(counter: uint) -> String {
+        fn num_to_string(counter: usize) -> String {
             let mut s = String::new();
             let (n, r) = (counter/26 + 1, counter % 26);
             let letter: char = from_u32((r+97) as u32).unwrap();
index 1b7e6c33c0575f723d341ec8373005765a0c5147..29f74d12ea3e814bb82c3030687b78d9eb7bd534 100644 (file)
@@ -37,7 +37,7 @@ use middle::ty_fold::TypeFolder;
 use std::collections::hash_map::{self, Entry};
 
 use super::InferCtxt;
-use super::unify::InferCtxtMethodsForSimplyUnifiableTypes;
+use super::unify::ToType;
 
 pub struct TypeFreshener<'a, 'tcx:'a> {
     infcx: &'a InferCtxt<'a, 'tcx>,
@@ -104,29 +104,38 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
     }
 
     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+        let tcx = self.infcx.tcx;
+
         match t.sty {
             ty::ty_infer(ty::TyVar(v)) => {
-                self.freshen(self.infcx.type_variables.borrow().probe(v),
-                               ty::TyVar(v),
-                               ty::FreshTy)
+                self.freshen(
+                    self.infcx.type_variables.borrow().probe(v),
+                    ty::TyVar(v),
+                    ty::FreshTy)
             }
 
             ty::ty_infer(ty::IntVar(v)) => {
-                self.freshen(self.infcx.probe_var(v),
-                             ty::IntVar(v),
-                             ty::FreshIntTy)
+                self.freshen(
+                    self.infcx.int_unification_table.borrow_mut()
+                                                    .probe(v)
+                                                    .map(|v| v.to_type(tcx)),
+                    ty::IntVar(v),
+                    ty::FreshIntTy)
             }
 
             ty::ty_infer(ty::FloatVar(v)) => {
-                self.freshen(self.infcx.probe_var(v),
-                             ty::FloatVar(v),
-                             ty::FreshIntTy)
+                self.freshen(
+                    self.infcx.float_unification_table.borrow_mut()
+                                                      .probe(v)
+                                                      .map(|v| v.to_type(tcx)),
+                    ty::FloatVar(v),
+                    ty::FreshIntTy)
             }
 
             ty::ty_infer(ty::FreshTy(c)) |
             ty::ty_infer(ty::FreshIntTy(c)) => {
                 if c >= self.freshen_count {
-                    self.tcx().sess.bug(
+                    tcx.sess.bug(
                         &format!("Encountered a freshend type with id {} \
                                   but our counter is only at {}",
                                  c,
@@ -135,7 +144,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
                 t
             }
 
-            ty::ty_open(..) |
             ty::ty_bool |
             ty::ty_char |
             ty::ty_int(..) |
index 33303808e84910ebb7062c4bf9147451ee7aaecd..5822fb0f2d432fba8d7c3fe10959268c158d3fc4 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::combine::*;
-use super::lattice::*;
+use super::combine::CombineFields;
 use super::higher_ranked::HigherRankedRelations;
-use super::{cres};
+use super::InferCtxt;
+use super::lattice::{self, LatticeDir};
 use super::Subtype;
 
-use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
-use syntax::ast::{MutImmutable, MutMutable, Unsafety};
-use util::ppaux::mt_to_string;
+use middle::ty_relate::{Relate, RelateResult, TypeRelation};
 use util::ppaux::Repr;
 
 /// "Greatest lower bound" (common subtype)
-pub struct Glb<'f, 'tcx: 'f> {
-    fields: CombineFields<'f, 'tcx>
+pub struct Glb<'a, 'tcx: 'a> {
+    fields: CombineFields<'a, 'tcx>
 }
 
-#[allow(non_snake_case)]
-pub fn Glb<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Glb<'f, 'tcx> {
-    Glb { fields: cf }
-}
-
-impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
-    fn tag(&self) -> String { "Glb".to_string() }
-    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
-
-    fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
-                         -> cres<'tcx, Ty<'tcx>>
-    {
-        match v {
-            ty::Invariant => self.equate().tys(a, b),
-            ty::Covariant => self.tys(a, b),
-            ty::Bivariant => self.bivariate().tys(a, b),
-            ty::Contravariant => self.lub().tys(a, b),
-        }
+impl<'a, 'tcx> Glb<'a, 'tcx> {
+    pub fn new(fields: CombineFields<'a, 'tcx>) -> Glb<'a, 'tcx> {
+        Glb { fields: fields }
     }
+}
 
-    fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
-                             -> cres<'tcx, ty::Region>
-    {
-        match v {
-            ty::Invariant => self.equate().regions(a, b),
-            ty::Covariant => self.regions(a, b),
-            ty::Bivariant => self.bivariate().regions(a, b),
-            ty::Contravariant => self.lub().regions(a, b),
-        }
-    }
-
-    fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
-        let tcx = self.fields.infcx.tcx;
-
-        debug!("{}.mts({}, {})",
-               self.tag(),
-               mt_to_string(tcx, a),
-               mt_to_string(tcx, b));
-
-        match (a.mutbl, b.mutbl) {
-            // If one side or both is mut, then the GLB must use
-            // the precise type from the mut side.
-            (MutMutable, MutMutable) => {
-                let t = try!(self.equate().tys(a.ty, b.ty));
-                Ok(ty::mt {ty: t, mutbl: MutMutable})
-            }
+impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Glb<'a, 'tcx> {
+    fn tag(&self) -> &'static str { "Glb" }
 
-            // If one side or both is immutable, we can use the GLB of
-            // both sides but mutbl must be `MutImmutable`.
-            (MutImmutable, MutImmutable) => {
-                let t = try!(self.tys(a.ty, b.ty));
-                Ok(ty::mt {ty: t, mutbl: MutImmutable})
-            }
+    fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.fields.tcx() }
 
-            // There is no mutual subtype of these combinations.
-            (MutMutable, MutImmutable) |
-            (MutImmutable, MutMutable) => {
-                Err(ty::terr_mutability)
-            }
-        }
-    }
+    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
 
-    fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
-        match (a, b) {
-          (Unsafety::Normal, _) | (_, Unsafety::Normal) => Ok(Unsafety::Normal),
-          (Unsafety::Unsafe, Unsafety::Unsafe) => Ok(Unsafety::Unsafe)
+    fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
+                                               variance: ty::Variance,
+                                               a: &T,
+                                               b: &T)
+                                               -> RelateResult<'tcx, T>
+    {
+        match variance {
+            ty::Invariant => self.fields.equate().relate(a, b),
+            ty::Covariant => self.relate(a, b),
+            ty::Bivariant => self.fields.bivariate().relate(a, b),
+            ty::Contravariant => self.fields.lub().relate(a, b),
         }
     }
 
-    fn builtin_bounds(&self,
-                      a: ty::BuiltinBounds,
-                      b: ty::BuiltinBounds)
-                      -> cres<'tcx, ty::BuiltinBounds> {
-        // More bounds is a subtype of fewer bounds, so
-        // the GLB (mutual subtype) is the union.
-        Ok(a.union(b))
+    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+        lattice::super_lattice_tys(self, a, b)
     }
 
-    fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
+    fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
         debug!("{}.regions({}, {})",
                self.tag(),
                a.repr(self.fields.infcx.tcx),
                b.repr(self.fields.infcx.tcx));
 
-        Ok(self.fields.infcx.region_vars.glb_regions(Subtype(self.trace()), a, b))
+        let origin = Subtype(self.fields.trace.clone());
+        Ok(self.fields.infcx.region_vars.glb_regions(origin, a, b))
     }
 
-    fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        super_lattice_tys(self, a, b)
+    fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
+                  -> RelateResult<'tcx, ty::Binder<T>>
+        where T: Relate<'a, 'tcx>
+    {
+        self.fields.higher_ranked_glb(a, b)
     }
+}
 
-    fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
-        where T : Combineable<'tcx>
-    {
-        self.higher_ranked_glb(a, b)
+impl<'a, 'tcx> LatticeDir<'a,'tcx> for Glb<'a, 'tcx> {
+    fn infcx(&self) -> &'a InferCtxt<'a,'tcx> {
+        self.fields.infcx
+    }
+
+    fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
+        let mut sub = self.fields.sub();
+        try!(sub.relate(&v, &a));
+        try!(sub.relate(&v, &b));
+        Ok(())
     }
 }
index a729156c88b3588e3d85e442d6878b6c526fcd15..f347d28b93c2b0aa06f41e6e4dd00abedc938ae1 100644 (file)
 //! Helper routines for higher-ranked things. See the `doc` module at
 //! the end of the file for details.
 
-use super::{CombinedSnapshot, cres, InferCtxt, HigherRankedType, SkolemizationMap};
-use super::combine::{Combine, Combineable};
+use super::{CombinedSnapshot, InferCtxt, HigherRankedType, SkolemizationMap};
+use super::combine::CombineFields;
 
+use middle::subst;
 use middle::ty::{self, Binder};
 use middle::ty_fold::{self, TypeFoldable};
+use middle::ty_relate::{Relate, RelateResult, TypeRelation};
 use syntax::codemap::Span;
 use util::nodemap::{FnvHashMap, FnvHashSet};
 use util::ppaux::Repr;
 
-pub trait HigherRankedRelations<'tcx> {
-    fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
-        where T : Combineable<'tcx>;
+pub trait HigherRankedRelations<'a,'tcx> {
+    fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> RelateResult<'tcx, Binder<T>>
+        where T: Relate<'a,'tcx>;
 
-    fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
-        where T : Combineable<'tcx>;
+    fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> RelateResult<'tcx, Binder<T>>
+        where T: Relate<'a,'tcx>;
 
-    fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
-        where T : Combineable<'tcx>;
+    fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> RelateResult<'tcx, Binder<T>>
+        where T: Relate<'a,'tcx>;
 }
 
 trait InferCtxtExt {
@@ -39,15 +41,15 @@ trait InferCtxtExt {
                                         -> Vec<ty::RegionVid>;
 }
 
-impl<'tcx,C> HigherRankedRelations<'tcx> for C
-    where C : Combine<'tcx>
-{
+impl<'a,'tcx> HigherRankedRelations<'a,'tcx> for CombineFields<'a,'tcx> {
     fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>)
-                            -> cres<'tcx, Binder<T>>
-        where T : Combineable<'tcx>
+                            -> RelateResult<'tcx, Binder<T>>
+        where T: Relate<'a,'tcx>
     {
+        let tcx = self.infcx.tcx;
+
         debug!("higher_ranked_sub(a={}, b={})",
-               a.repr(self.tcx()), b.repr(self.tcx()));
+               a.repr(tcx), b.repr(tcx));
 
         // Rather than checking the subtype relationship between `a` and `b`
         // as-is, we need to do some extra work here in order to make sure
@@ -59,32 +61,32 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
 
         // Start a snapshot so we can examine "all bindings that were
         // created as part of this type comparison".
-        return self.infcx().try(|snapshot| {
+        return self.infcx.commit_if_ok(|snapshot| {
             // First, we instantiate each bound region in the subtype with a fresh
             // region variable.
             let (a_prime, _) =
-                self.infcx().replace_late_bound_regions_with_fresh_var(
-                    self.trace().origin.span(),
+                self.infcx.replace_late_bound_regions_with_fresh_var(
+                    self.trace.origin.span(),
                     HigherRankedType,
                     a);
 
             // Second, we instantiate each bound region in the supertype with a
             // fresh concrete region.
             let (b_prime, skol_map) =
-                self.infcx().skolemize_late_bound_regions(b, snapshot);
+                self.infcx.skolemize_late_bound_regions(b, snapshot);
 
-            debug!("a_prime={}", a_prime.repr(self.tcx()));
-            debug!("b_prime={}", b_prime.repr(self.tcx()));
+            debug!("a_prime={}", a_prime.repr(tcx));
+            debug!("b_prime={}", b_prime.repr(tcx));
 
             // Compare types now that bound regions have been replaced.
-            let result = try!(Combineable::combine(self, &a_prime, &b_prime));
+            let result = try!(self.sub().relate(&a_prime, &b_prime));
 
             // Presuming type comparison succeeds, we need to check
             // that the skolemized regions do not "leak".
-            match leak_check(self.infcx(), &skol_map, snapshot) {
+            match leak_check(self.infcx, &skol_map, snapshot) {
                 Ok(()) => { }
                 Err((skol_br, tainted_region)) => {
-                    if self.a_is_expected() {
+                    if self.a_is_expected {
                         debug!("Not as polymorphic!");
                         return Err(ty::terr_regions_insufficiently_polymorphic(skol_br,
                                                                                tainted_region));
@@ -97,42 +99,42 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
             }
 
             debug!("higher_ranked_sub: OK result={}",
-                   result.repr(self.tcx()));
+                   result.repr(tcx));
 
             Ok(ty::Binder(result))
         });
     }
 
-    fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
-        where T : Combineable<'tcx>
+    fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> RelateResult<'tcx, Binder<T>>
+        where T: Relate<'a,'tcx>
     {
         // Start a snapshot so we can examine "all bindings that were
         // created as part of this type comparison".
-        return self.infcx().try(|snapshot| {
+        return self.infcx.commit_if_ok(|snapshot| {
             // Instantiate each bound region with a fresh region variable.
-            let span = self.trace().origin.span();
+            let span = self.trace.origin.span();
             let (a_with_fresh, a_map) =
-                self.infcx().replace_late_bound_regions_with_fresh_var(
+                self.infcx.replace_late_bound_regions_with_fresh_var(
                     span, HigherRankedType, a);
             let (b_with_fresh, _) =
-                self.infcx().replace_late_bound_regions_with_fresh_var(
+                self.infcx.replace_late_bound_regions_with_fresh_var(
                     span, HigherRankedType, b);
 
             // Collect constraints.
             let result0 =
-                try!(Combineable::combine(self, &a_with_fresh, &b_with_fresh));
+                try!(self.lub().relate(&a_with_fresh, &b_with_fresh));
             let result0 =
-                self.infcx().resolve_type_vars_if_possible(&result0);
+                self.infcx.resolve_type_vars_if_possible(&result0);
             debug!("lub result0 = {}", result0.repr(self.tcx()));
 
             // Generalize the regions appearing in result0 if possible
-            let new_vars = self.infcx().region_vars_confined_to_snapshot(snapshot);
-            let span = self.trace().origin.span();
+            let new_vars = self.infcx.region_vars_confined_to_snapshot(snapshot);
+            let span = self.trace.origin.span();
             let result1 =
                 fold_regions_in(
                     self.tcx(),
                     &result0,
-                    |r, debruijn| generalize_region(self.infcx(), span, snapshot, debruijn,
+                    |r, debruijn| generalize_region(self.infcx, span, snapshot, debruijn,
                                                     &new_vars, &a_map, r));
 
             debug!("lub({},{}) = {}",
@@ -189,44 +191,44 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
                 span,
                 &format!("region {:?} is not associated with \
                          any bound region from A!",
-                        r0)[])
+                        r0))
         }
     }
 
-    fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
-        where T : Combineable<'tcx>
+    fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> RelateResult<'tcx, Binder<T>>
+        where T: Relate<'a,'tcx>
     {
-        debug!("{}.higher_ranked_glb({}, {})",
-               self.tag(), a.repr(self.tcx()), b.repr(self.tcx()));
+        debug!("higher_ranked_glb({}, {})",
+               a.repr(self.tcx()), b.repr(self.tcx()));
 
         // Make a snapshot so we can examine "all bindings that were
         // created as part of this type comparison".
-        return self.infcx().try(|snapshot| {
+        return self.infcx.commit_if_ok(|snapshot| {
             // Instantiate each bound region with a fresh region variable.
             let (a_with_fresh, a_map) =
-                self.infcx().replace_late_bound_regions_with_fresh_var(
-                    self.trace().origin.span(), HigherRankedType, a);
+                self.infcx.replace_late_bound_regions_with_fresh_var(
+                    self.trace.origin.span(), HigherRankedType, a);
             let (b_with_fresh, b_map) =
-                self.infcx().replace_late_bound_regions_with_fresh_var(
-                    self.trace().origin.span(), HigherRankedType, b);
+                self.infcx.replace_late_bound_regions_with_fresh_var(
+                    self.trace.origin.span(), HigherRankedType, b);
             let a_vars = var_ids(self, &a_map);
             let b_vars = var_ids(self, &b_map);
 
             // Collect constraints.
             let result0 =
-                try!(Combineable::combine(self, &a_with_fresh, &b_with_fresh));
+                try!(self.glb().relate(&a_with_fresh, &b_with_fresh));
             let result0 =
-                self.infcx().resolve_type_vars_if_possible(&result0);
+                self.infcx.resolve_type_vars_if_possible(&result0);
             debug!("glb result0 = {}", result0.repr(self.tcx()));
 
             // Generalize the regions appearing in result0 if possible
-            let new_vars = self.infcx().region_vars_confined_to_snapshot(snapshot);
-            let span = self.trace().origin.span();
+            let new_vars = self.infcx.region_vars_confined_to_snapshot(snapshot);
+            let span = self.trace.origin.span();
             let result1 =
                 fold_regions_in(
                     self.tcx(),
                     &result0,
-                    |r, debruijn| generalize_region(self.infcx(), span, snapshot, debruijn,
+                    |r, debruijn| generalize_region(self.infcx, span, snapshot, debruijn,
                                                     &new_vars,
                                                     &a_map, &a_vars, &b_vars,
                                                     r));
@@ -322,7 +324,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
             }
             infcx.tcx.sess.span_bug(
                 span,
-                &format!("could not find original bound region for {:?}", r)[]);
+                &format!("could not find original bound region for {:?}", r));
         }
 
         fn fresh_bound_variable(infcx: &InferCtxt, debruijn: ty::DebruijnIndex) -> ty::Region {
@@ -331,17 +333,19 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
     }
 }
 
-fn var_ids<'tcx, T: Combine<'tcx>>(combiner: &T,
-                                   map: &FnvHashMap<ty::BoundRegion, ty::Region>)
-                                   -> Vec<ty::RegionVid> {
-    map.iter().map(|(_, r)| match *r {
-            ty::ReInfer(ty::ReVar(r)) => { r }
-            r => {
-                combiner.infcx().tcx.sess.span_bug(
-                    combiner.trace().origin.span(),
-                    &format!("found non-region-vid: {:?}", r)[]);
-            }
-        }).collect()
+fn var_ids<'a, 'tcx>(fields: &CombineFields<'a, 'tcx>,
+                      map: &FnvHashMap<ty::BoundRegion, ty::Region>)
+                     -> Vec<ty::RegionVid> {
+    map.iter()
+       .map(|(_, r)| match *r {
+           ty::ReInfer(ty::ReVar(r)) => { r }
+           r => {
+               fields.tcx().sess.span_bug(
+                   fields.trace.origin.span(),
+                   &format!("found non-region-vid: {:?}", r));
+           }
+       })
+       .collect()
 }
 
 fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool {
@@ -355,8 +359,8 @@ fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>,
                                unbound_value: &T,
                                mut fldr: F)
                                -> T
-    where T : Combineable<'tcx>,
-          F : FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region,
+    where T: TypeFoldable<'tcx>,
+          F: FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region,
 {
     unbound_value.fold_with(&mut ty_fold::RegionFolder::new(tcx, &mut |region, current_depth| {
         // we should only be encountering "escaping" late-bound regions here,
@@ -455,6 +459,63 @@ impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> {
     }
 }
 
+/// Constructs and returns a substitution that, for a given type
+/// scheme parameterized by `generics`, will replace every generic
+/// parmeter in the type with a skolemized type/region (which one can
+/// think of as a "fresh constant", except at the type/region level of
+/// reasoning).
+///
+/// Since we currently represent bound/free type parameters in the
+/// same way, this only has an effect on regions.
+///
+/// (Note that unlike a substitution from `ty::construct_free_substs`,
+/// this inserts skolemized regions rather than free regions; this
+/// allows one to use `fn leak_check` to catch attmepts to unify the
+/// skolemized regions with e.g. the `'static` lifetime)
+pub fn construct_skolemized_substs<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
+                                            generics: &ty::Generics<'tcx>,
+                                            snapshot: &CombinedSnapshot)
+                                            -> (subst::Substs<'tcx>, SkolemizationMap)
+{
+    let mut map = FnvHashMap();
+
+    // map T => T
+    let mut types = subst::VecPerParamSpace::empty();
+    push_types_from_defs(infcx.tcx, &mut types, generics.types.as_slice());
+
+    // map early- or late-bound 'a => fresh 'a
+    let mut regions = subst::VecPerParamSpace::empty();
+    push_region_params(infcx, &mut map, &mut regions, generics.regions.as_slice(), snapshot);
+
+    let substs = subst::Substs { types: types,
+                                 regions: subst::NonerasedRegions(regions) };
+    return (substs, map);
+
+    fn push_region_params<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
+                                   map: &mut SkolemizationMap,
+                                   regions: &mut subst::VecPerParamSpace<ty::Region>,
+                                   region_params: &[ty::RegionParameterDef],
+                                   snapshot: &CombinedSnapshot)
+    {
+        for r in region_params {
+            let br = r.to_bound_region();
+            let skol_var = infcx.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot);
+            let sanity_check = map.insert(br, skol_var);
+            assert!(sanity_check.is_none());
+            regions.push(r.space, skol_var);
+        }
+    }
+
+    fn push_types_from_defs<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                  types: &mut subst::VecPerParamSpace<ty::Ty<'tcx>>,
+                                  defs: &[ty::TypeParameterDef<'tcx>]) {
+        for def in defs {
+            let ty = ty::mk_param_from_def(tcx, def);
+            types.push(def.space, ty);
+        }
+    }
+}
+
 pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
                                                binder: &ty::Binder<T>,
                                                snapshot: &CombinedSnapshot)
@@ -465,7 +526,8 @@ pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
      * Replace all regions bound by `binder` with skolemized regions and
      * return a map indicating which bound-region was replaced with what
      * skolemized region. This is the first step of checking subtyping
-     * when higher-ranked things are involved. See `doc.rs` for more details.
+     * when higher-ranked things are involved. See `README.md` for more
+     * details.
      */
 
     let (result, map) = ty::replace_late_bound_regions(infcx.tcx, binder, |br| {
@@ -490,7 +552,7 @@ pub fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
      * and checks to determine whether any of the skolemized regions created
      * in `skol_map` would "escape" -- meaning that they are related to
      * other regions in some way. If so, the higher-ranked subtyping doesn't
-     * hold. See `doc.rs` for more details.
+     * hold. See `README.md` for more details.
      */
 
     debug!("leak_check: skol_map={}",
@@ -533,7 +595,7 @@ pub fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
 /// passed; currently, it's used in the trait matching code to create
 /// a set of nested obligations frmo an impl that matches against
 /// something higher-ranked.  More details can be found in
-/// `middle::traits::doc.rs`.
+/// `librustc/middle/traits/README.md`.
 ///
 /// As a brief example, consider the obligation `for<'a> Fn(&'a int)
 /// -> &'a int`, and the impl:
index 121e5405f26dc79c0595c91f5c71018082a54705..57001083b03e200e410d7fa0e9de3a76854a09a4 100644 (file)
 //! over a `LatticeValue`, which is a value defined with respect to
 //! a lattice.
 
-use super::*;
-use super::combine::*;
-use super::glb::Glb;
-use super::lub::Lub;
+use super::combine;
+use super::InferCtxt;
 
-use middle::ty::{TyVar};
+use middle::ty::TyVar;
 use middle::ty::{self, Ty};
+use middle::ty_relate::{RelateResult, TypeRelation};
 use util::ppaux::Repr;
 
-pub trait LatticeDir<'tcx> {
+pub trait LatticeDir<'f,'tcx> : TypeRelation<'f,'tcx> {
+    fn infcx(&self) -> &'f InferCtxt<'f, 'tcx>;
+
     // Relates the type `v` to `a` and `b` such that `v` represents
     // the LUB/GLB of `a` and `b` as appropriate.
-    fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, ()>;
-}
-
-impl<'a, 'tcx> LatticeDir<'tcx> for Lub<'a, 'tcx> {
-    fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, ()> {
-        let sub = self.sub();
-        try!(sub.tys(a, v));
-        try!(sub.tys(b, v));
-        Ok(())
-    }
-}
-
-impl<'a, 'tcx> LatticeDir<'tcx> for Glb<'a, 'tcx> {
-    fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, ()> {
-        let sub = self.sub();
-        try!(sub.tys(v, a));
-        try!(sub.tys(v, b));
-        Ok(())
-    }
+    fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()>;
 }
 
-pub fn super_lattice_tys<'tcx, L:LatticeDir<'tcx>+Combine<'tcx>>(this: &L,
-                                                                 a: Ty<'tcx>,
-                                                                 b: Ty<'tcx>)
-                                                                 -> cres<'tcx, Ty<'tcx>>
+pub fn super_lattice_tys<'a,'tcx,L:LatticeDir<'a,'tcx>>(this: &mut L,
+                                                        a: Ty<'tcx>,
+                                                        b: Ty<'tcx>)
+                                                        -> RelateResult<'tcx, Ty<'tcx>>
+    where 'tcx: 'a
 {
     debug!("{}.lattice_tys({}, {})",
            this.tag(),
-           a.repr(this.infcx().tcx),
-           b.repr(this.infcx().tcx));
+           a.repr(this.tcx()),
+           b.repr(this.tcx()));
 
     if a == b {
         return Ok(a);
@@ -95,7 +79,7 @@ pub fn super_lattice_tys<'tcx, L:LatticeDir<'tcx>+Combine<'tcx>>(this: &L,
         }
 
         _ => {
-            super_tys(this, a, b)
+            combine::super_combine_tys(this.infcx(), this, a, b)
         }
     }
 }
index 3570effa9fa709ff2de3c304db15f75f6dd4d428..f456687be13ac49567537768bfdc0c72f4a4a6a5 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::combine::*;
+use super::combine::CombineFields;
 use super::higher_ranked::HigherRankedRelations;
-use super::lattice::*;
-use super::{cres};
-use super::{Subtype};
+use super::InferCtxt;
+use super::lattice::{self, LatticeDir};
+use super::Subtype;
 
-use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
-use syntax::ast::{MutMutable, MutImmutable, Unsafety};
-use util::ppaux::mt_to_string;
+use middle::ty_relate::{Relate, RelateResult, TypeRelation};
 use util::ppaux::Repr;
 
 /// "Least upper bound" (common supertype)
-pub struct Lub<'f, 'tcx: 'f> {
-    fields: CombineFields<'f, 'tcx>
+pub struct Lub<'a, 'tcx: 'a> {
+    fields: CombineFields<'a, 'tcx>
 }
 
-#[allow(non_snake_case)]
-pub fn Lub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Lub<'f, 'tcx> {
-    Lub { fields: cf }
-}
-
-impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
-    fn tag(&self) -> String { "Lub".to_string() }
-    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
-
-    fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
-                         -> cres<'tcx, Ty<'tcx>>
-    {
-        match v {
-            ty::Invariant => self.equate().tys(a, b),
-            ty::Covariant => self.tys(a, b),
-            ty::Bivariant => self.bivariate().tys(a, b),
-            ty::Contravariant => self.glb().tys(a, b),
-        }
-    }
-
-    fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
-                             -> cres<'tcx, ty::Region>
-    {
-        match v {
-            ty::Invariant => self.equate().regions(a, b),
-            ty::Covariant => self.regions(a, b),
-            ty::Bivariant => self.bivariate().regions(a, b),
-            ty::Contravariant => self.glb().regions(a, b),
-        }
+impl<'a, 'tcx> Lub<'a, 'tcx> {
+    pub fn new(fields: CombineFields<'a, 'tcx>) -> Lub<'a, 'tcx> {
+        Lub { fields: fields }
     }
+}
 
-    fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
-        let tcx = self.tcx();
-
-        debug!("{}.mts({}, {})",
-               self.tag(),
-               mt_to_string(tcx, a),
-               mt_to_string(tcx, b));
-
-        if a.mutbl != b.mutbl {
-            return Err(ty::terr_mutability)
-        }
+impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Lub<'a, 'tcx> {
+    fn tag(&self) -> &'static str { "Lub" }
 
-        let m = a.mutbl;
-        match m {
-            MutImmutable => {
-                let t = try!(self.tys(a.ty, b.ty));
-                Ok(ty::mt {ty: t, mutbl: m})
-            }
+    fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.fields.tcx() }
 
-            MutMutable => {
-                let t = try!(self.equate().tys(a.ty, b.ty));
-                Ok(ty::mt {ty: t, mutbl: m})
-            }
-        }
-    }
+    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
 
-    fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
-        match (a, b) {
-          (Unsafety::Unsafe, _) | (_, Unsafety::Unsafe) => Ok(Unsafety::Unsafe),
-          (Unsafety::Normal, Unsafety::Normal) => Ok(Unsafety::Normal),
+    fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
+                                               variance: ty::Variance,
+                                               a: &T,
+                                               b: &T)
+                                               -> RelateResult<'tcx, T>
+    {
+        match variance {
+            ty::Invariant => self.fields.equate().relate(a, b),
+            ty::Covariant => self.relate(a, b),
+            ty::Bivariant => self.fields.bivariate().relate(a, b),
+            ty::Contravariant => self.fields.glb().relate(a, b),
         }
     }
 
-    fn builtin_bounds(&self,
-                      a: ty::BuiltinBounds,
-                      b: ty::BuiltinBounds)
-                      -> cres<'tcx, ty::BuiltinBounds> {
-        // More bounds is a subtype of fewer bounds, so
-        // the LUB (mutual supertype) is the intersection.
-        Ok(a.intersection(b))
+    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+        lattice::super_lattice_tys(self, a, b)
     }
 
-    fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
+    fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
         debug!("{}.regions({}, {})",
                self.tag(),
                a.repr(self.tcx()),
                b.repr(self.tcx()));
 
-        Ok(self.infcx().region_vars.lub_regions(Subtype(self.trace()), a, b))
+        let origin = Subtype(self.fields.trace.clone());
+        Ok(self.fields.infcx.region_vars.lub_regions(origin, a, b))
     }
 
-    fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        super_lattice_tys(self, a, b)
+    fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
+                  -> RelateResult<'tcx, ty::Binder<T>>
+        where T: Relate<'a, 'tcx>
+    {
+        self.fields.higher_ranked_lub(a, b)
     }
+}
 
-    fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
-        where T : Combineable<'tcx>
-    {
-        self.higher_ranked_lub(a, b)
+impl<'a, 'tcx> LatticeDir<'a,'tcx> for Lub<'a, 'tcx> {
+    fn infcx(&self) -> &'a InferCtxt<'a,'tcx> {
+        self.fields.infcx
+    }
+
+    fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
+        let mut sub = self.fields.sub();
+        try!(sub.relate(&a, &v));
+        try!(sub.relate(&b, &v));
+        Ok(())
     }
 }
+
index b0576ff55ff7390605b889c93df55b3b10aa6b2f..b11e25c059d08ffafc1af1184063aeef34f9982e 100644 (file)
@@ -28,21 +28,20 @@ use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric};
 use middle::ty::replace_late_bound_regions;
 use middle::ty::{self, Ty};
 use middle::ty_fold::{TypeFolder, TypeFoldable};
+use middle::ty_relate::{Relate, RelateResult, TypeRelation};
 use std::cell::{RefCell};
+use std::fmt;
 use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap;
 use syntax::codemap::Span;
 use util::nodemap::FnvHashMap;
-use util::ppaux::{ty_to_string};
+use util::ppaux::ty_to_string;
 use util::ppaux::{Repr, UserString};
 
-use self::combine::{Combine, Combineable, CombineFields};
+use self::combine::CombineFields;
 use self::region_inference::{RegionVarBindings, RegionSnapshot};
-use self::equate::Equate;
-use self::sub::Sub;
-use self::lub::Lub;
-use self::unify::{UnificationTable, InferCtxtMethodsForSimplyUnifiableTypes};
+use self::unify::{ToType, UnificationTable};
 use self::error_reporting::ErrorReporting;
 
 pub mod bivariate;
@@ -61,9 +60,7 @@ pub mod type_variable;
 pub mod unify;
 
 pub type Bound<T> = Option<T>;
-
-pub type cres<'tcx, T> = Result<T,ty::type_err<'tcx>>; // "combine result"
-pub type ures<'tcx> = cres<'tcx, ()>; // "unify result"
+pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
 pub type fres<T> = Result<T, fixup_err>; // "fixup result"
 
 pub struct InferCtxt<'a, 'tcx: 'a> {
@@ -128,6 +125,30 @@ pub enum TypeOrigin {
     EquatePredicate(Span),
 }
 
+impl TypeOrigin {
+    fn as_str(&self) -> &'static str {
+        match self {
+            &TypeOrigin::Misc(_) |
+            &TypeOrigin::RelateSelfType(_) |
+            &TypeOrigin::RelateOutputImplTypes(_) |
+            &TypeOrigin::ExprAssignable(_) => "mismatched types",
+            &TypeOrigin::RelateTraitRefs(_) => "mismatched traits",
+            &TypeOrigin::MethodCompatCheck(_) => "method not compatible with trait",
+            &TypeOrigin::MatchExpressionArm(_, _) => "match arms have incompatible types",
+            &TypeOrigin::IfExpression(_) => "if and else have incompatible types",
+            &TypeOrigin::IfExpressionWithNoElse(_) => "if may be missing an else clause",
+            &TypeOrigin::RangeExpression(_) => "start and end of range have incompatible types",
+            &TypeOrigin::EquatePredicate(_) => "equality predicate not satisfied",
+        }
+    }
+}
+
+impl fmt::Display for TypeOrigin {
+    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(),fmt::Error> {
+        fmt::Display::fmt(self.as_str(), f)
+    }
+}
+
 /// See `error_reporting.rs` for more details
 #[derive(Clone, Debug)]
 pub enum ValuePairs<'tcx> {
@@ -240,7 +261,7 @@ pub enum LateBoundRegionConversionTime {
 ///
 /// See `error_reporting.rs` for more details
 #[derive(Clone, Debug)]
-pub enum RegionVariableOrigin<'tcx> {
+pub enum RegionVariableOrigin {
     // Region variables created for ill-categorized reasons,
     // mostly indicates places in need of refactoring
     MiscVariable(Span),
@@ -255,7 +276,7 @@ pub enum RegionVariableOrigin<'tcx> {
     Autoref(Span),
 
     // Regions created as part of an automatic coercion
-    Coercion(TypeTrace<'tcx>),
+    Coercion(Span),
 
     // Region variables created as the values for early-bound regions
     EarlyBoundRegion(Span, ast::Name),
@@ -269,7 +290,7 @@ pub enum RegionVariableOrigin<'tcx> {
     BoundRegionInCoherence(ast::Name),
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum fixup_err {
     unresolved_int_ty(IntVid),
     unresolved_float_ty(FloatVid),
@@ -318,8 +339,7 @@ pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
         values: Types(expected_found(a_is_expected, a, b))
     };
 
-    let result =
-        cx.commit_if_ok(|| cx.lub(a_is_expected, trace.clone()).tys(a, b));
+    let result = cx.commit_if_ok(|_| cx.lub(a_is_expected, trace.clone()).relate(&a, &b));
     match result {
         Ok(t) => t,
         Err(ref err) => {
@@ -334,29 +354,28 @@ pub fn mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
                           origin: TypeOrigin,
                           a: Ty<'tcx>,
                           b: Ty<'tcx>)
-                          -> ures<'tcx>
+                          -> UnitResult<'tcx>
 {
     debug!("mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
-    cx.commit_if_ok(|| {
-        cx.sub_types(a_is_expected, origin, a, b)
-    })
+    cx.sub_types(a_is_expected, origin, a, b)
 }
 
 pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
                               a: Ty<'tcx>,
                               b: Ty<'tcx>)
-                              -> ures<'tcx> {
+                              -> UnitResult<'tcx> {
     debug!("can_mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
     cx.probe(|_| {
         let trace = TypeTrace {
             origin: Misc(codemap::DUMMY_SP),
             values: Types(expected_found(true, a, b))
         };
-        cx.sub(true, trace).tys(a, b).to_ures()
+        cx.sub(true, trace).relate(&a, &b).map(|_| ())
     })
 }
 
-pub fn can_mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> ures<'tcx>
+pub fn can_mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
+                             -> UnitResult<'tcx>
 {
     cx.can_equate(&a, &b)
 }
@@ -376,11 +395,10 @@ pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
                          origin: TypeOrigin,
                          a: Ty<'tcx>,
                          b: Ty<'tcx>)
-                         -> ures<'tcx>
+                         -> UnitResult<'tcx>
 {
     debug!("mk_eqty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
-    cx.commit_if_ok(
-        || cx.eq_types(a_is_expected, origin, a, b))
+    cx.commit_if_ok(|_| cx.eq_types(a_is_expected, origin, a, b))
 }
 
 pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
@@ -388,12 +406,11 @@ pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
                                    origin: TypeOrigin,
                                    a: ty::PolyTraitRef<'tcx>,
                                    b: ty::PolyTraitRef<'tcx>)
-                                   -> ures<'tcx>
+                                   -> UnitResult<'tcx>
 {
     debug!("mk_sub_trait_refs({} <: {})",
            a.repr(cx.tcx), b.repr(cx.tcx));
-    cx.commit_if_ok(
-        || cx.sub_poly_trait_refs(a_is_expected, origin, a.clone(), b.clone()))
+    cx.commit_if_ok(|_| cx.sub_poly_trait_refs(a_is_expected, origin, a.clone(), b.clone()))
 }
 
 fn expected_found<T>(a_is_expected: bool,
@@ -408,57 +425,6 @@ fn expected_found<T>(a_is_expected: bool,
     }
 }
 
-trait then<'tcx> {
-    fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where
-        T: Clone,
-        F: FnOnce() -> Result<T, ty::type_err<'tcx>>;
-}
-
-impl<'tcx> then<'tcx> for ures<'tcx> {
-    fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where
-        T: Clone,
-        F: FnOnce() -> Result<T, ty::type_err<'tcx>>,
-    {
-        self.and_then(move |_| f())
-    }
-}
-
-trait ToUres<'tcx> {
-    fn to_ures(&self) -> ures<'tcx>;
-}
-
-impl<'tcx, T> ToUres<'tcx> for cres<'tcx, T> {
-    fn to_ures(&self) -> ures<'tcx> {
-        match *self {
-          Ok(ref _v) => Ok(()),
-          Err(ref e) => Err((*e))
-        }
-    }
-}
-
-trait CresCompare<'tcx, T> {
-    fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where
-        F: FnOnce() -> ty::type_err<'tcx>;
-}
-
-impl<'tcx, T:Clone + PartialEq> CresCompare<'tcx, T> for cres<'tcx, T> {
-    fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where
-        F: FnOnce() -> ty::type_err<'tcx>,
-    {
-        (*self).clone().and_then(move |s| {
-            if s == t {
-                (*self).clone()
-            } else {
-                Err(f())
-            }
-        })
-    }
-}
-
-pub fn uok<'tcx>() -> ures<'tcx> {
-    Ok(())
-}
-
 #[must_use = "once you start a snapshot, you should always consume it"]
 pub struct CombinedSnapshot {
     type_snapshot: type_variable::Snapshot,
@@ -487,41 +453,56 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         use middle::ty::UnconstrainedNumeric::{Neither, UnconstrainedInt, UnconstrainedFloat};
         match ty.sty {
             ty::ty_infer(ty::IntVar(vid)) => {
-                match self.int_unification_table.borrow_mut().get(self.tcx, vid).value {
-                    None => UnconstrainedInt,
-                    _ => Neither,
+                if self.int_unification_table.borrow_mut().has_value(vid) {
+                    Neither
+                } else {
+                    UnconstrainedInt
                 }
             },
             ty::ty_infer(ty::FloatVar(vid)) => {
-                match self.float_unification_table.borrow_mut().get(self.tcx, vid).value {
-                    None => return UnconstrainedFloat,
-                    _ => Neither,
+                if self.float_unification_table.borrow_mut().has_value(vid) {
+                    Neither
+                } else {
+                    UnconstrainedFloat
                 }
             },
             _ => Neither,
         }
     }
 
-    pub fn combine_fields<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
-                              -> CombineFields<'b, 'tcx> {
+    fn combine_fields(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
+                      -> CombineFields<'a, 'tcx> {
         CombineFields {infcx: self,
                        a_is_expected: a_is_expected,
                        trace: trace}
     }
 
-    pub fn equate<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
-                      -> Equate<'b, 'tcx> {
-        Equate(self.combine_fields(a_is_expected, trace))
+    // public so that it can be used from the rustc_driver unit tests
+    pub fn equate(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
+              -> equate::Equate<'a, 'tcx>
+    {
+        self.combine_fields(a_is_expected, trace).equate()
+    }
+
+    // public so that it can be used from the rustc_driver unit tests
+    pub fn sub(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
+               -> sub::Sub<'a, 'tcx>
+    {
+        self.combine_fields(a_is_expected, trace).sub()
     }
 
-    pub fn sub<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
-                   -> Sub<'b, 'tcx> {
-        Sub(self.combine_fields(a_is_expected, trace))
+    // public so that it can be used from the rustc_driver unit tests
+    pub fn lub(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
+               -> lub::Lub<'a, 'tcx>
+    {
+        self.combine_fields(a_is_expected, trace).lub()
     }
 
-    pub fn lub<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
-                   -> Lub<'b, 'tcx> {
-        Lub(self.combine_fields(a_is_expected, trace))
+    // public so that it can be used from the rustc_driver unit tests
+    pub fn glb(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
+               -> glb::Glb<'a, 'tcx>
+    {
+        self.combine_fields(a_is_expected, trace).glb()
     }
 
     fn start_snapshot(&self) -> CombinedSnapshot {
@@ -584,11 +565,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         r
     }
 
-    /// Execute `f` and commit the bindings if successful
+    /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`
     pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
-        F: FnOnce() -> Result<T, E>
+        F: FnOnce(&CombinedSnapshot) -> Result<T, E>
     {
-        self.commit_unconditionally(move || self.try(move |_| f()))
+        debug!("commit_if_ok()");
+        let snapshot = self.start_snapshot();
+        let r = f(&snapshot);
+        debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok());
+        match r {
+            Ok(_) => { self.commit_from(snapshot); }
+            Err(_) => { self.rollback_to(snapshot); }
+        }
+        r
     }
 
     /// Execute `f` and commit only the region bindings if successful.
@@ -603,7 +592,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                float_snapshot,
                                region_vars_snapshot } = self.start_snapshot();
 
-        let r = self.try(move |_| f());
+        let r = self.commit_if_ok(|_| f());
 
         // Roll back any non-region bindings - they should be resolved
         // inside `f`, with, e.g. `resolve_type_vars_if_possible`.
@@ -624,25 +613,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         r
     }
 
-    /// Execute `f`, unroll bindings on panic
-    pub fn try<T, E, F>(&self, f: F) -> Result<T, E> where
-        F: FnOnce(&CombinedSnapshot) -> Result<T, E>
-    {
-        debug!("try()");
-        let snapshot = self.start_snapshot();
-        let r = f(&snapshot);
-        debug!("try() -- r.is_ok() = {}", r.is_ok());
-        match r {
-            Ok(_) => {
-                self.commit_from(snapshot);
-            }
-            Err(_) => {
-                self.rollback_to(snapshot);
-            }
-        }
-        r
-    }
-
     /// Execute `f` then unroll any bindings it creates
     pub fn probe<R, F>(&self, f: F) -> R where
         F: FnOnce(&CombinedSnapshot) -> R,
@@ -666,12 +636,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                      origin: TypeOrigin,
                      a: Ty<'tcx>,
                      b: Ty<'tcx>)
-                     -> ures<'tcx>
+                     -> UnitResult<'tcx>
     {
         debug!("sub_types({} <: {})", a.repr(self.tcx), b.repr(self.tcx));
-        self.commit_if_ok(|| {
+        self.commit_if_ok(|_| {
             let trace = TypeTrace::types(origin, a_is_expected, a, b);
-            self.sub(a_is_expected, trace).tys(a, b).to_ures()
+            self.sub(a_is_expected, trace).relate(&a, &b).map(|_| ())
         })
     }
 
@@ -680,11 +650,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     origin: TypeOrigin,
                     a: Ty<'tcx>,
                     b: Ty<'tcx>)
-                    -> ures<'tcx>
+                    -> UnitResult<'tcx>
     {
-        self.commit_if_ok(|| {
+        self.commit_if_ok(|_| {
             let trace = TypeTrace::types(origin, a_is_expected, a, b);
-            self.equate(a_is_expected, trace).tys(a, b).to_ures()
+            self.equate(a_is_expected, trace).relate(&a, &b).map(|_| ())
         })
     }
 
@@ -693,17 +663,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                           origin: TypeOrigin,
                           a: Rc<ty::TraitRef<'tcx>>,
                           b: Rc<ty::TraitRef<'tcx>>)
-                          -> ures<'tcx>
+                          -> UnitResult<'tcx>
     {
         debug!("sub_trait_refs({} <: {})",
                a.repr(self.tcx),
                b.repr(self.tcx));
-        self.commit_if_ok(|| {
+        self.commit_if_ok(|_| {
             let trace = TypeTrace {
                 origin: origin,
                 values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
             };
-            self.sub(a_is_expected, trace).trait_refs(&*a, &*b).to_ures()
+            self.sub(a_is_expected, trace).relate(&*a, &*b).map(|_| ())
         })
     }
 
@@ -712,20 +682,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                origin: TypeOrigin,
                                a: ty::PolyTraitRef<'tcx>,
                                b: ty::PolyTraitRef<'tcx>)
-                               -> ures<'tcx>
+                               -> UnitResult<'tcx>
     {
         debug!("sub_poly_trait_refs({} <: {})",
                a.repr(self.tcx),
                b.repr(self.tcx));
-        self.commit_if_ok(|| {
+        self.commit_if_ok(|_| {
             let trace = TypeTrace {
                 origin: origin,
                 values: PolyTraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
             };
-            self.sub(a_is_expected, trace).binders(&a, &b).to_ures()
+            self.sub(a_is_expected, trace).relate(&a, &b).map(|_| ())
         })
     }
 
+    pub fn construct_skolemized_subst(&self,
+                                      generics: &ty::Generics<'tcx>,
+                                      snapshot: &CombinedSnapshot)
+                                      -> (subst::Substs<'tcx>, SkolemizationMap) {
+        /*! See `higher_ranked::construct_skolemized_subst` */
+
+        higher_ranked::construct_skolemized_substs(self, generics, snapshot)
+    }
+
     pub fn skolemize_late_bound_regions<T>(&self,
                                            value: &ty::Binder<T>,
                                            snapshot: &CombinedSnapshot)
@@ -740,7 +719,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn leak_check(&self,
                       skol_map: &SkolemizationMap,
                       snapshot: &CombinedSnapshot)
-                      -> ures<'tcx>
+                      -> UnitResult<'tcx>
     {
         /*! See `higher_ranked::leak_check` */
 
@@ -765,8 +744,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn equality_predicate(&self,
                               span: Span,
                               predicate: &ty::PolyEquatePredicate<'tcx>)
-                              -> ures<'tcx> {
-        self.try(|snapshot| {
+                              -> UnitResult<'tcx> {
+        self.commit_if_ok(|snapshot| {
             let (ty::EquatePredicate(a, b), skol_map) =
                 self.skolemize_late_bound_regions(predicate, snapshot);
             let origin = EquatePredicate(span);
@@ -778,8 +757,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn region_outlives_predicate(&self,
                                      span: Span,
                                      predicate: &ty::PolyRegionOutlivesPredicate)
-                                     -> ures<'tcx> {
-        self.try(|snapshot| {
+                                     -> UnitResult<'tcx> {
+        self.commit_if_ok(|snapshot| {
             let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
                 self.skolemize_late_bound_regions(predicate, snapshot);
             let origin = RelateRegionParamBound(span);
@@ -802,7 +781,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         ty::mk_var(self.tcx, self.next_ty_var_id(true))
     }
 
-    pub fn next_ty_vars(&self, n: uint) -> Vec<Ty<'tcx>> {
+    pub fn next_ty_vars(&self, n: usize) -> Vec<Ty<'tcx>> {
         (0..n).map(|_i| self.next_ty_var()).collect()
     }
 
@@ -818,7 +797,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             .new_key(None)
     }
 
-    pub fn next_region_var(&self, origin: RegionVariableOrigin<'tcx>) -> ty::Region {
+    pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
         ty::ReInfer(ty::ReVar(self.region_vars.new_region_var(origin)))
     }
 
@@ -914,12 +893,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             }
 
             ty::ty_infer(ty::IntVar(v)) => {
-                self.probe_var(v)
+                self.int_unification_table
+                    .borrow_mut()
+                    .probe(v)
+                    .map(|v| v.to_type(self.tcx))
                     .unwrap_or(typ)
             }
 
             ty::ty_infer(ty::FloatVar(v)) => {
-                self.probe_var(v)
+                self.float_unification_table
+                    .borrow_mut()
+                    .probe(v)
+                    .map(|v| v.to_type(self.tcx))
                     .unwrap_or(typ)
             }
 
@@ -999,7 +984,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
                 self.tcx.sess.span_err(sp, &format!("{}{}",
                     mk_msg(resolved_expected.map(|t| self.ty_to_string(t)), actual_ty),
-                    error_str)[]);
+                    error_str));
 
                 if let Some(err) = err {
                     ty::note_and_explain_type_err(self.tcx, err)
@@ -1070,8 +1055,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         self.region_vars.verify_generic_bound(origin, kind, a, bs);
     }
 
-    pub fn can_equate<T>(&self, a: &T, b: &T) -> ures<'tcx>
-        where T : Combineable<'tcx> + Repr<'tcx>
+    pub fn can_equate<'b,T>(&'b self, a: &T, b: &T) -> UnitResult<'tcx>
+        where T: Relate<'b,'tcx> + Repr<'tcx>
     {
         debug!("can_equate({}, {})", a.repr(self.tcx), b.repr(self.tcx));
         self.probe(|_| {
@@ -1082,9 +1067,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             let e = self.tcx.types.err;
             let trace = TypeTrace { origin: Misc(codemap::DUMMY_SP),
                                     values: Types(expected_found(true, e, e)) };
-            let eq = self.equate(true, trace);
-            Combineable::combine(&eq, a, b)
-        }).to_ures()
+            self.equate(true, trace).relate(a, b)
+        }).map(|_| ())
     }
 }
 
@@ -1270,14 +1254,14 @@ impl<'tcx> Repr<'tcx> for SubregionOrigin<'tcx> {
     }
 }
 
-impl<'tcx> RegionVariableOrigin<'tcx> {
+impl RegionVariableOrigin {
     pub fn span(&self) -> Span {
         match *self {
             MiscVariable(a) => a,
             PatternRegion(a) => a,
             AddrOfRegion(a) => a,
             Autoref(a) => a,
-            Coercion(ref a) => a.span(),
+            Coercion(a) => a,
             EarlyBoundRegion(a, _) => a,
             LateBoundRegion(a, _, _) => a,
             BoundRegionInCoherence(_) => codemap::DUMMY_SP,
@@ -1286,7 +1270,7 @@ impl<'tcx> RegionVariableOrigin<'tcx> {
     }
 }
 
-impl<'tcx> Repr<'tcx> for RegionVariableOrigin<'tcx> {
+impl<'tcx> Repr<'tcx> for RegionVariableOrigin {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         match *self {
             MiscVariable(a) => {
@@ -1299,7 +1283,7 @@ impl<'tcx> Repr<'tcx> for RegionVariableOrigin<'tcx> {
                 format!("AddrOfRegion({})", a.repr(tcx))
             }
             Autoref(a) => format!("Autoref({})", a.repr(tcx)),
-            Coercion(ref a) => format!("Coercion({})", a.repr(tcx)),
+            Coercion(a) => format!("Coercion({})", a.repr(tcx)),
             EarlyBoundRegion(a, b) => {
                 format!("EarlyBoundRegion({},{})", a.repr(tcx), b.repr(tcx))
             }
index a009e0a8234b990008f7ca2304cf8400ac84d51c..e44211da4a7bb4cafc94ea5c93cecfe3d55f54f1 100644 (file)
@@ -249,114 +249,61 @@ there is a reference created whose lifetime does not enclose
 the borrow expression, we must issue sufficient restrictions to ensure
 that the pointee remains valid.
 
-## Adding closures
-
-The other significant complication to the region hierarchy is
-closures. I will describe here how closures should work, though some
-of the work to implement this model is ongoing at the time of this
-writing.
-
-The body of closures are type-checked along with the function that
-creates them. However, unlike other expressions that appear within the
-function body, it is not entirely obvious when a closure body executes
-with respect to the other expressions. This is because the closure
-body will execute whenever the closure is called; however, we can
-never know precisely when the closure will be called, especially
-without some sort of alias analysis.
-
-However, we can place some sort of limits on when the closure
-executes.  In particular, the type of every closure `fn:'r K` includes
-a region bound `'r`. This bound indicates the maximum lifetime of that
-closure; once we exit that region, the closure cannot be called
-anymore. Therefore, we say that the lifetime of the closure body is a
-sublifetime of the closure bound, but the closure body itself is unordered
-with respect to other parts of the code.
-
-For example, consider the following fragment of code:
-
-    'a: {
-         let closure: fn:'a() = || 'b: {
-             'c: ...
-         };
-         'd: ...
-    }
-
-Here we have four lifetimes, `'a`, `'b`, `'c`, and `'d`. The closure
-`closure` is bounded by the lifetime `'a`. The lifetime `'b` is the
-lifetime of the closure body, and `'c` is some statement within the
-closure body. Finally, `'d` is a statement within the outer block that
-created the closure.
-
-We can say that the closure body `'b` is a sublifetime of `'a` due to
-the closure bound. By the usual lexical scoping conventions, the
-statement `'c` is clearly a sublifetime of `'b`, and `'d` is a
-sublifetime of `'d`. However, there is no ordering between `'c` and
-`'d` per se (this kind of ordering between statements is actually only
-an issue for dataflow; passes like the borrow checker must assume that
-closures could execute at any time from the moment they are created
-until they go out of scope).
-
-### Complications due to closure bound inference
-
-There is only one problem with the above model: in general, we do not
-actually *know* the closure bounds during region inference! In fact,
-closure bounds are almost always region variables! This is very tricky
-because the inference system implicitly assumes that we can do things
-like compute the LUB of two scoped lifetimes without needing to know
-the values of any variables.
-
-Here is an example to illustrate the problem:
-
-    fn identify<T>(x: T) -> T { x }
-
-    fn foo() { // 'foo is the function body
-      'a: {
-           let closure = identity(|| 'b: {
-               'c: ...
-           });
-           'd: closure();
-      }
-      'e: ...;
-    }
-
-In this example, the closure bound is not explicit. At compile time,
-we will create a region variable (let's call it `V0`) to represent the
-closure bound.
-
-The primary difficulty arises during the constraint propagation phase.
-Imagine there is some variable with incoming edges from `'c` and `'d`.
-This means that the value of the variable must be `LUB('c,
-'d)`. However, without knowing what the closure bound `V0` is, we
-can't compute the LUB of `'c` and `'d`! Any we don't know the closure
-bound until inference is done.
-
-The solution is to rely on the fixed point nature of inference.
-Basically, when we must compute `LUB('c, 'd)`, we just use the current
-value for `V0` as the closure's bound. If `V0`'s binding should
-change, then we will do another round of inference, and the result of
-`LUB('c, 'd)` will change.
-
-One minor implication of this is that the graph does not in fact track
-the full set of dependencies between edges. We cannot easily know
-whether the result of a LUB computation will change, since there may
-be indirect dependencies on other variables that are not reflected on
-the graph. Therefore, we must *always* iterate over all edges when
-doing the fixed point calculation, not just those adjacent to nodes
-whose values have changed.
-
-Were it not for this requirement, we could in fact avoid fixed-point
-iteration altogether. In that universe, we could instead first
-identify and remove strongly connected components (SCC) in the graph.
-Note that such components must consist solely of region variables; all
-of these variables can effectively be unified into a single variable.
-Once SCCs are removed, we are left with a DAG.  At this point, we
-could walk the DAG in topological order once to compute the expanding
-nodes, and again in reverse topological order to compute the
-contracting nodes. However, as I said, this does not work given the
-current treatment of closure bounds, but perhaps in the future we can
-address this problem somehow and make region inference somewhat more
-efficient. Note that this is solely a matter of performance, not
-expressiveness.
+## Modeling closures
+
+Integrating closures properly into the model is a bit of
+work-in-progress. In an ideal world, we would model closures as
+closely as possible after their desugared equivalents. That is, a
+closure type would be modeled as a struct, and the region hierarchy of
+different closure bodies would be completely distinct from all other
+fns. We are generally moving in that direction but there are
+complications in terms of the implementation.
+
+In practice what we currently do is somewhat different. The basis for
+the current approach is the observation that the only time that
+regions from distinct fn bodies interact with one another is through
+an upvar or the type of a fn parameter (since closures live in the fn
+body namespace, they can in fact have fn parameters whose types
+include regions from the surrounding fn body). For these cases, there
+are separate mechanisms which ensure that the regions that appear in
+upvars/parameters outlive the dynamic extent of each call to the
+closure:
+
+1. Types must outlive the region of any expression where they are used.
+   For a closure type `C` to outlive a region `'r`, that implies that the
+   types of all its upvars must outlive `'r`.
+2. Parameters must outlive the region of any fn that they are passed to.
+
+Therefore, we can -- sort of -- assume that any region from an
+enclosing fns is larger than any region from one of its enclosed
+fn. And that is precisely what we do: when building the region
+hierarchy, each region lives in its own distinct subtree, but if we
+are asked to compute the `LUB(r1, r2)` of two regions, and those
+regions are in disjoint subtrees, we compare the lexical nesting of
+the two regions.
+
+*Ideas for improving the situation:* (FIXME #3696) The correctness
+argument here is subtle and a bit hand-wavy. The ideal, as stated
+earlier, would be to model things in such a way that it corresponds
+more closely to the desugared code. The best approach for doing this
+is a bit unclear: it may in fact be possible to *actually* desugar
+before we start, but I don't think so. The main option that I've been
+thinking through is imposing a "view shift" as we enter the fn body,
+so that regions appearing in the types of fn parameters and upvars are
+translated from being regions in the outer fn into free region
+parameters, just as they would be if we applied the desugaring. The
+challenge here is that type inference may not have fully run, so the
+types may not be fully known: we could probably do this translation
+lazilly, as type variables are instantiated. We would also have to
+apply a kind of inverse translation to the return value. This would be
+a good idea anyway, as right now it is possible for free regions
+instantiated within the closure to leak into the parent: this
+currently leads to type errors, since those regions cannot outlive any
+expressions within the parent hierarchy. Much like the current
+handling of closures, there are no known cases where this leads to a
+type-checking accepting incorrect code (though it sometimes rejects
+what might be considered correct code; see rust-lang/rust#22557), but
+it still doesn't feel like the right approach.
 
 ### Skolemization
 
index 67875ae225224e030918f037980a9a72cac7e56a..1fcbf80c904e0d7175c6cd69341529d0aa122f3a 100644 (file)
@@ -28,8 +28,10 @@ use util::ppaux::Repr;
 
 use std::borrow::Cow;
 use std::collections::hash_map::Entry::Vacant;
-use std::old_io::{self, File};
 use std::env;
+use std::fs::File;
+use std::io;
+use std::io::prelude::*;
 use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
 use syntax::ast;
 
@@ -67,13 +69,13 @@ pub fn maybe_print_constraints_for<'a, 'tcx>(region_vars: &RegionVarBindings<'a,
         return;
     }
 
-    let requested_output = env::var("RUST_REGION_GRAPH").ok();
+    let requested_output = env::var("RUST_REGION_GRAPH");
     debug!("requested_output: {:?} requested_node: {:?}",
            requested_output, requested_node);
 
     let output_path = {
         let output_template = match requested_output {
-            Some(ref s) if &**s == "help" => {
+            Ok(ref s) if &**s == "help" => {
                 static PRINTED_YET: AtomicBool = ATOMIC_BOOL_INIT;
                 if !PRINTED_YET.load(Ordering::SeqCst) {
                     print_help_message();
@@ -82,15 +84,15 @@ pub fn maybe_print_constraints_for<'a, 'tcx>(region_vars: &RegionVarBindings<'a,
                 return;
             }
 
-            Some(other_path) => other_path,
-            None => "/tmp/constraints.node%.dot".to_string(),
+            Ok(other_path) => other_path,
+            Err(_) => "/tmp/constraints.node%.dot".to_string(),
         };
 
         if output_template.len() == 0 {
             tcx.sess.bug("empty string provided as RUST_REGION_GRAPH");
         }
 
-        if output_template.contains_char('%') {
+        if output_template.contains('%') {
             let mut new_str = String::new();
             for c in output_template.chars() {
                 if c == '%' {
@@ -119,7 +121,7 @@ struct ConstraintGraph<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
     graph_name: String,
     map: &'a FnvHashMap<Constraint, SubregionOrigin<'tcx>>,
-    node_ids: FnvHashMap<Node, uint>,
+    node_ids: FnvHashMap<Node, usize>,
 }
 
 #[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)]
@@ -169,7 +171,7 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
 
 impl<'a, 'tcx> dot::Labeller<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> {
     fn graph_id(&self) -> dot::Id {
-        dot::Id::new(&*self.graph_name).ok().unwrap()
+        dot::Id::new(&*self.graph_name).unwrap()
     }
     fn node_id(&self, n: &Node) -> dot::Id {
         let node_id = match self.node_ids.get(n) {
@@ -256,10 +258,11 @@ pub type ConstraintMap<'tcx> = FnvHashMap<Constraint, SubregionOrigin<'tcx>>;
 
 fn dump_region_constraints_to<'a, 'tcx:'a >(tcx: &'a ty::ctxt<'tcx>,
                                             map: &ConstraintMap<'tcx>,
-                                            path: &str) -> old_io::IoResult<()> {
+                                            path: &str) -> io::Result<()> {
     debug!("dump_region_constraints map (len: {}) path: {}", map.len(), path);
     let g = ConstraintGraph::new(tcx, format!("region_constraints"), map);
-    let mut f = File::create(&Path::new(path));
     debug!("dump_region_constraints calling render");
-    dot::render(&g, &mut f)
+    let mut v = Vec::new();
+    dot::render(&g, &mut v).unwrap();
+    File::create(path).and_then(|mut f| f.write_all(&v))
 }
index b4fd34f206fa728d258a40241a13fafa32a84a80..d41fdc5f09acd4a03a8959ef94524f84a8dda44c 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! See doc.rs
+//! See README.md
 
 pub use self::Constraint::*;
 pub use self::Verify::*;
@@ -18,7 +18,6 @@ pub use self::RegionResolutionError::*;
 pub use self::VarValue::*;
 use self::Classification::*;
 
-use super::cres;
 use super::{RegionVariableOrigin, SubregionOrigin, TypeTrace, MiscVariable};
 
 use middle::region;
@@ -26,6 +25,7 @@ use middle::ty::{self, Ty};
 use middle::ty::{BoundRegion, FreeRegion, Region, RegionVid};
 use middle::ty::{ReEmpty, ReStatic, ReInfer, ReFree, ReEarlyBound};
 use middle::ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh};
+use middle::ty_relate::RelateResult;
 use middle::graph;
 use middle::graph::{Direction, NodeIndex};
 use util::common::indenter;
@@ -74,24 +74,24 @@ pub enum GenericKind<'tcx> {
     Projection(ty::ProjectionTy<'tcx>),
 }
 
-#[derive(Copy, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct TwoRegions {
     a: Region,
     b: Region,
 }
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum UndoLogEntry {
     OpenSnapshot,
     CommitedSnapshot,
     AddVar(RegionVid),
     AddConstraint(Constraint),
-    AddVerify(uint),
+    AddVerify(usize),
     AddGiven(ty::FreeRegion, ty::RegionVid),
     AddCombination(CombineMapType, TwoRegions)
 }
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum CombineMapType {
     Lub, Glb
 }
@@ -115,7 +115,7 @@ pub enum RegionResolutionError<'tcx> {
     /// Could not infer a value for `v` because `sub_r <= v` (due to
     /// `sub_origin`) but `v <= sup_r` (due to `sup_origin`) and
     /// `sub_r <= sup_r` does not hold.
-    SubSupConflict(RegionVariableOrigin<'tcx>,
+    SubSupConflict(RegionVariableOrigin,
                    SubregionOrigin<'tcx>, Region,
                    SubregionOrigin<'tcx>, Region),
 
@@ -124,7 +124,7 @@ pub enum RegionResolutionError<'tcx> {
     /// Could not infer a value for `v` because `v <= r1` (due to
     /// `origin1`) and `v <= r2` (due to `origin2`) and
     /// `r1` and `r2` have no intersection.
-    SupSupConflict(RegionVariableOrigin<'tcx>,
+    SupSupConflict(RegionVariableOrigin,
                    SubregionOrigin<'tcx>, Region,
                    SubregionOrigin<'tcx>, Region),
 
@@ -132,7 +132,7 @@ pub enum RegionResolutionError<'tcx> {
     /// more specific errors message by suggesting to the user where they
     /// should put a lifetime. In those cases we process and put those errors
     /// into `ProcessedErrors` before we do any reporting.
-    ProcessedErrors(Vec<RegionVariableOrigin<'tcx>>,
+    ProcessedErrors(Vec<RegionVariableOrigin>,
                     Vec<(TypeTrace<'tcx>, ty::type_err<'tcx>)>,
                     Vec<SameRegions>),
 }
@@ -168,7 +168,7 @@ pub type CombineMap = FnvHashMap<TwoRegions, RegionVid>;
 
 pub struct RegionVarBindings<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
-    var_origins: RefCell<Vec<RegionVariableOrigin<'tcx>>>,
+    var_origins: RefCell<Vec<RegionVariableOrigin>>,
 
     // Constraints of the form `A <= B` introduced by the region
     // checker.  Here at least one of `A` and `B` must be a region
@@ -224,7 +224,7 @@ pub struct RegionVarBindings<'a, 'tcx: 'a> {
 
 #[derive(Debug)]
 pub struct RegionSnapshot {
-    length: uint,
+    length: usize,
     skolemization_count: u32,
 }
 
@@ -284,7 +284,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                 AddVar(vid) => {
                     let mut var_origins = self.var_origins.borrow_mut();
                     var_origins.pop().unwrap();
-                    assert_eq!(var_origins.len(), vid.index as uint);
+                    assert_eq!(var_origins.len(), vid.index as usize);
                 }
                 AddConstraint(ref constraint) => {
                     self.constraints.borrow_mut().remove(constraint);
@@ -312,11 +312,11 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
     pub fn num_vars(&self) -> u32 {
         let len = self.var_origins.borrow().len();
         // enforce no overflow
-        assert!(len as u32 as uint == len);
+        assert!(len as u32 as usize == len);
         len as u32
     }
 
-    pub fn new_region_var(&self, origin: RegionVariableOrigin<'tcx>) -> RegionVid {
+    pub fn new_region_var(&self, origin: RegionVariableOrigin) -> RegionVid {
         let id = self.num_vars();
         self.var_origins.borrow_mut().push(origin.clone());
         let vid = RegionVid { index: id };
@@ -473,7 +473,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                 origin.span(),
                 &format!("cannot relate bound region: {} <= {}",
                         sub.repr(self.tcx),
-                        sup.repr(self.tcx))[]);
+                        sup.repr(self.tcx)));
           }
           (_, ReStatic) => {
             // all regions are subregions of static, so we can ignore this
@@ -557,7 +557,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         match *self.values.borrow() {
             None => {
                 self.tcx.sess.span_bug(
-                    (*self.var_origins.borrow())[rid.index as uint].span(),
+                    (*self.var_origins.borrow())[rid.index as usize].span(),
                     "attempt to resolve region variable before values have \
                      been computed!")
             }
@@ -629,7 +629,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         let mut result_set = vec!(r0);
         let mut result_index = 0;
         while result_index < result_set.len() {
-            // nb: can't use uint::range() here because result_set grows
+            // nb: can't use usize::range() here because result_set grows
             let r = result_set[result_index];
             debug!("result_index={}, r={:?}", result_index, r);
 
@@ -733,7 +733,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
             self.tcx.sess.bug(
                 &format!("cannot relate bound region: LUB({}, {})",
                         a.repr(self.tcx),
-                        b.repr(self.tcx))[]);
+                        b.repr(self.tcx)));
           }
 
           (ReStatic, _) | (_, ReStatic) => {
@@ -746,11 +746,11 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
 
           (ReInfer(ReVar(v_id)), _) | (_, ReInfer(ReVar(v_id))) => {
             self.tcx.sess.span_bug(
-                (*self.var_origins.borrow())[v_id.index as uint].span(),
+                (*self.var_origins.borrow())[v_id.index as usize].span(),
                 &format!("lub_concrete_regions invoked with \
                          non-concrete regions: {:?}, {:?}",
                         a,
-                        b)[]);
+                        b));
           }
 
           (ReFree(ref fr), ReScope(s_id)) |
@@ -760,15 +760,17 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
             // at least as big as the block fr.scope_id".  So, we can
             // reasonably compare free regions and scopes:
             let fr_scope = fr.scope.to_code_extent();
-            match self.tcx.region_maps.nearest_common_ancestor(fr_scope, s_id) {
+            let r_id = self.tcx.region_maps.nearest_common_ancestor(fr_scope, s_id);
+
+            if r_id == fr_scope {
               // if the free region's scope `fr.scope_id` is bigger than
               // the scope region `s_id`, then the LUB is the free
               // region itself:
-              Some(r_id) if r_id == fr_scope => f,
-
+              f
+            } else {
               // otherwise, we don't know what the free region is,
               // so we must conservatively say the LUB is static:
-              _ => ReStatic
+              ReStatic
             }
           }
 
@@ -776,10 +778,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
             // The region corresponding to an outer block is a
             // subtype of the region corresponding to an inner
             // block.
-            match self.tcx.region_maps.nearest_common_ancestor(a_id, b_id) {
-              Some(r_id) => ReScope(r_id),
-              _ => ReStatic
-            }
+            ReScope(self.tcx.region_maps.nearest_common_ancestor(a_id, b_id))
           }
 
           (ReFree(ref a_fr), ReFree(ref b_fr)) => {
@@ -799,7 +798,8 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
     /// regions are given as argument, in any order, a consistent result is returned.
     fn lub_free_regions(&self,
                         a: &FreeRegion,
-                        b: &FreeRegion) -> ty::Region
+                        b: &FreeRegion)
+                        -> ty::Region
     {
         return match a.cmp(b) {
             Less => helper(self, a, b),
@@ -824,7 +824,8 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
     fn glb_concrete_regions(&self,
                             a: Region,
                             b: Region)
-                         -> cres<'tcx, Region> {
+                            -> RelateResult<'tcx, Region>
+    {
         debug!("glb_concrete_regions({:?}, {:?})", a, b);
         match (a, b) {
             (ReLateBound(..), _) |
@@ -834,7 +835,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
               self.tcx.sess.bug(
                   &format!("cannot relate bound region: GLB({}, {})",
                           a.repr(self.tcx),
-                          b.repr(self.tcx))[]);
+                          b.repr(self.tcx)));
             }
 
             (ReStatic, r) | (r, ReStatic) => {
@@ -850,11 +851,11 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
             (ReInfer(ReVar(v_id)), _) |
             (_, ReInfer(ReVar(v_id))) => {
                 self.tcx.sess.span_bug(
-                    (*self.var_origins.borrow())[v_id.index as uint].span(),
+                    (*self.var_origins.borrow())[v_id.index as usize].span(),
                     &format!("glb_concrete_regions invoked with \
                              non-concrete regions: {:?}, {:?}",
                             a,
-                            b)[]);
+                            b));
             }
 
             (ReFree(ref fr), ReScope(s_id)) |
@@ -866,9 +867,10 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                 // is the scope `s_id`.  Otherwise, as we do not know
                 // big the free region is precisely, the GLB is undefined.
                 let fr_scope = fr.scope.to_code_extent();
-                match self.tcx.region_maps.nearest_common_ancestor(fr_scope, s_id) {
-                    Some(r_id) if r_id == fr_scope => Ok(s),
-                    _ => Err(ty::terr_regions_no_overlap(b, a))
+                if self.tcx.region_maps.nearest_common_ancestor(fr_scope, s_id) == fr_scope {
+                    Ok(s)
+                } else {
+                    Err(ty::terr_regions_no_overlap(b, a))
                 }
             }
 
@@ -898,7 +900,8 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
     /// returned.
     fn glb_free_regions(&self,
                         a: &FreeRegion,
-                        b: &FreeRegion) -> cres<'tcx, ty::Region>
+                        b: &FreeRegion)
+                        -> RelateResult<'tcx, ty::Region>
     {
         return match a.cmp(b) {
             Less => helper(self, a, b),
@@ -908,7 +911,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
 
         fn helper<'a, 'tcx>(this: &RegionVarBindings<'a, 'tcx>,
                             a: &FreeRegion,
-                            b: &FreeRegion) -> cres<'tcx, ty::Region>
+                            b: &FreeRegion) -> RelateResult<'tcx, ty::Region>
         {
             if this.tcx.region_maps.sub_free_region(*a, *b) {
                 Ok(ty::ReFree(*a))
@@ -926,7 +929,8 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                         region_a: ty::Region,
                         region_b: ty::Region,
                         scope_a: region::CodeExtent,
-                        scope_b: region::CodeExtent) -> cres<'tcx, Region>
+                        scope_b: region::CodeExtent)
+                        -> RelateResult<'tcx, Region>
     {
         // We want to generate the intersection of two
         // scopes or two free regions.  So, if one of
@@ -934,20 +938,23 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         // it. Otherwise fail.
         debug!("intersect_scopes(scope_a={:?}, scope_b={:?}, region_a={:?}, region_b={:?})",
                scope_a, scope_b, region_a, region_b);
-        match self.tcx.region_maps.nearest_common_ancestor(scope_a, scope_b) {
-            Some(r_id) if scope_a == r_id => Ok(ReScope(scope_b)),
-            Some(r_id) if scope_b == r_id => Ok(ReScope(scope_a)),
-            _ => Err(ty::terr_regions_no_overlap(region_a, region_b))
+        let r_id = self.tcx.region_maps.nearest_common_ancestor(scope_a, scope_b);
+        if r_id == scope_a {
+            Ok(ReScope(scope_b))
+        } else if r_id == scope_b {
+            Ok(ReScope(scope_a))
+        } else {
+            Err(ty::terr_regions_no_overlap(region_a, region_b))
         }
     }
 }
 
 // ______________________________________________________________________
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 enum Classification { Expanding, Contracting }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum VarValue { NoValue, Value(Region), ErrorValue }
 
 struct VarData {
@@ -984,7 +991,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
     }
 
     fn construct_var_data(&self) -> Vec<VarData> {
-        (0..self.num_vars() as uint).map(|_| {
+        (0..self.num_vars() as usize).map(|_| {
             VarData {
                 // All nodes are initially classified as contracting; during
                 // the expansion phase, we will shift the classification for
@@ -1013,14 +1020,14 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                                    .repr(self.tcx));
             match *constraint {
               ConstrainRegSubVar(a_region, b_vid) => {
-                let b_data = &mut var_data[b_vid.index as uint];
+                let b_data = &mut var_data[b_vid.index as usize];
                 self.expand_node(a_region, b_vid, b_data)
               }
               ConstrainVarSubVar(a_vid, b_vid) => {
-                match var_data[a_vid.index as uint].value {
+                match var_data[a_vid.index as usize].value {
                   NoValue | ErrorValue => false,
                   Value(a_region) => {
-                    let b_node = &mut var_data[b_vid.index as uint];
+                    let b_node = &mut var_data[b_vid.index as usize];
                     self.expand_node(a_region, b_vid, b_node)
                   }
                 }
@@ -1101,16 +1108,16 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                 false
               }
               ConstrainVarSubVar(a_vid, b_vid) => {
-                match var_data[b_vid.index as uint].value {
+                match var_data[b_vid.index as usize].value {
                   NoValue | ErrorValue => false,
                   Value(b_region) => {
-                    let a_data = &mut var_data[a_vid.index as uint];
+                    let a_data = &mut var_data[a_vid.index as usize];
                     self.contract_node(a_vid, a_data, b_region)
                   }
                 }
               }
               ConstrainVarSubReg(a_vid, b_region) => {
-                let a_data = &mut var_data[a_vid.index as uint];
+                let a_data = &mut var_data[a_vid.index as usize];
                 self.contract_node(a_vid, a_data, b_region)
               }
             }
@@ -1133,18 +1140,12 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                 true // changed
             }
 
-            ErrorValue => {
-                false // no change
-            }
+            ErrorValue => false, // no change
 
             Value(a_region) => {
                 match a_data.classification {
-                    Expanding => {
-                        check_node(self, a_vid, a_data, a_region, b_region)
-                    }
-                    Contracting => {
-                        adjust_node(self, a_vid, a_data, a_region, b_region)
-                    }
+                    Expanding => check_node(self, a_vid, a_data, a_region, b_region),
+                    Contracting => adjust_node(self, a_vid, a_data, a_region, b_region),
                 }
             }
         };
@@ -1154,7 +1155,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                       a_data: &mut VarData,
                       a_region: Region,
                       b_region: Region)
-                   -> bool {
+                      -> bool {
             if !this.is_subregion_of(a_region, b_region) {
                 debug!("Setting {:?} to ErrorValue: {} not subregion of {}",
                        a_vid,
@@ -1170,7 +1171,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                        a_data: &mut VarData,
                        a_region: Region,
                        b_region: Region)
-                    -> bool {
+                       -> bool {
             match this.glb_concrete_regions(a_region, b_region) {
                 Ok(glb) => {
                     if glb == a_region {
@@ -1256,11 +1257,11 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         // idea is to report errors that derive from independent
         // regions of the graph, but not those that derive from
         // overlapping locations.
-        let mut dup_vec: Vec<_> = repeat(u32::MAX).take(self.num_vars() as uint).collect();
+        let mut dup_vec: Vec<_> = repeat(u32::MAX).take(self.num_vars() as usize).collect();
 
         let mut opt_graph = None;
 
-        for idx in 0..self.num_vars() as uint {
+        for idx in 0..self.num_vars() as usize {
             match var_data[idx].value {
                 Value(_) => {
                     /* Inference successful */
@@ -1317,7 +1318,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
             }
         }
 
-        (0..self.num_vars() as uint).map(|idx| var_data[idx].value).collect()
+        (0..self.num_vars() as usize).map(|idx| var_data[idx].value).collect()
     }
 
     fn construct_graph(&self) -> RegionGraph {
@@ -1326,7 +1327,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         let constraints = self.constraints.borrow();
         let num_edges = constraints.len();
 
-        let mut graph = graph::Graph::with_capacity(num_vars as uint + 1,
+        let mut graph = graph::Graph::with_capacity(num_vars as usize + 1,
                                                     num_edges);
 
         for _ in 0..num_vars {
@@ -1337,17 +1338,17 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         for (constraint, _) in &*constraints {
             match *constraint {
                 ConstrainVarSubVar(a_id, b_id) => {
-                    graph.add_edge(NodeIndex(a_id.index as uint),
-                                   NodeIndex(b_id.index as uint),
+                    graph.add_edge(NodeIndex(a_id.index as usize),
+                                   NodeIndex(b_id.index as usize),
                                    *constraint);
                 }
                 ConstrainRegSubVar(_, b_id) => {
                     graph.add_edge(dummy_idx,
-                                   NodeIndex(b_id.index as uint),
+                                   NodeIndex(b_id.index as usize),
                                    *constraint);
                 }
                 ConstrainVarSubReg(a_id, _) => {
-                    graph.add_edge(NodeIndex(a_id.index as uint),
+                    graph.add_edge(NodeIndex(a_id.index as usize),
                                    dummy_idx,
                                    *constraint);
                 }
@@ -1401,7 +1402,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                     debug!("pushing SubSupConflict sub: {:?} sup: {:?}",
                            lower_bound.region, upper_bound.region);
                     errors.push(SubSupConflict(
-                        (*self.var_origins.borrow())[node_idx.index as uint].clone(),
+                        (*self.var_origins.borrow())[node_idx.index as usize].clone(),
                         lower_bound.origin.clone(),
                         lower_bound.region,
                         upper_bound.origin.clone(),
@@ -1412,12 +1413,12 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         }
 
         self.tcx.sess.span_bug(
-            (*self.var_origins.borrow())[node_idx.index as uint].span(),
+            (*self.var_origins.borrow())[node_idx.index as usize].span(),
             &format!("collect_error_for_expanding_node() could not find error \
                     for var {:?}, lower_bounds={}, upper_bounds={}",
                     node_idx,
                     lower_bounds.repr(self.tcx),
-                    upper_bounds.repr(self.tcx))[]);
+                    upper_bounds.repr(self.tcx)));
     }
 
     fn collect_error_for_contracting_node(
@@ -1445,7 +1446,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                   Ok(_) => {}
                   Err(_) => {
                     errors.push(SupSupConflict(
-                        (*self.var_origins.borrow())[node_idx.index as uint].clone(),
+                        (*self.var_origins.borrow())[node_idx.index as usize].clone(),
                         upper_bound_1.origin.clone(),
                         upper_bound_1.region,
                         upper_bound_2.origin.clone(),
@@ -1457,11 +1458,11 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
         }
 
         self.tcx.sess.span_bug(
-            (*self.var_origins.borrow())[node_idx.index as uint].span(),
+            (*self.var_origins.borrow())[node_idx.index as usize].span(),
             &format!("collect_error_for_contracting_node() could not find error \
                      for var {:?}, upper_bounds={}",
                     node_idx,
-                    upper_bounds.repr(self.tcx))[]);
+                    upper_bounds.repr(self.tcx)));
     }
 
     fn collect_concrete_regions(&self,
@@ -1491,12 +1492,12 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
 
         while !state.stack.is_empty() {
             let node_idx = state.stack.pop().unwrap();
-            let classification = var_data[node_idx.index as uint].classification;
+            let classification = var_data[node_idx.index as usize].classification;
 
             // check whether we've visited this node on some previous walk
-            if dup_vec[node_idx.index as uint] == u32::MAX {
-                dup_vec[node_idx.index as uint] = orig_node_idx.index;
-            } else if dup_vec[node_idx.index as uint] != orig_node_idx.index {
+            if dup_vec[node_idx.index as usize] == u32::MAX {
+                dup_vec[node_idx.index as usize] = orig_node_idx.index;
+            } else if dup_vec[node_idx.index as usize] != orig_node_idx.index {
                 state.dup_found = true;
             }
 
@@ -1524,7 +1525,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                          dir: Direction) {
             debug!("process_edges(source_vid={:?}, dir={:?})", source_vid, dir);
 
-            let source_node_index = NodeIndex(source_vid.index as uint);
+            let source_node_index = NodeIndex(source_vid.index as usize);
             graph.each_adjacent_edge(source_node_index, dir, |_, edge| {
                 match edge.data {
                     ConstrainVarSubVar(from_vid, to_vid) => {
@@ -1539,7 +1540,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                     ConstrainVarSubReg(_, region) => {
                         state.result.push(RegionAndOrigin {
                             region: region,
-                            origin: this.constraints.borrow()[edge.data].clone()
+                            origin: this.constraints.borrow().get(&edge.data).unwrap().clone()
                         });
                     }
                 }
@@ -1609,7 +1610,7 @@ fn normalize(values: &Vec<VarValue>, r: ty::Region) -> ty::Region {
 }
 
 fn lookup(values: &Vec<VarValue>, rid: ty::RegionVid) -> ty::Region {
-    match values[rid.index as uint] {
+    match values[rid.index as usize] {
         Value(r) => r,
         NoValue => ReEmpty, // No constraints, return ty::ReEmpty
         ErrorValue => ReStatic, // Previously reported error.
index 7bb3106b0ba6ccfa3bfce9fccf199aff5c46e1a6..b9025d01068cc9fc76c2cb7eeb011ad5ea807cc6 100644 (file)
@@ -96,7 +96,7 @@ impl<'a, 'tcx> ty_fold::TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
                 ty::ty_infer(_) => {
                     self.infcx.tcx.sess.bug(
                         &format!("Unexpected type in full type resolver: {}",
-                                t.repr(self.infcx.tcx))[]);
+                                t.repr(self.infcx.tcx)));
                 }
                 _ => {
                     ty_fold::super_fold_ty(self, t)
@@ -112,4 +112,3 @@ impl<'a, 'tcx> ty_fold::TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
         }
     }
 }
-
index 33da3092b2a256f8d4c8232f9eb50827603a87c8..31b654a5b3fd3b5fcfba885019ade59349aa69a6 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::combine::*;
-use super::{cres, CresCompare};
+use super::combine::{self, CombineFields};
 use super::higher_ranked::HigherRankedRelations;
-use super::{Subtype};
+use super::Subtype;
 use super::type_variable::{SubtypeOf, SupertypeOf};
 
-use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
 use middle::ty::TyVar;
+use middle::ty_relate::{Relate, RelateResult, TypeRelation};
 use util::ppaux::{Repr};
 
-use syntax::ast::{MutImmutable, MutMutable, Unsafety};
-
-
 /// "Greatest lower bound" (common subtype)
-pub struct Sub<'f, 'tcx: 'f> {
-    fields: CombineFields<'f, 'tcx>
+pub struct Sub<'a, 'tcx: 'a> {
+    fields: CombineFields<'a, 'tcx>
 }
 
-#[allow(non_snake_case)]
-pub fn Sub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Sub<'f, 'tcx> {
-    Sub { fields: cf }
+impl<'a, 'tcx> Sub<'a, 'tcx> {
+    pub fn new(f: CombineFields<'a, 'tcx>) -> Sub<'a, 'tcx> {
+        Sub { fields: f }
+    }
 }
 
-impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
-    fn tag(&self) -> String { "Sub".to_string() }
-    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
+impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Sub<'a, 'tcx> {
+    fn tag(&self) -> &'static str { "Sub" }
+    fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.fields.infcx.tcx }
+    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
 
-    fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
-                         -> cres<'tcx, Ty<'tcx>>
+    fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
+                                               variance: ty::Variance,
+                                               a: &T,
+                                               b: &T)
+                                               -> RelateResult<'tcx, T>
     {
-        match v {
-            ty::Invariant => self.equate().tys(a, b),
-            ty::Covariant => self.tys(a, b),
-            ty::Bivariant => self.bivariate().tys(a, b),
-            ty::Contravariant => Sub(self.fields.switch_expected()).tys(b, a),
+        match variance {
+            ty::Invariant => self.fields.equate().relate(a, b),
+            ty::Covariant => self.relate(a, b),
+            ty::Bivariant => self.fields.bivariate().relate(a, b),
+            ty::Contravariant => self.fields.switch_expected().sub().relate(b, a),
         }
     }
 
-    fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
-                             -> cres<'tcx, ty::Region>
-    {
-        match v {
-            ty::Invariant => self.equate().regions(a, b),
-            ty::Covariant => self.regions(a, b),
-            ty::Bivariant => self.bivariate().regions(a, b),
-            ty::Contravariant => Sub(self.fields.switch_expected()).regions(b, a),
-        }
-    }
+    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+        debug!("{}.tys({}, {})", self.tag(), a.repr(self.tcx()), b.repr(self.tcx()));
 
-    fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
-        debug!("{}.regions({}, {})",
-               self.tag(),
-               a.repr(self.tcx()),
-               b.repr(self.tcx()));
-        self.infcx().region_vars.make_subregion(Subtype(self.trace()), a, b);
-        Ok(a)
-    }
-
-    fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
-        debug!("mts({} <: {})",
-               a.repr(self.tcx()),
-               b.repr(self.tcx()));
-
-        if a.mutbl != b.mutbl {
-            return Err(ty::terr_mutability);
-        }
-
-        match b.mutbl {
-            MutMutable => {
-                // If supertype is mut, subtype must match exactly
-                // (i.e., invariant if mut):
-                try!(self.equate().tys(a.ty, b.ty));
-            }
-            MutImmutable => {
-                // Otherwise we can be covariant:
-                try!(self.tys(a.ty, b.ty));
-            }
-        }
-
-        Ok(*a) // return is meaningless in sub, just return *a
-    }
-
-    fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
-        self.lub().unsafeties(a, b).compare(b, || {
-            ty::terr_unsafety_mismatch(expected_found(self, a, b))
-        })
-    }
-
-    fn builtin_bounds(&self, a: BuiltinBounds, b: BuiltinBounds)
-                      -> cres<'tcx, BuiltinBounds> {
-        // More bounds is a subtype of fewer bounds.
-        //
-        // e.g., fn:Copy() <: fn(), because the former is a function
-        // that only closes over copyable things, but the latter is
-        // any function at all.
-        if a.is_superset(&b) {
-            Ok(a)
-        } else {
-            Err(ty::terr_builtin_bounds(expected_found(self, a, b)))
-        }
-    }
-
-    fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        debug!("{}.tys({}, {})", self.tag(),
-               a.repr(self.tcx()), b.repr(self.tcx()));
         if a == b { return Ok(a); }
 
         let infcx = self.fields.infcx;
@@ -128,8 +65,8 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
             }
             (&ty::ty_infer(TyVar(a_id)), _) => {
                 try!(self.fields
-                       .switch_expected()
-                       .instantiate(b, SupertypeOf, a_id));
+                         .switch_expected()
+                         .instantiate(b, SupertypeOf, a_id));
                 Ok(a)
             }
             (_, &ty::ty_infer(TyVar(b_id))) => {
@@ -142,15 +79,25 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
             }
 
             _ => {
-                super_tys(self, a, b)
+                combine::super_combine_tys(self.fields.infcx, self, a, b)
             }
         }
     }
 
-    fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
-        where T : Combineable<'tcx>
+    fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
+        debug!("{}.regions({}, {})",
+               self.tag(),
+               a.repr(self.tcx()),
+               b.repr(self.tcx()));
+        let origin = Subtype(self.fields.trace.clone());
+        self.fields.infcx.region_vars.make_subregion(origin, a, b);
+        Ok(a)
+    }
+
+    fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
+                  -> RelateResult<'tcx, ty::Binder<T>>
+        where T: Relate<'a,'tcx>
     {
-        self.higher_ranked_sub(a, b)
+        self.fields.higher_ranked_sub(a, b)
     }
 }
-
index a856137af090a706c68461ad0beac834086e1aa5..03612a6c1ae5bc2401e5ddc3ca4b82e1ed0a48f3 100644 (file)
@@ -47,7 +47,7 @@ struct Delegate<'tcx>(PhantomData<&'tcx ()>);
 
 type Relation = (RelationDir, ty::TyVid);
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum RelationDir {
     SubtypeOf, SupertypeOf, EqTo, BiTo
 }
@@ -69,11 +69,11 @@ impl<'tcx> TypeVariableTable<'tcx> {
     }
 
     fn relations<'a>(&'a mut self, a: ty::TyVid) -> &'a mut Vec<Relation> {
-        relations(self.values.get_mut(a.index as uint))
+        relations(self.values.get_mut(a.index as usize))
     }
 
     pub fn var_diverges<'a>(&'a self, vid: ty::TyVid) -> bool {
-        self.values.get(vid.index as uint).diverging
+        self.values.get(vid.index as usize).diverging
     }
 
     /// Records that `a <: b`, `a :> b`, or `a == b`, depending on `dir`.
@@ -97,7 +97,7 @@ impl<'tcx> TypeVariableTable<'tcx> {
         stack: &mut Vec<(Ty<'tcx>, RelationDir, ty::TyVid)>)
     {
         let old_value = {
-            let value_ptr = &mut self.values.get_mut(vid.index as uint).value;
+            let value_ptr = &mut self.values.get_mut(vid.index as usize).value;
             mem::replace(value_ptr, Known(ty))
         };
 
@@ -123,7 +123,7 @@ impl<'tcx> TypeVariableTable<'tcx> {
     }
 
     pub fn probe(&self, vid: ty::TyVid) -> Option<Ty<'tcx>> {
-        match self.values.get(vid.index as uint).value {
+        match self.values.get(vid.index as usize).value {
             Bounded(..) => None,
             Known(t) => Some(t)
         }
@@ -206,12 +206,12 @@ impl<'tcx> sv::SnapshotVecDelegate for Delegate<'tcx> {
                action: UndoEntry) {
         match action {
             SpecifyVar(vid, relations) => {
-                values[vid.index as uint].value = Bounded(relations);
+                values[vid.index as usize].value = Bounded(relations);
             }
 
             Relate(a, b) => {
-                relations(&mut (*values)[a.index as uint]).pop();
-                relations(&mut (*values)[b.index as uint]).pop();
+                relations(&mut (*values)[a.index as usize]).pop();
+                relations(&mut (*values)[b.index as usize]).pop();
             }
         }
     }
index 0675cec6f69b5d61a0dac228d73d24f8c3108cf3..4bbced1d75caf970924f990f25bd9ee2ae7fc336 100644 (file)
@@ -12,11 +12,8 @@ pub use self::VarValue::*;
 
 use std::marker;
 
-use middle::ty::{expected_found, IntVarValue};
+use middle::ty::{IntVarValue};
 use middle::ty::{self, Ty};
-use middle::infer::{uok, ures};
-use middle::infer::InferCtxt;
-use std::cell::RefCell;
 use std::fmt::Debug;
 use std::marker::PhantomData;
 use syntax::ast;
@@ -35,14 +32,9 @@ use util::snapshot_vec as sv;
 pub trait UnifyKey : Clone + Debug + PartialEq {
     type Value : UnifyValue;
 
-    fn index(&self) -> uint;
+    fn index(&self) -> u32;
 
-    fn from_index(u: uint) -> Self;
-
-    // Given an inference context, returns the unification table
-    // appropriate to this key type.
-    fn unification_table<'v>(infcx: &'v InferCtxt)
-                             -> &'v RefCell<UnificationTable<Self>>;
+    fn from_index(u: u32) -> Self;
 
     fn tag(k: Option<Self>) -> &'static str;
 }
@@ -67,7 +59,7 @@ pub trait UnifyValue : Clone + PartialEq + Debug {
 #[derive(PartialEq,Clone,Debug)]
 pub enum VarValue<K:UnifyKey> {
     Redirect(K),
-    Root(K::Value, uint),
+    Root(K::Value, usize),
 }
 
 /// Table of unification keys and their values.
@@ -89,10 +81,10 @@ pub struct Snapshot<K:UnifyKey> {
 pub struct Node<K:UnifyKey> {
     pub key: K,
     pub value: K::Value,
-    pub rank: uint,
+    pub rank: usize,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Delegate<K>(PhantomData<K>);
 
 // We can't use V:LatticeValue, much as I would like to,
@@ -130,21 +122,25 @@ impl<K:UnifyKey> UnificationTable<K> {
 
     pub fn new_key(&mut self, value: K::Value) -> K {
         let index = self.values.push(Root(value, 0));
-        let k = UnifyKey::from_index(index);
+        let k = UnifyKey::from_index(index as u32);
         debug!("{}: created new key: {:?}",
                UnifyKey::tag(None::<K>),
                k);
         k
     }
 
-    /// Find the root node for `vid`. This uses the standard union-find algorithm with path
-    /// compression: http://en.wikipedia.org/wiki/Disjoint-set_data_structure
-    pub fn get(&mut self, tcx: &ty::ctxt, vid: K) -> Node<K> {
-        let index = vid.index();
+    /// Find the root node for `vid`. This uses the standard
+    /// union-find algorithm with path compression:
+    /// <http://en.wikipedia.org/wiki/Disjoint-set_data_structure>.
+    ///
+    /// NB. This is a building-block operation and you would probably
+    /// prefer to call `probe` below.
+    fn get(&mut self, vid: K) -> Node<K> {
+        let index = vid.index() as usize;
         let value = (*self.values.get(index)).clone();
         match value {
             Redirect(redirect) => {
-                let node: Node<K> = self.get(tcx, redirect.clone());
+                let node: Node<K> = self.get(redirect.clone());
                 if node.key != redirect {
                     // Path compression
                     self.values.set(index, Redirect(node.key.clone()));
@@ -158,58 +154,58 @@ impl<K:UnifyKey> UnificationTable<K> {
     }
 
     fn is_root(&self, key: &K) -> bool {
-        match *self.values.get(key.index()) {
+        let index = key.index() as usize;
+        match *self.values.get(index) {
             Redirect(..) => false,
             Root(..) => true,
         }
     }
 
-    /// Sets the value for `vid` to `new_value`. `vid` MUST be a root node! Also, we must be in the
-    /// middle of a snapshot.
-    pub fn set<'tcx>(&mut self,
-                     _tcx: &ty::ctxt<'tcx>,
-                     key: K,
-                     new_value: VarValue<K>)
-    {
+    /// Sets the value for `vid` to `new_value`. `vid` MUST be a root
+    /// node! This is an internal operation used to impl other things.
+    fn set(&mut self, key: K, new_value: VarValue<K>) {
         assert!(self.is_root(&key));
 
         debug!("Updating variable {:?} to {:?}",
                key, new_value);
 
-        self.values.set(key.index(), new_value);
+        let index = key.index() as usize;
+        self.values.set(index, new_value);
     }
 
-    /// Either redirects node_a to node_b or vice versa, depending on the relative rank. Returns
-    /// the new root and rank. You should then update the value of the new root to something
-    /// suitable.
-    pub fn unify<'tcx>(&mut self,
-                       tcx: &ty::ctxt<'tcx>,
-                       node_a: &Node<K>,
-                       node_b: &Node<K>)
-                       -> (K, uint)
-    {
+    /// Either redirects `node_a` to `node_b` or vice versa, depending
+    /// on the relative rank. The value associated with the new root
+    /// will be `new_value`.
+    ///
+    /// NB: This is the "union" operation of "union-find". It is
+    /// really more of a building block. If the values associated with
+    /// your key are non-trivial, you would probably prefer to call
+    /// `unify_var_var` below.
+    fn unify(&mut self, node_a: &Node<K>, node_b: &Node<K>, new_value: K::Value) {
         debug!("unify(node_a(id={:?}, rank={:?}), node_b(id={:?}, rank={:?}))",
                node_a.key,
                node_a.rank,
                node_b.key,
                node_b.rank);
 
-        if node_a.rank > node_b.rank {
+        let (new_root, new_rank) = if node_a.rank > node_b.rank {
             // a has greater rank, so a should become b's parent,
             // i.e., b should redirect to a.
-            self.set(tcx, node_b.key.clone(), Redirect(node_a.key.clone()));
+            self.set(node_b.key.clone(), Redirect(node_a.key.clone()));
             (node_a.key.clone(), node_a.rank)
         } else if node_a.rank < node_b.rank {
             // b has greater rank, so a should redirect to b.
-            self.set(tcx, node_a.key.clone(), Redirect(node_b.key.clone()));
+            self.set(node_a.key.clone(), Redirect(node_b.key.clone()));
             (node_b.key.clone(), node_b.rank)
         } else {
             // If equal, redirect one to the other and increment the
             // other's rank.
             assert_eq!(node_a.rank, node_b.rank);
-            self.set(tcx, node_b.key.clone(), Redirect(node_a.key.clone()));
+            self.set(node_b.key.clone(), Redirect(node_a.key.clone()));
             (node_a.key.clone(), node_a.rank + 1)
-        }
+        };
+
+        self.set(new_root, Root(new_value, new_rank));
     }
 }
 
@@ -223,69 +219,26 @@ impl<K:UnifyKey> sv::SnapshotVecDelegate for Delegate<K> {
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// Code to handle simple keys like ints, floats---anything that
-// doesn't have a subtyping relationship we need to worry about.
-
-/// Indicates a type that does not have any kind of subtyping
-/// relationship.
-pub trait SimplyUnifiable<'tcx> : Clone + PartialEq + Debug {
-    fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx>;
-    fn to_type_err(expected_found<Self>) -> ty::type_err<'tcx>;
-}
-
-pub fn err<'tcx, V:SimplyUnifiable<'tcx>>(a_is_expected: bool,
-                                          a_t: V,
-                                          b_t: V)
-                                          -> ures<'tcx> {
-    if a_is_expected {
-        Err(SimplyUnifiable::to_type_err(
-            ty::expected_found {expected: a_t, found: b_t}))
-    } else {
-        Err(SimplyUnifiable::to_type_err(
-            ty::expected_found {expected: b_t, found: a_t}))
-    }
-}
-
-pub trait InferCtxtMethodsForSimplyUnifiableTypes<'tcx,K,V>
-    where K : UnifyKey<Value=Option<V>>,
-          V : SimplyUnifiable<'tcx>,
-          Option<V> : UnifyValue,
-{
-    fn simple_vars(&self,
-                   a_is_expected: bool,
-                   a_id: K,
-                   b_id: K)
-                   -> ures<'tcx>;
-    fn simple_var_t(&self,
-                    a_is_expected: bool,
-                    a_id: K,
-                    b: V)
-                    -> ures<'tcx>;
-    fn probe_var(&self, a_id: K) -> Option<Ty<'tcx>>;
-}
-
-impl<'a,'tcx,V,K> InferCtxtMethodsForSimplyUnifiableTypes<'tcx,K,V> for InferCtxt<'a,'tcx>
-    where K : UnifyKey<Value=Option<V>>,
-          V : SimplyUnifiable<'tcx>,
-          Option<V> : UnifyValue,
+// Code to handle keys which carry a value, like ints,
+// floats---anything that doesn't have a subtyping relationship we
+// need to worry about.
+
+impl<'tcx,K,V> UnificationTable<K>
+    where K: UnifyKey<Value=Option<V>>,
+          V: Clone+PartialEq,
+          Option<V>: UnifyValue,
 {
-    /// Unifies two simple keys. Because simple keys do not have any subtyping relationships, if
-    /// both keys have already been associated with a value, then those two values must be the
-    /// same.
-    fn simple_vars(&self,
-                   a_is_expected: bool,
-                   a_id: K,
-                   b_id: K)
-                   -> ures<'tcx>
+    pub fn unify_var_var(&mut self,
+                         a_id: K,
+                         b_id: K)
+                         -> Result<(),(V,V)>
     {
-        let tcx = self.tcx;
-        let table = UnifyKey::unification_table(self);
-        let node_a: Node<K> = table.borrow_mut().get(tcx, a_id);
-        let node_b: Node<K> = table.borrow_mut().get(tcx, b_id);
+        let node_a = self.get(a_id);
+        let node_b = self.get(b_id);
         let a_id = node_a.key.clone();
         let b_id = node_b.key.clone();
 
-        if a_id == b_id { return uok(); }
+        if a_id == b_id { return Ok(()); }
 
         let combined = {
             match (&node_a.value, &node_b.value) {
@@ -293,61 +246,52 @@ impl<'a,'tcx,V,K> InferCtxtMethodsForSimplyUnifiableTypes<'tcx,K,V> for InferCtx
                     None
                 }
                 (&Some(ref v), &None) | (&None, &Some(ref v)) => {
-                    Some((*v).clone())
+                    Some(v.clone())
                 }
                 (&Some(ref v1), &Some(ref v2)) => {
                     if *v1 != *v2 {
-                        return err(a_is_expected, (*v1).clone(), (*v2).clone())
+                        return Err((v1.clone(), v2.clone()));
                     }
-                    Some((*v1).clone())
+                    Some(v1.clone())
                 }
             }
         };
 
-        let (new_root, new_rank) = table.borrow_mut().unify(tcx,
-                                                            &node_a,
-                                                            &node_b);
-        table.borrow_mut().set(tcx, new_root, Root(combined, new_rank));
-        return Ok(())
+        Ok(self.unify(&node_a, &node_b, combined))
     }
 
     /// Sets the value of the key `a_id` to `b`. Because simple keys do not have any subtyping
     /// relationships, if `a_id` already has a value, it must be the same as `b`.
-    fn simple_var_t(&self,
-                    a_is_expected: bool,
-                    a_id: K,
-                    b: V)
-                    -> ures<'tcx>
+    pub fn unify_var_value(&mut self,
+                           a_id: K,
+                           b: V)
+                           -> Result<(),(V,V)>
     {
-        let tcx = self.tcx;
-        let table = UnifyKey::unification_table(self);
-        let node_a = table.borrow_mut().get(tcx, a_id);
+        let node_a = self.get(a_id);
         let a_id = node_a.key.clone();
 
         match node_a.value {
             None => {
-                table.borrow_mut().set(tcx, a_id, Root(Some(b), node_a.rank));
-                return Ok(());
+                self.set(a_id, Root(Some(b), node_a.rank));
+                Ok(())
             }
 
             Some(ref a_t) => {
                 if *a_t == b {
-                    return Ok(());
+                    Ok(())
                 } else {
-                    return err(a_is_expected, (*a_t).clone(), b);
+                    Err((a_t.clone(), b))
                 }
             }
         }
     }
 
-    fn probe_var(&self, a_id: K) -> Option<Ty<'tcx>> {
-        let tcx = self.tcx;
-        let table = UnifyKey::unification_table(self);
-        let node_a = table.borrow_mut().get(tcx, a_id);
-        match node_a.value {
-            None => None,
-            Some(ref a_t) => Some(a_t.to_type(tcx))
-        }
+    pub fn has_value(&mut self, id: K) -> bool {
+        self.get(id).value.is_some()
+    }
+
+    pub fn probe(&mut self, a_id: K) -> Option<V> {
+        self.get(a_id).value.clone()
     }
 }
 
@@ -355,33 +299,24 @@ impl<'a,'tcx,V,K> InferCtxtMethodsForSimplyUnifiableTypes<'tcx,K,V> for InferCtx
 
 // Integral type keys
 
+pub trait ToType<'tcx> {
+    fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx>;
+}
+
 impl UnifyKey for ty::IntVid {
     type Value = Option<IntVarValue>;
-
-    fn index(&self) -> uint { self.index as uint }
-
-    fn from_index(i: uint) -> ty::IntVid { ty::IntVid { index: i as u32 } }
-
-    fn unification_table<'v>(infcx: &'v InferCtxt) -> &'v RefCell<UnificationTable<ty::IntVid>> {
-        return &infcx.int_unification_table;
-    }
-
-    fn tag(_: Option<ty::IntVid>) -> &'static str {
-        "IntVid"
-    }
+    fn index(&self) -> u32 { self.index }
+    fn from_index(i: u32) -> ty::IntVid { ty::IntVid { index: i } }
+    fn tag(_: Option<ty::IntVid>) -> &'static str { "IntVid" }
 }
 
-impl<'tcx> SimplyUnifiable<'tcx> for IntVarValue {
+impl<'tcx> ToType<'tcx> for IntVarValue {
     fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
         match *self {
             ty::IntType(i) => ty::mk_mach_int(tcx, i),
             ty::UintType(i) => ty::mk_mach_uint(tcx, i),
         }
     }
-
-    fn to_type_err(err: expected_found<IntVarValue>) -> ty::type_err<'tcx> {
-        return ty::terr_int_mismatch(err);
-    }
 }
 
 impl UnifyValue for Option<IntVarValue> { }
@@ -390,29 +325,16 @@ impl UnifyValue for Option<IntVarValue> { }
 
 impl UnifyKey for ty::FloatVid {
     type Value = Option<ast::FloatTy>;
-
-    fn index(&self) -> uint { self.index as uint }
-
-    fn from_index(i: uint) -> ty::FloatVid { ty::FloatVid { index: i as u32 } }
-
-    fn unification_table<'v>(infcx: &'v InferCtxt) -> &'v RefCell<UnificationTable<ty::FloatVid>> {
-        return &infcx.float_unification_table;
-    }
-
-    fn tag(_: Option<ty::FloatVid>) -> &'static str {
-        "FloatVid"
-    }
+    fn index(&self) -> u32 { self.index }
+    fn from_index(i: u32) -> ty::FloatVid { ty::FloatVid { index: i } }
+    fn tag(_: Option<ty::FloatVid>) -> &'static str { "FloatVid" }
 }
 
 impl UnifyValue for Option<ast::FloatTy> {
 }
 
-impl<'tcx> SimplyUnifiable<'tcx> for ast::FloatTy {
+impl<'tcx> ToType<'tcx> for ast::FloatTy {
     fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
         ty::mk_mach_float(tcx, *self)
     }
-
-    fn to_type_err(err: expected_found<ast::FloatTy>) -> ty::type_err<'tcx> {
-        ty::terr_float_mismatch(err)
-    }
 }
index bd96a8a0f2cd78f980ea42ecb19fcb9749f59321..2a4c25345447fb84e980525862e8b8b984fafbd5 100644 (file)
@@ -28,8 +28,8 @@ pub fn check_crate(tcx: &ctxt) {
     let mut visitor = IntrinsicCheckingVisitor {
         tcx: tcx,
         param_envs: Vec::new(),
-        dummy_sized_ty: tcx.types.int,
-        dummy_unsized_ty: ty::mk_vec(tcx, tcx.types.int, None),
+        dummy_sized_ty: tcx.types.isize,
+        dummy_unsized_ty: ty::mk_vec(tcx, tcx.types.isize, None),
     };
     visit::walk_crate(&mut visitor, tcx.map.krate());
 }
index 56c5928a132b14cd56ac92d19588bc227c912c55..a08de58f909d3a5f177161d4a074be53b10700e0 100644 (file)
@@ -46,7 +46,7 @@ macro_rules! lets_do_this {
         $( $variant:ident, $name:expr, $method:ident; )*
     ) => {
 
-#[derive(Copy, FromPrimitive, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, FromPrimitive, PartialEq, Eq, Hash)]
 pub enum LangItem {
     $($variant),*
 }
@@ -70,8 +70,8 @@ impl LanguageItems {
         self.items.iter().enumerate()
     }
 
-    pub fn item_name(index: uint) -> &'static str {
-        let item: Option<LangItem> = FromPrimitive::from_uint(index);
+    pub fn item_name(index: usize) -> &'static str {
+        let item: Option<LangItem> = FromPrimitive::from_usize(index);
         match item {
             $( Some($variant) => $name, )*
             None => "???"
@@ -79,11 +79,11 @@ impl LanguageItems {
     }
 
     pub fn require(&self, it: LangItem) -> Result<ast::DefId, String> {
-        match self.items[it as uint] {
+        match self.items[it as usize] {
             Some(id) => Ok(id),
             None => {
                 Err(format!("requires `{}` lang_item",
-                            LanguageItems::item_name(it as uint)))
+                            LanguageItems::item_name(it as usize)))
             }
         }
     }
@@ -132,7 +132,7 @@ impl LanguageItems {
     $(
         #[allow(dead_code)]
         pub fn $method(&self) -> Option<ast::DefId> {
-            self.items[$variant as uint]
+            self.items[$variant as usize]
         }
     )*
 }
@@ -142,7 +142,7 @@ struct LanguageItemCollector<'a> {
 
     session: &'a Session,
 
-    item_refs: FnvHashMap<&'static str, uint>,
+    item_refs: FnvHashMap<&'static str, usize>,
 }
 
 impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> {
@@ -163,7 +163,7 @@ impl<'a> LanguageItemCollector<'a> {
     pub fn new(session: &'a Session) -> LanguageItemCollector<'a> {
         let mut item_refs = FnvHashMap();
 
-        $( item_refs.insert($name, $variant as uint); )*
+        $( item_refs.insert($name, $variant as usize); )*
 
         LanguageItemCollector {
             session: session,
@@ -172,7 +172,7 @@ impl<'a> LanguageItemCollector<'a> {
         }
     }
 
-    pub fn collect_item(&mut self, item_index: uint,
+    pub fn collect_item(&mut self, item_index: usize,
                         item_def_id: ast::DefId, span: Span) {
         // Check for duplicates.
         match self.items.items[item_index] {
@@ -239,6 +239,24 @@ pub fn collect_language_items(krate: &ast::Crate,
 
 lets_do_this! {
 //  Variant name,                    Name,                      Method name;
+    CharImplItem,                    "char",                    char_impl;
+    StrImplItem,                     "str",                     str_impl;
+    SliceImplItem,                   "slice",                   slice_impl;
+    ConstPtrImplItem,                "const_ptr",               const_ptr_impl;
+    MutPtrImplItem,                  "mut_ptr",                 mut_ptr_impl;
+    I8ImplItem,                      "i8",                      i8_impl;
+    I16ImplItem,                     "i16",                     i16_impl;
+    I32ImplItem,                     "i32",                     i32_impl;
+    I64ImplItem,                     "i64",                     i64_impl;
+    IsizeImplItem,                   "isize",                   isize_impl;
+    U8ImplItem,                      "u8",                      u8_impl;
+    U16ImplItem,                     "u16",                     u16_impl;
+    U32ImplItem,                     "u32",                     u32_impl;
+    U64ImplItem,                     "u64",                     u64_impl;
+    UsizeImplItem,                   "usize",                   usize_impl;
+    F32ImplItem,                     "f32",                     f32_impl;
+    F64ImplItem,                     "f64",                     f64_impl;
+
     SendTraitLangItem,               "send",                    send_trait;
     SizedTraitLangItem,              "sized",                   sized_trait;
     CopyTraitLangItem,               "copy",                    copy_trait;
@@ -298,9 +316,6 @@ lets_do_this! {
 
     StartFnLangItem,                 "start",                   start_fn;
 
-    TyDescStructLangItem,            "ty_desc",                 ty_desc;
-    OpaqueStructLangItem,            "opaque",                  opaque;
-
     EhPersonalityLangItem,           "eh_personality",          eh_personality;
 
     ExchangeHeapLangItem,            "exchange_heap",           exchange_heap;
index e58136fb3f4e454e18c6269b16ebd57f0dea5642..d7161607b61eb9c3e9a1ea032db5e76b42894166 100644 (file)
@@ -51,8 +51,8 @@
 //! enclosing function.  On the way down the tree, it identifies those AST
 //! nodes and variable IDs that will be needed for the liveness analysis
 //! and assigns them contiguous IDs.  The liveness id for an AST node is
-//! called a `live_node` (it's a newtype'd uint) and the id for a variable
-//! is called a `variable` (another newtype'd uint).
+//! called a `live_node` (it's a newtype'd usize) and the id for a variable
+//! is called a `variable` (another newtype'd usize).
 //!
 //! On the way back up the tree, as we are about to exit from a function
 //! declaration we allocate a `liveness` instance.  Now that we know
@@ -118,9 +118,11 @@ use middle::ty::ClosureTyper;
 use lint;
 use util::nodemap::NodeMap;
 
-use std::{fmt, old_io, uint};
-use std::rc::Rc;
+use std::{fmt, usize};
+use std::io::prelude::*;
+use std::io;
 use std::iter::repeat;
+use std::rc::Rc;
 use syntax::ast::{self, NodeId, Expr};
 use syntax::codemap::{BytePos, original_sp, Span};
 use syntax::parse::token::{self, special_idents};
@@ -137,18 +139,18 @@ enum LoopKind<'a> {
     WhileLoop(&'a Expr),
 }
 
-#[derive(Copy, PartialEq)]
-struct Variable(uint);
+#[derive(Copy, Clone, PartialEq)]
+struct Variable(usize);
 
 #[derive(Copy, PartialEq)]
-struct LiveNode(uint);
+struct LiveNode(usize);
 
 impl Variable {
-    fn get(&self) -> uint { let Variable(v) = *self; v }
+    fn get(&self) -> usize { let Variable(v) = *self; v }
 }
 
 impl LiveNode {
-    fn get(&self) -> uint { let LiveNode(v) = *self; v }
+    fn get(&self) -> usize { let LiveNode(v) = *self; v }
 }
 
 impl Clone for LiveNode {
@@ -157,7 +159,7 @@ impl Clone for LiveNode {
     }
 }
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 enum LiveNodeKind {
     FreeVarNode(Span),
     ExprNode(Span),
@@ -232,24 +234,24 @@ impl fmt::Debug for Variable {
 
 impl LiveNode {
     fn is_valid(&self) -> bool {
-        self.get() != uint::MAX
+        self.get() != usize::MAX
     }
 }
 
-fn invalid_node() -> LiveNode { LiveNode(uint::MAX) }
+fn invalid_node() -> LiveNode { LiveNode(usize::MAX) }
 
 struct CaptureInfo {
     ln: LiveNode,
     var_nid: NodeId
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 struct LocalInfo {
     id: NodeId,
     ident: ast::Ident
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 enum VarKind {
     Arg(NodeId, ast::Ident),
     Local(LocalInfo),
@@ -260,8 +262,8 @@ enum VarKind {
 struct IrMaps<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
 
-    num_live_nodes: uint,
-    num_vars: uint,
+    num_live_nodes: usize,
+    num_vars: usize,
     live_node_map: NodeMap<LiveNode>,
     variable_map: NodeMap<Variable>,
     capture_info_map: NodeMap<Rc<Vec<CaptureInfo>>>,
@@ -325,7 +327,7 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
             self.tcx
                 .sess
                 .span_bug(span, &format!("no variable registered for id {}",
-                                        node_id)[]);
+                                        node_id));
           }
         }
     }
@@ -445,8 +447,8 @@ fn visit_arm(ir: &mut IrMaps, arm: &ast::Arm) {
 fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
     match expr.node {
       // live nodes required for uses or definitions of variables:
-      ast::ExprPath(_) | ast::ExprQPath(_) => {
-        let def = ir.tcx.def_map.borrow()[expr.id].clone();
+      ast::ExprPath(..) => {
+        let def = ir.tcx.def_map.borrow().get(&expr.id).unwrap().full_def();
         debug!("expr {}: path that leads to {:?}", expr.id, def);
         if let DefLocal(..) = def {
             ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
@@ -532,7 +534,7 @@ fn invalid_users() -> Users {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Specials {
     exit_ln: LiveNode,
     fallthrough_ln: LiveNode,
@@ -540,9 +542,9 @@ struct Specials {
     clean_exit_var: Variable
 }
 
-static ACC_READ: uint = 1;
-static ACC_WRITE: uint = 2;
-static ACC_USE: uint = 4;
+const ACC_READ: u32 = 1;
+const ACC_WRITE: u32 = 2;
+const ACC_USE: u32 = 4;
 
 struct Liveness<'a, 'tcx: 'a> {
     ir: &'a mut IrMaps<'a, 'tcx>,
@@ -585,7 +587,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             self.ir.tcx.sess.span_bug(
                 span,
                 &format!("no live node registered for node {}",
-                        node_id)[]);
+                        node_id));
           }
         }
     }
@@ -631,7 +633,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         succ
     }
 
-    fn idx(&self, ln: LiveNode, var: Variable) -> uint {
+    fn idx(&self, ln: LiveNode, var: Variable) -> usize {
         ln.get() * self.ir.num_vars + var.get()
     }
 
@@ -670,7 +672,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     }
 
     fn indices2<F>(&mut self, ln: LiveNode, succ_ln: LiveNode, mut op: F) where
-        F: FnMut(&mut Liveness<'a, 'tcx>, uint, uint),
+        F: FnMut(&mut Liveness<'a, 'tcx>, usize, usize),
     {
         let node_base_idx = self.idx(ln, Variable(0));
         let succ_base_idx = self.idx(succ_ln, Variable(0));
@@ -680,11 +682,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     }
 
     fn write_vars<F>(&self,
-                     wr: &mut old_io::Writer,
+                     wr: &mut Write,
                      ln: LiveNode,
                      mut test: F)
-                     -> old_io::IoResult<()> where
-        F: FnMut(uint) -> LiveNode,
+                     -> io::Result<()> where
+        F: FnMut(usize) -> LiveNode,
     {
         let node_base_idx = self.idx(ln, Variable(0));
         for var_idx in 0..self.ir.num_vars {
@@ -705,8 +707,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             Some(_) => {
                 // Refers to a labeled loop. Use the results of resolve
                 // to find with one
-                match self.ir.tcx.def_map.borrow().get(&id) {
-                    Some(&DefLabel(loop_id)) => loop_id,
+                match self.ir.tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
+                    Some(DefLabel(loop_id)) => loop_id,
                     _ => self.ir.tcx.sess.span_bug(sp, "label on break/loop \
                                                         doesn't refer to a loop")
                 }
@@ -727,7 +729,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     fn ln_str(&self, ln: LiveNode) -> String {
         let mut wr = Vec::new();
         {
-            let wr = &mut wr as &mut old_io::Writer;
+            let wr = &mut wr as &mut Write;
             write!(wr, "[ln({:?}) of kind {:?} reads", ln.get(), self.ir.lnk(ln));
             self.write_vars(wr, ln, |idx| self.users[idx].reader);
             write!(wr, "  writes");
@@ -807,7 +809,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     }
 
     // Either read, write, or both depending on the acc bitset
-    fn acc(&mut self, ln: LiveNode, var: Variable, acc: uint) {
+    fn acc(&mut self, ln: LiveNode, var: Variable, acc: u32) {
         debug!("{:?} accesses[{:x}] {:?}: {}",
                ln, acc, var, self.ln_str(ln));
 
@@ -947,7 +949,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         match expr.node {
           // Interesting cases with control flow or which gen/kill
 
-          ast::ExprPath(_) | ast::ExprQPath(_) => {
+          ast::ExprPath(..) => {
               self.access_path(expr, succ, ACC_READ | ACC_USE)
           }
 
@@ -1275,7 +1277,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         // just ignore such cases and treat them as reads.
 
         match expr.node {
-            ast::ExprPath(_) | ast::ExprQPath(_) => succ,
+            ast::ExprPath(..) => succ,
             ast::ExprField(ref e, _) => self.propagate_through_expr(&**e, succ),
             ast::ExprTupField(ref e, _) => self.propagate_through_expr(&**e, succ),
             _ => self.propagate_through_expr(expr, succ)
@@ -1283,10 +1285,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     }
 
     // see comment on propagate_through_lvalue()
-    fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
+    fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
                     -> LiveNode {
         match expr.node {
-          ast::ExprPath(_) | ast::ExprQPath(_) => {
+          ast::ExprPath(..) => {
               self.access_path(expr, succ, acc)
           }
 
@@ -1298,9 +1300,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         }
     }
 
-    fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
+    fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
                    -> LiveNode {
-        match self.ir.tcx.def_map.borrow()[expr.id].clone() {
+        match self.ir.tcx.def_map.borrow().get(&expr.id).unwrap().full_def() {
           DefLocal(nid) => {
             let ln = self.live_node(expr.id, expr.span);
             if acc != 0 {
@@ -1468,7 +1470,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
       ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) |
       ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) |
       ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) |
-      ast::ExprRange(..) | ast::ExprQPath(..) => {
+      ast::ExprRange(..) => {
         visit::walk_expr(this, expr);
       }
       ast::ExprIfLet(..) => {
@@ -1496,7 +1498,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     fn fn_ret(&self, id: NodeId) -> ty::PolyFnOutput<'tcx> {
         let fn_ty = ty::node_id_to_type(self.ir.tcx, id);
         match fn_ty.sty {
-            ty::ty_closure(closure_def_id, _, substs) =>
+            ty::ty_closure(closure_def_id, substs) =>
                 self.ir.tcx.closure_type(closure_def_id, substs).sig.output(),
             _ =>
                 ty::ty_fn_ret(fn_ty),
@@ -1561,8 +1563,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
     fn check_lvalue(&mut self, expr: &Expr) {
         match expr.node {
-            ast::ExprPath(_) | ast::ExprQPath(_) => {
-                if let DefLocal(nid) = self.ir.tcx.def_map.borrow()[expr.id].clone() {
+            ast::ExprPath(..) => {
+                if let DefLocal(nid) = self.ir.tcx.def_map.borrow().get(&expr.id)
+                                                                   .unwrap()
+                                                                   .full_def() {
                     // Assignment to an immutable variable or argument: only legal
                     // if there is no later assignment. If this local is actually
                     // mutable, then check for a reassignment to flag the mutability
index 4be7bb9c365a16d57d846ac70a178dfda6f944ff..85255d04df4329adc0033d8451fa3940f62379cb 100644 (file)
@@ -71,11 +71,13 @@ pub use self::Note::*;
 pub use self::deref_kind::*;
 pub use self::categorization::*;
 
+use self::Aliasability::*;
+
 use middle::check_const;
 use middle::def;
 use middle::region;
 use middle::ty::{self, Ty};
-use util::nodemap::{NodeMap};
+use util::nodemap::NodeMap;
 use util::ppaux::{Repr, UserString};
 
 use syntax::ast::{MutImmutable, MutMutable};
@@ -94,7 +96,7 @@ pub enum categorization<'tcx> {
     cat_static_item,
     cat_upvar(Upvar),                          // upvar referenced by closure env
     cat_local(ast::NodeId),                    // local variable
-    cat_deref(cmt<'tcx>, uint, PointerKind),   // deref of a ptr
+    cat_deref(cmt<'tcx>, usize, PointerKind),   // deref of a ptr
     cat_interior(cmt<'tcx>, InteriorKind),     // something interior: field, tuple, etc
     cat_downcast(cmt<'tcx>, ast::DefId),       // selects a particular enum variant (*1)
 
@@ -135,7 +137,7 @@ pub enum InteriorKind {
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 pub enum FieldName {
     NamedField(ast::Name),
-    PositionalField(uint)
+    PositionalField(usize)
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
@@ -197,7 +199,7 @@ pub type cmt<'tcx> = Rc<cmt_<'tcx>>;
 
 // We pun on *T to mean both actual deref of a ptr as well
 // as accessing of components:
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum deref_kind {
     deref_ptr(PointerKind),
     deref_interior(InteriorKind),
@@ -261,6 +263,9 @@ pub struct MemCategorizationContext<'t,TYPER:'t> {
 }
 
 impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {}
+impl<'t,TYPER:'t> Clone for MemCategorizationContext<'t,TYPER> {
+    fn clone(&self) -> MemCategorizationContext<'t,TYPER> { *self }
+}
 
 pub type McResult<T> = Result<T, ()>;
 
@@ -295,23 +300,29 @@ pub trait Typer<'tcx> : ty::ClosureTyper<'tcx> {
 
 impl MutabilityCategory {
     pub fn from_mutbl(m: ast::Mutability) -> MutabilityCategory {
-        match m {
+        let ret = match m {
             MutImmutable => McImmutable,
             MutMutable => McDeclared
-        }
+        };
+        debug!("MutabilityCategory::{}({:?}) => {:?}",
+               "from_mutbl", m, ret);
+        ret
     }
 
     pub fn from_borrow_kind(borrow_kind: ty::BorrowKind) -> MutabilityCategory {
-        match borrow_kind {
+        let ret = match borrow_kind {
             ty::ImmBorrow => McImmutable,
             ty::UniqueImmBorrow => McImmutable,
             ty::MutBorrow => McDeclared,
-        }
+        };
+        debug!("MutabilityCategory::{}({:?}) => {:?}",
+               "from_borrow_kind", borrow_kind, ret);
+        ret
     }
 
-    pub fn from_pointer_kind(base_mutbl: MutabilityCategory,
-                             ptr: PointerKind) -> MutabilityCategory {
-        match ptr {
+    fn from_pointer_kind(base_mutbl: MutabilityCategory,
+                         ptr: PointerKind) -> MutabilityCategory {
+        let ret = match ptr {
             Unique => {
                 base_mutbl.inherit()
             }
@@ -321,11 +332,14 @@ impl MutabilityCategory {
             UnsafePtr(m) => {
                 MutabilityCategory::from_mutbl(m)
             }
-        }
+        };
+        debug!("MutabilityCategory::{}({:?}, {:?}) => {:?}",
+               "from_pointer_kind", base_mutbl, ptr, ret);
+        ret
     }
 
     fn from_local(tcx: &ty::ctxt, id: ast::NodeId) -> MutabilityCategory {
-        match tcx.map.get(id) {
+        let ret = match tcx.map.get(id) {
             ast_map::NodeLocal(p) | ast_map::NodeArg(p) => match p.node {
                 ast::PatIdent(bind_mode, _, _) => {
                     if bind_mode == ast::BindByValue(ast::MutMutable) {
@@ -337,30 +351,39 @@ impl MutabilityCategory {
                 _ => tcx.sess.span_bug(p.span, "expected identifier pattern")
             },
             _ => tcx.sess.span_bug(tcx.map.span(id), "expected identifier pattern")
-        }
+        };
+        debug!("MutabilityCategory::{}(tcx, id={:?}) => {:?}",
+               "from_local", id, ret);
+        ret
     }
 
     pub fn inherit(&self) -> MutabilityCategory {
-        match *self {
+        let ret = match *self {
             McImmutable => McImmutable,
             McDeclared => McInherited,
             McInherited => McInherited,
-        }
+        };
+        debug!("{:?}.inherit() => {:?}", self, ret);
+        ret
     }
 
     pub fn is_mutable(&self) -> bool {
-        match *self {
+        let ret = match *self {
             McImmutable => false,
             McInherited => true,
             McDeclared => true,
-        }
+        };
+        debug!("{:?}.is_mutable() => {:?}", self, ret);
+        ret
     }
 
     pub fn is_immutable(&self) -> bool {
-        match *self {
+        let ret = match *self {
             McImmutable => true,
             McDeclared | McInherited => false
-        }
+        };
+        debug!("{:?}.is_immutable() => {:?}", self, ret);
+        ret
     }
 
     pub fn to_user_str(&self) -> &'static str {
@@ -428,7 +451,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
 
             Some(adjustment) => {
                 match *adjustment {
-                    ty::AdjustReifyFnPointer(..) => {
+                    ty::AdjustReifyFnPointer(..) |
+                    ty::AdjustUnsafeFnPointer(..) => {
                         debug!("cat_expr(AdjustReifyFnPointer): {}",
                                expr.repr(self.tcx()));
                         // Convert a bare fn to a closure by adding NULL env.
@@ -461,7 +485,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
 
     pub fn cat_expr_autoderefd(&self,
                                expr: &ast::Expr,
-                               autoderefs: uint)
+                               autoderefs: usize)
                                -> McResult<cmt<'tcx>> {
         let mut cmt = try!(self.cat_expr_unadjusted(expr));
         debug!("cat_expr_autoderefd: autoderefs={}, cmt={}",
@@ -529,8 +553,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
             }
           }
 
-          ast::ExprPath(_) | ast::ExprQPath(_) => {
-            let def = (*self.tcx().def_map.borrow())[expr.id];
+          ast::ExprPath(..) => {
+            let def = self.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
             self.cat_def(expr.id, expr.span, expr_ty, def)
           }
 
@@ -575,14 +599,14 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
 
         match def {
           def::DefStruct(..) | def::DefVariant(..) | def::DefConst(..) |
-          def::DefFn(..) | def::DefStaticMethod(..) |  def::DefMethod(..) => {
+          def::DefFn(..) | def::DefMethod(..) => {
                 Ok(self.cat_rvalue_node(id, span, expr_ty))
           }
           def::DefMod(_) | def::DefForeignMod(_) | def::DefUse(_) |
           def::DefTrait(_) | def::DefTy(..) | def::DefPrimTy(_) |
-          def::DefTyParam(..) | def::DefTyParamBinder(..) | def::DefRegion(_) |
+          def::DefTyParam(..) | def::DefRegion(_) |
           def::DefLabel(_) | def::DefSelfTy(..) |
-          def::DefAssociatedTy(..) | def::DefAssociatedPath(..)=> {
+          def::DefAssociatedTy(..) => {
               Ok(Rc::new(cmt_ {
                   id:id,
                   span:span,
@@ -607,7 +631,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
           def::DefUpvar(var_id, fn_node_id) => {
               let ty = try!(self.node_ty(fn_node_id));
               match ty.sty {
-                  ty::ty_closure(closure_id, _, _) => {
+                  ty::ty_closure(closure_id, _) => {
                       match self.typer.closure_kind(closure_id) {
                           Some(kind) => {
                               self.cat_upvar(id, span, var_id, fn_node_id, kind)
@@ -624,7 +648,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                           span,
                           &format!("Upvar of non-closure {} - {}",
                                   fn_node_id,
-                                  ty.repr(self.tcx()))[]);
+                                  ty.repr(self.tcx())));
                   }
               }
           }
@@ -732,7 +756,9 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
             }
         };
 
-        Ok(Rc::new(cmt_result))
+        let ret = Rc::new(cmt_result);
+        debug!("cat_upvar ret={}", ret.repr(self.tcx()));
+        Ok(ret)
     }
 
     fn env_deref(&self,
@@ -793,14 +819,18 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
             McDeclared | McInherited => { }
         }
 
-        cmt_ {
+        let ret = cmt_ {
             id: id,
             span: span,
             cat: cat_deref(Rc::new(cmt_result), 0, env_ptr),
             mutbl: deref_mutbl,
             ty: var_ty,
             note: NoteClosureEnv(upvar_id)
-        }
+        };
+
+        debug!("env_deref ret {}", ret.repr(self.tcx()));
+
+        ret
     }
 
     pub fn cat_rvalue_node(&self,
@@ -830,7 +860,9 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                 }
             }
         };
-        self.cat_rvalue(id, span, re, expr_ty)
+        let ret = self.cat_rvalue(id, span, re, expr_ty);
+        debug!("cat_rvalue_node ret {}", ret.repr(self.tcx()));
+        ret
     }
 
     pub fn cat_rvalue(&self,
@@ -838,14 +870,16 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                       span: Span,
                       temp_scope: ty::Region,
                       expr_ty: Ty<'tcx>) -> cmt<'tcx> {
-        Rc::new(cmt_ {
+        let ret = Rc::new(cmt_ {
             id:cmt_id,
             span:span,
             cat:cat_rvalue(temp_scope),
             mutbl:McDeclared,
             ty:expr_ty,
             note: NoteNone
-        })
+        });
+        debug!("cat_rvalue ret {}", ret.repr(self.tcx()));
+        ret
     }
 
     pub fn cat_field<N:ast_node>(&self,
@@ -854,36 +888,40 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                                  f_name: ast::Name,
                                  f_ty: Ty<'tcx>)
                                  -> cmt<'tcx> {
-        Rc::new(cmt_ {
+        let ret = Rc::new(cmt_ {
             id: node.id(),
             span: node.span(),
             mutbl: base_cmt.mutbl.inherit(),
             cat: cat_interior(base_cmt, InteriorField(NamedField(f_name))),
             ty: f_ty,
             note: NoteNone
-        })
+        });
+        debug!("cat_field ret {}", ret.repr(self.tcx()));
+        ret
     }
 
     pub fn cat_tup_field<N:ast_node>(&self,
                                      node: &N,
                                      base_cmt: cmt<'tcx>,
-                                     f_idx: uint,
+                                     f_idx: usize,
                                      f_ty: Ty<'tcx>)
                                      -> cmt<'tcx> {
-        Rc::new(cmt_ {
+        let ret = Rc::new(cmt_ {
             id: node.id(),
             span: node.span(),
             mutbl: base_cmt.mutbl.inherit(),
             cat: cat_interior(base_cmt, InteriorField(PositionalField(f_idx))),
             ty: f_ty,
             note: NoteNone
-        })
+        });
+        debug!("cat_tup_field ret {}", ret.repr(self.tcx()));
+        ret
     }
 
     fn cat_deref<N:ast_node>(&self,
                              node: &N,
                              base_cmt: cmt<'tcx>,
-                             deref_cnt: uint,
+                             deref_cnt: usize,
                              deref_context: DerefKindContext)
                              -> McResult<cmt<'tcx>> {
         let adjustment = match self.typer.adjustments().borrow().get(&node.id()) {
@@ -912,10 +950,14 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
         };
         let base_cmt_ty = base_cmt.ty;
         match ty::deref(base_cmt_ty, true) {
-            Some(mt) => self.cat_deref_common(node, base_cmt, deref_cnt,
+            Some(mt) => {
+                let ret = self.cat_deref_common(node, base_cmt, deref_cnt,
                                               mt.ty,
                                               deref_context,
-                                              /* implicit: */ false),
+                                                /* implicit: */ false);
+                debug!("cat_deref ret {}", ret.repr(self.tcx()));
+                ret
+            }
             None => {
                 debug!("Explicit deref of non-derefable type: {}",
                        base_cmt_ty.repr(self.tcx()));
@@ -927,7 +969,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
     fn cat_deref_common<N:ast_node>(&self,
                                     node: &N,
                                     base_cmt: cmt<'tcx>,
-                                    deref_cnt: uint,
+                                    deref_cnt: usize,
                                     deref_ty: Ty<'tcx>,
                                     deref_context: DerefKindContext,
                                     implicit: bool)
@@ -953,14 +995,16 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                 (base_cmt.mutbl.inherit(), cat_interior(base_cmt, interior))
             }
         };
-        Ok(Rc::new(cmt_ {
+        let ret = Rc::new(cmt_ {
             id: node.id(),
             span: node.span(),
             cat: cat,
             mutbl: m,
             ty: deref_ty,
             note: NoteNone
-        }))
+        });
+        debug!("cat_deref_common ret {}", ret.repr(self.tcx()));
+        Ok(ret)
     }
 
     pub fn cat_index<N:ast_node>(&self,
@@ -1008,8 +1052,10 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
         };
 
         let m = base_cmt.mutbl.inherit();
-        return Ok(interior(elt, base_cmt.clone(), base_cmt.ty,
-                           m, context, element_ty));
+        let ret = interior(elt, base_cmt.clone(), base_cmt.ty,
+                           m, context, element_ty);
+        debug!("cat_index ret {}", ret.repr(self.tcx()));
+        return Ok(ret);
 
         fn interior<'tcx, N: ast_node>(elt: &N,
                                        of_cmt: cmt<'tcx>,
@@ -1038,14 +1084,14 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                              context: InteriorOffsetKind)
                              -> McResult<cmt<'tcx>>
     {
-        match try!(deref_kind(base_cmt.ty, Some(context))) {
+        let ret = match try!(deref_kind(base_cmt.ty, Some(context))) {
             deref_ptr(ptr) => {
                 // for unique ptrs, we inherit mutability from the
                 // owning reference.
                 let m = MutabilityCategory::from_pointer_kind(base_cmt.mutbl, ptr);
 
                 // the deref is explicit in the resulting cmt
-                Ok(Rc::new(cmt_ {
+                Rc::new(cmt_ {
                     id:elt.id(),
                     span:elt.span(),
                     cat:cat_deref(base_cmt.clone(), 0, ptr),
@@ -1055,13 +1101,15 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                         None => self.tcx().sess.bug("Found non-derefable type")
                     },
                     note: NoteNone
-                }))
+                })
             }
 
             deref_interior(_) => {
-                Ok(base_cmt)
+                base_cmt
             }
-        }
+        };
+        debug!("deref_vec ret {}", ret.repr(self.tcx()));
+        Ok(ret)
     }
 
     /// Given a pattern P like: `[_, ..Q, _]`, where `vec_cmt` is the cmt for `P`, `slice_pat` is
@@ -1111,14 +1159,16 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                                         interior_ty: Ty<'tcx>,
                                         interior: InteriorKind)
                                         -> cmt<'tcx> {
-        Rc::new(cmt_ {
+        let ret = Rc::new(cmt_ {
             id: node.id(),
             span: node.span(),
             mutbl: base_cmt.mutbl.inherit(),
             cat: cat_interior(base_cmt, interior),
             ty: interior_ty,
             note: NoteNone
-        })
+        });
+        debug!("cat_imm_interior ret={}", ret.repr(self.tcx()));
+        ret
     }
 
     pub fn cat_downcast<N:ast_node>(&self,
@@ -1127,14 +1177,16 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                                     downcast_ty: Ty<'tcx>,
                                     variant_did: ast::DefId)
                                     -> cmt<'tcx> {
-        Rc::new(cmt_ {
+        let ret = Rc::new(cmt_ {
             id: node.id(),
             span: node.span(),
             mutbl: base_cmt.mutbl.inherit(),
             cat: cat_downcast(base_cmt, variant_did),
             ty: downcast_ty,
             note: NoteNone
-        })
+        });
+        debug!("cat_downcast ret={}", ret.repr(self.tcx()));
+        ret
     }
 
     pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, mut op: F) -> McResult<()>
@@ -1199,14 +1251,13 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
 
         (*op)(self, cmt.clone(), pat);
 
-        let def_map = self.tcx().def_map.borrow();
-        let opt_def = def_map.get(&pat.id);
+        let opt_def = self.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def());
 
         // Note: This goes up here (rather than within the PatEnum arm
         // alone) because struct patterns can refer to struct types or
         // to struct variants within enums.
         let cmt = match opt_def {
-            Some(&def::DefVariant(enum_did, variant_did, _))
+            Some(def::DefVariant(enum_did, variant_did, _))
                 // univariant enums do not need downcasts
                 if !ty::enum_is_univariant(self.tcx(), enum_did) => {
                     self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did)
@@ -1224,7 +1275,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
           }
           ast::PatEnum(_, Some(ref subpats)) => {
             match opt_def {
-                Some(&def::DefVariant(..)) => {
+                Some(def::DefVariant(..)) => {
                     // variant(x, y, z)
                     for (i, subpat) in subpats.iter().enumerate() {
                         let subpat_ty = try!(self.pat_ty(&**subpat)); // see (*2)
@@ -1237,7 +1288,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                         try!(self.cat_pattern_(subcmt, &**subpat, op));
                     }
                 }
-                Some(&def::DefStruct(..)) => {
+                Some(def::DefStruct(..)) => {
                     for (i, subpat) in subpats.iter().enumerate() {
                         let subpat_ty = try!(self.pat_ty(&**subpat)); // see (*2)
                         let cmt_field =
@@ -1247,7 +1298,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                         try!(self.cat_pattern_(cmt_field, &**subpat, op));
                     }
                 }
-                Some(&def::DefConst(..)) => {
+                Some(def::DefConst(..)) => {
                     for subpat in subpats {
                         try!(self.cat_pattern_(cmt.clone(), &**subpat, op));
                     }
@@ -1341,17 +1392,25 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone, Debug)]
 pub enum InteriorSafety {
     InteriorUnsafe,
     InteriorSafe
 }
 
-#[derive(Copy)]
+#[derive(Clone, Debug)]
+pub enum Aliasability {
+    FreelyAliasable(AliasableReason),
+    NonAliasable,
+    ImmutableUnique(Box<Aliasability>),
+}
+
+#[derive(Copy, Clone, Debug)]
 pub enum AliasableReason {
     AliasableBorrowed,
     AliasableClosure(ast::NodeId), // Aliasable due to capture Fn closure env
     AliasableOther,
+    UnaliasableImmutable, // Created as needed upon seeing ImmutableUnique
     AliasableStatic(InteriorSafety),
     AliasableStaticMut(InteriorSafety),
 }
@@ -1380,9 +1439,9 @@ impl<'tcx> cmt_<'tcx> {
         }
     }
 
-    /// Returns `Some(_)` if this lvalue represents a freely aliasable pointer type.
+    /// Returns `FreelyAliasable(_)` if this lvalue represents a freely aliasable pointer type.
     pub fn freely_aliasable(&self, ctxt: &ty::ctxt<'tcx>)
-                            -> Option<AliasableReason> {
+                            -> Aliasability {
         // Maybe non-obvious: copied upvars can only be considered
         // non-aliasable in once closures, since any other kind can be
         // aliased and eventually recused.
@@ -1393,17 +1452,27 @@ impl<'tcx> cmt_<'tcx> {
             cat_deref(ref b, _, BorrowedPtr(ty::UniqueImmBorrow, _)) |
             cat_deref(ref b, _, Implicit(ty::UniqueImmBorrow, _)) |
             cat_downcast(ref b, _) |
-            cat_deref(ref b, _, Unique) |
             cat_interior(ref b, _) => {
                 // Aliasability depends on base cmt
                 b.freely_aliasable(ctxt)
             }
 
+            cat_deref(ref b, _, Unique) => {
+                let sub = b.freely_aliasable(ctxt);
+                if b.mutbl.is_mutable() {
+                    // Aliasability depends on base cmt alone
+                    sub
+                } else {
+                    // Do not allow mutation through an immutable box.
+                    ImmutableUnique(Box::new(sub))
+                }
+            }
+
             cat_rvalue(..) |
             cat_local(..) |
             cat_upvar(..) |
             cat_deref(_, _, UnsafePtr(..)) => { // yes, it's aliasable, but...
-                None
+                NonAliasable
             }
 
             cat_static_item(..) => {
@@ -1414,17 +1483,18 @@ impl<'tcx> cmt_<'tcx> {
                 };
 
                 if self.mutbl.is_mutable() {
-                    Some(AliasableStaticMut(int_safe))
+                    FreelyAliasable(AliasableStaticMut(int_safe))
                 } else {
-                    Some(AliasableStatic(int_safe))
+                    FreelyAliasable(AliasableStatic(int_safe))
                 }
             }
 
             cat_deref(ref base, _, BorrowedPtr(ty::ImmBorrow, _)) |
             cat_deref(ref base, _, Implicit(ty::ImmBorrow, _)) => {
                 match base.cat {
-                    cat_upvar(Upvar{ id, .. }) => Some(AliasableClosure(id.closure_expr_id)),
-                    _ => Some(AliasableBorrowed)
+                    cat_upvar(Upvar{ id, .. }) =>
+                        FreelyAliasable(AliasableClosure(id.closure_expr_id)),
+                    _ => FreelyAliasable(AliasableBorrowed)
                 }
             }
         }
@@ -1636,4 +1706,3 @@ impl<'tcx> UserString<'tcx> for Upvar {
         format!("captured outer variable in an `{}` closure", kind)
     }
 }
-
index 01dc55c3eeec0433b41fe45073e8231cb55cfcb8..12b56562c84d6b825087ef50c0aab5bf4d0caa31 100644 (file)
@@ -13,7 +13,7 @@ use middle::ty;
 use util::nodemap::FnvHashMap;
 
 use syntax::ast;
-use syntax::ast_util::{walk_pat};
+use syntax::ast_util::walk_pat;
 use syntax::codemap::{Span, DUMMY_SP};
 
 pub type PatIdMap = FnvHashMap<ast::Ident, ast::NodeId>;
@@ -34,8 +34,8 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &ast::Pat) -> bool {
         ast::PatEnum(_, _) |
         ast::PatIdent(_, _, None) |
         ast::PatStruct(..) => {
-            match dm.borrow().get(&pat.id) {
-                Some(&DefVariant(..)) => true,
+            match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
+                Some(DefVariant(..)) => true,
                 _ => false
             }
         }
@@ -49,8 +49,8 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
         ast::PatEnum(_, _) |
         ast::PatIdent(_, _, None) |
         ast::PatStruct(..) => {
-            match dm.borrow().get(&pat.id) {
-                Some(&DefVariant(..)) | Some(&DefStruct(..)) => true,
+            match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
+                Some(DefVariant(..)) | Some(DefStruct(..)) => true,
                 _ => false
             }
         }
@@ -61,8 +61,8 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
 pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
     match pat.node {
         ast::PatIdent(_, _, None) | ast::PatEnum(..) => {
-            match dm.borrow().get(&pat.id) {
-                Some(&DefConst(..)) => true,
+            match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
+                Some(DefConst(..)) => true,
                 _ => false
             }
         }
@@ -119,6 +119,39 @@ pub fn pat_contains_bindings(dm: &DefMap, pat: &ast::Pat) -> bool {
     contains_bindings
 }
 
+/// Checks if the pattern contains any `ref` or `ref mut` bindings.
+pub fn pat_contains_ref_binding(dm: &DefMap, pat: &ast::Pat) -> bool {
+    let mut result = false;
+    pat_bindings(dm, pat, |mode, _, _, _| {
+        match mode {
+            ast::BindingMode::BindByRef(_) => { result = true; }
+            ast::BindingMode::BindByValue(_) => { }
+        }
+    });
+    result
+}
+
+/// Checks if the patterns for this arm contain any `ref` or `ref mut`
+/// bindings.
+pub fn arm_contains_ref_binding(dm: &DefMap, arm: &ast::Arm) -> bool {
+    arm.pats.iter().any(|pat| pat_contains_ref_binding(dm, pat))
+}
+
+/// Checks if the pattern contains any patterns that bind something to
+/// an ident or wildcard, e.g. `foo`, or `Foo(_)`, `foo @ Bar(..)`,
+pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &ast::Pat) -> bool {
+    let mut contains_bindings = false;
+    walk_pat(pat, |p| {
+        if pat_is_binding_or_wild(dm, p) {
+            contains_bindings = true;
+            false // there's at least one binding/wildcard, can short circuit now.
+        } else {
+            true
+        }
+    });
+    contains_bindings
+}
+
 pub fn simple_identifier<'a>(pat: &'a ast::Pat) -> Option<&'a ast::Ident> {
     match pat.node {
         ast::PatIdent(ast::BindByValue(_), ref path1, None) => {
index dd1e32d13a2be07d512d3d506f159b8387d13f51..d8efb5655aaabc2c62ade363978214b7183ecc9a 100644 (file)
@@ -16,7 +16,7 @@ pub use self::PrivateDep::*;
 pub use self::ImportUse::*;
 pub use self::LastPrivate::*;
 
-use util::nodemap::{DefIdSet, NodeMap, NodeSet};
+use util::nodemap::{DefIdSet, NodeSet};
 
 use syntax::ast;
 
@@ -32,10 +32,7 @@ pub type ExternalExports = DefIdSet;
 /// reexporting a public struct doesn't inline the doc).
 pub type PublicItems = NodeSet;
 
-// FIXME: dox
-pub type LastPrivateMap = NodeMap<LastPrivate>;
-
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum LastPrivate {
     LastMod(PrivateDep),
     // `use` directives (imports) can refer to two separate definitions in the
@@ -49,14 +46,14 @@ pub enum LastPrivate {
                type_used: ImportUse},
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum PrivateDep {
     AllPublic,
     DependsOn(ast::DefId),
 }
 
 // How an import is used.
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum ImportUse {
     Unused,       // The import is not used.
     Used,         // The import is used.
index 0af226de251a182afe820b6c8ed4fe350b123d78..1bd45b5fc86017cd5a8afea2c994c2e181397d9e 100644 (file)
@@ -25,21 +25,11 @@ use std::collections::HashSet;
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{is_local, PostExpansionMethod};
-use syntax::attr::{InlineAlways, InlineHint, InlineNever, InlineNone};
+use syntax::ast_util::is_local;
 use syntax::attr;
 use syntax::visit::Visitor;
 use syntax::visit;
 
-// Returns true if the given set of attributes contains the `#[inline]`
-// attribute.
-fn attributes_specify_inlining(attrs: &[ast::Attribute]) -> bool {
-    match attr::find_inline_attr(attrs) {
-        InlineNone | InlineNever => false,
-        InlineAlways | InlineHint => true,
-    }
-}
-
 // Returns true if the given set of generics implies that the item it's
 // associated with must be inlined.
 fn generics_require_inlining(generics: &ast::Generics) -> bool {
@@ -50,7 +40,7 @@ fn generics_require_inlining(generics: &ast::Generics) -> bool {
 // monomorphized or it was marked with `#[inline]`. This will only return
 // true for functions.
 fn item_might_be_inlined(item: &ast::Item) -> bool {
-    if attributes_specify_inlining(&item.attrs[]) {
+    if attr::requests_inline(&item.attrs) {
         return true
     }
 
@@ -63,10 +53,11 @@ fn item_might_be_inlined(item: &ast::Item) -> bool {
     }
 }
 
-fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
+fn method_might_be_inlined(tcx: &ty::ctxt, sig: &ast::MethodSig,
+                           impl_item: &ast::ImplItem,
                            impl_src: ast::DefId) -> bool {
-    if attributes_specify_inlining(&method.attrs[]) ||
-        generics_require_inlining(method.pe_generics()) {
+    if attr::requests_inline(&impl_item.attrs) ||
+        generics_require_inlining(&sig.generics) {
         return true
     }
     if is_local(impl_src) {
@@ -76,13 +67,13 @@ fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
                     item_might_be_inlined(&*item)
                 }
                 Some(..) | None => {
-                    tcx.sess.span_bug(method.span, "impl did is not an item")
+                    tcx.sess.span_bug(impl_item.span, "impl did is not an item")
                 }
             }
         }
     } else {
-        tcx.sess.span_bug(method.span, "found a foreign impl as a parent of a \
-                                        local method")
+        tcx.sess.span_bug(impl_item.span, "found a foreign impl as a parent \
+                                           of a local method")
     }
 }
 
@@ -104,9 +95,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
     fn visit_expr(&mut self, expr: &ast::Expr) {
 
         match expr.node {
-            ast::ExprPath(_) | ast::ExprQPath(_) => {
+            ast::ExprPath(..) => {
                 let def = match self.tcx.def_map.borrow().get(&expr.id) {
-                    Some(&def) => def,
+                    Some(d) => d.full_def(),
                     None => {
                         self.tcx.sess.span_bug(expr.span,
                                                "def ID not in def map?!")
@@ -137,7 +128,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
             }
             ast::ExprMethodCall(..) => {
                 let method_call = ty::MethodCall::expr(expr.id);
-                match (*self.tcx.method_map.borrow())[method_call].origin {
+                match (*self.tcx.method_map.borrow()).get(&method_call).unwrap().origin {
                     ty::MethodStatic(def_id) => {
                         if is_local(def_id) {
                             if self.def_id_represents_local_inlined_item(def_id) {
@@ -191,18 +182,16 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                 }
             }
             Some(ast_map::NodeTraitItem(trait_method)) => {
-                match *trait_method {
-                    ast::RequiredMethod(_) => false,
-                    ast::ProvidedMethod(_) => true,
-                    ast::TypeTraitItem(_) => false,
+                match trait_method.node {
+                    ast::MethodTraitItem(_, ref body) => body.is_some(),
+                    ast::TypeTraitItem(..) => false,
                 }
             }
             Some(ast_map::NodeImplItem(impl_item)) => {
-                match *impl_item {
-                    ast::MethodImplItem(ref method) => {
-                        if generics_require_inlining(method.pe_generics()) ||
-                                attributes_specify_inlining(
-                                    &method.attrs[]) {
+                match impl_item.node {
+                    ast::MethodImplItem(ref sig, _) => {
+                        if generics_require_inlining(&sig.generics) ||
+                                attr::requests_inline(&impl_item.attrs) {
                             true
                         } else {
                             let impl_did = self.tcx
@@ -224,6 +213,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                         }
                     }
                     ast::TypeImplItem(_) => false,
+                    ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
                 }
             }
             Some(_) => false,
@@ -249,7 +239,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                 None => {
                     self.tcx.sess.bug(&format!("found unmapped ID in worklist: \
                                                {}",
-                                              search_item)[])
+                                              search_item))
                 }
             }
         }
@@ -301,7 +291,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     ast::ItemTy(..) | ast::ItemStatic(_, _, _) |
                     ast::ItemMod(..) | ast::ItemForeignMod(..) |
                     ast::ItemImpl(..) | ast::ItemTrait(..) |
-                    ast::ItemStruct(..) | ast::ItemEnum(..) => {}
+                    ast::ItemStruct(..) | ast::ItemEnum(..) |
+                    ast::ItemDefaultImpl(..) => {}
 
                     _ => {
                         self.tcx.sess.span_bug(item.span,
@@ -311,25 +302,26 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                 }
             }
             ast_map::NodeTraitItem(trait_method) => {
-                match *trait_method {
-                    ast::RequiredMethod(..) => {
+                match trait_method.node {
+                    ast::MethodTraitItem(_, None) => {
                         // Keep going, nothing to get exported
                     }
-                    ast::ProvidedMethod(ref method) => {
-                        visit::walk_block(self, &*method.pe_body());
+                    ast::MethodTraitItem(_, Some(ref body)) => {
+                        visit::walk_block(self, body);
                     }
-                    ast::TypeTraitItem(_) => {}
+                    ast::TypeTraitItem(..) => {}
                 }
             }
             ast_map::NodeImplItem(impl_item) => {
-                match *impl_item {
-                    ast::MethodImplItem(ref method) => {
+                match impl_item.node {
+                    ast::MethodImplItem(ref sig, ref body) => {
                         let did = self.tcx.map.get_parent_did(search_item);
-                        if method_might_be_inlined(self.tcx, &**method, did) {
-                            visit::walk_block(self, method.pe_body())
+                        if method_might_be_inlined(self.tcx, sig, impl_item, did) {
+                            visit::walk_block(self, body)
                         }
                     }
                     ast::TypeImplItem(_) => {}
+                    ast::MacImplItem(_) => self.tcx.sess.bug("unexpanded macro")
                 }
             }
             // Nothing to recurse on for these
@@ -342,7 +334,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     .bug(&format!("found unexpected thingy in worklist: {}",
                                  self.tcx
                                      .map
-                                     .node_to_string(search_item))[])
+                                     .node_to_string(search_item)))
             }
         }
     }
index e539f6ae6cb9382898b2167093e91fe5b288e3db..652f661325206fdf89ba15fc839c8e3780fc21c7 100644 (file)
@@ -25,7 +25,7 @@ use std::cell::RefCell;
 use syntax::codemap::{self, Span};
 use syntax::{ast, visit};
 use syntax::ast::{Block, Item, FnDecl, NodeId, Arm, Pat, Stmt, Expr, Local};
-use syntax::ast_util::{stmt_id};
+use syntax::ast_util::stmt_id;
 use syntax::ast_map;
 use syntax::ptr::P;
 use syntax::visit::{Visitor, FnKind};
@@ -136,7 +136,7 @@ impl DestructionScopeData {
          RustcDecodable, Debug, Copy)]
 pub struct BlockRemainder {
     pub block: ast::NodeId,
-    pub first_statement_index: uint,
+    pub first_statement_index: usize,
 }
 
 impl CodeExtent {
@@ -206,56 +206,72 @@ impl CodeExtent {
 }
 
 /// The region maps encode information about region relationships.
-///
-/// - `scope_map` maps from a scope id to the enclosing scope id; this is
-///   usually corresponding to the lexical nesting, though in the case of
-///   closures the parent scope is the innermost conditional expression or repeating
-///   block. (Note that the enclosing scope id for the block
-///   associated with a closure is the closure itself.)
-///
-/// - `var_map` maps from a variable or binding id to the block in which
-///   that variable is declared.
-///
-/// - `free_region_map` maps from a free region `a` to a list of free
-///   regions `bs` such that `a <= b for all b in bs`
-///   - the free region map is populated during type check as we check
-///     each function. See the function `relate_free_regions` for
-///     more information.
-///
-/// - `rvalue_scopes` includes entries for those expressions whose cleanup
-///   scope is larger than the default. The map goes from the expression
-///   id to the cleanup scope id. For rvalues not present in this table,
-///   the appropriate cleanup scope is the innermost enclosing statement,
-///   conditional expression, or repeating block (see `terminating_scopes`).
-///
-/// - `terminating_scopes` is a set containing the ids of each statement,
-///   or conditional/repeating expression. These scopes are calling "terminating
-///   scopes" because, when attempting to find the scope of a temporary, by
-///   default we search up the enclosing scopes until we encounter the
-///   terminating scope. A conditional/repeating
-///   expression is one which is not guaranteed to execute exactly once
-///   upon entering the parent scope. This could be because the expression
-///   only executes conditionally, such as the expression `b` in `a && b`,
-///   or because the expression may execute many times, such as a loop
-///   body. The reason that we distinguish such expressions is that, upon
-///   exiting the parent scope, we cannot statically know how many times
-///   the expression executed, and thus if the expression creates
-///   temporaries we cannot know statically how many such temporaries we
-///   would have to cleanup. Therefore we ensure that the temporaries never
-///   outlast the conditional/repeating expression, preventing the need
-///   for dynamic checks and/or arbitrary amounts of stack space.
 pub struct RegionMaps {
+    /// `scope_map` maps from a scope id to the enclosing scope id;
+    /// this is usually corresponding to the lexical nesting, though
+    /// in the case of closures the parent scope is the innermost
+    /// conditional expression or repeating block. (Note that the
+    /// enclosing scope id for the block associated with a closure is
+    /// the closure itself.)
     scope_map: RefCell<FnvHashMap<CodeExtent, CodeExtent>>,
+
+    /// `var_map` maps from a variable or binding id to the block in
+    /// which that variable is declared.
     var_map: RefCell<NodeMap<CodeExtent>>,
+
+    /// `free_region_map` maps from a free region `a` to a list of
+    /// free regions `bs` such that `a <= b for all b in bs`
+    ///
+    /// NB. the free region map is populated during type check as we
+    /// check each function. See the function `relate_free_regions`
+    /// for more information.
     free_region_map: RefCell<FnvHashMap<FreeRegion, Vec<FreeRegion>>>,
+
+    /// `rvalue_scopes` includes entries for those expressions whose cleanup scope is
+    /// larger than the default. The map goes from the expression id
+    /// to the cleanup scope id. For rvalues not present in this
+    /// table, the appropriate cleanup scope is the innermost
+    /// enclosing statement, conditional expression, or repeating
+    /// block (see `terminating_scopes`).
     rvalue_scopes: RefCell<NodeMap<CodeExtent>>,
+
+    /// `terminating_scopes` is a set containing the ids of each
+    /// statement, or conditional/repeating expression. These scopes
+    /// are calling "terminating scopes" because, when attempting to
+    /// find the scope of a temporary, by default we search up the
+    /// enclosing scopes until we encounter the terminating scope. A
+    /// conditional/repeating expression is one which is not
+    /// guaranteed to execute exactly once upon entering the parent
+    /// scope. This could be because the expression only executes
+    /// conditionally, such as the expression `b` in `a && b`, or
+    /// because the expression may execute many times, such as a loop
+    /// body. The reason that we distinguish such expressions is that,
+    /// upon exiting the parent scope, we cannot statically know how
+    /// many times the expression executed, and thus if the expression
+    /// creates temporaries we cannot know statically how many such
+    /// temporaries we would have to cleanup. Therefore we ensure that
+    /// the temporaries never outlast the conditional/repeating
+    /// expression, preventing the need for dynamic checks and/or
+    /// arbitrary amounts of stack space.
     terminating_scopes: RefCell<FnvHashSet<CodeExtent>>,
+
+    /// Encodes the hierarchy of fn bodies. Every fn body (including
+    /// closures) forms its own distinct region hierarchy, rooted in
+    /// the block that is the fn body. This map points from the id of
+    /// that root block to the id of the root block for the enclosing
+    /// fn, if any. Thus the map structures the fn bodies into a
+    /// hierarchy based on their lexical mapping. This is used to
+    /// handle the relationships between regions in a fn and in a
+    /// closure defined by that fn. See the "Modeling closures"
+    /// section of the README in middle::infer::region_inference for
+    /// more details.
+    fn_tree: RefCell<NodeMap<ast::NodeId>>,
 }
 
 /// Carries the node id for the innermost block or match expression,
 /// for building up the `var_map` which maps ids to the blocks in
 /// which they were declared.
-#[derive(PartialEq, Eq, Debug, Copy)]
+#[derive(PartialEq, Eq, Debug, Copy, Clone)]
 enum InnermostDeclaringBlock {
     None,
     Block(ast::NodeId),
@@ -280,11 +296,11 @@ impl InnermostDeclaringBlock {
 /// Contextual information for declarations introduced by a statement
 /// (i.e. `let`). It carries node-id's for statement and enclosing
 /// block both, as well as the statement's index within the block.
-#[derive(PartialEq, Eq, Debug, Copy)]
+#[derive(PartialEq, Eq, Debug, Copy, Clone)]
 struct DeclaringStatementContext {
     stmt_id: ast::NodeId,
     block_id: ast::NodeId,
-    stmt_index: uint,
+    stmt_index: usize,
 }
 
 impl DeclaringStatementContext {
@@ -296,7 +312,7 @@ impl DeclaringStatementContext {
     }
 }
 
-#[derive(PartialEq, Eq, Debug, Copy)]
+#[derive(PartialEq, Eq, Debug, Copy, Clone)]
 enum InnermostEnclosingExpr {
     None,
     Some(ast::NodeId),
@@ -318,10 +334,20 @@ impl InnermostEnclosingExpr {
     }
 }
 
-#[derive(Debug, Copy)]
+#[derive(Debug, Copy, Clone)]
 pub struct Context {
+    /// the root of the current region tree. This is typically the id
+    /// of the innermost fn body. Each fn forms its own disjoint tree
+    /// in the region hierarchy. These fn bodies are themselves
+    /// arranged into a tree. See the "Modeling closures" section of
+    /// the README in middle::infer::region_inference for more
+    /// details.
+    root_id: Option<ast::NodeId>,
+
+    /// the scope that contains any new variables declared
     var_parent: InnermostDeclaringBlock,
 
+    /// region parent of expressions etc
     parent: InnermostEnclosingExpr,
 }
 
@@ -379,19 +405,40 @@ impl RegionMaps {
         self.free_region_map.borrow_mut().insert(sub, vec!(sup));
     }
 
+    /// Records that `sub_fn` is defined within `sup_fn`. These ids
+    /// should be the id of the block that is the fn body, which is
+    /// also the root of the region hierarchy for that fn.
+    fn record_fn_parent(&self, sub_fn: ast::NodeId, sup_fn: ast::NodeId) {
+        debug!("record_fn_parent(sub_fn={:?}, sup_fn={:?})", sub_fn, sup_fn);
+        assert!(sub_fn != sup_fn);
+        let previous = self.fn_tree.borrow_mut().insert(sub_fn, sup_fn);
+        assert!(previous.is_none());
+    }
+
+    fn fn_is_enclosed_by(&self, mut sub_fn: ast::NodeId, sup_fn: ast::NodeId) -> bool {
+        let fn_tree = self.fn_tree.borrow();
+        loop {
+            if sub_fn == sup_fn { return true; }
+            match fn_tree.get(&sub_fn) {
+                Some(&s) => { sub_fn = s; }
+                None => { return false; }
+            }
+        }
+    }
+
     pub fn record_encl_scope(&self, sub: CodeExtent, sup: CodeExtent) {
         debug!("record_encl_scope(sub={:?}, sup={:?})", sub, sup);
         assert!(sub != sup);
         self.scope_map.borrow_mut().insert(sub, sup);
     }
 
-    pub fn record_var_scope(&self, var: ast::NodeId, lifetime: CodeExtent) {
+    fn record_var_scope(&self, var: ast::NodeId, lifetime: CodeExtent) {
         debug!("record_var_scope(sub={:?}, sup={:?})", var, lifetime);
         assert!(var != lifetime.node_id());
         self.var_map.borrow_mut().insert(var, lifetime);
     }
 
-    pub fn record_rvalue_scope(&self, var: ast::NodeId, lifetime: CodeExtent) {
+    fn record_rvalue_scope(&self, var: ast::NodeId, lifetime: CodeExtent) {
         debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime);
         assert!(var != lifetime.node_id());
         self.rvalue_scopes.borrow_mut().insert(var, lifetime);
@@ -400,7 +447,7 @@ impl RegionMaps {
     /// Records that a scope is a TERMINATING SCOPE. Whenever we create automatic temporaries --
     /// e.g. by an expression like `a().f` -- they will be freed within the innermost terminating
     /// scope.
-    pub fn mark_as_terminating_scope(&self, scope_id: CodeExtent) {
+    fn mark_as_terminating_scope(&self, scope_id: CodeExtent) {
         debug!("record_terminating_scope(scope_id={:?})", scope_id);
         self.terminating_scopes.borrow_mut().insert(scope_id);
     }
@@ -560,15 +607,15 @@ impl RegionMaps {
     pub fn nearest_common_ancestor(&self,
                                    scope_a: CodeExtent,
                                    scope_b: CodeExtent)
-                                   -> Option<CodeExtent> {
-        if scope_a == scope_b { return Some(scope_a); }
+                                   -> CodeExtent {
+        if scope_a == scope_b { return scope_a; }
 
         let a_ancestors = ancestors_of(self, scope_a);
         let b_ancestors = ancestors_of(self, scope_b);
         let mut a_index = a_ancestors.len() - 1;
         let mut b_index = b_ancestors.len() - 1;
 
-        // Here, ~[ab]_ancestors is a vector going from narrow to broad.
+        // Here, [ab]_ancestors is a vector going from narrow to broad.
         // The end of each vector will be the item where the scope is
         // defined; if there are any common ancestors, then the tails of
         // the vector will be the same.  So basically we want to walk
@@ -577,23 +624,47 @@ impl RegionMaps {
         // then the corresponding scope is a superscope of the other.
 
         if a_ancestors[a_index] != b_ancestors[b_index] {
-            return None;
+            // In this case, the two regions belong to completely
+            // different functions.  Compare those fn for lexical
+            // nesting. The reasoning behind this is subtle.  See the
+            // "Modeling closures" section of the README in
+            // middle::infer::region_inference for more details.
+            let a_root_scope = a_ancestors[a_index];
+            let b_root_scope = a_ancestors[a_index];
+            return match (a_root_scope, b_root_scope) {
+                (CodeExtent::DestructionScope(a_root_id),
+                 CodeExtent::DestructionScope(b_root_id)) => {
+                    if self.fn_is_enclosed_by(a_root_id, b_root_id) {
+                        // `a` is enclosed by `b`, hence `b` is the ancestor of everything in `a`
+                        scope_b
+                    } else if self.fn_is_enclosed_by(b_root_id, a_root_id) {
+                        // `b` is enclosed by `a`, hence `a` is the ancestor of everything in `b`
+                        scope_a
+                    } else {
+                        // neither fn encloses the other
+                        unreachable!()
+                    }
+                }
+                _ => {
+                    // root ids are always Misc right now
+                    unreachable!()
+                }
+            };
         }
 
         loop {
             // Loop invariant: a_ancestors[a_index] == b_ancestors[b_index]
             // for all indices between a_index and the end of the array
-            if a_index == 0 { return Some(scope_a); }
-            if b_index == 0 { return Some(scope_b); }
+            if a_index == 0 { return scope_a; }
+            if b_index == 0 { return scope_b; }
             a_index -= 1;
             b_index -= 1;
             if a_ancestors[a_index] != b_ancestors[b_index] {
-                return Some(a_ancestors[a_index + 1]);
+                return a_ancestors[a_index + 1];
             }
         }
 
-        fn ancestors_of(this: &RegionMaps, scope: CodeExtent)
-            -> Vec<CodeExtent> {
+        fn ancestors_of(this: &RegionMaps, scope: CodeExtent) -> Vec<CodeExtent> {
             // debug!("ancestors_of(scope={:?})", scope);
             let mut result = vec!(scope);
             let mut scope = scope;
@@ -643,6 +714,7 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block) {
     let prev_cx = visitor.cx;
 
     let blk_scope = CodeExtent::Misc(blk.id);
+
     // If block was previously marked as a terminating scope during
     // the recursive visit of its parent node in the AST, then we need
     // to account for the destruction scope representing the extent of
@@ -682,6 +754,7 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block) {
     // itself has returned.
 
     visitor.cx = Context {
+        root_id: prev_cx.root_id,
         var_parent: InnermostDeclaringBlock::Block(blk.id),
         parent: InnermostEnclosingExpr::Some(blk.id),
     };
@@ -708,6 +781,7 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block) {
                 record_superlifetime(
                     visitor, declaring.to_code_extent(), statement.span);
                 visitor.cx = Context {
+                    root_id: prev_cx.root_id,
                     var_parent: InnermostDeclaringBlock::Statement(declaring),
                     parent: InnermostEnclosingExpr::Statement(declaring),
                 };
@@ -852,7 +926,7 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
                 // The idea is that call.callee_id represents *the time when
                 // the invoked function is actually running* and call.id
                 // represents *the time to prepare the arguments and make the
-                // call*.  See the section "Borrows in Calls" borrowck/doc.rs
+                // call*.  See the section "Borrows in Calls" borrowck/README.md
                 // for an extended explanation of why this distinction is
                 // important.
                 //
@@ -1101,6 +1175,7 @@ fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &ast::Item) {
     // Items create a new outer block scope as far as we're concerned.
     let prev_cx = visitor.cx;
     visitor.cx = Context {
+        root_id: None,
         var_parent: InnermostDeclaringBlock::None,
         parent: InnermostEnclosingExpr::None
     };
@@ -1109,7 +1184,7 @@ fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &ast::Item) {
 }
 
 fn resolve_fn(visitor: &mut RegionResolutionVisitor,
-              fk: FnKind,
+              _: FnKind,
               decl: &ast::FnDecl,
               body: &ast::Block,
               sp: Span,
@@ -1125,42 +1200,36 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
 
     let body_scope = CodeExtent::from_node_id(body.id);
     visitor.region_maps.mark_as_terminating_scope(body_scope);
+
     let dtor_scope = CodeExtent::DestructionScope(body.id);
     visitor.region_maps.record_encl_scope(body_scope, dtor_scope);
+
     record_superlifetime(visitor, dtor_scope, body.span);
 
+    if let Some(root_id) = visitor.cx.root_id {
+        visitor.region_maps.record_fn_parent(body.id, root_id);
+    }
+
     let outer_cx = visitor.cx;
 
     // The arguments and `self` are parented to the body of the fn.
     visitor.cx = Context {
+        root_id: Some(body.id),
         parent: InnermostEnclosingExpr::Some(body.id),
         var_parent: InnermostDeclaringBlock::Block(body.id)
     };
     visit::walk_fn_decl(visitor, decl);
 
-    // The body of the fn itself is either a root scope (top-level fn)
-    // or it continues with the inherited scope (closures).
-    match fk {
-        visit::FkItemFn(..) | visit::FkMethod(..) => {
-            visitor.cx = Context {
-                parent: InnermostEnclosingExpr::None,
-                var_parent: InnermostDeclaringBlock::None
-            };
-            visitor.visit_block(body);
-            visitor.cx = outer_cx;
-        }
-        visit::FkFnBlock(..) => {
-            // FIXME(#3696) -- at present we are place the closure body
-            // within the region hierarchy exactly where it appears lexically.
-            // This is wrong because the closure may live longer
-            // than the enclosing expression. We should probably fix this,
-            // but the correct fix is a bit subtle, and I am also not sure
-            // that the present approach is unsound -- it may not permit
-            // any illegal programs. See issue for more details.
-            visitor.cx = outer_cx;
-            visitor.visit_block(body);
-        }
-    }
+    // The body of the every fn is a root scope.
+    visitor.cx = Context {
+        root_id: Some(body.id),
+        parent: InnermostEnclosingExpr::None,
+        var_parent: InnermostDeclaringBlock::None
+    };
+    visitor.visit_block(body);
+
+    // Restore context we had at the start.
+    visitor.cx = outer_cx;
 }
 
 impl<'a, 'v> Visitor<'v> for RegionResolutionVisitor<'a> {
@@ -1201,12 +1270,14 @@ pub fn resolve_crate(sess: &Session, krate: &ast::Crate) -> RegionMaps {
         free_region_map: RefCell::new(FnvHashMap()),
         rvalue_scopes: RefCell::new(NodeMap()),
         terminating_scopes: RefCell::new(FnvHashSet()),
+        fn_tree: RefCell::new(NodeMap()),
     };
     {
         let mut visitor = RegionResolutionVisitor {
             sess: sess,
             region_maps: &maps,
             cx: Context {
+                root_id: None,
                 parent: InnermostEnclosingExpr::None,
                 var_parent: InnermostDeclaringBlock::None,
             }
@@ -1223,6 +1294,7 @@ pub fn resolve_inlined_item(sess: &Session,
         sess: sess,
         region_maps: region_maps,
         cx: Context {
+            root_id: None,
             parent: InnermostEnclosingExpr::None,
             var_parent: InnermostDeclaringBlock::None
         }
index 3ba08c1032031075224aaa0dddcd1ac67902f5d4..a3d71c989bfdf8303c65e66e74db66c8a0a030e1 100644 (file)
@@ -28,7 +28,7 @@ use syntax::ast;
 use syntax::codemap::Span;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
-use syntax::print::pprust::{lifetime_to_string};
+use syntax::print::pprust::lifetime_to_string;
 use syntax::visit;
 use syntax::visit::Visitor;
 use util::nodemap::NodeMap;
@@ -115,6 +115,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
                 ast::ItemUse(_) |
                 ast::ItemMod(..) |
                 ast::ItemMac(..) |
+                ast::ItemDefaultImpl(..) |
                 ast::ItemForeignMod(..) |
                 ast::ItemStatic(..) |
                 ast::ItemConst(..) => {
@@ -141,12 +142,16 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
     fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
                 b: &'v ast::Block, s: Span, _: ast::NodeId) {
         match fk {
-            visit::FkItemFn(_, generics, _, _) |
-            visit::FkMethod(_, generics, _) => {
+            visit::FkItemFn(_, generics, _, _) => {
                 self.visit_early_late(subst::FnSpace, generics, |this| {
                     visit::walk_fn(this, fk, fd, b, s)
                 })
             }
+            visit::FkMethod(_, sig) => {
+                self.visit_early_late(subst::FnSpace, &sig.generics, |this| {
+                    visit::walk_fn(this, fk, fd, b, s)
+                })
+            }
             visit::FkFnBlock(..) => {
                 visit::walk_fn(self, fk, fd, b, s)
             }
@@ -164,13 +169,13 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
                     visit::walk_ty(this, ty);
                 });
             }
-            ast::TyPath(ref path, id) => {
+            ast::TyPath(None, ref path) => {
                 // if this path references a trait, then this will resolve to
                 // a trait ref, which introduces a binding scope.
-                match self.def_map.borrow().get(&id) {
-                    Some(&def::DefTrait(..)) => {
+                match self.def_map.borrow().get(&ty.id).map(|d| (d.base_def, d.depth)) {
+                    Some((def::DefTrait(..), 0)) => {
                         self.with(LateScope(&Vec::new(), self.scope), |_, this| {
-                            this.visit_path(path, id);
+                            this.visit_path(path, ty.id);
                         });
                     }
                     _ => {
@@ -184,10 +189,14 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
         }
     }
 
-    fn visit_ty_method(&mut self, m: &ast::TypeMethod) {
-        self.visit_early_late(
-            subst::FnSpace, &m.generics,
-            |this| visit::walk_ty_method(this, m))
+    fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
+        if let ast::MethodTraitItem(ref sig, None) = trait_item.node {
+            self.visit_early_late(
+                subst::FnSpace, &sig.generics,
+                |this| visit::walk_trait_item(this, trait_item))
+        } else {
+            visit::walk_trait_item(self, trait_item);
+        }
     }
 
     fn visit_block(&mut self, b: &ast::Block) {
@@ -269,16 +278,12 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
                 for lifetime in &trait_ref.bound_lifetimes {
                     this.visit_lifetime_def(lifetime);
                 }
-                this.visit_trait_ref(&trait_ref.trait_ref)
+                visit::walk_path(this, &trait_ref.trait_ref.path)
             })
         } else {
             self.visit_trait_ref(&trait_ref.trait_ref)
         }
     }
-
-    fn visit_trait_ref(&mut self, trait_ref: &ast::TraitRef) {
-        self.visit_path(&trait_ref.path, trait_ref.ref_id);
-    }
 }
 
 impl<'a> LifetimeContext<'a> {
index 0a0f555f977698e7581c1435489bc5bd9dfa6781..7043b2613605d4b9ddf16bbab1d2d0550c9b454a 100644 (file)
@@ -22,12 +22,11 @@ use syntax::codemap::{Span, DUMMY_SP};
 use syntax::{attr, visit};
 use syntax::ast;
 use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant};
-use syntax::ast::{Item, RequiredMethod, ProvidedMethod, TraitItem};
-use syntax::ast::{TypeMethod, Method, Generics, StructField, TypeTraitItem};
+use syntax::ast::{Item, Generics, StructField};
 use syntax::ast_util::is_local;
 use syntax::attr::{Stability, AttrMetaMethods};
-use syntax::visit::{FnKind, FkMethod, Visitor};
-use syntax::feature_gate::emit_feature_warn;
+use syntax::visit::{FnKind, Visitor};
+use syntax::feature_gate::emit_feature_err;
 use util::nodemap::{NodeMap, DefIdMap, FnvHashSet, FnvHashMap};
 use util::ppaux::Repr;
 
@@ -58,8 +57,10 @@ impl<'a> Annotator<'a> {
                    attrs: &Vec<Attribute>, item_sp: Span, f: F, required: bool) where
         F: FnOnce(&mut Annotator),
     {
+        debug!("annotate(id = {:?}, attrs = {:?})", id, attrs);
         match attr::find_stability(self.sess.diagnostic(), attrs, item_sp) {
             Some(stab) => {
+                debug!("annotate: found {:?}", stab);
                 self.index.local.insert(id, stab.clone());
 
                 // Don't inherit #[stable(feature = "rust1", since = "1.0.0")]
@@ -72,6 +73,8 @@ impl<'a> Annotator<'a> {
                 }
             }
             None => {
+                debug!("annotate: not found, use_parent = {:?}, parent = {:?}",
+                       use_parent, self.parent);
                 if use_parent {
                     if let Some(stab) = self.parent.clone() {
                         self.index.local.insert(id, stab);
@@ -120,31 +123,20 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
         }
     }
 
-    fn visit_fn(&mut self, fk: FnKind<'v>, _: &'v FnDecl,
-                _: &'v Block, sp: Span, _: NodeId) {
-        if let FkMethod(_, _, meth) = fk {
-            // Methods are not already annotated, so we annotate it
-            self.annotate(meth.id, true, &meth.attrs, sp, |_| {}, true);
-        }
+    fn visit_fn(&mut self, _: FnKind<'v>, _: &'v FnDecl,
+                _: &'v Block, _: Span, _: NodeId) {
         // Items defined in a function body have no reason to have
         // a stability attribute, so we don't recurse.
     }
 
-    fn visit_trait_item(&mut self, t: &TraitItem) {
-        let (id, attrs, sp) = match *t {
-            RequiredMethod(TypeMethod {id, ref attrs, span, ..}) => (id, attrs, span),
-
-            // work around lack of pattern matching for @ types
-            ProvidedMethod(ref method) => {
-                match **method {
-                    Method {ref attrs, id, span, ..} => (id, attrs, span),
-                }
-            }
+    fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
+        self.annotate(ti.id, true, &ti.attrs, ti.span,
+                      |v| visit::walk_trait_item(v, ti), true);
+    }
 
-            TypeTraitItem(ref typedef) => (typedef.ty_param.id, &typedef.attrs,
-                                           typedef.ty_param.span),
-        };
-        self.annotate(id, true, attrs, sp, |v| visit::walk_trait_item(v, t), true);
+    fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
+        self.annotate(ii.id, true, &ii.attrs, ii.span,
+                      |v| visit::walk_impl_item(v, ii), true);
     }
 
     fn visit_variant(&mut self, var: &Variant, g: &'v Generics) {
@@ -181,7 +173,7 @@ impl Index {
     pub fn new(krate: &Crate) -> Index {
         let mut staged_api = false;
         for attr in &krate.attrs {
-            if &attr.name()[] == "staged_api" {
+            if &attr.name()[..] == "staged_api" {
                 match attr.node.value.node {
                     ast::MetaWord(_) => {
                         attr::mark_used(attr);
@@ -245,7 +237,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                         None => format!("use of unstable library feature '{}'", &feature)
                     };
 
-                    emit_feature_warn(&self.tcx.sess.parse_sess.span_diagnostic,
+                    emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic,
                                       &feature, span, &msg);
                 }
             }
@@ -299,6 +291,12 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Checker<'a, 'tcx> {
                    &mut |id, sp, stab| self.check(id, sp, stab));
         visit::walk_path(self, path)
     }
+
+    fn visit_pat(&mut self, pat: &ast::Pat) {
+        check_pat(self.tcx, pat,
+                  &mut |id, sp, stab| self.check(id, sp, stab));
+        visit::walk_pat(self, pat)
+    }
 }
 
 /// Helper for discovering nodes to check for stability
@@ -321,26 +319,15 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool,
         // individually as it's possible to have a stable trait with unstable
         // items.
         ast::ItemImpl(_, _, _, Some(ref t), _, ref impl_items) => {
-            let trait_did = tcx.def_map.borrow()[t.ref_id].def_id();
+            let trait_did = tcx.def_map.borrow().get(&t.ref_id).unwrap().def_id();
             let trait_items = ty::trait_items(tcx, trait_did);
 
             for impl_item in impl_items {
-                let (ident, span) = match *impl_item {
-                    ast::MethodImplItem(ref method) => {
-                        (match method.node {
-                            ast::MethDecl(ident, _, _, _, _, _, _, _) => ident,
-                            ast::MethMac(..) => unreachable!(),
-                        }, method.span)
-                    }
-                    ast::TypeImplItem(ref typedef) => {
-                        (typedef.ident, typedef.span)
-                    }
-                };
                 let item = trait_items.iter().find(|item| {
-                    item.name() == ident.name
+                    item.name() == impl_item.ident.name
                 }).unwrap();
                 if warn_about_defns {
-                    maybe_do_stability_check(tcx, item.def_id(), span, cb);
+                    maybe_do_stability_check(tcx, item.def_id(), impl_item.span, cb);
                 }
             }
         }
@@ -352,8 +339,6 @@ pub fn check_item(tcx: &ty::ctxt, item: &ast::Item, warn_about_defns: bool,
 /// Helper for discovering nodes to check for stability
 pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
                   cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
-    if is_internal(tcx, e.span) { return; }
-
     let span;
     let id = match e.node {
         ast::ExprMethodCall(i, _, _) => {
@@ -385,6 +370,76 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
                 None => return
             }
         }
+        ast::ExprField(ref base_e, ref field) => {
+            span = field.span;
+            match ty::expr_ty_adjusted(tcx, base_e).sty {
+                ty::ty_struct(did, _) => {
+                    ty::lookup_struct_fields(tcx, did)
+                        .iter()
+                        .find(|f| f.name == field.node.name)
+                        .unwrap_or_else(|| {
+                            tcx.sess.span_bug(field.span,
+                                              "stability::check_expr: unknown named field access")
+                        })
+                        .id
+                }
+                _ => tcx.sess.span_bug(e.span,
+                                       "stability::check_expr: named field access on non-struct")
+            }
+        }
+        ast::ExprTupField(ref base_e, ref field) => {
+            span = field.span;
+            match ty::expr_ty_adjusted(tcx, base_e).sty {
+                ty::ty_struct(did, _) => {
+                    ty::lookup_struct_fields(tcx, did)
+                        .get(field.node)
+                        .unwrap_or_else(|| {
+                            tcx.sess.span_bug(field.span,
+                                              "stability::check_expr: unknown unnamed field access")
+                        })
+                        .id
+                }
+                ty::ty_tup(..) => return,
+                _ => tcx.sess.span_bug(e.span,
+                                       "stability::check_expr: unnamed field access on \
+                                        something other than a tuple or struct")
+            }
+        }
+        ast::ExprStruct(_, ref expr_fields, _) => {
+            let type_ = ty::expr_ty(tcx, e);
+            match type_.sty {
+                ty::ty_struct(did, _) => {
+                    let struct_fields = ty::lookup_struct_fields(tcx, did);
+                    // check the stability of each field that appears
+                    // in the construction expression.
+                    for field in expr_fields {
+                        let did = struct_fields
+                            .iter()
+                            .find(|f| f.name == field.ident.node.name)
+                            .unwrap_or_else(|| {
+                                tcx.sess.span_bug(field.span,
+                                                  "stability::check_expr: unknown named \
+                                                   field access")
+                            })
+                            .id;
+                        maybe_do_stability_check(tcx, did, field.span, cb);
+                    }
+
+                    // we're done.
+                    return
+                }
+                // we don't look at stability attributes on
+                // struct-like enums (yet...), but it's definitely not
+                // a bug to have construct one.
+                ty::ty_enum(..) => return,
+                _ => {
+                    tcx.sess.span_bug(e.span,
+                                      &format!("stability::check_expr: struct construction \
+                                                of non-struct, type {:?}",
+                                               type_.repr(tcx)));
+                }
+            }
+        }
         _ => return
     };
 
@@ -393,23 +448,67 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
 
 pub fn check_path(tcx: &ty::ctxt, path: &ast::Path, id: ast::NodeId,
                   cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
-    let did = match tcx.def_map.borrow().get(&id) {
-        Some(&def::DefPrimTy(..)) => return,
-        Some(def) => def.def_id(),
-        None => return
+    match tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
+        Some(def::DefPrimTy(..)) => {}
+        Some(def) => {
+            maybe_do_stability_check(tcx, def.def_id(), path.span, cb);
+        }
+        None => {}
+    }
+
+}
+
+pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat,
+                 cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
+    debug!("check_pat(pat = {:?})", pat);
+    if is_internal(tcx, pat.span) { return; }
+
+    let did = match ty::pat_ty_opt(tcx, pat) {
+        Some(&ty::TyS { sty: ty::ty_struct(did, _), .. }) => did,
+        Some(_) | None => return,
     };
-    maybe_do_stability_check(tcx, did, path.span, cb)
+    let struct_fields = ty::lookup_struct_fields(tcx, did);
+    match pat.node {
+        // Foo(a, b, c)
+        ast::PatEnum(_, Some(ref pat_fields)) => {
+            for (field, struct_field) in pat_fields.iter().zip(struct_fields.iter()) {
+                // a .. pattern is fine, but anything positional is
+                // not.
+                if let ast::PatWild(ast::PatWildMulti) = field.node {
+                    continue
+                }
+                maybe_do_stability_check(tcx, struct_field.id, field.span, cb)
+            }
+        }
+        // Foo { a, b, c }
+        ast::PatStruct(_, ref pat_fields, _) => {
+            for field in pat_fields {
+                let did = struct_fields
+                    .iter()
+                    .find(|f| f.name == field.node.ident.name)
+                    .unwrap_or_else(|| {
+                        tcx.sess.span_bug(field.span,
+                                          "stability::check_pat: unknown named field access")
+                    })
+                    .id;
+                maybe_do_stability_check(tcx, did, field.span, cb);
+            }
+        }
+        // everything else is fine.
+        _ => {}
+    }
 }
 
 fn maybe_do_stability_check(tcx: &ty::ctxt, id: ast::DefId, span: Span,
                             cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
     if !is_staged_api(tcx, id) { return  }
+    if is_internal(tcx, span) { return }
     let ref stability = lookup(tcx, id);
     cb(id, span, stability);
 }
 
 fn is_internal(tcx: &ty::ctxt, span: Span) -> bool {
-    tcx.sess.codemap().span_is_internal(span)
+    tcx.sess.codemap().span_allows_unstable(span)
 }
 
 fn is_staged_api(tcx: &ty::ctxt, id: DefId) -> bool {
index 04fd03ab34224a3af51bfeed5ab69aad2c355bf4..e2ebe2bc0f1e53fa1ad1cb39aebf17f116469f9b 100644 (file)
@@ -98,7 +98,7 @@ impl<'tcx> Substs<'tcx> {
     }
 
     pub fn type_for_def(&self, ty_param_def: &ty::TypeParameterDef) -> Ty<'tcx> {
-        *self.types.get(ty_param_def.space, ty_param_def.index as uint)
+        *self.types.get(ty_param_def.space, ty_param_def.index as usize)
     }
 
     pub fn has_regions_escaping_depth(&self, depth: u32) -> bool {
@@ -193,7 +193,7 @@ impl ParamSpace {
         [TypeSpace, SelfSpace, FnSpace]
     }
 
-    pub fn to_uint(self) -> uint {
+    pub fn to_uint(self) -> usize {
         match self {
             TypeSpace => 0,
             SelfSpace => 1,
@@ -201,7 +201,7 @@ impl ParamSpace {
         }
     }
 
-    pub fn from_uint(u: uint) -> ParamSpace {
+    pub fn from_uint(u: usize) -> ParamSpace {
         match u {
             0 => TypeSpace,
             1 => SelfSpace,
@@ -226,8 +226,8 @@ pub struct VecPerParamSpace<T> {
     // AF(self) = (self.content[..self.type_limit],
     //             self.content[self.type_limit..self.self_limit],
     //             self.content[self.self_limit..])
-    type_limit: uint,
-    self_limit: uint,
+    type_limit: usize,
+    self_limit: usize,
     content: Vec<T>,
 }
 
@@ -251,7 +251,7 @@ impl<T: fmt::Debug> fmt::Debug for VecPerParamSpace<T> {
 }
 
 impl<T> VecPerParamSpace<T> {
-    fn limits(&self, space: ParamSpace) -> (uint, uint) {
+    fn limits(&self, space: ParamSpace) -> (usize, usize) {
         match space {
             TypeSpace => (0, self.type_limit),
             SelfSpace => (self.type_limit, self.self_limit),
@@ -290,7 +290,7 @@ impl<T> VecPerParamSpace<T> {
         }
     }
 
-    fn new_internal(content: Vec<T>, type_limit: uint, self_limit: uint)
+    fn new_internal(content: Vec<T>, type_limit: usize, self_limit: usize)
                     -> VecPerParamSpace<T>
     {
         VecPerParamSpace {
@@ -343,7 +343,7 @@ impl<T> VecPerParamSpace<T> {
         }
     }
 
-    pub fn truncate(&mut self, space: ParamSpace, len: uint) {
+    pub fn truncate(&mut self, space: ParamSpace, len: usize) {
         // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
         while self.len(space) > len {
             self.pop(space);
@@ -364,7 +364,7 @@ impl<T> VecPerParamSpace<T> {
         if v.len() == 0 { None } else { Some(&v[0]) }
     }
 
-    pub fn len(&self, space: ParamSpace) -> uint {
+    pub fn len(&self, space: ParamSpace) -> usize {
         self.get_slice(space).len()
     }
 
@@ -384,13 +384,13 @@ impl<T> VecPerParamSpace<T> {
 
     pub fn opt_get<'a>(&'a self,
                        space: ParamSpace,
-                       index: uint)
+                       index: usize)
                        -> Option<&'a T> {
         let v = self.get_slice(space);
         if index < v.len() { Some(&v[index]) } else { None }
     }
 
-    pub fn get<'a>(&'a self, space: ParamSpace, index: uint) -> &'a T {
+    pub fn get<'a>(&'a self, space: ParamSpace, index: usize) -> &'a T {
         &self.get_slice(space)[index]
     }
 
@@ -441,7 +441,7 @@ impl<T> VecPerParamSpace<T> {
     }
 
     pub fn map_enumerated<U, P>(&self, pred: P) -> VecPerParamSpace<U> where
-        P: FnMut((ParamSpace, uint, &T)) -> U,
+        P: FnMut((ParamSpace, usize, &T)) -> U,
     {
         let result = self.iter_enumerated().map(pred).collect();
         VecPerParamSpace::new_internal(result,
@@ -487,8 +487,8 @@ impl<T> VecPerParamSpace<T> {
 #[derive(Clone)]
 pub struct EnumeratedItems<'a,T:'a> {
     vec: &'a VecPerParamSpace<T>,
-    space_index: uint,
-    elem_index: uint
+    space_index: usize,
+    elem_index: usize
 }
 
 impl<'a,T> EnumeratedItems<'a,T> {
@@ -511,9 +511,9 @@ impl<'a,T> EnumeratedItems<'a,T> {
 }
 
 impl<'a,T> Iterator for EnumeratedItems<'a,T> {
-    type Item = (ParamSpace, uint, &'a T);
+    type Item = (ParamSpace, usize, &'a T);
 
-    fn next(&mut self) -> Option<(ParamSpace, uint, &'a T)> {
+    fn next(&mut self) -> Option<(ParamSpace, usize, &'a T)> {
         let spaces = ParamSpace::all();
         if self.space_index < spaces.len() {
             let space = spaces[self.space_index];
@@ -598,7 +598,7 @@ struct SubstFolder<'a, 'tcx: 'a> {
     root_ty: Option<Ty<'tcx>>,
 
     // Depth of type stack
-    ty_stack_depth: uint,
+    ty_stack_depth: usize,
 
     // Number of region binders we have passed through while doing the substitution
     region_binders_passed: u32,
@@ -626,7 +626,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
                 match self.substs.regions {
                     ErasedRegions => ty::ReStatic,
                     NonerasedRegions(ref regions) =>
-                        match regions.opt_get(space, i as uint) {
+                        match regions.opt_get(space, i as usize) {
                             Some(&r) => {
                                 self.shift_region_through_binders(r)
                             }
@@ -639,7 +639,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
                                      (space={:?}, index={})",
                                     region_name.as_str(),
                                     self.root_ty.repr(self.tcx()),
-                                    space, i)[]);
+                                    space, i));
                             }
                         }
                 }
@@ -682,7 +682,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
 impl<'a,'tcx> SubstFolder<'a,'tcx> {
     fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
         // Look up the type in the substitutions. It really should be in there.
-        let opt_ty = self.substs.types.opt_get(p.space, p.idx as uint);
+        let opt_ty = self.substs.types.opt_get(p.space, p.idx as usize);
         let ty = match opt_ty {
             Some(t) => *t,
             None => {
@@ -696,7 +696,7 @@ impl<'a,'tcx> SubstFolder<'a,'tcx> {
                             p.space,
                             p.idx,
                             self.root_ty.repr(self.tcx()),
-                            self.substs.repr(self.tcx()))[]);
+                            self.substs.repr(self.tcx())));
             }
         };
 
index e199a60c370e30cf732f0dbb2d3a300f9276e3f8..2f2db8f38bd87e00ee12b8373c8edb5b302943e7 100644 (file)
@@ -8,24 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! See `doc.rs` for high-level documentation
+//! See `README.md` for high-level documentation
 
 use super::Normalized;
 use super::SelectionContext;
-use super::{ObligationCause};
+use super::ObligationCause;
 use super::PredicateObligation;
 use super::project;
 use super::util;
 
-use middle::subst::{Subst, TypeSpace};
+use middle::subst::{Subst, Substs, TypeSpace};
 use middle::ty::{self, ToPolyTraitRef, Ty};
 use middle::infer::{self, InferCtxt};
-use std::collections::HashSet;
 use std::rc::Rc;
 use syntax::ast;
-use syntax::codemap::DUMMY_SP;
+use syntax::codemap::{DUMMY_SP, Span};
 use util::ppaux::Repr;
 
+#[derive(Copy, Clone)]
+struct ParamIsLocal(bool);
+
 /// True if there exist types that satisfy both of the two given impls.
 pub fn overlapping_impls(infcx: &InferCtxt,
                          impl1_def_id: ast::DefId,
@@ -52,8 +54,21 @@ fn overlap(selcx: &mut SelectionContext,
            b_def_id: ast::DefId)
            -> bool
 {
-    let (a_trait_ref, a_obligations) = impl_trait_ref_and_oblig(selcx, a_def_id);
-    let (b_trait_ref, b_obligations) = impl_trait_ref_and_oblig(selcx, b_def_id);
+    debug!("overlap(a_def_id={}, b_def_id={})",
+           a_def_id.repr(selcx.tcx()),
+           b_def_id.repr(selcx.tcx()));
+
+    let (a_trait_ref, a_obligations) = impl_trait_ref_and_oblig(selcx,
+                                                                a_def_id,
+                                                                util::free_substs_for_impl);
+
+    let (b_trait_ref, b_obligations) = impl_trait_ref_and_oblig(selcx,
+                                                                b_def_id,
+                                                                util::fresh_type_vars_for_impl);
+
+    debug!("overlap: a_trait_ref={}", a_trait_ref.repr(selcx.tcx()));
+
+    debug!("overlap: b_trait_ref={}", b_trait_ref.repr(selcx.tcx()));
 
     // Does `a <: b` hold? If not, no overlap.
     if let Err(_) = infer::mk_sub_poly_trait_refs(selcx.infcx(),
@@ -64,21 +79,71 @@ fn overlap(selcx: &mut SelectionContext,
         return false;
     }
 
+    debug!("overlap: subtraitref check succeeded");
+
     // Are any of the obligations unsatisfiable? If so, no overlap.
-    a_obligations.iter()
-                 .chain(b_obligations.iter())
-                 .all(|o| selcx.evaluate_obligation(o))
+    let tcx = selcx.tcx();
+    let infcx = selcx.infcx();
+    let opt_failing_obligation =
+        a_obligations.iter()
+                     .chain(b_obligations.iter())
+                     .map(|o| infcx.resolve_type_vars_if_possible(o))
+                     .find(|o| !selcx.evaluate_obligation(o));
+
+    if let Some(failing_obligation) = opt_failing_obligation {
+        debug!("overlap: obligation unsatisfiable {}", failing_obligation.repr(tcx));
+        return false
+    }
+
+    true
+}
+
+pub fn trait_ref_is_knowable<'tcx>(tcx: &ty::ctxt<'tcx>, trait_ref: &ty::TraitRef<'tcx>) -> bool
+{
+    debug!("trait_ref_is_knowable(trait_ref={})", trait_ref.repr(tcx));
+
+    // if the orphan rules pass, that means that no ancestor crate can
+    // impl this, so it's up to us.
+    if orphan_check_trait_ref(tcx, trait_ref, ParamIsLocal(false)).is_ok() {
+        debug!("trait_ref_is_knowable: orphan check passed");
+        return true;
+    }
+
+    // if the trait is not marked fundamental, then it's always possible that
+    // an ancestor crate will impl this in the future, if they haven't
+    // already
+    if
+        trait_ref.def_id.krate != ast::LOCAL_CRATE &&
+        !ty::has_attr(tcx, trait_ref.def_id, "fundamental")
+    {
+        debug!("trait_ref_is_knowable: trait is neither local nor fundamental");
+        return false;
+    }
+
+    // find out when some downstream (or cousin) crate could impl this
+    // trait-ref, presuming that all the parameters were instantiated
+    // with downstream types. If not, then it could only be
+    // implemented by an upstream crate, which means that the impl
+    // must be visible to us, and -- since the trait is fundamental
+    // -- we can test.
+    orphan_check_trait_ref(tcx, trait_ref, ParamIsLocal(true)).is_err()
 }
 
+type SubstsFn = for<'a,'tcx> fn(infcx: &InferCtxt<'a, 'tcx>,
+                                span: Span,
+                                impl_def_id: ast::DefId)
+                                -> Substs<'tcx>;
+
 /// Instantiate fresh variables for all bound parameters of the impl
 /// and return the impl trait ref with those variables substituted.
 fn impl_trait_ref_and_oblig<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
-                                     impl_def_id: ast::DefId)
+                                     impl_def_id: ast::DefId,
+                                     substs_fn: SubstsFn)
                                      -> (Rc<ty::TraitRef<'tcx>>,
                                          Vec<PredicateObligation<'tcx>>)
 {
     let impl_substs =
-        &util::fresh_substs_for_impl(selcx.infcx(), DUMMY_SP, impl_def_id);
+        &substs_fn(selcx.infcx(), DUMMY_SP, impl_def_id);
     let impl_trait_ref =
         ty::impl_trait_ref(selcx.tcx(), impl_def_id).unwrap();
     let impl_trait_ref =
@@ -117,12 +182,12 @@ pub fn orphan_check<'tcx>(tcx: &ty::ctxt<'tcx>,
                           impl_def_id: ast::DefId)
                           -> Result<(), OrphanCheckErr<'tcx>>
 {
-    debug!("impl_is_local({})", impl_def_id.repr(tcx));
+    debug!("orphan_check({})", impl_def_id.repr(tcx));
 
     // We only except this routine to be invoked on implementations
     // of a trait, not inherent implementations.
     let trait_ref = ty::impl_trait_ref(tcx, impl_def_id).unwrap();
-    debug!("trait_ref={}", trait_ref.repr(tcx));
+    debug!("orphan_check: trait_ref={}", trait_ref.repr(tcx));
 
     // If the *trait* is local to the crate, ok.
     if trait_ref.def_id.krate == ast::LOCAL_CRATE {
@@ -131,34 +196,106 @@ pub fn orphan_check<'tcx>(tcx: &ty::ctxt<'tcx>,
         return Ok(());
     }
 
+    orphan_check_trait_ref(tcx, &trait_ref, ParamIsLocal(false))
+}
+
+fn orphan_check_trait_ref<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                trait_ref: &ty::TraitRef<'tcx>,
+                                param_is_local: ParamIsLocal)
+                                -> Result<(), OrphanCheckErr<'tcx>>
+{
+    debug!("orphan_check_trait_ref(trait_ref={}, param_is_local={})",
+           trait_ref.repr(tcx), param_is_local.0);
+
     // First, create an ordered iterator over all the type parameters to the trait, with the self
     // type appearing first.
     let input_tys = Some(trait_ref.self_ty());
     let input_tys = input_tys.iter().chain(trait_ref.substs.types.get_slice(TypeSpace).iter());
-    let mut input_tys = input_tys;
 
     // Find the first input type that either references a type parameter OR
     // some local type.
-    match input_tys.find(|&&input_ty| references_local_or_type_parameter(tcx, input_ty)) {
-        Some(&input_ty) => {
-            // Within this first type, check that all type parameters are covered by a local
-            // type constructor. Note that if there is no local type constructor, then any
-            // type parameter at all will be an error.
-            let covered_params = type_parameters_covered_by_ty(tcx, input_ty);
-            let all_params = type_parameters_reachable_from_ty(input_ty);
-            for &param in all_params.difference(&covered_params) {
-                return Err(OrphanCheckErr::UncoveredTy(param));
+    for input_ty in input_tys {
+        if ty_is_local(tcx, input_ty, param_is_local) {
+            debug!("orphan_check_trait_ref: ty_is_local `{}`", input_ty.repr(tcx));
+
+            // First local input type. Check that there are no
+            // uncovered type parameters.
+            let uncovered_tys = uncovered_tys(tcx, input_ty, param_is_local);
+            for uncovered_ty in uncovered_tys {
+                if let Some(param) = uncovered_ty.walk().find(|t| is_type_parameter(t)) {
+                    debug!("orphan_check_trait_ref: uncovered type `{}`", param.repr(tcx));
+                    return Err(OrphanCheckErr::UncoveredTy(param));
+                }
             }
+
+            // OK, found local type, all prior types upheld invariant.
+            return Ok(());
         }
-        None => {
-            return Err(OrphanCheckErr::NoLocalInputType);
+
+        // Otherwise, enforce invariant that there are no type
+        // parameters reachable.
+        if !param_is_local.0 {
+            if let Some(param) = input_ty.walk().find(|t| is_type_parameter(t)) {
+                debug!("orphan_check_trait_ref: uncovered type `{}`", param.repr(tcx));
+                return Err(OrphanCheckErr::UncoveredTy(param));
+            }
         }
     }
 
-    return Ok(());
+    // If we exit above loop, never found a local type.
+    debug!("orphan_check_trait_ref: no local type");
+    return Err(OrphanCheckErr::NoLocalInputType);
 }
 
-fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
+fn uncovered_tys<'tcx>(tcx: &ty::ctxt<'tcx>,
+                       ty: Ty<'tcx>,
+                       param_is_local: ParamIsLocal)
+                       -> Vec<Ty<'tcx>>
+{
+    if ty_is_local_constructor(tcx, ty, param_is_local) {
+        vec![]
+    } else if fundamental_ty(tcx, ty) {
+        ty.walk_shallow()
+          .flat_map(|t| uncovered_tys(tcx, t, param_is_local).into_iter())
+          .collect()
+    } else {
+        vec![ty]
+    }
+}
+
+fn is_type_parameter<'tcx>(ty: Ty<'tcx>) -> bool {
+    match ty.sty {
+        // FIXME(#20590) straighten story about projection types
+        ty::ty_projection(..) | ty::ty_param(..) => true,
+        _ => false,
+    }
+}
+
+fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>, param_is_local: ParamIsLocal) -> bool
+{
+    ty_is_local_constructor(tcx, ty, param_is_local) ||
+        fundamental_ty(tcx, ty) && ty.walk_shallow().any(|t| ty_is_local(tcx, t, param_is_local))
+}
+
+fn fundamental_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool
+{
+    match ty.sty {
+        ty::ty_uniq(..) | ty::ty_rptr(..) =>
+            true,
+        ty::ty_enum(def_id, _) | ty::ty_struct(def_id, _) =>
+            ty::has_attr(tcx, def_id, "fundamental"),
+        ty::ty_trait(ref data) =>
+            ty::has_attr(tcx, data.principal_def_id(), "fundamental"),
+        _ =>
+            false
+    }
+}
+
+fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                 ty: Ty<'tcx>,
+                                 param_is_local: ParamIsLocal)
+                                 -> bool
+{
     debug!("ty_is_local_constructor({})", ty.repr(tcx));
 
     match ty.sty {
@@ -173,11 +310,15 @@ fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
         ty::ty_ptr(..) |
         ty::ty_rptr(..) |
         ty::ty_tup(..) |
-        ty::ty_param(..) |
+        ty::ty_infer(..) |
         ty::ty_projection(..) => {
             false
         }
 
+        ty::ty_param(..) => {
+            param_is_local.0
+        }
+
         ty::ty_enum(def_id, _) |
         ty::ty_struct(def_id, _) => {
             def_id.krate == ast::LOCAL_CRATE
@@ -193,40 +334,12 @@ fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
         }
 
         ty::ty_closure(..) |
-        ty::ty_infer(..) |
-        ty::ty_open(..) |
         ty::ty_err => {
             tcx.sess.bug(
                 &format!("ty_is_local invoked on unexpected type: {}",
-                        ty.repr(tcx))[])
+                        ty.repr(tcx)))
         }
     }
 }
 
-fn type_parameters_covered_by_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                       ty: Ty<'tcx>)
-                                       -> HashSet<Ty<'tcx>>
-{
-    if ty_is_local_constructor(tcx, ty) {
-        type_parameters_reachable_from_ty(ty)
-    } else {
-        ty.walk_children().flat_map(|t| type_parameters_covered_by_ty(tcx, t).into_iter()).collect()
-    }
-}
-
-/// All type parameters reachable from `ty`
-fn type_parameters_reachable_from_ty<'tcx>(ty: Ty<'tcx>) -> HashSet<Ty<'tcx>> {
-    ty.walk().filter(|&t| is_type_parameter(t)).collect()
-}
 
-fn references_local_or_type_parameter<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
-    ty.walk().any(|ty| is_type_parameter(ty) || ty_is_local_constructor(tcx, ty))
-}
-
-fn is_type_parameter<'tcx>(ty: Ty<'tcx>) -> bool {
-    match ty.sty {
-        // FIXME(#20590) straighten story about projection types
-        ty::ty_projection(..) | ty::ty_param(..) => true,
-        _ => false,
-    }
-}
index 2197cbeb85db4afb7ead1629b4cc500a468ea140..d10ff060418ccb05cdca1061c2e816224c9fbacf 100644 (file)
@@ -12,6 +12,7 @@ use super::{
     FulfillmentError,
     FulfillmentErrorCode,
     MismatchedProjectionTypes,
+    Obligation,
     ObligationCauseCode,
     OutputTypeParameterMismatch,
     PredicateObligation,
@@ -21,6 +22,7 @@ use super::{
 use fmt_macros::{Parser, Piece, Position};
 use middle::infer::InferCtxt;
 use middle::ty::{self, AsPredicate, ReferencesError, ToPolyTraitRef, TraitRef};
+use middle::ty_fold::TypeFoldable;
 use std::collections::HashMap;
 use syntax::codemap::{DUMMY_SP, Span};
 use syntax::attr::{AttributeMethods, AttrMetaMethods};
@@ -137,24 +139,36 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
     report
 }
 
+/// Reports that an overflow has occurred and halts compilation. We
+/// halt compilation unconditionally because it is important that
+/// overflows never be masked -- they basically represent computations
+/// whose result could not be truly determined and thus we can't say
+/// if the program type checks or not -- and they are unusual
+/// occurrences in any case.
+pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
+                                          obligation: &Obligation<'tcx, T>)
+                                          -> !
+    where T: UserString<'tcx> + TypeFoldable<'tcx>
+{
+    let predicate =
+        infcx.resolve_type_vars_if_possible(&obligation.predicate);
+    span_err!(infcx.tcx.sess, obligation.cause.span, E0275,
+              "overflow evaluating the requirement `{}`",
+              predicate.user_string(infcx.tcx));
+
+    suggest_new_overflow_limit(infcx.tcx, obligation.cause.span);
+
+    note_obligation_cause(infcx, obligation);
+
+    infcx.tcx.sess.abort_if_errors();
+    unreachable!();
+}
+
 pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                         obligation: &PredicateObligation<'tcx>,
                                         error: &SelectionError<'tcx>)
 {
     match *error {
-        SelectionError::Overflow => {
-            // We could track the stack here more precisely if we wanted, I imagine.
-            let predicate =
-                infcx.resolve_type_vars_if_possible(&obligation.predicate);
-            span_err!(infcx.tcx.sess, obligation.cause.span, E0275,
-                    "overflow evaluating the requirement `{}`",
-                    predicate.user_string(infcx.tcx));
-
-            suggest_new_overflow_limit(infcx.tcx, obligation.cause.span);
-
-            note_obligation_cause(infcx, obligation);
-        }
-
         SelectionError::Unimplemented => {
             match &obligation.cause.code {
                 &ObligationCauseCode::CompareImplMethodObligation => {
@@ -309,8 +323,9 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
     }
 }
 
-fn note_obligation_cause<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
-                                   obligation: &PredicateObligation<'tcx>)
+fn note_obligation_cause<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
+                                      obligation: &Obligation<'tcx, T>)
+    where T: UserString<'tcx>
 {
     note_obligation_cause_code(infcx,
                                &obligation.predicate,
@@ -318,10 +333,11 @@ fn note_obligation_cause<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                &obligation.cause.code);
 }
 
-fn note_obligation_cause_code<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
-                                        predicate: &ty::Predicate<'tcx>,
-                                        cause_span: Span,
-                                        cause_code: &ObligationCauseCode<'tcx>)
+fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
+                                           predicate: &T,
+                                           cause_span: Span,
+                                           cause_code: &ObligationCauseCode<'tcx>)
+    where T: UserString<'tcx>
 {
     let tcx = infcx.tcx;
     match *cause_code {
@@ -422,5 +438,5 @@ pub fn suggest_new_overflow_limit(tcx: &ty::ctxt, span: Span) {
         span,
         &format!(
             "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
-            suggested_limit)[]);
+            suggested_limit));
 }
index a9cac4be3e368026e319a32b890df4a6f36263fb..ffd3299175de9de09c43efe9f0e0f0d48d6d878e 100644 (file)
@@ -8,10 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use middle::infer::{InferCtxt};
+use middle::infer::InferCtxt;
 use middle::ty::{self, RegionEscape, Ty};
 use std::collections::HashSet;
-use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::default::Default;
 use syntax::ast;
 use util::common::ErrorReported;
@@ -54,7 +53,7 @@ pub struct FulfillmentContext<'tcx> {
     // Remembers the count of trait obligations that we have already
     // attempted to select. This is used to avoid repeating work
     // when `select_new_obligations` is called.
-    attempted_mark: uint,
+    attempted_mark: usize,
 
     // A set of constraints that regionck must validate. Each
     // constraint has the form `T:'a`, meaning "some type `T` must
@@ -164,6 +163,8 @@ impl<'tcx> FulfillmentContext<'tcx> {
         // debug output much nicer to read and so on.
         let obligation = infcx.resolve_type_vars_if_possible(&obligation);
 
+        assert!(!obligation.has_escaping_regions());
+
         if !self.duplicate_set.insert(obligation.predicate.clone()) {
             debug!("register_predicate({}) -- already seen, skip", obligation.repr(infcx.tcx));
             return;
@@ -227,7 +228,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
     }
 
     pub fn pending_obligations(&self) -> &[PredicateObligation<'tcx>] {
-        &self.predicates[]
+        &self.predicates
     }
 
     /// Attempts to select obligations using `selcx`. If `only_new_obligations` is true, then it
@@ -437,9 +438,7 @@ fn register_region_obligation<'tcx>(tcx: &ty::ctxt<'tcx>,
     debug!("register_region_obligation({})",
            region_obligation.repr(tcx));
 
-    match region_obligations.entry(region_obligation.cause.body_id) {
-        Vacant(entry) => { entry.insert(vec![region_obligation]); },
-        Occupied(mut entry) => { entry.get_mut().push(region_obligation); },
-    }
+    region_obligations.entry(region_obligation.cause.body_id).or_insert(vec![])
+        .push(region_obligation);
 
 }
index a63dcfc24a10ec6d76314be312d3e0d81a671433..8809abdd70e62b10d664263917bdab2ed643f5b6 100644 (file)
@@ -18,14 +18,15 @@ pub use self::ObligationCauseCode::*;
 use middle::subst;
 use middle::ty::{self, HasProjectionTypes, Ty};
 use middle::ty_fold::TypeFoldable;
-use middle::infer::{self, InferCtxt};
+use middle::infer::{self, fixup_err_to_string, InferCtxt};
 use std::slice::Iter;
 use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::{Span, DUMMY_SP};
-use util::ppaux::{Repr, UserString};
+use util::ppaux::Repr;
 
 pub use self::error_reporting::report_fulfillment_errors;
+pub use self::error_reporting::report_overflow_error;
 pub use self::error_reporting::suggest_new_overflow_limit;
 pub use self::coherence::orphan_check;
 pub use self::coherence::overlapping_impls;
@@ -38,6 +39,7 @@ pub use self::object_safety::is_object_safe;
 pub use self::object_safety::object_safety_violations;
 pub use self::object_safety::ObjectSafetyViolation;
 pub use self::object_safety::MethodViolationCode;
+pub use self::object_safety::is_vtable_safe_method;
 pub use self::select::SelectionContext;
 pub use self::select::SelectionCache;
 pub use self::select::{MethodMatchResult, MethodMatched, MethodAmbiguous, MethodDidNotMatch};
@@ -47,6 +49,8 @@ pub use self::util::get_vtable_index_of_object_method;
 pub use self::util::trait_ref_for_builtin_bound;
 pub use self::util::supertraits;
 pub use self::util::Supertraits;
+pub use self::util::supertrait_def_ids;
+pub use self::util::SupertraitDefIds;
 pub use self::util::transitive_bounds;
 pub use self::util::upcast;
 
@@ -67,7 +71,7 @@ mod util;
 #[derive(Clone, PartialEq, Eq)]
 pub struct Obligation<'tcx, T> {
     pub cause: ObligationCause<'tcx>,
-    pub recursion_depth: uint,
+    pub recursion_depth: usize,
     pub predicate: T,
 }
 
@@ -151,7 +155,6 @@ pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;
 #[derive(Clone,Debug)]
 pub enum SelectionError<'tcx> {
     Unimplemented,
-    Overflow,
     OutputTypeParameterMismatch(ty::PolyTraitRef<'tcx>,
                                 ty::PolyTraitRef<'tcx>,
                                 ty::type_err<'tcx>),
@@ -221,6 +224,12 @@ pub enum Vtable<'tcx, N> {
     /// Vtable identifying a particular impl.
     VtableImpl(VtableImplData<'tcx, N>),
 
+    /// Vtable for default trait implementations
+    /// This carries the information and nested obligations with regards
+    /// to a default implementation for a trait `Trait`. The nested obligations
+    /// ensure the trait implementation holds for all the constituent types.
+    VtableDefaultImpl(VtableDefaultImplData<N>),
+
     /// Successful resolution to an obligation provided by the caller
     /// for some type parameter. The `Vec<N>` represents the
     /// obligations incurred from normalizing the where-clause (if
@@ -259,6 +268,12 @@ pub struct VtableImplData<'tcx, N> {
     pub nested: subst::VecPerParamSpace<N>
 }
 
+#[derive(Debug,Clone)]
+pub struct VtableDefaultImplData<N> {
+    pub trait_def_id: ast::DefId,
+    pub nested: Vec<N>
+}
+
 #[derive(Debug,Clone)]
 pub struct VtableBuiltinData<N> {
     pub nested: subst::VecPerParamSpace<N>
@@ -268,7 +283,11 @@ pub struct VtableBuiltinData<N> {
 /// for the object type `Foo`.
 #[derive(PartialEq,Eq,Clone)]
 pub struct VtableObjectData<'tcx> {
+    /// the object type `Foo`.
     pub object_ty: Ty<'tcx>,
+
+    /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
+    pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
 }
 
 /// Creates predicate obligations from the generic bounds.
@@ -311,16 +330,9 @@ pub fn evaluate_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
     let result = match fulfill_cx.select_all_or_error(infcx, typer) {
         Ok(()) => Ok(Some(())), // Success, we know it implements Copy.
         Err(errors) => {
-            // Check if overflow occurred anywhere and propagate that.
-            if errors.iter().any(
-                |err| match err.code { CodeSelectionError(Overflow) => true, _ => false })
-            {
-                return Err(Overflow);
-            }
-
-            // Otherwise, if there were any hard errors, propagate an
-            // arbitrary one of those. If no hard errors at all,
-            // report ambiguity.
+            // If there were any hard errors, propagate an arbitrary
+            // one of those. If no hard errors at all, report
+            // ambiguity.
             let sel_error =
                 errors.iter()
                       .filter_map(|err| {
@@ -368,68 +380,71 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
             // soldering on, so just treat this like not implemented
             false
         }
-        Err(Overflow) => {
-            span_err!(infcx.tcx.sess, span, E0285,
-                "overflow evaluating whether `{}` is `{}`",
-                      ty.user_string(infcx.tcx),
-                      bound.user_string(infcx.tcx));
-            suggest_new_overflow_limit(infcx.tcx, span);
-            false
-        }
         Err(_) => {
-            // other errors: not implemented.
+            // errors: not implemented.
             false
         }
     }
 }
 
+/// Normalizes the parameter environment, reporting errors if they occur.
 pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvironment<'a,'tcx>,
                                              cause: ObligationCause<'tcx>)
                                              -> ty::ParameterEnvironment<'a,'tcx>
 {
-    match normalize_param_env(&unnormalized_env, cause) {
-        Ok(p) => p,
+    // I'm not wild about reporting errors here; I'd prefer to
+    // have the errors get reported at a defined place (e.g.,
+    // during typeck). Instead I have all parameter
+    // environments, in effect, going through this function
+    // and hence potentially reporting errors. This ensurse of
+    // course that we never forget to normalize (the
+    // alternative seemed like it would involve a lot of
+    // manual invocations of this fn -- and then we'd have to
+    // deal with the errors at each of those sites).
+    //
+    // In any case, in practice, typeck constructs all the
+    // parameter environments once for every fn as it goes,
+    // and errors will get reported then; so after typeck we
+    // can be sure that no errors should occur.
+
+    let tcx = unnormalized_env.tcx;
+    let span = cause.span;
+    let body_id = cause.body_id;
+
+    debug!("normalize_param_env_or_error(unnormalized_env={})",
+           unnormalized_env.repr(tcx));
+
+    let infcx = infer::new_infer_ctxt(tcx);
+    let predicates = match fully_normalize(&infcx, &unnormalized_env, cause,
+                                           &unnormalized_env.caller_bounds) {
+        Ok(predicates) => predicates,
         Err(errors) => {
-            // I'm not wild about reporting errors here; I'd prefer to
-            // have the errors get reported at a defined place (e.g.,
-            // during typeck). Instead I have all parameter
-            // environments, in effect, going through this function
-            // and hence potentially reporting errors. This ensurse of
-            // course that we never forget to normalize (the
-            // alternative seemed like it would involve a lot of
-            // manual invocations of this fn -- and then we'd have to
-            // deal with the errors at each of those sites).
-            //
-            // In any case, in practice, typeck constructs all the
-            // parameter environments once for every fn as it goes,
-            // and errors will get reported then; so after typeck we
-            // can be sure that no errors should occur.
-            let infcx = infer::new_infer_ctxt(unnormalized_env.tcx);
             report_fulfillment_errors(&infcx, &errors);
-
-            // Normalized failed? use what they gave us, it's better than nothing.
-            unnormalized_env
+            return unnormalized_env; // an unnormalized env is better than nothing
         }
-    }
-}
-
-pub fn normalize_param_env<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx>,
-                                    cause: ObligationCause<'tcx>)
-                                    -> Result<ty::ParameterEnvironment<'a,'tcx>,
-                                              Vec<FulfillmentError<'tcx>>>
-{
-    let tcx = param_env.tcx;
-
-    debug!("normalize_param_env(param_env={})",
-           param_env.repr(tcx));
+    };
 
-    let infcx = infer::new_infer_ctxt(tcx);
-    let predicates = try!(fully_normalize(&infcx, param_env, cause, &param_env.caller_bounds));
+    infcx.resolve_regions_and_report_errors(body_id);
+    let predicates = match infcx.fully_resolve(&predicates) {
+        Ok(predicates) => predicates,
+        Err(fixup_err) => {
+            // If we encounter a fixup error, it means that some type
+            // variable wound up unconstrained. I actually don't know
+            // if this can happen, and I certainly don't expect it to
+            // happen often, but if it did happen it probably
+            // represents a legitimate failure due to some kind of
+            // unconstrained variable, and it seems better not to ICE,
+            // all things considered.
+            let err_msg = fixup_err_to_string(fixup_err);
+            tcx.sess.span_err(span, &err_msg);
+            return unnormalized_env; // an unnormalized env is better than nothing
+        }
+    };
 
-    debug!("normalize_param_env: predicates={}",
+    debug!("normalize_param_env_or_error: predicates={}",
            predicates.repr(tcx));
 
-    Ok(param_env.with_caller_bounds(predicates))
+    unnormalized_env.with_caller_bounds(predicates)
 }
 
 pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
@@ -441,8 +456,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
 {
     let tcx = closure_typer.tcx();
 
-    debug!("normalize_param_env(value={})",
-           value.repr(tcx));
+    debug!("normalize_param_env(value={})", value.repr(tcx));
 
     let mut selcx = &mut SelectionContext::new(infcx, closure_typer);
     let mut fulfill_cx = FulfillmentContext::new();
@@ -456,8 +470,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
     }
     try!(fulfill_cx.select_all_or_error(infcx, closure_typer));
     let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value);
-    debug!("normalize_param_env: resolved_value={}",
-           resolved_value.repr(tcx));
+    debug!("normalize_param_env: resolved_value={}", resolved_value.repr(tcx));
     Ok(resolved_value)
 }
 
@@ -472,7 +485,7 @@ impl<'tcx,O> Obligation<'tcx,O> {
     }
 
     fn with_depth(cause: ObligationCause<'tcx>,
-                  recursion_depth: uint,
+                  recursion_depth: usize,
                   trait_ref: O)
                   -> Obligation<'tcx, O>
     {
@@ -513,17 +526,18 @@ impl<'tcx, N> Vtable<'tcx, N> {
     pub fn iter_nested(&self) -> Iter<N> {
         match *self {
             VtableImpl(ref i) => i.iter_nested(),
-            VtableFnPointer(..) => (&[]).iter(),
-            VtableClosure(..) => (&[]).iter(),
             VtableParam(ref n) => n.iter(),
-            VtableObject(_) => (&[]).iter(),
             VtableBuiltin(ref i) => i.iter_nested(),
+            VtableObject(_) |
+            VtableDefaultImpl(..) | VtableFnPointer(..) |
+            VtableClosure(..) => (&[]).iter(),
         }
     }
 
     pub fn map_nested<M, F>(&self, op: F) -> Vtable<'tcx, M> where F: FnMut(&N) -> M {
         match *self {
             VtableImpl(ref i) => VtableImpl(i.map_nested(op)),
+            VtableDefaultImpl(ref t) => VtableDefaultImpl(t.map_nested(op)),
             VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()),
             VtableClosure(d, ref s) => VtableClosure(d, s.clone()),
             VtableParam(ref n) => VtableParam(n.iter().map(op).collect()),
@@ -539,6 +553,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
             VtableImpl(i) => VtableImpl(i.map_move_nested(op)),
             VtableFnPointer(sig) => VtableFnPointer(sig),
             VtableClosure(d, s) => VtableClosure(d, s),
+            VtableDefaultImpl(t) => VtableDefaultImpl(t.map_move_nested(op)),
             VtableParam(n) => VtableParam(n.into_iter().map(op).collect()),
             VtableObject(p) => VtableObject(p),
             VtableBuiltin(no) => VtableBuiltin(no.map_move_nested(op)),
@@ -573,6 +588,31 @@ impl<'tcx, N> VtableImplData<'tcx, N> {
     }
 }
 
+impl<N> VtableDefaultImplData<N> {
+    pub fn iter_nested(&self) -> Iter<N> {
+        self.nested.iter()
+    }
+
+    pub fn map_nested<M, F>(&self, op: F) -> VtableDefaultImplData<M> where
+        F: FnMut(&N) -> M,
+    {
+        VtableDefaultImplData {
+            trait_def_id: self.trait_def_id,
+            nested: self.nested.iter().map(op).collect()
+        }
+    }
+
+    pub fn map_move_nested<M, F>(self, op: F) -> VtableDefaultImplData<M> where
+        F: FnMut(N) -> M,
+    {
+        let VtableDefaultImplData { trait_def_id, nested } = self;
+        VtableDefaultImplData {
+            trait_def_id: trait_def_id,
+            nested: nested.into_iter().map(op).collect()
+        }
+    }
+}
+
 impl<N> VtableBuiltinData<N> {
     pub fn iter_nested(&self) -> Iter<N> {
         self.nested.iter()
@@ -600,19 +640,10 @@ impl<'tcx> FulfillmentError<'tcx> {
     {
         FulfillmentError { obligation: obligation, code: code }
     }
-
-    pub fn is_overflow(&self) -> bool {
-        match self.code {
-            CodeAmbiguity => false,
-            CodeSelectionError(Overflow) => true,
-            CodeSelectionError(_) => false,
-            CodeProjectionError(_) => false,
-        }
-    }
 }
 
 impl<'tcx> TraitObligation<'tcx> {
-    fn self_ty(&self) -> Ty<'tcx> {
-        self.predicate.0.self_ty()
+    fn self_ty(&self) -> ty::Binder<Ty<'tcx>> {
+        ty::Binder(self.predicate.skip_binder().self_ty())
     }
 }
index f10f7eb3951c7a0468a3a5e86367e9d4c024060f..af6bb4ccccd8026d35a4d3d9d7c5d7f57a597695 100644 (file)
@@ -22,7 +22,7 @@ use super::elaborate_predicates;
 
 use middle::subst::{self, SelfSpace, TypeSpace};
 use middle::traits;
-use middle::ty::{self, Ty};
+use middle::ty::{self, ToPolyTraitRef, Ty};
 use std::rc::Rc;
 use syntax::ast;
 use util::ppaux::Repr;
@@ -42,9 +42,6 @@ pub enum ObjectSafetyViolation<'tcx> {
 /// Reasons a method might not be object-safe.
 #[derive(Copy,Clone,Debug)]
 pub enum MethodViolationCode {
-    /// e.g., `fn(self)`
-    ByValueSelf,
-
     /// e.g., `fn foo()`
     StaticMethod,
 
@@ -56,36 +53,36 @@ pub enum MethodViolationCode {
 }
 
 pub fn is_object_safe<'tcx>(tcx: &ty::ctxt<'tcx>,
-                            trait_ref: ty::PolyTraitRef<'tcx>)
+                            trait_def_id: ast::DefId)
                             -> bool
 {
     // Because we query yes/no results frequently, we keep a cache:
     let cached_result =
-        tcx.object_safety_cache.borrow().get(&trait_ref.def_id()).cloned();
+        tcx.object_safety_cache.borrow().get(&trait_def_id).cloned();
 
     let result =
         cached_result.unwrap_or_else(|| {
-            let result = object_safety_violations(tcx, trait_ref.clone()).is_empty();
+            let result = object_safety_violations(tcx, trait_def_id).is_empty();
 
             // Record just a yes/no result in the cache; this is what is
             // queried most frequently. Note that this may overwrite a
             // previous result, but always with the same thing.
-            tcx.object_safety_cache.borrow_mut().insert(trait_ref.def_id(), result);
+            tcx.object_safety_cache.borrow_mut().insert(trait_def_id, result);
 
             result
         });
 
-    debug!("is_object_safe({}) = {}", trait_ref.repr(tcx), result);
+    debug!("is_object_safe({}) = {}", trait_def_id.repr(tcx), result);
 
     result
 }
 
 pub fn object_safety_violations<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                      sub_trait_ref: ty::PolyTraitRef<'tcx>)
+                                      trait_def_id: ast::DefId)
                                       -> Vec<ObjectSafetyViolation<'tcx>>
 {
-    supertraits(tcx, sub_trait_ref)
-        .flat_map(|tr| object_safety_violations_for_trait(tcx, tr.def_id()).into_iter())
+    traits::supertrait_def_ids(tcx, trait_def_id)
+        .flat_map(|def_id| object_safety_violations_for_trait(tcx, def_id).into_iter())
         .collect()
 }
 
@@ -99,7 +96,7 @@ fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
         .flat_map(|item| {
             match *item {
                 ty::MethodTraitItem(ref m) => {
-                    object_safety_violations_for_method(tcx, trait_def_id, &**m)
+                    object_safety_violation_for_method(tcx, trait_def_id, &**m)
                         .map(|code| ObjectSafetyViolation::Method(m.clone(), code))
                         .into_iter()
                 }
@@ -131,9 +128,12 @@ fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>,
 {
     let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
     let trait_ref = trait_def.trait_ref.clone();
-    let predicates = ty::predicates_for_trait_ref(tcx, &ty::Binder(trait_ref));
+    let trait_ref = trait_ref.to_poly_trait_ref();
+    let predicates = ty::lookup_super_predicates(tcx, trait_def_id);
     predicates
+        .predicates
         .into_iter()
+        .map(|predicate| predicate.subst_supertrait(tcx, &trait_ref))
         .any(|predicate| {
             match predicate {
                 ty::Predicate::Trait(ref data) => {
@@ -157,6 +157,16 @@ fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>,
 fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
                               trait_def_id: ast::DefId)
                               -> bool
+{
+    let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
+    let trait_predicates = ty::lookup_predicates(tcx, trait_def_id);
+    generics_require_sized_self(tcx, &trait_def.generics, &trait_predicates)
+}
+
+fn generics_require_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                     generics: &ty::Generics<'tcx>,
+                                     predicates: &ty::GenericPredicates<'tcx>)
+                                     -> bool
 {
     let sized_def_id = match tcx.lang_items.sized_trait() {
         Some(def_id) => def_id,
@@ -164,12 +174,8 @@ fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
     };
 
     // Search for a predicate like `Self : Sized` amongst the trait bounds.
-    let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
-    let free_substs = ty::construct_free_substs(tcx, &trait_def.generics, ast::DUMMY_NODE_ID);
-
-    let trait_predicates = ty::lookup_predicates(tcx, trait_def_id);
-    let predicates = trait_predicates.instantiate(tcx, &free_substs).predicates.into_vec();
-
+    let free_substs = ty::construct_free_substs(tcx, generics, ast::DUMMY_NODE_ID);
+    let predicates = predicates.instantiate(tcx, &free_substs).predicates.into_vec();
     elaborate_predicates(tcx, predicates)
         .any(|predicate| {
             match predicate {
@@ -187,22 +193,51 @@ fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
         })
 }
 
-fn object_safety_violations_for_method<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                             trait_def_id: ast::DefId,
-                                             method: &ty::Method<'tcx>)
-                                             -> Option<MethodViolationCode>
+/// Returns `Some(_)` if this method makes the containing trait not object safe.
+fn object_safety_violation_for_method<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                            trait_def_id: ast::DefId,
+                                            method: &ty::Method<'tcx>)
+                                            -> Option<MethodViolationCode>
 {
-    // The method's first parameter must be something that derefs to
-    // `&self`. For now, we only accept `&self` and `Box<Self>`.
-    match method.explicit_self {
-        ty::ByValueExplicitSelfCategory => {
-            return Some(MethodViolationCode::ByValueSelf);
-        }
+    // Any method that has a `Self : Sized` requisite is otherwise
+    // exempt from the regulations.
+    if generics_require_sized_self(tcx, &method.generics, &method.predicates) {
+        return None;
+    }
+
+    virtual_call_violation_for_method(tcx, trait_def_id, method)
+}
 
+/// We say a method is *vtable safe* if it can be invoked on a trait
+/// object.  Note that object-safe traits can have some
+/// non-vtable-safe methods, so long as they require `Self:Sized` or
+/// otherwise ensure that they cannot be used when `Self=Trait`.
+pub fn is_vtable_safe_method<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                   trait_def_id: ast::DefId,
+                                   method: &ty::Method<'tcx>)
+                                   -> bool
+{
+    virtual_call_violation_for_method(tcx, trait_def_id, method).is_none()
+}
+
+/// Returns `Some(_)` if this method cannot be called on a trait
+/// object; this does not necessarily imply that the enclosing trait
+/// is not object safe, because the method might have a where clause
+/// `Self:Sized`.
+fn virtual_call_violation_for_method<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                           trait_def_id: ast::DefId,
+                                           method: &ty::Method<'tcx>)
+                                           -> Option<MethodViolationCode>
+{
+    // The method's first parameter must be something that derefs (or
+    // autorefs) to `&self`. For now, we only accept `self`, `&self`
+    // and `Box<Self>`.
+    match method.explicit_self {
         ty::StaticExplicitSelfCategory => {
             return Some(MethodViolationCode::StaticMethod);
         }
 
+        ty::ByValueExplicitSelfCategory |
         ty::ByReferenceExplicitSelfCategory(..) |
         ty::ByBoxExplicitSelfCategory => {
         }
index 13f309e129ac9c9a63bd613cd9a5235211323bec..7488b8f046e74eff8215258fe5127b4c99895384 100644 (file)
@@ -11,9 +11,9 @@
 //! Code for projecting associated types out of trait references.
 
 use super::elaborate_predicates;
+use super::report_overflow_error;
 use super::Obligation;
 use super::ObligationCause;
-use super::Overflow;
 use super::PredicateObligation;
 use super::SelectionContext;
 use super::SelectionError;
@@ -81,7 +81,7 @@ pub fn poly_project_and_unify_type<'cx,'tcx>(
            obligation.repr(selcx.tcx()));
 
     let infcx = selcx.infcx();
-    infcx.try(|snapshot| {
+    infcx.commit_if_ok(|snapshot| {
         let (skol_predicate, skol_map) =
             infcx.skolemize_late_bound_regions(&obligation.predicate, snapshot);
 
@@ -154,7 +154,7 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext
     debug!("consider_unification_despite_ambiguity: self_ty.sty={:?}",
            self_ty.sty);
     match self_ty.sty {
-        ty::ty_closure(closure_def_id, _, substs) => {
+        ty::ty_closure(closure_def_id, substs) => {
             let closure_typer = selcx.closure_typer();
             let closure_type = closure_typer.closure_type(closure_def_id, substs);
             let ty::Binder((_, ret_type)) =
@@ -197,7 +197,7 @@ pub fn normalize<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>,
 /// As `normalize`, but with a custom depth.
 pub fn normalize_with_depth<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>,
                                           cause: ObligationCause<'tcx>,
-                                          depth: uint,
+                                          depth: usize,
                                           value: &T)
                                           -> Normalized<'tcx, T>
     where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx>
@@ -214,13 +214,13 @@ struct AssociatedTypeNormalizer<'a,'b:'a,'tcx:'b> {
     selcx: &'a mut SelectionContext<'b,'tcx>,
     cause: ObligationCause<'tcx>,
     obligations: Vec<PredicateObligation<'tcx>>,
-    depth: uint,
+    depth: usize,
 }
 
 impl<'a,'b,'tcx> AssociatedTypeNormalizer<'a,'b,'tcx> {
     fn new(selcx: &'a mut SelectionContext<'b,'tcx>,
            cause: ObligationCause<'tcx>,
-           depth: uint)
+           depth: usize)
            -> AssociatedTypeNormalizer<'a,'b,'tcx>
     {
         AssociatedTypeNormalizer {
@@ -291,6 +291,7 @@ impl<'a,'b,'tcx> TypeFolder<'tcx> for AssociatedTypeNormalizer<'a,'b,'tcx> {
     }
 }
 
+#[derive(Clone)]
 pub struct Normalized<'tcx,T> {
     pub value: T,
     pub obligations: Vec<PredicateObligation<'tcx>>,
@@ -314,7 +315,7 @@ pub fn normalize_projection_type<'a,'b,'tcx>(
     selcx: &'a mut SelectionContext<'b,'tcx>,
     projection_ty: ty::ProjectionTy<'tcx>,
     cause: ObligationCause<'tcx>,
-    depth: uint)
+    depth: usize)
     -> NormalizedTy<'tcx>
 {
     opt_normalize_projection_type(selcx, projection_ty.clone(), cause.clone(), depth)
@@ -344,7 +345,7 @@ fn opt_normalize_projection_type<'a,'b,'tcx>(
     selcx: &'a mut SelectionContext<'b,'tcx>,
     projection_ty: ty::ProjectionTy<'tcx>,
     cause: ObligationCause<'tcx>,
-    depth: uint)
+    depth: usize)
     -> Option<NormalizedTy<'tcx>>
 {
     debug!("normalize_projection_type(\
@@ -412,7 +413,7 @@ fn opt_normalize_projection_type<'a,'b,'tcx>(
 fn normalize_to_error<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
                                projection_ty: ty::ProjectionTy<'tcx>,
                                cause: ObligationCause<'tcx>,
-                               depth: uint)
+                               depth: usize)
                                -> NormalizedTy<'tcx>
 {
     let trait_ref = projection_ty.trait_ref.to_poly_trait_ref();
@@ -442,7 +443,7 @@ fn project_type<'cx,'tcx>(
     let recursion_limit = selcx.tcx().sess.recursion_limit.get();
     if obligation.recursion_depth >= recursion_limit {
         debug!("project: overflow!");
-        return Err(ProjectionTyError::TraitSelectionError(Overflow));
+        report_overflow_error(selcx.infcx(), &obligation);
     }
 
     let obligation_trait_ref =
@@ -535,7 +536,7 @@ fn assemble_candidates_from_param_env<'cx,'tcx>(
 /// In the case of a nested projection like <<A as Foo>::FooT as Bar>::BarT, we may find
 /// that the definition of `Foo` has some clues:
 ///
-/// ```rust
+/// ```
 /// trait Foo {
 ///     type FooT : Bar<BarT=i32>
 /// }
@@ -699,16 +700,17 @@ fn assemble_candidates_from_impls<'cx,'tcx>(
             // But wait, you say! What about an example like this:
             //
             // ```
-            // fn bar<T:SomeTrait<Foo=uint>>(...) { ... }
+            // fn bar<T:SomeTrait<Foo=usize>>(...) { ... }
             // ```
             //
-            // Doesn't the `T : Sometrait<Foo=uint>` predicate help
+            // Doesn't the `T : Sometrait<Foo=usize>` predicate help
             // resolve `T::Foo`? And of course it does, but in fact
             // that single predicate is desugared into two predicates
             // in the compiler: a trait predicate (`T : SomeTrait`) and a
             // projection. And the projection where clause is handled
             // in `assemble_candidates_from_param_env`.
         }
+        super::VtableDefaultImpl(..) |
         super::VtableBuiltin(..) => {
             // These traits have no associated types.
             selcx.tcx().sess.span_bug(
@@ -788,10 +790,13 @@ fn confirm_callable_candidate<'cx,'tcx>(
            obligation.repr(tcx),
            fn_sig.repr(tcx));
 
+    // the `Output` associated type is declared on `FnOnce`
+    let fn_once_def_id = tcx.lang_items.fn_once_trait().unwrap();
+
     // Note: we unwrap the binder here but re-create it below (1)
     let ty::Binder((trait_ref, ret_type)) =
         util::closure_trait_ref_and_return_type(tcx,
-                                                obligation.predicate.trait_ref.def_id,
+                                                fn_once_def_id,
                                                 obligation.predicate.trait_ref.self_ty(),
                                                 fn_sig,
                                                 flag);
@@ -853,10 +858,10 @@ fn confirm_impl_candidate<'cx,'tcx>(
     let impl_items_map = selcx.tcx().impl_items.borrow();
     let impl_or_trait_items_map = selcx.tcx().impl_or_trait_items.borrow();
 
-    let impl_items = &impl_items_map[impl_vtable.impl_def_id];
+    let impl_items = impl_items_map.get(&impl_vtable.impl_def_id).unwrap();
     let mut impl_ty = None;
     for impl_item in impl_items {
-        let assoc_type = match impl_or_trait_items_map[impl_item.def_id()] {
+        let assoc_type = match *impl_or_trait_items_map.get(&impl_item.def_id()).unwrap() {
             ty::TypeTraitItem(ref assoc_type) => assoc_type.clone(),
             ty::MethodTraitItem(..) => { continue; }
         };
index 0e29892084175d180047412a39c9a2e936c750a7..f7e7d071f8ca4b7c81d5373e5aa576c26e70cece 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! See `doc.rs` for high-level documentation
+//! See `README.md` for high-level documentation
 #![allow(dead_code)] // FIXME -- just temporarily
 
 pub use self::MethodMatchResult::*;
@@ -17,19 +17,21 @@ use self::SelectionCandidate::*;
 use self::BuiltinBoundConditions::*;
 use self::EvaluationResult::*;
 
-use super::{DerivedObligationCause};
-use super::{project};
-use super::project::Normalized;
+use super::coherence;
+use super::DerivedObligationCause;
+use super::project;
+use super::project::{normalize_with_depth, Normalized};
 use super::{PredicateObligation, TraitObligation, ObligationCause};
-use super::{ObligationCauseCode, BuiltinDerivedObligation};
-use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
-use super::{Selection};
-use super::{SelectionResult};
+use super::report_overflow_error;
+use super::{ObligationCauseCode, BuiltinDerivedObligation, ImplDerivedObligation};
+use super::{SelectionError, Unimplemented, OutputTypeParameterMismatch};
+use super::Selection;
+use super::SelectionResult;
 use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure,
-            VtableFnPointer, VtableObject};
-use super::{VtableImplData, VtableObjectData, VtableBuiltinData};
+            VtableFnPointer, VtableObject, VtableDefaultImpl};
+use super::{VtableImplData, VtableObjectData, VtableBuiltinData, VtableDefaultImplData};
 use super::object_safety;
-use super::{util};
+use super::util;
 
 use middle::fast_reject;
 use middle::subst::{Subst, Substs, TypeSpace, VecPerParamSpace};
@@ -37,11 +39,13 @@ use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
 use middle::infer;
 use middle::infer::{InferCtxt, TypeFreshener};
 use middle::ty_fold::TypeFoldable;
+use middle::ty_match;
+use middle::ty_relate::TypeRelation;
 use std::cell::RefCell;
-use std::collections::hash_map::HashMap;
 use std::rc::Rc;
 use syntax::{abi, ast};
 use util::common::ErrorReported;
+use util::nodemap::FnvHashMap;
 use util::ppaux::Repr;
 
 pub struct SelectionContext<'cx, 'tcx:'cx> {
@@ -80,13 +84,13 @@ struct TraitObligationStack<'prev, 'tcx: 'prev> {
     /// selection-context's freshener. Used to check for recursion.
     fresh_trait_ref: ty::PolyTraitRef<'tcx>,
 
-    previous: Option<&'prev TraitObligationStack<'prev, 'tcx>>
+    previous: TraitObligationStackList<'prev, 'tcx>,
 }
 
 #[derive(Clone)]
 pub struct SelectionCache<'tcx> {
-    hashmap: RefCell<HashMap<Rc<ty::TraitRef<'tcx>>,
-                             SelectionResult<'tcx, SelectionCandidate<'tcx>>>>,
+    hashmap: RefCell<FnvHashMap<Rc<ty::TraitRef<'tcx>>,
+                                SelectionResult<'tcx, SelectionCandidate<'tcx>>>>,
 }
 
 pub enum MethodMatchResult {
@@ -95,7 +99,7 @@ pub enum MethodMatchResult {
     MethodDidNotMatch,
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum MethodMatchedData {
     // In the case of a precise match, we don't really need to store
     // how the match was found. So don't.
@@ -109,7 +113,7 @@ pub enum 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
-/// apply to the obligation: perhaps it is defined for `uint` but the
+/// apply to the obligation: perhaps it is defined for `usize` but the
 /// obligation is for `int`. In that case, we drop the impl out of the
 /// list.  But the other cases are considered *candidates*.
 ///
@@ -136,6 +140,8 @@ enum SelectionCandidate<'tcx> {
     BuiltinCandidate(ty::BuiltinBound),
     ParamCandidate(ty::PolyTraitRef<'tcx>),
     ImplCandidate(ast::DefId),
+    DefaultImplCandidate(ast::DefId),
+    DefaultImplObjectCandidate(ast::DefId),
 
     /// This is a trait matching with a projected type as `Self`, and
     /// we found an applicable bound in the trait definition.
@@ -151,6 +157,8 @@ enum SelectionCandidate<'tcx> {
 
     ObjectCandidate,
 
+    BuiltinObjectCandidate,
+
     ErrorCandidate,
 }
 
@@ -167,7 +175,7 @@ struct SelectionCandidateSet<'tcx> {
 }
 
 enum BuiltinBoundConditions<'tcx> {
-    If(Vec<Ty<'tcx>>),
+    If(ty::Binder<Vec<Ty<'tcx>>>),
     ParameterBuiltin,
     AmbiguousBuiltin
 }
@@ -240,7 +248,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         debug!("select({})", obligation.repr(self.tcx()));
         assert!(!obligation.predicate.has_escaping_regions());
 
-        let stack = self.push_stack(None, obligation);
+        let stack = self.push_stack(TraitObligationStackList::empty(), obligation);
         match try!(self.candidate_from_obligation(&stack)) {
             None => {
                 self.consider_unification_despite_ambiguity(obligation);
@@ -288,9 +296,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // because if it is a closure type, it must be a closure type from
         // within this current fn, and hence none of the higher-ranked
         // lifetimes can appear inside the self-type.
-        let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
+        let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
         let (closure_def_id, substs) = match self_ty.sty {
-            ty::ty_closure(id, _, ref substs) => (id, substs.clone()),
+            ty::ty_closure(id, ref substs) => (id, substs.clone()),
             _ => { return; }
         };
         assert!(!substs.has_escaping_regions());
@@ -322,7 +330,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         debug!("evaluate_obligation({})",
                obligation.repr(self.tcx()));
 
-        self.evaluate_predicate_recursively(None, obligation).may_apply()
+        self.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation)
+            .may_apply()
     }
 
     fn evaluate_builtin_bound_recursively<'o>(&mut self,
@@ -341,7 +350,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         match obligation {
             Ok(obligation) => {
-                self.evaluate_predicate_recursively(Some(previous_stack), &obligation)
+                self.evaluate_predicate_recursively(previous_stack.list(), &obligation)
             }
             Err(ErrorReported) => {
                 EvaluatedToOk
@@ -350,7 +359,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn evaluate_predicates_recursively<'a,'o,I>(&mut self,
-                                                stack: Option<&TraitObligationStack<'o, 'tcx>>,
+                                                stack: TraitObligationStackList<'o, 'tcx>,
                                                 predicates: I)
                                                 -> EvaluationResult<'tcx>
         where I : Iterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
@@ -367,7 +376,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn evaluate_predicate_recursively<'o>(&mut self,
-                                          previous_stack: Option<&TraitObligationStack<'o, 'tcx>>,
+                                          previous_stack: TraitObligationStackList<'o, 'tcx>,
                                           obligation: &PredicateObligation<'tcx>)
                                            -> EvaluationResult<'tcx>
     {
@@ -418,14 +427,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn evaluate_obligation_recursively<'o>(&mut self,
-                                           previous_stack: Option<&TraitObligationStack<'o, 'tcx>>,
+                                           previous_stack: TraitObligationStackList<'o, 'tcx>,
                                            obligation: &TraitObligation<'tcx>)
                                            -> EvaluationResult<'tcx>
     {
         debug!("evaluate_obligation_recursively({})",
                obligation.repr(self.tcx()));
 
-        let stack = self.push_stack(previous_stack.map(|x| x), obligation);
+        let stack = self.push_stack(previous_stack, obligation);
 
         let result = self.evaluate_stack(&stack);
 
@@ -467,7 +476,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             unbound_input_types &&
              (self.intercrate ||
               stack.iter().skip(1).any(
-                  |prev| stack.fresh_trait_ref.def_id() == prev.fresh_trait_ref.def_id()))
+                  |prev| self.match_fresh_trait_refs(&stack.fresh_trait_ref,
+                                                     &prev.fresh_trait_ref)))
         {
             debug!("evaluate_stack({}) --> unbound argument, recursion -->  ambiguous",
                    stack.fresh_trait_ref.repr(self.tcx()));
@@ -533,7 +543,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                                        obligation.recursion_depth + 1,
                                                        skol_map,
                                                        snapshot);
-                    self.winnow_selection(None, VtableImpl(vtable_impl)).may_apply()
+                    self.winnow_selection(TraitObligationStackList::empty(),
+                                          VtableImpl(vtable_impl)).may_apply()
                 }
                 Err(()) => {
                     false
@@ -547,7 +558,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     //
     // The selection process begins by examining all in-scope impls,
     // caller obligations, and so forth and assembling a list of
-    // candidates. See `doc.rs` and the `Candidate` type for more details.
+    // candidates. See `README.md` and the `Candidate` type for more
+    // details.
 
     fn candidate_from_obligation<'o>(&mut self,
                                      stack: &TraitObligationStack<'o, 'tcx>)
@@ -557,10 +569,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // not update) the cache.
         let recursion_limit = self.infcx.tcx.sess.recursion_limit.get();
         if stack.obligation.recursion_depth >= recursion_limit {
-            debug!("{} --> overflow (limit={})",
-                   stack.obligation.repr(self.tcx()),
-                   recursion_limit);
-            return Err(Overflow)
+            report_overflow_error(self.infcx(), &stack.obligation);
         }
 
         // Check the cache. Note that we skolemize the trait-ref
@@ -604,6 +613,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             return Ok(Some(ErrorCandidate));
         }
 
+        if !self.is_knowable(stack) {
+            debug!("intercrate not knowable");
+            return Ok(None);
+        }
+
         let candidate_set = try!(self.assemble_candidates(stack));
 
         if candidate_set.ambiguous {
@@ -625,7 +639,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // for example, we are looking for $0:Eq where $0 is some
         // unconstrained type variable. In that case, we'll get a
         // candidate which assumes $0 == int, one that assumes $0 ==
-        // uint, etc. This spells an ambiguity.
+        // usize, etc. This spells an ambiguity.
 
         // If there is more than one candidate, first winnow them down
         // by considering extra conditions (nested obligations and so
@@ -704,6 +718,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         Ok(Some(candidate))
     }
 
+    fn is_knowable<'o>(&mut self,
+                       stack: &TraitObligationStack<'o, 'tcx>)
+                       -> bool
+    {
+        debug!("is_knowable(intercrate={})", self.intercrate);
+
+        if !self.intercrate {
+            return true;
+        }
+
+        let obligation = &stack.obligation;
+        let predicate = self.infcx().resolve_type_vars_if_possible(&obligation.predicate);
+
+        // ok to skip binder because of the nature of the
+        // trait-ref-is-knowable check, which does not care about
+        // bound regions
+        let trait_ref = &predicate.skip_binder().trait_ref;
+
+        coherence::trait_ref_is_knowable(self.tcx(), trait_ref)
+    }
+
     fn pick_candidate_cache(&self) -> &SelectionCache<'tcx> {
         // If there are any where-clauses in scope, then we always use
         // a cache local to this particular scope. Otherwise, we
@@ -817,31 +852,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 debug!("obligation self ty is {}",
                        obligation.predicate.0.self_ty().repr(self.tcx()));
 
+                // User-defined copy impls are permitted, but only for
+                // structs and enums.
                 try!(self.assemble_candidates_from_impls(obligation, &mut candidates));
 
+                // For other types, we'll use the builtin rules.
                 try!(self.assemble_builtin_bound_candidates(ty::BoundCopy,
                                                             stack,
                                                             &mut candidates));
             }
-            Some(bound @ ty::BoundSend) |
-            Some(bound @ ty::BoundSync) => {
-                try!(self.assemble_candidates_from_impls(obligation, &mut candidates));
-
-                // No explicit impls were declared for this type, consider the fallback rules.
-                if candidates.vec.is_empty() && !candidates.ambiguous {
-                    try!(self.assemble_builtin_bound_candidates(bound, stack, &mut candidates));
-                }
-            }
-
             Some(bound @ ty::BoundSized) => {
-                // Sized and Copy are always automatically computed.
+                // Sized is never implementable by end-users, it is
+                // always automatically computed.
                 try!(self.assemble_builtin_bound_candidates(bound, stack, &mut candidates));
             }
 
+            Some(ty::BoundSend) |
+            Some(ty::BoundSync) |
             None => {
-                // 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_closure_candidates(obligation, &mut candidates));
                 try!(self.assemble_fn_pointer_candidates(obligation, &mut candidates));
                 try!(self.assemble_candidates_from_impls(obligation, &mut candidates));
@@ -851,6 +879,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         self.assemble_candidates_from_projected_tys(obligation, &mut candidates);
         try!(self.assemble_candidates_from_caller_bounds(stack, &mut candidates));
+        // Default implementations have lower priority, so we only
+        // consider triggering a default if there is no other impl that can apply.
+        if candidates.vec.len() == 0 {
+            try!(self.assemble_candidates_from_default_impls(obligation, &mut candidates));
+        }
         debug!("candidate list size: {}", candidates.vec.len());
         Ok(candidates)
     }
@@ -1025,7 +1058,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         self.infcx().probe(move |_| {
             match self.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) {
                 Ok(obligations) => {
-                    self.evaluate_predicates_recursively(Some(stack), obligations.iter())
+                    self.evaluate_predicates_recursively(stack.list(), obligations.iter())
                 }
                 Err(()) => {
                     EvaluatedToErr(Unimplemented)
@@ -1050,9 +1083,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             None => { return Ok(()); }
         };
 
-        let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
+        // ok to skip binder because the substs on closure types never
+        // touch bound regions, they just capture the in-scope
+        // type/region parameters
+        let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
         let (closure_def_id, substs) = match self_ty.sty {
-            ty::ty_closure(id, _, ref substs) => (id, substs.clone()),
+            ty::ty_closure(id, ref substs) => (id, substs.clone()),
             ty::ty_infer(ty::TyVar(_)) => {
                 debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
                 candidates.ambiguous = true;
@@ -1069,7 +1105,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         match self.closure_typer.closure_kind(closure_def_id) {
             Some(closure_kind) => {
                 debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind);
-                if closure_kind == kind {
+                if closure_kind.extends(kind) {
                     candidates.vec.push(ClosureCandidate(closure_def_id, substs.clone()));
                 }
             }
@@ -1088,14 +1124,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                       candidates: &mut SelectionCandidateSet<'tcx>)
                                       -> Result<(),SelectionError<'tcx>>
     {
-        // We provide a `Fn` impl for fn pointers. There is no need to provide
-        // the other traits (e.g. `FnMut`) since those are provided by blanket
-        // impls.
-        if Some(obligation.predicate.def_id()) != self.tcx().lang_items.fn_trait() {
+        // We provide impl of all fn traits for fn pointers.
+        if self.tcx().lang_items.fn_trait_kind(obligation.predicate.def_id()).is_none() {
             return Ok(());
         }
 
-        let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
+        // ok to skip binder because what we are inspecting doesn't involve bound regions
+        let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
         match self_ty.sty {
             ty::ty_infer(ty::TyVar(_)) => {
                 debug!("assemble_fn_pointer_candidates: ambiguous self-type");
@@ -1127,10 +1162,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                       candidates: &mut SelectionCandidateSet<'tcx>)
                                       -> Result<(), SelectionError<'tcx>>
     {
-        let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
-        debug!("assemble_candidates_from_impls(self_ty={})", self_ty.repr(self.tcx()));
+        debug!("assemble_candidates_from_impls(obligation={})", obligation.repr(self.tcx()));
 
-        let all_impls = self.all_impls(obligation.predicate.def_id());
+        let def_id = obligation.predicate.def_id();
+        let all_impls = self.all_impls(def_id);
         for &impl_def_id in &all_impls {
             self.infcx.probe(|snapshot| {
                 let (skol_obligation_trait_pred, skol_map) =
@@ -1144,6 +1179,78 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
             });
         }
+
+        Ok(())
+    }
+
+    fn assemble_candidates_from_default_impls(&mut self,
+                                              obligation: &TraitObligation<'tcx>,
+                                              candidates: &mut SelectionCandidateSet<'tcx>)
+                                              -> Result<(), SelectionError<'tcx>>
+    {
+        // OK to skip binder here because the tests we do below do not involve bound regions
+        let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
+        debug!("assemble_candidates_from_default_impls(self_ty={})", self_ty.repr(self.tcx()));
+
+        let def_id = obligation.predicate.def_id();
+
+        if ty::trait_has_default_impl(self.tcx(), def_id) {
+            match self_ty.sty {
+                ty::ty_trait(..) => {
+                    // For object types, we don't know what the closed
+                    // over types are. For most traits, this means we
+                    // conservatively say nothing; a candidate may be
+                    // added by `assemble_candidates_from_object_ty`.
+                    // However, for the kind of magic reflect trait,
+                    // we consider it to be implemented even for
+                    // object types, because it just lets you reflect
+                    // onto the object type, not into the object's
+                    // interior.
+                    if ty::has_attr(self.tcx(), def_id, "rustc_reflect_like") {
+                        candidates.vec.push(DefaultImplObjectCandidate(def_id));
+                    }
+                }
+                ty::ty_param(..) |
+                ty::ty_projection(..) => {
+                    // In these cases, we don't know what the actual
+                    // type is.  Therefore, we cannot break it down
+                    // into its constituent types. So we don't
+                    // consider the `..` impl but instead just add no
+                    // candidates: this means that typeck will only
+                    // succeed if there is another reason to believe
+                    // that this obligation holds. That could be a
+                    // where-clause or, in the case of an object type,
+                    // it could be that the object type lists the
+                    // trait (e.g. `Foo+Send : Send`). See
+                    // `compile-fail/typeck-default-trait-impl-send-param.rs`
+                    // for an example of a test case that exercises
+                    // this path.
+                }
+                ty::ty_infer(ty::TyVar(_)) => {
+                    // the defaulted impl might apply, we don't know
+                    candidates.ambiguous = true;
+                }
+                _ => {
+                    if self.constituent_types_for_ty(self_ty).is_some() {
+                        candidates.vec.push(DefaultImplCandidate(def_id.clone()))
+                    } else {
+                        // We don't yet know what the constituent
+                        // types are. So call it ambiguous for now,
+                        // though this is a bit stronger than
+                        // necessary: that is, we know that the
+                        // defaulted impl applies, but we can't
+                        // process the confirmation step without
+                        // knowing the constituent types. (Anyway, in
+                        // the particular case of defaulted impls, it
+                        // doesn't really matter much either way,
+                        // since we won't be aiding inference by
+                        // processing the confirmation step.)
+                        candidates.ambiguous = true;
+                    }
+                }
+            }
+        }
+
         Ok(())
     }
 
@@ -1152,10 +1259,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                           obligation: &TraitObligation<'tcx>,
                                           candidates: &mut SelectionCandidateSet<'tcx>)
     {
-        let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
-
         debug!("assemble_candidates_from_object_ty(self_ty={})",
-               self_ty.repr(self.tcx()));
+               self.infcx.shallow_resolve(*obligation.self_ty().skip_binder()).repr(self.tcx()));
 
         // Object-safety candidates are only applicable to object-safe
         // traits. Including this check is useful because it helps
@@ -1164,43 +1269,56 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // self-type from one of the other inputs. Without this check,
         // these cases wind up being considered ambiguous due to a
         // (spurious) ambiguity introduced here.
-        if !object_safety::is_object_safe(self.tcx(), obligation.predicate.to_poly_trait_ref()) {
+        let predicate_trait_ref = obligation.predicate.to_poly_trait_ref();
+        if !object_safety::is_object_safe(self.tcx(), predicate_trait_ref.def_id()) {
             return;
         }
 
-        let poly_trait_ref = match self_ty.sty {
-            ty::ty_trait(ref data) => {
-                data.principal_trait_ref_with_self_ty(self.tcx(), self_ty)
-            }
-            ty::ty_infer(ty::TyVar(_)) => {
-                debug!("assemble_candidates_from_object_ty: ambiguous");
-                candidates.ambiguous = true; // could wind up being an object type
-                return;
-            }
-            _ => {
-                return;
-            }
-        };
+        self.infcx.commit_if_ok(|snapshot| {
+            let bound_self_ty =
+                self.infcx.resolve_type_vars_if_possible(&obligation.self_ty());
+            let (self_ty, _) =
+                self.infcx().skolemize_late_bound_regions(&bound_self_ty, snapshot);
+            let poly_trait_ref = match self_ty.sty {
+                ty::ty_trait(ref data) => {
+                    match self.tcx().lang_items.to_builtin_kind(obligation.predicate.def_id()) {
+                        Some(bound @ ty::BoundSend) | Some(bound @ ty::BoundSync) => {
+                            if data.bounds.builtin_bounds.contains(&bound) {
+                                debug!("assemble_candidates_from_object_ty: matched builtin bound, \
+                                        pushing candidate");
+                                candidates.vec.push(BuiltinObjectCandidate);
+                                return Ok(());
+                            }
+                        }
+                        _ => {}
+                    }
 
-        debug!("assemble_candidates_from_object_ty: poly_trait_ref={}",
-               poly_trait_ref.repr(self.tcx()));
+                    data.principal_trait_ref_with_self_ty(self.tcx(), self_ty)
+                }
+                ty::ty_infer(ty::TyVar(_)) => {
+                    debug!("assemble_candidates_from_object_ty: ambiguous");
+                    candidates.ambiguous = true; // could wind up being an object type
+                    return Ok(());
+                }
+                _ => {
+                    return Ok(());
+                }
+            };
 
-        // see whether the object trait can be upcast to the trait we are looking for
-        let obligation_def_id = obligation.predicate.def_id();
-        let upcast_trait_ref = match util::upcast(self.tcx(), poly_trait_ref, obligation_def_id) {
-            Some(r) => r,
-            None => { return; }
-        };
+            debug!("assemble_candidates_from_object_ty: poly_trait_ref={}",
+                   poly_trait_ref.repr(self.tcx()));
 
-        debug!("assemble_candidates_from_object_ty: upcast_trait_ref={}",
-               upcast_trait_ref.repr(self.tcx()));
+            // see whether the object trait can be upcast to the trait we are looking for
+            let upcast_trait_refs = self.upcast(poly_trait_ref, obligation);
+            if upcast_trait_refs.len() > 1 {
+                // can be upcast in many ways; need more type information
+                candidates.ambiguous = true;
+            } else if upcast_trait_refs.len() == 1 {
+                candidates.vec.push(ObjectCandidate);
+            }
 
-        // check whether the upcast version of the trait-ref matches what we are looking for
-        if let Ok(()) = self.infcx.probe(|_| self.match_poly_trait_ref(obligation,
-                                                                       upcast_trait_ref.clone())) {
-            debug!("assemble_candidates_from_object_ty: matched, pushing candidate");
-            candidates.vec.push(ObjectCandidate);
-        }
+            Ok::<(),()>(())
+        }).unwrap();
     }
 
     ///////////////////////////////////////////////////////////////////////////
@@ -1224,7 +1342,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let result = self.infcx.probe(|_| {
             let candidate = (*candidate).clone();
             match self.confirm_candidate(stack.obligation, candidate) {
-                Ok(selection) => self.winnow_selection(Some(stack), selection),
+                Ok(selection) => self.winnow_selection(stack.list(),
+                                                       selection),
                 Err(error) => EvaluatedToErr(error),
             }
         });
@@ -1234,7 +1353,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn winnow_selection<'o>(&mut self,
-                            stack: Option<&TraitObligationStack<'o, 'tcx>>,
+                            stack: TraitObligationStackList<'o,'tcx>,
                             selection: Selection<'tcx>)
                             -> EvaluationResult<'tcx>
     {
@@ -1257,6 +1376,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             (&ImplCandidate(..), &ParamCandidate(..)) |
             (&ClosureCandidate(..), &ParamCandidate(..)) |
             (&FnPointerCandidate(..), &ParamCandidate(..)) |
+            (&BuiltinObjectCandidate(..), &ParamCandidate(_)) |
             (&BuiltinCandidate(..), &ParamCandidate(..)) => {
                 // We basically prefer always prefer to use a
                 // where-clause over another option. Where clauses
@@ -1266,6 +1386,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // #18453.
                 true
             }
+            (&DefaultImplCandidate(_), _) => {
+                // Prefer other candidates over default implementations.
+                self.tcx().sess.bug(
+                    "default implementations shouldn't be recorded \
+                     when there are other valid candidates");
+            }
             (&ProjectionCandidate, &ParamCandidate(_)) => {
                 // FIXME(#20297) -- this gives where clauses precedent
                 // over projections. Really these are just two means
@@ -1337,92 +1463,76 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ty::ty_bare_fn(..) |
             ty::ty_char => {
                 // safe for everything
-                Ok(If(Vec::new()))
+                ok_if(Vec::new())
             }
 
-            ty::ty_uniq(referent_ty) => {  // Box<T>
+            ty::ty_uniq(_) => {  // Box<T>
                 match bound {
-                    ty::BoundCopy => {
-                        Err(Unimplemented)
-                    }
+                    ty::BoundCopy => Err(Unimplemented),
 
-                    ty::BoundSized => {
-                        Ok(If(Vec::new()))
-                    }
+                    ty::BoundSized => ok_if(Vec::new()),
 
-                    ty::BoundSync |
-                    ty::BoundSend => {
-                        Ok(If(vec![referent_ty]))
+                    ty::BoundSync | ty::BoundSend => {
+                        self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()");
                     }
                 }
             }
 
             ty::ty_ptr(..) => {     // *const T, *mut T
                 match bound {
-                    ty::BoundCopy |
-                    ty::BoundSized => {
-                        Ok(If(Vec::new()))
-                    }
+                    ty::BoundCopy | ty::BoundSized => ok_if(Vec::new()),
 
-                    ty::BoundSync |
-                    ty::BoundSend => {
-                        // sync and send are not implemented for *const, *mut
-                        Err(Unimplemented)
+                    ty::BoundSync | ty::BoundSend => {
+                        self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()");
                     }
                 }
             }
 
             ty::ty_trait(ref data) => {
                 match bound {
-                    ty::BoundSized => {
-                        Err(Unimplemented)
-                    }
-                    ty::BoundCopy | ty::BoundSync | ty::BoundSend => {
+                    ty::BoundSized => Err(Unimplemented),
+                    ty::BoundCopy => {
                         if data.bounds.builtin_bounds.contains(&bound) {
-                            Ok(If(Vec::new()))
+                            ok_if(Vec::new())
                         } else {
                             // Recursively check all supertraits to find out if any further
                             // bounds are required and thus we must fulfill.
                             let principal =
                                 data.principal_trait_ref_with_self_ty(self.tcx(),
                                                                       self.tcx().types.err);
+                            let desired_def_id = obligation.predicate.def_id();
                             for tr in util::supertraits(self.tcx(), principal) {
-                                let td = ty::lookup_trait_def(self.tcx(), tr.def_id());
-                                if td.bounds.builtin_bounds.contains(&bound) {
-                                    return Ok(If(Vec::new()))
+                                if tr.def_id() == desired_def_id {
+                                    return ok_if(Vec::new())
                                 }
                             }
 
                             Err(Unimplemented)
                         }
                     }
+                    ty::BoundSync | ty::BoundSend => {
+                        self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()");
+                    }
                 }
             }
 
-            ty::ty_rptr(_, ty::mt { ty: referent_ty, mutbl }) => {
+            ty::ty_rptr(_, ty::mt { ty: _, mutbl }) => {
                 // &mut T or &T
                 match bound {
                     ty::BoundCopy => {
                         match mutbl {
                             // &mut T is affine and hence never `Copy`
-                            ast::MutMutable => {
-                                Err(Unimplemented)
-                            }
+                            ast::MutMutable => Err(Unimplemented),
 
                             // &T is always copyable
-                            ast::MutImmutable => {
-                                Ok(If(Vec::new()))
-                            }
+                            ast::MutImmutable => ok_if(Vec::new()),
                         }
                     }
 
-                    ty::BoundSized => {
-                        Ok(If(Vec::new()))
-                    }
+                    ty::BoundSized => ok_if(Vec::new()),
 
-                    ty::BoundSync |
-                    ty::BoundSend => {
-                        Ok(If(vec![referent_ty]))
+                    ty::BoundSync | ty::BoundSend => {
+                        self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()");
                     }
                 }
             }
@@ -1432,28 +1542,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 match bound {
                     ty::BoundCopy => {
                         match *len {
-                            Some(_) => {
-                                // [T, ..n] is copy iff T is copy
-                                Ok(If(vec![element_ty]))
-                            }
-                            None => {
-                                // [T] is unsized and hence affine
-                                Err(Unimplemented)
-                            }
+                            // [T, ..n] is copy iff T is copy
+                            Some(_) => ok_if(vec![element_ty]),
+
+                            // [T] is unsized and hence affine
+                            None => Err(Unimplemented),
                         }
                     }
 
                     ty::BoundSized => {
                         if len.is_some() {
-                            Ok(If(Vec::new()))
+                            ok_if(Vec::new())
                         } else {
                             Err(Unimplemented)
                         }
                     }
 
-                    ty::BoundSync |
-                    ty::BoundSend => {
-                        Ok(If(vec![element_ty]))
+                    ty::BoundSync | ty::BoundSend => {
+                        self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()");
                     }
                 }
             }
@@ -1461,24 +1567,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ty::ty_str => {
                 // Equivalent to [u8]
                 match bound {
-                    ty::BoundSync |
-                    ty::BoundSend => {
-                        Ok(If(Vec::new()))
+                    ty::BoundSync | ty::BoundSend => {
+                        self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()");
                     }
 
-                    ty::BoundCopy |
-                    ty::BoundSized => {
-                        Err(Unimplemented)
-                    }
+                    ty::BoundCopy | ty::BoundSized => Err(Unimplemented),
                 }
             }
 
-            ty::ty_tup(ref tys) => {
-                // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
-                Ok(If(tys.clone()))
-            }
+            // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
+            ty::ty_tup(ref tys) => ok_if(tys.clone()),
 
-            ty::ty_closure(def_id, _, substs) => {
+            ty::ty_closure(def_id, substs) => {
                 // FIXME -- This case is tricky. In the case of by-ref
                 // closures particularly, we need the results of
                 // inference to decide how to reflect the type of each
@@ -1501,13 +1601,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // unsized, so the closure struct as a whole must be
                 // Sized.
                 if bound == ty::BoundSized {
-                    return Ok(If(Vec::new()));
+                    return ok_if(Vec::new());
                 }
 
                 match self.closure_typer.closure_upvars(def_id, substs) {
-                    Some(upvars) => {
-                        Ok(If(upvars.iter().map(|c| c.ty).collect()))
-                    }
+                    Some(upvars) => ok_if(upvars.iter().map(|c| c.ty).collect()),
                     None => {
                         debug!("assemble_builtin_bound_candidates: no upvar types available yet");
                         Ok(AmbiguousBuiltin)
@@ -1520,7 +1618,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     ty::struct_fields(self.tcx(), def_id, substs).iter()
                                                                  .map(|f| f.mt.ty)
                                                                  .collect();
-                nominal(self, bound, def_id, types)
+                nominal(bound, types)
             }
 
             ty::ty_enum(def_id, substs) => {
@@ -1530,11 +1628,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     .flat_map(|variant| variant.args.iter())
                     .cloned()
                     .collect();
-                nominal(self, bound, def_id, types)
+                nominal(bound, types)
             }
 
-            ty::ty_projection(_) |
-            ty::ty_param(_) => {
+            ty::ty_projection(_) | ty::ty_param(_) => {
                 // Note: A type parameter is only considered to meet a
                 // particular bound if there is a where clause telling
                 // us that it does, and that case is handled by
@@ -1550,67 +1647,193 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 Ok(AmbiguousBuiltin)
             }
 
-            ty::ty_open(ty) => {
-                // these only crop up in trans, and represent an
-                // "opened" unsized/existential type (one that has
-                // been dereferenced)
-                match bound {
-                    ty::BoundCopy |
-                    ty::BoundSync |
-                    ty::BoundSend => {
-                        Ok(If(vec!(ty)))
-                    }
-
-                    ty::BoundSized => {
-                        Err(Unimplemented)
-                    }
-                }
-            }
-            ty::ty_err => {
-                Ok(If(Vec::new()))
-            }
+            ty::ty_err => ok_if(Vec::new()),
 
-            ty::ty_infer(ty::FreshTy(_)) |
-            ty::ty_infer(ty::FreshIntTy(_)) => {
+            ty::ty_infer(ty::FreshTy(_))
+            ty::ty_infer(ty::FreshIntTy(_)) => {
                 self.tcx().sess.bug(
                     &format!(
                         "asked to assemble builtin bounds of unexpected type: {}",
-                        self_ty.repr(self.tcx()))[]);
+                        self_ty.repr(self.tcx())));
             }
         };
 
-        fn nominal<'cx, 'tcx>(this: &mut SelectionContext<'cx, 'tcx>,
-                              bound: ty::BuiltinBound,
-                              def_id: ast::DefId,
+        fn ok_if<'tcx>(v: Vec<Ty<'tcx>>)
+                       -> Result<BuiltinBoundConditions<'tcx>, SelectionError<'tcx>> {
+            Ok(If(ty::Binder(v)))
+        }
+
+        fn nominal<'cx, 'tcx>(bound: ty::BuiltinBound,
                               types: Vec<Ty<'tcx>>)
-                              -> Result<BuiltinBoundConditions<'tcx>,SelectionError<'tcx>>
+                              -> Result<BuiltinBoundConditions<'tcx>, SelectionError<'tcx>>
         {
             // First check for markers and other nonsense.
-            let tcx = this.tcx();
             match bound {
-                ty::BoundSend => {
-                    if Some(def_id) == tcx.lang_items.managed_bound() {
-                        return Err(Unimplemented)
-                    }
-                }
+                // Fallback to whatever user-defined impls exist in this case.
+                ty::BoundCopy => Ok(ParameterBuiltin),
 
-                ty::BoundCopy => {
-                    return Ok(ParameterBuiltin)
-                }
+                // Sized if all the component types are sized.
+                ty::BoundSized => ok_if(types),
+
+                // Shouldn't be coming through here.
+                ty::BoundSend | ty::BoundSync => unreachable!(),
+            }
+        }
+    }
+
+    /// For default impls, we need to break apart a type into its
+    /// "constituent types" -- meaning, the types that it contains.
+    ///
+    /// Here are some (simple) examples:
+    ///
+    /// ```
+    /// (i32, u32) -> [i32, u32]
+    /// Foo where struct Foo { x: i32, y: u32 } -> [i32, u32]
+    /// Bar<i32> where struct Bar<T> { x: T, y: u32 } -> [i32, u32]
+    /// Zed<i32> where enum Zed { A(T), B(u32) } -> [i32, u32]
+    /// ```
+    fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Option<Vec<Ty<'tcx>>> {
+        match t.sty {
+            ty::ty_uint(_) |
+            ty::ty_int(_) |
+            ty::ty_bool |
+            ty::ty_float(_) |
+            ty::ty_bare_fn(..) |
+            ty::ty_str |
+            ty::ty_err |
+            ty::ty_infer(ty::IntVar(_)) |
+            ty::ty_infer(ty::FloatVar(_)) |
+            ty::ty_char => {
+                Some(Vec::new())
+            }
+
+            ty::ty_trait(..) |
+            ty::ty_param(..) |
+            ty::ty_projection(..) |
+            ty::ty_infer(ty::TyVar(_)) |
+            ty::ty_infer(ty::FreshTy(_)) |
+            ty::ty_infer(ty::FreshIntTy(_)) => {
+                self.tcx().sess.bug(
+                    &format!(
+                        "asked to assemble constituent types of unexpected type: {}",
+                        t.repr(self.tcx())));
+            }
+
+            ty::ty_uniq(referent_ty) => {  // Box<T>
+                Some(vec![referent_ty])
+            }
+
+            ty::ty_ptr(ty::mt { ty: element_ty, ..}) |
+            ty::ty_rptr(_, ty::mt { ty: element_ty, ..}) => {
+                Some(vec![element_ty])
+            },
+
+            ty::ty_vec(element_ty, _) => {
+                Some(vec![element_ty])
+            }
 
-                ty::BoundSync => {
-                    if
-                        Some(def_id) == tcx.lang_items.managed_bound() ||
-                        Some(def_id) == tcx.lang_items.unsafe_cell_type()
-                    {
-                        return Err(Unimplemented)
+            ty::ty_tup(ref tys) => {
+                // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
+                Some(tys.clone())
+            }
+
+            ty::ty_closure(def_id, substs) => {
+                assert_eq!(def_id.krate, ast::LOCAL_CRATE);
+
+                match self.closure_typer.closure_upvars(def_id, substs) {
+                    Some(upvars) => {
+                        Some(upvars.iter().map(|c| c.ty).collect())
+                    }
+                    None => {
+                        None
                     }
                 }
+            }
+
+            // for `PhantomData<T>`, we pass `T`
+            ty::ty_struct(def_id, substs)
+                if Some(def_id) == self.tcx().lang_items.phantom_data() =>
+            {
+                Some(substs.types.get_slice(TypeSpace).to_vec())
+            }
 
-                ty::BoundSized => { }
+            ty::ty_struct(def_id, substs) => {
+                Some(ty::struct_fields(self.tcx(), def_id, substs).iter()
+                     .map(|f| f.mt.ty)
+                     .collect())
             }
 
-            Ok(If(types))
+            ty::ty_enum(def_id, substs) => {
+                Some(ty::substd_enum_variants(self.tcx(), def_id, substs)
+                     .iter()
+                     .flat_map(|variant| variant.args.iter())
+                     .map(|&ty| ty)
+                     .collect())
+            }
+        }
+    }
+
+    fn collect_predicates_for_types(&mut self,
+                                    obligation: &TraitObligation<'tcx>,
+                                    trait_def_id: ast::DefId,
+                                    types: ty::Binder<Vec<Ty<'tcx>>>)
+                                    -> Vec<PredicateObligation<'tcx>>
+    {
+        let derived_cause = match self.tcx().lang_items.to_builtin_kind(trait_def_id) {
+            Some(_) => {
+                self.derived_cause(obligation, BuiltinDerivedObligation)
+            },
+            None => {
+                self.derived_cause(obligation, ImplDerivedObligation)
+            }
+        };
+
+        // Because the types were potentially derived from
+        // higher-ranked obligations they may reference late-bound
+        // regions. For example, `for<'a> Foo<&'a int> : Copy` would
+        // yield a type like `for<'a> &'a int`. In general, we
+        // maintain the invariant that we never manipulate bound
+        // regions, so we have to process these bound regions somehow.
+        //
+        // The strategy is to:
+        //
+        // 1. Instantiate those regions to skolemized regions (e.g.,
+        //    `for<'a> &'a int` becomes `&0 int`.
+        // 2. Produce something like `&'0 int : Copy`
+        // 3. Re-bind the regions back to `for<'a> &'a int : Copy`
+
+        // Move the binder into the individual types
+        let bound_types: Vec<ty::Binder<Ty<'tcx>>> =
+            types.skip_binder()
+                 .iter()
+                 .map(|&nested_ty| ty::Binder(nested_ty))
+                 .collect();
+
+        // For each type, produce a vector of resulting obligations
+        let obligations: Result<Vec<Vec<_>>, _> = bound_types.iter().map(|nested_ty| {
+            self.infcx.commit_if_ok(|snapshot| {
+                let (skol_ty, skol_map) =
+                    self.infcx().skolemize_late_bound_regions(nested_ty, snapshot);
+                let Normalized { value: normalized_ty, mut obligations } =
+                    project::normalize_with_depth(self,
+                                                  obligation.cause.clone(),
+                                                  obligation.recursion_depth + 1,
+                                                  &skol_ty);
+                let skol_obligation =
+                    try!(util::predicate_for_trait_def(self.tcx(),
+                                                       derived_cause.clone(),
+                                                       trait_def_id,
+                                                       obligation.recursion_depth + 1,
+                                                       normalized_ty));
+                obligations.push(skol_obligation);
+                Ok(self.infcx().plug_leaks(skol_map, snapshot, &obligations))
+            })
+        }).collect();
+
+        // Flatten those vectors (couldn't do it above due `collect`)
+        match obligations {
+            Ok(obligations) => obligations.into_iter().flat_map(|o| o.into_iter()).collect(),
+            Err(ErrorReported) => Vec::new(),
         }
     }
 
@@ -1619,7 +1842,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     //
     // Confirmation unifies the output type parameters of the trait
     // with the values found in the obligation, possibly yielding a
-    // type error.  See `doc.rs` for more details.
+    // type error.  See `README.md` for more details.
 
     fn confirm_candidate(&mut self,
                          obligation: &TraitObligation<'tcx>,
@@ -1646,6 +1869,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 Ok(VtableParam(obligations))
             }
 
+            DefaultImplCandidate(trait_def_id) => {
+                let data = self.confirm_default_impl_candidate(obligation, trait_def_id);
+                Ok(VtableDefaultImpl(data))
+            }
+
+            DefaultImplObjectCandidate(trait_def_id) => {
+                let data = self.confirm_default_impl_object_candidate(obligation, trait_def_id);
+                Ok(VtableDefaultImpl(data))
+            }
+
             ImplCandidate(impl_def_id) => {
                 let vtable_impl =
                     try!(self.confirm_impl_candidate(obligation, impl_def_id));
@@ -1657,6 +1890,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 Ok(VtableClosure(closure_def_id, substs))
             }
 
+            BuiltinObjectCandidate => {
+                // This indicates something like `(Trait+Send) :
+                // Send`. In this case, we know that this holds
+                // because that's what the object type is telling us,
+                // and there's really no additional obligations to
+                // prove and no types in particular to unify etc.
+                Ok(VtableParam(Vec::new()))
+            }
+
             ObjectCandidate => {
                 let data = self.confirm_object_candidate(obligation);
                 Ok(VtableObject(data))
@@ -1679,7 +1921,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                     obligation: &TraitObligation<'tcx>)
     {
         let _: Result<(),()> =
-            self.infcx.try(|snapshot| {
+            self.infcx.commit_if_ok(|snapshot| {
                 let result =
                     self.match_projection_obligation_against_bounds_from_trait(obligation,
                                                                                snapshot);
@@ -1727,7 +1969,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 self.tcx().sess.span_bug(
                     obligation.cause.span,
                     &format!("builtin bound for {} was ambig",
-                            obligation.repr(self.tcx()))[]);
+                            obligation.repr(self.tcx())));
             }
         }
     }
@@ -1735,41 +1977,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     fn vtable_builtin_data(&mut self,
                            obligation: &TraitObligation<'tcx>,
                            bound: ty::BuiltinBound,
-                           nested: Vec<Ty<'tcx>>)
+                           nested: ty::Binder<Vec<Ty<'tcx>>>)
                            -> VtableBuiltinData<PredicateObligation<'tcx>>
     {
-        let derived_cause = self.derived_cause(obligation, BuiltinDerivedObligation);
-        let obligations = nested.iter().map(|&bound_ty| {
-            // the obligation might be higher-ranked, e.g. for<'a> &'a
-            // int : Copy. In that case, we will wind up with
-            // late-bound regions in the `nested` vector. So for each
-            // one we instantiate to a skolemized region, do our work
-            // to produce something like `&'0 int : Copy`, and then
-            // re-bind it. This is a bit of busy-work but preserves
-            // the invariant that we only manipulate free regions, not
-            // bound ones.
-            self.infcx.try(|snapshot| {
-                let (skol_ty, skol_map) =
-                    self.infcx().skolemize_late_bound_regions(&ty::Binder(bound_ty), snapshot);
-                let skol_predicate =
-                    util::predicate_for_builtin_bound(
-                        self.tcx(),
-                        derived_cause.clone(),
-                        bound,
-                        obligation.recursion_depth + 1,
-                        skol_ty);
-                match skol_predicate {
-                    Ok(skol_predicate) => Ok(self.infcx().plug_leaks(skol_map, snapshot,
-                                                                     &skol_predicate)),
-                    Err(ErrorReported) => Err(ErrorReported)
-                }
-            })
-        }).collect::<Result<_, _>>();
-        let obligations = match obligations {
-            Ok(o) => o,
-            Err(ErrorReported) => Vec::new()
+        let trait_def = match self.tcx().lang_items.from_builtin_kind(bound) {
+            Ok(def_id) => def_id,
+            Err(_) => {
+                self.tcx().sess.bug("builtin trait definition not found");
+            }
         };
 
+        let obligations = self.collect_predicates_for_types(obligation, trait_def, nested);
+
         let obligations = VecPerParamSpace::new(obligations, Vec::new(), Vec::new());
 
         debug!("vtable_builtin_data: obligations={}",
@@ -1778,6 +1997,107 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         VtableBuiltinData { nested: obligations }
     }
 
+    /// This handles the case where a `impl Foo for ..` impl is being used.
+    /// The idea is that the impl applies to `X : Foo` if the following conditions are met:
+    ///
+    /// 1. For each constituent type `Y` in `X`, `Y : Foo` holds
+    /// 2. For each where-clause `C` declared on `Foo`, `[Self => X] C` holds.
+    fn confirm_default_impl_candidate(&mut self,
+                                      obligation: &TraitObligation<'tcx>,
+                                      trait_def_id: ast::DefId)
+                                      -> VtableDefaultImplData<PredicateObligation<'tcx>>
+    {
+        debug!("confirm_default_impl_candidate({}, {})",
+               obligation.repr(self.tcx()),
+               trait_def_id.repr(self.tcx()));
+
+        // binder is moved below
+        let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
+        match self.constituent_types_for_ty(self_ty) {
+            Some(types) => self.vtable_default_impl(obligation, trait_def_id, ty::Binder(types)),
+            None => {
+                self.tcx().sess.bug(
+                    &format!(
+                        "asked to confirm default implementation for ambiguous type: {}",
+                        self_ty.repr(self.tcx())));
+            }
+        }
+    }
+
+    fn confirm_default_impl_object_candidate(&mut self,
+                                             obligation: &TraitObligation<'tcx>,
+                                             trait_def_id: ast::DefId)
+                                             -> VtableDefaultImplData<PredicateObligation<'tcx>>
+    {
+        debug!("confirm_default_impl_object_candidate({}, {})",
+               obligation.repr(self.tcx()),
+               trait_def_id.repr(self.tcx()));
+
+        assert!(ty::has_attr(self.tcx(), trait_def_id, "rustc_reflect_like"));
+
+        // OK to skip binder, it is reintroduced below
+        let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
+        match self_ty.sty {
+            ty::ty_trait(ref data) => {
+                // OK to skip the binder, it is reintroduced below
+                let input_types = data.principal.skip_binder().substs.types.get_slice(TypeSpace);
+                let assoc_types = data.bounds.projection_bounds
+                                             .iter()
+                                             .map(|pb| pb.skip_binder().ty);
+                let all_types: Vec<_> = input_types.iter().cloned()
+                                                          .chain(assoc_types)
+                                                          .collect();
+
+                // reintroduce the two binding levels we skipped, then flatten into one
+                let all_types = ty::Binder(ty::Binder(all_types));
+                let all_types = ty::flatten_late_bound_regions(self.tcx(), &all_types);
+
+                self.vtable_default_impl(obligation, trait_def_id, all_types)
+            }
+            _ => {
+                self.tcx().sess.bug(
+                    &format!(
+                        "asked to confirm default object implementation for non-object type: {}",
+                        self_ty.repr(self.tcx())));
+            }
+        }
+    }
+
+    /// See `confirm_default_impl_candidate`
+    fn vtable_default_impl(&mut self,
+                           obligation: &TraitObligation<'tcx>,
+                           trait_def_id: ast::DefId,
+                           nested: ty::Binder<Vec<Ty<'tcx>>>)
+                           -> VtableDefaultImplData<PredicateObligation<'tcx>>
+    {
+        debug!("vtable_default_impl_data: nested={}", nested.repr(self.tcx()));
+
+        let mut obligations = self.collect_predicates_for_types(obligation,
+                                                                trait_def_id,
+                                                                nested);
+
+        let trait_obligations: Result<VecPerParamSpace<_>,()> = self.infcx.commit_if_ok(|snapshot| {
+            let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
+            let (trait_ref, skol_map) =
+                self.infcx().skolemize_late_bound_regions(&poly_trait_ref, snapshot);
+            Ok(self.impl_or_trait_obligations(obligation.cause.clone(),
+                                              obligation.recursion_depth + 1,
+                                              trait_def_id,
+                                              &trait_ref.substs,
+                                              skol_map,
+                                              snapshot))
+        });
+
+        obligations.extend(trait_obligations.unwrap().into_iter()); // no Errors in that code above
+
+        debug!("vtable_default_impl_data: obligations={}", obligations.repr(self.tcx()));
+
+        VtableDefaultImplData {
+            trait_def_id: trait_def_id,
+            nested: obligations
+        }
+    }
+
     fn confirm_impl_candidate(&mut self,
                               obligation: &TraitObligation<'tcx>,
                               impl_def_id: ast::DefId)
@@ -1790,7 +2110,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         // First, create the substitutions by matching the impl again,
         // this time not in a probe.
-        self.infcx.try(|snapshot| {
+        self.infcx.commit_if_ok(|snapshot| {
             let (skol_obligation_trait_ref, skol_map) =
                 self.infcx().skolemize_late_bound_regions(&obligation.predicate, snapshot);
             let substs =
@@ -1806,7 +2126,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                    impl_def_id: ast::DefId,
                    substs: Normalized<'tcx, Substs<'tcx>>,
                    cause: ObligationCause<'tcx>,
-                   recursion_depth: uint,
+                   recursion_depth: usize,
                    skol_map: infer::SkolemizationMap,
                    snapshot: &infer::CombinedSnapshot)
                    -> VtableImplData<'tcx, PredicateObligation<'tcx>>
@@ -1818,12 +2138,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                skol_map.repr(self.tcx()));
 
         let mut impl_obligations =
-            self.impl_obligations(cause,
-                                 recursion_depth,
-                                 impl_def_id,
-                                 &substs.value,
-                                 skol_map,
-                                 snapshot);
+            self.impl_or_trait_obligations(cause,
+                                           recursion_depth,
+                                           impl_def_id,
+                                           &substs.value,
+                                           skol_map,
+                                           snapshot);
 
         debug!("vtable_impl: impl_def_id={} impl_obligations={}",
                impl_def_id.repr(self.tcx()),
@@ -1843,7 +2163,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         debug!("confirm_object_candidate({})",
                obligation.repr(self.tcx()));
 
-        let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
+        // FIXME skipping binder here seems wrong -- we should
+        // probably flatten the binder from the obligation and the
+        // binder from the object. Have to try to make a broken test
+        // case that results. -nmatsakis
+        let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
         let poly_trait_ref = match self_ty.sty {
             ty::ty_trait(ref data) => {
                 data.principal_trait_ref_with_self_ty(self.tcx(), self_ty)
@@ -1854,20 +2178,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             }
         };
 
-        let obligation_def_id = obligation.predicate.def_id();
-        let upcast_trait_ref = match util::upcast(self.tcx(),
-                                                  poly_trait_ref.clone(),
-                                                  obligation_def_id) {
-            Some(r) => r,
-            None => {
-                self.tcx().sess.span_bug(obligation.cause.span,
-                                         &format!("unable to upcast from {} to {}",
-                                                  poly_trait_ref.repr(self.tcx()),
-                                                  obligation_def_id.repr(self.tcx())));
-            }
-        };
+        // Upcast the object type to the obligation type. There must
+        // be exactly one applicable trait-reference; if this were not
+        // the case, we would have reported an ambiguity error rather
+        // than successfully selecting one of the candidates.
+        let upcast_trait_refs = self.upcast(poly_trait_ref.clone(), obligation);
+        assert_eq!(upcast_trait_refs.len(), 1);
+        let upcast_trait_ref = upcast_trait_refs.into_iter().next().unwrap();
 
-        match self.match_poly_trait_ref(obligation, upcast_trait_ref) {
+        match self.match_poly_trait_ref(obligation, upcast_trait_ref.clone()) {
             Ok(()) => { }
             Err(()) => {
                 self.tcx().sess.span_bug(obligation.cause.span,
@@ -1875,7 +2194,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             }
         }
 
-        VtableObjectData { object_ty: self_ty }
+        VtableObjectData { object_ty: self_ty,
+                           upcast_trait_ref: upcast_trait_ref }
     }
 
     fn confirm_fn_pointer_candidate(&mut self,
@@ -1885,15 +2205,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         debug!("confirm_fn_pointer_candidate({})",
                obligation.repr(self.tcx()));
 
-        let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
+        // ok to skip binder; it is reintroduced below
+        let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder());
         let sig = ty::ty_fn_sig(self_ty);
-        let ty::Binder((trait_ref, _)) =
+        let trait_ref =
             util::closure_trait_ref_and_return_type(self.tcx(),
                                                     obligation.predicate.def_id(),
                                                     self_ty,
                                                     sig,
-                                                    util::TupleArgumentsFlag::Yes);
-        let trait_ref = ty::Binder(trait_ref);
+                                                    util::TupleArgumentsFlag::Yes)
+            .map_bound(|(trait_ref, _)| trait_ref);
 
         try!(self.confirm_poly_trait_refs(obligation.cause.clone(),
                                           obligation.predicate.to_poly_trait_ref(),
@@ -1942,9 +2263,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ///
     ///     impl Fn(int) for Closure { ... }
     ///
-    /// Now imagine our obligation is `Fn(uint) for Closure`. So far
+    /// Now imagine our obligation is `Fn(usize) for Closure`. So far
     /// we have matched the self-type `Closure`. At this point we'll
-    /// compare the `int` to `uint` and generate an error.
+    /// compare the `int` to `usize` and generate an error.
     ///
     /// Note that this checking occurs *after* the impl has selected,
     /// because these output type parameters should not affect the
@@ -1988,14 +2309,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     {
         match self.match_impl(impl_def_id, obligation, snapshot,
                               skol_map, skol_obligation_trait_ref) {
-            Ok(substs) => {
-                substs
-            }
+            Ok(substs) => substs,
             Err(()) => {
                 self.tcx().sess.bug(
                     &format!("Impl {} was matchable against {} but now is not",
                             impl_def_id.repr(self.tcx()),
-                            obligation.repr(self.tcx()))[]);
+                            obligation.repr(self.tcx())));
             }
         }
     }
@@ -2017,9 +2336,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             return Err(());
         }
 
-        let impl_substs = util::fresh_substs_for_impl(self.infcx,
-                                                      obligation.cause.span,
-                                                      impl_def_id);
+        let impl_substs = util::fresh_type_vars_for_impl(self.infcx,
+                                                         obligation.cause.span,
+                                                         impl_def_id);
 
         let impl_trait_ref = impl_trait_ref.subst(self.tcx(),
                                                   &impl_substs);
@@ -2038,30 +2357,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                skol_obligation_trait_ref.repr(self.tcx()));
 
         let origin = infer::RelateOutputImplTypes(obligation.cause.span);
-        match self.infcx.sub_trait_refs(false,
-                                        origin,
-                                        impl_trait_ref.value.clone(),
-                                        skol_obligation_trait_ref) {
-            Ok(()) => { }
-            Err(e) => {
-                debug!("match_impl: failed sub_trait_refs due to `{}`",
-                       ty::type_err_to_str(self.tcx(), &e));
-                return Err(());
-            }
+        if let Err(e) = self.infcx.sub_trait_refs(false,
+                                                  origin,
+                                                  impl_trait_ref.value.clone(),
+                                                  skol_obligation_trait_ref) {
+            debug!("match_impl: failed sub_trait_refs due to `{}`",
+                   ty::type_err_to_str(self.tcx(), &e));
+            return Err(());
         }
 
-        match self.infcx.leak_check(skol_map, snapshot) {
-            Ok(()) => { }
-            Err(e) => {
-                debug!("match_impl: failed leak check due to `{}`",
-                       ty::type_err_to_str(self.tcx(), &e));
-                return Err(());
-            }
+        if let Err(e) = self.infcx.leak_check(skol_map, snapshot) {
+            debug!("match_impl: failed leak check due to `{}`",
+                   ty::type_err_to_str(self.tcx(), &e));
+            return Err(());
         }
 
         debug!("match_impl: success impl_substs={}", impl_substs.repr(self.tcx()));
-        Ok(Normalized { value: impl_substs,
-                        obligations: impl_trait_ref.obligations })
+        Ok(Normalized {
+            value: impl_substs,
+            obligations: impl_trait_ref.obligations
+        })
     }
 
     fn fast_reject_trait_refs(&mut self,
@@ -2097,9 +2412,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                     where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
                                     -> Result<Vec<PredicateObligation<'tcx>>,()>
     {
-        let () =
-            try!(self.match_poly_trait_ref(obligation, where_clause_trait_ref));
-
+        try!(self.match_poly_trait_ref(obligation, where_clause_trait_ref));
         Ok(Vec::new())
     }
 
@@ -2143,9 +2456,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     {
         // Create fresh type variables for each type parameter declared
         // on the impl etc.
-        let impl_substs = util::fresh_substs_for_impl(self.infcx,
-                                                      obligation_cause.span,
-                                                      impl_def_id);
+        let impl_substs = util::fresh_type_vars_for_impl(self.infcx,
+                                                         obligation_cause.span,
+                                                         impl_def_id);
 
         // Find the self type for the impl.
         let impl_self_ty = ty::lookup_item_type(self.tcx(), impl_def_id).ty;
@@ -2195,8 +2508,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ///////////////////////////////////////////////////////////////////////////
     // Miscellany
 
+    fn match_fresh_trait_refs(&self,
+                              previous: &ty::PolyTraitRef<'tcx>,
+                              current: &ty::PolyTraitRef<'tcx>)
+                              -> bool
+    {
+        let mut matcher = ty_match::Match::new(self.tcx());
+        matcher.relate(previous, current).is_ok()
+    }
+
     fn push_stack<'o,'s:'o>(&mut self,
-                            previous_stack: Option<&'s TraitObligationStack<'s, 'tcx>>,
+                            previous_stack: TraitObligationStackList<'s, 'tcx>,
                             obligation: &'o TraitObligation<'tcx>)
                             -> TraitObligationStack<'o, 'tcx>
     {
@@ -2206,7 +2528,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         TraitObligationStack {
             obligation: obligation,
             fresh_trait_ref: fresh_trait_ref,
-            previous: previous_stack.map(|p| p), // FIXME variance
+            previous: previous_stack,
         }
     }
 
@@ -2216,7 +2538,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         match self.tcx().trait_impls.borrow().get(&trait_def_id) {
             None => Vec::new(),
-            Some(impls) => impls.borrow().clone()
+            Some(impls) => impls.borrow().clone(),
         }
     }
 
@@ -2243,28 +2565,32 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         ty::Binder(trait_ref)
     }
 
-    fn impl_obligations(&mut self,
-                        cause: ObligationCause<'tcx>,
-                        recursion_depth: uint,
-                        impl_def_id: ast::DefId,
-                        impl_substs: &Substs<'tcx>,
-                        skol_map: infer::SkolemizationMap,
-                        snapshot: &infer::CombinedSnapshot)
-                        -> VecPerParamSpace<PredicateObligation<'tcx>>
+    /// Returns the obligations that are implied by instantiating an
+    /// impl or trait. The obligations are substituted and fully
+    /// normalized. This is used when confirming an impl or default
+    /// impl.
+    fn impl_or_trait_obligations(&mut self,
+                                 cause: ObligationCause<'tcx>,
+                                 recursion_depth: usize,
+                                 def_id: ast::DefId, // of impl or trait
+                                 substs: &Substs<'tcx>, // for impl or trait
+                                 skol_map: infer::SkolemizationMap,
+                                 snapshot: &infer::CombinedSnapshot)
+                                 -> VecPerParamSpace<PredicateObligation<'tcx>>
     {
-        let impl_bounds = ty::lookup_predicates(self.tcx(), impl_def_id);
-        let bounds = impl_bounds.instantiate(self.tcx(), impl_substs);
-        let normalized_bounds =
-            project::normalize_with_depth(self, cause.clone(), recursion_depth, &bounds);
-        let normalized_bounds =
-            self.infcx().plug_leaks(skol_map, snapshot, &normalized_bounds);
-        let mut impl_obligations =
+        debug!("impl_or_trait_obligations(def_id={})", def_id.repr(self.tcx()));
+
+        let predicates = ty::lookup_predicates(self.tcx(), def_id);
+        let predicates = predicates.instantiate(self.tcx(), substs);
+        let predicates = normalize_with_depth(self, cause.clone(), recursion_depth, &predicates);
+        let predicates = self.infcx().plug_leaks(skol_map, snapshot, &predicates);
+        let mut obligations =
             util::predicates_for_generics(self.tcx(),
                                           cause,
                                           recursion_depth,
-                                          &normalized_bounds.value);
-        impl_obligations.extend(TypeSpace, normalized_bounds.obligations.into_iter());
-        impl_obligations
+                                          &predicates.value);
+        obligations.extend(TypeSpace, predicates.obligations.into_iter());
+        obligations
     }
 
     #[allow(unused_comparisons)]
@@ -2298,6 +2624,32 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             obligation.cause.clone()
         }
     }
+
+    /// Upcasts an object trait-reference into those that match the obligation.
+    fn upcast(&mut self, obj_trait_ref: ty::PolyTraitRef<'tcx>, obligation: &TraitObligation<'tcx>)
+              -> Vec<ty::PolyTraitRef<'tcx>>
+    {
+        debug!("upcast(obj_trait_ref={}, obligation={})",
+               obj_trait_ref.repr(self.tcx()),
+               obligation.repr(self.tcx()));
+
+        let obligation_def_id = obligation.predicate.def_id();
+        let mut upcast_trait_refs = util::upcast(self.tcx(), obj_trait_ref, obligation_def_id);
+
+        // Retain only those upcast versions that match the trait-ref
+        // we are looking for.  In particular, we know that all of
+        // `upcast_trait_refs` apply to the correct trait, but
+        // possibly with incorrect type parameters. For example, we
+        // may be trying to upcast `Foo` to `Bar<i32>`, but `Foo` is
+        // declared as `trait Foo : Bar<u32>`.
+        upcast_trait_refs.retain(|upcast_trait_ref| {
+            let upcast_trait_ref = upcast_trait_ref.clone();
+            self.infcx.probe(|_| self.match_poly_trait_ref(obligation, upcast_trait_ref)).is_ok()
+        });
+
+        debug!("upcast: upcast_trait_refs={}", upcast_trait_refs.repr(self.tcx()));
+        upcast_trait_refs
+    }
 }
 
 impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> {
@@ -2306,13 +2658,14 @@ impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> {
             PhantomFnCandidate => format!("PhantomFnCandidate"),
             ErrorCandidate => format!("ErrorCandidate"),
             BuiltinCandidate(b) => format!("BuiltinCandidate({:?})", b),
+            BuiltinObjectCandidate => format!("BuiltinObjectCandidate"),
             ParamCandidate(ref a) => format!("ParamCandidate({})", a.repr(tcx)),
             ImplCandidate(a) => format!("ImplCandidate({})", a.repr(tcx)),
+            DefaultImplCandidate(t) => format!("DefaultImplCandidate({:?})", t),
+            DefaultImplObjectCandidate(t) => format!("DefaultImplObjectCandidate({:?})", t),
             ProjectionCandidate => format!("ProjectionCandidate"),
             FnPointerCandidate => format!("FnPointerCandidate"),
-            ObjectCandidate => {
-                format!("ObjectCandidate")
-            }
+            ObjectCandidate => format!("ObjectCandidate"),
             ClosureCandidate(c, ref s) => {
                 format!("ClosureCandidate({:?},{})", c, s.repr(tcx))
             }
@@ -2323,34 +2676,51 @@ impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> {
 impl<'tcx> SelectionCache<'tcx> {
     pub fn new() -> SelectionCache<'tcx> {
         SelectionCache {
-            hashmap: RefCell::new(HashMap::new())
+            hashmap: RefCell::new(FnvHashMap())
         }
     }
 }
 
-impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> {
-    fn iter(&self) -> Option<&TraitObligationStack<'o, 'tcx>> {
-        Some(self)
+impl<'o,'tcx> TraitObligationStack<'o,'tcx> {
+    fn list(&'o self) -> TraitObligationStackList<'o,'tcx> {
+        TraitObligationStackList::with(self)
+    }
+
+    fn iter(&'o self) -> TraitObligationStackList<'o,'tcx> {
+        self.list()
+    }
+}
+
+#[derive(Copy, Clone)]
+struct TraitObligationStackList<'o,'tcx:'o> {
+    head: Option<&'o TraitObligationStack<'o,'tcx>>
+}
+
+impl<'o,'tcx> TraitObligationStackList<'o,'tcx> {
+    fn empty() -> TraitObligationStackList<'o,'tcx> {
+        TraitObligationStackList { head: None }
+    }
+
+    fn with(r: &'o TraitObligationStack<'o,'tcx>) -> TraitObligationStackList<'o,'tcx> {
+        TraitObligationStackList { head: Some(r) }
     }
 }
 
-impl<'o, 'tcx> Iterator for Option<&'o TraitObligationStack<'o, 'tcx>> {
+impl<'o,'tcx> Iterator for TraitObligationStackList<'o,'tcx>{
     type Item = &'o TraitObligationStack<'o,'tcx>;
 
-    fn next(&mut self) -> Option<&'o TraitObligationStack<'o, 'tcx>> {
-        match *self {
+    fn next(&mut self) -> Option<&'o TraitObligationStack<'o,'tcx>> {
+        match self.head {
             Some(o) => {
                 *self = o.previous;
                 Some(o)
             }
-            None => {
-                None
-            }
+            None => None
         }
     }
 }
 
-impl<'o, 'tcx> Repr<'tcx> for TraitObligationStack<'o, 'tcx> {
+impl<'o,'tcx> Repr<'tcx> for TraitObligationStack<'o,'tcx> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         format!("TraitObligationStack({})",
                 self.obligation.repr(tcx))
@@ -2362,13 +2732,11 @@ impl<'tcx> EvaluationResult<'tcx> {
         match *self {
             EvaluatedToOk |
             EvaluatedToAmbig |
-            EvaluatedToErr(Overflow) |
-            EvaluatedToErr(OutputTypeParameterMismatch(..)) => {
-                true
-            }
-            EvaluatedToErr(Unimplemented) => {
-                false
-            }
+            EvaluatedToErr(OutputTypeParameterMismatch(..)) =>
+                true,
+
+            EvaluatedToErr(Unimplemented) =>
+                false,
         }
     }
 }
index 6c54da1c134f5c63c01086e7090ecccab78c9806..297cea13207e57a99a5f9871db3e36b9e8a752dd 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use middle::region;
 use middle::subst::{Substs, VecPerParamSpace};
 use middle::infer::InferCtxt;
 use middle::ty::{self, Ty, AsPredicate, ToPolyTraitRef};
@@ -20,7 +21,7 @@ use util::nodemap::FnvHashSet;
 use util::ppaux::Repr;
 
 use super::{Obligation, ObligationCause, PredicateObligation,
-            VtableImpl, VtableParam, VtableImplData};
+            VtableImpl, VtableParam, VtableImplData, VtableDefaultImplData};
 
 struct PredicateSet<'a,'tcx:'a> {
     tcx: &'a ty::ctxt<'tcx>,
@@ -76,15 +77,10 @@ impl<'a,'tcx> PredicateSet<'a,'tcx> {
 /// 'static`.
 pub struct Elaborator<'cx, 'tcx:'cx> {
     tcx: &'cx ty::ctxt<'tcx>,
-    stack: Vec<StackEntry<'tcx>>,
+    stack: Vec<ty::Predicate<'tcx>>,
     visited: PredicateSet<'cx,'tcx>,
 }
 
-struct StackEntry<'tcx> {
-    position: uint,
-    predicates: Vec<ty::Predicate<'tcx>>,
-}
-
 pub fn elaborate_trait_ref<'cx, 'tcx>(
     tcx: &'cx ty::ctxt<'tcx>,
     trait_ref: ty::PolyTraitRef<'tcx>)
@@ -111,21 +107,28 @@ pub fn elaborate_predicates<'cx, 'tcx>(
 {
     let mut visited = PredicateSet::new(tcx);
     predicates.retain(|pred| visited.insert(pred));
-    let entry = StackEntry { position: 0, predicates: predicates };
-    Elaborator { tcx: tcx, stack: vec![entry], visited: visited }
+    Elaborator { tcx: tcx, stack: predicates, visited: visited }
 }
 
 impl<'cx, 'tcx> Elaborator<'cx, 'tcx> {
-    pub fn filter_to_traits(self) -> Supertraits<'cx, 'tcx> {
-        Supertraits { elaborator: self }
+    pub fn filter_to_traits(self) -> FilterToTraits<Elaborator<'cx, 'tcx>> {
+        FilterToTraits::new(self)
     }
 
     fn push(&mut self, predicate: &ty::Predicate<'tcx>) {
         match *predicate {
             ty::Predicate::Trait(ref data) => {
-                let mut predicates =
-                    ty::predicates_for_trait_ref(self.tcx,
-                                                 &data.to_poly_trait_ref());
+                // Predicates declared on the trait.
+                let predicates = ty::lookup_super_predicates(self.tcx, data.def_id());
+
+                let mut predicates: Vec<_> =
+                    predicates.predicates
+                              .iter()
+                              .map(|p| p.subst_supertrait(self.tcx, &data.to_poly_trait_ref()))
+                              .collect();
+
+                debug!("super_predicates: data={} predicates={}",
+                       data.repr(self.tcx), predicates.repr(self.tcx));
 
                 // Only keep those bounds that we haven't already
                 // seen.  This is necessary to prevent infinite
@@ -134,8 +137,7 @@ impl<'cx, 'tcx> Elaborator<'cx, 'tcx> {
                 // Sized { }`.
                 predicates.retain(|r| self.visited.insert(r));
 
-                self.stack.push(StackEntry { position: 0,
-                                             predicates: predicates });
+                self.stack.extend(predicates.into_iter());
             }
             ty::Predicate::Equate(..) => {
                 // Currently, we do not "elaborate" predicates like
@@ -175,41 +177,16 @@ impl<'cx, 'tcx> Iterator for Elaborator<'cx, 'tcx> {
     type Item = ty::Predicate<'tcx>;
 
     fn next(&mut self) -> Option<ty::Predicate<'tcx>> {
-        loop {
-            // Extract next item from top-most stack frame, if any.
-            let next_predicate = match self.stack.last_mut() {
-                None => {
-                    // No more stack frames. Done.
-                    return None;
-                }
-                Some(entry) => {
-                    let p = entry.position;
-                    if p < entry.predicates.len() {
-                        // Still more predicates left in the top stack frame.
-                        entry.position += 1;
-
-                        let next_predicate =
-                            entry.predicates[p].clone();
-
-                        Some(next_predicate)
-                    } else {
-                        None
-                    }
-                }
-            };
-
-            match next_predicate {
-                Some(next_predicate) => {
-                    self.push(&next_predicate);
-                    return Some(next_predicate);
-                }
-
-                None => {
-                    // Top stack frame is exhausted, pop it.
-                    self.stack.pop();
-                }
+        // Extract next item from top-most stack frame, if any.
+        let next_predicate = match self.stack.pop() {
+            Some(predicate) => predicate,
+            None => {
+                // No more stack frames. Done.
+                return None;
             }
-        }
+        };
+        self.push(&next_predicate);
+        return Some(next_predicate);
     }
 }
 
@@ -217,11 +194,7 @@ impl<'cx, 'tcx> Iterator for Elaborator<'cx, 'tcx> {
 // Supertrait iterator
 ///////////////////////////////////////////////////////////////////////////
 
-/// A filter around the `Elaborator` that just yields up supertrait references,
-/// not other kinds of predicates.
-pub struct Supertraits<'cx, 'tcx:'cx> {
-    elaborator: Elaborator<'cx, 'tcx>,
-}
+pub type Supertraits<'cx, 'tcx> = FilterToTraits<Elaborator<'cx, 'tcx>>;
 
 pub fn supertraits<'cx, 'tcx>(tcx: &'cx ty::ctxt<'tcx>,
                               trait_ref: ty::PolyTraitRef<'tcx>)
@@ -237,12 +210,69 @@ pub fn transitive_bounds<'cx, 'tcx>(tcx: &'cx ty::ctxt<'tcx>,
     elaborate_trait_refs(tcx, bounds).filter_to_traits()
 }
 
-impl<'cx, 'tcx> Iterator for Supertraits<'cx, 'tcx> {
+///////////////////////////////////////////////////////////////////////////
+// Iterator over def-ids of supertraits
+
+pub struct SupertraitDefIds<'cx, 'tcx:'cx> {
+    tcx: &'cx ty::ctxt<'tcx>,
+    stack: Vec<ast::DefId>,
+    visited: FnvHashSet<ast::DefId>,
+}
+
+pub fn supertrait_def_ids<'cx, 'tcx>(tcx: &'cx ty::ctxt<'tcx>,
+                                     trait_def_id: ast::DefId)
+                                     -> SupertraitDefIds<'cx, 'tcx>
+{
+    SupertraitDefIds {
+        tcx: tcx,
+        stack: vec![trait_def_id],
+        visited: Some(trait_def_id).into_iter().collect(),
+    }
+}
+
+impl<'cx, 'tcx> Iterator for SupertraitDefIds<'cx, 'tcx> {
+    type Item = ast::DefId;
+
+    fn next(&mut self) -> Option<ast::DefId> {
+        let def_id = match self.stack.pop() {
+            Some(def_id) => def_id,
+            None => { return None; }
+        };
+
+        let predicates = ty::lookup_super_predicates(self.tcx, def_id);
+        let visited = &mut self.visited;
+        self.stack.extend(
+            predicates.predicates
+                      .iter()
+                      .filter_map(|p| p.to_opt_poly_trait_ref())
+                      .map(|t| t.def_id())
+                      .filter(|&super_def_id| visited.insert(super_def_id)));
+        Some(def_id)
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Other
+///////////////////////////////////////////////////////////////////////////
+
+/// A filter around an iterator of predicates that makes it yield up
+/// just trait references.
+pub struct FilterToTraits<I> {
+    base_iterator: I
+}
+
+impl<I> FilterToTraits<I> {
+    fn new(base: I) -> FilterToTraits<I> {
+        FilterToTraits { base_iterator: base }
+    }
+}
+
+impl<'tcx,I:Iterator<Item=ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
     type Item = ty::PolyTraitRef<'tcx>;
 
     fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
         loop {
-            match self.elaborator.next() {
+            match self.base_iterator.next() {
                 None => {
                     return None;
                 }
@@ -264,16 +294,44 @@ impl<'cx, 'tcx> Iterator for Supertraits<'cx, 'tcx> {
 // declared on the impl declaration e.g., `impl<A,B> for Box<[(A,B)]>`
 // would return ($0, $1) where $0 and $1 are freshly instantiated type
 // variables.
-pub fn fresh_substs_for_impl<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
-                                       span: Span,
-                                       impl_def_id: ast::DefId)
-                                       -> Substs<'tcx>
+pub fn fresh_type_vars_for_impl<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
+                                          span: Span,
+                                          impl_def_id: ast::DefId)
+                                          -> Substs<'tcx>
 {
     let tcx = infcx.tcx;
     let impl_generics = ty::lookup_item_type(tcx, impl_def_id).generics;
     infcx.fresh_substs_for_generics(span, &impl_generics)
 }
 
+// determine the `self` type, using fresh variables for all variables
+// declared on the impl declaration e.g., `impl<A,B> for Box<[(A,B)]>`
+// would return ($0, $1) where $0 and $1 are freshly instantiated type
+// variables.
+pub fn free_substs_for_impl<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
+                                      _span: Span,
+                                      impl_def_id: ast::DefId)
+                                      -> Substs<'tcx>
+{
+    let tcx = infcx.tcx;
+    let impl_generics = ty::lookup_item_type(tcx, impl_def_id).generics;
+
+    let some_types = impl_generics.types.map(|def| {
+        ty::mk_param_from_def(tcx, def)
+    });
+
+    let some_regions = impl_generics.regions.map(|def| {
+        // FIXME. This destruction scope information is pretty darn
+        // bogus; after all, the impl might not even be in this crate!
+        // But given what we do in coherence, it is harmless enough
+        // for now I think. -nmatsakis
+        let extent = region::DestructionScopeData::new(ast::DUMMY_NODE_ID);
+        ty::free_region_from_def(extent, def)
+    });
+
+    Substs::new(some_types, some_regions)
+}
+
 impl<'tcx, N> fmt::Debug for VtableImplData<'tcx, N> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "VtableImpl({:?})", self.impl_def_id)
@@ -289,7 +347,7 @@ impl<'tcx> fmt::Debug for super::VtableObjectData<'tcx> {
 /// See `super::obligations_for_generics`
 pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
                                      cause: ObligationCause<'tcx>,
-                                     recursion_depth: uint,
+                                     recursion_depth: usize,
                                      generic_bounds: &ty::InstantiatedPredicates<'tcx>)
                                      -> VecPerParamSpace<PredicateObligation<'tcx>>
 {
@@ -323,15 +381,13 @@ pub fn trait_ref_for_builtin_bound<'tcx>(
     }
 }
 
-pub fn predicate_for_builtin_bound<'tcx>(
-    tcx: &ty::ctxt<'tcx>,
+
+pub fn predicate_for_trait_ref<'tcx>(
     cause: ObligationCause<'tcx>,
-    builtin_bound: ty::BuiltinBound,
-    recursion_depth: uint,
-    param_ty: Ty<'tcx>)
+    trait_ref: Rc<ty::TraitRef<'tcx>>,
+    recursion_depth: usize)
     -> Result<PredicateObligation<'tcx>, ErrorReported>
 {
-    let trait_ref = try!(trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty));
     Ok(Obligation {
         cause: cause,
         recursion_depth: recursion_depth,
@@ -339,25 +395,48 @@ pub fn predicate_for_builtin_bound<'tcx>(
     })
 }
 
+pub fn predicate_for_trait_def<'tcx>(
+    tcx: &ty::ctxt<'tcx>,
+    cause: ObligationCause<'tcx>,
+    trait_def_id: ast::DefId,
+    recursion_depth: usize,
+    param_ty: Ty<'tcx>)
+    -> Result<PredicateObligation<'tcx>, ErrorReported>
+{
+    let trait_ref = Rc::new(ty::TraitRef {
+        def_id: trait_def_id,
+        substs: tcx.mk_substs(Substs::empty().with_self_ty(param_ty))
+    });
+    predicate_for_trait_ref(cause, trait_ref, recursion_depth)
+}
+
+pub fn predicate_for_builtin_bound<'tcx>(
+    tcx: &ty::ctxt<'tcx>,
+    cause: ObligationCause<'tcx>,
+    builtin_bound: ty::BuiltinBound,
+    recursion_depth: usize,
+    param_ty: Ty<'tcx>)
+    -> Result<PredicateObligation<'tcx>, ErrorReported>
+{
+    let trait_ref = try!(trait_ref_for_builtin_bound(tcx, builtin_bound, param_ty));
+    predicate_for_trait_ref(cause, trait_ref, recursion_depth)
+}
+
 /// Cast a trait reference into a reference to one of its super
 /// traits; returns `None` if `target_trait_def_id` is not a
 /// supertrait.
 pub fn upcast<'tcx>(tcx: &ty::ctxt<'tcx>,
                     source_trait_ref: ty::PolyTraitRef<'tcx>,
                     target_trait_def_id: ast::DefId)
-                    -> Option<ty::PolyTraitRef<'tcx>>
+                    -> Vec<ty::PolyTraitRef<'tcx>>
 {
     if source_trait_ref.def_id() == target_trait_def_id {
-        return Some(source_trait_ref); // shorcut the most common case
+        return vec![source_trait_ref]; // shorcut the most common case
     }
 
-    for super_trait_ref in supertraits(tcx, source_trait_ref) {
-        if super_trait_ref.def_id() == target_trait_def_id {
-            return Some(super_trait_ref);
-        }
-    }
-
-    None
+    supertraits(tcx, source_trait_ref)
+        .filter(|r| r.def_id() == target_trait_def_id)
+        .collect()
 }
 
 /// Given an object of type `object_trait_ref`, returns the index of
@@ -367,7 +446,7 @@ pub fn upcast<'tcx>(tcx: &ty::ctxt<'tcx>,
 pub fn get_vtable_index_of_object_method<'tcx>(tcx: &ty::ctxt<'tcx>,
                                                object_trait_ref: ty::PolyTraitRef<'tcx>,
                                                trait_def_id: ast::DefId,
-                                               method_offset_in_trait: uint) -> uint {
+                                               method_offset_in_trait: usize) -> usize {
     // We need to figure the "real index" of the method in a
     // listing of all the methods of an object. We do this by
     // iterating down the supertraits of the object's trait until
@@ -444,6 +523,9 @@ impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::Vtable<'tcx, N> {
             super::VtableImpl(ref v) =>
                 v.repr(tcx),
 
+            super::VtableDefaultImpl(ref t) =>
+                t.repr(tcx),
+
             super::VtableClosure(ref d, ref s) =>
                 format!("VtableClosure({},{})",
                         d.repr(tcx),
@@ -483,6 +565,14 @@ impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::VtableBuiltinData<N> {
     }
 }
 
+impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::VtableDefaultImplData<N> {
+    fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
+        format!("VtableDefaultImplData(trait_def_id={}, nested={})",
+                self.trait_def_id.repr(tcx),
+                self.nested.repr(tcx))
+    }
+}
+
 impl<'tcx> Repr<'tcx> for super::VtableObjectData<'tcx> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         format!("VtableObject(object_ty={})",
@@ -493,9 +583,6 @@ impl<'tcx> Repr<'tcx> for super::VtableObjectData<'tcx> {
 impl<'tcx> Repr<'tcx> for super::SelectionError<'tcx> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         match *self {
-            super::Overflow =>
-                format!("Overflow"),
-
             super::Unimplemented =>
                 format!("Unimplemented"),
 
@@ -547,5 +634,3 @@ impl<'tcx> fmt::Debug for super::MismatchedProjectionTypes<'tcx> {
         write!(f, "MismatchedProjectionTypes(..)")
     }
 }
-
-
index e9908397f970387782fb097c4d478013d92c480a..1123c9236312a70a9bd069445a5ef25d6b5ca0fe 100644 (file)
@@ -17,7 +17,6 @@ pub use self::InferTy::*;
 pub use self::InferRegion::*;
 pub use self::ImplOrTraitItemId::*;
 pub use self::ClosureKind::*;
-pub use self::ast_ty_to_ty_cache_entry::*;
 pub use self::Variance::*;
 pub use self::AutoAdjustment::*;
 pub use self::Representability::*;
@@ -48,47 +47,50 @@ use middle::check_const;
 use middle::const_eval;
 use middle::def::{self, DefMap, ExportMap};
 use middle::dependency_format;
-use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
-use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem};
+use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
 use middle::mem_categorization as mc;
 use middle::region;
 use middle::resolve_lifetime;
 use middle::infer;
+use middle::pat_util;
 use middle::stability;
-use middle::subst::{self, Subst, Substs, VecPerParamSpace};
+use middle::subst::{self, ParamSpace, Subst, Substs, VecPerParamSpace};
 use middle::traits;
 use middle::ty;
 use middle::ty_fold::{self, TypeFoldable, TypeFolder};
-use middle::ty_walk::TypeWalker;
+use middle::ty_walk::{self, TypeWalker};
 use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string};
 use util::ppaux::ty_to_string;
 use util::ppaux::{Repr, UserString};
 use util::common::{memoized, ErrorReported};
 use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
-use util::nodemap::{FnvHashMap};
+use util::nodemap::FnvHashMap;
 
 use arena::TypedArena;
 use std::borrow::{Borrow, Cow};
-use std::cell::{Cell, RefCell};
+use std::cell::{Cell, RefCell, Ref};
 use std::cmp;
 use std::fmt;
 use std::hash::{Hash, SipHasher, Hasher};
-#[cfg(stage0)] use std::hash::Writer;
 use std::mem;
+use std::num::ToPrimitive;
 use std::ops;
 use std::rc::Rc;
-use std::vec::{CowVec, IntoIter};
+use std::vec::IntoIter;
 use collections::enum_set::{EnumSet, CLike};
 use std::collections::{HashMap, HashSet};
 use syntax::abi;
 use syntax::ast::{CrateNum, DefId, Ident, ItemTrait, LOCAL_CRATE};
 use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
 use syntax::ast::{StmtExpr, StmtSemi, StructField, UnnamedField, Visibility};
-use syntax::ast_util::{self, is_local, lit_is_str, local_def, PostExpansionMethod};
-use syntax::attr::{self, AttrMetaMethods};
+use syntax::ast_util::{self, is_local, lit_is_str, local_def};
+use syntax::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
 use syntax::codemap::Span;
 use syntax::parse::token::{self, InternedString, special_idents};
-use syntax::{ast, ast_map};
+use syntax::print::pprust;
+use syntax::ptr::P;
+use syntax::ast;
+use syntax::ast_map::{self, LinkedPath};
 
 pub type Disr = u64;
 
@@ -260,17 +262,11 @@ pub struct field_ty {
 
 // Contains information needed to resolve types and (in the future) look up
 // the types of AST nodes.
-#[derive(Copy, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct creader_cache_key {
     pub cnum: CrateNum,
-    pub pos: uint,
-    pub len: uint
-}
-
-#[derive(Copy)]
-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 */
+    pub pos: usize,
+    pub len: usize
 }
 
 #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
@@ -290,22 +286,24 @@ pub enum Variance {
 #[derive(Clone, Debug)]
 pub enum AutoAdjustment<'tcx> {
     AdjustReifyFnPointer(ast::DefId), // go from a fn-item type to a fn-pointer type
+    AdjustUnsafeFnPointer, // go from a safe fn pointer to an unsafe fn pointer
     AdjustDerefRef(AutoDerefRef<'tcx>)
 }
 
 #[derive(Clone, PartialEq, Debug)]
 pub enum UnsizeKind<'tcx> {
-    // [T, ..n] -> [T], the uint field is n.
-    UnsizeLength(uint),
+    // [T, ..n] -> [T], the usize field is n.
+    UnsizeLength(usize),
     // An unsize coercion applied to the tail field of a struct.
-    // The uint is the index of the type parameter which is unsized.
-    UnsizeStruct(Box<UnsizeKind<'tcx>>, uint),
-    UnsizeVtable(TyTrait<'tcx>, /* the self type of the trait */ Ty<'tcx>)
+    // The usize is the index of the type parameter which is unsized.
+    UnsizeStruct(Box<UnsizeKind<'tcx>>, usize),
+    UnsizeVtable(TyTrait<'tcx>, /* the self type of the trait */ Ty<'tcx>),
+    UnsizeUpcast(Ty<'tcx>),
 }
 
 #[derive(Clone, Debug)]
 pub struct AutoDerefRef<'tcx> {
-    pub autoderefs: uint,
+    pub autoderefs: usize,
     pub autoref: Option<AutoRef<'tcx>>
 }
 
@@ -429,7 +427,7 @@ pub fn type_of_adjust<'tcx>(cx: &ctxt<'tcx>, adj: &AutoAdjustment<'tcx>) -> Opti
 #[derive(Clone, Copy, RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Debug)]
 pub struct param_index {
     pub space: subst::ParamSpace,
-    pub index: uint
+    pub index: usize
 }
 
 #[derive(Clone, Debug)]
@@ -458,10 +456,10 @@ pub struct MethodParam<'tcx> {
     // instantiated with fresh variables at this point.
     pub trait_ref: Rc<ty::TraitRef<'tcx>>,
 
-    // index of uint in the list of trait items. Note that this is NOT
+    // index of usize in the list of trait items. Note that this is NOT
     // the index into the vtable, because the list of trait items
     // includes associated types.
-    pub method_num: uint,
+    pub method_num: usize,
 
     /// The impl for the trait from which the method comes. This
     /// should only be used for certain linting/heuristic purposes
@@ -480,13 +478,13 @@ pub struct MethodObject<'tcx> {
     pub object_trait_id: ast::DefId,
 
     // index of the method to be invoked amongst the trait's items
-    pub method_num: uint,
+    pub method_num: usize,
 
     // index into the actual runtime vtable.
     // the vtable is formed by concatenating together the method lists of
     // the base object trait and all supertraits; this is the index into
     // that vtable
-    pub vtable_index: uint,
+    pub vtable_index: usize,
 }
 
 #[derive(Clone)]
@@ -517,7 +515,7 @@ pub struct MethodCall {
 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]
 pub enum ExprAdjustment {
     NoAdjustment,
-    AutoDeref(uint),
+    AutoDeref(usize),
     AutoObject
 }
 
@@ -536,7 +534,7 @@ impl MethodCall {
         }
     }
 
-    pub fn autoderef(expr_id: ast::NodeId, autoderef: uint) -> MethodCall {
+    pub fn autoderef(expr_id: ast::NodeId, autoderef: usize) -> MethodCall {
         MethodCall {
             expr_id: expr_id,
             adjustment: AutoDeref(1 + autoderef)
@@ -570,7 +568,7 @@ pub enum vtable_origin<'tcx> {
       The first argument is the param index (identifying T in the example),
       and the second is the bound number (identifying baz)
      */
-    vtable_param(param_index, uint),
+    vtable_param(param_index, usize),
 
     /*
       Vtable automatically generated for a closure. The def ID is the
@@ -598,7 +596,7 @@ pub type ObjectCastMap<'tcx> = RefCell<NodeMap<ty::PolyTraitRef<'tcx>>>;
 /// will push one or more such restriction into the
 /// `transmute_restrictions` vector during `intrinsicck`. They are
 /// then checked during `trans` by the fn `check_intrinsics`.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct TransmuteRestriction<'tcx> {
     /// The span whence the restriction comes.
     pub span: Span,
@@ -645,12 +643,12 @@ impl<'tcx> CtxtArenas<'tcx> {
 pub struct CommonTypes<'tcx> {
     pub bool: Ty<'tcx>,
     pub char: Ty<'tcx>,
-    pub int: Ty<'tcx>,
+    pub isize: Ty<'tcx>,
     pub i8: Ty<'tcx>,
     pub i16: Ty<'tcx>,
     pub i32: Ty<'tcx>,
     pub i64: Ty<'tcx>,
-    pub uint: Ty<'tcx>,
+    pub usize: Ty<'tcx>,
     pub u8: Ty<'tcx>,
     pub u16: Ty<'tcx>,
     pub u32: Ty<'tcx>,
@@ -691,7 +689,7 @@ pub struct ctxt<'tcx> {
     /// Stores the types for various nodes in the AST.  Note that this table
     /// is not guaranteed to be populated until after typeck.  See
     /// typeck::check::fn_ctxt for details.
-    pub node_types: RefCell<NodeMap<Ty<'tcx>>>,
+    node_types: RefCell<NodeMap<Ty<'tcx>>>,
 
     /// Stores the type parameters which were substituted to obtain the type
     /// of this node.  This only applies to nodes that refer to entities
@@ -710,25 +708,32 @@ pub struct ctxt<'tcx> {
 
     pub impl_trait_cache: RefCell<DefIdMap<Option<Rc<ty::TraitRef<'tcx>>>>>,
 
-    pub trait_refs: RefCell<NodeMap<Rc<TraitRef<'tcx>>>>,
+    pub impl_trait_refs: RefCell<NodeMap<Rc<TraitRef<'tcx>>>>,
     pub trait_defs: RefCell<DefIdMap<Rc<TraitDef<'tcx>>>>,
 
     /// Maps from the def-id of an item (trait/struct/enum/fn) to its
     /// associated predicates.
     pub predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>,
 
+    /// Maps from the def-id of a trait to the list of
+    /// super-predicates. This is a subset of the full list of
+    /// predicates. We store these in a separate map because we must
+    /// evaluate them even during type conversion, often before the
+    /// full predicates are available (note that supertraits have
+    /// additional acyclicity requirements).
+    pub super_predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>,
+
     /// Maps from node-id of a trait object cast (like `foo as
     /// Box<Trait>`) to the trait reference.
     pub object_cast_map: ObjectCastMap<'tcx>,
 
     pub map: ast_map::Map<'tcx>,
-    pub intrinsic_defs: RefCell<DefIdMap<Ty<'tcx>>>,
     pub freevars: RefCell<FreevarMap>,
     pub tcache: RefCell<DefIdMap<TypeScheme<'tcx>>>,
     pub rcache: RefCell<FnvHashMap<creader_cache_key, Ty<'tcx>>>,
     pub short_names_cache: RefCell<FnvHashMap<Ty<'tcx>, String>>,
     pub tc_cache: RefCell<FnvHashMap<Ty<'tcx>, TypeContents>>,
-    pub ast_ty_to_ty_cache: RefCell<NodeMap<ast_ty_to_ty_cache_entry<'tcx>>>,
+    pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
     pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>,
     pub ty_param_defs: RefCell<NodeMap<TypeParameterDef<'tcx>>>,
     pub adjustments: RefCell<NodeMap<AutoAdjustment<'tcx>>>,
@@ -757,6 +762,9 @@ pub struct ctxt<'tcx> {
     /// Maps a trait onto a list of impls of that trait.
     pub trait_impls: RefCell<DefIdMap<Rc<RefCell<Vec<ast::DefId>>>>>,
 
+    /// A set of traits that have a default impl
+    traits_with_default_impls: RefCell<DefIdMap<()>>,
+
     /// Maps a DefId of a type to a list of its inherent impls.
     /// Contains implementations of methods that are inherent to a type.
     /// Methods in these implementations don't need to be exported.
@@ -785,6 +793,9 @@ pub struct ctxt<'tcx> {
     /// is used for lazy resolution of traits.
     pub populated_external_traits: RefCell<DefIdSet>,
 
+    /// The set of external primitive inherent implementations that have been read.
+    pub populated_external_primitive_impls: RefCell<DefIdSet>,
+
     /// Borrows
     pub upvar_capture_map: RefCell<UpvarCaptureMap>,
 
@@ -843,6 +854,13 @@ pub struct ctxt<'tcx> {
     pub const_qualif_map: RefCell<NodeMap<check_const::ConstQualif>>,
 }
 
+impl<'tcx> ctxt<'tcx> {
+    pub fn node_types(&self) -> Ref<NodeMap<Ty<'tcx>>> { self.node_types.borrow() }
+    pub fn node_type_insert(&self, id: NodeId, ty: Ty<'tcx>) {
+        self.node_types.borrow_mut().insert(id, ty);
+    }
+}
+
 // Flags that we track on types. These flags are propagated upwards
 // through the type during type construction, so that we can quickly
 // check whether the type has various kinds of types in it without
@@ -868,12 +886,12 @@ macro_rules! sty_debug_print {
         // variable names.
         mod inner {
             use middle::ty;
-            #[derive(Copy)]
+            #[derive(Copy, Clone)]
             struct DebugStat {
-                total: uint,
-                region_infer: uint,
-                ty_infer: uint,
-                both_infer: uint,
+                total: usize,
+                region_infer: usize,
+                ty_infer: usize,
+                both_infer: usize,
             }
 
             pub fn go(tcx: &ty::ctxt) {
@@ -928,7 +946,7 @@ impl<'tcx> ctxt<'tcx> {
         sty_debug_print!(
             self,
             ty_enum, ty_uniq, ty_vec, ty_ptr, ty_rptr, ty_bare_fn, ty_trait,
-            ty_struct, ty_closure, ty_tup, ty_param, ty_open, ty_infer, ty_projection);
+            ty_struct, ty_closure, ty_tup, ty_param, ty_infer, ty_projection);
 
         println!("Substs interner: #{}", self.substs_interner.borrow().len());
         println!("BareFnTy interner: #{}", self.bare_fn_interner.borrow().len());
@@ -959,16 +977,9 @@ impl<'tcx> PartialEq for TyS<'tcx> {
 }
 impl<'tcx> Eq for TyS<'tcx> {}
 
-#[cfg(stage0)]
-impl<'tcx, S: Writer + Hasher> Hash<S> for TyS<'tcx> {
-    fn hash(&self, s: &mut S) {
-        (self as *const _).hash(s)
-    }
-}
-#[cfg(not(stage0))]
 impl<'tcx> Hash for TyS<'tcx> {
     fn hash<H: Hasher>(&self, s: &mut H) {
-        (self as *const _).hash(s)
+        (self as *const TyS).hash(s)
     }
 }
 
@@ -988,13 +999,6 @@ impl<'tcx> PartialEq for InternedTy<'tcx> {
 
 impl<'tcx> Eq for InternedTy<'tcx> {}
 
-#[cfg(stage0)]
-impl<'tcx, S: Writer + Hasher> Hash<S> for InternedTy<'tcx> {
-    fn hash(&self, s: &mut S) {
-        self.ty.sty.hash(s)
-    }
-}
-#[cfg(not(stage0))]
 impl<'tcx> Hash for InternedTy<'tcx> {
     fn hash<H: Hasher>(&self, s: &mut H) {
         self.ty.sty.hash(s)
@@ -1031,7 +1035,7 @@ pub fn type_has_late_bound_regions(ty: Ty) -> bool {
 ///
 /// So, for example, consider a type like the following, which has two binders:
 ///
-///    for<'a> fn(x: for<'b> fn(&'a int, &'b int))
+///    for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
 ///    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
 ///                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~  inner scope
 ///
@@ -1115,16 +1119,16 @@ pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
 
 impl<'tcx> PolyFnSig<'tcx> {
     pub fn inputs(&self) -> ty::Binder<Vec<Ty<'tcx>>> {
-        ty::Binder(self.0.inputs.clone())
+        self.map_bound_ref(|fn_sig| fn_sig.inputs.clone())
     }
-    pub fn input(&self, index: uint) -> ty::Binder<Ty<'tcx>> {
-        ty::Binder(self.0.inputs[index])
+    pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
+        self.map_bound_ref(|fn_sig| fn_sig.inputs[index])
     }
     pub fn output(&self) -> ty::Binder<FnOutput<'tcx>> {
-        ty::Binder(self.0.output.clone())
+        self.map_bound_ref(|fn_sig| fn_sig.output.clone())
     }
     pub fn variadic(&self) -> bool {
-        self.0.variadic
+        self.skip_binder().variadic
     }
 }
 
@@ -1139,7 +1143,7 @@ pub struct ParamTy {
 /// regions (and perhaps later types) in a higher-ranked setting. In
 /// particular, imagine a type like this:
 ///
-///     for<'a> fn(for<'b> fn(&'b int, &'a int), &'a char)
+///     for<'a> fn(for<'b> fn(&'b isize, &'a isize), &'a char)
 ///     ^          ^            |        |         |
 ///     |          |            |        |         |
 ///     |          +------------+ 1      |         |
@@ -1156,11 +1160,11 @@ pub struct ParamTy {
 /// count the number of binders, inside out. Some examples should help
 /// clarify what I mean.
 ///
-/// Let's start with the reference type `&'b int` that is the first
+/// Let's start with the reference type `&'b isize` that is the first
 /// argument to the inner function. This region `'b` is assigned a De
 /// Bruijn index of 1, meaning "the innermost binder" (in this case, a
 /// fn). The region `'a` that appears in the second argument type (`&'a
-/// int`) would then be assigned a De Bruijn index of 2, meaning "the
+/// isize`) would then be assigned a De Bruijn index of 2, meaning "the
 /// second-innermost binder". (These indices are written on the arrays
 /// in the diagram).
 ///
@@ -1241,14 +1245,14 @@ pub enum BorrowKind {
     /// implicit closure bindings. It is needed when you the closure
     /// is borrowing or mutating a mutable referent, e.g.:
     ///
-    ///    let x: &mut int = ...;
+    ///    let x: &mut isize = ...;
     ///    let y = || *x += 5;
     ///
     /// If we were to try to translate this closure into a more explicit
     /// form, we'd encounter an error with the code as written:
     ///
-    ///    struct Env { x: & &mut int }
-    ///    let x: &mut int = ...;
+    ///    struct Env { x: & &mut isize }
+    ///    let x: &mut isize = ...;
     ///    let y = (&mut Env { &x }, fn_ptr);  // Closure is pair of env and fn
     ///    fn fn_ptr(env: &mut Env) { **env.x += 5; }
     ///
@@ -1256,8 +1260,8 @@ pub enum BorrowKind {
     /// in an aliasable location. To solve, you'd have to translate with
     /// an `&mut` borrow:
     ///
-    ///    struct Env { x: & &mut int }
-    ///    let x: &mut int = ...;
+    ///    struct Env { x: & &mut isize }
+    ///    let x: &mut isize = ...;
     ///    let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
     ///    fn fn_ptr(env: &mut Env) { **env.x += 5; }
     ///
@@ -1364,11 +1368,11 @@ pub enum sty<'tcx> {
     /// definition and not a concrete use of it. To get the correct `ty_enum`
     /// from the tcx, use the `NodeId` from the `ast::Ty` and look it up in
     /// the `ast_ty_to_ty_cache`. This is probably true for `ty_struct` as
-    /// well.`
+    /// well.
     ty_enum(DefId, &'tcx Substs<'tcx>),
     ty_uniq(Ty<'tcx>),
     ty_str,
-    ty_vec(Ty<'tcx>, Option<uint>), // Second field is length.
+    ty_vec(Ty<'tcx>, Option<usize>), // Second field is length.
     ty_ptr(mt<'tcx>),
     ty_rptr(&'tcx Region, mt<'tcx>),
 
@@ -1379,19 +1383,13 @@ pub enum sty<'tcx> {
     ty_trait(Box<TyTrait<'tcx>>),
     ty_struct(DefId, &'tcx Substs<'tcx>),
 
-    ty_closure(DefId, &'tcx Region, &'tcx Substs<'tcx>),
+    ty_closure(DefId, &'tcx Substs<'tcx>),
 
     ty_tup(Vec<Ty<'tcx>>),
 
     ty_projection(ProjectionTy<'tcx>),
     ty_param(ParamTy), // type parameter
 
-    ty_open(Ty<'tcx>), // A deref'ed fat pointer, i.e., a dynamically sized value
-                       // and its size. Only ever used in trans. It is not necessary
-                       // earlier since we don't need to distinguish a DST with its
-                       // size (e.g., in a deref) vs a DST with the size elsewhere (
-                       // e.g., in a field).
-
     ty_infer(InferTy), // something used only during inference/typeck
     ty_err, // Also only used during inference/typeck, to represent
             // the type of an erroneous expression (helps cut down
@@ -1504,7 +1502,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
 }
 
 /// Binder is a binder for higher-ranked lifetimes. It is part of the
-/// compiler's representation for things like `for<'a> Fn(&'a int)`
+/// compiler's representation for things like `for<'a> Fn(&'a isize)`
 /// (which would be represented by the type `PolyTraitRef ==
 /// Binder<TraitRef>`). Note that when we skolemize, instantiate,
 /// erase, or otherwise "discharge" these bound regions, we change the
@@ -1513,6 +1511,43 @@ impl<'tcx> PolyTraitRef<'tcx> {
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct Binder<T>(pub T);
 
+impl<T> Binder<T> {
+    /// Skips the binder and returns the "bound" value. This is a
+    /// risky thing to do because it's easy to get confused about
+    /// debruijn indices and the like. It is usually better to
+    /// discharge the binder using `no_late_bound_regions` or
+    /// `replace_late_bound_regions` or something like
+    /// that. `skip_binder` is only valid when you are either
+    /// extracting data that has nothing to do with bound regions, you
+    /// are doing some sort of test that does not involve bound
+    /// regions, or you are being very careful about your depth
+    /// accounting.
+    ///
+    /// Some examples where `skip_binder` is reasonable:
+    /// - extracting the def-id from a PolyTraitRef;
+    /// - comparing the self type of a PolyTraitRef to see if it is equal to
+    ///   a type parameter `X`, since the type `X`  does not reference any regions
+    pub fn skip_binder(&self) -> &T {
+        &self.0
+    }
+
+    pub fn as_ref(&self) -> Binder<&T> {
+        ty::Binder(&self.0)
+    }
+
+    pub fn map_bound_ref<F,U>(&self, f: F) -> Binder<U>
+        where F: FnOnce(&T) -> U
+    {
+        self.as_ref().map_bound(f)
+    }
+
+    pub fn map_bound<F,U>(self, f: F) -> Binder<U>
+        where F: FnOnce(T) -> U
+    {
+        ty::Binder(f(self.0))
+    }
+}
+
 #[derive(Clone, Copy, PartialEq)]
 pub enum IntVarValue {
     IntType(ast::IntTy),
@@ -1544,9 +1579,9 @@ pub enum type_err<'tcx> {
     terr_ptr_mutability,
     terr_ref_mutability,
     terr_vec_mutability,
-    terr_tuple_size(expected_found<uint>),
-    terr_fixed_array_size(expected_found<uint>),
-    terr_ty_param_size(expected_found<uint>),
+    terr_tuple_size(expected_found<usize>),
+    terr_fixed_array_size(expected_found<usize>),
+    terr_ty_param_size(expected_found<usize>),
     terr_arg_count,
     terr_regions_does_not_outlive(Region, Region),
     terr_regions_not_same(Region, Region),
@@ -1563,7 +1598,7 @@ pub enum type_err<'tcx> {
     terr_cyclic_ty,
     terr_convergence_mismatch(expected_found<bool>),
     terr_projection_name_mismatched(expected_found<ast::Name>),
-    terr_projection_bounds_length(expected_found<uint>),
+    terr_projection_bounds_length(expected_found<usize>),
 }
 
 /// Bounds suitable for a named type parameter like `A` in `fn foo<A>`
@@ -1592,7 +1627,7 @@ pub type BuiltinBounds = EnumSet<BuiltinBound>;
 
 #[derive(Clone, RustcEncodable, PartialEq, Eq, RustcDecodable, Hash,
            Debug, Copy)]
-#[repr(uint)]
+#[repr(usize)]
 pub enum BuiltinBound {
     BoundSend,
     BoundSized,
@@ -1620,10 +1655,10 @@ pub fn region_existential_bound<'tcx>(r: ty::Region) -> ExistentialBounds<'tcx>
 }
 
 impl CLike for BuiltinBound {
-    fn to_usize(&self) -> uint {
-        *self as uint
+    fn to_usize(&self) -> usize {
+        *self as usize
     }
-    fn from_usize(v: uint) -> BuiltinBound {
+    fn from_usize(v: usize) -> BuiltinBound {
         unsafe { mem::transmute(v) }
     }
 }
@@ -1768,7 +1803,6 @@ pub struct TypeParameterDef<'tcx> {
     pub def_id: ast::DefId,
     pub space: subst::ParamSpace,
     pub index: u32,
-    pub bounds: ParamBounds<'tcx>,
     pub default: Option<Ty<'tcx>>,
     pub object_lifetime_default: Option<ObjectLifetimeDefault>,
 }
@@ -1786,6 +1820,9 @@ impl RegionParameterDef {
     pub fn to_early_bound_region(&self) -> ty::Region {
         ty::ReEarlyBound(self.def_id.node, self.space, self.index, self.name)
     }
+    pub fn to_bound_region(&self) -> ty::BoundRegion {
+        ty::BoundRegion::BrNamed(self.def_id, self.name)
+    }
 }
 
 /// Information about the formal type/lifetime parameters associated
@@ -1836,6 +1873,16 @@ impl<'tcx> GenericPredicates<'tcx> {
             predicates: self.predicates.subst(tcx, substs),
         }
     }
+
+    pub fn instantiate_supertrait(&self,
+                                  tcx: &ty::ctxt<'tcx>,
+                                  poly_trait_ref: &ty::PolyTraitRef<'tcx>)
+                                  -> InstantiatedPredicates<'tcx>
+    {
+        InstantiatedPredicates {
+            predicates: self.predicates.map(|pred| pred.subst_supertrait(tcx, poly_trait_ref))
+        }
+    }
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
@@ -1859,6 +1906,93 @@ pub enum Predicate<'tcx> {
     Projection(PolyProjectionPredicate<'tcx>),
 }
 
+impl<'tcx> Predicate<'tcx> {
+    /// Performs a substituion suitable for going from a
+    /// poly-trait-ref to supertraits that must hold if that
+    /// poly-trait-ref holds. This is slightly different from a normal
+    /// substitution in terms of what happens with bound regions.  See
+    /// lengthy comment below for details.
+    pub fn subst_supertrait(&self,
+                            tcx: &ty::ctxt<'tcx>,
+                            trait_ref: &ty::PolyTraitRef<'tcx>)
+                            -> ty::Predicate<'tcx>
+    {
+        // The interaction between HRTB and supertraits is not entirely
+        // obvious. Let me walk you (and myself) through an example.
+        //
+        // Let's start with an easy case. Consider two traits:
+        //
+        //     trait Foo<'a> : Bar<'a,'a> { }
+        //     trait Bar<'b,'c> { }
+        //
+        // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
+        // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
+        // knew that `Foo<'x>` (for any 'x) then we also know that
+        // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
+        // normal substitution.
+        //
+        // In terms of why this is sound, the idea is that whenever there
+        // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
+        // holds.  So if there is an impl of `T:Foo<'a>` that applies to
+        // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
+        // `'a`.
+        //
+        // Another example to be careful of is this:
+        //
+        //     trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
+        //     trait Bar1<'b,'c> { }
+        //
+        // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
+        // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
+        // reason is similar to the previous example: any impl of
+        // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`.  So
+        // basically we would want to collapse the bound lifetimes from
+        // the input (`trait_ref`) and the supertraits.
+        //
+        // To achieve this in practice is fairly straightforward. Let's
+        // consider the more complicated scenario:
+        //
+        // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
+        //   has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
+        //   where both `'x` and `'b` would have a DB index of 1.
+        //   The substitution from the input trait-ref is therefore going to be
+        //   `'a => 'x` (where `'x` has a DB index of 1).
+        // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
+        //   early-bound parameter and `'b' is a late-bound parameter with a
+        //   DB index of 1.
+        // - If we replace `'a` with `'x` from the input, it too will have
+        //   a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
+        //   just as we wanted.
+        //
+        // There is only one catch. If we just apply the substitution `'a
+        // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
+        // adjust the DB index because we substituting into a binder (it
+        // tries to be so smart...) resulting in `for<'x> for<'b>
+        // Bar1<'x,'b>` (we have no syntax for this, so use your
+        // imagination). Basically the 'x will have DB index of 2 and 'b
+        // will have DB index of 1. Not quite what we want. So we apply
+        // the substitution to the *contents* of the trait reference,
+        // rather than the trait reference itself (put another way, the
+        // substitution code expects equal binding levels in the values
+        // from the substitution and the value being substituted into, and
+        // this trick achieves that).
+
+        let substs = &trait_ref.0.substs;
+        match *self {
+            Predicate::Trait(ty::Binder(ref data)) =>
+                Predicate::Trait(ty::Binder(data.subst(tcx, substs))),
+            Predicate::Equate(ty::Binder(ref data)) =>
+                Predicate::Equate(ty::Binder(data.subst(tcx, substs))),
+            Predicate::RegionOutlives(ty::Binder(ref data)) =>
+                Predicate::RegionOutlives(ty::Binder(data.subst(tcx, substs))),
+            Predicate::TypeOutlives(ty::Binder(ref data)) =>
+                Predicate::TypeOutlives(ty::Binder(data.subst(tcx, substs))),
+            Predicate::Projection(ty::Binder(ref data)) =>
+                Predicate::Projection(ty::Binder(data.subst(tcx, substs))),
+        }
+    }
+}
+
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct TraitPredicate<'tcx> {
     pub trait_ref: Rc<TraitRef<'tcx>>
@@ -1955,8 +2089,7 @@ impl<'tcx> ToPolyTraitRef<'tcx> for Rc<TraitRef<'tcx>> {
 
 impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
     fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
-        // We are just preserving the binder levels here
-        ty::Binder(self.0.trait_ref.clone())
+        self.map_bound_ref(|trait_pred| trait_pred.trait_ref.clone())
     }
 }
 
@@ -2095,8 +2228,8 @@ impl<'tcx> Predicate<'tcx> {
 ///
 /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
 /// `[[], [U:Bar<T>]]`.  Now if there were some particular reference
-/// like `Foo<int,uint>`, then the `InstantiatedPredicates` would be `[[],
-/// [uint:Bar<int>]]`.
+/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
+/// [usize:Bar<isize>]]`.
 #[derive(Clone, Debug)]
 pub struct InstantiatedPredicates<'tcx> {
     pub predicates: VecPerParamSpace<Predicate<'tcx>>,
@@ -2186,8 +2319,8 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
     pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> {
         match cx.map.find(id) {
             Some(ast_map::NodeImplItem(ref impl_item)) => {
-                match **impl_item {
-                    ast::MethodImplItem(ref method) => {
+                match impl_item.node {
+                    ast::MethodImplItem(_, ref body) => {
                         let method_def_id = ast_util::local_def(id);
                         match ty::impl_or_trait_item(cx, method_def_id) {
                             MethodTraitItem(ref method_ty) => {
@@ -2195,10 +2328,10 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                 let method_bounds = &method_ty.predicates;
                                 construct_parameter_environment(
                                     cx,
-                                    method.span,
+                                    impl_item.span,
                                     method_generics,
                                     method_bounds,
-                                    method.pe_body().id)
+                                    body.id)
                             }
                             TypeTraitItem(_) => {
                                 cx.sess
@@ -2213,18 +2346,19 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                      can't create a parameter environment \
                                      for type impl items")
                     }
+                    ast::MacImplItem(_) => cx.sess.bug("unexpanded macro")
                 }
             }
-            Some(ast_map::NodeTraitItem(trait_method)) => {
-                match *trait_method {
-                    ast::RequiredMethod(ref required) => {
-                        cx.sess.span_bug(required.span,
+            Some(ast_map::NodeTraitItem(trait_item)) => {
+                match trait_item.node {
+                    ast::MethodTraitItem(_, None) => {
+                        cx.sess.span_bug(trait_item.span,
                                          "ParameterEnvironment::for_item():
                                           can't create a parameter \
                                           environment for required trait \
                                           methods")
                     }
-                    ast::ProvidedMethod(ref method) => {
+                    ast::MethodTraitItem(_, Some(ref body)) => {
                         let method_def_id = ast_util::local_def(id);
                         match ty::impl_or_trait_item(cx, method_def_id) {
                             MethodTraitItem(ref method_ty) => {
@@ -2232,10 +2366,10 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                                 let method_bounds = &method_ty.predicates;
                                 construct_parameter_environment(
                                     cx,
-                                    method.span,
+                                    trait_item.span,
                                     method_generics,
                                     method_bounds,
-                                    method.pe_body().id)
+                                    body.id)
                             }
                             TypeTraitItem(_) => {
                                 cx.sess
@@ -2245,7 +2379,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                             }
                         }
                     }
-                    ast::TypeTraitItem(_) => {
+                    ast::TypeTraitItem(..) => {
                         cx.sess.bug("ParameterEnvironment::from_item(): \
                                      can't create a parameter environment \
                                      for type trait items")
@@ -2295,7 +2429,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
             _ => {
                 cx.sess.bug(&format!("ParameterEnvironment::from_item(): \
                                      `{}` is not an item",
-                                    cx.map.node_to_string(id))[])
+                                    cx.map.node_to_string(id)))
             }
         }
     }
@@ -2343,9 +2477,6 @@ pub struct TraitDef<'tcx> {
     /// implements the trait.
     pub generics: Generics<'tcx>,
 
-    /// The "supertrait" bounds.
-    pub bounds: ParamBounds<'tcx>,
-
     pub trait_ref: Rc<ty::TraitRef<'tcx>>,
 
     /// A list of the associated types defined in this trait. Useful
@@ -2360,8 +2491,11 @@ pub struct ItemSubsts<'tcx> {
     pub substs: Substs<'tcx>,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
 pub enum ClosureKind {
+    // Warning: Ordering is significant here! The ordering is chosen
+    // because the trait Fn is a subtrait of FnMut and so in turn, and
+    // hence we order it so that Fn < FnMut < FnOnce.
     FnClosureKind,
     FnMutClosureKind,
     FnOnceClosureKind,
@@ -2383,6 +2517,20 @@ impl ClosureKind {
             Err(err) => cx.sess.fatal(&err[..]),
         }
     }
+
+    /// True if this a type that impls this closure kind
+    /// must also implement `other`.
+    pub fn extends(self, other: ty::ClosureKind) -> bool {
+        match (self, other) {
+            (FnClosureKind, FnClosureKind) => true,
+            (FnClosureKind, FnMutClosureKind) => true,
+            (FnClosureKind, FnOnceClosureKind) => true,
+            (FnMutClosureKind, FnMutClosureKind) => true,
+            (FnMutClosureKind, FnOnceClosureKind) => true,
+            (FnOnceClosureKind, FnOnceClosureKind) => true,
+            _ => false,
+        }
+    }
 }
 
 pub trait ClosureTyper<'tcx> {
@@ -2423,12 +2571,12 @@ impl<'tcx> CommonTypes<'tcx> {
             bool: intern_ty(arena, interner, ty_bool),
             char: intern_ty(arena, interner, ty_char),
             err: intern_ty(arena, interner, ty_err),
-            int: intern_ty(arena, interner, ty_int(ast::TyIs(false))),
+            isize: intern_ty(arena, interner, ty_int(ast::TyIs)),
             i8: intern_ty(arena, interner, ty_int(ast::TyI8)),
             i16: intern_ty(arena, interner, ty_int(ast::TyI16)),
             i32: intern_ty(arena, interner, ty_int(ast::TyI32)),
             i64: intern_ty(arena, interner, ty_int(ast::TyI64)),
-            uint: intern_ty(arena, interner, ty_uint(ast::TyUs(false))),
+            usize: intern_ty(arena, interner, ty_uint(ast::TyUs)),
             u8: intern_ty(arena, interner, ty_uint(ast::TyU8)),
             u16: intern_ty(arena, interner, ty_uint(ast::TyU16)),
             u32: intern_ty(arena, interner, ty_uint(ast::TyU32)),
@@ -2441,7 +2589,7 @@ impl<'tcx> CommonTypes<'tcx> {
 
 pub fn mk_ctxt<'tcx>(s: Session,
                      arenas: &'tcx CtxtArenas<'tcx>,
-                     dm: DefMap,
+                     def_map: DefMap,
                      named_region_map: resolve_lifetime::NamedRegionMap,
                      map: ast_map::Map<'tcx>,
                      freevars: RefCell<FreevarMap>,
@@ -2463,16 +2611,16 @@ pub fn mk_ctxt<'tcx>(s: Session,
         item_variance_map: RefCell::new(DefIdMap()),
         variance_computed: Cell::new(false),
         sess: s,
-        def_map: dm,
+        def_map: def_map,
         region_maps: region_maps,
         node_types: RefCell::new(FnvHashMap()),
         item_substs: RefCell::new(NodeMap()),
-        trait_refs: RefCell::new(NodeMap()),
+        impl_trait_refs: RefCell::new(NodeMap()),
         trait_defs: RefCell::new(DefIdMap()),
         predicates: RefCell::new(DefIdMap()),
+        super_predicates: RefCell::new(DefIdMap()),
         object_cast_map: RefCell::new(NodeMap()),
         map: map,
-        intrinsic_defs: RefCell::new(DefIdMap()),
         freevars: freevars,
         tcache: RefCell::new(DefIdMap()),
         rcache: RefCell::new(FnvHashMap()),
@@ -2493,12 +2641,14 @@ pub fn mk_ctxt<'tcx>(s: Session,
         destructor_for_type: RefCell::new(DefIdMap()),
         destructors: RefCell::new(DefIdSet()),
         trait_impls: RefCell::new(DefIdMap()),
+        traits_with_default_impls: RefCell::new(DefIdMap()),
         inherent_impls: RefCell::new(DefIdMap()),
         impl_items: RefCell::new(DefIdMap()),
         used_unsafe: RefCell::new(NodeSet()),
         used_mut_nodes: RefCell::new(NodeSet()),
         populated_external_types: RefCell::new(DefIdSet()),
         populated_external_traits: RefCell::new(DefIdSet()),
+        populated_external_primitive_impls: RefCell::new(DefIdSet()),
         upvar_capture_map: RefCell::new(FnvHashMap()),
         extern_const_statics: RefCell::new(DefIdMap()),
         extern_const_variants: RefCell::new(DefIdMap()),
@@ -2532,6 +2682,17 @@ impl<'tcx> ctxt<'tcx> {
         substs
     }
 
+    /// Create an unsafe fn ty based on a safe fn ty.
+    pub fn safe_to_unsafe_fn_ty(&self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> {
+        assert_eq!(bare_fn.unsafety, ast::Unsafety::Normal);
+        let unsafe_fn_ty_a = self.mk_bare_fn(ty::BareFnTy {
+            unsafety: ast::Unsafety::Unsafe,
+            abi: bare_fn.abi,
+            sig: bare_fn.sig.clone()
+        });
+        ty::mk_bare_fn(self, None, unsafe_fn_ty_a)
+    }
+
     pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> {
         if let Some(bare_fn) = self.bare_fn_interner.borrow().get(&bare_fn) {
             return *bare_fn;
@@ -2553,7 +2714,7 @@ impl<'tcx> ctxt<'tcx> {
     }
 
     pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
-        self.closure_kinds.borrow()[def_id]
+        *self.closure_kinds.borrow().get(&def_id).unwrap()
     }
 
     pub fn closure_type(&self,
@@ -2561,7 +2722,22 @@ impl<'tcx> ctxt<'tcx> {
                         substs: &subst::Substs<'tcx>)
                         -> ty::ClosureTy<'tcx>
     {
-        self.closure_tys.borrow()[def_id].subst(self, substs)
+        self.closure_tys.borrow().get(&def_id).unwrap().subst(self, substs)
+    }
+
+    pub fn type_parameter_def(&self,
+                              node_id: ast::NodeId)
+                              -> TypeParameterDef<'tcx>
+    {
+        self.ty_param_defs.borrow().get(&node_id).unwrap().clone()
+    }
+
+    pub fn pat_contains_ref_binding(&self, pat: &ast::Pat) -> bool {
+        pat_util::pat_contains_ref_binding(&self.def_map, pat)
+    }
+
+    pub fn arm_contains_ref_binding(&self, arm: &ast::Arm) -> bool {
+        pat_util::arm_contains_ref_binding(&self.def_map, arm)
     }
 }
 
@@ -2591,7 +2767,7 @@ fn intern_ty<'tcx>(type_arena: &'tcx TypedArena<TyS<'tcx>>,
     };
 
     debug!("Interned type: {:?} Pointer: {:?}",
-           ty, ty as *const _);
+           ty, ty as *const TyS);
 
     interner.insert(InternedTy { ty: ty }, ty);
 
@@ -2669,8 +2845,7 @@ impl FlagComputation {
                 }
             }
 
-            &ty_closure(_, region, substs) => {
-                self.add_region(*region);
+            &ty_closure(_, substs) => {
                 self.add_substs(substs);
             }
 
@@ -2700,7 +2875,7 @@ impl FlagComputation {
                 self.add_bounds(bounds);
             }
 
-            &ty_uniq(tt) | &ty_vec(tt, _) | &ty_open(tt) => {
+            &ty_uniq(tt) | &ty_vec(tt, _) => {
                 self.add_ty(tt)
             }
 
@@ -2737,7 +2912,7 @@ impl FlagComputation {
     fn add_fn_sig(&mut self, fn_sig: &PolyFnSig) {
         let mut computation = FlagComputation::new();
 
-        computation.add_tys(&fn_sig.0.inputs[]);
+        computation.add_tys(&fn_sig.0.inputs);
 
         if let ty::FnConverging(output) = fn_sig.0.output {
             computation.add_ty(output);
@@ -2786,7 +2961,7 @@ impl FlagComputation {
 
 pub fn mk_mach_int<'tcx>(tcx: &ctxt<'tcx>, tm: ast::IntTy) -> Ty<'tcx> {
     match tm {
-        ast::TyIs(_)   => tcx.types.int,
+        ast::TyIs   => tcx.types.isize,
         ast::TyI8   => tcx.types.i8,
         ast::TyI16  => tcx.types.i16,
         ast::TyI32  => tcx.types.i32,
@@ -2796,7 +2971,7 @@ pub fn mk_mach_int<'tcx>(tcx: &ctxt<'tcx>, tm: ast::IntTy) -> Ty<'tcx> {
 
 pub fn mk_mach_uint<'tcx>(tcx: &ctxt<'tcx>, tm: ast::UintTy) -> Ty<'tcx> {
     match tm {
-        ast::TyUs(_)   => tcx.types.uint,
+        ast::TyUs   => tcx.types.usize,
         ast::TyU8   => tcx.types.u8,
         ast::TyU16  => tcx.types.u16,
         ast::TyU32  => tcx.types.u32,
@@ -2855,7 +3030,7 @@ pub fn mk_nil_ptr<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
     mk_ptr(cx, mt {ty: mk_nil(cx), mutbl: ast::MutImmutable})
 }
 
-pub fn mk_vec<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, sz: Option<uint>) -> Ty<'tcx> {
+pub fn mk_vec<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, sz: Option<usize>) -> Ty<'tcx> {
     mk_t(cx, ty_vec(ty, sz))
 }
 
@@ -2875,6 +3050,10 @@ pub fn mk_nil<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
     mk_tup(cx, Vec::new())
 }
 
+pub fn mk_bool<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
+    mk_t(cx, ty_bool)
+}
+
 pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>,
                         opt_def_id: Option<ast::DefId>,
                         fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
@@ -2938,10 +3117,9 @@ pub fn mk_struct<'tcx>(cx: &ctxt<'tcx>, struct_id: ast::DefId,
     mk_t(cx, ty_struct(struct_id, substs))
 }
 
-pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId,
-                        region: &'tcx Region, substs: &'tcx Substs<'tcx>)
+pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &'tcx Substs<'tcx>)
                         -> Ty<'tcx> {
-    mk_t(cx, ty_closure(closure_id, region, substs))
+    mk_t(cx, ty_closure(closure_id, substs))
 }
 
 pub fn mk_var<'tcx>(cx: &ctxt<'tcx>, v: TyVid) -> Ty<'tcx> {
@@ -2975,8 +3153,6 @@ pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'t
     mk_param(cx, def.space, def.index, def.name)
 }
 
-pub fn mk_open<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_open(ty)) }
-
 impl<'tcx> TyS<'tcx> {
     /// Iterator that walks `self` and any types reachable from
     /// `self`, in depth-first order. Note that just walks the types
@@ -2984,29 +3160,19 @@ impl<'tcx> TyS<'tcx> {
     /// structs or variants. For example:
     ///
     /// ```notrust
-    /// int => { int }
-    /// Foo<Bar<int>> => { Foo<Bar<int>>, Bar<int>, int }
-    /// [int] => { [int], int }
+    /// isize => { isize }
+    /// Foo<Bar<isize>> => { Foo<Bar<isize>>, Bar<isize>, isize }
+    /// [isize] => { [isize], isize }
     /// ```
     pub fn walk(&'tcx self) -> TypeWalker<'tcx> {
         TypeWalker::new(self)
     }
 
-    /// Iterator that walks types reachable from `self`, in
-    /// depth-first order. Note that this is a shallow walk. For
-    /// example:
-    ///
-    /// ```notrust
-    /// int => { }
-    /// Foo<Bar<int>> => { Bar<int>, int }
-    /// [int] => { int }
-    /// ```
-    pub fn walk_children(&'tcx self) -> TypeWalker<'tcx> {
-        // Walks type reachable from `self` but not `self
-        let mut walker = self.walk();
-        let r = walker.next();
-        assert_eq!(r, Some(self));
-        walker
+    /// Iterator that walks the immediate children of `self`.  Hence
+    /// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
+    /// (but not `i32`, like `walk`).
+    pub fn walk_shallow(&'tcx self) -> IntoIter<Ty<'tcx>> {
+        ty_walk::walk_shallow(self)
     }
 
     pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
@@ -3015,6 +3181,13 @@ impl<'tcx> TyS<'tcx> {
             _ => None,
         }
     }
+
+    pub fn is_param(&self, space: ParamSpace, index: u32) -> bool {
+        match self.sty {
+            ty::ty_param(ref data) => data.space == space && data.idx == index,
+            _ => false,
+        }
+    }
 }
 
 pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F)
@@ -3175,9 +3348,8 @@ pub fn sequence_element_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
     match ty.sty {
         ty_vec(ty, _) => ty,
         ty_str => mk_mach_uint(cx, ast::TyU8),
-        ty_open(ty) => sequence_element_type(cx, ty),
         _ => cx.sess.bug(&format!("sequence_element_type called on non-sequence value: {}",
-                                 ty_to_string(cx, ty))[]),
+                                 ty_to_string(cx, ty))),
     }
 }
 
@@ -3191,7 +3363,7 @@ pub fn simd_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
     }
 }
 
-pub fn simd_size(cx: &ctxt, ty: Ty) -> uint {
+pub fn simd_size(cx: &ctxt, ty: Ty) -> usize {
     match ty.sty {
         ty_struct(did, _) => {
             let fields = lookup_struct_fields(cx, did);
@@ -3239,8 +3411,12 @@ pub fn type_is_scalar(ty: Ty) -> bool {
 /// Returns true if this type is a floating point type and false otherwise.
 pub fn type_is_floating_point(ty: Ty) -> bool {
     match ty.sty {
-        ty_float(_) => true,
-        _ => false,
+        ty_float(_) |
+        ty_infer(FloatVar(_)) =>
+            true,
+
+        _ =>
+            false,
     }
 }
 
@@ -3459,8 +3635,8 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
         cache.insert(ty, TC::None);
 
         let result = match ty.sty {
-            // uint and int are ffi-unsafe
-            ty_uint(ast::TyUs(_)) | ty_int(ast::TyIs(_)) => {
+            // usize and isize are ffi-unsafe
+            ty_uint(ast::TyUs) | ty_int(ast::TyIs) => {
                 TC::ReachesFfiUnsafe
             }
 
@@ -3520,13 +3696,11 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
                 apply_lang_items(cx, did, res)
             }
 
-            ty_closure(did, r, substs) => {
+            ty_closure(did, substs) => {
                 // FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
                 let param_env = ty::empty_parameter_environment(cx);
                 let upvars = closure_upvars(&param_env, did, substs).unwrap();
-                TypeContents::union(&upvars,
-                                    |f| tc_ty(cx, &f.ty, cache))
-                    | borrowed_contents(*r, MutMutable)
+                TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache))
             }
 
             ty_tup(ref tys) => {
@@ -3538,7 +3712,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
                 let variants = substd_enum_variants(cx, did, substs);
                 let mut res =
                     TypeContents::union(&variants[..], |variant| {
-                        TypeContents::union(&variant.args[],
+                        TypeContents::union(&variant.args,
                                             |arg_ty| {
                             tc_ty(cx, *arg_ty, cache)
                         })
@@ -3594,12 +3768,6 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
                 TC::All
             }
 
-            ty_open(ty) => {
-                let result = tc_ty(cx, ty, cache);
-                assert!(!result.is_sized(cx));
-                result.unsafe_pointer() | TC::Nonsized
-            }
-
             ty_infer(_) |
             ty_err => {
                 cx.sess.bug("asked to compute contents of error type");
@@ -3758,7 +3926,7 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
             ty_vec(_, None) => {
                 false
             }
-            ty_uniq(typ) | ty_open(typ) => {
+            ty_uniq(typ) => {
                 type_requires(cx, seen, r_ty, typ)
             }
             ty_rptr(_, ref mt) => {
@@ -3835,7 +4003,7 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
 ///
 /// The ordering of the cases is significant. They are sorted so that cmp::max
 /// will keep the "more erroneous" of two values.
-#[derive(Copy, PartialOrd, Ord, Eq, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq, Debug)]
 pub enum Representability {
     Representable,
     ContainsRecursive,
@@ -3909,7 +4077,7 @@ pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
                 let types_a = substs_a.types.get_slice(subst::TypeSpace);
                 let types_b = substs_b.types.get_slice(subst::TypeSpace);
 
-                let pairs = types_a.iter().zip(types_b.iter());
+                let mut pairs = types_a.iter().zip(types_b.iter());
 
                 pairs.all(|(&a, &b)| same_type(a, b))
             }
@@ -4031,7 +4199,7 @@ pub fn type_is_fresh(ty: Ty) -> bool {
 
 pub fn type_is_uint(ty: Ty) -> bool {
     match ty.sty {
-      ty_infer(IntVar(_)) | ty_uint(ast::TyUs(_)) => true,
+      ty_infer(IntVar(_)) | ty_uint(ast::TyUs) => true,
       _ => false
     }
 }
@@ -4077,7 +4245,7 @@ pub fn type_is_signed(ty: Ty) -> bool {
 
 pub fn type_is_machine(ty: Ty) -> bool {
     match ty.sty {
-        ty_int(ast::TyIs(_)) | ty_uint(ast::TyUs(_)) => false,
+        ty_int(ast::TyIs) | ty_uint(ast::TyUs) => false,
         ty_int(..) | ty_uint(..) | ty_float(..) => true,
         _ => false
     }
@@ -4117,14 +4285,6 @@ pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option<mt<'tcx>> {
     }
 }
 
-pub fn close_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-    match ty.sty {
-        ty_open(ty) => mk_rptr(cx, cx.mk_region(ReStatic), mt {ty: ty, mutbl:ast::MutImmutable}),
-        _ => cx.sess.bug(&format!("Trying to close a non-open type {}",
-                                 ty_to_string(cx, ty))[])
-    }
-}
-
 pub fn type_content<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
     match ty.sty {
         ty_uniq(ty) => ty,
@@ -4133,14 +4293,6 @@ pub fn type_content<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
     }
 }
 
-// Extract the unsized type in an open type (or just return ty if it is not open).
-pub fn unopen_type<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> {
-    match ty.sty {
-        ty_open(ty) => ty,
-        _ => ty
-    }
-}
-
 // Returns the type of ty[i]
 pub fn index<'tcx>(ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
     match ty.sty {
@@ -4164,7 +4316,7 @@ pub fn array_element_ty<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>
 /// For an enum `t`, `variant` is None only if `t` is a univariant enum.
 pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>,
                                    ty: Ty<'tcx>,
-                                   i: uint,
+                                   i: usize,
                                    variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
 
     match (&ty.sty, variant) {
@@ -4216,13 +4368,13 @@ pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>,
     }
 }
 
-pub fn node_id_to_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
+pub fn impl_id_to_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
                                   -> Rc<ty::TraitRef<'tcx>> {
-    match cx.trait_refs.borrow().get(&id) {
+    match cx.impl_trait_refs.borrow().get(&id) {
         Some(ty) => ty.clone(),
         None => cx.sess.bug(
-            &format!("node_id_to_trait_ref: no trait ref for node `{}`",
-                    cx.map.node_to_string(id))[])
+            &format!("impl_id_to_trait_ref: no trait ref for impl `{}`",
+                    cx.map.node_to_string(id)))
     }
 }
 
@@ -4231,7 +4383,7 @@ pub fn node_id_to_type<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Ty<'tcx> {
        Some(ty) => ty,
        None => cx.sess.bug(
            &format!("node_id_to_type: no type for node `{}`",
-                   cx.map.node_to_string(id))[])
+                   cx.map.node_to_string(id)))
     }
 }
 
@@ -4305,7 +4457,7 @@ pub fn ty_region(tcx: &ctxt,
             tcx.sess.span_bug(
                 span,
                 &format!("ty_region() invoked on an inappropriate ty: {:?}",
-                        s)[]);
+                        s));
         }
     }
 }
@@ -4327,6 +4479,9 @@ pub fn free_region_from_def(outlives_extent: region::DestructionScopeData,
 pub fn pat_ty<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Ty<'tcx> {
     return node_id_to_type(cx, pat.id);
 }
+pub fn pat_ty_opt<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Option<Ty<'tcx>> {
+    return node_id_to_type_opt(cx, pat.id);
+}
 
 
 // Returns the type of an expression as a monotype.
@@ -4337,8 +4492,8 @@ pub fn pat_ty<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Ty<'tcx> {
 // adjustments.  See `expr_ty_adjusted()` instead.
 //
 // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
-// ask for the type of "id" in "id(3)", it will return "fn(&int) -> int"
-// instead of "fn(ty) -> T with T = int".
+// ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
+// instead of "fn(ty) -> T with T = isize".
 pub fn expr_ty<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> {
     return node_id_to_type(cx, expr.id);
 }
@@ -4370,11 +4525,11 @@ pub fn expr_span(cx: &ctxt, id: NodeId) -> Span {
         Some(f) => {
             cx.sess.bug(&format!("Node id {} is not an expr: {:?}",
                                 id,
-                                f)[]);
+                                f));
         }
         None => {
             cx.sess.bug(&format!("Node id {} is not present \
-                                in the node map", id)[]);
+                                in the node map", id));
         }
     }
 }
@@ -4390,14 +4545,14 @@ pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString {
                     cx.sess.bug(
                         &format!("Variable id {} maps to {:?}, not local",
                                 id,
-                                pat)[]);
+                                pat));
                 }
             }
         }
         r => {
             cx.sess.bug(&format!("Variable id {} maps to {:?}, not local",
                                 id,
-                                r)[]);
+                                r));
         }
     }
 }
@@ -4428,11 +4583,23 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
                             cx.sess.bug(
                                 &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
                                          {:?}",
-                                        b)[]);
+                                        b));
                         }
                     }
                 }
 
+               AdjustUnsafeFnPointer => {
+                    match unadjusted_ty.sty {
+                        ty::ty_bare_fn(None, b) => cx.safe_to_unsafe_fn_ty(b),
+                        ref b => {
+                            cx.sess.bug(
+                                &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
+                                         {:?}",
+                                        b));
+                        }
+                    }
+               }
+
                 AdjustDerefRef(ref adj) => {
                     let mut adjusted_ty = unadjusted_ty;
 
@@ -4459,7 +4626,7 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
                                                 {}",
                                                 i,
                                                 ty_to_string(cx, adjusted_ty))
-                                        []);
+                                        );
                                 }
                             }
                         }
@@ -4522,7 +4689,7 @@ pub fn unsize_ty<'tcx>(cx: &ctxt<'tcx>,
             }
             _ => cx.sess.span_bug(span,
                                   &format!("UnsizeLength with bad sty: {:?}",
-                                          ty_to_string(cx, ty))[])
+                                          ty_to_string(cx, ty)))
         },
         &UnsizeStruct(box ref k, tp_index) => match ty.sty {
             ty_struct(did, substs) => {
@@ -4534,20 +4701,23 @@ pub fn unsize_ty<'tcx>(cx: &ctxt<'tcx>,
             }
             _ => cx.sess.span_bug(span,
                                   &format!("UnsizeStruct with bad sty: {:?}",
-                                          ty_to_string(cx, ty))[])
+                                          ty_to_string(cx, ty)))
         },
         &UnsizeVtable(TyTrait { ref principal, ref bounds }, _) => {
             mk_trait(cx, principal.clone(), bounds.clone())
         }
+        &UnsizeUpcast(target_ty) => {
+            target_ty
+        }
     }
 }
 
 pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
     match tcx.def_map.borrow().get(&expr.id) {
-        Some(&def) => def,
+        Some(def) => def.full_def(),
         None => {
             tcx.sess.span_bug(expr.span, &format!(
-                "no def-map entry for expr {}", expr.id)[]);
+                "no def-map entry for expr {}", expr.id));
         }
     }
 }
@@ -4564,7 +4734,7 @@ pub fn expr_is_lval(tcx: &ctxt, e: &ast::Expr) -> bool {
 /// two kinds of rvalues is an artifact of trans which reflects how we will
 /// generate code for that kind of expression.  See trans/expr.rs for more
 /// information.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum ExprKind {
     LvalueExpr,
     RvalueDpsExpr,
@@ -4592,7 +4762,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
     }
 
     match expr.node {
-        ast::ExprPath(_) | ast::ExprQPath(_) => {
+        ast::ExprPath(..) => {
             match resolve_expr(tcx, expr) {
                 def::DefVariant(tid, vid, _) => {
                     let variant_info = enum_variant_with_id(tcx, tid, vid);
@@ -4623,7 +4793,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
                 def::DefFn(_, true) => RvalueDpsExpr,
 
                 // Fn pointers are just scalar values.
-                def::DefFn(..) | def::DefStaticMethod(..) | def::DefMethod(..) => RvalueDatumExpr,
+                def::DefFn(..) | def::DefMethod(..) => RvalueDatumExpr,
 
                 // Note: there is actually a good case to be made that
                 // DefArg's, particularly those of immediate type, ought to
@@ -4639,7 +4809,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
                         expr.span,
                         &format!("uncategorized def for expr {}: {:?}",
                                 expr.id,
-                                def)[]);
+                                def));
                 }
             }
         }
@@ -4680,32 +4850,6 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
             RvalueDpsExpr
         }
 
-        ast::ExprCast(..) => {
-            match tcx.node_types.borrow().get(&expr.id) {
-                Some(&ty) => {
-                    if type_is_trait(ty) {
-                        RvalueDpsExpr
-                    } else {
-                        RvalueDatumExpr
-                    }
-                }
-                None => {
-                    // Technically, it should not happen that the expr is not
-                    // present within the table.  However, it DOES happen
-                    // during type check, because the final types from the
-                    // expressions are not yet recorded in the tcx.  At that
-                    // time, though, we are only interested in knowing lvalue
-                    // vs rvalue.  It would be better to base this decision on
-                    // the AST type in cast node---but (at the time of this
-                    // writing) it's not easy to distinguish casts to traits
-                    // from other casts based on the AST.  This should be
-                    // easier in the future, when casts to traits
-                    // would like @Foo, Box<Foo>, or &Foo.
-                    RvalueDatumExpr
-                }
-            }
-        }
-
         ast::ExprBreak(..) |
         ast::ExprAgain(..) |
         ast::ExprRet(..) |
@@ -4721,17 +4865,17 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
         ast::ExprUnary(..) |
         ast::ExprBox(None, _) |
         ast::ExprAddrOf(..) |
-        ast::ExprBinary(..) => {
+        ast::ExprBinary(..) |
+        ast::ExprCast(..) => {
             RvalueDatumExpr
         }
 
         ast::ExprBox(Some(ref place), _) => {
             // Special case `Box<T>` for now:
-            let definition = match tcx.def_map.borrow().get(&place.id) {
-                Some(&def) => def,
+            let def_id = match tcx.def_map.borrow().get(&place.id) {
+                Some(def) => def.def_id(),
                 None => panic!("no def for place"),
             };
-            let def_id = definition.def_id();
             if tcx.lang_items.exchange_heap() == Some(def_id) {
                 RvalueDatumExpr
             } else {
@@ -4759,7 +4903,7 @@ pub fn stmt_node_id(s: &ast::Stmt) -> ast::NodeId {
 }
 
 pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field])
-                     -> uint {
+                     -> usize {
     let mut i = 0;
     for f in fields { if f.name == name { return i; } i += 1; }
     tcx.sess.bug(&format!(
@@ -4767,11 +4911,11 @@ pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field])
         token::get_name(name),
         fields.iter()
               .map(|f| token::get_name(f.name).to_string())
-              .collect::<Vec<String>>())[]);
+              .collect::<Vec<String>>()));
 }
 
 pub fn impl_or_trait_item_idx(id: ast::Name, trait_items: &[ImplOrTraitItem])
-                              -> Option<uint> {
+                              -> Option<usize> {
     trait_items.iter().position(|m| m.name() == id)
 }
 
@@ -4813,7 +4957,6 @@ pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String {
             }
         }
         ty_err => "type error".to_string(),
-        ty_open(_) => "opened DST".to_string(),
     }
 }
 
@@ -4995,39 +5138,23 @@ pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option<ast::DefId> {
 pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
                                     -> Vec<Rc<Method<'tcx>>> {
     if is_local(id) {
-        match cx.map.find(id.node) {
-            Some(ast_map::NodeItem(item)) => {
-                match item.node {
-                    ItemTrait(_, _, _, ref ms) => {
-                        let (_, p) =
-                            ast_util::split_trait_methods(&ms[..]);
-                        p.iter()
-                         .map(|m| {
-                            match impl_or_trait_item(
-                                    cx,
-                                    ast_util::local_def(m.id)) {
-                                MethodTraitItem(m) => m,
-                                TypeTraitItem(_) => {
-                                    cx.sess.bug("provided_trait_methods(): \
-                                                 split_trait_methods() put \
-                                                 associated types in the \
-                                                 provided method bucket?!")
-                                }
-                            }
-                         }).collect()
-                    }
-                    _ => {
-                        cx.sess.bug(&format!("provided_trait_methods: `{:?}` is \
-                                             not a trait",
-                                            id)[])
+        if let ItemTrait(_, _, _, ref ms) = cx.map.expect_item(id.node).node {
+            ms.iter().filter_map(|ti| {
+                if let ast::MethodTraitItem(_, Some(_)) = ti.node {
+                    match impl_or_trait_item(cx, ast_util::local_def(ti.id)) {
+                        MethodTraitItem(m) => Some(m),
+                        TypeTraitItem(_) => {
+                            cx.sess.bug("provided_trait_methods(): \
+                                         associated type found from \
+                                         looking up ProvidedMethod?!")
+                        }
                     }
+                } else {
+                    None
                 }
-            }
-            _ => {
-                cx.sess.bug(&format!("provided_trait_methods: `{:?}` is not a \
-                                     trait",
-                                    id)[])
-            }
+            }).collect()
+        } else {
+            cx.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id))
         }
     } else {
         csearch::get_provided_trait_methods(cx, id)
@@ -5060,7 +5187,7 @@ fn lookup_locally_or_in_crate_store<V, F>(descr: &str,
     v
 }
 
-pub fn trait_item<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId, idx: uint)
+pub fn trait_item<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId, idx: usize)
                         -> ImplOrTraitItem<'tcx> {
     let method_def_id = (*ty::trait_item_def_ids(cx, trait_did))[idx].def_id();
     impl_or_trait_item(cx, method_def_id)
@@ -5135,10 +5262,10 @@ pub fn is_associated_type(cx: &ctxt, id: ast::DefId) -> bool {
 pub fn associated_type_parameter_index(cx: &ctxt,
                                        trait_def: &TraitDef,
                                        associated_type_id: ast::DefId)
-                                       -> uint {
+                                       -> usize {
     for type_parameter_def in trait_def.generics.types.iter() {
         if type_parameter_def.def_id == associated_type_id {
-            return type_parameter_def.index as uint
+            return type_parameter_def.index as usize
         }
     }
     cx.sess.bug("couldn't find associated type parameter index")
@@ -5159,22 +5286,16 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
     memoized(&cx.impl_trait_cache, id, |id: ast::DefId| {
         if id.krate == ast::LOCAL_CRATE {
             debug!("(impl_trait_ref) searching for trait impl {:?}", id);
-            match cx.map.find(id.node) {
-                Some(ast_map::NodeItem(item)) => {
-                    match item.node {
-                        ast::ItemImpl(_, _, _, ref opt_trait, _, _) => {
-                            match opt_trait {
-                                &Some(ref t) => {
-                                    let trait_ref = ty::node_id_to_trait_ref(cx, t.ref_id);
-                                    Some(trait_ref)
-                                }
-                                &None => None
-                            }
-                        }
-                        _ => None
+            if let Some(ast_map::NodeItem(item)) = cx.map.find(id.node) {
+                match item.node {
+                    ast::ItemImpl(_, _, _, Some(_), _, _) |
+                    ast::ItemDefaultImpl(..) => {
+                        Some(ty::impl_id_to_trait_ref(cx, id.node))
                     }
+                    _ => None
                 }
-                _ => None
+            } else {
+                None
             }
         } else {
             csearch::get_impl_trait(cx, id)
@@ -5183,10 +5304,7 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
 }
 
 pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId {
-    let def = *tcx.def_map.borrow()
-                     .get(&tr.ref_id)
-                     .expect("no def-map entry for trait");
-    def.def_id()
+    tcx.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
 }
 
 pub fn try_add_builtin_trait(
@@ -5212,7 +5330,7 @@ pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> {
             Some(tt.principal_def_id()),
         ty_struct(id, _) |
         ty_enum(id, _) |
-        ty_closure(id, _, _) =>
+        ty_closure(id, _) =>
             Some(id),
         _ =>
             None
@@ -5262,7 +5380,7 @@ impl<'tcx> VariantInfo<'tcx> {
                 };
             },
             ast::StructVariantKind(ref struct_def) => {
-                let fields: &[StructField] = &struct_def.fields[];
+                let fields: &[StructField] = &struct_def.fields;
 
                 assert!(fields.len() > 0);
 
@@ -5312,7 +5430,7 @@ pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> String {
     with_path(cx, id, |path| ast_map::path_to_string(path)).to_string()
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum DtorKind {
     NoDtor,
     TraitDtor(DefId, bool)
@@ -5357,7 +5475,7 @@ pub fn with_path<T, F>(cx: &ctxt, id: ast::DefId, f: F) -> T where
     if id.krate == ast::LOCAL_CRATE {
         cx.map.with_path(id.node, f)
     } else {
-        f(csearch::get_item_path(cx, id).iter().cloned().chain(None))
+        f(csearch::get_item_path(cx, id).iter().cloned().chain(LinkedPath::empty()))
     }
 }
 
@@ -5372,54 +5490,268 @@ pub fn type_is_empty(cx: &ctxt, ty: Ty) -> bool {
      }
 }
 
+trait IntTypeExt {
+    fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx>;
+    fn i64_to_disr(&self, val: i64) -> Option<Disr>;
+    fn u64_to_disr(&self, val: u64) -> Option<Disr>;
+    fn disr_incr(&self, val: Disr) -> Option<Disr>;
+    fn disr_string(&self, val: Disr) -> String;
+    fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr;
+}
+
+impl IntTypeExt for attr::IntType {
+    fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> {
+        match *self {
+            SignedInt(ast::TyI8)      => cx.types.i8,
+            SignedInt(ast::TyI16)     => cx.types.i16,
+            SignedInt(ast::TyI32)     => cx.types.i32,
+            SignedInt(ast::TyI64)     => cx.types.i64,
+            SignedInt(ast::TyIs)   => cx.types.isize,
+            UnsignedInt(ast::TyU8)    => cx.types.u8,
+            UnsignedInt(ast::TyU16)   => cx.types.u16,
+            UnsignedInt(ast::TyU32)   => cx.types.u32,
+            UnsignedInt(ast::TyU64)   => cx.types.u64,
+            UnsignedInt(ast::TyUs) => cx.types.usize,
+        }
+    }
+
+    fn i64_to_disr(&self, val: i64) -> Option<Disr> {
+        match *self {
+            SignedInt(ast::TyI8)    => val.to_i8()  .map(|v| v as Disr),
+            SignedInt(ast::TyI16)   => val.to_i16() .map(|v| v as Disr),
+            SignedInt(ast::TyI32)   => val.to_i32() .map(|v| v as Disr),
+            SignedInt(ast::TyI64)   => val.to_i64() .map(|v| v as Disr),
+            UnsignedInt(ast::TyU8)  => val.to_u8()  .map(|v| v as Disr),
+            UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr),
+            UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr),
+            UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr),
+
+            UnsignedInt(ast::TyUs) |
+            SignedInt(ast::TyIs) => unreachable!(),
+        }
+    }
+
+    fn u64_to_disr(&self, val: u64) -> Option<Disr> {
+        match *self {
+            SignedInt(ast::TyI8)    => val.to_i8()  .map(|v| v as Disr),
+            SignedInt(ast::TyI16)   => val.to_i16() .map(|v| v as Disr),
+            SignedInt(ast::TyI32)   => val.to_i32() .map(|v| v as Disr),
+            SignedInt(ast::TyI64)   => val.to_i64() .map(|v| v as Disr),
+            UnsignedInt(ast::TyU8)  => val.to_u8()  .map(|v| v as Disr),
+            UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr),
+            UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr),
+            UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr),
+
+            UnsignedInt(ast::TyUs) |
+            SignedInt(ast::TyIs) => unreachable!(),
+        }
+    }
+
+    fn disr_incr(&self, val: Disr) -> Option<Disr> {
+        macro_rules! add1 {
+            ($e:expr) => { $e.and_then(|v|v.checked_add(1)).map(|v| v as Disr) }
+        }
+        match *self {
+            // SignedInt repr means we *want* to reinterpret the bits
+            // treating the highest bit of Disr as a sign-bit, so
+            // cast to i64 before range-checking.
+            SignedInt(ast::TyI8)    => add1!((val as i64).to_i8()),
+            SignedInt(ast::TyI16)   => add1!((val as i64).to_i16()),
+            SignedInt(ast::TyI32)   => add1!((val as i64).to_i32()),
+            SignedInt(ast::TyI64)   => add1!(Some(val as i64)),
+
+            UnsignedInt(ast::TyU8)  => add1!(val.to_u8()),
+            UnsignedInt(ast::TyU16) => add1!(val.to_u16()),
+            UnsignedInt(ast::TyU32) => add1!(val.to_u32()),
+            UnsignedInt(ast::TyU64) => add1!(Some(val)),
+
+            UnsignedInt(ast::TyUs) |
+            SignedInt(ast::TyIs) => unreachable!(),
+        }
+    }
+
+    // This returns a String because (1.) it is only used for
+    // rendering an error message and (2.) a string can represent the
+    // full range from `i64::MIN` through `u64::MAX`.
+    fn disr_string(&self, val: Disr) -> String {
+        match *self {
+            SignedInt(ast::TyI8)    => format!("{}", val as i8 ),
+            SignedInt(ast::TyI16)   => format!("{}", val as i16),
+            SignedInt(ast::TyI32)   => format!("{}", val as i32),
+            SignedInt(ast::TyI64)   => format!("{}", val as i64),
+            UnsignedInt(ast::TyU8)  => format!("{}", val as u8 ),
+            UnsignedInt(ast::TyU16) => format!("{}", val as u16),
+            UnsignedInt(ast::TyU32) => format!("{}", val as u32),
+            UnsignedInt(ast::TyU64) => format!("{}", val as u64),
+
+            UnsignedInt(ast::TyUs) |
+            SignedInt(ast::TyIs) => unreachable!(),
+        }
+    }
+
+    fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr {
+        macro_rules! add1 {
+            ($e:expr) => { ($e).wrapping_add(1) as Disr }
+        }
+        let val = val.unwrap_or(ty::INITIAL_DISCRIMINANT_VALUE);
+        match *self {
+            SignedInt(ast::TyI8)    => add1!(val as i8 ),
+            SignedInt(ast::TyI16)   => add1!(val as i16),
+            SignedInt(ast::TyI32)   => add1!(val as i32),
+            SignedInt(ast::TyI64)   => add1!(val as i64),
+            UnsignedInt(ast::TyU8)  => add1!(val as u8 ),
+            UnsignedInt(ast::TyU16) => add1!(val as u16),
+            UnsignedInt(ast::TyU32) => add1!(val as u32),
+            UnsignedInt(ast::TyU64) => add1!(val as u64),
+
+            UnsignedInt(ast::TyUs) |
+            SignedInt(ast::TyIs) => unreachable!(),
+        }
+    }
+}
+
+/// Returns `(normalized_type, ty)`, where `normalized_type` is the
+/// IntType representation of one of {i64,i32,i16,i8,u64,u32,u16,u8},
+/// and `ty` is the original type (i.e. may include `isize` or
+/// `usize`).
+pub fn enum_repr_type<'tcx>(cx: &ctxt<'tcx>,
+                            opt_hint: Option<&attr::ReprAttr>)
+                            -> (attr::IntType, Ty<'tcx>)
+{
+    let repr_type = match opt_hint {
+        // Feed in the given type
+        Some(&attr::ReprInt(_, int_t)) => int_t,
+        // ... but provide sensible default if none provided
+        //
+        // NB. Historically `fn enum_variants` generate i64 here, while
+        // rustc_typeck::check would generate isize.
+        _ => SignedInt(ast::TyIs),
+    };
+
+    let repr_type_ty = repr_type.to_ty(cx);
+    let repr_type = match repr_type {
+        SignedInt(ast::TyIs) =>
+            SignedInt(cx.sess.target.int_type),
+        UnsignedInt(ast::TyUs) =>
+            UnsignedInt(cx.sess.target.uint_type),
+        other => other
+    };
+
+    (repr_type, repr_type_ty)
+}
+
+fn report_discrim_overflow(cx: &ctxt,
+                           variant_span: Span,
+                           variant_name: &str,
+                           repr_type: attr::IntType,
+                           prev_val: Disr) {
+    let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
+    let computed_value = repr_type.disr_string(computed_value);
+    let prev_val = repr_type.disr_string(prev_val);
+    let repr_type = repr_type.to_ty(cx).user_string(cx);
+    span_err!(cx.sess, variant_span, E0370,
+              "enum discriminant overflowed on value after {}: {}; \
+               set explicitly via {} = {} if that is desired outcome",
+              prev_val, repr_type, variant_name, computed_value);
+}
+
+// This computes the discriminant values for the sequence of Variants
+// attached to a particular enum, taking into account the #[repr] (if
+// any) provided via the `opt_hint`.
+fn compute_enum_variants<'tcx>(cx: &ctxt<'tcx>,
+                               vs: &'tcx [P<ast::Variant>],
+                               opt_hint: Option<&attr::ReprAttr>)
+                               -> Vec<Rc<ty::VariantInfo<'tcx>>> {
+    let mut variants: Vec<Rc<ty::VariantInfo>> = Vec::new();
+    let mut prev_disr_val: Option<ty::Disr> = None;
+
+    let (repr_type, repr_type_ty) = ty::enum_repr_type(cx, opt_hint);
+
+    for v in vs {
+        // If the discriminant value is specified explicitly in the
+        // enum, check whether the initialization expression is valid,
+        // otherwise use the last value plus one.
+        let current_disr_val;
+
+        // This closure marks cases where, when an error occurs during
+        // the computation, attempt to assign a (hopefully) fresh
+        // value to avoid spurious error reports downstream.
+        let attempt_fresh_value = move || -> Disr {
+            repr_type.disr_wrap_incr(prev_disr_val)
+        };
+
+        match v.node.disr_expr {
+            Some(ref e) => {
+                debug!("disr expr, checking {}", pprust::expr_to_string(&**e));
+
+                // check_expr (from check_const pass) doesn't guarantee
+                // that the expression is in a form that eval_const_expr can
+                // handle, so we may still get an internal compiler error
+                //
+                // pnkfelix: The above comment was transcribed from
+                // the version of this code taken from rustc_typeck.
+                // Presumably the implication is that we need to deal
+                // with such ICE's as they arise.
+                //
+                // Since this can be called from `ty::enum_variants`
+                // anyway, best thing is to make `eval_const_expr`
+                // more robust (on case-by-case basis).
+
+                match const_eval::eval_const_expr_partial(cx, &**e, Some(repr_type_ty)) {
+                    Ok(const_eval::const_int(val)) => current_disr_val = val as Disr,
+                    Ok(const_eval::const_uint(val)) => current_disr_val = val as Disr,
+                    Ok(_) => {
+                        span_err!(cx.sess, e.span, E0079,
+                                  "expected signed integer constant");
+                        current_disr_val = attempt_fresh_value();
+                    }
+                    Err(ref err) => {
+                        span_err!(cx.sess, err.span, E0080,
+                                  "constant evaluation error: {}",
+                                  err.description());
+                        current_disr_val = attempt_fresh_value();
+                    }
+                }
+            },
+            None => {
+                current_disr_val = match prev_disr_val {
+                    Some(prev_disr_val) => {
+                        if let Some(v) = repr_type.disr_incr(prev_disr_val) {
+                            v
+                        } else {
+                            report_discrim_overflow(cx, v.span, v.node.name.as_str(),
+                                                    repr_type, prev_disr_val);
+                            attempt_fresh_value()
+                        }
+                    }
+                    None => ty::INITIAL_DISCRIMINANT_VALUE
+                }
+            }
+        }
+
+        let variant_info = Rc::new(VariantInfo::from_ast_variant(cx, &**v, current_disr_val));
+        prev_disr_val = Some(current_disr_val);
+
+        variants.push(variant_info);
+    }
+
+    return variants;
+}
+
 pub fn enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
                            -> Rc<Vec<Rc<VariantInfo<'tcx>>>> {
     memoized(&cx.enum_var_cache, id, |id: ast::DefId| {
         if ast::LOCAL_CRATE != id.krate {
             Rc::new(csearch::get_enum_variants(cx, id))
         } else {
-            /*
-              Although both this code and check_enum_variants in typeck/check
-              call eval_const_expr, it should never get called twice for the same
-              expr, since check_enum_variants also updates the enum_var_cache
-             */
             match cx.map.get(id.node) {
                 ast_map::NodeItem(ref item) => {
                     match item.node {
                         ast::ItemEnum(ref enum_definition, _) => {
-                            let mut last_discriminant: Option<Disr> = None;
-                            Rc::new(enum_definition.variants.iter().map(|variant| {
-
-                                let mut discriminant = match last_discriminant {
-                                    Some(val) => val + 1,
-                                    None => INITIAL_DISCRIMINANT_VALUE
-                                };
-
-                                if let Some(ref e) = variant.node.disr_expr {
-                                    // Preserve all values, and prefer signed.
-                                    let ty = Some(cx.types.i64);
-                                    match const_eval::eval_const_expr_partial(cx, &**e, ty) {
-                                        Ok(const_eval::const_int(val)) => {
-                                            discriminant = val as Disr;
-                                        }
-                                        Ok(const_eval::const_uint(val)) => {
-                                            discriminant = val as Disr;
-                                        }
-                                        Ok(_) => {
-                                            span_err!(cx.sess, e.span, E0304,
-                                                      "expected signed integer constant");
-                                        }
-                                        Err(err) => {
-                                            span_err!(cx.sess, e.span, E0305,
-                                                      "expected constant: {}", err);
-                                        }
-                                    }
-                                };
-
-                                last_discriminant = Some(discriminant);
-                                Rc::new(VariantInfo::from_ast_variant(cx, &**variant,
-                                                                      discriminant))
-                            }).collect())
+                            Rc::new(compute_enum_variants(
+                                cx,
+                                &enum_definition.variants,
+                                lookup_repr_hints(cx, id).get(0)))
                         }
                         _ => {
                             cx.sess.bug("enum_variants: id not bound to an enum")
@@ -5463,7 +5795,7 @@ pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
     })
 }
 
-/// Given the did of a trait, returns its full set of predicates.
+/// Given the did of an item, returns its full set of predicates.
 pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
                                 -> GenericPredicates<'tcx>
 {
@@ -5473,117 +5805,14 @@ pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
     })
 }
 
-/// Given a reference to a trait, returns the "superbounds" declared
-/// on the trait, with appropriate substitutions applied. Basically,
-/// this applies a filter to the where clauses on the trait, returning
-/// those that have the form:
-///
-///     Self : SuperTrait<...>
-///     Self : 'region
-pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>,
-                                      trait_ref: &PolyTraitRef<'tcx>)
-                                      -> Vec<ty::Predicate<'tcx>>
+/// Given the did of a trait, returns its superpredicates.
+pub fn lookup_super_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
+                                     -> GenericPredicates<'tcx>
 {
-    let trait_def = lookup_trait_def(tcx, trait_ref.def_id());
-
-    debug!("bounds_for_trait_ref(trait_def={:?}, trait_ref={:?})",
-           trait_def.repr(tcx), trait_ref.repr(tcx));
-
-    // The interaction between HRTB and supertraits is not entirely
-    // obvious. Let me walk you (and myself) through an example.
-    //
-    // Let's start with an easy case. Consider two traits:
-    //
-    //     trait Foo<'a> : Bar<'a,'a> { }
-    //     trait Bar<'b,'c> { }
-    //
-    // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
-    // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
-    // knew that `Foo<'x>` (for any 'x) then we also know that
-    // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
-    // normal substitution.
-    //
-    // In terms of why this is sound, the idea is that whenever there
-    // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
-    // holds.  So if there is an impl of `T:Foo<'a>` that applies to
-    // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
-    // `'a`.
-    //
-    // Another example to be careful of is this:
-    //
-    //     trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
-    //     trait Bar1<'b,'c> { }
-    //
-    // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
-    // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
-    // reason is similar to the previous example: any impl of
-    // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`.  So
-    // basically we would want to collapse the bound lifetimes from
-    // the input (`trait_ref`) and the supertraits.
-    //
-    // To achieve this in practice is fairly straightforward. Let's
-    // consider the more complicated scenario:
-    //
-    // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
-    //   has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
-    //   where both `'x` and `'b` would have a DB index of 1.
-    //   The substitution from the input trait-ref is therefore going to be
-    //   `'a => 'x` (where `'x` has a DB index of 1).
-    // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
-    //   early-bound parameter and `'b' is a late-bound parameter with a
-    //   DB index of 1.
-    // - If we replace `'a` with `'x` from the input, it too will have
-    //   a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
-    //   just as we wanted.
-    //
-    // There is only one catch. If we just apply the substitution `'a
-    // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
-    // adjust the DB index because we substituting into a binder (it
-    // tries to be so smart...) resulting in `for<'x> for<'b>
-    // Bar1<'x,'b>` (we have no syntax for this, so use your
-    // imagination). Basically the 'x will have DB index of 2 and 'b
-    // will have DB index of 1. Not quite what we want. So we apply
-    // the substitution to the *contents* of the trait reference,
-    // rather than the trait reference itself (put another way, the
-    // substitution code expects equal binding levels in the values
-    // from the substitution and the value being substituted into, and
-    // this trick achieves that).
-
-    // Carefully avoid the binder introduced by each trait-ref by
-    // substituting over the substs, not the trait-refs themselves,
-    // thus achieving the "collapse" described in the big comment
-    // above.
-    let trait_bounds: Vec<_> =
-        trait_def.bounds.trait_bounds
-        .iter()
-        .map(|poly_trait_ref| ty::Binder(poly_trait_ref.0.subst(tcx, trait_ref.substs())))
-        .collect();
-
-    let projection_bounds: Vec<_> =
-        trait_def.bounds.projection_bounds
-        .iter()
-        .map(|poly_proj| ty::Binder(poly_proj.0.subst(tcx, trait_ref.substs())))
-        .collect();
-
-    debug!("bounds_for_trait_ref: trait_bounds={} projection_bounds={}",
-           trait_bounds.repr(tcx),
-           projection_bounds.repr(tcx));
-
-    // The region bounds and builtin bounds do not currently introduce
-    // binders so we can just substitute in a straightforward way here.
-    let region_bounds =
-        trait_def.bounds.region_bounds.subst(tcx, trait_ref.substs());
-    let builtin_bounds =
-        trait_def.bounds.builtin_bounds.subst(tcx, trait_ref.substs());
-
-    let bounds = ty::ParamBounds {
-        trait_bounds: trait_bounds,
-        region_bounds: region_bounds,
-        builtin_bounds: builtin_bounds,
-        projection_bounds: projection_bounds,
-    };
-
-    predicates(tcx, trait_ref.self_ty(), &bounds)
+    memoized(&cx.super_predicates, did, |did: DefId| {
+        assert!(did.krate != ast::LOCAL_CRATE);
+        csearch::get_super_predicates(cx, did)
+    })
 }
 
 pub fn predicates<'tcx>(
@@ -5621,10 +5850,9 @@ pub fn predicates<'tcx>(
 
 /// Get the attributes of a definition.
 pub fn get_attrs<'tcx>(tcx: &'tcx ctxt, did: DefId)
-                       -> CowVec<'tcx, ast::Attribute> {
+                       -> Cow<'tcx, [ast::Attribute]> {
     if is_local(did) {
-        let item = tcx.map.expect_item(did.node);
-        Cow::Borrowed(&item.attrs[])
+        Cow::Borrowed(tcx.map.attrs(did.node))
     } else {
         Cow::Owned(csearch::get_item_attrs(&tcx.sess.cstore, did))
     }
@@ -5669,9 +5897,7 @@ pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>,
         node_id_to_type(tcx, id.node)
     } else {
         let mut tcache = tcx.tcache.borrow_mut();
-        let pty = tcache.entry(id).get().unwrap_or_else(
-            |vacant_entry| vacant_entry.insert(csearch::get_field_type(tcx, struct_id, id)));
-        pty.ty
+        tcache.entry(id).or_insert_with(|| csearch::get_field_type(tcx, struct_id, id)).ty
     };
     ty.subst(tcx, substs)
 }
@@ -5686,7 +5912,7 @@ pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
             _ => {
                 cx.sess.bug(
                     &format!("ID not mapped to struct fields: {}",
-                            cx.map.node_to_string(did.node))[]);
+                            cx.map.node_to_string(did.node)));
             }
         }
     } else {
@@ -5719,7 +5945,7 @@ pub fn struct_fields<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId, substs: &Substs<'tc
 pub fn tup_fields<'tcx>(v: &[Ty<'tcx>]) -> Vec<field<'tcx>> {
     v.iter().enumerate().map(|(i, &f)| {
        field {
-            name: token::intern(&i.to_string()[]),
+            name: token::intern(&i.to_string()),
             mt: mt {
                 ty: f,
                 mutbl: MutImmutable
@@ -5792,113 +6018,39 @@ pub fn closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
     }
 }
 
-pub fn is_binopable<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, op: ast::BinOp) -> bool {
-    #![allow(non_upper_case_globals)]
-    static tycat_other: int = 0;
-    static tycat_bool: int = 1;
-    static tycat_char: int = 2;
-    static tycat_int: int = 3;
-    static tycat_float: int = 4;
-    static tycat_raw_ptr: int = 6;
-
-    static opcat_add: int = 0;
-    static opcat_sub: int = 1;
-    static opcat_mult: int = 2;
-    static opcat_shift: int = 3;
-    static opcat_rel: int = 4;
-    static opcat_eq: int = 5;
-    static opcat_bit: int = 6;
-    static opcat_logic: int = 7;
-    static opcat_mod: int = 8;
-
-    fn opcat(op: ast::BinOp) -> int {
-        match op.node {
-          ast::BiAdd => opcat_add,
-          ast::BiSub => opcat_sub,
-          ast::BiMul => opcat_mult,
-          ast::BiDiv => opcat_mult,
-          ast::BiRem => opcat_mod,
-          ast::BiAnd => opcat_logic,
-          ast::BiOr => opcat_logic,
-          ast::BiBitXor => opcat_bit,
-          ast::BiBitAnd => opcat_bit,
-          ast::BiBitOr => opcat_bit,
-          ast::BiShl => opcat_shift,
-          ast::BiShr => opcat_shift,
-          ast::BiEq => opcat_eq,
-          ast::BiNe => opcat_eq,
-          ast::BiLt => opcat_rel,
-          ast::BiLe => opcat_rel,
-          ast::BiGe => opcat_rel,
-          ast::BiGt => opcat_rel
-        }
-    }
-
-    fn tycat<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> int {
-        if type_is_simd(cx, ty) {
-            return tycat(cx, simd_type(cx, ty))
-        }
-        match ty.sty {
-          ty_char => tycat_char,
-          ty_bool => tycat_bool,
-          ty_int(_) | ty_uint(_) | ty_infer(IntVar(_)) => tycat_int,
-          ty_float(_) | ty_infer(FloatVar(_)) => tycat_float,
-          ty_ptr(_) => tycat_raw_ptr,
-          _ => tycat_other
-        }
-    }
-
-    static t: bool = true;
-    static f: bool = false;
-
-    let tbl = [
-    //           +, -, *, shift, rel, ==, bit, logic, mod
-    /*other*/   [f, f, f, f,     f,   f,  f,   f,     f],
-    /*bool*/    [f, f, f, f,     t,   t,  t,   t,     f],
-    /*char*/    [f, f, f, f,     t,   t,  f,   f,     f],
-    /*int*/     [t, t, t, t,     t,   t,  t,   f,     t],
-    /*float*/   [t, t, t, f,     t,   t,  f,   f,     f],
-    /*bot*/     [t, t, t, t,     t,   t,  t,   t,     t],
-    /*raw ptr*/ [f, f, f, f,     t,   t,  f,   f,     f]];
-
-    return tbl[tycat(cx, ty) as uint ][opcat(op) as uint];
-}
-
 // Returns the repeat count for a repeating vector expression.
-pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint {
-    match const_eval::eval_const_expr_partial(tcx, count_expr, Some(tcx.types.uint)) {
+pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> usize {
+    match const_eval::eval_const_expr_partial(tcx, count_expr, Some(tcx.types.usize)) {
         Ok(val) => {
             let found = match val {
-                const_eval::const_uint(count) => return count as uint,
-                const_eval::const_int(count) if count >= 0 => return count as uint,
-                const_eval::const_int(_) =>
-                    "negative integer",
-                const_eval::const_float(_) =>
-                    "float",
-                const_eval::const_str(_) =>
-                    "string",
-                const_eval::const_bool(_) =>
-                    "boolean",
-                const_eval::const_binary(_) =>
-                    "binary array"
+                const_eval::const_uint(count) => return count as usize,
+                const_eval::const_int(count) if count >= 0 => return count as usize,
+                const_eval::const_int(_) => "negative integer",
+                const_eval::const_float(_) => "float",
+                const_eval::const_str(_) => "string",
+                const_eval::const_bool(_) => "boolean",
+                const_eval::const_binary(_) => "binary array",
+                const_eval::Struct(..) => "struct",
+                const_eval::Tuple(_) => "tuple"
             };
             span_err!(tcx.sess, count_expr.span, E0306,
                 "expected positive integer for repeat count, found {}",
                 found);
         }
-        Err(_) => {
+        Err(err) => {
+            let err_description = err.description();
             let found = match count_expr.node {
-                ast::ExprPath(ast::Path {
+                ast::ExprPath(None, ast::Path {
                     global: false,
                     ref segments,
                     ..
                 }) if segments.len() == 1 =>
-                    "variable",
+                    format!("{}", "found variable"),
                 _ =>
-                    "non-constant expression"
+                    format!("but {}", err_description),
             };
             span_err!(tcx.sess, count_expr.span, E0307,
-                "expected constant integer for repeat count, found {}",
+                "expected constant integer for repeat count, {}",
                 found);
         }
     }
@@ -5979,19 +6131,25 @@ pub fn required_region_bounds<'tcx>(tcx: &ctxt<'tcx>,
         .collect()
 }
 
-pub fn get_tydesc_ty<'tcx>(tcx: &ctxt<'tcx>) -> Result<Ty<'tcx>, String> {
-    tcx.lang_items.require(TyDescStructLangItem).map(|tydesc_lang_item| {
-        tcx.intrinsic_defs.borrow().get(&tydesc_lang_item).cloned()
-            .expect("Failed to resolve TyDesc")
-    })
-}
-
 pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
     lookup_locally_or_in_crate_store(
         "item_variance_map", item_id, &mut *tcx.item_variance_map.borrow_mut(),
         || Rc::new(csearch::get_item_variances(&tcx.sess.cstore, item_id)))
 }
 
+pub fn trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) -> bool {
+    populate_implementations_for_trait_if_necessary(tcx, trait_def_id);
+    tcx.traits_with_default_impls.borrow().contains_key(&trait_def_id)
+}
+
+/// Records a trait-to-implementation mapping.
+pub fn record_trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) {
+    // We're using the latest implementation found as the reference one.
+    // Duplicated implementations are caught and reported in the coherence
+    // step.
+    tcx.traits_with_default_impls.borrow_mut().insert(trait_def_id, ());
+}
+
 /// Records a trait-to-implementation mapping.
 pub fn record_trait_implementation(tcx: &ctxt,
                                    trait_def_id: DefId,
@@ -6008,6 +6166,25 @@ pub fn record_trait_implementation(tcx: &ctxt,
     tcx.trait_impls.borrow_mut().insert(trait_def_id, Rc::new(RefCell::new(vec!(impl_def_id))));
 }
 
+/// Load primitive inherent implementations if necessary
+pub fn populate_implementations_for_primitive_if_necessary(tcx: &ctxt, lang_def_id: ast::DefId) {
+    if lang_def_id.krate == LOCAL_CRATE {
+        return
+    }
+    if tcx.populated_external_primitive_impls.borrow().contains(&lang_def_id) {
+        return
+    }
+
+    debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}", lang_def_id);
+
+    let impl_items = csearch::get_impl_items(&tcx.sess.cstore, lang_def_id);
+
+    // Store the implementation info.
+    tcx.impl_items.borrow_mut().insert(lang_def_id, impl_items);
+
+    tcx.populated_external_primitive_impls.borrow_mut().insert(lang_def_id);
+}
+
 /// Populates the type context with all the implementations for the given type
 /// if necessary.
 pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
@@ -6022,8 +6199,7 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
     debug!("populate_implementations_for_type_if_necessary: searching for {:?}", type_id);
 
     let mut inherent_impls = Vec::new();
-    csearch::each_implementation_for_type(&tcx.sess.cstore, type_id,
-            |impl_def_id| {
+    csearch::each_implementation_for_type(&tcx.sess.cstore, type_id, |impl_def_id| {
         let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id);
 
         // Record the trait->implementation mappings, if applicable.
@@ -6069,12 +6245,16 @@ pub fn populate_implementations_for_trait_if_necessary(
     if trait_id.krate == LOCAL_CRATE {
         return
     }
+
     if tcx.populated_external_traits.borrow().contains(&trait_id) {
         return
     }
 
-    csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id,
-            |implementation_def_id| {
+    if csearch::is_defaulted_trait(&tcx.sess.cstore, trait_id) {
+        record_trait_has_default_impl(tcx, trait_id);
+    }
+
+    csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id, |implementation_def_id| {
         let impl_items = csearch::get_impl_items(&tcx.sess.cstore, implementation_def_id);
 
         // Record the trait->implementation mapping.
@@ -6088,8 +6268,8 @@ pub fn populate_implementations_for_trait_if_necessary(
                 MethodTraitItem(method) => {
                     if let Some(source) = method.provided_source {
                         tcx.provided_method_sources
-                           .borrow_mut()
-                           .insert(method_def_id, source);
+                            .borrow_mut()
+                            .insert(method_def_id, source);
                     }
                 }
                 TypeTraitItem(_) => {}
@@ -6299,16 +6479,14 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
                     hash!(p.idx);
                     hash!(token::get_name(p.name));
                 }
-                ty_open(_) => byte!(22),
                 ty_infer(_) => unreachable!(),
-                ty_err => byte!(23),
-                ty_closure(d, r, _) => {
-                    byte!(24);
+                ty_err => byte!(21),
+                ty_closure(d, _) => {
+                    byte!(22);
                     did(state, d);
-                    region(state, *r);
                 }
                 ty_projection(ref data) => {
-                    byte!(25);
+                    byte!(23);
                     did(state, data.trait_ref.def_id);
                     hash!(token::get_name(data.item_name));
                 }
@@ -6518,7 +6696,7 @@ impl<'tcx> ctxt<'tcx> {
     }
 
     pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
-        Some(self.upvar_capture_map.borrow()[upvar_id].clone())
+        Some(self.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
     }
 }
 
@@ -6619,8 +6797,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
             ty_struct(_, substs) => {
                 accum_substs(accumulator, substs);
             }
-            ty_closure(_, region, substs) => {
-                accumulator.push(*region);
+            ty_closure(_, substs) => {
                 accum_substs(accumulator, substs);
             }
             ty_bool |
@@ -6637,7 +6814,6 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
             ty_projection(_) |
             ty_param(_) |
             ty_infer(_) |
-            ty_open(_) |
             ty_err => {
             }
         }
@@ -6689,6 +6865,7 @@ impl<'tcx> AutoAdjustment<'tcx> {
     pub fn is_identity(&self) -> bool {
         match *self {
             AdjustReifyFnPointer(..) => false,
+            AdjustUnsafeFnPointer(..) => false,
             AdjustDerefRef(ref r) => r.is_identity(),
         }
     }
@@ -6717,7 +6894,7 @@ pub fn liberate_late_bound_regions<'tcx, T>(
 pub fn count_late_bound_regions<'tcx, T>(
     tcx: &ty::ctxt<'tcx>,
     value: &Binder<T>)
-    -> uint
+    -> usize
     where T : TypeFoldable<'tcx> + Repr<'tcx>
 {
     let (_, skol_map) = replace_late_bound_regions(tcx, value, |_| ty::ReStatic);
@@ -6733,6 +6910,30 @@ pub fn binds_late_bound_regions<'tcx, T>(
     count_late_bound_regions(tcx, value) > 0
 }
 
+/// Flattens two binding levels into one. So `for<'a> for<'b> Foo`
+/// becomes `for<'a,'b> Foo`.
+pub fn flatten_late_bound_regions<'tcx, T>(
+    tcx: &ty::ctxt<'tcx>,
+    bound2_value: &Binder<Binder<T>>)
+    -> Binder<T>
+    where T: TypeFoldable<'tcx> + Repr<'tcx>
+{
+    let bound0_value = bound2_value.skip_binder().skip_binder();
+    let value = ty_fold::fold_regions(tcx, bound0_value, |region, current_depth| {
+        match region {
+            ty::ReLateBound(debruijn, br) if debruijn.depth >= current_depth => {
+                // should be true if no escaping regions from bound2_value
+                assert!(debruijn.depth - current_depth <= 1);
+                ty::ReLateBound(DebruijnIndex::new(current_depth), br)
+            }
+            _ => {
+                region
+            }
+        }
+    });
+    Binder(value)
+}
+
 pub fn no_late_bound_regions<'tcx, T>(
     tcx: &ty::ctxt<'tcx>,
     value: &Binder<T>)
@@ -6763,8 +6964,8 @@ pub fn erase_late_bound_regions<'tcx, T>(
 ///
 /// The chief purpose of this function is to canonicalize regions so that two
 /// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become
-/// structurally identical.  For example, `for<'a, 'b> fn(&'a int, &'b int)` and
-/// `for<'a, 'b> fn(&'b int, &'a int)` will become identical after anonymization.
+/// structurally identical.  For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and
+/// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization.
 pub fn anonymize_late_bound_regions<'tcx, T>(
     tcx: &ctxt<'tcx>,
     sig: &Binder<T>)
@@ -6797,9 +6998,7 @@ pub fn replace_late_bound_regions<'tcx, T, F>(
         debug!("region={}", region.repr(tcx));
         match region {
             ty::ReLateBound(debruijn, br) if debruijn.depth == current_depth => {
-                let region =
-                    * map.entry(br).get().unwrap_or_else(
-                        |vacant_entry| vacant_entry.insert(mapf(br)));
+                let region = *map.entry(br).or_insert_with(|| mapf(br));
 
                 if let ty::ReLateBound(debruijn1, br) = region {
                     // If the callback returns a late-bound region,
@@ -6838,6 +7037,9 @@ impl<'tcx> Repr<'tcx> for AutoAdjustment<'tcx> {
             AdjustReifyFnPointer(def_id) => {
                 format!("AdjustReifyFnPointer({})", def_id.repr(tcx))
             }
+            AdjustUnsafeFnPointer => {
+                format!("AdjustUnsafeFnPointer")
+            }
             AdjustDerefRef(ref data) => {
                 data.repr(tcx)
             }
@@ -6851,6 +7053,7 @@ impl<'tcx> Repr<'tcx> for UnsizeKind<'tcx> {
             UnsizeLength(n) => format!("UnsizeLength({})", n),
             UnsizeStruct(ref k, n) => format!("UnsizeStruct({},{})", k.repr(tcx), n),
             UnsizeVtable(ref a, ref b) => format!("UnsizeVtable({},{})", a.repr(tcx), b.repr(tcx)),
+            UnsizeUpcast(ref a) => format!("UnsizeUpcast({})", a.repr(tcx)),
         }
     }
 }
@@ -6951,7 +7154,7 @@ pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>,
     trait_ref.substs.clone().with_method(meth_tps, meth_regions)
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum CopyImplementationError {
     FieldDoesNotImplementCopy(ast::Name),
     VariantDoesNotImplementCopy(ast::Name),
@@ -7067,6 +7270,12 @@ impl<'tcx> RegionEscape for Predicate<'tcx> {
     }
 }
 
+impl<'tcx,P:RegionEscape> RegionEscape for traits::Obligation<'tcx,P> {
+    fn has_regions_escaping_depth(&self, depth: u32) -> bool {
+        self.predicate.has_regions_escaping_depth(depth)
+    }
+}
+
 impl<'tcx> RegionEscape for TraitRef<'tcx> {
     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
         self.substs.types.iter().any(|t| t.has_regions_escaping_depth(depth)) ||
index 5e46ce08e4f7605b57fd458e383a85ad4241342e..5f77574f65ed4351692f8cc5868678bd73117b25 100644 (file)
@@ -39,6 +39,8 @@ use middle::subst::VecPerParamSpace;
 use middle::ty::{self, Ty};
 use middle::traits;
 use std::rc::Rc;
+use syntax::abi;
+use syntax::ast;
 use syntax::owned_slice::OwnedSlice;
 use util::ppaux::Repr;
 
@@ -47,7 +49,7 @@ use util::ppaux::Repr;
 
 /// The TypeFoldable trait is implemented for every type that can be folded.
 /// Basically, every type that has a corresponding method in TypeFolder.
-pub trait TypeFoldable<'tcx> {
+pub trait TypeFoldable<'tcx>: Repr<'tcx> + Clone {
     fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self;
 }
 
@@ -149,12 +151,20 @@ pub trait TypeFolder<'tcx> : Sized {
 // can easily refactor the folding into the TypeFolder trait as
 // needed.
 
-impl<'tcx> TypeFoldable<'tcx> for () {
-    fn fold_with<F:TypeFolder<'tcx>>(&self, _: &mut F) -> () {
-        ()
+macro_rules! CopyImpls {
+    ($($ty:ty),+) => {
+        $(
+            impl<'tcx> TypeFoldable<'tcx> for $ty {
+                fn fold_with<F:TypeFolder<'tcx>>(&self, _: &mut F) -> $ty {
+                    *self
+                }
+            }
+        )+
     }
 }
 
+CopyImpls! { (), ast::Unsafety, abi::Abi }
+
 impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
     fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> (T, U) {
         (self.0.fold_with(folder), self.1.fold_with(folder))
@@ -377,7 +387,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> {
             def_id: self.def_id,
             space: self.space,
             index: self.index,
-            bounds: self.bounds.fold_with(folder),
             default: self.default.fold_with(folder),
             object_lifetime_default: self.object_lifetime_default.fold_with(folder),
         }
@@ -481,6 +490,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::UnsizeKind<'tcx> {
                     },
                     self_ty.fold_with(folder))
             }
+            ty::UnsizeUpcast(t) => ty::UnsizeUpcast(t.fold_with(folder)),
         }
     }
 }
@@ -507,6 +517,15 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<
     }
 }
 
+impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableDefaultImplData<N> {
+    fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableDefaultImplData<N> {
+        traits::VtableDefaultImplData {
+            trait_def_id: self.trait_def_id,
+            nested: self.nested.fold_with(folder),
+        }
+    }
+}
+
 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
     fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableBuiltinData<N> {
         traits::VtableBuiltinData {
@@ -519,6 +538,7 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N>
     fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::Vtable<'tcx, N> {
         match *self {
             traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
+            traits::VtableDefaultImpl(ref t) => traits::VtableDefaultImpl(t.fold_with(folder)),
             traits::VtableClosure(d, ref s) => {
                 traits::VtableClosure(d, s.fold_with(folder))
             }
@@ -535,7 +555,8 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N>
 impl<'tcx> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx> {
     fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableObjectData<'tcx> {
         traits::VtableObjectData {
-            object_ty: self.object_ty.fold_with(folder)
+            object_ty: self.object_ty.fold_with(folder),
+            upcast_trait_ref: self.upcast_trait_ref.fold_with(folder),
         }
     }
 }
@@ -616,9 +637,6 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
         ty::ty_vec(typ, sz) => {
             ty::ty_vec(typ.fold_with(this), sz)
         }
-        ty::ty_open(typ) => {
-            ty::ty_open(typ.fold_with(this))
-        }
         ty::ty_enum(tid, ref substs) => {
             let substs = substs.fold_with(this);
             ty::ty_enum(tid, this.tcx().mk_substs(substs))
@@ -644,10 +662,9 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
             let substs = substs.fold_with(this);
             ty::ty_struct(did, this.tcx().mk_substs(substs))
         }
-        ty::ty_closure(did, ref region, ref substs) => {
-            let r = region.fold_with(this);
+        ty::ty_closure(did, ref substs) => {
             let s = substs.fold_with(this);
-            ty::ty_closure(did, this.tcx().mk_region(r), this.tcx().mk_substs(s))
+            ty::ty_closure(did, this.tcx().mk_substs(s))
         }
         ty::ty_projection(ref data) => {
             ty::ty_projection(data.fold_with(this))
diff --git a/src/librustc/middle/ty_match.rs b/src/librustc/middle/ty_match.rs
new file mode 100644 (file)
index 0000000..bb00fad
--- /dev/null
@@ -0,0 +1,95 @@
+// 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.
+
+use middle::ty::{self, Ty};
+use middle::ty_relate::{self, Relate, TypeRelation, RelateResult};
+use util::ppaux::Repr;
+
+/// A type "A" *matches* "B" if the fresh types in B could be
+/// substituted with values so as to make it equal to A. Matching is
+/// intended to be used only on freshened types, and it basically
+/// indicates if the non-freshened versions of A and B could have been
+/// unified.
+///
+/// It is only an approximation. If it yields false, unification would
+/// definitely fail, but a true result doesn't mean unification would
+/// succeed. This is because we don't track the "side-constraints" on
+/// type variables, nor do we track if the same freshened type appears
+/// more than once. To some extent these approximations could be
+/// fixed, given effort.
+///
+/// Like subtyping, matching is really a binary relation, so the only
+/// important thing about the result is Ok/Err. Also, matching never
+/// affects any type variables or unification state.
+pub struct Match<'a, 'tcx: 'a> {
+    tcx: &'a ty::ctxt<'tcx>
+}
+
+impl<'a, 'tcx> Match<'a, 'tcx> {
+    pub fn new(tcx: &'a ty::ctxt<'tcx>) -> Match<'a, 'tcx> {
+        Match { tcx: tcx }
+    }
+}
+
+impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Match<'a, 'tcx> {
+    fn tag(&self) -> &'static str { "Match" }
+    fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.tcx }
+    fn a_is_expected(&self) -> bool { true } // irrelevant
+
+    fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
+                                               _: ty::Variance,
+                                               a: &T,
+                                               b: &T)
+                                               -> RelateResult<'tcx, T>
+    {
+        self.relate(a, b)
+    }
+
+    fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
+        debug!("{}.regions({}, {})",
+               self.tag(),
+               a.repr(self.tcx()),
+               b.repr(self.tcx()));
+        Ok(a)
+    }
+
+    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+        debug!("{}.tys({}, {})", self.tag(),
+               a.repr(self.tcx()), b.repr(self.tcx()));
+        if a == b { return Ok(a); }
+
+        match (&a.sty, &b.sty) {
+            (_, &ty::ty_infer(ty::FreshTy(_))) |
+            (_, &ty::ty_infer(ty::FreshIntTy(_))) => {
+                Ok(a)
+            }
+
+            (&ty::ty_infer(_), _) |
+            (_, &ty::ty_infer(_)) => {
+                Err(ty::terr_sorts(ty_relate::expected_found(self, &a, &b)))
+            }
+
+            (&ty::ty_err, _) | (_, &ty::ty_err) => {
+                Ok(self.tcx().types.err)
+            }
+
+            _ => {
+                ty_relate::super_relate_tys(self, a, b)
+            }
+        }
+    }
+
+    fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
+                  -> RelateResult<'tcx, ty::Binder<T>>
+        where T: Relate<'a,'tcx>
+    {
+        Ok(ty::Binder(try!(self.relate(a.skip_binder(), b.skip_binder()))))
+    }
+}
diff --git a/src/librustc/middle/ty_relate/mod.rs b/src/librustc/middle/ty_relate/mod.rs
new file mode 100644 (file)
index 0000000..1205b7d
--- /dev/null
@@ -0,0 +1,655 @@
+// Copyright 2012-2013 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.
+
+//! Generalized type relating mechanism. A type relation R relates a
+//! pair of values (A, B). A and B are usually types or regions but
+//! can be other things. Examples of type relations are subtyping,
+//! type equality, etc.
+
+use middle::subst::{ErasedRegions, NonerasedRegions, ParamSpace, Substs};
+use middle::ty::{self, Ty};
+use middle::ty_fold::TypeFoldable;
+use std::rc::Rc;
+use syntax::abi;
+use syntax::ast;
+use util::ppaux::Repr;
+
+pub type RelateResult<'tcx, T> = Result<T, ty::type_err<'tcx>>;
+
+pub trait TypeRelation<'a,'tcx> : Sized {
+    fn tcx(&self) -> &'a ty::ctxt<'tcx>;
+
+    /// Returns a static string we can use for printouts.
+    fn tag(&self) -> &'static str;
+
+    /// Returns true if the value `a` is the "expected" type in the
+    /// relation. Just affects error messages.
+    fn a_is_expected(&self) -> bool;
+
+    /// Generic relation routine suitable for most anything.
+    fn relate<T:Relate<'a,'tcx>>(&mut self, a: &T, b: &T) -> RelateResult<'tcx, T> {
+        Relate::relate(self, a, b)
+    }
+
+    /// Switch variance for the purpose of relating `a` and `b`.
+    fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
+                                               variance: ty::Variance,
+                                               a: &T,
+                                               b: &T)
+                                               -> RelateResult<'tcx, T>;
+
+    // Overrideable relations. You shouldn't typically call these
+    // directly, instead call `relate()`, which in turn calls
+    // these. This is both more uniform but also allows us to add
+    // additional hooks for other types in the future if needed
+    // without making older code, which called `relate`, obsolete.
+
+    fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>)
+           -> RelateResult<'tcx, Ty<'tcx>>;
+
+    fn regions(&mut self, a: ty::Region, b: ty::Region)
+               -> RelateResult<'tcx, ty::Region>;
+
+    fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
+                  -> RelateResult<'tcx, ty::Binder<T>>
+        where T: Relate<'a,'tcx>;
+}
+
+pub trait Relate<'a,'tcx>: TypeFoldable<'tcx> {
+    fn relate<R:TypeRelation<'a,'tcx>>(relation: &mut R,
+                                       a: &Self,
+                                       b: &Self)
+                                       -> RelateResult<'tcx, Self>;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Relate impls
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::mt<'tcx> {
+    fn relate<R>(relation: &mut R,
+                 a: &ty::mt<'tcx>,
+                 b: &ty::mt<'tcx>)
+                 -> RelateResult<'tcx, ty::mt<'tcx>>
+        where R: TypeRelation<'a,'tcx>
+    {
+        debug!("{}.mts({}, {})",
+               relation.tag(),
+               a.repr(relation.tcx()),
+               b.repr(relation.tcx()));
+        if a.mutbl != b.mutbl {
+            Err(ty::terr_mutability)
+        } else {
+            let mutbl = a.mutbl;
+            let variance = match mutbl {
+                ast::MutImmutable => ty::Covariant,
+                ast::MutMutable => ty::Invariant,
+            };
+            let ty = try!(relation.relate_with_variance(variance, &a.ty, &b.ty));
+            Ok(ty::mt {ty: ty, mutbl: mutbl})
+        }
+    }
+}
+
+// substitutions are not themselves relatable without more context,
+// but they is an important subroutine for things that ARE relatable,
+// like traits etc.
+fn relate_item_substs<'a,'tcx:'a,R>(relation: &mut R,
+                                    item_def_id: ast::DefId,
+                                    a_subst: &Substs<'tcx>,
+                                    b_subst: &Substs<'tcx>)
+                                    -> RelateResult<'tcx, Substs<'tcx>>
+    where R: TypeRelation<'a,'tcx>
+{
+    debug!("substs: item_def_id={} a_subst={} b_subst={}",
+           item_def_id.repr(relation.tcx()),
+           a_subst.repr(relation.tcx()),
+           b_subst.repr(relation.tcx()));
+
+    let variances;
+    let opt_variances = if relation.tcx().variance_computed.get() {
+        variances = ty::item_variances(relation.tcx(), item_def_id);
+        Some(&*variances)
+    } else {
+        None
+    };
+    relate_substs(relation, opt_variances, a_subst, b_subst)
+}
+
+fn relate_substs<'a,'tcx,R>(relation: &mut R,
+                            variances: Option<&ty::ItemVariances>,
+                            a_subst: &Substs<'tcx>,
+                            b_subst: &Substs<'tcx>)
+                            -> RelateResult<'tcx, Substs<'tcx>>
+    where R: TypeRelation<'a,'tcx>
+{
+    let mut substs = Substs::empty();
+
+    for &space in &ParamSpace::all() {
+        let a_tps = a_subst.types.get_slice(space);
+        let b_tps = b_subst.types.get_slice(space);
+        let t_variances = variances.map(|v| v.types.get_slice(space));
+        let tps = try!(relate_type_params(relation, t_variances, a_tps, b_tps));
+        substs.types.replace(space, tps);
+    }
+
+    match (&a_subst.regions, &b_subst.regions) {
+        (&ErasedRegions, _) | (_, &ErasedRegions) => {
+            substs.regions = ErasedRegions;
+        }
+
+        (&NonerasedRegions(ref a), &NonerasedRegions(ref b)) => {
+            for &space in &ParamSpace::all() {
+                let a_regions = a.get_slice(space);
+                let b_regions = b.get_slice(space);
+                let r_variances = variances.map(|v| v.regions.get_slice(space));
+                let regions = try!(relate_region_params(relation,
+                                                        r_variances,
+                                                        a_regions,
+                                                        b_regions));
+                substs.mut_regions().replace(space, regions);
+            }
+        }
+    }
+
+    Ok(substs)
+}
+
+fn relate_type_params<'a,'tcx,R>(relation: &mut R,
+                                 variances: Option<&[ty::Variance]>,
+                                 a_tys: &[Ty<'tcx>],
+                                 b_tys: &[Ty<'tcx>])
+                                 -> RelateResult<'tcx, Vec<Ty<'tcx>>>
+    where R: TypeRelation<'a,'tcx>
+{
+    if a_tys.len() != b_tys.len() {
+        return Err(ty::terr_ty_param_size(expected_found(relation,
+                                                         &a_tys.len(),
+                                                         &b_tys.len())));
+    }
+
+    (0 .. a_tys.len())
+        .map(|i| {
+            let a_ty = a_tys[i];
+            let b_ty = b_tys[i];
+            let v = variances.map_or(ty::Invariant, |v| v[i]);
+            relation.relate_with_variance(v, &a_ty, &b_ty)
+        })
+        .collect()
+}
+
+fn relate_region_params<'a,'tcx:'a,R>(relation: &mut R,
+                                      variances: Option<&[ty::Variance]>,
+                                      a_rs: &[ty::Region],
+                                      b_rs: &[ty::Region])
+                                      -> RelateResult<'tcx, Vec<ty::Region>>
+    where R: TypeRelation<'a,'tcx>
+{
+    let tcx = relation.tcx();
+    let num_region_params = a_rs.len();
+
+    debug!("relate_region_params(a_rs={}, \
+            b_rs={}, variances={})",
+           a_rs.repr(tcx),
+           b_rs.repr(tcx),
+           variances.repr(tcx));
+
+    assert_eq!(num_region_params,
+               variances.map_or(num_region_params,
+                                |v| v.len()));
+
+    assert_eq!(num_region_params, b_rs.len());
+
+    (0..a_rs.len())
+        .map(|i| {
+            let a_r = a_rs[i];
+            let b_r = b_rs[i];
+            let variance = variances.map_or(ty::Invariant, |v| v[i]);
+            relation.relate_with_variance(variance, &a_r, &b_r)
+        })
+        .collect()
+}
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::BareFnTy<'tcx> {
+    fn relate<R>(relation: &mut R,
+                 a: &ty::BareFnTy<'tcx>,
+                 b: &ty::BareFnTy<'tcx>)
+                 -> RelateResult<'tcx, ty::BareFnTy<'tcx>>
+        where R: TypeRelation<'a,'tcx>
+    {
+        let unsafety = try!(relation.relate(&a.unsafety, &b.unsafety));
+        let abi = try!(relation.relate(&a.abi, &b.abi));
+        let sig = try!(relation.relate(&a.sig, &b.sig));
+        Ok(ty::BareFnTy {unsafety: unsafety,
+                         abi: abi,
+                         sig: sig})
+    }
+}
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::FnSig<'tcx> {
+    fn relate<R>(relation: &mut R,
+                 a: &ty::FnSig<'tcx>,
+                 b: &ty::FnSig<'tcx>)
+                 -> RelateResult<'tcx, ty::FnSig<'tcx>>
+        where R: TypeRelation<'a,'tcx>
+    {
+        if a.variadic != b.variadic {
+            return Err(ty::terr_variadic_mismatch(
+                expected_found(relation, &a.variadic, &b.variadic)));
+        }
+
+        let inputs = try!(relate_arg_vecs(relation,
+                                          &a.inputs,
+                                          &b.inputs));
+
+        let output = try!(match (a.output, b.output) {
+            (ty::FnConverging(a_ty), ty::FnConverging(b_ty)) =>
+                Ok(ty::FnConverging(try!(relation.relate(&a_ty, &b_ty)))),
+            (ty::FnDiverging, ty::FnDiverging) =>
+                Ok(ty::FnDiverging),
+            (a, b) =>
+                Err(ty::terr_convergence_mismatch(
+                    expected_found(relation, &(a != ty::FnDiverging), &(b != ty::FnDiverging)))),
+        });
+
+        return Ok(ty::FnSig {inputs: inputs,
+                             output: output,
+                             variadic: a.variadic});
+    }
+}
+
+fn relate_arg_vecs<'a,'tcx,R>(relation: &mut R,
+                              a_args: &[Ty<'tcx>],
+                              b_args: &[Ty<'tcx>])
+                              -> RelateResult<'tcx, Vec<Ty<'tcx>>>
+    where R: TypeRelation<'a,'tcx>
+{
+    if a_args.len() != b_args.len() {
+        return Err(ty::terr_arg_count);
+    }
+
+    a_args.iter()
+          .zip(b_args.iter())
+          .map(|(a, b)| relation.relate_with_variance(ty::Contravariant, a, b))
+          .collect()
+}
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for ast::Unsafety {
+    fn relate<R>(relation: &mut R,
+                 a: &ast::Unsafety,
+                 b: &ast::Unsafety)
+                 -> RelateResult<'tcx, ast::Unsafety>
+        where R: TypeRelation<'a,'tcx>
+    {
+        if a != b {
+            Err(ty::terr_unsafety_mismatch(expected_found(relation, a, b)))
+        } else {
+            Ok(*a)
+        }
+    }
+}
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for abi::Abi {
+    fn relate<R>(relation: &mut R,
+                 a: &abi::Abi,
+                 b: &abi::Abi)
+                 -> RelateResult<'tcx, abi::Abi>
+        where R: TypeRelation<'a,'tcx>
+    {
+        if a == b {
+            Ok(*a)
+        } else {
+            Err(ty::terr_abi_mismatch(expected_found(relation, a, b)))
+        }
+    }
+}
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::ProjectionTy<'tcx> {
+    fn relate<R>(relation: &mut R,
+                 a: &ty::ProjectionTy<'tcx>,
+                 b: &ty::ProjectionTy<'tcx>)
+                 -> RelateResult<'tcx, ty::ProjectionTy<'tcx>>
+        where R: TypeRelation<'a,'tcx>
+    {
+        if a.item_name != b.item_name {
+            Err(ty::terr_projection_name_mismatched(
+                expected_found(relation, &a.item_name, &b.item_name)))
+        } else {
+            let trait_ref = try!(relation.relate(&*a.trait_ref, &*b.trait_ref));
+            Ok(ty::ProjectionTy { trait_ref: Rc::new(trait_ref), item_name: a.item_name })
+        }
+    }
+}
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::ProjectionPredicate<'tcx> {
+    fn relate<R>(relation: &mut R,
+                 a: &ty::ProjectionPredicate<'tcx>,
+                 b: &ty::ProjectionPredicate<'tcx>)
+                 -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>>
+        where R: TypeRelation<'a,'tcx>
+    {
+        let projection_ty = try!(relation.relate(&a.projection_ty, &b.projection_ty));
+        let ty = try!(relation.relate(&a.ty, &b.ty));
+        Ok(ty::ProjectionPredicate { projection_ty: projection_ty, ty: ty })
+    }
+}
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for Vec<ty::PolyProjectionPredicate<'tcx>> {
+    fn relate<R>(relation: &mut R,
+                 a: &Vec<ty::PolyProjectionPredicate<'tcx>>,
+                 b: &Vec<ty::PolyProjectionPredicate<'tcx>>)
+                 -> RelateResult<'tcx, Vec<ty::PolyProjectionPredicate<'tcx>>>
+        where R: TypeRelation<'a,'tcx>
+    {
+        // To be compatible, `a` and `b` must be for precisely the
+        // same set of traits and item names. We always require that
+        // projection bounds lists are sorted by trait-def-id and item-name,
+        // so we can just iterate through the lists pairwise, so long as they are the
+        // same length.
+        if a.len() != b.len() {
+            Err(ty::terr_projection_bounds_length(expected_found(relation, &a.len(), &b.len())))
+        } else {
+            a.iter()
+                .zip(b.iter())
+                .map(|(a, b)| relation.relate(a, b))
+                .collect()
+        }
+    }
+}
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::ExistentialBounds<'tcx> {
+    fn relate<R>(relation: &mut R,
+                 a: &ty::ExistentialBounds<'tcx>,
+                 b: &ty::ExistentialBounds<'tcx>)
+                 -> RelateResult<'tcx, ty::ExistentialBounds<'tcx>>
+        where R: TypeRelation<'a,'tcx>
+    {
+        let r = try!(relation.relate_with_variance(ty::Contravariant,
+                                                   &a.region_bound,
+                                                   &b.region_bound));
+        let nb = try!(relation.relate(&a.builtin_bounds, &b.builtin_bounds));
+        let pb = try!(relation.relate(&a.projection_bounds, &b.projection_bounds));
+        Ok(ty::ExistentialBounds { region_bound: r,
+                                   builtin_bounds: nb,
+                                   projection_bounds: pb })
+    }
+}
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::BuiltinBounds {
+    fn relate<R>(relation: &mut R,
+                 a: &ty::BuiltinBounds,
+                 b: &ty::BuiltinBounds)
+                 -> RelateResult<'tcx, ty::BuiltinBounds>
+        where R: TypeRelation<'a,'tcx>
+    {
+        // Two sets of builtin bounds are only relatable if they are
+        // precisely the same (but see the coercion code).
+        if a != b {
+            Err(ty::terr_builtin_bounds(expected_found(relation, a, b)))
+        } else {
+            Ok(*a)
+        }
+    }
+}
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::TraitRef<'tcx> {
+    fn relate<R>(relation: &mut R,
+                 a: &ty::TraitRef<'tcx>,
+                 b: &ty::TraitRef<'tcx>)
+                 -> RelateResult<'tcx, ty::TraitRef<'tcx>>
+        where R: TypeRelation<'a,'tcx>
+    {
+        // Different traits cannot be related
+        if a.def_id != b.def_id {
+            Err(ty::terr_traits(expected_found(relation, &a.def_id, &b.def_id)))
+        } else {
+            let substs = try!(relate_item_substs(relation, a.def_id, a.substs, b.substs));
+            Ok(ty::TraitRef { def_id: a.def_id, substs: relation.tcx().mk_substs(substs) })
+        }
+    }
+}
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for Ty<'tcx> {
+    fn relate<R>(relation: &mut R,
+                 a: &Ty<'tcx>,
+                 b: &Ty<'tcx>)
+                 -> RelateResult<'tcx, Ty<'tcx>>
+        where R: TypeRelation<'a,'tcx>
+    {
+        relation.tys(a, b)
+    }
+}
+
+/// The main "type relation" routine. Note that this does not handle
+/// inference artifacts, so you should filter those out before calling
+/// it.
+pub fn super_relate_tys<'a,'tcx:'a,R>(relation: &mut R,
+                                      a: Ty<'tcx>,
+                                      b: Ty<'tcx>)
+                                      -> RelateResult<'tcx, Ty<'tcx>>
+    where R: TypeRelation<'a,'tcx>
+{
+    let tcx = relation.tcx();
+    let a_sty = &a.sty;
+    let b_sty = &b.sty;
+    debug!("super_tys: a_sty={:?} b_sty={:?}", a_sty, b_sty);
+    match (a_sty, b_sty) {
+        (&ty::ty_infer(_), _) |
+        (_, &ty::ty_infer(_)) =>
+        {
+            // The caller should handle these cases!
+            tcx.sess.bug("var types encountered in super_relate_tys")
+        }
+
+        (&ty::ty_err, _) | (_, &ty::ty_err) =>
+        {
+            Ok(tcx.types.err)
+        }
+
+        (&ty::ty_char, _) |
+        (&ty::ty_bool, _) |
+        (&ty::ty_int(_), _) |
+        (&ty::ty_uint(_), _) |
+        (&ty::ty_float(_), _) |
+        (&ty::ty_str, _)
+            if a == b =>
+        {
+            Ok(a)
+        }
+
+        (&ty::ty_param(ref a_p), &ty::ty_param(ref b_p))
+            if a_p.idx == b_p.idx && a_p.space == b_p.space =>
+        {
+            Ok(a)
+        }
+
+        (&ty::ty_enum(a_id, a_substs), &ty::ty_enum(b_id, b_substs))
+            if a_id == b_id =>
+        {
+            let substs = try!(relate_item_substs(relation, a_id, a_substs, b_substs));
+            Ok(ty::mk_enum(tcx, a_id, tcx.mk_substs(substs)))
+        }
+
+        (&ty::ty_trait(ref a_), &ty::ty_trait(ref b_)) =>
+        {
+            let principal = try!(relation.relate(&a_.principal, &b_.principal));
+            let bounds = try!(relation.relate(&a_.bounds, &b_.bounds));
+            Ok(ty::mk_trait(tcx, principal, bounds))
+        }
+
+        (&ty::ty_struct(a_id, a_substs), &ty::ty_struct(b_id, b_substs))
+            if a_id == b_id =>
+        {
+            let substs = try!(relate_item_substs(relation, a_id, a_substs, b_substs));
+            Ok(ty::mk_struct(tcx, a_id, tcx.mk_substs(substs)))
+        }
+
+        (&ty::ty_closure(a_id, a_substs),
+         &ty::ty_closure(b_id, b_substs))
+            if a_id == b_id =>
+        {
+            // All ty_closure types with the same id represent
+            // the (anonymous) type of the same closure expression. So
+            // all of their regions should be equated.
+            let substs = try!(relate_substs(relation, None, a_substs, b_substs));
+            Ok(ty::mk_closure(tcx, a_id, tcx.mk_substs(substs)))
+        }
+
+        (&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) =>
+        {
+            let typ = try!(relation.relate(&a_inner, &b_inner));
+            Ok(ty::mk_uniq(tcx, typ))
+        }
+
+        (&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_mt)) =>
+        {
+            let mt = try!(relation.relate(a_mt, b_mt));
+            Ok(ty::mk_ptr(tcx, mt))
+        }
+
+        (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) =>
+        {
+            let r = try!(relation.relate_with_variance(ty::Contravariant, a_r, b_r));
+            let mt = try!(relation.relate(a_mt, b_mt));
+            Ok(ty::mk_rptr(tcx, tcx.mk_region(r), mt))
+        }
+
+        (&ty::ty_vec(a_t, Some(sz_a)), &ty::ty_vec(b_t, Some(sz_b))) =>
+        {
+            let t = try!(relation.relate(&a_t, &b_t));
+            if sz_a == sz_b {
+                Ok(ty::mk_vec(tcx, t, Some(sz_a)))
+            } else {
+                Err(ty::terr_fixed_array_size(expected_found(relation, &sz_a, &sz_b)))
+            }
+        }
+
+        (&ty::ty_vec(a_t, None), &ty::ty_vec(b_t, None)) =>
+        {
+            let t = try!(relation.relate(&a_t, &b_t));
+            Ok(ty::mk_vec(tcx, t, None))
+        }
+
+        (&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) =>
+        {
+            if as_.len() == bs.len() {
+                let ts = try!(as_.iter()
+                                 .zip(bs.iter())
+                                 .map(|(a, b)| relation.relate(a, b))
+                                 .collect::<Result<_, _>>());
+                Ok(ty::mk_tup(tcx, ts))
+            } else if as_.len() != 0 && bs.len() != 0 {
+                Err(ty::terr_tuple_size(
+                    expected_found(relation, &as_.len(), &bs.len())))
+            } else {
+                Err(ty::terr_sorts(expected_found(relation, &a, &b)))
+            }
+        }
+
+        (&ty::ty_bare_fn(a_opt_def_id, a_fty), &ty::ty_bare_fn(b_opt_def_id, b_fty))
+            if a_opt_def_id == b_opt_def_id =>
+        {
+            let fty = try!(relation.relate(a_fty, b_fty));
+            Ok(ty::mk_bare_fn(tcx, a_opt_def_id, tcx.mk_bare_fn(fty)))
+        }
+
+        (&ty::ty_projection(ref a_data), &ty::ty_projection(ref b_data)) =>
+        {
+            let projection_ty = try!(relation.relate(a_data, b_data));
+            Ok(ty::mk_projection(tcx, projection_ty.trait_ref, projection_ty.item_name))
+        }
+
+        _ =>
+        {
+            Err(ty::terr_sorts(expected_found(relation, &a, &b)))
+        }
+    }
+}
+
+impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::Region {
+    fn relate<R>(relation: &mut R,
+                 a: &ty::Region,
+                 b: &ty::Region)
+                 -> RelateResult<'tcx, ty::Region>
+        where R: TypeRelation<'a,'tcx>
+    {
+        relation.regions(*a, *b)
+    }
+}
+
+impl<'a,'tcx:'a,T> Relate<'a,'tcx> for ty::Binder<T>
+    where T: Relate<'a,'tcx>
+{
+    fn relate<R>(relation: &mut R,
+                 a: &ty::Binder<T>,
+                 b: &ty::Binder<T>)
+                 -> RelateResult<'tcx, ty::Binder<T>>
+        where R: TypeRelation<'a,'tcx>
+    {
+        relation.binders(a, b)
+    }
+}
+
+impl<'a,'tcx:'a,T> Relate<'a,'tcx> for Rc<T>
+    where T: Relate<'a,'tcx>
+{
+    fn relate<R>(relation: &mut R,
+                 a: &Rc<T>,
+                 b: &Rc<T>)
+                 -> RelateResult<'tcx, Rc<T>>
+        where R: TypeRelation<'a,'tcx>
+    {
+        let a: &T = a;
+        let b: &T = b;
+        Ok(Rc::new(try!(relation.relate(a, b))))
+    }
+}
+
+impl<'a,'tcx:'a,T> Relate<'a,'tcx> for Box<T>
+    where T: Relate<'a,'tcx>
+{
+    fn relate<R>(relation: &mut R,
+                 a: &Box<T>,
+                 b: &Box<T>)
+                 -> RelateResult<'tcx, Box<T>>
+        where R: TypeRelation<'a,'tcx>
+    {
+        let a: &T = a;
+        let b: &T = b;
+        Ok(Box::new(try!(relation.relate(a, b))))
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Error handling
+
+pub fn expected_found<'a,'tcx,R,T>(relation: &mut R,
+                                   a: &T,
+                                   b: &T)
+                                   -> ty::expected_found<T>
+    where R: TypeRelation<'a,'tcx>, T: Clone
+{
+    expected_found_bool(relation.a_is_expected(), a, b)
+}
+
+pub fn expected_found_bool<T>(a_is_expected: bool,
+                              a: &T,
+                              b: &T)
+                              -> ty::expected_found<T>
+    where T: Clone
+{
+    let a = a.clone();
+    let b = b.clone();
+    if a_is_expected {
+        ty::expected_found {expected: a, found: b}
+    } else {
+        ty::expected_found {expected: b, found: a}
+    }
+}
+
index 40dfd479364a6c18c76f960518bef48a3e87777b..ec09d6dcc1ee2c05e35f121c7b4d1e5e7af6f942 100644 (file)
 
 use middle::ty::{self, Ty};
 use std::iter::Iterator;
+use std::vec::IntoIter;
 
 pub struct TypeWalker<'tcx> {
     stack: Vec<Ty<'tcx>>,
-    last_subtree: uint,
+    last_subtree: usize,
 }
 
 impl<'tcx> TypeWalker<'tcx> {
@@ -23,71 +24,17 @@ impl<'tcx> TypeWalker<'tcx> {
         TypeWalker { stack: vec!(ty), last_subtree: 1, }
     }
 
-    fn push_subtypes(&mut self, parent_ty: Ty<'tcx>) {
-        match parent_ty.sty {
-            ty::ty_bool | ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
-            ty::ty_str | ty::ty_infer(_) | ty::ty_param(_) | ty::ty_err => {
-            }
-            ty::ty_uniq(ty) | ty::ty_vec(ty, _) | ty::ty_open(ty) => {
-                self.stack.push(ty);
-            }
-            ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => {
-                self.stack.push(mt.ty);
-            }
-            ty::ty_projection(ref data) => {
-                self.push_reversed(data.trait_ref.substs.types.as_slice());
-            }
-            ty::ty_trait(box ty::TyTrait { ref principal, ref bounds }) => {
-                self.push_reversed(principal.substs().types.as_slice());
-                self.push_reversed(&bounds.projection_bounds.iter().map(|pred| {
-                    pred.0.ty
-                }).collect::<Vec<_>>());
-            }
-            ty::ty_enum(_, ref substs) |
-            ty::ty_struct(_, ref substs) |
-            ty::ty_closure(_, _, ref substs) => {
-                self.push_reversed(substs.types.as_slice());
-            }
-            ty::ty_tup(ref ts) => {
-                self.push_reversed(ts);
-            }
-            ty::ty_bare_fn(_, ref ft) => {
-                self.push_sig_subtypes(&ft.sig);
-            }
-        }
-    }
-
-    fn push_sig_subtypes(&mut self, sig: &ty::PolyFnSig<'tcx>) {
-        match sig.0.output {
-            ty::FnConverging(output) => { self.stack.push(output); }
-            ty::FnDiverging => { }
-        }
-        self.push_reversed(&sig.0.inputs);
-    }
-
-    fn push_reversed(&mut self, tys: &[Ty<'tcx>]) {
-        // We push slices on the stack in reverse order so as to
-        // maintain a pre-order traversal. As of the time of this
-        // writing, the fact that the traversal is pre-order is not
-        // known to be significant to any code, but it seems like the
-        // natural order one would expect (basically, the order of the
-        // types as they are written).
-        for &ty in tys.iter().rev() {
-            self.stack.push(ty);
-        }
-    }
-
     /// Skips the subtree of types corresponding to the last type
     /// returned by `next()`.
     ///
-    /// Example: Imagine you are walking `Foo<Bar<int>, uint>`.
+    /// Example: Imagine you are walking `Foo<Bar<int>, usize>`.
     ///
-    /// ```rust
+    /// ```
     /// let mut iter: TypeWalker = ...;
     /// iter.next(); // yields Foo
     /// iter.next(); // yields Bar<int>
     /// iter.skip_current_subtree(); // skips int
-    /// iter.next(); // yields uint
+    /// iter.next(); // yields usize
     /// ```
     pub fn skip_current_subtree(&mut self) {
         self.stack.truncate(self.last_subtree);
@@ -105,10 +52,70 @@ impl<'tcx> Iterator for TypeWalker<'tcx> {
             }
             Some(ty) => {
                 self.last_subtree = self.stack.len();
-                self.push_subtypes(ty);
+                push_subtypes(&mut self.stack, ty);
                 debug!("next: stack={:?}", self.stack);
                 Some(ty)
             }
         }
     }
 }
+
+pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> IntoIter<Ty<'tcx>> {
+    let mut stack = vec![];
+    push_subtypes(&mut stack, ty);
+    stack.into_iter()
+}
+
+fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
+    match parent_ty.sty {
+        ty::ty_bool | ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
+        ty::ty_str | ty::ty_infer(_) | ty::ty_param(_) | ty::ty_err => {
+        }
+        ty::ty_uniq(ty) | ty::ty_vec(ty, _) => {
+            stack.push(ty);
+        }
+        ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => {
+            stack.push(mt.ty);
+        }
+        ty::ty_projection(ref data) => {
+            push_reversed(stack, data.trait_ref.substs.types.as_slice());
+        }
+        ty::ty_trait(box ty::TyTrait { ref principal, ref bounds }) => {
+            push_reversed(stack, principal.substs().types.as_slice());
+            push_reversed(stack, &bounds.projection_bounds.iter().map(|pred| {
+                pred.0.ty
+            }).collect::<Vec<_>>());
+        }
+        ty::ty_enum(_, ref substs) |
+        ty::ty_struct(_, ref substs) |
+        ty::ty_closure(_, ref substs) => {
+            push_reversed(stack, substs.types.as_slice());
+        }
+        ty::ty_tup(ref ts) => {
+            push_reversed(stack, ts);
+        }
+        ty::ty_bare_fn(_, ref ft) => {
+            push_sig_subtypes(stack, &ft.sig);
+        }
+    }
+}
+
+fn push_sig_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, sig: &ty::PolyFnSig<'tcx>) {
+    match sig.0.output {
+        ty::FnConverging(output) => { stack.push(output); }
+        ty::FnDiverging => { }
+    }
+    push_reversed(stack, &sig.0.inputs);
+}
+
+fn push_reversed<'tcx>(stack: &mut Vec<Ty<'tcx>>, tys: &[Ty<'tcx>]) {
+    // We push slices on the stack in reverse order so as to
+    // maintain a pre-order traversal. As of the time of this
+    // writing, the fact that the traversal is pre-order is not
+    // known to be significant to any code, but it seems like the
+    // natural order one would expect (basically, the order of the
+    // types as they are written).
+    for &ty in tys.iter().rev() {
+        stack.push(ty);
+    }
+}
index b3bc898748fdc00ba3637c5efde0d0bc473255cd..752e71bc19131b3dad208ac4f7a9559cf8883d6e 100644 (file)
@@ -14,10 +14,11 @@ use session::Session;
 use metadata::creader::CrateReader;
 use plugin::registry::Registry;
 
-use std::mem;
-use std::env;
-use std::dynamic_lib::DynamicLibrary;
 use std::borrow::ToOwned;
+use std::dynamic_lib::DynamicLibrary;
+use std::env;
+use std::mem;
+use std::path::PathBuf;
 use syntax::ast;
 use syntax::codemap::{Span, COMMAND_LINE_SP};
 use syntax::ptr::P;
@@ -98,9 +99,10 @@ impl<'a> PluginLoader<'a> {
     }
 
     // Dynamically link a registrar function into the compiler process.
+    #[allow(deprecated)] // until #23197
     fn dylink_registrar(&mut self,
                         span: Span,
-                        path: Path,
+                        path: PathBuf,
                         symbol: String) -> PluginRegistrarFun {
         // Make sure the path contains a / or the linker will search for it.
         let path = env::current_dir().unwrap().join(&path);
index 711ed43fe06062eec3590fa6b52ceeebeaaf398c..3162c4fc570236d75246364cea365867f97e9ed6 100644 (file)
@@ -47,7 +47,7 @@
 //! #![plugin(myplugin)]
 //! ```
 //!
-//! See [the compiler plugin guide](../../guide-plugin.html)
+//! See the [Plugins Chapter](../../book/plugins.html) of the book
 //! for more examples.
 
 pub use self::registry::Registry;
index 12634204f8b12f2bd31c02dc36d8ccf8b973c8c1..a73ed04ac0a41b974cbe7133ef06e4fb07f5fe97 100644 (file)
@@ -15,7 +15,7 @@ use session::Session;
 
 use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
 use syntax::ext::base::{IdentTT, Decorator, Modifier, MultiModifier, MacroRulesTT};
-use syntax::ext::base::{MacroExpanderFn};
+use syntax::ext::base::MacroExpanderFn;
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::ptr::P;
@@ -81,8 +81,12 @@ impl<'a> Registry<'a> {
     /// This is the most general hook into `libsyntax`'s expansion behavior.
     pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
         self.syntax_exts.push((name, match extension {
-            NormalTT(ext, _) => NormalTT(ext, Some(self.krate_span)),
-            IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)),
+            NormalTT(ext, _, allow_internal_unstable) => {
+                NormalTT(ext, Some(self.krate_span), allow_internal_unstable)
+            }
+            IdentTT(ext, _, allow_internal_unstable) => {
+                IdentTT(ext, Some(self.krate_span), allow_internal_unstable)
+            }
             Decorator(ext) => Decorator(ext),
             Modifier(ext) => Modifier(ext),
             MultiModifier(ext) => MultiModifier(ext),
@@ -99,7 +103,8 @@ impl<'a> Registry<'a> {
     /// It builds for you a `NormalTT` that calls `expander`,
     /// and also takes care of interning the macro's name.
     pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
-        self.register_syntax_extension(token::intern(name), NormalTT(box expander, None));
+        self.register_syntax_extension(token::intern(name),
+                                       NormalTT(Box::new(expander), None, false));
     }
 
     /// Register a compiler lint pass.
index 93a25de0491fe018ab8fef7d7e11435c80c211e4..a7d608d2c879c960df0158c2e09fe6a20f9d7d48 100644 (file)
@@ -35,9 +35,9 @@ use syntax::parse::token::InternedString;
 
 use getopts;
 use std::collections::HashMap;
-use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::env;
 use std::fmt;
+use std::path::PathBuf;
 
 use llvm;
 
@@ -80,6 +80,7 @@ pub struct Options {
 
     pub gc: bool,
     pub optimize: OptLevel,
+    pub debug_assertions: bool,
     pub debuginfo: DebugInfoLevel,
     pub lint_opts: Vec<(String, lint::Level)>,
     pub describe_lints: bool,
@@ -89,7 +90,7 @@ pub struct Options {
     // this.
     pub search_paths: SearchPaths,
     pub libs: Vec<(String, cstore::NativeLibraryKind)>,
-    pub maybe_sysroot: Option<Path>,
+    pub maybe_sysroot: Option<PathBuf>,
     pub target_triple: String,
     // User-specified cfg meta items. The compiler itself will add additional
     // items to the crate config, and during parsing the entire crate config
@@ -99,10 +100,11 @@ pub struct Options {
     pub test: bool,
     pub parse_only: bool,
     pub no_trans: bool,
+    pub treat_err_as_bug: bool,
     pub no_analysis: bool,
     pub debugging_opts: DebuggingOptions,
     /// Whether to write dependency files. It's (enabled, optional filename).
-    pub write_dependency_info: (bool, Option<Path>),
+    pub write_dependency_info: (bool, Option<PathBuf>),
     pub prints: Vec<PrintRequest>,
     pub cg: CodegenOptions,
     pub color: ColorConfig,
@@ -141,7 +143,7 @@ pub enum PrintRequest {
 
 pub enum Input {
     /// Load source from file
-    File(Path),
+    File(PathBuf),
     /// The string is the source
     Str(String)
 }
@@ -149,7 +151,8 @@ pub enum Input {
 impl Input {
     pub fn filestem(&self) -> String {
         match *self {
-            Input::File(ref ifile) => ifile.filestem_str().unwrap().to_string(),
+            Input::File(ref ifile) => ifile.file_stem().unwrap()
+                                           .to_str().unwrap().to_string(),
             Input::Str(_) => "rust_out".to_string(),
         }
     }
@@ -157,14 +160,14 @@ impl Input {
 
 #[derive(Clone)]
 pub struct OutputFilenames {
-    pub out_directory: Path,
+    pub out_directory: PathBuf,
     pub out_filestem: String,
-    pub single_output_file: Option<Path>,
+    pub single_output_file: Option<PathBuf>,
     pub extra: String,
 }
 
 impl OutputFilenames {
-    pub fn path(&self, flavor: OutputType) -> Path {
+    pub fn path(&self, flavor: OutputType) -> PathBuf {
         match self.single_output_file {
             Some(ref path) => return path.clone(),
             None => {}
@@ -172,8 +175,8 @@ impl OutputFilenames {
         self.temp_path(flavor)
     }
 
-    pub fn temp_path(&self, flavor: OutputType) -> Path {
-        let base = self.out_directory.join(self.filestem());
+    pub fn temp_path(&self, flavor: OutputType) -> PathBuf {
+        let base = self.out_directory.join(&self.filestem());
         match flavor {
             OutputTypeBitcode => base.with_extension("bc"),
             OutputTypeAssembly => base.with_extension("s"),
@@ -184,8 +187,8 @@ impl OutputFilenames {
         }
     }
 
-    pub fn with_extension(&self, extension: &str) -> Path {
-        self.out_directory.join(self.filestem()).with_extension(extension)
+    pub fn with_extension(&self, extension: &str) -> PathBuf {
+        self.out_directory.join(&self.filestem()).with_extension(extension)
     }
 
     pub fn filestem(&self) -> String {
@@ -223,6 +226,7 @@ pub fn basic_options() -> Options {
         test: false,
         parse_only: false,
         no_trans: false,
+        treat_err_as_bug: false,
         no_analysis: false,
         debugging_opts: basic_debugging_options(),
         write_dependency_info: (false, None),
@@ -234,7 +238,8 @@ pub fn basic_options() -> Options {
         crate_name: None,
         alt_std_name: None,
         libs: Vec::new(),
-        unstable_features: UnstableFeatures::Disallow
+        unstable_features: UnstableFeatures::Disallow,
+        debug_assertions: true,
     }
 }
 
@@ -242,7 +247,7 @@ pub fn basic_options() -> Options {
 // users can have their own entry
 // functions that don't start a
 // scheduler
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum EntryFnType {
     EntryMain,
     EntryStart,
@@ -257,7 +262,6 @@ pub enum CrateType {
     CrateTypeStaticlib,
 }
 
-
 #[derive(Clone)]
 pub enum Passes {
     SomePasses(Vec<String>),
@@ -300,7 +304,7 @@ macro_rules! options {
     {
         let mut op = $defaultfn();
         for option in matches.opt_strs($prefix) {
-            let mut iter = option.splitn(1, '=');
+            let mut iter = option.splitn(2, '=');
             let key = iter.next().unwrap();
             let value = iter.next();
             let option_to_lookup = key.replace("-", "_");
@@ -311,19 +315,19 @@ macro_rules! options {
                     match (value, opt_type_desc) {
                         (Some(..), None) => {
                             early_error(&format!("{} option `{}` takes no \
-                                                 value", $outputname, key)[])
+                                                 value", $outputname, key))
                         }
                         (None, Some(type_desc)) => {
                             early_error(&format!("{0} option `{1}` requires \
                                                  {2} ({3} {1}=<value>)",
                                                 $outputname, key,
-                                                type_desc, $prefix)[])
+                                                type_desc, $prefix))
                         }
                         (Some(value), Some(type_desc)) => {
                             early_error(&format!("incorrect value `{}` for {} \
                                                  option `{}` - {} was expected",
                                                  value, $outputname,
-                                                 key, type_desc)[])
+                                                 key, type_desc))
                         }
                         (None, None) => unreachable!()
                     }
@@ -333,7 +337,7 @@ macro_rules! options {
             }
             if !found {
                 early_error(&format!("unknown {} option: `{}`",
-                                    $outputname, key)[]);
+                                    $outputname, key));
             }
         }
         return op;
@@ -347,7 +351,8 @@ macro_rules! options {
     #[allow(non_upper_case_globals, dead_code)]
     mod $mod_desc {
         pub const parse_bool: Option<&'static str> = None;
-        pub const parse_opt_bool: Option<&'static str> = None;
+        pub const parse_opt_bool: Option<&'static str> =
+            Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
         pub const parse_string: Option<&'static str> = Some("a string");
         pub const parse_opt_string: Option<&'static str> = Some("a string");
         pub const parse_list: Option<&'static str> = Some("a space-separated list of strings");
@@ -378,7 +383,19 @@ macro_rules! options {
 
         fn parse_opt_bool(slot: &mut Option<bool>, v: Option<&str>) -> bool {
             match v {
-                Some(..) => false,
+                Some(s) => {
+                    match s {
+                        "n" | "no" | "off" => {
+                            *slot = Some(false);
+                        }
+                        "y" | "yes" | "on" => {
+                            *slot = Some(true);
+                        }
+                        _ => { return false; }
+                    }
+
+                    true
+                },
                 None => { *slot = Some(true); true }
             }
         }
@@ -422,14 +439,14 @@ macro_rules! options {
             }
         }
 
-        fn parse_uint(slot: &mut uint, v: Option<&str>) -> bool {
+        fn parse_uint(slot: &mut usize, v: Option<&str>) -> bool {
             match v.and_then(|s| s.parse().ok()) {
                 Some(i) => { *slot = i; true },
                 None => false
             }
         }
 
-        fn parse_opt_uint(slot: &mut Option<uint>, v: Option<&str>) -> bool {
+        fn parse_opt_uint(slot: &mut Option<usize>, v: Option<&str>) -> bool {
             match v {
                 Some(s) => { *slot = s.parse().ok(); slot.is_some() }
                 None => { *slot = None; true }
@@ -501,17 +518,19 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
          "metadata to mangle symbol names with"),
     extra_filename: String = ("".to_string(), parse_string,
          "extra data to put in each output filename"),
-    codegen_units: uint = (1, parse_uint,
+    codegen_units: usize = (1, parse_uint,
         "divide crate into N units to optimize in parallel"),
     remark: Passes = (SomePasses(Vec::new()), parse_passes,
         "print remarks for these optimization passes (space separated, or \"all\")"),
     no_stack_check: bool = (false, parse_bool,
         "disable checks for stack exhaustion (a memory-safety hazard!)"),
-    debuginfo: Option<uint> = (None, parse_opt_uint,
+    debuginfo: Option<usize> = (None, parse_opt_uint,
         "debug info emission level, 0 = no debug info, 1 = line tables only, \
          2 = full debug info with variable and type information"),
-    opt_level: Option<uint> = (None, parse_opt_uint,
+    opt_level: Option<usize> = (None, parse_opt_uint,
         "Optimize with possible levels 0-3"),
+    debug_assertions: Option<bool> = (None, parse_opt_bool,
+        "explicitly enable the cfg(debug_assertions) directive"),
 }
 
 
@@ -573,6 +592,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
           "Parse only; do not compile, assemble, or link"),
     no_trans: bool = (false, parse_bool,
           "Run all passes except translation; no output"),
+    treat_err_as_bug: bool = (false, parse_bool,
+          "Treat all errors that occur as bugs"),
     no_analysis: bool = (false, parse_bool,
           "Parse and expand the source, but run no analysis"),
     extra_plugins: Vec<String> = (Vec::new(), parse_list,
@@ -581,6 +602,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
           "Adds unstable command line options to rustc interface"),
     print_enum_sizes: bool = (false, parse_bool,
           "Print the size of enums and their variants"),
+    force_overflow_checks: Option<bool> = (None, parse_opt_bool,
+          "Force overflow checks on or off"),
+    force_dropflag_checks: Option<bool> = (None, parse_opt_bool,
+          "Force drop flag checks on or off"),
 }
 
 pub fn default_lib_output() -> CrateType {
@@ -590,10 +615,10 @@ pub fn default_lib_output() -> CrateType {
 pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
     use syntax::parse::token::intern_and_get_ident as intern;
 
-    let end = &sess.target.target.target_endian[];
-    let arch = &sess.target.target.arch[];
-    let wordsz = &sess.target.target.target_pointer_width[];
-    let os = &sess.target.target.target_os[];
+    let end = &sess.target.target.target_endian;
+    let arch = &sess.target.target.arch;
+    let wordsz = &sess.target.target.target_pointer_width;
+    let os = &sess.target.target.target_os;
 
     let fam = match sess.target.target.options.is_like_windows {
         true  => InternedString::new("windows"),
@@ -601,7 +626,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
     };
 
     let mk = attr::mk_name_value_item_str;
-    return vec!(// Target bindings.
+    let mut ret = vec![ // Target bindings.
          attr::mk_word_item(fam.clone()),
          mk(InternedString::new("target_os"), intern(os)),
          mk(InternedString::new("target_family"), fam),
@@ -609,7 +634,11 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
          mk(InternedString::new("target_endian"), intern(end)),
          mk(InternedString::new("target_pointer_width"),
             intern(wordsz))
-    );
+    ];
+    if sess.opts.debug_assertions {
+        ret.push(attr::mk_word_item(InternedString::new("debug_assertions")));
+    }
+    return ret;
 }
 
 pub fn append_configuration(cfg: &mut ast::CrateConfig,
@@ -634,18 +663,18 @@ pub fn build_configuration(sess: &Session) -> ast::CrateConfig {
 }
 
 pub fn build_target_config(opts: &Options, sp: &SpanHandler) -> Config {
-    let target = match Target::search(&opts.target_triple[]) {
+    let target = match Target::search(&opts.target_triple) {
         Ok(t) => t,
         Err(e) => {
             sp.handler().fatal(&format!("Error loading target specification: {}", e));
     }
     };
 
-    let (int_type, uint_type) = match &target.target_pointer_width[] {
+    let (int_type, uint_type) = match &target.target_pointer_width[..] {
         "32" => (ast::TyI32, ast::TyU32),
         "64" => (ast::TyI64, ast::TyU64),
         w    => sp.handler().fatal(&format!("target specification was invalid: unrecognized \
-                                             target-pointer-width {}", w)[])
+                                             target-pointer-width {}", w))
     };
 
     Config {
@@ -708,8 +737,8 @@ mod opt {
     use getopts;
     use super::RustcOptGroup;
 
-    type R = RustcOptGroup;
-    type S<'a> = &'a str;
+    pub type R = RustcOptGroup;
+    pub type S<'a> = &'a str;
 
     fn stable(g: getopts::OptGroup) -> R { RustcOptGroup::stable(g) }
     fn unstable(g: getopts::OptGroup) -> R { RustcOptGroup::unstable(g) }
@@ -843,6 +872,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let parse_only = debugging_opts.parse_only;
     let no_trans = debugging_opts.no_trans;
+    let treat_err_as_bug = debugging_opts.treat_err_as_bug;
     let no_analysis = debugging_opts.no_analysis;
 
     if debugging_opts.debug_llvm {
@@ -863,7 +893,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
                     "dep-info" => OutputTypeDepInfo,
                     _ => {
                         early_error(&format!("unknown emission type: `{}`",
-                                            part)[])
+                                            part))
                     }
                 };
                 output_types.push(output_type)
@@ -878,7 +908,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
 
     let cg = build_codegen_options(matches);
 
-    let sysroot_opt = matches.opt_str("sysroot").map(|m| Path::new(m));
+    let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
     let target = matches.opt_str("target").unwrap_or(
         host_triple().to_string());
     let opt_level = {
@@ -902,6 +932,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             }
         }
     };
+    let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == No);
     let gc = debugging_opts.gc;
     let debuginfo = if matches.opt_present("g") {
         if cg.debuginfo.is_some() {
@@ -927,25 +958,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     }
 
     let libs = matches.opt_strs("l").into_iter().map(|s| {
-        let mut parts = s.splitn(1, '=');
-        let kind = parts.next().unwrap();
-        if let Some(name) = parts.next() {
-            let kind = match kind {
-                "dylib" => cstore::NativeUnknown,
-                "framework" => cstore::NativeFramework,
-                "static" => cstore::NativeStatic,
-                s => {
-                    early_error(&format!("unknown library kind `{}`, expected \
-                                          one of dylib, framework, or static",
-                                         s));
-                }
-            };
-            return (name.to_string(), kind)
-        }
-
-        // FIXME(acrichto) remove this once crates have stopped using it, this
-        //                 is deprecated behavior now.
-        let mut parts = s.rsplitn(1, ':');
+        let mut parts = s.splitn(2, '=');
         let kind = parts.next().unwrap();
         let (name, kind) = match (parts.next(), kind) {
             (None, name) |
@@ -955,7 +968,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             (_, s) => {
                 early_error(&format!("unknown library kind `{}`, expected \
                                      one of dylib, framework, or static",
-                                    s)[]);
+                                    s));
             }
         };
         (name.to_string(), kind)
@@ -991,13 +1004,13 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         Some(arg) => {
             early_error(&format!("argument for --color must be auto, always \
                                  or never (instead was `{}`)",
-                                arg)[])
+                                arg))
         }
     };
 
     let mut externs = HashMap::new();
     for arg in &matches.opt_strs("extern") {
-        let mut parts = arg.splitn(1, '=');
+        let mut parts = arg.splitn(2, '=');
         let name = match parts.next() {
             Some(s) => s,
             None => early_error("--extern value must not be empty"),
@@ -1007,10 +1020,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             None => early_error("--extern value must be of the format `foo=bar`"),
         };
 
-        match externs.entry(name.to_string()) {
-            Vacant(entry) => { entry.insert(vec![location.to_string()]); },
-            Occupied(mut entry) => { entry.get_mut().push(location.to_string()); },
-        }
+        externs.entry(name.to_string()).or_insert(vec![]).push(location.to_string());
     }
 
     let crate_name = matches.opt_str("crate-name");
@@ -1030,6 +1040,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         test: test,
         parse_only: parse_only,
         no_trans: no_trans,
+        treat_err_as_bug: treat_err_as_bug,
         no_analysis: no_analysis,
         debugging_opts: debugging_opts,
         write_dependency_info: write_dependency_info,
@@ -1042,6 +1053,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         alt_std_name: None,
         libs: libs,
         unstable_features: get_unstable_features_setting(),
+        debug_assertions: debug_assertions,
     }
 }
 
@@ -1111,7 +1123,7 @@ mod test {
     #[test]
     fn test_switch_implies_cfg_test() {
         let matches =
-            &match getopts(&["--test".to_string()], &optgroups()[]) {
+            &match getopts(&["--test".to_string()], &optgroups()) {
               Ok(m) => m,
               Err(f) => panic!("test_switch_implies_cfg_test: {}", f)
             };
@@ -1128,7 +1140,7 @@ mod test {
     fn test_switch_implies_cfg_test_unless_cfg_test() {
         let matches =
             &match getopts(&["--test".to_string(), "--cfg=test".to_string()],
-                           &optgroups()[]) {
+                           &optgroups()) {
               Ok(m) => m,
               Err(f) => {
                 panic!("test_switch_implies_cfg_test_unless_cfg_test: {}", f)
@@ -1148,7 +1160,7 @@ mod test {
         {
             let matches = getopts(&[
                 "-Awarnings".to_string()
-            ], &optgroups()[]).unwrap();
+            ], &optgroups()).unwrap();
             let registry = diagnostics::registry::Registry::new(&[]);
             let sessopts = build_session_options(&matches);
             let sess = build_session(sessopts, None, registry);
@@ -1159,7 +1171,7 @@ mod test {
             let matches = getopts(&[
                 "-Awarnings".to_string(),
                 "-Dwarnings".to_string()
-            ], &optgroups()[]).unwrap();
+            ], &optgroups()).unwrap();
             let registry = diagnostics::registry::Registry::new(&[]);
             let sessopts = build_session_options(&matches);
             let sess = build_session(sessopts, None, registry);
@@ -1169,7 +1181,7 @@ mod test {
         {
             let matches = getopts(&[
                 "-Adead_code".to_string()
-            ], &optgroups()[]).unwrap();
+            ], &optgroups()).unwrap();
             let registry = diagnostics::registry::Registry::new(&[]);
             let sessopts = build_session_options(&matches);
             let sess = build_session(sessopts, None, registry);
index c1c5518887577d83462db5a07e032c48012f497e..3e3e5e17963cd1ac294782be0b19838f2132c91c 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 use lint;
 use metadata::cstore::CStore;
 use metadata::filesearch;
@@ -27,8 +26,9 @@ use syntax::{ast, codemap};
 
 use rustc_back::target::Target;
 
-use std::env;
+use std::path::{Path, PathBuf};
 use std::cell::{Cell, RefCell};
+use std::env;
 
 pub mod config;
 pub mod search_paths;
@@ -45,11 +45,11 @@ pub struct Session {
     pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>,
     pub entry_type: Cell<Option<config::EntryFnType>>,
     pub plugin_registrar_fn: Cell<Option<ast::NodeId>>,
-    pub default_sysroot: Option<Path>,
+    pub default_sysroot: Option<PathBuf>,
     // The name of the root source file of the crate, in the local file system. The path is always
     // expected to be absolute. `None` means that there is no source file.
-    pub local_crate_source_file: Option<Path>,
-    pub working_dir: Path,
+    pub local_crate_source_file: Option<PathBuf>,
+    pub working_dir: PathBuf,
     pub lint_store: RefCell<lint::LintStore>,
     pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>,
     pub crate_types: RefCell<Vec<config::CrateType>>,
@@ -58,37 +58,55 @@ pub struct Session {
 
     /// The maximum recursion limit for potentially infinitely recursive
     /// operations such as auto-dereference and monomorphization.
-    pub recursion_limit: Cell<uint>,
+    pub recursion_limit: Cell<usize>,
 
     pub can_print_warnings: bool
 }
 
 impl Session {
     pub fn span_fatal(&self, sp: Span, msg: &str) -> ! {
+        if self.opts.treat_err_as_bug {
+            self.span_bug(sp, msg);
+        }
         self.diagnostic().span_fatal(sp, msg)
     }
     pub fn span_fatal_with_code(&self, sp: Span, msg: &str, code: &str) -> ! {
+        if self.opts.treat_err_as_bug {
+            self.span_bug(sp, msg);
+        }
         self.diagnostic().span_fatal_with_code(sp, msg, code)
     }
     pub fn fatal(&self, msg: &str) -> ! {
+        if self.opts.treat_err_as_bug {
+            self.bug(msg);
+        }
         self.diagnostic().handler().fatal(msg)
     }
     pub fn span_err(&self, sp: Span, msg: &str) {
+        if self.opts.treat_err_as_bug {
+            self.span_bug(sp, msg);
+        }
         match split_msg_into_multilines(msg) {
             Some(msg) => self.diagnostic().span_err(sp, &msg[..]),
             None => self.diagnostic().span_err(sp, msg)
         }
     }
     pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
+        if self.opts.treat_err_as_bug {
+            self.span_bug(sp, msg);
+        }
         match split_msg_into_multilines(msg) {
             Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[..], code),
             None => self.diagnostic().span_err_with_code(sp, msg, code)
         }
     }
     pub fn err(&self, msg: &str) {
+        if self.opts.treat_err_as_bug {
+            self.bug(msg);
+        }
         self.diagnostic().handler().err(msg)
     }
-    pub fn err_count(&self) -> uint {
+    pub fn err_count(&self) -> usize {
         self.diagnostic().handler().err_count()
     }
     pub fn has_errors(&self) -> bool {
@@ -186,7 +204,7 @@ impl Session {
     // cases later on
     pub fn impossible_case(&self, sp: Span, msg: &str) -> ! {
         self.span_bug(sp,
-                      &format!("impossible case reached: {}", msg)[]);
+                      &format!("impossible case reached: {}", msg));
     }
     pub fn verbose(&self) -> bool { self.opts.debugging_opts.verbose }
     pub fn time_passes(&self) -> bool { self.opts.debugging_opts.time_passes }
@@ -228,7 +246,7 @@ impl Session {
     }
     pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch {
         filesearch::FileSearch::new(self.sysroot(),
-                                    &self.opts.target_triple[],
+                                    &self.opts.target_triple,
                                     &self.opts.search_paths,
                                     kind)
     }
@@ -280,9 +298,9 @@ fn split_msg_into_multilines(msg: &str) -> Option<String> {
     }
 
     let mut tail = &msg[head..];
-    let third = tail.find_str("(values differ")
-                   .or(tail.find_str("(lifetime"))
-                   .or(tail.find_str("(cyclic type of infinite size"));
+    let third = tail.find("(values differ")
+                   .or(tail.find("(lifetime"))
+                   .or(tail.find("(cyclic type of infinite size"));
     // Insert `\n` before any remaining messages which match.
     if let Some(pos) = third {
         // The end of the message may just be wrapped in `()` without
@@ -302,7 +320,7 @@ fn split_msg_into_multilines(msg: &str) -> Option<String> {
 }
 
 pub fn build_session(sopts: config::Options,
-                     local_crate_source_file: Option<Path>,
+                     local_crate_source_file: Option<PathBuf>,
                      registry: diagnostics::registry::Registry)
                      -> Session {
     // FIXME: This is not general enough to make the warning lint completely override
@@ -325,7 +343,7 @@ pub fn build_session(sopts: config::Options,
 }
 
 pub fn build_session_(sopts: config::Options,
-                      local_crate_source_file: Option<Path>,
+                      local_crate_source_file: Option<PathBuf>,
                       span_diagnostic: diagnostic::SpanHandler)
                       -> Session {
     let host = match Target::search(config::host_triple()) {
@@ -380,7 +398,6 @@ pub fn build_session_(sopts: config::Options,
         can_print_warnings: can_print_warnings
     };
 
-    sess.lint_store.borrow_mut().register_builtin(Some(&sess));
     sess
 }
 
index c314a999f246119cf1ca7d340b5c8586f0a245e3..3dc31f9524effe1e5b32668c7c7d707bbf9ce1fb 100644 (file)
@@ -9,15 +9,17 @@
 // except according to those terms.
 
 use std::slice;
+use std::path::{Path, PathBuf};
+use session::early_error;
 
 #[derive(Clone, Debug)]
 pub struct SearchPaths {
-    paths: Vec<(PathKind, Path)>,
+    paths: Vec<(PathKind, PathBuf)>,
 }
 
 pub struct Iter<'a> {
     kind: PathKind,
-    iter: slice::Iter<'a, (PathKind, Path)>,
+    iter: slice::Iter<'a, (PathKind, PathBuf)>,
 }
 
 #[derive(Eq, PartialEq, Clone, Copy, Debug)]
@@ -49,7 +51,10 @@ impl SearchPaths {
         } else {
             (PathKind::All, path)
         };
-        self.paths.push((kind, Path::new(path)));
+        if path.is_empty() {
+            early_error("empty search path given via `-L`");
+        }
+        self.paths.push((kind, PathBuf::from(path)));
     }
 
     pub fn iter(&self, kind: PathKind) -> Iter {
index c9d50b9cecf84ff005f033b439c589b5202a61fa..d71a68e2050524970304e1147c739ce190e88558 100644 (file)
 
 use std::cell::{RefCell, Cell};
 use std::collections::HashMap;
+use std::collections::hash_state::HashState;
+use std::ffi::CString;
 use std::fmt::Debug;
 use std::hash::Hash;
-#[cfg(stage0)] use std::hash::Hasher;
 use std::iter::repeat;
+use std::path::Path;
 use std::time::Duration;
-use std::collections::hash_state::HashState;
 
 use syntax::ast;
 use syntax::visit;
@@ -34,7 +35,7 @@ pub struct ErrorReported;
 pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
     F: FnOnce(U) -> T,
 {
-    thread_local!(static DEPTH: Cell<uint> = Cell::new(0));
+    thread_local!(static DEPTH: Cell<usize> = Cell::new(0));
     if !do_it { return f(u); }
 
     let old = DEPTH.with(|slot| {
@@ -139,57 +140,13 @@ pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -
 
 /// K: Eq + Hash<S>, V, S, H: Hasher<S>
 ///
-/// Determines whether there exists a path from `source` to `destination`.  The graph is defined by
-/// the `edges_map`, which maps from a node `S` to a list of its adjacent nodes `T`.
+/// Determines whether there exists a path from `source` to `destination`.  The
+/// graph is defined by the `edges_map`, which maps from a node `S` to a list of
+/// its adjacent nodes `T`.
 ///
-/// Efficiency note: This is implemented in an inefficient way because it is typically invoked on
-/// very small graphs. If the graphs become larger, a more efficient graph representation and
-/// algorithm would probably be advised.
-#[cfg(stage0)]
-pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
-                       destination: T) -> bool
-    where S: HashState,
-          <S as HashState>::Hasher: Hasher<Output=u64>,
-          T: Hash<<S as HashState>::Hasher> + Eq + Clone,
-{
-    if source == destination {
-        return true;
-    }
-
-    // Do a little breadth-first-search here.  The `queue` list
-    // doubles as a way to detect if we've seen a particular FR
-    // before.  Note that we expect this graph to be an *extremely
-    // shallow* tree.
-    let mut queue = vec!(source);
-    let mut i = 0;
-    while i < queue.len() {
-        match edges_map.get(&queue[i]) {
-            Some(edges) => {
-                for target in edges {
-                    if *target == destination {
-                        return true;
-                    }
-
-                    if !queue.iter().any(|x| x == target) {
-                        queue.push((*target).clone());
-                    }
-                }
-            }
-            None => {}
-        }
-        i += 1;
-    }
-    return false;
-}
-/// K: Eq + Hash<S>, V, S, H: Hasher<S>
-///
-/// Determines whether there exists a path from `source` to `destination`.  The graph is defined by
-/// the `edges_map`, which maps from a node `S` to a list of its adjacent nodes `T`.
-///
-/// Efficiency note: This is implemented in an inefficient way because it is typically invoked on
-/// very small graphs. If the graphs become larger, a more efficient graph representation and
-/// algorithm would probably be advised.
-#[cfg(not(stage0))]
+/// Efficiency note: This is implemented in an inefficient way because it is
+/// typically invoked on very small graphs. If the graphs become larger, a more
+/// efficient graph representation and algorithm would probably be advised.
 pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
                        destination: T) -> bool
     where S: HashState, T: Hash + Eq + Clone,
@@ -236,13 +193,13 @@ pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
 /// ```
 /// but currently it is not possible.
 ///
-/// # Example
+/// # Examples
 /// ```
 /// struct Context {
-///    cache: RefCell<HashMap<uint, uint>>
+///    cache: RefCell<HashMap<usize, usize>>
 /// }
 ///
-/// fn factorial(ctxt: &Context, n: uint) -> uint {
+/// fn factorial(ctxt: &Context, n: usize) -> usize {
 ///     memoized(&ctxt.cache, n, |n| match n {
 ///         0 | 1 => n,
 ///         _ => factorial(ctxt, n - 2) + factorial(ctxt, n - 1)
@@ -250,12 +207,10 @@ pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
 /// }
 /// ```
 #[inline(always)]
-#[cfg(stage0)]
 pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) -> U
-    where T: Clone + Hash<<S as HashState>::Hasher> + Eq,
+    where T: Clone + Hash + Eq,
           U: Clone,
           S: HashState,
-          <S as HashState>::Hasher: Hasher<Output=u64>,
           F: FnOnce(T) -> U,
 {
     let key = arg.clone();
@@ -269,47 +224,15 @@ pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) ->
         }
     }
 }
-/// Memoizes a one-argument closure using the given RefCell containing
-/// a type implementing MutableMap to serve as a cache.
-///
-/// In the future the signature of this function is expected to be:
-/// ```
-/// pub fn memoized<T: Clone, U: Clone, M: MutableMap<T, U>>(
-///    cache: &RefCell<M>,
-///    f: &|T| -> U
-/// ) -> impl |T| -> U {
-/// ```
-/// but currently it is not possible.
-///
-/// # Example
-/// ```
-/// struct Context {
-///    cache: RefCell<HashMap<uint, uint>>
-/// }
-///
-/// fn factorial(ctxt: &Context, n: uint) -> uint {
-///     memoized(&ctxt.cache, n, |n| match n {
-///         0 | 1 => n,
-///         _ => factorial(ctxt, n - 2) + factorial(ctxt, n - 1)
-///     })
-/// }
-/// ```
-#[inline(always)]
-#[cfg(not(stage0))]
-pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) -> U
-    where T: Clone + Hash + Eq,
-          U: Clone,
-          S: HashState,
-          F: FnOnce(T) -> U,
-{
-    let key = arg.clone();
-    let result = cache.borrow().get(&key).map(|result| result.clone());
-    match result {
-        Some(result) => result,
-        None => {
-            let result = f(arg);
-            cache.borrow_mut().insert(key, result.clone());
-            result
-        }
-    }
+
+#[cfg(unix)]
+pub fn path2cstr(p: &Path) -> CString {
+    use std::os::unix::prelude::*;
+    use std::ffi::OsStr;
+    let p: &OsStr = p.as_ref();
+    CString::new(p.as_bytes()).unwrap()
+}
+#[cfg(windows)]
+pub fn path2cstr(p: &Path) -> CString {
+    CString::new(p.to_str().unwrap()).unwrap()
 }
index 10a7b2abea80bb389e3213ec3895b27661ded2d8..28f8510ce3fee150100523f49c455f82e2c6e7c3 100644 (file)
@@ -10,7 +10,7 @@
 
 use std::cmp;
 
-pub fn lev_distance(me: &str, t: &str) -> uint {
+pub fn lev_distance(me: &str, t: &str) -> usize {
     if me.is_empty() { return t.chars().count(); }
     if t.is_empty() { return me.chars().count(); }
 
@@ -45,7 +45,7 @@ pub fn lev_distance(me: &str, t: &str) -> uint {
 fn test_lev_distance() {
     use std::char::{ from_u32, MAX };
     // Test bytelength agnosticity
-    for c in (0u32..MAX as u32)
+    for c in (0..MAX as u32)
              .filter_map(|i| from_u32(i))
              .map(|i| i.to_string()) {
         assert_eq!(lev_distance(&c[..], &c[..]), 0);
index 1b07ce789e77c8e7713c3ff2f2831fde021fc818..61d28e0ca1e646f51d28ab90ca98fa84dc419c47 100644 (file)
 
 #![allow(non_snake_case)]
 
-use std::collections::hash_state::{DefaultState};
+use std::collections::hash_state::DefaultState;
 use std::collections::{HashMap, HashSet};
 use std::default::Default;
 use std::hash::{Hasher, Hash};
-#[cfg(stage0)] use std::hash::Writer;
 use syntax::ast;
 
 pub type FnvHashMap<K, V> = HashMap<K, V, DefaultState<FnvHasher>>;
@@ -28,19 +27,9 @@ pub type DefIdMap<T> = FnvHashMap<ast::DefId, T>;
 pub type NodeSet = FnvHashSet<ast::NodeId>;
 pub type DefIdSet = FnvHashSet<ast::DefId>;
 
-#[cfg(stage0)]
-pub fn FnvHashMap<K: Hash<FnvHasher> + Eq, V>() -> FnvHashMap<K, V> {
-    Default::default()
-}
-#[cfg(stage0)]
-pub fn FnvHashSet<V: Hash<FnvHasher> + Eq>() -> FnvHashSet<V> {
-    Default::default()
-}
-#[cfg(not(stage0))]
 pub fn FnvHashMap<K: Hash + Eq, V>() -> FnvHashMap<K, V> {
     Default::default()
 }
-#[cfg(not(stage0))]
 pub fn FnvHashSet<V: Hash + Eq>() -> FnvHashSet<V> {
     Default::default()
 }
@@ -63,32 +52,12 @@ impl Default for FnvHasher {
     fn default() -> FnvHasher { FnvHasher(0xcbf29ce484222325) }
 }
 
-#[cfg(stage0)]
-impl Hasher for FnvHasher {
-    type Output = u64;
-    fn reset(&mut self) { *self = Default::default(); }
-    fn finish(&self) -> u64 { self.0 }
-}
-
-#[cfg(stage0)]
-impl Writer for FnvHasher {
-    fn write(&mut self, bytes: &[u8]) {
-        let FnvHasher(mut hash) = *self;
-        for byte in bytes {
-            hash = hash ^ (*byte as u64);
-            hash = hash * 0x100000001b3;
-        }
-        *self = FnvHasher(hash);
-    }
-}
-
-#[cfg(not(stage0))]
 impl Hasher for FnvHasher {
     fn write(&mut self, bytes: &[u8]) {
         let FnvHasher(mut hash) = *self;
         for byte in bytes {
             hash = hash ^ (*byte as u64);
-            hash = hash * 0x100000001b3;
+            hash = hash.wrapping_mul(0x100000001b3);
         }
         *self = FnvHasher(hash);
     }
index 1d46c011bb32e7298334fa4a1ea5318b1565feb4..60b422b3769d5bc0a2c322a590d89b776a691493 100644 (file)
@@ -20,8 +20,8 @@ use middle::ty::{ReSkolemized, ReVar, BrEnv};
 use middle::ty::{mt, Ty, ParamTy};
 use middle::ty::{ty_bool, ty_char, ty_struct, ty_enum};
 use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn};
-use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup, ty_open};
-use middle::ty::{ty_closure};
+use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup};
+use middle::ty::ty_closure;
 use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
 use middle::ty;
 use middle::ty_fold::TypeFoldable;
@@ -29,7 +29,6 @@ use middle::ty_fold::TypeFoldable;
 use std::collections::HashMap;
 use std::collections::hash_state::HashState;
 use std::hash::Hash;
-#[cfg(stage0)] use std::hash::Hasher;
 use std::rc::Rc;
 use syntax::abi;
 use syntax::ast_map;
@@ -58,12 +57,12 @@ pub fn note_and_explain_region(cx: &ctxt,
       (ref str, Some(span)) => {
         cx.sess.span_note(
             span,
-            &format!("{}{}{}", prefix, *str, suffix)[]);
+            &format!("{}{}{}", prefix, *str, suffix));
         Some(span)
       }
       (ref str, None) => {
         cx.sess.note(
-            &format!("{}{}{}", prefix, *str, suffix)[]);
+            &format!("{}{}{}", prefix, *str, suffix));
         None
       }
     }
@@ -116,7 +115,7 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
             region::CodeExtent::Misc(_) => tag,
             region::CodeExtent::DestructionScope(_) => {
                 new_string = format!("destruction scope surrounding {}", tag);
-                new_string.as_slice()
+                &*new_string
             }
             region::CodeExtent::Remainder(r) => {
                 new_string = format!("block suffix following statement {}",
@@ -274,7 +273,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
         };
 
         if abi != abi::Rust {
-            s.push_str(&format!("extern {} ", abi.to_string())[]);
+            s.push_str(&format!("extern {} ", abi.to_string()));
         };
 
         s.push_str("fn");
@@ -330,7 +329,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
             ty::FnConverging(t) => {
                 if !ty::type_is_nil(t) {
                    s.push_str(" -> ");
-                   s.push_str(&ty_to_string(cx, t)[]);
+                   s.push_str(&ty_to_string(cx, t));
                 }
             }
             ty::FnDiverging => {
@@ -367,11 +366,9 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
         }
         ty_rptr(r, ref tm) => {
             let mut buf = region_ptr_to_string(cx, *r);
-            buf.push_str(&mt_to_string(cx, tm)[]);
+            buf.push_str(&mt_to_string(cx, tm));
             buf
         }
-        ty_open(typ) =>
-            format!("opened<{}>", ty_to_string(cx, typ)),
         ty_tup(ref elems) => {
             let strs = elems
                 .iter()
@@ -387,13 +384,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
         }
         ty_infer(infer_ty) => infer_ty_to_string(cx, infer_ty),
         ty_err => "[type error]".to_string(),
-        ty_param(ref param_ty) => {
-            if cx.sess.verbose() {
-                param_ty.repr(cx)
-            } else {
-                param_ty.user_string(cx)
-            }
-        }
+        ty_param(ref param_ty) => param_ty.user_string(cx),
         ty_enum(did, substs) | ty_struct(did, substs) => {
             let base = ty::item_path_str(cx, did);
             parameterized(cx, &base, substs, did, &[],
@@ -409,7 +400,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
                     data.item_name.user_string(cx))
         }
         ty_str => "str".to_string(),
-        ty_closure(ref did, _, substs) => {
+        ty_closure(ref did, substs) => {
             let closure_tys = cx.closure_tys.borrow();
             closure_tys.get(did).map(|closure_type| {
                 closure_to_string(cx, &closure_type.subst(cx, substs))
@@ -561,7 +552,7 @@ pub fn parameterized<'tcx,GG>(cx: &ctxt<'tcx>,
                 } else if strs[0].starts_with("(") && strs[0].ends_with(")") {
                     &strs[0][1 .. strs[0].len() - 1] // Remove '(' and ')'
                 } else {
-                    &strs[0][]
+                    &strs[0][..]
                 },
                 tail)
     } else if strs.len() > 0 {
@@ -823,23 +814,19 @@ impl<'tcx> Repr<'tcx> for ty::TraitRef<'tcx> {
 
 impl<'tcx> Repr<'tcx> for ty::TraitDef<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
-        format!("TraitDef(generics={}, bounds={}, trait_ref={})",
+        format!("TraitDef(generics={}, trait_ref={})",
                 self.generics.repr(tcx),
-                self.bounds.repr(tcx),
                 self.trait_ref.repr(tcx))
     }
 }
 
 impl<'tcx> Repr<'tcx> for ast::TraitItem {
     fn repr(&self, _tcx: &ctxt) -> String {
-        match *self {
-            ast::RequiredMethod(ref data) => format!("RequiredMethod({}, id={})",
-                                                     data.ident, data.id),
-            ast::ProvidedMethod(ref data) => format!("ProvidedMethod(id={})",
-                                                     data.id),
-            ast::TypeTraitItem(ref data) => format!("TypeTraitItem({}, id={})",
-                                                     data.ty_param.ident, data.ty_param.id),
-        }
+        let kind = match self.node {
+            ast::MethodTraitItem(..) => "MethodTraitItem",
+            ast::TypeTraitItem(..) => "TypeTraitItem",
+        };
+        format!("{}({}, id={})", kind, self.ident, self.id)
     }
 }
 
@@ -1060,10 +1047,11 @@ impl<'tcx> Repr<'tcx> for ty::Variance {
 
 impl<'tcx> Repr<'tcx> for ty::Method<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
-        format!("method(name: {}, generics: {}, fty: {}, \
+        format!("method(name: {}, generics: {}, predicates: {}, fty: {}, \
                  explicit_self: {}, vis: {}, def_id: {})",
                 self.name.repr(tcx),
                 self.generics.repr(tcx),
+                self.predicates.repr(tcx),
                 self.fty.repr(tcx),
                 self.explicit_self.repr(tcx),
                 self.vis.repr(tcx),
@@ -1221,17 +1209,17 @@ impl<'tcx> Repr<'tcx> for ty::ExistentialBounds<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
         let mut res = Vec::new();
 
-        let region_str = self.region_bound.user_string(tcx);
+        let region_str = self.region_bound.repr(tcx);
         if !region_str.is_empty() {
             res.push(region_str);
         }
 
         for bound in &self.builtin_bounds {
-            res.push(bound.user_string(tcx));
+            res.push(bound.repr(tcx));
         }
 
         for projection_bound in &self.projection_bounds {
-            res.push(projection_bound.user_string(tcx));
+            res.push(projection_bound.repr(tcx));
         }
 
         res.connect("+")
@@ -1434,23 +1422,6 @@ impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for ty::Binder<T> {
     }
 }
 
-#[cfg(stage0)]
-impl<'tcx, S, K, V> Repr<'tcx> for HashMap<K, V, S>
-    where K: Hash<<S as HashState>::Hasher> + Eq + Repr<'tcx>,
-          V: Repr<'tcx>,
-          S: HashState,
-          <S as HashState>::Hasher: Hasher<Output=u64>,
-{
-    fn repr(&self, tcx: &ctxt<'tcx>) -> String {
-        format!("HashMap({})",
-                self.iter()
-                    .map(|(k,v)| format!("{} => {}", k.repr(tcx), v.repr(tcx)))
-                    .collect::<Vec<String>>()
-                    .connect(", "))
-    }
-}
-
-#[cfg(not(stage0))]
 impl<'tcx, S, K, V> Repr<'tcx> for HashMap<K, V, S>
     where K: Hash + Eq + Repr<'tcx>,
           V: Repr<'tcx>,
@@ -1555,3 +1526,9 @@ impl<'tcx> UserString<'tcx> for ty::Predicate<'tcx> {
         }
     }
 }
+
+impl<'tcx> Repr<'tcx> for ast::Unsafety {
+    fn repr(&self, _: &ctxt<'tcx>) -> String {
+        format!("{:?}", *self)
+    }
+}
index 8fbc682246f470078c18e5f6025ccbfc2e61b4d7..d2e0b3aec2f40236d3ac6615a42b8f4629858486 100644 (file)
@@ -30,10 +30,10 @@ pub enum UndoLog<D:SnapshotVecDelegate> {
     CommittedSnapshot,
 
     /// New variable with given index was created.
-    NewElem(uint),
+    NewElem(usize),
 
     /// Variable with given index was changed *from* the given value.
-    SetElem(uint, D::Value),
+    SetElem(usize, D::Value),
 
     /// Extensible set of actions
     Other(D::Undo)
@@ -48,7 +48,7 @@ pub struct SnapshotVec<D:SnapshotVecDelegate> {
 // Snapshots are tokens that should be created/consumed linearly.
 pub struct Snapshot {
     // Length of the undo log at the time the snapshot was taken.
-    length: uint,
+    length: usize,
 }
 
 pub trait SnapshotVecDelegate {
@@ -77,7 +77,7 @@ impl<D:SnapshotVecDelegate> SnapshotVec<D> {
         }
     }
 
-    pub fn push(&mut self, elem: D::Value) -> uint {
+    pub fn push(&mut self, elem: D::Value) -> usize {
         let len = self.values.len();
         self.values.push(elem);
 
@@ -88,20 +88,20 @@ impl<D:SnapshotVecDelegate> SnapshotVec<D> {
         len
     }
 
-    pub fn get<'a>(&'a self, index: uint) -> &'a D::Value {
+    pub fn get<'a>(&'a self, index: usize) -> &'a D::Value {
         &self.values[index]
     }
 
     /// Returns a mutable pointer into the vec; whatever changes you make here cannot be undone
     /// automatically, so you should be sure call `record()` with some sort of suitable undo
     /// action.
-    pub fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut D::Value {
+    pub fn get_mut<'a>(&'a mut self, index: usize) -> &'a mut D::Value {
         &mut self.values[index]
     }
 
     /// Updates the element at the given index. The old value will saved (and perhaps restored) if
     /// a snapshot is active.
-    pub fn set(&mut self, index: uint, new_elem: D::Value) {
+    pub fn set(&mut self, index: usize, new_elem: D::Value) {
         let old_elem = mem::replace(&mut self.values[index], new_elem);
         if self.in_snapshot() {
             self.undo_log.push(SetElem(index, old_elem));
index 4b9064aaa05f9ecc8e6970457ed6062a00361b96..c3a3a8d582aff91f2fc400141e0b57d16d605234 100644 (file)
@@ -8,17 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub const BOX_FIELD_DROP_GLUE: uint = 1;
-pub const BOX_FIELD_BODY: uint = 4;
+pub const BOX_FIELD_DROP_GLUE: usize = 1;
+pub const BOX_FIELD_BODY: usize = 4;
 
 /// The first half of a fat pointer.
 /// - For a closure, this is the code address.
 /// - For an object or trait instance, this is the address of the box.
 /// - For a slice, this is the base address.
-pub const FAT_PTR_ADDR: uint = 0;
+pub const FAT_PTR_ADDR: usize = 0;
 
 /// The second half of a fat pointer.
 /// - For a closure, this is the address of the environment.
 /// - For an object or trait instance, this is the address of the vtable.
 /// - For a slice, this is the length.
-pub const FAT_PTR_EXTRA: uint = 1;
+pub const FAT_PTR_EXTRA: usize = 1;
index c45ee258342ec1be9c24a8f83d03f2bdae694488..9f5751c421ecebe39ad56cc1f866e2bd0a916b19 100644 (file)
 
 //! A helper class for dealing with static archives
 
-use std::old_io::fs::PathExtensions;
-use std::old_io::process::{Command, ProcessOutput};
-use std::old_io::{fs, TempDir};
-use std::old_io;
 use std::env;
+use std::fs;
+use std::io::prelude::*;
+use std::io;
+use std::path::{Path, PathBuf};
+use std::process::{Command, Output, Stdio};
 use std::str;
 use syntax::diagnostic::Handler as ErrorHandler;
 
-pub static METADATA_FILENAME: &'static str = "rust.metadata.bin";
+use tempdir::TempDir;
+
+pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
 
 pub struct ArchiveConfig<'a> {
     pub handler: &'a ErrorHandler,
-    pub dst: Path,
-    pub lib_search_paths: Vec<Path>,
+    pub dst: PathBuf,
+    pub lib_search_paths: Vec<PathBuf>,
     pub slib_prefix: String,
     pub slib_suffix: String,
     pub maybe_ar_prog: Option<String>
@@ -31,8 +34,8 @@ pub struct ArchiveConfig<'a> {
 
 pub struct Archive<'a> {
     handler: &'a ErrorHandler,
-    dst: Path,
-    lib_search_paths: Vec<Path>,
+    dst: PathBuf,
+    lib_search_paths: Vec<PathBuf>,
     slib_prefix: String,
     slib_suffix: String,
     maybe_ar_prog: Option<String>
@@ -45,25 +48,25 @@ pub struct ArchiveBuilder<'a> {
     archive: Archive<'a>,
     work_dir: TempDir,
     /// Filename of each member that should be added to the archive.
-    members: Vec<Path>,
+    members: Vec<PathBuf>,
     should_update_symbols: bool,
 }
 
 fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
           args: &str, cwd: Option<&Path>,
-          paths: &[&Path]) -> ProcessOutput {
+          paths: &[&Path]) -> Output {
     let ar = match *maybe_ar_prog {
         Some(ref ar) => &ar[..],
         None => "ar"
     };
     let mut cmd = Command::new(ar);
 
-    cmd.arg(args).args(paths);
+    cmd.arg(args).args(paths).stdout(Stdio::piped()).stderr(Stdio::piped());
     debug!("{:?}", cmd);
 
     match cwd {
         Some(p) => {
-            cmd.cwd(p);
+            cmd.current_dir(p);
             debug!("inside {:?}", p.display());
         }
         None => {}
@@ -73,19 +76,19 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
         Ok(prog) => {
             let o = prog.wait_with_output().unwrap();
             if !o.status.success() {
-                handler.err(&format!("{:?} failed with: {}", cmd, o.status)[]);
+                handler.err(&format!("{:?} failed with: {}", cmd, o.status));
                 handler.note(&format!("stdout ---\n{}",
-                                  str::from_utf8(&o.output[]).unwrap())[]);
+                                  str::from_utf8(&o.stdout).unwrap()));
                 handler.note(&format!("stderr ---\n{}",
-                                  str::from_utf8(&o.error[]).unwrap())
-                             []);
+                                  str::from_utf8(&o.stderr).unwrap())
+                             );
                 handler.abort_if_errors();
             }
             o
         },
         Err(e) => {
             handler.err(&format!("could not exec `{}`: {}", &ar[..],
-                             e)[]);
+                             e));
             handler.abort_if_errors();
             panic!("rustc::back::archive::run_ar() should not reach this point");
         }
@@ -93,14 +96,15 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
 }
 
 pub fn find_library(name: &str, osprefix: &str, ossuffix: &str,
-                    search_paths: &[Path], handler: &ErrorHandler) -> Path {
+                    search_paths: &[PathBuf],
+                    handler: &ErrorHandler) -> PathBuf {
     // On Windows, static libraries sometimes show up as libfoo.a and other
     // times show up as foo.lib
     let oslibname = format!("{}{}{}", osprefix, name, ossuffix);
     let unixlibname = format!("lib{}.a", name);
 
     for path in search_paths {
-        debug!("looking for {} inside {:?}", name, path.display());
+        debug!("looking for {} inside {:?}", name, path);
         let test = path.join(&oslibname[..]);
         if test.exists() { return test }
         if oslibname != unixlibname {
@@ -110,7 +114,7 @@ pub fn find_library(name: &str, osprefix: &str, ossuffix: &str,
     }
     handler.fatal(&format!("could not find native static library `{}`, \
                            perhaps an -L flag is missing?",
-                          name)[]);
+                          name));
 }
 
 impl<'a> Archive<'a> {
@@ -142,7 +146,7 @@ impl<'a> Archive<'a> {
     /// Lists all files in an archive
     pub fn files(&self) -> Vec<String> {
         let output = run_ar(self.handler, &self.maybe_ar_prog, "t", None, &[&self.dst]);
-        let output = str::from_utf8(&output.output[]).unwrap();
+        let output = str::from_utf8(&output.stdout).unwrap();
         // use lines_any because windows delimits output with `\r\n` instead of
         // just `\n`
         output.lines_any().map(|s| s.to_string()).collect()
@@ -172,11 +176,11 @@ impl<'a> ArchiveBuilder<'a> {
 
     /// Adds all of the contents of a native library to this archive. This will
     /// search in the relevant locations for a library named `name`.
-    pub fn add_native_library(&mut self, name: &str) -> old_io::IoResult<()> {
+    pub fn add_native_library(&mut self, name: &str) -> io::Result<()> {
         let location = find_library(name,
-                                    &self.archive.slib_prefix[],
-                                    &self.archive.slib_suffix[],
-                                    &self.archive.lib_search_paths[],
+                                    &self.archive.slib_prefix,
+                                    &self.archive.slib_suffix,
+                                    &self.archive.lib_search_paths,
                                     self.archive.handler);
         self.add_archive(&location, name, |_| false)
     }
@@ -187,7 +191,7 @@ impl<'a> ArchiveBuilder<'a> {
     /// This ignores adding the bytecode from the rlib, and if LTO is enabled
     /// then the object file also isn't added.
     pub fn add_rlib(&mut self, rlib: &Path, name: &str,
-                    lto: bool) -> old_io::IoResult<()> {
+                    lto: bool) -> io::Result<()> {
         // Ignoring obj file starting with the crate name
         // as simple comparison is not enough - there
         // might be also an extra name suffix
@@ -205,11 +209,11 @@ impl<'a> ArchiveBuilder<'a> {
     }
 
     /// Adds an arbitrary file to this archive
-    pub fn add_file(&mut self, file: &Path) -> old_io::IoResult<()> {
-        let filename = Path::new(file.filename().unwrap());
+    pub fn add_file(&mut self, file: &Path) -> io::Result<()> {
+        let filename = Path::new(file.file_name().unwrap());
         let new_file = self.work_dir.path().join(&filename);
         try!(fs::copy(file, &new_file));
-        self.members.push(filename);
+        self.members.push(filename.to_path_buf());
         Ok(())
     }
 
@@ -226,8 +230,8 @@ impl<'a> ArchiveBuilder<'a> {
         // though we run it from `self.work_dir`.
         let abs_dst = env::current_dir().unwrap().join(&self.archive.dst);
         assert!(!abs_dst.is_relative());
-        let mut args = vec![&abs_dst];
-        let mut total_len = abs_dst.as_vec().len();
+        let mut args = vec![&*abs_dst];
+        let mut total_len = abs_dst.to_string_lossy().len();
 
         if self.members.is_empty() {
             // OSX `ar` does not allow using `r` with no members, but it does
@@ -242,10 +246,10 @@ impl<'a> ArchiveBuilder<'a> {
         // Don't allow the total size of `args` to grow beyond 32,000 bytes.
         // Windows will raise an error if the argument string is longer than
         // 32,768, and we leave a bit of extra space for the program name.
-        static ARG_LENGTH_LIMIT: uint = 32000;
+        const ARG_LENGTH_LIMIT: usize = 32_000;
 
         for member_name in &self.members {
-            let len = member_name.as_vec().len();
+            let len = member_name.to_string_lossy().len();
 
             // `len + 1` to account for the space that's inserted before each
             // argument.  (Windows passes command-line arguments as a single
@@ -258,7 +262,7 @@ impl<'a> ArchiveBuilder<'a> {
 
                 args.clear();
                 args.push(&abs_dst);
-                total_len = abs_dst.as_vec().len();
+                total_len = abs_dst.to_string_lossy().len();
             }
 
             args.push(member_name);
@@ -275,7 +279,7 @@ impl<'a> ArchiveBuilder<'a> {
     }
 
     fn add_archive<F>(&mut self, archive: &Path, name: &str,
-                      mut skip: F) -> old_io::IoResult<()>
+                      mut skip: F) -> io::Result<()>
         where F: FnMut(&str) -> bool,
     {
         let loc = TempDir::new("rsar").unwrap();
@@ -296,9 +300,10 @@ impl<'a> ArchiveBuilder<'a> {
         // We skip any files explicitly desired for skipping, and we also skip
         // all SYMDEF files as these are just magical placeholders which get
         // re-created when we make a new archive anyway.
-        let files = try!(fs::readdir(loc.path()));
-        for file in &files {
-            let filename = file.filename_str().unwrap();
+        let files = try!(fs::read_dir(loc.path()));
+        for file in files {
+            let file = try!(file).path();
+            let filename = file.file_name().unwrap().to_str().unwrap();
             if skip(filename) { continue }
             if filename.contains(".SYMDEF") { continue }
 
@@ -313,10 +318,9 @@ impl<'a> ArchiveBuilder<'a> {
                 filename
             };
             let new_filename = self.work_dir.path().join(&filename[..]);
-            try!(fs::rename(file, &new_filename));
-            self.members.push(Path::new(filename));
+            try!(fs::rename(&file, &new_filename));
+            self.members.push(PathBuf::from(filename));
         }
         Ok(())
     }
 }
-
index a4417b49f1c41e771fd65a0e18dbc692183597dd..7325e4e7a2ece9aa4a15bee6e35c2820e4159a0c 100644 (file)
@@ -61,7 +61,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
                 -a:0:64-n32".to_string()
           }
 
-          abi::OsFreebsd | abi::OsDragonfly | abi::OsOpenbsd => {
+          abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd => {
             "e-p:32:32:32\
                 -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
                 -f32:32:32-f64:64:64\
index acf49d1ca46e3b6d7a3c55cc44a607d48aea0681..231f6ee3be6adb317f0c5ac4bd6551919047d87d 100644 (file)
@@ -8,15 +8,29 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::old_io;
-use std::old_io::fs;
+use std::io;
 use std::env;
+#[allow(deprecated)] use std::old_path::{self, GenericPath};
+#[allow(deprecated)] use std::old_io;
+use std::path::{Path, PathBuf};
 
 /// Returns an absolute path in the filesystem that `path` points to. The
 /// returned path does not contain any symlinks in its hierarchy.
-pub fn realpath(original: &Path) -> old_io::IoResult<Path> {
-    static MAX_LINKS_FOLLOWED: uint = 256;
-    let original = try!(env::current_dir()).join(original);
+#[allow(deprecated)] // readlink is deprecated
+pub fn realpath(original: &Path) -> io::Result<PathBuf> {
+    let old = old_path::Path::new(original.to_str().unwrap());
+    match old_realpath(&old) {
+        Ok(p) => Ok(PathBuf::from(p.as_str().unwrap())),
+        Err(e) => Err(io::Error::new(io::ErrorKind::Other, e))
+    }
+}
+
+#[allow(deprecated)]
+fn old_realpath(original: &old_path::Path) -> old_io::IoResult<old_path::Path> {
+    use std::old_io::fs;
+    const MAX_LINKS_FOLLOWED: usize = 256;
+    let original = old_path::Path::new(env::current_dir().unwrap()
+                                           .to_str().unwrap()).join(original);
 
     // Right now lstat on windows doesn't work quite well
     if cfg!(windows) {
@@ -55,8 +69,9 @@ pub fn realpath(original: &Path) -> old_io::IoResult<Path> {
 mod test {
     use std::old_io;
     use std::old_io::fs::{File, symlink, mkdir, mkdir_recursive};
-    use super::realpath;
+    use super::old_realpath as realpath;
     use std::old_io::TempDir;
+    use std::old_path::{Path, GenericPath};
 
     #[test]
     fn realpath_works() {
index d589b063204c7d2d0fa903d6ff2848cd2de84454..7591ebf67f868e8ee43c71568f8aadc2845fd804 100644 (file)
@@ -21,6 +21,8 @@
 //! one that doesn't; the one that doesn't might get decent parallel
 //! build speedups.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rustc_back"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(hash)]
-#![feature(int_uint)]
+#![feature(old_fs)]
 #![feature(old_io)]
-#![feature(os)]
 #![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(env)]
+#![feature(rand)]
+#![feature(path_ext)]
+#![feature(step_by)]
+#![cfg_attr(test, feature(test, rand))]
 
 extern crate syntax;
 extern crate serialize;
@@ -48,6 +51,7 @@ extern crate serialize;
 
 pub mod abi;
 pub mod archive;
+pub mod tempdir;
 pub mod arm;
 pub mod fs;
 pub mod mips;
index cb44fe117f54645d7740dd287e0355f2b3fb40d1..b46150f75d084516102e96252fc7017489955254 100644 (file)
@@ -56,7 +56,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
                 -a:0:64-n32".to_string()
           }
 
-          abi::OsFreebsd | abi::OsDragonfly | abi::OsOpenbsd => {
+          abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd => {
             "E-p:32:32:32\
                 -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
                 -f32:32:32-f64:64:64\
index 7ee357fb1eaf35d7a28c8e4ea5c1559872535119..c7fa7aa879ac272c440982fe5ece76fadd3a70c0 100644 (file)
@@ -56,7 +56,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
                 -a:0:64-n32".to_string()
           }
 
-          abi::OsFreebsd | abi::OsDragonfly | abi::OsOpenbsd => {
+          abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd => {
             "e-p:32:32:32\
                 -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
                 -f32:32:32-f64:64:64\
index e7419d4bec30747717d0bf68c88a3a26db383d7b..ff3f0b78f91b317fae4c0485a0a835c796fdb8cf 100644 (file)
@@ -8,28 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 use std::collections::HashSet;
 use std::env;
-use std::old_io::IoError;
+use std::io;
+use std::path::{Path, PathBuf};
 use syntax::ast;
 
-pub struct RPathConfig<F, G> where
-    F: FnOnce() -> Path,
-    G: FnMut(&Path) -> Result<Path, IoError>,
-{
-    pub used_crates: Vec<(ast::CrateNum, Option<Path>)>,
-    pub out_filename: Path,
+pub struct RPathConfig<'a> {
+    pub used_crates: Vec<(ast::CrateNum, Option<PathBuf>)>,
+    pub out_filename: PathBuf,
     pub is_like_osx: bool,
     pub has_rpath: bool,
-    pub get_install_prefix_lib_path: F,
-    pub realpath: G,
+    pub get_install_prefix_lib_path: &'a mut FnMut() -> PathBuf,
+    pub realpath: &'a mut FnMut(&Path) -> io::Result<PathBuf>,
 }
 
-pub fn get_rpath_flags<F, G>(config: RPathConfig<F, G>) -> Vec<String> where
-    F: FnOnce() -> Path,
-    G: FnMut(&Path) -> Result<Path, IoError>,
-{
+pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
     // No rpath on windows
     if !config.has_rpath {
         return Vec::new();
@@ -49,15 +43,12 @@ pub fn get_rpath_flags<F, G>(config: RPathConfig<F, G>) -> Vec<String> where
 fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
     let mut ret = Vec::new();
     for rpath in rpaths {
-        ret.push(format!("-Wl,-rpath,{}", &(*rpath)[]));
+        ret.push(format!("-Wl,-rpath,{}", &(*rpath)));
     }
     return ret;
 }
 
-fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String> where
-    F: FnOnce() -> Path,
-    G: FnMut(&Path) -> Result<Path, IoError>,
-{
+fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec<String> {
     debug!("output: {:?}", config.out_filename.display());
     debug!("libs:");
     for libpath in libs {
@@ -67,7 +58,7 @@ fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String>
     // Use relative paths to the libraries. Binaries can be moved
     // as long as they maintain the relative relationship to the
     // crates they depend on.
-    let rel_rpaths = get_rpaths_relative_to_output(&mut config, libs);
+    let rel_rpaths = get_rpaths_relative_to_output(config, libs);
 
     // And a final backup rpath to the global library location.
     let fallback_rpaths = vec!(get_install_prefix_rpath(config));
@@ -90,18 +81,12 @@ fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String>
     return rpaths;
 }
 
-fn get_rpaths_relative_to_output<F, G>(config: &mut RPathConfig<F, G>,
-                                       libs: &[Path]) -> Vec<String> where
-    F: FnOnce() -> Path,
-    G: FnMut(&Path) -> Result<Path, IoError>,
-{
+fn get_rpaths_relative_to_output(config: &mut RPathConfig,
+                                 libs: &[PathBuf]) -> Vec<String> {
     libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
 }
 
-fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, lib: &Path) -> String where
-    F: FnOnce() -> Path,
-    G: FnMut(&Path) -> Result<Path, IoError>,
-{
+fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String {
     // Mac doesn't appear to support $ORIGIN
     let prefix = if config.is_like_osx {
         "@loader_path"
@@ -114,22 +99,63 @@ fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, lib: &Path
     lib.pop();
     let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap();
     output.pop();
-    let relative = lib.path_relative_from(&output);
-    let relative = relative.expect("could not create rpath relative to output");
+    let relative = path_relative_from(&lib, &output)
+        .expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib));
     // FIXME (#9639): This needs to handle non-utf8 paths
-    format!("{}/{}",
-            prefix,
-            relative.as_str().expect("non-utf8 component in path"))
+    format!("{}/{}", prefix,
+            relative.to_str().expect("non-utf8 component in path"))
 }
 
-fn get_install_prefix_rpath<F, G>(config: RPathConfig<F, G>) -> String where
-    F: FnOnce() -> Path,
-    G: FnMut(&Path) -> Result<Path, IoError>,
-{
+// This routine is adapted from the *old* Path's `path_relative_from`
+// function, which works differently from the new `relative_from` function.
+// In particular, this handles the case on unix where both paths are
+// absolute but with only the root as the common directory.
+fn path_relative_from(path: &Path, base: &Path) -> Option<PathBuf> {
+    use std::path::Component;
+
+    if path.is_absolute() != base.is_absolute() {
+        if path.is_absolute() {
+            Some(PathBuf::from(path))
+        } else {
+            None
+        }
+    } else {
+        let mut ita = path.components();
+        let mut itb = base.components();
+        let mut comps: Vec<Component> = vec![];
+        loop {
+            match (ita.next(), itb.next()) {
+                (None, None) => break,
+                (Some(a), None) => {
+                    comps.push(a);
+                    comps.extend(ita.by_ref());
+                    break;
+                }
+                (None, _) => comps.push(Component::ParentDir),
+                (Some(a), Some(b)) if comps.is_empty() && a == b => (),
+                (Some(a), Some(b)) if b == Component::CurDir => comps.push(a),
+                (Some(_), Some(b)) if b == Component::ParentDir => return None,
+                (Some(a), Some(_)) => {
+                    comps.push(Component::ParentDir);
+                    for _ in itb {
+                        comps.push(Component::ParentDir);
+                    }
+                    comps.push(a);
+                    comps.extend(ita.by_ref());
+                    break;
+                }
+            }
+        }
+        Some(comps.iter().map(|c| c.as_os_str()).collect())
+    }
+}
+
+
+fn get_install_prefix_rpath(config: &mut RPathConfig) -> String {
     let path = (config.get_install_prefix_lib_path)();
     let path = env::current_dir().unwrap().join(&path);
     // FIXME (#9639): This needs to handle non-utf8 paths
-    path.as_str().expect("non-utf8 component in rpath").to_string()
+    path.to_str().expect("non-utf8 component in rpath").to_string()
 }
 
 fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
@@ -147,6 +173,7 @@ fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
 mod test {
     use super::{RPathConfig};
     use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
+    use std::path::{Path, PathBuf};
 
     #[test]
     fn test_rpaths_to_flags() {
@@ -195,49 +222,31 @@ mod test {
     }
 
     #[test]
-    #[cfg(any(target_os = "linux", target_os = "android"))]
     fn test_rpath_relative() {
-        let config = &mut RPathConfig {
-            used_crates: Vec::new(),
-            out_filename: Path::new("bin/rustc"),
-            get_install_prefix_lib_path: || panic!(),
-            has_rpath: true,
-            is_like_osx: false,
-            realpath: |p| Ok(p.clone())
-        };
-        let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
-        assert_eq!(res, "$ORIGIN/../lib");
-    }
-
-    #[test]
-    #[cfg(any(target_os = "freebsd",
-              target_os = "dragonfly",
-              target_os = "openbsd"))]
-    fn test_rpath_relative() {
-        let config = &mut RPathConfig {
-            used_crates: Vec::new(),
-            has_rpath: true,
-            is_like_osx: false,
-            out_filename: Path::new("bin/rustc"),
-            get_install_prefix_lib_path: || panic!(),
-            realpath: |p| Ok(p.clone())
-        };
-        let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
-        assert_eq!(res, "$ORIGIN/../lib");
-    }
-
-    #[test]
-    #[cfg(target_os = "macos")]
-    fn test_rpath_relative() {
-        let config = &mut RPathConfig {
-            used_crates: Vec::new(),
-            has_rpath: true,
-            is_like_osx: true,
-            out_filename: Path::new("bin/rustc"),
-            get_install_prefix_lib_path: || panic!(),
-            realpath: |p| Ok(p.clone())
-        };
-        let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
-        assert_eq!(res, "@loader_path/../lib");
+        if cfg!(target_os = "macos") {
+            let config = &mut RPathConfig {
+                used_crates: Vec::new(),
+                has_rpath: true,
+                is_like_osx: true,
+                out_filename: PathBuf::from("bin/rustc"),
+                get_install_prefix_lib_path: &mut || panic!(),
+                realpath: &mut |p| Ok(p.to_path_buf()),
+            };
+            let res = get_rpath_relative_to_output(config,
+                                                   Path::new("lib/libstd.so"));
+            assert_eq!(res, "@loader_path/../lib");
+        } else {
+            let config = &mut RPathConfig {
+                used_crates: Vec::new(),
+                out_filename: PathBuf::from("bin/rustc"),
+                get_install_prefix_lib_path: &mut || panic!(),
+                has_rpath: true,
+                is_like_osx: false,
+                realpath: &mut |p| Ok(p.to_path_buf()),
+            };
+            let res = get_rpath_relative_to_output(config,
+                                                   Path::new("lib/libstd.so"));
+            assert_eq!(res, "$ORIGIN/../lib");
+        }
     }
 }
index 6654a46f7c31b51cdaee38add94af4f904eb793e..898f20e74518fca23d44b4912ea5da69d2d7eb47 100644 (file)
@@ -14,7 +14,7 @@
 
 #![allow(deprecated)] // to_be32
 
-use std::iter::{range_step, repeat};
+use std::iter::repeat;
 use std::num::Int;
 use std::slice::bytes::{MutableByteVector, copy_memory};
 use serialize::hex::ToHex;
@@ -64,7 +64,7 @@ impl ToBits for u64 {
 fn add_bytes_to_bits<T: Int + ToBits>(bits: T, bytes: T) -> T {
     let (new_high_bits, new_low_bits) = bytes.to_bits();
 
-    if new_high_bits > Int::zero() {
+    if new_high_bits > T::zero() {
         panic!("numeric overflow occurred.")
     }
 
@@ -90,36 +90,36 @@ trait FixedBuffer {
 
     /// Zero the buffer up until the specified index. The buffer position currently must not be
     /// greater than that index.
-    fn zero_until(&mut self, idx: uint);
+    fn zero_until(&mut self, idx: usize);
 
     /// Get a slice of the buffer of the specified size. There must be at least that many bytes
     /// remaining in the buffer.
-    fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8];
+    fn next<'s>(&'s mut self, len: usize) -> &'s mut [u8];
 
     /// Get the current buffer. The buffer must already be full. This clears the buffer as well.
     fn full_buffer<'s>(&'s mut self) -> &'s [u8];
 
     /// Get the current position of the buffer.
-    fn position(&self) -> uint;
+    fn position(&self) -> usize;
 
     /// Get the number of bytes remaining in the buffer until it is full.
-    fn remaining(&self) -> uint;
+    fn remaining(&self) -> usize;
 
     /// Get the size of the buffer
-    fn size(&self) -> uint;
+    fn size(&self) -> usize;
 }
 
 /// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
 struct FixedBuffer64 {
     buffer: [u8; 64],
-    buffer_idx: uint,
+    buffer_idx: usize,
 }
 
 impl FixedBuffer64 {
     /// Create a new FixedBuffer64
     fn new() -> FixedBuffer64 {
         return FixedBuffer64 {
-            buffer: [0u8; 64],
+            buffer: [0; 64],
             buffer_idx: 0
         };
     }
@@ -139,15 +139,15 @@ impl FixedBuffer for FixedBuffer64 {
             let buffer_remaining = size - self.buffer_idx;
             if input.len() >= buffer_remaining {
                     copy_memory(
-                        &mut self.buffer[self.buffer_idx..size],
-                        &input[..buffer_remaining]);
+                        &input[..buffer_remaining],
+                        &mut self.buffer[self.buffer_idx..size]);
                 self.buffer_idx = 0;
                 func(&self.buffer);
                 i += buffer_remaining;
             } else {
                 copy_memory(
-                    &mut self.buffer[self.buffer_idx..self.buffer_idx + input.len()],
-                    input);
+                    input,
+                    &mut self.buffer[self.buffer_idx..self.buffer_idx + input.len()]);
                 self.buffer_idx += input.len();
                 return;
             }
@@ -165,8 +165,8 @@ impl FixedBuffer for FixedBuffer64 {
         // be empty.
         let input_remaining = input.len() - i;
         copy_memory(
-            &mut self.buffer[..input_remaining],
-            &input[i..]);
+            &input[i..],
+            &mut self.buffer[..input_remaining]);
         self.buffer_idx += input_remaining;
     }
 
@@ -174,13 +174,13 @@ impl FixedBuffer for FixedBuffer64 {
         self.buffer_idx = 0;
     }
 
-    fn zero_until(&mut self, idx: uint) {
+    fn zero_until(&mut self, idx: usize) {
         assert!(idx >= self.buffer_idx);
         self.buffer[self.buffer_idx..idx].set_memory(0);
         self.buffer_idx = idx;
     }
 
-    fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8] {
+    fn next<'s>(&'s mut self, len: usize) -> &'s mut [u8] {
         self.buffer_idx += len;
         return &mut self.buffer[self.buffer_idx - len..self.buffer_idx];
     }
@@ -191,11 +191,11 @@ impl FixedBuffer for FixedBuffer64 {
         return &self.buffer[..64];
     }
 
-    fn position(&self) -> uint { self.buffer_idx }
+    fn position(&self) -> usize { self.buffer_idx }
 
-    fn remaining(&self) -> uint { 64 - self.buffer_idx }
+    fn remaining(&self) -> usize { 64 - self.buffer_idx }
 
-    fn size(&self) -> uint { 64 }
+    fn size(&self) -> usize { 64 }
 }
 
 /// The StandardPadding trait adds a method useful for Sha256 to a FixedBuffer struct.
@@ -204,11 +204,11 @@ trait StandardPadding {
     /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least
     /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled
     /// with zeros again until only rem bytes are remaining.
-    fn standard_padding<F>(&mut self, rem: uint, func: F) where F: FnMut(&[u8]);
+    fn standard_padding<F>(&mut self, rem: usize, func: F) where F: FnMut(&[u8]);
 }
 
 impl <T: FixedBuffer> StandardPadding for T {
-    fn standard_padding<F>(&mut self, rem: uint, mut func: F) where F: FnMut(&[u8]) {
+    fn standard_padding<F>(&mut self, rem: usize, mut func: F) where F: FnMut(&[u8]) {
         let size = self.size();
 
         self.next(1)[0] = 128;
@@ -244,7 +244,7 @@ pub trait Digest {
     fn reset(&mut self);
 
     /// Get the output size in bits.
-    fn output_bits(&self) -> uint;
+    fn output_bits(&self) -> usize;
 
     /// Convenience function that feeds a string into a digest.
     ///
@@ -258,7 +258,7 @@ pub trait Digest {
     /// Convenience function that retrieves the result of a digest as a
     /// newly allocated vec of bytes.
     fn result_bytes(&mut self) -> Vec<u8> {
-        let mut buf: Vec<u8> = repeat(0u8).take((self.output_bits()+7)/8).collect();
+        let mut buf: Vec<u8> = repeat(0).take((self.output_bits()+7)/8).collect();
         self.result(&mut buf);
         buf
     }
@@ -342,22 +342,24 @@ impl Engine256State {
         let mut g = self.h6;
         let mut h = self.h7;
 
-        let mut w = [0u32; 64];
+        let mut w = [0; 64];
 
         // Sha-512 and Sha-256 use basically the same calculations which are implemented
         // by these macros. Inlining the calculations seems to result in better generated code.
         macro_rules! schedule_round { ($t:expr) => (
-                w[$t] = sigma1(w[$t - 2]) + w[$t - 7] + sigma0(w[$t - 15]) + w[$t - 16];
-                )
+            w[$t] = sigma1(w[$t - 2]).wrapping_add(w[$t - 7])
+                .wrapping_add(sigma0(w[$t - 15])).wrapping_add(w[$t - 16]);
+            )
         }
 
         macro_rules! sha2_round {
             ($A:ident, $B:ident, $C:ident, $D:ident,
              $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
                 {
-                    $H += sum1($E) + ch($E, $F, $G) + $K[$t] + w[$t];
-                    $D += $H;
-                    $H += sum0($A) + maj($A, $B, $C);
+                    $H = $H.wrapping_add(sum1($E)).wrapping_add(ch($E, $F, $G))
+                        .wrapping_add($K[$t]).wrapping_add(w[$t]);
+                    $D = $D.wrapping_add($H);
+                    $H = $H.wrapping_add(sum0($A)).wrapping_add(maj($A, $B, $C));
                 }
              )
         }
@@ -366,7 +368,7 @@ impl Engine256State {
 
         // Putting the message schedule inside the same loop as the round calculations allows for
         // the compiler to generate better code.
-        for t in range_step(0, 48, 8) {
+        for t in (0..48).step_by(8) {
             schedule_round!(t + 16);
             schedule_round!(t + 17);
             schedule_round!(t + 18);
@@ -386,7 +388,7 @@ impl Engine256State {
             sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
         }
 
-        for t in range_step(48, 64, 8) {
+        for t in (48..64).step_by(8) {
             sha2_round!(a, b, c, d, e, f, g, h, K32, t);
             sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
             sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
@@ -397,14 +399,14 @@ impl Engine256State {
             sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
         }
 
-        self.h0 += a;
-        self.h1 += b;
-        self.h2 += c;
-        self.h3 += d;
-        self.h4 += e;
-        self.h5 += f;
-        self.h6 += g;
-        self.h7 += h;
+        self.h0 = self.h0.wrapping_add(a);
+        self.h1 = self.h1.wrapping_add(b);
+        self.h2 = self.h2.wrapping_add(c);
+        self.h3 = self.h3.wrapping_add(d);
+        self.h4 = self.h4.wrapping_add(e);
+        self.h5 = self.h5.wrapping_add(f);
+        self.h6 = self.h6.wrapping_add(g);
+        self.h7 = self.h7.wrapping_add(h);
     }
 }
 
@@ -512,7 +514,7 @@ impl Digest for Sha256 {
         self.engine.reset(&H256);
     }
 
-    fn output_bits(&self) -> uint { 256 }
+    fn output_bits(&self) -> usize { 256 }
 }
 
 static H256: [u32; 8] = [
@@ -535,7 +537,7 @@ mod tests {
     use self::rand::isaac::IsaacRng;
     use serialize::hex::FromHex;
     use std::iter::repeat;
-    use std::num::Int;
+    use std::u64;
     use super::{Digest, Sha256, FixedBuffer};
 
     // A normal addition - no overflow occurs
@@ -546,9 +548,9 @@ mod tests {
 
     // A simple failure case - adding 1 to the max value
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_add_bytes_to_bits_overflow() {
-        super::add_bytes_to_bits::<u64>(Int::max_value(), 1);
+        super::add_bytes_to_bits::<u64>(u64::MAX, 1);
     }
 
     struct Test {
@@ -604,14 +606,14 @@ mod tests {
 
         let tests = wikipedia_tests;
 
-        let mut sh = box Sha256::new();
+        let mut sh: Box<_> = box Sha256::new();
 
         test_hash(&mut *sh, &tests);
     }
 
     /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is
     /// correct.
-    fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: uint, expected: &str) {
+    fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: usize, expected: &str) {
         let total_size = 1000000;
         let buffer: Vec<u8> = repeat('a' as u8).take(blocksize * 2).collect();
         let mut rng = IsaacRng::new_unseeded();
@@ -620,7 +622,7 @@ mod tests {
         digest.reset();
 
         while count < total_size {
-            let next: uint = rng.gen_range(0, 2 * blocksize + 1);
+            let next: usize = rng.gen_range(0, 2 * blocksize + 1);
             let remaining = total_size - count;
             let size = if next > remaining { remaining } else { next };
             digest.input(&buffer[..size]);
@@ -658,7 +660,7 @@ mod bench {
     #[bench]
     pub fn sha256_10(b: &mut Bencher) {
         let mut sh = Sha256::new();
-        let bytes = [1u8; 10];
+        let bytes = [1; 10];
         b.iter(|| {
             sh.input(&bytes);
         });
@@ -668,7 +670,7 @@ mod bench {
     #[bench]
     pub fn sha256_1k(b: &mut Bencher) {
         let mut sh = Sha256::new();
-        let bytes = [1u8; 1024];
+        let bytes = [1; 1024];
         b.iter(|| {
             sh.input(&bytes);
         });
@@ -678,7 +680,7 @@ mod bench {
     #[bench]
     pub fn sha256_64k(b: &mut Bencher) {
         let mut sh = Sha256::new();
-        let bytes = [1u8; 65536];
+        let bytes = [1; 65536];
         b.iter(|| {
             sh.input(&bytes);
         });
index c33d10bfbab39aaef7a08149d03304f76cfe0230..f9416d53a8fa3a51dcf74ab662d2393d152ab8d3 100644 (file)
@@ -48,7 +48,6 @@
 
 use std::fmt;
 use std::hash::{Hash, SipHasher, Hasher};
-use std::iter::range_step;
 use syntax::ast;
 use syntax::visit;
 
@@ -64,7 +63,7 @@ impl Svh {
     }
 
     pub fn as_str<'a>(&'a self) -> &'a str {
-        &self.hash[]
+        &self.hash
     }
 
     pub fn calculate(metadata: &Vec<String>, krate: &ast::Crate) -> Svh {
@@ -103,7 +102,7 @@ impl Svh {
 
         let hash = state.finish();
         return Svh {
-            hash: range_step(0, 64, 4).map(|i| hex(hash >> i)).collect()
+            hash: (0..64).step_by(4).map(|i| hex(hash >> i)).collect()
         };
 
         fn hex(b: u64) -> char {
@@ -188,8 +187,8 @@ mod svh_visitor {
         SawTy,
         SawGenerics,
         SawFn,
-        SawTyMethod,
-        SawTraitMethod,
+        SawTraitItem,
+        SawImplItem,
         SawStructField,
         SawVariant,
         SawExplicitSelf,
@@ -222,7 +221,7 @@ mod svh_visitor {
 
         SawExprLoop(Option<token::InternedString>),
         SawExprField(token::InternedString),
-        SawExprTupField(uint),
+        SawExprTupField(usize),
         SawExprBreak(Option<token::InternedString>),
         SawExprAgain(Option<token::InternedString>),
 
@@ -244,8 +243,7 @@ mod svh_visitor {
         SawExprAssignOp(ast::BinOp_),
         SawExprIndex,
         SawExprRange,
-        SawExprPath,
-        SawExprQPath,
+        SawExprPath(Option<usize>),
         SawExprAddrOf(ast::Mutability),
         SawExprRet,
         SawExprInlineAsm(&'a ast::InlineAsm),
@@ -277,8 +275,7 @@ mod svh_visitor {
             ExprTupField(_, id)      => SawExprTupField(id.node),
             ExprIndex(..)            => SawExprIndex,
             ExprRange(..)            => SawExprRange,
-            ExprPath(..)             => SawExprPath,
-            ExprQPath(..)            => SawExprQPath,
+            ExprPath(ref qself, _)   => SawExprPath(qself.as_ref().map(|q| q.position)),
             ExprAddrOf(m, _)         => SawExprAddrOf(m),
             ExprBreak(id)            => SawExprBreak(id.map(content)),
             ExprAgain(id)            => SawExprAgain(id.map(content)),
@@ -329,7 +326,7 @@ mod svh_visitor {
             // macro invocations, namely macro_rules definitions,
             // *can* appear as items, even in the expanded crate AST.
 
-            if &macro_name(mac)[] == "macro_rules" {
+            if &macro_name(mac)[..] == "macro_rules" {
                 // Pretty-printing definition to a string strips out
                 // surface artifacts (currently), such as the span
                 // information, yielding a content-based hash.
@@ -356,7 +353,7 @@ mod svh_visitor {
             fn macro_name(mac: &Mac) -> token::InternedString {
                 match &mac.node {
                     &MacInvocTT(ref path, ref _tts, ref _stx_ctxt) => {
-                        let s = &path.segments[];
+                        let s = &path.segments;
                         assert_eq!(s.len(), 1);
                         content(s[0].identifier)
                     }
@@ -465,12 +462,12 @@ mod svh_visitor {
             SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s)
         }
 
-        fn visit_ty_method(&mut self, t: &TypeMethod) {
-            SawTyMethod.hash(self.st); visit::walk_ty_method(self, t)
+        fn visit_trait_item(&mut self, ti: &TraitItem) {
+            SawTraitItem.hash(self.st); visit::walk_trait_item(self, ti)
         }
 
-        fn visit_trait_item(&mut self, t: &TraitItem) {
-            SawTraitMethod.hash(self.st); visit::walk_trait_item(self, t)
+        fn visit_impl_item(&mut self, ii: &ImplItem) {
+            SawImplItem.hash(self.st); visit::walk_impl_item(self, ii)
         }
 
         fn visit_struct_field(&mut self, s: &StructField) {
index 904b337c03f46e63e664126f01cc470d457c013a..7dcd6ba6cd11f9fae652f40f996aa23d88ba43c8 100644 (file)
@@ -8,13 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::old_io::{Command, IoError, OtherIoError};
+use std::io;
+use std::process::Command;
 use target::TargetOptions;
 
 use self::Arch::*;
 
 #[allow(non_camel_case_types)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum Arch {
     Armv7,
     Armv7s,
@@ -40,16 +41,16 @@ pub fn get_sdk_root(sdk_name: &str) -> String {
                       .arg("--show-sdk-path")
                       .arg("-sdk")
                       .arg(sdk_name)
-                      .spawn()
-                      .and_then(|c| c.wait_with_output())
+                      .output()
                       .and_then(|output| {
                           if output.status.success() {
-                              Ok(String::from_utf8(output.output).unwrap())
+                              Ok(String::from_utf8(output.stdout).unwrap())
                           } else {
-                              Err(IoError {
-                                  kind: OtherIoError,
-                                  desc: "process exit with error",
-                                  detail: String::from_utf8(output.error).ok()})
+                              let error = String::from_utf8(output.stderr);
+                              let error = format!("process exit with error: {}",
+                                                  error.unwrap());
+                              Err(io::Error::new(io::ErrorKind::Other,
+                                                 &error[..]))
                           }
                       });
 
diff --git a/src/librustc_back/target/bitrig_base.rs b/src/librustc_back/target/bitrig_base.rs
new file mode 100644 (file)
index 0000000..6e5a48c
--- /dev/null
@@ -0,0 +1,28 @@
+// 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 target::TargetOptions;
+use std::default::Default;
+
+pub fn opts() -> TargetOptions {
+    TargetOptions {
+        linker: "cc".to_string(),
+        dynamic_linking: true,
+        executables: true,
+        morestack: false,
+        linker_is_gnu: true,
+        has_rpath: true,
+        position_independent_executables: true,
+        pre_link_args: vec!(
+        ),
+
+        .. Default::default()
+    }
+}
index 79d79b7e736bb89f46ac274a70aa32f05989053b..a56621ff97ea541cba2cd0e500a2ce471d4ef5d1 100644 (file)
@@ -32,4 +32,3 @@ pub fn opts() -> TargetOptions {
         .. Default::default()
     }
 }
-
index ab8398fc60511d4ba9e98d27feb0a9aa188e3b42..dcf1a12f2c9ad762dd6f1b84cc0227e473d88c9b 100644 (file)
@@ -27,4 +27,3 @@ pub fn opts() -> TargetOptions {
         .. Default::default()
     }
 }
-
index 01a5f0d6e20f881c481ad0e62f8153fdc21d3ece..07528df97f1334686123652efacf0c9525324fd0 100644 (file)
@@ -48,7 +48,7 @@
 use serialize::json::Json;
 use syntax::{diagnostic, abi};
 use std::default::Default;
-use std::old_io::fs::PathExtensions;
+use std::io::prelude::*;
 
 mod windows_base;
 mod linux_base;
@@ -56,6 +56,7 @@ mod apple_base;
 mod apple_ios_base;
 mod freebsd_base;
 mod dragonfly_base;
+mod bitrig_base;
 mod openbsd_base;
 
 mod armv7_apple_ios;
@@ -80,6 +81,7 @@ mod x86_64_apple_ios;
 mod x86_64_pc_windows_gnu;
 mod x86_64_unknown_freebsd;
 mod x86_64_unknown_dragonfly;
+mod x86_64_unknown_bitrig;
 mod x86_64_unknown_linux_gnu;
 mod x86_64_unknown_openbsd;
 
@@ -155,7 +157,7 @@ pub struct TargetOptions {
     /// particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false.
     pub is_like_osx: bool,
     /// Whether the target toolchain is like Windows'. Only useful for compiling against Windows,
-    /// only realy used for figuring out how to find libraries, since Windows uses its own
+    /// only really used for figuring out how to find libraries, since Windows uses its own
     /// library naming convention. Defaults to false.
     pub is_like_windows: bool,
     /// Whether the target toolchain is like Android's. Only useful for compiling against Android.
@@ -237,7 +239,7 @@ impl Target {
                      .and_then(|os| os.map(|s| s.to_string())) {
                 Some(val) => val,
                 None =>
-                    handler.fatal(&format!("Field {} in target specification is required", name)[])
+                    handler.fatal(&format!("Field {} in target specification is required", name))
             }
         };
 
@@ -300,22 +302,26 @@ impl Target {
         base
     }
 
-    /// Search RUST_TARGET_PATH for a JSON file specifying the given target triple. Note that it
-    /// could also just be a bare filename already, so also check for that. If one of the hardcoded
-    /// targets we know about, just return it directly.
+    /// Search RUST_TARGET_PATH for a JSON file specifying the given target
+    /// triple. Note that it could also just be a bare filename already, so also
+    /// check for that. If one of the hardcoded targets we know about, just
+    /// return it directly.
     ///
-    /// The error string could come from any of the APIs called, including filesystem access and
-    /// JSON decoding.
+    /// The error string could come from any of the APIs called, including
+    /// filesystem access and JSON decoding.
     pub fn search(target: &str) -> Result<Target, String> {
         use std::env;
         use std::ffi::OsString;
-        use std::old_io::File;
-        use std::old_path::Path;
+        use std::fs::File;
+        use std::path::{Path, PathBuf};
         use serialize::json;
 
         fn load_file(path: &Path) -> Result<Target, String> {
-            let mut f = try!(File::open(path).map_err(|e| format!("{:?}", e)));
-            let obj = try!(json::from_reader(&mut f).map_err(|e| format!("{:?}", e)));
+            let mut f = try!(File::open(path).map_err(|e| e.to_string()));
+            let mut contents = Vec::new();
+            try!(f.read_to_end(&mut contents).map_err(|e| e.to_string()));
+            let obj = try!(json::from_reader(&mut &contents[..])
+                                .map_err(|e| e.to_string()));
             Ok(Target::from_json(obj))
         }
 
@@ -361,6 +367,7 @@ impl Target {
             i686_unknown_dragonfly,
             x86_64_unknown_dragonfly,
 
+            x86_64_unknown_bitrig,
             x86_64_unknown_openbsd,
 
             x86_64_apple_darwin,
@@ -386,15 +393,16 @@ impl Target {
         let path = {
             let mut target = target.to_string();
             target.push_str(".json");
-            Path::new(target)
+            PathBuf::from(target)
         };
 
-        let target_path = env::var_os("RUST_TARGET_PATH").unwrap_or(OsString::from_str(""));
+        let target_path = env::var_os("RUST_TARGET_PATH")
+                              .unwrap_or(OsString::new());
 
         // FIXME 16351: add a sane default search path?
 
         for dir in env::split_paths(&target_path) {
-            let p =  dir.join(path.clone());
+            let p =  dir.join(&path);
             if p.is_file() {
                 return load_file(&p);
             }
index 42220a87bd414891ea17830790cdfcdeefeaeb9d..0f2ab32be2431e059a37eeec09adb539ba7bbcef 100644 (file)
@@ -20,9 +20,13 @@ pub fn opts() -> TargetOptions {
         linker_is_gnu: true,
         has_rpath: true,
         pre_link_args: vec!(
+            // GNU-style linkers will use this to omit linking to libraries
+            // which don't actually fulfill any relocations, but only for
+            // libraries which follow this flag.  Thus, use it before
+            // specifying libraries to link to.
+            "-Wl,--as-needed".to_string(),
         ),
         position_independent_executables: true,
         .. Default::default()
     }
 }
-
diff --git a/src/librustc_back/target/x86_64_unknown_bitrig.rs b/src/librustc_back/target/x86_64_unknown_bitrig.rs
new file mode 100644 (file)
index 0000000..7b7877c
--- /dev/null
@@ -0,0 +1,28 @@
+// 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 target::Target;
+
+pub fn target() -> Target {
+    let mut base = super::bitrig_base::opts();
+    base.pre_link_args.push("-m64".to_string());
+
+    Target {
+        data_layout: "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+                     f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+                     s0:64:64-f80:128:128-n8:16:32:64-S128".to_string(),
+        llvm_target: "x86_64-unknown-bitrig".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        arch: "x86_64".to_string(),
+        target_os: "bitrig".to_string(),
+        options: base,
+    }
+}
diff --git a/src/librustc_back/tempdir.rs b/src/librustc_back/tempdir.rs
new file mode 100644 (file)
index 0000000..b12732f
--- /dev/null
@@ -0,0 +1,120 @@
+// Copyright 2015 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 std::env;
+use std::io::{self, Error, ErrorKind};
+use std::fs;
+use std::path::{self, PathBuf, Path};
+use std::rand::{thread_rng, Rng};
+
+/// A wrapper for a path to temporary directory implementing automatic
+/// scope-based deletion.
+pub struct TempDir {
+    path: Option<PathBuf>,
+}
+
+// How many times should we (re)try finding an unused random name? It should be
+// enough that an attacker will run out of luck before we run out of patience.
+const NUM_RETRIES: u32 = 1 << 31;
+// How many characters should we include in a random file name? It needs to
+// be enough to dissuade an attacker from trying to preemptively create names
+// of that length, but not so huge that we unnecessarily drain the random number
+// generator of entropy.
+const NUM_RAND_CHARS: usize = 12;
+
+impl TempDir {
+    /// Attempts to make a temporary directory inside of `tmpdir` whose name
+    /// will have the prefix `prefix`. The directory will be automatically
+    /// deleted once the returned wrapper is destroyed.
+    ///
+    /// If no directory can be created, `Err` is returned.
+    #[allow(deprecated)] // rand usage
+    pub fn new_in<P: AsRef<Path>>(tmpdir: P, prefix: &str)
+                                  -> io::Result<TempDir> {
+        let storage;
+        let mut tmpdir = tmpdir.as_ref();
+        if !tmpdir.is_absolute() {
+            let cur_dir = try!(env::current_dir());
+            storage = cur_dir.join(tmpdir);
+            tmpdir = &storage;
+            // return TempDir::new_in(&cur_dir.join(tmpdir), prefix);
+        }
+
+        let mut rng = thread_rng();
+        for _ in 0..NUM_RETRIES {
+            let suffix: String = rng.gen_ascii_chars().take(NUM_RAND_CHARS).collect();
+            let leaf = if prefix.len() > 0 {
+                format!("{}.{}", prefix, suffix)
+            } else {
+                // If we're given an empty string for a prefix, then creating a
+                // directory starting with "." would lead to it being
+                // semi-invisible on some systems.
+                suffix
+            };
+            let path = tmpdir.join(&leaf);
+            match fs::create_dir(&path) {
+                Ok(_) => return Ok(TempDir { path: Some(path) }),
+                Err(ref e) if e.kind() == ErrorKind::AlreadyExists => {}
+                Err(e) => return Err(e)
+            }
+        }
+
+        Err(Error::new(ErrorKind::AlreadyExists,
+                       "too many temporary directories already exist"))
+    }
+
+    /// Attempts to make a temporary directory inside of `env::temp_dir()` whose
+    /// name will have the prefix `prefix`. The directory will be automatically
+    /// deleted once the returned wrapper is destroyed.
+    ///
+    /// If no directory can be created, `Err` is returned.
+    #[allow(deprecated)]
+    pub fn new(prefix: &str) -> io::Result<TempDir> {
+        TempDir::new_in(&env::temp_dir(), prefix)
+    }
+
+    /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper.
+    /// This discards the wrapper so that the automatic deletion of the
+    /// temporary directory is prevented.
+    pub fn into_path(mut self) -> PathBuf {
+        self.path.take().unwrap()
+    }
+
+    /// Access the wrapped `std::path::Path` to the temporary directory.
+    pub fn path(&self) -> &path::Path {
+        self.path.as_ref().unwrap()
+    }
+
+    /// Close and remove the temporary directory
+    ///
+    /// Although `TempDir` removes the directory on drop, in the destructor
+    /// any errors are ignored. To detect errors cleaning up the temporary
+    /// directory, call `close` instead.
+    pub fn close(mut self) -> io::Result<()> {
+        self.cleanup_dir()
+    }
+
+    fn cleanup_dir(&mut self) -> io::Result<()> {
+        match self.path {
+            Some(ref p) => fs::remove_dir_all(p),
+            None => Ok(())
+        }
+    }
+}
+
+impl Drop for TempDir {
+    fn drop(&mut self) {
+        let _ = self.cleanup_dir();
+    }
+}
+
+// the tests for this module need to change the path using change_dir,
+// and this doesn't play nicely with other tests so these unit tests are located
+// in src/test/run-pass/tempfile.rs
index 9d1b7347d0651039a799e10bccfd7e3a1113fd21..1c6eacc355947850044b035fb5d6db4f8690a1c9 100644 (file)
@@ -45,13 +45,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os)
             "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
           }
 
-          abi::OsFreebsd => {
-            "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
-          }
-          abi::OsDragonfly => {
-            "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
-          }
-          abi::OsOpenbsd => {
+          abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd => {
             "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
           }
 
index 2f13bb3158119ad6e8a8f1661bd36b2014f431f7..d016bd12c698fdd5646cafbf4f5c7e298ba10c7a 100644 (file)
@@ -47,17 +47,7 @@ pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs
                 s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
           }
 
-          abi::OsFreebsd => {
-            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
-                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a:0:64-\
-                s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
-          }
-          abi::OsDragonfly => {
-            "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
-                f32:32:32-f64:64:64-v64:64:64-v128:128:128-a:0:64-\
-                s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
-          }
-          abi::OsOpenbsd => {
+          abi::OsFreebsd | abi::OsDragonfly | abi::OsBitrig | abi::OsOpenbsd => {
             "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
                 f32:32:32-f64:64:64-v64:64:64-v128:128:128-a:0:64-\
                 s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
index 370a5d48decaec85298da73575468e6a98efb5f0..93a2a5d125778eeab36329aa661ec2dec366a926 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rustc_bitflags"]
 #![feature(staged_api)]
 #![staged_api]
@@ -15,6 +18,7 @@
 #![feature(no_std)]
 #![no_std]
 #![unstable(feature = "rustc_private")]
+#![cfg_attr(test, feature(hash))]
 
 //! A typesafe bitmask flag generator.
 
 /// The flags should only be defined for integer types, otherwise unexpected
 /// type errors may occur at compile time.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```{.rust}
+/// # #![feature(rustc_private)]
 /// #[macro_use] extern crate rustc_bitflags;
 ///
 /// bitflags! {
@@ -55,6 +60,7 @@
 /// The generated `struct`s can also be extended with type and trait implementations:
 ///
 /// ```{.rust}
+/// # #![feature(rustc_private)]
 /// #[macro_use] extern crate rustc_bitflags;
 ///
 /// use std::fmt;
@@ -83,7 +89,7 @@
 ///     let mut flags = FLAG_A | FLAG_B;
 ///     flags.clear();
 ///     assert!(flags.is_empty());
-///     assert_eq!(format!("{:?}", flags).as_slice(), "hi!");
+///     assert_eq!(format!("{:?}", flags), "hi!");
 /// }
 /// ```
 ///
@@ -316,7 +322,7 @@ mod tests {
 
     bitflags! {
         flags AnotherSetOfFlags: i8 {
-            const AnotherFlag = -1_i8,
+            const AnotherFlag = -1,
         }
     }
 
@@ -327,7 +333,7 @@ mod tests {
         assert_eq!(FlagABC.bits(), 0b00000111);
 
         assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
-        assert_eq!(AnotherFlag.bits(), !0_i8);
+        assert_eq!(AnotherFlag.bits(), !0);
     }
 
     #[test]
@@ -338,7 +344,7 @@ mod tests {
         assert!(Flags::from_bits(0b11) == Some(FlagA | FlagB));
         assert!(Flags::from_bits(0b1000) == None);
 
-        assert!(AnotherSetOfFlags::from_bits(!0_i8) == Some(AnotherFlag));
+        assert!(AnotherSetOfFlags::from_bits(!0) == Some(AnotherFlag));
     }
 
     #[test]
@@ -350,7 +356,7 @@ mod tests {
         assert!(Flags::from_bits_truncate(0b1000) == Flags::empty());
         assert!(Flags::from_bits_truncate(0b1001) == FlagA);
 
-        assert!(AnotherSetOfFlags::from_bits_truncate(0_i8) == AnotherSetOfFlags::empty());
+        assert!(AnotherSetOfFlags::from_bits_truncate(0) == AnotherSetOfFlags::empty());
     }
 
     #[test]
index c5a304289227117c4840801cc637928790e4f769..08f0897e7617e918e320dedd16d3ae3201cdd45b 100644 (file)
@@ -53,8 +53,8 @@ Here `x` represents some variable, `LV.f` is a field reference,
 and `*LV` is a pointer dereference. There is no auto-deref or other
 niceties. This means that if you have a type like:
 
-```text
-struct S { f: uint }
+```rust
+struct S { f: i32 }
 ```
 
 and a variable `a: Box<S>`, then the rust expression `a.f` would correspond
@@ -63,8 +63,8 @@ to an `LV` of `(*a).f`.
 Here is the formal grammar for the types we'll consider:
 
 ```text
-TY = () | S<'LT...> | Box<TY> | & 'LT MQ TY
-MQ = mut | imm | const
+TY = i32 | bool | S<'LT...> | Box<TY> | & 'LT MQ TY
+MQ = mut | imm
 ```
 
 Most of these types should be pretty self explanatory. Here `S` is a
@@ -82,13 +82,13 @@ SD = struct S<'LT...> { (f: TY)... }
 
 Now, imagine we had a program like this:
 
-```text
-struct Foo { f: uint, g: uint }
+```rust
+struct Foo { f: i32, g: i32 }
 ...
 'a: {
-  let mut x: Box<Foo> = ...;
-  let y = &mut (*x).f;
-  x = ...;
+    let mut x: Box<Foo> = ...;
+    let y = &mut (*x).f;
+    x = ...;
 }
 ```
 
@@ -198,7 +198,7 @@ The kinds of expressions which in-scope loans can render illegal are:
 
 Now that we hopefully have some kind of intuitive feeling for how the
 borrow checker works, let's look a bit more closely now at the precise
-conditions that it uses. For simplicity I will ignore const loans.
+conditions that it uses.
 
 I will present the rules in a modified form of standard inference
 rules, which looks as follows:
@@ -261,12 +261,11 @@ that will go into the final loan. We'll discuss in more detail below.
 ## Checking mutability
 
 Checking mutability is fairly straightforward. We just want to prevent
-immutable data from being borrowed as mutable. Note that it is ok to
-borrow mutable data as immutable, since that is simply a
-freeze. Formally we define a predicate `MUTABLE(LV, MQ)` which, if
-defined, means that "borrowing `LV` with mutability `MQ` is ok. The
-Rust code corresponding to this predicate is the function
-`check_mutability` in `middle::borrowck::gather_loans`.
+immutable data from being borrowed as mutable. Note that it is ok to borrow
+mutable data as immutable, since that is simply a freeze. The judgement
+`MUTABILITY(LV, MQ)` means the mutability of `LV` is compatible with a borrow
+of mutability `MQ`. The Rust code corresponding to this predicate is the
+function `check_mutability` in `middle::borrowck::gather_loans`.
 
 ### Checking mutability of variables
 
@@ -275,15 +274,14 @@ but also the code in `mem_categorization`.
 
 Let's begin with the rules for variables, which state that if a
 variable is declared as mutable, it may be borrowed any which way, but
-otherwise the variable must be borrowed as immutable or const:
+otherwise the variable must be borrowed as immutable:
 
 ```text
 MUTABILITY(X, MQ)                   // M-Var-Mut
   DECL(X) = mut
 
-MUTABILITY(X, MQ)                   // M-Var-Imm
+MUTABILITY(X, imm)                  // M-Var-Imm
   DECL(X) = imm
-  MQ = imm | const
 ```
 
 ### Checking mutability of owned content
@@ -304,12 +302,11 @@ MUTABILITY(*LV, MQ)                 // M-Deref-Unique
 ### Checking mutability of immutable pointer types
 
 Immutable pointer types like `&T` can only
-be borrowed if MQ is immutable or const:
+be borrowed if MQ is immutable:
 
 ```text
-MUTABILITY(*LV, MQ)                // M-Deref-Borrowed-Imm
+MUTABILITY(*LV, imm)               // M-Deref-Borrowed-Imm
   TYPE(LV) = &Ty
-  MQ == imm | const
 ```
 
 ### Checking mutability of mutable pointer types
@@ -323,12 +320,11 @@ MUTABILITY(*LV, MQ)                 // M-Deref-Borrowed-Mut
 
 ## Checking aliasability
 
-The goal of the aliasability check is to ensure that we never permit
-`&mut` borrows of aliasable data. Formally we define a predicate
-`ALIASABLE(LV, MQ)` which if defined means that
-"borrowing `LV` with mutability `MQ` is ok". The
-Rust code corresponding to this predicate is the function
-`check_aliasability()` in `middle::borrowck::gather_loans`.
+The goal of the aliasability check is to ensure that we never permit `&mut`
+borrows of aliasable data. The judgement `ALIASABLE(LV, MQ)` means the
+aliasability of `LV` is compatible with a borrow of mutability `MQ`. The Rust
+code corresponding to this predicate is the function `check_aliasability()` in
+`middle::borrowck::gather_loans`.
 
 ### Checking aliasability of variables
 
@@ -379,40 +375,6 @@ Formally, we define a predicate `LIFETIME(LV, LT, MQ)`, which states that
 `MQ`". The Rust code corresponding to this predicate is the module
 `middle::borrowck::gather_loans::lifetime`.
 
-### The Scope function
-
-Several of the rules refer to a helper function `SCOPE(LV)=LT`.  The
-`SCOPE(LV)` yields the lifetime `LT` for which the lvalue `LV` is
-guaranteed to exist, presuming that no mutations occur.
-
-The scope of a local variable is the block where it is declared:
-
-```text
-  SCOPE(X) = block where X is declared
-```
-
-The scope of a field is the scope of the struct:
-
-```text
-  SCOPE(LV.f) = SCOPE(LV)
-```
-
-The scope of a unique referent is the scope of the pointer, since
-(barring mutation or moves) the pointer will not be freed until
-the pointer itself `LV` goes out of scope:
-
-```text
-  SCOPE(*LV) = SCOPE(LV) if LV has type Box<T>
-```
-
-The scope of a borrowed referent is the scope associated with the
-pointer.  This is a conservative approximation, since the data that
-the pointer points at may actually live longer:
-
-```text
-  SCOPE(*LV) = LT if LV has type &'LT T or &'LT mut T
-```
-
 ### Checking lifetime of variables
 
 The rule for variables states that a variable can only be borrowed a
@@ -420,7 +382,7 @@ lifetime `LT` that is a subregion of the variable's scope:
 
 ```text
 LIFETIME(X, LT, MQ)                 // L-Local
-  LT <= SCOPE(X)
+  LT <= block where X is declared
 ```
 
 ### Checking lifetime for owned content
@@ -466,15 +428,12 @@ are computed based on the kind of borrow:
 ```text
 &mut LV =>   RESTRICTIONS(LV, LT, MUTATE|CLAIM|FREEZE)
 &LV =>       RESTRICTIONS(LV, LT, MUTATE|CLAIM)
-&const LV => RESTRICTIONS(LV, LT, [])
 ```
 
 The reasoning here is that a mutable borrow must be the only writer,
 therefore it prevents other writes (`MUTATE`), mutable borrows
 (`CLAIM`), and immutable borrows (`FREEZE`). An immutable borrow
 permits other immutable borrows but forbids writes and mutable borrows.
-Finally, a const borrow just wants to be sure that the value is not
-moved out from under it, so no actions are forbidden.
 
 ### Restrictions for loans of a local variable
 
@@ -548,8 +507,8 @@ specify that the lifetime of the loan must be less than the lifetime
 of the `&Ty` pointer. In simple cases, this clause is redundant, since
 the `LIFETIME()` function will already enforce the required rule:
 
-```
-fn foo(point: &'a Point) -> &'static f32 {
+```rust
+fn foo(point: &'a Point) -> &'static i32 {
     &point.x // Error
 }
 ```
@@ -558,8 +517,8 @@ The above example fails to compile both because of clause (1) above
 but also by the basic `LIFETIME()` check. However, in more advanced
 examples involving multiple nested pointers, clause (1) is needed:
 
-```
-fn foo(point: &'a &'b mut Point) -> &'b f32 {
+```rust
+fn foo(point: &'a &'b mut Point) -> &'b i32 {
     &point.x // Error
 }
 ```
@@ -577,8 +536,8 @@ which is only `'a`, not `'b`. Hence this example yields an error.
 As a final twist, consider the case of two nested *immutable*
 pointers, rather than a mutable pointer within an immutable one:
 
-```
-fn foo(point: &'a &'b Point) -> &'b f32 {
+```rust
+fn foo(point: &'a &'b Point) -> &'b i32 {
     &point.x // OK
 }
 ```
@@ -599,8 +558,8 @@ The rules pertaining to `LIFETIME` exist to ensure that we don't
 create a borrowed pointer that outlives the memory it points at. So
 `LIFETIME` prevents a function like this:
 
-```
-fn get_1<'a>() -> &'a int {
+```rust
+fn get_1<'a>() -> &'a i32 {
     let x = 1;
     &x
 }
@@ -619,8 +578,8 @@ after we return and hence the remaining code in `'a` cannot possibly
 mutate it. This distinction is important for type checking functions
 like this one:
 
-```
-fn inc_and_get<'a>(p: &'a mut Point) -> &'a int {
+```rust
+fn inc_and_get<'a>(p: &'a mut Point) -> &'a i32 {
     p.x += 1;
     &p.x
 }
@@ -641,19 +600,6 @@ in terms of capability, the caller passed in the ability to mutate
 `*p` is borrowed since that would be a move of `p`, as `&mut` pointers
 are affine.)
 
-### Restrictions for loans of const aliasable referents
-
-Freeze pointers are read-only. There may be `&mut` or `&` aliases, and
-we can not prevent *anything* but moves in that case. So the
-`RESTRICTIONS` function is only defined if `ACTIONS` is the empty set.
-Because moves from a `&const` lvalue are never legal, it is not
-necessary to add any restrictions at all to the final result.
-
-```text
-    RESTRICTIONS(*LV, LT, []) = []                // R-Deref-Freeze-Borrowed
-      TYPE(LV) = &const Ty
-```
-
 ### Restrictions for loans of mutable borrowed referents
 
 Mutable borrowed pointers are guaranteed to be the only way to mutate
@@ -685,7 +631,7 @@ maximum of `LT'`.
 
 Here is a concrete example of a bug this rule prevents:
 
-```
+```rust
 // Test region-reborrow-from-shorter-mut-ref.rs:
 fn copy_pointer<'a,'b,T>(x: &'a mut &'b mut T) -> &'b mut T {
     &mut **p // ERROR due to clause (1)
@@ -713,10 +659,10 @@ ways to violate the rules is to move the base pointer to a new name
 and access it via that new name, thus bypassing the restrictions on
 the old name. Here is an example:
 
-```
+```rust
 // src/test/compile-fail/borrowck-move-mut-base-ptr.rs
-fn foo(t0: &mut int) {
-    let p: &int = &*t0; // Freezes `*t0`
+fn foo(t0: &mut i32) {
+    let p: &i32 = &*t0; // Freezes `*t0`
     let t1 = t0;        //~ ERROR cannot move out of `t0`
     *t1 = 22;           // OK, not a write through `*t0`
 }
@@ -733,11 +679,11 @@ danger is to mutably borrow the base path. This can lead to two bad
 scenarios. The most obvious is that the mutable borrow itself becomes
 another path to access the same data, as shown here:
 
-```
+```rust
 // src/test/compile-fail/borrowck-mut-borrow-of-mut-base-ptr.rs
-fn foo<'a>(mut t0: &'a mut int,
-           mut t1: &'a mut int) {
-    let p: &int = &*t0;     // Freezes `*t0`
+fn foo<'a>(mut t0: &'a mut i32,
+           mut t1: &'a mut i32) {
+    let p: &i32 = &*t0;     // Freezes `*t0`
     let mut t2 = &mut t0;   //~ ERROR cannot borrow `t0`
     **t2 += 1;              // Mutates `*t0`
 }
@@ -754,11 +700,11 @@ of `t0`. Hence the claim `&mut t0` is illegal.
 Another danger with an `&mut` pointer is that we could swap the `t0`
 value away to create a new path:
 
-```
+```rust
 // src/test/compile-fail/borrowck-swap-mut-base-ptr.rs
-fn foo<'a>(mut t0: &'a mut int,
-           mut t1: &'a mut int) {
-    let p: &int = &*t0;     // Freezes `*t0`
+fn foo<'a>(mut t0: &'a mut i32,
+           mut t1: &'a mut i32) {
+    let p: &i32 = &*t0;     // Freezes `*t0`
     swap(&mut t0, &mut t1); //~ ERROR cannot borrow `t0`
     *t1 = 22;
 }
@@ -772,37 +718,37 @@ careful to ensure this example is still illegal.
 referent is claimed, even freezing the base pointer can be dangerous,
 as shown in the following example:
 
-```
+```rust
 // src/test/compile-fail/borrowck-borrow-of-mut-base-ptr.rs
-fn foo<'a>(mut t0: &'a mut int,
-           mut t1: &'a mut int) {
-    let p: &mut int = &mut *t0; // Claims `*t0`
+fn foo<'a>(mut t0: &'a mut i32,
+           mut t1: &'a mut i32) {
+    let p: &mut i32 = &mut *t0; // Claims `*t0`
     let mut t2 = &t0;           //~ ERROR cannot borrow `t0`
-    let q: &int = &*t2;         // Freezes `*t0` but not through `*p`
+    let q: &i32 = &*t2;         // Freezes `*t0` but not through `*p`
     *p += 1;                    // violates type of `*q`
 }
 ```
 
 Here the problem is that `*t0` is claimed by `p`, and hence `p` wants
 to be the controlling pointer through which mutation or freezes occur.
-But `t2` would -- if it were legal -- have the type `& &mut int`, and
+But `t2` would -- if it were legal -- have the type `& &mut i32`, and
 hence would be a mutable pointer in an aliasable location, which is
 considered frozen (since no one can write to `**t2` as it is not a
-unique path). Therefore, we could reasonably create a frozen `&int`
+unique path). Therefore, we could reasonably create a frozen `&i32`
 pointer pointing at `*t0` that coexists with the mutable pointer `p`,
 which is clearly unsound.
 
 However, it is not always unsafe to freeze the base pointer. In
 particular, if the referent is frozen, there is no harm in it:
 
-```
+```rust
 // src/test/run-pass/borrowck-borrow-of-mut-base-ptr-safe.rs
-fn foo<'a>(mut t0: &'a mut int,
-           mut t1: &'a mut int) {
-    let p: &int = &*t0; // Freezes `*t0`
+fn foo<'a>(mut t0: &'a mut i32,
+           mut t1: &'a mut i32) {
+    let p: &i32 = &*t0; // Freezes `*t0`
     let mut t2 = &t0;
-    let q: &int = &*t2; // Freezes `*t0`, but that's ok...
-    let r: &int = &*t0; // ...after all, could do same thing directly.
+    let q: &i32 = &*t2; // Freezes `*t0`, but that's ok...
+    let r: &i32 = &*t0; // ...after all, could do same thing directly.
 }
 ```
 
@@ -811,11 +757,11 @@ thing `t2` can be used for is to further freeze `*t0`, which is
 already frozen. In particular, we cannot assign to `*t0` through the
 new alias `t2`, as demonstrated in this test case:
 
-```
+```rust
 // src/test/run-pass/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs
-fn foo(t0: & &mut int) {
+fn foo(t0: & &mut i32) {
     let t1 = t0;
-    let p: &int = &**t0;
+    let p: &i32 = &**t0;
     **t1 = 22; //~ ERROR cannot assign
 }
 ```
@@ -855,6 +801,9 @@ prohibited from both freezes and claims. This would avoid the need to
 prevent `const` borrows of the base pointer when the referent is
 borrowed.
 
+[ Previous revisions of this document discussed `&const` in more detail.
+See the revision history. ]
+
 # Moves and initialization
 
 The borrow checker is also in charge of ensuring that:
@@ -881,9 +830,9 @@ moves/uninitializations of the variable that is being used.
 
 Let's look at a simple example:
 
-```
-fn foo(a: Box<int>) {
-    let b: Box<int>;   // Gen bit 0.
+```rust
+fn foo(a: Box<i32>) {
+    let b: Box<i32>;   // Gen bit 0.
 
     if cond {          // Bits: 0
         use(&*a);
@@ -897,7 +846,7 @@ fn foo(a: Box<int>) {
     use(&*b);          // Error.
 }
 
-fn use(a: &int) { }
+fn use(a: &i32) { }
 ```
 
 In this example, the variable `b` is created uninitialized. In one
@@ -1028,8 +977,8 @@ not) the destructor invocation for that path.
 A simple example of this is the following:
 
 ```rust
-struct D { p: int }
-impl D { fn new(x: int) -> D { ... }
+struct D { p: i32 }
+impl D { fn new(x: i32) -> D { ... }
 impl Drop for D { ... }
 
 fn foo(a: D, b: D, t: || -> bool) {
@@ -1142,7 +1091,7 @@ the elements of an array that has been passed by value, such as
 the following:
 
 ```rust
-fn foo(a: [D; 10], i: uint) -> D {
+fn foo(a: [D; 10], i: i32) -> D {
     a[i]
 }
 ```
@@ -1158,7 +1107,7 @@ all-but-one element of the array.  A place where that distinction
 would arise is the following:
 
 ```rust
-fn foo(a: [D; 10], b: [D; 10], i: uint, t: bool) -> D {
+fn foo(a: [D; 10], b: [D; 10], i: i32, t: bool) -> D {
     if t {
         a[i]
     } else {
@@ -1173,7 +1122,7 @@ fn foo(a: [D; 10], b: [D; 10], i: uint, t: bool) -> D {
 
 There are a number of ways that the trans backend could choose to
 compile this (e.g. a `[bool; 10]` array for each such moved array;
-or an `Option<uint>` for each moved array).  From the viewpoint of the
+or an `Option<usize>` for each moved array).  From the viewpoint of the
 borrow-checker, the important thing is to record what kind of fragment
 is implied by the relevant moves.
 
index abe01d193b4929b308f04dc3051b7cff761ccec5..ce7b492c51af158de887e36a92efb09feacb8a6e 100644 (file)
@@ -335,7 +335,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
         return true;
     }
 
-    pub fn loans_generated_by(&self, scope: region::CodeExtent) -> Vec<uint> {
+    pub fn loans_generated_by(&self, scope: region::CodeExtent) -> Vec<usize> {
         //! Returns a vector of the loans that are generated as
         //! we enter `scope`.
 
@@ -466,7 +466,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                         new_loan.span,
                         &format!("cannot borrow `{}`{} as mutable \
                                 more than once at a time",
-                                nl, new_loan_msg)[])
+                                nl, new_loan_msg))
                 }
 
                 (ty::UniqueImmBorrow, _) => {
@@ -474,7 +474,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                         new_loan.span,
                         &format!("closure requires unique access to `{}` \
                                 but {} is already borrowed{}",
-                                nl, ol_pronoun, old_loan_msg)[]);
+                                nl, ol_pronoun, old_loan_msg));
                 }
 
                 (_, ty::UniqueImmBorrow) => {
@@ -482,7 +482,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                         new_loan.span,
                         &format!("cannot borrow `{}`{} as {} because \
                                 previous closure requires unique access",
-                                nl, new_loan_msg, new_loan.kind.to_user_str())[]);
+                                nl, new_loan_msg, new_loan.kind.to_user_str()));
                 }
 
                 (_, _) => {
@@ -495,7 +495,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                                 new_loan.kind.to_user_str(),
                                 ol_pronoun,
                                 old_loan.kind.to_user_str(),
-                                old_loan_msg)[]);
+                                old_loan_msg));
                 }
             }
 
@@ -504,7 +504,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                     self.bccx.span_note(
                         span,
                         &format!("borrow occurs due to use of `{}` in closure",
-                                nl)[]);
+                                nl));
                 }
                 _ => { }
             }
@@ -553,7 +553,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
 
             self.bccx.span_note(
                 old_loan.span,
-                &format!("{}; {}", borrow_summary, rule_summary)[]);
+                &format!("{}; {}", borrow_summary, rule_summary));
 
             let old_loan_span = self.tcx().map.span(old_loan.kill_scope.node_id());
             self.bccx.span_end_note(old_loan_span,
@@ -623,13 +623,13 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                 self.bccx.span_err(
                     span,
                     &format!("cannot use `{}` because it was mutably borrowed",
-                            &self.bccx.loan_path_to_string(copy_path)[])
-                    []);
+                            &self.bccx.loan_path_to_string(copy_path))
+                    );
                 self.bccx.span_note(
                     loan_span,
                     &format!("borrow of `{}` occurs here",
-                            &self.bccx.loan_path_to_string(&*loan_path)[])
-                    []);
+                            &self.bccx.loan_path_to_string(&*loan_path))
+                    );
             }
         }
     }
@@ -648,20 +648,20 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                 let err_message = match move_kind {
                     move_data::Captured =>
                         format!("cannot move `{}` into closure because it is borrowed",
-                                &self.bccx.loan_path_to_string(move_path)[]),
+                                &self.bccx.loan_path_to_string(move_path)),
                     move_data::Declared |
                     move_data::MoveExpr |
                     move_data::MovePat =>
                         format!("cannot move out of `{}` because it is borrowed",
-                                &self.bccx.loan_path_to_string(move_path)[])
+                                &self.bccx.loan_path_to_string(move_path))
                 };
 
                 self.bccx.span_err(span, &err_message[..]);
                 self.bccx.span_note(
                     loan_span,
                     &format!("borrow of `{}` occurs here",
-                            &self.bccx.loan_path_to_string(&*loan_path)[])
-                    []);
+                            &self.bccx.loan_path_to_string(&*loan_path))
+                    );
             }
         }
     }
@@ -727,7 +727,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
     /// let a: int;
     /// a = 10; // ok, even though a is uninitialized
     ///
-    /// struct Point { x: uint, y: uint }
+    /// struct Point { x: usize, y: usize }
     /// let p: Point;
     /// p.x = 22; // ok, even though `p` is uninitialized
     ///
@@ -842,7 +842,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                     self.bccx.span_err(
                         assignment_span,
                         &format!("cannot assign to {}",
-                                self.bccx.cmt_to_string(&*assignee_cmt))[]);
+                                self.bccx.cmt_to_string(&*assignee_cmt)));
                     self.bccx.span_help(
                         self.tcx().map.span(upvar_id.closure_expr_id),
                         "consider changing this closure to take self by mutable reference");
@@ -851,7 +851,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                         assignment_span,
                         &format!("cannot assign to {} {}",
                                 assignee_cmt.mutbl.to_user_str(),
-                                self.bccx.cmt_to_string(&*assignee_cmt))[]);
+                                self.bccx.cmt_to_string(&*assignee_cmt)));
                 }
             }
             _ => match opt_loan_path(&assignee_cmt) {
@@ -861,14 +861,14 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                         &format!("cannot assign to {} {} `{}`",
                                 assignee_cmt.mutbl.to_user_str(),
                                 self.bccx.cmt_to_string(&*assignee_cmt),
-                                self.bccx.loan_path_to_string(&*lp))[]);
+                                self.bccx.loan_path_to_string(&*lp)));
                 }
                 None => {
                     self.bccx.span_err(
                         assignment_span,
                         &format!("cannot assign to {} {}",
                                 assignee_cmt.mutbl.to_user_str(),
-                                self.bccx.cmt_to_string(&*assignee_cmt))[]);
+                                self.bccx.cmt_to_string(&*assignee_cmt)));
                 }
             }
         }
@@ -943,13 +943,20 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                                                       cmt: mc::cmt<'tcx>)
                                                       -> bool {
             match cmt.freely_aliasable(this.tcx()) {
-                None => {
+                mc::Aliasability::NonAliasable => {
                     return true;
                 }
-                Some(mc::AliasableStaticMut(..)) => {
+                mc::Aliasability::FreelyAliasable(mc::AliasableStaticMut(..)) => {
                     return true;
                 }
-                Some(cause) => {
+                mc::Aliasability::ImmutableUnique(_) => {
+                    this.bccx.report_aliasability_violation(
+                        span,
+                        MutabilityViolation,
+                        mc::AliasableReason::UnaliasableImmutable);
+                    return false;
+                }
+                mc::Aliasability::FreelyAliasable(cause) => {
                     this.bccx.report_aliasability_violation(
                         span,
                         MutabilityViolation,
@@ -988,10 +995,10 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
         self.bccx.span_err(
             span,
             &format!("cannot assign to `{}` because it is borrowed",
-                    self.bccx.loan_path_to_string(loan_path))[]);
+                    self.bccx.loan_path_to_string(loan_path)));
         self.bccx.span_note(
             loan.span,
             &format!("borrow of `{}` occurs here",
-                    self.bccx.loan_path_to_string(loan_path))[]);
+                    self.bccx.loan_path_to_string(loan_path)));
     }
 }
index c873831cb0f657b6faa3fb81a16641b55211ce5c..a13d1d1112a84ff923f936fe66c1274e7c78e05e 100644 (file)
 
 //! Helper routines used for fragmenting structural paths due to moves for
 //! tracking drop obligations. Please see the extensive comments in the
-//! section "Structural fragments" in `doc.rs`.
+//! section "Structural fragments" in `README.md`.
 
 use self::Fragment::*;
 
 use borrowck::InteriorKind::{InteriorField, InteriorElement};
-use borrowck::{LoanPath};
+use borrowck::LoanPath;
 use borrowck::LoanPathKind::{LpVar, LpUpvar, LpDowncast, LpExtend};
 use borrowck::LoanPathElem::{LpDeref, LpInterior};
-use borrowck::move_data::{InvalidMovePathIndex};
+use borrowck::move_data::InvalidMovePathIndex;
 use borrowck::move_data::{MoveData, MovePathIndex};
 use rustc::middle::ty;
 use rustc::middle::mem_categorization as mc;
@@ -26,7 +26,6 @@ use rustc::util::ppaux::{Repr, UserString};
 use std::mem;
 use std::rc::Rc;
 use syntax::ast;
-use syntax::ast_map;
 use syntax::attr::AttrMetaMethods;
 use syntax::codemap::Span;
 
@@ -119,24 +118,9 @@ pub fn instrument_move_fragments<'tcx>(this: &MoveData<'tcx>,
                                        tcx: &ty::ctxt<'tcx>,
                                        sp: Span,
                                        id: ast::NodeId) {
-    let (span_err, print) = {
-        let attrs : &[ast::Attribute];
-        attrs = match tcx.map.find(id) {
-            Some(ast_map::NodeItem(ref item)) =>
-                &item.attrs[],
-            Some(ast_map::NodeImplItem(&ast::MethodImplItem(ref m))) =>
-                &m.attrs[],
-            Some(ast_map::NodeTraitItem(&ast::ProvidedMethod(ref m))) =>
-                &m.attrs[],
-            _ => &[][],
-        };
-
-        let span_err =
-            attrs.iter().any(|a| a.check_name("rustc_move_fragments"));
-        let print = tcx.sess.opts.debugging_opts.print_move_fragments;
-
-        (span_err, print)
-    };
+    let span_err = tcx.map.attrs(id).iter()
+                          .any(|a| a.check_name("rustc_move_fragments"));
+    let print = tcx.sess.opts.debugging_opts.print_move_fragments;
 
     if !span_err && !print { return; }
 
@@ -144,7 +128,7 @@ pub fn instrument_move_fragments<'tcx>(this: &MoveData<'tcx>,
         for (i, mpi) in vec_rc.iter().enumerate() {
             let render = || this.path_loan_path(*mpi).user_string(tcx);
             if span_err {
-                tcx.sess.span_err(sp, &format!("{}: `{}`", kind, render())[]);
+                tcx.sess.span_err(sp, &format!("{}: `{}`", kind, render()));
             }
             if print {
                 println!("id:{} {}[{}] `{}`", id, kind, i, render());
@@ -156,7 +140,7 @@ pub fn instrument_move_fragments<'tcx>(this: &MoveData<'tcx>,
         for (i, f) in vec_rc.iter().enumerate() {
             let render = || f.loan_path_user_string(this, tcx);
             if span_err {
-                tcx.sess.span_err(sp, &format!("{}: `{}`", kind, render())[]);
+                tcx.sess.span_err(sp, &format!("{}: `{}`", kind, render()));
             }
             if print {
                 println!("id:{} {}[{}] `{}`", id, kind, i, render());
index 1c57097ae26339a9c70626cc96617836836521a1..9f7b4cf26e1c47fa60dabc40b6bdc37abb10c293 100644 (file)
@@ -106,8 +106,6 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
         //! lvalue `cmt` is guaranteed to be valid without any
         //! rooting etc, and presuming `cmt` is not mutated.
 
-        // See the SCOPE(LV) function in doc.rs
-
         match cmt.cat {
             mc::cat_rvalue(temp_scope) => {
                 temp_scope
index 4e308c5809f45ba96657628d891ba0b2fe36ea52..733d486d2d22d3ae495b10f2ddc233b423a1de4a 100644 (file)
@@ -22,7 +22,7 @@ use rustc::middle::expr_use_visitor as euv;
 use rustc::middle::mem_categorization as mc;
 use rustc::middle::region;
 use rustc::middle::ty;
-use rustc::util::ppaux::{Repr};
+use rustc::util::ppaux::Repr;
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::visit;
@@ -151,10 +151,11 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
               assignee_cmt: mc::cmt<'tcx>,
               mode: euv::MutateMode)
     {
-        debug!("mutate(assignment_id={}, assignee_cmt={})",
-               assignment_id, assignee_cmt.repr(self.tcx()));
+        let opt_lp = opt_loan_path(&assignee_cmt);
+        debug!("mutate(assignment_id={}, assignee_cmt={}) opt_lp={:?}",
+               assignment_id, assignee_cmt.repr(self.tcx()), opt_lp);
 
-        match opt_loan_path(&assignee_cmt) {
+        match opt_lp {
             Some(lp) => {
                 gather_moves::gather_assignment(self.bccx, &self.move_data,
                                                 assignment_id, assignment_span,
@@ -173,7 +174,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
     }
 }
 
-/// Implements the A-* rules in doc.rs.
+/// Implements the A-* rules in README.md.
 fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                                 borrow_span: Span,
                                 loan_cause: euv::LoanCause,
@@ -181,12 +182,16 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                                 req_kind: ty::BorrowKind)
                                 -> Result<(),()> {
 
-    match (cmt.freely_aliasable(bccx.tcx), req_kind) {
-        (None, _) => {
+    let aliasability = cmt.freely_aliasable(bccx.tcx);
+    debug!("check_aliasability aliasability={:?} req_kind={:?}",
+           aliasability, req_kind);
+
+    match (aliasability, req_kind) {
+        (mc::Aliasability::NonAliasable, _) => {
             /* Uniquely accessible path -- OK for `&` and `&mut` */
             Ok(())
         }
-        (Some(mc::AliasableStatic(safety)), ty::ImmBorrow) => {
+        (mc::Aliasability::FreelyAliasable(mc::AliasableStatic(safety)), ty::ImmBorrow) => {
             // Borrow of an immutable static item:
             match safety {
                 mc::InteriorUnsafe => {
@@ -202,13 +207,20 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                 }
             }
         }
-        (Some(mc::AliasableStaticMut(..)), _) => {
+        (mc::Aliasability::FreelyAliasable(mc::AliasableStaticMut(..)), _) => {
             // Even touching a static mut is considered unsafe. We assume the
             // user knows what they're doing in these cases.
             Ok(())
         }
-        (Some(alias_cause), ty::UniqueImmBorrow) |
-        (Some(alias_cause), ty::MutBorrow) => {
+        (mc::Aliasability::ImmutableUnique(_), ty::MutBorrow) => {
+            bccx.report_aliasability_violation(
+                        borrow_span,
+                        BorrowViolation(loan_cause),
+                        mc::AliasableReason::UnaliasableImmutable);
+            Err(())
+        }
+        (mc::Aliasability::FreelyAliasable(alias_cause), ty::UniqueImmBorrow) |
+        (mc::Aliasability::FreelyAliasable(alias_cause), ty::MutBorrow) => {
             bccx.report_aliasability_violation(
                         borrow_span,
                         BorrowViolation(loan_cause),
@@ -307,7 +319,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
                         self.tcx().sess.span_bug(
                             cmt.span,
                             &format!("invalid borrow lifetime: {:?}",
-                                    loan_region)[]);
+                                    loan_region));
                     }
                 };
                 debug!("loan_scope = {:?}", loan_scope);
@@ -375,8 +387,9 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
                                       cmt: mc::cmt<'tcx>,
                                       req_kind: ty::BorrowKind)
                                       -> Result<(),()> {
-            //! Implements the M-* rules in doc.rs.
-
+            //! Implements the M-* rules in README.md.
+            debug!("check_mutability(cause={:?} cmt={} req_kind={:?}",
+                   cause, cmt.repr(bccx.tcx), req_kind);
             match req_kind {
                 ty::UniqueImmBorrow | ty::ImmBorrow => {
                     match cmt.mutbl {
@@ -491,7 +504,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> {
         if let ast::ExprAddrOf(mutbl, ref base) = ex.node {
             let param_env = ty::empty_parameter_environment(self.bccx.tcx);
             let mc = mc::MemCategorizationContext::new(&param_env);
-            let base_cmt = mc.cat_expr(&**base).ok().unwrap();
+            let base_cmt = mc.cat_expr(&**base).unwrap();
             let borrow_kind = ty::BorrowKind::from_mutbl(mutbl);
             // Check that we don't allow borrows of unsafe static items.
             if check_aliasability(self.bccx, ex.span, euv::AddrOf,
index da5c847a04607e7cc79fc8e3de8e01726906d578..84636ebaae42b608d7ce09f161bfbb5574d7e075 100644 (file)
@@ -121,7 +121,7 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
         mc::cat_static_item => {
             bccx.span_err(move_from.span,
                           &format!("cannot move out of {}",
-                                  move_from.descriptive_string(bccx.tcx))[]);
+                                  move_from.descriptive_string(bccx.tcx)));
         }
 
         mc::cat_interior(ref b, mc::InteriorElement(Kind::Index, _)) => {
@@ -130,7 +130,7 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                 bccx.span_err(move_from.span,
                               &format!("cannot move out of type `{}`, \
                                         a non-copy fixed-size array",
-                                       b.ty.user_string(bccx.tcx))[]);
+                                       b.ty.user_string(bccx.tcx)));
             }
         }
 
@@ -143,7 +143,7 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                         move_from.span,
                         &format!("cannot move out of type `{}`, \
                                  which defines the `Drop` trait",
-                                b.ty.user_string(bccx.tcx))[]);
+                                b.ty.user_string(bccx.tcx)));
                 },
                 _ => {
                     bccx.span_bug(move_from.span, "this path should not cause illegal move")
@@ -165,15 +165,15 @@ fn note_move_destination(bccx: &BorrowckCtxt,
         bccx.span_note(
             move_to_span,
             "attempting to move value to here");
-        bccx.span_help(
+        bccx.fileline_help(
             move_to_span,
             &format!("to prevent the move, \
                      use `ref {0}` or `ref mut {0}` to capture value by \
                      reference",
-                    pat_name)[]);
+                    pat_name));
     } else {
         bccx.span_note(move_to_span,
                        &format!("and here (use `ref {0}` or `ref mut {0}`)",
-                               pat_name)[]);
+                               pat_name));
     }
 }
index 518e4bc472ca4aa6c117c8db26f9e0796ad5ce93..f8da075e4bdc239929212106049be19c7bf0beca 100644 (file)
@@ -88,7 +88,7 @@ pub fn check_crate(tcx: &ty::ctxt) {
                  make_stat(&bccx, bccx.stats.stable_paths));
     }
 
-    fn make_stat(bccx: &BorrowckCtxt, stat: uint) -> String {
+    fn make_stat(bccx: &BorrowckCtxt, stat: usize) -> String {
         let total = bccx.stats.guaranteed_paths as f64;
         let perc = if total == 0.0 { 0.0 } else { stat as f64 * 100.0 / total };
         format!("{} ({:.0}%)", stat, perc)
@@ -105,10 +105,10 @@ fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
         ast::ItemConst(_, ref ex) => {
             gather_loans::gather_loans_in_static_initializer(this, &**ex);
         }
-        _ => {
-            visit::walk_item(this, item);
-        }
+        _ => { }
     }
+
+    visit::walk_item(this, item);
 }
 
 /// Collection of conclusions determined via borrow checker analyses.
@@ -238,10 +238,10 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> {
 }
 
 struct BorrowStats {
-    loaned_paths_same: uint,
-    loaned_paths_imm: uint,
-    stable_paths: uint,
-    guaranteed_paths: uint
+    loaned_paths_same: usize,
+    loaned_paths_imm: usize,
+    stable_paths: usize,
+    guaranteed_paths: usize
 }
 
 pub type BckResult<'tcx, T> = Result<T, BckError<'tcx>>;
@@ -251,7 +251,7 @@ pub type BckResult<'tcx, T> = Result<T, BckError<'tcx>>;
 
 /// Record of a loan that was issued.
 pub struct Loan<'tcx> {
-    index: uint,
+    index: usize,
     loan_path: Rc<LoanPath<'tcx>>,
     kind: ty::BorrowKind,
     restricted_paths: Vec<Rc<LoanPath<'tcx>>>,
@@ -295,7 +295,7 @@ impl<'tcx> PartialEq for LoanPath<'tcx> {
 
 #[derive(PartialEq, Eq, Hash, Debug)]
 pub enum LoanPathKind<'tcx> {
-    LpVar(ast::NodeId),                         // `x` in doc.rs
+    LpVar(ast::NodeId),                         // `x` in README.md
     LpUpvar(ty::UpvarId),                       // `x` captured by-value into closure
     LpDowncast(Rc<LoanPath<'tcx>>, ast::DefId), // `x` downcast to particular enum variant
     LpExtend(Rc<LoanPath<'tcx>>, mc::MutabilityCategory, LoanPathElem)
@@ -312,7 +312,7 @@ impl<'tcx> LoanPath<'tcx> {
 // FIXME (pnkfelix): See discussion here
 // https://github.com/pnkfelix/rust/commit/
 //     b2b39e8700e37ad32b486b9a8409b50a8a53aa51#commitcomment-7892003
-static DOWNCAST_PRINTED_OPERATOR : &'static str = " as ";
+const DOWNCAST_PRINTED_OPERATOR: &'static str = " as ";
 
 // A local, "cleaned" version of `mc::InteriorKind` that drops
 // information that is not relevant to loan-path analysis. (In
@@ -334,10 +334,10 @@ impl ToInteriorKind for mc::InteriorKind {
     }
 }
 
-#[derive(Copy, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub enum LoanPathElem {
-    LpDeref(mc::PointerKind),    // `*LV` in doc.rs
-    LpInterior(InteriorKind),    // `LV.f` in doc.rs
+    LpDeref(mc::PointerKind),    // `*LV` in README.md
+    LpInterior(InteriorKind),    // `LV.f` in README.md
 }
 
 pub fn closure_to_block(closure_id: ast::NodeId,
@@ -382,7 +382,7 @@ impl<'tcx> LoanPath<'tcx> {
         }
     }
 
-    fn depth(&self) -> uint {
+    fn depth(&self) -> usize {
         match self.kind {
             LpExtend(ref base, _, LpDeref(_)) => base.depth(),
             LpExtend(ref base, _, LpInterior(_)) => base.depth() + 1,
@@ -500,13 +500,13 @@ pub struct BckError<'tcx> {
     code: bckerr_code
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum AliasableViolationKind {
     MutabilityViolation,
     BorrowViolation(euv::LoanCause)
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum MovedValueUseKind {
     MovedInUse,
     MovedInCapture,
@@ -524,7 +524,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
     pub fn report(&self, err: BckError<'tcx>) {
         self.span_err(
             err.span,
-            &self.bckerr_to_string(&err)[]);
+            &self.bckerr_to_string(&err));
         self.note_and_explain_bckerr(err);
     }
 
@@ -546,7 +546,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     use_span,
                     &format!("{} of possibly uninitialized variable: `{}`",
                             verb,
-                            self.loan_path_to_string(lp))[]);
+                            self.loan_path_to_string(lp)));
                 (self.loan_path_to_string(moved_lp),
                  String::new())
             }
@@ -588,7 +588,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     &format!("{} of {}moved value: `{}`",
                             verb,
                             msg,
-                            nl)[]);
+                            nl));
                 (ol, moved_lp_msg)
             }
         };
@@ -607,18 +607,31 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                         self.tcx.sess.bug(&format!("MoveExpr({}) maps to \
                                                    {:?}, not Expr",
                                                   the_move.id,
-                                                  r)[])
+                                                  r))
                     }
                 };
                 let (suggestion, _) =
                     move_suggestion(param_env, expr_span, expr_ty, ("moved by default", ""));
-                self.tcx.sess.span_note(
-                    expr_span,
-                    &format!("`{}` moved here{} because it has type `{}`, which is {}",
-                            ol,
-                            moved_lp_msg,
-                            expr_ty.user_string(self.tcx),
-                            suggestion)[]);
+                // If the two spans are the same, it's because the expression will be evaluated
+                // multiple times. Avoid printing the same span and adjust the wording so it makes
+                // more sense that it's from multiple evalutations.
+                if expr_span == use_span {
+                    self.tcx.sess.note(
+                        &format!("`{}` was previously moved here{} because it has type `{}`, \
+                                  which is {}",
+                                 ol,
+                                 moved_lp_msg,
+                                 expr_ty.user_string(self.tcx),
+                                 suggestion));
+                } else {
+                    self.tcx.sess.span_note(
+                        expr_span,
+                        &format!("`{}` moved here{} because it has type `{}`, which is {}",
+                                 ol,
+                                 moved_lp_msg,
+                                 expr_ty.user_string(self.tcx),
+                                 suggestion));
+                }
             }
 
             move_data::MovePat => {
@@ -629,8 +642,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                              which is moved by default",
                             ol,
                             moved_lp_msg,
-                            pat_ty.user_string(self.tcx))[]);
-                self.tcx.sess.span_help(span,
+                            pat_ty.user_string(self.tcx)));
+                self.tcx.sess.fileline_help(span,
                     "use `ref` to override");
             }
 
@@ -645,7 +658,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                         self.tcx.sess.bug(&format!("Captured({}) maps to \
                                                    {:?}, not Expr",
                                                   the_move.id,
-                                                  r)[])
+                                                  r))
                     }
                 };
                 let (suggestion, help) =
@@ -661,8 +674,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                             ol,
                             moved_lp_msg,
                             expr_ty.user_string(self.tcx),
-                            suggestion)[]);
-                self.tcx.sess.span_help(expr_span, help);
+                            suggestion));
+                self.tcx.sess.fileline_help(expr_span, help);
             }
         }
 
@@ -691,9 +704,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
         self.tcx
             .sess
             .span_err(span,
-                      (format!("partial reinitialization of uninitialized \
+                      &format!("partial reinitialization of uninitialized \
                                structure `{}`",
-                               self.loan_path_to_string(lp))).as_slice());
+                               self.loan_path_to_string(lp)));
     }
 
     pub fn report_reassigned_immutable_variable(&self,
@@ -704,7 +717,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
         self.tcx.sess.span_err(
             span,
             &format!("re-assignment of immutable variable `{}`",
-                    self.loan_path_to_string(lp))[]);
+                    self.loan_path_to_string(lp)));
         self.tcx.sess.span_note(assign.span, "prior assignment occurs here");
     }
 
@@ -728,6 +741,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
         self.tcx.sess.span_help(s, m);
     }
 
+    pub fn fileline_help(&self, s: Span, m: &str) {
+        self.tcx.sess.fileline_help(s, m);
+    }
+
     pub fn bckerr_to_string(&self, err: &BckError<'tcx>) -> String {
         match err.code {
             err_mutbl => {
@@ -825,7 +842,13 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                 self.tcx.sess.span_err(
                     span,
                     &format!("{} in an aliasable location",
-                             prefix)[]);
+                             prefix));
+            }
+            mc::AliasableReason::UnaliasableImmutable => {
+                self.tcx.sess.span_err(
+                    span,
+                    &format!("{} in an immutable container",
+                             prefix));
             }
             mc::AliasableClosure(id) => {
                 self.tcx.sess.span_err(span,
@@ -847,17 +870,17 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
             mc::AliasableStaticMut(..) => {
                 self.tcx.sess.span_err(
                     span,
-                    &format!("{} in a static location", prefix)[]);
+                    &format!("{} in a static location", prefix));
             }
             mc::AliasableBorrowed => {
                 self.tcx.sess.span_err(
                     span,
-                    &format!("{} in a `&` reference", prefix)[]);
+                    &format!("{} in a `&` reference", prefix));
             }
         }
 
         if is_closure {
-            self.tcx.sess.span_help(
+            self.tcx.sess.fileline_help(
                 span,
                 "closures behind references must be called via `&mut`");
         }
@@ -920,12 +943,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                 note_and_explain_region(
                     self.tcx,
                     &format!("{} would have to be valid for ",
-                            descr)[],
+                            descr),
                     loan_scope,
                     "...");
                 note_and_explain_region(
                     self.tcx,
-                    &format!("...but {} is only valid for ", descr)[],
+                    &format!("...but {} is only valid for ", descr),
                     ptr_scope,
                     "");
             }
@@ -945,7 +968,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                 out.push('(');
                 self.append_loan_path_to_string(&**lp_base, out);
                 out.push_str(DOWNCAST_PRINTED_OPERATOR);
-                out.push_str(&ty::item_path_str(self.tcx, variant_def_id)[]);
+                out.push_str(&ty::item_path_str(self.tcx, variant_def_id));
                 out.push(')');
             }
 
@@ -959,7 +982,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     }
                     mc::PositionalField(idx) => {
                         out.push('.');
-                        out.push_str(&idx.to_string()[]);
+                        out.push_str(&idx.to_string());
                     }
                 }
             }
@@ -991,7 +1014,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                 out.push('(');
                 self.append_autoderefd_loan_path_to_string(&**lp_base, out);
                 out.push(':');
-                out.push_str(&ty::item_path_str(self.tcx, variant_def_id)[]);
+                out.push_str(&ty::item_path_str(self.tcx, variant_def_id));
                 out.push(')');
             }
 
@@ -1026,7 +1049,7 @@ fn is_statement_scope(tcx: &ty::ctxt, region: ty::Region) -> bool {
 
 impl BitwiseOperator for LoanDataFlowOperator {
     #[inline]
-    fn join(&self, succ: uint, pred: uint) -> uint {
+    fn join(&self, succ: usize, pred: usize) -> usize {
         succ | pred // loans from both preds are in scope
     }
 }
index 9c5ddc06519b97208e523379170d84609ef430b4..2d1b57243d1cccd192b7037d2a79134835b39d32 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 //! Data structures used for tracking moves. Please see the extensive
-//! comments in the section "Moves and initialization" in `doc.rs`.
+//! comments in the section "Moves and initialization" in `README.md`.
 
 pub use self::MoveKind::*;
 
@@ -33,7 +33,7 @@ use syntax::codemap::Span;
 pub mod fragments;
 
 pub struct MoveData<'tcx> {
-    /// Move paths. See section "Move paths" in `doc.rs`.
+    /// Move paths. See section "Move paths" in `README.md`.
     pub paths: RefCell<Vec<MovePath<'tcx>>>,
 
     /// Cache of loan path to move path index, for easy lookup.
@@ -76,10 +76,10 @@ pub struct FlowedMoveData<'a, 'tcx: 'a> {
 
 /// Index into `MoveData.paths`, used like a pointer
 #[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
-pub struct MovePathIndex(uint);
+pub struct MovePathIndex(usize);
 
 impl MovePathIndex {
-    fn get(&self) -> uint {
+    fn get(&self) -> usize {
         let MovePathIndex(v) = *self; v
     }
 }
@@ -91,22 +91,20 @@ impl Clone for MovePathIndex {
 }
 
 #[allow(non_upper_case_globals)]
-static InvalidMovePathIndex: MovePathIndex =
-    MovePathIndex(usize::MAX);
+const InvalidMovePathIndex: MovePathIndex = MovePathIndex(usize::MAX);
 
 /// Index into `MoveData.moves`, used like a pointer
-#[derive(Copy, PartialEq)]
-pub struct MoveIndex(uint);
+#[derive(Copy, Clone, PartialEq)]
+pub struct MoveIndex(usize);
 
 impl MoveIndex {
-    fn get(&self) -> uint {
+    fn get(&self) -> usize {
         let MoveIndex(v) = *self; v
     }
 }
 
 #[allow(non_upper_case_globals)]
-static InvalidMoveIndex: MoveIndex =
-    MoveIndex(usize::MAX);
+const InvalidMoveIndex: MoveIndex = MoveIndex(usize::MAX);
 
 pub struct MovePath<'tcx> {
     /// Loan path corresponding to this move path
@@ -127,7 +125,7 @@ pub struct MovePath<'tcx> {
     pub next_sibling: MovePathIndex,
 }
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum MoveKind {
     Declared,   // When declared, variables start out "moved".
     MoveExpr,   // Expression or binding that moves a variable
@@ -135,7 +133,7 @@ pub enum MoveKind {
     Captured    // Closure creation that moves a value
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Move {
     /// Path being moved.
     pub path: MovePathIndex,
@@ -150,7 +148,7 @@ pub struct Move {
     pub next_move: MoveIndex
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Assignment {
     /// Path being assigned.
     pub path: MovePathIndex,
@@ -162,7 +160,7 @@ pub struct Assignment {
     pub span: Span,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct VariantMatch {
     /// downcast to the variant.
     pub path: MovePathIndex,
@@ -464,7 +462,7 @@ impl<'tcx> MoveData<'tcx> {
     /// assignments into the provided data flow contexts.
     /// Moves are generated by moves and killed by assignments and
     /// scoping. Assignments are generated by assignment to variables and
-    /// killed by scoping. See `doc.rs` for more details.
+    /// killed by scoping. See `README.md` for more details.
     fn add_gen_kills(&self,
                      tcx: &ty::ctxt<'tcx>,
                      dfcx_moves: &mut MoveDataFlow,
@@ -488,7 +486,7 @@ impl<'tcx> MoveData<'tcx> {
             match path.loan_path.kind {
                 LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
                     let kill_scope = path.loan_path.kill_scope(tcx);
-                    let path = self.path_map.borrow()[path.loan_path];
+                    let path = *self.path_map.borrow().get(&path.loan_path).unwrap();
                     self.kill_moves(path, kill_scope.node_id(), dfcx_moves);
                 }
                 LpExtend(..) => {}
@@ -742,7 +740,7 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
 
 impl BitwiseOperator for MoveDataFlowOperator {
     #[inline]
-    fn join(&self, succ: uint, pred: uint) -> uint {
+    fn join(&self, succ: usize, pred: usize) -> usize {
         succ | pred // moves from both preds are in scope
     }
 }
@@ -756,7 +754,7 @@ impl DataFlowOperator for MoveDataFlowOperator {
 
 impl BitwiseOperator for AssignDataFlowOperator {
     #[inline]
-    fn join(&self, succ: uint, pred: uint) -> uint {
+    fn join(&self, succ: usize, pred: usize) -> usize {
         succ | pred // moves from both preds are in scope
     }
 }
index 39c9d9ba6ad24ae5f067b893c66627c6d4e209a8..ade52bfde35e6cac3cb3425429849f8a0756e7ad 100644 (file)
@@ -20,13 +20,13 @@ use rustc::middle::cfg::graphviz as cfg_dot;
 use borrowck;
 use borrowck::{BorrowckCtxt, LoanPath};
 use dot;
-use rustc::middle::cfg::{CFGIndex};
+use rustc::middle::cfg::CFGIndex;
 use rustc::middle::dataflow::{DataFlowOperator, DataFlowContext, EntryOrExit};
 use rustc::middle::dataflow;
 use std::rc::Rc;
 use std::borrow::IntoCow;
 
-#[derive(Debug, Copy)]
+#[derive(Debug, Copy, Clone)]
 pub enum Variant {
     Loans,
     Moves,
@@ -52,7 +52,7 @@ pub struct DataflowLabeller<'a, 'tcx: 'a> {
 
 impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
     fn dataflow_for(&self, e: EntryOrExit, n: &Node<'a>) -> String {
-        let id = n.1.data.id;
+        let id = n.1.data.id();
         debug!("dataflow_for({:?}, id={}) {:?}", e, id, self.variants);
         let mut sets = "".to_string();
         let mut seen_one = false;
@@ -60,7 +60,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
             if seen_one { sets.push_str(" "); } else { seen_one = true; }
             sets.push_str(variant.short_name());
             sets.push_str(": ");
-            sets.push_str(&self.dataflow_for_variant(e, n, variant)[]);
+            sets.push_str(&self.dataflow_for_variant(e, n, variant));
         }
         sets
     }
@@ -79,7 +79,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
                                         cfgidx: CFGIndex,
                                         dfcx: &DataFlowContext<'a, 'tcx, O>,
                                         mut to_lp: F) -> String where
-        F: FnMut(uint) -> Rc<LoanPath<'tcx>>,
+        F: FnMut(usize) -> Rc<LoanPath<'tcx>>,
     {
         let mut saw_some = false;
         let mut set = "{".to_string();
index b7cfda280925701495074fcb68d1955b03b3a058..54feed930a80d7b9766d1e54bade1090abcf5da6 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rustc_borrowck"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
 
 #![allow(non_camel_case_types)]
 
-#![feature(core)]
-#![feature(int_uint)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(unsafe_destructor)]
+#![feature(into_cow)]
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
 
 // for "clarity", rename the graphviz crate to dot; graphviz within `borrowck`
 // refers to the borrowck-specific graphviz adapter traits.
-extern crate "graphviz" as dot;
+extern crate graphviz as dot;
 extern crate rustc;
 
 pub use borrowck::check_crate;
index a260997f605940da7ac8d8fd6b83c9e93232af1b..fe05b489229ad6841feadab13d0009193d0fcd7f 100644 (file)
@@ -33,12 +33,13 @@ use serialize::json;
 
 use std::env;
 use std::ffi::OsString;
-use std::old_io::fs;
-use std::old_io;
+use std::fs;
+use std::io::{self, Write};
+use std::path::{Path, PathBuf};
 use syntax::ast;
 use syntax::ast_map;
 use syntax::attr;
-use syntax::attr::{AttrMetaMethods};
+use syntax::attr::AttrMetaMethods;
 use syntax::diagnostics;
 use syntax::parse;
 use syntax::parse::token;
@@ -47,8 +48,8 @@ use syntax;
 pub fn compile_input(sess: Session,
                      cfg: ast::CrateConfig,
                      input: &Input,
-                     outdir: &Option<Path>,
-                     output: &Option<Path>,
+                     outdir: &Option<PathBuf>,
+                     output: &Option<PathBuf>,
                      addl_plugins: Option<Vec<String>>,
                      control: CompileController) {
     macro_rules! controller_entry_point{($point: ident, $make_state: expr) => ({
@@ -77,10 +78,10 @@ pub fn compile_input(sess: Session,
             let outputs = build_output_filenames(input,
                                                  outdir,
                                                  output,
-                                                 &krate.attrs[],
+                                                 &krate.attrs,
                                                  &sess);
             let id = link::find_crate_name(Some(&sess),
-                                           &krate.attrs[],
+                                           &krate.attrs,
                                            input);
             let expanded_crate
                 = match phase_2_configure_and_expand(&sess,
@@ -112,6 +113,7 @@ pub fn compile_input(sess: Session,
                                                                      &sess,
                                                                      outdir,
                                                                      &ast_map,
+                                                                     &ast_map.krate(),
                                                                      &id[..]));
 
         let analysis = phase_3_run_analysis_passes(sess,
@@ -164,7 +166,7 @@ pub fn anon_src() -> String {
 pub fn source_name(input: &Input) -> String {
     match *input {
         // FIXME (#9639): This needs to handle non-utf8 paths
-        Input::File(ref ifile) => ifile.as_str().unwrap().to_string(),
+        Input::File(ref ifile) => ifile.to_str().unwrap().to_string(),
         Input::Str(_) => anon_src()
     }
 }
@@ -241,12 +243,12 @@ pub struct CompileState<'a, 'ast: 'a, 'tcx: 'a> {
 impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
     fn empty(input: &'a Input,
              session: &'a Session,
-             out_dir: &'a Option<Path>)
+             out_dir: &'a Option<PathBuf>)
              -> CompileState<'a, 'ast, 'tcx> {
         CompileState {
             input: input,
             session: session,
-            out_dir: out_dir.as_ref(),
+            out_dir: out_dir.as_ref().map(|s| &**s),
             cfg: None,
             krate: None,
             crate_name: None,
@@ -261,7 +263,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
 
     fn state_after_parse(input: &'a Input,
                          session: &'a Session,
-                         out_dir: &'a Option<Path>,
+                         out_dir: &'a Option<PathBuf>,
                          krate: &'a ast::Crate)
                          -> CompileState<'a, 'ast, 'tcx> {
         CompileState {
@@ -272,7 +274,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
 
     fn state_after_expand(input: &'a Input,
                           session: &'a Session,
-                          out_dir: &'a Option<Path>,
+                          out_dir: &'a Option<PathBuf>,
                           expanded_crate: &'a ast::Crate,
                           crate_name: &'a str)
                           -> CompileState<'a, 'ast, 'tcx> {
@@ -285,28 +287,30 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
 
     fn state_after_write_deps(input: &'a Input,
                               session: &'a Session,
-                              out_dir: &'a Option<Path>,
+                              out_dir: &'a Option<PathBuf>,
                               ast_map: &'a ast_map::Map<'ast>,
+                              expanded_crate: &'a ast::Crate,
                               crate_name: &'a str)
                               -> CompileState<'a, 'ast, 'tcx> {
         CompileState {
             crate_name: Some(crate_name),
             ast_map: Some(ast_map),
+            expanded_crate: Some(expanded_crate),
             .. CompileState::empty(input, session, out_dir)
         }
     }
 
     fn state_after_analysis(input: &'a Input,
                             session: &'a Session,
-                            out_dir: &'a Option<Path>,
-                            krate: &'a ast::Crate,
+                            out_dir: &'a Option<PathBuf>,
+                            expanded_crate: &'a ast::Crate,
                             analysis: &'a ty::CrateAnalysis<'tcx>,
                             tcx: &'a ty::ctxt<'tcx>)
                             -> CompileState<'a, 'ast, 'tcx> {
         CompileState {
             analysis: Some(analysis),
             tcx: Some(tcx),
-            krate: Some(krate),
+            expanded_crate: Some(expanded_crate),
             .. CompileState::empty(input, session, out_dir)
         }
     }
@@ -314,7 +318,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
 
     fn state_after_llvm(input: &'a Input,
                         session: &'a Session,
-                        out_dir: &'a Option<Path>,
+                        out_dir: &'a Option<PathBuf>,
                         trans: &'a trans::CrateTranslation)
                         -> CompileState<'a, 'ast, 'tcx> {
         CompileState {
@@ -375,9 +379,9 @@ pub fn phase_2_configure_and_expand(sess: &Session,
     let time_passes = sess.time_passes();
 
     *sess.crate_types.borrow_mut() =
-        collect_crate_types(sess, &krate.attrs[]);
+        collect_crate_types(sess, &krate.attrs);
     *sess.crate_metadata.borrow_mut() =
-        collect_crate_metadata(sess, &krate.attrs[]);
+        collect_crate_metadata(sess, &krate.attrs);
 
     time(time_passes, "recursion limit", (), |_| {
         middle::recursion_limit::update_recursion_limit(sess, &krate);
@@ -464,7 +468,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
             // dependent dlls. Note that this uses cfg!(windows) as opposed to
             // targ_cfg because syntax extensions are always loaded for the host
             // compiler, not for the target.
-            let mut _old_path = OsString::from_str("");
+            let mut _old_path = OsString::new();
             if cfg!(windows) {
                 _old_path = env::var_os("PATH").unwrap_or(_old_path);
                 let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths();
@@ -489,12 +493,15 @@ pub fn phase_2_configure_and_expand(sess: &Session,
         }
     );
 
-    // Needs to go *after* expansion to be able to check the results of macro expansion.
-    time(time_passes, "complete gated feature checking", (), |_| {
+    // Needs to go *after* expansion to be able to check the results
+    // of macro expansion.  This runs before #[cfg] to try to catch as
+    // much as possible (e.g. help the programmer avoid platform
+    // specific differences)
+    time(time_passes, "complete gated feature checking 1", (), |_| {
         let features =
             syntax::feature_gate::check_crate(sess.codemap(),
-                                          &sess.parse_sess.span_diagnostic,
-                                          &krate);
+                                              &sess.parse_sess.span_diagnostic,
+                                              &krate);
         *sess.features.borrow_mut() = features;
         sess.abort_if_errors();
     });
@@ -517,6 +524,18 @@ pub fn phase_2_configure_and_expand(sess: &Session,
     time(time_passes, "checking that all macro invocations are gone", &krate, |krate|
          syntax::ext::expand::check_for_macros(&sess.parse_sess, krate));
 
+    // One final feature gating of the true AST that gets compiled
+    // later, to make sure we've got everything (e.g. configuration
+    // can insert new attributes via `cfg_attr`)
+    time(time_passes, "complete gated feature checking 2", (), |_| {
+        let features =
+            syntax::feature_gate::check_crate(sess.codemap(),
+                                              &sess.parse_sess.span_diagnostic,
+                                              &krate);
+        *sess.features.borrow_mut() = features;
+        sess.abort_if_errors();
+    });
+
     Some(krate)
 }
 
@@ -568,7 +587,6 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
         export_map,
         trait_map,
         external_exports,
-        last_private_map,
         glob_map,
     } =
         time(time_passes, "resolution", (),
@@ -617,10 +635,9 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
     time(time_passes, "const checking", (), |_|
          middle::check_const::check_crate(&ty_cx));
 
-    let maps = (external_exports, last_private_map);
     let (exported_items, public_items) =
-            time(time_passes, "privacy checking", maps, |(a, b)|
-                 rustc_privacy::check_crate(&ty_cx, &export_map, a, b));
+            time(time_passes, "privacy checking", (), |_|
+                 rustc_privacy::check_crate(&ty_cx, &export_map, external_exports));
 
     // Do not move this check past lint
     time(time_passes, "stability index", (), |_|
@@ -715,13 +732,13 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
 
         // Remove assembly source, unless --save-temps was specified
         if !sess.opts.cg.save_temps {
-            fs::unlink(&outputs.temp_path(config::OutputTypeAssembly)).unwrap();
+            fs::remove_file(&outputs.temp_path(config::OutputTypeAssembly)).unwrap();
         }
     } else {
         time(sess.time_passes(), "LLVM passes", (), |_|
             write::run_passes(sess,
                               trans,
-                              &sess.opts.output_types[],
+                              &sess.opts.output_types,
                               outputs));
     }
 
@@ -733,7 +750,7 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
 pub fn phase_6_link_output(sess: &Session,
                            trans: &trans::CrateTranslation,
                            outputs: &OutputFilenames) {
-    let old_path = env::var_os("PATH").unwrap_or(OsString::from_str(""));
+    let old_path = env::var_os("PATH").unwrap_or(OsString::new());
     let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths();
     new_path.extend(env::split_paths(&old_path));
     env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap());
@@ -742,7 +759,7 @@ pub fn phase_6_link_output(sess: &Session,
          link::link_binary(sess,
                            trans,
                            outputs,
-                           &trans.link.crate_name[]));
+                           &trans.link.crate_name));
 
     env::set_var("PATH", &old_path);
 }
@@ -791,17 +808,19 @@ fn write_out_deps(sess: &Session,
         _ => return,
     };
 
-    let result = (|| -> old_io::IoResult<()> {
+    let result = (|| -> io::Result<()> {
         // Build a list of files used to compile the output and
         // write Makefile-compatible dependency rules
         let files: Vec<String> = sess.codemap().files.borrow()
-                                   .iter().filter(|fmap| fmap.is_real_file())
-                                   .map(|fmap| escape_dep_filename(&fmap.name[]))
+                                   .iter()
+                                   .filter(|fmap| fmap.is_real_file())
+                                   .filter(|fmap| !fmap.is_imported())
+                                   .map(|fmap| escape_dep_filename(&fmap.name))
                                    .collect();
-        let mut file = try!(old_io::File::create(&deps_filename));
+        let mut file = try!(fs::File::create(&deps_filename));
         for path in &out_filenames {
-            try!(write!(&mut file as &mut Writer,
-                          "{}: {}\n\n", path.display(), files.connect(" ")));
+            try!(write!(&mut file,
+                        "{}: {}\n\n", path.display(), files.connect(" ")));
         }
         Ok(())
     })();
@@ -810,7 +829,7 @@ fn write_out_deps(sess: &Session,
         Ok(()) => {}
         Err(e) => {
             sess.fatal(&format!("error writing dependencies to `{}`: {}",
-                               deps_filename.display(), e)[]);
+                               deps_filename.display(), e));
         }
     }
 }
@@ -881,7 +900,7 @@ pub fn collect_crate_types(session: &Session,
         if !res {
             session.warn(&format!("dropping unsupported crate type `{}` \
                                    for target `{}`",
-                                 *crate_type, session.opts.target_triple)[]);
+                                 *crate_type, session.opts.target_triple));
         }
 
         res
@@ -894,8 +913,8 @@ pub fn collect_crate_metadata(session: &Session,
 }
 
 pub fn build_output_filenames(input: &Input,
-                              odir: &Option<Path>,
-                              ofile: &Option<Path>,
+                              odir: &Option<PathBuf>,
+                              ofile: &Option<PathBuf>,
                               attrs: &[ast::Attribute],
                               sess: &Session)
                            -> OutputFilenames {
@@ -906,7 +925,7 @@ pub fn build_output_filenames(input: &Input,
             // We want to toss everything after the final '.'
             let dirpath = match *odir {
                 Some(ref d) => d.clone(),
-                None => Path::new(".")
+                None => PathBuf::new()
             };
 
             // If a crate name is present, we use it as the link name
@@ -933,9 +952,13 @@ pub fn build_output_filenames(input: &Input,
             if *odir != None {
                 sess.warn("ignoring --out-dir flag due to -o flag.");
             }
+
+            let cur_dir = Path::new("");
+
             OutputFilenames {
-                out_directory: out_file.dir_path(),
-                out_filestem: out_file.filestem_str().unwrap().to_string(),
+                out_directory: out_file.parent().unwrap_or(cur_dir).to_path_buf(),
+                out_filestem: out_file.file_stem().unwrap()
+                                      .to_str().unwrap().to_string(),
                 single_output_file: ofile,
                 extra: sess.opts.cg.extra_filename.clone(),
             }
index 2550432c8101adde411a3828936cb1a031eecaa0..b32c6829a221ba481d87a8e5f865fc50e1ba69e1 100644 (file)
@@ -14,6 +14,8 @@
 //!
 //! This API is completely unstable and subject to change.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rustc_driver"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
 
 #![feature(box_syntax)]
 #![feature(collections)]
-#![feature(core)]
-#![feature(env)]
-#![feature(int_uint)]
-#![feature(old_io)]
 #![feature(libc)]
-#![feature(os)]
-#![feature(old_path)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
 #![feature(unsafe_destructor)]
 #![feature(staged_api)]
+#![feature(exit_status)]
+#![feature(set_stdio)]
 #![feature(unicode)]
 
 extern crate arena;
@@ -47,12 +45,13 @@ extern crate libc;
 extern crate rustc;
 extern crate rustc_back;
 extern crate rustc_borrowck;
+extern crate rustc_lint;
 extern crate rustc_privacy;
 extern crate rustc_resolve;
 extern crate rustc_trans;
 extern crate rustc_typeck;
 extern crate serialize;
-extern crate "rustc_llvm" as llvm;
+extern crate rustc_llvm as llvm;
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
 
@@ -72,10 +71,12 @@ use rustc::metadata;
 use rustc::util::common::time;
 
 use std::cmp::Ordering::Equal;
-use std::old_io::{self, stdio};
-use std::iter::repeat;
 use std::env;
-use std::sync::mpsc::channel;
+use std::io::{self, Read, Write};
+use std::iter::repeat;
+use std::path::PathBuf;
+use std::str;
+use std::sync::{Arc, Mutex};
 use std::thread;
 
 use rustc::session::early_error;
@@ -92,11 +93,11 @@ pub mod driver;
 pub mod pretty;
 
 
-static BUG_REPORT_URL: &'static str =
+const BUG_REPORT_URL: &'static str =
     "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports";
 
 
-pub fn run(args: Vec<String>) -> int {
+pub fn run(args: Vec<String>) -> isize {
     monitor(move || run_compiler(&args, &mut RustcDefaultCalls));
     0
 }
@@ -124,7 +125,7 @@ pub fn run_compiler<'a>(args: &[String],
     let sopts = config::build_session_options(&matches);
 
     let (odir, ofile) = make_output(&matches);
-    let (input, input_file_path) = match make_input(&matches.free[]) {
+    let (input, input_file_path) = match make_input(&matches.free) {
         Some((input, input_file_path)) => callbacks.some_input(input, input_file_path),
         None => match callbacks.no_input(&matches, &sopts, &odir, &ofile, &descriptions) {
             Some((input, input_file_path)) => (input, input_file_path),
@@ -133,6 +134,7 @@ pub fn run_compiler<'a>(args: &[String],
     };
 
     let mut sess = build_session(sopts, input_file_path, descriptions);
+    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
     if sess.unstable_options() {
         sess.opts.show_span = matches.opt_str("show-span");
     }
@@ -157,22 +159,22 @@ pub fn run_compiler<'a>(args: &[String],
 }
 
 // Extract output directory and file from matches.
-fn make_output(matches: &getopts::Matches) -> (Option<Path>, Option<Path>) {
-    let odir = matches.opt_str("out-dir").map(|o| Path::new(o));
-    let ofile = matches.opt_str("o").map(|o| Path::new(o));
+fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>) {
+    let odir = matches.opt_str("out-dir").map(|o| PathBuf::from(&o));
+    let ofile = matches.opt_str("o").map(|o| PathBuf::from(&o));
     (odir, ofile)
 }
 
 // Extract input (string or file and optional path) from matches.
-fn make_input(free_matches: &[String]) -> Option<(Input, Option<Path>)> {
+fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>)> {
     if free_matches.len() == 1 {
-        let ifile = &free_matches[0][];
+        let ifile = &free_matches[0][..];
         if ifile == "-" {
-            let contents = old_io::stdin().read_to_end().unwrap();
-            let src = String::from_utf8(contents).unwrap();
+            let mut src = String::new();
+            io::stdin().read_to_string(&mut src).unwrap();
             Some((Input::Str(src), None))
         } else {
-            Some((Input::File(Path::new(ifile)), Some(Path::new(ifile))))
+            Some((Input::File(PathBuf::from(ifile)), Some(PathBuf::from(ifile))))
         }
     } else {
         None
@@ -180,7 +182,7 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option<Path>)> {
 }
 
 // Whether to stop or continue compilation.
-#[derive(Copy, Debug, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum Compilation {
     Stop,
     Continue,
@@ -213,14 +215,15 @@ pub trait CompilerCalls<'a> {
                      &getopts::Matches,
                      &Session,
                      &Input,
-                     &Option<Path>,
-                     &Option<Path>)
+                     &Option<PathBuf>,
+                     &Option<PathBuf>)
                      -> Compilation;
 
     // Called after we extract the input from the arguments. Gives the implementer
     // an opportunity to change the inputs or to add some custom input handling.
     // The default behaviour is to simply pass through the inputs.
-    fn some_input(&mut self, input: Input, input_path: Option<Path>) -> (Input, Option<Path>) {
+    fn some_input(&mut self, input: Input, input_path: Option<PathBuf>)
+                  -> (Input, Option<PathBuf>) {
         (input, input_path)
     }
 
@@ -232,10 +235,10 @@ pub trait CompilerCalls<'a> {
     fn no_input(&mut self,
                 &getopts::Matches,
                 &config::Options,
-                &Option<Path>,
-                &Option<Path>,
+                &Option<PathBuf>,
+                &Option<PathBuf>,
                 &diagnostics::registry::Registry)
-                -> Option<(Input, Option<Path>)>;
+                -> Option<(Input, Option<PathBuf>)>;
 
     // Parse pretty printing information from the arguments. The implementer can
     // choose to ignore this (the default will return None) which will skip pretty
@@ -262,7 +265,7 @@ pub trait CompilerCalls<'a> {
 }
 
 // CompilerCalls instance for a regular rustc build.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct RustcDefaultCalls;
 
 impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
@@ -277,7 +280,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
                         println!("{}", description);
                     }
                     None => {
-                        early_error(&format!("no extended information for {}", code)[]);
+                        early_error(&format!("no extended information for {}", code));
                     }
                 }
                 return Compilation::Stop;
@@ -291,19 +294,20 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
     fn no_input(&mut self,
                 matches: &getopts::Matches,
                 sopts: &config::Options,
-                odir: &Option<Path>,
-                ofile: &Option<Path>,
+                odir: &Option<PathBuf>,
+                ofile: &Option<PathBuf>,
                 descriptions: &diagnostics::registry::Registry)
-                -> Option<(Input, Option<Path>)> {
+                -> Option<(Input, Option<PathBuf>)> {
         match matches.free.len() {
             0 => {
                 if sopts.describe_lints {
                     let mut ls = lint::LintStore::new();
-                    ls.register_builtin(None);
+                    rustc_lint::register_builtins(&mut ls, None);
                     describe_lints(&ls, false);
                     return None;
                 }
                 let sess = build_session(sopts.clone(), None, descriptions.clone());
+                rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
                 let should_stop = RustcDefaultCalls::print_crate_info(&sess, None, odir, ofile);
                 if should_stop == Compilation::Stop {
                     return None;
@@ -343,8 +347,8 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
                      matches: &getopts::Matches,
                      sess: &Session,
                      input: &Input,
-                     odir: &Option<Path>,
-                     ofile: &Option<Path>)
+                     odir: &Option<PathBuf>,
+                     ofile: &Option<PathBuf>)
                      -> Compilation {
         RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile).and_then(
             || RustcDefaultCalls::list_metadata(sess, matches, input))
@@ -373,11 +377,13 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
 
         if sess.opts.debugging_opts.save_analysis {
             control.after_analysis.callback = box |state| {
-                time(state.session.time_passes(), "save analysis", state.krate.unwrap(), |krate|
-                     save::process_crate(state.session,
-                                         krate,
-                                         state.analysis.unwrap(),
-                                         state.out_dir));
+                time(state.session.time_passes(),
+                     "save analysis",
+                     state.expanded_crate.unwrap(),
+                     |krate| save::process_crate(state.session,
+                                                 krate,
+                                                 state.analysis.unwrap(),
+                                                 state.out_dir));
             };
             control.make_glob_map = resolve::MakeGlobMap::Yes;
         }
@@ -395,11 +401,12 @@ impl RustcDefaultCalls {
         if r.contains(&("ls".to_string())) {
             match input {
                 &Input::File(ref ifile) => {
-                    let mut stdout = old_io::stdout();
                     let path = &(*ifile);
+                    let mut v = Vec::new();
                     metadata::loader::list_file_metadata(sess.target.target.options.is_like_osx,
                                                          path,
-                                                         &mut stdout).unwrap();
+                                                         &mut v).unwrap();
+                    println!("{}", String::from_utf8(v).unwrap());
                 }
                 &Input::Str(_) => {
                     early_error("cannot list metadata for stdin");
@@ -414,8 +421,8 @@ impl RustcDefaultCalls {
 
     fn print_crate_info(sess: &Session,
                         input: Option<&Input>,
-                        odir: &Option<Path>,
-                        ofile: &Option<Path>)
+                        odir: &Option<PathBuf>,
+                        ofile: &Option<PathBuf>)
                         -> Compilation {
         if sess.opts.prints.len() == 0 {
             return Compilation::Continue;
@@ -452,7 +459,8 @@ impl RustcDefaultCalls {
                                                              style,
                                                              &id,
                                                              &t_outputs.with_extension(""));
-                        println!("{}", fname.filename_display());
+                        println!("{}", fname.file_name().unwrap()
+                                            .to_string_lossy());
                     }
                 }
             }
@@ -607,8 +615,7 @@ Available lint options:
 
     let print_lint_groups = |lints: Vec<(&'static str, Vec<lint::LintId>)>| {
         for (name, to) in lints {
-            let name = name.chars().map(|x| x.to_lowercase())
-                           .collect::<String>().replace("_", "-");
+            let name = name.to_lowercase().replace("_", "-");
             let desc = to.into_iter().map(|x| x.as_str().replace("_", "-"))
                          .collect::<Vec<String>>().connect(", ");
             println!("    {}  {}",
@@ -677,39 +684,57 @@ pub fn handle_options(mut args: Vec<String>) -> Option<getopts::Matches> {
         return None;
     }
 
-    let matches =
-        match getopts::getopts(&args[..], &config::optgroups()[]) {
-            Ok(m) => m,
-            Err(f_stable_attempt) => {
-                // redo option parsing, including unstable options this time,
-                // in anticipation that the mishandled option was one of the
-                // unstable ones.
-                let all_groups : Vec<getopts::OptGroup>
-                    = config::rustc_optgroups().into_iter().map(|x|x.opt_group).collect();
-                match getopts::getopts(&args, &all_groups) {
-                    Ok(m_unstable) => {
-                        let r = m_unstable.opt_strs("Z");
-                        let include_unstable_options = r.iter().any(|x| *x == "unstable-options");
-                        if include_unstable_options {
-                            m_unstable
+    fn allows_unstable_options(matches: &getopts::Matches) -> bool {
+        let r = matches.opt_strs("Z");
+        r.iter().any(|x| *x == "unstable-options")
+    }
+
+    fn parse_all_options(args: &Vec<String>) -> getopts::Matches {
+        let all_groups : Vec<getopts::OptGroup>
+            = config::rustc_optgroups().into_iter().map(|x|x.opt_group).collect();
+        match getopts::getopts(&args[..], &all_groups) {
+            Ok(m) => {
+                if !allows_unstable_options(&m) {
+                    // If -Z unstable-options was not specified, verify that
+                    // no unstable options were present.
+                    for opt in config::rustc_optgroups().into_iter().filter(|x| !x.is_stable()) {
+                        let opt_name = if !opt.opt_group.long_name.is_empty() {
+                            &opt.opt_group.long_name
                         } else {
-                            early_error(&f_stable_attempt.to_string());
+                            &opt.opt_group.short_name
+                        };
+                        if m.opt_present(opt_name) {
+                            early_error(&format!("use of unstable option '{}' requires \
+                                                  -Z unstable-options", opt_name));
                         }
                     }
-                    Err(_) => {
-                        // ignore the error from the unstable attempt; just
-                        // pass the error we got from the first try.
-                        early_error(&f_stable_attempt.to_string());
-                    }
                 }
+                m
             }
-        };
+            Err(f) => early_error(&f.to_string())
+        }
+    }
 
-    let r = matches.opt_strs("Z");
-    let include_unstable_options = r.iter().any(|x| *x == "unstable-options");
+    // As a speed optimization, first try to parse the command-line using just
+    // the stable options.
+    let matches = match getopts::getopts(&args[..], &config::optgroups()) {
+        Ok(ref m) if allows_unstable_options(m) => {
+            // If -Z unstable-options was specified, redo parsing with the
+            // unstable options to ensure that unstable options are defined
+            // in the returned getopts::Matches.
+            parse_all_options(&args)
+        }
+        Ok(m) => m,
+        Err(_) => {
+            // redo option parsing, including unstable options this time,
+            // in anticipation that the mishandled option was one of the
+            // unstable ones.
+            parse_all_options(&args)
+        }
+    };
 
     if matches.opt_present("h") || matches.opt_present("help") {
-        usage(matches.opt_present("verbose"), include_unstable_options);
+        usage(matches.opt_present("verbose"), allows_unstable_options(&matches));
         return None;
     }
 
@@ -764,12 +789,20 @@ fn parse_crate_attrs(sess: &Session, input: &Input) ->
 ///
 /// The diagnostic emitter yielded to the procedure should be used for reporting
 /// errors of the compiler.
+#[allow(deprecated)]
 pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
-    static STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB
+    const STACK_SIZE: usize = 8 * 1024 * 1024; // 8MB
 
-    let (tx, rx) = channel();
-    let w = old_io::ChanWriter::new(tx);
-    let mut r = old_io::ChanReader::new(rx);
+    struct Sink(Arc<Mutex<Vec<u8>>>);
+    impl Write for Sink {
+        fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+            Write::write(&mut *self.0.lock().unwrap(), data)
+        }
+        fn flush(&mut self) -> io::Result<()> { Ok(()) }
+    }
+
+    let data = Arc::new(Mutex::new(Vec::new()));
+    let err = Sink(data.clone());
 
     let mut cfg = thread::Builder::new().name("rustc".to_string());
 
@@ -779,7 +812,7 @@ pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
         cfg = cfg.stack_size(STACK_SIZE);
     }
 
-    match cfg.spawn(move || { stdio::set_stderr(box w); f() }).unwrap().join() {
+    match cfg.spawn(move || { io::set_panic(box err); f() }).unwrap().join() {
         Ok(()) => { /* fallthrough */ }
         Err(value) => {
             // Thread panicked without emitting a fatal diagnostic
@@ -806,22 +839,13 @@ pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
                     emitter.emit(None, &note[..], None, diagnostic::Note)
                 }
 
-                match r.read_to_string() {
-                    Ok(s) => println!("{}", s),
-                    Err(e) => {
-                        emitter.emit(None,
-                                     &format!("failed to read internal \
-                                              stderr: {}", e)[],
-                                     None,
-                                     diagnostic::Error)
-                    }
-                }
+                println!("{}", str::from_utf8(&data.lock().unwrap()).unwrap());
             }
 
             // Panic so the process returns a failure code, but don't pollute the
             // output with some unnecessary panic messages, we've already
             // printed everything that we needed to.
-            old_io::stdio::set_stderr(box old_io::util::NullWriter);
+            io::set_panic(box io::sink());
             panic!();
         }
     }
@@ -831,9 +855,9 @@ pub fn diagnostics_registry() -> diagnostics::registry::Registry {
     use syntax::diagnostics::registry::Registry;
 
     let all_errors = Vec::new() +
-        rustc::diagnostics::DIAGNOSTICS.as_slice() +
-        rustc_typeck::diagnostics::DIAGNOSTICS.as_slice() +
-        rustc_resolve::diagnostics::DIAGNOSTICS.as_slice();
+        &rustc::diagnostics::DIAGNOSTICS[..] +
+        &rustc_typeck::diagnostics::DIAGNOSTICS[..] +
+        &rustc_resolve::diagnostics::DIAGNOSTICS[..];
 
     Registry::new(&*all_errors)
 }
@@ -842,4 +866,3 @@ pub fn main() {
     let result = run(env::args().collect());
     std::env::set_exit_status(result as i32);
 }
-
index 0fbfa5fd89dd7f3fdc1216ccb271332640b6fff2..410f31e0900c4cabd7776454291e4f95b7d28785 100644 (file)
@@ -38,11 +38,13 @@ use syntax::ptr::P;
 
 use graphviz as dot;
 
-use std::old_io::{self, MemReader};
+use std::fs::File;
+use std::io::{self, Write};
 use std::option;
+use std::path::PathBuf;
 use std::str::FromStr;
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum PpSourceMode {
     PpmNormal,
     PpmEveryBodyLoops,
@@ -54,7 +56,7 @@ pub enum PpSourceMode {
 }
 
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum PpFlowGraphMode {
     Default,
     /// Drops the labels from the edges in the flowgraph output. This
@@ -63,7 +65,7 @@ pub enum PpFlowGraphMode {
     /// have become a pain to maintain.
     UnlabelledEdges,
 }
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum PpMode {
     PpmSource(PpSourceMode),
     PpmFlowGraph(PpFlowGraphMode),
@@ -72,7 +74,7 @@ pub enum PpMode {
 pub fn parse_pretty(sess: &Session,
                     name: &str,
                     extended: bool) -> (PpMode, Option<UserIdentifiedItem>) {
-    let mut split = name.splitn(1, '=');
+    let mut split = name.splitn(2, '=');
     let first = split.next().unwrap();
     let opt_second = split.next();
     let first = match (first, extended) {
@@ -208,7 +210,7 @@ impl<'ast> PrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
 impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
     fn pre(&self,
            s: &mut pprust::State,
-           node: pprust::AnnNode) -> old_io::IoResult<()> {
+           node: pprust::AnnNode) -> io::Result<()> {
         match node {
             pprust::NodeExpr(_) => s.popen(),
             _ => Ok(())
@@ -216,7 +218,7 @@ impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
     }
     fn post(&self,
             s: &mut pprust::State,
-            node: pprust::AnnNode) -> old_io::IoResult<()> {
+            node: pprust::AnnNode) -> io::Result<()> {
         match node {
             pprust::NodeIdent(_) | pprust::NodeName(_) => Ok(()),
 
@@ -224,6 +226,10 @@ impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
                 try!(pp::space(&mut s.s));
                 s.synth_comment(item.id.to_string())
             }
+            pprust::NodeSubItem(id) => {
+                try!(pp::space(&mut s.s));
+                s.synth_comment(id.to_string())
+            }
             pprust::NodeBlock(blk) => {
                 try!(pp::space(&mut s.s));
                 s.synth_comment(format!("block {}", blk.id))
@@ -259,7 +265,7 @@ impl<'ast> PrinterSupport<'ast> for HygieneAnnotation<'ast> {
 impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
     fn post(&self,
             s: &mut pprust::State,
-            node: pprust::AnnNode) -> old_io::IoResult<()> {
+            node: pprust::AnnNode) -> io::Result<()> {
         match node {
             pprust::NodeIdent(&ast::Ident { name: ast::Name(nm), ctxt }) => {
                 try!(pp::space(&mut s.s));
@@ -294,7 +300,7 @@ impl<'tcx> PrinterSupport<'tcx> for TypedAnnotation<'tcx> {
 impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> {
     fn pre(&self,
            s: &mut pprust::State,
-           node: pprust::AnnNode) -> old_io::IoResult<()> {
+           node: pprust::AnnNode) -> io::Result<()> {
         match node {
             pprust::NodeExpr(_) => s.popen(),
             _ => Ok(())
@@ -302,7 +308,7 @@ impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> {
     }
     fn post(&self,
             s: &mut pprust::State,
-            node: pprust::AnnNode) -> old_io::IoResult<()> {
+            node: pprust::AnnNode) -> io::Result<()> {
         let tcx = &self.analysis.ty_cx;
         match node {
             pprust::NodeExpr(expr) => {
@@ -312,7 +318,7 @@ impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> {
                 try!(pp::word(&mut s.s,
                               &ppaux::ty_to_string(
                                   tcx,
-                                  ty::expr_ty(tcx, expr))[]));
+                                  ty::expr_ty(tcx, expr))));
                 s.pclose()
             }
             _ => Ok(())
@@ -348,7 +354,7 @@ impl FromStr for UserIdentifiedItem {
     type Err = ();
     fn from_str(s: &str) -> Result<UserIdentifiedItem, ()> {
         Ok(s.parse().map(ItemViaNode).unwrap_or_else(|_| {
-            ItemViaPath(s.split_str("::").map(|s| s.to_string()).collect())
+            ItemViaPath(s.split("::").map(|s| s.to_string()).collect())
         }))
     }
 }
@@ -507,7 +513,7 @@ pub fn pretty_print_input(sess: Session,
                           input: &Input,
                           ppm: PpMode,
                           opt_uii: Option<UserIdentifiedItem>,
-                          ofile: Option<Path>) {
+                          ofile: Option<PathBuf>) {
     let krate = driver::phase_1_parse_input(&sess, cfg, input);
 
     let krate = if let PpmSource(PpmEveryBodyLoops) = ppm {
@@ -542,25 +548,20 @@ pub fn pretty_print_input(sess: Session,
 
     let src_name = driver::source_name(input);
     let src = sess.codemap().get_filemap(&src_name[..])
-                            .src.as_bytes().to_vec();
-    let mut rdr = MemReader::new(src);
+                            .src
+                            .as_ref()
+                            .unwrap()
+                            .as_bytes()
+                            .to_vec();
+    let mut rdr = &src[..];
 
-    let out = match ofile {
-        None => box old_io::stdout() as Box<Writer+'static>,
-        Some(p) => {
-            let r = old_io::File::create(&p);
-            match r {
-                Ok(w) => box w as Box<Writer+'static>,
-                Err(e) => panic!("print-print failed to open {} due to {}",
-                                p.display(), e),
-            }
-        }
-    };
+    let mut out = Vec::new();
 
     match (ppm, opt_uii) {
-        (PpmSource(s), None) =>
+        (PpmSource(s), None) => {
+            let out: &mut Write = &mut out;
             s.call_with_pp_support(
-                sess, ast_map, &arenas, id, out, |annotation, out| {
+                sess, ast_map, &arenas, id, box out, |annotation, out| {
                     debug!("pretty printing source code {:?}", s);
                     let sess = annotation.sess();
                     pprust::print_crate(sess.codemap(),
@@ -571,9 +572,11 @@ pub fn pretty_print_input(sess: Session,
                                         out,
                                         annotation.pp_ann(),
                                         is_expanded)
-                }),
+            })
+        }
 
-        (PpmSource(s), Some(uii)) =>
+        (PpmSource(s), Some(uii)) => {
+            let out: &mut Write = &mut out;
             s.call_with_pp_support(
                 sess, ast_map, &arenas, id, (out,uii), |annotation, (out,uii)| {
                     debug!("pretty printing source code {:?}", s);
@@ -585,7 +588,7 @@ pub fn pretty_print_input(sess: Session,
                                                       sess.diagnostic(),
                                                       src_name.to_string(),
                                                       &mut rdr,
-                                                      out,
+                                                      box out,
                                                       annotation.pp_ann(),
                                                       is_expanded);
                     for node_id in uii.all_matching_node_ids(ast_map) {
@@ -596,13 +599,14 @@ pub fn pretty_print_input(sess: Session,
                         try!(pp::hardbreak(&mut pp_state.s));
                     }
                     pp::eof(&mut pp_state.s)
-                }),
+                })
+        }
 
         (PpmFlowGraph(mode), opt_uii) => {
             debug!("pretty printing flow graph for {:?}", opt_uii);
             let uii = opt_uii.unwrap_or_else(|| {
                 sess.fatal(&format!("`pretty flowgraph=..` needs NodeId (int) or
-                                     unique path suffix (b::c::d)")[])
+                                     unique path suffix (b::c::d)"))
 
             });
             let ast_map = ast_map.expect("--pretty flowgraph missing ast_map");
@@ -610,10 +614,11 @@ pub fn pretty_print_input(sess: Session,
 
             let node = ast_map.find(nodeid).unwrap_or_else(|| {
                 sess.fatal(&format!("--pretty flowgraph couldn't find id: {}",
-                                   nodeid)[])
+                                   nodeid))
             });
 
             let code = blocks::Code::from_node(node);
+            let out: &mut Write = &mut out;
             match code {
                 Some(code) => {
                     let variants = gather_flowgraph_variants(&sess);
@@ -638,14 +643,25 @@ pub fn pretty_print_input(sess: Session,
                 }
             }
         }
-    }.unwrap()
+    }.unwrap();
+
+    match ofile {
+        None => print!("{}", String::from_utf8(out).unwrap()),
+        Some(p) => {
+            match File::create(&p) {
+                Ok(mut w) => w.write_all(&out).unwrap(),
+                Err(e) => panic!("print-print failed to open {} due to {}",
+                                p.display(), e),
+            }
+        }
+    }
 }
 
-fn print_flowgraph<W:old_io::Writer>(variants: Vec<borrowck_dot::Variant>,
-                                 analysis: ty::CrateAnalysis,
-                                 code: blocks::Code,
-                                 mode: PpFlowGraphMode,
-                                 mut out: W) -> old_io::IoResult<()> {
+fn print_flowgraph<W: Write>(variants: Vec<borrowck_dot::Variant>,
+                             analysis: ty::CrateAnalysis,
+                             code: blocks::Code,
+                             mode: PpFlowGraphMode,
+                             mut out: W) -> io::Result<()> {
     let ty_cx = &analysis.ty_cx;
     let cfg = match code {
         blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block),
@@ -685,17 +701,10 @@ fn print_flowgraph<W:old_io::Writer>(variants: Vec<borrowck_dot::Variant>,
         }
     }
 
-    fn expand_err_details(r: old_io::IoResult<()>) -> old_io::IoResult<()> {
+    fn expand_err_details(r: io::Result<()>) -> io::Result<()> {
         r.map_err(|ioerr| {
-            let orig_detail = ioerr.detail.clone();
-            let m = "graphviz::render failed";
-            old_io::IoError {
-                detail: Some(match orig_detail {
-                    None => m.to_string(),
-                    Some(d) => format!("{}: {}", m, d)
-                }),
-                ..ioerr
-            }
+            io::Error::new(io::ErrorKind::Other,
+                           &format!("graphviz::render failed: {}", ioerr)[..])
         })
     }
 }
index fbbd72e2c76be6efd75fe6182759d3d578997c0a..f9be71561e384b5b2a85800eeca108ef90fef1c7 100644 (file)
@@ -13,6 +13,7 @@
 use diagnostic;
 use diagnostic::Emitter;
 use driver;
+use rustc_lint;
 use rustc_resolve as resolve;
 use rustc_typeck::middle::lang_items;
 use rustc_typeck::middle::region::{self, CodeExtent, DestructionScopeData};
@@ -21,7 +22,7 @@ use rustc_typeck::middle::stability;
 use rustc_typeck::middle::subst;
 use rustc_typeck::middle::subst::Subst;
 use rustc_typeck::middle::ty::{self, Ty};
-use rustc_typeck::middle::infer::combine::Combine;
+use rustc_typeck::middle::ty_relate::TypeRelation;
 use rustc_typeck::middle::infer;
 use rustc_typeck::middle::infer::lub::Lub;
 use rustc_typeck::middle::infer::glb::Glb;
@@ -43,7 +44,7 @@ struct RH<'a> {
     sub: &'a [RH<'a>]
 }
 
-static EMPTY_SOURCE_STR: &'static str = "#![feature(no_std)] #![no_std]";
+const EMPTY_SOURCE_STR: &'static str = "#![feature(no_std)] #![no_std]";
 
 struct ExpectErrorEmitter {
     messages: Vec<String>
@@ -87,13 +88,13 @@ impl Emitter for ExpectErrorEmitter {
     }
 }
 
-fn errors(msgs: &[&str]) -> (Box<Emitter+Send>, uint) {
+fn errors(msgs: &[&str]) -> (Box<Emitter+Send>, usize) {
     let v = msgs.iter().map(|m| m.to_string()).collect();
     (box ExpectErrorEmitter { messages: v } as Box<Emitter+Send>, msgs.len())
 }
 
 fn test_env<F>(source_string: &str,
-               (emitter, expected_err_count): (Box<Emitter+Send>, uint),
+               (emitter, expected_err_count): (Box<Emitter+Send>, usize),
                body: F) where
     F: FnOnce(Env),
 {
@@ -108,6 +109,7 @@ fn test_env<F>(source_string: &str,
         diagnostic::mk_span_handler(diagnostic_handler, codemap);
 
     let sess = session::build_session_(options, None, span_diagnostic_handler);
+    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
     let krate_config = Vec::new();
     let input = config::Input::Str(source_string.to_string());
     let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
@@ -176,7 +178,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
 
         fn search_mod(this: &Env,
                       m: &ast::Mod,
-                      idx: uint,
+                      idx: usize,
                       names: &[String])
                       -> Option<ast::NodeId> {
             assert!(idx < names.len());
@@ -190,7 +192,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
 
         fn search(this: &Env,
                   it: &ast::Item,
-                  idx: uint,
+                  idx: usize,
                   names: &[String])
                   -> Option<ast::NodeId> {
             if idx == names.len() {
@@ -206,7 +208,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
 
                 ast::ItemEnum(..) | ast::ItemStruct(..) |
                 ast::ItemTrait(..) | ast::ItemImpl(..) |
-                ast::ItemMac(..) => {
+                ast::ItemMac(..) | ast::ItemDefaultImpl(..) => {
                     None
                 }
 
@@ -298,14 +300,14 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
     pub fn t_rptr(&self, r: ty::Region) -> Ty<'tcx> {
         ty::mk_imm_rptr(self.infcx.tcx,
                         self.infcx.tcx.mk_region(r),
-                        self.tcx().types.int)
+                        self.tcx().types.isize)
     }
 
     pub fn t_rptr_late_bound(&self, id: u32) -> Ty<'tcx> {
         let r = self.re_late_bound_with_debruijn(id, ty::DebruijnIndex::new(1));
         ty::mk_imm_rptr(self.infcx.tcx,
                         self.infcx.tcx.mk_region(r),
-                        self.tcx().types.int)
+                        self.tcx().types.isize)
     }
 
     pub fn t_rptr_late_bound_with_debruijn(&self,
@@ -315,13 +317,13 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
         let r = self.re_late_bound_with_debruijn(id, debruijn);
         ty::mk_imm_rptr(self.infcx.tcx,
                         self.infcx.tcx.mk_region(r),
-                        self.tcx().types.int)
+                        self.tcx().types.isize)
     }
 
     pub fn t_rptr_scope(&self, id: ast::NodeId) -> Ty<'tcx> {
         let r = ty::ReScope(CodeExtent::from_node_id(id));
         ty::mk_imm_rptr(self.infcx.tcx, self.infcx.tcx.mk_region(r),
-                        self.tcx().types.int)
+                        self.tcx().types.isize)
     }
 
     pub fn re_free(&self, nid: ast::NodeId, id: u32) -> ty::Region {
@@ -333,13 +335,13 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
         let r = self.re_free(nid, id);
         ty::mk_imm_rptr(self.infcx.tcx,
                         self.infcx.tcx.mk_region(r),
-                        self.tcx().types.int)
+                        self.tcx().types.isize)
     }
 
     pub fn t_rptr_static(&self) -> Ty<'tcx> {
         ty::mk_imm_rptr(self.infcx.tcx,
                         self.infcx.tcx.mk_region(ty::ReStatic),
-                        self.tcx().types.int)
+                        self.tcx().types.isize)
     }
 
     pub fn dummy_type_trace(&self) -> infer::TypeTrace<'tcx> {
@@ -348,21 +350,21 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
 
     pub fn sub(&self) -> Sub<'a, 'tcx> {
         let trace = self.dummy_type_trace();
-        Sub(self.infcx.combine_fields(true, trace))
+        self.infcx.sub(true, trace)
     }
 
     pub fn lub(&self) -> Lub<'a, 'tcx> {
         let trace = self.dummy_type_trace();
-        Lub(self.infcx.combine_fields(true, trace))
+        self.infcx.lub(true, trace)
     }
 
     pub fn glb(&self) -> Glb<'a, 'tcx> {
         let trace = self.dummy_type_trace();
-        Glb(self.infcx.combine_fields(true, trace))
+        self.infcx.glb(true, trace)
     }
 
     pub fn make_lub_ty(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> Ty<'tcx> {
-        match self.lub().tys(t1, t2) {
+        match self.lub().relate(&t1, &t2) {
             Ok(t) => t,
             Err(ref e) => panic!("unexpected error computing LUB: {}",
                                 ty::type_err_to_str(self.infcx.tcx, e))
@@ -372,7 +374,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
     /// Checks that `t1 <: t2` is true (this may register additional
     /// region checks).
     pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
-        match self.sub().tys(t1, t2) {
+        match self.sub().relate(&t1, &t2) {
             Ok(_) => { }
             Err(ref e) => {
                 panic!("unexpected error computing sub({},{}): {}",
@@ -386,7 +388,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
     /// Checks that `t1 <: t2` is false (this may register additional
     /// region checks).
     pub fn check_not_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
-        match self.sub().tys(t1, t2) {
+        match self.sub().relate(&t1, &t2) {
             Err(_) => { }
             Ok(_) => {
                 panic!("unexpected success computing sub({},{})",
@@ -398,7 +400,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
 
     /// Checks that `LUB(t1,t2) == t_lub`
     pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) {
-        match self.lub().tys(t1, t2) {
+        match self.lub().relate(&t1, &t2) {
             Ok(t) => {
                 self.assert_eq(t, t_lub);
             }
@@ -415,7 +417,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
                self.ty_to_string(t1),
                self.ty_to_string(t2),
                self.ty_to_string(t_glb));
-        match self.glb().tys(t1, t2) {
+        match self.glb().relate(&t1, &t2) {
             Err(e) => {
                 panic!("unexpected error computing LUB: {:?}", e)
             }
@@ -462,15 +464,15 @@ fn contravariant_region_ptr_err() {
 fn sub_free_bound_false() {
     //! Test that:
     //!
-    //!     fn(&'a int) <: for<'b> fn(&'b int)
+    //!     fn(&'a isize) <: for<'b> fn(&'b isize)
     //!
     //! does NOT hold.
 
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let t_rptr_free1 = env.t_rptr_free(0, 1);
         let t_rptr_bound1 = env.t_rptr_late_bound(1);
-        env.check_not_sub(env.t_fn(&[t_rptr_free1], env.tcx().types.int),
-                          env.t_fn(&[t_rptr_bound1], env.tcx().types.int));
+        env.check_not_sub(env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
+                          env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
     })
 }
 
@@ -478,15 +480,15 @@ fn sub_free_bound_false() {
 fn sub_bound_free_true() {
     //! Test that:
     //!
-    //!     for<'a> fn(&'a int) <: fn(&'b int)
+    //!     for<'a> fn(&'a isize) <: fn(&'b isize)
     //!
     //! DOES hold.
 
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let t_rptr_bound1 = env.t_rptr_late_bound(1);
         let t_rptr_free1 = env.t_rptr_free(0, 1);
-        env.check_sub(env.t_fn(&[t_rptr_bound1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_free1], env.tcx().types.int));
+        env.check_sub(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_free1], env.tcx().types.isize));
     })
 }
 
@@ -494,15 +496,15 @@ fn sub_bound_free_true() {
 fn sub_free_bound_false_infer() {
     //! Test that:
     //!
-    //!     fn(_#1) <: for<'b> fn(&'b int)
+    //!     fn(_#1) <: for<'b> fn(&'b isize)
     //!
     //! does NOT hold for any instantiation of `_#1`.
 
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let t_infer1 = env.infcx.next_ty_var();
         let t_rptr_bound1 = env.t_rptr_late_bound(1);
-        env.check_not_sub(env.t_fn(&[t_infer1], env.tcx().types.int),
-                          env.t_fn(&[t_rptr_bound1], env.tcx().types.int));
+        env.check_not_sub(env.t_fn(&[t_infer1], env.tcx().types.isize),
+                          env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
     })
 }
 
@@ -510,19 +512,19 @@ fn sub_free_bound_false_infer() {
 fn lub_free_bound_infer() {
     //! Test result of:
     //!
-    //!     LUB(fn(_#1), for<'b> fn(&'b int))
+    //!     LUB(fn(_#1), for<'b> fn(&'b isize))
     //!
-    //! This should yield `fn(&'_ int)`. We check
-    //! that it yields `fn(&'x int)` for some free `'x`,
+    //! This should yield `fn(&'_ isize)`. We check
+    //! that it yields `fn(&'x isize)` for some free `'x`,
     //! anyhow.
 
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let t_infer1 = env.infcx.next_ty_var();
         let t_rptr_bound1 = env.t_rptr_late_bound(1);
         let t_rptr_free1 = env.t_rptr_free(0, 1);
-        env.check_lub(env.t_fn(&[t_infer1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_bound1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_free1], env.tcx().types.int));
+        env.check_lub(env.t_fn(&[t_infer1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_free1], env.tcx().types.isize));
     });
 }
 
@@ -531,9 +533,9 @@ fn lub_bound_bound() {
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let t_rptr_bound1 = env.t_rptr_late_bound(1);
         let t_rptr_bound2 = env.t_rptr_late_bound(2);
-        env.check_lub(env.t_fn(&[t_rptr_bound1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_bound2], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_bound1], env.tcx().types.int));
+        env.check_lub(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_bound2], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
     })
 }
 
@@ -542,9 +544,9 @@ fn lub_bound_free() {
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let t_rptr_bound1 = env.t_rptr_late_bound(1);
         let t_rptr_free1 = env.t_rptr_free(0, 1);
-        env.check_lub(env.t_fn(&[t_rptr_bound1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_free1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_free1], env.tcx().types.int));
+        env.check_lub(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_free1], env.tcx().types.isize));
     })
 }
 
@@ -553,9 +555,9 @@ fn lub_bound_static() {
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let t_rptr_bound1 = env.t_rptr_late_bound(1);
         let t_rptr_static = env.t_rptr_static();
-        env.check_lub(env.t_fn(&[t_rptr_bound1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_static], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_static], env.tcx().types.int));
+        env.check_lub(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_static], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_static], env.tcx().types.isize));
     })
 }
 
@@ -576,9 +578,9 @@ fn lub_free_free() {
         let t_rptr_free1 = env.t_rptr_free(0, 1);
         let t_rptr_free2 = env.t_rptr_free(0, 2);
         let t_rptr_static = env.t_rptr_static();
-        env.check_lub(env.t_fn(&[t_rptr_free1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_free2], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_static], env.tcx().types.int));
+        env.check_lub(env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_free2], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_static], env.tcx().types.isize));
     })
 }
 
@@ -586,6 +588,7 @@ fn lub_free_free() {
 fn lub_returning_scope() {
     test_env(EMPTY_SOURCE_STR,
              errors(&["cannot infer an appropriate lifetime"]), |env| {
+                 env.create_simple_region_hierarchy();
                  let t_rptr_scope10 = env.t_rptr_scope(10);
                  let t_rptr_scope11 = env.t_rptr_scope(11);
 
@@ -601,9 +604,9 @@ fn glb_free_free_with_common_scope() {
         let t_rptr_free1 = env.t_rptr_free(0, 1);
         let t_rptr_free2 = env.t_rptr_free(0, 2);
         let t_rptr_scope = env.t_rptr_scope(0);
-        env.check_glb(env.t_fn(&[t_rptr_free1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_free2], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_scope], env.tcx().types.int));
+        env.check_glb(env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_free2], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_scope], env.tcx().types.isize));
     })
 }
 
@@ -612,9 +615,9 @@ fn glb_bound_bound() {
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let t_rptr_bound1 = env.t_rptr_late_bound(1);
         let t_rptr_bound2 = env.t_rptr_late_bound(2);
-        env.check_glb(env.t_fn(&[t_rptr_bound1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_bound2], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_bound1], env.tcx().types.int));
+        env.check_glb(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_bound2], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
     })
 }
 
@@ -623,9 +626,9 @@ fn glb_bound_free() {
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let t_rptr_bound1 = env.t_rptr_late_bound(1);
         let t_rptr_free1 = env.t_rptr_free(0, 1);
-        env.check_glb(env.t_fn(&[t_rptr_bound1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_free1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_bound1], env.tcx().types.int));
+        env.check_glb(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
     })
 }
 
@@ -635,14 +638,14 @@ fn glb_bound_free_infer() {
         let t_rptr_bound1 = env.t_rptr_late_bound(1);
         let t_infer1 = env.infcx.next_ty_var();
 
-        // compute GLB(fn(_) -> int, for<'b> fn(&'b int) -> int),
-        // which should yield for<'b> fn(&'b int) -> int
-        env.check_glb(env.t_fn(&[t_rptr_bound1], env.tcx().types.int),
-                      env.t_fn(&[t_infer1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_bound1], env.tcx().types.int));
+        // compute GLB(fn(_) -> isize, for<'b> fn(&'b isize) -> isize),
+        // which should yield for<'b> fn(&'b isize) -> isize
+        env.check_glb(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
+                      env.t_fn(&[t_infer1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
 
         // as a side-effect, computing GLB should unify `_` with
-        // `&'_ int`
+        // `&'_ isize`
         let t_resolve1 = env.infcx.shallow_resolve(t_infer1);
         match t_resolve1.sty {
             ty::ty_rptr(..) => { }
@@ -656,9 +659,9 @@ fn glb_bound_static() {
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let t_rptr_bound1 = env.t_rptr_late_bound(1);
         let t_rptr_static = env.t_rptr_static();
-        env.check_glb(env.t_fn(&[t_rptr_bound1], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_static], env.tcx().types.int),
-                      env.t_fn(&[t_rptr_bound1], env.tcx().types.int));
+        env.check_glb(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_static], env.tcx().types.isize),
+                      env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
     })
 }
 
@@ -682,7 +685,7 @@ fn subst_ty_renumber_bound() {
         let substs = subst::Substs::new_type(vec![t_rptr_bound1], vec![]);
         let t_substituted = t_source.subst(env.infcx.tcx, &substs);
 
-        // t_expected = fn(&'a int)
+        // t_expected = fn(&'a isize)
         let t_expected = {
             let t_ptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, ty::DebruijnIndex::new(2));
             env.t_fn(&[t_ptr_bound2], env.t_nil())
@@ -717,7 +720,7 @@ fn subst_ty_renumber_some_bounds() {
         let substs = subst::Substs::new_type(vec![t_rptr_bound1], vec![]);
         let t_substituted = t_source.subst(env.infcx.tcx, &substs);
 
-        // t_expected = (&'a int, fn(&'a int))
+        // t_expected = (&'a isize, fn(&'a isize))
         //
         // but not that the Debruijn index is different in the different cases.
         let t_expected = {
@@ -769,7 +772,7 @@ fn subst_region_renumber_region() {
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let re_bound1 = env.re_late_bound_with_debruijn(1, ty::DebruijnIndex::new(1));
 
-        // type t_source<'a> = fn(&'a int)
+        // type t_source<'a> = fn(&'a isize)
         let t_source = {
             let re_early = env.re_early_bound(subst::TypeSpace, 0, "'a");
             env.t_fn(&[env.t_rptr(re_early)], env.t_nil())
@@ -778,7 +781,7 @@ fn subst_region_renumber_region() {
         let substs = subst::Substs::new_type(vec![], vec![re_bound1]);
         let t_substituted = t_source.subst(env.infcx.tcx, &substs);
 
-        // t_expected = fn(&'a int)
+        // t_expected = fn(&'a isize)
         //
         // but not that the Debruijn index is different in the different cases.
         let t_expected = {
@@ -800,18 +803,17 @@ fn subst_region_renumber_region() {
 fn walk_ty() {
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let tcx = env.infcx.tcx;
-        let int_ty = tcx.types.int;
-        let uint_ty = tcx.types.uint;
+        let int_ty = tcx.types.isize;
+        let uint_ty = tcx.types.usize;
         let tup1_ty = ty::mk_tup(tcx, vec!(int_ty, uint_ty, int_ty, uint_ty));
         let tup2_ty = ty::mk_tup(tcx, vec!(tup1_ty, tup1_ty, uint_ty));
         let uniq_ty = ty::mk_uniq(tcx, tup2_ty);
         let walked: Vec<_> = uniq_ty.walk().collect();
-        assert_eq!(vec!(uniq_ty,
-                        tup2_ty,
-                        tup1_ty, int_ty, uint_ty, int_ty, uint_ty,
-                        tup1_ty, int_ty, uint_ty, int_ty, uint_ty,
-                        uint_ty),
-                   walked);
+        assert_eq!(walked, [uniq_ty,
+                            tup2_ty,
+                            tup1_ty, int_ty, uint_ty, int_ty, uint_ty,
+                            tup1_ty, int_ty, uint_ty, int_ty, uint_ty,
+                            uint_ty]);
     })
 }
 
@@ -819,8 +821,8 @@ fn walk_ty() {
 fn walk_ty_skip_subtree() {
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
         let tcx = env.infcx.tcx;
-        let int_ty = tcx.types.int;
-        let uint_ty = tcx.types.uint;
+        let int_ty = tcx.types.isize;
+        let uint_ty = tcx.types.usize;
         let tup1_ty = ty::mk_tup(tcx, vec!(int_ty, uint_ty, int_ty, uint_ty));
         let tup2_ty = ty::mk_tup(tcx, vec!(tup1_ty, tup1_ty, uint_ty));
         let uniq_ty = ty::mk_uniq(tcx, tup2_ty);
@@ -834,7 +836,7 @@ fn walk_ty_skip_subtree() {
                                 (uint_ty, false),
                                 (int_ty, false),
                                 (uint_ty, false),
-                                (tup1_ty, true), // skip the int/uint/int/uint
+                                (tup1_ty, true), // skip the isize/usize/isize/usize
                                 (uint_ty, false));
         expected.reverse();
 
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
new file mode 100644 (file)
index 0000000..3bb737d
--- /dev/null
@@ -0,0 +1,2109 @@
+// Copyright 2012-2015 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.
+
+//! Lints in the Rust compiler.
+//!
+//! This contains lints which can feasibly be implemented as their own
+//! AST visitor. Also see `rustc::lint::builtin`, which contains the
+//! definitions of lints that are emitted directly inside the main
+//! compiler.
+//!
+//! To add a new lint to rustc, declare it here using `declare_lint!()`.
+//! Then add code to emit the new lint in the appropriate circumstances.
+//! You can do that in an existing `LintPass` if it makes sense, or in a
+//! new `LintPass`, or using `Session::add_lint` elsewhere in the
+//! compiler. Only do the latter if the check can't be written cleanly as a
+//! `LintPass` (also, note that such lints will need to be defined in
+//! `rustc::lint::builtin`, not here).
+//!
+//! If you define a new `LintPass`, you will also need to add it to the
+//! `add_builtin!` or `add_builtin_with_new!` invocation in `lib.rs`.
+//! Use the former for unit-like structs and the latter for structs with
+//! a `pub fn new()`.
+
+use metadata::{csearch, decoder};
+use middle::def::*;
+use middle::subst::Substs;
+use middle::ty::{self, Ty};
+use middle::{def, pat_util, stability};
+use middle::const_eval::{eval_const_expr_partial, const_int, const_uint};
+use middle::cfg;
+use util::ppaux::ty_to_string;
+use util::nodemap::{FnvHashMap, NodeSet};
+use lint::{Level, Context, LintPass, LintArray, Lint};
+
+use std::collections::{HashSet, BitSet};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
+use std::{cmp, slice};
+use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
+
+use syntax::{abi, ast, ast_map};
+use syntax::ast_util::{self, is_shift_binop, local_def};
+use syntax::attr::{self, AttrMetaMethods};
+use syntax::codemap::{self, Span};
+use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType};
+use syntax::parse::token;
+use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};
+use syntax::ptr::P;
+use syntax::visit::{self, Visitor};
+
+// hardwired lints from librustc
+pub use lint::builtin::*;
+
+declare_lint! {
+    WHILE_TRUE,
+    Warn,
+    "suggest using `loop { }` instead of `while true { }`"
+}
+
+#[derive(Copy, Clone)]
+pub struct WhileTrue;
+
+impl LintPass for WhileTrue {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(WHILE_TRUE)
+    }
+
+    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
+        if let ast::ExprWhile(ref cond, _, _) = e.node {
+            if let ast::ExprLit(ref lit) = cond.node {
+                if let ast::LitBool(true) = lit.node {
+                    cx.span_lint(WHILE_TRUE, e.span,
+                                 "denote infinite loops with loop { ... }");
+                }
+            }
+        }
+    }
+}
+
+declare_lint! {
+    UNSIGNED_NEGATION,
+    Warn,
+    "using an unary minus operator on unsigned type"
+}
+
+declare_lint! {
+    UNUSED_COMPARISONS,
+    Warn,
+    "comparisons made useless by limits of the types involved"
+}
+
+declare_lint! {
+    OVERFLOWING_LITERALS,
+    Warn,
+    "literal out of range for its type"
+}
+
+declare_lint! {
+    EXCEEDING_BITSHIFTS,
+    Deny,
+    "shift exceeds the type's number of bits"
+}
+
+#[derive(Copy, Clone)]
+pub struct TypeLimits {
+    /// Id of the last visited negated expression
+    negated_expr_id: ast::NodeId,
+}
+
+impl TypeLimits {
+    pub fn new() -> TypeLimits {
+        TypeLimits {
+            negated_expr_id: !0,
+        }
+    }
+}
+
+impl LintPass for TypeLimits {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(UNSIGNED_NEGATION, UNUSED_COMPARISONS, OVERFLOWING_LITERALS,
+                    EXCEEDING_BITSHIFTS)
+    }
+
+    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
+        match e.node {
+            ast::ExprUnary(ast::UnNeg, ref expr) => {
+                match expr.node  {
+                    ast::ExprLit(ref lit) => {
+                        match lit.node {
+                            ast::LitInt(_, ast::UnsignedIntLit(_)) => {
+                                cx.span_lint(UNSIGNED_NEGATION, e.span,
+                                             "negation of unsigned int literal may \
+                                             be unintentional");
+                            },
+                            _ => ()
+                        }
+                    },
+                    _ => {
+                        let t = ty::expr_ty(cx.tcx, &**expr);
+                        match t.sty {
+                            ty::ty_uint(_) => {
+                                cx.span_lint(UNSIGNED_NEGATION, e.span,
+                                             "negation of unsigned int variable may \
+                                             be unintentional");
+                            },
+                            _ => ()
+                        }
+                    }
+                };
+                // propagate negation, if the negation itself isn't negated
+                if self.negated_expr_id != e.id {
+                    self.negated_expr_id = expr.id;
+                }
+            },
+            ast::ExprParen(ref expr) if self.negated_expr_id == e.id => {
+                self.negated_expr_id = expr.id;
+            },
+            ast::ExprBinary(binop, ref l, ref r) => {
+                if is_comparison(binop) && !check_limits(cx.tcx, binop, &**l, &**r) {
+                    cx.span_lint(UNUSED_COMPARISONS, e.span,
+                                 "comparison is useless due to type limits");
+                }
+
+                if is_shift_binop(binop.node) {
+                    let opt_ty_bits = match ty::expr_ty(cx.tcx, &**l).sty {
+                        ty::ty_int(t) => Some(int_ty_bits(t, cx.sess().target.int_type)),
+                        ty::ty_uint(t) => Some(uint_ty_bits(t, cx.sess().target.uint_type)),
+                        _ => None
+                    };
+
+                    if let Some(bits) = opt_ty_bits {
+                        let exceeding = if let ast::ExprLit(ref lit) = r.node {
+                            if let ast::LitInt(shift, _) = lit.node { shift >= bits }
+                            else { false }
+                        } else {
+                            match eval_const_expr_partial(cx.tcx, &**r, Some(cx.tcx.types.usize)) {
+                                Ok(const_int(shift)) => { shift as u64 >= bits },
+                                Ok(const_uint(shift)) => { shift >= bits },
+                                _ => { false }
+                            }
+                        };
+                        if exceeding {
+                            cx.span_lint(EXCEEDING_BITSHIFTS, e.span,
+                                         "bitshift exceeds the type's number of bits");
+                        }
+                    };
+                }
+            },
+            ast::ExprLit(ref lit) => {
+                match ty::expr_ty(cx.tcx, e).sty {
+                    ty::ty_int(t) => {
+                        match lit.node {
+                            ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
+                            ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
+                                let int_type = if let ast::TyIs = t {
+                                    cx.sess().target.int_type
+                                } else {
+                                    t
+                                };
+                                let (min, max) = int_ty_range(int_type);
+                                let negative = self.negated_expr_id == e.id;
+
+                                if (negative && v > (min.abs() as u64)) ||
+                                   (!negative && v > (max.abs() as u64)) {
+                                    cx.span_lint(OVERFLOWING_LITERALS, e.span,
+                                                 &*format!("literal out of range for {:?}", t));
+                                    return;
+                                }
+                            }
+                            _ => panic!()
+                        };
+                    },
+                    ty::ty_uint(t) => {
+                        let uint_type = if let ast::TyUs = t {
+                            cx.sess().target.uint_type
+                        } else {
+                            t
+                        };
+                        let (min, max) = uint_ty_range(uint_type);
+                        let lit_val: u64 = match lit.node {
+                            ast::LitByte(_v) => return,  // _v is u8, within range by definition
+                            ast::LitInt(v, _) => v,
+                            _ => panic!()
+                        };
+                        if lit_val < min || lit_val > max {
+                            cx.span_lint(OVERFLOWING_LITERALS, e.span,
+                                         &*format!("literal out of range for {:?}", t));
+                        }
+                    },
+                    ty::ty_float(t) => {
+                        let (min, max) = float_ty_range(t);
+                        let lit_val: f64 = match lit.node {
+                            ast::LitFloat(ref v, _) |
+                            ast::LitFloatUnsuffixed(ref v) => {
+                                match v.parse() {
+                                    Ok(f) => f,
+                                    Err(_) => return
+                                }
+                            }
+                            _ => panic!()
+                        };
+                        if lit_val < min || lit_val > max {
+                            cx.span_lint(OVERFLOWING_LITERALS, e.span,
+                                         &*format!("literal out of range for {:?}", t));
+                        }
+                    },
+                    _ => ()
+                };
+            },
+            _ => ()
+        };
+
+        fn is_valid<T:cmp::PartialOrd>(binop: ast::BinOp, v: T,
+                                min: T, max: T) -> bool {
+            match binop.node {
+                ast::BiLt => v >  min && v <= max,
+                ast::BiLe => v >= min && v <  max,
+                ast::BiGt => v >= min && v <  max,
+                ast::BiGe => v >  min && v <= max,
+                ast::BiEq | ast::BiNe => v >= min && v <= max,
+                _ => panic!()
+            }
+        }
+
+        fn rev_binop(binop: ast::BinOp) -> ast::BinOp {
+            codemap::respan(binop.span, match binop.node {
+                ast::BiLt => ast::BiGt,
+                ast::BiLe => ast::BiGe,
+                ast::BiGt => ast::BiLt,
+                ast::BiGe => ast::BiLe,
+                _ => return binop
+            })
+        }
+
+        // for isize & usize, be conservative with the warnings, so that the
+        // warnings are consistent between 32- and 64-bit platforms
+        fn int_ty_range(int_ty: ast::IntTy) -> (i64, i64) {
+            match int_ty {
+                ast::TyIs => (i64::MIN,        i64::MAX),
+                ast::TyI8 =>    (i8::MIN  as i64, i8::MAX  as i64),
+                ast::TyI16 =>   (i16::MIN as i64, i16::MAX as i64),
+                ast::TyI32 =>   (i32::MIN as i64, i32::MAX as i64),
+                ast::TyI64 =>   (i64::MIN,        i64::MAX)
+            }
+        }
+
+        fn uint_ty_range(uint_ty: ast::UintTy) -> (u64, u64) {
+            match uint_ty {
+                ast::TyUs => (u64::MIN,         u64::MAX),
+                ast::TyU8 =>    (u8::MIN   as u64, u8::MAX   as u64),
+                ast::TyU16 =>   (u16::MIN  as u64, u16::MAX  as u64),
+                ast::TyU32 =>   (u32::MIN  as u64, u32::MAX  as u64),
+                ast::TyU64 =>   (u64::MIN,         u64::MAX)
+            }
+        }
+
+        fn float_ty_range(float_ty: ast::FloatTy) -> (f64, f64) {
+            match float_ty {
+                ast::TyF32 => (f32::MIN as f64, f32::MAX as f64),
+                ast::TyF64 => (f64::MIN,        f64::MAX)
+            }
+        }
+
+        fn int_ty_bits(int_ty: ast::IntTy, target_int_ty: ast::IntTy) -> u64 {
+            match int_ty {
+                ast::TyIs => int_ty_bits(target_int_ty, target_int_ty),
+                ast::TyI8 =>    i8::BITS  as u64,
+                ast::TyI16 =>   i16::BITS as u64,
+                ast::TyI32 =>   i32::BITS as u64,
+                ast::TyI64 =>   i64::BITS as u64
+            }
+        }
+
+        fn uint_ty_bits(uint_ty: ast::UintTy, target_uint_ty: ast::UintTy) -> u64 {
+            match uint_ty {
+                ast::TyUs => uint_ty_bits(target_uint_ty, target_uint_ty),
+                ast::TyU8 =>    u8::BITS  as u64,
+                ast::TyU16 =>   u16::BITS as u64,
+                ast::TyU32 =>   u32::BITS as u64,
+                ast::TyU64 =>   u64::BITS as u64
+            }
+        }
+
+        fn check_limits(tcx: &ty::ctxt, binop: ast::BinOp,
+                        l: &ast::Expr, r: &ast::Expr) -> bool {
+            let (lit, expr, swap) = match (&l.node, &r.node) {
+                (&ast::ExprLit(_), _) => (l, r, true),
+                (_, &ast::ExprLit(_)) => (r, l, false),
+                _ => return true
+            };
+            // Normalize the binop so that the literal is always on the RHS in
+            // the comparison
+            let norm_binop = if swap {
+                rev_binop(binop)
+            } else {
+                binop
+            };
+            match ty::expr_ty(tcx, expr).sty {
+                ty::ty_int(int_ty) => {
+                    let (min, max) = int_ty_range(int_ty);
+                    let lit_val: i64 = match lit.node {
+                        ast::ExprLit(ref li) => match li.node {
+                            ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
+                            ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => v as i64,
+                            ast::LitInt(v, ast::SignedIntLit(_, ast::Minus)) |
+                            ast::LitInt(v, ast::UnsuffixedIntLit(ast::Minus)) => -(v as i64),
+                            _ => return true
+                        },
+                        _ => panic!()
+                    };
+                    is_valid(norm_binop, lit_val, min, max)
+                }
+                ty::ty_uint(uint_ty) => {
+                    let (min, max): (u64, u64) = uint_ty_range(uint_ty);
+                    let lit_val: u64 = match lit.node {
+                        ast::ExprLit(ref li) => match li.node {
+                            ast::LitInt(v, _) => v,
+                            _ => return true
+                        },
+                        _ => panic!()
+                    };
+                    is_valid(norm_binop, lit_val, min, max)
+                }
+                _ => true
+            }
+        }
+
+        fn is_comparison(binop: ast::BinOp) -> bool {
+            match binop.node {
+                ast::BiEq | ast::BiLt | ast::BiLe |
+                ast::BiNe | ast::BiGe | ast::BiGt => true,
+                _ => false
+            }
+        }
+    }
+}
+
+declare_lint! {
+    IMPROPER_CTYPES,
+    Warn,
+    "proper use of libc types in foreign modules"
+}
+
+struct ImproperCTypesVisitor<'a, 'tcx: 'a> {
+    cx: &'a Context<'a, 'tcx>
+}
+
+impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
+    fn check_def(&mut self, sp: Span, id: ast::NodeId) {
+        match self.cx.tcx.def_map.borrow().get(&id).unwrap().full_def() {
+            def::DefPrimTy(ast::TyInt(ast::TyIs)) => {
+                self.cx.span_lint(IMPROPER_CTYPES, sp,
+                                  "found rust type `isize` in foreign module, while \
+                                   libc::c_int or libc::c_long should be used");
+            }
+            def::DefPrimTy(ast::TyUint(ast::TyUs)) => {
+                self.cx.span_lint(IMPROPER_CTYPES, sp,
+                                  "found rust type `usize` in foreign module, while \
+                                   libc::c_uint or libc::c_ulong should be used");
+            }
+            def::DefTy(..) => {
+                let tty = match self.cx.tcx.ast_ty_to_ty_cache.borrow().get(&id) {
+                    Some(&t) => t,
+                    None => panic!("ast_ty_to_ty_cache was incomplete after typeck!")
+                };
+
+                if !ty::is_ffi_safe(self.cx.tcx, tty) {
+                    self.cx.span_lint(IMPROPER_CTYPES, sp,
+                                      "found type without foreign-function-safe \
+                                       representation annotation in foreign module, consider \
+                                       adding a #[repr(...)] attribute to the type");
+                }
+            }
+            _ => ()
+        }
+    }
+}
+
+impl<'a, 'tcx, 'v> Visitor<'v> for ImproperCTypesVisitor<'a, 'tcx> {
+    fn visit_ty(&mut self, ty: &ast::Ty) {
+        if let ast::TyPath(..) = ty.node {
+            self.check_def(ty.span, ty.id);
+        }
+        visit::walk_ty(self, ty);
+    }
+}
+
+#[derive(Copy, Clone)]
+pub struct ImproperCTypes;
+
+impl LintPass for ImproperCTypes {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(IMPROPER_CTYPES)
+    }
+
+    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
+        fn check_ty(cx: &Context, ty: &ast::Ty) {
+            let mut vis = ImproperCTypesVisitor { cx: cx };
+            vis.visit_ty(ty);
+        }
+
+        fn check_foreign_fn(cx: &Context, decl: &ast::FnDecl) {
+            for input in &decl.inputs {
+                check_ty(cx, &*input.ty);
+            }
+            if let ast::Return(ref ret_ty) = decl.output {
+                check_ty(cx, &**ret_ty);
+            }
+        }
+
+        match it.node {
+            ast::ItemForeignMod(ref nmod) if nmod.abi != abi::RustIntrinsic => {
+                for ni in &nmod.items {
+                    match ni.node {
+                        ast::ForeignItemFn(ref decl, _) => check_foreign_fn(cx, &**decl),
+                        ast::ForeignItemStatic(ref t, _) => check_ty(cx, &**t)
+                    }
+                }
+            }
+            _ => (),
+        }
+    }
+}
+
+declare_lint! {
+    BOX_POINTERS,
+    Allow,
+    "use of owned (Box type) heap memory"
+}
+
+#[derive(Copy, Clone)]
+pub struct BoxPointers;
+
+impl BoxPointers {
+    fn check_heap_type<'a, 'tcx>(&self, cx: &Context<'a, 'tcx>,
+                                 span: Span, ty: Ty<'tcx>) {
+        let mut n_uniq: usize = 0;
+        ty::fold_ty(cx.tcx, ty, |t| {
+            match t.sty {
+                ty::ty_uniq(_) => {
+                    n_uniq += 1;
+                }
+                _ => ()
+            };
+            t
+        });
+
+        if n_uniq > 0 {
+            let s = ty_to_string(cx.tcx, ty);
+            let m = format!("type uses owned (Box type) pointers: {}", s);
+            cx.span_lint(BOX_POINTERS, span, &m[..]);
+        }
+    }
+}
+
+impl LintPass for BoxPointers {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(BOX_POINTERS)
+    }
+
+    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
+        match it.node {
+            ast::ItemFn(..) |
+            ast::ItemTy(..) |
+            ast::ItemEnum(..) |
+            ast::ItemStruct(..) =>
+                self.check_heap_type(cx, it.span,
+                                     ty::node_id_to_type(cx.tcx, it.id)),
+            _ => ()
+        }
+
+        // If it's a struct, we also have to check the fields' types
+        match it.node {
+            ast::ItemStruct(ref struct_def, _) => {
+                for struct_field in &struct_def.fields {
+                    self.check_heap_type(cx, struct_field.span,
+                                         ty::node_id_to_type(cx.tcx, struct_field.node.id));
+                }
+            }
+            _ => ()
+        }
+    }
+
+    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
+        let ty = ty::expr_ty(cx.tcx, e);
+        self.check_heap_type(cx, e.span, ty);
+    }
+}
+
+declare_lint! {
+    RAW_POINTER_DERIVE,
+    Warn,
+    "uses of #[derive] with raw pointers are rarely correct"
+}
+
+struct RawPtrDeriveVisitor<'a, 'tcx: 'a> {
+    cx: &'a Context<'a, 'tcx>
+}
+
+impl<'a, 'tcx, 'v> Visitor<'v> for RawPtrDeriveVisitor<'a, 'tcx> {
+    fn visit_ty(&mut self, ty: &ast::Ty) {
+        const MSG: &'static str = "use of `#[derive]` with a raw pointer";
+        if let ast::TyPtr(..) = ty.node {
+            self.cx.span_lint(RAW_POINTER_DERIVE, ty.span, MSG);
+        }
+        visit::walk_ty(self, ty);
+    }
+    // explicit override to a no-op to reduce code bloat
+    fn visit_expr(&mut self, _: &ast::Expr) {}
+    fn visit_block(&mut self, _: &ast::Block) {}
+}
+
+pub struct RawPointerDerive {
+    checked_raw_pointers: NodeSet,
+}
+
+impl RawPointerDerive {
+    pub fn new() -> RawPointerDerive {
+        RawPointerDerive {
+            checked_raw_pointers: NodeSet(),
+        }
+    }
+}
+
+impl LintPass for RawPointerDerive {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(RAW_POINTER_DERIVE)
+    }
+
+    fn check_item(&mut self, cx: &Context, item: &ast::Item) {
+        if !attr::contains_name(&item.attrs, "automatically_derived") {
+            return;
+        }
+        let did = match item.node {
+            ast::ItemImpl(_, _, _, ref t_ref_opt, _, _) => {
+                // Deriving the Copy trait does not cause a warning
+                if let &Some(ref trait_ref) = t_ref_opt {
+                    let def_id = ty::trait_ref_to_def_id(cx.tcx, trait_ref);
+                    if Some(def_id) == cx.tcx.lang_items.copy_trait() {
+                        return;
+                    }
+                }
+
+                match ty::node_id_to_type(cx.tcx, item.id).sty {
+                    ty::ty_enum(did, _) => did,
+                    ty::ty_struct(did, _) => did,
+                    _ => return,
+                }
+            }
+            _ => return,
+        };
+        if !ast_util::is_local(did) {
+            return;
+        }
+        let item = match cx.tcx.map.find(did.node) {
+            Some(ast_map::NodeItem(item)) => item,
+            _ => return,
+        };
+        if !self.checked_raw_pointers.insert(item.id) {
+            return;
+        }
+        match item.node {
+            ast::ItemStruct(..) | ast::ItemEnum(..) => {
+                let mut visitor = RawPtrDeriveVisitor { cx: cx };
+                visit::walk_item(&mut visitor, &*item);
+            }
+            _ => {}
+        }
+    }
+}
+
+declare_lint! {
+    UNUSED_ATTRIBUTES,
+    Warn,
+    "detects attributes that were not used by the compiler"
+}
+
+#[derive(Copy, Clone)]
+pub struct UnusedAttributes;
+
+impl LintPass for UnusedAttributes {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(UNUSED_ATTRIBUTES)
+    }
+
+    fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
+        // Note that check_name() marks the attribute as used if it matches.
+        for &(ref name, ty) in KNOWN_ATTRIBUTES {
+            match ty {
+                AttributeType::Whitelisted
+                | AttributeType::Gated(_, _) if attr.check_name(name) => {
+                    break;
+                },
+                _ => ()
+            }
+        }
+
+        if !attr::is_used(attr) {
+            cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
+            if KNOWN_ATTRIBUTES.contains(&(&attr.name(), AttributeType::CrateLevel)) {
+                let msg = match attr.node.style {
+                    ast::AttrOuter => "crate-level attribute should be an inner \
+                                       attribute: add an exclamation mark: #![foo]",
+                    ast::AttrInner => "crate-level attribute should be in the \
+                                       root module",
+                };
+                cx.span_lint(UNUSED_ATTRIBUTES, attr.span, msg);
+            }
+        }
+    }
+}
+
+declare_lint! {
+    pub PATH_STATEMENTS,
+    Warn,
+    "path statements with no effect"
+}
+
+#[derive(Copy, Clone)]
+pub struct PathStatements;
+
+impl LintPass for PathStatements {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(PATH_STATEMENTS)
+    }
+
+    fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
+        match s.node {
+            ast::StmtSemi(ref expr, _) => {
+                match expr.node {
+                    ast::ExprPath(..) => cx.span_lint(PATH_STATEMENTS, s.span,
+                                                      "path statement with no effect"),
+                    _ => ()
+                }
+            }
+            _ => ()
+        }
+    }
+}
+
+declare_lint! {
+    pub UNUSED_MUST_USE,
+    Warn,
+    "unused result of a type flagged as #[must_use]"
+}
+
+declare_lint! {
+    pub UNUSED_RESULTS,
+    Allow,
+    "unused result of an expression in a statement"
+}
+
+#[derive(Copy, Clone)]
+pub struct UnusedResults;
+
+impl LintPass for UnusedResults {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(UNUSED_MUST_USE, UNUSED_RESULTS)
+    }
+
+    fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
+        let expr = match s.node {
+            ast::StmtSemi(ref expr, _) => &**expr,
+            _ => return
+        };
+
+        if let ast::ExprRet(..) = expr.node {
+            return;
+        }
+
+        let t = ty::expr_ty(cx.tcx, expr);
+        let warned = match t.sty {
+            ty::ty_tup(ref tys) if tys.is_empty() => return,
+            ty::ty_bool => return,
+            ty::ty_struct(did, _) |
+            ty::ty_enum(did, _) => {
+                if ast_util::is_local(did) {
+                    if let ast_map::NodeItem(it) = cx.tcx.map.get(did.node) {
+                        check_must_use(cx, &it.attrs, s.span)
+                    } else {
+                        false
+                    }
+                } else {
+                    let attrs = csearch::get_item_attrs(&cx.sess().cstore, did);
+                    check_must_use(cx, &attrs[..], s.span)
+                }
+            }
+            _ => false,
+        };
+        if !warned {
+            cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
+        }
+
+        fn check_must_use(cx: &Context, attrs: &[ast::Attribute], sp: Span) -> bool {
+            for attr in attrs {
+                if attr.check_name("must_use") {
+                    let mut msg = "unused result which must be used".to_string();
+                    // check for #[must_use="..."]
+                    match attr.value_str() {
+                        None => {}
+                        Some(s) => {
+                            msg.push_str(": ");
+                            msg.push_str(&s);
+                        }
+                    }
+                    cx.span_lint(UNUSED_MUST_USE, sp, &msg);
+                    return true;
+                }
+            }
+            false
+        }
+    }
+}
+
+declare_lint! {
+    pub NON_CAMEL_CASE_TYPES,
+    Warn,
+    "types, variants, traits and type parameters should have camel case names"
+}
+
+#[derive(Copy, Clone)]
+pub struct NonCamelCaseTypes;
+
+impl NonCamelCaseTypes {
+    fn check_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
+        fn is_camel_case(ident: ast::Ident) -> bool {
+            let ident = token::get_ident(ident);
+            if ident.is_empty() {
+                return true;
+            }
+            let ident = ident.trim_matches('_');
+
+            // start with a non-lowercase letter rather than non-uppercase
+            // ones (some scripts don't have a concept of upper/lowercase)
+            ident.len() > 0 && !ident.char_at(0).is_lowercase() && !ident.contains('_')
+        }
+
+        fn to_camel_case(s: &str) -> String {
+            s.split('_').flat_map(|word| word.chars().enumerate().map(|(i, c)|
+                if i == 0 {
+                    c.to_uppercase().collect::<String>()
+                } else {
+                    c.to_lowercase().collect()
+                }
+            )).collect::<Vec<_>>().concat()
+        }
+
+        let s = token::get_ident(ident);
+
+        if !is_camel_case(ident) {
+            let c = to_camel_case(&s);
+            let m = if c.is_empty() {
+                format!("{} `{}` should have a camel case name such as `CamelCase`", sort, s)
+            } else {
+                format!("{} `{}` should have a camel case name such as `{}`", sort, s, c)
+            };
+            cx.span_lint(NON_CAMEL_CASE_TYPES, span, &m[..]);
+        }
+    }
+}
+
+impl LintPass for NonCamelCaseTypes {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(NON_CAMEL_CASE_TYPES)
+    }
+
+    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
+        let has_extern_repr = it.attrs.iter().any(|attr| {
+            attr::find_repr_attrs(cx.tcx.sess.diagnostic(), attr).iter()
+                .any(|r| r == &attr::ReprExtern)
+        });
+        if has_extern_repr {
+            return;
+        }
+
+        match it.node {
+            ast::ItemTy(..) | ast::ItemStruct(..) => {
+                self.check_case(cx, "type", it.ident, it.span)
+            }
+            ast::ItemTrait(..) => {
+                self.check_case(cx, "trait", it.ident, it.span)
+            }
+            ast::ItemEnum(ref enum_definition, _) => {
+                if has_extern_repr {
+                    return;
+                }
+                self.check_case(cx, "type", it.ident, it.span);
+                for variant in &enum_definition.variants {
+                    self.check_case(cx, "variant", variant.node.name, variant.span);
+                }
+            }
+            _ => ()
+        }
+    }
+
+    fn check_generics(&mut self, cx: &Context, it: &ast::Generics) {
+        for gen in &*it.ty_params {
+            self.check_case(cx, "type parameter", gen.ident, gen.span);
+        }
+    }
+}
+
+#[derive(PartialEq)]
+enum MethodContext {
+    TraitDefaultImpl,
+    TraitImpl,
+    PlainImpl
+}
+
+fn method_context(cx: &Context, id: ast::NodeId, span: Span) -> MethodContext {
+    match cx.tcx.impl_or_trait_items.borrow().get(&local_def(id)) {
+        None => cx.sess().span_bug(span, "missing method descriptor?!"),
+        Some(item) => match item.container() {
+            ty::TraitContainer(..) => MethodContext::TraitDefaultImpl,
+            ty::ImplContainer(cid) => {
+                match ty::impl_trait_ref(cx.tcx, cid) {
+                    Some(_) => MethodContext::TraitImpl,
+                    None => MethodContext::PlainImpl
+                }
+            }
+        }
+    }
+}
+
+declare_lint! {
+    pub NON_SNAKE_CASE,
+    Warn,
+    "methods, functions, lifetime parameters and modules should have snake case names"
+}
+
+#[derive(Copy, Clone)]
+pub struct NonSnakeCase;
+
+impl NonSnakeCase {
+    fn to_snake_case(mut str: &str) -> String {
+        let mut words = vec![];
+        // Preserve leading underscores
+        str = str.trim_left_matches(|c: char| {
+            if c == '_' {
+                words.push(String::new());
+                true
+            } else {
+                false
+            }
+        });
+        for s in str.split('_') {
+            let mut last_upper = false;
+            let mut buf = String::new();
+            if s.is_empty() {
+                continue;
+            }
+            for ch in s.chars() {
+                if !buf.is_empty() && buf != "'"
+                                   && ch.is_uppercase()
+                                   && !last_upper {
+                    words.push(buf);
+                    buf = String::new();
+                }
+                last_upper = ch.is_uppercase();
+                buf.extend(ch.to_lowercase());
+            }
+            words.push(buf);
+        }
+        words.connect("_")
+    }
+
+    fn check_snake_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
+        fn is_snake_case(ident: ast::Ident) -> bool {
+            let ident = token::get_ident(ident);
+            if ident.is_empty() {
+                return true;
+            }
+            let ident = ident.trim_left_matches('\'');
+            let ident = ident.trim_matches('_');
+
+            let mut allow_underscore = true;
+            ident.chars().all(|c| {
+                allow_underscore = match c {
+                    '_' if !allow_underscore => return false,
+                    '_' => false,
+                    c if !c.is_uppercase() => true,
+                    _ => return false,
+                };
+                true
+            })
+        }
+
+        let s = token::get_ident(ident);
+
+        if !is_snake_case(ident) {
+            let sc = NonSnakeCase::to_snake_case(&s);
+            if sc != &s[..] {
+                cx.span_lint(NON_SNAKE_CASE, span,
+                    &*format!("{} `{}` should have a snake case name such as `{}`",
+                            sort, s, sc));
+            } else {
+                cx.span_lint(NON_SNAKE_CASE, span,
+                    &*format!("{} `{}` should have a snake case name",
+                            sort, s));
+            }
+        }
+    }
+}
+
+impl LintPass for NonSnakeCase {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(NON_SNAKE_CASE)
+    }
+
+    fn check_fn(&mut self, cx: &Context,
+                fk: visit::FnKind, _: &ast::FnDecl,
+                _: &ast::Block, span: Span, id: ast::NodeId) {
+        match fk {
+            visit::FkMethod(ident, _) => match method_context(cx, id, span) {
+                MethodContext::PlainImpl => {
+                    self.check_snake_case(cx, "method", ident, span)
+                },
+                MethodContext::TraitDefaultImpl => {
+                    self.check_snake_case(cx, "trait method", ident, span)
+                },
+                _ => (),
+            },
+            visit::FkItemFn(ident, _, _, _) => {
+                self.check_snake_case(cx, "function", ident, span)
+            },
+            _ => (),
+        }
+    }
+
+    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
+        if let ast::ItemMod(_) = it.node {
+            self.check_snake_case(cx, "module", it.ident, it.span);
+        }
+    }
+
+    fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
+        if let ast::MethodTraitItem(_, None) = trait_item.node {
+            self.check_snake_case(cx, "trait method", trait_item.ident, trait_item.span);
+        }
+    }
+
+    fn check_lifetime_def(&mut self, cx: &Context, t: &ast::LifetimeDef) {
+        self.check_snake_case(cx, "lifetime", t.lifetime.name.ident(), t.lifetime.span);
+    }
+
+    fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
+        if let &ast::PatIdent(_, ref path1, _) = &p.node {
+            let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
+            if let Some(def::DefLocal(_)) = def {
+                self.check_snake_case(cx, "variable", path1.node, p.span);
+            }
+        }
+    }
+
+    fn check_struct_def(&mut self, cx: &Context, s: &ast::StructDef,
+                        _: ast::Ident, _: &ast::Generics, _: ast::NodeId) {
+        for sf in &s.fields {
+            if let ast::StructField_ { kind: ast::NamedField(ident, _), .. } = sf.node {
+                self.check_snake_case(cx, "structure field", ident, sf.span);
+            }
+        }
+    }
+}
+
+declare_lint! {
+    pub NON_UPPER_CASE_GLOBALS,
+    Warn,
+    "static constants should have uppercase identifiers"
+}
+
+#[derive(Copy, Clone)]
+pub struct NonUpperCaseGlobals;
+
+impl NonUpperCaseGlobals {
+    fn check_upper_case(cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
+        let s = token::get_ident(ident);
+
+        if s.chars().any(|c| c.is_lowercase()) {
+            let uc = NonSnakeCase::to_snake_case(&s).to_uppercase();
+            if uc != &s[..] {
+                cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
+                    &format!("{} `{}` should have an upper case name such as `{}`",
+                             sort, s, uc));
+            } else {
+                cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
+                    &format!("{} `{}` should have an upper case name",
+                             sort, s));
+            }
+        }
+    }
+}
+
+impl LintPass for NonUpperCaseGlobals {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(NON_UPPER_CASE_GLOBALS)
+    }
+
+    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
+        match it.node {
+            // only check static constants
+            ast::ItemStatic(_, ast::MutImmutable, _) => {
+                NonUpperCaseGlobals::check_upper_case(cx, "static constant", it.ident, it.span);
+            }
+            ast::ItemConst(..) => {
+                NonUpperCaseGlobals::check_upper_case(cx, "constant", it.ident, it.span);
+            }
+            _ => {}
+        }
+    }
+
+    fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
+        // Lint for constants that look like binding identifiers (#7526)
+        match (&p.node, cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def())) {
+            (&ast::PatIdent(_, ref path1, _), Some(def::DefConst(..))) => {
+                NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
+                                                      path1.node, p.span);
+            }
+            _ => {}
+        }
+    }
+}
+
+declare_lint! {
+    UNUSED_PARENS,
+    Warn,
+    "`if`, `match`, `while` and `return` do not need parentheses"
+}
+
+#[derive(Copy, Clone)]
+pub struct UnusedParens;
+
+impl UnusedParens {
+    fn check_unused_parens_core(&self, cx: &Context, value: &ast::Expr, msg: &str,
+                                struct_lit_needs_parens: bool) {
+        if let ast::ExprParen(ref inner) = value.node {
+            let necessary = struct_lit_needs_parens && contains_exterior_struct_lit(&**inner);
+            if !necessary {
+                cx.span_lint(UNUSED_PARENS, value.span,
+                             &format!("unnecessary parentheses around {}", msg))
+            }
+        }
+
+        /// Expressions that syntactically contain an "exterior" struct
+        /// literal i.e. not surrounded by any parens or other
+        /// delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo
+        /// == X { y: 1 }` and `X { y: 1 } == foo` all do, but `(X {
+        /// y: 1 }) == foo` does not.
+        fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
+            match value.node {
+                ast::ExprStruct(..) => true,
+
+                ast::ExprAssign(ref lhs, ref rhs) |
+                ast::ExprAssignOp(_, ref lhs, ref rhs) |
+                ast::ExprBinary(_, ref lhs, ref rhs) => {
+                    // X { y: 1 } + X { y: 2 }
+                    contains_exterior_struct_lit(&**lhs) ||
+                        contains_exterior_struct_lit(&**rhs)
+                }
+                ast::ExprUnary(_, ref x) |
+                ast::ExprCast(ref x, _) |
+                ast::ExprField(ref x, _) |
+                ast::ExprTupField(ref x, _) |
+                ast::ExprIndex(ref x, _) => {
+                    // &X { y: 1 }, X { y: 1 }.y
+                    contains_exterior_struct_lit(&**x)
+                }
+
+                ast::ExprMethodCall(_, _, ref exprs) => {
+                    // X { y: 1 }.bar(...)
+                    contains_exterior_struct_lit(&*exprs[0])
+                }
+
+                _ => false
+            }
+        }
+    }
+}
+
+impl LintPass for UnusedParens {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(UNUSED_PARENS)
+    }
+
+    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
+        let (value, msg, struct_lit_needs_parens) = match e.node {
+            ast::ExprIf(ref cond, _, _) => (cond, "`if` condition", true),
+            ast::ExprWhile(ref cond, _, _) => (cond, "`while` condition", true),
+            ast::ExprMatch(ref head, _, source) => match source {
+                ast::MatchSource::Normal => (head, "`match` head expression", true),
+                ast::MatchSource::IfLetDesugar { .. } => (head, "`if let` head expression", true),
+                ast::MatchSource::WhileLetDesugar => (head, "`while let` head expression", true),
+                ast::MatchSource::ForLoopDesugar => (head, "`for` head expression", true),
+            },
+            ast::ExprRet(Some(ref value)) => (value, "`return` value", false),
+            ast::ExprAssign(_, ref value) => (value, "assigned value", false),
+            ast::ExprAssignOp(_, _, ref value) => (value, "assigned value", false),
+            _ => return
+        };
+        self.check_unused_parens_core(cx, &**value, msg, struct_lit_needs_parens);
+    }
+
+    fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
+        let (value, msg) = match s.node {
+            ast::StmtDecl(ref decl, _) => match decl.node {
+                ast::DeclLocal(ref local) => match local.init {
+                    Some(ref value) => (value, "assigned value"),
+                    None => return
+                },
+                _ => return
+            },
+            _ => return
+        };
+        self.check_unused_parens_core(cx, &**value, msg, false);
+    }
+}
+
+declare_lint! {
+    UNUSED_IMPORT_BRACES,
+    Allow,
+    "unnecessary braces around an imported item"
+}
+
+#[derive(Copy, Clone)]
+pub struct UnusedImportBraces;
+
+impl LintPass for UnusedImportBraces {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(UNUSED_IMPORT_BRACES)
+    }
+
+    fn check_item(&mut self, cx: &Context, item: &ast::Item) {
+        if let ast::ItemUse(ref view_path) = item.node {
+            if let ast::ViewPathList(_, ref items) = view_path.node {
+                if items.len() == 1 {
+                    if let ast::PathListIdent {ref name, ..} = items[0].node {
+                        let m = format!("braces around {} is unnecessary",
+                                        &token::get_ident(*name));
+                        cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
+                                     &m[..]);
+                    }
+                }
+            }
+        }
+    }
+}
+
+declare_lint! {
+    NON_SHORTHAND_FIELD_PATTERNS,
+    Warn,
+    "using `Struct { x: x }` instead of `Struct { x }`"
+}
+
+#[derive(Copy, Clone)]
+pub struct NonShorthandFieldPatterns;
+
+impl LintPass for NonShorthandFieldPatterns {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(NON_SHORTHAND_FIELD_PATTERNS)
+    }
+
+    fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
+        let def_map = cx.tcx.def_map.borrow();
+        if let ast::PatStruct(_, ref v, _) = pat.node {
+            let field_pats = v.iter().filter(|fieldpat| {
+                if fieldpat.node.is_shorthand {
+                    return false;
+                }
+                let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def());
+                def == Some(def::DefLocal(fieldpat.node.pat.id))
+            });
+            for fieldpat in field_pats {
+                if let ast::PatIdent(_, ident, None) = fieldpat.node.pat.node {
+                    if ident.node.as_str() == fieldpat.node.ident.as_str() {
+                        cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
+                                     &format!("the `{}:` in this pattern is redundant and can \
+                                              be removed", ident.node.as_str()))
+                    }
+                }
+            }
+        }
+    }
+}
+
+declare_lint! {
+    pub UNUSED_UNSAFE,
+    Warn,
+    "unnecessary use of an `unsafe` block"
+}
+
+#[derive(Copy, Clone)]
+pub struct UnusedUnsafe;
+
+impl LintPass for UnusedUnsafe {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(UNUSED_UNSAFE)
+    }
+
+    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
+        if let ast::ExprBlock(ref blk) = e.node {
+            // Don't warn about generated blocks, that'll just pollute the output.
+            if blk.rules == ast::UnsafeBlock(ast::UserProvided) &&
+                !cx.tcx.used_unsafe.borrow().contains(&blk.id) {
+                    cx.span_lint(UNUSED_UNSAFE, blk.span, "unnecessary `unsafe` block");
+            }
+        }
+    }
+}
+
+declare_lint! {
+    UNSAFE_CODE,
+    Allow,
+    "usage of `unsafe` code"
+}
+
+#[derive(Copy, Clone)]
+pub struct UnsafeCode;
+
+impl LintPass for UnsafeCode {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(UNSAFE_CODE)
+    }
+
+    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
+        if let ast::ExprBlock(ref blk) = e.node {
+            // Don't warn about generated blocks, that'll just pollute the output.
+            if blk.rules == ast::UnsafeBlock(ast::UserProvided) {
+                cx.span_lint(UNSAFE_CODE, blk.span, "usage of an `unsafe` block");
+            }
+        }
+    }
+
+    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
+        match it.node {
+            ast::ItemTrait(ast::Unsafety::Unsafe, _, _, _) =>
+                cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` trait"),
+
+            ast::ItemImpl(ast::Unsafety::Unsafe, _, _, _, _, _) =>
+                cx.span_lint(UNSAFE_CODE, it.span, "implementation of an `unsafe` trait"),
+
+            _ => return,
+        }
+    }
+
+    fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl,
+                _: &ast::Block, span: Span, _: ast::NodeId) {
+        match fk {
+            visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _) =>
+                cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"),
+
+            visit::FkMethod(_, sig) => {
+                if sig.unsafety == ast::Unsafety::Unsafe {
+                    cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method")
+                }
+            },
+
+            _ => (),
+        }
+    }
+
+    fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
+        if let ast::MethodTraitItem(ref sig, None) = trait_item.node {
+            if sig.unsafety == ast::Unsafety::Unsafe {
+                cx.span_lint(UNSAFE_CODE, trait_item.span,
+                             "declaration of an `unsafe` method")
+            }
+        }
+    }
+}
+
+declare_lint! {
+    pub UNUSED_MUT,
+    Warn,
+    "detect mut variables which don't need to be mutable"
+}
+
+#[derive(Copy, Clone)]
+pub struct 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
+        // avoid false warnings in match arms with multiple patterns
+
+        let mut mutables = FnvHashMap();
+        for p in pats {
+            pat_util::pat_bindings(&cx.tcx.def_map, &**p, |mode, id, _, path1| {
+                let ident = path1.node;
+                if let ast::BindByValue(ast::MutMutable) = mode {
+                    if !token::get_ident(ident).starts_with("_") {
+                        match mutables.entry(ident.name.usize()) {
+                            Vacant(entry) => { entry.insert(vec![id]); },
+                            Occupied(mut entry) => { entry.get_mut().push(id); },
+                        }
+                    }
+                }
+            });
+        }
+
+        let used_mutables = cx.tcx.used_mut_nodes.borrow();
+        for (_, v) in &mutables {
+            if !v.iter().any(|e| used_mutables.contains(e)) {
+                cx.span_lint(UNUSED_MUT, cx.tcx.map.span(v[0]),
+                             "variable does not need to be mutable");
+            }
+        }
+    }
+}
+
+impl LintPass for UnusedMut {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(UNUSED_MUT)
+    }
+
+    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
+        if let ast::ExprMatch(_, ref arms, _) = e.node {
+            for a in arms {
+                self.check_unused_mut_pat(cx, &a.pats)
+            }
+        }
+    }
+
+    fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
+        if let ast::StmtDecl(ref d, _) = s.node {
+            if let ast::DeclLocal(ref l) = d.node {
+                self.check_unused_mut_pat(cx, slice::ref_slice(&l.pat));
+            }
+        }
+    }
+
+    fn check_fn(&mut self, cx: &Context,
+                _: visit::FnKind, decl: &ast::FnDecl,
+                _: &ast::Block, _: Span, _: ast::NodeId) {
+        for a in &decl.inputs {
+            self.check_unused_mut_pat(cx, slice::ref_slice(&a.pat));
+        }
+    }
+}
+
+declare_lint! {
+    UNUSED_ALLOCATION,
+    Warn,
+    "detects unnecessary allocations that can be eliminated"
+}
+
+#[derive(Copy, Clone)]
+pub struct UnusedAllocation;
+
+impl LintPass for UnusedAllocation {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(UNUSED_ALLOCATION)
+    }
+
+    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
+        match e.node {
+            ast::ExprUnary(ast::UnUniq, _) => (),
+            _ => return
+        }
+
+        if let Some(adjustment) = cx.tcx.adjustments.borrow().get(&e.id) {
+            if let ty::AdjustDerefRef(ty::AutoDerefRef { ref autoref, .. }) = *adjustment {
+                match autoref {
+                    &Some(ty::AutoPtr(_, ast::MutImmutable, None)) => {
+                        cx.span_lint(UNUSED_ALLOCATION, e.span,
+                                     "unnecessary allocation, use & instead");
+                    }
+                    &Some(ty::AutoPtr(_, ast::MutMutable, None)) => {
+                        cx.span_lint(UNUSED_ALLOCATION, e.span,
+                                     "unnecessary allocation, use &mut instead");
+                    }
+                    _ => ()
+                }
+            }
+        }
+    }
+}
+
+declare_lint! {
+    MISSING_DOCS,
+    Allow,
+    "detects missing documentation for public members"
+}
+
+pub struct MissingDoc {
+    /// Stack of IDs of struct definitions.
+    struct_def_stack: Vec<ast::NodeId>,
+
+    /// True if inside variant definition
+    in_variant: bool,
+
+    /// Stack of whether #[doc(hidden)] is set
+    /// at each level which has lint attributes.
+    doc_hidden_stack: Vec<bool>,
+
+    /// Private traits or trait items that leaked through. Don't check their methods.
+    private_traits: HashSet<ast::NodeId>,
+}
+
+impl MissingDoc {
+    pub fn new() -> MissingDoc {
+        MissingDoc {
+            struct_def_stack: vec!(),
+            in_variant: false,
+            doc_hidden_stack: vec!(false),
+            private_traits: HashSet::new(),
+        }
+    }
+
+    fn doc_hidden(&self) -> bool {
+        *self.doc_hidden_stack.last().expect("empty doc_hidden_stack")
+    }
+
+    fn check_missing_docs_attrs(&self,
+                               cx: &Context,
+                               id: Option<ast::NodeId>,
+                               attrs: &[ast::Attribute],
+                               sp: Span,
+                               desc: &'static str) {
+        // If we're building a test harness, then warning about
+        // documentation is probably not really relevant right now.
+        if cx.sess().opts.test {
+            return;
+        }
+
+        // `#[doc(hidden)]` disables missing_docs check.
+        if self.doc_hidden() {
+            return;
+        }
+
+        // Only check publicly-visible items, using the result from the privacy pass.
+        // It's an option so the crate root can also use this function (it doesn't
+        // have a NodeId).
+        if let Some(ref id) = id {
+            if !cx.exported_items.contains(id) {
+                return;
+            }
+        }
+
+        let has_doc = attrs.iter().any(|a| {
+            match a.node.value.node {
+                ast::MetaNameValue(ref name, _) if *name == "doc" => true,
+                _ => false
+            }
+        });
+        if !has_doc {
+            cx.span_lint(MISSING_DOCS, sp,
+                         &format!("missing documentation for {}", desc));
+        }
+    }
+}
+
+impl LintPass for MissingDoc {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(MISSING_DOCS)
+    }
+
+    fn enter_lint_attrs(&mut self, _: &Context, attrs: &[ast::Attribute]) {
+        let doc_hidden = self.doc_hidden() || attrs.iter().any(|attr| {
+            attr.check_name("doc") && match attr.meta_item_list() {
+                None => false,
+                Some(l) => attr::contains_name(&l[..], "hidden"),
+            }
+        });
+        self.doc_hidden_stack.push(doc_hidden);
+    }
+
+    fn exit_lint_attrs(&mut self, _: &Context, _: &[ast::Attribute]) {
+        self.doc_hidden_stack.pop().expect("empty doc_hidden_stack");
+    }
+
+    fn check_struct_def(&mut self, _: &Context, _: &ast::StructDef,
+                        _: ast::Ident, _: &ast::Generics, id: ast::NodeId) {
+        self.struct_def_stack.push(id);
+    }
+
+    fn check_struct_def_post(&mut self, _: &Context, _: &ast::StructDef,
+                             _: ast::Ident, _: &ast::Generics, id: ast::NodeId) {
+        let popped = self.struct_def_stack.pop().expect("empty struct_def_stack");
+        assert!(popped == id);
+    }
+
+    fn check_crate(&mut self, cx: &Context, krate: &ast::Crate) {
+        self.check_missing_docs_attrs(cx, None, &krate.attrs, krate.span, "crate");
+    }
+
+    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
+        let desc = match it.node {
+            ast::ItemFn(..) => "a function",
+            ast::ItemMod(..) => "a module",
+            ast::ItemEnum(..) => "an enum",
+            ast::ItemStruct(..) => "a struct",
+            ast::ItemTrait(_, _, _, ref items) => {
+                // Issue #11592, traits are always considered exported, even when private.
+                if it.vis == ast::Visibility::Inherited {
+                    self.private_traits.insert(it.id);
+                    for itm in items {
+                        self.private_traits.insert(itm.id);
+                    }
+                    return
+                }
+                "a trait"
+            },
+            ast::ItemTy(..) => "a type alias",
+            ast::ItemImpl(_, _, _, Some(ref trait_ref), _, ref impl_items) => {
+                // If the trait is private, add the impl items to private_traits so they don't get
+                // reported for missing docs.
+                let real_trait = ty::trait_ref_to_def_id(cx.tcx, trait_ref);
+                match cx.tcx.map.find(real_trait.node) {
+                    Some(ast_map::NodeItem(item)) => if item.vis == ast::Visibility::Inherited {
+                        for itm in impl_items {
+                            self.private_traits.insert(itm.id);
+                        }
+                    },
+                    _ => { }
+                }
+                return
+            },
+            _ => return
+        };
+
+        self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc);
+    }
+
+    fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
+        if self.private_traits.contains(&trait_item.id) { return }
+
+        let desc = match trait_item.node {
+            ast::MethodTraitItem(..) => "a trait method",
+            ast::TypeTraitItem(..) => "an associated type"
+        };
+
+        self.check_missing_docs_attrs(cx, Some(trait_item.id),
+                                      &trait_item.attrs,
+                                      trait_item.span, desc);
+    }
+
+    fn check_impl_item(&mut self, cx: &Context, impl_item: &ast::ImplItem) {
+        // If the method is an impl for a trait, don't doc.
+        if method_context(cx, impl_item.id, impl_item.span) == MethodContext::TraitImpl {
+            return;
+        }
+
+        let desc = match impl_item.node {
+            ast::MethodImplItem(..) => "a method",
+            ast::TypeImplItem(_) => "an associated type",
+            ast::MacImplItem(_) => "an impl item macro"
+        };
+        self.check_missing_docs_attrs(cx, Some(impl_item.id),
+                                      &impl_item.attrs,
+                                      impl_item.span, desc);
+    }
+
+    fn check_struct_field(&mut self, cx: &Context, sf: &ast::StructField) {
+        if let ast::NamedField(_, vis) = sf.node.kind {
+            if vis == ast::Public || self.in_variant {
+                let cur_struct_def = *self.struct_def_stack.last()
+                    .expect("empty struct_def_stack");
+                self.check_missing_docs_attrs(cx, Some(cur_struct_def),
+                                              &sf.node.attrs, sf.span,
+                                              "a struct field")
+            }
+        }
+    }
+
+    fn check_variant(&mut self, cx: &Context, v: &ast::Variant, _: &ast::Generics) {
+        self.check_missing_docs_attrs(cx, Some(v.node.id), &v.node.attrs, v.span, "a variant");
+        assert!(!self.in_variant);
+        self.in_variant = true;
+    }
+
+    fn check_variant_post(&mut self, _: &Context, _: &ast::Variant, _: &ast::Generics) {
+        assert!(self.in_variant);
+        self.in_variant = false;
+    }
+}
+
+declare_lint! {
+    pub MISSING_COPY_IMPLEMENTATIONS,
+    Allow,
+    "detects potentially-forgotten implementations of `Copy`"
+}
+
+#[derive(Copy, Clone)]
+pub struct 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(&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, local_def(item.id),
+                              cx.tcx.mk_substs(Substs::empty()))
+            }
+            ast::ItemEnum(_, ref ast_generics) => {
+                if ast_generics.is_parameterized() {
+                    return;
+                }
+                ty::mk_enum(cx.tcx, local_def(item.id),
+                            cx.tcx.mk_substs(Substs::empty()))
+            }
+            _ => return,
+        };
+        let parameter_environment = ty::empty_parameter_environment(cx.tcx);
+        if !ty::type_moves_by_default(&parameter_environment, item.span, ty) {
+            return;
+        }
+        if ty::can_type_implement_copy(&parameter_environment, item.span, ty).is_ok() {
+            cx.span_lint(MISSING_COPY_IMPLEMENTATIONS,
+                         item.span,
+                         "type could implement `Copy`; consider adding `impl \
+                          Copy`")
+        }
+    }
+}
+
+declare_lint! {
+    MISSING_DEBUG_IMPLEMENTATIONS,
+    Allow,
+    "detects missing implementations of fmt::Debug"
+}
+
+pub struct MissingDebugImplementations {
+    impling_types: Option<NodeSet>,
+}
+
+impl MissingDebugImplementations {
+    pub fn new() -> MissingDebugImplementations {
+        MissingDebugImplementations {
+            impling_types: None,
+        }
+    }
+}
+
+impl LintPass for MissingDebugImplementations {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(MISSING_DEBUG_IMPLEMENTATIONS)
+    }
+
+    fn check_item(&mut self, cx: &Context, item: &ast::Item) {
+        if !cx.exported_items.contains(&item.id) {
+            return;
+        }
+
+        match item.node {
+            ast::ItemStruct(..) | ast::ItemEnum(..) => {},
+            _ => return,
+        }
+
+        let debug = match cx.tcx.lang_items.debug_trait() {
+            Some(debug) => debug,
+            None => return,
+        };
+
+        if self.impling_types.is_none() {
+            let impls = cx.tcx.trait_impls.borrow();
+            let impls = match impls.get(&debug) {
+                Some(impls) => {
+                    impls.borrow().iter()
+                         .filter(|d| d.krate == ast::LOCAL_CRATE)
+                         .filter_map(|d| ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)))
+                         .map(|d| d.node)
+                         .collect()
+                }
+                None => NodeSet(),
+            };
+            self.impling_types = Some(impls);
+            debug!("{:?}", self.impling_types);
+        }
+
+        if !self.impling_types.as_ref().unwrap().contains(&item.id) {
+            cx.span_lint(MISSING_DEBUG_IMPLEMENTATIONS,
+                         item.span,
+                         "type does not implement `fmt::Debug`; consider adding #[derive(Debug)] \
+                          or a manual implementation")
+        }
+    }
+}
+
+declare_lint! {
+    DEPRECATED,
+    Warn,
+    "detects use of #[deprecated] items"
+}
+
+/// Checks for use of items with `#[deprecated]` attributes
+#[derive(Copy, Clone)]
+pub struct Stability;
+
+impl Stability {
+    fn lint(&self, cx: &Context, _id: ast::DefId, span: Span, stability: &Option<attr::Stability>) {
+        // Deprecated attributes apply in-crate and cross-crate.
+        let (lint, label) = match *stability {
+            Some(attr::Stability { deprecated_since: Some(_), .. }) =>
+                (DEPRECATED, "deprecated"),
+            _ => return
+        };
+
+        output(cx, span, stability, lint, label);
+
+        fn output(cx: &Context, span: Span, stability: &Option<attr::Stability>,
+                  lint: &'static Lint, label: &'static str) {
+            let msg = match *stability {
+                Some(attr::Stability { reason: Some(ref s), .. }) => {
+                    format!("use of {} item: {}", label, *s)
+                }
+                _ => format!("use of {} item", label)
+            };
+
+            cx.span_lint(lint, span, &msg[..]);
+        }
+    }
+}
+
+impl LintPass for Stability {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(DEPRECATED)
+    }
+
+    fn check_item(&mut self, cx: &Context, item: &ast::Item) {
+        stability::check_item(cx.tcx, item, false,
+                              &mut |id, sp, stab| self.lint(cx, id, sp, stab));
+    }
+
+    fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
+        stability::check_expr(cx.tcx, e,
+                              &mut |id, sp, stab| self.lint(cx, id, sp, stab));
+    }
+
+    fn check_path(&mut self, cx: &Context, path: &ast::Path, id: ast::NodeId) {
+        stability::check_path(cx.tcx, path, id,
+                              &mut |id, sp, stab| self.lint(cx, id, sp, stab));
+    }
+
+    fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
+        stability::check_pat(cx.tcx, pat,
+                             &mut |id, sp, stab| self.lint(cx, id, sp, stab))
+    }
+}
+
+declare_lint! {
+    pub UNCONDITIONAL_RECURSION,
+    Warn,
+    "functions that cannot return without calling themselves"
+}
+
+#[derive(Copy, Clone)]
+pub struct UnconditionalRecursion;
+
+
+impl LintPass for UnconditionalRecursion {
+    fn get_lints(&self) -> LintArray {
+        lint_array![UNCONDITIONAL_RECURSION]
+    }
+
+    fn check_fn(&mut self, cx: &Context, fn_kind: visit::FnKind, _: &ast::FnDecl,
+                blk: &ast::Block, sp: Span, id: ast::NodeId) {
+        // FIXME(#23542) Replace with type ascription.
+        #![allow(trivial_casts)]
+
+        type F = for<'tcx> fn(&ty::ctxt<'tcx>,
+                              ast::NodeId, ast::NodeId, ast::Ident, ast::NodeId) -> bool;
+
+        let (name, checker) = match fn_kind {
+            visit::FkItemFn(name, _, _, _) => (name, id_refers_to_this_fn as F),
+            visit::FkMethod(name, _) => (name, id_refers_to_this_method as F),
+            // closures can't recur, so they don't matter.
+            visit::FkFnBlock => return
+        };
+
+        let impl_def_id = ty::impl_of_method(cx.tcx, local_def(id))
+            .unwrap_or(local_def(ast::DUMMY_NODE_ID));
+        assert!(ast_util::is_local(impl_def_id));
+        let impl_node_id = impl_def_id.node;
+
+        // Walk through this function (say `f`) looking to see if
+        // every possible path references itself, i.e. the function is
+        // called recursively unconditionally. This is done by trying
+        // to find a path from the entry node to the exit node that
+        // *doesn't* call `f` by traversing from the entry while
+        // pretending that calls of `f` are sinks (i.e. ignoring any
+        // exit edges from them).
+        //
+        // NB. this has an edge case with non-returning statements,
+        // like `loop {}` or `panic!()`: control flow never reaches
+        // the exit node through these, so one can have a function
+        // that never actually calls itselfs but is still picked up by
+        // this lint:
+        //
+        //     fn f(cond: bool) {
+        //         if !cond { panic!() } // could come from `assert!(cond)`
+        //         f(false)
+        //     }
+        //
+        // In general, functions of that form may be able to call
+        // itself a finite number of times and then diverge. The lint
+        // considers this to be an error for two reasons, (a) it is
+        // easier to implement, and (b) it seems rare to actually want
+        // to have behaviour like the above, rather than
+        // e.g. accidentally recurring after an assert.
+
+        let cfg = cfg::CFG::new(cx.tcx, blk);
+
+        let mut work_queue = vec![cfg.entry];
+        let mut reached_exit_without_self_call = false;
+        let mut self_call_spans = vec![];
+        let mut visited = BitSet::new();
+
+        while let Some(idx) = work_queue.pop() {
+            if idx == cfg.exit {
+                // found a path!
+                reached_exit_without_self_call = true;
+                break;
+            }
+
+            let cfg_id = idx.node_id();
+            if visited.contains(&cfg_id) {
+                // already done
+                continue;
+            }
+            visited.insert(cfg_id);
+
+            let node_id = cfg.graph.node_data(idx).id();
+
+            // is this a recursive call?
+            if node_id != ast::DUMMY_NODE_ID && checker(cx.tcx, impl_node_id, id, name, node_id) {
+                self_call_spans.push(cx.tcx.map.span(node_id));
+                // this is a self call, so we shouldn't explore past
+                // this node in the CFG.
+                continue;
+            }
+            // add the successors of this node to explore the graph further.
+            cfg.graph.each_outgoing_edge(idx, |_, edge| {
+                let target_idx = edge.target();
+                let target_cfg_id = target_idx.node_id();
+                if !visited.contains(&target_cfg_id) {
+                    work_queue.push(target_idx)
+                }
+                true
+            });
+        }
+
+        // Check the number of self calls because a function that
+        // doesn't return (e.g. calls a `-> !` function or `loop { /*
+        // no break */ }`) shouldn't be linted unless it actually
+        // recurs.
+        if !reached_exit_without_self_call && self_call_spans.len() > 0 {
+            cx.span_lint(UNCONDITIONAL_RECURSION, sp,
+                         "function cannot return without recurring");
+
+            // FIXME #19668: these could be span_lint_note's instead of this manual guard.
+            if cx.current_level(UNCONDITIONAL_RECURSION) != Level::Allow {
+                let sess = cx.sess();
+                // offer some help to the programmer.
+                for call in &self_call_spans {
+                    sess.span_note(*call, "recursive call site")
+                }
+                sess.fileline_help(sp, "a `loop` may express intention \
+                                        better if this is on purpose")
+            }
+        }
+
+        // all done
+        return;
+
+        // Functions for identifying if the given NodeId `id`
+        // represents a call to the function `fn_id`/method
+        // `method_id`.
+
+        fn id_refers_to_this_fn<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                      _: ast::NodeId,
+                                      fn_id: ast::NodeId,
+                                      _: ast::Ident,
+                                      id: ast::NodeId) -> bool {
+            tcx.def_map.borrow().get(&id)
+               .map_or(false, |def| def.def_id() == local_def(fn_id))
+        }
+
+        // check if the method call `id` refers to method `method_id`
+        // (with name `method_name` contained in impl `impl_id`).
+        fn id_refers_to_this_method<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                          impl_id: ast::NodeId,
+                                          method_id: ast::NodeId,
+                                          method_name: ast::Ident,
+                                          id: ast::NodeId) -> bool {
+            let did = match tcx.method_map.borrow().get(&ty::MethodCall::expr(id)) {
+                None => return false,
+                Some(m) => match m.origin {
+                    // There's no way to know if a method call via a
+                    // vtable is recursion, so we assume it's not.
+                    ty::MethodTraitObject(_) => return false,
+
+                    // This `did` refers directly to the method definition.
+                    ty::MethodStatic(did) | ty::MethodStaticClosure(did) => did,
+
+                    // MethodTypeParam are methods from traits:
+
+                    // The `impl ... for ...` of this method call
+                    // isn't known, e.g. it might be a default method
+                    // in a trait, so we get the def-id of the trait
+                    // method instead.
+                    ty::MethodTypeParam(
+                        ty::MethodParam { ref trait_ref, method_num, impl_def_id: None, }) => {
+                        ty::trait_item(tcx, trait_ref.def_id, method_num).def_id()
+                    }
+
+                    // The `impl` is known, so we check that with a
+                    // special case:
+                    ty::MethodTypeParam(
+                        ty::MethodParam { impl_def_id: Some(impl_def_id), .. }) => {
+
+                        let name = match tcx.map.expect_expr(id).node {
+                            ast::ExprMethodCall(ref sp_ident, _, _) => sp_ident.node,
+                            _ => tcx.sess.span_bug(
+                                tcx.map.span(id),
+                                "non-method call expr behaving like a method call?")
+                        };
+                        // It matches if it comes from the same impl,
+                        // and has the same method name.
+                        return ast_util::is_local(impl_def_id)
+                            && impl_def_id.node == impl_id
+                            && method_name.name == name.name
+                    }
+                }
+            };
+
+            ast_util::is_local(did) && did.node == method_id
+        }
+    }
+}
+
+declare_lint! {
+    PLUGIN_AS_LIBRARY,
+    Warn,
+    "compiler plugin used as ordinary library in non-plugin crate"
+}
+
+#[derive(Copy, Clone)]
+pub struct PluginAsLibrary;
+
+impl LintPass for PluginAsLibrary {
+    fn get_lints(&self) -> LintArray {
+        lint_array![PLUGIN_AS_LIBRARY]
+    }
+
+    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
+        if cx.sess().plugin_registrar_fn.get().is_some() {
+            // We're compiling a plugin; it's fine to link other plugins.
+            return;
+        }
+
+        match it.node {
+            ast::ItemExternCrate(..) => (),
+            _ => return,
+        };
+
+        let md = match cx.sess().cstore.find_extern_mod_stmt_cnum(it.id) {
+            Some(cnum) => cx.sess().cstore.get_crate_data(cnum),
+            None => {
+                // Probably means we aren't linking the crate for some reason.
+                //
+                // Not sure if / when this could happen.
+                return;
+            }
+        };
+
+        if decoder::get_plugin_registrar_fn(md.data()).is_some() {
+            cx.span_lint(PLUGIN_AS_LIBRARY, it.span,
+                         "compiler plugin used as an ordinary library");
+        }
+    }
+}
+
+declare_lint! {
+    PRIVATE_NO_MANGLE_FNS,
+    Warn,
+    "functions marked #[no_mangle] should be exported"
+}
+
+declare_lint! {
+    PRIVATE_NO_MANGLE_STATICS,
+    Warn,
+    "statics marked #[no_mangle] should be exported"
+}
+
+declare_lint! {
+    NO_MANGLE_CONST_ITEMS,
+    Deny,
+    "const items will not have their symbols exported"
+}
+
+#[derive(Copy, Clone)]
+pub struct InvalidNoMangleItems;
+
+impl LintPass for InvalidNoMangleItems {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(PRIVATE_NO_MANGLE_FNS,
+                    PRIVATE_NO_MANGLE_STATICS,
+                    NO_MANGLE_CONST_ITEMS)
+    }
+
+    fn check_item(&mut self, cx: &Context, it: &ast::Item) {
+        match it.node {
+            ast::ItemFn(..) => {
+                if attr::contains_name(&it.attrs, "no_mangle") &&
+                       !cx.exported_items.contains(&it.id) {
+                    let msg = format!("function {} is marked #[no_mangle], but not exported",
+                                      it.ident);
+                    cx.span_lint(PRIVATE_NO_MANGLE_FNS, it.span, &msg);
+                }
+            },
+            ast::ItemStatic(..) => {
+                if attr::contains_name(&it.attrs, "no_mangle") &&
+                       !cx.exported_items.contains(&it.id) {
+                    let msg = format!("static {} is marked #[no_mangle], but not exported",
+                                      it.ident);
+                    cx.span_lint(PRIVATE_NO_MANGLE_STATICS, it.span, &msg);
+                }
+            },
+            ast::ItemConst(..) => {
+                if attr::contains_name(&it.attrs, "no_mangle") {
+                    // Const items do not refer to a particular location in memory, and therefore
+                    // don't have anything to attach a symbol to
+                    let msg = "const items should never be #[no_mangle], consider instead using \
+                               `pub static`";
+                    cx.span_lint(NO_MANGLE_CONST_ITEMS, it.span, msg);
+                }
+            }
+            _ => {},
+        }
+    }
+}
+
+/// Forbids using the `#[feature(...)]` attribute
+#[derive(Copy, Clone)]
+pub struct UnstableFeatures;
+
+declare_lint! {
+    UNSTABLE_FEATURES,
+    Allow,
+    "enabling unstable features"
+}
+
+impl LintPass for UnstableFeatures {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(UNSTABLE_FEATURES)
+    }
+    fn check_attribute(&mut self, ctx: &Context, attr: &ast::Attribute) {
+        if attr::contains_name(&[attr.node.value.clone()], "feature") {
+            ctx.span_lint(UNSTABLE_FEATURES, attr.span, "unstable feature");
+        }
+    }
+}
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
new file mode 100644 (file)
index 0000000..34f7436
--- /dev/null
@@ -0,0 +1,136 @@
+// Copyright 2015 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.
+
+//! Lints in the Rust compiler.
+//!
+//! This currently only contains the definitions and implementations
+//! of most of the lints that `rustc` supports directly, it does not
+//! contain the infrastructure for defining/registering lints. That is
+//! available in `rustc::lint` and `rustc::plugin` respectively.
+//!
+//! # Note
+//!
+//! This API is completely unstable and subject to change.
+
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
+#![crate_name = "rustc_lint"]
+#![unstable(feature = "rustc_private")]
+#![staged_api]
+#![crate_type = "dylib"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+      html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+      html_root_url = "http://doc.rust-lang.org/nightly/")]
+
+#![feature(box_patterns)]
+#![feature(box_syntax)]
+#![feature(collections)]
+#![feature(core)]
+#![feature(quote)]
+#![feature(rustc_diagnostic_macros)]
+#![feature(rustc_private)]
+#![feature(unsafe_destructor)]
+#![feature(staged_api)]
+#![feature(str_char)]
+#![cfg_attr(test, feature(test))]
+
+extern crate syntax;
+#[macro_use]
+extern crate rustc;
+#[macro_use]
+extern crate log;
+
+pub use rustc::lint as lint;
+pub use rustc::metadata as metadata;
+pub use rustc::middle as middle;
+pub use rustc::session as session;
+pub use rustc::util as util;
+
+use session::Session;
+use lint::LintId;
+
+mod builtin;
+
+/// Tell the `LintStore` about all the built-in lints (the ones
+/// defined in this crate and the ones defined in
+/// `rustc::lint::builtin`).
+pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
+    macro_rules! add_builtin {
+        ($sess:ident, $($name:ident),*,) => (
+            {$(
+                store.register_pass($sess, false, box builtin::$name);
+                )*}
+            )
+    }
+
+    macro_rules! add_builtin_with_new {
+        ($sess:ident, $($name:ident),*,) => (
+            {$(
+                store.register_pass($sess, false, box builtin::$name::new());
+                )*}
+            )
+    }
+
+    macro_rules! add_lint_group {
+        ($sess:ident, $name:expr, $($lint:ident),*) => (
+            store.register_group($sess, false, $name, vec![$(LintId::of(builtin::$lint)),*]);
+            )
+    }
+
+    add_builtin!(sess,
+                 HardwiredLints,
+                 WhileTrue,
+                 ImproperCTypes,
+                 BoxPointers,
+                 UnusedAttributes,
+                 PathStatements,
+                 UnusedResults,
+                 NonCamelCaseTypes,
+                 NonSnakeCase,
+                 NonUpperCaseGlobals,
+                 UnusedParens,
+                 UnusedImportBraces,
+                 NonShorthandFieldPatterns,
+                 UnusedUnsafe,
+                 UnsafeCode,
+                 UnusedMut,
+                 UnusedAllocation,
+                 MissingCopyImplementations,
+                 UnstableFeatures,
+                 Stability,
+                 UnconditionalRecursion,
+                 InvalidNoMangleItems,
+                 PluginAsLibrary,
+                 );
+
+    add_builtin_with_new!(sess,
+                          TypeLimits,
+                          RawPointerDerive,
+                          MissingDoc,
+                          MissingDebugImplementations,
+                          );
+
+    add_lint_group!(sess, "bad_style",
+                    NON_CAMEL_CASE_TYPES, NON_SNAKE_CASE, NON_UPPER_CASE_GLOBALS);
+
+    add_lint_group!(sess, "unused",
+                    UNUSED_IMPORTS, UNUSED_VARIABLES, UNUSED_ASSIGNMENTS, DEAD_CODE,
+                    UNUSED_MUT, UNREACHABLE_CODE, UNUSED_MUST_USE,
+                    UNUSED_UNSAFE, PATH_STATEMENTS);
+
+    // We have one lint pass defined specially
+    store.register_pass(sess, false, box lint::GatherNodeLevels);
+
+    // Insert temporary renamings for a one-time deprecation
+    store.register_renamed("raw_pointer_deriving", "raw_pointer_derive");
+
+    store.register_renamed("unknown_features", "unused_features");
+}
index 14a99026aac8ac18c8e06b377e68981ca534f52b..647f4bc6a40fdbe7118dd31349b6de4657af6bae 100644 (file)
@@ -14,8 +14,8 @@ use libc;
 use ArchiveRef;
 
 use std::ffi::CString;
-use std::mem;
-use std::raw;
+use std::slice;
+use std::path::Path;
 
 pub struct ArchiveRO {
     ptr: ArchiveRef,
@@ -29,14 +29,26 @@ impl ArchiveRO {
     /// If this archive is used with a mutable method, then an error will be
     /// raised.
     pub fn open(dst: &Path) -> Option<ArchiveRO> {
-        unsafe {
-            let s = CString::new(dst.as_vec()).unwrap();
+        return unsafe {
+            let s = path2cstr(dst);
             let ar = ::LLVMRustOpenArchive(s.as_ptr());
             if ar.is_null() {
                 None
             } else {
                 Some(ArchiveRO { ptr: ar })
             }
+        };
+
+        #[cfg(unix)]
+        fn path2cstr(p: &Path) -> CString {
+            use std::os::unix::prelude::*;
+            use std::ffi::OsStr;
+            let p: &OsStr = p.as_ref();
+            CString::new(p.as_bytes()).unwrap()
+        }
+        #[cfg(windows)]
+        fn path2cstr(p: &Path) -> CString {
+            CString::new(p.to_str().unwrap()).unwrap()
         }
     }
 
@@ -50,10 +62,7 @@ impl ArchiveRO {
             if ptr.is_null() {
                 None
             } else {
-                Some(mem::transmute(raw::Slice {
-                    data: ptr,
-                    len: size as uint,
-                }))
+                Some(slice::from_raw_parts(ptr as *const u8, size as usize))
             }
         }
     }
index aca4d265bc963d12ec40d18a2c072c9fd9efac9f..e6350ae44d43f924d7ff2b12ea46435b6d551230 100644 (file)
@@ -18,7 +18,7 @@ use std::ptr;
 
 use {ValueRef, TwineRef, DebugLocRef, DiagnosticInfoRef};
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum OptimizationDiagnosticKind {
     OptimizationRemark,
     OptimizationMissed,
@@ -38,7 +38,7 @@ impl OptimizationDiagnosticKind {
 }
 
 #[allow(raw_pointer_derive)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct OptimizationDiagnostic {
     pub kind: OptimizationDiagnosticKind,
     pub pass_name: *const c_char,
@@ -69,14 +69,13 @@ impl OptimizationDiagnostic {
     }
 }
 
+#[derive(Copy, Clone)]
 pub struct InlineAsmDiagnostic {
     pub cookie: c_uint,
     pub message: TwineRef,
     pub instruction: ValueRef,
 }
 
-impl Copy for InlineAsmDiagnostic {}
-
 impl InlineAsmDiagnostic {
     unsafe fn unpack(di: DiagnosticInfoRef)
             -> InlineAsmDiagnostic {
@@ -96,7 +95,7 @@ impl InlineAsmDiagnostic {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum Diagnostic {
     Optimization(OptimizationDiagnostic),
     InlineAsm(InlineAsmDiagnostic),
index 09a187befb2130ec01ccb05fb84f16265d300e86..9b0ae2e9ef858e852aa2c17788cb1f68636bcda4 100644 (file)
@@ -8,10 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![allow(non_upper_case_globals)]
 #![allow(non_camel_case_types)]
 #![allow(non_snake_case)]
 #![allow(dead_code)]
+#![allow(trivial_casts)]
 
 #![crate_name = "rustc_llvm"]
 #![unstable(feature = "rustc_private")]
 
 #![feature(box_syntax)]
 #![feature(collections)]
-#![feature(core)]
-#![feature(int_uint)]
 #![feature(libc)]
 #![feature(link_args)]
-#![feature(old_path)]
 #![feature(staged_api)]
-#![feature(std_misc)]
 
 extern crate libc;
 #[macro_use] #[no_link] extern crate rustc_bitflags;
@@ -57,7 +56,7 @@ pub use self::Linkage::*;
 
 use std::ffi::CString;
 use std::cell::RefCell;
-use std::{raw, mem};
+use std::{slice, mem};
 use libc::{c_uint, c_ushort, uint64_t, c_int, size_t, c_char};
 use libc::{c_longlong, c_ulonglong, c_void};
 use debuginfo::{DIBuilderRef, DIDescriptor,
@@ -75,9 +74,9 @@ pub type Bool = c_uint;
 pub const True: Bool = 1 as Bool;
 pub const False: Bool = 0 as Bool;
 
-// Consts for the LLVM CallConv type, pre-cast to uint.
+// Consts for the LLVM CallConv type, pre-cast to usize.
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum CallConv {
     CCallConv = 0,
     FastCallConv = 8,
@@ -87,7 +86,7 @@ pub enum CallConv {
     X86_64_Win64 = 79,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum Visibility {
     LLVMDefaultVisibility = 0,
     HiddenVisibility = 1,
@@ -98,7 +97,7 @@ pub enum Visibility {
 // DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage.
 // LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
 // they've been removed in upstream LLVM commit r203866.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum Linkage {
     ExternalLinkage = 0,
     AvailableExternallyLinkage = 1,
@@ -114,7 +113,7 @@ pub enum Linkage {
 }
 
 #[repr(C)]
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum DiagnosticSeverity {
     Error,
     Warning,
@@ -155,7 +154,7 @@ bitflags! {
 
 
 #[repr(u64)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum OtherAttribute {
     // The following are not really exposed in
     // the LLVM c api so instead to add these
@@ -176,13 +175,13 @@ pub enum OtherAttribute {
     NonNullAttribute = 1 << 44,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum SpecialAttribute {
     DereferenceableAttribute(u64)
 }
 
 #[repr(C)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum AttributeSet {
     ReturnIndex = 0,
     FunctionIndex = !0
@@ -240,7 +239,7 @@ impl AttrHelper for SpecialAttribute {
 }
 
 pub struct AttrBuilder {
-    attrs: Vec<(uint, Box<AttrHelper+'static>)>
+    attrs: Vec<(usize, Box<AttrHelper+'static>)>
 }
 
 impl AttrBuilder {
@@ -250,13 +249,13 @@ impl AttrBuilder {
         }
     }
 
-    pub fn arg<'a, T: AttrHelper + 'static>(&'a mut self, idx: uint, a: T) -> &'a mut AttrBuilder {
+    pub fn arg<'a, T: AttrHelper + 'static>(&'a mut self, idx: usize, a: T) -> &'a mut AttrBuilder {
         self.attrs.push((idx, box a as Box<AttrHelper+'static>));
         self
     }
 
     pub fn ret<'a, T: AttrHelper + 'static>(&'a mut self, a: T) -> &'a mut AttrBuilder {
-        self.attrs.push((ReturnIndex as uint, box a as Box<AttrHelper+'static>));
+        self.attrs.push((ReturnIndex as usize, box a as Box<AttrHelper+'static>));
         self
     }
 
@@ -274,7 +273,7 @@ impl AttrBuilder {
 }
 
 // enum for the LLVM IntPredicate type
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum IntPredicate {
     IntEQ = 32,
     IntNE = 33,
@@ -289,7 +288,7 @@ pub enum IntPredicate {
 }
 
 // enum for the LLVM RealPredicate type
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum RealPredicate {
     RealPredicateFalse = 0,
     RealOEQ = 1,
@@ -311,7 +310,7 @@ pub enum RealPredicate {
 
 // The LLVM TypeKind type - must stay in sync with the def of
 // LLVMTypeKind in llvm/include/llvm-c/Core.h
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 #[repr(C)]
 pub enum TypeKind {
     Void      = 0,
@@ -333,7 +332,7 @@ pub enum TypeKind {
 }
 
 #[repr(C)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum AtomicBinOp {
     AtomicXchg = 0,
     AtomicAdd  = 1,
@@ -349,7 +348,7 @@ pub enum AtomicBinOp {
 }
 
 #[repr(C)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum AtomicOrdering {
     NotAtomic = 0,
     Unordered = 1,
@@ -363,13 +362,13 @@ pub enum AtomicOrdering {
 
 // Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
 #[repr(C)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum FileType {
     AssemblyFileType = 0,
     ObjectFileType = 1
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum MetadataType {
     MD_dbg = 0,
     MD_tbaa = 1,
@@ -386,13 +385,13 @@ pub enum MetadataType {
 }
 
 // Inline Asm Dialect
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum AsmDialect {
     AD_ATT   = 0,
     AD_Intel = 1
 }
 
-#[derive(Copy, PartialEq, Clone)]
+#[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
 pub enum CodeGenOptLevel {
     CodeGenLevelNone = 0,
@@ -401,7 +400,7 @@ pub enum CodeGenOptLevel {
     CodeGenLevelAggressive = 3,
 }
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
 pub enum RelocMode {
     RelocDefault = 0,
@@ -411,7 +410,7 @@ pub enum RelocMode {
 }
 
 #[repr(C)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum CodeGenModel {
     CodeModelDefault = 0,
     CodeModelJITDefault = 1,
@@ -422,7 +421,7 @@ pub enum CodeGenModel {
 }
 
 #[repr(C)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum DiagnosticKind {
     DK_InlineAsm = 0,
     DK_StackSize,
@@ -534,7 +533,7 @@ pub mod debuginfo {
     pub type DIEnumerator = DIDescriptor;
     pub type DITemplateTypeParameter = DIDescriptor;
 
-    #[derive(Copy)]
+    #[derive(Copy, Clone)]
     pub enum DIDescriptorFlags {
       FlagPrivate            = 1 << 0,
       FlagProtected          = 1 << 1,
@@ -691,7 +690,7 @@ extern {
                          -> ValueRef;
     pub fn LLVMConstFCmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef)
                          -> ValueRef;
-    /* only for int/vector */
+    /* only for isize/vector */
     pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
     pub fn LLVMIsConstant(Val: ValueRef) -> Bool;
     pub fn LLVMIsNull(Val: ValueRef) -> Bool;
@@ -1976,6 +1975,7 @@ extern {
     pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;
 
     pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
+    pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
 
     pub fn LLVMInitializeX86TargetInfo();
     pub fn LLVMInitializeX86Target();
@@ -2165,7 +2165,7 @@ impl ObjectFile {
     pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
         unsafe {
             let llof = LLVMCreateObjectFile(llmb);
-            if llof as int == 0 {
+            if llof as isize == 0 {
                 // LLVMCreateObjectFile took ownership of llmb
                 return None
             }
@@ -2225,10 +2225,7 @@ type RustStringRepr = *mut RefCell<Vec<u8>>;
 pub unsafe extern "C" fn rust_llvm_string_write_impl(sr: RustStringRef,
                                                      ptr: *const c_char,
                                                      size: size_t) {
-    let slice: &[u8] = mem::transmute(raw::Slice {
-        data: ptr as *const u8,
-        len: size as uint,
-    });
+    let slice = slice::from_raw_parts(ptr as *const u8, size as usize);
 
     let sr: RustStringRepr = mem::transmute(sr);
     (*sr).borrow_mut().push_all(slice);
index 5662a74a53d34d087f06eae47370427c8e01d1e0..44ab09628137112f028fd9d0bb2b360d10b4b2d7 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rustc_privacy"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
@@ -17,8 +19,6 @@
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/")]
 
-#![feature(core)]
-#![feature(int_uint)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
@@ -38,17 +38,16 @@ use rustc::middle::def;
 use rustc::middle::privacy::ImportUse::*;
 use rustc::middle::privacy::LastPrivate::*;
 use rustc::middle::privacy::PrivateDep::*;
-use rustc::middle::privacy::{ExportedItems, PublicItems, LastPrivateMap};
-use rustc::middle::privacy::{ExternalExports};
+use rustc::middle::privacy::{ExternalExports, ExportedItems, PublicItems};
 use rustc::middle::ty::{MethodTypeParam, MethodStatic};
 use rustc::middle::ty::{MethodCall, MethodMap, MethodOrigin, MethodParam};
 use rustc::middle::ty::{MethodStaticClosure, MethodObject};
-use rustc::middle::ty::{MethodTraitObject};
+use rustc::middle::ty::MethodTraitObject;
 use rustc::middle::ty::{self, Ty};
 use rustc::util::nodemap::{NodeMap, NodeSet};
 
 use syntax::{ast, ast_map};
-use syntax::ast_util::{is_local, local_def, PostExpansionMethod};
+use syntax::ast_util::{is_local, local_def};
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::visit::{self, Visitor};
@@ -92,17 +91,9 @@ impl<'v> Visitor<'v> for ParentVisitor {
             // method to the root. In this case, if the trait is private, then
             // parent all the methods to the trait to indicate that they're
             // private.
-            ast::ItemTrait(_, _, _, ref methods) if item.vis != ast::Public => {
-                for m in methods {
-                    match *m {
-                        ast::ProvidedMethod(ref m) => {
-                            self.parents.insert(m.id, item.id);
-                        }
-                        ast::RequiredMethod(ref m) => {
-                            self.parents.insert(m.id, item.id);
-                        }
-                        ast::TypeTraitItem(_) => {}
-                    };
+            ast::ItemTrait(_, _, _, ref trait_items) if item.vis != ast::Public => {
+                for trait_item in trait_items {
+                    self.parents.insert(trait_item.id, item.id);
                 }
             }
 
@@ -209,7 +200,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
         match item.node {
             // impls/extern blocks do not break the "public chain" because they
             // cannot have visibility qualifiers on them anyway
-            ast::ItemImpl(..) | ast::ItemForeignMod(..) => {}
+            ast::ItemImpl(..) | ast::ItemDefaultImpl(..) | ast::ItemForeignMod(..) => {}
 
             // Traits are a little special in that even if they themselves are
             // not public they may still be exported.
@@ -235,6 +226,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
             ast::ItemEnum(ref def, _) if public_first => {
                 for variant in &def.variants {
                     self.exported_items.insert(variant.node.id);
+                    self.public_items.insert(variant.node.id);
                 }
             }
 
@@ -259,8 +251,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
             // * Private trait impls for private types can be completely ignored
             ast::ItemImpl(_, _, _, _, ref ty, ref impl_items) => {
                 let public_ty = match ty.node {
-                    ast::TyPath(_, id) => {
-                        match self.tcx.def_map.borrow()[id].clone() {
+                    ast::TyPath(..) => {
+                        match self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def() {
                             def::DefPrimTy(..) => true,
                             def => {
                                 let did = def.def_id();
@@ -279,18 +271,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
 
                 if public_ty || public_trait {
                     for impl_item in impl_items {
-                        match *impl_item {
-                            ast::MethodImplItem(ref method) => {
-                                let meth_public =
-                                    match method.pe_explicit_self().node {
-                                        ast::SelfStatic => public_ty,
-                                        _ => true,
-                                    } && method.pe_vis() == ast::Public;
+                        match impl_item.node {
+                            ast::MethodImplItem(ref sig, _) => {
+                                let meth_public = match sig.explicit_self.node {
+                                    ast::SelfStatic => public_ty,
+                                    _ => true,
+                                } && impl_item.vis == ast::Public;
                                 if meth_public || tr.is_some() {
-                                    self.exported_items.insert(method.id);
+                                    self.exported_items.insert(impl_item.id);
                                 }
                             }
-                            ast::TypeImplItem(_) => {}
+                            ast::TypeImplItem(_) |
+                            ast::MacImplItem(_) => {}
                         }
                     }
                 }
@@ -298,22 +290,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
 
             // Default methods on traits are all public so long as the trait
             // is public
-            ast::ItemTrait(_, _, _, ref methods) if public_first => {
-                for method in methods {
-                    match *method {
-                        ast::ProvidedMethod(ref m) => {
-                            debug!("provided {}", m.id);
-                            self.exported_items.insert(m.id);
-                        }
-                        ast::RequiredMethod(ref m) => {
-                            debug!("required {}", m.id);
-                            self.exported_items.insert(m.id);
-                        }
-                        ast::TypeTraitItem(ref t) => {
-                            debug!("typedef {}", t.ty_param.id);
-                            self.exported_items.insert(t.ty_param.id);
-                        }
-                    }
+            ast::ItemTrait(_, _, _, ref trait_items) if public_first => {
+                for trait_item in trait_items {
+                    debug!("trait item {}", trait_item.id);
+                    self.exported_items.insert(trait_item.id);
                 }
             }
 
@@ -323,11 +303,20 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
                     Some(id) => { self.exported_items.insert(id); }
                     None => {}
                 }
+                // fields can be public or private, so lets check
+                for field in &def.fields {
+                    let vis = match field.node.kind {
+                        ast::NamedField(_, vis) | ast::UnnamedField(vis) => vis
+                    };
+                    if vis == ast::Public {
+                        self.public_items.insert(field.node.id);
+                    }
+                }
             }
 
             ast::ItemTy(ref ty, _) if public_first => {
-                if let ast::TyPath(_, id) = ty.node {
-                    match self.tcx.def_map.borrow()[id].clone() {
+                if let ast::TyPath(..) = ty.node {
+                    match self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def() {
                         def::DefPrimTy(..) | def::DefTyParam(..) => {},
                         def => {
                             let did = def.def_id();
@@ -359,7 +348,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
         // crate module gets processed as well.
         if self.prev_exported {
             assert!(self.export_map.contains_key(&id), "wut {}", id);
-            for export in &self.export_map[id] {
+            for export in self.export_map.get(&id).unwrap() {
                 if is_local(export.def_id) {
                     self.reexports.insert(export.def_id.node);
                 }
@@ -379,7 +368,6 @@ struct PrivacyVisitor<'a, 'tcx: 'a> {
     in_foreign: bool,
     parents: NodeMap<ast::NodeId>,
     external_exports: ExternalExports,
-    last_private_map: LastPrivateMap,
 }
 
 enum PrivacyResult {
@@ -389,7 +377,7 @@ enum PrivacyResult {
 }
 
 enum FieldName {
-    UnnamedField(uint), // index
+    UnnamedField(usize), // index
     // (Name, not Ident, because struct fields are not macro-hygienic)
     NamedField(ast::Name),
 }
@@ -501,19 +489,20 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
                 // FIXME(#10573) is this the right behavior? Why not consider
                 //               where the method was defined?
                 Some(ast_map::NodeImplItem(ii)) => {
-                    match *ii {
-                        ast::MethodImplItem(ref m) => {
+                    match ii.node {
+                        ast::MethodImplItem(..) => {
                             let imp = self.tcx.map
                                           .get_parent_did(closest_private_id);
                             match ty::impl_trait_ref(self.tcx, imp) {
                                 Some(..) => return Allowable,
-                                _ if m.pe_vis() == ast::Public => {
+                                _ if ii.vis == ast::Public => {
                                     return Allowable
                                 }
-                                _ => m.pe_vis()
+                                _ => ii.vis
                             }
                         }
-                        ast::TypeImplItem(_) => return Allowable,
+                        ast::TypeImplItem(_) |
+                        ast::MacImplItem(_) => return Allowable,
                     }
                 }
                 Some(ast_map::NodeTraitItem(_)) => {
@@ -535,7 +524,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
             // if we've reached the root, then everything was allowable and this
             // access is public.
             if closest_private_id == ast::CRATE_NODE_ID { return Allowable }
-            closest_private_id = self.parents[closest_private_id];
+            closest_private_id = *self.parents.get(&closest_private_id).unwrap();
 
             // If we reached the top, then we were public all the way down and
             // we can allow this access.
@@ -553,7 +542,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
     /// whether the node is accessible by the current module that iteration is
     /// inside.
     fn private_accessible(&self, id: ast::NodeId) -> bool {
-        let parent = self.parents[id];
+        let parent = *self.parents.get(&id).unwrap();
         debug!("privacy - accessible parent {}", self.nodestr(parent));
 
         // After finding `did`'s closest private member, we roll ourselves back
@@ -577,7 +566,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
                 _ => {}
             }
 
-            cur = self.parents[cur];
+            cur = *self.parents.get(&cur).unwrap();
         }
     }
 
@@ -628,11 +617,11 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
                     // back up the chains to find the relevant struct/enum that
                     // was private.
                     ast::ItemImpl(_, _, _, _, ref ty, _) => {
-                        let id = match ty.node {
-                            ast::TyPath(_, id) => id,
+                        match ty.node {
+                            ast::TyPath(..) => {}
                             _ => return Some((err_span, err_msg, None)),
                         };
-                        let def = self.tcx.def_map.borrow()[id].clone();
+                        let def = self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def();
                         let did = def.def_id();
                         assert!(is_local(did));
                         match self.tcx.map.get(did.node) {
@@ -712,25 +701,25 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
                                              method_id,
                                              None,
                                              &format!("method `{}`",
-                                                     string)[]));
+                                                     string)));
     }
 
     // Checks that a path is in scope.
-    fn check_path(&mut self, span: Span, path_id: ast::NodeId, path: &ast::Path) {
+    fn check_path(&mut self, span: Span, path_id: ast::NodeId, last: ast::Ident) {
         debug!("privacy - path {}", self.nodestr(path_id));
-        let orig_def = self.tcx.def_map.borrow()[path_id].clone();
+        let path_res = *self.tcx.def_map.borrow().get(&path_id).unwrap();
         let ck = |tyname: &str| {
             let ck_public = |def: ast::DefId| {
                 debug!("privacy - ck_public {:?}", def);
-                let name = token::get_ident(path.segments.last().unwrap().identifier);
-                let origdid = orig_def.def_id();
+                let name = token::get_ident(last);
+                let origdid = path_res.def_id();
                 self.ensure_public(span,
                                    def,
                                    Some(origdid),
-                                   &format!("{} `{}`", tyname, name)[])
+                                   &format!("{} `{}`", tyname, name))
             };
 
-            match self.last_private_map[path_id] {
+            match path_res.last_private {
                 LastMod(AllPublic) => {},
                 LastMod(DependsOn(def)) => {
                     self.report_error(ck_public(def));
@@ -794,8 +783,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
         // def map is not. Therefore the names we work out below will not always
         // be accurate and we can get slightly wonky error messages (but type
         // checking is always correct).
-        match self.tcx.def_map.borrow()[path_id].clone() {
-            def::DefStaticMethod(..) => ck("static method"),
+        match path_res.full_def() {
             def::DefFn(..) => ck("function"),
             def::DefStatic(..) => ck("static"),
             def::DefConst(..) => ck("const"),
@@ -804,7 +792,6 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
             def::DefTy(_, true) => ck("enum"),
             def::DefTrait(..) => ck("trait"),
             def::DefStruct(..) => ck("struct"),
-            def::DefMethod(_, Some(..), _) => ck("trait method"),
             def::DefMethod(..) => ck("method"),
             def::DefMod(..) => ck("module"),
             _ => {}
@@ -832,37 +819,22 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
 
 impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
     fn visit_item(&mut self, item: &ast::Item) {
-        match item.node {
-            ast::ItemUse(ref vpath) => {
-                match vpath.node {
-                    ast::ViewPathSimple(..) | ast::ViewPathGlob(..) => {}
-                    ast::ViewPathList(ref prefix, ref list) => {
-                        for pid in list {
-                            match pid.node {
-                                ast::PathListIdent { id, name } => {
-                                    debug!("privacy - ident item {}", id);
-                                    let seg = ast::PathSegment {
-                                        identifier: name,
-                                        parameters: ast::PathParameters::none(),
-                                    };
-                                    let segs = vec![seg];
-                                    let path = ast::Path {
-                                        global: false,
-                                        span: pid.span,
-                                        segments: segs,
-                                    };
-                                    self.check_path(pid.span, id, &path);
-                                }
-                                ast::PathListMod { id } => {
-                                    debug!("privacy - mod item {}", id);
-                                    self.check_path(pid.span, id, prefix);
-                                }
-                            }
+        if let ast::ItemUse(ref vpath) = item.node {
+            if let ast::ViewPathList(ref prefix, ref list) = vpath.node {
+                for pid in list {
+                    match pid.node {
+                        ast::PathListIdent { id, name } => {
+                            debug!("privacy - ident item {}", id);
+                            self.check_path(pid.span, id, name);
+                        }
+                        ast::PathListMod { id } => {
+                            debug!("privacy - mod item {}", id);
+                            let name = prefix.segments.last().unwrap().identifier;
+                            self.check_path(pid.span, id, name);
                         }
                     }
                 }
             }
-            _ => {}
         }
         let orig_curitem = replace(&mut self.curitem, item.id);
         visit::walk_item(self, item);
@@ -908,7 +880,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
                         }
                     }
                     ty::ty_enum(_, _) => {
-                        match self.tcx.def_map.borrow()[expr.id].clone() {
+                        match self.tcx.def_map.borrow().get(&expr.id).unwrap().full_def() {
                             def::DefVariant(_, variant_id, _) => {
                                 for field in fields {
                                     self.check_field(expr.span, variant_id,
@@ -927,7 +899,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
                                                             struct type?!"),
                 }
             }
-            ast::ExprPath(_) | ast::ExprQPath(_) => {
+            ast::ExprPath(..) => {
                 let guard = |did: ast::DefId| {
                     let fields = ty::lookup_struct_fields(self.tcx, did);
                     let any_priv = fields.iter().any(|f| {
@@ -941,8 +913,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
                              with private fields");
                     }
                 };
-                match self.tcx.def_map.borrow().get(&expr.id) {
-                    Some(&def::DefStruct(did)) => {
+                match self.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
+                    Some(def::DefStruct(did)) => {
                         guard(if is_local(did) {
                             local_def(self.tcx.map.get_parent(did.node))
                         } else {
@@ -981,8 +953,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
                         }
                     }
                     ty::ty_enum(_, _) => {
-                        match self.tcx.def_map.borrow().get(&pattern.id) {
-                            Some(&def::DefVariant(_, variant_id, _)) => {
+                        match self.tcx.def_map.borrow().get(&pattern.id).map(|d| d.full_def()) {
+                            Some(def::DefVariant(_, variant_id, _)) => {
                                 for field in fields {
                                     self.check_field(pattern.span, variant_id,
                                                      NamedField(field.node.ident.name));
@@ -1033,7 +1005,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
     }
 
     fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
-        self.check_path(path.span, id, path);
+        self.check_path(path.span, id, path.segments.last().unwrap().identifier);
         visit::walk_path(self, path);
     }
 }
@@ -1096,12 +1068,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
                                 "visibility qualifiers have no effect on trait \
                                  impls");
                 for impl_item in impl_items {
-                    match *impl_item {
-                        ast::MethodImplItem(ref m) => {
-                            check_inherited(m.span, m.pe_vis(), "");
-                        }
-                        ast::TypeImplItem(_) => {}
-                    }
+                    check_inherited(impl_item.span, impl_item.vis, "");
                 }
             }
 
@@ -1129,22 +1096,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
                 }
             }
 
-            ast::ItemTrait(_, _, _, ref methods) => {
-                for m in methods {
-                    match *m {
-                        ast::ProvidedMethod(ref m) => {
-                            check_inherited(m.span, m.pe_vis(),
-                                            "unnecessary visibility");
-                        }
-                        ast::RequiredMethod(ref m) => {
-                            check_inherited(m.span, m.vis,
-                                            "unnecessary visibility");
-                        }
-                        ast::TypeTraitItem(_) => {}
-                    }
-                }
-            }
-
+            ast::ItemTrait(..) | ast::ItemDefaultImpl(..) |
             ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemStruct(..) |
             ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
             ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemMac(..) => {}
@@ -1172,11 +1124,12 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
         match item.node {
             ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
                 for impl_item in impl_items {
-                    match *impl_item {
-                        ast::MethodImplItem(ref m) => {
-                            check_inherited(tcx, m.span, m.pe_vis());
+                    match impl_item.node {
+                        ast::MethodImplItem(..) => {
+                            check_inherited(tcx, impl_item.span, impl_item.vis);
                         }
-                        ast::TypeImplItem(_) => {}
+                        ast::TypeImplItem(_) |
+                        ast::MacImplItem(_) => {}
                     }
                 }
             }
@@ -1193,18 +1146,8 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
 
             ast::ItemStruct(ref def, _) => check_struct(&**def),
 
-            ast::ItemTrait(_, _, _, ref methods) => {
-                for m in methods {
-                    match *m {
-                        ast::RequiredMethod(..) => {}
-                        ast::ProvidedMethod(ref m) => check_inherited(tcx, m.span,
-                                                                m.pe_vis()),
-                        ast::TypeTraitItem(_) => {}
-                    }
-                }
-            }
-
             ast::ItemExternCrate(_) | ast::ItemUse(_) |
+            ast::ItemTrait(..) | ast::ItemDefaultImpl(..) |
             ast::ItemStatic(..) | ast::ItemConst(..) |
             ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
             ast::ItemMac(..) => {}
@@ -1232,7 +1175,7 @@ struct CheckTypeForPrivatenessVisitor<'a, 'b: 'a, 'tcx: 'b> {
 
 impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
     fn path_is_private_type(&self, path_id: ast::NodeId) -> bool {
-        let did = match self.tcx.def_map.borrow().get(&path_id).cloned() {
+        let did = match self.tcx.def_map.borrow().get(&path_id).map(|d| d.full_def()) {
             // `int` etc. (None doesn't seem to occur.)
             None | Some(def::DefPrimTy(..)) => return false,
             Some(def) => def.def_id()
@@ -1242,6 +1185,7 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
         if !is_local(did) {
             return false
         }
+
         // .. and it corresponds to a private type in the AST (this returns
         // None for type parameters)
         match self.tcx.map.find(did.node) {
@@ -1262,18 +1206,21 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
             if !self.tcx.sess.features.borrow().visible_private_types &&
                 self.path_is_private_type(trait_ref.trait_ref.ref_id) {
                     let span = trait_ref.trait_ref.path.span;
-                    self.tcx.sess.span_err(span,
-                                           "private trait in exported type \
-                                            parameter bound");
+                    self.tcx.sess.span_err(span, "private trait in exported type \
+                                                  parameter bound");
             }
         }
     }
+
+    fn item_is_public(&self, id: &ast::NodeId, vis: ast::Visibility) -> bool {
+        self.exported_items.contains(id) || vis == ast::Public
+    }
 }
 
 impl<'a, 'b, 'tcx, 'v> Visitor<'v> for CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
     fn visit_ty(&mut self, ty: &ast::Ty) {
-        if let ast::TyPath(_, path_id) = ty.node {
-            if self.inner.path_is_private_type(path_id) {
+        if let ast::TyPath(..) = ty.node {
+            if self.inner.path_is_private_type(ty.id) {
                 self.contains_private = true;
                 // found what we're looking for so let's stop
                 // working.
@@ -1315,7 +1262,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
             // error messages without (too many) false positives
             // (i.e. we could just return here to not check them at
             // all, or some worse estimation of whether an impl is
-            // publicly visible.
+            // publicly visible).
             ast::ItemImpl(_, _, ref g, ref trait_ref, ref self_, ref impl_items) => {
                 // `impl [... for] Private` is never visible.
                 let self_contains_private;
@@ -1359,11 +1306,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                     trait_ref.is_some() ||
                     impl_items.iter()
                               .any(|impl_item| {
-                                  match *impl_item {
-                                      ast::MethodImplItem(ref m) => {
-                                          self.exported_items.contains(&m.id)
+                                  match impl_item.node {
+                                      ast::MethodImplItem(..) => {
+                                          self.exported_items.contains(&impl_item.id)
                                       }
-                                      ast::TypeImplItem(_) => false,
+                                      ast::TypeImplItem(_) |
+                                      ast::MacImplItem(_) => false,
                                   }
                               });
 
@@ -1376,19 +1324,30 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                     match *trait_ref {
                         None => {
                             for impl_item in impl_items {
-                                match *impl_item {
-                                    ast::MethodImplItem(ref method) => {
-                                        visit::walk_method_helper(self, &**method)
+                                // This is where we choose whether to walk down
+                                // further into the impl to check its items. We
+                                // should only walk into public items so that we
+                                // don't erroneously report errors for private
+                                // types in private items.
+                                match impl_item.node {
+                                    ast::MethodImplItem(..)
+                                        if self.item_is_public(&impl_item.id, impl_item.vis) =>
+                                    {
+                                        visit::walk_impl_item(self, impl_item)
+                                    }
+                                    ast::TypeImplItem(..) => {
+                                        visit::walk_impl_item(self, impl_item)
                                     }
-                                    ast::TypeImplItem(_) => {}
+                                    _ => {}
                                 }
                             }
                         }
                         Some(ref tr) => {
-                            // Any private types in a trait impl fall into two
+                            // Any private types in a trait impl fall into three
                             // categories.
                             // 1. mentioned in the trait definition
                             // 2. mentioned in the type params/generics
+                            // 3. mentioned in the associated types of the impl
                             //
                             // Those in 1. can only occur if the trait is in
                             // this crate and will've been warned about on the
@@ -1397,7 +1356,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                             //
                             // Those in 2. are warned via walk_generics and this
                             // call here.
-                            self.visit_trait_ref(tr)
+                            visit::walk_path(self, &tr.path);
+
+                            // Those in 3. are warned with this call.
+                            for impl_item in impl_items {
+                                match impl_item.node {
+                                    ast::TypeImplItem(ref ty) => {
+                                        self.visit_ty(ty);
+                                    }
+                                    ast::MethodImplItem(..) |
+                                    ast::MacImplItem(_) => {},
+                                }
+                            }
                         }
                     }
                 } else if trait_ref.is_none() && self_is_public_path {
@@ -1405,17 +1375,16 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                     // methods will be visible as `Public::foo`.
                     let mut found_pub_static = false;
                     for impl_item in impl_items {
-                        match *impl_item {
-                            ast::MethodImplItem(ref method) => {
-                                if method.pe_explicit_self().node ==
-                                        ast::SelfStatic &&
-                                        self.exported_items
-                                            .contains(&method.id) {
+                        match impl_item.node {
+                            ast::MethodImplItem(ref sig, _) => {
+                                if sig.explicit_self.node == ast::SelfStatic &&
+                                        self.item_is_public(&impl_item.id, impl_item.vis) {
                                     found_pub_static = true;
-                                    visit::walk_method_helper(self, &**method);
+                                    visit::walk_impl_item(self, impl_item);
                                 }
                             }
-                            ast::TypeImplItem(_) => {}
+                            ast::TypeImplItem(_) |
+                            ast::MacImplItem(_) => {}
                         }
                     }
                     if found_pub_static {
@@ -1430,15 +1399,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
             ast::ItemTy(..) => return,
 
             // not at all public, so we don't care
-            _ if !self.exported_items.contains(&item.id) => return,
+            _ if !self.item_is_public(&item.id, item.vis) => {
+                return;
+            }
 
             _ => {}
         }
 
-        // we've carefully constructed it so that if we're here, then
+        // We've carefully constructed it so that if we're here, then
         // any `visit_ty`'s will be called on things that are in
         // public signatures, i.e. things that we're interested in for
         // this visitor.
+        debug!("VisiblePrivateTypesVisitor entering item {:?}", item);
         visit::walk_item(self, item);
     }
 
@@ -1469,20 +1441,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
         }
     }
 
-    fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
-                b: &'v ast::Block, s: Span, id: ast::NodeId) {
-        // needs special handling for methods.
-        if self.exported_items.contains(&id) {
-            visit::walk_fn(self, fk, fd, b, s);
-        }
-    }
-
     fn visit_ty(&mut self, t: &ast::Ty) {
-        if let ast::TyPath(ref p, path_id) = t.node {
+        debug!("VisiblePrivateTypesVisitor checking ty {:?}", t);
+        if let ast::TyPath(_, ref p) = t.node {
             if !self.tcx.sess.features.borrow().visible_private_types &&
-                self.path_is_private_type(path_id) {
-                self.tcx.sess.span_err(p.span,
-                                       "private type in exported type signature");
+                self.path_is_private_type(t.id) {
+                self.tcx.sess.span_err(p.span, "private type in exported type signature");
             }
         }
         visit::walk_ty(self, t)
@@ -1516,8 +1480,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
 
 pub fn check_crate(tcx: &ty::ctxt,
                    export_map: &def::ExportMap,
-                   external_exports: ExternalExports,
-                   last_private_map: LastPrivateMap)
+                   external_exports: ExternalExports)
                    -> (ExportedItems, PublicItems) {
     let krate = tcx.map.krate();
 
@@ -1535,7 +1498,6 @@ pub fn check_crate(tcx: &ty::ctxt,
         tcx: tcx,
         parents: visitor.parents,
         external_exports: external_exports,
-        last_private_map: last_private_map,
     };
     visit::walk_crate(&mut visitor, krate);
 
index 2f25f34a92ad07434340f8a6ab5b5fdaa85a910e..52db6013f4d5df0b54f01abe3c47a026fc486b5d 100644 (file)
 //! any imports resolved.
 
 use {DefModifiers, PUBLIC, IMPORTABLE};
-use ImportDirective;
-use ImportDirectiveSubclass::{self, SingleImport, GlobImport};
-use ImportResolution;
+use resolve_imports::ImportDirective;
+use resolve_imports::ImportDirectiveSubclass::{self, SingleImport, GlobImport};
+use resolve_imports::ImportResolution;
 use Module;
 use ModuleKind::*;
 use Namespace::{TypeNS, ValueNS};
 use NameBindings;
+use {names_to_string, module_to_string};
 use ParentLink::{self, ModuleParentLink, BlockParentLink};
 use Resolver;
-use RibKind::*;
-use Shadowable;
+use resolve_imports::Shadowable;
 use TypeNsDef;
-use TypeParameters::HasTypeParameters;
 
 use self::DuplicateCheckingMode::*;
 use self::NamespaceError::*;
@@ -34,27 +33,23 @@ use self::NamespaceError::*;
 use rustc::metadata::csearch;
 use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
 use rustc::middle::def::*;
-use rustc::middle::subst::FnSpace;
 
 use syntax::ast::{Block, Crate};
 use syntax::ast::{DeclItem, DefId};
 use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic};
 use syntax::ast::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn};
-use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
+use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
 use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
-use syntax::ast::{MethodImplItem, Name, NamedField, NodeId};
-use syntax::ast::{PathListIdent, PathListMod};
-use syntax::ast::{Public, SelfStatic};
+use syntax::ast::{Name, NamedField, NodeId};
+use syntax::ast::{PathListIdent, PathListMod, Public};
 use syntax::ast::StmtDecl;
 use syntax::ast::StructVariantKind;
 use syntax::ast::TupleVariantKind;
-use syntax::ast::TyObjectSum;
-use syntax::ast::{TypeImplItem, UnnamedField};
+use syntax::ast::UnnamedField;
 use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
-use syntax::ast::{Visibility};
-use syntax::ast::TyPath;
+use syntax::ast::Visibility;
 use syntax::ast;
-use syntax::ast_util::{self, PostExpansionMethod, local_def};
+use syntax::ast_util::local_def;
 use syntax::attr::AttrMetaMethods;
 use syntax::parse::token::{self, special_idents};
 use syntax::codemap::{Span, DUMMY_SP};
@@ -66,7 +61,7 @@ use std::rc::Rc;
 
 // Specifies how duplicates should be handled when adding a child item if
 // another item exists with the same name in some namespace.
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 enum DuplicateCheckingMode {
     ForbidDuplicateModules,
     ForbidDuplicateTypesAndModules,
@@ -75,7 +70,7 @@ enum DuplicateCheckingMode {
     OverwriteDuplicates
 }
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 enum NamespaceError {
     NoError,
     ModuleError,
@@ -181,12 +176,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                         Some(TypeNS)
                     }
                     ForbidDuplicateTypesAndModules => {
-                        match child.def_for_namespace(TypeNS) {
-                            None => {}
-                            Some(_) if child.get_module_if_available()
-                                            .map(|m| m.kind.get()) ==
-                                       Some(ImplModuleKind) => {}
-                            Some(_) => duplicate_type = TypeError
+                        if child.defined_in_namespace(TypeNS) {
+                            duplicate_type = TypeError;
                         }
                         Some(TypeNS)
                     }
@@ -220,14 +211,14 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                     self.resolve_error(sp,
                         &format!("duplicate definition of {} `{}`",
                              namespace_error_to_string(duplicate_type),
-                             token::get_name(name))[]);
+                             token::get_name(name)));
                     {
                         let r = child.span_for_namespace(ns);
                         if let Some(sp) = r {
                             self.session.span_note(sp,
                                  &format!("first definition of {} `{}` here",
                                       namespace_error_to_string(duplicate_type),
-                                      token::get_name(name))[]);
+                                      token::get_name(name)));
                         }
                     }
                 }
@@ -307,8 +298,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                     ViewPathSimple(binding, ref full_path) => {
                         let source_name =
                             full_path.segments.last().unwrap().identifier.name;
-                        if &token::get_name(source_name)[] == "mod" ||
-                           &token::get_name(source_name)[] == "self" {
+                        if &token::get_name(source_name)[..] == "mod" ||
+                           &token::get_name(source_name)[..] == "self" {
                             self.resolve_error(view_path.span,
                                 "`self` imports are only allowed within a { } list");
                         }
@@ -381,8 +372,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
             ItemExternCrate(_) => {
                 // n.b. we don't need to look at the path option here, because cstore already did
-                for &crate_id in self.session.cstore
-                                     .find_extern_mod_stmt_cnum(item.id).iter() {
+                if let Some(crate_id) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) {
                     let def_id = DefId { krate: crate_id, node: 0 };
                     self.external_exports.insert(def_id);
                     let parent_link = ModuleParentLink(parent.downgrade(), name);
@@ -392,7 +382,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                                               false,
                                                               true));
                     debug!("(build reduced graph for item) found extern `{}`",
-                            self.module_to_string(&*external_module));
+                            module_to_string(&*external_module));
                     self.check_for_conflicts_between_external_crates(&**parent, name, sp);
                     parent.external_module_children.borrow_mut()
                           .insert(name, external_module.clone());
@@ -410,7 +400,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                             Some(def_id),
                                             NormalModuleKind,
                                             false,
-                                            item.vis == ast::Public,
+                                            is_public,
                                             sp);
 
                 name_bindings.get_module()
@@ -442,8 +432,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             // These items live in the type namespace.
             ItemTy(..) => {
                 let name_bindings =
-                    self.add_child(name, parent, ForbidDuplicateTypesAndModules,
-                                   sp);
+                    self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp);
 
                 name_bindings.define_type(DefTy(local_def(item.id), false), sp,
                                           modifiers);
@@ -465,9 +454,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 name_bindings.define_type(DefTy(local_def(item.id), true), sp, modifiers);
 
                 let parent_link = self.get_parent_link(parent, name);
-                // We want to make sure the module type is EnumModuleKind
-                // even if there's already an ImplModuleKind module defined,
-                // since that's how we prevent duplicate enum definitions
                 name_bindings.set_module_kind(parent_link,
                                               Some(local_def(item.id)),
                                               EnumModuleKind,
@@ -517,146 +503,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 parent.clone()
             }
 
-            ItemImpl(_, _, _, None, ref ty, ref impl_items) => {
-                // If this implements an anonymous trait, then add all the
-                // methods within to a new module, if the type was defined
-                // within this module.
-
-                let mod_name = match ty.node {
-                    TyPath(ref path, _) if path.segments.len() == 1 => {
-                        // FIXME(18446) we should distinguish between the name of
-                        // a trait and the name of an impl of that trait.
-                        Some(path.segments.last().unwrap().identifier.name)
-                    }
-                    TyObjectSum(ref lhs_ty, _) => {
-                        match lhs_ty.node {
-                            TyPath(ref path, _) if path.segments.len() == 1 => {
-                                Some(path.segments.last().unwrap().identifier.name)
-                            }
-                            _ => {
-                                None
-                            }
-                        }
-                    }
-                    _ => {
-                        None
-                    }
-                };
-
-                let mod_name = match mod_name {
-                    Some(mod_name) => mod_name,
-                    None => {
-                        self.resolve_error(ty.span,
-                                           "inherent implementations may \
-                                            only be implemented in the same \
-                                            module as the type they are \
-                                            implemented for");
-                        return parent.clone();
-                    }
-                };
-                // Create the module and add all methods.
-                let child_opt = parent.children.borrow().get(&mod_name)
-                                       .and_then(|m| m.get_module_if_available());
-                let new_parent = match child_opt {
-                    // It already exists
-                    Some(ref child) if (child.kind.get() == ImplModuleKind ||
-                                        child.kind.get() == TraitModuleKind) => {
-                        child.clone()
-                    }
-                    Some(ref child) if child.kind.get() == EnumModuleKind ||
-                                       child.kind.get() == TypeModuleKind => {
-                        child.clone()
-                    }
-                    // Create the module
-                    _ => {
-                        let name_bindings =
-                            self.add_child(mod_name, parent, ForbidDuplicateModules, sp);
-
-                        let parent_link = self.get_parent_link(parent, name);
-                        let def_id = local_def(item.id);
-                        let ns = TypeNS;
-                        let is_public =
-                            !name_bindings.defined_in_namespace(ns) ||
-                            name_bindings.defined_in_public_namespace(ns);
-
-                        name_bindings.define_module(parent_link,
-                                                    Some(def_id),
-                                                    ImplModuleKind,
-                                                    false,
-                                                    is_public,
-                                                    sp);
-
-                        name_bindings.get_module()
-                    }
-                };
-
-                // For each implementation item...
-                for impl_item in impl_items {
-                    match *impl_item {
-                        MethodImplItem(ref method) => {
-                            // Add the method to the module.
-                            let name = method.pe_ident().name;
-                            let method_name_bindings =
-                                self.add_child(name,
-                                               &new_parent,
-                                               ForbidDuplicateValues,
-                                               method.span);
-                            let def = match method.pe_explicit_self()
-                                .node {
-                                    SelfStatic => {
-                                        // Static methods become
-                                        // `DefStaticMethod`s.
-                                        DefStaticMethod(local_def(method.id),
-                                                        FromImpl(local_def(item.id)))
-                                    }
-                                    _ => {
-                                        // Non-static methods become
-                                        // `DefMethod`s.
-                                        DefMethod(local_def(method.id),
-                                                  None,
-                                                  FromImpl(local_def(item.id)))
-                                    }
-                                };
-
-                            // NB: not IMPORTABLE
-                            let modifiers = if method.pe_vis() == ast::Public {
-                                PUBLIC
-                            } else {
-                                DefModifiers::empty()
-                            };
-                            method_name_bindings.define_value(
-                                def,
-                                method.span,
-                                modifiers);
-                        }
-                        TypeImplItem(ref typedef) => {
-                            // Add the typedef to the module.
-                            let name = typedef.ident.name;
-                            let typedef_name_bindings =
-                                self.add_child(
-                                    name,
-                                    &new_parent,
-                                    ForbidDuplicateTypesAndModules,
-                                    typedef.span);
-                            let def = DefAssociatedTy(local_def(
-                                typedef.id));
-                            // NB: not IMPORTABLE
-                            let modifiers = if typedef.vis == ast::Public {
-                                PUBLIC
-                            } else {
-                                DefModifiers::empty()
-                            };
-                            typedef_name_bindings.define_type(
-                                def,
-                                typedef.span,
-                                modifiers);
-                        }
-                    }
-                }
-                parent.clone()
-            }
-
-            ItemImpl(_, _, _, Some(_), _, _) => parent.clone(),
+            ItemDefaultImpl(_, _) |
+            ItemImpl(..) => parent.clone(),
 
             ItemTrait(_, _, _, ref items) => {
                 let name_bindings =
@@ -668,7 +516,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                             Some(local_def(item.id)),
                                             TraitModuleKind,
                                             false,
-                                            item.vis == ast::Public,
+                                            is_public,
                                             sp);
                 let module_parent = name_bindings.get_module();
 
@@ -676,63 +524,28 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
                 // Add the names of all the items to the trait info.
                 for trait_item in items {
-                    let (name, kind) = match *trait_item {
-                        ast::RequiredMethod(_) |
-                        ast::ProvidedMethod(_) => {
-                            let ty_m = ast_util::trait_item_to_ty_method(trait_item);
-
-                            let name = ty_m.ident.name;
-
-                            // Add it as a name in the trait module.
-                            let (def, static_flag) = match ty_m.explicit_self
-                                                               .node {
-                                SelfStatic => {
-                                    // Static methods become `DefStaticMethod`s.
-                                    (DefStaticMethod(
-                                            local_def(ty_m.id),
-                                            FromTrait(local_def(item.id))),
-                                     StaticMethodTraitItemKind)
-                                }
-                                _ => {
-                                    // Non-static methods become `DefMethod`s.
-                                    (DefMethod(local_def(ty_m.id),
-                                               Some(local_def(item.id)),
-                                               FromTrait(local_def(item.id))),
-                                     NonstaticMethodTraitItemKind)
-                                }
-                            };
-
-                            let method_name_bindings =
-                                self.add_child(name,
-                                               &module_parent,
-                                               ForbidDuplicateTypesAndValues,
-                                               ty_m.span);
+                    let name_bindings = self.add_child(trait_item.ident.name,
+                                        &module_parent,
+                                        ForbidDuplicateTypesAndValues,
+                                        trait_item.span);
+
+                    match trait_item.node {
+                        ast::MethodTraitItem(..) => {
+                            let def = DefMethod(local_def(trait_item.id),
+                                                FromTrait(local_def(item.id)));
                             // NB: not IMPORTABLE
-                            method_name_bindings.define_value(def,
-                                                              ty_m.span,
-                                                              PUBLIC);
-
-                            (name, static_flag)
+                            name_bindings.define_value(def, trait_item.span, PUBLIC);
                         }
-                        ast::TypeTraitItem(ref associated_type) => {
-                            let def = DefAssociatedTy(local_def(
-                                    associated_type.ty_param.id));
-
-                            let name_bindings =
-                                self.add_child(associated_type.ty_param.ident.name,
-                                               &module_parent,
-                                               ForbidDuplicateTypesAndValues,
-                                               associated_type.ty_param.span);
+                        ast::TypeTraitItem(..) => {
+                            let def = DefAssociatedTy(local_def(item.id),
+                                                      local_def(trait_item.id));
                             // NB: not IMPORTABLE
-                            name_bindings.define_type(def,
-                                                      associated_type.ty_param.span,
-                                                      PUBLIC);
-
-                            (associated_type.ty_param.ident.name, TypeTraitItemKind)
+                            name_bindings.define_type(def, trait_item.span, PUBLIC);
                         }
-                    };
+                    }
 
-                    self.trait_item_map.insert((name, def_id), kind);
+                    self.trait_item_map.insert((trait_item.ident.name, def_id),
+                                               local_def(trait_item.id));
                 }
 
                 name_bindings.define_type(DefTrait(def_id), sp, modifiers);
@@ -772,12 +585,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
     }
 
     /// Constructs the reduced graph for one foreign item.
-    fn build_reduced_graph_for_foreign_item<F>(&mut self,
-                                               foreign_item: &ForeignItem,
-                                               parent: &Rc<Module>,
-                                               f: F) where
-        F: FnOnce(&mut Resolver),
-    {
+    fn build_reduced_graph_for_foreign_item(&mut self,
+                                            foreign_item: &ForeignItem,
+                                            parent: &Rc<Module>) {
         let name = foreign_item.ident.name;
         let is_public = foreign_item.vis == ast::Public;
         let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
@@ -785,25 +595,15 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             self.add_child(name, parent, ForbidDuplicateValues,
                            foreign_item.span);
 
-        match foreign_item.node {
-            ForeignItemFn(_, ref generics) => {
-                let def = DefFn(local_def(foreign_item.id), false);
-                name_bindings.define_value(def, foreign_item.span, modifiers);
-
-                self.with_type_parameter_rib(
-                    HasTypeParameters(generics,
-                                      FnSpace,
-                                      foreign_item.id,
-                                      NormalRibKind),
-                    f);
+        let def = match foreign_item.node {
+            ForeignItemFn(..) => {
+                DefFn(local_def(foreign_item.id), false)
             }
             ForeignItemStatic(_, m) => {
-                let def = DefStatic(local_def(foreign_item.id), m);
-                name_bindings.define_value(def, foreign_item.span, modifiers);
-
-                f(self.resolver)
+                DefStatic(local_def(foreign_item.id), m)
             }
-        }
+        };
+        name_bindings.define_value(def, foreign_item.span, modifiers);
     }
 
     fn build_reduced_graph_for_block(&mut self, block: &Block, parent: &Rc<Module>) -> Rc<Module> {
@@ -835,8 +635,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                            name: Name,
                            new_parent: &Rc<Module>) {
         debug!("(building reduced graph for \
-                external crate) building external def, priv {:?}",
-               vis);
+                external crate) building external def {}, priv {:?}",
+               final_ident, vis);
         let is_public = vis == ast::Public;
         let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
         let is_exported = is_public && match new_parent.def_id.get() {
@@ -849,8 +649,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
         let kind = match def {
             DefTy(_, true) => EnumModuleKind,
-            DefTy(_, false) => TypeModuleKind,
-            DefStruct(..) => ImplModuleKind,
+            DefTy(_, false) | DefStruct(..) => TypeModuleKind,
             _ => NormalModuleKind
         };
 
@@ -867,7 +666,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
               Some(_) | None => {
                 debug!("(building reduced graph for \
                         external crate) building module \
-                        {}", final_ident);
+                        {} {}", final_ident, is_public);
                 let parent_link = self.get_parent_link(new_parent, name);
 
                 child_name_bindings.define_module(parent_link,
@@ -904,7 +703,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
                     .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
           }
-          DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
+          DefFn(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
             debug!("(building reduced graph for external \
                     crate) building value (fn/static) {}", final_ident);
             // impl methods have already been defined with the correct importability modifier
@@ -926,21 +725,19 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
               let trait_item_def_ids =
                 csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
-              for trait_item_def_id in &trait_item_def_ids {
-                  let (trait_item_name, trait_item_kind) =
-                      csearch::get_trait_item_name_and_kind(
-                          &self.session.cstore,
-                          trait_item_def_id.def_id());
+              for trait_item_def in &trait_item_def_ids {
+                  let trait_item_name = csearch::get_trait_name(&self.session.cstore,
+                                                                trait_item_def.def_id());
 
                   debug!("(building reduced graph for external crate) ... \
                           adding trait item '{}'",
                          token::get_name(trait_item_name));
 
-                  self.trait_item_map.insert((trait_item_name, def_id), trait_item_kind);
+                  self.trait_item_map.insert((trait_item_name, def_id),
+                                             trait_item_def.def_id());
 
                   if is_exported {
-                      self.external_exports
-                          .insert(trait_item_def_id.def_id());
+                      self.external_exports.insert(trait_item_def.def_id());
                   }
               }
 
@@ -955,7 +752,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                                   is_public,
                                                   DUMMY_SP)
           }
-          DefTy(..) | DefAssociatedTy(..) | DefAssociatedPath(..) => {
+          DefTy(..) | DefAssociatedTy(..) => {
               debug!("(building reduced graph for external \
                       crate) building type {}", final_ident);
 
@@ -979,7 +776,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
           }
           DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
           DefUse(..) | DefUpvar(..) | DefRegion(..) |
-          DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
+          DefLabel(..) | DefSelfTy(..) => {
             panic!("didn't expect `{:?}`", def);
           }
         }
@@ -1026,92 +823,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                     }
                 }
             }
-            DlImpl(def) => {
-                match csearch::get_type_name_if_impl(&self.session.cstore, def) {
-                    None => {}
-                    Some(final_name) => {
-                        let methods_opt =
-                            csearch::get_methods_if_impl(&self.session.cstore, def);
-                        match methods_opt {
-                            Some(ref methods) if
-                                methods.len() >= 1 => {
-                                debug!("(building reduced graph for \
-                                        external crate) processing \
-                                        static methods for type name {}",
-                                        token::get_name(final_name));
-
-                                let child_name_bindings =
-                                    self.add_child(
-                                        final_name,
-                                        root,
-                                        OverwriteDuplicates,
-                                        DUMMY_SP);
-
-                                // Process the static methods. First,
-                                // create the module.
-                                let type_module;
-                                let type_def = child_name_bindings.type_def.borrow().clone();
-                                match type_def {
-                                    Some(TypeNsDef {
-                                        module_def: Some(module_def),
-                                        ..
-                                    }) => {
-                                        // We already have a module. This
-                                        // is OK.
-                                        type_module = module_def;
-
-                                        // Mark it as an impl module if
-                                        // necessary.
-                                        type_module.kind.set(ImplModuleKind);
-                                    }
-                                    Some(_) | None => {
-                                        let parent_link =
-                                            self.get_parent_link(root, final_name);
-                                        child_name_bindings.define_module(
-                                            parent_link,
-                                            Some(def),
-                                            ImplModuleKind,
-                                            true,
-                                            true,
-                                            DUMMY_SP);
-                                        type_module =
-                                            child_name_bindings.
-                                                get_module();
-                                    }
-                                }
-
-                                // Add each static method to the module.
-                                let new_parent = type_module;
-                                for method_info in methods {
-                                    let name = method_info.name;
-                                    debug!("(building reduced graph for \
-                                             external crate) creating \
-                                             static method '{}'",
-                                           token::get_name(name));
-
-                                    let method_name_bindings =
-                                        self.add_child(name,
-                                                       &new_parent,
-                                                       OverwriteDuplicates,
-                                                       DUMMY_SP);
-                                    let def = DefFn(method_info.def_id, false);
-
-                                    // NB: not IMPORTABLE
-                                    let modifiers = if method_info.vis == ast::Public {
-                                        PUBLIC
-                                    } else {
-                                        DefModifiers::empty()
-                                    };
-                                    method_name_bindings.define_value(
-                                        def, DUMMY_SP, modifiers);
-                                }
-                            }
-
-                            // Otherwise, do nothing.
-                            Some(_) | None => {}
-                        }
-                    }
-                }
+            DlImpl(_) => {
+                debug!("(building reduced graph for external crate) \
+                        ignoring impl");
             }
             DlField => {
                 debug!("(building reduced graph for external crate) \
@@ -1123,7 +837,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
     /// Builds the reduced graph rooted at the given external module.
     fn populate_external_module(&mut self, module: &Rc<Module>) {
         debug!("(populating external module) attempting to populate {}",
-               self.module_to_string(&**module));
+               module_to_string(&**module));
 
         let def_id = match module.def_id.get() {
             None => {
@@ -1189,18 +903,14 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
         match subclass {
             SingleImport(target, _) => {
-                debug!("(building import directive) building import \
-                        directive: {}::{}",
-                       self.names_to_string(&module_.imports.borrow().last().unwrap().
-                                                             module_path[]),
+                debug!("(building import directive) building import directive: {}::{}",
+                       names_to_string(&module_.imports.borrow().last().unwrap().module_path),
                        token::get_name(target));
 
-                let mut import_resolutions = module_.import_resolutions
-                                                    .borrow_mut();
+                let mut import_resolutions = module_.import_resolutions.borrow_mut();
                 match import_resolutions.get_mut(&target) {
                     Some(resolution) => {
-                        debug!("(building import directive) bumping \
-                                reference");
+                        debug!("(building import directive) bumping reference");
                         resolution.outstanding_references += 1;
 
                         // the source of this name is different now
@@ -1240,16 +950,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
     }
 
     fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
-        let parent = &self.parent;
-        self.builder.build_reduced_graph_for_foreign_item(foreign_item,
-                                                          parent,
-                                                          |r| {
-            let mut v = BuildReducedGraphVisitor {
-                builder: GraphBuilder { resolver: r },
-                parent: parent.clone()
-            };
-            visit::walk_foreign_item(&mut v, foreign_item);
-        })
+        self.builder.build_reduced_graph_for_foreign_item(foreign_item, &self.parent);
     }
 
     fn visit_block(&mut self, block: &Block) {
index a239c73c110dbd67e96353ad8efca3f20b6b82b5..aebbe14407380336174b9c85f82bd693b5084dbd 100644 (file)
@@ -68,17 +68,17 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
                                   "unused import".to_string());
         }
 
-        let (v_priv, t_priv) = match self.last_private.get(&id) {
-            Some(&LastImport {
-                value_priv: v,
-                value_used: _,
-                type_priv: t,
-                type_used: _
-            }) => (v, t),
-            Some(_) => {
+        let mut def_map = self.def_map.borrow_mut();
+        let path_res = if let Some(r) = def_map.get_mut(&id) {
+            r
+        } else {
+            return;
+        };
+        let (v_priv, t_priv) = match path_res.last_private {
+            LastImport { value_priv, type_priv, .. } => (value_priv, type_priv),
+            _ => {
                 panic!("we should only have LastImport for `use` directives")
             }
-            _ => return,
         };
 
         let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
@@ -100,10 +100,12 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
             _ => {},
         }
 
-        self.last_private.insert(id, LastImport{value_priv: v_priv,
-                                                value_used: v_used,
-                                                type_priv: t_priv,
-                                                type_used: t_used});
+        path_res.last_private = LastImport {
+            value_priv: v_priv,
+            value_used: v_used,
+            type_priv: t_priv,
+            type_used: t_used
+        };
     }
 }
 
index 124aa39243529178149313bbc03b7744e55fe7c7..c586faae6e886dd32f5c398085c401904fe3fa41 100644 (file)
@@ -24,7 +24,9 @@ register_diagnostics! {
     E0258, // import conflicts with existing submodule
     E0259, // an extern crate has already been imported into this module
     E0260, // name conflicts with an external crate that has been imported into this module
-    E0317 // user-defined types or type parameters cannot shadow the primitive types
+    E0317, // user-defined types or type parameters cannot shadow the primitive types
+    E0364, // item is private
+    E0365  // item is private
 }
 
 __build_diagnostic_array! { DIAGNOSTICS }
index 333d32d76b6d5fc85c8f63ea874eec047c5a46e5..045320e4fa42565e3782bd682d76757d03631911 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rustc_resolve"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
 
 #![feature(alloc)]
 #![feature(collections)]
-#![feature(core)]
-#![feature(int_uint)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(std_misc)]
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
@@ -36,19 +35,16 @@ use self::PatternBindingMode::*;
 use self::Namespace::*;
 use self::NamespaceResult::*;
 use self::NameDefinition::*;
-use self::ImportDirectiveSubclass::*;
 use self::ResolveResult::*;
 use self::FallbackSuggestion::*;
 use self::TypeParameters::*;
 use self::RibKind::*;
-use self::MethodSort::*;
 use self::UseLexicalScopeFlag::*;
 use self::ModulePrefixResult::*;
 use self::NameSearchType::*;
 use self::BareIdentifierPatternResolution::*;
 use self::ParentLink::*;
 use self::ModuleKind::*;
-use self::TraitReferenceType::*;
 use self::FallbackChecks::*;
 
 use rustc::session::Session;
@@ -66,31 +62,28 @@ use rustc::util::lev_distance::lev_distance;
 
 use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
 use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField};
-use syntax::ast::{ExprClosure, ExprLoop, ExprWhile, ExprMethodCall};
-use syntax::ast::{ExprPath, ExprQPath, ExprStruct, FnDecl};
+use syntax::ast::{ExprLoop, ExprWhile, ExprMethodCall};
+use syntax::ast::{ExprPath, ExprStruct, FnDecl};
 use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
 use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
-use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
+use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
 use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
-use syntax::ast::{Local, MethodImplItem, Mod, Name, NodeId};
+use syntax::ast::{Local, MethodImplItem, Name, NodeId};
 use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
-use syntax::ast::{PatRange, PatStruct, Path};
-use syntax::ast::{PolyTraitRef, PrimTy, SelfExplicit};
-use syntax::ast::{RegionTyParamBound, StructField};
-use syntax::ast::{TraitRef, TraitTyParamBound};
-use syntax::ast::{Ty, TyBool, TyChar, TyF32};
-use syntax::ast::{TyF64, TyFloat, TyIs, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum};
-use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyQPath};
+use syntax::ast::{PatRange, PatStruct, Path, PrimTy};
+use syntax::ast::{TraitRef, Ty, TyBool, TyChar, TyF32};
+use syntax::ast::{TyF64, TyFloat, TyIs, TyI8, TyI16, TyI32, TyI64, TyInt};
+use syntax::ast::{TyPath, TyPtr};
 use syntax::ast::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint};
-use syntax::ast::{TypeImplItem};
+use syntax::ast::TypeImplItem;
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{PostExpansionMethod, local_def, walk_pat};
+use syntax::ast_util::{local_def, walk_pat};
 use syntax::attr::AttrMetaMethods;
 use syntax::ext::mtwt;
 use syntax::parse::token::{self, special_names, special_idents};
-use syntax::codemap::{Span, Pos};
-use syntax::owned_slice::OwnedSlice;
+use syntax::ptr::P;
+use syntax::codemap::{self, Span, Pos};
 use syntax::visit::{self, Visitor};
 
 use std::collections::{HashMap, HashSet};
@@ -101,6 +94,10 @@ use std::mem::replace;
 use std::rc::{Rc, Weak};
 use std::usize;
 
+use resolve_imports::{Target, ImportDirective, ImportResolution};
+use resolve_imports::Shadowable;
+
+
 // NB: This module needs to be declared first so diagnostics are
 // registered before they are used.
 pub mod diagnostics;
@@ -108,8 +105,9 @@ pub mod diagnostics;
 mod check_unused;
 mod record_exports;
 mod build_reduced_graph;
+mod resolve_imports;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct BindingInfo {
     span: Span,
     binding_mode: BindingMode,
@@ -118,14 +116,14 @@ struct BindingInfo {
 // Map from the name in a pattern to its binding mode.
 type BindingMap = HashMap<Name, BindingInfo>;
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 enum PatternBindingMode {
     RefutableMode,
     LocalIrrefutableMode,
     ArgumentIrrefutableMode,
 }
 
-#[derive(Copy, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 enum Namespace {
     TypeNS,
     ValueNS
@@ -164,9 +162,12 @@ impl NamespaceResult {
 }
 
 enum NameDefinition {
-    NoNameDefinition,           //< The name was unbound.
-    ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
-    ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
+    // The name was unbound.
+    NoNameDefinition,
+    // The name identifies an immediate child.
+    ChildNameDefinition(Def, LastPrivate),
+    // The name identifies an import.
+    ImportNameDefinition(Def, LastPrivate),
 }
 
 impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
@@ -188,13 +189,72 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
     fn visit_ty(&mut self, ty: &Ty) {
         self.resolve_type(ty);
     }
-}
+    fn visit_generics(&mut self, generics: &Generics) {
+        self.resolve_generics(generics);
+    }
+    fn visit_poly_trait_ref(&mut self,
+                            tref: &ast::PolyTraitRef,
+                            m: &ast::TraitBoundModifier) {
+        match self.resolve_trait_reference(tref.trait_ref.ref_id, &tref.trait_ref.path, 0) {
+            Ok(def) => self.record_def(tref.trait_ref.ref_id, def),
+            Err(_) => { /* error already reported */ }
+        }
+        visit::walk_poly_trait_ref(self, tref, m);
+    }
+    fn visit_variant(&mut self, variant: &ast::Variant, generics: &Generics) {
+        if let Some(ref dis_expr) = variant.node.disr_expr {
+            // resolve the discriminator expr as a constant
+            self.with_constant_rib(|this| {
+                this.visit_expr(&**dis_expr);
+            });
+        }
 
-/// Contains data for specific types of import directives.
-#[derive(Copy,Debug)]
-enum ImportDirectiveSubclass {
-    SingleImport(Name /* target */, Name /* source */),
-    GlobImport
+        // `visit::walk_variant` without the discriminant expression.
+        match variant.node.kind {
+            ast::TupleVariantKind(ref variant_arguments) => {
+                for variant_argument in variant_arguments.iter() {
+                    self.visit_ty(&*variant_argument.ty);
+                }
+            }
+            ast::StructVariantKind(ref struct_definition) => {
+                self.visit_struct_def(&**struct_definition,
+                                      variant.node.name,
+                                      generics,
+                                      variant.node.id);
+            }
+        }
+    }
+    fn visit_foreign_item(&mut self, foreign_item: &ast::ForeignItem) {
+        let type_parameters = match foreign_item.node {
+            ForeignItemFn(_, ref generics) => {
+                HasTypeParameters(generics, FnSpace, ItemRibKind)
+            }
+            ForeignItemStatic(..) => NoTypeParameters
+        };
+        self.with_type_parameter_rib(type_parameters, |this| {
+            visit::walk_foreign_item(this, foreign_item);
+        });
+    }
+    fn visit_fn(&mut self,
+                function_kind: visit::FnKind<'v>,
+                declaration: &'v FnDecl,
+                block: &'v Block,
+                _: Span,
+                node_id: NodeId) {
+        let rib_kind = match function_kind {
+            visit::FkItemFn(_, generics, _, _) => {
+                self.visit_generics(generics);
+                ItemRibKind
+            }
+            visit::FkMethod(_, sig) => {
+                self.visit_generics(&sig.generics);
+                self.visit_explicit_self(&sig.explicit_self);
+                MethodRibKind
+            }
+            visit::FkFnBlock(..) => ClosureRibKind(node_id)
+        };
+        self.resolve_function(rib_kind, declaration, block);
+    }
 }
 
 type ErrorMessage = Option<(Span, String)>;
@@ -220,7 +280,7 @@ enum FallbackSuggestion {
     TraitMethod(String),
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum TypeParameters<'a> {
     NoTypeParameters,
     HasTypeParameters(
@@ -231,16 +291,13 @@ enum TypeParameters<'a> {
         // were declared on (type, fn, etc)
         ParamSpace,
 
-        // ID of the enclosing item.
-        NodeId,
-
         // The kind of the rib used for type parameters.
         RibKind)
 }
 
 // The rib kind controls the translation of local
 // definitions (`DefLocal`) to upvars (`DefUpvar`).
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 enum RibKind {
     // No translation needs to be applied.
     NormalRibKind,
@@ -253,8 +310,7 @@ enum RibKind {
     // methods. Allow references to ty params that impl or trait
     // binds. Disallow any other upvars (including other ty params that are
     // upvars).
-              // parent;   method itself
-    MethodRibKind(NodeId, MethodSort),
+    MethodRibKind,
 
     // We passed through an item scope. Disallow upvars.
     ItemRibKind,
@@ -263,14 +319,7 @@ enum RibKind {
     ConstantItemRibKind
 }
 
-// Methods can be required or provided. RequiredMethod methods only occur in traits.
-#[derive(Copy, Debug)]
-enum MethodSort {
-    RequiredMethod,
-    ProvidedMethod(NodeId)
-}
-
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum UseLexicalScopeFlag {
     DontUseLexicalScope,
     UseLexicalScope
@@ -278,10 +327,10 @@ enum UseLexicalScopeFlag {
 
 enum ModulePrefixResult {
     NoPrefixFound,
-    PrefixFound(Rc<Module>, uint)
+    PrefixFound(Rc<Module>, usize)
 }
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 enum NameSearchType {
     /// We're doing a name search in order to resolve a `use` directive.
     ImportSearch,
@@ -291,7 +340,7 @@ enum NameSearchType {
     PathSearch,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum BareIdentifierPatternResolution {
     FoundStructOrEnumVariant(Def, LastPrivate),
     FoundConst(Def, LastPrivate),
@@ -314,144 +363,6 @@ impl Rib {
     }
 }
 
-/// Whether an import can be shadowed by another import.
-#[derive(Debug,PartialEq,Clone,Copy)]
-enum Shadowable {
-    Always,
-    Never
-}
-
-/// One import directive.
-#[derive(Debug)]
-struct ImportDirective {
-    module_path: Vec<Name>,
-    subclass: ImportDirectiveSubclass,
-    span: Span,
-    id: NodeId,
-    is_public: bool, // see note in ImportResolution about how to use this
-    shadowable: Shadowable,
-}
-
-impl ImportDirective {
-    fn new(module_path: Vec<Name> ,
-           subclass: ImportDirectiveSubclass,
-           span: Span,
-           id: NodeId,
-           is_public: bool,
-           shadowable: Shadowable)
-           -> ImportDirective {
-        ImportDirective {
-            module_path: module_path,
-            subclass: subclass,
-            span: span,
-            id: id,
-            is_public: is_public,
-            shadowable: shadowable,
-        }
-    }
-}
-
-/// The item that an import resolves to.
-#[derive(Clone,Debug)]
-struct Target {
-    target_module: Rc<Module>,
-    bindings: Rc<NameBindings>,
-    shadowable: Shadowable,
-}
-
-impl Target {
-    fn new(target_module: Rc<Module>,
-           bindings: Rc<NameBindings>,
-           shadowable: Shadowable)
-           -> Target {
-        Target {
-            target_module: target_module,
-            bindings: bindings,
-            shadowable: shadowable,
-        }
-    }
-}
-
-/// An ImportResolution represents a particular `use` directive.
-#[derive(Debug)]
-struct ImportResolution {
-    /// Whether this resolution came from a `use` or a `pub use`. Note that this
-    /// should *not* be used whenever resolution is being performed, this is
-    /// only looked at for glob imports statements currently. Privacy testing
-    /// occurs during a later phase of compilation.
-    is_public: bool,
-
-    // The number of outstanding references to this name. When this reaches
-    // zero, outside modules can count on the targets being correct. Before
-    // then, all bets are off; future imports could override this name.
-    outstanding_references: uint,
-
-    /// The value that this `use` directive names, if there is one.
-    value_target: Option<Target>,
-    /// The source node of the `use` directive leading to the value target
-    /// being non-none
-    value_id: NodeId,
-
-    /// The type that this `use` directive names, if there is one.
-    type_target: Option<Target>,
-    /// The source node of the `use` directive leading to the type target
-    /// being non-none
-    type_id: NodeId,
-}
-
-impl ImportResolution {
-    fn new(id: NodeId, is_public: bool) -> ImportResolution {
-        ImportResolution {
-            type_id: id,
-            value_id: id,
-            outstanding_references: 0,
-            value_target: None,
-            type_target: None,
-            is_public: is_public,
-        }
-    }
-
-    fn target_for_namespace(&self, namespace: Namespace)
-                                -> Option<Target> {
-        match namespace {
-            TypeNS  => self.type_target.clone(),
-            ValueNS => self.value_target.clone(),
-        }
-    }
-
-    fn id(&self, namespace: Namespace) -> NodeId {
-        match namespace {
-            TypeNS  => self.type_id,
-            ValueNS => self.value_id,
-        }
-    }
-
-    fn shadowable(&self, namespace: Namespace) -> Shadowable {
-        let target = self.target_for_namespace(namespace);
-        if target.is_none() {
-            return Shadowable::Always;
-        }
-
-        target.unwrap().shadowable
-    }
-
-    fn set_target_and_id(&mut self,
-                         namespace: Namespace,
-                         target: Option<Target>,
-                         id: NodeId) {
-        match namespace {
-            TypeNS  => {
-                self.type_target = target;
-                self.type_id = id;
-            }
-            ValueNS => {
-                self.value_target = target;
-                self.value_id = id;
-            }
-        }
-    }
-}
-
 /// The link from a module up to its nearest parent node.
 #[derive(Clone,Debug)]
 enum ParentLink {
@@ -461,18 +372,17 @@ enum ParentLink {
 }
 
 /// The type of module this is.
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 enum ModuleKind {
     NormalModuleKind,
     TraitModuleKind,
-    ImplModuleKind,
     EnumModuleKind,
     TypeModuleKind,
     AnonymousModuleKind,
 }
 
 /// One node in the tree of modules.
-struct Module {
+pub struct Module {
     parent_link: ParentLink,
     def_id: Cell<Option<DefId>>,
     kind: Cell<ModuleKind>,
@@ -505,10 +415,10 @@ struct Module {
     import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
 
     // The number of unresolved globs that this module exports.
-    glob_count: Cell<uint>,
+    glob_count: Cell<usize>,
 
     // The index of the import we're resolving.
-    resolved_import_count: Cell<uint>,
+    resolved_import_count: Cell<usize>,
 
     // Whether this module is populated. If not populated, any attempt to
     // access the children must be preceded with a
@@ -581,21 +491,11 @@ struct ValueNsDef {
 // Records the definitions (at most one for each namespace) that a name is
 // bound to.
 #[derive(Debug)]
-struct NameBindings {
+pub struct NameBindings {
     type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
     value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
 }
 
-/// Ways in which a trait can be referenced
-#[derive(Copy)]
-enum TraitReferenceType {
-    TraitImplementation,             // impl SomeTrait for T { ... }
-    TraitDerivation,                 // trait T : SomeTrait { ... }
-    TraitBoundingTypeParameter,      // fn f<T:SomeTrait>() { ... }
-    TraitObject,                     // Box<for<'a> SomeTrait>
-    TraitQPath,                      // <T as SomeTrait>::
-}
-
 impl NameBindings {
     fn new() -> NameBindings {
         NameBindings {
@@ -814,6 +714,19 @@ impl NameBindings {
             None
         }
     }
+
+    fn is_public(&self, namespace: Namespace) -> bool {
+        match namespace {
+            TypeNS  => {
+                let type_def = self.type_def.borrow();
+                type_def.as_ref().unwrap().modifiers.contains(PUBLIC)
+            }
+            ValueNS => {
+                let value_def = self.value_def.borrow();
+                value_def.as_ref().unwrap().modifiers.contains(PUBLIC)
+            }
+        }
+    }
 }
 
 /// Interns the names of the primitive types.
@@ -831,15 +744,13 @@ impl PrimitiveTypeTable {
         table.intern("char",    TyChar);
         table.intern("f32",     TyFloat(TyF32));
         table.intern("f64",     TyFloat(TyF64));
-        table.intern("int",     TyInt(TyIs(true)));
-        table.intern("isize",   TyInt(TyIs(false)));
+        table.intern("isize",   TyInt(TyIs));
         table.intern("i8",      TyInt(TyI8));
         table.intern("i16",     TyInt(TyI16));
         table.intern("i32",     TyInt(TyI32));
         table.intern("i64",     TyInt(TyI64));
         table.intern("str",     TyStr);
-        table.intern("uint",    TyUint(TyUs(true)));
-        table.intern("usize",   TyUint(TyUs(false)));
+        table.intern("usize",   TyUint(TyUs));
         table.intern("u8",      TyUint(TyU8));
         table.intern("u16",     TyUint(TyU16));
         table.intern("u32",     TyUint(TyU32));
@@ -854,19 +765,19 @@ impl PrimitiveTypeTable {
 }
 
 /// The main resolver class.
-struct Resolver<'a, 'tcx:'a> {
+pub struct Resolver<'a, 'tcx:'a> {
     session: &'a Session,
 
     ast_map: &'a ast_map::Map<'tcx>,
 
     graph_root: NameBindings,
 
-    trait_item_map: FnvHashMap<(Name, DefId), TraitItemKind>,
+    trait_item_map: FnvHashMap<(Name, DefId), DefId>,
 
     structs: FnvHashMap<DefId, Vec<Name>>,
 
     // The number of imports that are currently unresolved.
-    unresolved_imports: uint,
+    unresolved_imports: usize,
 
     // The module that represents the current item scope.
     current_module: Rc<Module>,
@@ -887,11 +798,6 @@ struct Resolver<'a, 'tcx:'a> {
     // The current self type if inside an impl (used for better errors).
     current_self_type: Option<Ty>,
 
-    // The ident for the keyword "self".
-    self_name: Name,
-    // The ident for the non-keyword "Self".
-    type_self_name: Name,
-
     // The idents for the primitive types.
     primitive_type_table: PrimitiveTypeTable,
 
@@ -901,7 +807,6 @@ struct Resolver<'a, 'tcx:'a> {
     export_map: ExportMap,
     trait_map: TraitMap,
     external_exports: ExternalExports,
-    last_private: LastPrivateMap,
 
     // Whether or not to print error messages. Can be set to true
     // when getting additional info for error message suggestions,
@@ -923,7 +828,6 @@ enum FallbackChecks {
     OnlyTraitAndStatics
 }
 
-
 impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn new(session: &'a Session,
            ast_map: &'a ast_map::Map<'tcx>,
@@ -963,9 +867,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             current_trait_ref: None,
             current_self_type: None,
 
-            self_name: special_names::self_,
-            type_self_name: special_names::type_self,
-
             primitive_type_table: PrimitiveTypeTable::new(),
 
             def_map: RefCell::new(NodeMap()),
@@ -976,7 +877,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             used_imports: HashSet::new(),
             used_crates: HashSet::new(),
             external_exports: DefIdSet(),
-            last_private: NodeMap(),
 
             emit_errors: true,
             make_glob_map: make_glob_map == MakeGlobMap::Yes,
@@ -984,158 +884,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
-    // Import resolution
-    //
-    // This is a fixed-point algorithm. We resolve imports until our efforts
-    // are stymied by an unresolved import; then we bail out of the current
-    // module and continue. We terminate successfully once no more imports
-    // remain or unsuccessfully when no forward progress in resolving imports
-    // is made.
-
-    /// Resolves all imports for the crate. This method performs the fixed-
-    /// point iteration.
-    fn resolve_imports(&mut self) {
-        let mut i = 0;
-        let mut prev_unresolved_imports = 0;
-        loop {
-            debug!("(resolving imports) iteration {}, {} imports left",
-                   i, self.unresolved_imports);
-
-            let module_root = self.graph_root.get_module();
-            self.resolve_imports_for_module_subtree(module_root.clone());
-
-            if self.unresolved_imports == 0 {
-                debug!("(resolving imports) success");
-                break;
-            }
-
-            if self.unresolved_imports == prev_unresolved_imports {
-                self.report_unresolved_imports(module_root);
-                break;
-            }
-
-            i += 1;
-            prev_unresolved_imports = self.unresolved_imports;
-        }
-    }
-
-    /// Attempts to resolve imports for the given module and all of its
-    /// submodules.
-    fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
-        debug!("(resolving imports for module subtree) resolving {}",
-               self.module_to_string(&*module_));
-        let orig_module = replace(&mut self.current_module, module_.clone());
-        self.resolve_imports_for_module(module_.clone());
-        self.current_module = orig_module;
-
-        build_reduced_graph::populate_module_if_necessary(self, &module_);
-        for (_, child_node) in &*module_.children.borrow() {
-            match child_node.get_module_if_available() {
-                None => {
-                    // Nothing to do.
-                }
-                Some(child_module) => {
-                    self.resolve_imports_for_module_subtree(child_module);
-                }
-            }
-        }
-
-        for (_, child_module) in &*module_.anonymous_children.borrow() {
-            self.resolve_imports_for_module_subtree(child_module.clone());
-        }
-    }
-
-    /// Attempts to resolve imports for the given module only.
-    fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
-        if module.all_imports_resolved() {
-            debug!("(resolving imports for module) all imports resolved for \
-                   {}",
-                   self.module_to_string(&*module));
-            return;
-        }
-
-        let imports = module.imports.borrow();
-        let import_count = imports.len();
-        while module.resolved_import_count.get() < import_count {
-            let import_index = module.resolved_import_count.get();
-            let import_directive = &(*imports)[import_index];
-            match self.resolve_import_for_module(module.clone(),
-                                                 import_directive) {
-                Failed(err) => {
-                    let (span, help) = match err {
-                        Some((span, msg)) => (span, format!(". {}", msg)),
-                        None => (import_directive.span, String::new())
-                    };
-                    let msg = format!("unresolved import `{}`{}",
-                                      self.import_path_to_string(
-                                          &import_directive.module_path[],
-                                          import_directive.subclass),
-                                      help);
-                    self.resolve_error(span, &msg[..]);
-                }
-                Indeterminate => break, // Bail out. We'll come around next time.
-                Success(()) => () // Good. Continue.
-            }
-
-            module.resolved_import_count
-                  .set(module.resolved_import_count.get() + 1);
-        }
-    }
-
-    fn names_to_string(&self, names: &[Name]) -> String {
-        let mut first = true;
-        let mut result = String::new();
-        for name in names {
-            if first {
-                first = false
-            } else {
-                result.push_str("::")
-            }
-            result.push_str(&token::get_name(*name));
-        };
-        result
-    }
-
-    fn path_names_to_string(&self, path: &Path) -> String {
-        let names: Vec<ast::Name> = path.segments
-                                        .iter()
-                                        .map(|seg| seg.identifier.name)
-                                        .collect();
-        self.names_to_string(&names[..])
-    }
-
-    fn import_directive_subclass_to_string(&mut self,
-                                        subclass: ImportDirectiveSubclass)
-                                        -> String {
-        match subclass {
-            SingleImport(_, source) => {
-                token::get_name(source).to_string()
-            }
-            GlobImport => "*".to_string()
-        }
-    }
-
-    fn import_path_to_string(&mut self,
-                          names: &[Name],
-                          subclass: ImportDirectiveSubclass)
-                          -> String {
-        if names.is_empty() {
-            self.import_directive_subclass_to_string(subclass)
-        } else {
-            (format!("{}::{}",
-                     self.names_to_string(names),
-                     self.import_directive_subclass_to_string(
-                         subclass))).to_string()
-        }
-    }
-
     #[inline]
     fn record_import_use(&mut self, import_id: NodeId, name: Name) {
         if !self.make_glob_map {
             return;
         }
         if self.glob_map.contains_key(&import_id) {
-            self.glob_map[import_id].insert(name);
+            self.glob_map.get_mut(&import_id).unwrap().insert(name);
             return;
         }
 
@@ -1152,102 +907,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
-    /// Attempts to resolve the given import. The return value indicates
-    /// failure if we're certain the name does not exist, indeterminate if we
-    /// don't know whether the name exists at the moment due to other
-    /// currently-unresolved imports, or success if we know the name exists.
-    /// If successful, the resolved bindings are written into the module.
-    fn resolve_import_for_module(&mut self,
-                                 module_: Rc<Module>,
-                                 import_directive: &ImportDirective)
-                                 -> ResolveResult<()> {
-        let mut resolution_result = Failed(None);
-        let module_path = &import_directive.module_path;
-
-        debug!("(resolving import for module) resolving import `{}::...` in `{}`",
-               self.names_to_string(&module_path[..]),
-               self.module_to_string(&*module_));
-
-        // First, resolve the module path for the directive, if necessary.
-        let container = if module_path.len() == 0 {
-            // Use the crate root.
-            Some((self.graph_root.get_module(), LastMod(AllPublic)))
-        } else {
-            match self.resolve_module_path(module_.clone(),
-                                           &module_path[..],
-                                           DontUseLexicalScope,
-                                           import_directive.span,
-                                           ImportSearch) {
-                Failed(err) => {
-                    resolution_result = Failed(err);
-                    None
-                },
-                Indeterminate => {
-                    resolution_result = Indeterminate;
-                    None
-                }
-                Success(container) => Some(container),
-            }
-        };
-
-        match container {
-            None => {}
-            Some((containing_module, lp)) => {
-                // We found the module that the target is contained
-                // within. Attempt to resolve the import within it.
-
-                match import_directive.subclass {
-                    SingleImport(target, source) => {
-                        resolution_result =
-                            self.resolve_single_import(&*module_,
-                                                       containing_module,
-                                                       target,
-                                                       source,
-                                                       import_directive,
-                                                       lp);
-                    }
-                    GlobImport => {
-                        resolution_result =
-                            self.resolve_glob_import(&*module_,
-                                                     containing_module,
-                                                     import_directive,
-                                                     lp);
-                    }
-                }
-            }
-        }
-
-        // Decrement the count of unresolved imports.
-        match resolution_result {
-            Success(()) => {
-                assert!(self.unresolved_imports >= 1);
-                self.unresolved_imports -= 1;
-            }
-            _ => {
-                // Nothing to do here; just return the error.
-            }
-        }
-
-        // Decrement the count of unresolved globs if necessary. But only if
-        // the resolution result is indeterminate -- otherwise we'll stop
-        // processing imports here. (See the loop in
-        // resolve_imports_for_module.)
-
-        if !resolution_result.indeterminate() {
-            match import_directive.subclass {
-                GlobImport => {
-                    assert!(module_.glob_count.get() >= 1);
-                    module_.glob_count.set(module_.glob_count.get() - 1);
-                }
-                SingleImport(..) => {
-                    // Ignore.
-                }
-            }
-        }
-
-        return resolution_result;
-    }
-
     fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
         NameBindings {
             type_def: RefCell::new(Some(TypeNsDef {
@@ -1260,626 +919,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
-    fn resolve_single_import(&mut self,
-                             module_: &Module,
-                             containing_module: Rc<Module>,
-                             target: Name,
-                             source: Name,
-                             directive: &ImportDirective,
-                             lp: LastPrivate)
-                                 -> ResolveResult<()> {
-        debug!("(resolving single import) resolving `{}` = `{}::{}` from \
-                `{}` id {}, last private {:?}",
-               token::get_name(target),
-               self.module_to_string(&*containing_module),
-               token::get_name(source),
-               self.module_to_string(module_),
-               directive.id,
-               lp);
-
-        let lp = match lp {
-            LastMod(lp) => lp,
-            LastImport {..} => {
-                self.session
-                    .span_bug(directive.span,
-                              "not expecting Import here, must be LastMod")
-            }
-        };
-
-        // We need to resolve both namespaces for this to succeed.
-        //
-
-        let mut value_result = UnknownResult;
-        let mut type_result = UnknownResult;
-
-        // Search for direct children of the containing module.
-        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
-
-        match containing_module.children.borrow().get(&source) {
-            None => {
-                // Continue.
-            }
-            Some(ref child_name_bindings) => {
-                if child_name_bindings.defined_in_namespace(ValueNS) {
-                    debug!("(resolving single import) found value binding");
-                    value_result = BoundResult(containing_module.clone(),
-                                               (*child_name_bindings).clone());
-                }
-                if child_name_bindings.defined_in_namespace(TypeNS) {
-                    debug!("(resolving single import) found type binding");
-                    type_result = BoundResult(containing_module.clone(),
-                                              (*child_name_bindings).clone());
-                }
-            }
-        }
-
-        // Unless we managed to find a result in both namespaces (unlikely),
-        // search imports as well.
-        let mut value_used_reexport = false;
-        let mut type_used_reexport = false;
-        match (value_result.clone(), type_result.clone()) {
-            (BoundResult(..), BoundResult(..)) => {} // Continue.
-            _ => {
-                // If there is an unresolved glob at this point in the
-                // containing module, bail out. We don't know enough to be
-                // able to resolve this import.
-
-                if containing_module.glob_count.get() > 0 {
-                    debug!("(resolving single import) unresolved glob; \
-                            bailing out");
-                    return Indeterminate;
-                }
-
-                // Now search the exported imports within the containing module.
-                match containing_module.import_resolutions.borrow().get(&source) {
-                    None => {
-                        debug!("(resolving single import) no import");
-                        // The containing module definitely doesn't have an
-                        // exported import with the name in question. We can
-                        // therefore accurately report that the names are
-                        // unbound.
-
-                        if value_result.is_unknown() {
-                            value_result = UnboundResult;
-                        }
-                        if type_result.is_unknown() {
-                            type_result = UnboundResult;
-                        }
-                    }
-                    Some(import_resolution)
-                            if import_resolution.outstanding_references == 0 => {
-
-                        fn get_binding(this: &mut Resolver,
-                                       import_resolution: &ImportResolution,
-                                       namespace: Namespace,
-                                       source: &Name)
-                                    -> NamespaceResult {
-
-                            // Import resolutions must be declared with "pub"
-                            // in order to be exported.
-                            if !import_resolution.is_public {
-                                return UnboundResult;
-                            }
-
-                            match import_resolution.
-                                    target_for_namespace(namespace) {
-                                None => {
-                                    return UnboundResult;
-                                }
-                                Some(Target {
-                                    target_module,
-                                    bindings,
-                                    shadowable: _
-                                }) => {
-                                    debug!("(resolving single import) found \
-                                            import in ns {:?}", namespace);
-                                    let id = import_resolution.id(namespace);
-                                    // track used imports and extern crates as well
-                                    this.used_imports.insert((id, namespace));
-                                    this.record_import_use(id, *source);
-                                    match target_module.def_id.get() {
-                                        Some(DefId{krate: kid, ..}) => {
-                                            this.used_crates.insert(kid);
-                                        },
-                                        _ => {}
-                                    }
-                                    return BoundResult(target_module, bindings);
-                                }
-                            }
-                        }
-
-                        // The name is an import which has been fully
-                        // resolved. We can, therefore, just follow it.
-                        if value_result.is_unknown() {
-                            value_result = get_binding(self,
-                                                       import_resolution,
-                                                       ValueNS,
-                                                       &source);
-                            value_used_reexport = import_resolution.is_public;
-                        }
-                        if type_result.is_unknown() {
-                            type_result = get_binding(self,
-                                                      import_resolution,
-                                                      TypeNS,
-                                                      &source);
-                            type_used_reexport = import_resolution.is_public;
-                        }
-
-                    }
-                    Some(_) => {
-                        // If containing_module is the same module whose import we are resolving
-                        // and there it has an unresolved import with the same name as `source`,
-                        // then the user is actually trying to import an item that is declared
-                        // in the same scope
-                        //
-                        // e.g
-                        // use self::submodule;
-                        // pub mod submodule;
-                        //
-                        // In this case we continue as if we resolved the import and let the
-                        // check_for_conflicts_between_imports_and_items call below handle
-                        // the conflict
-                        match (module_.def_id.get(),  containing_module.def_id.get()) {
-                            (Some(id1), Some(id2)) if id1 == id2  => {
-                                if value_result.is_unknown() {
-                                    value_result = UnboundResult;
-                                }
-                                if type_result.is_unknown() {
-                                    type_result = UnboundResult;
-                                }
-                            }
-                            _ =>  {
-                                // The import is unresolved. Bail out.
-                                debug!("(resolving single import) unresolved import; \
-                                        bailing out");
-                                return Indeterminate;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        // If we didn't find a result in the type namespace, search the
-        // external modules.
-        let mut value_used_public = false;
-        let mut type_used_public = false;
-        match type_result {
-            BoundResult(..) => {}
-            _ => {
-                match containing_module.external_module_children.borrow_mut()
-                                       .get(&source).cloned() {
-                    None => {} // Continue.
-                    Some(module) => {
-                        debug!("(resolving single import) found external \
-                                module");
-                        // track the module as used.
-                        match module.def_id.get() {
-                            Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
-                            _ => {}
-                        }
-                        let name_bindings =
-                            Rc::new(Resolver::create_name_bindings_from_module(
-                                module));
-                        type_result = BoundResult(containing_module.clone(),
-                                                  name_bindings);
-                        type_used_public = true;
-                    }
-                }
-            }
-        }
-
-        // We've successfully resolved the import. Write the results in.
-        let mut import_resolutions = module_.import_resolutions.borrow_mut();
-        let import_resolution = &mut (*import_resolutions)[target];
-        {
-            let mut check_and_write_import = |namespace, result: &_, used_public: &mut bool| {
-                let namespace_name = match namespace {
-                    TypeNS => "type",
-                    ValueNS => "value",
-                };
-
-                match *result {
-                    BoundResult(ref target_module, ref name_bindings) => {
-                        debug!("(resolving single import) found {:?} target: {:?}",
-                               namespace_name,
-                               name_bindings.def_for_namespace(namespace));
-                        self.check_for_conflicting_import(
-                            &import_resolution.target_for_namespace(namespace),
-                            directive.span,
-                            target,
-                            namespace);
-
-                        self.check_that_import_is_importable(
-                            &**name_bindings,
-                            directive.span,
-                            target,
-                            namespace);
-
-                        let target = Some(Target::new(target_module.clone(),
-                                                      name_bindings.clone(),
-                                                      directive.shadowable));
-                        import_resolution.set_target_and_id(namespace, target, directive.id);
-                        import_resolution.is_public = directive.is_public;
-                        *used_public = name_bindings.defined_in_public_namespace(namespace);
-                    }
-                    UnboundResult => { /* Continue. */ }
-                    UnknownResult => {
-                        panic!("{:?} result should be known at this point", namespace_name);
-                    }
-                }
-            };
-            check_and_write_import(ValueNS, &value_result, &mut value_used_public);
-            check_and_write_import(TypeNS, &type_result, &mut type_used_public);
-        }
-
-        self.check_for_conflicts_between_imports_and_items(
-            module_,
-            import_resolution,
-            directive.span,
-            target);
-
-        if value_result.is_unbound() && type_result.is_unbound() {
-            let msg = format!("There is no `{}` in `{}`",
-                              token::get_name(source),
-                              self.module_to_string(&*containing_module));
-            return Failed(Some((directive.span, msg)));
-        }
-        let value_used_public = value_used_reexport || value_used_public;
-        let type_used_public = type_used_reexport || type_used_public;
-
-        assert!(import_resolution.outstanding_references >= 1);
-        import_resolution.outstanding_references -= 1;
-
-        // record what this import resolves to for later uses in documentation,
-        // this may resolve to either a value or a type, but for documentation
-        // purposes it's good enough to just favor one over the other.
-        let value_private = match import_resolution.value_target {
-            Some(ref target) => {
-                let def = target.bindings.def_for_namespace(ValueNS).unwrap();
-                self.def_map.borrow_mut().insert(directive.id, def);
-                let did = def.def_id();
-                if value_used_public {Some(lp)} else {Some(DependsOn(did))}
-            },
-            // AllPublic here and below is a dummy value, it should never be used because
-            // _exists is false.
-            None => None,
-        };
-        let type_private = match import_resolution.type_target {
-            Some(ref target) => {
-                let def = target.bindings.def_for_namespace(TypeNS).unwrap();
-                self.def_map.borrow_mut().insert(directive.id, def);
-                let did = def.def_id();
-                if type_used_public {Some(lp)} else {Some(DependsOn(did))}
-            },
-            None => None,
-        };
-
-        self.last_private.insert(directive.id, LastImport{value_priv: value_private,
-                                                          value_used: Used,
-                                                          type_priv: type_private,
-                                                          type_used: Used});
-
-        debug!("(resolving single import) successfully resolved import");
-        return Success(());
-    }
-
-    // Resolves a glob import. Note that this function cannot fail; it either
-    // succeeds or bails out (as importing * from an empty module or a module
-    // that exports nothing is valid). containing_module is the module we are
-    // actually importing, i.e., `foo` in `use foo::*`.
-    fn resolve_glob_import(&mut self,
-                           module_: &Module,
-                           containing_module: Rc<Module>,
-                           import_directive: &ImportDirective,
-                           lp: LastPrivate)
-                           -> ResolveResult<()> {
-        let id = import_directive.id;
-        let is_public = import_directive.is_public;
-
-        // This function works in a highly imperative manner; it eagerly adds
-        // everything it can to the list of import resolutions of the module
-        // node.
-        debug!("(resolving glob import) resolving glob import {}", id);
-
-        // We must bail out if the node has unresolved imports of any kind
-        // (including globs).
-        if !(*containing_module).all_imports_resolved() {
-            debug!("(resolving glob import) target module has unresolved \
-                    imports; bailing out");
-            return Indeterminate;
-        }
-
-        assert_eq!(containing_module.glob_count.get(), 0);
-
-        // Add all resolved imports from the containing module.
-        let import_resolutions = containing_module.import_resolutions.borrow();
-        for (ident, target_import_resolution) in &*import_resolutions {
-            debug!("(resolving glob import) writing module resolution \
-                    {} into `{}`",
-                   token::get_name(*ident),
-                   self.module_to_string(module_));
-
-            if !target_import_resolution.is_public {
-                debug!("(resolving glob import) nevermind, just kidding");
-                continue
-            }
-
-            // Here we merge two import resolutions.
-            let mut import_resolutions = module_.import_resolutions.borrow_mut();
-            match import_resolutions.get_mut(ident) {
-                Some(dest_import_resolution) => {
-                    // Merge the two import resolutions at a finer-grained
-                    // level.
-
-                    match target_import_resolution.value_target {
-                        None => {
-                            // Continue.
-                        }
-                        Some(ref value_target) => {
-                            self.check_for_conflicting_import(&dest_import_resolution.value_target,
-                                                              import_directive.span,
-                                                              *ident,
-                                                              ValueNS);
-                            dest_import_resolution.value_target = Some(value_target.clone());
-                        }
-                    }
-                    match target_import_resolution.type_target {
-                        None => {
-                            // Continue.
-                        }
-                        Some(ref type_target) => {
-                            self.check_for_conflicting_import(&dest_import_resolution.type_target,
-                                                              import_directive.span,
-                                                              *ident,
-                                                              TypeNS);
-                            dest_import_resolution.type_target = Some(type_target.clone());
-                        }
-                    }
-                    dest_import_resolution.is_public = is_public;
-                    continue;
-                }
-                None => {}
-            }
-
-            // Simple: just copy the old import resolution.
-            let mut new_import_resolution = ImportResolution::new(id, is_public);
-            new_import_resolution.value_target =
-                target_import_resolution.value_target.clone();
-            new_import_resolution.type_target =
-                target_import_resolution.type_target.clone();
-
-            import_resolutions.insert(*ident, new_import_resolution);
-        }
-
-        // Add all children from the containing module.
-        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
-
-        for (&name, name_bindings) in &*containing_module.children.borrow() {
-            self.merge_import_resolution(module_,
-                                         containing_module.clone(),
-                                         import_directive,
-                                         name,
-                                         name_bindings.clone());
-
-        }
-
-        // Add external module children from the containing module.
-        for (&name, module) in &*containing_module.external_module_children.borrow() {
-            let name_bindings =
-                Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
-            self.merge_import_resolution(module_,
-                                         containing_module.clone(),
-                                         import_directive,
-                                         name,
-                                         name_bindings);
-        }
-
-        // Record the destination of this import
-        match containing_module.def_id.get() {
-            Some(did) => {
-                self.def_map.borrow_mut().insert(id, DefMod(did));
-                self.last_private.insert(id, lp);
-            }
-            None => {}
-        }
-
-        debug!("(resolving glob import) successfully resolved import");
-        return Success(());
-    }
-
-    fn merge_import_resolution(&mut self,
-                               module_: &Module,
-                               containing_module: Rc<Module>,
-                               import_directive: &ImportDirective,
-                               name: Name,
-                               name_bindings: Rc<NameBindings>) {
-        let id = import_directive.id;
-        let is_public = import_directive.is_public;
-
-        let mut import_resolutions = module_.import_resolutions.borrow_mut();
-        let dest_import_resolution = import_resolutions.entry(name).get().unwrap_or_else(
-            |vacant_entry| {
-                // Create a new import resolution from this child.
-                vacant_entry.insert(ImportResolution::new(id, is_public))
-            });
-
-        debug!("(resolving glob import) writing resolution `{}` in `{}` \
-               to `{}`",
-               &token::get_name(name),
-               self.module_to_string(&*containing_module),
-               self.module_to_string(module_));
-
-        // Merge the child item into the import resolution.
-        {
-            let mut merge_child_item = |namespace| {
-                if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
-                    let namespace_name = match namespace {
-                        TypeNS => "type",
-                        ValueNS => "value",
-                    };
-                    debug!("(resolving glob import) ... for {} target", namespace_name);
-                    if dest_import_resolution.shadowable(namespace) == Shadowable::Never {
-                        let msg = format!("a {} named `{}` has already been imported \
-                                           in this module",
-                                          namespace_name,
-                                          &token::get_name(name));
-                        span_err!(self.session, import_directive.span, E0251, "{}", msg);
-                    } else {
-                        let target = Target::new(containing_module.clone(),
-                                                 name_bindings.clone(),
-                                                 import_directive.shadowable);
-                        dest_import_resolution.set_target_and_id(namespace,
-                                                                 Some(target),
-                                                                 id);
-                    }
-                }
-            };
-            merge_child_item(ValueNS);
-            merge_child_item(TypeNS);
-        }
-
-        dest_import_resolution.is_public = is_public;
-
-        self.check_for_conflicts_between_imports_and_items(
-            module_,
-            dest_import_resolution,
-            import_directive.span,
-            name);
-    }
-
-    /// Checks that imported names and items don't have the same name.
-    fn check_for_conflicting_import(&mut self,
-                                    target: &Option<Target>,
-                                    import_span: Span,
-                                    name: Name,
-                                    namespace: Namespace) {
-        debug!("check_for_conflicting_import: {}; target exists: {}",
-               &token::get_name(name),
-               target.is_some());
-
-        match *target {
-            Some(ref target) if target.shadowable != Shadowable::Always => {
-                let msg = format!("a {} named `{}` has already been imported \
-                                   in this module",
-                                  match namespace {
-                                    TypeNS => "type",
-                                    ValueNS => "value",
-                                  },
-                                  &token::get_name(name));
-                span_err!(self.session, import_span, E0252, "{}", &msg[..]);
-            }
-            Some(_) | None => {}
-        }
-    }
-
-    /// Checks that an import is actually importable
-    fn check_that_import_is_importable(&mut self,
-                                       name_bindings: &NameBindings,
-                                       import_span: Span,
-                                       name: Name,
-                                       namespace: Namespace) {
-        if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
-            let msg = format!("`{}` is not directly importable",
-                              token::get_name(name));
-            span_err!(self.session, import_span, E0253, "{}", &msg[..]);
-        }
-    }
-
-    /// Checks that imported names and items don't have the same name.
-    fn check_for_conflicts_between_imports_and_items(&mut self,
-                                                     module: &Module,
-                                                     import_resolution:
-                                                     &ImportResolution,
-                                                     import_span: Span,
-                                                     name: Name) {
-        // First, check for conflicts between imports and `extern crate`s.
-        if module.external_module_children
-                 .borrow()
-                 .contains_key(&name) {
-            match import_resolution.type_target {
-                Some(ref target) if target.shadowable != Shadowable::Always => {
-                    let msg = format!("import `{0}` conflicts with imported \
-                                       crate in this module \
-                                       (maybe you meant `use {0}::*`?)",
-                                      &token::get_name(name));
-                    span_err!(self.session, import_span, E0254, "{}", &msg[..]);
-                }
-                Some(_) | None => {}
-            }
-        }
-
-        // Check for item conflicts.
-        let children = module.children.borrow();
-        let name_bindings = match children.get(&name) {
-            None => {
-                // There can't be any conflicts.
-                return
-            }
-            Some(ref name_bindings) => (*name_bindings).clone(),
-        };
-
-        match import_resolution.value_target {
-            Some(ref target) if target.shadowable != Shadowable::Always => {
-                if let Some(ref value) = *name_bindings.value_def.borrow() {
-                    let msg = format!("import `{}` conflicts with value \
-                                       in this module",
-                                      &token::get_name(name));
-                    span_err!(self.session, import_span, E0255, "{}", &msg[..]);
-                    if let Some(span) = value.value_span {
-                        self.session.span_note(span,
-                                               "conflicting value here");
-                    }
-                }
-            }
-            Some(_) | None => {}
-        }
-
-        match import_resolution.type_target {
-            Some(ref target) if target.shadowable != Shadowable::Always => {
-                if let Some(ref ty) = *name_bindings.type_def.borrow() {
-                    match ty.module_def {
-                        None => {
-                            let msg = format!("import `{}` conflicts with type in \
-                                               this module",
-                                              &token::get_name(name));
-                            span_err!(self.session, import_span, E0256, "{}", &msg[..]);
-                            if let Some(span) = ty.type_span {
-                                self.session.span_note(span,
-                                                       "note conflicting type here")
-                            }
-                        }
-                        Some(ref module_def) => {
-                            match module_def.kind.get() {
-                                ImplModuleKind => {
-                                    if let Some(span) = ty.type_span {
-                                        let msg = format!("inherent implementations \
-                                                           are only allowed on types \
-                                                           defined in the current module");
-                                        span_err!(self.session, span, E0257, "{}", &msg[..]);
-                                        self.session.span_note(import_span,
-                                                               "import from other module here")
-                                    }
-                                }
-                                _ => {
-                                    let msg = format!("import `{}` conflicts with existing \
-                                                       submodule",
-                                                      &token::get_name(name));
-                                    span_err!(self.session, import_span, E0258, "{}", &msg[..]);
-                                    if let Some(span) = ty.type_span {
-                                        self.session.span_note(span,
-                                                               "note conflicting module here")
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            Some(_) | None => {}
-        }
-    }
-
     /// Checks that the names of external crates don't collide with other
     /// external crates.
     fn check_for_conflicts_between_external_crates(&self,
@@ -1912,7 +951,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn resolve_module_path_from_root(&mut self,
                                      module_: Rc<Module>,
                                      module_path: &[Name],
-                                     index: uint,
+                                     index: usize,
                                      span: Span,
                                      name_search_type: NameSearchType,
                                      lp: LastPrivate)
@@ -1947,7 +986,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                               false) {
                 Failed(None) => {
                     let segment_name = token::get_name(name);
-                    let module_name = self.module_to_string(&*search_module);
+                    let module_name = module_to_string(&*search_module);
                     let mut span = span;
                     let msg = if "???" == &module_name[..] {
                         span.hi = span.lo + Pos::from_usize(segment_name.len());
@@ -1955,10 +994,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         match search_parent_externals(name,
                                                      &self.current_module) {
                             Some(module) => {
-                                let path_str = self.names_to_string(module_path);
-                                let target_mod_str = self.module_to_string(&*module);
+                                let path_str = names_to_string(module_path);
+                                let target_mod_str = module_to_string(&*module);
                                 let current_mod_str =
-                                    self.module_to_string(&*self.current_module);
+                                    module_to_string(&*self.current_module);
 
                                 let prefix = if target_mod_str == current_mod_str {
                                     "self::".to_string()
@@ -2049,8 +1088,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         assert!(module_path_len > 0);
 
         debug!("(resolving module path for import) processing `{}` rooted at `{}`",
-               self.names_to_string(module_path),
-               self.module_to_string(&*module_));
+               names_to_string(module_path),
+               module_to_string(&*module_));
 
         // Resolve the module prefix, if any.
         let module_prefix_result = self.resolve_module_prefix(module_.clone(),
@@ -2061,7 +1100,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let last_private;
         match module_prefix_result {
             Failed(None) => {
-                let mpath = self.names_to_string(module_path);
+                let mpath = names_to_string(module_path);
                 let mpath = &mpath[..];
                 match mpath.rfind(':') {
                     Some(idx) => {
@@ -2144,7 +1183,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 namespace {:?} in `{}`",
                token::get_name(name),
                namespace,
-               self.module_to_string(&*module_));
+               module_to_string(&*module_));
 
         // The current module node is handled specially. First, check for
         // its immediate children.
@@ -2226,7 +1265,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             return Failed(None);
                         }
                         TraitModuleKind |
-                        ImplModuleKind |
                         EnumModuleKind |
                         TypeModuleKind |
                         AnonymousModuleKind => {
@@ -2247,7 +1285,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                               true) {
                 Failed(Some((span, msg))) =>
                     self.resolve_error(span, &format!("failed to resolve. {}",
-                                                     msg)[]),
+                                                     msg)),
                 Failed(None) => (), // Continue up the search chain.
                 Indeterminate => {
                     // We couldn't see through the higher scope because of an
@@ -2324,7 +1362,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     match new_module.kind.get() {
                         NormalModuleKind => return Some(new_module),
                         TraitModuleKind |
-                        ImplModuleKind |
                         EnumModuleKind |
                         TypeModuleKind |
                         AnonymousModuleKind => module_ = new_module,
@@ -2341,7 +1378,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         match module_.kind.get() {
             NormalModuleKind => return module_,
             TraitModuleKind |
-            ImplModuleKind |
             EnumModuleKind |
             TypeModuleKind |
             AnonymousModuleKind => {
@@ -2384,7 +1420,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 break
             }
             debug!("(resolving module prefix) resolving `super` at {}",
-                   self.module_to_string(&*containing_module));
+                   module_to_string(&*containing_module));
             match self.get_nearest_normal_module_parent(containing_module) {
                 None => return Failed(None),
                 Some(new_module) => {
@@ -2395,7 +1431,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
 
         debug!("(resolving module prefix) finished resolving prefix at {}",
-               self.module_to_string(&*containing_module));
+               module_to_string(&*containing_module));
 
         return Success(PrefixFound(containing_module, i));
     }
@@ -2415,7 +1451,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                               -> ResolveResult<(Target, bool)> {
         debug!("(resolving name in module) resolving `{}` in `{}`",
                &token::get_name(name),
-               self.module_to_string(&*module_));
+               module_to_string(&*module_));
 
         // First, check the direct children of the module.
         build_reduced_graph::populate_module_if_necessary(self, &module_);
@@ -2569,7 +1605,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     None => {
                         debug!("!!! (with scope) didn't find `{}` in `{}`",
                                token::get_name(name),
-                               self.module_to_string(&*orig_module));
+                               module_to_string(&*orig_module));
                     }
                     Some(name_bindings) => {
                         match (*name_bindings).get_module_if_available() {
@@ -2577,7 +1613,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 debug!("!!! (with scope) didn't find module \
                                         for `{}` in `{}`",
                                        token::get_name(name),
-                                       self.module_to_string(&*orig_module));
+                                       module_to_string(&*orig_module));
                             }
                             Some(module_) => {
                                 self.current_module = module_;
@@ -2600,14 +1636,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 def_like: DefLike,
                 span: Span)
                 -> Option<DefLike> {
-        match def_like {
-            DlDef(d @ DefUpvar(..)) => {
+        let mut def = match def_like {
+            DlDef(def) => def,
+            _ => return Some(def_like)
+        };
+        match def {
+            DefUpvar(..) => {
                 self.session.span_bug(span,
-                    &format!("unexpected {:?} in bindings", d)[])
+                    &format!("unexpected {:?} in bindings", def))
             }
-            DlDef(d @ DefLocal(_)) => {
-                let node_id = d.def_id().node;
-                let mut def = d;
+            DefLocal(node_id) => {
                 for rib in ribs {
                     match rib.kind {
                         NormalRibKind => {
@@ -2631,39 +1669,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             }.push(Freevar { def: prev_def, span: span });
                             seen.insert(node_id);
                         }
-                        MethodRibKind(item_id, _) => {
-                            // If the def is a ty param, and came from the parent
-                            // item, it's ok
-                            match def {
-                                DefTyParam(_, _, did, _) if {
-                                    self.def_map.borrow().get(&did.node).cloned()
-                                        == Some(DefTyParamBinder(item_id))
-                                } => {} // ok
-                                DefSelfTy(did) if did == item_id => {} // ok
-                                _ => {
-                                    // This was an attempt to access an upvar inside a
-                                    // named function item. This is not allowed, so we
-                                    // report an error.
-
-                                    self.resolve_error(
-                                        span,
-                                        "can't capture dynamic environment in a fn item; \
-                                        use the || { ... } closure form instead");
-
-                                    return None;
-                                }
-                            }
-                        }
-                        ItemRibKind => {
+                        ItemRibKind | MethodRibKind => {
                             // This was an attempt to access an upvar inside a
                             // named function item. This is not allowed, so we
                             // report an error.
 
-                            self.resolve_error(
-                                span,
+                            self.resolve_error(span,
                                 "can't capture dynamic environment in a fn item; \
-                                use the || { ... } closure form instead");
-
+                                 use the || { ... } closure form instead");
                             return None;
                         }
                         ConstantItemRibKind => {
@@ -2671,42 +1684,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             self.resolve_error(span,
                                                "attempt to use a non-constant \
                                                 value in a constant");
-
+                            return None;
                         }
                     }
                 }
-                Some(DlDef(def))
             }
-            DlDef(def @ DefTyParam(..)) |
-            DlDef(def @ DefSelfTy(..)) => {
+            DefTyParam(..) | DefSelfTy(_) => {
                 for rib in ribs {
                     match rib.kind {
-                        NormalRibKind | ClosureRibKind(..) => {
+                        NormalRibKind | MethodRibKind | ClosureRibKind(..) => {
                             // Nothing to do. Continue.
                         }
-                        MethodRibKind(item_id, _) => {
-                            // If the def is a ty param, and came from the parent
-                            // item, it's ok
-                            match def {
-                                DefTyParam(_, _, did, _) if {
-                                    self.def_map.borrow().get(&did.node).cloned()
-                                        == Some(DefTyParamBinder(item_id))
-                                } => {} // ok
-                                DefSelfTy(did) if did == item_id => {} // ok
-
-                                _ => {
-                                    // This was an attempt to use a type parameter outside
-                                    // its scope.
-
-                                    self.resolve_error(span,
-                                                        "can't use type parameters from \
-                                                        outer function; try using a local \
-                                                        type parameter instead");
-
-                                    return None;
-                                }
-                            }
-                        }
                         ItemRibKind => {
                             // This was an attempt to use a type parameter outside
                             // its scope.
@@ -2715,7 +1703,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                                "can't use type parameters from \
                                                 outer function; try using a local \
                                                 type parameter instead");
-
                             return None;
                         }
                         ConstantItemRibKind => {
@@ -2723,14 +1710,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             self.resolve_error(span,
                                                "cannot use an outer type \
                                                 parameter in this context");
-
+                            return None;
                         }
                     }
                 }
-                Some(DlDef(def))
             }
-            _ => Some(def_like)
+            _ => {}
         }
+        Some(DlDef(def))
     }
 
     /// Searches the current set of local scopes and
@@ -2743,13 +1730,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         // FIXME #4950: Try caching?
 
         for (i, rib) in ribs.iter().enumerate().rev() {
-            match rib.bindings.get(&name).cloned() {
-                Some(def_like) => {
-                    return self.upvarify(&ribs[i + 1..], def_like, span);
-                }
-                None => {
-                    // Continue.
-                }
+            if let Some(def_like) = rib.bindings.get(&name).cloned() {
+                return self.upvarify(&ribs[i + 1..], def_like, span);
             }
         }
 
@@ -2797,56 +1779,32 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                token::get_name(name));
 
         match item.node {
-
-            // enum item: resolve all the variants' discrs,
-            // then resolve the ty params
-            ItemEnum(ref enum_def, ref generics) => {
+            ItemEnum(_, ref generics) |
+            ItemTy(_, ref generics) |
+            ItemStruct(_, ref generics) => {
                 self.check_if_primitive_type_name(name, item.span);
 
-                for variant in &(*enum_def).variants {
-                    if let Some(ref dis_expr) = variant.node.disr_expr {
-                        // resolve the discriminator expr
-                        // as a constant
-                        self.with_constant_rib(|this| {
-                            this.resolve_expr(&**dis_expr);
-                        });
-                    }
-                }
-
-                // n.b. the discr expr gets visited twice.
-                // but maybe it's okay since the first time will signal an
-                // error if there is one? -- tjc
                 self.with_type_parameter_rib(HasTypeParameters(generics,
                                                                TypeSpace,
-                                                               item.id,
                                                                ItemRibKind),
-                                             |this| {
-                    this.resolve_type_parameters(&generics.ty_params);
-                    this.resolve_where_clause(&generics.where_clause);
-                    visit::walk_item(this, item);
-                });
+                                             |this| visit::walk_item(this, item));
             }
-
-            ItemTy(_, ref generics) => {
-                self.check_if_primitive_type_name(name, item.span);
-
+            ItemFn(_, _, _, ref generics, _) => {
                 self.with_type_parameter_rib(HasTypeParameters(generics,
-                                                               TypeSpace,
-                                                               item.id,
+                                                               FnSpace,
                                                                ItemRibKind),
-                                             |this| {
-                    this.resolve_type_parameters(&generics.ty_params);
-                    visit::walk_item(this, item);
-                });
+                                             |this| visit::walk_item(this, item));
             }
 
+            ItemDefaultImpl(_, ref trait_ref) => {
+                self.with_optional_trait_ref(Some(trait_ref), |_| {});
+            }
             ItemImpl(_, _,
                      ref generics,
                      ref implemented_traits,
                      ref self_type,
                      ref impl_items) => {
-                self.resolve_implementation(item.id,
-                                            generics,
+                self.resolve_implementation(generics,
                                             implemented_traits,
                                             &**self_type,
                                             &impl_items[..]);
@@ -2859,123 +1817,51 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 let mut self_type_rib = Rib::new(ItemRibKind);
 
                 // plain insert (no renaming, types are not currently hygienic....)
-                let name = self.type_self_name;
+                let name = special_names::type_self;
                 self_type_rib.bindings.insert(name, DlDef(DefSelfTy(item.id)));
                 self.type_ribs.push(self_type_rib);
 
                 // Create a new rib for the trait-wide type parameters.
                 self.with_type_parameter_rib(HasTypeParameters(generics,
                                                                TypeSpace,
-                                                               item.id,
                                                                NormalRibKind),
                                              |this| {
-                    this.resolve_type_parameters(&generics.ty_params);
-                    this.resolve_where_clause(&generics.where_clause);
+                    this.visit_generics(generics);
+                    visit::walk_ty_param_bounds_helper(this, bounds);
 
-                    this.resolve_type_parameter_bounds(item.id, bounds,
-                                                       TraitDerivation);
-
-                    for trait_item in &(*trait_items) {
+                    for trait_item in trait_items {
                         // Create a new rib for the trait_item-specific type
                         // parameters.
                         //
                         // FIXME #4951: Do we need a node ID here?
 
-                        match *trait_item {
-                          ast::RequiredMethod(ref ty_m) => {
-                            this.with_type_parameter_rib
-                                (HasTypeParameters(&ty_m.generics,
-                                                   FnSpace,
-                                                   item.id,
-                                        MethodRibKind(item.id, RequiredMethod)),
-                                 |this| {
-
-                                // Resolve the method-specific type
-                                // parameters.
-                                this.resolve_type_parameters(
-                                    &ty_m.generics.ty_params);
-                                this.resolve_where_clause(&ty_m.generics
-                                                               .where_clause);
-
-                                for argument in &ty_m.decl.inputs {
-                                    this.resolve_type(&*argument.ty);
-                                }
-
-                                if let SelfExplicit(ref typ, _) = ty_m.explicit_self.node {
-                                    this.resolve_type(&**typ)
-                                }
-
-                                if let ast::Return(ref ret_ty) = ty_m.decl.output {
-                                    this.resolve_type(&**ret_ty);
-                                }
-                            });
-                          }
-                          ast::ProvidedMethod(ref m) => {
-                              this.resolve_method(MethodRibKind(item.id,
-                                                                ProvidedMethod(m.id)),
-                                                  &**m)
-                          }
-                          ast::TypeTraitItem(ref data) => {
-                              this.resolve_type_parameter(&data.ty_param);
-                              visit::walk_trait_item(this, trait_item);
-                          }
-                        }
+                        let type_parameters = match trait_item.node {
+                            ast::MethodTraitItem(ref sig, _) => {
+                                HasTypeParameters(&sig.generics,
+                                                  FnSpace,
+                                                  MethodRibKind)
+                            }
+                            ast::TypeTraitItem(..) => {
+                                this.check_if_primitive_type_name(trait_item.ident.name,
+                                                                  trait_item.span);
+                                NoTypeParameters
+                            }
+                        };
+                        this.with_type_parameter_rib(type_parameters, |this| {
+                            visit::walk_trait_item(this, trait_item)
+                        });
                     }
                 });
 
                 self.type_ribs.pop();
             }
 
-            ItemStruct(ref struct_def, ref generics) => {
-                self.check_if_primitive_type_name(name, item.span);
-
-                self.resolve_struct(item.id,
-                                    generics,
-                                    &struct_def.fields[]);
-            }
-
-            ItemMod(ref module_) => {
+            ItemMod(_) | ItemForeignMod(_) => {
                 self.with_scope(Some(name), |this| {
-                    this.resolve_module(module_, item.span, name,
-                                        item.id);
-                });
-            }
-
-            ItemForeignMod(ref foreign_module) => {
-                self.with_scope(Some(name), |this| {
-                    for foreign_item in &foreign_module.items {
-                        match foreign_item.node {
-                            ForeignItemFn(_, ref generics) => {
-                                this.with_type_parameter_rib(
-                                    HasTypeParameters(
-                                        generics, FnSpace, foreign_item.id,
-                                        ItemRibKind),
-                                    |this| {
-                                        this.resolve_type_parameters(&generics.ty_params);
-                                        this.resolve_where_clause(&generics.where_clause);
-                                        visit::walk_foreign_item(this, &**foreign_item)
-                                    });
-                            }
-                            ForeignItemStatic(..) => {
-                                visit::walk_foreign_item(this,
-                                                         &**foreign_item);
-                            }
-                        }
-                    }
+                    visit::walk_item(this, item);
                 });
             }
 
-            ItemFn(ref fn_decl, _, _, ref generics, ref block) => {
-                self.resolve_function(ItemRibKind,
-                                      Some(&**fn_decl),
-                                      HasTypeParameters
-                                        (generics,
-                                         FnSpace,
-                                         item.id,
-                                         ItemRibKind),
-                                      &**block);
-            }
-
             ItemConst(..) | ItemStatic(..) => {
                 self.with_constant_rib(|this| {
                     visit::walk_item(this, item);
@@ -2985,8 +1871,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             ItemUse(ref view_path) => {
                 // check for imports shadowing primitive types
                 if let ast::ViewPathSimple(ident, _) = view_path.node {
-                    match self.def_map.borrow().get(&item.id) {
-                        Some(&DefTy(..)) | Some(&DefStruct(..)) | Some(&DefTrait(..)) | None => {
+                    match self.def_map.borrow().get(&item.id).map(|d| d.full_def()) {
+                        Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
                             self.check_if_primitive_type_name(ident.name, item.span);
                         }
                         _ => {}
@@ -3004,35 +1890,29 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         F: FnOnce(&mut Resolver),
     {
         match type_parameters {
-            HasTypeParameters(generics, space, node_id, rib_kind) => {
+            HasTypeParameters(generics, space, rib_kind) => {
                 let mut function_type_rib = Rib::new(rib_kind);
                 let mut seen_bindings = HashSet::new();
                 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
                     let name = type_parameter.ident.name;
-                    debug!("with_type_parameter_rib: {} {}", node_id,
-                           type_parameter.id);
+                    debug!("with_type_parameter_rib: {}", type_parameter.id);
 
                     if seen_bindings.contains(&name) {
                         self.resolve_error(type_parameter.span,
                                            &format!("the name `{}` is already \
-                                                    used for a type \
-                                                    parameter in this type \
-                                                    parameter list",
-                                                   token::get_name(
-                                                       name))[])
+                                                     used for a type \
+                                                     parameter in this type \
+                                                     parameter list",
+                                                    token::get_name(name)))
                     }
                     seen_bindings.insert(name);
 
-                    let def_like = DlDef(DefTyParam(space,
-                                                    index as u32,
-                                                    local_def(type_parameter.id),
-                                                    name));
-                    // Associate this type parameter with
-                    // the item that bound it
-                    self.record_def(type_parameter.id,
-                                    (DefTyParamBinder(node_id), LastMod(AllPublic)));
                     // plain insert (no renaming)
-                    function_type_rib.bindings.insert(name, def_like);
+                    function_type_rib.bindings.insert(name,
+                        DlDef(DefTyParam(space,
+                                         index as u32,
+                                         local_def(type_parameter.id),
+                                         name)));
                 }
                 self.type_ribs.push(function_type_rib);
             }
@@ -3054,240 +1934,100 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         F: FnOnce(&mut Resolver),
     {
         self.label_ribs.push(Rib::new(NormalRibKind));
-        f(self);
-        self.label_ribs.pop();
-    }
-
-    fn with_constant_rib<F>(&mut self, f: F) where
-        F: FnOnce(&mut Resolver),
-    {
-        self.value_ribs.push(Rib::new(ConstantItemRibKind));
-        self.type_ribs.push(Rib::new(ConstantItemRibKind));
-        f(self);
-        self.type_ribs.pop();
-        self.value_ribs.pop();
-    }
-
-    fn resolve_function(&mut self,
-                        rib_kind: RibKind,
-                        optional_declaration: Option<&FnDecl>,
-                        type_parameters: TypeParameters,
-                        block: &Block) {
-        // Create a value rib for the function.
-        let function_value_rib = Rib::new(rib_kind);
-        self.value_ribs.push(function_value_rib);
-
-        // Create a label rib for the function.
-        let function_label_rib = Rib::new(rib_kind);
-        self.label_ribs.push(function_label_rib);
-
-        // If this function has type parameters, add them now.
-        self.with_type_parameter_rib(type_parameters, |this| {
-            // Resolve the type parameters.
-            match type_parameters {
-                NoTypeParameters => {
-                    // Continue.
-                }
-                HasTypeParameters(ref generics, _, _, _) => {
-                    this.resolve_type_parameters(&generics.ty_params);
-                    this.resolve_where_clause(&generics.where_clause);
-                }
-            }
-
-            // Add each argument to the rib.
-            match optional_declaration {
-                None => {
-                    // Nothing to do.
-                }
-                Some(declaration) => {
-                    let mut bindings_list = HashMap::new();
-                    for argument in &declaration.inputs {
-                        this.resolve_pattern(&*argument.pat,
-                                             ArgumentIrrefutableMode,
-                                             &mut bindings_list);
-
-                        this.resolve_type(&*argument.ty);
-
-                        debug!("(resolving function) recorded argument");
-                    }
-
-                    if let ast::Return(ref ret_ty) = declaration.output {
-                        this.resolve_type(&**ret_ty);
-                    }
-                }
-            }
-
-            // Resolve the function body.
-            this.resolve_block(&*block);
-
-            debug!("(resolving function) leaving function");
-        });
-
+        f(self);
         self.label_ribs.pop();
-        self.value_ribs.pop();
     }
 
-    fn resolve_type_parameters(&mut self,
-                               type_parameters: &OwnedSlice<TyParam>) {
-        for type_parameter in &**type_parameters {
-            self.resolve_type_parameter(type_parameter);
-        }
+    fn with_constant_rib<F>(&mut self, f: F) where
+        F: FnOnce(&mut Resolver),
+    {
+        self.value_ribs.push(Rib::new(ConstantItemRibKind));
+        self.type_ribs.push(Rib::new(ConstantItemRibKind));
+        f(self);
+        self.type_ribs.pop();
+        self.value_ribs.pop();
     }
 
-    fn resolve_type_parameter(&mut self,
-                              type_parameter: &TyParam) {
-        self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span);
-        for bound in &*type_parameter.bounds {
-            self.resolve_type_parameter_bound(type_parameter.id, bound,
-                                              TraitBoundingTypeParameter);
-        }
-        match type_parameter.default {
-            Some(ref ty) => self.resolve_type(&**ty),
-            None => {}
-        }
-    }
+    fn resolve_function(&mut self,
+                        rib_kind: RibKind,
+                        declaration: &FnDecl,
+                        block: &Block) {
+        // Create a value rib for the function.
+        self.value_ribs.push(Rib::new(rib_kind));
 
-    fn resolve_type_parameter_bounds(&mut self,
-                                     id: NodeId,
-                                     type_parameter_bounds: &OwnedSlice<TyParamBound>,
-                                     reference_type: TraitReferenceType) {
-        for type_parameter_bound in &**type_parameter_bounds {
-            self.resolve_type_parameter_bound(id, type_parameter_bound,
-                                              reference_type);
-        }
-    }
+        // Create a label rib for the function.
+        self.label_ribs.push(Rib::new(rib_kind));
 
-    fn resolve_type_parameter_bound(&mut self,
-                                    id: NodeId,
-                                    type_parameter_bound: &TyParamBound,
-                                    reference_type: TraitReferenceType) {
-        match *type_parameter_bound {
-            TraitTyParamBound(ref tref, _) => {
-                self.resolve_poly_trait_reference(id, tref, reference_type)
-            }
-            RegionTyParamBound(..) => {}
+        // Add each argument to the rib.
+        let mut bindings_list = HashMap::new();
+        for argument in &declaration.inputs {
+            self.resolve_pattern(&*argument.pat,
+                                 ArgumentIrrefutableMode,
+                                 &mut bindings_list);
+
+            self.visit_ty(&*argument.ty);
+
+            debug!("(resolving function) recorded argument");
         }
-    }
+        visit::walk_fn_ret_ty(self, &declaration.output);
+
+        // Resolve the function body.
+        self.visit_block(&*block);
 
-    fn resolve_poly_trait_reference(&mut self,
-                                    id: NodeId,
-                                    poly_trait_reference: &PolyTraitRef,
-                                    reference_type: TraitReferenceType) {
-        self.resolve_trait_reference(id, &poly_trait_reference.trait_ref, reference_type)
+        debug!("(resolving function) leaving function");
+
+        self.label_ribs.pop();
+        self.value_ribs.pop();
     }
 
     fn resolve_trait_reference(&mut self,
                                id: NodeId,
-                               trait_reference: &TraitRef,
-                               reference_type: TraitReferenceType) {
-        match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
-            None => {
-                let path_str = self.path_names_to_string(&trait_reference.path);
-                let usage_str = match reference_type {
-                    TraitBoundingTypeParameter => "bound type parameter with",
-                    TraitImplementation        => "implement",
-                    TraitDerivation            => "derive",
-                    TraitObject                => "reference",
-                    TraitQPath                 => "extract an associated item from",
-                };
+                               trait_path: &Path,
+                               path_depth: usize)
+                               -> Result<PathResolution, ()> {
+        if let Some(path_res) = self.resolve_path(id, trait_path, path_depth, TypeNS, true) {
+            if let DefTrait(_) = path_res.base_def {
+                debug!("(resolving trait) found trait def: {:?}", path_res);
+                Ok(path_res)
+            } else {
+                self.resolve_error(trait_path.span,
+                    &format!("`{}` is not a trait",
+                             path_names_to_string(trait_path, path_depth)));
 
-                let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
-                self.resolve_error(trait_reference.path.span, &msg[..]);
-            }
-            Some(def) => {
-                match def {
-                    (DefTrait(_), _) => {
-                        debug!("(resolving trait) found trait def: {:?}", def);
-                        self.record_def(trait_reference.ref_id, def);
-                    }
-                    (def, _) => {
-                        self.resolve_error(trait_reference.path.span,
-                                           &format!("`{}` is not a trait",
-                                                   self.path_names_to_string(
-                                                       &trait_reference.path))[]);
-
-                        // If it's a typedef, give a note
-                        if let DefTy(..) = def {
-                            self.session.span_note(
-                                trait_reference.path.span,
-                                &format!("`type` aliases cannot be used for traits")
-                                []);
-                        }
-                    }
+                // If it's a typedef, give a note
+                if let DefTy(..) = path_res.base_def {
+                    self.session.span_note(trait_path.span,
+                                           "`type` aliases cannot be used for traits");
                 }
+                Err(())
             }
+        } else {
+            let msg = format!("use of undeclared trait name `{}`",
+                              path_names_to_string(trait_path, path_depth));
+            self.resolve_error(trait_path.span, &msg);
+            Err(())
         }
     }
 
-    fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
-        for predicate in &where_clause.predicates {
+    fn resolve_generics(&mut self, generics: &Generics) {
+        for type_parameter in &*generics.ty_params {
+            self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span);
+        }
+        for predicate in &generics.where_clause.predicates {
             match predicate {
-                &ast::WherePredicate::BoundPredicate(ref bound_pred) => {
-                    self.resolve_type(&*bound_pred.bounded_ty);
-
-                    for bound in &*bound_pred.bounds {
-                        self.resolve_type_parameter_bound(bound_pred.bounded_ty.id, bound,
-                                                          TraitBoundingTypeParameter);
-                    }
-                }
+                &ast::WherePredicate::BoundPredicate(_) |
                 &ast::WherePredicate::RegionPredicate(_) => {}
                 &ast::WherePredicate::EqPredicate(ref eq_pred) => {
-                    match self.resolve_path(eq_pred.id, &eq_pred.path, TypeNS, true) {
-                        Some((def @ DefTyParam(..), last_private)) => {
-                            self.record_def(eq_pred.id, (def, last_private));
-                        }
-                        _ => {
-                            self.resolve_error(eq_pred.path.span,
-                                               "undeclared associated type");
-                        }
+                    let path_res = self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true);
+                    if let Some(PathResolution { base_def: DefTyParam(..), .. }) = path_res {
+                        self.record_def(eq_pred.id, path_res.unwrap());
+                    } else {
+                        self.resolve_error(eq_pred.path.span, "undeclared associated type");
                     }
-
-                    self.resolve_type(&*eq_pred.ty);
                 }
             }
         }
-    }
-
-    fn resolve_struct(&mut self,
-                      id: NodeId,
-                      generics: &Generics,
-                      fields: &[StructField]) {
-        // If applicable, create a rib for the type parameters.
-        self.with_type_parameter_rib(HasTypeParameters(generics,
-                                                       TypeSpace,
-                                                       id,
-                                                       ItemRibKind),
-                                     |this| {
-            // Resolve the type parameters.
-            this.resolve_type_parameters(&generics.ty_params);
-            this.resolve_where_clause(&generics.where_clause);
-
-            // Resolve fields.
-            for field in fields {
-                this.resolve_type(&*field.node.ty);
-            }
-        });
-    }
-
-    // Does this really need to take a RibKind or is it always going
-    // to be NormalRibKind?
-    fn resolve_method(&mut self,
-                      rib_kind: RibKind,
-                      method: &ast::Method) {
-        let method_generics = method.pe_generics();
-        let type_parameters = HasTypeParameters(method_generics,
-                                                FnSpace,
-                                                method.id,
-                                                rib_kind);
-
-        if let SelfExplicit(ref typ, _) = method.pe_explicit_self().node {
-            self.resolve_type(&**typ);
-        }
-
-        self.resolve_function(rib_kind,
-                              Some(method.pe_fn_decl()),
-                              type_parameters,
-                              method.pe_body());
+        visit::walk_generics(self, generics);
     }
 
     fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
@@ -3300,25 +2040,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         result
     }
 
-    fn with_optional_trait_ref<T, F>(&mut self, id: NodeId,
-                                     opt_trait_ref: &Option<TraitRef>,
-                                     f: F) -> T where
-        F: FnOnce(&mut Resolver) -> T,
+    fn with_optional_trait_ref<T, F>(&mut self,
+                                     opt_trait_ref: Option<&TraitRef>,
+                                     f: F)
+                                     -> T
+        where F: FnOnce(&mut Resolver) -> T,
     {
-        let new_val = match *opt_trait_ref {
-            Some(ref trait_ref) => {
-                self.resolve_trait_reference(id, trait_ref, TraitImplementation);
-
-                match self.def_map.borrow().get(&trait_ref.ref_id) {
-                    Some(def) => {
-                        let did = def.def_id();
-                        Some((did, trait_ref.clone()))
-                    }
-                    None => None
+        let mut new_val = None;
+        if let Some(trait_ref) = opt_trait_ref {
+            match self.resolve_trait_reference(trait_ref.ref_id, &trait_ref.path, 0) {
+                Ok(path_res) => {
+                    self.record_def(trait_ref.ref_id, path_res);
+                    new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
                 }
+                Err(_) => { /* error was already reported */ }
             }
-            None => None
-        };
+            visit::walk_trait_ref(self, trait_ref);
+        }
         let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
         let result = f(self);
         self.current_trait_ref = original_trait_ref;
@@ -3326,121 +2064,82 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     }
 
     fn resolve_implementation(&mut self,
-                              id: NodeId,
                               generics: &Generics,
                               opt_trait_reference: &Option<TraitRef>,
                               self_type: &Ty,
-                              impl_items: &[ImplItem]) {
+                              impl_items: &[P<ImplItem>]) {
         // If applicable, create a rib for the type parameters.
         self.with_type_parameter_rib(HasTypeParameters(generics,
                                                        TypeSpace,
-                                                       id,
-                                                       NormalRibKind),
+                                                       ItemRibKind),
                                      |this| {
             // Resolve the type parameters.
-            this.resolve_type_parameters(&generics.ty_params);
-            this.resolve_where_clause(&generics.where_clause);
+            this.visit_generics(generics);
 
             // Resolve the trait reference, if necessary.
-            this.with_optional_trait_ref(id, opt_trait_reference, |this| {
+            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this| {
                 // Resolve the self type.
-                this.resolve_type(self_type);
+                this.visit_ty(self_type);
 
                 this.with_current_self_type(self_type, |this| {
                     for impl_item in impl_items {
-                        match *impl_item {
-                            MethodImplItem(ref method) => {
+                        match impl_item.node {
+                            MethodImplItem(ref sig, _) => {
                                 // If this is a trait impl, ensure the method
                                 // exists in trait
-                                this.check_trait_item(method.pe_ident().name,
-                                                      method.span);
+                                this.check_trait_item(impl_item.ident.name,
+                                                      impl_item.span);
 
                                 // We also need a new scope for the method-
                                 // specific type parameters.
-                                this.resolve_method(
-                                    MethodRibKind(id, ProvidedMethod(method.id)),
-                                    &**method);
+                                let type_parameters =
+                                    HasTypeParameters(&sig.generics,
+                                                      FnSpace,
+                                                      MethodRibKind);
+                                this.with_type_parameter_rib(type_parameters, |this| {
+                                    visit::walk_impl_item(this, impl_item);
+                                });
                             }
-                            TypeImplItem(ref typedef) => {
+                            TypeImplItem(ref ty) => {
                                 // If this is a trait impl, ensure the method
                                 // exists in trait
-                                this.check_trait_item(typedef.ident.name,
-                                                      typedef.span);
+                                this.check_trait_item(impl_item.ident.name,
+                                                      impl_item.span);
 
-                                this.resolve_type(&*typedef.typ);
+                                this.visit_ty(ty);
                             }
+                            ast::MacImplItem(_) => {}
                         }
                     }
                 });
             });
         });
-
-        // Check that the current type is indeed a type, if we have an anonymous impl
-        if opt_trait_reference.is_none() {
-            match self_type.node {
-                // TyPath is the only thing that we handled in `build_reduced_graph_for_item`,
-                // where we created a module with the name of the type in order to implement
-                // an anonymous trait. In the case that the path does not resolve to an actual
-                // type, the result will be that the type name resolves to a module but not
-                // a type (shadowing any imported modules or types with this name), leading
-                // to weird user-visible bugs. So we ward this off here. See #15060.
-                TyPath(ref path, path_id) => {
-                    match self.def_map.borrow().get(&path_id) {
-                        // FIXME: should we catch other options and give more precise errors?
-                        Some(&DefMod(_)) => {
-                            self.resolve_error(path.span, "inherent implementations are not \
-                                                           allowed for types not defined in \
-                                                           the current module");
-                        }
-                        _ => {}
-                    }
-                }
-                _ => { }
-            }
-        }
     }
 
     fn check_trait_item(&self, name: Name, span: Span) {
         // If there is a TraitRef in scope for an impl, then the method must be in the trait.
         if let Some((did, ref trait_ref)) = self.current_trait_ref {
-            if self.trait_item_map.get(&(name, did)).is_none() {
-                let path_str = self.path_names_to_string(&trait_ref.path);
+            if !self.trait_item_map.contains_key(&(name, did)) {
+                let path_str = path_names_to_string(&trait_ref.path, 0);
                 self.resolve_error(span,
                                     &format!("method `{}` is not a member of trait `{}`",
                                             token::get_name(name),
-                                            path_str)[]);
+                                            path_str));
             }
         }
     }
 
-    fn resolve_module(&mut self, module: &Mod, _span: Span,
-                      _name: Name, id: NodeId) {
-        // Write the implementations in scope into the module metadata.
-        debug!("(resolving module) resolving module ID {}", id);
-        visit::walk_mod(self, module);
-    }
-
     fn resolve_local(&mut self, local: &Local) {
         // Resolve the type.
-        if let Some(ref ty) = local.ty {
-            self.resolve_type(&**ty);
-        }
+        visit::walk_ty_opt(self, &local.ty);
 
-        // Resolve the initializer, if necessary.
-        match local.init {
-            None => {
-                // Nothing to do.
-            }
-            Some(ref initializer) => {
-                self.resolve_expr(&**initializer);
-            }
-        }
+        // Resolve the initializer.
+        visit::walk_expr_opt(self, &local.init);
 
         // Resolve the pattern.
-        let mut bindings_list = HashMap::new();
         self.resolve_pattern(&*local.pat,
                              LocalIrrefutableMode,
-                             &mut bindings_list);
+                             &mut HashMap::new());
     }
 
     // build a map from pattern identifiers to binding-info's.
@@ -3477,7 +2176,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         &format!("variable `{}` from pattern #1 is \
                                   not bound in pattern #{}",
                                 token::get_name(key),
-                                i + 1)[]);
+                                i + 1));
                   }
                   Some(binding_i) => {
                     if binding_0.binding_mode != binding_i.binding_mode {
@@ -3486,7 +2185,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             &format!("variable `{}` is bound with different \
                                       mode in pattern #{} than in pattern #1",
                                     token::get_name(key),
-                                    i + 1)[]);
+                                    i + 1));
                     }
                   }
                 }
@@ -3499,7 +2198,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         &format!("variable `{}` from pattern {}{} is \
                                   not bound in pattern {}1",
                                 token::get_name(key),
-                                "#", i + 1, "#")[]);
+                                "#", i + 1, "#"));
                 }
             }
         }
@@ -3518,7 +2217,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         self.check_consistent_bindings(arm);
 
         visit::walk_expr_opt(self, &arm.guard);
-        self.resolve_expr(&*arm.body);
+        self.visit_expr(&*arm.body);
 
         self.value_ribs.pop();
     }
@@ -3570,90 +2269,63 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     fn resolve_type(&mut self, ty: &Ty) {
         match ty.node {
-            // Like path expressions, the interpretation of path types depends
-            // on whether the path has multiple elements in it or not.
+            // `<T>::a::b::c` is resolved by typeck alone.
+            TyPath(Some(ast::QSelf { position: 0, .. }), _) => {}
+
+            TyPath(ref maybe_qself, ref path) => {
+                let max_assoc_types = if let Some(ref qself) = *maybe_qself {
+                    // Make sure the trait is valid.
+                    let _ = self.resolve_trait_reference(ty.id, path, 1);
+                    path.segments.len() - qself.position
+                } else {
+                    path.segments.len()
+                };
 
-            TyPath(ref path, path_id) => {
-                // This is a path in the type namespace. Walk through scopes
-                // looking for it.
-                let mut result_def = None;
-
-                // First, check to see whether the name is a primitive type.
-                if path.segments.len() == 1 {
-                    let id = path.segments.last().unwrap().identifier;
-
-                    match self.primitive_type_table
-                            .primitive_types
-                            .get(&id.name) {
-
-                        Some(&primitive_type) => {
-                            result_def =
-                                Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
-
-                            if path.segments[0].parameters.has_lifetimes() {
-                                span_err!(self.session, path.span, E0157,
-                                    "lifetime parameters are not allowed on this type");
-                            } else if !path.segments[0].parameters.is_empty() {
-                                span_err!(self.session, path.span, E0153,
-                                    "type parameters are not allowed on this type");
-                            }
-                        }
-                        None => {
-                            // Continue.
-                        }
+                let mut resolution = None;
+                for depth in 0..max_assoc_types {
+                    self.with_no_errors(|this| {
+                        resolution = this.resolve_path(ty.id, path, depth, TypeNS, true);
+                    });
+                    if resolution.is_some() {
+                        break;
                     }
                 }
-
-                if let None = result_def {
-                    result_def = self.resolve_path(ty.id, path, TypeNS, true);
+                if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
+                    // A module is not a valid type.
+                    resolution = None;
                 }
 
-                match result_def {
+                // This is a path in the type namespace. Walk through scopes
+                // looking for it.
+                match resolution {
                     Some(def) => {
                         // Write the result into the def map.
                         debug!("(resolving type) writing resolution for `{}` \
                                 (id {}) = {:?}",
-                               self.path_names_to_string(path),
-                               path_id, def);
-                        self.record_def(path_id, def);
+                               path_names_to_string(path, 0),
+                               ty.id, def);
+                        self.record_def(ty.id, def);
                     }
                     None => {
-                        let msg = format!("use of undeclared type name `{}`",
-                                          self.path_names_to_string(path));
-                        self.resolve_error(ty.span, &msg[..]);
-                    }
-                }
-            }
+                        // Keep reporting some errors even if they're ignored above.
+                        self.resolve_path(ty.id, path, 0, TypeNS, true);
 
-            TyObjectSum(ref ty, ref bound_vec) => {
-                self.resolve_type(&**ty);
-                self.resolve_type_parameter_bounds(ty.id, bound_vec,
-                                                       TraitBoundingTypeParameter);
-            }
+                        let kind = if maybe_qself.is_some() {
+                            "associated type"
+                        } else {
+                            "type name"
+                        };
 
-            TyQPath(ref qpath) => {
-                self.resolve_type(&*qpath.self_type);
-                self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
-                for ty in qpath.item_path.parameters.types() {
-                    self.resolve_type(&**ty);
-                }
-                for binding in qpath.item_path.parameters.bindings() {
-                    self.resolve_type(&*binding.ty);
+                        let msg = format!("use of undeclared {} `{}`", kind,
+                                          path_names_to_string(path, 0));
+                        self.resolve_error(ty.span, &msg[..]);
+                    }
                 }
             }
-
-            TyPolyTraitRef(ref bounds) => {
-                self.resolve_type_parameter_bounds(
-                    ty.id,
-                    bounds,
-                    TraitObject);
-                visit::walk_ty(self, ty);
-            }
-            _ => {
-                // Just resolve embedded types.
-                visit::walk_ty(self, ty);
-            }
+            _ => {}
         }
+        // Resolve embedded types.
+        visit::walk_ty(self, ty);
     }
 
     fn resolve_pattern(&mut self,
@@ -3680,7 +2352,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     let renamed = mtwt::resolve(ident);
 
                     match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
-                        FoundStructOrEnumVariant(ref def, lp)
+                        FoundStructOrEnumVariant(def, lp)
                                 if mode == RefutableMode => {
                             debug!("(resolving pattern) resolving `{}` to \
                                     struct or enum variant",
@@ -3690,7 +2362,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 pattern,
                                 binding_mode,
                                 "an enum variant");
-                            self.record_def(pattern.id, (def.clone(), lp));
+                            self.record_def(pattern.id, PathResolution {
+                                base_def: def,
+                                last_private: lp,
+                                depth: 0
+                            });
                         }
                         FoundStructOrEnumVariant(..) => {
                             self.resolve_error(
@@ -3698,9 +2374,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 &format!("declaration of `{}` shadows an enum \
                                          variant or unit-like struct in \
                                          scope",
-                                        token::get_name(renamed))[]);
+                                        token::get_name(renamed)));
                         }
-                        FoundConst(ref def, lp) if mode == RefutableMode => {
+                        FoundConst(def, lp) if mode == RefutableMode => {
                             debug!("(resolving pattern) resolving `{}` to \
                                     constant",
                                    token::get_name(renamed));
@@ -3709,7 +2385,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 pattern,
                                 binding_mode,
                                 "a constant");
-                            self.record_def(pattern.id, (def.clone(), lp));
+                            self.record_def(pattern.id, PathResolution {
+                                base_def: def,
+                                last_private: lp,
+                                depth: 0
+                            });
                         }
                         FoundConst(..) => {
                             self.resolve_error(pattern.span,
@@ -3726,7 +2406,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             // will be able to distinguish variants from
                             // locals in patterns.
 
-                            self.record_def(pattern.id, (def, LastMod(AllPublic)));
+                            self.record_def(pattern.id, PathResolution {
+                                base_def: def,
+                                last_private: LastMod(AllPublic),
+                                depth: 0
+                            });
 
                             // Add the binding to the local ribs, if it
                             // doesn't already exist in the bindings list. (We
@@ -3750,7 +2434,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                                             list",
                                                            token::get_ident(
                                                                ident))
-                                                   [])
+                                                   )
                             } else if bindings_list.get(&renamed) ==
                                     Some(&pat_id) {
                                 // Then this is a duplicate variable in the
@@ -3759,7 +2443,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     &format!("identifier `{}` is bound \
                                              more than once in the same \
                                              pattern",
-                                            token::get_ident(ident))[]);
+                                            token::get_ident(ident)));
                             }
                             // Else, not bound in the same pattern: do
                             // nothing.
@@ -3769,50 +2453,34 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
                 PatEnum(ref path, _) => {
                     // This must be an enum variant, struct or const.
-                    match self.resolve_path(pat_id, path, ValueNS, false) {
-                        Some(def @ (DefVariant(..), _)) |
-                        Some(def @ (DefStruct(..), _))  |
-                        Some(def @ (DefConst(..), _)) => {
-                            self.record_def(pattern.id, def);
-                        }
-                        Some((DefStatic(..), _)) => {
-                            self.resolve_error(path.span,
-                                               "static variables cannot be \
-                                                referenced in a pattern, \
-                                                use a `const` instead");
-                        }
-                        Some(_) => {
-                            self.resolve_error(path.span,
-                                &format!("`{}` is not an enum variant, struct or const",
-                                    token::get_ident(
-                                        path.segments.last().unwrap().identifier)));
-                        }
-                        None => {
-                            self.resolve_error(path.span,
-                                &format!("unresolved enum variant, struct or const `{}`",
-                                    token::get_ident(path.segments.last().unwrap().identifier)));
+                    if let Some(path_res) = self.resolve_path(pat_id, path, 0, ValueNS, false) {
+                        match path_res.base_def {
+                            DefVariant(..) | DefStruct(..) | DefConst(..) => {
+                                self.record_def(pattern.id, path_res);
+                            }
+                            DefStatic(..) => {
+                                self.resolve_error(path.span,
+                                                   "static variables cannot be \
+                                                    referenced in a pattern, \
+                                                    use a `const` instead");
+                            }
+                            _ => {
+                                self.resolve_error(path.span,
+                                    &format!("`{}` is not an enum variant, struct or const",
+                                        token::get_ident(
+                                            path.segments.last().unwrap().identifier)));
+                            }
                         }
+                    } else {
+                        self.resolve_error(path.span,
+                            &format!("unresolved enum variant, struct or const `{}`",
+                                token::get_ident(path.segments.last().unwrap().identifier)));
                     }
-
-                    // Check the types in the path pattern.
-                    for ty in path.segments
-                                  .iter()
-                                  .flat_map(|s| s.parameters.types().into_iter()) {
-                        self.resolve_type(&**ty);
-                    }
-                }
-
-                PatLit(ref expr) => {
-                    self.resolve_expr(&**expr);
-                }
-
-                PatRange(ref first_expr, ref last_expr) => {
-                    self.resolve_expr(&**first_expr);
-                    self.resolve_expr(&**last_expr);
+                    visit::walk_path(self, path);
                 }
 
                 PatStruct(ref path, _, _) => {
-                    match self.resolve_path(pat_id, path, TypeNS, false) {
+                    match self.resolve_path(pat_id, path, 0, TypeNS, false) {
                         Some(definition) => {
                             self.record_def(pattern.id, definition);
                         }
@@ -3820,10 +2488,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             debug!("(resolving pattern) didn't find struct \
                                     def: {:?}", result);
                             let msg = format!("`{}` does not name a structure",
-                                              self.path_names_to_string(path));
+                                              path_names_to_string(path, 0));
                             self.resolve_error(path.span, &msg[..]);
                         }
                     }
+                    visit::walk_path(self, path);
+                }
+
+                PatLit(_) | PatRange(..) => {
+                    visit::walk_pat(self, pattern);
                 }
 
                 _ => {
@@ -3883,7 +2556,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 match err {
                     Some((span, msg)) => {
                         self.resolve_error(span, &format!("failed to resolve: {}",
-                                                         msg)[]);
+                                                         msg));
                     }
                     None => ()
                 }
@@ -3897,98 +2570,74 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     /// If `check_ribs` is true, checks the local definitions first; i.e.
     /// doesn't skip straight to the containing module.
+    /// Skips `path_depth` trailing segments, which is also reflected in the
+    /// returned value. See `middle::def::PathResolution` for more info.
     fn resolve_path(&mut self,
                     id: NodeId,
                     path: &Path,
+                    path_depth: usize,
                     namespace: Namespace,
-                    check_ribs: bool) -> Option<(Def, LastPrivate)> {
-        // First, resolve the types and associated type bindings.
-        for ty in path.segments.iter().flat_map(|s| s.parameters.types().into_iter()) {
-            self.resolve_type(&**ty);
-        }
-        for binding in path.segments.iter().flat_map(|s| s.parameters.bindings().into_iter()) {
-            self.resolve_type(&*binding.ty);
-        }
+                    check_ribs: bool) -> Option<PathResolution> {
+        let span = path.span;
+        let segments = &path.segments[..path.segments.len()-path_depth];
 
-        // A special case for sugared associated type paths `T::A` where `T` is
-        // a type parameter and `A` is an associated type on some bound of `T`.
-        if namespace == TypeNS && path.segments.len() == 2 {
-            match self.resolve_identifier(path.segments[0].identifier,
-                                          TypeNS,
-                                          true,
-                                          path.span) {
-                Some((def, last_private)) => {
-                    match def {
-                        DefTyParam(_, _, did, _) => {
-                            let def = DefAssociatedPath(TyParamProvenance::FromParam(did),
-                                                        path.segments.last()
-                                                            .unwrap().identifier);
-                            return Some((def, last_private));
-                        }
-                        DefSelfTy(nid) => {
-                            let def = DefAssociatedPath(TyParamProvenance::FromSelf(local_def(nid)),
-                                                        path.segments.last()
-                                                            .unwrap().identifier);
-                            return Some((def, last_private));
-                        }
-                        _ => {}
-                    }
-                }
-                _ => {}
-            }
-        }
+        let mk_res = |(def, lp)| PathResolution::new(def, lp, path_depth);
 
         if path.global {
-            return self.resolve_crate_relative_path(path, namespace);
+            let def = self.resolve_crate_relative_path(span, segments, namespace);
+            return def.map(mk_res);
         }
 
         // Try to find a path to an item in a module.
         let unqualified_def =
-                self.resolve_identifier(path.segments.last().unwrap().identifier,
+                self.resolve_identifier(segments.last().unwrap().identifier,
                                         namespace,
                                         check_ribs,
-                                        path.span);
-
-        if path.segments.len() > 1 {
-            let def = self.resolve_module_relative_path(path, namespace);
-            match (def, unqualified_def) {
-                (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
-                    self.session
-                        .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
-                                  id,
-                                  path.span,
-                                  "unnecessary qualification".to_string());
-                }
-                _ => ()
-            }
+                                        span);
+
+        if segments.len() <= 1 {
+            return unqualified_def.map(mk_res);
+        }
 
-            return def;
+        let def = self.resolve_module_relative_path(span, segments, namespace);
+        match (def, unqualified_def) {
+            (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
+                self.session
+                    .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
+                              id, span,
+                              "unnecessary qualification".to_string());
+            }
+            _ => {}
         }
 
-        return unqualified_def;
+        def.map(mk_res)
     }
 
-    // resolve a single identifier (used as a varref)
+    // Resolve a single identifier.
     fn resolve_identifier(&mut self,
                           identifier: Ident,
                           namespace: Namespace,
                           check_ribs: bool,
                           span: Span)
                           -> Option<(Def, LastPrivate)> {
+        // First, check to see whether the name is a primitive type.
+        if namespace == TypeNS {
+            if let Some(&prim_ty) = self.primitive_type_table
+                                        .primitive_types
+                                        .get(&identifier.name) {
+                return Some((DefPrimTy(prim_ty), LastMod(AllPublic)));
+            }
+        }
+
         if check_ribs {
-            match self.resolve_identifier_in_local_ribs(identifier,
-                                                        namespace,
-                                                        span) {
-                Some(def) => {
-                    return Some((def, LastMod(AllPublic)));
-                }
-                None => {
-                    // Continue.
-                }
+            if let Some(def) = self.resolve_identifier_in_local_ribs(identifier,
+                                                                     namespace,
+                                                                     span) {
+                return Some((def, LastMod(AllPublic)));
             }
         }
 
-        return self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace);
+        self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace)
     }
 
     // FIXME #4952: Merge me with resolve_name_in_module?
@@ -4005,8 +2654,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 match child_name_bindings.def_for_namespace(namespace) {
                     Some(def) => {
                         // Found it. Stop the search here.
-                        let p = child_name_bindings.defined_in_public_namespace(
-                                        namespace);
+                        let p = child_name_bindings.defined_in_public_namespace(namespace);
                         let lp = if p {LastMod(AllPublic)} else {
                             LastMod(DependsOn(def.def_id()))
                         };
@@ -4067,33 +2715,34 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     // resolve a "module-relative" path, e.g. a::b::c
     fn resolve_module_relative_path(&mut self,
-                                    path: &Path,
+                                    span: Span,
+                                    segments: &[ast::PathSegment],
                                     namespace: Namespace)
                                     -> Option<(Def, LastPrivate)> {
-        let module_path = path.segments.init().iter()
-                                              .map(|ps| ps.identifier.name)
-                                              .collect::<Vec<_>>();
+        let module_path = segments.init().iter()
+                                         .map(|ps| ps.identifier.name)
+                                         .collect::<Vec<_>>();
 
         let containing_module;
         let last_private;
-        let module = self.current_module.clone();
-        match self.resolve_module_path(module,
+        let current_module = self.current_module.clone();
+        match self.resolve_module_path(current_module,
                                        &module_path[..],
                                        UseLexicalScope,
-                                       path.span,
+                                       span,
                                        PathSearch) {
             Failed(err) => {
                 let (span, msg) = match err {
                     Some((span, msg)) => (span, msg),
                     None => {
                         let msg = format!("Use of undeclared type or module `{}`",
-                                          self.names_to_string(&module_path));
-                        (path.span, msg)
+                                          names_to_string(&module_path));
+                        (span, msg)
                     }
                 };
 
                 self.resolve_error(span, &format!("failed to resolve. {}",
-                                                 msg)[]);
+                                                 msg));
                 return None;
             }
             Indeterminate => panic!("indeterminate unexpected"),
@@ -4103,7 +2752,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
         }
 
-        let name = path.segments.last().unwrap().identifier.name;
+        let name = segments.last().unwrap().identifier.name;
         let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
                                                                   name,
                                                                   namespace) {
@@ -4124,12 +2773,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     /// Invariant: This must be called only during main resolution, not during
     /// import resolution.
     fn resolve_crate_relative_path(&mut self,
-                                   path: &Path,
+                                   span: Span,
+                                   segments: &[ast::PathSegment],
                                    namespace: Namespace)
                                        -> Option<(Def, LastPrivate)> {
-        let module_path = path.segments.init().iter()
-                                              .map(|ps| ps.identifier.name)
-                                              .collect::<Vec<_>>();
+        let module_path = segments.init().iter()
+                                         .map(|ps| ps.identifier.name)
+                                         .collect::<Vec<_>>();
 
         let root_module = self.graph_root.get_module();
 
@@ -4138,7 +2788,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         match self.resolve_module_path_from_root(root_module,
                                                  &module_path[..],
                                                  0,
-                                                 path.span,
+                                                 span,
                                                  PathSearch,
                                                  LastMod(AllPublic)) {
             Failed(err) => {
@@ -4146,13 +2796,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     Some((span, msg)) => (span, msg),
                     None => {
                         let msg = format!("Use of undeclared module `::{}`",
-                                          self.names_to_string(&module_path[..]));
-                        (path.span, msg)
+                                          names_to_string(&module_path[..]));
+                        (span, msg)
                     }
                 };
 
                 self.resolve_error(span, &format!("failed to resolve. {}",
-                                                 msg)[]);
+                                                 msg));
                 return None;
             }
 
@@ -4166,7 +2816,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
         }
 
-        let name = path.segments.last().unwrap().identifier.name;
+        let name = segments.last().unwrap().identifier.name;
         match self.resolve_definition_of_name_in_module(containing_module,
                                                         name,
                                                         namespace) {
@@ -4193,20 +2843,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
             TypeNS => {
                 let name = ident.name;
-                self.search_ribs(&self.type_ribs[], name, span)
+                self.search_ribs(&self.type_ribs, name, span)
             }
         };
 
         match search_result {
             Some(DlDef(def)) => {
-                debug!("(resolving path in local ribs) resolved `{}` to \
-                        local: {:?}",
+                debug!("(resolving path in local ribs) resolved `{}` to local: {:?}",
                        token::get_ident(ident),
                        def);
-                return Some(def);
+                Some(def)
             }
             Some(DlField) | Some(DlImpl(_)) | None => {
-                return None;
+                None
             }
         }
     }
@@ -4245,15 +2894,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 panic!("unexpected indeterminate result");
             }
             Failed(err) => {
-                match err {
-                    Some((span, msg)) =>
-                        self.resolve_error(span, &format!("failed to resolve. {}",
-                                                         msg)[]),
-                    None => ()
-                }
-
                 debug!("(resolving item path by identifier in lexical scope) \
                          failed to resolve {}", token::get_name(name));
+
+                if let Some((span, msg)) = err {
+                    self.resolve_error(span, &format!("failed to resolve. {}", msg))
+                }
+
                 return None;
             }
         }
@@ -4278,7 +2925,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
                                                     -> Option<(Path, NodeId, FallbackChecks)> {
             match t.node {
-                TyPath(ref path, node_id) => Some((path.clone(), node_id, allow)),
+                TyPath(None, ref path) => Some((path.clone(), t.id, allow)),
                 TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
                 TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
                 // This doesn't handle the remaining `Ty` variants as they are not
@@ -4305,16 +2952,35 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 }
             } else {
                 match this.resolve_module_path(root,
-                                                &name_path[..],
-                                                UseLexicalScope,
-                                                span,
-                                                PathSearch) {
+                                               &name_path[..],
+                                               UseLexicalScope,
+                                               span,
+                                               PathSearch) {
                     Success((module, _)) => Some(module),
                     _ => None
                 }
             }
         }
 
+        fn is_static_method(this: &Resolver, did: DefId) -> bool {
+            if did.krate == ast::LOCAL_CRATE {
+                let sig = match this.ast_map.get(did.node) {
+                    ast_map::NodeTraitItem(trait_item) => match trait_item.node {
+                        ast::MethodTraitItem(ref sig, _) => sig,
+                        _ => return false
+                    },
+                    ast_map::NodeImplItem(impl_item) => match impl_item.node {
+                        ast::MethodImplItem(ref sig, _) => sig,
+                        _ => return false
+                    },
+                    _ => return false
+                };
+                sig.explicit_self.node == ast::SelfStatic
+            } else {
+                csearch::is_static_method(&this.session.cstore, did)
+            }
+        }
+
         let (path, node_id, allowed) = match self.current_self_type {
             Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
                 Some(x) => x,
@@ -4325,10 +2991,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         if allowed == Everything {
             // Look for a field with the same name in the current self_type.
-            match self.def_map.borrow().get(&node_id) {
-                 Some(&DefTy(did, _))
-                | Some(&DefStruct(did))
-                | Some(&DefVariant(_, did, _)) => match self.structs.get(&did) {
+            match self.def_map.borrow().get(&node_id).map(|d| d.full_def()) {
+                Some(DefTy(did, _)) |
+                Some(DefStruct(did)) |
+                Some(DefVariant(_, did, _)) => match self.structs.get(&did) {
                     None => {}
                     Some(fields) => {
                         if fields.iter().any(|&field_name| name == field_name) {
@@ -4343,52 +3009,41 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
 
         // Look for a method in the current self type's impl module.
-        match get_module(self, path.span, &name_path[..]) {
-            Some(module) => match module.children.borrow().get(&name) {
-                Some(binding) => {
-                    let p_str = self.path_names_to_string(&path);
-                    match binding.def_for_namespace(ValueNS) {
-                        Some(DefStaticMethod(_, provenance)) => {
-                            match provenance {
-                                FromImpl(_) => return StaticMethod(p_str),
-                                FromTrait(_) => unreachable!()
-                            }
-                        }
-                        Some(DefMethod(_, None, _)) if allowed == Everything => return Method,
-                        Some(DefMethod(_, Some(_), _)) => return TraitItem,
-                        _ => ()
+        if let Some(module) = get_module(self, path.span, &name_path) {
+            if let Some(binding) = module.children.borrow().get(&name) {
+                if let Some(DefMethod(did, _)) = binding.def_for_namespace(ValueNS) {
+                    if is_static_method(self, did) {
+                        return StaticMethod(path_names_to_string(&path, 0))
+                    }
+                    if self.current_trait_ref.is_some() {
+                        return TraitItem;
+                    } else if allowed == Everything {
+                        return Method;
                     }
                 }
-                None => {}
-            },
-            None => {}
+            }
         }
 
         // Look for a method in the current trait.
-        match self.current_trait_ref {
-            Some((did, ref trait_ref)) => {
-                let path_str = self.path_names_to_string(&trait_ref.path);
-
-                match self.trait_item_map.get(&(name, did)) {
-                    Some(&StaticMethodTraitItemKind) => {
-                        return TraitMethod(path_str)
-                    }
-                    Some(_) => return TraitItem,
-                    None => {}
+        if let Some((trait_did, ref trait_ref)) = self.current_trait_ref {
+            if let Some(&did) = self.trait_item_map.get(&(name, trait_did)) {
+                if is_static_method(self, did) {
+                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
+                } else {
+                    return TraitItem;
                 }
             }
-            None => {}
         }
 
         NoSuggestion
     }
 
-    fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
+    fn find_best_match_for_name(&mut self, name: &str, max_distance: usize)
                                 -> Option<String> {
         let this = &mut *self;
 
         let mut maybes: Vec<token::InternedString> = Vec::new();
-        let mut values: Vec<uint> = Vec::new();
+        let mut values: Vec<usize> = Vec::new();
 
         for rib in this.value_ribs.iter().rev() {
             for (&k, _) in &rib.bindings {
@@ -4410,7 +3065,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             values[smallest] != usize::MAX &&
             values[smallest] < name.len() + 2 &&
             values[smallest] <= max_distance &&
-            name != &maybes[smallest][] {
+            name != &maybes[smallest][..] {
 
             Some(maybes[smallest].to_string())
 
@@ -4427,118 +3082,149 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         // Next, resolve the node.
         match expr.node {
-            // The interpretation of paths depends on whether the path has
-            // multiple elements in it or not.
-
-            ExprPath(_) | ExprQPath(_) => {
-                let mut path_from_qpath;
-                let path = match expr.node {
-                    ExprPath(ref path) => path,
-                    ExprQPath(ref qpath) => {
-                        self.resolve_type(&*qpath.self_type);
-                        self.resolve_trait_reference(expr.id, &*qpath.trait_ref, TraitQPath);
-                        path_from_qpath = qpath.trait_ref.path.clone();
-                        path_from_qpath.segments.push(qpath.item_path.clone());
-                        &path_from_qpath
-                    }
-                    _ => unreachable!()
+            // `<T>::a::b::c` is resolved by typeck alone.
+            ExprPath(Some(ast::QSelf { position: 0, .. }), ref path) => {
+                let method_name = path.segments.last().unwrap().identifier.name;
+                let traits = self.search_for_traits_containing_method(method_name);
+                self.trait_map.insert(expr.id, traits);
+                visit::walk_expr(self, expr);
+            }
+
+            ExprPath(ref maybe_qself, ref path) => {
+                let max_assoc_types = if let Some(ref qself) = *maybe_qself {
+                    // Make sure the trait is valid.
+                    let _ = self.resolve_trait_reference(expr.id, path, 1);
+                    path.segments.len() - qself.position
+                } else {
+                    path.segments.len()
                 };
+
+                let mut resolution = self.with_no_errors(|this| {
+                    this.resolve_path(expr.id, path, 0, ValueNS, true)
+                });
+                for depth in 1..max_assoc_types {
+                    if resolution.is_some() {
+                        break;
+                    }
+                    self.with_no_errors(|this| {
+                        resolution = this.resolve_path(expr.id, path, depth, TypeNS, true);
+                    });
+                }
+                if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
+                    // A module is not a valid type or value.
+                    resolution = None;
+                }
+
                 // This is a local path in the value namespace. Walk through
                 // scopes looking for it.
-                match self.resolve_path(expr.id, path, ValueNS, true) {
+                if let Some(path_res) = resolution {
                     // Check if struct variant
-                    Some((DefVariant(_, _, true), _)) => {
-                        let path_name = self.path_names_to_string(path);
+                    if let DefVariant(_, _, true) = path_res.base_def {
+                        let path_name = path_names_to_string(path, 0);
                         self.resolve_error(expr.span,
                                 &format!("`{}` is a struct variant name, but \
                                           this expression \
                                           uses it like a function name",
                                          path_name));
 
-                        self.session.span_help(expr.span,
-                            &format!("Did you mean to write: \
-                                     `{} {{ /* fields */ }}`?",
-                                     path_name));
-                    }
-                    Some(def) => {
+                        let msg = format!("Did you mean to write: \
+                                           `{} {{ /* fields */ }}`?",
+                                          path_name);
+                        if self.emit_errors {
+                            self.session.fileline_help(expr.span, &msg);
+                        } else {
+                            self.session.span_help(expr.span, &msg);
+                        }
+                    } else {
                         // Write the result into the def map.
                         debug!("(resolving expr) resolved `{}`",
-                               self.path_names_to_string(path));
+                               path_names_to_string(path, 0));
+
+                        // Partial resolutions will need the set of traits in scope,
+                        // so they can be completed during typeck.
+                        if path_res.depth != 0 {
+                            let method_name = path.segments.last().unwrap().identifier.name;
+                            let traits = self.search_for_traits_containing_method(method_name);
+                            self.trait_map.insert(expr.id, traits);
+                        }
 
-                        self.record_def(expr.id, def);
+                        self.record_def(expr.id, path_res);
                     }
-                    None => {
-                        // Be helpful if the name refers to a struct
-                        // (The pattern matching def_tys where the id is in self.structs
-                        // matches on regular structs while excluding tuple- and enum-like
-                        // structs, which wouldn't result in this error.)
-                        let path_name = self.path_names_to_string(path);
-                        match self.with_no_errors(|this|
-                            this.resolve_path(expr.id, path, TypeNS, false)) {
-                            Some((DefTy(struct_id, _), _))
-                              if self.structs.contains_key(&struct_id) => {
+                } else {
+                    // Be helpful if the name refers to a struct
+                    // (The pattern matching def_tys where the id is in self.structs
+                    // matches on regular structs while excluding tuple- and enum-like
+                    // structs, which wouldn't result in this error.)
+                    let path_name = path_names_to_string(path, 0);
+                    let type_res = self.with_no_errors(|this| {
+                        this.resolve_path(expr.id, path, 0, TypeNS, false)
+                    });
+                    match type_res.map(|r| r.base_def) {
+                        Some(DefTy(struct_id, _))
+                            if self.structs.contains_key(&struct_id) => {
                                 self.resolve_error(expr.span,
-                                        &format!("`{}` is a structure name, but \
-                                                  this expression \
-                                                  uses it like a function name",
-                                                 path_name));
-
-                                self.session.span_help(expr.span,
-                                    &format!("Did you mean to write: \
-                                             `{} {{ /* fields */ }}`?",
-                                             path_name));
-
-                            }
-                            _ => {
-                                let mut method_scope = false;
-                                self.value_ribs.iter().rev().all(|rib| {
-                                    let res = match *rib {
-                                        Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
-                                        Rib { bindings: _, kind: ItemRibKind } => false,
-                                        _ => return true, // Keep advancing
-                                    };
-
-                                    method_scope = res;
-                                    false // Stop advancing
-                                });
-
-                                if method_scope && &token::get_name(self.self_name)[]
-                                                                   == path_name {
-                                        self.resolve_error(
-                                            expr.span,
-                                            "`self` is not available \
-                                             in a static method. Maybe a \
-                                             `self` argument is missing?");
+                                    &format!("`{}` is a structure name, but \
+                                                this expression \
+                                                uses it like a function name",
+                                                path_name));
+
+                                let msg = format!("Did you mean to write: \
+                                                     `{} {{ /* fields */ }}`?",
+                                                    path_name);
+                                if self.emit_errors {
+                                    self.session.fileline_help(expr.span, &msg);
                                 } else {
-                                    let last_name = path.segments.last().unwrap().identifier.name;
-                                    let mut msg = match self.find_fallback_in_self_type(last_name) {
-                                        NoSuggestion => {
-                                            // limit search to 5 to reduce the number
-                                            // of stupid suggestions
-                                            self.find_best_match_for_name(&path_name, 5)
-                                                                .map_or("".to_string(),
-                                                                        |x| format!("`{}`", x))
-                                        }
-                                        Field =>
-                                            format!("`self.{}`", path_name),
-                                        Method
-                                        | TraitItem =>
-                                            format!("to call `self.{}`", path_name),
-                                        TraitMethod(path_str)
-                                        | StaticMethod(path_str) =>
-                                            format!("to call `{}::{}`", path_str, path_name)
-                                    };
-
-                                    if msg.len() > 0 {
-                                        msg = format!(". Did you mean {}?", msg)
-                                    }
+                                    self.session.span_help(expr.span, &msg);
+                                }
+                            }
+                        _ => {
+                            // Keep reporting some errors even if they're ignored above.
+                            self.resolve_path(expr.id, path, 0, ValueNS, true);
+
+                            let mut method_scope = false;
+                            self.value_ribs.iter().rev().all(|rib| {
+                                method_scope = match rib.kind {
+                                    MethodRibKind => true,
+                                    ItemRibKind | ConstantItemRibKind => false,
+                                    _ => return true, // Keep advancing
+                                };
+                                false // Stop advancing
+                            });
 
+                            if method_scope &&
+                               &token::get_name(special_names::self_)[..] == path_name {
                                     self.resolve_error(
                                         expr.span,
-                                        &format!("unresolved name `{}`{}",
-                                                 path_name,
-                                                 msg));
+                                        "`self` is not available \
+                                         in a static method. Maybe a \
+                                         `self` argument is missing?");
+                            } else {
+                                let last_name = path.segments.last().unwrap().identifier.name;
+                                let mut msg = match self.find_fallback_in_self_type(last_name) {
+                                    NoSuggestion => {
+                                        // limit search to 5 to reduce the number
+                                        // of stupid suggestions
+                                        self.find_best_match_for_name(&path_name, 5)
+                                                            .map_or("".to_string(),
+                                                                    |x| format!("`{}`", x))
+                                    }
+                                    Field => format!("`self.{}`", path_name),
+                                    Method |
+                                    TraitItem =>
+                                        format!("to call `self.{}`", path_name),
+                                    TraitMethod(path_str) |
+                                    StaticMethod(path_str) =>
+                                        format!("to call `{}::{}`", path_str, path_name)
+                                };
+
+                                if msg.len() > 0 {
+                                    msg = format!(". Did you mean {}?", msg)
                                 }
+
+                                self.resolve_error(
+                                    expr.span,
+                                    &format!("unresolved name `{}`{}",
+                                             path_name, msg));
                             }
                         }
                     }
@@ -4547,23 +3233,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 visit::walk_expr(self, expr);
             }
 
-            ExprClosure(_, ref fn_decl, ref block) => {
-                self.resolve_function(ClosureRibKind(expr.id),
-                                      Some(&**fn_decl), NoTypeParameters,
-                                      &**block);
-            }
-
             ExprStruct(ref path, _, _) => {
                 // Resolve the path to the structure it goes to. We don't
                 // check to ensure that the path is actually a structure; that
                 // is checked later during typeck.
-                match self.resolve_path(expr.id, path, TypeNS, false) {
+                match self.resolve_path(expr.id, path, 0, TypeNS, false) {
                     Some(definition) => self.record_def(expr.id, definition),
-                    result => {
-                        debug!("(resolving expression) didn't find struct \
-                                def: {:?}", result);
+                    None => {
+                        debug!("(resolving expression) didn't find struct def",);
                         let msg = format!("`{}` does not name a structure",
-                                          self.path_names_to_string(path));
+                                          path_names_to_string(path, 0));
                         self.resolve_error(path.span, &msg[..]);
                     }
                 }
@@ -4592,11 +3271,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         self.resolve_error(
                             expr.span,
                             &format!("use of undeclared label `{}`",
-                                    token::get_ident(label))[])
+                                    token::get_ident(label)))
                     }
                     Some(DlDef(def @ DefLabel(_))) => {
                         // Since this def is a label, it is never read.
-                        self.record_def(expr.id, (def, LastMod(AllPublic)))
+                        self.record_def(expr.id, PathResolution {
+                            base_def: def,
+                            last_private: LastMod(AllPublic),
+                            depth: 0
+                        })
                     }
                     Some(_) => {
                         self.session.span_bug(expr.span,
@@ -4714,26 +3397,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         found_traits
     }
 
-    fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
-        debug!("(recording def) recording {:?} for {}, last private {:?}",
-                def, node_id, lp);
-        assert!(match lp {LastImport{..} => false, _ => true},
+    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
+        debug!("(recording def) recording {:?} for {}", resolution, node_id);
+        assert!(match resolution.last_private {LastImport{..} => false, _ => true},
                 "Import should only be used for `use` directives");
-        self.last_private.insert(node_id, lp);
 
-        match self.def_map.borrow_mut().entry(node_id) {
-            // Resolve appears to "resolve" the same ID multiple
-            // times, so here is a sanity check it at least comes to
-            // the same conclusion! - nmatsakis
-            Occupied(entry) => if def != *entry.get() {
-                self.session
-                    .bug(&format!("node_id {} resolved first to {:?} and \
-                                  then {:?}",
-                                 node_id,
-                                 *entry.get(),
-                                 def)[]);
-            },
-            Vacant(entry) => { entry.insert(def); },
+        if let Some(prev_res) = self.def_map.borrow_mut().insert(node_id, resolution) {
+            let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP);
+            self.session.span_bug(span, &format!("path resolved multiple times \
+                                                  ({:?} before, {:?} now)",
+                                                 prev_res, resolution));
         }
     }
 
@@ -4747,7 +3420,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 self.resolve_error(pat.span,
                                    &format!("cannot use `ref` binding mode \
                                             with {}",
-                                           descr)[]);
+                                           descr));
             }
         }
     }
@@ -4759,36 +3432,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     // hit.
     //
 
-    /// A somewhat inefficient routine to obtain the name of a module.
-    fn module_to_string(&self, module: &Module) -> String {
-        let mut names = Vec::new();
-
-        fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
-            match module.parent_link {
-                NoParentLink => {}
-                ModuleParentLink(ref module, name) => {
-                    names.push(name);
-                    collect_mod(names, &*module.upgrade().unwrap());
-                }
-                BlockParentLink(ref module, _) => {
-                    // danger, shouldn't be ident?
-                    names.push(special_idents::opaque.name);
-                    collect_mod(names, &*module.upgrade().unwrap());
-                }
-            }
-        }
-        collect_mod(&mut names, module);
-
-        if names.len() == 0 {
-            return "???".to_string();
-        }
-        self.names_to_string(&names.into_iter().rev()
-                                  .collect::<Vec<ast::Name>>()[])
-    }
-
     #[allow(dead_code)]   // useful for debugging
     fn dump_module(&mut self, module_: Rc<Module>) {
-        debug!("Dump of module `{}`:", self.module_to_string(&*module_));
+        debug!("Dump of module `{}`:", module_to_string(&*module_));
 
         debug!("Children:");
         build_reduced_graph::populate_module_if_necessary(self, &module_);
@@ -4822,17 +3468,66 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     }
 }
 
+
+fn names_to_string(names: &[Name]) -> String {
+    let mut first = true;
+    let mut result = String::new();
+    for name in names {
+        if first {
+            first = false
+        } else {
+            result.push_str("::")
+        }
+        result.push_str(&token::get_name(*name));
+    };
+    result
+}
+
+fn path_names_to_string(path: &Path, depth: usize) -> String {
+    let names: Vec<ast::Name> = path.segments[..path.segments.len()-depth]
+                                    .iter()
+                                    .map(|seg| seg.identifier.name)
+                                    .collect();
+    names_to_string(&names[..])
+}
+
+/// A somewhat inefficient routine to obtain the name of a module.
+fn module_to_string(module: &Module) -> String {
+    let mut names = Vec::new();
+
+    fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
+        match module.parent_link {
+            NoParentLink => {}
+            ModuleParentLink(ref module, name) => {
+                names.push(name);
+                collect_mod(names, &*module.upgrade().unwrap());
+            }
+            BlockParentLink(ref module, _) => {
+                // danger, shouldn't be ident?
+                names.push(special_idents::opaque.name);
+                collect_mod(names, &*module.upgrade().unwrap());
+            }
+        }
+    }
+    collect_mod(&mut names, module);
+
+    if names.len() == 0 {
+        return "???".to_string();
+    }
+    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
+}
+
+
 pub struct CrateMap {
     pub def_map: DefMap,
     pub freevars: RefCell<FreevarMap>,
     pub export_map: ExportMap,
     pub trait_map: TraitMap,
     pub external_exports: ExternalExports,
-    pub last_private_map: LastPrivateMap,
     pub glob_map: Option<GlobMap>
 }
 
-#[derive(PartialEq,Copy)]
+#[derive(PartialEq,Copy, Clone)]
 pub enum MakeGlobMap {
     Yes,
     No
@@ -4850,7 +3545,7 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
     build_reduced_graph::build_reduced_graph(&mut resolver, krate);
     session.abort_if_errors();
 
-    resolver.resolve_imports();
+    resolve_imports::resolve_imports(&mut resolver);
     session.abort_if_errors();
 
     record_exports::record(&mut resolver);
@@ -4867,7 +3562,6 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
         export_map: resolver.export_map,
         trait_map: resolver.trait_map,
         external_exports: resolver.external_exports,
-        last_private_map: resolver.last_private,
         glob_map: if resolver.make_glob_map {
                         Some(resolver.glob_map)
                     } else {
index 5d025f40d32398490597b23e1be838c23a5d2e7a..e953b6398f9c08e6eab61bfc34e807b28c92e740 100644 (file)
@@ -22,6 +22,7 @@ use {Module, NameBindings, Resolver};
 use Namespace::{self, TypeNS, ValueNS};
 
 use build_reduced_graph;
+use module_to_string;
 
 use rustc::middle::def::Export;
 use syntax::ast;
@@ -60,19 +61,19 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
                 // OK. Continue.
                 debug!("(recording exports for module subtree) recording \
                         exports for local module `{}`",
-                       self.module_to_string(&*module_));
+                       module_to_string(&*module_));
             }
             None => {
                 // Record exports for the root module.
                 debug!("(recording exports for module subtree) recording \
                         exports for root module `{}`",
-                       self.module_to_string(&*module_));
+                       module_to_string(&*module_));
             }
             Some(_) => {
                 // Bail out.
                 debug!("(recording exports for module subtree) not recording \
                         exports for `{}`",
-                       self.module_to_string(&*module_));
+                       module_to_string(&*module_));
                 return;
             }
         }
@@ -133,13 +134,13 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
     fn add_exports_for_module(&mut self,
                               exports: &mut Vec<Export>,
                               module_: &Module) {
-        for (name, importresolution) in &*module_.import_resolutions.borrow() {
-            if !importresolution.is_public {
+        for (name, import_resolution) in &*module_.import_resolutions.borrow() {
+            if !import_resolution.is_public {
                 continue
             }
             let xs = [TypeNS, ValueNS];
             for &ns in &xs {
-                match importresolution.target_for_namespace(ns) {
+                match import_resolution.target_for_namespace(ns) {
                     Some(target) => {
                         debug!("(computing exports) maybe export '{}'",
                                token::get_name(*name));
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
new file mode 100644 (file)
index 0000000..f1a8507
--- /dev/null
@@ -0,0 +1,1018 @@
+// Copyright 2015 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 self::ImportDirectiveSubclass::*;
+
+use {PUBLIC, IMPORTABLE};
+use Module;
+use Namespace::{self, TypeNS, ValueNS};
+use NameBindings;
+use NamespaceResult::{BoundResult, UnboundResult, UnknownResult};
+use NamespaceResult;
+use NameSearchType;
+use ResolveResult;
+use Resolver;
+use UseLexicalScopeFlag;
+use {names_to_string, module_to_string};
+
+use build_reduced_graph;
+
+use rustc::middle::def::*;
+use rustc::middle::privacy::*;
+
+use syntax::ast::{DefId, NodeId, Name};
+use syntax::attr::AttrMetaMethods;
+use syntax::parse::token;
+use syntax::codemap::Span;
+
+use std::mem::replace;
+use std::rc::Rc;
+
+
+/// Contains data for specific types of import directives.
+#[derive(Copy, Clone,Debug)]
+pub enum ImportDirectiveSubclass {
+    SingleImport(Name /* target */, Name /* source */),
+    GlobImport
+}
+
+/// Whether an import can be shadowed by another import.
+#[derive(Debug,PartialEq,Clone,Copy)]
+pub enum Shadowable {
+    Always,
+    Never
+}
+
+/// One import directive.
+#[derive(Debug)]
+pub struct ImportDirective {
+    pub module_path: Vec<Name>,
+    pub subclass: ImportDirectiveSubclass,
+    pub span: Span,
+    pub id: NodeId,
+    pub is_public: bool, // see note in ImportResolution about how to use this
+    pub shadowable: Shadowable,
+}
+
+impl ImportDirective {
+    pub fn new(module_path: Vec<Name> ,
+           subclass: ImportDirectiveSubclass,
+           span: Span,
+           id: NodeId,
+           is_public: bool,
+           shadowable: Shadowable)
+           -> ImportDirective {
+        ImportDirective {
+            module_path: module_path,
+            subclass: subclass,
+            span: span,
+            id: id,
+            is_public: is_public,
+            shadowable: shadowable,
+        }
+    }
+}
+
+/// The item that an import resolves to.
+#[derive(Clone,Debug)]
+pub struct Target {
+    pub target_module: Rc<Module>,
+    pub bindings: Rc<NameBindings>,
+    pub shadowable: Shadowable,
+}
+
+impl Target {
+    pub fn new(target_module: Rc<Module>,
+           bindings: Rc<NameBindings>,
+           shadowable: Shadowable)
+           -> Target {
+        Target {
+            target_module: target_module,
+            bindings: bindings,
+            shadowable: shadowable,
+        }
+    }
+}
+
+/// An ImportResolution represents a particular `use` directive.
+#[derive(Debug)]
+pub struct ImportResolution {
+    /// Whether this resolution came from a `use` or a `pub use`. Note that this
+    /// should *not* be used whenever resolution is being performed. Privacy
+    /// testing occurs during a later phase of compilation.
+    pub is_public: bool,
+
+    // The number of outstanding references to this name. When this reaches
+    // zero, outside modules can count on the targets being correct. Before
+    // then, all bets are off; future imports could override this name.
+    // Note that this is usually either 0 or 1 - shadowing is forbidden the only
+    // way outstanding_references is > 1 in a legal program is if the name is
+    // used in both namespaces.
+    pub outstanding_references: usize,
+
+    /// The value that this `use` directive names, if there is one.
+    pub value_target: Option<Target>,
+    /// The source node of the `use` directive leading to the value target
+    /// being non-none
+    pub value_id: NodeId,
+
+    /// The type that this `use` directive names, if there is one.
+    pub type_target: Option<Target>,
+    /// The source node of the `use` directive leading to the type target
+    /// being non-none
+    pub type_id: NodeId,
+}
+
+impl ImportResolution {
+    pub fn new(id: NodeId, is_public: bool) -> ImportResolution {
+        ImportResolution {
+            type_id: id,
+            value_id: id,
+            outstanding_references: 0,
+            value_target: None,
+            type_target: None,
+            is_public: is_public,
+        }
+    }
+
+    pub fn target_for_namespace(&self, namespace: Namespace)
+                                -> Option<Target> {
+        match namespace {
+            TypeNS  => self.type_target.clone(),
+            ValueNS => self.value_target.clone(),
+        }
+    }
+
+    pub fn id(&self, namespace: Namespace) -> NodeId {
+        match namespace {
+            TypeNS  => self.type_id,
+            ValueNS => self.value_id,
+        }
+    }
+
+    pub fn shadowable(&self, namespace: Namespace) -> Shadowable {
+        let target = self.target_for_namespace(namespace);
+        if target.is_none() {
+            return Shadowable::Always;
+        }
+
+        target.unwrap().shadowable
+    }
+
+    pub fn set_target_and_id(&mut self,
+                         namespace: Namespace,
+                         target: Option<Target>,
+                         id: NodeId) {
+        match namespace {
+            TypeNS  => {
+                self.type_target = target;
+                self.type_id = id;
+            }
+            ValueNS => {
+                self.value_target = target;
+                self.value_id = id;
+            }
+        }
+    }
+}
+
+
+struct ImportResolver<'a, 'b:'a, 'tcx:'b> {
+    resolver: &'a mut Resolver<'b, 'tcx>
+}
+
+impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
+    // Import resolution
+    //
+    // This is a fixed-point algorithm. We resolve imports until our efforts
+    // are stymied by an unresolved import; then we bail out of the current
+    // module and continue. We terminate successfully once no more imports
+    // remain or unsuccessfully when no forward progress in resolving imports
+    // is made.
+
+    /// Resolves all imports for the crate. This method performs the fixed-
+    /// point iteration.
+    fn resolve_imports(&mut self) {
+        let mut i = 0;
+        let mut prev_unresolved_imports = 0;
+        loop {
+            debug!("(resolving imports) iteration {}, {} imports left",
+                   i, self.resolver.unresolved_imports);
+
+            let module_root = self.resolver.graph_root.get_module();
+            self.resolve_imports_for_module_subtree(module_root.clone());
+
+            if self.resolver.unresolved_imports == 0 {
+                debug!("(resolving imports) success");
+                break;
+            }
+
+            if self.resolver.unresolved_imports == prev_unresolved_imports {
+                self.resolver.report_unresolved_imports(module_root);
+                break;
+            }
+
+            i += 1;
+            prev_unresolved_imports = self.resolver.unresolved_imports;
+        }
+    }
+
+    /// Attempts to resolve imports for the given module and all of its
+    /// submodules.
+    fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
+        debug!("(resolving imports for module subtree) resolving {}",
+               module_to_string(&*module_));
+        let orig_module = replace(&mut self.resolver.current_module, module_.clone());
+        self.resolve_imports_for_module(module_.clone());
+        self.resolver.current_module = orig_module;
+
+        build_reduced_graph::populate_module_if_necessary(self.resolver, &module_);
+        for (_, child_node) in &*module_.children.borrow() {
+            match child_node.get_module_if_available() {
+                None => {
+                    // Nothing to do.
+                }
+                Some(child_module) => {
+                    self.resolve_imports_for_module_subtree(child_module);
+                }
+            }
+        }
+
+        for (_, child_module) in &*module_.anonymous_children.borrow() {
+            self.resolve_imports_for_module_subtree(child_module.clone());
+        }
+    }
+
+    /// Attempts to resolve imports for the given module only.
+    fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
+        if module.all_imports_resolved() {
+            debug!("(resolving imports for module) all imports resolved for \
+                   {}",
+                   module_to_string(&*module));
+            return;
+        }
+
+        let imports = module.imports.borrow();
+        let import_count = imports.len();
+        while module.resolved_import_count.get() < import_count {
+            let import_index = module.resolved_import_count.get();
+            let import_directive = &(*imports)[import_index];
+            match self.resolve_import_for_module(module.clone(),
+                                                 import_directive) {
+                ResolveResult::Failed(err) => {
+                    let (span, help) = match err {
+                        Some((span, msg)) => (span, format!(". {}", msg)),
+                        None => (import_directive.span, String::new())
+                    };
+                    let msg = format!("unresolved import `{}`{}",
+                                      import_path_to_string(
+                                          &import_directive.module_path,
+                                          import_directive.subclass),
+                                      help);
+                    self.resolver.resolve_error(span, &msg[..]);
+                }
+                ResolveResult::Indeterminate => break, // Bail out. We'll come around next time.
+                ResolveResult::Success(()) => () // Good. Continue.
+            }
+
+            module.resolved_import_count
+                  .set(module.resolved_import_count.get() + 1);
+        }
+    }
+
+    /// Attempts to resolve the given import. The return value indicates
+    /// failure if we're certain the name does not exist, indeterminate if we
+    /// don't know whether the name exists at the moment due to other
+    /// currently-unresolved imports, or success if we know the name exists.
+    /// If successful, the resolved bindings are written into the module.
+    fn resolve_import_for_module(&mut self,
+                                 module_: Rc<Module>,
+                                 import_directive: &ImportDirective)
+                                 -> ResolveResult<()> {
+        let mut resolution_result = ResolveResult::Failed(None);
+        let module_path = &import_directive.module_path;
+
+        debug!("(resolving import for module) resolving import `{}::...` in `{}`",
+               names_to_string(&module_path[..]),
+               module_to_string(&*module_));
+
+        // First, resolve the module path for the directive, if necessary.
+        let container = if module_path.len() == 0 {
+            // Use the crate root.
+            Some((self.resolver.graph_root.get_module(), LastMod(AllPublic)))
+        } else {
+            match self.resolver.resolve_module_path(module_.clone(),
+                                                    &module_path[..],
+                                                    UseLexicalScopeFlag::DontUseLexicalScope,
+                                                    import_directive.span,
+                                                    NameSearchType::ImportSearch) {
+                ResolveResult::Failed(err) => {
+                    resolution_result = ResolveResult::Failed(err);
+                    None
+                },
+                ResolveResult::Indeterminate => {
+                    resolution_result = ResolveResult::Indeterminate;
+                    None
+                }
+                ResolveResult::Success(container) => Some(container),
+            }
+        };
+
+        match container {
+            None => {}
+            Some((containing_module, lp)) => {
+                // We found the module that the target is contained
+                // within. Attempt to resolve the import within it.
+
+                match import_directive.subclass {
+                    SingleImport(target, source) => {
+                        resolution_result =
+                            self.resolve_single_import(&module_,
+                                                       containing_module,
+                                                       target,
+                                                       source,
+                                                       import_directive,
+                                                       lp);
+                    }
+                    GlobImport => {
+                        resolution_result =
+                            self.resolve_glob_import(&module_,
+                                                     containing_module,
+                                                     import_directive,
+                                                     lp);
+                    }
+                }
+            }
+        }
+
+        // Decrement the count of unresolved imports.
+        match resolution_result {
+            ResolveResult::Success(()) => {
+                assert!(self.resolver.unresolved_imports >= 1);
+                self.resolver.unresolved_imports -= 1;
+            }
+            _ => {
+                // Nothing to do here; just return the error.
+            }
+        }
+
+        // Decrement the count of unresolved globs if necessary. But only if
+        // the resolution result is indeterminate -- otherwise we'll stop
+        // processing imports here. (See the loop in
+        // resolve_imports_for_module).
+
+        if !resolution_result.indeterminate() {
+            match import_directive.subclass {
+                GlobImport => {
+                    assert!(module_.glob_count.get() >= 1);
+                    module_.glob_count.set(module_.glob_count.get() - 1);
+                }
+                SingleImport(..) => {
+                    // Ignore.
+                }
+            }
+        }
+
+        return resolution_result;
+    }
+
+    fn resolve_single_import(&mut self,
+                             module_: &Module,
+                             target_module: Rc<Module>,
+                             target: Name,
+                             source: Name,
+                             directive: &ImportDirective,
+                             lp: LastPrivate)
+                             -> ResolveResult<()> {
+        debug!("(resolving single import) resolving `{}` = `{}::{}` from \
+                `{}` id {}, last private {:?}",
+               token::get_name(target),
+               module_to_string(&*target_module),
+               token::get_name(source),
+               module_to_string(module_),
+               directive.id,
+               lp);
+
+        let lp = match lp {
+            LastMod(lp) => lp,
+            LastImport {..} => {
+                self.resolver.session
+                    .span_bug(directive.span,
+                              "not expecting Import here, must be LastMod")
+            }
+        };
+
+        // We need to resolve both namespaces for this to succeed.
+        //
+
+        let mut value_result = UnknownResult;
+        let mut type_result = UnknownResult;
+
+        // Search for direct children of the containing module.
+        build_reduced_graph::populate_module_if_necessary(self.resolver, &target_module);
+
+        match target_module.children.borrow().get(&source) {
+            None => {
+                // Continue.
+            }
+            Some(ref child_name_bindings) => {
+                // pub_err makes sure we don't give the same error twice.
+                let mut pub_err = false;
+                if child_name_bindings.defined_in_namespace(ValueNS) {
+                    debug!("(resolving single import) found value binding");
+                    value_result = BoundResult(target_module.clone(),
+                                               (*child_name_bindings).clone());
+                    if directive.is_public && !child_name_bindings.is_public(ValueNS) {
+                        let msg = format!("`{}` is private", token::get_name(source));
+                        span_err!(self.resolver.session, directive.span, E0364, "{}", &msg);
+                        pub_err = true;
+                    }
+                }
+                if child_name_bindings.defined_in_namespace(TypeNS) {
+                    debug!("(resolving single import) found type binding");
+                    type_result = BoundResult(target_module.clone(),
+                                              (*child_name_bindings).clone());
+                    if !pub_err && directive.is_public && !child_name_bindings.is_public(TypeNS) {
+                        let msg = format!("`{}` is private", token::get_name(source));
+                        span_err!(self.resolver.session, directive.span, E0365, "{}", &msg);
+                    }
+                }
+            }
+        }
+
+        // Unless we managed to find a result in both namespaces (unlikely),
+        // search imports as well.
+        let mut value_used_reexport = false;
+        let mut type_used_reexport = false;
+        match (value_result.clone(), type_result.clone()) {
+            (BoundResult(..), BoundResult(..)) => {} // Continue.
+            _ => {
+                // If there is an unresolved glob at this point in the
+                // containing module, bail out. We don't know enough to be
+                // able to resolve this import.
+
+                if target_module.glob_count.get() > 0 {
+                    debug!("(resolving single import) unresolved glob; \
+                            bailing out");
+                    return ResolveResult::Indeterminate;
+                }
+
+                // Now search the exported imports within the containing module.
+                match target_module.import_resolutions.borrow().get(&source) {
+                    None => {
+                        debug!("(resolving single import) no import");
+                        // The containing module definitely doesn't have an
+                        // exported import with the name in question. We can
+                        // therefore accurately report that the names are
+                        // unbound.
+
+                        if value_result.is_unknown() {
+                            value_result = UnboundResult;
+                        }
+                        if type_result.is_unknown() {
+                            type_result = UnboundResult;
+                        }
+                    }
+                    Some(import_resolution)
+                            if import_resolution.outstanding_references == 0 => {
+
+                        fn get_binding(this: &mut Resolver,
+                                       import_resolution: &ImportResolution,
+                                       namespace: Namespace,
+                                       source: &Name)
+                                    -> NamespaceResult {
+
+                            // Import resolutions must be declared with "pub"
+                            // in order to be exported.
+                            if !import_resolution.is_public {
+                                return UnboundResult;
+                            }
+
+                            match import_resolution.target_for_namespace(namespace) {
+                                None => {
+                                    return UnboundResult;
+                                }
+                                Some(Target {
+                                    target_module,
+                                    bindings,
+                                    shadowable: _
+                                }) => {
+                                    debug!("(resolving single import) found \
+                                            import in ns {:?}", namespace);
+                                    let id = import_resolution.id(namespace);
+                                    // track used imports and extern crates as well
+                                    this.used_imports.insert((id, namespace));
+                                    this.record_import_use(id, *source);
+                                    match target_module.def_id.get() {
+                                        Some(DefId{krate: kid, ..}) => {
+                                            this.used_crates.insert(kid);
+                                        },
+                                        _ => {}
+                                    }
+                                    return BoundResult(target_module, bindings);
+                                }
+                            }
+                        }
+
+                        // The name is an import which has been fully
+                        // resolved. We can, therefore, just follow it.
+                        if value_result.is_unknown() {
+                            value_result = get_binding(self.resolver,
+                                                       import_resolution,
+                                                       ValueNS,
+                                                       &source);
+                            value_used_reexport = import_resolution.is_public;
+                        }
+                        if type_result.is_unknown() {
+                            type_result = get_binding(self.resolver,
+                                                      import_resolution,
+                                                      TypeNS,
+                                                      &source);
+                            type_used_reexport = import_resolution.is_public;
+                        }
+
+                    }
+                    Some(_) => {
+                        // If target_module is the same module whose import we are resolving
+                        // and there it has an unresolved import with the same name as `source`,
+                        // then the user is actually trying to import an item that is declared
+                        // in the same scope
+                        //
+                        // e.g
+                        // use self::submodule;
+                        // pub mod submodule;
+                        //
+                        // In this case we continue as if we resolved the import and let the
+                        // check_for_conflicts_between_imports_and_items call below handle
+                        // the conflict
+                        match (module_.def_id.get(),  target_module.def_id.get()) {
+                            (Some(id1), Some(id2)) if id1 == id2  => {
+                                if value_result.is_unknown() {
+                                    value_result = UnboundResult;
+                                }
+                                if type_result.is_unknown() {
+                                    type_result = UnboundResult;
+                                }
+                            }
+                            _ =>  {
+                                // The import is unresolved. Bail out.
+                                debug!("(resolving single import) unresolved import; \
+                                        bailing out");
+                                return ResolveResult::Indeterminate;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        let mut value_used_public = false;
+        let mut type_used_public = false;
+
+        // If we didn't find a result in the type namespace, search the
+        // external modules.
+        match type_result {
+            BoundResult(..) => {}
+            _ => {
+                match target_module.external_module_children.borrow_mut().get(&source).cloned() {
+                    None => {} // Continue.
+                    Some(module) => {
+                        debug!("(resolving single import) found external module");
+                        // track the module as used.
+                        match module.def_id.get() {
+                            Some(DefId{krate: kid, ..}) => {
+                                self.resolver.used_crates.insert(kid);
+                            }
+                            _ => {}
+                        }
+                        let name_bindings =
+                            Rc::new(Resolver::create_name_bindings_from_module(module));
+                        type_result = BoundResult(target_module.clone(), name_bindings);
+                        type_used_public = true;
+                    }
+                }
+            }
+        }
+
+        // We've successfully resolved the import. Write the results in.
+        let mut import_resolutions = module_.import_resolutions.borrow_mut();
+        let import_resolution = import_resolutions.get_mut(&target).unwrap();
+
+        {
+            let mut check_and_write_import = |namespace, result: &_, used_public: &mut bool| {
+                let namespace_name = match namespace {
+                    TypeNS => "type",
+                    ValueNS => "value",
+                };
+
+                match *result {
+                    BoundResult(ref target_module, ref name_bindings) => {
+                        debug!("(resolving single import) found {:?} target: {:?}",
+                               namespace_name,
+                               name_bindings.def_for_namespace(namespace));
+                        self.check_for_conflicting_import(
+                            &import_resolution.target_for_namespace(namespace),
+                            directive.span,
+                            target,
+                            namespace);
+
+                        self.check_that_import_is_importable(
+                            &**name_bindings,
+                            directive.span,
+                            target,
+                            namespace);
+
+                        let target = Some(Target::new(target_module.clone(),
+                                                      name_bindings.clone(),
+                                                      directive.shadowable));
+                        import_resolution.set_target_and_id(namespace, target, directive.id);
+                        import_resolution.is_public = directive.is_public;
+                        *used_public = name_bindings.defined_in_public_namespace(namespace);
+                    }
+                    UnboundResult => { /* Continue. */ }
+                    UnknownResult => {
+                        panic!("{:?} result should be known at this point", namespace_name);
+                    }
+                }
+            };
+            check_and_write_import(ValueNS, &value_result, &mut value_used_public);
+            check_and_write_import(TypeNS, &type_result, &mut type_used_public);
+        }
+
+        self.check_for_conflicts_between_imports_and_items(
+            module_,
+            import_resolution,
+            directive.span,
+            target);
+
+        if value_result.is_unbound() && type_result.is_unbound() {
+            let msg = format!("There is no `{}` in `{}`",
+                              token::get_name(source),
+                              module_to_string(&target_module));
+            return ResolveResult::Failed(Some((directive.span, msg)));
+        }
+        let value_used_public = value_used_reexport || value_used_public;
+        let type_used_public = type_used_reexport || type_used_public;
+
+        assert!(import_resolution.outstanding_references >= 1);
+        import_resolution.outstanding_references -= 1;
+
+        // Record what this import resolves to for later uses in documentation,
+        // this may resolve to either a value or a type, but for documentation
+        // purposes it's good enough to just favor one over the other.
+        let value_def_and_priv = import_resolution.value_target.as_ref().map(|target| {
+            let def = target.bindings.def_for_namespace(ValueNS).unwrap();
+            (def, if value_used_public { lp } else { DependsOn(def.def_id()) })
+        });
+        let type_def_and_priv = import_resolution.type_target.as_ref().map(|target| {
+            let def = target.bindings.def_for_namespace(TypeNS).unwrap();
+            (def, if type_used_public { lp } else { DependsOn(def.def_id()) })
+        });
+
+        let import_lp = LastImport {
+            value_priv: value_def_and_priv.map(|(_, p)| p),
+            value_used: Used,
+            type_priv: type_def_and_priv.map(|(_, p)| p),
+            type_used: Used
+        };
+
+        if let Some((def, _)) = value_def_and_priv {
+            self.resolver.def_map.borrow_mut().insert(directive.id, PathResolution {
+                base_def: def,
+                last_private: import_lp,
+                depth: 0
+            });
+        }
+        if let Some((def, _)) = type_def_and_priv {
+            self.resolver.def_map.borrow_mut().insert(directive.id, PathResolution {
+                base_def: def,
+                last_private: import_lp,
+                depth: 0
+            });
+        }
+
+        debug!("(resolving single import) successfully resolved import");
+        return ResolveResult::Success(());
+    }
+
+    // Resolves a glob import. Note that this function cannot fail; it either
+    // succeeds or bails out (as importing * from an empty module or a module
+    // that exports nothing is valid). target_module is the module we are
+    // actually importing, i.e., `foo` in `use foo::*`.
+    fn resolve_glob_import(&mut self,
+                           module_: &Module,
+                           target_module: Rc<Module>,
+                           import_directive: &ImportDirective,
+                           lp: LastPrivate)
+                           -> ResolveResult<()> {
+        let id = import_directive.id;
+        let is_public = import_directive.is_public;
+
+        // This function works in a highly imperative manner; it eagerly adds
+        // everything it can to the list of import resolutions of the module
+        // node.
+        debug!("(resolving glob import) resolving glob import {}", id);
+
+        // We must bail out if the node has unresolved imports of any kind
+        // (including globs).
+        if !(*target_module).all_imports_resolved() {
+            debug!("(resolving glob import) target module has unresolved \
+                    imports; bailing out");
+            return ResolveResult::Indeterminate;
+        }
+
+        assert_eq!(target_module.glob_count.get(), 0);
+
+        // Add all resolved imports from the containing module.
+        let import_resolutions = target_module.import_resolutions.borrow();
+        for (ident, target_import_resolution) in &*import_resolutions {
+            debug!("(resolving glob import) writing module resolution \
+                    {} into `{}`",
+                   token::get_name(*ident),
+                   module_to_string(module_));
+
+            if !target_import_resolution.is_public {
+                debug!("(resolving glob import) nevermind, just kidding");
+                continue
+            }
+
+            // Here we merge two import resolutions.
+            let mut import_resolutions = module_.import_resolutions.borrow_mut();
+            match import_resolutions.get_mut(ident) {
+                Some(dest_import_resolution) => {
+                    // Merge the two import resolutions at a finer-grained
+                    // level.
+
+                    match target_import_resolution.value_target {
+                        None => {
+                            // Continue.
+                        }
+                        Some(ref value_target) => {
+                            self.check_for_conflicting_import(&dest_import_resolution.value_target,
+                                                              import_directive.span,
+                                                              *ident,
+                                                              ValueNS);
+                            dest_import_resolution.value_target = Some(value_target.clone());
+                        }
+                    }
+                    match target_import_resolution.type_target {
+                        None => {
+                            // Continue.
+                        }
+                        Some(ref type_target) => {
+                            self.check_for_conflicting_import(&dest_import_resolution.type_target,
+                                                              import_directive.span,
+                                                              *ident,
+                                                              TypeNS);
+                            dest_import_resolution.type_target = Some(type_target.clone());
+                        }
+                    }
+                    dest_import_resolution.is_public = is_public;
+                    continue;
+                }
+                None => {}
+            }
+
+            // Simple: just copy the old import resolution.
+            let mut new_import_resolution = ImportResolution::new(id, is_public);
+            new_import_resolution.value_target =
+                target_import_resolution.value_target.clone();
+            new_import_resolution.type_target =
+                target_import_resolution.type_target.clone();
+
+            import_resolutions.insert(*ident, new_import_resolution);
+        }
+
+        // Add all children from the containing module.
+        build_reduced_graph::populate_module_if_necessary(self.resolver, &target_module);
+
+        for (&name, name_bindings) in &*target_module.children.borrow() {
+            self.merge_import_resolution(module_,
+                                         target_module.clone(),
+                                         import_directive,
+                                         name,
+                                         name_bindings.clone());
+
+        }
+
+        // Add external module children from the containing module.
+        for (&name, module) in &*target_module.external_module_children.borrow() {
+            let name_bindings =
+                Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
+            self.merge_import_resolution(module_,
+                                         target_module.clone(),
+                                         import_directive,
+                                         name,
+                                         name_bindings);
+        }
+
+        // Record the destination of this import
+        if let Some(did) = target_module.def_id.get() {
+            self.resolver.def_map.borrow_mut().insert(id, PathResolution {
+                base_def: DefMod(did),
+                last_private: lp,
+                depth: 0
+            });
+        }
+
+        debug!("(resolving glob import) successfully resolved import");
+        return ResolveResult::Success(());
+    }
+
+    fn merge_import_resolution(&mut self,
+                               module_: &Module,
+                               containing_module: Rc<Module>,
+                               import_directive: &ImportDirective,
+                               name: Name,
+                               name_bindings: Rc<NameBindings>) {
+        let id = import_directive.id;
+        let is_public = import_directive.is_public;
+
+        let mut import_resolutions = module_.import_resolutions.borrow_mut();
+        let dest_import_resolution = import_resolutions.entry(name)
+            .or_insert_with(|| ImportResolution::new(id, is_public));
+
+        debug!("(resolving glob import) writing resolution `{}` in `{}` \
+               to `{}`",
+               &token::get_name(name),
+               module_to_string(&*containing_module),
+               module_to_string(module_));
+
+        // Merge the child item into the import resolution.
+        {
+            let mut merge_child_item = |namespace| {
+                if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
+                    let namespace_name = match namespace {
+                        TypeNS => "type",
+                        ValueNS => "value",
+                    };
+                    debug!("(resolving glob import) ... for {} target", namespace_name);
+                    if dest_import_resolution.shadowable(namespace) == Shadowable::Never {
+                        let msg = format!("a {} named `{}` has already been imported \
+                                           in this module",
+                                          namespace_name,
+                                          &token::get_name(name));
+                        span_err!(self.resolver.session, import_directive.span, E0251, "{}", msg);
+                    } else {
+                        let target = Target::new(containing_module.clone(),
+                                                 name_bindings.clone(),
+                                                 import_directive.shadowable);
+                        dest_import_resolution.set_target_and_id(namespace,
+                                                                 Some(target),
+                                                                 id);
+                    }
+                }
+            };
+            merge_child_item(ValueNS);
+            merge_child_item(TypeNS);
+        }
+
+        dest_import_resolution.is_public = is_public;
+
+        self.check_for_conflicts_between_imports_and_items(
+            module_,
+            dest_import_resolution,
+            import_directive.span,
+            name);
+    }
+
+    /// Checks that imported names and items don't have the same name.
+    fn check_for_conflicting_import(&mut self,
+                                    target: &Option<Target>,
+                                    import_span: Span,
+                                    name: Name,
+                                    namespace: Namespace) {
+        debug!("check_for_conflicting_import: {}; target exists: {}",
+               &token::get_name(name),
+               target.is_some());
+
+        match *target {
+            Some(ref target) if target.shadowable != Shadowable::Always => {
+                let msg = format!("a {} named `{}` has already been imported \
+                                   in this module",
+                                  match namespace {
+                                    TypeNS => "type",
+                                    ValueNS => "value",
+                                  },
+                                  &token::get_name(name));
+                span_err!(self.resolver.session, import_span, E0252, "{}", &msg[..]);
+            }
+            Some(_) | None => {}
+        }
+    }
+
+    /// Checks that an import is actually importable
+    fn check_that_import_is_importable(&mut self,
+                                       name_bindings: &NameBindings,
+                                       import_span: Span,
+                                       name: Name,
+                                       namespace: Namespace) {
+        if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
+            let msg = format!("`{}` is not directly importable",
+                              token::get_name(name));
+            span_err!(self.resolver.session, import_span, E0253, "{}", &msg[..]);
+        }
+    }
+
+    /// Checks that imported names and items don't have the same name.
+    fn check_for_conflicts_between_imports_and_items(&mut self,
+                                                     module: &Module,
+                                                     import_resolution:
+                                                     &ImportResolution,
+                                                     import_span: Span,
+                                                     name: Name) {
+        // First, check for conflicts between imports and `extern crate`s.
+        if module.external_module_children
+                 .borrow()
+                 .contains_key(&name) {
+            match import_resolution.type_target {
+                Some(ref target) if target.shadowable != Shadowable::Always => {
+                    let msg = format!("import `{0}` conflicts with imported \
+                                       crate in this module \
+                                       (maybe you meant `use {0}::*`?)",
+                                      &token::get_name(name));
+                    span_err!(self.resolver.session, import_span, E0254, "{}", &msg[..]);
+                }
+                Some(_) | None => {}
+            }
+        }
+
+        // Check for item conflicts.
+        let children = module.children.borrow();
+        let name_bindings = match children.get(&name) {
+            None => {
+                // There can't be any conflicts.
+                return
+            }
+            Some(ref name_bindings) => (*name_bindings).clone(),
+        };
+
+        match import_resolution.value_target {
+            Some(ref target) if target.shadowable != Shadowable::Always => {
+                if let Some(ref value) = *name_bindings.value_def.borrow() {
+                    span_err!(self.resolver.session, import_span, E0255,
+                              "import `{}` conflicts with value in this module",
+                              &token::get_name(name));
+                    if let Some(span) = value.value_span {
+                        self.resolver.session.span_note(span, "conflicting value here");
+                    }
+                }
+            }
+            Some(_) | None => {}
+        }
+
+        match import_resolution.type_target {
+            Some(ref target) if target.shadowable != Shadowable::Always => {
+                if let Some(ref ty) = *name_bindings.type_def.borrow() {
+                    let (what, note) = if ty.module_def.is_some() {
+                        ("existing submodule", "note conflicting module here")
+                    } else {
+                        ("type in this module", "note conflicting type here")
+                    };
+                    span_err!(self.resolver.session, import_span, E0256,
+                              "import `{}` conflicts with {}",
+                              &token::get_name(name), what);
+                    if let Some(span) = ty.type_span {
+                        self.resolver.session.span_note(span, note);
+                    }
+                }
+            }
+            Some(_) | None => {}
+        }
+    }
+}
+
+fn import_path_to_string(names: &[Name],
+                         subclass: ImportDirectiveSubclass)
+                         -> String {
+    if names.is_empty() {
+        import_directive_subclass_to_string(subclass)
+    } else {
+        (format!("{}::{}",
+                 names_to_string(names),
+                 import_directive_subclass_to_string(subclass))).to_string()
+    }
+}
+
+fn import_directive_subclass_to_string(subclass: ImportDirectiveSubclass) -> String {
+    match subclass {
+        SingleImport(_, source) => {
+            token::get_name(source).to_string()
+        }
+        GlobImport => "*".to_string()
+    }
+}
+
+pub fn resolve_imports(resolver: &mut Resolver) {
+    let mut import_resolver = ImportResolver {
+        resolver: resolver,
+    };
+    import_resolver.resolve_imports();
+}
index 3904db4433c892a69bffc712ea2d01afa73788c0..1f416d5404d2778d0fdea4768371232068e2bae8 100644 (file)
@@ -1 +1 @@
-See the README.txt in ../librustc.
+See the README.md in ../librustc.
index ef849bb3dca056348147adbf6a0a154e5c9d2dd4..ad777351898912f6608370e51c4c63c78e477309 100644 (file)
@@ -26,13 +26,15 @@ use middle::ty::{self, Ty};
 use util::common::time;
 use util::ppaux;
 use util::sha2::{Digest, Sha256};
+use rustc_back::tempdir::TempDir;
 
-use std::old_io::fs::PathExtensions;
-use std::old_io::{fs, TempDir, Command};
-use std::old_io;
+use std::ffi::OsString;
+use std::fs::{self, PathExt};
+use std::io::{self, Read, Write};
 use std::mem;
+use std::path::{Path, PathBuf};
+use std::process::Command;
 use std::str;
-use std::string::String;
 use flate;
 use serialize::hex::ToHex;
 use syntax::ast;
@@ -58,16 +60,16 @@ pub const RLIB_BYTECODE_OBJECT_MAGIC: &'static [u8] = b"RUST_OBJECT";
 pub const RLIB_BYTECODE_OBJECT_VERSION: u32 = 1;
 
 // The offset in bytes the bytecode object format version number can be found at
-pub const RLIB_BYTECODE_OBJECT_VERSION_OFFSET: uint = 11;
+pub const RLIB_BYTECODE_OBJECT_VERSION_OFFSET: usize = 11;
 
 // The offset in bytes the size of the compressed bytecode can be found at in
 // format version 1
-pub const RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET: uint =
+pub const RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET: usize =
     RLIB_BYTECODE_OBJECT_VERSION_OFFSET + 4;
 
 // The offset in bytes the compressed LLVM bytecode can be found at in format
 // version 1
-pub const RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: uint =
+pub const RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: usize =
     RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET + 8;
 
 
@@ -156,12 +158,20 @@ pub fn find_crate_name(sess: Option<&Session>,
         return validate(s.to_string(), Some(attr.span));
     }
     if let Input::File(ref path) = *input {
-        if let Some(s) = path.filestem_str() {
-            return validate(s.to_string(), None);
+        if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
+            if s.starts_with("-") {
+                let msg = format!("crate names cannot start with a `-`, but \
+                                   `{}` has a leading hyphen", s);
+                if let Some(sess) = sess {
+                    sess.err(&msg);
+                }
+            } else {
+                return validate(s.replace("-", "_"), None);
+            }
         }
     }
 
-    "rust-out".to_string()
+    "rust_out".to_string()
 }
 
 pub fn build_link_meta(sess: &Session, krate: &ast::Crate,
@@ -191,17 +201,17 @@ fn symbol_hash<'tcx>(tcx: &ty::ctxt<'tcx>,
     // to be independent of one another in the crate.
 
     symbol_hasher.reset();
-    symbol_hasher.input_str(&link_meta.crate_name[]);
+    symbol_hasher.input_str(&link_meta.crate_name);
     symbol_hasher.input_str("-");
     symbol_hasher.input_str(link_meta.crate_hash.as_str());
     for meta in &*tcx.sess.crate_metadata.borrow() {
         symbol_hasher.input_str(&meta[..]);
     }
     symbol_hasher.input_str("-");
-    symbol_hasher.input_str(&encoder::encoded_ty(tcx, t)[]);
+    symbol_hasher.input_str(&encoder::encoded_ty(tcx, t));
     // Prefix with 'h' so that it never blends into adjacent digits
     let mut hash = String::from_str("h");
-    hash.push_str(&truncated_hash_result(symbol_hasher)[]);
+    hash.push_str(&truncated_hash_result(symbol_hasher));
     hash
 }
 
@@ -288,7 +298,7 @@ pub fn mangle<PI: Iterator<Item=PathElem>>(path: PI,
 
     fn push(n: &mut String, s: &str) {
         let sani = sanitize(s);
-        n.push_str(&format!("{}{}", sani.len(), sani)[]);
+        n.push_str(&format!("{}{}", sani.len(), sani));
     }
 
     // First, connect each component with <len, name> pairs.
@@ -317,11 +327,11 @@ pub fn mangle_exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, path: PathEl
     // e.g. `fn foo() { { fn a() {} } { fn a() {} } }`, so we
     // generate unique characters from the node id. For now
     // hopefully 3 characters is enough to avoid collisions.
-    static EXTRA_CHARS: &'static str =
+    const EXTRA_CHARS: &'static str =
         "abcdefghijklmnopqrstuvwxyz\
          ABCDEFGHIJKLMNOPQRSTUVWXYZ\
          0123456789";
-    let id = id as uint;
+    let id = id as usize;
     let extra1 = id % EXTRA_CHARS.len();
     let id = id / EXTRA_CHARS.len();
     let extra2 = id % EXTRA_CHARS.len();
@@ -356,12 +366,12 @@ pub fn get_cc_prog(sess: &Session) -> String {
 }
 
 pub fn remove(sess: &Session, path: &Path) {
-    match fs::unlink(path) {
+    match fs::remove_file(path) {
         Ok(..) => {}
         Err(e) => {
             sess.err(&format!("failed to remove {}: {}",
                              path.display(),
-                             e)[]);
+                             e));
         }
     }
 }
@@ -371,12 +381,12 @@ pub fn remove(sess: &Session, path: &Path) {
 pub fn link_binary(sess: &Session,
                    trans: &CrateTranslation,
                    outputs: &OutputFilenames,
-                   crate_name: &str) -> Vec<Path> {
+                   crate_name: &str) -> Vec<PathBuf> {
     let mut out_filenames = Vec::new();
     for &crate_type in &*sess.crate_types.borrow() {
         if invalid_output_for_target(sess, crate_type) {
             sess.bug(&format!("invalid output type `{:?}` for target os `{}`",
-                             crate_type, sess.opts.target_triple)[]);
+                             crate_type, sess.opts.target_triple));
         }
         let out_file = link_binary_output(sess, trans, crate_type, outputs,
                                           crate_name);
@@ -425,35 +435,39 @@ pub fn invalid_output_for_target(sess: &Session,
 }
 
 fn is_writeable(p: &Path) -> bool {
-    match p.stat() {
+    match p.metadata() {
         Err(..) => true,
-        Ok(m) => m.perm & old_io::USER_WRITE == old_io::USER_WRITE
+        Ok(m) => !m.permissions().readonly()
     }
 }
 
 pub fn filename_for_input(sess: &Session,
                           crate_type: config::CrateType,
                           name: &str,
-                          out_filename: &Path) -> Path {
+                          out_filename: &Path) -> PathBuf {
     let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
     match crate_type {
         config::CrateTypeRlib => {
-            out_filename.with_filename(format!("lib{}.rlib", libname))
+            out_filename.with_file_name(&format!("lib{}.rlib", libname))
         }
         config::CrateTypeDylib => {
-            let (prefix, suffix) = (&sess.target.target.options.dll_prefix[],
-                                    &sess.target.target.options.dll_suffix[]);
-            out_filename.with_filename(format!("{}{}{}",
-                                               prefix,
-                                               libname,
-                                               suffix))
+            let (prefix, suffix) = (&sess.target.target.options.dll_prefix,
+                                    &sess.target.target.options.dll_suffix);
+            out_filename.with_file_name(&format!("{}{}{}",
+                                                  prefix,
+                                                 libname,
+                                                 suffix))
         }
         config::CrateTypeStaticlib => {
-            out_filename.with_filename(format!("lib{}.a", libname))
+            out_filename.with_file_name(&format!("lib{}.a", libname))
         }
         config::CrateTypeExecutable => {
-            let suffix = &sess.target.target.options.exe_suffix[];
-            out_filename.with_filename(format!("{}{}", libname, suffix))
+            let suffix = &sess.target.target.options.exe_suffix;
+            if suffix.len() == 0 {
+                out_filename.to_path_buf()
+            } else {
+                out_filename.with_extension(&suffix[1..])
+            }
         }
     }
 }
@@ -462,7 +476,7 @@ fn link_binary_output(sess: &Session,
                       trans: &CrateTranslation,
                       crate_type: config::CrateType,
                       outputs: &OutputFilenames,
-                      crate_name: &str) -> Path {
+                      crate_name: &str) -> PathBuf {
     let obj_filename = outputs.temp_path(OutputTypeObject);
     let out_filename = match outputs.single_output_file {
         Some(ref file) => file.clone(),
@@ -481,12 +495,12 @@ fn link_binary_output(sess: &Session,
     if !out_is_writeable {
         sess.fatal(&format!("output file {} is not writeable -- check its \
                             permissions.",
-                           out_filename.display())[]);
+                           out_filename.display()));
     }
     else if !obj_is_writeable {
         sess.fatal(&format!("object file {} is not writeable -- check its \
                             permissions.",
-                           obj_filename.display())[]);
+                           obj_filename.display()));
     }
 
     match crate_type {
@@ -507,10 +521,10 @@ fn link_binary_output(sess: &Session,
     out_filename
 }
 
-fn archive_search_paths(sess: &Session) -> Vec<Path> {
+fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
     let mut search = Vec::new();
     sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
-        search.push(path.clone());
+        search.push(path.to_path_buf());
         FileDoesntMatch
     });
     return search;
@@ -529,7 +543,7 @@ fn link_rlib<'a>(sess: &'a Session,
     let handler = &sess.diagnostic().handler;
     let config = ArchiveConfig {
         handler: handler,
-        dst: out_filename.clone(),
+        dst: out_filename.to_path_buf(),
         lib_search_paths: archive_search_paths(sess),
         slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
         slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
@@ -588,12 +602,14 @@ fn link_rlib<'a>(sess: &'a Session,
             // the same filename for metadata (stomping over one another)
             let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir");
             let metadata = tmpdir.path().join(METADATA_FILENAME);
-            match fs::File::create(&metadata).write_all(&trans.metadata[]) {
+            match fs::File::create(&metadata).and_then(|mut f| {
+                f.write_all(&trans.metadata)
+            }) {
                 Ok(..) => {}
                 Err(e) => {
                     sess.err(&format!("failed to write {}: {}",
                                      metadata.display(),
-                                     e)[]);
+                                     e));
                     sess.abort_if_errors();
                 }
             }
@@ -611,34 +627,33 @@ fn link_rlib<'a>(sess: &'a Session,
                 // was exactly 16 bytes.
                 let bc_filename = obj_filename.with_extension(&format!("{}.bc", i));
                 let bc_deflated_filename = obj_filename.with_extension(
-                    &format!("{}.bytecode.deflate", i)[]);
+                    &format!("{}.bytecode.deflate", i));
 
-                let bc_data = match fs::File::open(&bc_filename).read_to_end() {
-                    Ok(buffer) => buffer,
+                let mut bc_data = Vec::new();
+                match fs::File::open(&bc_filename).and_then(|mut f| {
+                    f.read_to_end(&mut bc_data)
+                }) {
+                    Ok(..) => {}
                     Err(e) => sess.fatal(&format!("failed to read bytecode: {}",
-                                                 e)[])
-                };
+                                                 e))
+                }
 
-                let bc_data_deflated = match flate::deflate_bytes(&bc_data[..]) {
-                    Some(compressed) => compressed,
-                    None => sess.fatal(&format!("failed to compress bytecode from {}",
-                                               bc_filename.display())[])
-                };
+                let bc_data_deflated = flate::deflate_bytes(&bc_data[..]);
 
                 let mut bc_file_deflated = match fs::File::create(&bc_deflated_filename) {
                     Ok(file) => file,
                     Err(e) => {
-                        sess.fatal(&format!("failed to create compressed bytecode \
-                                            file: {}", e)[])
+                        sess.fatal(&format!("failed to create compressed \
+                                             bytecode file: {}", e))
                     }
                 };
 
                 match write_rlib_bytecode_object_v1(&mut bc_file_deflated,
-                                                    bc_data_deflated.as_slice()) {
+                                                    &bc_data_deflated) {
                     Ok(()) => {}
                     Err(e) => {
                         sess.err(&format!("failed to write compressed bytecode: \
-                                          {}", e)[]);
+                                          {}", e));
                         sess.abort_if_errors()
                     }
                 };
@@ -670,27 +685,35 @@ fn link_rlib<'a>(sess: &'a Session,
     ab
 }
 
-fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T,
-                                            bc_data_deflated: &[u8])
-                                         -> ::std::old_io::IoResult<()> {
+fn write_rlib_bytecode_object_v1(writer: &mut Write,
+                                 bc_data_deflated: &[u8]) -> io::Result<()> {
     let bc_data_deflated_size: u64 = bc_data_deflated.len() as u64;
 
-    try! { writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC) };
-    try! { writer.write_le_u32(1) };
-    try! { writer.write_le_u64(bc_data_deflated_size) };
-    try! { writer.write_all(&bc_data_deflated[..]) };
+    try!(writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC));
+    try!(writer.write_all(&[1, 0, 0, 0]));
+    try!(writer.write_all(&[
+        (bc_data_deflated_size >>  0) as u8,
+        (bc_data_deflated_size >>  8) as u8,
+        (bc_data_deflated_size >> 16) as u8,
+        (bc_data_deflated_size >> 24) as u8,
+        (bc_data_deflated_size >> 32) as u8,
+        (bc_data_deflated_size >> 40) as u8,
+        (bc_data_deflated_size >> 48) as u8,
+        (bc_data_deflated_size >> 56) as u8,
+    ]));
+    try!(writer.write_all(&bc_data_deflated));
 
     let number_of_bytes_written_so_far =
         RLIB_BYTECODE_OBJECT_MAGIC.len() +                // magic id
         mem::size_of_val(&RLIB_BYTECODE_OBJECT_VERSION) + // version
         mem::size_of_val(&bc_data_deflated_size) +        // data size field
-        bc_data_deflated_size as uint;                    // actual data
+        bc_data_deflated_size as usize;                    // actual data
 
     // If the number of bytes written to the object so far is odd, add a
     // padding byte to make it even. This works around a crash bug in LLDB
     // (see issue #15950)
     if number_of_bytes_written_so_far % 2 == 1 {
-        try! { writer.write_u8(0) };
+        try!(writer.write_all(&[0]));
     }
 
     return Ok(());
@@ -729,7 +752,7 @@ fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
         let p = match *path {
             Some(ref p) => p.clone(), None => {
                 sess.err(&format!("could not find rlib for: `{}`",
-                                 name)[]);
+                                 name));
                 continue
             }
         };
@@ -755,7 +778,7 @@ fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
             cstore::NativeUnknown => "library",
             cstore::NativeFramework => "framework",
         };
-        sess.note(&format!("{}: {}", name, *lib)[]);
+        sess.note(&format!("{}: {}", name, *lib));
     }
 }
 
@@ -771,10 +794,10 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
     let pname = get_cc_prog(sess);
     let mut cmd = Command::new(&pname[..]);
 
-    cmd.args(&sess.target.target.options.pre_link_args[]);
+    cmd.args(&sess.target.target.options.pre_link_args);
     link_args(&mut cmd, sess, dylib, tmpdir.path(),
               trans, obj_filename, out_filename);
-    cmd.args(&sess.target.target.options.post_link_args[]);
+    cmd.args(&sess.target.target.options.post_link_args);
     if !sess.target.target.options.no_compiler_rt {
         cmd.arg("-lcompiler-rt");
     }
@@ -794,20 +817,20 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
             if !prog.status.success() {
                 sess.err(&format!("linking with `{}` failed: {}",
                                  pname,
-                                 prog.status)[]);
-                sess.note(&format!("{:?}", &cmd)[]);
-                let mut output = prog.error.clone();
-                output.push_all(&prog.output[]);
+                                 prog.status));
+                sess.note(&format!("{:?}", &cmd));
+                let mut output = prog.stderr.clone();
+                output.push_all(&prog.stdout);
                 sess.note(str::from_utf8(&output[..]).unwrap());
                 sess.abort_if_errors();
             }
-            debug!("linker stderr:\n{}", String::from_utf8(prog.error).unwrap());
-            debug!("linker stdout:\n{}", String::from_utf8(prog.output).unwrap());
+            debug!("linker stderr:\n{}", String::from_utf8(prog.stderr).unwrap());
+            debug!("linker stdout:\n{}", String::from_utf8(prog.stdout).unwrap());
         },
         Err(e) => {
             sess.err(&format!("could not exec the linker `{}`: {}",
                              pname,
-                             e)[]);
+                             e));
             sess.abort_if_errors();
         }
     }
@@ -819,7 +842,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
         match Command::new("dsymutil").arg(out_filename).output() {
             Ok(..) => {}
             Err(e) => {
-                sess.err(&format!("failed to run dsymutil: {}", e)[]);
+                sess.err(&format!("failed to run dsymutil: {}", e));
                 sess.abort_if_errors();
             }
         }
@@ -866,9 +889,9 @@ fn link_args(cmd: &mut Command,
         if t.options.is_like_osx {
             let morestack = lib_path.join("libmorestack.a");
 
-            let mut v = b"-Wl,-force_load,".to_vec();
-            v.push_all(morestack.as_vec());
-            cmd.arg(&v[..]);
+            let mut v = OsString::from("-Wl,-force_load,");
+            v.push(&morestack);
+            cmd.arg(&v);
         } else {
             cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]);
         }
@@ -878,7 +901,7 @@ fn link_args(cmd: &mut Command,
     // executable. This metadata is in a separate object file from the main
     // object file, so we link that in here.
     if dylib {
-        cmd.arg(obj_filename.with_extension("metadata.o"));
+        cmd.arg(&obj_filename.with_extension("metadata.o"));
     }
 
     if t.options.is_like_osx {
@@ -991,9 +1014,9 @@ fn link_args(cmd: &mut Command,
             cmd.args(&["-dynamiclib", "-Wl,-dylib"]);
 
             if sess.opts.cg.rpath {
-                let mut v = "-Wl,-install_name,@rpath/".as_bytes().to_vec();
-                v.push_all(out_filename.filename().unwrap());
-                cmd.arg(&v[..]);
+                let mut v = OsString::from("-Wl,-install_name,@rpath/");
+                v.push(out_filename.file_name().unwrap());
+                cmd.arg(&v);
             }
         } else {
             cmd.arg("-shared");
@@ -1005,30 +1028,30 @@ fn link_args(cmd: &mut Command,
     // addl_lib_search_paths
     if sess.opts.cg.rpath {
         let sysroot = sess.sysroot();
-        let target_triple = &sess.opts.target_triple[];
-        let get_install_prefix_lib_path = || {
+        let target_triple = &sess.opts.target_triple;
+        let mut get_install_prefix_lib_path = || {
             let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
             let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
-            let mut path = Path::new(install_prefix);
+            let mut path = PathBuf::from(install_prefix);
             path.push(&tlib);
 
             path
         };
-        let rpath_config = RPathConfig {
+        let mut rpath_config = RPathConfig {
             used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic),
-            out_filename: out_filename.clone(),
+            out_filename: out_filename.to_path_buf(),
             has_rpath: sess.target.target.options.has_rpath,
             is_like_osx: sess.target.target.options.is_like_osx,
-            get_install_prefix_lib_path: get_install_prefix_lib_path,
-            realpath: ::util::fs::realpath
+            get_install_prefix_lib_path: &mut get_install_prefix_lib_path,
+            realpath: &mut ::util::fs::realpath
         };
-        cmd.args(&rpath::get_rpath_flags(rpath_config)[]);
+        cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
     }
 
     // Finally add all the linker arguments provided on the command line along
     // with any #[link_args] attributes found inside the crate
     let empty = Vec::new();
-    cmd.args(&sess.opts.cg.link_args.as_ref().unwrap_or(&empty)[]);
+    cmd.args(&sess.opts.cg.link_args.as_ref().unwrap_or(&empty));
     cmd.args(&used_link_args[..]);
 }
 
@@ -1082,7 +1105,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
     let search_path = archive_search_paths(sess);
     for l in staticlibs {
         if takes_hints {
-            cmd.arg(format!("-l{}", l));
+            cmd.arg(&format!("-l{}", l));
         } else {
             // -force_load is the OSX equivalent of --whole-archive, but it
             // involves passing the full path to the library to link.
@@ -1091,9 +1114,9 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
                                             &sess.target.target.options.staticlib_suffix,
                                             &search_path[..],
                                             &sess.diagnostic().handler);
-            let mut v = b"-Wl,-force_load,".to_vec();
-            v.push_all(lib.as_vec());
-            cmd.arg(&v[..]);
+            let mut v = OsString::from("-Wl,-force_load,");
+            v.push(&lib);
+            cmd.arg(&v);
         }
     }
     if takes_hints {
@@ -1103,7 +1126,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
     for &(ref l, kind) in others {
         match kind {
             cstore::NativeUnknown => {
-                cmd.arg(format!("-l{}", l));
+                cmd.arg(&format!("-l{}", l));
             }
             cstore::NativeFramework => {
                 cmd.arg("-framework").arg(&l[..]);
@@ -1130,9 +1153,9 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
     // involves just passing the right -l flag.
 
     let data = if dylib {
-        &trans.crate_formats[config::CrateTypeDylib]
+        trans.crate_formats.get(&config::CrateTypeDylib).unwrap()
     } else {
-        &trans.crate_formats[config::CrateTypeExecutable]
+        trans.crate_formats.get(&config::CrateTypeExecutable).unwrap()
     };
 
     // Invoke get_used_crates to ensure that we get a topological sorting of
@@ -1143,25 +1166,25 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
         // We may not pass all crates through to the linker. Some crates may
         // appear statically in an existing dylib, meaning we'll pick up all the
         // symbols from the dylib.
-        let kind = match data[cnum as uint - 1] {
+        let kind = match data[cnum as usize - 1] {
             Some(t) => t,
             None => continue
         };
         let src = sess.cstore.get_used_crate_source(cnum).unwrap();
         match kind {
             cstore::RequireDynamic => {
-                add_dynamic_crate(cmd, sess, src.dylib.unwrap().0)
+                add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0)
             }
             cstore::RequireStatic => {
-                add_static_crate(cmd, sess, tmpdir, src.rlib.unwrap().0)
+                add_static_crate(cmd, sess, tmpdir, &src.rlib.unwrap().0)
             }
         }
 
     }
 
     // Converts a library file-stem into a cc -l argument
-    fn unlib<'a>(config: &config::Config, stem: &'a [u8]) -> &'a [u8] {
-        if stem.starts_with("lib".as_bytes()) && !config.target.options.is_like_windows {
+    fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str {
+        if stem.starts_with("lib") && !config.target.options.is_like_windows {
             &stem[3..]
         } else {
             stem
@@ -1170,7 +1193,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
 
     // Adds the static "rlib" versions of all crates to the command line.
     fn add_static_crate(cmd: &mut Command, sess: &Session, tmpdir: &Path,
-                        cratepath: Path) {
+                        cratepath: &Path) {
         // When performing LTO on an executable output, all of the
         // bytecode from the upstream libraries has already been
         // included in our object file output. We need to modify all of
@@ -1186,31 +1209,35 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
         // If we're not doing LTO, then our job is simply to just link
         // against the archive.
         if sess.lto() {
-            let name = cratepath.filename_str().unwrap();
+            let name = cratepath.file_name().unwrap().to_str().unwrap();
             let name = &name[3..name.len() - 5]; // chop off lib/.rlib
             time(sess.time_passes(),
-                 &format!("altering {}.rlib", name)[],
+                 &format!("altering {}.rlib", name),
                  (), |()| {
-                let dst = tmpdir.join(cratepath.filename().unwrap());
+                let dst = tmpdir.join(cratepath.file_name().unwrap());
                 match fs::copy(&cratepath, &dst) {
                     Ok(..) => {}
                     Err(e) => {
                         sess.err(&format!("failed to copy {} to {}: {}",
                                          cratepath.display(),
                                          dst.display(),
-                                         e)[]);
+                                         e));
                         sess.abort_if_errors();
                     }
                 }
                 // Fix up permissions of the copy, as fs::copy() preserves
                 // permissions, but the original file may have been installed
                 // by a package manager and may be read-only.
-                match fs::chmod(&dst, old_io::USER_READ | old_io::USER_WRITE) {
+                match fs::metadata(&dst).and_then(|m| {
+                    let mut perms = m.permissions();
+                    perms.set_readonly(false);
+                    fs::set_permissions(&dst, perms)
+                }) {
                     Ok(..) => {}
                     Err(e) => {
                         sess.err(&format!("failed to chmod {} when preparing \
                                           for LTO: {}", dst.display(),
-                                         e)[]);
+                                         e));
                         sess.abort_if_errors();
                     }
                 }
@@ -1224,10 +1251,10 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
                     maybe_ar_prog: sess.opts.cg.ar.clone()
                 };
                 let mut archive = Archive::open(config);
-                archive.remove_file(&format!("{}.o", name)[]);
+                archive.remove_file(&format!("{}.o", name));
                 let files = archive.files();
-                if files.iter().any(|s| s[].ends_with(".o")) {
-                    cmd.arg(dst);
+                if files.iter().any(|s| s.ends_with(".o")) {
+                    cmd.arg(&dst);
                 }
             });
         } else {
@@ -1236,19 +1263,18 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
     }
 
     // Same thing as above, but for dynamic crates instead of static crates.
-    fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: Path) {
+    fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: &Path) {
         // If we're performing LTO, then it should have been previously required
         // that all upstream rust dependencies were available in an rlib format.
         assert!(!sess.lto());
 
         // Just need to tell the linker about where the library lives and
         // what its name is
-        let dir = cratepath.dirname();
-        if !dir.is_empty() { cmd.arg("-L").arg(dir); }
-
-        let mut v = "-l".as_bytes().to_vec();
-        v.push_all(unlib(&sess.target, cratepath.filestem().unwrap()));
-        cmd.arg(&v[..]);
+        if let Some(dir) = cratepath.parent() {
+            cmd.arg("-L").arg(dir);
+        }
+        let filestem = cratepath.file_stem().unwrap().to_str().unwrap();
+        cmd.arg(&format!("-l{}", unlib(&sess.target, filestem)));
     }
 }
 
@@ -1286,7 +1312,7 @@ fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) {
         for &(kind, ref lib) in &libs {
             match kind {
                 cstore::NativeUnknown => {
-                    cmd.arg(format!("-l{}", *lib));
+                    cmd.arg(&format!("-l{}", *lib));
                 }
                 cstore::NativeFramework => {
                     cmd.arg("-framework");
index 0a0f2a9c18627adeb821ca15e03c7f21b881119d..4e099a4ca875e1b6873ad1aa59006b9ea1e58fb2 100644 (file)
@@ -21,8 +21,8 @@ use libc;
 use flate;
 
 use std::ffi::CString;
-use std::iter;
 use std::mem;
+#[allow(deprecated)]
 use std::num::Int;
 
 pub fn run(sess: &session::Session, llmod: ModuleRef,
@@ -54,21 +54,21 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
             Some(p) => p,
             None => {
                 sess.fatal(&format!("could not find rlib for: `{}`",
-                                   name)[]);
+                                   name));
             }
         };
 
         let archive = ArchiveRO::open(&path).expect("wanted an rlib");
-        let file = path.filename_str().unwrap();
+        let file = path.file_name().unwrap().to_str().unwrap();
         let file = &file[3..file.len() - 5]; // chop off lib/.rlib
         debug!("reading {}", file);
-        for i in iter::count(0, 1) {
+        for i in 0.. {
             let bc_encoded = time(sess.time_passes(),
                                   &format!("check for {}.{}.bytecode.deflate", name, i),
                                   (),
                                   |_| {
                                       archive.read(&format!("{}.{}.bytecode.deflate",
-                                                           file, i)[])
+                                                           file, i))
                                   });
             let bc_encoded = match bc_encoded {
                 Some(data) => data,
@@ -76,7 +76,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                     if i == 0 {
                         // No bitcode was found at all.
                         sess.fatal(&format!("missing compressed bytecode in {}",
-                                           path.display())[]);
+                                           path.display()));
                     }
                     // No more bitcode files to read.
                     break;
@@ -93,18 +93,18 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                         let data_size = extract_compressed_bytecode_size_v1(bc_encoded);
                         let compressed_data = &bc_encoded[
                             link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET..
-                            (link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET + data_size as uint)];
+                            (link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET + data_size as usize)];
 
                         match flate::inflate_bytes(compressed_data) {
-                            Some(inflated) => inflated,
-                            None => {
+                            Ok(inflated) => inflated,
+                            Err(_) => {
                                 sess.fatal(&format!("failed to decompress bc of `{}`",
-                                                   name)[])
+                                                   name))
                             }
                         }
                     } else {
                         sess.fatal(&format!("Unsupported bytecode format version {}",
-                                           version)[])
+                                           version))
                     }
                 })
             } else {
@@ -112,10 +112,10 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                 // the object must be in the old, pre-versioning format, so simply
                 // inflate everything and let LLVM decide if it can make sense of it
                     match flate::inflate_bytes(bc_encoded) {
-                        Some(bc) => bc,
-                        None => {
+                        Ok(bc) => bc,
+                        Err(_) => {
                             sess.fatal(&format!("failed to decompress bc of `{}`",
-                                               name)[])
+                                               name))
                         }
                     }
                 })
@@ -124,7 +124,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
             let ptr = bc_decoded.as_ptr();
             debug!("linking {}, part {}", name, i);
             time(sess.time_passes(),
-                 &format!("ll link {}.{}", name, i)[],
+                 &format!("ll link {}.{}", name, i),
                  (),
                  |()| unsafe {
                 if !llvm::LLVMRustLinkInExternalBitcode(llmod,
@@ -167,7 +167,12 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
         llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod);
         llvm::LLVMRustAddPass(pm, "verify\0".as_ptr() as *const _);
 
-        let opt = sess.opts.cg.opt_level.unwrap_or(0) as libc::c_uint;
+        let opt = match sess.opts.optimize {
+            config::No => 0,
+            config::Less => 1,
+            config::Default => 2,
+            config::Aggressive => 3,
+        };
 
         let builder = llvm::LLVMPassManagerBuilderCreate();
         llvm::LLVMPassManagerBuilderSetOptLevel(builder, opt);
@@ -200,7 +205,8 @@ fn extract_compressed_bytecode_size_v1(bc: &[u8]) -> u64 {
     return read_from_le_bytes::<u64>(bc, link::RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET);
 }
 
-fn read_from_le_bytes<T: Int>(bytes: &[u8], position_in_bytes: uint) -> T {
+#[allow(deprecated)]
+fn read_from_le_bytes<T: Int>(bytes: &[u8], position_in_bytes: usize) -> T {
     let byte_data = &bytes[position_in_bytes..position_in_bytes + mem::size_of::<T>()];
     let data = unsafe {
         *(byte_data.as_ptr() as *const T)
@@ -208,4 +214,3 @@ fn read_from_le_bytes<T: Int>(bytes: &[u8], position_in_bytes: uint) -> T {
 
     Int::from_le(data)
 }
-
index 86b720d3fc171191f451bb9bc31a32e4eedef4ef..cc588a365f6e68c5ab2ca3d950f1787d5eee82e6 100644 (file)
@@ -18,17 +18,19 @@ use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, Conte
 use llvm::SMDiagnosticRef;
 use trans::{CrateTranslation, ModuleTranslation};
 use util::common::time;
+use util::common::path2cstr;
 use syntax::codemap;
 use syntax::diagnostic;
 use syntax::diagnostic::{Emitter, Handler, Level, mk_handler};
 
 use std::ffi::{CStr, CString};
-use std::old_io::Command;
-use std::old_io::fs;
+use std::fs;
 use std::iter::Unfold;
+use std::mem;
+use std::path::Path;
+use std::process::{Command, Stdio};
 use std::ptr;
 use std::str;
-use std::mem;
 use std::sync::{Arc, Mutex};
 use std::sync::mpsc::channel;
 use std::thread;
@@ -54,7 +56,7 @@ pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! {
             libc::free(cstr as *mut _);
             handler.fatal(&format!("{}: {}",
                                   &msg[..],
-                                  &err[..])[]);
+                                  &err[..]));
         }
     }
 }
@@ -67,7 +69,7 @@ pub fn write_output_file(
         output: &Path,
         file_type: llvm::FileType) {
     unsafe {
-        let output_c = CString::new(output.as_vec()).unwrap();
+        let output_c = path2cstr(output);
         let result = llvm::LLVMRustWriteOutputFile(
                 target, pm, m, output_c.as_ptr(), file_type);
         if !result {
@@ -104,13 +106,13 @@ impl SharedEmitter {
             match diag.code {
                 Some(ref code) => {
                     handler.emit_with_code(None,
-                                           &diag.msg[],
+                                           &diag.msg,
                                            &code[..],
                                            diag.lvl);
                 },
                 None => {
                     handler.emit(None,
-                                 &diag.msg[],
+                                 &diag.msg,
                                  diag.lvl);
                 },
             }
@@ -166,7 +168,7 @@ fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
 fn create_target_machine(sess: &Session) -> TargetMachineRef {
     let reloc_model_arg = match sess.opts.cg.relocation_model {
         Some(ref s) => &s[..],
-        None => &sess.target.target.options.relocation_model[]
+        None => &sess.target.target.options.relocation_model[..],
     };
     let reloc_model = match reloc_model_arg {
         "pic" => llvm::RelocPIC,
@@ -177,7 +179,7 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
             sess.err(&format!("{:?} is not a valid relocation mode",
                              sess.opts
                                  .cg
-                                 .relocation_model)[]);
+                                 .relocation_model));
             sess.abort_if_errors();
             unreachable!();
         }
@@ -199,7 +201,7 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
 
     let code_model_arg = match sess.opts.cg.code_model {
         Some(ref s) => &s[..],
-        None => &sess.target.target.options.code_model[]
+        None => &sess.target.target.options.code_model[..],
     };
 
     let code_model = match code_model_arg {
@@ -212,13 +214,13 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
             sess.err(&format!("{:?} is not a valid code model",
                              sess.opts
                                  .cg
-                                 .code_model)[]);
+                                 .code_model));
             sess.abort_if_errors();
             unreachable!();
         }
     };
 
-    let triple = &sess.target.target.llvm_target[];
+    let triple = &sess.target.target.llvm_target;
 
     let tm = unsafe {
         let triple = CString::new(triple.as_bytes()).unwrap();
@@ -424,7 +426,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
     if config.emit_no_opt_bc {
         let ext = format!("{}.no-opt.bc", name_extra);
         let out = output_names.with_extension(&ext);
-        let out = CString::new(out.as_vec()).unwrap();
+        let out = path2cstr(&out);
         llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
     }
 
@@ -477,7 +479,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
                     if config.emit_lto_bc {
                         let name = format!("{}.lto.bc", name_extra);
                         let out = output_names.with_extension(&name);
-                        let out = CString::new(out.as_vec()).unwrap();
+                        let out = path2cstr(&out);
                         llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
                     }
                 },
@@ -511,7 +513,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
     if config.emit_bc {
         let ext = format!("{}.bc", name_extra);
         let out = output_names.with_extension(&ext);
-        let out = CString::new(out.as_vec()).unwrap();
+        let out = path2cstr(&out);
         llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
     }
 
@@ -519,21 +521,21 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
         if config.emit_ir {
             let ext = format!("{}.ll", name_extra);
             let out = output_names.with_extension(&ext);
-            let out = CString::new(out.as_vec()).unwrap();
+            let out = path2cstr(&out);
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
                 llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr());
             })
         }
 
         if config.emit_asm {
-            let path = output_names.with_extension(&format!("{}.s", name_extra)[]);
+            let path = output_names.with_extension(&format!("{}.s", name_extra));
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
                 write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::AssemblyFileType);
             });
         }
 
         if config.emit_obj {
-            let path = output_names.with_extension(&format!("{}.o", name_extra)[]);
+            let path = output_names.with_extension(&format!("{}.o", name_extra));
             with_codegen(tm, llmod, config.no_builtins, |cpm| {
                 write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::ObjectFileType);
             });
@@ -647,7 +649,7 @@ pub fn run_passes(sess: &Session,
 
     // Process the work items, optionally using worker threads.
     if sess.opts.cg.codegen_units == 1 {
-        run_work_singlethreaded(sess, &trans.reachable[], work_items);
+        run_work_singlethreaded(sess, &trans.reachable, work_items);
     } else {
         run_work_multithreaded(sess, work_items, sess.opts.cg.codegen_units);
     }
@@ -679,7 +681,7 @@ pub fn run_passes(sess: &Session,
                 // 2) Multiple codegen units, with `-o some_name`.  We have
                 //    no good solution for this case, so warn the user.
                 sess.warn(&format!("ignoring -o because multiple .{} files were produced",
-                                  ext)[]);
+                                  ext));
             } else {
                 // 3) Multiple codegen units, but no `-o some_name`.  We
                 //    just leave the `foo.0.x` files in place.
@@ -713,38 +715,35 @@ pub fn run_passes(sess: &Session,
         let pname = get_cc_prog(sess);
         let mut cmd = Command::new(&pname[..]);
 
-        cmd.args(&sess.target.target.options.pre_link_args[]);
+        cmd.args(&sess.target.target.options.pre_link_args);
         cmd.arg("-nostdlib");
 
         for index in 0..trans.modules.len() {
-            cmd.arg(crate_output.with_extension(&format!("{}.o", index)[]));
+            cmd.arg(&crate_output.with_extension(&format!("{}.o", index)));
         }
 
-        cmd.arg("-r")
-           .arg("-o")
-           .arg(windows_output_path.as_ref().unwrap_or(output_path));
+        cmd.arg("-r").arg("-o")
+           .arg(windows_output_path.as_ref().map(|s| &**s).unwrap_or(output_path));
 
-        cmd.args(&sess.target.target.options.post_link_args[]);
+        cmd.args(&sess.target.target.options.post_link_args);
 
         if sess.opts.debugging_opts.print_link_args {
             println!("{:?}", &cmd);
         }
 
-        cmd.stdin(::std::old_io::process::Ignored)
-           .stdout(::std::old_io::process::InheritFd(1))
-           .stderr(::std::old_io::process::InheritFd(2));
+        cmd.stdin(Stdio::null());
         match cmd.status() {
             Ok(status) => {
                 if !status.success() {
                     sess.err(&format!("linking of {} with `{:?}` failed",
-                                     output_path.display(), cmd)[]);
+                                     output_path.display(), cmd));
                     sess.abort_if_errors();
                 }
             },
             Err(e) => {
                 sess.err(&format!("could not exec the linker `{}`: {}",
                                  pname,
-                                 e)[]);
+                                 e));
                 sess.abort_if_errors();
             },
         }
@@ -851,7 +850,9 @@ pub fn run_passes(sess: &Session,
 
     // FIXME: time_llvm_passes support - does this use a global context or
     // something?
-    //if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
+    if sess.opts.cg.codegen_units == 1 && sess.time_llvm_passes() {
+        unsafe { llvm::LLVMRustPrintPassTimings(); }
+    }
 }
 
 struct WorkItem {
@@ -897,7 +898,7 @@ fn run_work_singlethreaded(sess: &Session,
 
 fn run_work_multithreaded(sess: &Session,
                           work_items: Vec<WorkItem>,
-                          num_workers: uint) {
+                          num_workers: usize) {
     // Run some workers to process the work items.
     let work_items_arc = Arc::new(Mutex::new(work_items));
     let mut diag_emitter = SharedEmitter::new();
@@ -962,19 +963,19 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
     let pname = get_cc_prog(sess);
     let mut cmd = Command::new(&pname[..]);
 
-    cmd.arg("-c").arg("-o").arg(outputs.path(config::OutputTypeObject))
-                           .arg(outputs.temp_path(config::OutputTypeAssembly));
-    debug!("{:?}", &cmd);
+    cmd.arg("-c").arg("-o").arg(&outputs.path(config::OutputTypeObject))
+                           .arg(&outputs.temp_path(config::OutputTypeAssembly));
+    debug!("{:?}", cmd);
 
     match cmd.output() {
         Ok(prog) => {
             if !prog.status.success() {
                 sess.err(&format!("linking with `{}` failed: {}",
                                  pname,
-                                 prog.status)[]);
-                sess.note(&format!("{:?}", &cmd)[]);
-                let mut note = prog.error.clone();
-                note.push_all(&prog.output[]);
+                                 prog.status));
+                sess.note(&format!("{:?}", &cmd));
+                let mut note = prog.stderr.clone();
+                note.push_all(&prog.stdout);
                 sess.note(str::from_utf8(&note[..]).unwrap());
                 sess.abort_if_errors();
             }
@@ -982,7 +983,7 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
         Err(e) => {
             sess.err(&format!("could not exec the linker `{}`: {}",
                              pname,
-                             e)[]);
+                             e));
             sess.abort_if_errors();
         }
     }
@@ -1018,7 +1019,7 @@ unsafe fn configure_llvm(sess: &Session) {
         if sess.target.target.arch == "aarch64" { add("-fast-isel=0"); }
 
         for arg in &sess.opts.cg.llvm_args {
-            add(&(*arg)[]);
+            add(&(*arg));
         }
     }
 
index 3deca436a1f903be1c63edf3aaed4cfe1639fc79..b0eacd1a55d4150221e924c8b3bf390f8d81d9ca 100644 (file)
@@ -14,6 +14,8 @@
 //!
 //! This API is completely unstable and subject to change.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rustc_trans"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(int_uint)]
-#![feature(old_io)]
-#![feature(env)]
 #![feature(libc)]
-#![feature(old_path)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
 #![feature(unsafe_destructor)]
 #![feature(staged_api)]
-#![feature(std_misc)]
 #![feature(unicode)]
+#![feature(path_ext)]
+#![feature(fs)]
+#![feature(path_relative_from)]
+
+#![allow(trivial_casts)]
 
 extern crate arena;
 extern crate flate;
@@ -49,7 +51,7 @@ extern crate libc;
 extern crate rustc;
 extern crate rustc_back;
 extern crate serialize;
-extern crate "rustc_llvm" as llvm;
+extern crate rustc_llvm as llvm;
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
index 8d2a2d51ee42366b6f78d8262abf701d8966481a..26fcf947e4f900e179c6365bbc0fb5ddaad20674 100644 (file)
@@ -33,10 +33,11 @@ use middle::def;
 use middle::ty::{self, Ty};
 
 use std::cell::Cell;
-use std::old_io::{self, File, fs};
 use std::env;
+use std::fs::{self, File};
+use std::path::{Path, PathBuf};
 
-use syntax::ast_util::{self, PostExpansionMethod};
+use syntax::ast_util;
 use syntax::ast::{self, NodeId, DefId};
 use syntax::ast_map::NodeItem;
 use syntax::attr;
@@ -94,7 +95,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
 
         // dump info about all the external crates referenced from this crate
         self.sess.cstore.iter_crate_data(|n, cmd| {
-            self.fmt.external_crate_str(krate.span, &cmd.name[], n);
+            self.fmt.external_crate_str(krate.span, &cmd.name, n);
         });
         self.fmt.recorder.record("end_external_crates\n");
     }
@@ -216,9 +217,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
     fn lookup_type_ref(&self, ref_id: NodeId) -> Option<DefId> {
         if !self.analysis.ty_cx.def_map.borrow().contains_key(&ref_id) {
             self.sess.bug(&format!("def_map has no key for {} in lookup_type_ref",
-                                  ref_id)[]);
+                                  ref_id));
         }
-        let def = (*self.analysis.ty_cx.def_map.borrow())[ref_id];
+        let def = self.analysis.ty_cx.def_map.borrow().get(&ref_id).unwrap().full_def();
         match def {
             def::DefPrimTy(_) => None,
             _ => Some(def.def_id()),
@@ -229,16 +230,15 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         let def_map = self.analysis.ty_cx.def_map.borrow();
         if !def_map.contains_key(&ref_id) {
             self.sess.span_bug(span, &format!("def_map has no key for {} in lookup_def_kind",
-                                             ref_id)[]);
+                                             ref_id));
         }
-        let def = (*def_map)[ref_id];
+        let def = def_map.get(&ref_id).unwrap().full_def();
         match def {
             def::DefMod(_) |
             def::DefForeignMod(_) => Some(recorder::ModRef),
             def::DefStruct(_) => Some(recorder::StructRef),
             def::DefTy(..) |
             def::DefAssociatedTy(..) |
-            def::DefAssociatedPath(..) |
             def::DefTrait(_) => Some(recorder::TypeRef),
             def::DefStatic(_, _) |
             def::DefConst(_) |
@@ -250,15 +250,13 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
 
             def::DefSelfTy(_) |
             def::DefRegion(_) |
-            def::DefTyParamBinder(_) |
             def::DefLabel(_) |
-            def::DefStaticMethod(..) |
             def::DefTyParam(..) |
             def::DefUse(_) |
             def::DefMethod(..) |
             def::DefPrimTy(_) => {
                 self.sess.span_bug(span, &format!("lookup_def_kind for unexpected item: {:?}",
-                                                 def)[]);
+                                                 def));
             },
         }
     }
@@ -271,23 +269,28 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             self.collecting = false;
             let span_utils = self.span.clone();
             for &(id, ref p, _, _) in &self.collected_paths {
-                let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
-                    (*self.analysis.ty_cx.node_types.borrow())[id]);
+                let typ =
+                    ppaux::ty_to_string(
+                        &self.analysis.ty_cx,
+                        *self.analysis.ty_cx.node_types().get(&id).unwrap());
                 // get the span only for the name of the variable (I hope the path is only ever a
                 // variable name, but who knows?)
                 self.fmt.formal_str(p.span,
                                     span_utils.span_for_last_ident(p.span),
                                     id,
                                     qualname,
-                                    &path_to_string(p)[],
+                                    &path_to_string(p),
                                     &typ[..]);
             }
             self.collected_paths.clear();
         }
     }
 
-    fn process_method(&mut self, method: &ast::Method) {
-        if generated_code(method.span) {
+    fn process_method(&mut self, sig: &ast::MethodSig,
+                      body: Option<&ast::Block>,
+                      id: ast::NodeId, ident: ast::Ident,
+                      span: Span) {
+        if generated_code(span) {
             return;
         }
 
@@ -295,17 +298,17 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         // The qualname for a method is the trait name or name of the struct in an impl in
         // which the method is declared in, followed by the method's name.
         let qualname = match ty::impl_of_method(&self.analysis.ty_cx,
-                                                ast_util::local_def(method.id)) {
+                                                ast_util::local_def(id)) {
             Some(impl_id) => match self.analysis.ty_cx.map.get(impl_id.node) {
                 NodeItem(item) => {
                     scope_id = item.id;
                     match item.node {
                         ast::ItemImpl(_, _, _, _, ref ty, _) => {
                             let mut result = String::from_str("<");
-                            result.push_str(&ty_to_string(&**ty)[]);
+                            result.push_str(&ty_to_string(&**ty));
 
                             match ty::trait_of_item(&self.analysis.ty_cx,
-                                                    ast_util::local_def(method.id)) {
+                                                    ast_util::local_def(id)) {
                                 Some(def_id) => {
                                     result.push_str(" as ");
                                     result.push_str(
@@ -317,23 +320,20 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             result
                         }
                         _ => {
-                            self.sess.span_bug(method.span,
-                                               &format!("Container {} for method {} not an impl?",
-                                                       impl_id.node, method.id)[]);
+                            self.sess.span_bug(span,
+                                &format!("Container {} for method {} not an impl?",
+                                         impl_id.node, id));
                         },
                     }
                 },
                 _ => {
-                    self.sess.span_bug(method.span,
-                                       &format!(
-                                           "Container {} for method {} is not a node item {:?}",
-                                           impl_id.node,
-                                           method.id,
-                                           self.analysis.ty_cx.map.get(impl_id.node))[]);
+                    self.sess.span_bug(span,
+                        &format!("Container {} for method {} is not a node item {:?}",
+                                 impl_id.node, id, self.analysis.ty_cx.map.get(impl_id.node)));
                 },
             },
             None => match ty::trait_of_item(&self.analysis.ty_cx,
-                                            ast_util::local_def(method.id)) {
+                                            ast_util::local_def(id)) {
                 Some(def_id) => {
                     scope_id = def_id.node;
                     match self.analysis.ty_cx.map.get(def_id.node) {
@@ -341,69 +341,72 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             format!("::{}", ty::item_path_str(&self.analysis.ty_cx, def_id))
                         }
                         _ => {
-                            self.sess.span_bug(method.span,
-                                               &format!("Could not find container {} for method {}",
-                                                       def_id.node, method.id)[]);
+                            self.sess.span_bug(span,
+                                &format!("Could not find container {} for method {}",
+                                         def_id.node, id));
                         }
                     }
                 },
                 None => {
-                    self.sess.span_bug(method.span,
-                                       &format!("Could not find container for method {}",
-                                               method.id)[]);
+                    self.sess.span_bug(span,
+                        &format!("Could not find container for method {}", id));
                 },
             },
         };
 
-        let qualname = format!("{}::{}", qualname, &get_ident(method.pe_ident()));
-        let qualname = &qualname[..];
+        let qualname = &format!("{}::{}", qualname, &get_ident(ident));
 
         // record the decl for this def (if it has one)
         let decl_id = ty::trait_item_of_item(&self.analysis.ty_cx,
-                                             ast_util::local_def(method.id))
+                                             ast_util::local_def(id))
             .and_then(|def_id| {
                 if match def_id {
                     ty::MethodTraitItemId(def_id) => {
-                        def_id.node != 0 && def_id != ast_util::local_def(method.id)
+                        def_id.node != 0 && def_id != ast_util::local_def(id)
                     }
                     ty::TypeTraitItemId(_) => false,
                 } {
-                    Some(def_id)
+                    Some(def_id.def_id())
                 } else {
                     None
                 }
             });
-        let decl_id = match decl_id {
-            None => None,
-            Some(id) => Some(id.def_id()),
-        };
 
-        let sub_span = self.span.sub_span_after_keyword(method.span, keywords::Fn);
-        self.fmt.method_str(method.span,
-                            sub_span,
-                            method.id,
-                            qualname,
-                            decl_id,
-                            scope_id);
-
-        self.process_formals(&method.pe_fn_decl().inputs, qualname);
+        let sub_span = self.span.sub_span_after_keyword(span, keywords::Fn);
+        if body.is_some() {
+            self.fmt.method_str(span,
+                                sub_span,
+                                id,
+                                qualname,
+                                decl_id,
+                                scope_id);
+            self.process_formals(&sig.decl.inputs, qualname);
+        } else {
+            self.fmt.method_decl_str(span,
+                                     sub_span,
+                                     id,
+                                     qualname,
+                                     scope_id);
+        }
 
         // walk arg and return types
-        for arg in &method.pe_fn_decl().inputs {
-            self.visit_ty(&*arg.ty);
+        for arg in &sig.decl.inputs {
+            self.visit_ty(&arg.ty);
         }
 
-        if let ast::Return(ref ret_ty) = method.pe_fn_decl().output {
-            self.visit_ty(&**ret_ty);
+        if let ast::Return(ref ret_ty) = sig.decl.output {
+            self.visit_ty(ret_ty);
         }
 
         // walk the fn body
-        self.nest(method.id, |v| v.visit_block(&*method.pe_body()));
+        if let Some(body) = body {
+            self.nest(id, |v| v.visit_block(body));
+        }
 
-        self.process_generic_params(method.pe_generics(),
-                                    method.span,
+        self.process_generic_params(&sig.generics,
+                                    span,
                                     qualname,
-                                    method.id);
+                                    id);
     }
 
     fn process_trait_ref(&mut self,
@@ -430,8 +433,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             ast::NamedField(ident, _) => {
                 let name = get_ident(ident);
                 let qualname = format!("{}::{}", qualname, name);
-                let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
-                    (*self.analysis.ty_cx.node_types.borrow())[field.node.id]);
+                let typ =
+                    ppaux::ty_to_string(
+                        &self.analysis.ty_cx,
+                        *self.analysis.ty_cx.node_types().get(&field.node.id).unwrap());
                 match self.span.sub_span_before_token(field.span, token::Colon) {
                     Some(sub_span) => self.fmt.field_str(field.span,
                                                          Some(sub_span),
@@ -442,7 +447,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                                          scope_id),
                     None => self.sess.span_bug(field.span,
                                                &format!("Could not find sub-span for field {}",
-                                                       qualname)[]),
+                                                       qualname)),
                 }
             },
             _ => (),
@@ -460,7 +465,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
         // However full span is the entire enum/fn/struct block, so we only want
         // the first few to match the number of generics we're looking for.
         let param_sub_spans = self.span.spans_for_ty_params(full_span,
-                                                           (generics.ty_params.len() as int));
+                                                           (generics.ty_params.len() as isize));
         for (param, param_ss) in generics.ty_params.iter().zip(param_sub_spans.iter()) {
             // Append $id to name to make sure each one is unique
             let name = format!("{}::{}${}",
@@ -528,7 +533,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             &get_ident(item.ident),
                             &qualname[..],
                             &value[..],
-                            &ty_to_string(&*typ)[],
+                            &ty_to_string(&*typ),
                             self.cur_scope);
 
         // walk type and init value
@@ -551,7 +556,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                             &get_ident(item.ident),
                             &qualname[..],
                             "",
-                            &ty_to_string(&*typ)[],
+                            &ty_to_string(&*typ),
                             self.cur_scope);
 
         // walk type and init value
@@ -603,7 +608,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                                 &val[..]),
             None => self.sess.span_bug(item.span,
                                        &format!("Could not find subspan for enum {}",
-                                               enum_name)[]),
+                                               enum_name)),
         }
         for variant in &enum_definition.variants {
             let name = get_ident(variant.node.name);
@@ -658,28 +663,26 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                     type_parameters: &ast::Generics,
                     trait_ref: &Option<ast::TraitRef>,
                     typ: &ast::Ty,
-                    impl_items: &Vec<ast::ImplItem>) {
+                    impl_items: &[P<ast::ImplItem>]) {
         let trait_id = trait_ref.as_ref().and_then(|tr| self.lookup_type_ref(tr.ref_id));
         match typ.node {
             // Common case impl for a struct or something basic.
-            ast::TyPath(ref path, id) => {
-                match self.lookup_type_ref(id) {
-                    Some(id) => {
-                        let sub_span = self.span.sub_span_for_type_name(path.span);
-                        self.fmt.ref_str(recorder::TypeRef,
-                                         path.span,
-                                         sub_span,
-                                         id,
-                                         self.cur_scope);
-                        self.fmt.impl_str(path.span,
-                                          sub_span,
-                                          item.id,
-                                          Some(id),
-                                          trait_id,
-                                          self.cur_scope);
-                    },
-                    None => ()
-                }
+            ast::TyPath(None, ref path) => {
+                let sub_span = self.span.sub_span_for_type_name(path.span);
+                let self_id = self.lookup_type_ref(typ.id).map(|id| {
+                    self.fmt.ref_str(recorder::TypeRef,
+                                     path.span,
+                                     sub_span,
+                                     id,
+                                     self.cur_scope);
+                    id
+                });
+                self.fmt.impl_str(path.span,
+                                  sub_span,
+                                  item.id,
+                                  self_id,
+                                  trait_id,
+                                  self.cur_scope);
             },
             _ => {
                 // Less useful case, impl for a compound type.
@@ -702,14 +705,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
 
         self.process_generic_params(type_parameters, item.span, "", item.id);
         for impl_item in impl_items {
-            match *impl_item {
-                ast::MethodImplItem(ref method) => {
-                    visit::walk_method_helper(self, &**method)
-                }
-                ast::TypeImplItem(ref typedef) => {
-                    visit::walk_ty(self, &*typedef.typ)
-                }
-            }
+            visit::walk_impl_item(self, impl_item);
         }
     }
 
@@ -717,7 +713,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                      item: &ast::Item,
                      generics: &ast::Generics,
                      trait_refs: &OwnedSlice<ast::TyParamBound>,
-                     methods: &Vec<ast::TraitItem>) {
+                     methods: &[P<ast::TraitItem>]) {
         let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
         let val = self.span.snippet(item.span);
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait);
@@ -797,9 +793,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             self.sess.span_bug(span,
                                &format!("def_map has no key for {} in visit_expr", id));
         }
-        let def = &(*def_map)[id];
+        let def = def_map.get(&id).unwrap().full_def();
         let sub_span = self.span.span_for_last_ident(span);
-        match *def {
+        match def {
             def::DefUpvar(..) |
             def::DefLocal(..) |
             def::DefStatic(..) |
@@ -819,8 +815,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                                       sub_span,
                                                       def_id,
                                                       self.cur_scope),
-            def::DefStaticMethod(declid, provenence) |
-            def::DefMethod(declid, _, provenence) => {
+            def::DefMethod(declid, provenence) => {
                 let sub_span = self.span.sub_span_for_meth_name(span);
                 let defid = if declid.krate == ast::LOCAL_CRATE {
                     let ti = ty::impl_or_trait_item(&self.analysis.ty_cx,
@@ -841,7 +836,8 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                                  .ty_cx
                                                  .impl_items
                                                  .borrow();
-                            Some((*impl_items)[def_id]
+                            Some(impl_items.get(&def_id)
+                                           .unwrap()
                                            .iter()
                                            .find(|mr| {
                                                 ty::impl_or_trait_item(
@@ -872,11 +868,18 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                     &format!("Unexpected def kind while looking \
                                               up path in `{}`: `{:?}`",
                                              self.span.snippet(span),
-                                             *def)[]),
+                                             def)),
         }
         // modules or types in the path prefix
-        match *def {
-            def::DefStaticMethod(..) => self.write_sub_path_trait_truncated(path),
+        match def {
+            def::DefMethod(did, _) => {
+                let ti = ty::impl_or_trait_item(&self.analysis.ty_cx, did);
+                if let ty::MethodTraitItem(m) = ti {
+                    if m.explicit_self == ty::StaticExplicitSelfCategory {
+                        self.write_sub_path_trait_truncated(path);
+                    }
+                }
+            }
             def::DefLocal(_) |
             def::DefStatic(_,_) |
             def::DefConst(..) |
@@ -943,7 +946,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                            ex: &ast::Expr,
                            args: &Vec<P<ast::Expr>>) {
         let method_map = self.analysis.ty_cx.method_map.borrow();
-        let method_callee = &(*method_map)[ty::MethodCall::expr(ex.id)];
+        let method_callee = method_map.get(&ty::MethodCall::expr(ex.id)).unwrap();
         let (def_id, decl_id) = match method_callee.origin {
             ty::MethodStatic(def_id) |
             ty::MethodStaticClosure(def_id) => {
@@ -1002,28 +1005,39 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             ast::PatStruct(ref path, ref fields, _) => {
                 self.collected_paths.push((p.id, path.clone(), false, recorder::StructRef));
                 visit::walk_path(self, path);
-                let struct_def = match self.lookup_type_ref(p.id) {
-                    Some(sd) => sd,
-                    None => {
-                        self.sess.span_bug(p.span,
-                                           &format!("Could not find struct_def for `{}`",
-                                                   self.span.snippet(p.span))[]);
+
+                let def = self.analysis.ty_cx.def_map.borrow().get(&p.id).unwrap().full_def();
+                let struct_def = match def {
+                    def::DefConst(..) => None,
+                    def::DefVariant(_, variant_id, _) => Some(variant_id),
+                    _ => {
+                        match ty::ty_to_def_id(ty::node_id_to_type(&self.analysis.ty_cx, p.id)) {
+                            None => {
+                                self.sess.span_bug(p.span,
+                                                   &format!("Could not find struct_def for `{}`",
+                                                            self.span.snippet(p.span)));
+                            }
+                            Some(def_id) => Some(def_id),
+                        }
                     }
                 };
-                for &Spanned { node: ref field, span } in fields {
-                    let sub_span = self.span.span_for_first_ident(span);
-                    let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, struct_def);
-                    for f in fields {
-                        if f.name == field.ident.name {
-                            self.fmt.ref_str(recorder::VarRef,
-                                             span,
-                                             sub_span,
-                                             f.id,
-                                             self.cur_scope);
-                            break;
+
+                if let Some(struct_def) = struct_def {
+                    let struct_fields = ty::lookup_struct_fields(&self.analysis.ty_cx, struct_def);
+                    for &Spanned { node: ref field, span } in fields {
+                        let sub_span = self.span.span_for_first_ident(span);
+                        for f in &struct_fields {
+                            if f.name == field.ident.name {
+                                self.fmt.ref_str(recorder::VarRef,
+                                                 span,
+                                                 sub_span,
+                                                 f.id,
+                                                 self.cur_scope);
+                                break;
+                            }
                         }
+                        self.visit_pat(&*field.pat);
                     }
-                    self.visit_pat(&*field.pat);
                 }
             }
             ast::PatEnum(ref path, _) => {
@@ -1104,7 +1118,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                         let glob_map = &self.analysis.glob_map;
                         let glob_map = glob_map.as_ref().unwrap();
                         if glob_map.contains_key(&item.id) {
-                            for n in &glob_map[item.id] {
+                            for n in glob_map.get(&item.id).unwrap() {
                                 if name_string.len() > 0 {
                                     name_string.push_str(", ");
                                 }
@@ -1151,7 +1165,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                 let name = get_ident(item.ident);
                 let name = &name;
                 let location = match *s {
-                    Some((ref s, _)) => s.to_string(),
+                    Some(s) => s.to_string(),
                     None => name.to_string(),
                 };
                 let alias_span = self.span.span_for_last_ident(item.span);
@@ -1220,71 +1234,24 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
         }
     }
 
-    // We don't actually index functions here, that is done in visit_item/ItemFn.
-    // Here we just visit methods.
-    fn visit_fn(&mut self,
-                fk: visit::FnKind<'v>,
-                fd: &'v ast::FnDecl,
-                b: &'v ast::Block,
-                s: Span,
-                _: ast::NodeId) {
-        if generated_code(s) {
-            return;
-        }
-
-        match fk {
-            visit::FkMethod(_, _, method) => self.process_method(method),
-            _ => visit::walk_fn(self, fk, fd, b, s),
+    fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
+        match trait_item.node {
+            ast::MethodTraitItem(ref sig, ref body) => {
+                self.process_method(sig, body.as_ref().map(|x| &**x),
+                                    trait_item.id, trait_item.ident, trait_item.span);
+            }
+            ast::TypeTraitItem(..) => {}
         }
     }
 
-    fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
-        match *tm {
-            ast::RequiredMethod(ref method_type) => {
-                if generated_code(method_type.span) {
-                    return;
-                }
-
-                let mut scope_id;
-                let mut qualname = match ty::trait_of_item(&self.analysis.ty_cx,
-                                                           ast_util::local_def(method_type.id)) {
-                    Some(def_id) => {
-                        scope_id = def_id.node;
-                        format!("::{}::", ty::item_path_str(&self.analysis.ty_cx, def_id))
-                    },
-                    None => {
-                        self.sess.span_bug(method_type.span,
-                                           &format!("Could not find trait for method {}",
-                                                   method_type.id)[]);
-                    },
-                };
-
-                qualname.push_str(&get_ident(method_type.ident));
-                let qualname = &qualname[..];
-
-                let sub_span = self.span.sub_span_after_keyword(method_type.span, keywords::Fn);
-                self.fmt.method_decl_str(method_type.span,
-                                         sub_span,
-                                         method_type.id,
-                                         qualname,
-                                         scope_id);
-
-                // walk arg and return types
-                for arg in &method_type.decl.inputs {
-                    self.visit_ty(&*arg.ty);
-                }
-
-                if let ast::Return(ref ret_ty) = method_type.decl.output {
-                    self.visit_ty(&**ret_ty);
-                }
-
-                self.process_generic_params(&method_type.generics,
-                                            method_type.span,
-                                            qualname,
-                                            method_type.id);
+    fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) {
+        match impl_item.node {
+            ast::MethodImplItem(ref sig, ref body) => {
+                self.process_method(sig, Some(body), impl_item.id,
+                                    impl_item.ident, impl_item.span);
             }
-            ast::ProvidedMethod(ref method) => self.process_method(&**method),
-            ast::TypeTraitItem(_) => {}
+            ast::TypeImplItem(_) |
+            ast::MacImplItem(_) => {}
         }
     }
 
@@ -1294,8 +1261,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
         }
 
         match t.node {
-            ast::TyPath(ref path, id) => {
-                match self.lookup_type_ref(id) {
+            ast::TyPath(_, ref path) => {
+                match self.lookup_type_ref(t.id) {
                     Some(id) => {
                         let sub_span = self.span.sub_span_for_type_name(t.span);
                         self.fmt.ref_str(recorder::TypeRef,
@@ -1325,16 +1292,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                 // Don't need to do anything for function calls,
                 // because just walking the callee path does what we want.
                 visit::walk_expr(self, ex);
-            },
-            ast::ExprPath(ref path) => {
-                self.process_path(ex.id, path.span, path, None);
-                visit::walk_path(self, path);
             }
-            ast::ExprQPath(ref qpath) => {
-                let mut path = qpath.trait_ref.path.clone();
-                path.segments.push(qpath.item_path.clone());
-                self.process_path(ex.id, ex.span, &path, None);
-                visit::walk_qpath(self, ex.span, &**qpath);
+            ast::ExprPath(_, ref path) => {
+                self.process_path(ex.id, path.span, path, None);
+                visit::walk_expr(self, ex);
             }
             ast::ExprStruct(ref path, ref fields, ref base) =>
                 self.process_struct_lit(ex, path, fields, base),
@@ -1362,7 +1323,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                         }
                     }
                     _ => self.sess.span_bug(ex.span,
-                                            &format!("Expected struct type, found {:?}", ty)[]),
+                                            &format!("Expected struct type, found {:?}", ty)),
                 }
             },
             ast::ExprTupField(ref sub_ex, idx) => {
@@ -1391,7 +1352,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                     ty::ty_tup(_) => {}
                     _ => self.sess.span_bug(ex.span,
                                             &format!("Expected struct or tuple \
-                                                      type, found {:?}", ty)[]),
+                                                      type, found {:?}", ty)),
                 }
             },
             ast::ExprClosure(_, ref decl, ref body) => {
@@ -1400,7 +1361,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                 }
 
                 let mut id = String::from_str("$");
-                id.push_str(&ex.id.to_string()[]);
+                id.push_str(&ex.id.to_string());
                 self.process_formals(&decl.inputs, &id[..]);
 
                 // walk arg and return types
@@ -1448,10 +1409,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
             if !def_map.contains_key(&id) {
                 self.sess.span_bug(p.span,
                                    &format!("def_map has no key for {} in visit_arm",
-                                           id)[]);
+                                           id));
             }
-            let def = &(*def_map)[id];
-            match *def {
+            let def = def_map.get(&id).unwrap().full_def();
+            match def {
                 def::DefLocal(id)  => {
                     let value = if *immut {
                         self.span.snippet(p.span).to_string()
@@ -1463,7 +1424,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                     self.fmt.variable_str(p.span,
                                           Some(p.span),
                                           id,
-                                          &path_to_string(p)[],
+                                          &path_to_string(p),
                                           &value[..],
                                           "")
                 }
@@ -1474,7 +1435,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                 def::DefStatic(_, _) => {}
                 def::DefConst(..) => {}
                 _ => error!("unexpected definition kind when processing collected paths: {:?}",
-                            *def)
+                            def)
             }
         }
         for &(id, ref path, ref_kind) in &paths_to_process {
@@ -1510,8 +1471,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
 
         for &(id, ref p, ref immut, _) in &self.collected_paths {
             let value = if *immut { value.to_string() } else { "<mutable>".to_string() };
-            let types = self.analysis.ty_cx.node_types.borrow();
-            let typ = ppaux::ty_to_string(&self.analysis.ty_cx, (*types)[id]);
+            let types = self.analysis.ty_cx.node_types();
+            let typ = ppaux::ty_to_string(&self.analysis.ty_cx, *types.get(&id).unwrap());
             // Get the span only for the name of the variable (I hope the path
             // is only ever a variable name, but who knows?).
             let sub_span = self.span.span_for_last_ident(p.span);
@@ -1519,7 +1480,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
             self.fmt.variable_str(p.span,
                                   sub_span,
                                   id,
-                                  &path_to_string(p)[],
+                                  &path_to_string(p),
                                   &value[..],
                                   &typ[..]);
         }
@@ -1531,6 +1492,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
     }
 }
 
+#[allow(deprecated)]
 pub fn process_crate(sess: &Session,
                      krate: &ast::Crate,
                      analysis: &ty::CrateAnalysis,
@@ -1540,7 +1502,7 @@ pub fn process_crate(sess: &Session,
     }
 
     assert!(analysis.glob_map.is_some());
-    let cratename = match attr::find_crate_name(&krate.attrs[]) {
+    let cratename = match attr::find_crate_name(&krate.attrs) {
         Some(name) => name.to_string(),
         None => {
             info!("Could not find crate name, using 'unknown_crate'");
@@ -1551,17 +1513,17 @@ pub fn process_crate(sess: &Session,
     info!("Dumping crate {}", cratename);
 
     // find a path to dump our data to
-    let mut root_path = match env::var("DXR_RUST_TEMP_FOLDER") {
-        Ok(val) => Path::new(val),
-        Err(..) => match odir {
+    let mut root_path = match env::var_os("DXR_RUST_TEMP_FOLDER") {
+        Some(val) => PathBuf::from(val),
+        None => match odir {
             Some(val) => val.join("dxr"),
-            None => Path::new("dxr-temp"),
+            None => PathBuf::from("dxr-temp"),
         },
     };
 
-    match fs::mkdir_recursive(&root_path, old_io::USER_RWX) {
+    match fs::create_dir_all(&root_path) {
         Err(e) => sess.err(&format!("Could not create directory {}: {}",
-                           root_path.display(), e)[]),
+                           root_path.display(), e)),
         _ => (),
     }
 
@@ -1573,12 +1535,12 @@ pub fn process_crate(sess: &Session,
     // Create output file.
     let mut out_name = cratename.clone();
     out_name.push_str(".csv");
-    root_path.push(out_name);
+    root_path.push(&out_name);
     let output_file = match File::create(&root_path) {
         Ok(f) => box f,
         Err(e) => {
             let disp = root_path.display();
-            sess.fatal(&format!("Could not open {}: {}", disp, e)[]);
+            sess.fatal(&format!("Could not open {}: {}", disp, e));
         }
     };
     root_path.pop();
@@ -1589,7 +1551,7 @@ pub fn process_crate(sess: &Session,
         collected_paths: vec!(),
         collecting: false,
         fmt: FmtStrs::new(box Recorder {
-                            out: output_file as Box<Writer+'static>,
+                            out: output_file,
                             dump_spans: false,
                         },
                         SpanUtils {
index 08e36bb1d85bb3eefc504b5c81b7244c7fff5ba5..db724b0ef6b650b5eac3238af14bfc607add3b11 100644 (file)
@@ -13,7 +13,7 @@ pub use self::Row::*;
 use super::escape;
 use super::span_utils::SpanUtils;
 
-use std::vec::Vec;
+use std::io::Write;
 
 use syntax::ast;
 use syntax::ast::{NodeId,DefId};
@@ -23,7 +23,7 @@ const ZERO_DEF_ID: DefId = DefId { node: 0, krate: 0 };
 
 pub struct Recorder {
     // output file
-    pub out: Box<Writer+'static>,
+    pub out: Box<Write+'static>,
     pub dump_spans: bool,
 }
 
@@ -62,7 +62,7 @@ macro_rules! svec {
     })
 }
 
-#[derive(Copy, Debug, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum Row {
     Variable,
     Enum,
@@ -162,7 +162,7 @@ impl<'a> FmtStrs<'a> {
         if values.len() != fields.len() {
             self.span.sess.span_bug(span, &format!(
                 "Mismatch between length of fields for '{}', expected '{}', found '{}'",
-                kind, fields.len(), values.len())[]);
+                kind, fields.len(), values.len()));
         }
 
         let values = values.iter().map(|s| {
@@ -191,7 +191,7 @@ impl<'a> FmtStrs<'a> {
         if needs_span {
             self.span.sess.span_bug(span, &format!(
                 "Called record_without_span for '{}' which does requires a span",
-                label)[]);
+                label));
         }
         assert!(!dump_spans);
 
@@ -268,7 +268,7 @@ impl<'a> FmtStrs<'a> {
         // variable def's node id
         let mut qualname = String::from_str(name);
         qualname.push_str("$");
-        qualname.push_str(&id.to_string()[]);
+        qualname.push_str(&id.to_string());
         self.check_and_record(Variable,
                               span,
                               sub_span,
index 223d46e4e4a93ebbb902c7f1d49fecfa031b77b6..84a7678959d3efdcb792489e81aff6e98f913441 100644 (file)
@@ -24,7 +24,7 @@ use syntax::parse::token::{keywords, Token};
 #[derive(Clone)]
 pub struct SpanUtils<'a> {
     pub sess: &'a Session,
-    pub err_count: Cell<int>,
+    pub err_count: Cell<isize>,
 }
 
 impl<'a> SpanUtils<'a> {
@@ -219,7 +219,7 @@ impl<'a> SpanUtils<'a> {
             let loc = self.sess.codemap().lookup_char_pos(span.lo);
             self.sess.span_bug(span,
                 &format!("Mis-counted brackets when breaking path? Parsing '{}' in {}, line {}",
-                        self.snippet(span), loc.file.name, loc.line)[]);
+                        self.snippet(span), loc.file.name, loc.line));
         }
         if result.is_none() && prev.tok.is_ident() && bracket_count == 0 {
             return self.make_sub_span(span, Some(prev.sp));
@@ -232,12 +232,13 @@ impl<'a> SpanUtils<'a> {
     // example with Foo<Bar<T,V>, Bar<T,V>>
     // Nesting = 0: all idents outside of brackets: ~[Foo]
     // Nesting = 1: idents within one level of brackets: ~[Bar, Bar]
-    pub fn spans_with_brackets(&self, span: Span, nesting: int, limit: int) -> Vec<Span> {
+    pub fn spans_with_brackets(&self, span: Span, nesting: isize, limit: isize) -> Vec<Span> {
         let mut result: Vec<Span> = vec!();
 
         let mut toks = self.retokenise_span(span);
         // We keep track of how many brackets we're nested in
         let mut bracket_count = 0;
+        let mut found_ufcs_sep = false;
         loop {
             let ts = toks.real_token();
             if ts.tok == token::Eof {
@@ -245,22 +246,29 @@ impl<'a> SpanUtils<'a> {
                     let loc = self.sess.codemap().lookup_char_pos(span.lo);
                     self.sess.span_bug(span, &format!(
                         "Mis-counted brackets when breaking path? Parsing '{}' in {}, line {}",
-                         self.snippet(span), loc.file.name, loc.line)[]);
+                         self.snippet(span), loc.file.name, loc.line));
                 }
                 return result
             }
-            if (result.len() as int) == limit {
+            if (result.len() as isize) == limit {
                 return result;
             }
             bracket_count += match ts.tok {
                 token::Lt => 1,
-                token::Gt => -1,
+                token::Gt => {
+                    // Ignore the `>::` in `<Type as Trait>::AssocTy`.
+                    if !found_ufcs_sep && bracket_count == 0 {
+                        found_ufcs_sep = true;
+                        0
+                    } else {
+                        -1
+                    }
+                }
                 token::BinOp(token::Shl) => 2,
                 token::BinOp(token::Shr) => -2,
                 _ => 0
             };
-            if ts.tok.is_ident() &&
-               bracket_count == nesting {
+            if ts.tok.is_ident() && bracket_count == nesting {
                 result.push(self.make_sub_span(span, Some(ts.sp)).unwrap());
             }
         }
@@ -339,7 +347,7 @@ impl<'a> SpanUtils<'a> {
 
     // Return an owned vector of the subspans of the param identifier
     // tokens found in span.
-    pub fn spans_for_ty_params(&self, span: Span, number: int) -> Vec<Span> {
+    pub fn spans_for_ty_params(&self, span: Span, number: isize) -> Vec<Span> {
         if generated_code(span) {
             return vec!();
         }
index 2826afb71a2c23cfcc945a66c908b6c806a7a3c3..ef599a01e7c40fc5b8697ced0b52811c936bea3c 100644 (file)
@@ -28,7 +28,7 @@
 //! constituent pattern.  N here is usually the number of arms but may be
 //! greater, if some arms have multiple alternatives.  For example, here:
 //!
-//!     enum Foo { A, B(int), C(uint, uint) }
+//!     enum Foo { A, B(int), C(usize, usize) }
 //!     match foo {
 //!         A => ...,
 //!         B(x) => ...,
@@ -200,7 +200,7 @@ use middle::mem_categorization as mc;
 use middle::pat_util::*;
 use trans::adt;
 use trans::base::*;
-use trans::build::{AddCase, And, BitCast, Br, CondBr, GEPi, InBoundsGEP, Load};
+use trans::build::{AddCase, And, Br, CondBr, GEPi, InBoundsGEP, Load, PointerCast};
 use trans::build::{Not, Store, Sub, add_comment};
 use trans::build;
 use trans::callee;
@@ -228,7 +228,7 @@ use syntax::codemap::Span;
 use syntax::fold::Folder;
 use syntax::ptr::P;
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 struct ConstantExpr<'a>(&'a ast::Expr);
 
 impl<'a> ConstantExpr<'a> {
@@ -246,9 +246,9 @@ enum Opt<'a, 'tcx> {
     ConstantValue(ConstantExpr<'a>, DebugLoc),
     ConstantRange(ConstantExpr<'a>, ConstantExpr<'a>, DebugLoc),
     Variant(ty::Disr, Rc<adt::Repr<'tcx>>, ast::DefId, DebugLoc),
-    SliceLengthEqual(uint, DebugLoc),
-    SliceLengthGreaterOrEqual(/* prefix length */ uint,
-                              /* suffix length */ uint,
+    SliceLengthEqual(usize, DebugLoc),
+    SliceLengthGreaterOrEqual(/* prefix length */ usize,
+                              /* suffix length */ usize,
                               DebugLoc),
 }
 
@@ -311,7 +311,7 @@ impl<'a, 'tcx> Opt<'a, 'tcx> {
     }
 }
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum BranchKind {
     NoBranch,
     Single,
@@ -326,7 +326,7 @@ pub enum OptResult<'blk, 'tcx: 'blk> {
     LowerBound(Result<'blk, 'tcx>)
 }
 
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, PartialEq)]
 pub enum TransBindingMode {
     TrByCopy(/* llbinding */ ValueRef),
     TrByMove,
@@ -381,7 +381,7 @@ impl<'a, 'p, 'blk, 'tcx> Repr<'tcx> for Match<'a, 'p, 'blk, 'tcx> {
     }
 }
 
-fn has_nested_bindings(m: &[Match], col: uint) -> bool {
+fn has_nested_bindings(m: &[Match], col: usize) -> bool {
     for br in m {
         match br.pats[col].node {
             ast::PatIdent(_, _, Some(_)) => return true,
@@ -393,7 +393,7 @@ fn has_nested_bindings(m: &[Match], col: uint) -> bool {
 
 fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                               m: &[Match<'a, 'p, 'blk, 'tcx>],
-                                              col: uint,
+                                              col: usize,
                                               val: ValueRef)
                                               -> Vec<Match<'a, 'p, 'blk, 'tcx>> {
     debug!("expand_nested_bindings(bcx={}, m={}, col={}, val={})",
@@ -430,7 +430,7 @@ fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
                                           dm: &DefMap,
                                           m: &[Match<'a, 'p, 'blk, 'tcx>],
-                                          col: uint,
+                                          col: usize,
                                           val: ValueRef,
                                           mut e: F)
                                           -> Vec<Match<'a, 'p, 'blk, 'tcx>> where
@@ -444,7 +444,7 @@ fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
     let _indenter = indenter();
 
     m.iter().filter_map(|br| {
-        e(&br.pats[]).map(|pats| {
+        e(&br.pats).map(|pats| {
             let this = br.pats[col];
             let mut bound_ptrs = br.bound_ptrs.clone();
             match this.node {
@@ -476,7 +476,7 @@ fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
 fn enter_default<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                      dm: &DefMap,
                                      m: &[Match<'a, 'p, 'blk, 'tcx>],
-                                     col: uint,
+                                     col: usize,
                                      val: ValueRef)
                                      -> Vec<Match<'a, 'p, 'blk, 'tcx>> {
     debug!("enter_default(bcx={}, m={}, col={}, val={})",
@@ -532,8 +532,8 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>(
              dm: &DefMap,
              m: &[Match<'a, 'p, 'blk, 'tcx>],
              opt: &Opt,
-             col: uint,
-             variant_size: uint,
+             col: usize,
+             variant_size: usize,
              val: ValueRef)
              -> Vec<Match<'a, 'p, 'blk, 'tcx>> {
     debug!("enter_opt(bcx={}, m={}, opt={:?}, col={}, val={})",
@@ -575,7 +575,7 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>(
 // on a set of enum variants or a literal.
 fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                     m: &[Match<'a, 'p, 'blk, 'tcx>],
-                                    col: uint)
+                                    col: usize)
                                     -> Vec<Opt<'p, 'tcx>> {
     let tcx = bcx.tcx();
 
@@ -598,7 +598,7 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             }
             ast::PatIdent(..) | ast::PatEnum(..) | ast::PatStruct(..) => {
                 // This is either an enum variant or a variable binding.
-                let opt_def = tcx.def_map.borrow().get(&cur.id).cloned();
+                let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def());
                 match opt_def {
                     Some(def::DefVariant(enum_id, var_id, _)) => {
                         let variant = ty::enum_variant_with_id(tcx, enum_id, var_id);
@@ -656,11 +656,11 @@ fn match_datum<'tcx>(val: ValueRef, left_ty: Ty<'tcx>) -> Datum<'tcx, Lvalue> {
 fn bind_subslice_pat(bcx: Block,
                      pat_id: ast::NodeId,
                      val: ValueRef,
-                     offset_left: uint,
-                     offset_right: uint) -> ValueRef {
+                     offset_left: usize,
+                     offset_right: usize) -> ValueRef {
     let _icx = push_ctxt("match::bind_subslice_pat");
     let vec_ty = node_id_type(bcx, pat_id);
-    let vt = tvec::vec_types(bcx, ty::sequence_element_type(bcx.tcx(), ty::type_content(vec_ty)));
+    let unit_ty = ty::sequence_element_type(bcx.tcx(), ty::type_content(vec_ty));
     let vec_datum = match_datum(val, vec_ty);
     let (base, len) = vec_datum.get_vec_base_and_len(bcx);
 
@@ -669,7 +669,7 @@ fn bind_subslice_pat(bcx: Block,
     let slice_len = Sub(bcx, len, slice_len_offset, DebugLoc::None);
     let slice_ty = ty::mk_slice(bcx.tcx(),
                                 bcx.tcx().mk_region(ty::ReStatic),
-                                ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable});
+                                ty::mt {ty: unit_ty, mutbl: ast::MutImmutable});
     let scratch = rvalue_scratch_datum(bcx, slice_ty, "");
     Store(bcx, slice_begin,
           GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_ADDR]));
@@ -678,9 +678,9 @@ fn bind_subslice_pat(bcx: Block,
 }
 
 fn extract_vec_elems<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                 left_ty: Ty,
-                                 before: uint,
-                                 after: uint,
+                                 left_ty: Ty<'tcx>,
+                                 before: usize,
+                                 after: usize,
                                  val: ValueRef)
                                  -> ExtractedBlock<'blk, 'tcx> {
     let _icx = push_ctxt("match::extract_vec_elems");
@@ -711,28 +711,28 @@ macro_rules! any_pat {
     )
 }
 
-fn any_uniq_pat(m: &[Match], col: uint) -> bool {
+fn any_uniq_pat(m: &[Match], col: usize) -> bool {
     any_pat!(m, col, ast::PatBox(_))
 }
 
-fn any_region_pat(m: &[Match], col: uint) -> bool {
+fn any_region_pat(m: &[Match], col: usize) -> bool {
     any_pat!(m, col, ast::PatRegion(..))
 }
 
-fn any_irrefutable_adt_pat(tcx: &ty::ctxt, m: &[Match], col: uint) -> bool {
+fn any_irrefutable_adt_pat(tcx: &ty::ctxt, m: &[Match], col: usize) -> bool {
     m.iter().any(|br| {
         let pat = br.pats[col];
         match pat.node {
             ast::PatTup(_) => true,
             ast::PatStruct(..) => {
-                match tcx.def_map.borrow().get(&pat.id) {
-                    Some(&def::DefVariant(..)) => false,
+                match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
+                    Some(def::DefVariant(..)) => false,
                     _ => true,
                 }
             }
             ast::PatEnum(..) | ast::PatIdent(_, _, None) => {
-                match tcx.def_map.borrow().get(&pat.id) {
-                    Some(&def::DefStruct(..)) => true,
+                match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
+                    Some(def::DefStruct(..)) => true,
                     _ => false
                 }
             }
@@ -772,8 +772,8 @@ impl FailureHandler {
     }
 }
 
-fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<uint> {
-    fn pat_score(def_map: &DefMap, pat: &ast::Pat) -> uint {
+fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<usize> {
+    fn pat_score(def_map: &DefMap, pat: &ast::Pat) -> usize {
         match pat.node {
             ast::PatIdent(_, _, Some(ref inner)) => pat_score(def_map, &**inner),
             _ if pat_is_refutable(def_map, pat) => 1,
@@ -781,7 +781,7 @@ fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<uint> {
         }
     }
 
-    let column_score = |m: &[Match], col: uint| -> uint {
+    let column_score = |m: &[Match], col: usize| -> usize {
         let total_score = m.iter()
             .map(|row| row.pats[col])
             .map(|pat| pat_score(def_map, pat))
@@ -789,13 +789,13 @@ fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<uint> {
 
         // Irrefutable columns always go first, they'd only be duplicated in the branches.
         if total_score == 0 {
-            std::uint::MAX
+            std::usize::MAX
         } else {
             total_score
         }
     };
 
-    let column_contains_any_nonwild_patterns = |&col: &uint| -> bool {
+    let column_contains_any_nonwild_patterns = |&col: &usize| -> bool {
         m.iter().any(|row| match row.pats[col].node {
             ast::PatWild(_) => false,
             _ => true
@@ -825,7 +825,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
         let did = langcall(cx,
                            None,
                            &format!("comparison of `{}`",
-                                   cx.ty_to_string(rhs_t))[],
+                                   cx.ty_to_string(rhs_t)),
                            StrEqFnLangItem);
         let t = ty::mk_str_slice(cx.tcx(), cx.tcx().mk_region(ty::ReStatic), ast::MutImmutable);
         // The comparison function gets the slices by value, so we have to make copies here. Even
@@ -853,14 +853,31 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
             ty::ty_str => compare_str(cx, lhs, rhs, rhs_t, debug_loc),
             ty::ty_vec(ty, _) => match ty.sty {
                 ty::ty_uint(ast::TyU8) => {
-                    // NOTE: cast &[u8] to &str and abuse the str_eq lang item,
+                    // NOTE: cast &[u8] and &[u8; N] to &str and abuse the str_eq lang item,
                     // which calls memcmp().
-                    let t = ty::mk_str_slice(cx.tcx(),
-                                             cx.tcx().mk_region(ty::ReStatic),
-                                             ast::MutImmutable);
-                    let lhs = BitCast(cx, lhs, type_of::type_of(cx.ccx(), t).ptr_to());
-                    let rhs = BitCast(cx, rhs, type_of::type_of(cx.ccx(), t).ptr_to());
-                    compare_str(cx, lhs, rhs, rhs_t, debug_loc)
+                    let pat_len = val_ty(rhs).element_type().array_length();
+                    let ty_str_slice = ty::mk_str_slice(cx.tcx(),
+                                                        cx.tcx().mk_region(ty::ReStatic),
+                                                        ast::MutImmutable);
+
+                    let rhs_str = alloc_ty(cx, ty_str_slice, "rhs_str");
+                    Store(cx, GEPi(cx, rhs, &[0, 0]), expr::get_dataptr(cx, rhs_str));
+                    Store(cx, C_uint(cx.ccx(), pat_len), expr::get_len(cx, rhs_str));
+
+                    let lhs_str;
+                    if val_ty(lhs) == val_ty(rhs) {
+                        // Both the discriminant and the pattern are thin pointers
+                        lhs_str = alloc_ty(cx, ty_str_slice, "lhs_str");
+                        Store(cx, GEPi(cx, lhs, &[0, 0]), expr::get_dataptr(cx, lhs_str));
+                        Store(cx, C_uint(cx.ccx(), pat_len), expr::get_len(cx, lhs_str));
+                    }
+                    else {
+                        // The discriminant is a fat pointer
+                        let llty_str_slice = type_of::type_of(cx.ccx(), ty_str_slice).ptr_to();
+                        lhs_str = PointerCast(cx, lhs, llty_str_slice);
+                    }
+
+                    compare_str(cx, lhs_str, rhs_str, rhs_t, debug_loc)
                 },
                 _ => cx.sess().bug("only byte strings supported in compare_values"),
             },
@@ -1000,9 +1017,14 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         None => {
             let data = &m[0].data;
             for &(ref ident, ref value_ptr) in &m[0].bound_ptrs {
-                let llmatch = data.bindings_map[*ident].llmatch;
-                call_lifetime_start(bcx, llmatch);
-                Store(bcx, *value_ptr, llmatch);
+                let binfo = *data.bindings_map.get(ident).unwrap();
+                call_lifetime_start(bcx, binfo.llmatch);
+                if binfo.trmode == TrByRef && type_is_fat_ptr(bcx.tcx(), binfo.ty) {
+                    expr::copy_fat_ptr(bcx, *value_ptr, binfo.llmatch);
+                }
+                else {
+                    Store(bcx, *value_ptr, binfo.llmatch);
+                }
             }
             match data.arm.guard {
                 Some(ref guard_expr) => {
@@ -1025,7 +1047,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                                  m: &[Match<'a, 'p, 'blk, 'tcx>],
                                                  vals: &[ValueRef],
                                                  chk: &FailureHandler,
-                                                 col: uint,
+                                                 col: usize,
                                                  val: ValueRef,
                                                  has_genuine_default: bool) {
     let fcx = bcx.fcx;
@@ -1070,7 +1092,6 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             _ => None
         }
     };
-
     match adt_vals {
         Some(field_vals) => {
             let pats = enter_match(bcx, dm, m, col, val, |pats|
@@ -1166,7 +1187,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                     let t = if kind == Compare {
                         left_ty
                     } else {
-                        tcx.types.uint // vector length
+                        tcx.types.usize // vector length
                     };
                     let Result { bcx: after_cx, val: matches } = {
                         match opt.trans(bcx) {
@@ -1277,20 +1298,20 @@ pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 /// Checks whether the binding in `discr` is assigned to anywhere in the expression `body`
 fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool {
     let (vid, field) = match discr.node {
-        ast::ExprPath(_) | ast::ExprQPath(_) => match bcx.def(discr.id) {
+        ast::ExprPath(..) => match bcx.def(discr.id) {
             def::DefLocal(vid) | def::DefUpvar(vid, _) => (vid, None),
             _ => return false
         },
         ast::ExprField(ref base, field) => {
-            let vid = match bcx.tcx().def_map.borrow().get(&base.id) {
-                Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _)) => vid,
+            let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
+                Some(def::DefLocal(vid)) | Some(def::DefUpvar(vid, _)) => vid,
                 _ => return false
             };
             (vid, Some(mc::NamedField(field.node.name)))
         },
         ast::ExprTupField(ref base, field) => {
-            let vid = match bcx.tcx().def_map.borrow().get(&base.id) {
-                Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _)) => vid,
+            let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
+                Some(def::DefLocal(vid)) | Some(def::DefUpvar(vid, _)) => vid,
                 _ => return false
             };
             (vid, Some(mc::PositionalField(field.node)))
@@ -1331,12 +1352,12 @@ impl<'tcx> euv::Delegate<'tcx> for ReassignmentChecker {
     fn mutate(&mut self, _: ast::NodeId, _: Span, cmt: mc::cmt, _: euv::MutateMode) {
         match cmt.cat {
             mc::cat_upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, .. }, .. }) |
-            mc::cat_local(vid) => self.reassigned = self.node == vid,
+            mc::cat_local(vid) => self.reassigned |= self.node == vid,
             mc::cat_interior(ref base_cmt, mc::InteriorField(field)) => {
                 match base_cmt.cat {
                     mc::cat_upvar(mc::Upvar { id: ty::UpvarId { var_id: vid, .. }, .. }) |
                     mc::cat_local(vid) => {
-                        self.reassigned = self.node == vid && Some(field) == self.field
+                        self.reassigned |= self.node == vid && Some(field) == self.field
                     },
                     _ => {}
                 }
@@ -1375,7 +1396,7 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
                                  "__llmatch");
                 trmode = TrByCopy(alloca_no_lifetime(bcx,
                                          llvariable_ty,
-                                         &bcx.ident(ident)[]));
+                                         &bcx.ident(ident)));
             }
             ast::BindByValue(_) => {
                 // in this case, the final type of the variable will be T,
@@ -1383,13 +1404,13 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
                 // above
                 llmatch = alloca_no_lifetime(bcx,
                                  llvariable_ty.ptr_to(),
-                                 &bcx.ident(ident)[]);
+                                 &bcx.ident(ident));
                 trmode = TrByMove;
             }
             ast::BindByRef(_) => {
                 llmatch = alloca_no_lifetime(bcx,
                                  llvariable_ty,
-                                 &bcx.ident(ident)[]);
+                                 &bcx.ident(ident));
                 trmode = TrByRef;
             }
         };
@@ -1499,6 +1520,7 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     fn create_dummy_locals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                        pat: &ast::Pat)
                                        -> Block<'blk, 'tcx> {
+        let _icx = push_ctxt("create_dummy_locals");
         // create dummy memory for the variables if we have no
         // value to store into them immediately
         let tcx = bcx.tcx();
@@ -1506,7 +1528,7 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let scope = cleanup::var_scope(tcx, p_id);
             bcx = mk_binding_alloca(
                 bcx, p_id, &path1.node, scope, (),
-                |(), bcx, llval, ty| { zero_mem(bcx, llval, ty); bcx });
+                |(), bcx, llval, ty| { drop_done_fill_mem(bcx, llval, ty); bcx });
         });
         bcx
     }
@@ -1610,7 +1632,7 @@ fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
     let var_ty = node_id_type(bcx, p_id);
 
     // Allocate memory on stack for the binding.
-    let llval = alloc_ty(bcx, var_ty, &bcx.ident(*ident)[]);
+    let llval = alloc_ty(bcx, var_ty, &bcx.ident(*ident));
 
     // Subtle: be sure that we *populate* the memory *before*
     // we schedule the cleanup.
@@ -1648,7 +1670,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     if bcx.sess().asm_comments() {
         add_comment(bcx, &format!("bind_irrefutable_pat(pat={})",
-                                 pat.repr(bcx.tcx()))[]);
+                                 pat.repr(bcx.tcx())));
     }
 
     let _indenter = indenter();
@@ -1676,8 +1698,14 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
                             ast::BindByRef(_) => {
                                 // By ref binding: the value of the variable
-                                // is the pointer `val` itself.
-                                Store(bcx, val, llval);
+                                // is the pointer `val` itself or fat pointer referenced by `val`
+                                if type_is_fat_ptr(bcx.tcx(), ty) {
+                                    expr::copy_fat_ptr(bcx, val, llval);
+                                }
+                                else {
+                                    Store(bcx, val, llval);
+                                }
+
                                 bcx
                             }
                         }
@@ -1689,7 +1717,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             }
         }
         ast::PatEnum(_, ref sub_pats) => {
-            let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).cloned();
+            let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def());
             match opt_def {
                 Some(def::DefVariant(enum_id, var_id, _)) => {
                     let repr = adt::represent_node(bcx, pat.id);
index eaf6eaa2f089d1273bec3b9f574fa24be70d68dc..fd1fff308dfe3a543252305d73c4a9e427c3b326 100644 (file)
@@ -45,6 +45,7 @@
 
 pub use self::Repr::*;
 
+#[allow(deprecated)]
 use std::num::Int;
 use std::rc::Rc;
 
@@ -81,14 +82,18 @@ pub enum Repr<'tcx> {
     /// Structs with destructors need a dynamic destroyedness flag to
     /// avoid running the destructor too many times; this is included
     /// in the `Struct` if present.
-    Univariant(Struct<'tcx>, bool),
+    /// (The flag if nonzero, represents the initialization value to use;
+    ///  if zero, then use no flag at all.)
+    Univariant(Struct<'tcx>, u8),
     /// General-case enums: for each case there is a struct, and they
     /// all start with a field for the discriminant.
     ///
     /// Types with destructors need a dynamic destroyedness flag to
     /// avoid running the destructor too many times; the last argument
     /// indicates whether such a flag is present.
-    General(IntType, Vec<Struct<'tcx>>, bool),
+    /// (The flag, if nonzero, represents the initialization value to use;
+    ///  if zero, then use no flag at all.)
+    General(IntType, Vec<Struct<'tcx>>, u8),
     /// Two cases distinguished by a nullable pointer: the case with discriminant
     /// `nndiscr` must have single field which is known to be nonnull due to its type.
     /// The other case is known to be zero sized. Hence we represent the enum
@@ -151,11 +156,59 @@ pub fn represent_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     repr
 }
 
+macro_rules! repeat_u8_as_u32 {
+    ($name:expr) => { (($name as u32) << 24 |
+                       ($name as u32) << 16 |
+                       ($name as u32) <<  8 |
+                       ($name as u32)) }
+}
+macro_rules! repeat_u8_as_u64 {
+    ($name:expr) => { ((repeat_u8_as_u32!($name) as u64) << 32 |
+                       (repeat_u8_as_u32!($name) as u64)) }
+}
+
+pub const DTOR_NEEDED: u8 = 0xd4;
+pub const DTOR_NEEDED_U32: u32 = repeat_u8_as_u32!(DTOR_NEEDED);
+pub const DTOR_NEEDED_U64: u64 = repeat_u8_as_u64!(DTOR_NEEDED);
+#[allow(dead_code)]
+pub fn dtor_needed_usize(ccx: &CrateContext) -> usize {
+    match &ccx.tcx().sess.target.target.target_pointer_width[..] {
+        "32" => DTOR_NEEDED_U32 as usize,
+        "64" => DTOR_NEEDED_U64 as usize,
+        tws => panic!("Unsupported target word size for int: {}", tws),
+    }
+}
+
+pub const DTOR_DONE: u8 = 0x1d;
+pub const DTOR_DONE_U32: u32 = repeat_u8_as_u32!(DTOR_DONE);
+pub const DTOR_DONE_U64: u64 = repeat_u8_as_u64!(DTOR_DONE);
+#[allow(dead_code)]
+pub fn dtor_done_usize(ccx: &CrateContext) -> usize {
+    match &ccx.tcx().sess.target.target.target_pointer_width[..] {
+        "32" => DTOR_DONE_U32 as usize,
+        "64" => DTOR_DONE_U64 as usize,
+        tws => panic!("Unsupported target word size for int: {}", tws),
+    }
+}
+
+fn dtor_to_init_u8(dtor: bool) -> u8 {
+    if dtor { DTOR_NEEDED } else { 0 }
+}
+
+pub trait GetDtorType<'tcx> { fn dtor_type(&self) -> Ty<'tcx>; }
+impl<'tcx> GetDtorType<'tcx> for ty::ctxt<'tcx> {
+    fn dtor_type(&self) -> Ty<'tcx> { self.types.u8 }
+}
+
+fn dtor_active(flag: u8) -> bool {
+    flag != 0
+}
+
 fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                      t: Ty<'tcx>) -> Repr<'tcx> {
     match t.sty {
         ty::ty_tup(ref elems) => {
-            Univariant(mk_struct(cx, &elems[..], false, t), false)
+            Univariant(mk_struct(cx, &elems[..], false, t), 0)
         }
         ty::ty_struct(def_id, substs) => {
             let fields = ty::lookup_struct_fields(cx.tcx(), def_id);
@@ -165,19 +218,19 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             }).collect::<Vec<_>>();
             let packed = ty::lookup_packed(cx.tcx(), def_id);
             let dtor = ty::ty_dtor(cx.tcx(), def_id).has_drop_flag();
-            if dtor { ftys.push(cx.tcx().types.bool); }
+            if dtor { ftys.push(cx.tcx().dtor_type()); }
 
-            Univariant(mk_struct(cx, &ftys[..], packed, t), dtor)
+            Univariant(mk_struct(cx, &ftys[..], packed, t), dtor_to_init_u8(dtor))
         }
-        ty::ty_closure(def_id, _, substs) => {
+        ty::ty_closure(def_id, substs) => {
             let typer = NormalizingClosureTyper::new(cx.tcx());
             let upvars = typer.closure_upvars(def_id, substs).unwrap();
             let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
-            Univariant(mk_struct(cx, &upvar_types[..], false, t), false)
+            Univariant(mk_struct(cx, &upvar_types[..], false, t), 0)
         }
         ty::ty_enum(def_id, substs) => {
             let cases = get_cases(cx.tcx(), def_id, substs);
-            let hint = *ty::lookup_repr_hints(cx.tcx(), def_id)[].get(0)
+            let hint = *ty::lookup_repr_hints(cx.tcx(), def_id).get(0)
                 .unwrap_or(&attr::ReprAny);
 
             let dtor = ty::ty_dtor(cx.tcx(), def_id).has_drop_flag();
@@ -186,9 +239,9 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 // Uninhabitable; represent as unit
                 // (Typechecking will reject discriminant-sizing attrs.)
                 assert_eq!(hint, attr::ReprAny);
-                let ftys = if dtor { vec!(cx.tcx().types.bool) } else { vec!() };
+                let ftys = if dtor { vec!(cx.tcx().dtor_type()) } else { vec!() };
                 return Univariant(mk_struct(cx, &ftys[..], false, t),
-                                  dtor);
+                                  dtor_to_init_u8(dtor));
             }
 
             if !dtor && cases.iter().all(|c| c.tys.len() == 0) {
@@ -210,7 +263,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 cx.sess().bug(&format!("non-C-like enum {} with specified \
                                       discriminants",
                                       ty::item_path_str(cx.tcx(),
-                                                        def_id))[]);
+                                                        def_id)));
             }
 
             if cases.len() == 1 {
@@ -218,9 +271,9 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 // (Typechecking will reject discriminant-sizing attrs.)
                 assert_eq!(hint, attr::ReprAny);
                 let mut ftys = cases[0].tys.clone();
-                if dtor { ftys.push(cx.tcx().types.bool); }
+                if dtor { ftys.push(cx.tcx().dtor_type()); }
                 return Univariant(mk_struct(cx, &ftys[..], false, t),
-                                  dtor);
+                                  dtor_to_init_u8(dtor));
             }
 
             if !dtor && cases.len() == 2 && hint == attr::ReprAny {
@@ -228,7 +281,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 let mut discr = 0;
                 while discr < 2 {
                     if cases[1 - discr].is_zerolen(cx, t) {
-                        let st = mk_struct(cx, &cases[discr].tys[],
+                        let st = mk_struct(cx, &cases[discr].tys,
                                            false, t);
                         match cases[discr].find_ptr(cx) {
                             Some(ref df) if df.len() == 1 && st.fields.len() == 1 => {
@@ -266,7 +319,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let fields : Vec<_> = cases.iter().map(|c| {
                 let mut ftys = vec!(ty_of_inttype(cx.tcx(), min_ity));
                 ftys.push_all(&c.tys);
-                if dtor { ftys.push(cx.tcx().types.bool); }
+                if dtor { ftys.push(cx.tcx().dtor_type()); }
                 mk_struct(cx, &ftys, false, t)
             }).collect();
 
@@ -318,17 +371,17 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
             let fields : Vec<_> = cases.iter().map(|c| {
                 let mut ftys = vec!(ty_of_inttype(cx.tcx(), ity));
-                ftys.push_all(&c.tys[]);
-                if dtor { ftys.push(cx.tcx().types.bool); }
+                ftys.push_all(&c.tys);
+                if dtor { ftys.push(cx.tcx().dtor_type()); }
                 mk_struct(cx, &ftys[..], false, t)
             }).collect();
 
             ensure_enum_fits_in_address_space(cx, &fields[..], t);
 
-            General(ity, fields, dtor)
+            General(ity, fields, dtor_to_init_u8(dtor))
         }
         _ => cx.sess().bug(&format!("adt::represent_type called on non-ADT type: {}",
-                           ty_to_string(cx.tcx(), t))[])
+                           ty_to_string(cx.tcx(), t)))
     }
 }
 
@@ -339,7 +392,7 @@ struct Case<'tcx> {
 }
 
 /// This represents the (GEP) indices to follow to get to the discriminant field
-pub type DiscrField = Vec<uint>;
+pub type DiscrField = Vec<usize>;
 
 fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
                                     ty: Ty<'tcx>,
@@ -414,7 +467,7 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
 
 impl<'tcx> Case<'tcx> {
     fn is_zerolen<'a>(&self, cx: &CrateContext<'a, 'tcx>, scapegoat: Ty<'tcx>) -> bool {
-        mk_struct(cx, &self.tys[], false, scapegoat).size == 0
+        mk_struct(cx, &self.tys, false, scapegoat).size == 0
     }
 
     fn find_ptr<'a>(&self, cx: &CrateContext<'a, 'tcx>) -> Option<DiscrField> {
@@ -487,12 +540,12 @@ fn range_to_inttype(cx: &CrateContext, hint: Hint, bounds: &IntBounds) -> IntTyp
     debug!("range_to_inttype: {:?} {:?}", hint, bounds);
     // Lists of sizes to try.  u64 is always allowed as a fallback.
     #[allow(non_upper_case_globals)]
-    static choose_shortest: &'static[IntType] = &[
+    const choose_shortest: &'static [IntType] = &[
         attr::UnsignedInt(ast::TyU8), attr::SignedInt(ast::TyI8),
         attr::UnsignedInt(ast::TyU16), attr::SignedInt(ast::TyI16),
         attr::UnsignedInt(ast::TyU32), attr::SignedInt(ast::TyI32)];
     #[allow(non_upper_case_globals)]
-    static at_least_32: &'static[IntType] = &[
+    const at_least_32: &'static [IntType] = &[
         attr::UnsignedInt(ast::TyU32), attr::SignedInt(ast::TyI32)];
 
     let attempts;
@@ -504,7 +557,7 @@ fn range_to_inttype(cx: &CrateContext, hint: Hint, bounds: &IntBounds) -> IntTyp
             return ity;
         }
         attr::ReprExtern => {
-            attempts = match &cx.sess().target.target.arch[] {
+            attempts = match &cx.sess().target.target.arch[..] {
                 // WARNING: the ARM EABI has two variants; the one corresponding to `at_least_32`
                 // appears to be used on Linux and NetBSD, but some systems may use the variant
                 // corresponding to `choose_shortest`.  However, we don't run on those yet...?
@@ -624,7 +677,7 @@ pub fn finish_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     match *r {
         CEnum(..) | General(..) | RawNullablePointer { .. } => { }
         Univariant(ref st, _) | StructWrappedNullablePointer { nonnull: ref st, .. } =>
-            llty.set_struct_body(&struct_llfields(cx, st, false, false)[],
+            llty.set_struct_body(&struct_llfields(cx, st, false, false),
                                  st.packed)
     }
 }
@@ -640,7 +693,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         Univariant(ref st, _) | StructWrappedNullablePointer { nonnull: ref st, .. } => {
             match name {
                 None => {
-                    Type::struct_(cx, &struct_llfields(cx, st, sizing, dst)[],
+                    Type::struct_(cx, &struct_llfields(cx, st, sizing, dst),
                                   st.packed)
                 }
                 Some(name) => { assert_eq!(sizing, false); Type::named_struct(cx, name) }
@@ -699,7 +752,7 @@ fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, st: &Struct<'tcx>,
         st.fields.iter().filter(|&ty| !dst || type_is_sized(cx.tcx(), *ty))
             .map(|&ty| type_of::sizing_type_of(cx, ty)).collect()
     } else {
-        st.fields.iter().map(|&ty| type_of::type_of(cx, ty)).collect()
+        st.fields.iter().map(|&ty| type_of::in_memory_type_of(cx, ty)).collect()
     }
 }
 
@@ -776,9 +829,11 @@ fn load_discr(bcx: Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr)
     assert_eq!(val_ty(ptr), llty.ptr_to());
     let bits = machine::llbitsize_of_real(bcx.ccx(), llty);
     assert!(bits <= 64);
-    let  bits = bits as uint;
-    let mask = (-1u64 >> (64 - bits)) as Disr;
-    if (max + 1) & mask == min & mask {
+    let  bits = bits as usize;
+    let mask = (!0u64 >> (64 - bits)) as Disr;
+    // For a (max) discr of -1, max will be `-1 as usize`, which overflows.
+    // However, that is fine here (it would still represent the full range),
+    if (max.wrapping_add(1)) & mask == min & mask {
         // i.e., if the range is everything.  The lo==hi case would be
         // rejected by the LLVM verifier (it would mean either an
         // empty set, which is impossible, or the entire range of the
@@ -787,7 +842,7 @@ fn load_discr(bcx: Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr)
     } else {
         // llvm::ConstantRange can deal with ranges that wrap around,
         // so an overflow on (max + 1) is fine.
-        LoadRangeAssert(bcx, ptr, min, (max+1), /* signed: */ True)
+        LoadRangeAssert(bcx, ptr, min, (max.wrapping_add(1)), /* signed: */ True)
     }
 }
 
@@ -828,18 +883,18 @@ pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
                   val)
         }
         General(ity, ref cases, dtor) => {
-            if dtor {
+            if dtor_active(dtor) {
                 let ptr = trans_field_ptr(bcx, r, val, discr,
-                                          cases[discr as uint].fields.len() - 2);
-                Store(bcx, C_u8(bcx.ccx(), 1), ptr);
+                                          cases[discr as usize].fields.len() - 2);
+                Store(bcx, C_u8(bcx.ccx(), DTOR_NEEDED as usize), ptr);
             }
             Store(bcx, C_integral(ll_inttype(bcx.ccx(), ity), discr as u64, true),
                   GEPi(bcx, val, &[0, 0]))
         }
         Univariant(ref st, dtor) => {
             assert_eq!(discr, 0);
-            if dtor {
-                Store(bcx, C_u8(bcx.ccx(), 1),
+            if dtor_active(dtor) {
+                Store(bcx, C_u8(bcx.ccx(), DTOR_NEEDED as usize),
                     GEPi(bcx, val, &[0, st.fields.len() - 1]));
             }
         }
@@ -868,15 +923,15 @@ fn assert_discr_in_range(ity: IntType, min: Disr, max: Disr, discr: Disr) {
 
 /// The number of fields in a given case; for use when obtaining this
 /// information from the type or definition is less convenient.
-pub fn num_args(r: &Repr, discr: Disr) -> uint {
+pub fn num_args(r: &Repr, discr: Disr) -> usize {
     match *r {
         CEnum(..) => 0,
         Univariant(ref st, dtor) => {
             assert_eq!(discr, 0);
-            st.fields.len() - (if dtor { 1 } else { 0 })
+            st.fields.len() - (if dtor_active(dtor) { 1 } else { 0 })
         }
         General(_, ref cases, dtor) => {
-            cases[discr as uint].fields.len() - 1 - (if dtor { 1 } else { 0 })
+            cases[discr as usize].fields.len() - 1 - (if dtor_active(dtor) { 1 } else { 0 })
         }
         RawNullablePointer { nndiscr, ref nullfields, .. } => {
             if discr == nndiscr { 1 } else { nullfields.len() }
@@ -890,7 +945,7 @@ pub fn num_args(r: &Repr, discr: Disr) -> uint {
 
 /// Access a field, at a point when the value's case is known.
 pub fn trans_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
-                                   val: ValueRef, discr: Disr, ix: uint) -> ValueRef {
+                                   val: ValueRef, discr: Disr, ix: usize) -> ValueRef {
     // Note: if this ever needs to generate conditionals (e.g., if we
     // decide to do some kind of cdr-coding-like non-unique repr
     // someday), it will need to return a possibly-new bcx as well.
@@ -903,7 +958,7 @@ pub fn trans_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
             struct_field_ptr(bcx, st, val, ix, false)
         }
         General(_, ref cases, _) => {
-            struct_field_ptr(bcx, &cases[discr as uint], val, ix + 1, true)
+            struct_field_ptr(bcx, &cases[discr as usize], val, ix + 1, true)
         }
         RawNullablePointer { nndiscr, ref nullfields, .. } |
         StructWrappedNullablePointer { nndiscr, ref nullfields, .. } if discr != nndiscr => {
@@ -929,7 +984,7 @@ pub fn trans_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
 }
 
 pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, val: ValueRef,
-                                    ix: uint, needs_cast: bool) -> ValueRef {
+                                    ix: usize, needs_cast: bool) -> ValueRef {
     let val = if needs_cast {
         let ccx = bcx.ccx();
         let fields = st.fields.iter().map(|&ty| type_of::type_of(ccx, ty)).collect::<Vec<_>>();
@@ -965,7 +1020,7 @@ pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
 
             for (discr, case) in cases.iter().enumerate() {
                 let mut variant_cx = fcx.new_temp_block(
-                    &format!("enum-variant-iter-{}", &discr.to_string())[]
+                    &format!("enum-variant-iter-{}", &discr.to_string())
                 );
                 let rhs_val = C_integral(ll_inttype(ccx, ity), discr as u64, true);
                 AddCase(llswitch, rhs_val, variant_cx.llbb);
@@ -990,17 +1045,17 @@ pub fn trans_drop_flag_ptr<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, r: &Repr<'tcx
                                        -> datum::DatumBlock<'blk, 'tcx, datum::Expr>
 {
     let tcx = bcx.tcx();
-    let ptr_ty = ty::mk_imm_ptr(bcx.tcx(), tcx.types.bool);
+    let ptr_ty = ty::mk_imm_ptr(bcx.tcx(), tcx.dtor_type());
     match *r {
-        Univariant(ref st, true) => {
+        Univariant(ref st, dtor) if dtor_active(dtor) => {
             let flag_ptr = GEPi(bcx, val, &[0, st.fields.len() - 1]);
             datum::immediate_rvalue_bcx(bcx, flag_ptr, ptr_ty).to_expr_datumblock()
         }
-        General(_, _, true) => {
+        General(_, _, dtor) if dtor_active(dtor) => {
             let fcx = bcx.fcx;
             let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
             let scratch = unpack_datum!(bcx, datum::lvalue_scratch_datum(
-                bcx, tcx.types.bool, "drop_flag", false,
+                bcx, tcx.dtor_type(), "drop_flag",
                 cleanup::CustomScope(custom_cleanup_scope), (), |_, bcx, _| bcx
             ));
             bcx = fold_variants(bcx, r, val, |variant_cx, st, value| {
@@ -1044,7 +1099,7 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr
             C_integral(ll_inttype(ccx, ity), discr as u64, true)
         }
         General(ity, ref cases, _) => {
-            let case = &cases[discr as uint];
+            let case = &cases[discr as usize];
             let (max_sz, _) = union_size_and_align(&cases[..]);
             let lldiscr = C_integral(ll_inttype(ccx, ity), discr as u64, true);
             let mut f = vec![lldiscr];
@@ -1070,7 +1125,7 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr
             if discr == nndiscr {
                 C_struct(ccx, &build_const_struct(ccx,
                                                  nonnull,
-                                                 vals)[],
+                                                 vals),
                          false)
             } else {
                 let vals = nonnull.fields.iter().map(|&ty| {
@@ -1080,7 +1135,7 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, r: &Repr<'tcx>, discr
                 }).collect::<Vec<ValueRef>>();
                 C_struct(ccx, &build_const_struct(ccx,
                                                  nonnull,
-                                                 &vals[..])[],
+                                                 &vals[..]),
                          false)
             }
         }
@@ -1182,7 +1237,7 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef) -> Disr {
 /// (Not to be confused with `common::const_get_elt`, which operates on
 /// raw LLVM-level structs and arrays.)
 pub fn const_get_field(ccx: &CrateContext, r: &Repr, val: ValueRef,
-                       _discr: Disr, ix: uint) -> ValueRef {
+                       _discr: Disr, ix: usize) -> ValueRef {
     match *r {
         CEnum(..) => ccx.sess().bug("element access in C-like enum const"),
         Univariant(..) => const_struct_field(ccx, val, ix),
@@ -1196,7 +1251,7 @@ pub fn const_get_field(ccx: &CrateContext, r: &Repr, val: ValueRef,
 }
 
 /// Extract field of struct-like const, skipping our alignment padding.
-fn const_struct_field(ccx: &CrateContext, val: ValueRef, ix: uint) -> ValueRef {
+fn const_struct_field(ccx: &CrateContext, val: ValueRef, ix: usize) -> ValueRef {
     // Get the ix-th non-undef element of the struct.
     let mut real_ix = 0; // actual position in the struct
     let mut ix = ix; // logical index relative to real_ix
index a3bd0cf6b1a623bac1cf719408aa45f7d1696859..d6c85e8b173459c5449a60a68dbccc6bdb6d7e99 100644 (file)
@@ -76,43 +76,33 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
     // no failure occurred preparing operands, no need to cleanup
     fcx.pop_custom_cleanup_scope(temp_scope);
 
-    let mut constraints = constraints.iter()
-                                     .map(|s| s.to_string())
-                                     .chain(ext_constraints.into_iter())
-                                     .collect::<Vec<String>>()
-                                     .connect(",");
-
-    let mut clobbers = ia.clobbers.iter()
-                                  .map(|s| format!("~{{{}}}", &s))
-                                  .collect::<Vec<String>>()
-                                  .connect(",");
-    let more_clobbers = get_clobbers();
-    if !more_clobbers.is_empty() {
-        if !clobbers.is_empty() {
-            clobbers.push(',');
-        }
-        clobbers.push_str(&more_clobbers[..]);
-    }
-
-    // Add the clobbers to our constraints list
-    if clobbers.len() != 0 && constraints.len() != 0 {
-        constraints.push(',');
-        constraints.push_str(&clobbers[..]);
-    } else {
-        constraints.push_str(&clobbers[..]);
-    }
+    let clobbers = ia.clobbers.iter()
+                              .map(|s| format!("~{{{}}}", &s));
+
+    // Default per-arch clobbers
+    // Basically what clang does
+    let arch_clobbers = match &bcx.sess().target.target.arch[..] {
+        "x86" | "x86_64" => vec!("~{dirflag}", "~{fpsr}", "~{flags}"),
+        _                => Vec::new()
+    };
 
-    debug!("Asm Constraints: {}", &constraints[..]);
+    let all_constraints= constraints.iter()
+                                    .map(|s| s.to_string())
+                                    .chain(ext_constraints.into_iter())
+                                    .chain(clobbers)
+                                    .chain(arch_clobbers.iter()
+                                               .map(|s| s.to_string()))
+                                    .collect::<Vec<String>>()
+                                    .connect(",");
 
-    let num_outputs = outputs.len();
+    debug!("Asm Constraints: {}", &all_constraints[..]);
 
     // Depending on how many outputs we have, the return type is different
-    let output_type = if num_outputs == 0 {
-        Type::void(bcx.ccx())
-    } else if num_outputs == 1 {
-        output_types[0]
-    } else {
-        Type::struct_(bcx.ccx(), &output_types[..], false)
+    let num_outputs = outputs.len();
+    let output_type = match num_outputs {
+        0 => Type::void(bcx.ccx()),
+        1 => output_types[0],
+        _ => Type::struct_(bcx.ccx(), &output_types[..], false)
     };
 
     let dialect = match ia.dialect {
@@ -121,10 +111,10 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
     };
 
     let asm = CString::new(ia.asm.as_bytes()).unwrap();
-    let constraints = CString::new(constraints).unwrap();
+    let constraint_cstr = CString::new(all_constraints).unwrap();
     let r = InlineAsmCall(bcx,
                           asm.as_ptr(),
-                          constraints.as_ptr(),
+                          constraint_cstr.as_ptr(),
                           &inputs,
                           output_type,
                           ia.volatile,
@@ -158,15 +148,3 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
 
 }
 
-// Default per-arch clobbers
-// Basically what clang does
-
-#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
-fn get_clobbers() -> String {
-    "".to_string()
-}
-
-#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-fn get_clobbers() -> String {
-    "~{dirflag},~{fpsr},~{flags}".to_string()
-}
index 3091c852f5587baa80a11f567d4cc31104f72f43..05c366a645e76daaec0816d2d4187d436d1ee565 100644 (file)
@@ -30,10 +30,10 @@ pub use self::ValueOrigin::*;
 use super::CrateTranslation;
 use super::ModuleTranslation;
 
-use back::link::{mangle_exported_name};
+use back::link::mangle_exported_name;
 use back::{link, abi};
 use lint;
-use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
+use llvm::{AttrHelper, BasicBlockRef, Linkage, ValueRef, Vector, get_param};
 use llvm;
 use metadata::{csearch, encoder, loader};
 use middle::astencode;
@@ -41,7 +41,7 @@ use middle::cfg;
 use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
 use middle::weak_lang_items;
 use middle::subst::{Subst, Substs};
-use middle::ty::{self, Ty, ClosureTyper};
+use middle::ty::{self, Ty, ClosureTyper, type_is_simd, simd_size};
 use session::config::{self, NoDebugInfo};
 use session::Session;
 use trans::_match;
@@ -52,13 +52,12 @@ use trans::callee;
 use trans::cleanup::CleanupMethods;
 use trans::cleanup;
 use trans::closure;
-use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_integral};
+use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_int, C_integral};
 use trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_undef};
 use trans::common::{CrateContext, ExternMap, FunctionContext};
 use trans::common::{Result, NodeIdAndSpan};
 use trans::common::{node_id_type, return_type_is_void};
-use trans::common::{tydesc_info, type_is_immediate};
-use trans::common::{type_is_zero_size, val_ty};
+use trans::common::{type_is_immediate, type_is_zero_size, val_ty};
 use trans::common;
 use trans::consts;
 use trans::context::SharedCrateContext;
@@ -90,7 +89,6 @@ use std::ffi::{CStr, CString};
 use std::cell::{Cell, RefCell};
 use std::collections::HashSet;
 use std::mem;
-use std::rc::Rc;
 use std::str;
 use std::{i8, i16, i32, i64};
 use syntax::abi::{Rust, RustCall, RustIntrinsic, Abi};
@@ -153,7 +151,7 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
 pub struct StatRecorder<'a, 'tcx: 'a> {
     ccx: &'a CrateContext<'a, 'tcx>,
     name: Option<String>,
-    istart: uint,
+    istart: usize,
 }
 
 impl<'a, 'tcx> StatRecorder<'a, 'tcx> {
@@ -271,7 +269,7 @@ pub fn self_type_for_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 }
 
 pub fn kind_for_closure(ccx: &CrateContext, closure_id: ast::DefId) -> ty::ClosureKind {
-    ccx.tcx().closure_kinds.borrow()[closure_id]
+    *ccx.tcx().closure_kinds.borrow().get(&closure_id).unwrap()
 }
 
 pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
@@ -291,7 +289,7 @@ pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         ty::ty_bare_fn(_, ref f) => {
             (&f.sig, f.abi, None)
         }
-        ty::ty_closure(closure_did, _, substs) => {
+        ty::ty_closure(closure_did, substs) => {
             let typer = common::NormalizingClosureTyper::new(ccx.tcx());
             function_type = typer.closure_type(closure_did, substs);
             let self_type = self_type_for_closure(ccx, closure_did, fn_ty);
@@ -301,7 +299,7 @@ pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                    self_type.repr(ccx.tcx()));
             (&function_type.sig, RustCall, Some(llenvironment_type))
         }
-        _ => panic!("expected closure or fn")
+        _ => ccx.sess().bug("expected closure or fn")
     };
 
     let sig = ty::erase_late_bound_regions(ccx.tcx(), sig);
@@ -365,7 +363,7 @@ fn require_alloc_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         Err(s) => {
             bcx.sess().fatal(&format!("allocation of `{}` {}",
                                      bcx.ty_to_string(info_ty),
-                                     s)[]);
+                                     s));
         }
     }
 }
@@ -392,22 +390,6 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
 }
 
-// Type descriptor and type glue stuff
-
-pub fn get_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-                            t: Ty<'tcx>) -> Rc<tydesc_info<'tcx>> {
-    match ccx.tydescs().borrow().get(&t) {
-        Some(inf) => return inf.clone(),
-        _ => { }
-    }
-
-    ccx.stats().n_static_tydescs.set(ccx.stats().n_static_tydescs.get() + 1);
-    let inf = Rc::new(glue::declare_tydesc(ccx, t));
-
-    ccx.tydescs().borrow_mut().insert(t, inf.clone());
-    inf
-}
-
 #[allow(dead_code)] // useful
 pub fn set_optimize_for_size(f: ValueRef) {
     llvm::SetFunctionAttribute(f, llvm::OptimizeForSizeAttribute)
@@ -433,29 +415,27 @@ pub fn set_inline_hint(f: ValueRef) {
 }
 
 pub fn set_llvm_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) {
-    use syntax::attr::*;
+    use syntax::attr::{find_inline_attr, InlineAttr};
     // Set the inline hint if there is one
-    match find_inline_attr(attrs) {
-        InlineHint   => set_inline_hint(llfn),
-        InlineAlways => set_always_inline(llfn),
-        InlineNever  => set_no_inline(llfn),
-        InlineNone   => { /* fallthrough */ }
+    match find_inline_attr(Some(ccx.sess().diagnostic()), attrs) {
+        InlineAttr::Hint   => set_inline_hint(llfn),
+        InlineAttr::Always => set_always_inline(llfn),
+        InlineAttr::Never  => set_no_inline(llfn),
+        InlineAttr::None   => { /* fallthrough */ }
     }
 
     for attr in attrs {
         let mut used = true;
-        match &attr.name()[] {
+        match &attr.name()[..] {
             "no_stack_check" => unset_split_stack(llfn),
-            "no_split_stack" => {
-                unset_split_stack(llfn);
-                ccx.sess().span_warn(attr.span,
-                                     "no_split_stack is a deprecated synonym for no_stack_check");
-            }
             "cold" => unsafe {
                 llvm::LLVMAddFunctionAttribute(llfn,
                                                llvm::FunctionIndex as c_uint,
                                                llvm::ColdAttribute as uint64_t)
             },
+            "allocator" => {
+                llvm::NoAliasAttribute.apply_llfn(llvm::ReturnIndex as c_uint, llfn);
+            }
             _ => used = false,
         }
         if used {
@@ -486,7 +466,7 @@ pub fn unset_split_stack(f: ValueRef) {
 // silently mangles such symbols, breaking our linkage model.
 pub fn note_unique_llvm_symbol(ccx: &CrateContext, sym: String) {
     if ccx.all_llvm_symbols().borrow().contains(&sym) {
-        ccx.sess().bug(&format!("duplicate LLVM symbol: {}", sym)[]);
+        ccx.sess().bug(&format!("duplicate LLVM symbol: {}", sym));
     }
     ccx.all_llvm_symbols().borrow_mut().insert(sym);
 }
@@ -541,7 +521,7 @@ pub fn bin_op_to_icmp_predicate(ccx: &CrateContext, op: ast::BinOp_, signed: boo
         ast::BiGe => if signed { llvm::IntSGE } else { llvm::IntUGE },
         op => {
             ccx.sess().bug(&format!("comparison_op_to_icmp_predicate: expected \
-                                     comparison operator, found {:?}", op)[]);
+                                     comparison operator, found {:?}", op));
         }
     }
 }
@@ -557,7 +537,7 @@ pub fn bin_op_to_fcmp_predicate(ccx: &CrateContext, op: ast::BinOp_)
         ast::BiGe => llvm::RealOGE,
         op => {
             ccx.sess().bug(&format!("comparison_op_to_fcmp_predicate: expected \
-                                     comparison operator, found {:?}", op)[]);
+                                     comparison operator, found {:?}", op));
         }
     }
 }
@@ -580,7 +560,7 @@ pub fn compare_scalar_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 _ => bcx.sess().bug("compare_scalar_types: must be a comparison operator")
             }
         }
-        ty::ty_bool | ty::ty_uint(_) | ty::ty_char => {
+        ty::ty_bare_fn(..) | ty::ty_bool | ty::ty_uint(_) | ty::ty_char => {
             ICmp(bcx, bin_op_to_icmp_predicate(bcx.ccx(), op, false), lhs, rhs, debug_loc)
         }
         ty::ty_ptr(mt) if common::type_is_sized(bcx.tcx(), mt.ty) => {
@@ -676,8 +656,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
                   let val = if common::type_is_sized(cx.tcx(), field_ty) {
                       llfld_a
                   } else {
-                      let boxed_ty = ty::mk_open(cx.tcx(), field_ty);
-                      let scratch = datum::rvalue_scratch_datum(cx, boxed_ty, "__fat_ptr_iter");
+                      let scratch = datum::rvalue_scratch_datum(cx, field_ty, "__fat_ptr_iter");
                       Store(cx, llfld_a, GEPi(cx, scratch.val, &[0, abi::FAT_PTR_ADDR]));
                       Store(cx, info.unwrap(), GEPi(cx, scratch.val, &[0, abi::FAT_PTR_EXTRA]));
                       scratch.val
@@ -686,7 +665,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
               }
           })
       }
-      ty::ty_closure(def_id, _, substs) => {
+      ty::ty_closure(def_id, substs) => {
           let repr = adt::represent_type(cx.ccx(), t);
           let typer = common::NormalizingClosureTyper::new(cx.tcx());
           let upvars = typer.closure_upvars(def_id, substs).unwrap();
@@ -700,6 +679,10 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
         let unit_ty = ty::sequence_element_type(cx.tcx(), t);
         cx = tvec::iter_vec_raw(cx, base, unit_ty, len, f);
       }
+      ty::ty_vec(_, None) | ty::ty_str => {
+        let unit_ty = ty::sequence_element_type(cx.tcx(), t);
+        cx = tvec::iter_vec_raw(cx, data_ptr, unit_ty, info.unwrap(), f);
+      }
       ty::ty_tup(ref args) => {
           let repr = adt::represent_type(cx.ccx(), t);
           for (i, arg) in args.iter().enumerate() {
@@ -724,7 +707,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
                                     substs, &mut f);
               }
               (_match::Switch, Some(lldiscrim_a)) => {
-                  cx = f(cx, lldiscrim_a, cx.tcx().types.int);
+                  cx = f(cx, lldiscrim_a, cx.tcx().types.isize);
                   let unr_cx = fcx.new_temp_block("enum-iter-unr");
                   Unreachable(unr_cx);
                   let llswitch = Switch(cx, lldiscrim_a, unr_cx.llbb,
@@ -735,8 +718,8 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
                       let variant_cx =
                           fcx.new_temp_block(
                               &format!("enum-iter-variant-{}",
-                                      &variant.disr_val.to_string()[])
-                              []);
+                                      &variant.disr_val.to_string())
+                              );
                       match adt::trans_case(cx, &*repr, variant.disr_val) {
                           _match::SingleResult(r) => {
                               AddCase(llswitch, r.val, variant_cx.llbb)
@@ -761,14 +744,14 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
       }
       _ => {
           cx.sess().unimpl(&format!("type in iter_structural_ty: {}",
-                                   ty_to_string(cx.tcx(), t))[])
+                                   ty_to_string(cx.tcx(), t)))
       }
     }
     return cx;
 }
 
 pub fn cast_shift_expr_rhs(cx: Block,
-                           op: ast::BinOp,
+                           op: ast::BinOp_,
                            lhs: ValueRef,
                            rhs: ValueRef)
                            -> ValueRef {
@@ -777,24 +760,24 @@ pub fn cast_shift_expr_rhs(cx: Block,
                    |a,b| ZExt(cx, a, b))
 }
 
-pub fn cast_shift_const_rhs(op: ast::BinOp,
+pub fn cast_shift_const_rhs(op: ast::BinOp_,
                             lhs: ValueRef, rhs: ValueRef) -> ValueRef {
     cast_shift_rhs(op, lhs, rhs,
                    |a, b| unsafe { llvm::LLVMConstTrunc(a, b.to_ref()) },
                    |a, b| unsafe { llvm::LLVMConstZExt(a, b.to_ref()) })
 }
 
-pub fn cast_shift_rhs<F, G>(op: ast::BinOp,
-                            lhs: ValueRef,
-                            rhs: ValueRef,
-                            trunc: F,
-                            zext: G)
-                            -> ValueRef where
+fn cast_shift_rhs<F, G>(op: ast::BinOp_,
+                        lhs: ValueRef,
+                        rhs: ValueRef,
+                        trunc: F,
+                        zext: G)
+                        -> ValueRef where
     F: FnOnce(ValueRef, Type) -> ValueRef,
     G: FnOnce(ValueRef, Type) -> ValueRef,
 {
     // Shifts may have any size int on the rhs
-    if ast_util::is_shift_binop(op.node) {
+    if ast_util::is_shift_binop(op) {
         let mut rhs_llty = val_ty(rhs);
         let mut lhs_llty = val_ty(lhs);
         if rhs_llty.kind() == Vector { rhs_llty = rhs_llty.element_type() }
@@ -834,16 +817,25 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
 
     let (is_zero, is_signed) = match rhs_t.sty {
         ty::ty_int(t) => {
-            let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, false);
+            let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0, false);
             (ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), true)
         }
         ty::ty_uint(t) => {
-            let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, false);
+            let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0, false);
             (ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), false)
         }
+        ty::ty_struct(_, _) if type_is_simd(cx.tcx(), rhs_t) => {
+            let mut res = C_bool(cx.ccx(), false);
+            for i in 0 .. simd_size(cx.tcx(), rhs_t) {
+                res = Or(cx, res,
+                         IsNull(cx,
+                                ExtractElement(cx, rhs, C_int(cx.ccx(), i as i64))), debug_loc);
+            }
+            (res, false)
+        }
         _ => {
             cx.sess().bug(&format!("fail-if-zero on unexpected type: {}",
-                                  ty_to_string(cx.tcx(), rhs_t))[]);
+                                  ty_to_string(cx.tcx(), rhs_t)));
         }
     };
     let bcx = with_cond(cx, is_zero, |bcx| {
@@ -864,8 +856,8 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
             ty::ty_int(t) => {
                 let llty = Type::int_from_ty(cx.ccx(), t);
                 let min = match t {
-                    ast::TyIs(_) if llty == Type::i32(cx.ccx()) => i32::MIN as u64,
-                    ast::TyIs(_) => i64::MIN as u64,
+                    ast::TyIs if llty == Type::i32(cx.ccx()) => i32::MIN as u64,
+                    ast::TyIs => i64::MIN as u64,
                     ast::TyI8 => i8::MIN as u64,
                     ast::TyI16 => i16::MIN as u64,
                     ast::TyI32 => i32::MIN as u64,
@@ -876,7 +868,7 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
             _ => unreachable!(),
         };
         let minus_one = ICmp(bcx, llvm::IntEQ, rhs,
-                             C_integral(llty, -1, false), debug_loc);
+                             C_integral(llty, !0, false), debug_loc);
         with_cond(bcx, minus_one, |bcx| {
             let is_min = ICmp(bcx, llvm::IntEQ, lhs,
                               C_integral(llty, min, true), debug_loc);
@@ -904,8 +896,10 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                     ccx.sess().bug("unexpected intrinsic in trans_external_path")
                 }
                 _ => {
-                    foreign::register_foreign_item_fn(ccx, fn_ty.abi, t,
-                                                      &name[..])
+                    let llfn = foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, &name[..]);
+                    let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did);
+                    set_llvm_fn_attrs(ccx, &attrs, llfn);
+                    llfn
                 }
             }
         }
@@ -993,56 +987,72 @@ pub fn load_if_immediate<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
 /// gives us better information about what we are loading.
 pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                            ptr: ValueRef, t: Ty<'tcx>) -> ValueRef {
-    if type_is_zero_size(cx.ccx(), t) {
-        C_undef(type_of::type_of(cx.ccx(), t))
-    } else if type_is_immediate(cx.ccx(), t) && type_of::type_of(cx.ccx(), t).is_aggregate() {
-        // We want to pass small aggregates as immediate values, but using an aggregate LLVM type
-        // for this leads to bad optimizations, so its arg type is an appropriately sized integer
-        // and we have to convert it
-        Load(cx, BitCast(cx, ptr, type_of::arg_type_of(cx.ccx(), t).ptr_to()))
-    } else {
-        unsafe {
-            let global = llvm::LLVMIsAGlobalVariable(ptr);
-            if !global.is_null() && llvm::LLVMIsGlobalConstant(global) == llvm::True {
-                let val = llvm::LLVMGetInitializer(global);
-                if !val.is_null() {
-                    // This could go into its own function, for DRY.
-                    // (something like "pre-store packing/post-load unpacking")
-                    if ty::type_is_bool(t) {
-                        return Trunc(cx, val, Type::i1(cx.ccx()));
-                    } else {
-                        return val;
-                    }
-                }
+    if cx.unreachable.get() || type_is_zero_size(cx.ccx(), t) {
+        return C_undef(type_of::type_of(cx.ccx(), t));
+    }
+
+    let ptr = to_arg_ty_ptr(cx, ptr, t);
+
+    if type_is_immediate(cx.ccx(), t) && type_of::type_of(cx.ccx(), t).is_aggregate() {
+        return Load(cx, ptr);
+    }
+
+    unsafe {
+        let global = llvm::LLVMIsAGlobalVariable(ptr);
+        if !global.is_null() && llvm::LLVMIsGlobalConstant(global) == llvm::True {
+            let val = llvm::LLVMGetInitializer(global);
+            if !val.is_null() {
+                return from_arg_ty(cx, val, t);
             }
         }
-        if ty::type_is_bool(t) {
-            Trunc(cx, LoadRangeAssert(cx, ptr, 0, 2, llvm::False), Type::i1(cx.ccx()))
-        } else if ty::type_is_char(t) {
-            // a char is a Unicode codepoint, and so takes values from 0
-            // to 0x10FFFF inclusive only.
-            LoadRangeAssert(cx, ptr, 0, 0x10FFFF + 1, llvm::False)
-        } else if (ty::type_is_region_ptr(t) || ty::type_is_unique(t))
-                  && !common::type_is_fat_ptr(cx.tcx(), t) {
-            LoadNonNull(cx, ptr)
-        } else {
-            Load(cx, ptr)
-        }
     }
+
+    let val =  if ty::type_is_bool(t) {
+        LoadRangeAssert(cx, ptr, 0, 2, llvm::False)
+    } else if ty::type_is_char(t) {
+        // a char is a Unicode codepoint, and so takes values from 0
+        // to 0x10FFFF inclusive only.
+        LoadRangeAssert(cx, ptr, 0, 0x10FFFF + 1, llvm::False)
+    } else if (ty::type_is_region_ptr(t) || ty::type_is_unique(t))
+        && !common::type_is_fat_ptr(cx.tcx(), t) {
+            LoadNonNull(cx, ptr)
+    } else {
+        Load(cx, ptr)
+    };
+
+    from_arg_ty(cx, val, t)
 }
 
 /// Helper for storing values in memory. Does the necessary conversion if the in-memory type
 /// differs from the type used for SSA values.
 pub fn store_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, dst: ValueRef, t: Ty<'tcx>) {
-    if ty::type_is_bool(t) {
-        Store(cx, ZExt(cx, v, Type::i8(cx.ccx())), dst);
-    } else if type_is_immediate(cx.ccx(), t) && type_of::type_of(cx.ccx(), t).is_aggregate() {
+    Store(cx, to_arg_ty(cx, v, t), to_arg_ty_ptr(cx, dst, t));
+}
+
+pub fn to_arg_ty(bcx: Block, val: ValueRef, ty: Ty) -> ValueRef {
+    if ty::type_is_bool(ty) {
+        ZExt(bcx, val, Type::i8(bcx.ccx()))
+    } else {
+        val
+    }
+}
+
+pub fn from_arg_ty(bcx: Block, val: ValueRef, ty: Ty) -> ValueRef {
+    if ty::type_is_bool(ty) {
+        Trunc(bcx, val, Type::i1(bcx.ccx()))
+    } else {
+        val
+    }
+}
+
+pub fn to_arg_ty_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ptr: ValueRef, ty: Ty<'tcx>) -> ValueRef {
+    if type_is_immediate(bcx.ccx(), ty) && type_of::type_of(bcx.ccx(), ty).is_aggregate() {
         // We want to pass small aggregates as immediate values, but using an aggregate LLVM type
         // for this leads to bad optimizations, so its arg type is an appropriately sized integer
         // and we have to convert it
-        Store(cx, v, BitCast(cx, dst, type_of::arg_type_of(cx.ccx(), t).ptr_to()));
+        BitCast(bcx, ptr, type_of::arg_type_of(bcx.ccx(), ty).ptr_to())
     } else {
-        Store(cx, v, dst);
+        ptr
     }
 }
 
@@ -1116,7 +1126,7 @@ pub fn call_lifetime_end(cx: Block, ptr: ValueRef) {
 pub fn call_memcpy(cx: Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) {
     let _icx = push_ctxt("call_memcpy");
     let ccx = cx.ccx();
-    let key = match &ccx.sess().target.target.target_pointer_width[] {
+    let key = match &ccx.sess().target.target.target_pointer_width[..] {
         "32" => "llvm.memcpy.p0i8.p0i8.i32",
         "64" => "llvm.memcpy.p0i8.p0i8.i64",
         tws => panic!("Unsupported target word size for memcpy: {}", tws),
@@ -1145,25 +1155,32 @@ pub fn memcpy_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 }
 
-pub fn zero_mem<'blk, 'tcx>(cx: Block<'blk, 'tcx>, llptr: ValueRef, t: Ty<'tcx>) {
+pub fn drop_done_fill_mem<'blk, 'tcx>(cx: Block<'blk, 'tcx>, llptr: ValueRef, t: Ty<'tcx>) {
+    if cx.unreachable.get() { return; }
+    let _icx = push_ctxt("drop_done_fill_mem");
+    let bcx = cx;
+    memfill(&B(bcx), llptr, t, adt::DTOR_DONE);
+}
+
+pub fn init_zero_mem<'blk, 'tcx>(cx: Block<'blk, 'tcx>, llptr: ValueRef, t: Ty<'tcx>) {
     if cx.unreachable.get() { return; }
-    let _icx = push_ctxt("zero_mem");
+    let _icx = push_ctxt("init_zero_mem");
     let bcx = cx;
-    memzero(&B(bcx), llptr, t);
+    memfill(&B(bcx), llptr, t, 0);
 }
 
-// Always use this function instead of storing a zero constant to the memory
-// in question. If you store a zero constant, LLVM will drown in vreg
+// Always use this function instead of storing a constant byte to the memory
+// in question. e.g. if you store a zero constant, LLVM will drown in vreg
 // allocation for large data structures, and the generated code will be
 // awful. (A telltale sign of this is large quantities of
 // `mov [byte ptr foo],0` in the generated code.)
-fn memzero<'a, 'tcx>(b: &Builder<'a, 'tcx>, llptr: ValueRef, ty: Ty<'tcx>) {
-    let _icx = push_ctxt("memzero");
+fn memfill<'a, 'tcx>(b: &Builder<'a, 'tcx>, llptr: ValueRef, ty: Ty<'tcx>, byte: u8) {
+    let _icx = push_ctxt("memfill");
     let ccx = b.ccx;
 
     let llty = type_of::type_of(ccx, ty);
 
-    let intrinsic_key = match &ccx.sess().target.target.target_pointer_width[] {
+    let intrinsic_key = match &ccx.sess().target.target.target_pointer_width[..] {
         "32" => "llvm.memset.p0i8.i32",
         "64" => "llvm.memset.p0i8.i64",
         tws => panic!("Unsupported target word size for memset: {}", tws),
@@ -1171,7 +1188,7 @@ fn memzero<'a, 'tcx>(b: &Builder<'a, 'tcx>, llptr: ValueRef, ty: Ty<'tcx>) {
 
     let llintrinsicfn = ccx.get_intrinsic(&intrinsic_key);
     let llptr = b.pointercast(llptr, Type::i8(ccx).ptr_to());
-    let llzeroval = C_u8(ccx, 0);
+    let llzeroval = C_u8(ccx, byte as usize);
     let size = machine::llsize_of(ccx, llty);
     let align = C_i32(ccx, type_of::align_of(ccx, ty) as i32);
     let volatile = C_bool(ccx, false);
@@ -1204,21 +1221,6 @@ pub fn alloca_no_lifetime(cx: Block, ty: Type, name: &str) -> ValueRef {
     Alloca(cx, ty, name)
 }
 
-pub fn alloca_zeroed<'blk, 'tcx>(cx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
-                                 name: &str) -> ValueRef {
-    let llty = type_of::type_of(cx.ccx(), ty);
-    if cx.unreachable.get() {
-        unsafe {
-            return llvm::LLVMGetUndef(llty.ptr_to().to_ref());
-        }
-    }
-    let p = alloca_no_lifetime(cx, llty, name);
-    let b = cx.fcx.ccx.builder();
-    b.position_before(cx.fcx.alloca_insert_pt.get().unwrap());
-    memzero(&b, p, ty);
-    p
-}
-
 // Creates the alloca slot which holds the pointer to the slot for the final return value
 pub fn make_return_slot_pointer<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
                                           output_type: Ty<'tcx>) -> ValueRef {
@@ -1284,47 +1286,35 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
                 _ => tcx.sess.bug("unexpected item variant in has_nested_returns")
             }
         }
-        Some(ast_map::NodeTraitItem(trait_method)) => {
-            match *trait_method {
-                ast::ProvidedMethod(ref m) => {
-                    match m.node {
-                        ast::MethDecl(_, _, _, _, _, _, ref blk, _) => {
-                            blk
-                        }
-                        ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
-                    }
-                }
-                ast::RequiredMethod(_) => {
+        Some(ast_map::NodeTraitItem(trait_item)) => {
+            match trait_item.node {
+                ast::MethodTraitItem(_, Some(ref body)) => body,
+                ast::MethodTraitItem(_, None) => {
                     tcx.sess.bug("unexpected variant: required trait method \
                                   in has_nested_returns")
                 }
-                ast::TypeTraitItem(_) => {
-                    tcx.sess.bug("unexpected variant: type trait item in \
+                ast::TypeTraitItem(..) => {
+                    tcx.sess.bug("unexpected variant: associated type trait item in \
                                   has_nested_returns")
                 }
             }
         }
-        Some(ast_map::NodeImplItem(ii)) => {
-            match *ii {
-                ast::MethodImplItem(ref m) => {
-                    match m.node {
-                        ast::MethDecl(_, _, _, _, _, _, ref blk, _) => {
-                            blk
-                        }
-                        ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
-                    }
-                }
+        Some(ast_map::NodeImplItem(impl_item)) => {
+            match impl_item.node {
+                ast::MethodImplItem(_, ref body) => body,
                 ast::TypeImplItem(_) => {
-                    tcx.sess.bug("unexpected variant: type impl item in \
+                    tcx.sess.bug("unexpected variant: associated type impl item in \
+                                  has_nested_returns")
+                }
+                ast::MacImplItem(_) => {
+                    tcx.sess.bug("unexpected variant: unexpanded macro impl item in \
                                   has_nested_returns")
                 }
             }
         }
         Some(ast_map::NodeExpr(e)) => {
             match e.node {
-                ast::ExprClosure(_, _, ref blk) => {
-                    blk
-                }
+                ast::ExprClosure(_, _, ref blk) => blk,
                 _ => tcx.sess.bug("unexpected expr variant in has_nested_returns")
             }
         }
@@ -1338,7 +1328,7 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
                                    tcx.map.path_to_string(id)))
     };
 
-    (blk.id, Some(cfg::CFG::new(tcx, &**blk)))
+    (blk.id, Some(cfg::CFG::new(tcx, blk)))
 }
 
 // Checks for the presence of "nested returns" in a function.
@@ -1353,7 +1343,7 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
 // the clobbering of the existing value in the return slot.
 fn has_nested_returns(tcx: &ty::ctxt, cfg: &cfg::CFG, blk_id: ast::NodeId) -> bool {
     for n in cfg.graph.depth_traverse(cfg.entry) {
-        match tcx.map.find(n.id) {
+        match tcx.map.find(n.id()) {
             Some(ast_map::NodeExpr(ex)) => {
                 if let ast::ExprRet(Some(ref ret_expr)) = ex.node {
                     let mut visitor = FindNestedReturn::new();
@@ -1398,7 +1388,7 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
     common::validate_substs(param_substs);
 
     debug!("new_fn_ctxt(path={}, id={}, param_substs={})",
-           if id == -1 {
+           if id == !0 {
                "".to_string()
            } else {
                ccx.tcx().map.path_to_string(id).to_string()
@@ -1501,7 +1491,7 @@ pub fn arg_kind<'a, 'tcx>(cx: &FunctionContext<'a, 'tcx>, t: Ty<'tcx>)
 }
 
 // work around bizarre resolve errors
-type RvalueDatum<'tcx> = datum::Datum<'tcx, datum::Rvalue>;
+pub type RvalueDatum<'tcx> = datum::Datum<'tcx, datum::Rvalue>;
 
 // create_datums_for_fn_args: creates rvalue datums for each of the
 // incoming function arguments. These will later be stored into
@@ -1548,7 +1538,6 @@ fn create_datums_for_fn_args_under_call_abi<'blk, 'tcx>(
                                   datum::lvalue_scratch_datum(bcx,
                                                               arg_ty,
                                                               "tupled_args",
-                                                              false,
                                                               tuple_args_scope_id,
                                                               (),
                                                               |(),
@@ -1613,55 +1602,6 @@ fn copy_args_to_allocas<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     bcx
 }
 
-fn copy_closure_args_to_allocas<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
-                                            arg_scope: cleanup::CustomScopeIndex,
-                                            args: &[ast::Arg],
-                                            arg_datums: Vec<RvalueDatum<'tcx>>,
-                                            monomorphized_arg_types: &[Ty<'tcx>])
-                                            -> Block<'blk, 'tcx> {
-    let _icx = push_ctxt("copy_closure_args_to_allocas");
-    let arg_scope_id = cleanup::CustomScope(arg_scope);
-
-    assert_eq!(arg_datums.len(), 1);
-
-    let arg_datum = arg_datums.into_iter().next().unwrap();
-
-    // Untuple the rest of the arguments.
-    let tuple_datum =
-        unpack_datum!(bcx,
-                      arg_datum.to_lvalue_datum_in_scope(bcx,
-                                                         "argtuple",
-                                                         arg_scope_id));
-    let untupled_arg_types = match monomorphized_arg_types[0].sty {
-        ty::ty_tup(ref types) => &types[..],
-        _ => {
-            bcx.tcx().sess.span_bug(args[0].pat.span,
-                                    "first arg to `rust-call` ABI function \
-                                     wasn't a tuple?!")
-        }
-    };
-    for j in 0..args.len() {
-        let tuple_element_type = untupled_arg_types[j];
-        let tuple_element_datum =
-            tuple_datum.get_element(bcx,
-                                    tuple_element_type,
-                                    |llval| GEPi(bcx, llval, &[0, j]));
-        let tuple_element_datum = tuple_element_datum.to_expr_datum();
-        let tuple_element_datum =
-            unpack_datum!(bcx,
-                          tuple_element_datum.to_rvalue_datum(bcx,
-                                                              "arg"));
-        bcx = _match::store_arg(bcx,
-                                &*args[j].pat,
-                                tuple_element_datum,
-                                arg_scope_id);
-
-        debuginfo::create_argument_metadata(bcx, &args[j]);
-    }
-
-    bcx
-}
-
 // Ties up the llstaticallocas -> llloadenv -> lltop edges,
 // and builds the return block.
 pub fn finish_fn<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
@@ -1819,33 +1759,18 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     debug!("trans_closure: function lltype: {}",
            bcx.fcx.ccx.tn().val_to_string(bcx.fcx.llfn));
 
-    let arg_datums = if abi != RustCall {
-        create_datums_for_fn_args(&fcx,
-                                  &monomorphized_arg_types[..])
-    } else {
-        create_datums_for_fn_args_under_call_abi(
-            bcx,
-            arg_scope,
-            &monomorphized_arg_types[..])
-    };
-
-    bcx = match closure_env {
-        closure::ClosureEnv::NotClosure => {
-            copy_args_to_allocas(bcx,
-                                 arg_scope,
-                                 &decl.inputs[],
-                                 arg_datums)
+    let arg_datums = match closure_env {
+        closure::ClosureEnv::NotClosure if abi == RustCall => {
+            create_datums_for_fn_args_under_call_abi(bcx, arg_scope, &monomorphized_arg_types[..])
         }
-        closure::ClosureEnv::Closure(_) => {
-            copy_closure_args_to_allocas(
-                bcx,
-                arg_scope,
-                &decl.inputs[],
-                arg_datums,
-                &monomorphized_arg_types[..])
+        _ => {
+            let arg_tys = untuple_arguments_if_necessary(ccx, &monomorphized_arg_types, abi);
+            create_datums_for_fn_args(&fcx, &arg_tys)
         }
     };
 
+    bcx = copy_args_to_allocas(bcx, arg_scope, &decl.inputs, arg_datums);
+
     bcx = closure_env.load(bcx, cleanup::CustomScope(arg_scope));
 
     // Up until here, IR instructions for this function have explicitly not been annotated with
@@ -1964,7 +1889,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         _ => ccx.sess().bug(
             &format!("trans_enum_variant_constructor: \
                      unexpected ctor return type {}",
-                     ctor_ty.repr(tcx))[])
+                     ctor_ty.repr(tcx)))
     };
 
     // Get location to store the result. If the user does not care about
@@ -2042,7 +1967,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx
         _ => ccx.sess().bug(
             &format!("trans_enum_variant_or_tuple_like_struct: \
                      unexpected ctor return type {}",
-                    ty_to_string(ccx.tcx(), ctor_ty))[])
+                    ty_to_string(ccx.tcx(), ctor_ty)))
     };
 
     let (arena, fcx): (TypedArena<_>, FunctionContext);
@@ -2143,7 +2068,7 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span,
                             *lvlsrc.unwrap(), Some(sp),
                             &format!("enum variant is more than three times larger \
                                      ({} bytes) than the next largest (ignoring padding)",
-                                    largest)[]);
+                                    largest));
 
         ccx.sess().span_note(enum_def.variants[largest_index].span,
                              "this variant is the largest");
@@ -2187,7 +2112,7 @@ pub fn llvm_linkage_by_name(name: &str) -> Option<Linkage> {
 
 
 /// Enum describing the origin of an LLVM `Value`, for linkage purposes.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum ValueOrigin {
     /// The LLVM `Value` is in this context because the corresponding item was
     /// assigned to the current compilation unit.
@@ -2261,7 +2186,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
     match item.node {
       ast::ItemFn(ref decl, _fn_style, abi, ref generics, ref body) => {
         if !generics.is_type_parameterized() {
-            let trans_everywhere = attr::requests_inline(&item.attrs[]);
+            let trans_everywhere = attr::requests_inline(&item.attrs);
             // Ignore `trans_everywhere` for cross-crate inlined items
             // (`from_external`).  `trans_item` will be called once for each
             // compilation unit that references the item, so it will still get
@@ -2273,7 +2198,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
                     foreign::trans_rust_fn_with_foreign_abi(ccx,
                                                             &**decl,
                                                             &**body,
-                                                            &item.attrs[],
+                                                            &item.attrs,
                                                             llfn,
                                                             empty_substs,
                                                             item.id,
@@ -2285,7 +2210,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
                              llfn,
                              empty_substs,
                              item.id,
-                             &item.attrs[]);
+                             &item.attrs);
                 }
                 update_linkage(ccx,
                                llfn,
@@ -2332,14 +2257,19 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
 
           // Do static_assert checking. It can't really be done much earlier
           // because we need to get the value of the bool out of LLVM
-          if attr::contains_name(&item.attrs[], "static_assert") {
+          if attr::contains_name(&item.attrs, "static_assert") {
+              if !ty::type_is_bool(ty::expr_ty(ccx.tcx(), expr)) {
+                  ccx.sess().span_fatal(expr.span,
+                                        "can only have static_assert on a static \
+                                         with type `bool`");
+              }
               if m == ast::MutMutable {
                   ccx.sess().span_fatal(expr.span,
                                         "cannot have static_assert on a mutable \
                                          static");
               }
 
-              let v = ccx.static_values().borrow()[item.id].clone();
+              let v = ccx.static_values().borrow().get(&item.id).unwrap().clone();
               unsafe {
                   if !(llvm::LLVMConstIntGetZExtValue(v) != 0) {
                       ccx.sess().span_fatal(expr.span, "static assertion failed");
@@ -2410,12 +2340,15 @@ fn register_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                          node_id: ast::NodeId,
                          node_type: Ty<'tcx>)
                          -> ValueRef {
-    match node_type.sty {
-        ty::ty_bare_fn(_, ref f) => {
-            assert!(f.abi == Rust || f.abi == RustCall);
+    if let ty::ty_bare_fn(_, ref f) = node_type.sty {
+        if f.abi != Rust && f.abi != RustCall {
+            ccx.sess().span_bug(sp, &format!("only the `{}` or `{}` calling conventions are valid \
+                                              for this function; `{}` was specified",
+                                              Rust.name(), RustCall.name(), f.abi.name()));
         }
-        _ => panic!("expected bare rust fn")
-    };
+    } else {
+        ccx.sess().span_bug(sp, "expected bare rust function")
+    }
 
     let llfn = decl_rust_fn(ccx, node_type, &sym[..]);
     finish_register_fn(ccx, sp, sym, node_id, llfn);
@@ -2428,32 +2361,34 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
     use middle::ty::{BrAnon, ReLateBound};
 
     let function_type;
-    let (fn_sig, abi, has_env) = match fn_ty.sty {
-        ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, false),
-        ty::ty_closure(closure_did, _, substs) => {
+    let (fn_sig, abi, env_ty) = match fn_ty.sty {
+        ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, None),
+        ty::ty_closure(closure_did, substs) => {
             let typer = common::NormalizingClosureTyper::new(ccx.tcx());
             function_type = typer.closure_type(closure_did, substs);
-            (&function_type.sig, RustCall, true)
+            let self_type = self_type_for_closure(ccx, closure_did, fn_ty);
+            (&function_type.sig, RustCall, Some(self_type))
         }
         _ => ccx.sess().bug("expected closure or function.")
     };
 
     let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);
 
-    // Since index 0 is the return value of the llvm func, we start
-    // at either 1 or 2 depending on whether there's an env slot or not
-    let mut first_arg_offset = if has_env { 2 } else { 1 };
     let mut attrs = llvm::AttrBuilder::new();
     let ret_ty = fn_sig.output;
 
     // These have an odd calling convention, so we need to manually
     // unpack the input ty's
     let input_tys = match fn_ty.sty {
-        ty::ty_closure(_, _, _) => {
+        ty::ty_closure(..) => {
             assert!(abi == RustCall);
 
             match fn_sig.inputs[0].sty {
-                ty::ty_tup(ref inputs) => inputs.clone(),
+                ty::ty_tup(ref inputs) => {
+                    let mut full_inputs = vec![env_ty.expect("Missing closure environment")];
+                    full_inputs.push_all(inputs);
+                    full_inputs
+                }
                 _ => ccx.sess().bug("expected tuple'd inputs")
             }
         },
@@ -2471,6 +2406,8 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
         _ => fn_sig.inputs.clone()
     };
 
+    // Index 0 is the return value of the llvm func, so we start at 1
+    let mut first_arg_offset = 1;
     if let ty::FnConverging(ret_ty) = ret_ty {
         // A function pointer is called without the declaration
         // available, so we have to apply any attributes with ABI
@@ -2746,7 +2683,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
     let val = match item {
         ast_map::NodeItem(i) => {
             let ty = ty::node_id_to_type(ccx.tcx(), i.id);
-            let sym = || exported_name(ccx, id, ty, &i.attrs[]);
+            let sym = || exported_name(ccx, id, ty, &i.attrs);
 
             let v = match i.node {
                 ast::ItemStatic(_, _, ref expr) => {
@@ -2773,13 +2710,13 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                         if contains_null(&sym[..]) {
                             ccx.sess().fatal(
                                 &format!("Illegal null byte in export_name \
-                                         value: `{}`", sym)[]);
+                                         value: `{}`", sym));
                         }
                         let buf = CString::new(sym.clone()).unwrap();
                         let g = llvm::LLVMAddGlobal(ccx.llmod(), llty,
                                                     buf.as_ptr());
 
-                        if attr::contains_name(&i.attrs[],
+                        if attr::contains_name(&i.attrs,
                                                "thread_local") {
                             llvm::set_thread_local(g, true);
                         }
@@ -2798,19 +2735,19 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                                                                    sym,
                                                                    i.id)
                     };
-                    set_llvm_fn_attrs(ccx, &i.attrs[], llfn);
+                    set_llvm_fn_attrs(ccx, &i.attrs, llfn);
                     llfn
                 }
 
-                _ => panic!("get_item_val: weird result in table")
+                _ => ccx.sess().bug("get_item_val: weird result in table")
             };
 
-            match attr::first_attr_value_str_by_name(&i.attrs[],
+            match attr::first_attr_value_str_by_name(&i.attrs,
                                                      "link_section") {
                 Some(sect) => {
                     if contains_null(&sect) {
                         ccx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`",
-                                                 &sect)[]);
+                                                 &sect));
                     }
                     unsafe {
                         let buf = CString::new(sect.as_bytes()).unwrap();
@@ -2823,26 +2760,31 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
             v
         }
 
-        ast_map::NodeTraitItem(trait_method) => {
+        ast_map::NodeTraitItem(trait_item) => {
             debug!("get_item_val(): processing a NodeTraitItem");
-            match *trait_method {
-                ast::RequiredMethod(_) | ast::TypeTraitItem(_) => {
-                    ccx.sess().bug("unexpected variant: required trait \
-                                    method in get_item_val()");
+            match trait_item.node {
+                ast::MethodTraitItem(_, None) | ast::TypeTraitItem(..) => {
+                    ccx.sess().span_bug(trait_item.span,
+                        "unexpected variant: required trait method in get_item_val()");
                 }
-                ast::ProvidedMethod(ref m) => {
-                    register_method(ccx, id, &**m)
+                ast::MethodTraitItem(_, Some(_)) => {
+                    register_method(ccx, id, &trait_item.attrs, trait_item.span)
                 }
             }
         }
 
-        ast_map::NodeImplItem(ii) => {
-            match *ii {
-                ast::MethodImplItem(ref m) => register_method(ccx, id, &**m),
-                ast::TypeImplItem(ref typedef) => {
-                    ccx.sess().span_bug(typedef.span,
-                                        "unexpected variant: required impl \
-                                         method in get_item_val()")
+        ast_map::NodeImplItem(impl_item) => {
+            match impl_item.node {
+                ast::MethodImplItem(..) => {
+                    register_method(ccx, id, &impl_item.attrs, impl_item.span)
+                }
+                ast::TypeImplItem(_) => {
+                    ccx.sess().span_bug(impl_item.span,
+                        "unexpected variant: associated type in get_item_val()")
+                }
+                ast::MacImplItem(_) => {
+                    ccx.sess().span_bug(impl_item.span,
+                        "unexpected variant: unexpanded macro in get_item_val()")
                 }
             }
         }
@@ -2853,7 +2795,9 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                     let abi = ccx.tcx().map.get_foreign_abi(id);
                     let ty = ty::node_id_to_type(ccx.tcx(), ni.id);
                     let name = foreign::link_name(&*ni);
-                    foreign::register_foreign_item_fn(ccx, abi, ty, &name)
+                    let llfn = foreign::register_foreign_item_fn(ccx, abi, ty, &name);
+                    set_llvm_fn_attrs(ccx, &ni.attrs, llfn);
+                    llfn
                 }
                 ast::ForeignItemStatic(..) => {
                     foreign::register_static(ccx, &*ni)
@@ -2866,7 +2810,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
             let args = match v.node.kind {
                 ast::TupleVariantKind(ref args) => args,
                 ast::StructVariantKind(_) => {
-                    panic!("struct variant kind unexpected in get_item_val")
+                    ccx.sess().bug("struct variant kind unexpected in get_item_val")
                 }
             };
             assert!(args.len() != 0);
@@ -2876,13 +2820,13 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
             let sym = exported_name(ccx,
                                     id,
                                     ty,
-                                    &enm.attrs[]);
+                                    &enm.attrs);
 
             llfn = match enm.node {
                 ast::ItemEnum(_, _) => {
                     register_fn(ccx, (*v).span, sym, id, ty)
                 }
-                _ => panic!("NodeVariant, shouldn't happen")
+                _ => ccx.sess().bug("NodeVariant, shouldn't happen")
             };
             set_inline_hint(llfn);
             llfn
@@ -2903,7 +2847,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
             let sym = exported_name(ccx,
                                     id,
                                     ty,
-                                    &struct_item.attrs[]);
+                                    &struct_item.attrs);
             let llfn = register_fn(ccx, struct_item.span,
                                    sym, ctor_id, ty);
             set_inline_hint(llfn);
@@ -2912,7 +2856,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
 
         ref variant => {
             ccx.sess().bug(&format!("get_item_val(): unexpected variant: {:?}",
-                                   variant)[])
+                                   variant))
         }
     };
 
@@ -2930,14 +2874,22 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
 }
 
 fn register_method(ccx: &CrateContext, id: ast::NodeId,
-                   m: &ast::Method) -> ValueRef {
+                   attrs: &[ast::Attribute], span: Span) -> ValueRef {
     let mty = ty::node_id_to_type(ccx.tcx(), id);
 
-    let sym = exported_name(ccx, id, mty, &m.attrs[]);
+    let sym = exported_name(ccx, id, mty, &attrs);
 
-    let llfn = register_fn(ccx, m.span, sym, id, mty);
-    set_llvm_fn_attrs(ccx, &m.attrs[], llfn);
-    llfn
+    if let ty::ty_bare_fn(_, ref f) = mty.sty {
+        let llfn = if f.abi == Rust || f.abi == RustCall {
+            register_fn(ccx, span, sym, id, mty)
+        } else {
+            foreign::register_rust_fn_with_foreign_abi(ccx, span, sym, id)
+        };
+        set_llvm_fn_attrs(ccx, &attrs, llfn);
+        return llfn;
+    } else {
+        ccx.sess().span_bug(span, "expected bare rust function");
+    }
 }
 
 pub fn crate_ctxt_to_encode_parms<'a, 'tcx>(cx: &'a SharedCrateContext<'tcx>,
@@ -2966,15 +2918,12 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
     }
 
     let encode_inlined_item: encoder::EncodeInlinedItem =
-        box |ecx, rbml_w, ii| astencode::encode_inlined_item(ecx, rbml_w, ii);
+        Box::new(|ecx, rbml_w, ii| astencode::encode_inlined_item(ecx, rbml_w, ii));
 
     let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
     let metadata = encoder::encode_metadata(encode_parms, krate);
     let mut compressed = encoder::metadata_encoding_version.to_vec();
-    compressed.push_all(&match flate::deflate_bytes(&metadata) {
-        Some(compressed) => compressed,
-        None => cx.sess().fatal("failed to compress metadata"),
-    });
+    compressed.push_all(&flate::deflate_bytes(&metadata));
     let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[..]);
     let llconst = C_struct_in_context(cx.metadata_llcx(), &[llmeta], false);
     let name = format!("rust_metadata_{}_{}",
@@ -3083,6 +3032,18 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
     let ty::CrateAnalysis { ty_cx: tcx, export_map, reachable, name, .. } = analysis;
     let krate = tcx.map.krate();
 
+    let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks {
+        v
+    } else {
+        tcx.sess.opts.debug_assertions
+    };
+
+    let check_dropflag = if let Some(v) = tcx.sess.opts.debugging_opts.force_dropflag_checks {
+        v
+    } else {
+        tcx.sess.opts.debug_assertions
+    };
+
     // Before we touch LLVM, make sure that multithreading is enabled.
     unsafe {
         use std::sync::{Once, ONCE_INIT};
@@ -3104,13 +3065,15 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
     let link_meta = link::build_link_meta(&tcx.sess, krate, name);
 
     let codegen_units = tcx.sess.opts.cg.codegen_units;
-    let shared_ccx = SharedCrateContext::new(&link_meta.crate_name[],
+    let shared_ccx = SharedCrateContext::new(&link_meta.crate_name,
                                              codegen_units,
                                              tcx,
                                              export_map,
                                              Sha256::new(),
                                              link_meta.clone(),
-                                             reachable);
+                                             reachable,
+                                             check_overflow,
+                                             check_dropflag);
 
     {
         let ccx = shared_ccx.get_ccx(0);
@@ -3126,7 +3089,6 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
     }
 
     for ccx in shared_ccx.iter() {
-        glue::emit_tydescs(&ccx);
         if ccx.sess().opts.debuginfo != NoDebugInfo {
             debuginfo::finalize(&ccx);
         }
@@ -3138,7 +3100,6 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
     if shared_ccx.sess().trans_stats() {
         let stats = shared_ccx.stats();
         println!("--- trans stats ---");
-        println!("n_static_tydescs: {}", stats.n_static_tydescs.get());
         println!("n_glues_created: {}", stats.n_glues_created.get());
         println!("n_null_glues: {}", stats.n_null_glues.get());
         println!("n_real_glues: {}", stats.n_real_glues.get());
@@ -3206,7 +3167,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
         llmod: shared_ccx.metadata_llmod(),
     };
     let formats = shared_ccx.tcx().dependency_formats.borrow().clone();
-    let no_builtins = attr::contains_name(&krate.attrs[], "no_builtins");
+    let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
 
     let translation = CrateTranslation {
         modules: modules,
index f11c3154274e7f741bb824532795d2e4803c6080..d3d055cda120293d172413158976fef590039b96 100644 (file)
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 use llvm;
-use llvm::{BasicBlockRef};
+use llvm::BasicBlockRef;
 use trans::value::{Users, Value};
 use std::iter::{Filter, Map};
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct BasicBlock(pub BasicBlockRef);
 
 pub type Preds = Map<Filter<Users, fn(&Value) -> bool>, fn(Value) -> BasicBlock>;
index 2fcfc5e43931d2770391bde8b4c03e92b6505954..a16c4d6c2c4a78f1e1bb42a1095df124622a7167 100644 (file)
@@ -105,7 +105,7 @@ pub fn CondBr(cx: Block,
     B(cx).cond_br(if_, then, else_);
 }
 
-pub fn Switch(cx: Block, v: ValueRef, else_: BasicBlockRef, num_cases: uint)
+pub fn Switch(cx: Block, v: ValueRef, else_: BasicBlockRef, num_cases: usize)
     -> ValueRef {
     if cx.unreachable.get() { return _Undef(v); }
     check_not_terminated(cx);
@@ -122,7 +122,7 @@ pub fn AddCase(s: ValueRef, on_val: ValueRef, dest: BasicBlockRef) {
 
 pub fn IndirectBr(cx: Block,
                   addr: ValueRef,
-                  num_dests: uint,
+                  num_dests: usize,
                   debug_loc: DebugLoc) {
     if cx.unreachable.get() {
         return;
@@ -673,7 +673,7 @@ pub fn GEP(cx: Block, pointer: ValueRef, indices: &[ValueRef]) -> ValueRef {
 // Simple wrapper around GEP that takes an array of ints and wraps them
 // in C_i32()
 #[inline]
-pub fn GEPi(cx: Block, base: ValueRef, ixs: &[uint]) -> ValueRef {
+pub fn GEPi(cx: Block, base: ValueRef, ixs: &[usize]) -> ValueRef {
     unsafe {
         if cx.unreachable.get() {
             return llvm::LLVMGetUndef(Type::nil(cx.ccx()).ptr_to().to_ref());
@@ -691,7 +691,7 @@ pub fn InBoundsGEP(cx: Block, pointer: ValueRef, indices: &[ValueRef]) -> ValueR
     }
 }
 
-pub fn StructGEP(cx: Block, pointer: ValueRef, idx: uint) -> ValueRef {
+pub fn StructGEP(cx: Block, pointer: ValueRef, idx: usize) -> ValueRef {
     unsafe {
         if cx.unreachable.get() {
             return llvm::LLVMGetUndef(Type::nil(cx.ccx()).ptr_to().to_ref());
@@ -1011,7 +1011,7 @@ pub fn ShuffleVector(cx: Block, v1: ValueRef, v2: ValueRef,
     }
 }
 
-pub fn VectorSplat(cx: Block, num_elts: uint, elt_val: ValueRef) -> ValueRef {
+pub fn VectorSplat(cx: Block, num_elts: usize, elt_val: ValueRef) -> ValueRef {
     unsafe {
         if cx.unreachable.get() {
             return llvm::LLVMGetUndef(Type::nil(cx.ccx()).to_ref());
@@ -1020,7 +1020,7 @@ pub fn VectorSplat(cx: Block, num_elts: uint, elt_val: ValueRef) -> ValueRef {
     }
 }
 
-pub fn ExtractValue(cx: Block, agg_val: ValueRef, index: uint) -> ValueRef {
+pub fn ExtractValue(cx: Block, agg_val: ValueRef, index: usize) -> ValueRef {
     unsafe {
         if cx.unreachable.get() {
             return llvm::LLVMGetUndef(Type::nil(cx.ccx()).to_ref());
@@ -1029,7 +1029,7 @@ pub fn ExtractValue(cx: Block, agg_val: ValueRef, index: uint) -> ValueRef {
     }
 }
 
-pub fn InsertValue(cx: Block, agg_val: ValueRef, elt_val: ValueRef, index: uint) -> ValueRef {
+pub fn InsertValue(cx: Block, agg_val: ValueRef, elt_val: ValueRef, index: usize) -> ValueRef {
     unsafe {
         if cx.unreachable.get() {
             return llvm::LLVMGetUndef(Type::nil(cx.ccx()).to_ref());
@@ -1070,7 +1070,7 @@ pub fn Trap(cx: Block) {
 }
 
 pub fn LandingPad(cx: Block, ty: Type, pers_fn: ValueRef,
-                  num_clauses: uint) -> ValueRef {
+                  num_clauses: usize) -> ValueRef {
     check_not_terminated(cx);
     assert!(!cx.unreachable.get());
     B(cx).landing_pad(ty, pers_fn, num_clauses)
index 8199e6189c93b495c926ac1d9715ee29b1ddb90f..92bc20bafcfbe59412f82290db5173b71a044e6c 100644 (file)
@@ -140,13 +140,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
-    pub fn switch(&self, v: ValueRef, else_llbb: BasicBlockRef, num_cases: uint) -> ValueRef {
+    pub fn switch(&self, v: ValueRef, else_llbb: BasicBlockRef, num_cases: usize) -> ValueRef {
         unsafe {
             llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, num_cases as c_uint)
         }
     }
 
-    pub fn indirect_br(&self, addr: ValueRef, num_dests: uint) {
+    pub fn indirect_br(&self, addr: ValueRef, num_dests: usize) {
         self.count_insn("indirectbr");
         unsafe {
             llvm::LLVMBuildIndirectBr(self.llbuilder, addr, num_dests as c_uint);
@@ -555,7 +555,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     // Simple wrapper around GEP that takes an array of ints and wraps them
     // in C_i32()
     #[inline]
-    pub fn gepi(&self, base: ValueRef, ixs: &[uint]) -> ValueRef {
+    pub fn gepi(&self, base: ValueRef, ixs: &[usize]) -> ValueRef {
         // Small vector optimization. This should catch 100% of the cases that
         // we care about.
         if ixs.len() < 16 {
@@ -579,7 +579,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
-    pub fn struct_gep(&self, ptr: ValueRef, idx: uint) -> ValueRef {
+    pub fn struct_gep(&self, ptr: ValueRef, idx: usize) -> ValueRef {
         self.count_insn("structgep");
         unsafe {
             llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, noname())
@@ -886,7 +886,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
-    pub fn vector_splat(&self, num_elts: uint, elt: ValueRef) -> ValueRef {
+    pub fn vector_splat(&self, num_elts: usize, elt: ValueRef) -> ValueRef {
         unsafe {
             let elt_ty = val_ty(elt);
             let undef = llvm::LLVMGetUndef(Type::vector(&elt_ty, num_elts as u64).to_ref());
@@ -896,7 +896,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
-    pub fn extract_value(&self, agg_val: ValueRef, idx: uint) -> ValueRef {
+    pub fn extract_value(&self, agg_val: ValueRef, idx: usize) -> ValueRef {
         self.count_insn("extractvalue");
         unsafe {
             llvm::LLVMBuildExtractValue(self.llbuilder, agg_val, idx as c_uint, noname())
@@ -904,7 +904,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     }
 
     pub fn insert_value(&self, agg_val: ValueRef, elt: ValueRef,
-                       idx: uint) -> ValueRef {
+                       idx: usize) -> ValueRef {
         self.count_insn("insertvalue");
         unsafe {
             llvm::LLVMBuildInsertValue(self.llbuilder, agg_val, elt, idx as c_uint,
@@ -940,7 +940,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             let m: ModuleRef = llvm::LLVMGetGlobalParent(fn_);
             let p = "llvm.trap\0".as_ptr();
             let t: ValueRef = llvm::LLVMGetNamedFunction(m, p as *const _);
-            assert!((t as int != 0));
+            assert!((t as isize != 0));
             let args: &[ValueRef] = &[];
             self.count_insn("trap");
             llvm::LLVMBuildCall(
@@ -948,7 +948,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
-    pub fn landing_pad(&self, ty: Type, pers_fn: ValueRef, num_clauses: uint) -> ValueRef {
+    pub fn landing_pad(&self, ty: Type, pers_fn: ValueRef, num_clauses: usize) -> ValueRef {
         self.count_insn("landingpad");
         unsafe {
             llvm::LLVMBuildLandingPad(
index 7abcdd07cc5da6a0ea6bb4827ce190ddcbe54969..0ff5264c00f0f8346ebd9d3180affdf7787c9216 100644 (file)
@@ -109,7 +109,7 @@ pub fn compute_abi_info(ccx: &CrateContext,
                         atys: &[Type],
                         rty: Type,
                         ret_def: bool) -> FnType {
-    match &ccx.sess().target.target.arch[] {
+    match &ccx.sess().target.target.arch[..] {
         "x86" => cabi_x86::compute_abi_info(ccx, atys, rty, ret_def),
         "x86_64" => if ccx.sess().target.target.options.is_like_windows {
             cabi_x86_win64::compute_abi_info(ccx, atys, rty, ret_def)
@@ -128,6 +128,6 @@ pub fn compute_abi_info(ccx: &CrateContext,
         "mips" => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def),
         "powerpc" => cabi_powerpc::compute_abi_info(ccx, atys, rty, ret_def),
         a => ccx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a)
-                              []),
+                              ),
     }
 }
index 5d1e6d2c9e84400a54e52c8ae6ac96351ce0acde..8ac4f84d6ef9f9088db9e15af7ac05c49e36f148 100644 (file)
@@ -18,18 +18,18 @@ use trans::type_::Type;
 
 use std::cmp;
 
-fn align_up_to(off: uint, a: uint) -> uint {
+fn align_up_to(off: usize, a: usize) -> usize {
     return (off + a - 1) / a * a;
 }
 
-fn align(off: uint, ty: Type) -> uint {
+fn align(off: usize, ty: Type) -> usize {
     let a = ty_align(ty);
     return align_up_to(off, a);
 }
 
-fn ty_align(ty: Type) -> uint {
+fn ty_align(ty: Type) -> usize {
     match ty.kind() {
-        Integer => ((ty.int_width() as uint) + 7) / 8,
+        Integer => ((ty.int_width() as usize) + 7) / 8,
         Pointer => 8,
         Float => 4,
         Double => 8,
@@ -54,9 +54,9 @@ fn ty_align(ty: Type) -> uint {
     }
 }
 
-fn ty_size(ty: Type) -> uint {
+fn ty_size(ty: Type) -> usize {
     match ty.kind() {
-        Integer => ((ty.int_width() as uint) + 7) / 8,
+        Integer => ((ty.int_width() as usize) + 7) / 8,
         Pointer => 8,
         Float => 4,
         Double => 8,
@@ -117,7 +117,7 @@ fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     let size = ty_size(ty);
     if size <= 16 {
         let llty = if size == 0 {
-            Type::array(&Type::i64(ccx), 0u64)
+            Type::array(&Type::i64(ccx), 0)
         } else if size == 1 {
             Type::i8(ccx)
         } else if size == 2 {
index 50014230df67b2f88a5207f42f9901d4d2f24739..941c065e3d5d43b9769ce8bc49bf44c60dd0bf64 100644 (file)
@@ -23,20 +23,20 @@ pub enum Flavor {
     Ios
 }
 
-type TyAlignFn = fn(ty: Type) -> uint;
+type TyAlignFn = fn(ty: Type) -> usize;
 
-fn align_up_to(off: uint, a: uint) -> uint {
+fn align_up_to(off: usize, a: usize) -> usize {
     return (off + a - 1) / a * a;
 }
 
-fn align(off: uint, ty: Type, align_fn: TyAlignFn) -> uint {
+fn align(off: usize, ty: Type, align_fn: TyAlignFn) -> usize {
     let a = align_fn(ty);
     return align_up_to(off, a);
 }
 
-fn general_ty_align(ty: Type) -> uint {
+fn general_ty_align(ty: Type) -> usize {
     match ty.kind() {
-        Integer => ((ty.int_width() as uint) + 7) / 8,
+        Integer => ((ty.int_width() as usize) + 7) / 8,
         Pointer => 4,
         Float => 4,
         Double => 8,
@@ -68,9 +68,9 @@ fn general_ty_align(ty: Type) -> uint {
 // ARMv6
 // https://developer.apple.com/library/ios/documentation/Xcode/Conceptual
 //    /iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html
-fn ios_ty_align(ty: Type) -> uint {
+fn ios_ty_align(ty: Type) -> usize {
     match ty.kind() {
-        Integer => cmp::min(4, ((ty.int_width() as uint) + 7) / 8),
+        Integer => cmp::min(4, ((ty.int_width() as usize) + 7) / 8),
         Pointer => 4,
         Float => 4,
         Double => 4,
@@ -95,9 +95,9 @@ fn ios_ty_align(ty: Type) -> uint {
     }
 }
 
-fn ty_size(ty: Type, align_fn: TyAlignFn) -> uint {
+fn ty_size(ty: Type, align_fn: TyAlignFn) -> usize {
     match ty.kind() {
-        Integer => ((ty.int_width() as uint) + 7) / 8,
+        Integer => ((ty.int_width() as usize) + 7) / 8,
         Pointer => 4,
         Float => 4,
         Double => 8,
index bc171e3ae4381fbbce881c5fdc3e3627b53e1d1e..2d7fdd2f2eba47a0acdcff06e96804d69bb680e3 100644 (file)
@@ -19,18 +19,18 @@ use trans::cabi::{ArgType, FnType};
 use trans::context::CrateContext;
 use trans::type_::Type;
 
-fn align_up_to(off: uint, a: uint) -> uint {
+fn align_up_to(off: usize, a: usize) -> usize {
     return (off + a - 1) / a * a;
 }
 
-fn align(off: uint, ty: Type) -> uint {
+fn align(off: usize, ty: Type) -> usize {
     let a = ty_align(ty);
     return align_up_to(off, a);
 }
 
-fn ty_align(ty: Type) -> uint {
+fn ty_align(ty: Type) -> usize {
     match ty.kind() {
-        Integer => ((ty.int_width() as uint) + 7) / 8,
+        Integer => ((ty.int_width() as usize) + 7) / 8,
         Pointer => 4,
         Float => 4,
         Double => 8,
@@ -55,9 +55,9 @@ fn ty_align(ty: Type) -> uint {
     }
 }
 
-fn ty_size(ty: Type) -> uint {
+fn ty_size(ty: Type) -> usize {
     match ty.kind() {
-        Integer => ((ty.int_width() as uint) + 7) / 8,
+        Integer => ((ty.int_width() as usize) + 7) / 8,
         Pointer => 4,
         Float => 4,
         Double => 8,
@@ -96,7 +96,7 @@ fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     }
 }
 
-fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut uint) -> ArgType {
+fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut usize) -> ArgType {
     let orig_offset = *offset;
     let size = ty_size(ty) * 8;
     let mut align = ty_align(ty);
@@ -129,7 +129,7 @@ fn is_reg_ty(ty: Type) -> bool {
     };
 }
 
-fn padding_ty(ccx: &CrateContext, align: uint, offset: uint) -> Option<Type> {
+fn padding_ty(ccx: &CrateContext, align: usize, offset: usize) -> Option<Type> {
     if ((align - 1 ) & offset) > 0 {
         Some(Type::i32(ccx))
     } else {
@@ -137,7 +137,7 @@ fn padding_ty(ccx: &CrateContext, align: uint, offset: uint) -> Option<Type> {
     }
 }
 
-fn coerce_to_int(ccx: &CrateContext, size: uint) -> Vec<Type> {
+fn coerce_to_int(ccx: &CrateContext, size: usize) -> Vec<Type> {
     let int_ty = Type::i32(ccx);
     let mut args = Vec::new();
 
index 4871617e89f3bfd1b0b9c5f319f984cd774ac18c..8c30d4fcc2b1f2c35310ee9dd557819f4e1f8842 100644 (file)
@@ -18,20 +18,20 @@ use trans::type_::Type;
 
 use std::cmp;
 
-fn align_up_to(off: uint, a: uint) -> uint {
+fn align_up_to(off: usize, a: usize) -> usize {
     return (off + a - 1) / a * a;
 }
 
-fn align(off: uint, ty: Type) -> uint {
+fn align(off: usize, ty: Type) -> usize {
     let a = ty_align(ty);
     return align_up_to(off, a);
 }
 
-fn ty_align(ty: Type) -> uint {
+fn ty_align(ty: Type) -> usize {
     match ty.kind() {
         Integer => {
             unsafe {
-                ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
+                ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as usize) + 7) / 8
             }
         }
         Pointer => 4,
@@ -53,11 +53,11 @@ fn ty_align(ty: Type) -> uint {
     }
 }
 
-fn ty_size(ty: Type) -> uint {
+fn ty_size(ty: Type) -> usize {
     match ty.kind() {
         Integer => {
             unsafe {
-                ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8
+                ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as usize) + 7) / 8
             }
         }
         Pointer => 4,
@@ -92,7 +92,7 @@ fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     }
 }
 
-fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut uint) -> ArgType {
+fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut usize) -> ArgType {
     let orig_offset = *offset;
     let size = ty_size(ty) * 8;
     let mut align = ty_align(ty);
@@ -124,7 +124,7 @@ fn is_reg_ty(ty: Type) -> bool {
     };
 }
 
-fn padding_ty(ccx: &CrateContext, align: uint, offset: uint) -> Option<Type> {
+fn padding_ty(ccx: &CrateContext, align: usize, offset: usize) -> Option<Type> {
     if ((align - 1 ) & offset) > 0 {
         Some(Type::i32(ccx))
     } else {
@@ -132,7 +132,7 @@ fn padding_ty(ccx: &CrateContext, align: uint, offset: uint) -> Option<Type> {
     }
 }
 
-fn coerce_to_int(ccx: &CrateContext, size: uint) -> Vec<Type> {
+fn coerce_to_int(ccx: &CrateContext, size: usize) -> Vec<Type> {
     let int_ty = Type::i32(ccx);
     let mut args = Vec::new();
 
index ab41fe31a6e20b0343e7fbe409b75404119557b3..754b7ee5cf555d7c26ad89e7ecb3947d8b759ef3 100644 (file)
@@ -86,14 +86,14 @@ impl ClassList for [RegClass] {
 }
 
 fn classify_ty(ty: Type) -> Vec<RegClass> {
-    fn align(off: uint, ty: Type) -> uint {
+    fn align(off: usize, ty: Type) -> usize {
         let a = ty_align(ty);
         return (off + a - 1) / a * a;
     }
 
-    fn ty_align(ty: Type) -> uint {
+    fn ty_align(ty: Type) -> usize {
         match ty.kind() {
-            Integer => ((ty.int_width() as uint) + 7) / 8,
+            Integer => ((ty.int_width() as usize) + 7) / 8,
             Pointer => 8,
             Float => 4,
             Double => 8,
@@ -118,9 +118,9 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
         }
     }
 
-    fn ty_size(ty: Type) -> uint {
+    fn ty_size(ty: Type) -> usize {
         match ty.kind() {
-            Integer => (ty.int_width() as uint + 7) / 8,
+            Integer => (ty.int_width() as usize + 7) / 8,
             Pointer => 8,
             Float => 4,
             Double => 8,
@@ -157,7 +157,7 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
     }
 
     fn unify(cls: &mut [RegClass],
-             i: uint,
+             i: usize,
              newv: RegClass) {
         if cls[i] == newv { return }
 
@@ -191,8 +191,8 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
 
     fn classify_struct(tys: &[Type],
                        cls: &mut [RegClass],
-                       i: uint,
-                       off: uint,
+                       i: usize,
+                       off: usize,
                        packed: bool) {
         let mut field_off = off;
         for ty in tys {
@@ -205,8 +205,8 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
     }
 
     fn classify(ty: Type,
-                cls: &mut [RegClass], ix: uint,
-                off: uint) {
+                cls: &mut [RegClass], ix: usize,
+                off: usize) {
         let t_align = ty_align(ty);
         let t_size = ty_size(ty);
 
@@ -331,7 +331,7 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
 }
 
 fn llreg_ty(ccx: &CrateContext, cls: &[RegClass]) -> Type {
-    fn llvec_len(cls: &[RegClass]) -> uint {
+    fn llvec_len(cls: &[RegClass]) -> usize {
         let mut len = 1;
         for c in cls {
             if *c != SSEUp {
index 3d3e35cd776f0fd311affbe03d9188f46312d44c..9eb46d3ff549a80bd33a7ef06295fc67f8a676a8 100644 (file)
@@ -21,7 +21,7 @@ pub use self::CallArgs::*;
 use arena::TypedArena;
 use back::link;
 use session;
-use llvm::{ValueRef};
+use llvm::ValueRef;
 use llvm::get_param;
 use llvm;
 use metadata::csearch;
@@ -60,7 +60,7 @@ use syntax::ast;
 use syntax::ast_map;
 use syntax::ptr::P;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct MethodData {
     pub llfn: ValueRef,
     pub llself: ValueRef,
@@ -93,7 +93,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
 
     // pick out special kinds of expressions that can be called:
     match expr.node {
-        ast::ExprPath(_) | ast::ExprQPath(_) => {
+        ast::ExprPath(..) => {
             return trans_def(bcx, bcx.def(expr.id), expr);
         }
         _ => {}
@@ -118,7 +118,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                     expr.span,
                     &format!("type of callee is neither bare-fn nor closure: \
                              {}",
-                            bcx.ty_to_string(datum.ty))[]);
+                            bcx.ty_to_string(datum.ty)));
             }
         }
     }
@@ -165,13 +165,11 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                 let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
                 Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
             }
-            def::DefFn(did, _) | def::DefMethod(did, _, def::FromImpl(_)) |
-            def::DefStaticMethod(did, def::FromImpl(_)) => {
+            def::DefFn(did, _) | def::DefMethod(did, def::FromImpl(_)) => {
                 fn_callee(bcx, trans_fn_ref(bcx.ccx(), did, ExprId(ref_expr.id),
                                             bcx.fcx.param_substs).val)
             }
-            def::DefStaticMethod(meth_did, def::FromTrait(trait_did)) |
-            def::DefMethod(meth_did, _, def::FromTrait(trait_did)) => {
+            def::DefMethod(meth_did, def::FromTrait(trait_did)) => {
                 fn_callee(bcx, meth::trans_static_method_callee(bcx.ccx(),
                                                                 meth_did,
                                                                 trait_did,
@@ -209,13 +207,12 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
             }
             def::DefMod(..) | def::DefForeignMod(..) | def::DefTrait(..) |
             def::DefTy(..) | def::DefPrimTy(..) | def::DefAssociatedTy(..) |
-            def::DefUse(..) | def::DefTyParamBinder(..) |
-            def::DefRegion(..) | def::DefLabel(..) | def::DefTyParam(..) |
-            def::DefSelfTy(..) | def::DefAssociatedPath(..) => {
+            def::DefUse(..) | def::DefRegion(..) | def::DefLabel(..) |
+            def::DefTyParam(..) | def::DefSelfTy(..) => {
                 bcx.tcx().sess.span_bug(
                     ref_expr.span,
                     &format!("cannot translate def {:?} \
-                             to a callable thing!", def)[]);
+                             to a callable thing!", def));
             }
         }
     }
@@ -256,7 +253,7 @@ fn trans_fn_ref_with_substs_to_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 /// Translates an adapter that implements the `Fn` trait for a fn
 /// pointer. This is basically the equivalent of something like:
 ///
-/// ```rust
+/// ```
 /// impl<'a> Fn(&'a int) -> &'a int for fn(&int) -> &int {
 ///     extern "rust-abi" fn call(&self, args: (&'a int,)) -> &'a int {
 ///         (*self)(args.0)
@@ -267,14 +264,29 @@ fn trans_fn_ref_with_substs_to_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 /// but for the bare function type given.
 pub fn trans_fn_pointer_shim<'a, 'tcx>(
     ccx: &'a CrateContext<'a, 'tcx>,
+    closure_kind: ty::ClosureKind,
     bare_fn_ty: Ty<'tcx>)
     -> ValueRef
 {
     let _icx = push_ctxt("trans_fn_pointer_shim");
     let tcx = ccx.tcx();
 
+    // Normalize the type for better caching.
     let bare_fn_ty = common::erase_regions(tcx, &bare_fn_ty);
-    match ccx.fn_pointer_shims().borrow().get(&bare_fn_ty) {
+
+    // If this is an impl of `Fn` or `FnMut` trait, the receiver is `&self`.
+    let is_by_ref = match closure_kind {
+        ty::FnClosureKind | ty::FnMutClosureKind => true,
+        ty::FnOnceClosureKind => false,
+    };
+    let bare_fn_ty_maybe_ref = if is_by_ref {
+        ty::mk_imm_rptr(tcx, tcx.mk_region(ty::ReStatic), bare_fn_ty)
+    } else {
+        bare_fn_ty
+    };
+
+    // Check if we already trans'd this shim.
+    match ccx.fn_pointer_shims().borrow().get(&bare_fn_ty_maybe_ref) {
         Some(&llval) => { return llval; }
         None => { }
     }
@@ -282,9 +294,6 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
     debug!("trans_fn_pointer_shim(bare_fn_ty={})",
            bare_fn_ty.repr(tcx));
 
-    // This is an impl of `Fn` trait, so receiver is `&self`.
-    let bare_fn_ty_ref = ty::mk_imm_rptr(tcx, tcx.mk_region(ty::ReStatic), bare_fn_ty);
-
     // Construct the "tuply" version of `bare_fn_ty`. It takes two arguments: `self`,
     // which is the fn pointer, and `args`, which is the arguments tuple.
     let (opt_def_id, sig) =
@@ -298,7 +307,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
 
             _ => {
                 tcx.sess.bug(&format!("trans_fn_pointer_shim invoked on invalid type: {}",
-                                           bare_fn_ty.repr(tcx))[]);
+                                           bare_fn_ty.repr(tcx)));
             }
         };
     let sig = ty::erase_late_bound_regions(tcx, sig);
@@ -309,7 +318,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
                                          unsafety: ast::Unsafety::Normal,
                                          abi: synabi::RustCall,
                                          sig: ty::Binder(ty::FnSig {
-                                             inputs: vec![bare_fn_ty_ref,
+                                             inputs: vec![bare_fn_ty_maybe_ref,
                                                           tuple_input_ty],
                                              output: sig.output,
                                              variadic: false
@@ -340,8 +349,11 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
     let mut bcx = init_function(&fcx, false, sig.output);
 
     // the first argument (`self`) will be ptr to the the fn pointer
-    let llfnpointer =
-        Load(bcx, get_param(fcx.llfn, fcx.arg_pos(0) as u32));
+    let llfnpointer = if is_by_ref {
+        Load(bcx, get_param(fcx.llfn, fcx.arg_pos(0) as u32))
+    } else {
+        get_param(fcx.llfn, fcx.arg_pos(0) as u32)
+    };
 
     // the remaining arguments will be the untupled values
     let llargs: Vec<_> =
@@ -364,7 +376,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
 
     finish_fn(&fcx, bcx, sig.output, DebugLoc::None);
 
-    ccx.fn_pointer_shims().borrow_mut().insert(bare_fn_ty, llfn);
+    ccx.fn_pointer_shims().borrow_mut().insert(bare_fn_ty_maybe_ref, llfn);
 
     llfn
 }
@@ -514,7 +526,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
             let ref_ty = match node {
                 ExprId(id) => ty::node_id_to_type(tcx, id),
                 MethodCallKey(method_call) => {
-                    (*tcx.method_map.borrow())[method_call].ty
+                    tcx.method_map.borrow().get(&method_call).unwrap().ty
                 }
             };
             let ref_ty = monomorphize::apply_param_substs(tcx,
@@ -606,7 +618,18 @@ pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("trans_method_call");
     debug!("trans_method_call(call_expr={})", call_expr.repr(bcx.tcx()));
     let method_call = MethodCall::expr(call_expr.id);
-    let method_ty = (*bcx.tcx().method_map.borrow())[method_call].ty;
+    let method_ty = match bcx.tcx().method_map.borrow().get(&method_call) {
+        Some(method) => match method.origin {
+            ty::MethodTraitObject(_) => match method.ty.sty {
+                ty::ty_bare_fn(_, ref fty) => {
+                    ty::mk_bare_fn(bcx.tcx(), None, meth::opaque_method_ty(bcx.tcx(), fty))
+                }
+                _ => method.ty
+            },
+            _ => method.ty
+        },
+        None => panic!("method not found in trans_method_call")
+    };
     trans_call_inner(
         bcx,
         call_expr.debug_loc(),
@@ -737,7 +760,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
             };
             if !is_rust_fn ||
               type_of::return_uses_outptr(ccx, ret_ty) ||
-              common::type_needs_drop(bcx.tcx(), ret_ty) {
+              bcx.fcx.type_needs_drop(ret_ty) {
                 // Push the out-pointer if we use an out-pointer for this
                 // return type, otherwise push "undef".
                 if common::type_is_zero_size(ccx, ret_ty) {
@@ -765,8 +788,16 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
     if is_rust_fn {
         let mut llargs = Vec::new();
 
-        if let (ty::FnConverging(ret_ty), Some(llretslot)) = (ret_ty, opt_llretslot) {
+        if let (ty::FnConverging(ret_ty), Some(mut llretslot)) = (ret_ty, opt_llretslot) {
             if type_of::return_uses_outptr(ccx, ret_ty) {
+                let llformal_ret_ty = type_of::type_of(ccx, ret_ty).ptr_to();
+                let llret_ty = common::val_ty(llretslot);
+                if llformal_ret_ty != llret_ty {
+                    // this could happen due to e.g. subtyping
+                    debug!("casting actual return type ({}) to match formal ({})",
+                        bcx.llty_str(llret_ty), bcx.llty_str(llformal_ret_ty));
+                    llretslot = PointerCast(bcx, llretslot, llformal_ret_ty);
+                }
                 llargs.push(llretslot);
             }
         }
@@ -922,20 +953,21 @@ fn trans_args_under_call_abi<'blk, 'tcx>(
                                                           tuple_expr.id));
             let repr = adt::represent_type(bcx.ccx(), tuple_type);
             let repr_ptr = &*repr;
-            for i in 0..field_types.len() {
+            llargs.extend(field_types.iter().enumerate().map(|(i, field_type)| {
                 let arg_datum = tuple_lvalue_datum.get_element(
                     bcx,
-                    field_types[i],
+                    field_type,
                     |srcval| {
                         adt::trans_field_ptr(bcx, repr_ptr, srcval, 0, i)
-                    });
-                let arg_datum = arg_datum.to_expr_datum();
-                let arg_datum =
-                    unpack_datum!(bcx, arg_datum.to_rvalue_datum(bcx, "arg"));
-                let arg_datum =
-                    unpack_datum!(bcx, arg_datum.to_appropriate_datum(bcx));
-                llargs.push(arg_datum.add_clean(bcx.fcx, arg_cleanup_scope));
-            }
+                    }).to_expr_datum();
+                unpack_result!(bcx, trans_arg_datum(
+                    bcx,
+                    field_type,
+                    arg_datum,
+                    arg_cleanup_scope,
+                    DontAutorefArg)
+                )
+            }));
         }
         _ => {
             bcx.sess().span_bug(tuple_expr.span,
@@ -1078,7 +1110,7 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
     bcx
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum AutorefArg {
     DontAutorefArg,
     DoAutorefArg(ast::NodeId)
index 85e53618f6da9c7ed664b3a0e1643664d59eaab8..19891e9307229fa52ee380c21b743b0f67fe9d5b 100644 (file)
@@ -153,14 +153,14 @@ pub struct CleanupScope<'blk, 'tcx: 'blk> {
     cached_landing_pad: Option<BasicBlockRef>,
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub struct CustomScopeIndex {
-    index: uint
+    index: usize
 }
 
-pub const EXIT_BREAK: uint = 0;
-pub const EXIT_LOOP: uint = 1;
-pub const EXIT_MAX: uint = 2;
+pub const EXIT_BREAK: usize = 0;
+pub const EXIT_LOOP: usize = 1;
+pub const EXIT_MAX: usize = 2;
 
 pub enum CleanupScopeKind<'blk, 'tcx: 'blk> {
     CustomScopeKind,
@@ -184,14 +184,14 @@ impl<'blk, 'tcx: 'blk> fmt::Debug for CleanupScopeKind<'blk, 'tcx> {
     }
 }
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum EarlyExitLabel {
     UnwindExit,
     ReturnExit,
-    LoopExit(ast::NodeId, uint)
+    LoopExit(ast::NodeId, usize)
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct CachedEarlyExit {
     label: EarlyExitLabel,
     cleanup_block: BasicBlockRef,
@@ -209,7 +209,7 @@ pub trait Cleanup<'tcx> {
 
 pub type CleanupObj<'tcx> = Box<Cleanup<'tcx>+'tcx>;
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum ScopeId {
     AstScope(ast::NodeId),
     CustomScope(CustomScopeIndex)
@@ -357,7 +357,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
     /// break/continue (depending on `exit`) out of the loop with id `cleanup_scope`
     fn normal_exit_block(&'blk self,
                          cleanup_scope: ast::NodeId,
-                         exit: uint) -> BasicBlockRef {
+                         exit: usize) -> BasicBlockRef {
         self.trans_cleanups_to_exit_scope(LoopExit(cleanup_scope, exit))
     }
 
@@ -386,7 +386,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
                          cleanup_scope: ScopeId,
                          val: ValueRef,
                          ty: Ty<'tcx>) {
-        if !common::type_needs_drop(self.ccx.tcx(), ty) { return; }
+        if !self.type_needs_drop(ty) { return; }
         let drop = box DropValue {
             is_immediate: false,
             must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty),
@@ -408,7 +408,8 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
                                   cleanup_scope: ScopeId,
                                   val: ValueRef,
                                   ty: Ty<'tcx>) {
-        if !common::type_needs_drop(self.ccx.tcx(), ty) { return; }
+        if !self.type_needs_drop(ty) { return; }
+
         let drop = box DropValue {
             is_immediate: false,
             must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty),
@@ -432,7 +433,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
                                val: ValueRef,
                                ty: Ty<'tcx>) {
 
-        if !common::type_needs_drop(self.ccx.tcx(), ty) { return; }
+        if !self.type_needs_drop(ty) { return; }
         let drop = box DropValue {
             is_immediate: true,
             must_unwind: common::type_needs_unwind_cleanup(self.ccx, ty),
@@ -513,7 +514,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
 
         self.ccx.sess().bug(
             &format!("no cleanup scope {} found",
-                    self.ccx.tcx().map.node_to_string(cleanup_scope))[]);
+                    self.ccx.tcx().map.node_to_string(cleanup_scope)));
     }
 
     /// Schedules a cleanup to occur in the top-most scope, which must be a temporary scope.
@@ -584,7 +585,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
         None
     }
 
-    fn top_nonempty_cleanup_scope(&self) -> Option<uint> {
+    fn top_nonempty_cleanup_scope(&self) -> Option<usize> {
         self.scopes.borrow().iter().rev().position(|s| !s.cleanups.is_empty())
     }
 
@@ -613,7 +614,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
         bcx
     }
 
-    fn scopes_len(&self) -> uint {
+    fn scopes_len(&self) -> usize {
         self.scopes.borrow().len()
     }
 
@@ -695,7 +696,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
                     LoopExit(id, _) => {
                         self.ccx.sess().bug(&format!(
                                 "cannot exit from scope {}, \
-                                not in scope", id)[]);
+                                not in scope", id));
                     }
                 }
             }
@@ -961,7 +962,7 @@ impl<'blk, 'tcx> CleanupScopeKind<'blk, 'tcx> {
     /// If this is a loop scope with id `id`, return the early exit block `exit`, else `None`
     fn early_exit_block(&self,
                         id: ast::NodeId,
-                        exit: uint) -> Option<BasicBlockRef> {
+                        exit: usize) -> Option<BasicBlockRef> {
         match *self {
             LoopScopeKind(i, ref exits) if id == i => Some(exits[exit].llbb),
             _ => None,
@@ -981,7 +982,7 @@ impl EarlyExitLabel {
 ///////////////////////////////////////////////////////////////////////////
 // Cleanup types
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct DropValue<'tcx> {
     is_immediate: bool,
     must_unwind: bool,
@@ -1007,24 +1008,25 @@ impl<'tcx> Cleanup<'tcx> for DropValue<'tcx> {
                    bcx: Block<'blk, 'tcx>,
                    debug_loc: DebugLoc)
                    -> Block<'blk, 'tcx> {
+        let _icx = base::push_ctxt("<DropValue as Cleanup>::trans");
         let bcx = if self.is_immediate {
             glue::drop_ty_immediate(bcx, self.val, self.ty, debug_loc)
         } else {
             glue::drop_ty(bcx, self.val, self.ty, debug_loc)
         };
         if self.zero {
-            base::zero_mem(bcx, self.val, self.ty);
+            base::drop_done_fill_mem(bcx, self.val, self.ty);
         }
         bcx
     }
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum Heap {
     HeapExchange
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct FreeValue<'tcx> {
     ptr: ValueRef,
     heap: Heap,
@@ -1059,7 +1061,7 @@ impl<'tcx> Cleanup<'tcx> for FreeValue<'tcx> {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct FreeSlice {
     ptr: ValueRef,
     size: ValueRef,
@@ -1096,7 +1098,7 @@ impl<'tcx> Cleanup<'tcx> for FreeSlice {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct LifetimeEnd {
     ptr: ValueRef,
 }
@@ -1135,7 +1137,7 @@ pub fn temporary_scope(tcx: &ty::ctxt,
         }
         None => {
             tcx.sess.bug(&format!("no temporary scope available for expr {}",
-                                 id)[])
+                                 id))
         }
     }
 }
@@ -1180,7 +1182,7 @@ pub trait CleanupMethods<'blk, 'tcx> {
     fn top_loop_scope(&self) -> ast::NodeId;
     fn normal_exit_block(&'blk self,
                          cleanup_scope: ast::NodeId,
-                         exit: uint) -> BasicBlockRef;
+                         exit: usize) -> BasicBlockRef;
     fn return_exit_block(&'blk self) -> BasicBlockRef;
     fn schedule_lifetime_end(&self,
                          cleanup_scope: ScopeId,
@@ -1223,7 +1225,7 @@ pub trait CleanupMethods<'blk, 'tcx> {
 
 trait CleanupHelperMethods<'blk, 'tcx> {
     fn top_ast_scope(&self) -> Option<ast::NodeId>;
-    fn top_nonempty_cleanup_scope(&self) -> Option<uint>;
+    fn top_nonempty_cleanup_scope(&self) -> Option<usize>;
     fn is_valid_to_pop_custom_scope(&self, custom_scope: CustomScopeIndex) -> bool;
     fn is_valid_custom_scope(&self, custom_scope: CustomScopeIndex) -> bool;
     fn trans_scope_cleanups(&self,
@@ -1233,7 +1235,7 @@ trait CleanupHelperMethods<'blk, 'tcx> {
                                     label: EarlyExitLabel)
                                     -> BasicBlockRef;
     fn get_or_create_landing_pad(&'blk self) -> BasicBlockRef;
-    fn scopes_len(&self) -> uint;
+    fn scopes_len(&self) -> usize;
     fn push_scope(&self, scope: CleanupScope<'blk, 'tcx>);
     fn pop_scope(&self) -> CleanupScope<'blk, 'tcx>;
     fn top_scope<R, F>(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R;
index 1d4bbd79d71057baecdc624201e5d7a367355068..c1aade3663e6e8f37ec7dde9f1547d95d961c546 100644 (file)
@@ -8,24 +8,27 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use back::link::mangle_internal_name_by_path_and_seq;
-use llvm::ValueRef;
+use arena::TypedArena;
+use back::link::{self, mangle_internal_name_by_path_and_seq};
+use llvm::{ValueRef, get_param};
 use middle::mem_categorization::Typer;
 use trans::adt;
 use trans::base::*;
 use trans::build::*;
-use trans::cleanup::{CleanupMethods, ScopeId};
+use trans::callee::{self, ArgVals, Callee, TraitItem, MethodData};
+use trans::cleanup::{CleanupMethods, CustomScope, ScopeId};
 use trans::common::*;
-use trans::datum::{Datum, rvalue_scratch_datum};
-use trans::datum::{Rvalue, ByValue};
-use trans::debuginfo;
+use trans::datum::{self, Datum, rvalue_scratch_datum, Rvalue, ByValue};
+use trans::debuginfo::{self, DebugLoc};
 use trans::expr;
 use trans::monomorphize::{self, MonoId};
 use trans::type_of::*;
 use middle::ty::{self, ClosureTyper};
-use middle::subst::{Substs};
+use middle::subst::Substs;
 use session::config::FullDebugInfo;
+use util::ppaux::Repr;
 
+use syntax::abi::RustCall;
 use syntax::ast;
 use syntax::ast_util;
 
@@ -138,7 +141,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
     // duplicate declarations
     let function_type = erase_regions(ccx.tcx(), &function_type);
     let params = match function_type.sty {
-        ty::ty_closure(_, _, substs) => &substs.types,
+        ty::ty_closure(_, substs) => &substs.types,
         _ => unreachable!()
     };
     let mono_id = MonoId {
@@ -239,11 +242,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
     // Create the closure.
     for (i, freevar) in freevars.iter().enumerate() {
         let datum = expr::trans_local_var(bcx, freevar.def);
-        let upvar_slot_dest = adt::trans_field_ptr(bcx,
-                                                   &*repr,
-                                                   dest_addr,
-                                                   0,
-                                                   i);
+        let upvar_slot_dest = adt::trans_field_ptr(bcx, &*repr, dest_addr, 0, i);
         let upvar_id = ty::UpvarId { var_id: freevar.def.local_node_id(),
                                      closure_expr_id: id };
         match tcx.upvar_capture(upvar_id).unwrap() {
@@ -260,3 +259,185 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
     Some(bcx)
 }
 
+pub fn trans_closure_method<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
+                                      closure_def_id: ast::DefId,
+                                      substs: Substs<'tcx>,
+                                      node: ExprOrMethodCall,
+                                      param_substs: &'tcx Substs<'tcx>,
+                                      trait_closure_kind: ty::ClosureKind)
+                                      -> ValueRef
+{
+    // The substitutions should have no type parameters remaining
+    // after passing through fulfill_obligation
+    let llfn = callee::trans_fn_ref_with_substs(ccx,
+                                                closure_def_id,
+                                                node,
+                                                param_substs,
+                                                substs.clone()).val;
+
+    // If the closure is a Fn closure, but a FnOnce is needed (etc),
+    // then adapt the self type
+    let closure_kind = ccx.tcx().closure_kind(closure_def_id);
+    trans_closure_adapter_shim(ccx,
+                               closure_def_id,
+                               substs,
+                               closure_kind,
+                               trait_closure_kind,
+                               llfn)
+}
+
+fn trans_closure_adapter_shim<'a, 'tcx>(
+    ccx: &'a CrateContext<'a, 'tcx>,
+    closure_def_id: ast::DefId,
+    substs: Substs<'tcx>,
+    llfn_closure_kind: ty::ClosureKind,
+    trait_closure_kind: ty::ClosureKind,
+    llfn: ValueRef)
+    -> ValueRef
+{
+    let _icx = push_ctxt("trans_closure_adapter_shim");
+    let tcx = ccx.tcx();
+
+    debug!("trans_closure_adapter_shim(llfn_closure_kind={:?}, \
+           trait_closure_kind={:?}, \
+           llfn={})",
+           llfn_closure_kind,
+           trait_closure_kind,
+           ccx.tn().val_to_string(llfn));
+
+    match (llfn_closure_kind, trait_closure_kind) {
+        (ty::FnClosureKind, ty::FnClosureKind) |
+        (ty::FnMutClosureKind, ty::FnMutClosureKind) |
+        (ty::FnOnceClosureKind, ty::FnOnceClosureKind) => {
+            // No adapter needed.
+            llfn
+        }
+        (ty::FnClosureKind, ty::FnMutClosureKind) => {
+            // The closure fn `llfn` is a `fn(&self, ...)`.  We want a
+            // `fn(&mut self, ...)`. In fact, at trans time, these are
+            // basically the same thing, so we can just return llfn.
+            llfn
+        }
+        (ty::FnClosureKind, ty::FnOnceClosureKind) |
+        (ty::FnMutClosureKind, ty::FnOnceClosureKind) => {
+            // The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut
+            // self, ...)`.  We want a `fn(self, ...)`. We can produce
+            // this by doing something like:
+            //
+            //     fn call_once(self, ...) { call_mut(&self, ...) }
+            //     fn call_once(mut self, ...) { call_mut(&mut self, ...) }
+            //
+            // These are both the same at trans time.
+            trans_fn_once_adapter_shim(ccx, closure_def_id, substs, llfn)
+        }
+        _ => {
+            tcx.sess.bug(&format!("trans_closure_adapter_shim: cannot convert {:?} to {:?}",
+                                  llfn_closure_kind,
+                                  trait_closure_kind));
+        }
+    }
+}
+
+fn trans_fn_once_adapter_shim<'a, 'tcx>(
+    ccx: &'a CrateContext<'a, 'tcx>,
+    closure_def_id: ast::DefId,
+    substs: Substs<'tcx>,
+    llreffn: ValueRef)
+    -> ValueRef
+{
+    debug!("trans_fn_once_adapter_shim(closure_def_id={}, substs={}, llreffn={})",
+           closure_def_id.repr(ccx.tcx()),
+           substs.repr(ccx.tcx()),
+           ccx.tn().val_to_string(llreffn));
+
+    let tcx = ccx.tcx();
+    let typer = NormalizingClosureTyper::new(tcx);
+
+    // Find a version of the closure type. Substitute static for the
+    // region since it doesn't really matter.
+    let substs = tcx.mk_substs(substs);
+    let closure_ty = ty::mk_closure(tcx, closure_def_id, substs);
+    let ref_closure_ty = ty::mk_imm_rptr(tcx, tcx.mk_region(ty::ReStatic), closure_ty);
+
+    // Make a version with the type of by-ref closure.
+    let ty::ClosureTy { unsafety, abi, mut sig } = typer.closure_type(closure_def_id, substs);
+    sig.0.inputs.insert(0, ref_closure_ty); // sig has no self type as of yet
+    let llref_bare_fn_ty = tcx.mk_bare_fn(ty::BareFnTy { unsafety: unsafety,
+                                                               abi: abi,
+                                                               sig: sig.clone() });
+    let llref_fn_ty = ty::mk_bare_fn(tcx, None, llref_bare_fn_ty);
+    debug!("trans_fn_once_adapter_shim: llref_fn_ty={}",
+           llref_fn_ty.repr(tcx));
+
+    // Make a version of the closure type with the same arguments, but
+    // with argument #0 being by value.
+    assert_eq!(abi, RustCall);
+    sig.0.inputs[0] = closure_ty;
+    let llonce_bare_fn_ty = tcx.mk_bare_fn(ty::BareFnTy { unsafety: unsafety,
+                                                                abi: abi,
+                                                                sig: sig });
+    let llonce_fn_ty = ty::mk_bare_fn(tcx, None, llonce_bare_fn_ty);
+
+    // Create the by-value helper.
+    let function_name = link::mangle_internal_name_by_type_and_seq(ccx, llonce_fn_ty, "once_shim");
+    let lloncefn = decl_internal_rust_fn(ccx, llonce_fn_ty, &function_name);
+
+    let sig = ty::erase_late_bound_regions(tcx, &llonce_bare_fn_ty.sig);
+    let (block_arena, fcx): (TypedArena<_>, FunctionContext);
+    block_arena = TypedArena::new();
+    fcx = new_fn_ctxt(ccx,
+                      lloncefn,
+                      ast::DUMMY_NODE_ID,
+                      false,
+                      sig.output,
+                      substs,
+                      None,
+                      &block_arena);
+    let mut bcx = init_function(&fcx, false, sig.output);
+
+    // the first argument (`self`) will be the (by value) closure env.
+    let self_scope = fcx.push_custom_cleanup_scope();
+    let self_scope_id = CustomScope(self_scope);
+    let rvalue_mode = datum::appropriate_rvalue_mode(ccx, closure_ty);
+    let llself = get_param(lloncefn, fcx.arg_pos(0) as u32);
+    let env_datum = Datum::new(llself, closure_ty, Rvalue::new(rvalue_mode));
+    let env_datum = unpack_datum!(bcx,
+                                  env_datum.to_lvalue_datum_in_scope(bcx, "self",
+                                                                     self_scope_id));
+
+    debug!("trans_fn_once_adapter_shim: env_datum={}",
+           bcx.val_to_string(env_datum.val));
+
+    // the remaining arguments will be packed up in a tuple.
+    let input_tys = match sig.inputs[1].sty {
+        ty::ty_tup(ref tys) => &**tys,
+        _ => bcx.sess().bug(&format!("trans_fn_once_adapter_shim: not rust-call! \
+                                      closure_def_id={}",
+                                     closure_def_id.repr(tcx)))
+    };
+    let llargs: Vec<_> =
+        input_tys.iter()
+                 .enumerate()
+                 .map(|(i, _)| get_param(lloncefn, fcx.arg_pos(i+1) as u32))
+                 .collect();
+
+    let dest =
+        fcx.llretslotptr.get().map(
+            |_| expr::SaveIn(fcx.get_ret_slot(bcx, sig.output, "ret_slot")));
+
+    let callee_data = TraitItem(MethodData { llfn: llreffn,
+                                             llself: env_datum.val });
+
+    bcx = callee::trans_call_inner(bcx,
+                                   DebugLoc::None,
+                                   llref_fn_ty,
+                                   |bcx, _| Callee { bcx: bcx, data: callee_data },
+                                   ArgVals(&llargs),
+                                   dest).bcx;
+
+    fcx.pop_custom_cleanup_scope(self_scope);
+
+    finish_fn(&fcx, bcx, sig.output, DebugLoc::None);
+
+    lloncefn
+}
index a9cda94bebac52513d98848c30cf01ca6a7262d5..c5985e930e97b98b72fc9e3ffdb72a3c6e1af935 100644 (file)
@@ -46,6 +46,7 @@ use arena::TypedArena;
 use libc::{c_uint, c_char};
 use std::ffi::CString;
 use std::cell::{Cell, RefCell};
+use std::result::Result as StdResult;
 use std::vec::Vec;
 use syntax::ast::Ident;
 use syntax::ast;
@@ -120,14 +121,16 @@ pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T
 // Is the type's representation size known at compile time?
 pub fn type_is_sized<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
     let param_env = ty::empty_parameter_environment(tcx);
-    ty::type_is_sized(&param_env, DUMMY_SP, ty)
-}
-
-pub fn lltype_is_sized<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
-    match ty.sty {
-        ty::ty_open(_) => true,
-        _ => type_is_sized(cx, ty),
+    // FIXME(#4287) This can cause errors due to polymorphic recursion,
+    // a better span should be provided, if available.
+    let err_count = tcx.sess.err_count();
+    let is_sized = ty::type_is_sized(&param_env, DUMMY_SP, ty);
+    // Those errors aren't fatal, but an incorrect result can later
+    // trip over asserts in both rustc's trans and LLVM.
+    if err_count < tcx.sess.err_count() {
+        tcx.sess.abort_if_errors();
     }
+    is_sized
 }
 
 pub fn type_is_fat_ptr<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
@@ -211,10 +214,43 @@ pub fn type_needs_unwind_cleanup<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<
     }
 }
 
-pub fn type_needs_drop<'tcx>(cx: &ty::ctxt<'tcx>,
-                         ty: Ty<'tcx>)
-                         -> bool {
-    ty::type_contents(cx, ty).needs_drop(cx)
+/// If `type_needs_drop` returns true, then `ty` is definitely
+/// non-copy and *might* have a destructor attached; if it returns
+/// false, then `ty` definitely has no destructor (i.e. no drop glue).
+///
+/// (Note that this implies that if `ty` has a destructor attached,
+/// then `type_needs_drop` will definitely return `true` for `ty`.)
+pub fn type_needs_drop<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
+    type_needs_drop_given_env(cx, ty, &ty::empty_parameter_environment(cx))
+}
+
+/// Core implementation of type_needs_drop, potentially making use of
+/// and/or updating caches held in the `param_env`.
+fn type_needs_drop_given_env<'a,'tcx>(cx: &ty::ctxt<'tcx>,
+                                      ty: Ty<'tcx>,
+                                      param_env: &ty::ParameterEnvironment<'a,'tcx>) -> bool {
+    // Issue #22536: We first query type_moves_by_default.  It sees a
+    // normalized version of the type, and therefore will definitely
+    // know whether the type implements Copy (and thus needs no
+    // cleanup/drop/zeroing) ...
+    let implements_copy = !ty::type_moves_by_default(&param_env, DUMMY_SP, ty);
+
+    if implements_copy { return false; }
+
+    // ... (issue #22536 continued) but as an optimization, still use
+    // prior logic of asking if the `needs_drop` bit is set; we need
+    // not zero non-Copy types if they have no destructor.
+
+    // FIXME(#22815): Note that calling `ty::type_contents` is a
+    // conservative heuristic; it may report that `needs_drop` is set
+    // when actual type does not actually have a destructor associated
+    // with it. But since `ty` absolutely did not have the `Copy`
+    // bound attached (see above), it is sound to treat it as having a
+    // destructor (e.g. zero its memory on move).
+
+    let contents = ty::type_contents(cx, ty);
+    debug!("type_needs_drop ty={} contents={:?}", ty.repr(cx), contents);
+    contents.needs_drop(cx)
 }
 
 fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
@@ -278,16 +314,7 @@ pub fn gensym_name(name: &str) -> PathElem {
     let num = token::gensym(name).usize();
     // use one colon which will get translated to a period by the mangler, and
     // we're guaranteed that `num` is globally unique for this crate.
-    PathName(token::gensym(&format!("{}:{}", name, num)[]))
-}
-
-#[derive(Copy)]
-pub struct tydesc_info<'tcx> {
-    pub ty: Ty<'tcx>,
-    pub tydesc: ValueRef,
-    pub size: ValueRef,
-    pub align: ValueRef,
-    pub name: ValueRef,
+    PathName(token::gensym(&format!("{}:{}", name, num)))
 }
 
 /*
@@ -316,7 +343,7 @@ pub struct tydesc_info<'tcx> {
 *
 */
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct NodeIdAndSpan {
     pub id: ast::NodeId,
     pub span: Span,
@@ -352,7 +379,7 @@ pub fn validate_substs(substs: &Substs) {
 
 // work around bizarre resolve errors
 type RvalueDatum<'tcx> = datum::Datum<'tcx, datum::Rvalue>;
-type LvalueDatum<'tcx> = datum::Datum<'tcx, datum::Lvalue>;
+pub type LvalueDatum<'tcx> = datum::Datum<'tcx, datum::Lvalue>;
 
 // Function context.  Every LLVM function we create will have one of
 // these.
@@ -432,7 +459,7 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
-    pub fn arg_pos(&self, arg: uint) -> uint {
+    pub fn arg_pos(&self, arg: usize) -> usize {
         let arg = self.env_arg_pos() + arg;
         if self.llenv.is_some() {
             arg + 1
@@ -441,7 +468,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
         }
     }
 
-    pub fn env_arg_pos(&self) -> uint {
+    pub fn env_arg_pos(&self) -> usize {
         if self.caller_expects_out_pointer {
             1
         } else {
@@ -534,6 +561,12 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
                                          self.param_substs,
                                          value)
     }
+
+    /// This is the same as `common::type_needs_drop`, except that it
+    /// may use or update caches within this `FunctionContext`.
+    pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
+        type_needs_drop_given_env(self.ccx.tcx(), ty, &self.param_env)
+    }
 }
 
 // Basic block context.  We create a block context for each basic block
@@ -603,10 +636,10 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
 
     pub fn def(&self, nid: ast::NodeId) -> def::Def {
         match self.tcx().def_map.borrow().get(&nid) {
-            Some(v) => v.clone(),
+            Some(v) => v.full_def(),
             None => {
                 self.tcx().sess.bug(&format!(
-                    "no def associated with node id {}", nid)[]);
+                    "no def associated with node id {}", nid));
             }
         }
     }
@@ -676,7 +709,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
     }
 
     fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
-        Some(self.tcx().upvar_capture_map.borrow()[upvar_id].clone())
+        Some(self.tcx().upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
     }
 
     fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool {
@@ -774,6 +807,10 @@ pub fn C_i32(ccx: &CrateContext, i: i32) -> ValueRef {
     C_integral(Type::i32(ccx), i as u64, true)
 }
 
+pub fn C_u32(ccx: &CrateContext, i: u32) -> ValueRef {
+    C_integral(Type::i32(ccx), i as u64, false)
+}
+
 pub fn C_u64(ccx: &CrateContext, i: u64) -> ValueRef {
     C_integral(Type::i64(ccx), i, false)
 }
@@ -809,13 +846,13 @@ pub trait AsU64 { fn as_u64(self) -> u64; }
 // are host-architecture-dependent
 impl AsI64 for i64 { fn as_i64(self) -> i64 { self as i64 }}
 impl AsI64 for i32 { fn as_i64(self) -> i64 { self as i64 }}
-impl AsI64 for int { fn as_i64(self) -> i64 { self as i64 }}
+impl AsI64 for isize { fn as_i64(self) -> i64 { self as i64 }}
 
 impl AsU64 for u64  { fn as_u64(self) -> u64 { self as u64 }}
 impl AsU64 for u32  { fn as_u64(self) -> u64 { self as u64 }}
-impl AsU64 for uint { fn as_u64(self) -> u64 { self as u64 }}
+impl AsU64 for usize { fn as_u64(self) -> u64 { self as u64 }}
 
-pub fn C_u8(ccx: &CrateContext, i: uint) -> ValueRef {
+pub fn C_u8(ccx: &CrateContext, i: usize) -> ValueRef {
     C_integral(Type::i8(ccx), i as u64, false)
 }
 
@@ -926,6 +963,32 @@ pub fn const_to_uint(v: ValueRef) -> u64 {
     }
 }
 
+fn is_const_integral(v: ValueRef) -> bool {
+    unsafe {
+        !llvm::LLVMIsAConstantInt(v).is_null()
+    }
+}
+
+pub fn const_to_opt_int(v: ValueRef) -> Option<i64> {
+    unsafe {
+        if is_const_integral(v) {
+            Some(llvm::LLVMConstIntGetSExtValue(v))
+        } else {
+            None
+        }
+    }
+}
+
+pub fn const_to_opt_uint(v: ValueRef) -> Option<u64> {
+    unsafe {
+        if is_const_integral(v) {
+            Some(llvm::LLVMConstIntGetZExtValue(v))
+        } else {
+            None
+        }
+    }
+}
+
 pub fn is_undef(val: ValueRef) -> bool {
     unsafe {
         llvm::LLVMIsUndef(val) != False
@@ -961,9 +1024,9 @@ pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) ->
 /// do not (necessarily) resolve all nested obligations on the impl. Note that type check should
 /// guarantee to us that all nested obligations *could be* resolved if we wanted to.
 pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-                                span: Span,
-                                trait_ref: ty::PolyTraitRef<'tcx>)
-                                -> traits::Vtable<'tcx, ()>
+                                    span: Span,
+                                    trait_ref: ty::PolyTraitRef<'tcx>)
+                                    -> traits::Vtable<'tcx, ()>
 {
     let tcx = ccx.tcx();
 
@@ -988,8 +1051,9 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     // shallow result we are looking for -- that is, what specific impl.
     let typer = NormalizingClosureTyper::new(tcx);
     let mut selcx = traits::SelectionContext::new(&infcx, &typer);
-    let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
-                                             trait_ref.to_poly_trait_predicate());
+    let obligation =
+        traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID),
+                                trait_ref.to_poly_trait_predicate());
     let selection = match selcx.select(&obligation) {
         Ok(Some(selection)) => selection,
         Ok(None) => {
@@ -1011,7 +1075,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                 span,
                 &format!("Encountered error `{}` selecting `{}` during trans",
                         e.repr(tcx),
-                        trait_ref.repr(tcx))[])
+                        trait_ref.repr(tcx)))
         }
     };
 
@@ -1022,7 +1086,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     let vtable = selection.map_move_nested(|predicate| {
         fulfill_cx.register_predicate_obligation(&infcx, predicate);
     });
-    let vtable = drain_fulfillment_cx(span, &infcx, &mut fulfill_cx, &vtable);
+    let vtable = drain_fulfillment_cx_or_panic(span, &infcx, &mut fulfill_cx, &vtable);
 
     info!("Cache miss: {}", trait_ref.repr(ccx.tcx()));
     ccx.trait_cache().borrow_mut().insert(trait_ref,
@@ -1031,6 +1095,35 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     vtable
 }
 
+/// Normalizes the predicates and checks whether they hold.  If this
+/// returns false, then either normalize encountered an error or one
+/// of the predicates did not hold. Used when creating vtables to
+/// check for unsatisfiable methods.
+pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
+                                               predicates: Vec<ty::Predicate<'tcx>>)
+                                               -> bool
+{
+    debug!("normalize_and_test_predicates(predicates={})",
+           predicates.repr(ccx.tcx()));
+
+    let tcx = ccx.tcx();
+    let infcx = infer::new_infer_ctxt(tcx);
+    let typer = NormalizingClosureTyper::new(tcx);
+    let mut selcx = traits::SelectionContext::new(&infcx, &typer);
+    let mut fulfill_cx = traits::FulfillmentContext::new();
+    let cause = traits::ObligationCause::dummy();
+    let traits::Normalized { value: predicates, obligations } =
+        traits::normalize(&mut selcx, cause.clone(), &predicates);
+    for obligation in obligations {
+        fulfill_cx.register_predicate_obligation(&infcx, obligation);
+    }
+    for predicate in predicates {
+        let obligation = traits::Obligation::new(cause.clone(), predicate);
+        fulfill_cx.register_predicate_obligation(&infcx, obligation);
+    }
+    drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok()
+}
+
 pub struct NormalizingClosureTyper<'a,'tcx:'a> {
     param_env: ty::ParameterEnvironment<'a, 'tcx>
 }
@@ -1078,11 +1171,35 @@ impl<'a,'tcx> ty::ClosureTyper<'tcx> for NormalizingClosureTyper<'a,'tcx> {
     }
 }
 
-pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
-                                   infcx: &infer::InferCtxt<'a,'tcx>,
-                                   fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
-                                   result: &T)
-                                   -> T
+pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
+                                                infcx: &infer::InferCtxt<'a,'tcx>,
+                                                fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
+                                                result: &T)
+                                                -> T
+    where T : TypeFoldable<'tcx> + Repr<'tcx>
+{
+    match drain_fulfillment_cx(infcx, fulfill_cx, result) {
+        Ok(v) => v,
+        Err(errors) => {
+            infcx.tcx.sess.span_bug(
+                span,
+                &format!("Encountered errors `{}` fulfilling during trans",
+                         errors.repr(infcx.tcx)));
+        }
+    }
+}
+
+/// Finishes processes any obligations that remain in the fulfillment
+/// context, and then "freshens" and returns `result`. This is
+/// primarily used during normalization and other cases where
+/// processing the obligations in `fulfill_cx` may cause type
+/// inference variables that appear in `result` to be unified, and
+/// hence we need to process those obligations to get the complete
+/// picture of the type.
+pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &infer::InferCtxt<'a,'tcx>,
+                                       fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
+                                       result: &T)
+                                       -> StdResult<T,Vec<traits::FulfillmentError<'tcx>>>
     where T : TypeFoldable<'tcx> + Repr<'tcx>
 {
     debug!("drain_fulfillment_cx(result={})",
@@ -1095,17 +1212,7 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
     match fulfill_cx.select_all_or_error(infcx, &typer) {
         Ok(()) => { }
         Err(errors) => {
-            if errors.iter().all(|e| e.is_overflow()) {
-                // See Ok(None) case above.
-                infcx.tcx.sess.span_fatal(
-                    span,
-                    "reached the recursion limit during monomorphization");
-            } else {
-                infcx.tcx.sess.span_bug(
-                    span,
-                    &format!("Encountered errors `{}` fulfilling during trans",
-                            errors.repr(infcx.tcx))[]);
-            }
+            return Err(errors);
         }
     }
 
@@ -1114,11 +1221,11 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
     // sort of overkill because we do not expect there to be any
     // unbound type variables, hence no `TyFresh` types should ever be
     // inserted.
-    result.fold_with(&mut infcx.freshener())
+    Ok(result.fold_with(&mut infcx.freshener()))
 }
 
 // Key used to lookup values supplied for type parameters in an expr.
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum ExprOrMethodCall {
     // Type parameters for a path like `None::<int>`
     ExprId(ast::NodeId),
@@ -1138,13 +1245,13 @@ pub fn node_id_substs<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             ty::node_id_item_substs(tcx, id).substs
         }
         MethodCallKey(method_call) => {
-            (*tcx.method_map.borrow())[method_call].substs.clone()
+            tcx.method_map.borrow().get(&method_call).unwrap().substs.clone()
         }
     };
 
     if substs.types.any(|t| ty::type_needs_infer(*t)) {
             tcx.sess.bug(&format!("type parameters for node {:?} include inference types: {:?}",
-                                 node, substs.repr(tcx))[]);
+                                 node, substs.repr(tcx)));
         }
 
         monomorphize::apply_param_substs(tcx,
index 7705b53ee38c69ad7a4c74254666fc3901776dbe..c32cb28ec78dbb9bbdbf83fced5510b615f2780e 100644 (file)
@@ -14,6 +14,14 @@ use llvm;
 use llvm::{ConstFCmp, ConstICmp, SetLinkage, SetUnnamedAddr};
 use llvm::{InternalLinkage, ValueRef, Bool, True};
 use middle::{check_const, const_eval, def};
+use middle::const_eval::{const_int_checked_neg, const_uint_checked_neg};
+use middle::const_eval::{const_int_checked_add, const_uint_checked_add};
+use middle::const_eval::{const_int_checked_sub, const_uint_checked_sub};
+use middle::const_eval::{const_int_checked_mul, const_uint_checked_mul};
+use middle::const_eval::{const_int_checked_div, const_uint_checked_div};
+use middle::const_eval::{const_int_checked_rem, const_uint_checked_rem};
+use middle::const_eval::{const_int_checked_shl, const_uint_checked_shl};
+use middle::const_eval::{const_int_checked_shr, const_uint_checked_shr};
 use trans::{adt, closure, debuginfo, expr, inline, machine};
 use trans::base::{self, push_ctxt};
 use trans::common::*;
@@ -53,8 +61,8 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit)
                 }
                 _ => cx.sess().span_bug(lit.span,
                         &format!("integer literal has type {} (expected int \
-                                 or uint)",
-                                ty_to_string(cx.tcx(), lit_int_ty))[])
+                                 or usize)",
+                                ty_to_string(cx.tcx(), lit_int_ty)))
             }
         }
         ast::LitFloat(ref fs, t) => {
@@ -75,14 +83,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit)
         ast::LitBool(b) => C_bool(cx, b),
         ast::LitStr(ref s, _) => C_str_slice(cx, (*s).clone()),
         ast::LitBinary(ref data) => {
-            let g = addr_of(cx, C_bytes(cx, &data[..]), "binary", e.id);
-            let base = ptrcast(g, Type::i8p(cx));
-            let prev_const = cx.const_unsized().borrow_mut()
-                               .insert(base, g);
-            assert!(prev_const.is_none() || prev_const == Some(g));
-            assert_eq!(abi::FAT_PTR_ADDR, 0);
-            assert_eq!(abi::FAT_PTR_EXTRA, 1);
-            C_struct(cx, &[base, C_uint(cx, data.len())], false)
+            addr_of(cx, C_bytes(cx, &data[..]), "binary", e.id)
         }
     }
 }
@@ -146,13 +147,13 @@ fn const_deref<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 (const_deref_ptr(cx, v), mt.ty)
             } else {
                 // Derefing a fat pointer does not change the representation,
-                // just the type to ty_open.
-                (v, ty::mk_open(cx.tcx(), mt.ty))
+                // just the type to the unsized contents.
+                (v, mt.ty)
             }
         }
         None => {
             cx.sess().bug(&format!("unexpected dereferenceable type {}",
-                                   ty_to_string(cx.tcx(), ty))[])
+                                   ty_to_string(cx.tcx(), ty)))
         }
     }
 }
@@ -173,8 +174,8 @@ pub fn get_const_expr<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         &**expr
     } else {
         ccx.sess().span_bug(ref_expr.span,
-                            &format!("get_const_val given non-constant item {}",
-                                     item.repr(ccx.tcx()))[]);
+                            &format!("get_const_expr given non-constant item {}",
+                                     item.repr(ccx.tcx())));
     }
 }
 
@@ -193,8 +194,8 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                           -> ValueRef {
     // Special-case constants to cache a common global for all uses.
     match expr.node {
-        ast::ExprPath(_) => {
-            let def = ccx.tcx().def_map.borrow()[expr.id];
+        ast::ExprPath(..) => {
+            let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
             match def {
                 def::DefConst(def_id) => {
                     if !ccx.tcx().adjustments.borrow().contains_key(&expr.id) {
@@ -253,6 +254,9 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             // FIXME(#19925) once fn item types are
             // zero-sized, we'll need to do something here
         }
+        Some(ty::AdjustUnsafeFnPointer) => {
+            // purely a type-level thing
+        }
         Some(ty::AdjustDerefRef(adj)) => {
             let mut ty = ety;
             // Save the last autoderef in case we can avoid it.
@@ -290,18 +294,10 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                         // an optimisation, it is necessary for mutable vectors to
                         // work properly.
                         ty = match ty::deref(ty, true) {
-                            Some(mt) => {
-                                if type_is_sized(cx.tcx(), mt.ty) {
-                                    mt.ty
-                                } else {
-                                    // Derefing a fat pointer does not change the representation,
-                                    // just the type to ty_open.
-                                    ty::mk_open(cx.tcx(), mt.ty)
-                                }
-                            }
+                            Some(mt) => mt.ty,
                             None => {
                                 cx.sess().bug(&format!("unexpected dereferenceable type {}",
-                                                       ty_to_string(cx.tcx(), ty))[])
+                                                       ty_to_string(cx.tcx(), ty)))
                             }
                         }
                     }
@@ -309,7 +305,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 }
                 Some(autoref) => {
                     cx.sess().span_bug(e.span,
-                        &format!("unimplemented const first autoref {:?}", autoref)[])
+                        &format!("unimplemented const first autoref {:?}", autoref))
                 }
             };
             match second_autoref {
@@ -319,11 +315,15 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                     llconst = addr_of(cx, llconst, "autoref", e.id);
                 }
                 Some(box ty::AutoUnsize(ref k)) => {
+                    let info =
+                        expr::unsized_info(
+                            cx, k, e.id, ty, param_substs,
+                            || const_get_elt(cx, llconst, &[abi::FAT_PTR_EXTRA as u32]));
+
                     let unsized_ty = ty::unsize_ty(cx.tcx(), ty, k, e.span);
-                    let info = expr::unsized_info(cx, k, e.id, ty, param_substs,
-                        |t| ty::mk_imm_rptr(cx.tcx(), cx.tcx().mk_region(ty::ReStatic), t));
+                    let ptr_ty = type_of::in_memory_type_of(cx, unsized_ty).ptr_to();
+                    let base = ptrcast(llconst, ptr_ty);
 
-                    let base = ptrcast(llconst, type_of::type_of(cx, unsized_ty).ptr_to());
                     let prev_const = cx.const_unsized().borrow_mut()
                                        .insert(base, llconst);
                     assert!(prev_const.is_none() || prev_const == Some(llconst));
@@ -333,7 +333,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 }
                 Some(autoref) => {
                     cx.sess().span_bug(e.span,
-                        &format!("unimplemented const second autoref {:?}", autoref)[])
+                        &format!("unimplemented const second autoref {:?}", autoref))
                 }
             }
         }
@@ -344,6 +344,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let csize = machine::llsize_of_alloc(cx, val_ty(llconst));
     let tsize = machine::llsize_of_alloc(cx, llty);
     if csize != tsize {
+        cx.sess().abort_if_errors();
         unsafe {
             // FIXME these values could use some context
             llvm::LLVMDumpValue(llconst);
@@ -351,22 +352,123 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         }
         cx.sess().bug(&format!("const {} of type {} has size {} instead of {}",
                          e.repr(cx.tcx()), ty_to_string(cx.tcx(), ety_adjusted),
-                         csize, tsize)[]);
+                         csize, tsize));
     }
     (llconst, ety_adjusted)
 }
 
+fn check_unary_expr_validity(cx: &CrateContext, e: &ast::Expr, t: Ty,
+                             te: ValueRef) {
+    // The only kind of unary expression that we check for validity
+    // here is `-expr`, to check if it "overflows" (e.g. `-i32::MIN`).
+    if let ast::ExprUnary(ast::UnNeg, ref inner_e) = e.node {
+
+        // An unfortunate special case: we parse e.g. -128 as a
+        // negation of the literal 128, which means if we're expecting
+        // a i8 (or if it was already suffixed, e.g. `-128_i8`), then
+        // 128 will have already overflowed to -128, and so then the
+        // constant evaluator thinks we're trying to negate -128.
+        //
+        // Catch this up front by looking for ExprLit directly,
+        // and just accepting it.
+        if let ast::ExprLit(_) = inner_e.node { return; }
+
+        let result = match t.sty {
+            ty::ty_int(int_type) => {
+                let input = match const_to_opt_int(te) {
+                    Some(v) => v,
+                    None => return,
+                };
+                const_int_checked_neg(
+                    input, e, Some(const_eval::IntTy::from(cx.tcx(), int_type)))
+            }
+            ty::ty_uint(uint_type) => {
+                let input = match const_to_opt_uint(te) {
+                    Some(v) => v,
+                    None => return,
+                };
+                const_uint_checked_neg(
+                    input, e, Some(const_eval::UintTy::from(cx.tcx(), uint_type)))
+            }
+            _ => return,
+        };
+
+        // We do not actually care about a successful result.
+        if let Err(err) = result {
+            cx.tcx().sess.span_err(e.span, &err.description());
+        }
+    }
+}
+
+fn check_binary_expr_validity(cx: &CrateContext, e: &ast::Expr, t: Ty,
+                              te1: ValueRef, te2: ValueRef) {
+    let b = if let ast::ExprBinary(b, _, _) = e.node { b } else { return };
+
+    let result = match t.sty {
+        ty::ty_int(int_type) => {
+            let (lhs, rhs) = match (const_to_opt_int(te1),
+                                    const_to_opt_int(te2)) {
+                (Some(v1), Some(v2)) => (v1, v2),
+                _ => return,
+            };
+
+            let opt_ety = Some(const_eval::IntTy::from(cx.tcx(), int_type));
+            match b.node {
+                ast::BiAdd => const_int_checked_add(lhs, rhs, e, opt_ety),
+                ast::BiSub => const_int_checked_sub(lhs, rhs, e, opt_ety),
+                ast::BiMul => const_int_checked_mul(lhs, rhs, e, opt_ety),
+                ast::BiDiv => const_int_checked_div(lhs, rhs, e, opt_ety),
+                ast::BiRem => const_int_checked_rem(lhs, rhs, e, opt_ety),
+                ast::BiShl => const_int_checked_shl(lhs, rhs, e, opt_ety),
+                ast::BiShr => const_int_checked_shr(lhs, rhs, e, opt_ety),
+                _ => return,
+            }
+        }
+        ty::ty_uint(uint_type) => {
+            let (lhs, rhs) = match (const_to_opt_uint(te1),
+                                    const_to_opt_uint(te2)) {
+                (Some(v1), Some(v2)) => (v1, v2),
+                _ => return,
+            };
+
+            let opt_ety = Some(const_eval::UintTy::from(cx.tcx(), uint_type));
+            match b.node {
+                ast::BiAdd => const_uint_checked_add(lhs, rhs, e, opt_ety),
+                ast::BiSub => const_uint_checked_sub(lhs, rhs, e, opt_ety),
+                ast::BiMul => const_uint_checked_mul(lhs, rhs, e, opt_ety),
+                ast::BiDiv => const_uint_checked_div(lhs, rhs, e, opt_ety),
+                ast::BiRem => const_uint_checked_rem(lhs, rhs, e, opt_ety),
+                ast::BiShl => const_uint_checked_shl(lhs, rhs, e, opt_ety),
+                ast::BiShr => const_uint_checked_shr(lhs, rhs, e, opt_ety),
+                _ => return,
+            }
+        }
+        _ => return,
+    };
+    // We do not actually care about a successful result.
+    if let Err(err) = result {
+        cx.tcx().sess.span_err(e.span, &err.description());
+    }
+}
+
 fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                    e: &ast::Expr,
                                    ety: Ty<'tcx>,
-                                   param_substs: &'tcx Substs<'tcx>) -> ValueRef {
+                                   param_substs: &'tcx Substs<'tcx>)
+                                   -> ValueRef
+{
+    debug!("const_expr_unadjusted(e={}, ety={}, param_substs={})",
+           e.repr(cx.tcx()),
+           ety.repr(cx.tcx()),
+           param_substs.repr(cx.tcx()));
+
     let map_list = |exprs: &[P<ast::Expr>]| {
         exprs.iter().map(|e| const_expr(cx, &**e, param_substs).0)
              .fold(Vec::new(), |mut l, val| { l.push(val); l })
     };
     unsafe {
         let _icx = push_ctxt("const_expr");
-        return match e.node {
+        match e.node {
           ast::ExprLit(ref lit) => {
               const_lit(cx, e, &**lit)
           }
@@ -374,6 +476,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             /* Neither type is bottom, and we expect them to be unified
              * already, so the following is safe. */
             let (te1, ty) = const_expr(cx, &**e1, param_substs);
+            debug!("const_expr_unadjusted: te1={}, ty={}",
+                   cx.tn().val_to_string(te1),
+                   ty.repr(cx.tcx()));
             let is_simd = ty::type_is_simd(cx.tcx(), ty);
             let intype = if is_simd {
                 ty::simd_type(cx.tcx(), ty)
@@ -384,9 +489,10 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let signed = ty::type_is_signed(intype);
 
             let (te2, _) = const_expr(cx, &**e2, param_substs);
-            let te2 = base::cast_shift_const_rhs(b, te1, te2);
 
-            return match b.node {
+            check_binary_expr_validity(cx, e, ty, te1, te2);
+
+            match b.node {
               ast::BiAdd   => {
                 if is_float { llvm::LLVMConstFAdd(te1, te2) }
                 else        { llvm::LLVMConstAdd(te1, te2) }
@@ -414,8 +520,12 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
               ast::BiBitXor => llvm::LLVMConstXor(te1, te2),
               ast::BiBitAnd => llvm::LLVMConstAnd(te1, te2),
               ast::BiBitOr  => llvm::LLVMConstOr(te1, te2),
-              ast::BiShl    => llvm::LLVMConstShl(te1, te2),
+              ast::BiShl    => {
+                let te2 = base::cast_shift_const_rhs(b.node, te1, te2);
+                llvm::LLVMConstShl(te1, te2)
+              }
               ast::BiShr    => {
+                let te2 = base::cast_shift_const_rhs(b.node, te1, te2);
                 if signed { llvm::LLVMConstAShr(te1, te2) }
                 else      { llvm::LLVMConstLShr(te1, te2) }
               }
@@ -437,10 +547,13 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
               }
             }
           },
-          ast::ExprUnary(u, ref e) => {
-            let (te, ty) = const_expr(cx, &**e, param_substs);
+          ast::ExprUnary(u, ref inner_e) => {
+            let (te, ty) = const_expr(cx, &**inner_e, param_substs);
+
+            check_unary_expr_validity(cx, e, ty, te);
+
             let is_float = ty::type_is_fp(ty);
-            return match u {
+            match u {
               ast::UnUniq | ast::UnDeref => {
                 const_deref(cx, te, ty).0
               }
@@ -469,24 +582,18 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
           ast::ExprIndex(ref base, ref index) => {
               let (bv, bt) = const_expr(cx, &**base, param_substs);
-              let iv = match const_eval::eval_const_expr(cx.tcx(), &**index) {
-                  const_eval::const_int(i) => i as u64,
-                  const_eval::const_uint(u) => u,
+              let iv = match const_eval::eval_const_expr_partial(cx.tcx(), &**index, None) {
+                  Ok(const_eval::const_int(i)) => i as u64,
+                  Ok(const_eval::const_uint(u)) => u,
                   _ => cx.sess().span_bug(index.span,
                                           "index is not an integer-constant expression")
               };
               let (arr, len) = match bt.sty {
                   ty::ty_vec(_, Some(u)) => (bv, C_uint(cx, u)),
-                  ty::ty_open(ty) => match ty.sty {
-                      ty::ty_vec(_, None) | ty::ty_str => {
-                          let e1 = const_get_elt(cx, bv, &[0]);
-                          (const_deref_ptr(cx, e1), const_get_elt(cx, bv, &[1]))
-                      },
-                      _ => cx.sess().span_bug(base.span,
-                                              &format!("index-expr base must be a vector \
-                                                       or string type, found {}",
-                                                      ty_to_string(cx.tcx(), bt))[])
-                  },
+                  ty::ty_vec(_, None) | ty::ty_str => {
+                      let e1 = const_get_elt(cx, bv, &[0]);
+                      (const_deref_ptr(cx, e1), const_get_elt(cx, bv, &[1]))
+                  }
                   ty::ty_rptr(_, mt) => match mt.ty.sty {
                       ty::ty_vec(_, Some(u)) => {
                           (const_deref_ptr(cx, bv), C_uint(cx, u))
@@ -494,12 +601,12 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                       _ => cx.sess().span_bug(base.span,
                                               &format!("index-expr base must be a vector \
                                                        or string type, found {}",
-                                                      ty_to_string(cx.tcx(), bt))[])
+                                                      ty_to_string(cx.tcx(), bt)))
                   },
                   _ => cx.sess().span_bug(base.span,
                                           &format!("index-expr base must be a vector \
                                                    or string type, found {}",
-                                                  ty_to_string(cx.tcx(), bt))[])
+                                                  ty_to_string(cx.tcx(), bt)))
               };
 
               let len = llvm::LLVMConstIntGetZExtValue(len) as u64;
@@ -518,8 +625,10 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                   // pass. Reporting here is a bit late.
                   cx.sess().span_err(e.span,
                                      "const index-expr is out of bounds");
+                  C_undef(type_of::type_of(cx, bt).element_type())
+              } else {
+                  const_get_elt(cx, arr, &[iv as c_uint])
               }
-              const_get_elt(cx, arr, &[iv as c_uint])
           }
           ast::ExprCast(ref base, _) => {
             let llty = type_of::type_of(cx, ety);
@@ -527,8 +636,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             if expr::cast_is_noop(basety, ety) {
                 return v;
             }
-            return match (expr::cast_type_kind(cx.tcx(), basety),
-                           expr::cast_type_kind(cx.tcx(), ety)) {
+            match (expr::cast_type_kind(cx.tcx(), basety),
+                   expr::cast_type_kind(cx.tcx(), ety)) {
 
               (expr::cast_integral, expr::cast_integral) => {
                 let s = ty::type_is_signed(basety) as Bool;
@@ -595,15 +704,15 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                       _ => break,
                   }
               }
-              let opt_def = cx.tcx().def_map.borrow().get(&cur.id).cloned();
+              let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def());
               if let Some(def::DefStatic(def_id, _)) = opt_def {
-                  return get_static_val(cx, def_id, ety);
+                  get_static_val(cx, def_id, ety)
+              } else {
+                  // If this isn't the address of a static, then keep going through
+                  // normal constant evaluation.
+                  let (v, _) = const_expr(cx, &**sub, param_substs);
+                  addr_of(cx, v, "ref", e.id)
               }
-
-              // If this isn't the address of a static, then keep going through
-              // normal constant evaluation.
-              let (v, _) = const_expr(cx, &**sub, param_substs);
-              addr_of(cx, v, "ref", e.id)
           }
           ast::ExprAddrOf(ast::MutMutable, ref sub) => {
               let (v, _) = const_expr(cx, &**sub, param_substs);
@@ -663,11 +772,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
           ast::ExprRepeat(ref elem, ref count) => {
             let unit_ty = ty::sequence_element_type(cx.tcx(), ety);
             let llunitty = type_of::type_of(cx, unit_ty);
-            let n = match const_eval::eval_const_expr(cx.tcx(), &**count) {
-                const_eval::const_int(i)  => i as uint,
-                const_eval::const_uint(i) => i as uint,
-                _ => cx.sess().span_bug(count.span, "count must be integral const expression.")
-            };
+            let n = ty::eval_repeat_count(cx.tcx(), count);
             let unit_val = const_expr(cx, &**elem, param_substs).0;
             let vs: Vec<_> = repeat(unit_val).take(n).collect();
             if val_ty(unit_val) != llunitty {
@@ -676,10 +781,10 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 C_array(llunitty, &vs[..])
             }
           }
-          ast::ExprPath(_) | ast::ExprQPath(_) => {
-            let def = cx.tcx().def_map.borrow()[e.id];
+          ast::ExprPath(..) => {
+            let def = cx.tcx().def_map.borrow().get(&e.id).unwrap().full_def();
             match def {
-                def::DefFn(..) | def::DefStaticMethod(..) | def::DefMethod(..) => {
+                def::DefFn(..) | def::DefMethod(..) => {
                     expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val
                 }
                 def::DefConst(def_id) => {
@@ -714,7 +819,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             }
           }
           ast::ExprCall(ref callee, ref args) => {
-              let opt_def = cx.tcx().def_map.borrow().get(&callee.id).cloned();
+              let opt_def = cx.tcx().def_map.borrow().get(&callee.id).map(|d| d.full_def());
               let arg_vals = map_list(&args[..]);
               match opt_def {
                   Some(def::DefStruct(_)) => {
@@ -753,7 +858,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
           }
           _ => cx.sess().span_bug(e.span,
                   "bad constant expression type in consts::const_expr")
-        };
+        }
     }
 }
 
@@ -763,7 +868,7 @@ pub fn trans_static(ccx: &CrateContext, m: ast::Mutability, id: ast::NodeId) {
         let g = base::get_item_val(ccx, id);
         // At this point, get_item_val has already translated the
         // constant's initializer to determine its LLVM type.
-        let v = ccx.static_values().borrow()[id].clone();
+        let v = ccx.static_values().borrow().get(&id).unwrap().clone();
         // boolean SSA values are i1, but they have to be stored in i8 slots,
         // otherwise some LLVM optimization passes don't work as expected
         let v = if llvm::LLVMTypeOf(v) == Type::i1(ccx).to_ref() {
index eb07bdb7ba11bb6a860a2c71a1b462f440d196e5..8919a386a45fb0ac1182174d8dbc65301f9f0318 100644 (file)
@@ -10,7 +10,7 @@
 
 use llvm;
 use llvm::{ContextRef, ModuleRef, ValueRef, BuilderRef};
-use llvm::{TargetData};
+use llvm::TargetData;
 use llvm::mk_target_data;
 use metadata::common::LinkMeta;
 use middle::def::ExportMap;
@@ -18,7 +18,7 @@ use middle::traits;
 use trans::adt;
 use trans::base;
 use trans::builder::Builder;
-use trans::common::{ExternMap,tydesc_info,BuilderRef_res};
+use trans::common::{ExternMap,BuilderRef_res};
 use trans::debuginfo;
 use trans::monomorphize::MonoId;
 use trans::type_::{Type, TypeNames};
@@ -38,18 +38,17 @@ use syntax::ast;
 use syntax::parse::token::InternedString;
 
 pub struct Stats {
-    pub n_static_tydescs: Cell<uint>,
-    pub n_glues_created: Cell<uint>,
-    pub n_null_glues: Cell<uint>,
-    pub n_real_glues: Cell<uint>,
-    pub n_fns: Cell<uint>,
-    pub n_monos: Cell<uint>,
-    pub n_inlines: Cell<uint>,
-    pub n_closures: Cell<uint>,
-    pub n_llvm_insns: Cell<uint>,
-    pub llvm_insns: RefCell<FnvHashMap<String, uint>>,
+    pub n_glues_created: Cell<usize>,
+    pub n_null_glues: Cell<usize>,
+    pub n_real_glues: Cell<usize>,
+    pub n_fns: Cell<usize>,
+    pub n_monos: Cell<usize>,
+    pub n_inlines: Cell<usize>,
+    pub n_closures: Cell<usize>,
+    pub n_llvm_insns: Cell<usize>,
+    pub llvm_insns: RefCell<FnvHashMap<String, usize>>,
     // (ident, llvm-instructions)
-    pub fn_stats: RefCell<Vec<(String, uint)> >,
+    pub fn_stats: RefCell<Vec<(String, usize)> >,
 }
 
 /// The shared portion of a `CrateContext`.  There is one `SharedCrateContext`
@@ -69,6 +68,8 @@ pub struct SharedCrateContext<'tcx> {
     symbol_hasher: RefCell<Sha256>,
     tcx: ty::ctxt<'tcx>,
     stats: Stats,
+    check_overflow: bool,
+    check_drop_flag_for_sanity: bool,
 
     available_monomorphizations: RefCell<FnvHashSet<String>>,
     available_drop_glues: RefCell<FnvHashMap<Ty<'tcx>, String>>,
@@ -88,10 +89,6 @@ pub struct LocalCrateContext<'tcx> {
     needs_unwind_cleanup_cache: RefCell<FnvHashMap<Ty<'tcx>, bool>>,
     fn_pointer_shims: RefCell<FnvHashMap<Ty<'tcx>, ValueRef>>,
     drop_glues: RefCell<FnvHashMap<Ty<'tcx>, ValueRef>>,
-    tydescs: RefCell<FnvHashMap<Ty<'tcx>, Rc<tydesc_info<'tcx>>>>,
-    /// Set when running emit_tydescs to enforce that no more tydescs are
-    /// created.
-    finished_tydescs: Cell<bool>,
     /// Track mapping of external ids to local items imported for inlining
     external: RefCell<DefIdMap<Option<ast::NodeId>>>,
     /// Backwards version of the `external` map (inlined items to where they
@@ -99,9 +96,9 @@ pub struct LocalCrateContext<'tcx> {
     external_srcs: RefCell<NodeMap<ast::DefId>>,
     /// Cache instances of monomorphized functions
     monomorphized: RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>>,
-    monomorphizing: RefCell<DefIdMap<uint>>,
+    monomorphizing: RefCell<DefIdMap<usize>>,
     /// Cache generated vtables
-    vtables: RefCell<FnvHashMap<(Ty<'tcx>, ty::PolyTraitRef<'tcx>), ValueRef>>,
+    vtables: RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>>,
     /// Cache of constant strings,
     const_cstr_cache: RefCell<FnvHashMap<InternedString, ValueRef>>,
 
@@ -153,7 +150,7 @@ pub struct LocalCrateContext<'tcx> {
     /// Number of LLVM instructions translated into this `LocalCrateContext`.
     /// This is used to perform some basic load-balancing to keep all LLVM
     /// contexts around the same size.
-    n_llvm_insns: Cell<uint>,
+    n_llvm_insns: Cell<usize>,
 
     trait_cache: RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>,
                                     traits::Vtable<'tcx, ()>>>,
@@ -164,12 +161,12 @@ pub struct CrateContext<'a, 'tcx: 'a> {
     local: &'a LocalCrateContext<'tcx>,
     /// The index of `local` in `shared.local_ccxs`.  This is used in
     /// `maybe_iter(true)` to identify the original `LocalCrateContext`.
-    index: uint,
+    index: usize,
 }
 
 pub struct CrateContextIterator<'a, 'tcx: 'a> {
     shared: &'a SharedCrateContext<'tcx>,
-    index: uint,
+    index: usize,
 }
 
 impl<'a, 'tcx> Iterator for CrateContextIterator<'a,'tcx> {
@@ -194,9 +191,9 @@ impl<'a, 'tcx> Iterator for CrateContextIterator<'a,'tcx> {
 /// The iterator produced by `CrateContext::maybe_iter`.
 pub struct CrateContextMaybeIterator<'a, 'tcx: 'a> {
     shared: &'a SharedCrateContext<'tcx>,
-    index: uint,
+    index: usize,
     single: bool,
-    origin: uint,
+    origin: usize,
 }
 
 impl<'a, 'tcx> Iterator for CrateContextMaybeIterator<'a, 'tcx> {
@@ -240,12 +237,14 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
 
 impl<'tcx> SharedCrateContext<'tcx> {
     pub fn new(crate_name: &str,
-               local_count: uint,
+               local_count: usize,
                tcx: ty::ctxt<'tcx>,
                export_map: ExportMap,
                symbol_hasher: Sha256,
                link_meta: LinkMeta,
-               reachable: NodeSet)
+               reachable: NodeSet,
+               check_overflow: bool,
+               check_drop_flag_for_sanity: bool)
                -> SharedCrateContext<'tcx> {
         let (metadata_llcx, metadata_llmod) = unsafe {
             create_context_and_module(&tcx.sess, "metadata")
@@ -262,7 +261,6 @@ impl<'tcx> SharedCrateContext<'tcx> {
             symbol_hasher: RefCell::new(symbol_hasher),
             tcx: tcx,
             stats: Stats {
-                n_static_tydescs: Cell::new(0),
                 n_glues_created: Cell::new(0),
                 n_null_glues: Cell::new(0),
                 n_real_glues: Cell::new(0),
@@ -274,6 +272,8 @@ impl<'tcx> SharedCrateContext<'tcx> {
                 llvm_insns: RefCell::new(FnvHashMap()),
                 fn_stats: RefCell::new(Vec::new()),
             },
+            check_overflow: check_overflow,
+            check_drop_flag_for_sanity: check_drop_flag_for_sanity,
             available_monomorphizations: RefCell::new(FnvHashSet()),
             available_drop_glues: RefCell::new(FnvHashMap()),
         };
@@ -302,7 +302,7 @@ impl<'tcx> SharedCrateContext<'tcx> {
         }
     }
 
-    pub fn get_ccx<'a>(&'a self, index: uint) -> CrateContext<'a, 'tcx> {
+    pub fn get_ccx<'a>(&'a self, index: usize) -> CrateContext<'a, 'tcx> {
         CrateContext {
             shared: self,
             local: &self.local_ccxs[index],
@@ -378,7 +378,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
                                           .target
                                           .target
                                           .data_layout
-                                          []);
+                                          );
 
             let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo {
                 Some(debuginfo::CrateDebugContext::new(llmod))
@@ -396,8 +396,6 @@ impl<'tcx> LocalCrateContext<'tcx> {
                 needs_unwind_cleanup_cache: RefCell::new(FnvHashMap()),
                 fn_pointer_shims: RefCell::new(FnvHashMap()),
                 drop_glues: RefCell::new(FnvHashMap()),
-                tydescs: RefCell::new(FnvHashMap()),
-                finished_tydescs: Cell::new(false),
                 external: RefCell::new(DefIdMap()),
                 external_srcs: RefCell::new(NodeMap()),
                 monomorphized: RefCell::new(FnvHashMap()),
@@ -439,8 +437,6 @@ impl<'tcx> LocalCrateContext<'tcx> {
                 str_slice_ty.set_struct_body(&[Type::i8p(&ccx), ccx.int_type()], false);
                 ccx.tn().associate_type("str_slice", &str_slice_ty);
 
-                ccx.tn().associate_type("tydesc", &Type::tydesc(&ccx, str_slice_ty));
-
                 if ccx.sess().count_llvm_insns() {
                     base::init_insn_ctxt()
                 }
@@ -463,7 +459,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
         CrateContext {
             shared: shared,
             local: self,
-            index: -1 as uint,
+            index: !0 as usize,
         }
     }
 }
@@ -516,10 +512,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         self.local.builder.b
     }
 
-    pub fn tydesc_type(&self) -> Type {
-        self.local.tn.find_type("tydesc").unwrap()
-    }
-
     pub fn get_intrinsic(&self, key: & &'static str) -> ValueRef {
         if let Some(v) = self.intrinsics().borrow().get(key).cloned() {
             return v;
@@ -587,14 +579,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.local.drop_glues
     }
 
-    pub fn tydescs<'a>(&'a self) -> &'a RefCell<FnvHashMap<Ty<'tcx>, Rc<tydesc_info<'tcx>>>> {
-        &self.local.tydescs
-    }
-
-    pub fn finished_tydescs<'a>(&'a self) -> &'a Cell<bool> {
-        &self.local.finished_tydescs
-    }
-
     pub fn external<'a>(&'a self) -> &'a RefCell<DefIdMap<Option<ast::NodeId>>> {
         &self.local.external
     }
@@ -607,12 +591,11 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.local.monomorphized
     }
 
-    pub fn monomorphizing<'a>(&'a self) -> &'a RefCell<DefIdMap<uint>> {
+    pub fn monomorphizing<'a>(&'a self) -> &'a RefCell<DefIdMap<usize>> {
         &self.local.monomorphizing
     }
 
-    pub fn vtables<'a>(&'a self) -> &'a RefCell<FnvHashMap<(Ty<'tcx>, ty::PolyTraitRef<'tcx>),
-                                                            ValueRef>> {
+    pub fn vtables<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>> {
         &self.local.vtables
     }
 
@@ -731,7 +714,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
     /// currently conservatively bounded to 1 << 47 as that is enough to cover the current usable
     /// address space on 64-bit ARMv8 and x86_64.
     pub fn obj_size_bound(&self) -> u64 {
-        match &self.sess().target.target.target_pointer_width[] {
+        match &self.sess().target.target.target_pointer_width[..] {
             "32" => 1 << 31,
             "64" => 1 << 47,
             _ => unreachable!() // error handled by config::build_target_config
@@ -741,7 +724,18 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
     pub fn report_overbig_object(&self, obj: Ty<'tcx>) -> ! {
         self.sess().fatal(
             &format!("the type `{}` is too big for the current architecture",
-                    obj.repr(self.tcx()))[])
+                    obj.repr(self.tcx())))
+    }
+
+    pub fn check_overflow(&self) -> bool {
+        self.shared.check_overflow
+    }
+
+    pub fn check_drop_flag_for_sanity(&self) -> bool {
+        // This controls whether we emit a conditional llvm.debugtrap
+        // guarded on whether the dropflag is one of its (two) valid
+        // values.
+        self.shared.check_drop_flag_for_sanity
     }
 }
 
index 26e12a1af403dac45981d8bd2e4751c9f60fec69..5b1ac88c2089b951113911b16527cba09b547af8 100644 (file)
@@ -12,6 +12,7 @@ use llvm::ValueRef;
 use middle::def;
 use middle::lang_items::{PanicFnLangItem, PanicBoundsCheckFnLangItem};
 use trans::base::*;
+use trans::basic_block::BasicBlock;
 use trans::build::*;
 use trans::callee;
 use trans::cleanup::CleanupMethods;
@@ -39,8 +40,12 @@ pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
     let fcx = cx.fcx;
     debug!("trans_stmt({})", s.repr(cx.tcx()));
 
+    if cx.unreachable.get() {
+        return cx;
+    }
+
     if cx.sess().asm_comments() {
-        add_span_comment(cx, s.span, &s.repr(cx.tcx())[]);
+        add_span_comment(cx, s.span, &s.repr(cx.tcx()));
     }
 
     let mut bcx = cx;
@@ -75,8 +80,13 @@ pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
 pub fn trans_stmt_semi<'blk, 'tcx>(cx: Block<'blk, 'tcx>, e: &ast::Expr)
                                    -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_stmt_semi");
+
+    if cx.unreachable.get() {
+        return cx;
+    }
+
     let ty = expr_ty(cx, e);
-    if type_needs_drop(cx.tcx(), ty) {
+    if cx.fcx.type_needs_drop(ty) {
         expr::trans_to_lvalue(cx, e, "stmt").bcx
     } else {
         expr::trans_into(cx, e, expr::Ignore)
@@ -88,6 +98,11 @@ pub fn trans_block<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                mut dest: expr::Dest)
                                -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_block");
+
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     let fcx = bcx.fcx;
     let mut bcx = bcx;
 
@@ -140,6 +155,11 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
            bcx.to_str(), if_id, bcx.expr_to_string(cond), thn.id,
            dest.to_string(bcx.ccx()));
     let _icx = push_ctxt("trans_if");
+
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     let mut bcx = bcx;
 
     let cond_val = unpack_result!(bcx, expr::trans(bcx, cond).to_llbool());
@@ -213,6 +233,11 @@ pub fn trans_while<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                body: &ast::Block)
                                -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_while");
+
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     let fcx = bcx.fcx;
 
     //            bcx
@@ -256,6 +281,11 @@ pub fn trans_loop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                               body: &ast::Block)
                               -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_loop");
+
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     let fcx = bcx.fcx;
 
     //            bcx
@@ -280,30 +310,36 @@ pub fn trans_loop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     fcx.pop_loop_cleanup_scope(loop_expr.id);
 
+    // If there are no predecessors for the next block, we just translated an endless loop and the
+    // next block is unreachable
+    if BasicBlock(next_bcx_in.llbb).pred_iter().next().is_none() {
+        Unreachable(next_bcx_in);
+    }
+
     return next_bcx_in;
 }
 
 pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                     expr: &ast::Expr,
                                     opt_label: Option<Ident>,
-                                    exit: uint)
+                                    exit: usize)
                                     -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_break_cont");
-    let fcx = bcx.fcx;
 
     if bcx.unreachable.get() {
         return bcx;
     }
 
+    let fcx = bcx.fcx;
+
     // Locate loop that we will break to
     let loop_id = match opt_label {
         None => fcx.top_loop_scope(),
         Some(_) => {
-            match bcx.tcx().def_map.borrow().get(&expr.id) {
-                Some(&def::DefLabel(loop_id)) => loop_id,
-                ref r => {
-                    bcx.tcx().sess.bug(&format!("{:?} in def-map for label",
-                                               r)[])
+            match bcx.tcx().def_map.borrow().get(&expr.id).map(|d| d.full_def())  {
+                Some(def::DefLabel(loop_id)) => loop_id,
+                r => {
+                    bcx.tcx().sess.bug(&format!("{:?} in def-map for label", r))
                 }
             }
         }
@@ -335,6 +371,11 @@ pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                              retval_expr: Option<&ast::Expr>)
                              -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_ret");
+
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     let fcx = bcx.fcx;
     let mut bcx = bcx;
     let dest = match (fcx.llretslotptr.get(), retval_expr) {
@@ -366,11 +407,15 @@ pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let ccx = bcx.ccx();
     let _icx = push_ctxt("trans_fail_value");
 
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     let v_str = C_str_slice(ccx, fail_str);
     let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
-    let filename = token::intern_and_get_ident(&loc.file.name[]);
+    let filename = token::intern_and_get_ident(&loc.file.name);
     let filename = C_str_slice(ccx, filename);
-    let line = C_uint(ccx, loc.line);
+    let line = C_u32(ccx, loc.line as u32);
     let expr_file_line_const = C_struct(ccx, &[v_str, filename, line], false);
     let expr_file_line = consts::addr_of(ccx, expr_file_line_const,
                                          "panic_loc", call_info.id);
@@ -393,13 +438,17 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let ccx = bcx.ccx();
     let _icx = push_ctxt("trans_fail_bounds_check");
 
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
     // Extract the file/line from the span
     let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
-    let filename = token::intern_and_get_ident(&loc.file.name[]);
+    let filename = token::intern_and_get_ident(&loc.file.name);
 
     // Invoke the lang item
     let filename = C_str_slice(ccx,  filename);
-    let line = C_uint(ccx, loc.line);
+    let line = C_u32(ccx, loc.line as u32);
     let file_line_const = C_struct(ccx, &[filename, line], false);
     let file_line = consts::addr_of(ccx, file_line_const,
                                     "panic_bounds_check_loc", call_info.id);
index f4a5ba98b676749f76f42b73fc9d19e2001c8efb..a736a9fe88a1408de7da76457766aa7ca8fa8f52 100644 (file)
@@ -113,7 +113,7 @@ use trans::expr;
 use trans::tvec;
 use trans::type_of;
 use middle::ty::{self, Ty};
-use util::ppaux::{ty_to_string};
+use util::ppaux::ty_to_string;
 
 use std::fmt;
 use syntax::ast;
@@ -122,7 +122,7 @@ use syntax::codemap::DUMMY_SP;
 /// A `Datum` encapsulates the result of evaluating an expression.  It
 /// describes where the value is stored, what Rust type the value has,
 /// whether it is addressed by reference, and so forth. Please refer
-/// the section on datums in `doc.rs` for more details.
+/// the section on datums in `README.md` for more details.
 #[derive(Clone, Copy)]
 pub struct Datum<'tcx, K> {
     /// The llvm value.  This is either a pointer to the Rust value or
@@ -172,7 +172,7 @@ impl Drop for Rvalue {
     fn drop(&mut self) { }
 }
 
-#[derive(Copy, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub enum RvalueMode {
     /// `val` is a pointer to the actual value (and thus has type *T)
     ByRef,
@@ -195,24 +195,18 @@ pub fn immediate_rvalue_bcx<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
 /// Allocates temporary space on the stack using alloca() and returns a by-ref Datum pointing to
 /// it. The memory will be dropped upon exit from `scope`. The callback `populate` should
-/// initialize the memory. If `zero` is true, the space will be zeroed when it is allocated; this
-/// is not necessary unless `bcx` does not dominate the end of `scope`.
+/// initialize the memory.
 pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
                                               ty: Ty<'tcx>,
                                               name: &str,
-                                              zero: bool,
                                               scope: cleanup::ScopeId,
                                               arg: A,
                                               populate: F)
                                               -> DatumBlock<'blk, 'tcx, Lvalue> where
     F: FnOnce(A, Block<'blk, 'tcx>, ValueRef) -> Block<'blk, 'tcx>,
 {
-    let scratch = if zero {
-        alloca_zeroed(bcx, ty, name)
-    } else {
-        let llty = type_of::type_of(bcx.ccx(), ty);
-        alloca(bcx, llty, name)
-    };
+    let llty = type_of::type_of(bcx.ccx(), ty);
+    let scratch = alloca(bcx, llty, name);
 
     // Subtle. Populate the scratch memory *before* scheduling cleanup.
     let bcx = populate(arg, bcx, scratch);
@@ -311,9 +305,10 @@ impl KindOps for Lvalue {
                               val: ValueRef,
                               ty: Ty<'tcx>)
                               -> Block<'blk, 'tcx> {
-        if type_needs_drop(bcx.tcx(), ty) {
-            // cancel cleanup of affine values by zeroing out
-            let () = zero_mem(bcx, val, ty);
+        let _icx = push_ctxt("<Lvalue as KindOps>::post_store");
+        if bcx.fcx.type_needs_drop(ty) {
+            // cancel cleanup of affine values by drop-filling the memory
+            let () = drop_done_fill_mem(bcx, val, ty);
             bcx
         } else {
             bcx
@@ -382,7 +377,7 @@ impl<'tcx> Datum<'tcx, Rvalue> {
 
             ByValue => {
                 lvalue_scratch_datum(
-                    bcx, self.ty, name, false, scope, self,
+                    bcx, self.ty, name, scope, self,
                     |this, bcx, llval| this.store_to(bcx, llval))
             }
         }
@@ -476,15 +471,6 @@ impl<'tcx> Datum<'tcx, Expr> {
             })
     }
 
-    /// Ensures that `self` will get cleaned up, if it is not an lvalue already.
-    pub fn clean<'blk>(self,
-                       bcx: Block<'blk, 'tcx>,
-                       name: &'static str,
-                       expr_id: ast::NodeId)
-                       -> Block<'blk, 'tcx> {
-        self.to_lvalue_datum(bcx, name, expr_id).bcx
-    }
-
     pub fn to_lvalue_datum<'blk>(self,
                                  bcx: Block<'blk, 'tcx>,
                                  name: &str,
@@ -492,8 +478,6 @@ impl<'tcx> Datum<'tcx, Expr> {
                                  -> DatumBlock<'blk, 'tcx, Lvalue> {
         debug!("to_lvalue_datum self: {}", self.to_string(bcx.ccx()));
 
-        assert!(lltype_is_sized(bcx.tcx(), self.ty),
-                "Trying to convert unsized value to lval");
         self.match_kind(
             |l| DatumBlock::new(bcx, l),
             |r| {
@@ -549,15 +533,10 @@ impl<'tcx> Datum<'tcx, Lvalue> {
                                 -> Datum<'tcx, Lvalue> where
         F: FnOnce(ValueRef) -> ValueRef,
     {
-        let val = match self.ty.sty {
-            _ if type_is_sized(bcx.tcx(), self.ty) => gep(self.val),
-            ty::ty_open(_) => {
-                let base = Load(bcx, expr::get_dataptr(bcx, self.val));
-                gep(base)
-            }
-            _ => bcx.tcx().sess.bug(
-                &format!("Unexpected unsized type in get_element: {}",
-                        bcx.ty_to_string(self.ty))[])
+        let val = if type_is_sized(bcx.tcx(), self.ty) {
+            gep(self.val)
+        } else {
+            gep(Load(bcx, expr::get_dataptr(bcx, self.val)))
         };
         Datum {
             val: val,
@@ -566,7 +545,8 @@ impl<'tcx> Datum<'tcx, Lvalue> {
         }
     }
 
-    pub fn get_vec_base_and_len(&self, bcx: Block) -> (ValueRef, ValueRef) {
+    pub fn get_vec_base_and_len<'blk>(&self, bcx: Block<'blk, 'tcx>)
+                                      -> (ValueRef, ValueRef) {
         //! Converts a vector into the slice pair.
 
         tvec::get_base_and_len(bcx, self.val, self.ty)
@@ -662,7 +642,7 @@ impl<'tcx, K: KindOps + fmt::Debug> Datum<'tcx, K> {
     /// scalar-ish (like an int or a pointer) which (1) does not require drop glue and (2) is
     /// naturally passed around by value, and not by reference.
     pub fn to_llscalarish<'blk>(self, bcx: Block<'blk, 'tcx>) -> ValueRef {
-        assert!(!type_needs_drop(bcx.tcx(), self.ty));
+        assert!(!bcx.fcx.type_needs_drop(self.ty));
         assert!(self.appropriate_rvalue_mode(bcx.ccx()) == ByValue);
         if self.kind.is_by_ref() {
             load_ty(bcx, self.val, self.ty)
index fc0129239aac7e9b316749ef013d818c528b7602..2747288b60755c9245156bb496e4278d859e1aef 100644 (file)
@@ -206,16 +206,17 @@ use middle::pat_util;
 use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
 use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
 use util::ppaux;
+use util::common::path2cstr;
 
 use libc::{c_uint, c_longlong};
-use std::ffi::CString;
 use std::cell::{Cell, RefCell};
+use std::ffi::CString;
+use std::path::Path;
 use std::ptr;
 use std::rc::{Rc, Weak};
 use syntax::util::interner::Interner;
 use syntax::codemap::{Span, Pos};
 use syntax::{ast, codemap, ast_util, ast_map, attr};
-use syntax::ast_util::PostExpansionMethod;
 use syntax::parse::token::{self, special_idents};
 
 const DW_LANG_RUST: c_uint = 0x9000;
@@ -286,7 +287,7 @@ impl<'tcx> TypeMap<'tcx> {
                                        metadata: DIType) {
         if self.type_to_metadata.insert(type_, metadata).is_some() {
             cx.sess().bug(&format!("Type metadata for Ty '{}' is already in the TypeMap!",
-                                   ppaux::ty_to_string(cx.tcx(), type_))[]);
+                                   ppaux::ty_to_string(cx.tcx(), type_)));
         }
     }
 
@@ -299,7 +300,7 @@ impl<'tcx> TypeMap<'tcx> {
         if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
             let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id);
             cx.sess().bug(&format!("Type metadata for unique id '{}' is already in the TypeMap!",
-                                  &unique_type_id_str[..])[]);
+                                  &unique_type_id_str[..]));
         }
     }
 
@@ -412,7 +413,7 @@ impl<'tcx> TypeMap<'tcx> {
             ty::ty_vec(inner_type, optional_length) => {
                 match optional_length {
                     Some(len) => {
-                        unique_type_id.push_str(&format!("[{}]", len)[]);
+                        unique_type_id.push_str(&format!("[{}]", len));
                     }
                     None => {
                         unique_type_id.push_str("[]");
@@ -472,7 +473,7 @@ impl<'tcx> TypeMap<'tcx> {
                     }
                 }
             },
-            ty::ty_closure(def_id, _, substs) => {
+            ty::ty_closure(def_id, substs) => {
                 let typer = NormalizingClosureTyper::new(cx.tcx());
                 let closure_ty = typer.closure_type(def_id, substs);
                 self.get_unique_type_id_of_closure_type(cx,
@@ -481,8 +482,8 @@ impl<'tcx> TypeMap<'tcx> {
             },
             _ => {
                 cx.sess().bug(&format!("get_unique_type_id_of_type() - unexpected type: {}, {:?}",
-                                      &ppaux::ty_to_string(cx.tcx(), type_)[],
-                                      type_.sty)[])
+                                      &ppaux::ty_to_string(cx.tcx(), type_),
+                                      type_.sty))
             }
         };
 
@@ -525,7 +526,7 @@ impl<'tcx> TypeMap<'tcx> {
 
             output.push_str(crate_hash.as_str());
             output.push_str("/");
-            output.push_str(&format!("{:x}", def_id.node)[]);
+            output.push_str(&format!("{:x}", def_id.node));
 
             // Maybe check that there is no self type here.
 
@@ -600,7 +601,7 @@ impl<'tcx> TypeMap<'tcx> {
                                               -> UniqueTypeId {
         let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
         let enum_variant_type_id = format!("{}::{}",
-                                           &self.get_unique_type_id_as_string(enum_type_id)[],
+                                           &self.get_unique_type_id_as_string(enum_type_id),
                                            variant_name);
         let interner_key = self.unique_id_interner.intern(Rc::new(enum_variant_type_id));
         UniqueTypeId(interner_key)
@@ -693,8 +694,9 @@ impl FunctionDebugContext {
 struct FunctionDebugContextData {
     scope_map: RefCell<NodeMap<DIScope>>,
     fn_metadata: DISubprogram,
-    argument_counter: Cell<uint>,
+    argument_counter: Cell<usize>,
     source_locations_enabled: Cell<bool>,
+    source_location_override: Cell<bool>,
 }
 
 enum VariableAccess<'a> {
@@ -706,7 +708,7 @@ enum VariableAccess<'a> {
 }
 
 enum VariableKind {
-    ArgumentVariable(uint /*index*/),
+    ArgumentVariable(usize /*index*/),
     LocalVariable,
     CapturedVariable,
 }
@@ -783,19 +785,19 @@ pub fn create_global_var_metadata(cx: &CrateContext,
                                          create_global_var_metadata() -
                                          Captured var-id refers to \
                                          unexpected ast_item variant: {:?}",
-                                        var_item)[])
+                                        var_item))
                 }
             }
         },
         _ => cx.sess().bug(&format!("debuginfo::create_global_var_metadata() \
                                     - Captured var-id refers to unexpected \
                                     ast_map variant: {:?}",
-                                   var_item)[])
+                                   var_item))
     };
 
     let (file_metadata, line_number) = if span != codemap::DUMMY_SP {
         let loc = span_start(cx, span);
-        (file_metadata(cx, &loc.file.name[]), loc.line as c_uint)
+        (file_metadata(cx, &loc.file.name), loc.line as c_uint)
     } else {
         (UNKNOWN_FILE_METADATA, UNKNOWN_LINE_NUMBER)
     };
@@ -847,7 +849,7 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
             None => {
                 bcx.sess().span_bug(span,
                     &format!("no entry in lllocals table for {}",
-                            node_id)[]);
+                            node_id));
             }
         };
 
@@ -874,7 +876,7 @@ pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
 pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                 node_id: ast::NodeId,
                                                 env_pointer: ValueRef,
-                                                env_index: uint,
+                                                env_index: usize,
                                                 captured_by_ref: bool,
                                                 span: Span) {
     if bcx.unreachable.get() ||
@@ -903,7 +905,7 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                 "debuginfo::create_captured_var_metadata() - \
                                  Captured var-id refers to unexpected \
                                  ast_map variant: {:?}",
-                                 ast_item)[]);
+                                 ast_item));
                 }
             }
         }
@@ -913,7 +915,7 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                         &format!("debuginfo::create_captured_var_metadata() - \
                                  Captured var-id refers to unexpected \
                                  ast_map variant: {:?}",
-                                ast_item)[]);
+                                ast_item));
         }
     };
 
@@ -1025,7 +1027,7 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
             None => {
                 bcx.sess().span_bug(span,
                     &format!("no entry in lllocals table for {}",
-                            node_id)[]);
+                            node_id));
             }
         };
 
@@ -1174,6 +1176,12 @@ pub fn set_source_location(fcx: &FunctionContext,
             return;
         }
         FunctionDebugContext::RegularContext(box ref function_debug_context) => {
+            if function_debug_context.source_location_override.get() {
+                // Just ignore any attempts to set a new debug location while
+                // the override is active.
+                return;
+            }
+
             let cx = fcx.ccx;
 
             debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
@@ -1192,6 +1200,35 @@ pub fn set_source_location(fcx: &FunctionContext,
     }
 }
 
+/// This function makes sure that all debug locations emitted while executing
+/// `wrapped_function` are set to the given `debug_loc`.
+pub fn with_source_location_override<F, R>(fcx: &FunctionContext,
+                                           debug_loc: DebugLoc,
+                                           wrapped_function: F) -> R
+    where F: FnOnce() -> R
+{
+    match fcx.debug_context {
+        FunctionDebugContext::DebugInfoDisabled => {
+            wrapped_function()
+        }
+        FunctionDebugContext::FunctionWithoutDebugInfo => {
+            set_debug_location(fcx.ccx, UnknownLocation);
+            wrapped_function()
+        }
+        FunctionDebugContext::RegularContext(box ref function_debug_context) => {
+            if function_debug_context.source_location_override.get() {
+                wrapped_function()
+            } else {
+                debug_loc.apply(fcx);
+                function_debug_context.source_location_override.set(true);
+                let result = wrapped_function();
+                function_debug_context.source_location_override.set(false);
+                result
+            }
+        }
+    }
+}
+
 /// Clears the current debug location.
 ///
 /// Instructions generated hereafter won't be assigned a source location.
@@ -1254,7 +1291,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
             match item.node {
                 ast::ItemFn(ref fn_decl, _, _, ref generics, ref top_level_block) => {
-                    (item.ident, &**fn_decl, generics, &**top_level_block, item.span, true)
+                    (item.ident, fn_decl, generics, top_level_block, item.span, true)
                 }
                 _ => {
                     cx.sess().span_bug(item.span,
@@ -1262,25 +1299,30 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 }
             }
         }
-        ast_map::NodeImplItem(ref item) => {
-            match **item {
-                ast::MethodImplItem(ref method) => {
-                    if contains_nodebug_attribute(&method.attrs) {
+        ast_map::NodeImplItem(impl_item) => {
+            match impl_item.node {
+                ast::MethodImplItem(ref sig, ref body) => {
+                    if contains_nodebug_attribute(&impl_item.attrs) {
                         return FunctionDebugContext::FunctionWithoutDebugInfo;
                     }
 
-                    (method.pe_ident(),
-                     method.pe_fn_decl(),
-                     method.pe_generics(),
-                     method.pe_body(),
-                     method.span,
+                    (impl_item.ident,
+                     &sig.decl,
+                     &sig.generics,
+                     body,
+                     impl_item.span,
                      true)
                 }
-                ast::TypeImplItem(ref typedef) => {
-                    cx.sess().span_bug(typedef.span,
+                ast::TypeImplItem(_) => {
+                    cx.sess().span_bug(impl_item.span,
                                        "create_function_debug_context() \
                                         called on associated type?!")
                 }
+                ast::MacImplItem(_) => {
+                    cx.sess().span_bug(impl_item.span,
+                                       "create_function_debug_context() \
+                                        called on unexpanded macro?!")
+                }
             }
         }
         ast_map::NodeExpr(ref expr) => {
@@ -1288,11 +1330,11 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                 ast::ExprClosure(_, ref fn_decl, ref top_level_block) => {
                     let name = format!("fn{}", token::gensym("fn"));
                     let name = token::str_to_ident(&name[..]);
-                    (name, &**fn_decl,
+                    (name, fn_decl,
                         // This is not quite right. It should actually inherit
                         // the generics of the enclosing function.
                         &empty_generics,
-                        &**top_level_block,
+                        top_level_block,
                         expr.span,
                         // Don't try to lookup the item path:
                         false)
@@ -1301,25 +1343,25 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                         "create_function_debug_context: expected an expr_fn_block here")
             }
         }
-        ast_map::NodeTraitItem(ref trait_method) => {
-            match **trait_method {
-                ast::ProvidedMethod(ref method) => {
-                    if contains_nodebug_attribute(&method.attrs) {
+        ast_map::NodeTraitItem(trait_item) => {
+            match trait_item.node {
+                ast::MethodTraitItem(ref sig, Some(ref body)) => {
+                    if contains_nodebug_attribute(&trait_item.attrs) {
                         return FunctionDebugContext::FunctionWithoutDebugInfo;
                     }
 
-                    (method.pe_ident(),
-                     method.pe_fn_decl(),
-                     method.pe_generics(),
-                     method.pe_body(),
-                     method.span,
+                    (trait_item.ident,
+                     &sig.decl,
+                     &sig.generics,
+                     body,
+                     trait_item.span,
                      true)
                 }
                 _ => {
                     cx.sess()
                       .bug(&format!("create_function_debug_context: \
                                     unexpected sort of node: {:?}",
-                                    fnitem)[])
+                                    fnitem))
                 }
             }
         }
@@ -1330,7 +1372,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         }
         _ => cx.sess().bug(&format!("create_function_debug_context: \
                                     unexpected sort of node: {:?}",
-                                   fnitem)[])
+                                   fnitem))
     };
 
     // This can be the case for functions inlined from another crate
@@ -1339,7 +1381,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     }
 
     let loc = span_start(cx, span);
-    let file_metadata = file_metadata(cx, &loc.file.name[]);
+    let file_metadata = file_metadata(cx, &loc.file.name);
 
     let function_type_metadata = unsafe {
         let fn_signature = get_function_signature(cx,
@@ -1412,6 +1454,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         fn_metadata: fn_metadata,
         argument_counter: Cell::new(1),
         source_locations_enabled: Cell::new(false),
+        source_location_override: Cell::new(false),
     };
 
 
@@ -1588,20 +1631,13 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
                 cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
                 fallback_path(cx)
             } else {
-                match abs_path.path_relative_from(work_dir) {
+                match abs_path.relative_from(work_dir) {
                     Some(ref p) if p.is_relative() => {
-                        // prepend "./" if necessary
-                        let dotdot = b"..";
-                        let prefix: &[u8] = &[dotdot[0], ::std::old_path::SEP_BYTE];
-                        let mut path_bytes = p.as_vec().to_vec();
-
-                        if &path_bytes[..2] != prefix &&
-                           &path_bytes[..2] != dotdot {
-                            path_bytes.insert(0, prefix[0]);
-                            path_bytes.insert(1, prefix[1]);
+                        if p.starts_with(Path::new("./")) {
+                            path2cstr(p)
+                        } else {
+                            path2cstr(&Path::new(".").join(p))
                         }
-
-                        CString::new(path_bytes).unwrap()
                     }
                     _ => fallback_path(cx)
                 }
@@ -1614,7 +1650,7 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
                            (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
 
     let compile_unit_name = compile_unit_name.as_ptr();
-    let work_dir = CString::new(work_dir.as_vec()).unwrap();
+    let work_dir = path2cstr(&work_dir);
     let producer = CString::new(producer).unwrap();
     let flags = "\0";
     let split_name = "\0";
@@ -1659,7 +1695,7 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     };
 
     let name = CString::new(name.as_bytes()).unwrap();
-    match (variable_access, [].as_slice()) {
+    match (variable_access, &[][..]) {
         (DirectVariable { alloca }, address_operations) |
         (IndirectVariable {alloca, address_operations}, _) => {
             let metadata = unsafe {
@@ -1716,7 +1752,7 @@ fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
     debug!("file_metadata: {}", full_path);
 
     // FIXME (#9639): This needs to handle non-utf8 paths
-    let work_dir = cx.sess().working_dir.as_str().unwrap();
+    let work_dir = cx.sess().working_dir.to_str().unwrap();
     let file_name =
         if full_path.starts_with(work_dir) {
             &full_path[work_dir.len() + 1..full_path.len()]
@@ -1751,7 +1787,7 @@ fn scope_metadata(fcx: &FunctionContext,
 
             fcx.ccx.sess().span_bug(error_reporting_span,
                 &format!("debuginfo: Could not find scope info for node {:?}",
-                        node)[]);
+                        node));
         }
     }
 }
@@ -1778,14 +1814,14 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         ty::ty_bool => ("bool".to_string(), DW_ATE_boolean),
         ty::ty_char => ("char".to_string(), DW_ATE_unsigned_char),
         ty::ty_int(int_ty) => match int_ty {
-            ast::TyIs(_) => ("isize".to_string(), DW_ATE_signed),
+            ast::TyIs => ("isize".to_string(), DW_ATE_signed),
             ast::TyI8 => ("i8".to_string(), DW_ATE_signed),
             ast::TyI16 => ("i16".to_string(), DW_ATE_signed),
             ast::TyI32 => ("i32".to_string(), DW_ATE_signed),
             ast::TyI64 => ("i64".to_string(), DW_ATE_signed)
         },
         ty::ty_uint(uint_ty) => match uint_ty {
-            ast::TyUs(_) => ("usize".to_string(), DW_ATE_unsigned),
+            ast::TyUs => ("usize".to_string(), DW_ATE_unsigned),
             ast::TyU8 => ("u8".to_string(), DW_ATE_unsigned),
             ast::TyU16 => ("u16".to_string(), DW_ATE_unsigned),
             ast::TyU32 => ("u32".to_string(), DW_ATE_unsigned),
@@ -1837,7 +1873,7 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 //=-----------------------------------------------------------------------------
 
 enum MemberOffset {
-    FixedMemberOffset { bytes: uint },
+    FixedMemberOffset { bytes: usize },
     // For ComputedMemberOffset, the offset is read from the llvm type definition
     ComputedMemberOffset
 }
@@ -1947,7 +1983,7 @@ impl<'tcx> RecursiveTypeDescription<'tcx> {
                         cx.sess().bug(&format!("Forward declaration of potentially recursive type \
                                               '{}' was not found in TypeMap!",
                                               ppaux::ty_to_string(cx.tcx(), unfinished_type))
-                                      []);
+                                      );
                     }
                 }
 
@@ -1986,7 +2022,7 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> {
         }
 
         let field_size = if self.is_simd {
-            machine::llsize_of_alloc(cx, type_of::type_of(cx, self.fields[0].mt.ty)) as uint
+            machine::llsize_of_alloc(cx, type_of::type_of(cx, self.fields[0].mt.ty)) as usize
         } else {
             0xdeadbeef
         };
@@ -2209,7 +2245,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
                 // DWARF representation of enums uniform.
 
                 // First create a description of the artificial wrapper struct:
-                let non_null_variant = &(*self.variants)[non_null_variant_index as uint];
+                let non_null_variant = &(*self.variants)[non_null_variant_index as usize];
                 let non_null_variant_name = token::get_name(non_null_variant.name);
 
                 // The llvm type and metadata of the pointer
@@ -2254,7 +2290,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
 
                 // Encode the information about the null variant in the union
                 // member's name.
-                let null_variant_index = (1 - non_null_variant_index) as uint;
+                let null_variant_index = (1 - non_null_variant_index) as usize;
                 let null_variant_name = token::get_name((*self.variants)[null_variant_index].name);
                 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
                                                 0,
@@ -2280,7 +2316,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
                     describe_enum_variant(cx,
                                           self.enum_type,
                                           struct_def,
-                                          &*(*self.variants)[nndiscr as uint],
+                                          &*(*self.variants)[nndiscr as usize],
                                           OptimizedDiscriminant,
                                           self.containing_scope,
                                           self.span);
@@ -2295,7 +2331,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
 
                 // Encode the information about the null variant in the union
                 // member's name.
-                let null_variant_index = (1 - nndiscr) as uint;
+                let null_variant_index = (1 - nndiscr) as usize;
                 let null_variant_name = token::get_name((*self.variants)[null_variant_index].name);
                 let discrfield = discrfield.iter()
                                            .skip(1)
@@ -2346,7 +2382,7 @@ impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum EnumDiscriminantInfo {
     RegularDiscriminant(DIType),
     OptimizedDiscriminant,
@@ -2370,7 +2406,7 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                     .iter()
                                     .map(|&t| type_of::type_of(cx, t))
                                     .collect::<Vec<_>>()
-                                    [],
+                                    ,
                       struct_def.packed);
     // Could do some consistency checks here: size, align, field count, discr type
 
@@ -2437,7 +2473,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, enum_def_id);
     let loc = span_start(cx, definition_span);
-    let file_metadata = file_metadata(cx, &loc.file.name[]);
+    let file_metadata = file_metadata(cx, &loc.file.name);
 
     let variants = ty::enum_variants(cx.tcx(), enum_def_id);
 
@@ -2624,7 +2660,7 @@ fn set_members_of_composite_type(cx: &CrateContext,
                                         Please use a rustc built with anewer \
                                         version of LLVM.",
                                        llvm_version_major,
-                                       llvm_version_minor)[]);
+                                       llvm_version_minor));
             } else {
                 cx.sess().bug("debuginfo::set_members_of_composite_type() - \
                                Already completed forward declaration re-encountered.");
@@ -2777,7 +2813,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         MemberDescription {
             name: "length".to_string(),
             llvm_type: member_llvm_types[1],
-            type_metadata: type_metadata(cx, cx.tcx().types.uint, span),
+            type_metadata: type_metadata(cx, cx.tcx().types.usize, span),
             offset: ComputedMemberOffset,
             flags: FLAGS_NONE
         },
@@ -2786,7 +2822,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     assert!(member_descriptions.len() == member_llvm_types.len());
 
     let loc = span_start(cx, span);
-    let file_metadata = file_metadata(cx, &loc.file.name[]);
+    let file_metadata = file_metadata(cx, &loc.file.name);
 
     let metadata = composite_type_metadata(cx,
                                            slice_llvm_type,
@@ -2865,7 +2901,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_type);
             cx.sess().bug(&format!("debuginfo: Unexpected trait-object type in \
                                    trait_pointer_metadata(): {}",
-                                   &pp_type_name[..])[]);
+                                   &pp_type_name[..]));
         }
     };
 
@@ -2983,7 +3019,7 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         ty::ty_bare_fn(_, ref barefnty) => {
             subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
         }
-        ty::ty_closure(def_id, _, substs) => {
+        ty::ty_closure(def_id, substs) => {
             let typer = NormalizingClosureTyper::new(cx.tcx());
             let sig = typer.closure_type(def_id, substs).sig;
             subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span)
@@ -3005,7 +3041,7 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         }
         _ => {
             cx.sess().bug(&format!("debuginfo: unexpected type in type_metadata: {:?}",
-                                  sty)[])
+                                  sty))
         }
     };
 
@@ -3070,14 +3106,14 @@ impl MetadataCreationResult {
     }
 }
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 enum InternalDebugLocation {
-    KnownLocation { scope: DIScope, line: uint, col: uint },
+    KnownLocation { scope: DIScope, line: usize, col: usize },
     UnknownLocation
 }
 
 impl InternalDebugLocation {
-    fn new(scope: DIScope, line: uint, col: uint) -> InternalDebugLocation {
+    fn new(scope: DIScope, line: usize, col: usize) -> InternalDebugLocation {
         KnownLocation {
             scope: scope,
             line: line,
@@ -3171,7 +3207,7 @@ fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
 fn assert_type_for_node_id(cx: &CrateContext,
                            node_id: ast::NodeId,
                            error_reporting_span: Span) {
-    if !cx.tcx().node_types.borrow().contains_key(&node_id) {
+    if !cx.tcx().node_types().contains_key(&node_id) {
         cx.sess().span_bug(error_reporting_span,
                            "debuginfo: Could not find type for node id!");
     }
@@ -3248,7 +3284,7 @@ fn create_scope_map(cx: &CrateContext,
     {
         // Create a new lexical scope and push it onto the stack
         let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
-        let file_metadata = file_metadata(cx, &loc.file.name[]);
+        let file_metadata = file_metadata(cx, &loc.file.name);
         let parent_scope = scope_stack.last().unwrap().scope_metadata;
 
         let scope_metadata = unsafe {
@@ -3370,7 +3406,7 @@ fn create_scope_map(cx: &CrateContext,
                     if need_new_scope {
                         // Create a new lexical scope and push it onto the stack
                         let loc = cx.sess().codemap().lookup_char_pos(pat.span.lo);
-                        let file_metadata = file_metadata(cx, &loc.file.name[]);
+                        let file_metadata = file_metadata(cx, &loc.file.name);
                         let parent_scope = scope_stack.last().unwrap().scope_metadata;
 
                         let scope_metadata = unsafe {
@@ -3487,8 +3523,7 @@ fn create_scope_map(cx: &CrateContext,
             ast::ExprLit(_)   |
             ast::ExprBreak(_) |
             ast::ExprAgain(_) |
-            ast::ExprPath(_)  |
-            ast::ExprQPath(_) => {}
+            ast::ExprPath(..) => {}
 
             ast::ExprCast(ref sub_exp, _)     |
             ast::ExprAddrOf(_, ref sub_exp)  |
@@ -3710,12 +3745,12 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         ty::ty_bool              => output.push_str("bool"),
         ty::ty_char              => output.push_str("char"),
         ty::ty_str               => output.push_str("str"),
-        ty::ty_int(ast::TyIs(_))     => output.push_str("isize"),
+        ty::ty_int(ast::TyIs)     => output.push_str("isize"),
         ty::ty_int(ast::TyI8)    => output.push_str("i8"),
         ty::ty_int(ast::TyI16)   => output.push_str("i16"),
         ty::ty_int(ast::TyI32)   => output.push_str("i32"),
         ty::ty_int(ast::TyI64)   => output.push_str("i64"),
-        ty::ty_uint(ast::TyUs(_))    => output.push_str("usize"),
+        ty::ty_uint(ast::TyUs)    => output.push_str("usize"),
         ty::ty_uint(ast::TyU8)   => output.push_str("u8"),
         ty::ty_uint(ast::TyU16)  => output.push_str("u16"),
         ty::ty_uint(ast::TyU32)  => output.push_str("u32"),
@@ -3828,11 +3863,10 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         }
         ty::ty_err |
         ty::ty_infer(_) |
-        ty::ty_open(_) |
         ty::ty_projection(..) |
         ty::ty_param(_) => {
             cx.sess().bug(&format!("debuginfo: Trying to create type name for \
-                unexpected type: {}", ppaux::ty_to_string(cx.tcx(), t))[]);
+                unexpected type: {}", ppaux::ty_to_string(cx.tcx(), t)));
         }
     }
 
@@ -3915,13 +3949,13 @@ impl NamespaceTreeNode {
                 None => {}
             }
             let string = token::get_name(node.name);
-            output.push_str(&format!("{}", string.len())[]);
+            output.push_str(&format!("{}", string.len()));
             output.push_str(&string);
         }
 
         let mut name = String::from_str("_ZN");
         fill_nested(self, &mut name);
-        name.push_str(&format!("{}", item_name.len())[]);
+        name.push_str(&format!("{}", item_name.len()));
         name.push_str(item_name);
         name.push('E');
         name
@@ -3929,7 +3963,7 @@ impl NamespaceTreeNode {
 }
 
 fn crate_root_namespace<'a>(cx: &'a CrateContext) -> &'a str {
-    &cx.link_meta().crate_name[]
+    &cx.link_meta().crate_name
 }
 
 fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTreeNode> {
@@ -4005,7 +4039,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTree
             None => {
                 cx.sess().bug(&format!("debuginfo::namespace_for_item(): \
                                        path too short for {:?}",
-                                      def_id)[]);
+                                      def_id));
             }
         }
     })
@@ -4020,7 +4054,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTree
 /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
 pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx: &CrateContext) {
     if needs_gdb_debug_scripts_section(ccx) {
-        let empty = CString::new(b"").unwrap();
+        let empty = CString::new("").unwrap();
         let gdb_debug_scripts_section_global =
             get_or_insert_gdb_debug_scripts_section_global(ccx);
         unsafe {
index 1af9fa87c6b7d2f6fd7bf31ce2877ebe46ecb36c..5a79aa35bfae175b1eee83da494f2a9ae2563a39 100644 (file)
@@ -72,8 +72,8 @@ use trans::monomorphize;
 use trans::tvec;
 use trans::type_of;
 use middle::ty::{struct_fields, tup_fields};
-use middle::ty::{AdjustDerefRef, AdjustReifyFnPointer, AutoUnsafe};
-use middle::ty::{AutoPtr};
+use middle::ty::{AdjustDerefRef, AdjustReifyFnPointer, AdjustUnsafeFnPointer, AutoUnsafe};
+use middle::ty::AutoPtr;
 use middle::ty::{self, Ty};
 use middle::ty::MethodCall;
 use util::common::indenter;
@@ -82,6 +82,7 @@ use trans::machine::{llsize_of, llsize_of_alloc};
 use trans::type_::Type;
 
 use syntax::{ast, ast_util, codemap};
+use syntax::parse::token::InternedString;
 use syntax::ptr::P;
 use syntax::parse::token;
 use std::iter::repeat;
@@ -93,7 +94,7 @@ use std::rc::Rc;
 // These are passed around by the code generating functions to track the
 // destination of a computation's value.
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum Dest {
     SaveIn(ValueRef),
     Ignore,
@@ -125,7 +126,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         return datum.store_to_dest(bcx, dest, expr.id);
     }
 
-    let qualif = bcx.tcx().const_qualif_map.borrow()[expr.id];
+    let qualif = *bcx.tcx().const_qualif_map.borrow().get(&expr.id).unwrap();
     if !qualif.intersects(check_const::NOT_CONST | check_const::NEEDS_DROP) {
         if !qualif.intersects(check_const::PREFER_IN_PLACE) {
             if let SaveIn(lldest) = dest {
@@ -143,10 +144,10 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             // it prefers in-place instantiation, likely because it contains
             // `[x; N]` somewhere within.
             match expr.node {
-                ast::ExprPath(_) | ast::ExprQPath(_) => {
+                ast::ExprPath(..) => {
                     match bcx.def(expr.id) {
                         def::DefConst(did) => {
-                            let expr = consts::get_const_expr(bcx.ccx(), did, expr);
+                            let const_expr = consts::get_const_expr(bcx.ccx(), did, expr);
                             // Temporarily get cleanup scopes out of the way,
                             // as they require sub-expressions to be contained
                             // inside the current AST scope.
@@ -154,7 +155,13 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                             // can't have destructors.
                             let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(),
                                                       vec![]);
-                            bcx = trans_into(bcx, expr, dest);
+                            // Lock emitted debug locations to the location of
+                            // the constant reference expression.
+                            debuginfo::with_source_location_override(bcx.fcx,
+                                                                     expr.debug_loc(),
+                                                                     || {
+                                bcx = trans_into(bcx, const_expr, dest)
+                            });
                             let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(),
                                                       scopes);
                             assert!(scopes.is_empty());
@@ -202,7 +209,7 @@ pub fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     let mut bcx = bcx;
     let fcx = bcx.fcx;
-    let qualif = bcx.tcx().const_qualif_map.borrow()[expr.id];
+    let qualif = *bcx.tcx().const_qualif_map.borrow().get(&expr.id).unwrap();
     let adjusted_global = !qualif.intersects(check_const::NON_STATIC_BORROWS);
     let global = if !qualif.intersects(check_const::NOT_CONST | check_const::NEEDS_DROP) {
         let global = consts::get_const_expr_as_global(bcx.ccx(), expr, qualif,
@@ -278,24 +285,46 @@ pub fn get_dataptr(bcx: Block, fat_ptr: ValueRef) -> ValueRef {
     GEPi(bcx, fat_ptr, &[0, abi::FAT_PTR_ADDR])
 }
 
+pub fn copy_fat_ptr(bcx: Block, src_ptr: ValueRef, dst_ptr: ValueRef) {
+    Store(bcx, Load(bcx, get_dataptr(bcx, src_ptr)), get_dataptr(bcx, dst_ptr));
+    Store(bcx, Load(bcx, get_len(bcx, src_ptr)), get_len(bcx, dst_ptr));
+}
+
 // Retrieve the information we are losing (making dynamic) in an unsizing
 // adjustment.
-// When making a dtor, we need to do different things depending on the
-// ownership of the object.. mk_ty is a function for turning `unadjusted_ty`
-// into a type to be destructed. If we want to end up with a Box pointer,
-// then mk_ty should make a Box pointer (T -> Box<T>), if we want a
-// borrowed reference then it should be T -> &T.
-pub fn unsized_info<'a, 'tcx, F>(ccx: &CrateContext<'a, 'tcx>,
-                                 kind: &ty::UnsizeKind<'tcx>,
-                                 id: ast::NodeId,
-                                 unadjusted_ty: Ty<'tcx>,
-                                 param_substs: &'tcx subst::Substs<'tcx>,
-                                 mk_ty: F) -> ValueRef where
-    F: FnOnce(Ty<'tcx>) -> Ty<'tcx>,
-{
-    // FIXME(#19596) workaround: `|t| t` causes monomorphization recursion
-    fn identity<T>(t: T) -> T { t }
+//
+// The `unadjusted_val` argument is a bit funny. It is intended
+// for use in an upcast, where the new vtable for an object will
+// be drived from the old one. Hence it is a pointer to the fat
+// pointer.
+pub fn unsized_info_bcx<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                                    kind: &ty::UnsizeKind<'tcx>,
+                                    id: ast::NodeId,
+                                    unadjusted_ty: Ty<'tcx>,
+                                    unadjusted_val: ValueRef, // see above (*)
+                                    param_substs: &'tcx subst::Substs<'tcx>)
+                                    -> ValueRef {
+    unsized_info(
+        bcx.ccx(),
+        kind,
+        id,
+        unadjusted_ty,
+        param_substs,
+        || Load(bcx, GEPi(bcx, unadjusted_val, &[0, abi::FAT_PTR_EXTRA])))
+}
 
+// Same as `unsize_info_bcx`, but does not require a bcx -- instead it
+// takes an extra closure to compute the upcast vtable.
+pub fn unsized_info<'ccx, 'tcx, MK_UPCAST_VTABLE>(
+    ccx: &CrateContext<'ccx, 'tcx>,
+    kind: &ty::UnsizeKind<'tcx>,
+    id: ast::NodeId,
+    unadjusted_ty: Ty<'tcx>,
+    param_substs: &'tcx subst::Substs<'tcx>,
+    mk_upcast_vtable: MK_UPCAST_VTABLE) // see notes above
+    -> ValueRef
+    where MK_UPCAST_VTABLE: FnOnce() -> ValueRef
+{
     debug!("unsized_info(kind={:?}, id={}, unadjusted_ty={})",
            kind, id, unadjusted_ty.repr(ccx.tcx()));
     match kind {
@@ -303,12 +332,11 @@ pub fn unsized_info<'a, 'tcx, F>(ccx: &CrateContext<'a, 'tcx>,
         &ty::UnsizeStruct(box ref k, tp_index) => match unadjusted_ty.sty {
             ty::ty_struct(_, ref substs) => {
                 let ty_substs = substs.types.get_slice(subst::TypeSpace);
-                // The dtor for a field treats it like a value, so mk_ty
-                // should just be the identity function.
-                unsized_info(ccx, k, id, ty_substs[tp_index], param_substs, identity)
+                unsized_info(ccx, k, id, ty_substs[tp_index], param_substs,
+                             mk_upcast_vtable)
             }
             _ => ccx.sess().bug(&format!("UnsizeStruct with bad sty: {}",
-                                         unadjusted_ty.repr(ccx.tcx()))[])
+                                         unadjusted_ty.repr(ccx.tcx())))
         },
         &ty::UnsizeVtable(ty::TyTrait { ref principal, .. }, _) => {
             // Note that we preserve binding levels here:
@@ -319,10 +347,15 @@ pub fn unsized_info<'a, 'tcx, F>(ccx: &CrateContext<'a, 'tcx>,
             let trait_ref = monomorphize::apply_param_substs(ccx.tcx(),
                                                              param_substs,
                                                              &trait_ref);
-            let box_ty = mk_ty(unadjusted_ty);
-            consts::ptrcast(meth::get_vtable(ccx, box_ty, trait_ref, param_substs),
+            consts::ptrcast(meth::get_vtable(ccx, trait_ref, param_substs),
                             Type::vtable_ptr(ccx))
         }
+        &ty::UnsizeUpcast(_) => {
+            // For now, upcasts are limited to changes in marker
+            // traits, and hence never actually require an actual
+            // change to the vtable.
+            mk_upcast_vtable()
+        }
     }
 }
 
@@ -331,7 +364,8 @@ pub fn unsized_info<'a, 'tcx, F>(ccx: &CrateContext<'a, 'tcx>,
 fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                  expr: &ast::Expr,
                                  datum: Datum<'tcx, Expr>)
-                                 -> DatumBlock<'blk, 'tcx, Expr> {
+                                 -> DatumBlock<'blk, 'tcx, Expr>
+{
     let mut bcx = bcx;
     let mut datum = datum;
     let adjustment = match bcx.tcx().adjustments.borrow().get(&expr.id).cloned() {
@@ -340,15 +374,18 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         }
         Some(adj) => { adj }
     };
-    debug!("unadjusted datum for expr {}: {}, adjustment={}",
+    debug!("unadjusted datum for expr {}: {} adjustment={:?}",
            expr.repr(bcx.tcx()),
            datum.to_string(bcx.ccx()),
-           adjustment.repr(bcx.tcx()));
+           adjustment);
     match adjustment {
         AdjustReifyFnPointer(_def_id) => {
             // FIXME(#19925) once fn item types are
             // zero-sized, we'll need to do something here
         }
+        AdjustUnsafeFnPointer => {
+            // purely a type-level thing
+        }
         AdjustDerefRef(ref adj) => {
             let (autoderefs, use_autoref) = match adj.autoref {
                 // Extracting a value from a box counts as a deref, but if we are
@@ -427,7 +464,6 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 debug!("  AutoUnsize");
                 unpack_datum!(bcx, unsize_expr(bcx, expr, datum, k))
             }
-
             &ty::AutoUnsizeUniq(ty::UnsizeLength(len)) => {
                 debug!("  AutoUnsizeUniq(UnsizeLength)");
                 unpack_datum!(bcx, unsize_unique_vec(bcx, expr, datum, len))
@@ -451,37 +487,41 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         let datum_ty = datum.ty;
         let unsized_ty = ty::unsize_ty(tcx, datum_ty, k, expr.span);
         debug!("unsized_ty={}", unsized_ty.repr(bcx.tcx()));
-        let dest_ty = ty::mk_open(tcx, unsized_ty);
-        debug!("dest_ty={}", unsized_ty.repr(bcx.tcx()));
 
-        let info = unsized_info(bcx.ccx(), k, expr.id, datum_ty, bcx.fcx.param_substs,
-                                |t| ty::mk_imm_rptr(tcx, tcx.mk_region(ty::ReStatic), t));
+        let info = unsized_info_bcx(bcx, k, expr.id, datum_ty, datum.val, bcx.fcx.param_substs);
 
         // Arrange cleanup
-        let lval = unpack_datum!(bcx,
-                                 datum.to_lvalue_datum(bcx, "into_fat_ptr", expr.id));
+        let lval = unpack_datum!(bcx, datum.to_lvalue_datum(bcx, "into_fat_ptr", expr.id));
+
         // Compute the base pointer. This doesn't change the pointer value,
         // but merely its type.
-        let base = match *k {
-            ty::UnsizeStruct(..) | ty::UnsizeVtable(..) => {
-                PointerCast(bcx, lval.val, type_of::type_of(bcx.ccx(), unsized_ty).ptr_to())
-            }
-            ty::UnsizeLength(..) => {
-                GEPi(bcx, lval.val, &[0, 0])
-            }
+        let ptr_ty = type_of::in_memory_type_of(bcx.ccx(), unsized_ty).ptr_to();
+        let base = if !type_is_sized(bcx.tcx(), lval.ty) {
+            // Normally, the source is a thin pointer and we are
+            // adding extra info to make a fat pointer. The exception
+            // is when we are upcasting an existing object fat pointer
+            // to use a different vtable. In that case, we want to
+            // load out the original data pointer so we can repackage
+            // it.
+            Load(bcx, get_dataptr(bcx, lval.val))
+        } else {
+            lval.val
         };
+        let base = PointerCast(bcx, base, ptr_ty);
 
-        let scratch = rvalue_scratch_datum(bcx, dest_ty, "__fat_ptr");
-        Store(bcx, base, get_dataptr(bcx, scratch.val));
-        Store(bcx, info, get_len(bcx, scratch.val));
+        let llty = type_of::type_of(bcx.ccx(), unsized_ty);
+        // HACK(eddyb) get around issues with lifetime intrinsics.
+        let scratch = alloca_no_lifetime(bcx, llty, "__fat_ptr");
+        Store(bcx, base, get_dataptr(bcx, scratch));
+        Store(bcx, info, get_len(bcx, scratch));
 
-        DatumBlock::new(bcx, scratch.to_expr_datum())
+        DatumBlock::new(bcx, Datum::new(scratch, unsized_ty, LvalueExpr))
     }
 
     fn unsize_unique_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                      expr: &ast::Expr,
                                      datum: Datum<'tcx, Expr>,
-                                     len: uint)
+                                     len: usize)
                                      -> DatumBlock<'blk, 'tcx, Expr> {
         let mut bcx = bcx;
         let tcx = bcx.tcx();
@@ -524,7 +564,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         let unboxed_ty = match datum_ty.sty {
             ty::ty_uniq(t) => t,
             _ => bcx.sess().bug(&format!("Expected ty_uniq, found {}",
-                                        bcx.ty_to_string(datum_ty))[])
+                                        bcx.ty_to_string(datum_ty)))
         };
         let result_ty = ty::mk_uniq(tcx, ty::unsize_ty(tcx, unboxed_ty, k, expr.span));
 
@@ -539,8 +579,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         let base = PointerCast(bcx, get_dataptr(bcx, scratch.val), llbox_ty.ptr_to());
         bcx = datum.store_to(bcx, base);
 
-        let info = unsized_info(bcx.ccx(), k, expr.id, unboxed_ty, bcx.fcx.param_substs,
-                                |t| ty::mk_uniq(tcx, t));
+        let info = unsized_info_bcx(bcx, k, expr.id, unboxed_ty, base, bcx.fcx.param_substs);
         Store(bcx, info, get_len(bcx, scratch.val));
 
         DatumBlock::new(bcx, scratch.to_expr_datum())
@@ -635,7 +674,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         ast::ExprParen(ref e) => {
             trans(bcx, &**e)
         }
-        ast::ExprPath(_) | ast::ExprQPath(_) => {
+        ast::ExprPath(..) => {
             trans_def(bcx, expr, bcx.def(expr.id))
         }
         ast::ExprField(ref base, ident) => {
@@ -696,7 +735,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 expr.span,
                 &format!("trans_rvalue_datum_unadjusted reached \
                          fall-through case: {:?}",
-                        expr.node)[]);
+                        expr.node));
         }
     }
 }
@@ -705,13 +744,13 @@ fn trans_field<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
                               base: &ast::Expr,
                               get_idx: F)
                               -> DatumBlock<'blk, 'tcx, Expr> where
-    F: FnOnce(&'blk ty::ctxt<'tcx>, &[ty::field<'tcx>]) -> uint,
+    F: FnOnce(&'blk ty::ctxt<'tcx>, &[ty::field<'tcx>]) -> usize,
 {
     let mut bcx = bcx;
     let _icx = push_ctxt("trans_rec_field");
 
     let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, base, "field"));
-    let bare_ty = ty::unopen_type(base_datum.ty);
+    let bare_ty = base_datum.ty;
     let repr = adt::represent_type(bcx.ccx(), bare_ty);
     with_field_tys(bcx.tcx(), bare_ty, None, move |discr, field_tys| {
         let ix = get_idx(bcx.tcx(), field_tys);
@@ -723,7 +762,7 @@ fn trans_field<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
         if type_is_sized(bcx.tcx(), d.ty) {
             DatumBlock { datum: d.to_expr_datum(), bcx: bcx }
         } else {
-            let scratch = rvalue_scratch_datum(bcx, ty::mk_open(bcx.tcx(), d.ty), "");
+            let scratch = rvalue_scratch_datum(bcx, d.ty, "");
             Store(bcx, d.val, get_dataptr(bcx, scratch.val));
             let info = Load(bcx, get_len(bcx, base_datum.val));
             Store(bcx, info, get_len(bcx, scratch.val));
@@ -746,7 +785,7 @@ fn trans_rec_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 /// Translates `base.<idx>`.
 fn trans_rec_tup_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                    base: &ast::Expr,
-                                   idx: uint)
+                                   idx: usize)
                                    -> DatumBlock<'blk, 'tcx, Expr> {
     trans_field(bcx, base, |_, _| idx)
 }
@@ -804,12 +843,12 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                base_datum,
                                                vec![(ix_datum, idx.id)],
                                                Some(SaveIn(scratch.val)),
-                                               true));
+                                               false));
             let datum = scratch.to_expr_datum();
             if type_is_sized(bcx.tcx(), elt_ty) {
                 Datum::new(datum.to_llscalarish(bcx), elt_ty, LvalueExpr)
             } else {
-                Datum::new(datum.val, ty::mk_open(bcx.tcx(), elt_ty), LvalueExpr)
+                Datum::new(datum.val, elt_ty, LvalueExpr)
             }
         }
         None => {
@@ -837,10 +876,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 }
             };
 
-            let vt =
-                tvec::vec_types(bcx,
-                                ty::sequence_element_type(bcx.tcx(),
-                                                          base_datum.ty));
+            let unit_ty = ty::sequence_element_type(bcx.tcx(), base_datum.ty);
 
             let (base, len) = base_datum.get_vec_base_and_len(bcx);
 
@@ -865,8 +901,8 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                      len)
             });
             let elt = InBoundsGEP(bcx, base, &[ix_val]);
-            let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to());
-            Datum::new(elt, vt.unit_ty, LvalueExpr)
+            let elt = PointerCast(bcx, elt, type_of::type_of(ccx, unit_ty).ptr_to());
+            Datum::new(elt, unit_ty, LvalueExpr)
         }
     };
 
@@ -881,7 +917,7 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     let _icx = push_ctxt("trans_def_lvalue");
     match def {
-        def::DefFn(..) | def::DefStaticMethod(..) | def::DefMethod(..) |
+        def::DefFn(..) | def::DefMethod(..) |
         def::DefStruct(_) | def::DefVariant(..) => {
             let datum = trans_def_fn_unadjusted(bcx.ccx(), ref_expr, def,
                                                 bcx.fcx.param_substs);
@@ -980,7 +1016,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let src_datum = unpack_datum!(bcx, trans(bcx, &**src));
             let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &**dst, "assign"));
 
-            if type_needs_drop(bcx.tcx(), dst_datum.ty) {
+            if bcx.fcx.type_needs_drop(dst_datum.ty) {
                 // If there are destructors involved, make sure we
                 // are copying from an rvalue, since that cannot possible
                 // alias an lvalue. We are concerned about code like:
@@ -1020,7 +1056,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 expr.span,
                 &format!("trans_rvalue_stmt_unadjusted reached \
                          fall-through case: {:?}",
-                        expr.node)[]);
+                        expr.node));
         }
     }
 }
@@ -1039,7 +1075,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         ast::ExprParen(ref e) => {
             trans_into(bcx, &**e, dest)
         }
-        ast::ExprPath(_) | ast::ExprQPath(_) => {
+        ast::ExprPath(..) => {
             trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest)
         }
         ast::ExprIf(ref cond, ref thn, ref els) => {
@@ -1113,7 +1149,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             }
         }
         ast::ExprTup(ref args) => {
-            let numbered_fields: Vec<(uint, &ast::Expr)> =
+            let numbered_fields: Vec<(usize, &ast::Expr)> =
                 args.iter().enumerate().map(|(i, arg)| (i, &**arg)).collect();
             trans_adt(bcx,
                       expr_ty(bcx, expr),
@@ -1191,22 +1227,9 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), base,
                                 vec![(idx_datum, idx.id)], Some(dest), true).bcx
         }
-        ast::ExprCast(ref val, _) => {
-            // DPS output mode means this is a trait cast:
-            if ty::type_is_trait(node_id_type(bcx, expr.id)) {
-                let trait_ref =
-                    bcx.tcx().object_cast_map.borrow()
-                                             .get(&expr.id)
-                                             .cloned()
-                                             .unwrap();
-                let trait_ref = bcx.monomorphize(&trait_ref);
-                let datum = unpack_datum!(bcx, trans(bcx, &**val));
-                meth::trans_trait_cast(bcx, datum, expr.id,
-                                       trait_ref, dest)
-            } else {
-                bcx.tcx().sess.span_bug(expr.span,
-                                        "expr_cast of non-trait");
-            }
+        ast::ExprCast(..) => {
+            // Trait casts used to come this way, now they should be coercions.
+            bcx.tcx().sess.span_bug(expr.span, "DPS expr_cast (residual trait cast?)")
         }
         ast::ExprAssignOp(op, ref dst, ref src) => {
             trans_assign_op(bcx, expr, op, &**dst, &**src)
@@ -1216,7 +1239,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 expr.span,
                 &format!("trans_rvalue_dps_unadjusted reached fall-through \
                          case: {:?}",
-                        expr.node)[]);
+                        expr.node));
         }
     }
 }
@@ -1266,7 +1289,7 @@ fn trans_def_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         _ => {
             bcx.tcx().sess.span_bug(ref_expr.span, &format!(
                 "Non-DPS def {:?} referened by {}",
-                def, bcx.node_id_to_string(ref_expr.id))[]);
+                def, bcx.node_id_to_string(ref_expr.id)));
         }
     }
 }
@@ -1281,12 +1304,10 @@ pub fn trans_def_fn_unadjusted<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     match def {
         def::DefFn(did, _) |
         def::DefStruct(did) | def::DefVariant(_, did, _) |
-        def::DefStaticMethod(did, def::FromImpl(_)) |
-        def::DefMethod(did, _, def::FromImpl(_)) => {
+        def::DefMethod(did, def::FromImpl(_)) => {
             callee::trans_fn_ref(ccx, did, ExprId(ref_expr.id), param_substs)
         }
-        def::DefStaticMethod(impl_did, def::FromTrait(trait_did)) |
-        def::DefMethod(impl_did, _, def::FromTrait(trait_did)) => {
+        def::DefMethod(impl_did, def::FromTrait(trait_did)) => {
             meth::trans_static_method_callee(ccx, impl_did,
                                              trait_did, ref_expr.id,
                                              param_substs)
@@ -1295,7 +1316,7 @@ pub fn trans_def_fn_unadjusted<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             ccx.tcx().sess.span_bug(ref_expr.span, &format!(
                     "trans_def_fn_unadjusted invoked on: {:?} for {}",
                     def,
-                    ref_expr.repr(ccx.tcx()))[]);
+                    ref_expr.repr(ccx.tcx())));
         }
     }
 }
@@ -1315,7 +1336,7 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 None => {
                     bcx.sess().bug(&format!(
                         "trans_local_var: no llval for upvar {} found",
-                        nid)[]);
+                        nid));
                 }
             }
         }
@@ -1325,7 +1346,7 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 None => {
                     bcx.sess().bug(&format!(
                         "trans_local_var: no datum for local/arg {} found",
-                        nid)[]);
+                        nid));
                 }
             };
             debug!("take_local(nid={}, v={}, ty={})",
@@ -1335,7 +1356,7 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         _ => {
             bcx.sess().unimpl(&format!(
                 "unsupported def type in trans_local_var: {:?}",
-                def)[]);
+                def));
         }
     }
 }
@@ -1358,7 +1379,7 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>,
         }
 
         ty::ty_tup(ref v) => {
-            op(0, &tup_fields(&v[..])[])
+            op(0, &tup_fields(&v[..]))
         }
 
         ty::ty_enum(_, substs) => {
@@ -1368,14 +1389,13 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>,
                     tcx.sess.bug(&format!(
                         "cannot get field types from the enum type {} \
                          without a node ID",
-                        ty.repr(tcx))[]);
+                        ty.repr(tcx)));
                 }
                 Some(node_id) => {
-                    let def = tcx.def_map.borrow()[node_id].clone();
+                    let def = tcx.def_map.borrow().get(&node_id).unwrap().full_def();
                     match def {
                         def::DefVariant(enum_id, variant_id, _) => {
-                            let variant_info = ty::enum_variant_with_id(
-                                tcx, enum_id, variant_id);
+                            let variant_info = ty::enum_variant_with_id(tcx, enum_id, variant_id);
                             let fields = struct_fields(tcx, variant_id, substs);
                             let fields = monomorphize::normalize_associated_type(tcx, &fields);
                             op(variant_info.disr_val, &fields[..])
@@ -1392,7 +1412,7 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>,
         _ => {
             tcx.sess.bug(&format!(
                 "cannot get field types from the type {}",
-                ty.repr(tcx))[]);
+                ty.repr(tcx)));
         }
     }
 }
@@ -1465,7 +1485,7 @@ pub struct StructBaseInfo<'a, 'tcx> {
     /// The base expression; will be evaluated after all explicit fields.
     expr: &'a ast::Expr,
     /// The indices of fields to copy paired with their types.
-    fields: Vec<(uint, Ty<'tcx>)>
+    fields: Vec<(usize, Ty<'tcx>)>
 }
 
 /// Constructs an ADT instance:
@@ -1479,7 +1499,7 @@ pub struct StructBaseInfo<'a, 'tcx> {
 pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                  ty: Ty<'tcx>,
                                  discr: ty::Disr,
-                                 fields: &[(uint, &ast::Expr)],
+                                 fields: &[(usize, &ast::Expr)],
                                  optbase: Option<StructBaseInfo<'a, 'tcx>>,
                                  dest: Dest,
                                  debug_location: DebugLoc)
@@ -1501,31 +1521,14 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     // panic occur before the ADT as a whole is ready.
     let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
 
-    // First we trans the base, if we have one, to the dest
-    if let Some(base) = optbase {
-        assert_eq!(discr, 0);
-
-        match ty::expr_kind(bcx.tcx(), &*base.expr) {
-            ty::RvalueDpsExpr | ty::RvalueDatumExpr if !type_needs_drop(bcx.tcx(), ty) => {
-                bcx = trans_into(bcx, &*base.expr, SaveIn(addr));
-            },
-            ty::RvalueStmtExpr => bcx.tcx().sess.bug("unexpected expr kind for struct base expr"),
-            _ => {
-                let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &*base.expr, "base"));
-                for &(i, t) in &base.fields {
-                    let datum = base_datum.get_element(
-                            bcx, t, |srcval| adt::trans_field_ptr(bcx, &*repr, srcval, discr, i));
-                    assert!(type_is_sized(bcx.tcx(), datum.ty));
-                    let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
-                    bcx = datum.store_to(bcx, dest);
-                }
-            }
-        }
-    }
-
-    debug_location.apply(bcx.fcx);
-
     if ty::type_is_simd(bcx.tcx(), ty) {
+        // Issue 23112: The original logic appeared vulnerable to same
+        // order-of-eval bug. But, SIMD values are tuple-structs;
+        // i.e. functional record update (FRU) syntax is unavailable.
+        //
+        // To be safe, double-check that we did not get here via FRU.
+        assert!(optbase.is_none());
+
         // This is the constructor of a SIMD type, such types are
         // always primitive machine types and so do not have a
         // destructor or require any clean-up.
@@ -1544,8 +1547,45 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             vec_val = InsertElement(bcx, vec_val, value, position);
         }
         Store(bcx, vec_val, addr);
+    } else if let Some(base) = optbase {
+        // Issue 23112: If there is a base, then order-of-eval
+        // requires field expressions eval'ed before base expression.
+
+        // First, trans field expressions to temporary scratch values.
+        let scratch_vals: Vec<_> = fields.iter().map(|&(i, ref e)| {
+            let datum = unpack_datum!(bcx, trans(bcx, &**e));
+            (i, datum)
+        }).collect();
+
+        debug_location.apply(bcx.fcx);
+
+        // Second, trans the base to the dest.
+        assert_eq!(discr, 0);
+
+        match ty::expr_kind(bcx.tcx(), &*base.expr) {
+            ty::RvalueDpsExpr | ty::RvalueDatumExpr if !bcx.fcx.type_needs_drop(ty) => {
+                bcx = trans_into(bcx, &*base.expr, SaveIn(addr));
+            },
+            ty::RvalueStmtExpr => bcx.tcx().sess.bug("unexpected expr kind for struct base expr"),
+            _ => {
+                let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &*base.expr, "base"));
+                for &(i, t) in &base.fields {
+                    let datum = base_datum.get_element(
+                            bcx, t, |srcval| adt::trans_field_ptr(bcx, &*repr, srcval, discr, i));
+                    assert!(type_is_sized(bcx.tcx(), datum.ty));
+                    let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
+                    bcx = datum.store_to(bcx, dest);
+                }
+            }
+        }
+
+        // Finally, move scratch field values into actual field locations
+        for (i, datum) in scratch_vals.into_iter() {
+            let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
+            bcx = datum.store_to(bcx, dest);
+        }
     } else {
-        // Now, we just overwrite the fields we've explicitly specified
+        // No base means we can write all fields directly in place.
         for &(i, ref e) in fields {
             let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
             let e_ty = expr_ty_adjusted(bcx, &**e);
@@ -1671,7 +1711,7 @@ fn trans_uniq_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 fn ref_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                            lval: Datum<'tcx, Lvalue>)
                            -> DatumBlock<'blk, 'tcx, Expr> {
-    let dest_ty = ty::close_type(bcx.tcx(), lval.ty);
+    let dest_ty = ty::mk_imm_rptr(bcx.tcx(), bcx.tcx().mk_region(ty::ReStatic), lval.ty);
     let scratch = rvalue_scratch_datum(bcx, dest_ty, "__fat_ptr");
     memcpy_ty(bcx, scratch.val, lval.val, scratch.ty);
 
@@ -1685,16 +1725,13 @@ fn trans_addr_of<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("trans_addr_of");
     let mut bcx = bcx;
     let sub_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, subexpr, "addr_of"));
-    match sub_datum.ty.sty {
-        ty::ty_open(_) => {
-            // Opened DST value, close to a fat pointer
-            ref_fat_ptr(bcx, sub_datum)
-        }
-        _ => {
-            // Sized value, ref to a thin pointer
-            let ty = expr_ty(bcx, expr);
-            immediate_rvalue_bcx(bcx, sub_datum.val, ty).to_expr_datumblock()
-        }
+    if !type_is_sized(bcx.tcx(), sub_datum.ty) {
+        // DST lvalue, close to a fat pointer
+        ref_fat_ptr(bcx, sub_datum)
+    } else {
+        // Sized value, ref to a thin pointer
+        let ty = expr_ty(bcx, expr);
+        immediate_rvalue_bcx(bcx, sub_datum.val, ty).to_expr_datumblock()
     }
 }
 
@@ -1720,8 +1757,7 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     };
     let is_float = ty::type_is_fp(intype);
     let is_signed = ty::type_is_signed(intype);
-
-    let rhs = base::cast_shift_expr_rhs(bcx, op, lhs, rhs);
+    let info = expr_info(binop_expr);
 
     let binop_debug_loc = binop_expr.debug_loc();
 
@@ -1730,22 +1766,37 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
       ast::BiAdd => {
         if is_float {
             FAdd(bcx, lhs, rhs, binop_debug_loc)
-        } else {
+        } else if is_simd {
             Add(bcx, lhs, rhs, binop_debug_loc)
+        } else {
+            let (newbcx, res) = with_overflow_check(
+                bcx, OverflowOp::Add, info, lhs_t, lhs, rhs, binop_debug_loc);
+            bcx = newbcx;
+            res
         }
       }
       ast::BiSub => {
         if is_float {
             FSub(bcx, lhs, rhs, binop_debug_loc)
-        } else {
+        } else if is_simd {
             Sub(bcx, lhs, rhs, binop_debug_loc)
+        } else {
+            let (newbcx, res) = with_overflow_check(
+                bcx, OverflowOp::Sub, info, lhs_t, lhs, rhs, binop_debug_loc);
+            bcx = newbcx;
+            res
         }
       }
       ast::BiMul => {
         if is_float {
             FMul(bcx, lhs, rhs, binop_debug_loc)
-        } else {
+        } else if is_simd {
             Mul(bcx, lhs, rhs, binop_debug_loc)
+        } else {
+            let (newbcx, res) = with_overflow_check(
+                bcx, OverflowOp::Mul, info, lhs_t, lhs, rhs, binop_debug_loc);
+            bcx = newbcx;
+            res
         }
       }
       ast::BiDiv => {
@@ -1784,13 +1835,17 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
       ast::BiBitOr => Or(bcx, lhs, rhs, binop_debug_loc),
       ast::BiBitAnd => And(bcx, lhs, rhs, binop_debug_loc),
       ast::BiBitXor => Xor(bcx, lhs, rhs, binop_debug_loc),
-      ast::BiShl => Shl(bcx, lhs, rhs, binop_debug_loc),
+      ast::BiShl => {
+          let (newbcx, res) = with_overflow_check(
+              bcx, OverflowOp::Shl, info, lhs_t, lhs, rhs, binop_debug_loc);
+          bcx = newbcx;
+          res
+      }
       ast::BiShr => {
-        if is_signed {
-            AShr(bcx, lhs, rhs, binop_debug_loc)
-        } else {
-            LShr(bcx, lhs, rhs, binop_debug_loc)
-        }
+          let (newbcx, res) = with_overflow_check(
+              bcx, OverflowOp::Shr, info, lhs_t, lhs, rhs, binop_debug_loc);
+          bcx = newbcx;
+          res
       }
       ast::BiEq | ast::BiNe | ast::BiLt | ast::BiGe | ast::BiLe | ast::BiGt => {
         if is_simd {
@@ -1902,7 +1957,7 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                    dest: Option<Dest>,
                                    autoref: bool)
                                    -> Result<'blk, 'tcx> {
-    let method_ty = (*bcx.tcx().method_map.borrow())[method_call].ty;
+    let method_ty = bcx.tcx().method_map.borrow().get(&method_call).unwrap().ty;
     callee::trans_call_inner(bcx,
                              expr.debug_loc(),
                              monomorphize_type(bcx, method_ty),
@@ -1923,10 +1978,12 @@ fn trans_overloaded_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                          dest: Option<Dest>)
                                          -> Block<'blk, 'tcx> {
     let method_call = MethodCall::expr(expr.id);
-    let method_type = (*bcx.tcx()
-                           .method_map
-                           .borrow())[method_call]
-                           .ty;
+    let method_type = bcx.tcx()
+                         .method_map
+                         .borrow()
+                         .get(&method_call)
+                         .unwrap()
+                         .ty;
     let mut all_args = vec!(callee);
     all_args.extend(args.iter().map(|e| &**e));
     unpack_result!(bcx,
@@ -1981,7 +2038,7 @@ fn float_cast(bcx: Block,
     } else { llsrc };
 }
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum cast_kind {
     cast_pointer,
     cast_integral,
@@ -2027,7 +2084,7 @@ fn trans_imm_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let mut bcx = bcx;
     let ccx = bcx.ccx();
 
-    let t_in = expr_ty(bcx, expr);
+    let t_in = expr_ty_adjusted(bcx, expr);
     let t_out = node_id_type(bcx, id);
     let k_in = cast_type_kind(bcx.tcx(), t_in);
     let k_out = cast_type_kind(bcx.tcx(), t_out);
@@ -2039,7 +2096,8 @@ fn trans_imm_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     // by-value as appropriate given its type:
     let mut datum = unpack_datum!(bcx, trans(bcx, expr));
 
-    if cast_is_noop(datum.ty, t_out) {
+    let datum_ty = monomorphize_type(bcx, datum.ty);
+    if cast_is_noop(datum_ty, t_out) {
         datum.ty = t_out;
         return DatumBlock::new(bcx, datum);
     }
@@ -2097,7 +2155,7 @@ fn trans_imm_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                             t_in.repr(bcx.tcx()),
                                             k_in,
                                             t_out.repr(bcx.tcx()),
-                                            k_out)[])
+                                            k_out))
                 }
             }
         }
@@ -2106,7 +2164,7 @@ fn trans_imm_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                     t_in.repr(bcx.tcx()),
                                     k_in,
                                     t_out.repr(bcx.tcx()),
-                                    k_out)[])
+                                    k_out))
     };
     return immediate_rvalue_bcx(bcx, newval, t_out).to_expr_datumblock();
 }
@@ -2127,7 +2185,7 @@ fn trans_assign_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     // Evaluate LHS (destination), which should be an lvalue
     let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign_op"));
-    assert!(!type_needs_drop(bcx.tcx(), dst_datum.ty));
+    assert!(!bcx.fcx.type_needs_drop(dst_datum.ty));
     let dst_ty = dst_datum.ty;
     let dst = load_ty(bcx, dst_datum.val, dst_datum.ty);
 
@@ -2170,7 +2228,7 @@ fn auto_ref<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 fn deref_multiple<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                               expr: &ast::Expr,
                               datum: Datum<'tcx, Expr>,
-                              times: uint)
+                              times: usize)
                               -> DatumBlock<'blk, 'tcx, Expr> {
     let mut bcx = bcx;
     let mut datum = datum;
@@ -2234,16 +2292,15 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             if type_is_sized(bcx.tcx(), content_ty) {
                 deref_owned_pointer(bcx, expr, datum, content_ty)
             } else {
-                // A fat pointer and an opened DST value have the same
-                // representation just different types. Since there is no
-                // temporary for `*e` here (because it is unsized), we cannot
-                // emulate the sized object code path for running drop glue and
-                // free. Instead, we schedule cleanup for `e`, turning it into
-                // an lvalue.
+                // A fat pointer and a DST lvalue have the same representation
+                // just different types. Since there is no temporary for `*e`
+                // here (because it is unsized), we cannot emulate the sized
+                // object code path for running drop glue and free. Instead,
+                // we schedule cleanup for `e`, turning it into an lvalue.
                 let datum = unpack_datum!(
                     bcx, datum.to_lvalue_datum(bcx, "deref", expr.id));
 
-                let datum = Datum::new(datum.val, ty::mk_open(bcx.tcx(), content_ty), LvalueExpr);
+                let datum = Datum::new(datum.val, content_ty, LvalueExpr);
                 DatumBlock::new(bcx, datum)
             }
         }
@@ -2260,11 +2317,9 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 // owner (or, in the case of *T, by the user).
                 DatumBlock::new(bcx, Datum::new(ptr, content_ty, LvalueExpr))
             } else {
-                // A fat pointer and an opened DST value have the same representation
+                // A fat pointer and a DST lvalue have the same representation
                 // just different types.
-                DatumBlock::new(bcx, Datum::new(datum.val,
-                                                ty::mk_open(bcx.tcx(), content_ty),
-                                                LvalueExpr))
+                DatumBlock::new(bcx, Datum::new(datum.val, content_ty, LvalueExpr))
             }
         }
 
@@ -2272,7 +2327,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             bcx.tcx().sess.span_bug(
                 expr.span,
                 &format!("deref invoked on expr of illegal type {}",
-                        datum.ty.repr(bcx.tcx()))[]);
+                        datum.ty.repr(bcx.tcx())));
         }
     };
 
@@ -2328,3 +2383,247 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         DatumBlock { bcx: bcx, datum: datum }
     }
 }
+
+#[derive(Debug)]
+enum OverflowOp {
+    Add,
+    Sub,
+    Mul,
+    Shl,
+    Shr,
+}
+
+impl OverflowOp {
+    fn codegen_strategy(&self) -> OverflowCodegen {
+        use self::OverflowCodegen::{ViaIntrinsic, ViaInputCheck};
+        match *self {
+            OverflowOp::Add => ViaIntrinsic(OverflowOpViaIntrinsic::Add),
+            OverflowOp::Sub => ViaIntrinsic(OverflowOpViaIntrinsic::Sub),
+            OverflowOp::Mul => ViaIntrinsic(OverflowOpViaIntrinsic::Mul),
+
+            OverflowOp::Shl => ViaInputCheck(OverflowOpViaInputCheck::Shl),
+            OverflowOp::Shr => ViaInputCheck(OverflowOpViaInputCheck::Shr),
+        }
+    }
+}
+
+enum OverflowCodegen {
+    ViaIntrinsic(OverflowOpViaIntrinsic),
+    ViaInputCheck(OverflowOpViaInputCheck),
+}
+
+enum OverflowOpViaInputCheck { Shl, Shr, }
+
+#[derive(Debug)]
+enum OverflowOpViaIntrinsic { Add, Sub, Mul, }
+
+impl OverflowOpViaIntrinsic {
+    fn to_intrinsic<'blk, 'tcx>(&self, bcx: Block<'blk, 'tcx>, lhs_ty: Ty) -> ValueRef {
+        let name = self.to_intrinsic_name(bcx.tcx(), lhs_ty);
+        bcx.ccx().get_intrinsic(&name)
+    }
+    fn to_intrinsic_name(&self, tcx: &ty::ctxt, ty: Ty) -> &'static str {
+        use syntax::ast::IntTy::*;
+        use syntax::ast::UintTy::*;
+        use middle::ty::{ty_int, ty_uint};
+
+        let new_sty = match ty.sty {
+            ty_int(TyIs) => match &tcx.sess.target.target.target_pointer_width[..] {
+                "32" => ty_int(TyI32),
+                "64" => ty_int(TyI64),
+                _ => panic!("unsupported target word size")
+            },
+            ty_uint(TyUs) => match &tcx.sess.target.target.target_pointer_width[..] {
+                "32" => ty_uint(TyU32),
+                "64" => ty_uint(TyU64),
+                _ => panic!("unsupported target word size")
+            },
+            ref t @ ty_uint(_) | ref t @ ty_int(_) => t.clone(),
+            _ => panic!("tried to get overflow intrinsic for {:?} applied to non-int type",
+                        *self)
+        };
+
+        match *self {
+            OverflowOpViaIntrinsic::Add => match new_sty {
+                ty_int(TyI8) => "llvm.sadd.with.overflow.i8",
+                ty_int(TyI16) => "llvm.sadd.with.overflow.i16",
+                ty_int(TyI32) => "llvm.sadd.with.overflow.i32",
+                ty_int(TyI64) => "llvm.sadd.with.overflow.i64",
+
+                ty_uint(TyU8) => "llvm.uadd.with.overflow.i8",
+                ty_uint(TyU16) => "llvm.uadd.with.overflow.i16",
+                ty_uint(TyU32) => "llvm.uadd.with.overflow.i32",
+                ty_uint(TyU64) => "llvm.uadd.with.overflow.i64",
+
+                _ => unreachable!(),
+            },
+            OverflowOpViaIntrinsic::Sub => match new_sty {
+                ty_int(TyI8) => "llvm.ssub.with.overflow.i8",
+                ty_int(TyI16) => "llvm.ssub.with.overflow.i16",
+                ty_int(TyI32) => "llvm.ssub.with.overflow.i32",
+                ty_int(TyI64) => "llvm.ssub.with.overflow.i64",
+
+                ty_uint(TyU8) => "llvm.usub.with.overflow.i8",
+                ty_uint(TyU16) => "llvm.usub.with.overflow.i16",
+                ty_uint(TyU32) => "llvm.usub.with.overflow.i32",
+                ty_uint(TyU64) => "llvm.usub.with.overflow.i64",
+
+                _ => unreachable!(),
+            },
+            OverflowOpViaIntrinsic::Mul => match new_sty {
+                ty_int(TyI8) => "llvm.smul.with.overflow.i8",
+                ty_int(TyI16) => "llvm.smul.with.overflow.i16",
+                ty_int(TyI32) => "llvm.smul.with.overflow.i32",
+                ty_int(TyI64) => "llvm.smul.with.overflow.i64",
+
+                ty_uint(TyU8) => "llvm.umul.with.overflow.i8",
+                ty_uint(TyU16) => "llvm.umul.with.overflow.i16",
+                ty_uint(TyU32) => "llvm.umul.with.overflow.i32",
+                ty_uint(TyU64) => "llvm.umul.with.overflow.i64",
+
+                _ => unreachable!(),
+            },
+        }
+    }
+
+    fn build_intrinsic_call<'blk, 'tcx>(&self, bcx: Block<'blk, 'tcx>,
+                                        info: NodeIdAndSpan,
+                                        lhs_t: Ty<'tcx>, lhs: ValueRef,
+                                        rhs: ValueRef,
+                                        binop_debug_loc: DebugLoc)
+                                        -> (Block<'blk, 'tcx>, ValueRef) {
+        let llfn = self.to_intrinsic(bcx, lhs_t);
+
+        let val = Call(bcx, llfn, &[lhs, rhs], None, binop_debug_loc);
+        let result = ExtractValue(bcx, val, 0); // iN operation result
+        let overflow = ExtractValue(bcx, val, 1); // i1 "did it overflow?"
+
+        let cond = ICmp(bcx, llvm::IntEQ, overflow, C_integral(Type::i1(bcx.ccx()), 1, false),
+                        binop_debug_loc);
+
+        let expect = bcx.ccx().get_intrinsic(&"llvm.expect.i1");
+        Call(bcx, expect, &[cond, C_integral(Type::i1(bcx.ccx()), 0, false)],
+             None, binop_debug_loc);
+
+        let bcx =
+            base::with_cond(bcx, cond, |bcx|
+                controlflow::trans_fail(bcx, info,
+                    InternedString::new("arithmetic operation overflowed")));
+
+        (bcx, result)
+    }
+}
+
+impl OverflowOpViaInputCheck {
+    fn build_with_input_check<'blk, 'tcx>(&self,
+                                          bcx: Block<'blk, 'tcx>,
+                                          info: NodeIdAndSpan,
+                                          lhs_t: Ty<'tcx>,
+                                          lhs: ValueRef,
+                                          rhs: ValueRef,
+                                          binop_debug_loc: DebugLoc)
+                                          -> (Block<'blk, 'tcx>, ValueRef)
+    {
+        let lhs_llty = val_ty(lhs);
+        let rhs_llty = val_ty(rhs);
+
+        // Panic if any bits are set outside of bits that we always
+        // mask in.
+        //
+        // Note that the mask's value is derived from the LHS type
+        // (since that is where the 32/64 distinction is relevant) but
+        // the mask's type must match the RHS type (since they will
+        // both be fed into a and-binop)
+        let invert_mask = !shift_mask_val(lhs_llty);
+        let invert_mask = C_integral(rhs_llty, invert_mask, true);
+
+        let outer_bits = And(bcx, rhs, invert_mask, binop_debug_loc);
+        let cond = ICmp(bcx, llvm::IntNE, outer_bits,
+                        C_integral(rhs_llty, 0, false), binop_debug_loc);
+        let result = match *self {
+            OverflowOpViaInputCheck::Shl =>
+                build_unchecked_lshift(bcx, lhs, rhs, binop_debug_loc),
+            OverflowOpViaInputCheck::Shr =>
+                build_unchecked_rshift(bcx, lhs_t, lhs, rhs, binop_debug_loc),
+        };
+        let bcx =
+            base::with_cond(bcx, cond, |bcx|
+                controlflow::trans_fail(bcx, info,
+                    InternedString::new("shift operation overflowed")));
+
+        (bcx, result)
+    }
+}
+
+fn shift_mask_val(llty: Type) -> u64 {
+    // i8/u8 can shift by at most 7, i16/u16 by at most 15, etc.
+    llty.int_width() - 1
+}
+
+// To avoid UB from LLVM, these two functions mask RHS with an
+// appropriate mask unconditionally (i.e. the fallback behavior for
+// all shifts). For 32- and 64-bit types, this matches the semantics
+// of Java. (See related discussion on #1877 and #10183.)
+
+fn build_unchecked_lshift<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                                      lhs: ValueRef,
+                                      rhs: ValueRef,
+                                      binop_debug_loc: DebugLoc) -> ValueRef {
+    let rhs = base::cast_shift_expr_rhs(bcx, ast::BinOp_::BiShl, lhs, rhs);
+    // #1877, #10183: Ensure that input is always valid
+    let rhs = shift_mask_rhs(bcx, rhs, binop_debug_loc);
+    Shl(bcx, lhs, rhs, binop_debug_loc)
+}
+
+fn build_unchecked_rshift<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                                      lhs_t: Ty<'tcx>,
+                                      lhs: ValueRef,
+                                      rhs: ValueRef,
+                                      binop_debug_loc: DebugLoc) -> ValueRef {
+    let rhs = base::cast_shift_expr_rhs(bcx, ast::BinOp_::BiShr, lhs, rhs);
+    // #1877, #10183: Ensure that input is always valid
+    let rhs = shift_mask_rhs(bcx, rhs, binop_debug_loc);
+    let is_signed = ty::type_is_signed(lhs_t);
+    if is_signed {
+        AShr(bcx, lhs, rhs, binop_debug_loc)
+    } else {
+        LShr(bcx, lhs, rhs, binop_debug_loc)
+    }
+}
+
+fn shift_mask_rhs<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                              rhs: ValueRef,
+                              debug_loc: DebugLoc) -> ValueRef {
+    let rhs_llty = val_ty(rhs);
+    let mask = shift_mask_val(rhs_llty);
+    And(bcx, rhs, C_integral(rhs_llty, mask, false), debug_loc)
+}
+
+fn with_overflow_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, oop: OverflowOp, info: NodeIdAndSpan,
+                                   lhs_t: Ty<'tcx>, lhs: ValueRef,
+                                   rhs: ValueRef,
+                                   binop_debug_loc: DebugLoc)
+                                   -> (Block<'blk, 'tcx>, ValueRef) {
+    if bcx.unreachable.get() { return (bcx, _Undef(lhs)); }
+    if bcx.ccx().check_overflow() {
+
+        match oop.codegen_strategy() {
+            OverflowCodegen::ViaIntrinsic(oop) =>
+                oop.build_intrinsic_call(bcx, info, lhs_t, lhs, rhs, binop_debug_loc),
+            OverflowCodegen::ViaInputCheck(oop) =>
+                oop.build_with_input_check(bcx, info, lhs_t, lhs, rhs, binop_debug_loc),
+        }
+    } else {
+        let res = match oop {
+            OverflowOp::Add => Add(bcx, lhs, rhs, binop_debug_loc),
+            OverflowOp::Sub => Sub(bcx, lhs, rhs, binop_debug_loc),
+            OverflowOp::Mul => Mul(bcx, lhs, rhs, binop_debug_loc),
+
+            OverflowOp::Shl =>
+                build_unchecked_lshift(bcx, lhs, rhs, binop_debug_loc),
+            OverflowOp::Shr =>
+                build_unchecked_rshift(bcx, lhs_t, lhs, rhs, binop_debug_loc),
+        };
+        (bcx, res)
+    }
+}
index 4508fe21a65fadb90abcf37975190fd609b13139..e87a5865df05446f5f08f51a649348d648547b87 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-use back::{link};
+use back::link;
 use llvm::{ValueRef, CallConv, get_param};
 use llvm;
 use middle::weak_lang_items;
@@ -35,7 +35,7 @@ use syntax::abi::{RustIntrinsic, Rust, RustCall, Stdcall, Fastcall, System};
 use syntax::codemap::Span;
 use syntax::parse::token::{InternedString, special_idents};
 use syntax::parse::token;
-use syntax::{ast};
+use syntax::ast;
 use syntax::{attr, ast_map};
 use syntax::print::pprust;
 use util::ppaux::Repr;
@@ -111,7 +111,7 @@ pub fn register_static(ccx: &CrateContext,
     let llty = type_of::type_of(ccx, ty);
 
     let ident = link_name(foreign_item);
-    match attr::first_attr_value_str_by_name(&foreign_item.attrs[],
+    match attr::first_attr_value_str_by_name(&foreign_item.attrs,
                                              "linkage") {
         // If this is a static with a linkage specified, then we need to handle
         // it a little specially. The typesystem prevents things like &T and
@@ -240,11 +240,11 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);
     let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[..]);
     let fn_type = cabi::compute_abi_info(ccx,
-                                         &llsig.llarg_tys[],
+                                         &llsig.llarg_tys,
                                          llsig.llret_ty,
                                          llsig.ret_def);
 
-    let arg_tys: &[cabi::ArgType] = &fn_type.arg_tys[];
+    let arg_tys: &[cabi::ArgType] = &fn_type.arg_tys;
 
     let mut llargs_foreign = Vec::new();
 
@@ -439,8 +439,8 @@ fn gate_simd_ffi(tcx: &ty::ctxt, decl: &ast::FnDecl, ty: &ty::BareFnTy) {
                 tcx.sess.span_err(ast_ty.span,
                               &format!("use of SIMD type `{}` in FFI is highly experimental and \
                                         may result in invalid code",
-                                       pprust::ty_to_string(ast_ty))[]);
-                tcx.sess.span_help(ast_ty.span,
+                                       pprust::ty_to_string(ast_ty)));
+                tcx.sess.fileline_help(ast_ty.span,
                                    "add #![feature(simd_ffi)] to the crate attributes to enable");
             }
         };
@@ -470,8 +470,8 @@ pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) {
                                                      "foreign fn's sty isn't a bare_fn_ty?")
                     }
 
-                    register_foreign_item_fn(ccx, abi, ty,
-                                             &lname);
+                    let llfn = register_foreign_item_fn(ccx, abi, ty, &lname);
+                    base::set_llvm_fn_attrs(ccx, &foreign_item.attrs, llfn);
                     // Unlike for other items, we shouldn't call
                     // `base::update_linkage` here.  Foreign items have
                     // special linkage requirements, which are handled
@@ -603,7 +603,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                 ccx.sess().bug(&format!("build_rust_fn: extern fn {} has ty {}, \
                                         expected a bare fn ty",
                                        ccx.tcx().map.path_to_string(id),
-                                       t.repr(tcx))[]);
+                                       t.repr(tcx)));
             }
         };
 
@@ -868,9 +868,9 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 // the massive simplifications that have occurred.
 
 pub fn link_name(i: &ast::ForeignItem) -> InternedString {
-    match attr::first_attr_value_str_by_name(&i.attrs[], "link_name") {
+    match attr::first_attr_value_str_by_name(&i.attrs, "link_name") {
         Some(ln) => ln.clone(),
-        None => match weak_lang_items::link_name(&i.attrs[]) {
+        None => match weak_lang_items::link_name(&i.attrs) {
             Some(name) => name,
             None => token::get_ident(i.ident),
         }
@@ -913,7 +913,7 @@ fn foreign_types_for_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);
     let llsig = foreign_signature(ccx, &fn_sig, &fn_sig.inputs);
     let fn_ty = cabi::compute_abi_info(ccx,
-                                       &llsig.llarg_tys[],
+                                       &llsig.llarg_tys,
                                        llsig.llret_ty,
                                        llsig.ret_def);
     debug!("foreign_types_for_fn_ty(\
@@ -922,7 +922,7 @@ fn foreign_types_for_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
            fn_ty={} -> {}, \
            ret_def={}",
            ty.repr(ccx.tcx()),
-           ccx.tn().types_to_str(&llsig.llarg_tys[]),
+           ccx.tn().types_to_str(&llsig.llarg_tys),
            ccx.tn().type_to_string(llsig.llret_ty),
            ccx.tn().types_to_str(&fn_ty.arg_tys.iter().map(|t| t.ty).collect::<Vec<_>>()),
            ccx.tn().type_to_string(fn_ty.ret_ty.ty),
index 268b65c6ceb30c14f9af1889c890a870712e7fd8..32b4d14177c2a050fbd512c4df1b0efe32b09448 100644 (file)
 
 //!
 //
-// Code relating to taking, dropping, etc as well as type descriptors.
+// Code relating to drop glue.
 
 
 use back::abi;
 use back::link::*;
-use llvm::{ValueRef, True, get_param};
+use llvm::{ValueRef, get_param};
 use llvm;
 use middle::lang_items::ExchangeFreeFnLangItem;
 use middle::subst;
 use middle::subst::{Subst, Substs};
 use trans::adt;
+use trans::adt::GetDtorType; // for tcx.dtor_type()
 use trans::base::*;
 use trans::build::*;
 use trans::callee;
 use trans::cleanup;
 use trans::cleanup::CleanupMethods;
-use trans::consts;
 use trans::common::*;
 use trans::datum;
 use trans::debuginfo::DebugLoc;
 use trans::expr;
 use trans::machine::*;
-use trans::tvec;
 use trans::type_::Type;
 use trans::type_of::{type_of, sizing_type_of, align_of};
 use middle::ty::{self, Ty};
@@ -41,9 +40,7 @@ use util::ppaux;
 
 use arena::TypedArena;
 use libc::c_uint;
-use std::ffi::CString;
 use syntax::ast;
-use syntax::parse::token;
 
 pub fn trans_exchange_free_dyn<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                                            v: ValueRef,
@@ -99,6 +96,16 @@ pub fn get_drop_glue_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     if !type_is_sized(tcx, t) {
         return t
     }
+
+    // FIXME (#22815): note that type_needs_drop conservatively
+    // approximates in some cases and may say a type expression
+    // requires drop glue when it actually does not.
+    //
+    // (In this case it is not clear whether any harm is done, i.e.
+    // erroneously returning `t` in some cases where we could have
+    // returned `tcx.types.i8` does not appear unsound. The impact on
+    // code quality is unknown at this time.)
+
     if !type_needs_drop(tcx, t) {
         return tcx.types.i8;
     }
@@ -125,7 +132,7 @@ pub fn drop_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     // NB: v is an *alias* of type t here, not a direct value.
     debug!("drop_ty(t={})", t.repr(bcx.tcx()));
     let _icx = push_ctxt("drop_ty");
-    if type_needs_drop(bcx.tcx(), t) {
+    if bcx.fcx.type_needs_drop(t) {
         let ccx = bcx.ccx();
         let glue = get_drop_glue(ccx, t);
         let glue_type = get_drop_glue_type(ccx, t);
@@ -168,31 +175,46 @@ pub fn get_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Val
 
     let llfnty = Type::glue_fn(ccx, llty);
 
-    let (glue, new_sym) = match ccx.available_drop_glues().borrow().get(&t) {
-        Some(old_sym) => {
-            let glue = decl_cdecl_fn(ccx, &old_sym[..], llfnty, ty::mk_nil(ccx.tcx()));
-            (glue, None)
-        },
-        None => {
-            let (sym, glue) = declare_generic_glue(ccx, t, llfnty, "drop");
-            (glue, Some(sym))
-        },
+    // To avoid infinite recursion, don't `make_drop_glue` until after we've
+    // added the entry to the `drop_glues` cache.
+    if let Some(old_sym) = ccx.available_drop_glues().borrow().get(&t) {
+        let llfn = decl_cdecl_fn(ccx, &old_sym, llfnty, ty::mk_nil(ccx.tcx()));
+        ccx.drop_glues().borrow_mut().insert(t, llfn);
+        return llfn;
     };
 
-    ccx.drop_glues().borrow_mut().insert(t, glue);
+    let fn_nm = mangle_internal_name_by_type_and_seq(ccx, t, "drop");
+    let llfn = decl_cdecl_fn(ccx, &fn_nm, llfnty, ty::mk_nil(ccx.tcx()));
+    note_unique_llvm_symbol(ccx, fn_nm.clone());
+    ccx.available_drop_glues().borrow_mut().insert(t, fn_nm);
 
-    // To avoid infinite recursion, don't `make_drop_glue` until after we've
-    // added the entry to the `drop_glues` cache.
-    match new_sym {
-        Some(sym) => {
-            ccx.available_drop_glues().borrow_mut().insert(t, sym);
-            // We're creating a new drop glue, so also generate a body.
-            make_generic_glue(ccx, t, glue, make_drop_glue, "drop");
-        },
-        None => {},
-    }
+    let _s = StatRecorder::new(ccx, format!("drop {}", ty_to_short_str(ccx.tcx(), t)));
 
-    glue
+    let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
+    let (arena, fcx): (TypedArena<_>, FunctionContext);
+    arena = TypedArena::new();
+    fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, false,
+                      ty::FnConverging(ty::mk_nil(ccx.tcx())),
+                      empty_substs, None, &arena);
+
+    let bcx = init_function(&fcx, false, ty::FnConverging(ty::mk_nil(ccx.tcx())));
+
+    update_linkage(ccx, llfn, None, OriginalTranslation);
+
+    ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1);
+    // All glue functions take values passed *by alias*; this is a
+    // requirement since in many contexts glue is invoked indirectly and
+    // the caller has no idea if it's dealing with something that can be
+    // passed by value.
+    //
+    // llfn is expected be declared to take a parameter of the appropriate
+    // type, so we don't need to explicitly cast the function parameter.
+
+    let llrawptr0 = get_param(llfn, fcx.arg_pos(0) as c_uint);
+    let bcx = make_drop_glue(bcx, llrawptr0, t);
+    finish_fn(&fcx, bcx, ty::FnConverging(ty::mk_nil(ccx.tcx())), DebugLoc::None);
+
+    llfn
 }
 
 fn trans_struct_drop_flag<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
@@ -210,9 +232,31 @@ fn trans_struct_drop_flag<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         Load(bcx, llval)
     };
     let drop_flag = unpack_datum!(bcx, adt::trans_drop_flag_ptr(bcx, &*repr, struct_data));
-    with_cond(bcx, load_ty(bcx, drop_flag.val, bcx.tcx().types.bool), |cx| {
+    let loaded = load_ty(bcx, drop_flag.val, bcx.tcx().dtor_type());
+    let drop_flag_llty = type_of(bcx.fcx.ccx, bcx.tcx().dtor_type());
+    let init_val = C_integral(drop_flag_llty, adt::DTOR_NEEDED as u64, false);
+
+    let bcx = if !bcx.ccx().check_drop_flag_for_sanity() {
+        bcx
+    } else {
+        let drop_flag_llty = type_of(bcx.fcx.ccx, bcx.tcx().dtor_type());
+        let done_val = C_integral(drop_flag_llty, adt::DTOR_DONE as u64, false);
+        let not_init = ICmp(bcx, llvm::IntNE, loaded, init_val, DebugLoc::None);
+        let not_done = ICmp(bcx, llvm::IntNE, loaded, done_val, DebugLoc::None);
+        let drop_flag_neither_initialized_nor_cleared =
+            And(bcx, not_init, not_done, DebugLoc::None);
+        with_cond(bcx, drop_flag_neither_initialized_nor_cleared, |cx| {
+            let llfn = cx.ccx().get_intrinsic(&("llvm.debugtrap"));
+            Call(cx, llfn, &[], None, DebugLoc::None);
+            cx
+        })
+    };
+
+    let drop_flag_dtor_needed = ICmp(bcx, llvm::IntEQ, loaded, init_val, DebugLoc::None);
+    with_cond(bcx, drop_flag_dtor_needed, |cx| {
         trans_struct_drop(cx, t, v0, dtor_did, class_did, substs)
     })
+
 }
 
 fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
@@ -243,7 +287,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             sig.inputs[0]
         }
         _ => bcx.sess().bug(&format!("Expected function type, found {}",
-                                    bcx.ty_to_string(fty))[])
+                                    bcx.ty_to_string(fty)))
     };
 
     let (struct_data, info) = if type_is_sized(bcx.tcx(), t) {
@@ -265,8 +309,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         assert_eq!(params.len(), 1);
         let self_arg = if type_is_fat_ptr(bcx.tcx(), self_ty) {
             // The dtor expects a fat pointer, so make one, even if we have to fake it.
-            let boxed_ty = ty::mk_open(bcx.tcx(), t);
-            let scratch = datum::rvalue_scratch_datum(bcx, boxed_ty, "__fat_ptr_drop_self");
+            let scratch = datum::rvalue_scratch_datum(bcx, t, "__fat_ptr_drop_self");
             Store(bcx, value, GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_ADDR]));
             Store(bcx,
                   // If we just had a thin pointer, make a fat pointer by sticking
@@ -284,20 +327,18 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         // Add all the fields as a value which needs to be cleaned at the end of
         // this scope. Iterate in reverse order so a Drop impl doesn't reverse
         // the order in which fields get dropped.
-        for (i, ty) in st.fields.iter().enumerate().rev() {
+        for (i, &ty) in st.fields.iter().enumerate().rev() {
             let llfld_a = adt::struct_field_ptr(variant_cx, &*st, value, i, false);
 
-            let val = if type_is_sized(bcx.tcx(), *ty) {
+            let val = if type_is_sized(bcx.tcx(), ty) {
                 llfld_a
             } else {
-                let boxed_ty = ty::mk_open(bcx.tcx(), *ty);
-                let scratch = datum::rvalue_scratch_datum(bcx, boxed_ty, "__fat_ptr_drop_field");
+                let scratch = datum::rvalue_scratch_datum(bcx, ty, "__fat_ptr_drop_field");
                 Store(bcx, llfld_a, GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_ADDR]));
                 Store(bcx, info.unwrap(), GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_EXTRA]));
                 scratch.val
             };
-            variant_cx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope),
-                                             val, *ty);
+            variant_cx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope), val, ty);
         }
 
         let dtor_ty = ty::mk_ctor_fn(bcx.tcx(),
@@ -306,8 +347,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                      ty::mk_nil(bcx.tcx()));
         let (_, variant_cx) = invoke(variant_cx, dtor_addr, &args[..], dtor_ty, DebugLoc::None);
 
-        variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope);
-        variant_cx
+        variant_cx.fcx.pop_and_trans_custom_cleanup_scope(variant_cx, field_scope)
     })
 }
 
@@ -370,7 +410,7 @@ fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, info:
              C_uint(bcx.ccx(), unit_align))
         }
         _ => bcx.sess().bug(&format!("Unexpected unsized type, found {}",
-                                    bcx.ty_to_string(t))[])
+                                    bcx.ty_to_string(t)))
     }
 }
 
@@ -378,53 +418,49 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
                               -> Block<'blk, 'tcx> {
     // NB: v0 is an *alias* of type t here, not a direct value.
     let _icx = push_ctxt("make_drop_glue");
+
+    // Only drop the value when it ... well, we used to check for
+    // non-null, (and maybe we need to continue doing so), but we now
+    // must definitely check for special bit-patterns corresponding to
+    // the special dtor markings.
+
+    let inttype = Type::int(bcx.ccx());
+    let dropped_pattern = C_integral(inttype, adt::dtor_done_usize(bcx.fcx.ccx) as u64, false);
+
     match t.sty {
         ty::ty_uniq(content_ty) => {
-            match content_ty.sty {
-                ty::ty_vec(ty, None) => {
-                    tvec::make_drop_glue_unboxed(bcx, v0, ty, true)
-                }
-                ty::ty_str => {
-                    let unit_ty = ty::sequence_element_type(bcx.tcx(), content_ty);
-                    tvec::make_drop_glue_unboxed(bcx, v0, unit_ty, true)
-                }
-                ty::ty_trait(..) => {
-                    let lluniquevalue = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
-                    // Only drop the value when it is non-null
-                    let concrete_ptr = Load(bcx, lluniquevalue);
-                    with_cond(bcx, IsNotNull(bcx, concrete_ptr), |bcx| {
-                        let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]));
-                        let dtor = Load(bcx, dtor_ptr);
-                        Call(bcx,
-                             dtor,
-                             &[PointerCast(bcx, lluniquevalue, Type::i8p(bcx.ccx()))],
-                             None,
-                             DebugLoc::None);
-                        bcx
-                    })
-                }
-                ty::ty_struct(..) if !type_is_sized(bcx.tcx(), content_ty) => {
-                    let llval = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
-                    let llbox = Load(bcx, llval);
-                    let not_null = IsNotNull(bcx, llbox);
-                    with_cond(bcx, not_null, |bcx| {
-                        let bcx = drop_ty(bcx, v0, content_ty, DebugLoc::None);
-                        let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]);
-                        let info = Load(bcx, info);
-                        let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info);
+            if !type_is_sized(bcx.tcx(), content_ty) {
+                let llval = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
+                let llbox = Load(bcx, llval);
+                let llbox_as_usize = PtrToInt(bcx, llbox, Type::int(bcx.ccx()));
+                let drop_flag_not_dropped_already =
+                    ICmp(bcx, llvm::IntNE, llbox_as_usize, dropped_pattern, DebugLoc::None);
+                with_cond(bcx, drop_flag_not_dropped_already, |bcx| {
+                    let bcx = drop_ty(bcx, v0, content_ty, DebugLoc::None);
+                    let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]);
+                    let info = Load(bcx, info);
+                    let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info);
+
+                    // `Box<ZeroSizeType>` does not allocate.
+                    let needs_free = ICmp(bcx,
+                                          llvm::IntNE,
+                                          llsize,
+                                          C_uint(bcx.ccx(), 0u64),
+                                          DebugLoc::None);
+                    with_cond(bcx, needs_free, |bcx| {
                         trans_exchange_free_dyn(bcx, llbox, llsize, llalign, DebugLoc::None)
                     })
-                }
-                _ => {
-                    assert!(type_is_sized(bcx.tcx(), content_ty));
-                    let llval = v0;
-                    let llbox = Load(bcx, llval);
-                    let not_null = IsNotNull(bcx, llbox);
-                    with_cond(bcx, not_null, |bcx| {
-                        let bcx = drop_ty(bcx, llbox, content_ty, DebugLoc::None);
-                        trans_exchange_free_ty(bcx, llbox, content_ty, DebugLoc::None)
-                    })
-                }
+                })
+            } else {
+                let llval = v0;
+                let llbox = Load(bcx, llval);
+                let llbox_as_usize = PtrToInt(bcx, llbox, inttype);
+                let drop_flag_not_dropped_already =
+                    ICmp(bcx, llvm::IntNE, llbox_as_usize, dropped_pattern, DebugLoc::None);
+                with_cond(bcx, drop_flag_not_dropped_already, |bcx| {
+                    let bcx = drop_ty(bcx, llbox, content_ty, DebugLoc::None);
+                    trans_exchange_free_ty(bcx, llbox, content_ty, DebugLoc::None)
+                })
             }
         }
         ty::ty_struct(did, substs) | ty::ty_enum(did, substs) => {
@@ -443,7 +479,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
                         bcx.sess().warn(&format!("Ignoring drop flag in destructor for {}\
                                                  because the struct is unsized. See issue\
                                                  #16758",
-                                                bcx.ty_to_string(t))[]);
+                                                bcx.ty_to_string(t)));
                         trans_struct_drop(bcx, t, v0, dtor, did, substs)
                     }
                 }
@@ -456,34 +492,19 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
                 }
             }
         }
-        ty::ty_closure(..) => {
-            iter_structural_ty(bcx,
-                               v0,
-                               t,
-                               |bb, vv, tt| drop_ty(bb, vv, tt, DebugLoc::None))
-        }
         ty::ty_trait(..) => {
-            // No need to do a null check here (as opposed to the Box<trait case
-            // above), because this happens for a trait field in an unsized
-            // struct. If anything is null, it is the whole struct and we won't
-            // get here.
-            let lluniquevalue = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
-            let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]));
-            let dtor = Load(bcx, dtor_ptr);
+            let data_ptr = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
+            let vtable_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]));
+            let dtor = Load(bcx, vtable_ptr);
             Call(bcx,
                  dtor,
-                 &[PointerCast(bcx, Load(bcx, lluniquevalue), Type::i8p(bcx.ccx()))],
+                 &[PointerCast(bcx, Load(bcx, data_ptr), Type::i8p(bcx.ccx()))],
                  None,
                  DebugLoc::None);
             bcx
-        },
-        ty::ty_vec(_, None) | ty::ty_str => {
-            let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
-            tvec::make_drop_glue_unboxed(bcx, v0, unit_ty, false)
-        },
+        }
         _ => {
-            assert!(type_is_sized(bcx.tcx(), t));
-            if type_needs_drop(bcx.tcx(), t) && ty::type_is_structural(t) {
+            if bcx.fcx.type_needs_drop(t) {
                 iter_structural_ty(bcx,
                                    v0,
                                    t,
@@ -494,121 +515,3 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
         }
     }
 }
-
-// Generates the declaration for (but doesn't emit) a type descriptor.
-pub fn declare_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
-                                -> tydesc_info<'tcx> {
-    // If emit_tydescs already ran, then we shouldn't be creating any new
-    // tydescs.
-    assert!(!ccx.finished_tydescs().get());
-
-    let llty = type_of(ccx, t);
-
-    if ccx.sess().count_type_sizes() {
-        println!("{}\t{}", llsize_of_real(ccx, llty),
-                 ppaux::ty_to_string(ccx.tcx(), t));
-    }
-
-    let llsize = llsize_of(ccx, llty);
-    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 buf = CString::new(name.clone()).unwrap();
-    let gvar = unsafe {
-        llvm::LLVMAddGlobal(ccx.llmod(), ccx.tydesc_type().to_ref(),
-                            buf.as_ptr())
-    };
-    note_unique_llvm_symbol(ccx, name);
-
-    let ty_name = token::intern_and_get_ident(
-        &ppaux::ty_to_string(ccx.tcx(), t)[]);
-    let ty_name = C_str_slice(ccx, ty_name);
-
-    debug!("--- declare_tydesc {}", ppaux::ty_to_string(ccx.tcx(), t));
-    tydesc_info {
-        ty: t,
-        tydesc: gvar,
-        size: llsize,
-        align: llalign,
-        name: ty_name,
-    }
-}
-
-fn declare_generic_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>,
-                                  llfnty: Type, name: &str) -> (String, ValueRef) {
-    let _icx = push_ctxt("declare_generic_glue");
-    let fn_nm = mangle_internal_name_by_type_and_seq(
-        ccx,
-        t,
-        &format!("glue_{}", name)[]);
-    let llfn = decl_cdecl_fn(ccx, &fn_nm[..], llfnty, ty::mk_nil(ccx.tcx()));
-    note_unique_llvm_symbol(ccx, fn_nm.clone());
-    return (fn_nm, llfn);
-}
-
-fn make_generic_glue<'a, 'tcx, F>(ccx: &CrateContext<'a, 'tcx>,
-                                  t: Ty<'tcx>,
-                                  llfn: ValueRef,
-                                  helper: F,
-                                  name: &str)
-                                  -> ValueRef where
-    F: for<'blk> FnOnce(Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
-{
-    let _icx = push_ctxt("make_generic_glue");
-    let glue_name = format!("glue {} {}", name, ty_to_short_str(ccx.tcx(), t));
-    let _s = StatRecorder::new(ccx, glue_name);
-
-    let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
-    let (arena, fcx): (TypedArena<_>, FunctionContext);
-    arena = TypedArena::new();
-    fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, false,
-                      ty::FnConverging(ty::mk_nil(ccx.tcx())),
-                      empty_substs, None, &arena);
-
-    let bcx = init_function(&fcx, false, ty::FnConverging(ty::mk_nil(ccx.tcx())));
-
-    update_linkage(ccx, llfn, None, OriginalTranslation);
-
-    ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1);
-    // All glue functions take values passed *by alias*; this is a
-    // requirement since in many contexts glue is invoked indirectly and
-    // the caller has no idea if it's dealing with something that can be
-    // passed by value.
-    //
-    // llfn is expected be declared to take a parameter of the appropriate
-    // type, so we don't need to explicitly cast the function parameter.
-
-    let llrawptr0 = get_param(llfn, fcx.arg_pos(0) as c_uint);
-    let bcx = helper(bcx, llrawptr0, t);
-    finish_fn(&fcx, bcx, ty::FnConverging(ty::mk_nil(ccx.tcx())), DebugLoc::None);
-
-    llfn
-}
-
-pub fn emit_tydescs(ccx: &CrateContext) {
-    let _icx = push_ctxt("emit_tydescs");
-    // As of this point, allow no more tydescs to be created.
-    ccx.finished_tydescs().set(true);
-    let glue_fn_ty = Type::generic_glue_fn(ccx).ptr_to();
-    for (_, ti) in &*ccx.tydescs().borrow() {
-        // Each of the glue functions needs to be cast to a generic type
-        // before being put into the tydesc because we only have a singleton
-        // tydesc type. Then we'll recast each function to its real type when
-        // calling it.
-        let drop_glue = consts::ptrcast(get_drop_glue(ccx, ti.ty), glue_fn_ty);
-        ccx.stats().n_real_glues.set(ccx.stats().n_real_glues.get() + 1);
-
-        let tydesc = C_named_struct(ccx.tydesc_type(),
-                                    &[ti.size, // size
-                                      ti.align, // align
-                                      drop_glue, // drop_glue
-                                      ti.name]); // name
-
-        unsafe {
-            let gvar = ti.tydesc;
-            llvm::LLVMSetInitializer(gvar, tydesc);
-            llvm::LLVMSetGlobalConstant(gvar, True);
-            llvm::SetLinkage(gvar, llvm::InternalLinkage);
-        }
-    };
-}
index 56fda20e0e8dcdc79d666da21b94e4f10247fc32..2034c6223c13410d0d77b964d1043cda27309b86 100644 (file)
@@ -17,7 +17,7 @@ use trans::common::*;
 use middle::ty;
 
 use syntax::ast;
-use syntax::ast_util::{local_def, PostExpansionMethod};
+use syntax::ast_util::local_def;
 
 fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
     -> Option<ast::DefId> {
@@ -40,9 +40,9 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
     let csearch_result =
         csearch::maybe_get_item_ast(
             ccx.tcx(), fn_id,
-            box |a,b,c,d| astencode::decode_inlined_item(a, b, c, d));
+            Box::new(|a,b,c,d| astencode::decode_inlined_item(a, b, c, d)));
 
-    let inline_def = match csearch_result {
+    let inline_id = match csearch_result {
         csearch::FoundAst::NotFound => {
             ccx.external().borrow_mut().insert(fn_id, None);
             return None;
@@ -88,12 +88,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
                 None => {}
             }
 
-            local_def(item.id)
+            item.id
         }
         csearch::FoundAst::Found(&ast::IIForeign(ref item)) => {
             ccx.external().borrow_mut().insert(fn_id, Some(item.id));
             ccx.external_srcs().borrow_mut().insert(item.id, fn_id);
-            local_def(item.id)
+            item.id
         }
         csearch::FoundAst::FoundParent(parent_id, &ast::IIItem(ref item)) => {
             ccx.external().borrow_mut().insert(parent_id, Some(item.id));
@@ -122,67 +122,53 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
                                  non-enum, non-struct parent")
           }
           trans_item(ccx, &**item);
-          local_def(my_id)
+          my_id
         }
         csearch::FoundAst::FoundParent(_, _) => {
             ccx.sess().bug("maybe_get_item_ast returned a FoundParent \
              with a non-item parent");
         }
         csearch::FoundAst::Found(&ast::IITraitItem(_, ref trait_item)) => {
-            match *trait_item {
-                ast::RequiredMethod(_) => ccx.sess().bug("found RequiredMethod IITraitItem"),
-                ast::ProvidedMethod(ref mth) => {
-                    ccx.external().borrow_mut().insert(fn_id, Some(mth.id));
-                    ccx.external_srcs().borrow_mut().insert(mth.id, fn_id);
-
-                    ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
-
-                    // If this is a default method, we can't look up the
-                    // impl type. But we aren't going to translate anyways, so
-                    // don't.
-                    local_def(mth.id)
-                }
-                ast::TypeTraitItem(_) => {
-                    ccx.sess().bug("found TypeTraitItem IITraitItem")
-                }
-            }
+            ccx.external().borrow_mut().insert(fn_id, Some(trait_item.id));
+            ccx.external_srcs().borrow_mut().insert(trait_item.id, fn_id);
+
+            ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
+
+            // If this is a default method, we can't look up the
+            // impl type. But we aren't going to translate anyways, so
+            // don't.
+            trait_item.id
         }
         csearch::FoundAst::Found(&ast::IIImplItem(impl_did, ref impl_item)) => {
-            match *impl_item {
-                ast::MethodImplItem(ref mth) => {
-                    ccx.external().borrow_mut().insert(fn_id, Some(mth.id));
-                    ccx.external_srcs().borrow_mut().insert(mth.id, fn_id);
+            ccx.external().borrow_mut().insert(fn_id, Some(impl_item.id));
+            ccx.external_srcs().borrow_mut().insert(impl_item.id, fn_id);
 
-                    ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
-
-                    let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
-                    let unparameterized = impl_tpt.generics.types.is_empty() &&
-                            mth.pe_generics().ty_params.is_empty();
+            ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
 
+            // Translate monomorphic impl methods immediately.
+            if let ast::MethodImplItem(ref sig, ref body) = impl_item.node {
+                let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
+                if impl_tpt.generics.types.is_empty() &&
+                        sig.generics.ty_params.is_empty() {
                     let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
-                    if unparameterized {
-                        let llfn = get_item_val(ccx, mth.id);
-                        trans_fn(ccx,
-                                 &*mth.pe_fn_decl(),
-                                 &*mth.pe_body(),
-                                 llfn,
-                                 empty_substs,
-                                 mth.id,
-                                 &[]);
-                        // Use InternalLinkage so LLVM can optimize more
-                        // aggressively.
-                        SetLinkage(llfn, InternalLinkage);
-                    }
-                    local_def(mth.id)
-                }
-                ast::TypeImplItem(_) => {
-                    ccx.sess().bug("found TypeImplItem IIImplItem")
+                    let llfn = get_item_val(ccx, impl_item.id);
+                    trans_fn(ccx,
+                             &sig.decl,
+                             body,
+                             llfn,
+                             empty_substs,
+                             impl_item.id,
+                             &[]);
+                    // Use InternalLinkage so LLVM can optimize more aggressively.
+                    SetLinkage(llfn, InternalLinkage);
                 }
             }
+
+            impl_item.id
         }
     };
 
-    return Some(inline_def);
+    Some(local_def(inline_id))
 }
 
 pub fn get_local_instance(ccx: &CrateContext, fn_id: ast::DefId)
index a1b66ed94f06bc8dfed134ea44cace4fd76e274d..62a6ede4c2f936bdcdefaec91e8e21c5e12cca96 100644 (file)
@@ -36,7 +36,7 @@ use syntax::parse::token;
 use util::ppaux::{Repr, ty_to_string};
 
 pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Option<ValueRef> {
-    let name = match &token::get_ident(item.ident)[] {
+    let name = match &token::get_ident(item.ident)[..] {
         "sqrtf32" => "llvm.sqrt.f32",
         "sqrtf64" => "llvm.sqrt.f64",
         "powif32" => "llvm.powi.f32",
@@ -121,10 +121,10 @@ pub fn check_intrinsics(ccx: &CrateContext) {
                     &format!("transmute called on types with potentially different sizes: \
                               {} (could be {} bit{}) to {} (could be {} bit{})",
                              ty_to_string(ccx.tcx(), transmute_restriction.original_from),
-                             from_type_size as uint,
+                             from_type_size as usize,
                              if from_type_size == 1 {""} else {"s"},
                              ty_to_string(ccx.tcx(), transmute_restriction.original_to),
-                             to_type_size as uint,
+                             to_type_size as usize,
                              if to_type_size == 1 {""} else {"s"}));
             } else {
                 ccx.sess().span_err(
@@ -132,10 +132,10 @@ pub fn check_intrinsics(ccx: &CrateContext) {
                     &format!("transmute called on types with different sizes: \
                               {} ({} bit{}) to {} ({} bit{})",
                              ty_to_string(ccx.tcx(), transmute_restriction.original_from),
-                             from_type_size as uint,
+                             from_type_size as usize,
                              if from_type_size == 1 {""} else {"s"},
                              ty_to_string(ccx.tcx(), transmute_restriction.original_to),
-                             to_type_size as uint,
+                             to_type_size as usize,
                              if to_type_size == 1 {""} else {"s"}));
             }
         }
@@ -156,6 +156,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     let ccx = fcx.ccx;
     let tcx = bcx.tcx();
 
+    let _icx = push_ctxt("trans_intrinsic_call");
+
     let ret_ty = match callee_ty.sty {
         ty::ty_bare_fn(_, ref f) => {
             ty::erase_late_bound_regions(bcx.tcx(), &f.sig.output())
@@ -345,15 +347,10 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             bcx = src.store_to(bcx, llargs[0]);
             C_nil(ccx)
         }
-        (_, "get_tydesc") => {
+        (_, "type_name") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
-            let static_ti = get_tydesc(ccx, tp_ty);
-
-            // FIXME (#3730): ideally this shouldn't need a cast,
-            // but there's a circularity between translating rust types to llvm
-            // types and having a tydesc type available. So I can't directly access
-            // the llvm type of intrinsic::TyDesc struct.
-            PointerCast(bcx, static_ti.tydesc, llret_ty)
+            let ty_name = token::intern_and_get_ident(&ty_to_string(ccx.tcx(), tp_ty));
+            C_str_slice(ccx, ty_name)
         }
         (_, "type_id") => {
             let hash = ty::hash_crate_independent(
@@ -362,11 +359,18 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                 &ccx.link_meta().crate_hash);
             C_u64(ccx, hash)
         }
+        (_, "init_dropped") => {
+            let tp_ty = *substs.types.get(FnSpace, 0);
+            if !return_type_is_void(ccx, tp_ty) {
+                drop_done_fill_mem(bcx, llresult, tp_ty);
+            }
+            C_nil(ccx)
+        }
         (_, "init") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
             if !return_type_is_void(ccx, tp_ty) {
                 // Just zero out the stack slot. (See comment on base::memzero for explanation)
-                zero_mem(bcx, llresult, tp_ty);
+                init_zero_mem(bcx, llresult, tp_ty);
             }
             C_nil(ccx)
         }
@@ -376,7 +380,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         }
         (_, "needs_drop") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
-            C_bool(ccx, type_needs_drop(ccx.tcx(), tp_ty))
+
+            C_bool(ccx, bcx.fcx.type_needs_drop(tp_ty))
         }
         (_, "owns_managed") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
@@ -388,27 +393,27 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             InBoundsGEP(bcx, ptr, &[offset])
         }
 
-        (_, "copy_nonoverlapping_memory") => {
+        (_, "copy_nonoverlapping") => {
             copy_intrinsic(bcx,
                            false,
                            false,
                            *substs.types.get(FnSpace, 0),
-                           llargs[0],
                            llargs[1],
+                           llargs[0],
                            llargs[2],
                            call_debug_location)
         }
-        (_, "copy_memory") => {
+        (_, "copy") => {
             copy_intrinsic(bcx,
                            true,
                            false,
                            *substs.types.get(FnSpace, 0),
-                           llargs[0],
                            llargs[1],
+                           llargs[0],
                            llargs[2],
                            call_debug_location)
         }
-        (_, "set_memory") => {
+        (_, "write_bytes") => {
             memset_intrinsic(bcx,
                              false,
                              *substs.types.get(FnSpace, 0),
@@ -448,10 +453,15 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                              call_debug_location)
         }
         (_, "volatile_load") => {
-            VolatileLoad(bcx, llargs[0])
+            let tp_ty = *substs.types.get(FnSpace, 0);
+            let ptr = to_arg_ty_ptr(bcx, llargs[0], tp_ty);
+            from_arg_ty(bcx, VolatileLoad(bcx, ptr), tp_ty)
         },
         (_, "volatile_store") => {
-            VolatileStore(bcx, llargs[1], llargs[0]);
+            let tp_ty = *substs.types.get(FnSpace, 0);
+            let ptr = to_arg_ty_ptr(bcx, llargs[0], tp_ty);
+            let val = to_arg_ty(bcx, llargs[1], tp_ty);
+            VolatileStore(bcx, val, ptr);
             C_nil(ccx)
         },
 
@@ -657,6 +667,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                     llargs[0],
                                     llargs[1],
                                     call_debug_location),
+
+        (_, "overflowing_add") => Add(bcx, llargs[0], llargs[1], call_debug_location),
+        (_, "overflowing_sub") => Sub(bcx, llargs[0], llargs[1], call_debug_location),
+        (_, "overflowing_mul") => Mul(bcx, llargs[0], llargs[1], call_debug_location),
+
         (_, "return_address") => {
             if !fcx.caller_expects_out_pointer {
                 tcx.sess.span_err(call_info.span,
@@ -706,8 +721,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                             llvm::SequentiallyConsistent
                     };
 
-                    let res = AtomicCmpXchg(bcx, llargs[0], llargs[1],
-                                            llargs[2], order,
+                    let tp_ty = *substs.types.get(FnSpace, 0);
+                    let ptr = to_arg_ty_ptr(bcx, llargs[0], tp_ty);
+                    let cmp = to_arg_ty(bcx, llargs[1], tp_ty);
+                    let src = to_arg_ty(bcx, llargs[2], tp_ty);
+                    let res = AtomicCmpXchg(bcx, ptr, cmp, src, order,
                                             strongest_failure_ordering);
                     if unsafe { llvm::LLVMVersionMinor() >= 5 } {
                         ExtractValue(bcx, res, 0)
@@ -717,10 +735,15 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                 }
 
                 "load" => {
-                    AtomicLoad(bcx, llargs[0], order)
+                    let tp_ty = *substs.types.get(FnSpace, 0);
+                    let ptr = to_arg_ty_ptr(bcx, llargs[0], tp_ty);
+                    from_arg_ty(bcx, AtomicLoad(bcx, ptr, order), tp_ty)
                 }
                 "store" => {
-                    AtomicStore(bcx, llargs[1], llargs[0], order);
+                    let tp_ty = *substs.types.get(FnSpace, 0);
+                    let ptr = to_arg_ty_ptr(bcx, llargs[0], tp_ty);
+                    let val = to_arg_ty(bcx, llargs[1], tp_ty);
+                    AtomicStore(bcx, val, ptr, order);
                     C_nil(ccx)
                 }
 
@@ -746,7 +769,10 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                         _ => ccx.sess().fatal("unknown atomic operation")
                     };
 
-                    AtomicRMW(bcx, atom_op, llargs[0], llargs[1], order)
+                    let tp_ty = *substs.types.get(FnSpace, 0);
+                    let ptr = to_arg_ty_ptr(bcx, llargs[0], tp_ty);
+                    let val = to_arg_ty(bcx, llargs[1], tp_ty);
+                    AtomicRMW(bcx, atom_op, ptr, val, order)
                 }
             }
 
index de0f714276d0de4ec94a6513de0161193b24d001..6dd566797970e5aa820675ee245706d293a424b7 100644 (file)
@@ -34,5 +34,3 @@ impl LlvmRepr for ValueRef {
         ccx.tn().val_to_string(*self)
     }
 }
-
-
index 1552ac0bea0fe0f4e714fc81e22a1faaccdc39b4..ce37d38dc894fb3ff2efcedfca6c705bf8d0266c 100644 (file)
@@ -12,9 +12,7 @@
 
 #![allow(non_camel_case_types)]
 
-use llvm;
-use llvm::{ValueRef};
-use llvm::False;
+use llvm::{self, ValueRef};
 use trans::common::*;
 
 use trans::type_::Type;
@@ -101,17 +99,7 @@ pub fn llalign_of_min(cx: &CrateContext, ty: Type) -> llalign {
     }
 }
 
-// Returns the "default" alignment of t, which is calculated by casting
-// null to a record containing a single-bit followed by a t value, then
-// doing gep(0,1) to get at the trailing (and presumably padded) t cell.
-pub fn llalign_of(cx: &CrateContext, ty: Type) -> ValueRef {
-    unsafe {
-        return llvm::LLVMConstIntCast(
-            llvm::LLVMAlignOf(ty.to_ref()), cx.int_type().to_ref(), False);
-    }
-}
-
-pub fn llelement_offset(cx: &CrateContext, struct_ty: Type, element: uint) -> u64 {
+pub fn llelement_offset(cx: &CrateContext, struct_ty: Type, element: usize) -> u64 {
     unsafe {
         return llvm::LLVMOffsetOfElement(cx.td().lltd, struct_ty.to_ref(),
                                          element as u32);
index 1d5d24a64036dd6d69760ae564c7ce8dc6595f49..190e44c9674cb5a13d10826aa60156fb15b40adc 100644 (file)
@@ -13,20 +13,22 @@ use back::abi;
 use back::link;
 use llvm::{ValueRef, get_param};
 use metadata::csearch;
-use middle::subst::Substs;
+use middle::subst::{Subst, Substs};
 use middle::subst::VecPerParamSpace;
 use middle::subst;
 use middle::traits;
+use middle::ty::ClosureTyper;
 use trans::base::*;
 use trans::build::*;
 use trans::callee::*;
 use trans::callee;
 use trans::cleanup;
+use trans::closure;
 use trans::common::*;
 use trans::consts;
 use trans::datum::*;
 use trans::debuginfo::DebugLoc;
-use trans::expr::{SaveIn, Ignore};
+use trans::expr::SaveIn;
 use trans::expr;
 use trans::glue;
 use trans::machine;
@@ -41,11 +43,11 @@ use std::rc::Rc;
 use syntax::abi::{Rust, RustCall};
 use syntax::parse::token;
 use syntax::{ast, ast_map, attr, visit};
-use syntax::ast_util::PostExpansionMethod;
 use syntax::codemap::DUMMY_SP;
+use syntax::ptr::P;
 
 // drop_glue pointer, size, align.
-static VTABLE_OFFSET: uint = 3;
+const VTABLE_OFFSET: usize = 3;
 
 /// The main "translation" pass for methods.  Generates code
 /// for non-monomorphized methods only.  Other methods will
@@ -53,7 +55,7 @@ static VTABLE_OFFSET: uint = 3;
 /// see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
 pub fn trans_impl(ccx: &CrateContext,
                   name: ast::Ident,
-                  impl_items: &[ast::ImplItem],
+                  impl_items: &[P<ast::ImplItem>],
                   generics: &ast::Generics,
                   id: ast::NodeId) {
     let _icx = push_ctxt("meth::trans_impl");
@@ -61,47 +63,42 @@ pub fn trans_impl(ccx: &CrateContext,
 
     debug!("trans_impl(name={}, id={})", name.repr(tcx), id);
 
+    let mut v = TransItemVisitor { ccx: ccx };
+
     // Both here and below with generic methods, be sure to recurse and look for
     // items that we need to translate.
     if !generics.ty_params.is_empty() {
-        let mut v = TransItemVisitor{ ccx: ccx };
         for impl_item in impl_items {
-            match *impl_item {
-                ast::MethodImplItem(ref method) => {
-                    visit::walk_method_helper(&mut v, &**method);
+            match impl_item.node {
+                ast::MethodImplItem(..) => {
+                    visit::walk_impl_item(&mut v, impl_item);
                 }
-                ast::TypeImplItem(_) => {}
+                ast::TypeImplItem(_) |
+                ast::MacImplItem(_) => {}
             }
         }
         return;
     }
     for impl_item in impl_items {
-        match *impl_item {
-            ast::MethodImplItem(ref method) => {
-                if method.pe_generics().ty_params.len() == 0 {
-                    let trans_everywhere = attr::requests_inline(&method.attrs[]);
+        match impl_item.node {
+            ast::MethodImplItem(ref sig, ref body) => {
+                if sig.generics.ty_params.len() == 0 {
+                    let trans_everywhere = attr::requests_inline(&impl_item.attrs);
                     for (ref ccx, is_origin) in ccx.maybe_iter(trans_everywhere) {
-                        let llfn = get_item_val(ccx, method.id);
+                        let llfn = get_item_val(ccx, impl_item.id);
                         let empty_substs = tcx.mk_substs(Substs::trans_empty());
-                        trans_fn(ccx,
-                                 method.pe_fn_decl(),
-                                 method.pe_body(),
-                                 llfn,
-                                 empty_substs,
-                                 method.id,
-                                 &[]);
+                        trans_fn(ccx, &sig.decl, body, llfn,
+                                 empty_substs, impl_item.id, &[]);
                         update_linkage(ccx,
                                        llfn,
-                                       Some(method.id),
+                                       Some(impl_item.id),
                                        if is_origin { OriginalTranslation } else { InlinedCopy });
                     }
                 }
-                let mut v = TransItemVisitor {
-                    ccx: ccx,
-                };
-                visit::walk_method_helper(&mut v, &**method);
+                visit::walk_impl_item(&mut v, impl_item);
             }
-            ast::TypeImplItem(_) => {}
+            ast::TypeImplItem(_) |
+            ast::MacImplItem(_) => {}
         }
     }
 }
@@ -189,17 +186,7 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     let mname = if method_id.krate == ast::LOCAL_CRATE {
         match tcx.map.get(method_id.node) {
-            ast_map::NodeTraitItem(method) => {
-                let ident = match *method {
-                    ast::RequiredMethod(ref m) => m.ident,
-                    ast::ProvidedMethod(ref m) => m.pe_ident(),
-                    ast::TypeTraitItem(_) => {
-                        tcx.sess.bug("trans_static_method_callee() on \
-                                      an associated type?!")
-                    }
-                };
-                ident.name
-            }
+            ast_map::NodeTraitItem(trait_item) => trait_item.ident.name,
             _ => panic!("callee is not a trait method")
         }
     } else {
@@ -300,12 +287,15 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                   .position(|item| item.def_id() == method_id)
                                   .unwrap();
             let (llfn, ty) =
-                trans_object_shim(ccx, data.object_ty, trait_id, method_offset_in_trait);
+                trans_object_shim(ccx,
+                                  data.object_ty,
+                                  data.upcast_trait_ref.clone(),
+                                  method_offset_in_trait);
             immediate_rvalue(llfn, ty)
         }
         _ => {
             tcx.sess.bug(&format!("static call to invalid vtable: {}",
-                                 vtbl.repr(tcx))[]);
+                                 vtbl.repr(tcx)));
         }
     }
 }
@@ -335,7 +325,7 @@ fn method_with_name(ccx: &CrateContext, impl_id: ast::DefId, name: ast::Name)
 fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                           method_call: MethodCall,
                                           trait_id: ast::DefId,
-                                          n_method: uint,
+                                          n_method: usize,
                                           vtable: traits::Vtable<'tcx, ()>)
                                           -> Callee<'blk, 'tcx> {
     let _icx = push_ctxt("meth::trans_monomorphized_callee");
@@ -370,30 +360,36 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         traits::VtableClosure(closure_def_id, substs) => {
             // The substitutions should have no type parameters remaining
             // after passing through fulfill_obligation
-            let llfn = trans_fn_ref_with_substs(bcx.ccx(),
-                                                closure_def_id,
-                                                MethodCallKey(method_call),
-                                                bcx.fcx.param_substs,
-                                                substs).val;
-
+            let trait_closure_kind = bcx.tcx().lang_items.fn_trait_kind(trait_id).unwrap();
+            let llfn = closure::trans_closure_method(bcx.ccx(),
+                                                     closure_def_id,
+                                                     substs,
+                                                     MethodCallKey(method_call),
+                                                     bcx.fcx.param_substs,
+                                                     trait_closure_kind);
             Callee {
                 bcx: bcx,
                 data: Fn(llfn),
             }
         }
         traits::VtableFnPointer(fn_ty) => {
-            let llfn = trans_fn_pointer_shim(bcx.ccx(), fn_ty);
+            let trait_closure_kind = bcx.tcx().lang_items.fn_trait_kind(trait_id).unwrap();
+            let llfn = trans_fn_pointer_shim(bcx.ccx(), trait_closure_kind, fn_ty);
             Callee { bcx: bcx, data: Fn(llfn) }
         }
         traits::VtableObject(ref data) => {
-            let (llfn, _) = trans_object_shim(bcx.ccx(), data.object_ty, trait_id, n_method);
+            let (llfn, _) = trans_object_shim(bcx.ccx(),
+                                              data.object_ty,
+                                              data.upcast_trait_ref.clone(),
+                                              n_method);
             Callee { bcx: bcx, data: Fn(llfn) }
         }
         traits::VtableBuiltin(..) |
+        traits::VtableDefaultImpl(..) |
         traits::VtableParam(..) => {
             bcx.sess().bug(
                 &format!("resolved vtable bad vtable {} in trans",
-                        vtable.repr(bcx.tcx()))[]);
+                        vtable.repr(bcx.tcx())));
         }
     }
 }
@@ -441,7 +437,7 @@ fn combine_impl_and_methods_tps<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 /// extract the self data and vtable out of the pair.
 fn trans_trait_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                   method_ty: Ty<'tcx>,
-                                  vtable_index: uint,
+                                  vtable_index: usize,
                                   self_expr: &ast::Expr,
                                   arg_cleanup_scope: cleanup::ScopeId)
                                   -> Callee<'blk, 'tcx> {
@@ -453,7 +449,7 @@ fn trans_trait_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let self_datum = unpack_datum!(
         bcx, expr::trans(bcx, self_expr));
 
-    let llval = if type_needs_drop(bcx.tcx(), self_datum.ty) {
+    let llval = if bcx.fcx.type_needs_drop(self_datum.ty) {
         let self_datum = unpack_datum!(
             bcx, self_datum.to_rvalue_datum(bcx, "trait_callee"));
 
@@ -478,7 +474,7 @@ fn trans_trait_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 /// pair.
 pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                  callee_ty: Ty<'tcx>,
-                                                 vtable_index: uint,
+                                                 vtable_index: usize,
                                                  llpair: ValueRef)
                                                  -> Callee<'blk, 'tcx> {
     let _icx = push_ctxt("meth::trans_trait_callee");
@@ -550,16 +546,17 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 pub fn trans_object_shim<'a, 'tcx>(
     ccx: &'a CrateContext<'a, 'tcx>,
     object_ty: Ty<'tcx>,
-    trait_id: ast::DefId,
-    method_offset_in_trait: uint)
+    upcast_trait_ref: ty::PolyTraitRef<'tcx>,
+    method_offset_in_trait: usize)
     -> (ValueRef, Ty<'tcx>)
 {
     let _icx = push_ctxt("trans_object_shim");
     let tcx = ccx.tcx();
+    let trait_id = upcast_trait_ref.def_id();
 
-    debug!("trans_object_shim(object_ty={}, trait_id={}, method_offset_in_trait={})",
+    debug!("trans_object_shim(object_ty={}, upcast_trait_ref={}, method_offset_in_trait={})",
            object_ty.repr(tcx),
-           trait_id.repr(tcx),
+           upcast_trait_ref.repr(tcx),
            method_offset_in_trait);
 
     let object_trait_ref =
@@ -574,7 +571,6 @@ pub fn trans_object_shim<'a, 'tcx>(
         };
 
     // Upcast to the trait in question and extract out the substitutions.
-    let upcast_trait_ref = traits::upcast(ccx.tcx(), object_trait_ref.clone(), trait_id).unwrap();
     let upcast_trait_ref = ty::erase_late_bound_regions(tcx, &upcast_trait_ref);
     let object_substs = upcast_trait_ref.substs.clone().erase_regions();
     debug!("trans_object_shim: object_substs={}", object_substs.repr(tcx));
@@ -588,15 +584,16 @@ pub fn trans_object_shim<'a, 'tcx>(
     };
     let fty = monomorphize::apply_param_substs(tcx, &object_substs, &method_ty.fty);
     let fty = tcx.mk_bare_fn(fty);
-    debug!("trans_object_shim: fty={}", fty.repr(tcx));
+    let method_ty = opaque_method_ty(tcx, fty);
+    debug!("trans_object_shim: fty={} method_ty={}", fty.repr(tcx), method_ty.repr(tcx));
 
     //
-    let method_bare_fn_ty =
-        ty::mk_bare_fn(tcx, None, fty);
+    let shim_fn_ty = ty::mk_bare_fn(tcx, None, fty);
+    let method_bare_fn_ty = ty::mk_bare_fn(tcx, None, method_ty);
     let function_name =
-        link::mangle_internal_name_by_type_and_seq(ccx, method_bare_fn_ty, "object_shim");
+        link::mangle_internal_name_by_type_and_seq(ccx, shim_fn_ty, "object_shim");
     let llfn =
-        decl_internal_rust_fn(ccx, method_bare_fn_ty, &function_name);
+        decl_internal_rust_fn(ccx, shim_fn_ty, &function_name);
 
     let sig = ty::erase_late_bound_regions(ccx.tcx(), &fty.sig);
 
@@ -652,9 +649,6 @@ pub fn trans_object_shim<'a, 'tcx>(
 
     assert!(!fcx.needs_ret_allocas);
 
-    let sig =
-        ty::erase_late_bound_regions(bcx.tcx(), &fty.sig);
-
     let dest =
         fcx.llretslotptr.get().map(
             |_| expr::SaveIn(fcx.get_ret_slot(bcx, sig.output, "ret_slot")));
@@ -687,11 +681,8 @@ pub fn trans_object_shim<'a, 'tcx>(
 ///
 /// The `trait_ref` encodes the erased self type. Hence if we are
 /// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
-/// `trait_ref` would map `T:Trait`, but `box_ty` would be
-/// `Foo<T>`. This `box_ty` is primarily used to encode the destructor.
-/// This will hopefully change now that DST is underway.
+/// `trait_ref` would map `T:Trait`.
 pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-                            box_ty: Ty<'tcx>,
                             trait_ref: ty::PolyTraitRef<'tcx>,
                             param_substs: &'tcx subst::Substs<'tcx>)
                             -> ValueRef
@@ -699,13 +690,10 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     let tcx = ccx.tcx();
     let _icx = push_ctxt("meth::get_vtable");
 
-    debug!("get_vtable(box_ty={}, trait_ref={})",
-           box_ty.repr(tcx),
-           trait_ref.repr(tcx));
+    debug!("get_vtable(trait_ref={})", trait_ref.repr(tcx));
 
     // Check the cache.
-    let cache_key = (box_ty, trait_ref.clone());
-    match ccx.vtables().borrow().get(&cache_key) {
+    match ccx.vtables().borrow().get(&trait_ref) {
         Some(&val) => { return val }
         None => { }
     }
@@ -714,6 +702,8 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     let methods = traits::supertraits(tcx, trait_ref.clone()).flat_map(|trait_ref| {
         let vtable = fulfill_obligation(ccx, DUMMY_SP, trait_ref.clone());
         match vtable {
+            // Should default trait error here?
+            traits::VtableDefaultImpl(_) |
             traits::VtableBuiltin(_) => {
                 Vec::new().into_iter()
             }
@@ -725,17 +715,18 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                 emit_vtable_methods(ccx, id, substs, param_substs).into_iter()
             }
             traits::VtableClosure(closure_def_id, substs) => {
-                let llfn = trans_fn_ref_with_substs(
-                    ccx,
-                    closure_def_id,
-                    ExprId(0),
-                    param_substs,
-                    substs).val;
-
+                let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_ref.def_id()).unwrap();
+                let llfn = closure::trans_closure_method(ccx,
+                                                         closure_def_id,
+                                                         substs,
+                                                         ExprId(0),
+                                                         param_substs,
+                                                         trait_closure_kind);
                 vec![llfn].into_iter()
             }
             traits::VtableFnPointer(bare_fn_ty) => {
-                vec![trans_fn_pointer_shim(ccx, bare_fn_ty)].into_iter()
+                let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_ref.def_id()).unwrap();
+                vec![trans_fn_pointer_shim(ccx, trait_closure_kind, bare_fn_ty)].into_iter()
             }
             traits::VtableObject(ref data) => {
                 // this would imply that the Self type being erased is
@@ -749,7 +740,7 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                 tcx.sess.bug(
                     &format!("resolved vtable for {} to bad vtable {} in trans",
                             trait_ref.repr(tcx),
-                            vtable.repr(tcx))[]);
+                            vtable.repr(tcx)));
             }
         }
     });
@@ -760,7 +751,7 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     let components: Vec<_> = vec![
         // Generate a destructor for the vtable.
-        glue::get_drop_glue(ccx, box_ty),
+        glue::get_drop_glue(ccx, trait_ref.self_ty()),
         C_uint(ccx, size),
         C_uint(ccx, align)
     ].into_iter().chain(methods).collect();
@@ -768,7 +759,7 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     let vtable = consts::addr_of(ccx, C_struct(ccx, &components, false),
                                  "vtable", trait_ref.def_id().node);
 
-    ccx.vtables().borrow_mut().insert(cache_key, vtable);
+    ccx.vtables().borrow_mut().insert(trait_ref, vtable);
     vtable
 }
 
@@ -776,9 +767,15 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                  impl_id: ast::DefId,
                                  substs: subst::Substs<'tcx>,
                                  param_substs: &'tcx subst::Substs<'tcx>)
-                                 -> Vec<ValueRef> {
+                                 -> Vec<ValueRef>
+{
     let tcx = ccx.tcx();
 
+    debug!("emit_vtable_methods(impl_id={}, substs={}, param_substs={})",
+           impl_id.repr(tcx),
+           substs.repr(tcx),
+           param_substs.repr(tcx));
+
     let trt_id = match ty::impl_trait_ref(tcx, impl_id) {
         Some(t_id) => t_id.def_id,
         None       => ccx.sess().bug("make_impl_vtable: don't know how to \
@@ -787,82 +784,87 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     ty::populate_implementations_for_trait_if_necessary(tcx, trt_id);
 
+    let nullptr = C_null(Type::nil(ccx).ptr_to());
     let trait_item_def_ids = ty::trait_item_def_ids(tcx, trt_id);
-    trait_item_def_ids.iter().flat_map(|method_def_id| {
-        let method_def_id = method_def_id.def_id();
-        let name = ty::impl_or_trait_item(tcx, method_def_id).name();
-        // The substitutions we have are on the impl, so we grab
-        // the method type from the impl to substitute into.
-        let m_id = method_with_name(ccx, impl_id, name);
-        let ti = ty::impl_or_trait_item(tcx, m_id);
-        match ti {
-            ty::MethodTraitItem(m) => {
-                debug!("(making impl vtable) emitting method {} at subst {}",
-                       m.repr(tcx),
-                       substs.repr(tcx));
-                if m.generics.has_type_params(subst::FnSpace) ||
-                    ty::type_has_self(ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(m.fty.clone())))
-                {
-                    debug!("(making impl vtable) method has self or type \
-                            params: {}",
-                           token::get_name(name));
-                    Some(C_null(Type::nil(ccx).ptr_to())).into_iter()
-                } else {
-                    let fn_ref = trans_fn_ref_with_substs(
-                        ccx,
-                        m_id,
-                        ExprId(0),
-                        param_substs,
-                        substs.clone()).val;
-
-                    // currently, at least, by-value self is not object safe
-                    assert!(m.explicit_self != ty::ByValueExplicitSelfCategory);
-
-                    Some(fn_ref).into_iter()
-                }
-            }
-            ty::TypeTraitItem(_) => {
-                None.into_iter()
+    trait_item_def_ids
+        .iter()
+
+        // Filter out the associated types.
+        .filter_map(|item_def_id| {
+            match *item_def_id {
+                ty::MethodTraitItemId(def_id) => Some(def_id),
+                ty::TypeTraitItemId(_) => None,
             }
-        }
-    }).collect()
-}
+        })
 
-/// Generates the code to convert from a pointer (`Box<T>`, `&T`, etc) into an object
-/// (`Box<Trait>`, `&Trait`, etc). This means creating a pair where the first word is the vtable
-/// and the second word is the pointer.
-pub fn trans_trait_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                    datum: Datum<'tcx, Expr>,
-                                    id: ast::NodeId,
-                                    trait_ref: ty::PolyTraitRef<'tcx>,
-                                    dest: expr::Dest)
-                                    -> Block<'blk, 'tcx> {
-    let mut bcx = bcx;
-    let _icx = push_ctxt("meth::trans_trait_cast");
+        // Now produce pointers for each remaining method. If the
+        // method could never be called from this object, just supply
+        // null.
+        .map(|trait_method_def_id| {
+            debug!("emit_vtable_methods: trait_method_def_id={}",
+                   trait_method_def_id.repr(tcx));
 
-    let lldest = match dest {
-        Ignore => {
-            return datum.clean(bcx, "trait_trait_cast", id);
-        }
-        SaveIn(dest) => dest
-    };
+            let trait_method_type = match ty::impl_or_trait_item(tcx, trait_method_def_id) {
+                ty::MethodTraitItem(m) => m,
+                ty::TypeTraitItem(_) => ccx.sess().bug("should be a method, not assoc type")
+            };
+            let name = trait_method_type.name;
+
+            // Some methods cannot be called on an object; skip those.
+            if !traits::is_vtable_safe_method(tcx, trt_id, &trait_method_type) {
+                debug!("emit_vtable_methods: not vtable safe");
+                return nullptr;
+            }
 
-    debug!("trans_trait_cast: trait_ref={}",
-           trait_ref.repr(bcx.tcx()));
+            debug!("emit_vtable_methods: trait_method_type={}",
+                   trait_method_type.repr(tcx));
 
-    let datum_ty = datum.ty;
-    let llbox_ty = type_of(bcx.ccx(), datum_ty);
+            // The substitutions we have are on the impl, so we grab
+            // the method type from the impl to substitute into.
+            let impl_method_def_id = method_with_name(ccx, impl_id, name);
+            let impl_method_type = match ty::impl_or_trait_item(tcx, impl_method_def_id) {
+                ty::MethodTraitItem(m) => m,
+                ty::TypeTraitItem(_) => ccx.sess().bug("should be a method, not assoc type")
+            };
 
-    // Store the pointer into the first half of pair.
-    let llboxdest = GEPi(bcx, lldest, &[0, abi::FAT_PTR_ADDR]);
-    let llboxdest = PointerCast(bcx, llboxdest, llbox_ty.ptr_to());
-    bcx = datum.store_to(bcx, llboxdest);
+            debug!("emit_vtable_methods: impl_method_type={}",
+                   impl_method_type.repr(tcx));
+
+            // If this is a default method, it's possible that it
+            // relies on where clauses that do not hold for this
+            // particular set of type parameters. Note that this
+            // method could then never be called, so we do not want to
+            // try and trans it, in that case. Issue #23435.
+            if ty::provided_source(tcx, impl_method_def_id).is_some() {
+                let predicates = impl_method_type.predicates.predicates.subst(tcx, &substs);
+                if !normalize_and_test_predicates(ccx, predicates.into_vec()) {
+                    debug!("emit_vtable_methods: predicates do not hold");
+                    return nullptr;
+                }
+            }
 
-    // Store the vtable into the second half of pair.
-    let vtable = get_vtable(bcx.ccx(), datum_ty, trait_ref, bcx.fcx.param_substs);
-    let llvtabledest = GEPi(bcx, lldest, &[0, abi::FAT_PTR_EXTRA]);
-    let llvtabledest = PointerCast(bcx, llvtabledest, val_ty(vtable).ptr_to());
-    Store(bcx, vtable, llvtabledest);
+            trans_fn_ref_with_substs(ccx,
+                                     impl_method_def_id,
+                                     ExprId(0),
+                                     param_substs,
+                                     substs.clone()).val
+        })
+        .collect()
+}
 
-    bcx
+/// Replace the self type (&Self or Box<Self>) with an opaque pointer.
+pub fn opaque_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, method_ty: &ty::BareFnTy<'tcx>)
+        -> &'tcx ty::BareFnTy<'tcx> {
+    let mut inputs = method_ty.sig.0.inputs.clone();
+    inputs[0] = ty::mk_mut_ptr(tcx, ty::mk_mach_int(tcx, ast::TyI8));
+
+    tcx.mk_bare_fn(ty::BareFnTy {
+        unsafety: method_ty.unsafety,
+        abi: method_ty.abi,
+        sig: ty::Binder(ty::FnSig {
+            inputs: inputs,
+            output: method_ty.sig.0.output,
+            variadic: method_ty.sig.0.variadic,
+        }),
+    })
 }
index f7433e6a774093de216abddf42379d9c492081ff..c7857d6a775f3f3163c81b191b5b5033f25b605e 100644 (file)
@@ -57,7 +57,7 @@ mod basic_block;
 mod llrepr;
 mod cleanup;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct ModuleTranslation {
     pub llcx: ContextRef,
     pub llmod: ModuleRef,
index ec48ab0d34a06b60d84d5312084649225a4816bd..dcb21c5cd93b1459ba2a06d45b55088a8462e15d 100644 (file)
@@ -29,7 +29,7 @@ use util::ppaux::Repr;
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{local_def, PostExpansionMethod};
+use syntax::ast_util::local_def;
 use syntax::attr;
 use syntax::codemap::DUMMY_SP;
 use std::hash::{Hasher, Hash, SipHasher};
@@ -177,7 +177,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                   ..
               } => {
                   let d = mk_lldecl(abi);
-                  let needs_body = setup_lldecl(d, &i.attrs[]);
+                  let needs_body = setup_lldecl(d, &i.attrs);
                   if needs_body {
                       if abi != abi::Rust {
                           foreign::trans_rust_fn_with_foreign_abi(
@@ -216,18 +216,18 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             }
             d
         }
-        ast_map::NodeImplItem(ii) => {
-            match *ii {
-                ast::MethodImplItem(ref mth) => {
+        ast_map::NodeImplItem(impl_item) => {
+            match impl_item.node {
+                ast::MethodImplItem(ref sig, ref body) => {
                     let d = mk_lldecl(abi::Rust);
-                    let needs_body = setup_lldecl(d, &mth.attrs[]);
+                    let needs_body = setup_lldecl(d, &impl_item.attrs);
                     if needs_body {
                         trans_fn(ccx,
-                                 mth.pe_fn_decl(),
-                                 mth.pe_body(),
+                                 &sig.decl,
+                                 body,
                                  d,
                                  psubsts,
-                                 mth.id,
+                                 impl_item.id,
                                  &[]);
                     }
                     d
@@ -235,22 +235,25 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                 ast::TypeImplItem(_) => {
                     ccx.sess().bug("can't monomorphize an associated type")
                 }
+                ast::MacImplItem(_) => {
+                    ccx.sess().bug("can't monomorphize an unexpanded macro")
+                }
             }
         }
-        ast_map::NodeTraitItem(method) => {
-            match *method {
-                ast::ProvidedMethod(ref mth) => {
+        ast_map::NodeTraitItem(trait_item) => {
+            match trait_item.node {
+                ast::MethodTraitItem(ref sig, Some(ref body)) => {
                     let d = mk_lldecl(abi::Rust);
-                    let needs_body = setup_lldecl(d, &mth.attrs[]);
+                    let needs_body = setup_lldecl(d, &trait_item.attrs);
                     if needs_body {
-                        trans_fn(ccx, mth.pe_fn_decl(), mth.pe_body(), d,
-                                 psubsts, mth.id, &[]);
+                        trans_fn(ccx, &sig.decl, body, d,
+                                 psubsts, trait_item.id, &[]);
                     }
                     d
                 }
                 _ => {
                     ccx.sess().bug(&format!("can't monomorphize a {:?}",
-                                           map_node)[])
+                                           map_node))
                 }
             }
         }
@@ -258,7 +261,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             let d = mk_lldecl(abi::Rust);
             set_inline_hint(d);
             base::trans_tuple_struct(ccx,
-                                     &struct_def.fields[],
+                                     &struct_def.fields,
                                      struct_def.ctor_id.expect("ast-mapped tuple struct \
                                                                 didn't have a ctor id"),
                                      psubsts,
@@ -276,7 +279,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         ast_map::NodePat(..) |
         ast_map::NodeLocal(..) => {
             ccx.sess().bug(&format!("can't monomorphize a {:?}",
-                                   map_node)[])
+                                   map_node))
         }
     };
 
@@ -336,7 +339,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
     for obligation in obligations {
         fulfill_cx.register_predicate_obligation(&infcx, obligation);
     }
-    let result = drain_fulfillment_cx(DUMMY_SP, &infcx, &mut fulfill_cx, &result);
+    let result = drain_fulfillment_cx_or_panic(DUMMY_SP, &infcx, &mut fulfill_cx, &result);
 
     result
 }
index 7b59e0258ee224c4ec6cdd91e4c012afa800c072..791b58d88a93e97d84e934371ad2df617c49c3f2 100644 (file)
@@ -12,7 +12,7 @@
 
 use back::abi;
 use llvm;
-use llvm::{ValueRef};
+use llvm::ValueRef;
 use trans::base::*;
 use trans::base;
 use trans::build::*;
@@ -24,8 +24,6 @@ use trans::datum::*;
 use trans::debuginfo::DebugLoc;
 use trans::expr::{Dest, Ignore, SaveIn};
 use trans::expr;
-use trans::glue;
-use trans::machine;
 use trans::machine::llsize_of_alloc;
 use trans::type_::Type;
 use trans::type_of;
@@ -35,80 +33,17 @@ use util::ppaux::ty_to_string;
 use syntax::ast;
 use syntax::parse::token::InternedString;
 
-fn get_len(bcx: Block, vptr: ValueRef) -> ValueRef {
-    let _icx = push_ctxt("tvec::get_lenl");
-    Load(bcx, expr::get_len(bcx, vptr))
-}
-
-fn get_dataptr(bcx: Block, vptr: ValueRef) -> ValueRef {
-    let _icx = push_ctxt("tvec::get_dataptr");
-    Load(bcx, expr::get_dataptr(bcx, vptr))
-}
-
-pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                          vptr: ValueRef,
-                                          unit_ty: Ty<'tcx>,
-                                          should_deallocate: bool)
-                                          -> Block<'blk, 'tcx> {
-    let not_null = IsNotNull(bcx, vptr);
-    with_cond(bcx, not_null, |bcx| {
-        let ccx = bcx.ccx();
-        let tcx = bcx.tcx();
-        let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
-
-        let dataptr = get_dataptr(bcx, vptr);
-        let bcx = if type_needs_drop(tcx, unit_ty) {
-            let len = get_len(bcx, vptr);
-            iter_vec_raw(bcx,
-                         dataptr,
-                         unit_ty,
-                         len,
-                         |bb, vv, tt| glue::drop_ty(bb, vv, tt, DebugLoc::None))
-        } else {
-            bcx
-        };
-
-        if should_deallocate {
-            let llty = type_of::type_of(ccx, unit_ty);
-            let unit_size = llsize_of_alloc(ccx, llty);
-            if unit_size != 0 {
-                let len = get_len(bcx, vptr);
-                let not_empty = ICmp(bcx,
-                                     llvm::IntNE,
-                                     len,
-                                     C_uint(ccx, 0_u32),
-                                     DebugLoc::None);
-                with_cond(bcx, not_empty, |bcx| {
-                    let llalign = C_uint(ccx, machine::llalign_of_min(ccx, llty));
-                    let size = Mul(bcx, C_uint(ccx, unit_size), len, DebugLoc::None);
-                    glue::trans_exchange_free_dyn(bcx,
-                                                  dataptr,
-                                                  size,
-                                                  llalign,
-                                                  DebugLoc::None)
-                })
-            } else {
-                bcx
-            }
-        } else {
-            bcx
-        }
-    })
-}
-
-#[derive(Copy)]
-pub struct VecTypes<'tcx> {
-    pub unit_ty: Ty<'tcx>,
-    pub llunit_ty: Type,
-    pub llunit_alloc_size: u64
+#[derive(Copy, Clone)]
+struct VecTypes<'tcx> {
+    unit_ty: Ty<'tcx>,
+    llunit_ty: Type
 }
 
 impl<'tcx> VecTypes<'tcx> {
     pub fn to_string<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> String {
-        format!("VecTypes {{unit_ty={}, llunit_ty={}, llunit_alloc_size={}}}",
+        format!("VecTypes {{unit_ty={}, llunit_ty={}}}",
                 ty_to_string(ccx.tcx(), self.unit_ty),
-                ccx.tn().type_to_string(self.llunit_ty),
-                self.llunit_alloc_size)
+                ccx.tn().type_to_string(self.llunit_ty))
     }
 }
 
@@ -222,12 +157,12 @@ pub fn trans_lit_str<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 }
 
-pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                 vt: &VecTypes<'tcx>,
-                                 vstore_expr: &ast::Expr,
-                                 content_expr: &ast::Expr,
-                                 dest: Dest)
-                                 -> Block<'blk, 'tcx> {
+fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                             vt: &VecTypes<'tcx>,
+                             vstore_expr: &ast::Expr,
+                             content_expr: &ast::Expr,
+                             dest: Dest)
+                             -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("tvec::write_content");
     let fcx = bcx.fcx;
     let mut bcx = bcx;
@@ -294,7 +229,7 @@ pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 }
                 SaveIn(lldest) => {
                     match ty::eval_repeat_count(bcx.tcx(), &**count_expr) {
-                        0 => bcx,
+                        0 => expr::trans_into(bcx, &**element, Ignore),
                         1 => expr::trans_into(bcx, &**element, SaveIn(lldest)),
                         count => {
                             let elem = unpack_datum!(bcx, expr::trans(bcx, &**element));
@@ -316,28 +251,21 @@ pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 }
 
-pub fn vec_types_from_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                       vec_expr: &ast::Expr)
-                                       -> VecTypes<'tcx> {
+fn vec_types_from_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, vec_expr: &ast::Expr)
+                                   -> VecTypes<'tcx> {
     let vec_ty = node_id_type(bcx, vec_expr.id);
     vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty))
 }
 
-pub fn vec_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                             unit_ty: Ty<'tcx>)
-                             -> VecTypes<'tcx> {
-    let ccx = bcx.ccx();
-    let llunit_ty = type_of::type_of(ccx, unit_ty);
-    let llunit_alloc_size = llsize_of_alloc(ccx, llunit_ty);
-
+fn vec_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, unit_ty: Ty<'tcx>)
+                         -> VecTypes<'tcx> {
     VecTypes {
         unit_ty: unit_ty,
-        llunit_ty: llunit_ty,
-        llunit_alloc_size: llunit_alloc_size
+        llunit_ty: type_of::type_of(bcx.ccx(), unit_ty)
     }
 }
 
-pub fn elements_required(bcx: Block, content_expr: &ast::Expr) -> uint {
+fn elements_required(bcx: Block, content_expr: &ast::Expr) -> usize {
     //! Figure out the number of elements we need to store this content
 
     match content_expr.node {
@@ -363,7 +291,7 @@ pub fn elements_required(bcx: Block, content_expr: &ast::Expr) -> uint {
 /// which should be by ref.
 pub fn get_fixed_base_and_len(bcx: Block,
                               llval: ValueRef,
-                              vec_length: uint)
+                              vec_length: usize)
                               -> (ValueRef, ValueRef) {
     let ccx = bcx.ccx();
 
@@ -372,54 +300,51 @@ pub fn get_fixed_base_and_len(bcx: Block,
     (base, len)
 }
 
-fn get_slice_base_and_len(bcx: Block,
-                          llval: ValueRef)
-                          -> (ValueRef, ValueRef) {
-    let base = Load(bcx, GEPi(bcx, llval, &[0, abi::FAT_PTR_ADDR]));
-    let len = Load(bcx, GEPi(bcx, llval, &[0, abi::FAT_PTR_EXTRA]));
-    (base, len)
-}
-
 /// Converts a vector into the slice pair.  The vector should be stored in `llval` which should be
 /// by-reference.  If you have a datum, you would probably prefer to call
 /// `Datum::get_base_and_len()` which will handle any conversions for you.
-pub fn get_base_and_len(bcx: Block,
-                        llval: ValueRef,
-                        vec_ty: Ty)
-                        -> (ValueRef, ValueRef) {
+pub fn get_base_and_len<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                                    llval: ValueRef,
+                                    vec_ty: Ty<'tcx>)
+                                    -> (ValueRef, ValueRef) {
     let ccx = bcx.ccx();
 
     match vec_ty.sty {
         ty::ty_vec(_, Some(n)) => get_fixed_base_and_len(bcx, llval, n),
-        ty::ty_open(ty) => match ty.sty {
-            ty::ty_vec(_, None) | ty::ty_str => get_slice_base_and_len(bcx, llval),
-            _ => ccx.sess().bug("unexpected type in get_base_and_len")
-        },
+        ty::ty_vec(_, None) | ty::ty_str => {
+            let base = Load(bcx, expr::get_dataptr(bcx, llval));
+            let len = Load(bcx, expr::get_len(bcx, llval));
+            (base, len)
+        }
 
         // Only used for pattern matching.
-        ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty.sty {
-            ty::ty_vec(_, None) | ty::ty_str => get_slice_base_and_len(bcx, llval),
-            ty::ty_vec(_, Some(n)) => {
-                let base = GEPi(bcx, Load(bcx, llval), &[0, 0]);
-                (base, C_uint(ccx, n))
-            }
-            _ => ccx.sess().bug("unexpected type in get_base_and_len"),
+        ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => {
+            let inner = if type_is_sized(bcx.tcx(), ty) {
+                Load(bcx, llval)
+            } else {
+                llval
+            };
+            get_base_and_len(bcx, inner, ty)
         },
         _ => ccx.sess().bug("unexpected type in get_base_and_len"),
     }
 }
 
-pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
-                                     data_ptr: ValueRef,
-                                     vt: &VecTypes<'tcx>,
-                                     count: ValueRef,
-                                     f: F)
-                                     -> Block<'blk, 'tcx> where
+fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
+                                data_ptr: ValueRef,
+                                vt: &VecTypes<'tcx>,
+                                count: ValueRef,
+                                f: F)
+                                -> Block<'blk, 'tcx> where
     F: FnOnce(Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
 {
     let _icx = push_ctxt("tvec::iter_vec_loop");
-    let fcx = bcx.fcx;
 
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
+    let fcx = bcx.fcx;
     let loop_bcx = fcx.new_temp_block("expr_repeat");
     let next_bcx = fcx.new_temp_block("expr_repeat: next");
 
@@ -430,7 +355,7 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
 
     let bcx = loop_bcx;
 
-    let lleltptr = if vt.llunit_alloc_size == 0 {
+    let lleltptr = if llsize_of_alloc(bcx.ccx(), vt.llunit_ty) == 0 {
         data_ptr
     } else {
         InBoundsGEP(bcx, data_ptr, &[loop_counter])
@@ -458,7 +383,7 @@ pub fn iter_vec_raw<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
 
     let vt = vec_types(bcx, unit_ty);
 
-    if vt.llunit_alloc_size == 0 {
+    if llsize_of_alloc(bcx.ccx(), vt.llunit_ty) == 0 {
         // Special-case vectors with elements of size 0  so they don't go out of bounds (#9890)
         iter_vec_loop(bcx, data_ptr, &vt, len, f)
     } else {
@@ -475,7 +400,7 @@ pub fn iter_vec_raw<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
         let body_bcx = fcx.new_temp_block("iter_vec_loop_body");
         let next_bcx = fcx.new_temp_block("iter_vec_next");
         CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb, DebugLoc::None);
-        let body_bcx = f(body_bcx, data_ptr, vt.unit_ty);
+        let body_bcx = f(body_bcx, data_ptr, unit_ty);
         AddIncomingToPhi(data_ptr, InBoundsGEP(body_bcx, data_ptr,
                                                &[C_int(bcx.ccx(), 1)]),
                          body_bcx.llbb);
index ad83135a0d46fa3681df8b6f4d6bc2cb8b7d7d64..339b4734ee4b1b82da3ed88cf46794314666ade2 100644 (file)
@@ -109,7 +109,7 @@ impl Type {
     }
 
     pub fn int(ccx: &CrateContext) -> Type {
-        match &ccx.tcx().sess.target.target.target_pointer_width[] {
+        match &ccx.tcx().sess.target.target.target_pointer_width[..] {
             "32" => Type::i32(ccx),
             "64" => Type::i64(ccx),
             tws => panic!("Unsupported target word size for int: {}", tws),
@@ -118,7 +118,7 @@ impl Type {
 
     pub fn int_from_ty(ccx: &CrateContext, t: ast::IntTy) -> Type {
         match t {
-            ast::TyIs(_) => ccx.int_type(),
+            ast::TyIs => ccx.int_type(),
             ast::TyI8 => Type::i8(ccx),
             ast::TyI16 => Type::i16(ccx),
             ast::TyI32 => Type::i32(ccx),
@@ -128,7 +128,7 @@ impl Type {
 
     pub fn uint_from_ty(ccx: &CrateContext, t: ast::UintTy) -> Type {
         match t {
-            ast::TyUs(_) => ccx.int_type(),
+            ast::TyUs => ccx.int_type(),
             ast::TyU8 => Type::i8(ccx),
             ast::TyU16 => Type::i16(ccx),
             ast::TyU32 => Type::i32(ccx),
@@ -175,41 +175,10 @@ impl Type {
         Type::array(&Type::i8p(ccx).ptr_to(), 1)
     }
 
-    pub fn generic_glue_fn(cx: &CrateContext) -> Type {
-        match cx.tn().find_type("glue_fn") {
-            Some(ty) => return ty,
-            None => ()
-        }
-
-        let ty = Type::glue_fn(cx, Type::i8p(cx));
-        cx.tn().associate_type("glue_fn", &ty);
-
-        ty
-    }
-
     pub fn glue_fn(ccx: &CrateContext, t: Type) -> Type {
         Type::func(&[t], &Type::void(ccx))
     }
 
-    pub fn tydesc(ccx: &CrateContext, str_slice_ty: Type) -> Type {
-        let mut tydesc = Type::named_struct(ccx, "tydesc");
-        let glue_fn_ty = Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to();
-
-        let int_ty = Type::int(ccx);
-
-        // Must mirror:
-        //
-        // std::unstable::intrinsics::TyDesc
-
-        let elems = [int_ty,     // size
-                     int_ty,     // align
-                     glue_fn_ty, // drop
-                     str_slice_ty]; // name
-        tydesc.set_struct_body(&elems, false);
-
-        tydesc
-    }
-
     pub fn array(ty: &Type, len: u64) -> Type {
         ty!(llvm::LLVMRustArrayType(ty.to_ref(), len))
     }
@@ -232,14 +201,6 @@ impl Type {
         Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to().ptr_to()
     }
 
-    pub fn opaque_trait(ccx: &CrateContext) -> Type {
-        Type::struct_(ccx, &[Type::opaque_trait_data(ccx).ptr_to(), Type::vtable_ptr(ccx)], false)
-    }
-
-    pub fn opaque_trait_data(ccx: &CrateContext) -> Type {
-        Type::i8(ccx)
-    }
-
     pub fn kind(&self) -> TypeKind {
         unsafe {
             llvm::LLVMGetTypeKind(self.to_ref())
@@ -278,21 +239,21 @@ impl Type {
     }
 
     /// Return the number of elements in `self` if it is a LLVM vector type.
-    pub fn vector_length(&self) -> uint {
+    pub fn vector_length(&self) -> usize {
         unsafe {
-            llvm::LLVMGetVectorSize(self.to_ref()) as uint
+            llvm::LLVMGetVectorSize(self.to_ref()) as usize
         }
     }
 
-    pub fn array_length(&self) -> uint {
+    pub fn array_length(&self) -> usize {
         unsafe {
-            llvm::LLVMGetArrayLength(self.to_ref()) as uint
+            llvm::LLVMGetArrayLength(self.to_ref()) as usize
         }
     }
 
     pub fn field_types(&self) -> Vec<Type> {
         unsafe {
-            let n_elts = llvm::LLVMCountStructElementTypes(self.to_ref()) as uint;
+            let n_elts = llvm::LLVMCountStructElementTypes(self.to_ref()) as usize;
             if n_elts == 0 {
                 return Vec::new();
             }
@@ -309,7 +270,7 @@ impl Type {
 
     pub fn func_params(&self) -> Vec<Type> {
         unsafe {
-            let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as uint;
+            let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as usize;
             let mut args: Vec<_> = repeat(Type { rf: ptr::null_mut() }).take(n_args).collect();
             llvm::LLVMGetParamTypes(self.to_ref(),
                                     args.as_mut_ptr() as *mut TypeRef);
@@ -317,7 +278,7 @@ impl Type {
         }
     }
 
-    pub fn float_width(&self) -> uint {
+    pub fn float_width(&self) -> usize {
         match self.kind() {
             Float => 32,
             Double => 64,
index 489b56bbe6825f567968c2bc802549a21fcaf34b..2e577a0bd19b0a0e232dd0a01de4e1a86fd2723d 100644 (file)
@@ -10,8 +10,6 @@
 
 #![allow(non_camel_case_types)]
 
-pub use self::named_ty::*;
-
 use middle::subst;
 use trans::adt;
 use trans::common::*;
@@ -23,6 +21,7 @@ use util::ppaux::Repr;
 
 use trans::type_::Type;
 
+#[allow(deprecated)]
 use std::num::Int;
 use syntax::abi;
 use syntax::ast;
@@ -183,9 +182,8 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
     }
 
     let llsizingty = match t.sty {
-        _ if !lltype_is_sized(cx.tcx(), t) => {
-            cx.sess().bug(&format!("trying to take the sizing type of {}, an unsized type",
-                                  ppaux::ty_to_string(cx.tcx(), t))[])
+        _ if !type_is_sized(cx.tcx(), t) => {
+            Type::struct_(cx, &[Type::i8p(cx), Type::i8p(cx)], false)
         }
 
         ty::ty_bool => Type::bool(cx),
@@ -232,15 +230,11 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
             }
         }
 
-        ty::ty_open(_) => {
-            Type::struct_(cx, &[Type::i8p(cx), Type::i8p(cx)], false)
-        }
-
         ty::ty_projection(..) | ty::ty_infer(..) | ty::ty_param(..) | ty::ty_err(..) => {
             cx.sess().bug(&format!("fictitious type {} in sizing_type_of()",
-                                  ppaux::ty_to_string(cx.tcx(), t))[])
+                                  ppaux::ty_to_string(cx.tcx(), t)))
         }
-        ty::ty_vec(_, None) | ty::ty_trait(..) | ty::ty_str => panic!("unreachable")
+        ty::ty_vec(_, None) | ty::ty_trait(..) | ty::ty_str => unreachable!()
     };
 
     cx.llsizingtypes().borrow_mut().insert(t, llsizingty);
@@ -270,25 +264,37 @@ pub fn arg_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
     }
 }
 
-// NB: If you update this, be sure to update `sizing_type_of()` as well.
-pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
-    fn type_of_unsize_info<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
-        // It is possible to end up here with a sized type. This happens with a
-        // struct which might be unsized, but is monomorphised to a sized type.
-        // In this case we'll fake a fat pointer with no unsize info (we use 0).
-        // However, its still a fat pointer, so we need some type use.
-        if type_is_sized(cx.tcx(), t) {
-            return Type::i8p(cx);
-        }
-
-        match unsized_part_of_type(cx.tcx(), t).sty {
-            ty::ty_str | ty::ty_vec(..) => Type::uint_from_ty(cx, ast::TyUs(false)),
-            ty::ty_trait(_) => Type::vtable_ptr(cx),
-            _ => panic!("Unexpected type returned from unsized_part_of_type : {}",
-                       t.repr(cx.tcx()))
-        }
-    }
+/// Get the LLVM type corresponding to a Rust type, i.e. `middle::ty::Ty`.
+/// This is the right LLVM type for an alloca containing a value of that type,
+/// and the pointee of an Lvalue Datum (which is always a LLVM pointer).
+/// For unsized types, the returned type is a fat pointer, thus the resulting
+/// LLVM type for a `Trait` Lvalue is `{ i8*, void(i8*)** }*`, which is a double
+/// indirection to the actual data, unlike a `i8` Lvalue, which is just `i8*`.
+/// This is needed due to the treatment of immediate values, as a fat pointer
+/// is too large for it to be placed in SSA value (by our rules).
+/// For the raw type without far pointer indirection, see `in_memory_type_of`.
+pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> Type {
+    let ty = if !type_is_sized(cx.tcx(), ty) {
+        ty::mk_imm_ptr(cx.tcx(), ty)
+    } else {
+        ty
+    };
+    in_memory_type_of(cx, ty)
+}
 
+/// Get the LLVM type corresponding to a Rust type, i.e. `middle::ty::Ty`.
+/// This is the right LLVM type for a field/array element of that type,
+/// and is the same as `type_of` for all Sized types.
+/// Unsized types, however, are represented by a "minimal unit", e.g.
+/// `[T]` becomes `T`, while `str` and `Trait` turn into `i8` - this
+/// is useful for indexing slices, as `&[T]`'s data pointer is `T*`.
+/// If the type is an unsized struct, the regular layout is generated,
+/// with the inner-most trailing unsized field using the "minimal unit"
+/// of that field's type - this is useful for taking the address of
+/// that field and ensuring the struct has the right alignment.
+/// For the LLVM type of a value as a whole, see `type_of`.
+/// NB: If you update this, be sure to update `sizing_type_of()` as well.
+pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
     // Check the cache.
     match cx.lltypes().borrow().get(&t) {
         Some(&llty) => return llty,
@@ -307,7 +313,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
     let t_norm = erase_regions(cx.tcx(), &t);
 
     if t != t_norm {
-        let llty = type_of(cx, t_norm);
+        let llty = in_memory_type_of(cx, t_norm);
         debug!("--> normalized {} {:?} to {} {:?} llty={}",
                 t.repr(cx.tcx()),
                 t,
@@ -331,10 +337,10 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
           // of the enum's variants refers to the enum itself.
           let repr = adt::represent_type(cx, t);
           let tps = substs.types.get_slice(subst::TypeSpace);
-          let name = llvm_type_name(cx, an_enum, did, tps);
+          let name = llvm_type_name(cx, did, tps);
           adt::incomplete_type_of(cx, &*repr, &name[..])
       }
-      ty::ty_closure(did, _, ref substs) => {
+      ty::ty_closure(..) => {
           // Only create the named struct, but don't fill it in. We
           // fill it in *after* placing it into the type cache.
           let repr = adt::represent_type(cx, t);
@@ -342,41 +348,47 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
           // inherited from their environment, so we use entire
           // contents of the VecPerParamSpace to to construct the llvm
           // name
-          let name = llvm_type_name(cx, a_closure, did, substs.types.as_slice());
-          adt::incomplete_type_of(cx, &*repr, &name[..])
+          adt::incomplete_type_of(cx, &*repr, "closure")
       }
 
       ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) | ty::ty_ptr(ty::mt{ty, ..}) => {
-          match ty.sty {
-              ty::ty_str => {
+          if !type_is_sized(cx.tcx(), ty) {
+              if let ty::ty_str = ty.sty {
                   // This means we get a nicer name in the output (str is always
                   // unsized).
                   cx.tn().find_type("str_slice").unwrap()
+              } else {
+                  let ptr_ty = in_memory_type_of(cx, ty).ptr_to();
+                  let unsized_part = unsized_part_of_type(cx.tcx(), ty);
+                  let info_ty = match unsized_part.sty {
+                      ty::ty_str | ty::ty_vec(..) => {
+                          Type::uint_from_ty(cx, ast::TyUs)
+                      }
+                      ty::ty_trait(_) => Type::vtable_ptr(cx),
+                      _ => panic!("Unexpected type returned from \
+                                   unsized_part_of_type: {} for ty={}",
+                                  unsized_part.repr(cx.tcx()), ty.repr(cx.tcx()))
+                  };
+                  Type::struct_(cx, &[ptr_ty, info_ty], false)
               }
-              ty::ty_trait(..) => Type::opaque_trait(cx),
-              _ if !type_is_sized(cx.tcx(), ty) => {
-                  let p_ty = type_of(cx, ty).ptr_to();
-                  Type::struct_(cx, &[p_ty, type_of_unsize_info(cx, ty)], false)
-              }
-              _ => type_of(cx, ty).ptr_to(),
+          } else {
+              in_memory_type_of(cx, ty).ptr_to()
           }
       }
 
       ty::ty_vec(ty, Some(size)) => {
           let size = size as u64;
-          let llty = type_of(cx, ty);
+          let llty = in_memory_type_of(cx, ty);
           ensure_array_fits_in_address_space(cx, llty, size, t);
           Type::array(&llty, size)
       }
-      ty::ty_vec(ty, None) => {
-          type_of(cx, ty)
-      }
 
-      ty::ty_trait(..) => {
-          Type::opaque_trait_data(cx)
-      }
-
-      ty::ty_str => Type::i8(cx),
+      // Unsized slice types (and str) have the type of their element, and
+      // traits have the type of u8. This is so that the data pointer inside
+      // fat pointers is of the right type (e.g. for array accesses), even
+      // when taking the address of an unsized field in a struct.
+      ty::ty_vec(ty, None) => in_memory_type_of(cx, ty),
+      ty::ty_str | ty::ty_trait(..) => Type::i8(cx),
 
       ty::ty_bare_fn(..) => {
           type_of_fn_from_ty(cx, t).ptr_to()
@@ -388,7 +400,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
       }
       ty::ty_struct(did, ref substs) => {
           if ty::type_is_simd(cx.tcx(), t) {
-              let llet = type_of(cx, ty::simd_type(cx.tcx(), t));
+              let llet = in_memory_type_of(cx, ty::simd_type(cx.tcx(), t));
               let n = ty::simd_size(cx.tcx(), t) as u64;
               ensure_array_fits_in_address_space(cx, llet, n, t);
               Type::vector(&llet, n)
@@ -398,29 +410,11 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
               // infinite recursion with recursive struct types.
               let repr = adt::represent_type(cx, t);
               let tps = substs.types.get_slice(subst::TypeSpace);
-              let name = llvm_type_name(cx, a_struct, did, tps);
+              let name = llvm_type_name(cx, did, tps);
               adt::incomplete_type_of(cx, &*repr, &name[..])
           }
       }
 
-      ty::ty_open(t) => match t.sty {
-          ty::ty_struct(..) => {
-              let p_ty = type_of(cx, t).ptr_to();
-              Type::struct_(cx, &[p_ty, type_of_unsize_info(cx, t)], false)
-          }
-          ty::ty_vec(ty, None) => {
-              let p_ty = type_of(cx, ty).ptr_to();
-              Type::struct_(cx, &[p_ty, type_of_unsize_info(cx, t)], false)
-          }
-          ty::ty_str => {
-              let p_ty = Type::i8p(cx);
-              Type::struct_(cx, &[p_ty, type_of_unsize_info(cx, t)], false)
-          }
-          ty::ty_trait(..) => Type::opaque_trait(cx),
-          _ => cx.sess().bug(&format!("ty_open with sized type: {}",
-                                     ppaux::ty_to_string(cx.tcx(), t))[])
-      },
-
       ty::ty_infer(..) => cx.sess().bug("type_of with ty_infer"),
       ty::ty_projection(..) => cx.sess().bug("type_of with ty_projection"),
       ty::ty_param(..) => cx.sess().bug("type_of with ty_param"),
@@ -444,7 +438,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
         _ => ()
     }
 
-    return llty;
+    llty
 }
 
 pub fn align_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
@@ -453,37 +447,22 @@ pub fn align_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
     machine::llalign_of_min(cx, llty)
 }
 
-// Want refinements! (Or case classes, I guess
-#[derive(Copy)]
-pub enum named_ty {
-    a_struct,
-    an_enum,
-    a_closure,
-}
-
-pub fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
-                                what: named_ty,
-                                did: ast::DefId,
-                                tps: &[Ty<'tcx>])
-                                -> String {
-    let name = match what {
-        a_struct => "struct",
-        an_enum => "enum",
-        a_closure => return "closure".to_string(),
-    };
-
+fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
+                            did: ast::DefId,
+                            tps: &[Ty<'tcx>])
+                            -> String {
     let base = ty::item_path_str(cx.tcx(), did);
     let strings: Vec<String> = tps.iter().map(|t| t.repr(cx.tcx())).collect();
     let tstr = if strings.is_empty() {
         base
     } else {
-        format!("{}<{:?}>", base, strings)
+        format!("{}<{}>", base, strings.connect(", "))
     };
 
     if did.krate == 0 {
-        format!("{}.{}", name, tstr)
+        tstr
     } else {
-        format!("{}.{}[{}{}]", name, tstr, "#", did.krate)
+        format!("{}.{}", did.krate, tstr)
     }
 }
 
index 464522f167b472b6aa46667095e1b1ba999bc547..bc71278c157434988a59da92ab11681d4b141976 100644 (file)
@@ -14,7 +14,7 @@ use trans::basic_block::BasicBlock;
 use trans::common::Block;
 use libc::c_uint;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Value(pub ValueRef);
 
 macro_rules! opt_val { ($e:expr) => (
@@ -107,7 +107,7 @@ impl Value {
 
     /// Returns the requested operand of this instruction
     /// Returns None, if there's no operand at the given index
-    pub fn get_operand(self, i: uint) -> Option<Value> {
+    pub fn get_operand(self, i: usize) -> Option<Value> {
         opt_val!(llvm::LLVMGetOperand(self.get(), i as c_uint))
     }
 
@@ -125,7 +125,7 @@ impl Value {
 }
 
 /// Wrapper for LLVM UseRef
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Use(UseRef);
 
 impl Use {
index e3c1c66f78c9c47774ee1740b52a42a538f45c37..939142cff1c32b6d7aba9d61bf675e7fc75c0cdd 100644 (file)
 //! case but `&a` in the second.  Basically, defaults that appear inside
 //! an rptr (`&r.T`) use the region `r` that appears in the rptr.
 
-use middle::astconv_util::{ast_ty_to_prim_ty, check_path_args, NO_TPS, NO_REGIONS};
+use middle::astconv_util::{prim_ty_to_ty, check_path_args, NO_TPS, NO_REGIONS};
 use middle::const_eval;
 use middle::def;
 use middle::resolve_lifetime as rl;
+use middle::privacy::{AllPublic, LastMod};
 use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
 use middle::traits;
-use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty};
+use middle::ty::{self, RegionEscape, Ty};
 use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
              ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope};
-use TypeAndSubsts;
 use util::common::{ErrorReported, FN_OUTPUT_NAME};
-use util::nodemap::DefIdMap;
 use util::ppaux::{self, Repr, UserString};
 
-use std::rc::Rc;
 use std::iter::{repeat, AdditiveIterator};
+use std::rc::Rc;
+use std::slice;
 use syntax::{abi, ast, ast_util};
 use syntax::codemap::Span;
 use syntax::parse::token;
@@ -72,9 +72,32 @@ use syntax::print::pprust;
 pub trait AstConv<'tcx> {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
 
-    fn get_item_type_scheme(&self, id: ast::DefId) -> ty::TypeScheme<'tcx>;
-
-    fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef<'tcx>>;
+    /// Identify the type scheme for an item with a type, like a type
+    /// alias, fn, or struct. This allows you to figure out the set of
+    /// type parameters defined on the item.
+    fn get_item_type_scheme(&self, span: Span, id: ast::DefId)
+                            -> Result<ty::TypeScheme<'tcx>, ErrorReported>;
+
+    /// Returns the `TraitDef` for a given trait. This allows you to
+    /// figure out the set of type parameters defined on the trait.
+    fn get_trait_def(&self, span: Span, id: ast::DefId)
+                     -> Result<Rc<ty::TraitDef<'tcx>>, ErrorReported>;
+
+    /// Ensure that the super-predicates for the trait with the given
+    /// id are available and also for the transitive set of
+    /// super-predicates.
+    fn ensure_super_predicates(&self, span: Span, id: ast::DefId)
+                               -> Result<(), ErrorReported>;
+
+    /// Returns the set of bounds in scope for the type parameter with
+    /// the given id.
+    fn get_type_parameter_bounds(&self, span: Span, def_id: ast::NodeId)
+                                 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>;
+
+    /// Returns true if the trait with id `trait_def_id` defines an
+    /// associated type with the name `name`.
+    fn trait_defines_associated_type_named(&self, trait_def_id: ast::DefId, name: ast::Name)
+                                           -> bool;
 
     /// Return an (optional) substitution to convert bound type parameters that
     /// are in scope into free ones. This function should only return Some
@@ -117,13 +140,7 @@ pub trait AstConv<'tcx> {
                     span: Span,
                     _trait_ref: Rc<ty::TraitRef<'tcx>>,
                     _item_name: ast::Name)
-                    -> Ty<'tcx>
-    {
-        span_err!(self.tcx().sess, span, E0213,
-            "associated types are not accepted in this context");
-
-        self.tcx().types.err
-    }
+                    -> Ty<'tcx>;
 }
 
 pub fn ast_region_to_region(tcx: &ty::ctxt, lifetime: &ast::Lifetime)
@@ -195,29 +212,29 @@ pub fn opt_ast_region_to_region<'tcx>(
                                     help_name
                                 } else {
                                     format!("one of {}'s {} elided lifetimes", help_name, n)
-                                })[]);
+                                })[..]);
 
                                 if len == 2 && i == 0 {
                                     m.push_str(" or ");
-                                } else if i == len - 2 {
+                                } else if i + 2 == len {
                                     m.push_str(", or ");
-                                } else if i != len - 1 {
+                                } else if i + 1 != len {
                                     m.push_str(", ");
                                 }
                             }
                             if len == 1 {
-                                span_help!(this.tcx().sess, default_span,
+                                fileline_help!(this.tcx().sess, default_span,
                                     "this function's return type contains a borrowed value, but \
                                      the signature does not say which {} it is borrowed from",
                                     m);
                             } else if len == 0 {
-                                span_help!(this.tcx().sess, default_span,
+                                fileline_help!(this.tcx().sess, default_span,
                                     "this function's return type contains a borrowed value, but \
                                      there is no value for it to be borrowed from");
-                                span_help!(this.tcx().sess, default_span,
+                                fileline_help!(this.tcx().sess, default_span,
                                     "consider giving it a 'static lifetime");
                             } else {
-                                span_help!(this.tcx().sess, default_span,
+                                fileline_help!(this.tcx().sess, default_span,
                                     "this function's return type contains a borrowed value, but \
                                      the signature does not say whether it is borrowed from {}",
                                     m);
@@ -245,8 +262,10 @@ pub fn opt_ast_region_to_region<'tcx>(
 pub fn ast_path_substs_for_ty<'tcx>(
     this: &AstConv<'tcx>,
     rscope: &RegionScope,
+    span: Span,
+    param_mode: PathParamMode,
     decl_generics: &ty::Generics<'tcx>,
-    path: &ast::Path)
+    item_segment: &ast::PathSegment)
     -> Substs<'tcx>
 {
     let tcx = this.tcx();
@@ -262,27 +281,36 @@ pub fn ast_path_substs_for_ty<'tcx>(
     assert!(decl_generics.regions.all(|d| d.space == TypeSpace));
     assert!(decl_generics.types.all(|d| d.space != FnSpace));
 
-    let (regions, types, assoc_bindings) = match path.segments.last().unwrap().parameters {
+    let (regions, types, assoc_bindings) = match item_segment.parameters {
         ast::AngleBracketedParameters(ref data) => {
-            convert_angle_bracketed_parameters(this, rscope, path.span, decl_generics, data)
+            convert_angle_bracketed_parameters(this, rscope, span, decl_generics, data)
         }
         ast::ParenthesizedParameters(ref data) => {
-            span_err!(tcx.sess, path.span, E0214,
+            span_err!(tcx.sess, span, E0214,
                 "parenthesized parameters may only be used with a trait");
-            convert_parenthesized_parameters(this, rscope, path.span, decl_generics, data)
+            convert_parenthesized_parameters(this, rscope, span, decl_generics, data)
         }
     };
 
     prohibit_projections(this.tcx(), &assoc_bindings);
 
     create_substs_for_ast_path(this,
-                               path.span,
+                               span,
+                               param_mode,
                                decl_generics,
                                None,
                                types,
                                regions)
 }
 
+#[derive(PartialEq, Eq)]
+pub enum PathParamMode {
+    // Any path in a type context.
+    Explicit,
+    // The `module::Type` in `module::Type::method` in an expression.
+    Optional
+}
+
 fn create_region_substs<'tcx>(
     this: &AstConv<'tcx>,
     rscope: &RegionScope,
@@ -305,9 +333,9 @@ fn create_region_substs<'tcx>(
             rscope.anon_regions(span, expected_num_region_params);
 
         if supplied_num_region_params != 0 || anon_regions.is_err() {
-            span_err!(tcx.sess, span, E0107,
-                      "wrong number of lifetime parameters: expected {}, found {}",
-                      expected_num_region_params, supplied_num_region_params);
+            report_lifetime_number_error(tcx, span,
+                                         supplied_num_region_params,
+                                         expected_num_region_params);
         }
 
         match anon_regions {
@@ -330,6 +358,7 @@ fn create_region_substs<'tcx>(
 fn create_substs_for_ast_path<'tcx>(
     this: &AstConv<'tcx>,
     span: Span,
+    param_mode: PathParamMode,
     decl_generics: &ty::Generics<'tcx>,
     self_ty: Option<Ty<'tcx>>,
     types_provided: Vec<Ty<'tcx>>,
@@ -348,38 +377,29 @@ fn create_substs_for_ast_path<'tcx>(
 
     // Convert the type parameters supplied by the user.
     let ty_param_defs = decl_generics.types.get_slice(TypeSpace);
-    let supplied_ty_param_count = types_provided.len();
     let formal_ty_param_count = ty_param_defs.len();
     let required_ty_param_count = ty_param_defs.iter()
                                                .take_while(|x| x.default.is_none())
                                                .count();
 
-    let mut type_substs = types_provided;
+    // Fill with `ty_infer` if no params were specified, as long as
+    // they were optional (e.g. paths inside expressions).
+    let mut type_substs = if param_mode == PathParamMode::Optional &&
+                             types_provided.is_empty() {
+        (0..formal_ty_param_count).map(|_| this.ty_infer(span)).collect()
+    } else {
+        types_provided
+    };
+
+    let supplied_ty_param_count = type_substs.len();
+    check_type_argument_count(this.tcx(), span, supplied_ty_param_count,
+                              required_ty_param_count, formal_ty_param_count);
+
     if supplied_ty_param_count < required_ty_param_count {
-        let expected = if required_ty_param_count < formal_ty_param_count {
-            "expected at least"
-        } else {
-            "expected"
-        };
-        span_err!(this.tcx().sess, span, E0243,
-                  "wrong number of type arguments: {} {}, found {}",
-                  expected,
-                  required_ty_param_count,
-                  supplied_ty_param_count);
         while type_substs.len() < required_ty_param_count {
             type_substs.push(tcx.types.err);
         }
     } else if supplied_ty_param_count > formal_ty_param_count {
-        let expected = if required_ty_param_count < formal_ty_param_count {
-            "expected at most"
-        } else {
-            "expected"
-        };
-        span_err!(this.tcx().sess, span, E0244,
-                  "wrong number of type arguments: {} {}, found {}",
-                  expected,
-                  formal_ty_param_count,
-                  supplied_ty_param_count);
         type_substs.truncate(formal_ty_param_count);
     }
     assert!(type_substs.len() >= required_ty_param_count &&
@@ -431,7 +451,7 @@ fn create_substs_for_ast_path<'tcx>(
         }
     }
 
-    return substs;
+    substs
 }
 
 struct ConvertedBinding<'tcx> {
@@ -478,9 +498,9 @@ fn convert_angle_bracketed_parameters<'tcx>(this: &AstConv<'tcx>,
 /// (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)>)
+                              -> (Option<ty::Region>, Vec<(String, usize)>)
 {
-    let mut lifetimes_for_params: Vec<(String, uint)> = Vec::new();
+    let mut lifetimes_for_params: Vec<(String, usize)> = Vec::new();
     let mut possible_implied_output_region = None;
 
     for (input_type, input_pat) in input_tys.iter().zip(input_pats.into_iter()) {
@@ -508,7 +528,7 @@ fn find_implied_output_region(input_tys: &[Ty], input_pats: Vec<String>)
 
 fn convert_ty_with_lifetime_elision<'tcx>(this: &AstConv<'tcx>,
                                           implied_output_region: Option<ty::Region>,
-                                          param_lifetimes: Vec<(String, uint)>,
+                                          param_lifetimes: Vec<(String, usize)>,
                                           ty: &ast::Ty)
                                           -> Ty<'tcx>
 {
@@ -582,24 +602,16 @@ pub fn instantiate_poly_trait_ref<'tcx>(
     poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
     -> ty::PolyTraitRef<'tcx>
 {
-    let mut projections = Vec::new();
-
-    // The trait reference introduces a binding level here, so
-    // we need to shift the `rscope`. It'd be nice if we could
-    // do away with this rscope stuff and work this knowledge
-    // into resolve_lifetimes, as we do with non-omitted
-    // lifetimes. Oh well, not there yet.
-    let shifted_rscope = ShiftedRscope::new(rscope);
-
-    let trait_ref =
-        instantiate_trait_ref(this, &shifted_rscope, &ast_trait_ref.trait_ref,
-                              self_ty, Some(&mut projections));
-
-    for projection in projections {
-        poly_projections.push(ty::Binder(projection));
-    }
-
-    ty::Binder(trait_ref)
+    let trait_ref = &ast_trait_ref.trait_ref;
+    let trait_def_id = trait_def_id(this, trait_ref);
+    ast_path_to_poly_trait_ref(this,
+                               rscope,
+                               trait_ref.path.span,
+                               PathParamMode::Explicit,
+                               trait_def_id,
+                               self_ty,
+                               trait_ref.path.segments.last().unwrap(),
+                               poly_projections)
 }
 
 /// Instantiates the path for the given trait reference, assuming that it's
@@ -608,29 +620,30 @@ pub fn instantiate_poly_trait_ref<'tcx>(
 ///
 /// If the `projections` argument is `None`, then assoc type bindings like `Foo<T=X>`
 /// are disallowed. Otherwise, they are pushed onto the vector given.
-pub fn instantiate_trait_ref<'tcx>(
+pub fn instantiate_mono_trait_ref<'tcx>(
     this: &AstConv<'tcx>,
     rscope: &RegionScope,
-    ast_trait_ref: &ast::TraitRef,
-    self_ty: Option<Ty<'tcx>>,
-    projections: Option<&mut Vec<ty::ProjectionPredicate<'tcx>>>)
+    trait_ref: &ast::TraitRef,
+    self_ty: Option<Ty<'tcx>>)
     -> Rc<ty::TraitRef<'tcx>>
 {
-    match ::lookup_def_tcx(this.tcx(), ast_trait_ref.path.span, ast_trait_ref.ref_id) {
-        def::DefTrait(trait_def_id) => {
-            let trait_ref = ast_path_to_trait_ref(this,
-                                                  rscope,
-                                                  trait_def_id,
-                                                  self_ty,
-                                                  &ast_trait_ref.path,
-                                                  projections);
-            this.tcx().trait_refs.borrow_mut().insert(ast_trait_ref.ref_id, trait_ref.clone());
-            trait_ref
-        }
+    let trait_def_id = trait_def_id(this, trait_ref);
+    ast_path_to_mono_trait_ref(this,
+                               rscope,
+                               trait_ref.path.span,
+                               PathParamMode::Explicit,
+                               trait_def_id,
+                               self_ty,
+                               trait_ref.path.segments.last().unwrap())
+}
+
+fn trait_def_id<'tcx>(this: &AstConv<'tcx>, trait_ref: &ast::TraitRef) -> ast::DefId {
+    let path = &trait_ref.path;
+    match ::lookup_full_def(this.tcx(), path.span, trait_ref.ref_id) {
+        def::DefTrait(trait_def_id) => trait_def_id,
         _ => {
-            span_fatal!(this.tcx().sess, ast_trait_ref.path.span, E0245,
-                "`{}` is not a trait",
-                        ast_trait_ref.path.user_string(this.tcx()));
+            span_fatal!(this.tcx().sess, path.span, E0245, "`{}` is not a trait",
+                        path.user_string(this.tcx()));
         }
     }
 }
@@ -638,103 +651,160 @@ pub fn instantiate_trait_ref<'tcx>(
 fn object_path_to_poly_trait_ref<'a,'tcx>(
     this: &AstConv<'tcx>,
     rscope: &RegionScope,
+    span: Span,
+    param_mode: PathParamMode,
     trait_def_id: ast::DefId,
-    path: &ast::Path,
+    trait_segment: &ast::PathSegment,
     mut projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
     -> ty::PolyTraitRef<'tcx>
 {
-    // we are introducing a binder here, so shift the
-    // anonymous regions depth to account for that
-    let shifted_rscope = ShiftedRscope::new(rscope);
-
-    let mut tmp = Vec::new();
-    let trait_ref = ty::Binder(ast_path_to_trait_ref(this,
-                                                     &shifted_rscope,
-                                                     trait_def_id,
-                                                     None,
-                                                     path,
-                                                     Some(&mut tmp)));
-    projections.extend(tmp.into_iter().map(ty::Binder));
-    trait_ref
+    ast_path_to_poly_trait_ref(this,
+                               rscope,
+                               span,
+                               param_mode,
+                               trait_def_id,
+                               None,
+                               trait_segment,
+                               projections)
 }
 
-fn ast_path_to_trait_ref<'a,'tcx>(
+fn ast_path_to_poly_trait_ref<'a,'tcx>(
     this: &AstConv<'tcx>,
     rscope: &RegionScope,
+    span: Span,
+    param_mode: PathParamMode,
     trait_def_id: ast::DefId,
     self_ty: Option<Ty<'tcx>>,
-    path: &ast::Path,
-    mut projections: Option<&mut Vec<ty::ProjectionPredicate<'tcx>>>)
-    -> Rc<ty::TraitRef<'tcx>>
+    trait_segment: &ast::PathSegment,
+    poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
+    -> ty::PolyTraitRef<'tcx>
+{
+    // The trait reference introduces a binding level here, so
+    // we need to shift the `rscope`. It'd be nice if we could
+    // do away with this rscope stuff and work this knowledge
+    // into resolve_lifetimes, as we do with non-omitted
+    // lifetimes. Oh well, not there yet.
+    let shifted_rscope = &ShiftedRscope::new(rscope);
+
+    let (substs, assoc_bindings) =
+        create_substs_for_ast_trait_ref(this,
+                                        shifted_rscope,
+                                        span,
+                                        param_mode,
+                                        trait_def_id,
+                                        self_ty,
+                                        trait_segment);
+    let poly_trait_ref = ty::Binder(Rc::new(ty::TraitRef::new(trait_def_id, substs)));
+
+    {
+        let converted_bindings =
+            assoc_bindings
+            .iter()
+            .filter_map(|binding| {
+                // specify type to assert that error was already reported in Err case:
+                let predicate: Result<_, ErrorReported> =
+                    ast_type_binding_to_poly_projection_predicate(this,
+                                                                  poly_trait_ref.clone(),
+                                                                  self_ty,
+                                                                  binding);
+                predicate.ok() // ok to ignore Err() because ErrorReported (see above)
+            });
+        poly_projections.extend(converted_bindings);
+    }
+
+    poly_trait_ref
+}
+
+fn ast_path_to_mono_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
+                                       rscope: &RegionScope,
+                                       span: Span,
+                                       param_mode: PathParamMode,
+                                       trait_def_id: ast::DefId,
+                                       self_ty: Option<Ty<'tcx>>,
+                                       trait_segment: &ast::PathSegment)
+                                       -> Rc<ty::TraitRef<'tcx>>
+{
+    let (substs, assoc_bindings) =
+        create_substs_for_ast_trait_ref(this,
+                                        rscope,
+                                        span,
+                                        param_mode,
+                                        trait_def_id,
+                                        self_ty,
+                                        trait_segment);
+    prohibit_projections(this.tcx(), &assoc_bindings);
+    Rc::new(ty::TraitRef::new(trait_def_id, substs))
+}
+
+fn create_substs_for_ast_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
+                                            rscope: &RegionScope,
+                                            span: Span,
+                                            param_mode: PathParamMode,
+                                            trait_def_id: ast::DefId,
+                                            self_ty: Option<Ty<'tcx>>,
+                                            trait_segment: &ast::PathSegment)
+                                            -> (&'tcx Substs<'tcx>, Vec<ConvertedBinding<'tcx>>)
 {
-    debug!("ast_path_to_trait_ref {:?}", path);
-    let trait_def = this.get_trait_def(trait_def_id);
+    debug!("create_substs_for_ast_trait_ref(trait_segment={:?})",
+           trait_segment);
+
+    let trait_def = match this.get_trait_def(span, trait_def_id) {
+        Ok(trait_def) => trait_def,
+        Err(ErrorReported) => {
+            // No convenient way to recover from a cycle here. Just bail. Sorry!
+            this.tcx().sess.abort_if_errors();
+            this.tcx().sess.bug("ErrorReported returned, but no errors reports?")
+        }
+    };
 
-    let (regions, types, assoc_bindings) = match path.segments.last().unwrap().parameters {
+    let (regions, types, assoc_bindings) = match trait_segment.parameters {
         ast::AngleBracketedParameters(ref data) => {
             // For now, require that parenthetical notation be used
             // only with `Fn()` etc.
             if !this.tcx().sess.features.borrow().unboxed_closures && trait_def.paren_sugar {
-                span_err!(this.tcx().sess, path.span, E0215,
+                span_err!(this.tcx().sess, span, E0215,
                                          "angle-bracket notation is not stable when \
                                          used with the `Fn` family of traits, use parentheses");
-                span_help!(this.tcx().sess, path.span,
+                fileline_help!(this.tcx().sess, span,
                            "add `#![feature(unboxed_closures)]` to \
                             the crate attributes to enable");
             }
 
-            convert_angle_bracketed_parameters(this, rscope, path.span, &trait_def.generics, data)
+            convert_angle_bracketed_parameters(this, rscope, span, &trait_def.generics, data)
         }
         ast::ParenthesizedParameters(ref data) => {
             // For now, require that parenthetical notation be used
             // only with `Fn()` etc.
             if !this.tcx().sess.features.borrow().unboxed_closures && !trait_def.paren_sugar {
-                span_err!(this.tcx().sess, path.span, E0216,
+                span_err!(this.tcx().sess, span, E0216,
                                          "parenthetical notation is only stable when \
                                          used with the `Fn` family of traits");
-                span_help!(this.tcx().sess, path.span,
+                fileline_help!(this.tcx().sess, span,
                            "add `#![feature(unboxed_closures)]` to \
                             the crate attributes to enable");
             }
 
-            convert_parenthesized_parameters(this, rscope, path.span, &trait_def.generics, data)
+            convert_parenthesized_parameters(this, rscope, span, &trait_def.generics, data)
         }
     };
 
     let substs = create_substs_for_ast_path(this,
-                                            path.span,
+                                            span,
+                                            param_mode,
                                             &trait_def.generics,
                                             self_ty,
                                             types,
                                             regions);
-    let substs = this.tcx().mk_substs(substs);
-
-    let trait_ref = Rc::new(ty::TraitRef::new(trait_def_id, substs));
 
-    match projections {
-        None => {
-            prohibit_projections(this.tcx(), &assoc_bindings);
-        }
-        Some(ref mut v) => {
-            for binding in &assoc_bindings {
-                match ast_type_binding_to_projection_predicate(this, trait_ref.clone(),
-                                                               self_ty, binding) {
-                    Ok(pp) => { v.push(pp); }
-                    Err(ErrorReported) => { }
-                }
-            }
-        }
-    }
-
-    trait_ref
+    (this.tcx().mk_substs(substs), assoc_bindings)
 }
 
-fn ast_type_binding_to_projection_predicate<'tcx>(
+fn ast_type_binding_to_poly_projection_predicate<'tcx>(
     this: &AstConv<'tcx>,
-    mut trait_ref: Rc<ty::TraitRef<'tcx>>,
+    mut trait_ref: ty::PolyTraitRef<'tcx>,
     self_ty: Option<Ty<'tcx>>,
     binding: &ConvertedBinding<'tcx>)
-    -> Result<ty::ProjectionPredicate<'tcx>, ErrorReported>
+    -> Result<ty::PolyProjectionPredicate<'tcx>, ErrorReported>
 {
     let tcx = this.tcx();
 
@@ -755,14 +825,14 @@ fn ast_type_binding_to_projection_predicate<'tcx>(
     // We want to produce `<B as SuperTrait<int>>::T == foo`.
 
     // Simple case: X is defined in the current trait.
-    if trait_defines_associated_type_named(this, trait_ref.def_id, binding.item_name) {
-        return Ok(ty::ProjectionPredicate {
-            projection_ty: ty::ProjectionTy {
-                trait_ref: trait_ref,
+    if this.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) {
+        return Ok(ty::Binder(ty::ProjectionPredicate {      // <-------------------+
+            projection_ty: ty::ProjectionTy {               //                     |
+                trait_ref: trait_ref.skip_binder().clone(), // Binder moved here --+
                 item_name: binding.item_name,
             },
             ty: binding.ty,
-        });
+        }));
     }
 
     // Otherwise, we have to walk through the supertraits to find
@@ -775,16 +845,18 @@ fn ast_type_binding_to_projection_predicate<'tcx>(
 
     let dummy_self_ty = ty::mk_infer(tcx, ty::FreshTy(0));
     if self_ty.is_none() { // if converting for an object type
-        let mut dummy_substs = trait_ref.substs.clone();
-        assert!(dummy_substs.self_ty().is_none());
-        dummy_substs.types.push(SelfSpace, dummy_self_ty);
-        trait_ref = Rc::new(ty::TraitRef::new(trait_ref.def_id,
-                                              tcx.mk_substs(dummy_substs)));
+        let mut dummy_substs = trait_ref.skip_binder().substs.clone(); // binder moved here -+
+        assert!(dummy_substs.self_ty().is_none());                     //                    |
+        dummy_substs.types.push(SelfSpace, dummy_self_ty);             //                    |
+        trait_ref = ty::Binder(Rc::new(ty::TraitRef::new(trait_ref.def_id(), // <------------+
+                                                         tcx.mk_substs(dummy_substs))));
     }
 
+    try!(this.ensure_super_predicates(binding.span, trait_ref.def_id()));
+
     let mut candidates: Vec<ty::PolyTraitRef> =
-        traits::supertraits(tcx, trait_ref.to_poly_trait_ref())
-        .filter(|r| trait_defines_associated_type_named(this, r.def_id(), binding.item_name))
+        traits::supertraits(tcx, trait_ref.clone())
+        .filter(|r| this.trait_defines_associated_type_named(r.def_id(), binding.item_name))
         .collect();
 
     // If converting for an object type, then remove the dummy-ty from `Self` now.
@@ -818,95 +890,48 @@ fn ast_type_binding_to_projection_predicate<'tcx>(
         }
     };
 
-    if ty::binds_late_bound_regions(tcx, &candidate) {
-        span_err!(tcx.sess, binding.span, E0219,
-            "associated type `{}` defined in higher-ranked supertrait `{}`",
-                    token::get_name(binding.item_name),
-                    candidate.user_string(tcx));
-        return Err(ErrorReported);
-    }
-
-    Ok(ty::ProjectionPredicate {
-        projection_ty: ty::ProjectionTy {
-            trait_ref: candidate.0,
+    Ok(ty::Binder(ty::ProjectionPredicate {             // <-------------------------+
+        projection_ty: ty::ProjectionTy {               //                           |
+            trait_ref: candidate.skip_binder().clone(), // binder is moved up here --+
             item_name: binding.item_name,
         },
         ty: binding.ty,
-    })
+    }))
 }
 
-pub fn ast_path_to_ty<'tcx>(
+fn ast_path_to_ty<'tcx>(
     this: &AstConv<'tcx>,
     rscope: &RegionScope,
+    span: Span,
+    param_mode: PathParamMode,
     did: ast::DefId,
-    path: &ast::Path)
-    -> TypeAndSubsts<'tcx>
+    item_segment: &ast::PathSegment)
+    -> Ty<'tcx>
 {
     let tcx = this.tcx();
-    let ty::TypeScheme {
-        generics,
-        ty: decl_ty
-    } = this.get_item_type_scheme(did);
+    let (generics, decl_ty) = match this.get_item_type_scheme(span, did) {
+        Ok(ty::TypeScheme { generics,  ty: decl_ty }) => {
+            (generics, decl_ty)
+        }
+        Err(ErrorReported) => {
+            return tcx.types.err;
+        }
+    };
 
     let substs = ast_path_substs_for_ty(this,
                                         rscope,
+                                        span,
+                                        param_mode,
                                         &generics,
-                                        path);
-    let ty = decl_ty.subst(tcx, &substs);
-    TypeAndSubsts { substs: substs, ty: ty }
-}
+                                        item_segment);
 
-/// Converts the given AST type to a built-in type. A "built-in type" is, at
-/// present, either a core numeric type, a string, or `Box`.
-pub fn ast_ty_to_builtin_ty<'tcx>(
-        this: &AstConv<'tcx>,
-        rscope: &RegionScope,
-        ast_ty: &ast::Ty)
-        -> Option<Ty<'tcx>> {
-    match ast_ty_to_prim_ty(this.tcx(), ast_ty) {
-        Some(typ) => return Some(typ),
-        None => {}
+    // FIXME(#12938): This is a hack until we have full support for DST.
+    if Some(did) == this.tcx().lang_items.owned_box() {
+        assert_eq!(substs.types.len(TypeSpace), 1);
+        return ty::mk_uniq(this.tcx(), *substs.types.get(TypeSpace, 0));
     }
 
-    match ast_ty.node {
-        ast::TyPath(ref path, id) => {
-            let a_def = match this.tcx().def_map.borrow().get(&id) {
-                None => {
-                    this.tcx()
-                        .sess
-                        .span_bug(ast_ty.span,
-                                  &format!("unbound path {}",
-                                          path.repr(this.tcx()))[])
-                }
-                Some(&d) => d
-            };
-
-            // FIXME(#12938): This is a hack until we have full support for
-            // DST.
-            match a_def {
-                def::DefTy(did, _) |
-                def::DefStruct(did) if Some(did) == this.tcx().lang_items.owned_box() => {
-                    let ty = ast_path_to_ty(this, rscope, did, path).ty;
-                    match ty.sty {
-                        ty::ty_struct(struct_def_id, ref substs) => {
-                            assert_eq!(struct_def_id, did);
-                            assert_eq!(substs.types.len(TypeSpace), 1);
-                            let referent_ty = *substs.types.get(TypeSpace, 0);
-                            Some(ty::mk_uniq(this.tcx(), referent_ty))
-                        }
-                        _ => {
-                            this.tcx().sess.span_bug(
-                                path.span,
-                                &format!("converting `Box` to `{}`",
-                                        ty.repr(this.tcx()))[]);
-                        }
-                    }
-                }
-                _ => None
-            }
-        }
-        _ => None
-    }
+    decl_ty.subst(this.tcx(), &substs)
 }
 
 type TraitAndProjections<'tcx> = (ty::PolyTraitRef<'tcx>, Vec<ty::PolyProjectionPredicate<'tcx>>);
@@ -929,14 +954,20 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
      */
 
     match ty.node {
-        ast::TyPath(ref path, id) => {
-            match this.tcx().def_map.borrow().get(&id) {
-                Some(&def::DefTrait(trait_def_id)) => {
+        ast::TyPath(None, ref path) => {
+            let def = match this.tcx().def_map.borrow().get(&ty.id) {
+                Some(&def::PathResolution { base_def, depth: 0, .. }) => Some(base_def),
+                _ => None
+            };
+            match def {
+                Some(def::DefTrait(trait_def_id)) => {
                     let mut projection_bounds = Vec::new();
                     let trait_ref = object_path_to_poly_trait_ref(this,
                                                                   rscope,
+                                                                  path.span,
+                                                                  PathParamMode::Explicit,
                                                                   trait_def_id,
-                                                                  path,
+                                                                  path.segments.last().unwrap(),
                                                                   &mut projection_bounds);
                     Ok((trait_ref, projection_bounds))
                 }
@@ -952,14 +983,14 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
                       pprust::ty_to_string(ty));
             match ty.node {
                 ast::TyRptr(None, ref mut_ty) => {
-                    span_help!(this.tcx().sess, ty.span,
+                    fileline_help!(this.tcx().sess, ty.span,
                                "perhaps you meant `&{}({} +{})`? (per RFC 438)",
                                ppaux::mutability_to_string(mut_ty.mutbl),
                                pprust::ty_to_string(&*mut_ty.ty),
                                pprust::bounds_to_string(bounds));
                 }
                ast::TyRptr(Some(ref lt), ref mut_ty) => {
-                    span_help!(this.tcx().sess, ty.span,
+                    fileline_help!(this.tcx().sess, ty.span,
                                "perhaps you meant `&{} {}({} +{})`? (per RFC 438)",
                                pprust::lifetime_to_string(lt),
                                ppaux::mutability_to_string(mut_ty.mutbl),
@@ -968,7 +999,7 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
                 }
 
                 _ => {
-                    span_help!(this.tcx().sess, ty.span,
+                    fileline_help!(this.tcx().sess, ty.span,
                                "perhaps you forgot parentheses? (per RFC 438)");
                 }
             }
@@ -999,45 +1030,89 @@ fn trait_ref_to_object_type<'tcx>(this: &AstConv<'tcx>,
     result
 }
 
+fn report_ambiguous_associated_type(tcx: &ty::ctxt,
+                                    span: Span,
+                                    type_str: &str,
+                                    trait_str: &str,
+                                    name: &str) {
+    span_err!(tcx.sess, span, E0223,
+              "ambiguous associated type; specify the type using the syntax \
+               `<{} as {}>::{}`",
+              type_str, trait_str, name);
+}
+
+// Create a type from a a path to an associated type.
+// For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C
+// and item_segment is the path segment for D. We return a type and a def for
+// the whole path.
+// Will fail except for T::A and Self::A; i.e., if ty/ty_path_def are not a type
+// parameter or Self.
 fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
-                                   ast_ty: &ast::Ty,
-                                   provenance: def::TyParamProvenance,
-                                   assoc_name: ast::Name)
-                                   -> Ty<'tcx>
+                                   span: Span,
+                                   ty: Ty<'tcx>,
+                                   ty_path_def: def::Def,
+                                   item_segment: &ast::PathSegment)
+                                   -> (Ty<'tcx>, def::Def)
 {
     let tcx = this.tcx();
-    let ty_param_def_id = provenance.def_id();
-
-    let mut suitable_bounds: Vec<_>;
-    let ty_param_name: ast::Name;
-    { // contain scope of refcell:
-        let ty_param_defs = tcx.ty_param_defs.borrow();
-        let ty_param_def = &ty_param_defs[ty_param_def_id.node];
-        ty_param_name = ty_param_def.name;
-
-        // FIXME(#20300) -- search where clauses, not bounds
-        suitable_bounds =
-            traits::transitive_bounds(tcx, &ty_param_def.bounds.trait_bounds)
-            .filter(|b| trait_defines_associated_type_named(this, b.def_id(), assoc_name))
-            .collect();
+    let assoc_name = item_segment.identifier.name;
+
+    debug!("associated_path_def_to_ty: {}::{}", ty.repr(tcx), token::get_name(assoc_name));
+
+    check_path_args(tcx, slice::ref_slice(item_segment), NO_TPS | NO_REGIONS);
+
+    // Check that the path prefix given by ty/ty_path_def is a type parameter/Self.
+    match (&ty.sty, ty_path_def) {
+        (&ty::ty_param(_), def::DefTyParam(..)) |
+        (&ty::ty_param(_), def::DefSelfTy(_)) => {}
+        _ => {
+            report_ambiguous_associated_type(tcx,
+                                             span,
+                                             &ty.user_string(tcx),
+                                             "Trait",
+                                             &token::get_name(assoc_name));
+            return (tcx.types.err, ty_path_def);
+        }
     }
 
+    let ty_param_node_id = ty_path_def.local_node_id();
+    let ty_param_name = tcx.ty_param_defs.borrow().get(&ty_param_node_id).unwrap().name;
+
+    let bounds = match this.get_type_parameter_bounds(span, ty_param_node_id) {
+        Ok(v) => v,
+        Err(ErrorReported) => {
+            return (tcx.types.err, ty_path_def);
+        }
+    };
+
+    // Ensure the super predicates and stop if we encountered an error.
+    if bounds.iter().any(|b| this.ensure_super_predicates(span, b.def_id()).is_err()) {
+        return (this.tcx().types.err, ty_path_def);
+    }
+
+    // Check that there is exactly one way to find an associated type with the
+    // correct name.
+    let mut suitable_bounds: Vec<_> =
+        traits::transitive_bounds(tcx, &bounds)
+        .filter(|b| this.trait_defines_associated_type_named(b.def_id(), assoc_name))
+        .collect();
+
     if suitable_bounds.len() == 0 {
-        span_err!(tcx.sess, ast_ty.span, E0220,
+        span_err!(tcx.sess, span, E0220,
                           "associated type `{}` not found for type parameter `{}`",
                                   token::get_name(assoc_name),
                                   token::get_name(ty_param_name));
-        return this.tcx().types.err;
+        return (this.tcx().types.err, ty_path_def);
     }
 
     if suitable_bounds.len() > 1 {
-        span_err!(tcx.sess, ast_ty.span, E0221,
+        span_err!(tcx.sess, span, E0221,
                           "ambiguous associated type `{}` in bounds of `{}`",
                                   token::get_name(assoc_name),
                                   token::get_name(ty_param_name));
 
         for suitable_bound in &suitable_bounds {
-            span_note!(this.tcx().sess, ast_ty.span,
+            span_note!(this.tcx().sess, span,
                        "associated type `{}` could derive from `{}`",
                        token::get_name(ty_param_name),
                        suitable_bound.user_string(this.tcx()));
@@ -1045,46 +1120,71 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
     }
 
     let suitable_bound = suitable_bounds.pop().unwrap().clone();
-    return this.projected_ty_from_poly_trait_ref(ast_ty.span, suitable_bound, assoc_name);
-}
+    let trait_did = suitable_bound.0.def_id;
+
+    let ty = this.projected_ty_from_poly_trait_ref(span, suitable_bound, assoc_name);
+
+    let item_did = if trait_did.krate == ast::LOCAL_CRATE {
+        // `ty::trait_items` used below requires information generated
+        // by type collection, which may be in progress at this point.
+        match this.tcx().map.expect_item(trait_did.node).node {
+            ast::ItemTrait(_, _, _, ref trait_items) => {
+                let item = trait_items.iter()
+                                      .find(|i| i.ident.name == assoc_name)
+                                      .expect("missing associated type");
+                ast_util::local_def(item.id)
+            }
+            _ => unreachable!()
+        }
+    } else {
+        let trait_items = ty::trait_items(this.tcx(), trait_did);
+        let item = trait_items.iter().find(|i| i.name() == assoc_name);
+        item.expect("missing associated type").def_id()
+    };
 
-fn trait_defines_associated_type_named(this: &AstConv,
-                                       trait_def_id: ast::DefId,
-                                       assoc_name: ast::Name)
-                                       -> bool
-{
-    let tcx = this.tcx();
-    let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
-    trait_def.associated_type_names.contains(&assoc_name)
+    (ty, def::DefAssociatedTy(trait_did, item_did))
 }
 
 fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
                      rscope: &RegionScope,
-                     ast_ty: &ast::Ty, // the TyQPath
-                     qpath: &ast::QPath)
+                     span: Span,
+                     param_mode: PathParamMode,
+                     opt_self_ty: Option<Ty<'tcx>>,
+                     trait_def_id: ast::DefId,
+                     trait_segment: &ast::PathSegment,
+                     item_segment: &ast::PathSegment)
                      -> Ty<'tcx>
 {
-    debug!("qpath_to_ty(ast_ty={})",
-           ast_ty.repr(this.tcx()));
+    let tcx = this.tcx();
 
-    let self_type = ast_ty_to_ty(this, rscope, &*qpath.self_type);
+    check_path_args(tcx, slice::ref_slice(item_segment), NO_TPS | NO_REGIONS);
 
-    debug!("qpath_to_ty: self_type={}", self_type.repr(this.tcx()));
+    let self_ty = if let Some(ty) = opt_self_ty {
+        ty
+    } else {
+        let path_str = ty::item_path_str(tcx, trait_def_id);
+        report_ambiguous_associated_type(tcx,
+                                         span,
+                                         "Type",
+                                         &path_str,
+                                         &token::get_ident(item_segment.identifier));
+        return tcx.types.err;
+    };
 
-    let trait_ref = instantiate_trait_ref(this,
-                                          rscope,
-                                          &*qpath.trait_ref,
-                                          Some(self_type),
-                                          None);
+    debug!("qpath_to_ty: self_type={}", self_ty.repr(tcx));
 
-    debug!("qpath_to_ty: trait_ref={}", trait_ref.repr(this.tcx()));
+    let trait_ref =
+        ast_path_to_mono_trait_ref(this,
+                                   rscope,
+                                   span,
+                                   param_mode,
+                                   trait_def_id,
+                                   Some(self_ty),
+                                   trait_segment);
 
-    // `<T as Trait>::U<V>` shouldn't parse right now.
-    assert!(qpath.item_path.parameters.is_empty());
+    debug!("qpath_to_ty: trait_ref={}", trait_ref.repr(tcx));
 
-    return this.projected_ty(ast_ty.span,
-                             trait_ref,
-                             qpath.item_path.identifier.name);
+    this.projected_ty(span, trait_ref, item_segment.identifier.name)
 }
 
 /// Convert a type supplied as value for a type argument from AST into our
@@ -1120,6 +1220,115 @@ pub fn ast_ty_arg_to_ty<'tcx>(this: &AstConv<'tcx>,
     }
 }
 
+// Note that both base_segments and assoc_segments may be empty, although not at
+// the same time.
+pub fn finish_resolving_def_to_ty<'tcx>(this: &AstConv<'tcx>,
+                                        rscope: &RegionScope,
+                                        span: Span,
+                                        param_mode: PathParamMode,
+                                        def: &def::Def,
+                                        opt_self_ty: Option<Ty<'tcx>>,
+                                        base_segments: &[ast::PathSegment],
+                                        assoc_segments: &[ast::PathSegment])
+                                        -> Ty<'tcx> {
+    let tcx = this.tcx();
+
+    let base_ty = match *def {
+        def::DefTrait(trait_def_id) => {
+            // N.B. this case overlaps somewhat with
+            // TyObjectSum, see that fn for details
+            let mut projection_bounds = Vec::new();
+
+            let trait_ref = object_path_to_poly_trait_ref(this,
+                                                          rscope,
+                                                          span,
+                                                          param_mode,
+                                                          trait_def_id,
+                                                          base_segments.last().unwrap(),
+                                                          &mut projection_bounds);
+
+            check_path_args(tcx, base_segments.init(), NO_TPS | NO_REGIONS);
+            trait_ref_to_object_type(this,
+                                     rscope,
+                                     span,
+                                     trait_ref,
+                                     projection_bounds,
+                                     &[])
+        }
+        def::DefTy(did, _) | def::DefStruct(did) => {
+            check_path_args(tcx, base_segments.init(), NO_TPS | NO_REGIONS);
+            ast_path_to_ty(this, rscope, span,
+                           param_mode, did,
+                           base_segments.last().unwrap())
+        }
+        def::DefTyParam(space, index, _, name) => {
+            check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS);
+            ty::mk_param(tcx, space, index, name)
+        }
+        def::DefSelfTy(_) => {
+            // N.b.: resolve guarantees that the this type only appears in a
+            // trait, which we rely upon in various places when creating
+            // substs.
+            check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS);
+            ty::mk_self_type(tcx)
+        }
+        def::DefAssociatedTy(trait_did, _) => {
+            check_path_args(tcx, &base_segments[..base_segments.len()-2], NO_TPS | NO_REGIONS);
+            qpath_to_ty(this,
+                        rscope,
+                        span,
+                        param_mode,
+                        opt_self_ty,
+                        trait_did,
+                        &base_segments[base_segments.len()-2],
+                        base_segments.last().unwrap())
+        }
+        def::DefMod(id) => {
+            // Used as sentinel by callers to indicate the `<T>::A::B::C` form.
+            // FIXME(#22519) This part of the resolution logic should be
+            // avoided entirely for that form, once we stop needed a Def
+            // for `associated_path_def_to_ty`.
+
+            if !base_segments.is_empty() {
+                span_err!(tcx.sess,
+                          span,
+                          E0247,
+                          "found module name used as a type: {}",
+                          tcx.map.node_to_string(id.node));
+                return this.tcx().types.err;
+            }
+
+            opt_self_ty.expect("missing T in <T>::a::b::c")
+        }
+        def::DefPrimTy(prim_ty) => {
+            prim_ty_to_ty(tcx, base_segments, prim_ty)
+        }
+        _ => {
+            span_err!(tcx.sess, span, E0248,
+                      "found value name used as a type: {:?}", *def);
+            return this.tcx().types.err;
+        }
+    };
+
+    // If any associated type segments remain, attempt to resolve them.
+    let mut ty = base_ty;
+    let mut def = *def;
+    for segment in assoc_segments {
+        if ty.sty == ty::ty_err {
+            break;
+        }
+        // This is pretty bad (it will fail except for T::A and Self::A).
+        let (a_ty, a_def) = associated_path_def_to_ty(this,
+                                                      span,
+                                                      ty,
+                                                      def,
+                                                      segment);
+        ty = a_ty;
+        def = a_def;
+    }
+    ty
+}
+
 /// Parses the programmer's textual representation of a type into our
 /// internal notion of a type.
 pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
@@ -1132,189 +1341,145 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
 
     let tcx = this.tcx();
 
-    let mut ast_ty_to_ty_cache = tcx.ast_ty_to_ty_cache.borrow_mut();
-    match ast_ty_to_ty_cache.get(&ast_ty.id) {
-        Some(&ty::atttce_resolved(ty)) => return ty,
-        Some(&ty::atttce_unresolved) => {
-            span_fatal!(tcx.sess, ast_ty.span, E0246,
-                                "illegal recursive type; insert an enum \
-                                 or struct in the cycle, if this is \
-                                 desired");
-        }
-        None => { /* go on */ }
+    if let Some(&ty) = tcx.ast_ty_to_ty_cache.borrow().get(&ast_ty.id) {
+        return ty;
     }
-    ast_ty_to_ty_cache.insert(ast_ty.id, ty::atttce_unresolved);
-    drop(ast_ty_to_ty_cache);
 
-    let typ = ast_ty_to_builtin_ty(this, rscope, ast_ty).unwrap_or_else(|| {
-        match ast_ty.node {
-            ast::TyVec(ref ty) => {
-                ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty), None)
-            }
-            ast::TyObjectSum(ref ty, ref bounds) => {
-                match ast_ty_to_trait_ref(this, rscope, &**ty, &bounds[..]) {
-                    Ok((trait_ref, projection_bounds)) => {
-                        trait_ref_to_object_type(this,
-                                                 rscope,
-                                                 ast_ty.span,
-                                                 trait_ref,
-                                                 projection_bounds,
-                                                 &bounds[..])
-                    }
-                    Err(ErrorReported) => {
-                        this.tcx().types.err
-                    }
+    let typ = match ast_ty.node {
+        ast::TyVec(ref ty) => {
+            ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty), None)
+        }
+        ast::TyObjectSum(ref ty, ref bounds) => {
+            match ast_ty_to_trait_ref(this, rscope, &**ty, bounds) {
+                Ok((trait_ref, projection_bounds)) => {
+                    trait_ref_to_object_type(this,
+                                             rscope,
+                                             ast_ty.span,
+                                             trait_ref,
+                                             projection_bounds,
+                                             bounds)
                 }
-            }
-            ast::TyPtr(ref mt) => {
-                ty::mk_ptr(tcx, ty::mt {
-                    ty: ast_ty_to_ty(this, rscope, &*mt.ty),
-                    mutbl: mt.mutbl
-                })
-            }
-            ast::TyRptr(ref region, ref mt) => {
-                let r = opt_ast_region_to_region(this, rscope, ast_ty.span, region);
-                debug!("ty_rptr r={}", r.repr(this.tcx()));
-                let rscope1 =
-                    &ObjectLifetimeDefaultRscope::new(
-                        rscope,
-                        Some(ty::ObjectLifetimeDefault::Specific(r)));
-                let t = ast_ty_to_ty(this, rscope1, &*mt.ty);
-                ty::mk_rptr(tcx, tcx.mk_region(r), ty::mt {ty: t, mutbl: mt.mutbl})
-            }
-            ast::TyTup(ref fields) => {
-                let flds = fields.iter()
-                                 .map(|t| ast_ty_to_ty(this, rscope, &**t))
-                                 .collect();
-                ty::mk_tup(tcx, flds)
-            }
-            ast::TyParen(ref typ) => ast_ty_to_ty(this, rscope, &**typ),
-            ast::TyBareFn(ref bf) => {
-                if bf.decl.variadic && bf.abi != abi::C {
-                    span_err!(tcx.sess, ast_ty.span, E0222,
-                                      "variadic function must have C calling convention");
+                Err(ErrorReported) => {
+                    this.tcx().types.err
                 }
-                let bare_fn = ty_of_bare_fn(this, bf.unsafety, bf.abi, &*bf.decl);
-                ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(bare_fn))
             }
-            ast::TyPolyTraitRef(ref bounds) => {
-                conv_ty_poly_trait_ref(this, rscope, ast_ty.span, &bounds[..])
+        }
+        ast::TyPtr(ref mt) => {
+            ty::mk_ptr(tcx, ty::mt {
+                ty: ast_ty_to_ty(this, rscope, &*mt.ty),
+                mutbl: mt.mutbl
+            })
+        }
+        ast::TyRptr(ref region, ref mt) => {
+            let r = opt_ast_region_to_region(this, rscope, ast_ty.span, region);
+            debug!("ty_rptr r={}", r.repr(this.tcx()));
+            let rscope1 =
+                &ObjectLifetimeDefaultRscope::new(
+                    rscope,
+                    Some(ty::ObjectLifetimeDefault::Specific(r)));
+            let t = ast_ty_to_ty(this, rscope1, &*mt.ty);
+            ty::mk_rptr(tcx, tcx.mk_region(r), ty::mt {ty: t, mutbl: mt.mutbl})
+        }
+        ast::TyTup(ref fields) => {
+            let flds = fields.iter()
+                             .map(|t| ast_ty_to_ty(this, rscope, &**t))
+                             .collect();
+            ty::mk_tup(tcx, flds)
+        }
+        ast::TyParen(ref typ) => ast_ty_to_ty(this, rscope, &**typ),
+        ast::TyBareFn(ref bf) => {
+            if bf.decl.variadic && bf.abi != abi::C {
+                span_err!(tcx.sess, ast_ty.span, E0222,
+                          "variadic function must have C calling convention");
             }
-            ast::TyPath(ref path, id) => {
-                let a_def = match tcx.def_map.borrow().get(&id) {
-                    None => {
-                        tcx.sess
-                           .span_bug(ast_ty.span,
-                                     &format!("unbound path {}",
-                                             path.repr(tcx))[])
-                    }
-                    Some(&d) => d
-                };
-                match a_def {
-                    def::DefTrait(trait_def_id) => {
-                        // N.B. this case overlaps somewhat with
-                        // TyObjectSum, see that fn for details
-                        let mut projection_bounds = Vec::new();
-
-                        let trait_ref = object_path_to_poly_trait_ref(this,
-                                                                      rscope,
-                                                                      trait_def_id,
-                                                                      path,
-                                                                      &mut projection_bounds);
-
-                        trait_ref_to_object_type(this, rscope, path.span,
-                                                 trait_ref, projection_bounds, &[])
-                    }
-                    def::DefTy(did, _) | def::DefStruct(did) => {
-                        ast_path_to_ty(this, rscope, did, path).ty
-                    }
-                    def::DefTyParam(space, index, _, name) => {
-                        check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                        ty::mk_param(tcx, space, index, name)
-                    }
-                    def::DefSelfTy(_) => {
-                        // n.b.: resolve guarantees that the this type only appears in a
-                        // trait, which we rely upon in various places when creating
-                        // substs
-                        check_path_args(tcx, path, NO_TPS | NO_REGIONS);
-                        ty::mk_self_type(tcx)
-                    }
-                    def::DefMod(id) => {
-                        span_fatal!(tcx.sess, ast_ty.span, E0247,
-                            "found module name used as a type: {}",
-                                    tcx.map.node_to_string(id.node));
-                    }
-                    def::DefPrimTy(_) => {
-                        panic!("DefPrimTy arm missed in previous ast_ty_to_prim_ty call");
-                    }
-                    def::DefAssociatedTy(trait_type_id) => {
-                        let path_str = tcx.map.path_to_string(
-                            tcx.map.get_parent(trait_type_id.node));
-                        span_err!(tcx.sess, ast_ty.span, E0223,
-                                          "ambiguous associated \
-                                                   type; specify the type \
-                                                   using the syntax `<Type \
-                                                   as {}>::{}`",
-                                                  path_str,
-                                                  &token::get_ident(
-                                                      path.segments
-                                                          .last()
-                                                          .unwrap()
-                                                          .identifier));
-                        this.tcx().types.err
-                    }
-                    def::DefAssociatedPath(provenance, assoc_ident) => {
-                        associated_path_def_to_ty(this, ast_ty, provenance, assoc_ident.name)
-                    }
-                    _ => {
-                        span_fatal!(tcx.sess, ast_ty.span, E0248,
-                                            "found value name used \
-                                                     as a type: {:?}",
-                                                    a_def);
-                    }
+            let bare_fn = ty_of_bare_fn(this, bf.unsafety, bf.abi, &*bf.decl);
+            ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(bare_fn))
+        }
+        ast::TyPolyTraitRef(ref bounds) => {
+            conv_ty_poly_trait_ref(this, rscope, ast_ty.span, bounds)
+        }
+        ast::TyPath(ref maybe_qself, ref path) => {
+            let path_res = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) {
+                d
+            } else if let Some(ast::QSelf { position: 0, .. }) = *maybe_qself {
+                // Create some fake resolution that can't possibly be a type.
+                def::PathResolution {
+                    base_def: def::DefMod(ast_util::local_def(ast::CRATE_NODE_ID)),
+                    last_private: LastMod(AllPublic),
+                    depth: path.segments.len()
                 }
+            } else {
+                tcx.sess.span_bug(ast_ty.span,
+                                  &format!("unbound path {}", ast_ty.repr(tcx)))
+            };
+            let def = path_res.base_def;
+            let base_ty_end = path.segments.len() - path_res.depth;
+            let opt_self_ty = maybe_qself.as_ref().map(|qself| {
+                ast_ty_to_ty(this, rscope, &qself.ty)
+            });
+            let ty = finish_resolving_def_to_ty(this,
+                                                rscope,
+                                                ast_ty.span,
+                                                PathParamMode::Explicit,
+                                                &def,
+                                                opt_self_ty,
+                                                &path.segments[..base_ty_end],
+                                                &path.segments[base_ty_end..]);
+
+            if path_res.depth != 0 && ty.sty != ty::ty_err {
+                // Write back the new resolution.
+                tcx.def_map.borrow_mut().insert(ast_ty.id, def::PathResolution {
+                    base_def: def,
+                    last_private: path_res.last_private,
+                    depth: 0
+                });
             }
-            ast::TyQPath(ref qpath) => {
-                qpath_to_ty(this, rscope, ast_ty, &**qpath)
-            }
-            ast::TyFixedLengthVec(ref ty, ref e) => {
-                match const_eval::eval_const_expr_partial(tcx, &**e, Some(tcx.types.uint)) {
-                    Ok(ref r) => {
-                        match *r {
-                            const_eval::const_int(i) =>
-                                ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty),
-                                           Some(i as uint)),
-                            const_eval::const_uint(i) =>
-                                ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty),
-                                           Some(i as uint)),
-                            _ => {
-                                span_fatal!(tcx.sess, ast_ty.span, E0249,
-                                            "expected constant expr for array length");
-                            }
+
+            ty
+        }
+        ast::TyFixedLengthVec(ref ty, ref e) => {
+            match const_eval::eval_const_expr_partial(tcx, &**e, Some(tcx.types.usize)) {
+                Ok(r) => {
+                    match r {
+                        const_eval::const_int(i) =>
+                            ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty),
+                                        Some(i as usize)),
+                        const_eval::const_uint(i) =>
+                            ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty),
+                                        Some(i as usize)),
+                        _ => {
+                            span_err!(tcx.sess, ast_ty.span, E0249,
+                                      "expected constant expr for array length");
+                            this.tcx().types.err
                         }
                     }
-                    Err(ref r) => {
-                        span_fatal!(tcx.sess, ast_ty.span, E0250,
-                            "expected constant expr for array \
-                                     length: {}",
-                                    *r);
+                }
+                Err(ref r) => {
+                    let subspan  =
+                        ast_ty.span.lo <= r.span.lo && r.span.hi <= ast_ty.span.hi;
+                    span_err!(tcx.sess, r.span, E0250,
+                              "array length constant evaluation error: {}",
+                              r.description());
+                    if !subspan {
+                        span_note!(tcx.sess, ast_ty.span, "for array length here")
                     }
+                    this.tcx().types.err
                 }
             }
-            ast::TyTypeof(ref _e) => {
-                tcx.sess.span_bug(ast_ty.span, "typeof is reserved but unimplemented");
-            }
-            ast::TyInfer => {
-                // TyInfer also appears as the type of arguments or return
-                // values in a ExprClosure, or as
-                // the type of local variables. Both of these cases are
-                // handled specially and will not descend into this routine.
-                this.ty_infer(ast_ty.span)
-            }
         }
-    });
+        ast::TyTypeof(ref _e) => {
+            tcx.sess.span_bug(ast_ty.span, "typeof is reserved but unimplemented");
+        }
+        ast::TyInfer => {
+            // TyInfer also appears as the type of arguments or return
+            // values in a ExprClosure, or as
+            // the type of local variables. Both of these cases are
+            // handled specially and will not descend into this routine.
+            this.ty_infer(ast_ty.span)
+        }
+    };
 
-    tcx.ast_ty_to_ty_cache.borrow_mut().insert(ast_ty.id, ty::atttce_resolved(typ));
+    tcx.ast_ty_to_ty_cache.borrow_mut().insert(ast_ty.id, typ);
     return typ;
 }
 
@@ -1337,22 +1502,19 @@ struct SelfInfo<'a, 'tcx> {
 }
 
 pub fn ty_of_method<'tcx>(this: &AstConv<'tcx>,
-                          unsafety: ast::Unsafety,
-                          untransformed_self_ty: Ty<'tcx>,
-                          explicit_self: &ast::ExplicitSelf,
-                          decl: &ast::FnDecl,
-                          abi: abi::Abi)
+                          sig: &ast::MethodSig,
+                          untransformed_self_ty: Ty<'tcx>)
                           -> (ty::BareFnTy<'tcx>, ty::ExplicitSelfCategory) {
     let self_info = Some(SelfInfo {
         untransformed_self_ty: untransformed_self_ty,
-        explicit_self: explicit_self,
+        explicit_self: &sig.explicit_self,
     });
     let (bare_fn_ty, optional_explicit_self_category) =
         ty_of_method_or_bare_fn(this,
-                                unsafety,
-                                abi,
+                                sig.unsafety,
+                                sig.abi,
                                 self_info,
-                                decl);
+                                &sig.decl);
     (bare_fn_ty, optional_explicit_self_category.unwrap())
 }
 
@@ -1419,7 +1581,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>,
     let input_params = if self_ty.is_some() {
         &decl.inputs[1..]
     } else {
-        &decl.inputs[]
+        &decl.inputs[..]
     };
     let input_tys = input_params.iter().map(|a| ty_of_arg(this, &rb, a, None));
     let input_pats: Vec<String> = input_params.iter()
@@ -1541,7 +1703,7 @@ fn determine_explicit_self_category<'a, 'tcx>(this: &AstConv<'tcx>,
         }
     };
 
-    fn count_modifiers(ty: Ty) -> uint {
+    fn count_modifiers(ty: Ty) -> usize {
         match ty.sty {
             ty::ty_rptr(_, mt) => count_modifiers(mt.ty) + 1,
             ty::ty_uniq(t) => count_modifiers(t) + 1,
@@ -1731,6 +1893,10 @@ fn compute_object_lifetime_bound<'tcx>(
         return ast_region_to_region(tcx, r);
     }
 
+    if let Err(ErrorReported) = this.ensure_super_predicates(span,principal_trait_ref.def_id()) {
+        return ty::ReStatic;
+    }
+
     // No explicit region bound specified. Therefore, examine trait
     // bounds and see if we can derive region bounds from those.
     let derived_region_bounds =
@@ -1816,38 +1982,24 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
     let mut builtin_bounds = ty::empty_builtin_bounds();
     let mut region_bounds = Vec::new();
     let mut trait_bounds = Vec::new();
-    let mut trait_def_ids = DefIdMap();
     for ast_bound in ast_bounds {
         match *ast_bound {
             ast::TraitTyParamBound(ref b, ast::TraitBoundModifier::None) => {
-                match ::lookup_def_tcx(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {
+                match ::lookup_full_def(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {
                     def::DefTrait(trait_did) => {
-                        match trait_def_ids.get(&trait_did) {
-                            // Already seen this trait. We forbid
-                            // duplicates in the list (for some
-                            // reason).
-                            Some(span) => {
-                                span_err!(
-                                    tcx.sess, b.trait_ref.path.span, E0127,
-                                    "trait `{}` already appears in the \
-                                     list of bounds",
-                                    b.trait_ref.path.user_string(tcx));
-                                tcx.sess.span_note(
-                                    *span,
-                                    "previous appearance is here");
-
-                                continue;
-                            }
-
-                            None => { }
-                        }
-
-                        trait_def_ids.insert(trait_did, b.trait_ref.path.span);
-
                         if ty::try_add_builtin_trait(tcx,
                                                      trait_did,
                                                      &mut builtin_bounds) {
-                            // FIXME(#20302) -- we should check for things like Copy<T>
+                            let segments = &b.trait_ref.path.segments;
+                            let parameters = &segments[segments.len() - 1].parameters;
+                            if parameters.types().len() > 0 {
+                                check_type_argument_count(tcx, b.trait_ref.path.span,
+                                                          parameters.types().len(), 0, 0);
+                            }
+                            if parameters.lifetimes().len() > 0{
+                                report_lifetime_number_error(tcx, b.trait_ref.path.span,
+                                                             parameters.lifetimes().len(), 0);
+                            }
                             continue; // success
                         }
                     }
@@ -1880,3 +2032,34 @@ fn prohibit_projections<'tcx>(tcx: &ty::ctxt<'tcx>,
             "associated type bindings are not allowed here");
     }
 }
+
+fn check_type_argument_count(tcx: &ty::ctxt, span: Span, supplied: usize,
+                             required: usize, accepted: usize) {
+    if supplied < required {
+        let expected = if required < accepted {
+            "expected at least"
+        } else {
+            "expected"
+        };
+        span_err!(tcx.sess, span, E0243,
+                  "wrong number of type arguments: {} {}, found {}",
+                  expected, required, supplied);
+    } else if supplied > accepted {
+        let expected = if required < accepted {
+            "expected at most"
+        } else {
+            "expected"
+        };
+        span_err!(tcx.sess, span, E0244,
+                  "wrong number of type arguments: {} {}, found {}",
+                  expected,
+                  accepted,
+                  supplied);
+    }
+}
+
+fn report_lifetime_number_error(tcx: &ty::ctxt, span: Span, number: usize, expected: usize) {
+    span_err!(tcx.sess, span, E0107,
+              "wrong number of lifetime parameters: expected {}, found {}",
+              expected, number);
+}
index 34c52981b794dff838208073f38a0d048a9cb59f..8f1a67723cb79c90dc06e35af8a30dde6124724a 100644 (file)
@@ -12,7 +12,7 @@ use middle::const_eval;
 use middle::def;
 use middle::infer;
 use middle::pat_util::{PatIdMap, pat_id_map, pat_is_binding, pat_is_const};
-use middle::subst::{Substs};
+use middle::subst::Substs;
 use middle::ty::{self, Ty};
 use check::{check_expr, check_expr_has_type, check_expr_with_expectation};
 use check::{check_expr_coercable_to_type, demand, FnCtxt, Expectation};
@@ -48,7 +48,23 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
         ast::PatLit(ref lt) => {
             check_expr(fcx, &**lt);
             let expr_ty = fcx.expr_ty(&**lt);
-            fcx.write_ty(pat.id, expr_ty);
+
+            // Byte string patterns behave the same way as array patterns
+            // They can denote both statically and dynamically sized byte arrays
+            let mut pat_ty = expr_ty;
+            if let ast::ExprLit(ref lt) = lt.node {
+                if let ast::LitBinary(_) = lt.node {
+                    let expected_ty = structurally_resolved_type(fcx, pat.span, expected);
+                    if let ty::ty_rptr(_, mt) = expected_ty.sty {
+                        if let ty::ty_vec(_, None) = mt.ty.sty {
+                            pat_ty = ty::mk_slice(tcx, tcx.mk_region(ty::ReStatic),
+                                ty::mt{ ty: tcx.types.u8, mutbl: ast::MutImmutable })
+                        }
+                    }
+                }
+            }
+
+            fcx.write_ty(pat.id, pat_ty);
 
             // somewhat surprising: in this case, the subtyping
             // relation goes the opposite way as the other
@@ -62,7 +78,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             //     &'static str <: expected
             //
             // that's equivalent to there existing a LUB.
-            demand::suptype(fcx, pat.span, expected, expr_ty);
+            demand::suptype(fcx, pat.span, expected, pat_ty);
         }
         ast::PatRange(ref begin, ref end) => {
             check_expr(fcx, &**begin);
@@ -103,7 +119,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             demand::eqtype(fcx, pat.span, expected, lhs_ty);
         }
         ast::PatEnum(..) | ast::PatIdent(..) if pat_is_const(&tcx.def_map, pat) => {
-            let const_did = tcx.def_map.borrow()[pat.id].clone().def_id();
+            let const_did = tcx.def_map.borrow().get(&pat.id).unwrap().def_id();
             let const_scheme = ty::lookup_item_type(tcx, const_did);
             assert!(const_scheme.generics.is_empty());
             let const_ty = pcx.fcx.instantiate_type_scheme(pat.span,
@@ -147,7 +163,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
 
             // if there are multiple arms, make sure they all agree on
             // what the type of the binding `x` ought to be
-            let canon_id = pcx.map[path.node];
+            let canon_id = *pcx.map.get(&path.node).unwrap();
             if canon_id != pat.id {
                 let ct = fcx.local_ty(pat.span, canon_id);
                 demand::eqtype(fcx, pat.span, ct, typ);
@@ -271,10 +287,11 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     // (nmatsakis) an hour or two debugging to remember, so I thought
     // I'd write them down this time.
     //
-    // 1. Most importantly, there is no loss of expressiveness
-    // here. What we are saying is that the type of `x`
-    // becomes *exactly* what is expected. This might seem
-    // like it will cause errors in a case like this:
+    // 1. There is no loss of expressiveness here, though it does
+    // cause some inconvenience. What we are saying is that the type
+    // of `x` becomes *exactly* what is expected. This can cause unnecessary
+    // errors in some cases, such as this one:
+    // it will cause errors in a case like this:
     //
     // ```
     // fn foo<'x>(x: &'x int) {
@@ -345,8 +362,21 @@ pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                              match_src: ast::MatchSource) {
     let tcx = fcx.ccx.tcx;
 
-    let discrim_ty = fcx.infcx().next_ty_var();
-    check_expr_has_type(fcx, discrim, discrim_ty);
+    // Not entirely obvious: if matches may create ref bindings, we
+    // want to use the *precise* type of the discriminant, *not* some
+    // supertype, as the "discriminant type" (issue #23116).
+    let contains_ref_bindings = arms.iter().any(|a| tcx.arm_contains_ref_binding(a));
+    let discrim_ty;
+    if contains_ref_bindings {
+        check_expr(fcx, discrim);
+        discrim_ty = fcx.expr_ty(discrim);
+    } else {
+        // ...but otherwise we want to use any supertype of the
+        // discriminant. This is sort of a workaround, see note (*) in
+        // `check_pat` for some details.
+        discrim_ty = fcx.infcx().next_ty_var();
+        check_expr_has_type(fcx, discrim, discrim_ty);
+    };
 
     // Typecheck the patterns first, so that we get types for all the
     // bindings.
@@ -433,7 +463,7 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
     let fcx = pcx.fcx;
     let tcx = pcx.fcx.ccx.tcx;
 
-    let def = tcx.def_map.borrow()[pat.id].clone();
+    let def = tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
     let (enum_def_id, variant_def_id) = match def {
         def::DefTrait(_) => {
             let name = pprust::path_to_string(path);
@@ -470,7 +500,7 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
     };
 
     instantiate_path(pcx.fcx,
-                     path,
+                     &path.segments,
                      ty::lookup_item_type(tcx, enum_def_id),
                      &ty::lookup_predicates(tcx, enum_def_id),
                      None,
@@ -502,7 +532,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     let fcx = pcx.fcx;
     let tcx = pcx.fcx.ccx.tcx;
 
-    let def = tcx.def_map.borrow()[pat.id].clone();
+    let def = tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
     let enum_def = def.variant_def_ids()
         .map_or_else(|| def.def_id(), |(enum_def, _)| enum_def);
 
@@ -517,7 +547,9 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     } else {
         ctor_scheme
     };
-    instantiate_path(pcx.fcx, path, path_scheme, &ctor_predicates, None, def, pat.span, pat.id);
+    instantiate_path(pcx.fcx, &path.segments,
+                     path_scheme, &ctor_predicates,
+                     None, def, pat.span, pat.id);
 
     let pat_ty = fcx.node_ty(pat.id);
     demand::eqtype(fcx, pat.span, expected, pat_ty);
index 0ad15456df98f16daab554c59b289287426b0523..3f9c14e0afe398ab8d3b905cf60e3ef082dfb029 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use super::autoderef;
-use super::AutorefArgs;
 use super::check_argument_types;
 use super::check_expr;
 use super::check_method_argument_types;
@@ -63,7 +62,7 @@ pub fn check_legal_trait_for_method_call(ccx: &CrateCtxt, span: Span, trait_id:
         span_err!(tcx.sess, span, E0174,
                   "explicit use of unboxed closure method `{}` is experimental",
                   method);
-        span_help!(tcx.sess, span,
+        fileline_help!(tcx.sess, span,
                    "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
     }
 }
@@ -84,9 +83,7 @@ pub fn check_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                   UnresolvedTypeAction::Error,
                   LvaluePreference::NoPreference,
                   |adj_ty, idx| {
-                      let autoderefref = ty::AutoDerefRef { autoderefs: idx, autoref: None };
-                      try_overloaded_call_step(fcx, call_expr, callee_expr,
-                                               adj_ty, autoderefref)
+                      try_overloaded_call_step(fcx, call_expr, callee_expr, adj_ty, idx)
                   });
 
     match result {
@@ -120,13 +117,15 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                       call_expr: &'tcx ast::Expr,
                                       callee_expr: &'tcx ast::Expr,
                                       adjusted_ty: Ty<'tcx>,
-                                      autoderefref: ty::AutoDerefRef<'tcx>)
+                                      autoderefs: usize)
                                       -> Option<CallStep<'tcx>>
 {
-    debug!("try_overloaded_call_step(call_expr={}, adjusted_ty={}, autoderefref={})",
+    debug!("try_overloaded_call_step(call_expr={}, adjusted_ty={}, autoderefs={})",
            call_expr.repr(fcx.tcx()),
            adjusted_ty.repr(fcx.tcx()),
-           autoderefref.repr(fcx.tcx()));
+           autoderefs);
+
+    let autoderefref = ty::AutoDerefRef { autoderefs: autoderefs, autoref: None };
 
     // If the callee is a bare function or a closure, then we're all set.
     match structurally_resolved_type(fcx, callee_expr.span, adjusted_ty).sty {
@@ -137,7 +136,7 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             return Some(CallStep::Builtin);
         }
 
-        ty::ty_closure(def_id, _, substs) => {
+        ty::ty_closure(def_id, substs) => {
             assert_eq!(def_id.krate, ast::LOCAL_CRATE);
 
             // Check whether this is a call to a closure where we
@@ -152,16 +151,28 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                                           &closure_ty.sig).0;
                 fcx.record_deferred_call_resolution(
                     def_id,
-                    box CallResolution {call_expr: call_expr,
-                                        callee_expr: callee_expr,
-                                        adjusted_ty: adjusted_ty,
-                                        autoderefref: autoderefref,
-                                        fn_sig: fn_sig.clone(),
-                                        closure_def_id: def_id});
+                    Box::new(CallResolution {call_expr: call_expr,
+                                         callee_expr: callee_expr,
+                                         adjusted_ty: adjusted_ty,
+                                         autoderefref: autoderefref,
+                                         fn_sig: fn_sig.clone(),
+                                         closure_def_id: def_id}));
                 return Some(CallStep::DeferredClosure(fn_sig));
             }
         }
 
+        // Hack: we know that there are traits implementing Fn for &F
+        // where F:Fn and so forth. In the particular case of types
+        // like `x: &mut FnMut()`, if there is a call `x()`, we would
+        // normally translate to `FnMut::call_mut(&mut x, ())`, but
+        // that winds up requiring `mut x: &mut FnMut()`. A little
+        // over the top. The simplest fix by far is to just ignore
+        // this case and deref again, so we wind up with
+        // `FnMut::call_mut(&mut *x, ())`.
+        ty::ty_rptr(..) if autoderefs == 0 => {
+            return None;
+        }
+
         _ => {}
     }
 
@@ -258,7 +269,6 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                          &fn_sig.inputs,
                          &expected_arg_tys[..],
                          arg_exprs,
-                         AutorefArgs::No,
                          fn_sig.variadic,
                          TupleArgumentsFlag::DontTupleArguments);
 
@@ -288,7 +298,6 @@ fn confirm_deferred_closure_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                          &*fn_sig.inputs,
                          &*expected_arg_tys,
                          arg_exprs,
-                         AutorefArgs::No,
                          fn_sig.variadic,
                          TupleArgumentsFlag::TupleArguments);
 
@@ -308,7 +317,6 @@ fn confirm_overloaded_call<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                     method_callee.ty,
                                     callee_expr,
                                     arg_exprs,
-                                    AutorefArgs::No,
                                     TupleArgumentsFlag::TupleArguments,
                                     expected);
     write_call(fcx, call_expr, output_type);
index 0b7c5b04aaa44d5802f117f8312ed294b6018ad9..d2a06fcf9909138d1a1b354350c9dc1ea903b5ce 100644 (file)
@@ -16,7 +16,7 @@ use astconv;
 use middle::region;
 use middle::subst;
 use middle::ty::{self, ToPolyTraitRef, Ty};
-use rscope::RegionScope;
+use std::cmp;
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_util;
@@ -61,17 +61,8 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
         abi::RustCall,
         expected_sig);
 
-    let region = match fcx.anon_regions(expr.span, 1) {
-        Err(_) => {
-            fcx.ccx.tcx.sess.span_bug(expr.span,
-                                      "can't make anon regions here?!")
-        }
-        Ok(regions) => regions[0],
-    };
-
     let closure_type = ty::mk_closure(fcx.ccx.tcx,
                                       expr_def_id,
-                                      fcx.ccx.tcx.mk_region(region),
                                       fcx.ccx.tcx.mk_substs(
                                         fcx.inh.param_env.free_substs.clone()));
 
@@ -119,15 +110,11 @@ fn deduce_expectations_from_expected_type<'a,'tcx>(
         ty::ty_trait(ref object_type) => {
             let proj_bounds = object_type.projection_bounds_with_self_ty(fcx.tcx(),
                                                                          fcx.tcx().types.err);
-            let expectations =
-                proj_bounds.iter()
-                           .filter_map(|pb| deduce_expectations_from_projection(fcx, pb))
-                           .next();
-
-            match expectations {
-                Some((sig, kind)) => (Some(sig), Some(kind)),
-                None => (None, None)
-            }
+            let sig = proj_bounds.iter()
+                                 .filter_map(|pb| deduce_sig_from_projection(fcx, pb))
+                                 .next();
+            let kind = fcx.tcx().lang_items.fn_trait_kind(object_type.principal_def_id());
+            (sig, kind)
         }
         ty::ty_infer(ty::TyVar(vid)) => {
             deduce_expectations_from_obligations(fcx, vid)
@@ -146,7 +133,7 @@ fn deduce_expectations_from_obligations<'a,'tcx>(
     let fulfillment_cx = fcx.inh.fulfillment_cx.borrow();
     // Here `expected_ty` is known to be a type inference variable.
 
-    let expected_sig_and_kind =
+    let expected_sig =
         fulfillment_cx
         .pending_obligations()
         .iter()
@@ -160,7 +147,7 @@ fn deduce_expectations_from_obligations<'a,'tcx>(
                 ty::Predicate::Projection(ref proj_predicate) => {
                     let trait_ref = proj_predicate.to_poly_trait_ref();
                     self_type_matches_expected_vid(fcx, trait_ref, expected_vid)
-                        .and_then(|_| deduce_expectations_from_projection(fcx, proj_predicate))
+                        .and_then(|_| deduce_sig_from_projection(fcx, proj_predicate))
                 }
                 _ => {
                     None
@@ -169,14 +156,10 @@ fn deduce_expectations_from_obligations<'a,'tcx>(
         })
         .next();
 
-    match expected_sig_and_kind {
-        Some((sig, kind)) => { return (Some(sig), Some(kind)); }
-        None => { }
-    }
-
     // Even if we can't infer the full signature, we may be able to
     // infer the kind. This can occur if there is a trait-reference
-    // like `F : Fn<A>`.
+    // like `F : Fn<A>`. Note that due to subtyping we could encounter
+    // many viable options, so pick the most restrictive.
     let expected_kind =
         fulfillment_cx
         .pending_obligations()
@@ -193,54 +176,61 @@ fn deduce_expectations_from_obligations<'a,'tcx>(
                 .and_then(|trait_ref| self_type_matches_expected_vid(fcx, trait_ref, expected_vid))
                 .and_then(|trait_ref| fcx.tcx().lang_items.fn_trait_kind(trait_ref.def_id()))
         })
-        .next();
+        .fold(None, pick_most_restrictive_closure_kind);
 
-    (None, expected_kind)
+    (expected_sig, expected_kind)
+}
+
+fn pick_most_restrictive_closure_kind(best: Option<ty::ClosureKind>,
+                                      cur: ty::ClosureKind)
+                                      -> Option<ty::ClosureKind>
+{
+    match best {
+        None => Some(cur),
+        Some(best) => Some(cmp::min(best, cur))
+    }
 }
 
 /// Given a projection like "<F as Fn(X)>::Result == Y", we can deduce
 /// everything we need to know about a closure.
-fn deduce_expectations_from_projection<'a,'tcx>(
+fn deduce_sig_from_projection<'a,'tcx>(
     fcx: &FnCtxt<'a,'tcx>,
     projection: &ty::PolyProjectionPredicate<'tcx>)
-    -> Option<(ty::FnSig<'tcx>, ty::ClosureKind)>
+    -> Option<ty::FnSig<'tcx>>
 {
     let tcx = fcx.tcx();
 
-    debug!("deduce_expectations_from_projection({})",
+    debug!("deduce_sig_from_projection({})",
            projection.repr(tcx));
 
     let trait_ref = projection.to_poly_trait_ref();
 
-    let kind = match tcx.lang_items.fn_trait_kind(trait_ref.def_id()) {
-        Some(k) => k,
-        None => { return None; }
-    };
-
-    debug!("found object type {:?}", kind);
+    if tcx.lang_items.fn_trait_kind(trait_ref.def_id()).is_none() {
+        return None;
+    }
 
     let arg_param_ty = *trait_ref.substs().types.get(subst::TypeSpace, 0);
     let arg_param_ty = fcx.infcx().resolve_type_vars_if_possible(&arg_param_ty);
-    debug!("arg_param_ty {}", arg_param_ty.repr(tcx));
+    debug!("deduce_sig_from_projection: arg_param_ty {}", arg_param_ty.repr(tcx));
 
     let input_tys = match arg_param_ty.sty {
         ty::ty_tup(ref tys) => { (*tys).clone() }
         _ => { return None; }
     };
-    debug!("input_tys {}", input_tys.repr(tcx));
+    debug!("deduce_sig_from_projection: input_tys {}", input_tys.repr(tcx));
 
     let ret_param_ty = projection.0.ty;
     let ret_param_ty = fcx.infcx().resolve_type_vars_if_possible(&ret_param_ty);
-    debug!("ret_param_ty {}", ret_param_ty.repr(tcx));
+    debug!("deduce_sig_from_projection: ret_param_ty {}", ret_param_ty.repr(tcx));
 
     let fn_sig = ty::FnSig {
         inputs: input_tys,
         output: ty::FnConverging(ret_param_ty),
         variadic: false
     };
-    debug!("fn_sig {}", fn_sig.repr(tcx));
+    debug!("deduce_sig_from_projection: fn_sig {}", fn_sig.repr(tcx));
 
-    return Some((fn_sig, kind));
+    Some(fn_sig)
 }
 
 fn self_type_matches_expected_vid<'a,'tcx>(
@@ -258,5 +248,3 @@ fn self_type_matches_expected_vid<'a,'tcx>(
         _ => None,
     }
 }
-
-
index 04a3f423dce11015ed08cf935ee13edf6c4784f1..ced6cec3ef0dc3daef00349ce18f90f9e057a242 100644 (file)
 
 use check::{autoderef, FnCtxt, NoPreference, PreferMutLvalue, UnresolvedTypeAction};
 
-use middle::infer::{self, cres, Coercion, TypeTrace};
-use middle::infer::combine::Combine;
-use middle::infer::sub::Sub;
+use middle::infer::{self, Coercion};
 use middle::subst;
 use middle::ty::{AutoPtr, AutoDerefRef, AdjustDerefRef, AutoUnsize, AutoUnsafe};
 use middle::ty::{self, mt, Ty};
+use middle::ty_relate::RelateResult;
 use util::common::indent;
 use util::ppaux;
 use util::ppaux::Repr;
@@ -76,10 +75,10 @@ use syntax::ast;
 
 struct Coerce<'a, 'tcx: 'a> {
     fcx: &'a FnCtxt<'a, 'tcx>,
-    trace: TypeTrace<'tcx>
+    origin: infer::TypeOrigin,
 }
 
-type CoerceResult<'tcx> = cres<'tcx, Option<ty::AutoAdjustment<'tcx>>>;
+type CoerceResult<'tcx> = RelateResult<'tcx, Option<ty::AutoAdjustment<'tcx>>>;
 
 impl<'f, 'tcx> Coerce<'f, 'tcx> {
     fn tcx(&self) -> &ty::ctxt<'tcx> {
@@ -87,11 +86,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     }
 
     fn subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
-        let sub = Sub(self.fcx.infcx().combine_fields(false, self.trace.clone()));
-        try!(sub.tys(a, b));
+        try!(self.fcx.infcx().sub_types(false, self.origin.clone(), a, b));
         Ok(None) // No coercion required.
     }
 
+    fn outlives(&self,
+                origin: infer::SubregionOrigin<'tcx>,
+                a: ty::Region,
+                b: ty::Region)
+                -> RelateResult<'tcx, ()> {
+        infer::mk_subr(self.fcx.infcx(), origin, b, a);
+        Ok(())
+    }
+
     fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where
         F: FnOnce(Ty<'tcx>) -> T,
     {
@@ -143,6 +150,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                     // require double indirection).
                     self.coerce_from_fn_item(a, a_def_id, a_f, b)
                 }
+                ty::ty_bare_fn(None, a_f) => {
+                    // We permit coercion of fn pointers to drop the
+                    // unsafe qualifier.
+                    self.coerce_from_fn_pointer(a, a_f, b)
+                }
                 _ => {
                     // Otherwise, just use subtyping rules.
                     self.subtype(a, b)
@@ -179,7 +191,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             _ => return self.subtype(a, b)
         }
 
-        let coercion = Coercion(self.trace.clone());
+        let coercion = Coercion(self.origin.span());
         let r_borrow = self.fcx.infcx().next_region_var(coercion);
         let autoref = Some(AutoPtr(r_borrow, mutbl_b, None));
 
@@ -203,7 +215,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             }
             let ty = ty::mk_rptr(self.tcx(), r_borrow,
                                  mt {ty: inner_ty, mutbl: mutbl_b});
-            if let Err(err) = self.fcx.infcx().try(|_| self.subtype(ty, b)) {
+            if let Err(err) = self.subtype(ty, b) {
                 if first_error.is_none() {
                     first_error = Some(err);
                 }
@@ -247,70 +259,64 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
         match (&a.sty, &b.sty) {
             (&ty::ty_rptr(_, ty::mt{ty: t_a, mutbl: mutbl_a}), &ty::ty_rptr(_, mt_b)) => {
-                self.unpack_actual_value(t_a, |a| {
-                    match self.unsize_ty(t_a, a, mt_b.ty) {
-                        Some((ty, kind)) => {
-                            if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
-                                return Err(ty::terr_mutability);
-                            }
-
-                            let coercion = Coercion(self.trace.clone());
-                            let r_borrow = self.fcx.infcx().next_region_var(coercion);
-                            let ty = ty::mk_rptr(self.tcx(),
-                                                 self.tcx().mk_region(r_borrow),
-                                                 ty::mt{ty: ty, mutbl: mt_b.mutbl});
-                            try!(self.fcx.infcx().try(|_| self.subtype(ty, b)));
-                            debug!("Success, coerced with AutoDerefRef(1, \
-                                    AutoPtr(AutoUnsize({:?})))", kind);
-                            Ok(Some(AdjustDerefRef(AutoDerefRef {
-                                autoderefs: 1,
-                                autoref: Some(ty::AutoPtr(r_borrow, mt_b.mutbl,
-                                                          Some(box AutoUnsize(kind))))
-                            })))
+                match self.unsize_ty(t_a, mt_b.ty) {
+                    Some((ty, kind)) => {
+                        if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
+                            return Err(ty::terr_mutability);
                         }
-                        _ => Err(ty::terr_mismatch)
+
+                        let coercion = Coercion(self.origin.span());
+                        let r_borrow = self.fcx.infcx().next_region_var(coercion);
+                        let ty = ty::mk_rptr(self.tcx(),
+                                             self.tcx().mk_region(r_borrow),
+                                             ty::mt{ty: ty, mutbl: mt_b.mutbl});
+                        try!(self.subtype(ty, b));
+                        debug!("Success, coerced with AutoDerefRef(1, \
+                                AutoPtr(AutoUnsize({:?})))", kind);
+                        Ok(Some(AdjustDerefRef(AutoDerefRef {
+                            autoderefs: 1,
+                            autoref: Some(ty::AutoPtr(r_borrow, mt_b.mutbl,
+                                                      Some(box AutoUnsize(kind))))
+                        })))
                     }
-                })
+                    _ => Err(ty::terr_mismatch)
+                }
             }
             (&ty::ty_rptr(_, ty::mt{ty: t_a, mutbl: mutbl_a}), &ty::ty_ptr(mt_b)) => {
-                self.unpack_actual_value(t_a, |a| {
-                    match self.unsize_ty(t_a, a, mt_b.ty) {
-                        Some((ty, kind)) => {
-                            if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
-                                return Err(ty::terr_mutability);
-                            }
-
-                            let ty = ty::mk_ptr(self.tcx(),
-                                                 ty::mt{ty: ty, mutbl: mt_b.mutbl});
-                            try!(self.fcx.infcx().try(|_| self.subtype(ty, b)));
-                            debug!("Success, coerced with AutoDerefRef(1, \
-                                    AutoPtr(AutoUnsize({:?})))", kind);
-                            Ok(Some(AdjustDerefRef(AutoDerefRef {
-                                autoderefs: 1,
-                                autoref: Some(ty::AutoUnsafe(mt_b.mutbl,
-                                                             Some(box AutoUnsize(kind))))
-                            })))
+                match self.unsize_ty(t_a, mt_b.ty) {
+                    Some((ty, kind)) => {
+                        if !can_coerce_mutbls(mutbl_a, mt_b.mutbl) {
+                            return Err(ty::terr_mutability);
                         }
-                        _ => Err(ty::terr_mismatch)
+
+                        let ty = ty::mk_ptr(self.tcx(),
+                                             ty::mt{ty: ty, mutbl: mt_b.mutbl});
+                        try!(self.subtype(ty, b));
+                        debug!("Success, coerced with AutoDerefRef(1, \
+                                AutoPtr(AutoUnsize({:?})))", kind);
+                        Ok(Some(AdjustDerefRef(AutoDerefRef {
+                            autoderefs: 1,
+                            autoref: Some(ty::AutoUnsafe(mt_b.mutbl,
+                                                         Some(box AutoUnsize(kind))))
+                        })))
                     }
-                })
+                    _ => Err(ty::terr_mismatch)
+                }
             }
             (&ty::ty_uniq(t_a), &ty::ty_uniq(t_b)) => {
-                self.unpack_actual_value(t_a, |a| {
-                    match self.unsize_ty(t_a, a, t_b) {
-                        Some((ty, kind)) => {
-                            let ty = ty::mk_uniq(self.tcx(), ty);
-                            try!(self.fcx.infcx().try(|_| self.subtype(ty, b)));
-                            debug!("Success, coerced with AutoDerefRef(1, \
-                                    AutoUnsizeUniq({:?}))", kind);
-                            Ok(Some(AdjustDerefRef(AutoDerefRef {
-                                autoderefs: 1,
-                                autoref: Some(ty::AutoUnsizeUniq(kind))
-                            })))
-                        }
-                        _ => Err(ty::terr_mismatch)
+                match self.unsize_ty(t_a, t_b) {
+                    Some((ty, kind)) => {
+                        let ty = ty::mk_uniq(self.tcx(), ty);
+                        try!(self.subtype(ty, b));
+                        debug!("Success, coerced with AutoDerefRef(1, \
+                                AutoUnsizeUniq({:?}))", kind);
+                        Ok(Some(AdjustDerefRef(AutoDerefRef {
+                            autoderefs: 1,
+                            autoref: Some(ty::AutoUnsizeUniq(kind))
+                        })))
                     }
-                })
+                    _ => Err(ty::terr_mismatch)
+                }
             }
             _ => Err(ty::terr_mismatch)
         }
@@ -321,76 +327,148 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
     // E.g., `[T, ..n]` -> `([T], UnsizeLength(n))`
     fn unsize_ty(&self,
                  ty_a: Ty<'tcx>,
-                 a: Ty<'tcx>,
                  ty_b: Ty<'tcx>)
-                 -> Option<(Ty<'tcx>, ty::UnsizeKind<'tcx>)> {
-        debug!("unsize_ty(a={:?}, ty_b={})", a, ty_b.repr(self.tcx()));
-
+                 -> Option<(Ty<'tcx>, ty::UnsizeKind<'tcx>)>
+    {
         let tcx = self.tcx();
 
-        self.unpack_actual_value(ty_b, |b|
-            match (&a.sty, &b.sty) {
-                (&ty::ty_vec(t_a, Some(len)), &ty::ty_vec(_, None)) => {
-                    let ty = ty::mk_vec(tcx, t_a, None);
-                    Some((ty, ty::UnsizeLength(len)))
-                }
-                (&ty::ty_trait(..), &ty::ty_trait(..)) => {
-                    None
-                }
-                (_, &ty::ty_trait(box ty::TyTrait { ref principal, ref bounds })) => {
-                    // FIXME what is the purpose of `ty`?
-                    let ty = ty::mk_trait(tcx, principal.clone(), bounds.clone());
-                    Some((ty, ty::UnsizeVtable(ty::TyTrait { principal: principal.clone(),
-                                                             bounds: bounds.clone() },
-                                               ty_a)))
-                }
-                (&ty::ty_struct(did_a, substs_a), &ty::ty_struct(did_b, substs_b))
-                  if did_a == did_b => {
-                    debug!("unsizing a struct");
-                    // Try unsizing each type param in turn to see if we end up with ty_b.
-                    let ty_substs_a = substs_a.types.get_slice(subst::TypeSpace);
-                    let ty_substs_b = substs_b.types.get_slice(subst::TypeSpace);
-                    assert!(ty_substs_a.len() == ty_substs_b.len());
-
-                    let mut result = None;
-                    let tps = ty_substs_a.iter().zip(ty_substs_b.iter()).enumerate();
-                    for (i, (tp_a, tp_b)) in tps {
-                        if self.fcx.infcx().try(|_| self.subtype(*tp_a, *tp_b)).is_ok() {
-                            continue;
+        self.unpack_actual_value(ty_a, |a| {
+            self.unpack_actual_value(ty_b, |b| {
+                debug!("unsize_ty(a={}, b={})", a.repr(self.tcx()), b.repr(self.tcx()));
+                match (&a.sty, &b.sty) {
+                    (&ty::ty_vec(t_a, Some(len)), &ty::ty_vec(_, None)) => {
+                        let ty = ty::mk_vec(tcx, t_a, None);
+                        Some((ty, ty::UnsizeLength(len)))
+                    }
+                    (&ty::ty_trait(ref data_a), &ty::ty_trait(ref data_b)) => {
+                        // Upcasts permit two things:
+                        //
+                        // 1. Dropping builtin bounds, e.g. `Foo+Send` to `Foo`
+                        // 2. Tightening the region bound, e.g. `Foo+'a` to `Foo+'b` if `'a : 'b`
+                        //
+                        // Note that neither of these changes requires any
+                        // change at runtime.  Eventually this will be
+                        // generalized.
+                        //
+                        // We always upcast when we can because of reason
+                        // #2 (region bounds).
+                        if data_a.bounds.builtin_bounds.is_superset(&data_b.bounds.builtin_bounds) {
+                            // construct a type `a1` which is a version of
+                            // `a` using the upcast bounds from `b`
+                            let bounds_a1 = ty::ExistentialBounds {
+                                // From type b
+                                region_bound: data_b.bounds.region_bound,
+                                builtin_bounds: data_b.bounds.builtin_bounds,
+
+                                // From type a
+                                projection_bounds: data_a.bounds.projection_bounds.clone(),
+                            };
+                            let ty_a1 = ty::mk_trait(tcx, data_a.principal.clone(), bounds_a1);
+
+                            // relate `a1` to `b`
+                            let result = self.fcx.infcx().commit_if_ok(|_| {
+                                // it's ok to upcast from Foo+'a to Foo+'b so long as 'a : 'b
+                                try!(self.outlives(infer::RelateObjectBound(self.origin.span()),
+                                                   data_a.bounds.region_bound,
+                                                   data_b.bounds.region_bound));
+                                self.subtype(ty_a1, ty_b)
+                            });
+
+                            // if that was successful, we have a coercion
+                            match result {
+                                Ok(_) => Some((ty_b, ty::UnsizeUpcast(ty_b))),
+                                Err(_) => None,
+                            }
+                        } else {
+                            None
                         }
-                        match
-                            self.unpack_actual_value(
-                                *tp_a,
-                                |tp| self.unsize_ty(*tp_a, tp, *tp_b))
-                        {
-                            Some((new_tp, k)) => {
-                                // Check that the whole types match.
-                                let mut new_substs = substs_a.clone();
-                                new_substs.types.get_mut_slice(subst::TypeSpace)[i] = new_tp;
-                                let ty = ty::mk_struct(tcx, did_a, tcx.mk_substs(new_substs));
-                                if self.fcx.infcx().try(|_| self.subtype(ty, ty_b)).is_err() {
-                                    debug!("Unsized type parameter '{}', but still \
-                                            could not match types {} and {}",
-                                           ppaux::ty_to_string(tcx, *tp_a),
-                                           ppaux::ty_to_string(tcx, ty),
-                                           ppaux::ty_to_string(tcx, ty_b));
-                                    // We can only unsize a single type parameter, so
-                                    // if we unsize one and it doesn't give us the
-                                    // type we want, then we won't succeed later.
+                    }
+                    (_, &ty::ty_trait(ref data)) => {
+                        Some((ty_b, ty::UnsizeVtable(ty::TyTrait {
+                                                         principal: data.principal.clone(),
+                                                         bounds: data.bounds.clone()
+                                                     },
+                                                     ty_a)))
+                    }
+                    (&ty::ty_struct(did_a, substs_a), &ty::ty_struct(did_b, substs_b))
+                      if did_a == did_b => {
+                        debug!("unsizing a struct");
+                        // Try unsizing each type param in turn to see if we end up with ty_b.
+                        let ty_substs_a = substs_a.types.get_slice(subst::TypeSpace);
+                        let ty_substs_b = substs_b.types.get_slice(subst::TypeSpace);
+                        assert!(ty_substs_a.len() == ty_substs_b.len());
+
+                        let mut result = None;
+                        let tps = ty_substs_a.iter().zip(ty_substs_b.iter()).enumerate();
+                        for (i, (tp_a, tp_b)) in tps {
+                            if self.subtype(*tp_a, *tp_b).is_ok() {
+                                continue;
+                            }
+                            match self.unsize_ty(*tp_a, *tp_b) {
+                                Some((new_tp, k)) => {
+                                    // Check that the whole types match.
+                                    let mut new_substs = substs_a.clone();
+                                    new_substs.types.get_mut_slice(subst::TypeSpace)[i] = new_tp;
+                                    let ty = ty::mk_struct(tcx, did_a, tcx.mk_substs(new_substs));
+                                    if self.subtype(ty, ty_b).is_err() {
+                                        debug!("Unsized type parameter '{}', but still \
+                                                could not match types {} and {}",
+                                               ppaux::ty_to_string(tcx, *tp_a),
+                                               ppaux::ty_to_string(tcx, ty),
+                                               ppaux::ty_to_string(tcx, ty_b));
+                                        // We can only unsize a single type parameter, so
+                                        // if we unsize one and it doesn't give us the
+                                        // type we want, then we won't succeed later.
+                                        break;
+                                    }
+
+                                    result = Some((ty, ty::UnsizeStruct(box k, i)));
                                     break;
                                 }
-
-                                result = Some((ty, ty::UnsizeStruct(box k, i)));
-                                break;
+                                None => {}
                             }
-                            None => {}
                         }
+                        result
                     }
-                    result
+                    _ => None
+                }
+            })
+        })
+    }
+
+    fn coerce_from_fn_pointer(&self,
+                           a: Ty<'tcx>,
+                           fn_ty_a: &'tcx ty::BareFnTy<'tcx>,
+                           b: Ty<'tcx>)
+                           -> CoerceResult<'tcx>
+    {
+        /*!
+         * Attempts to coerce from the type of a Rust function item
+         * into a closure or a `proc`.
+         */
+
+        self.unpack_actual_value(b, |b| {
+            debug!("coerce_from_fn_pointer(a={}, b={})",
+                   a.repr(self.tcx()), b.repr(self.tcx()));
+
+            match b.sty {
+                ty::ty_bare_fn(None, fn_ty_b) => {
+                    match (fn_ty_a.unsafety, fn_ty_b.unsafety) {
+                        (ast::Unsafety::Normal, ast::Unsafety::Unsafe) => {
+                            let unsafe_a = self.tcx().safe_to_unsafe_fn_ty(fn_ty_a);
+                            try!(self.subtype(unsafe_a, b));
+                            Ok(Some(ty::AdjustUnsafeFnPointer))
+                        }
+                        _ => {
+                            self.subtype(a, b)
+                        }
+                    }
+                }
+                _ => {
+                    return self.subtype(a, b)
                 }
-                _ => None
             }
-        )
+        })
     }
 
     fn coerce_from_fn_item(&self,
@@ -458,14 +536,13 @@ pub fn mk_assignty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                              expr: &ast::Expr,
                              a: Ty<'tcx>,
                              b: Ty<'tcx>)
-                             -> cres<'tcx, ()> {
+                             -> RelateResult<'tcx, ()> {
     debug!("mk_assignty({} -> {})", a.repr(fcx.tcx()), b.repr(fcx.tcx()));
     let adjustment = try!(indent(|| {
-        fcx.infcx().commit_if_ok(|| {
-            let origin = infer::ExprAssignable(expr.span);
+        fcx.infcx().commit_if_ok(|_| {
             Coerce {
                 fcx: fcx,
-                trace: infer::TypeTrace::types(origin, false, a, b)
+                origin: infer::ExprAssignable(expr.span),
             }.coerce(expr, a, b)
         })
     }));
index 1e1d7e0926038ee833713e13e6f1ca8b7928bbae..532277d75b2e06af52afc2002fffe37f62957b58 100644 (file)
@@ -15,7 +15,7 @@ use middle::subst::{self, Subst, Substs, VecPerParamSpace};
 use util::ppaux::{self, Repr};
 
 use syntax::ast;
-use syntax::codemap::{Span};
+use syntax::codemap::Span;
 use syntax::parse::token;
 
 use super::assoc;
@@ -282,7 +282,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
     let trait_fty = ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(trait_m.fty.clone()));
     let trait_fty = trait_fty.subst(tcx, &trait_to_skol_substs);
 
-    let err = infcx.try(|snapshot| {
+    let err = infcx.commit_if_ok(|snapshot| {
         let origin = infer::MethodCompatCheck(impl_m_span);
 
         let (impl_sig, _) =
index 6f2d0cb3667418023cc69a0d954305d84bab85cb..cd6a1226e00c9d639d8c83d38891caaf13122e85 100644 (file)
@@ -53,9 +53,11 @@ pub fn eqtype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
     }
 }
 
-// Checks that the type `actual` can be coerced to `expected`.
-pub fn coerce<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
-                        expected: Ty<'tcx>, expr: &ast::Expr) {
+// Checks that the type of `expr` can be coerced to `expected`.
+pub fn coerce<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                        sp: Span,
+                        expected: Ty<'tcx>,
+                        expr: &ast::Expr) {
     let expr_ty = fcx.expr_ty(expr);
     debug!("demand::coerce(expected = {}, expr_ty = {})",
            expected.repr(fcx.ccx.tcx),
index ce67369ca9dda132ecfa707b24b6c0ea8d9cc0be..2f7e0073e1751ad0f99ee08fc7714ee5269749ff 100644 (file)
@@ -12,12 +12,249 @@ use check::regionck::{self, Rcx};
 
 use middle::infer;
 use middle::region;
-use middle::subst;
+use middle::subst::{self, Subst};
 use middle::ty::{self, Ty};
-use util::ppaux::{Repr};
+use util::ppaux::{Repr, UserString};
+
+use syntax::ast;
+use syntax::codemap::{self, Span};
+
+/// check_drop_impl confirms that the Drop implementation identfied by
+/// `drop_impl_did` is not any more specialized than the type it is
+/// attached to (Issue #8142).
+///
+/// This means:
+///
+/// 1. The self type must be nominal (this is already checked during
+///    coherence),
+///
+/// 2. The generic region/type parameters of the impl's self-type must
+///    all be parameters of the Drop impl itself (i.e. no
+///    specialization like `impl Drop for Foo<i32>`), and,
+///
+/// 3. Any bounds on the generic parameters must be reflected in the
+///    struct/enum definition for the nominal type itself (i.e.
+///    cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
+///
+pub fn check_drop_impl(tcx: &ty::ctxt, drop_impl_did: ast::DefId) -> Result<(), ()> {
+    let ty::TypeScheme { generics: ref dtor_generics,
+                         ty: ref dtor_self_type } = ty::lookup_item_type(tcx, drop_impl_did);
+    let dtor_predicates = ty::lookup_predicates(tcx, drop_impl_did);
+    match dtor_self_type.sty {
+        ty::ty_enum(self_type_did, self_to_impl_substs) |
+        ty::ty_struct(self_type_did, self_to_impl_substs) |
+        ty::ty_closure(self_type_did, self_to_impl_substs) => {
+            try!(ensure_drop_params_and_item_params_correspond(tcx,
+                                                               drop_impl_did,
+                                                               dtor_generics,
+                                                               dtor_self_type,
+                                                               self_type_did));
+
+            ensure_drop_predicates_are_implied_by_item_defn(tcx,
+                                                            drop_impl_did,
+                                                            &dtor_predicates,
+                                                            self_type_did,
+                                                            self_to_impl_substs)
+        }
+        _ => {
+            // Destructors only work on nominal types.  This was
+            // already checked by coherence, so we can panic here.
+            let span = tcx.map.def_id_span(drop_impl_did, codemap::DUMMY_SP);
+            tcx.sess.span_bug(
+                span, &format!("should have been rejected by coherence check: {}",
+                               dtor_self_type.repr(tcx)));
+        }
+    }
+}
+
+fn ensure_drop_params_and_item_params_correspond<'tcx>(
+    tcx: &ty::ctxt<'tcx>,
+    drop_impl_did: ast::DefId,
+    drop_impl_generics: &ty::Generics<'tcx>,
+    drop_impl_ty: &ty::Ty<'tcx>,
+    self_type_did: ast::DefId) -> Result<(), ()>
+{
+    // New strategy based on review suggestion from nikomatsakis.
+    //
+    // (In the text and code below, "named" denotes "struct/enum", and
+    // "generic params" denotes "type and region params")
+    //
+    // 1. Create fresh skolemized type/region "constants" for each of
+    //    the named type's generic params.  Instantiate the named type
+    //    with the fresh constants, yielding `named_skolem`.
+    //
+    // 2. Create unification variables for each of the Drop impl's
+    //    generic params.  Instantiate the impl's Self's type with the
+    //    unification-vars, yielding `drop_unifier`.
+    //
+    // 3. Attempt to unify Self_unif with Type_skolem.  If unification
+    //    succeeds, continue (i.e. with the predicate checks).
+
+    let ty::TypeScheme { generics: ref named_type_generics,
+                         ty: named_type } =
+        ty::lookup_item_type(tcx, self_type_did);
+
+    let infcx = infer::new_infer_ctxt(tcx);
+    infcx.commit_if_ok(|snapshot| {
+        let (named_type_to_skolem, skol_map) =
+            infcx.construct_skolemized_subst(named_type_generics, snapshot);
+        let named_type_skolem = named_type.subst(tcx, &named_type_to_skolem);
+
+        let drop_impl_span = tcx.map.def_id_span(drop_impl_did, codemap::DUMMY_SP);
+        let drop_to_unifier =
+            infcx.fresh_substs_for_generics(drop_impl_span, drop_impl_generics);
+        let drop_unifier = drop_impl_ty.subst(tcx, &drop_to_unifier);
+
+        if let Ok(()) = infer::mk_eqty(&infcx, true, infer::TypeOrigin::Misc(drop_impl_span),
+                                       named_type_skolem, drop_unifier) {
+            // Even if we did manage to equate the types, the process
+            // may have just gathered unsolvable region constraints
+            // like `R == 'static` (represented as a pair of subregion
+            // constraints) for some skolemization constant R.
+            //
+            // However, the leak_check method allows us to confirm
+            // that no skolemized regions escaped (i.e. were related
+            // to other regions in the constraint graph).
+            if let Ok(()) = infcx.leak_check(&skol_map, snapshot) {
+                return Ok(())
+            }
+        }
+
+        span_err!(tcx.sess, drop_impl_span, E0366,
+                  "Implementations of Drop cannot be specialized");
+        let item_span = tcx.map.span(self_type_did.node);
+        tcx.sess.span_note(item_span,
+                           "Use same sequence of generic type and region \
+                            parameters that is on the struct/enum definition");
+        return Err(());
+    })
+}
+
+/// Confirms that every predicate imposed by dtor_predicates is
+/// implied by assuming the predicates attached to self_type_did.
+fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
+    tcx: &ty::ctxt<'tcx>,
+    drop_impl_did: ast::DefId,
+    dtor_predicates: &ty::GenericPredicates<'tcx>,
+    self_type_did: ast::DefId,
+    self_to_impl_substs: &subst::Substs<'tcx>) -> Result<(), ()> {
+
+    // Here is an example, analogous to that from
+    // `compare_impl_method`.
+    //
+    // Consider a struct type:
+    //
+    //     struct Type<'c, 'b:'c, 'a> {
+    //         x: &'a Contents            // (contents are irrelevant;
+    //         y: &'c Cell<&'b Contents>, //  only the bounds matter for our purposes.)
+    //     }
+    //
+    // and a Drop impl:
+    //
+    //     impl<'z, 'y:'z, 'x:'y> Drop for P<'z, 'y, 'x> {
+    //         fn drop(&mut self) { self.y.set(self.x); } // (only legal if 'x: 'y)
+    //     }
+    //
+    // We start out with self_to_impl_substs, that maps the generic
+    // parameters of Type to that of the Drop impl.
+    //
+    //     self_to_impl_substs = {'c => 'z, 'b => 'y, 'a => 'x}
+    //
+    // Applying this to the predicates (i.e. assumptions) provided by the item
+    // definition yields the instantiated assumptions:
+    //
+    //     ['y : 'z]
+    //
+    // We then check all of the predicates of the Drop impl:
+    //
+    //     ['y:'z, 'x:'y]
+    //
+    // and ensure each is in the list of instantiated
+    // assumptions. Here, `'y:'z` is present, but `'x:'y` is
+    // absent. So we report an error that the Drop impl injected a
+    // predicate that is not present on the struct definition.
+
+    assert_eq!(self_type_did.krate, ast::LOCAL_CRATE);
+
+    let drop_impl_span = tcx.map.def_id_span(drop_impl_did, codemap::DUMMY_SP);
+
+    // We can assume the predicates attached to struct/enum definition
+    // hold.
+    let generic_assumptions = ty::lookup_predicates(tcx, self_type_did);
+
+    let assumptions_in_impl_context = generic_assumptions.instantiate(tcx, &self_to_impl_substs);
+    assert!(assumptions_in_impl_context.predicates.is_empty_in(subst::SelfSpace));
+    assert!(assumptions_in_impl_context.predicates.is_empty_in(subst::FnSpace));
+    let assumptions_in_impl_context =
+        assumptions_in_impl_context.predicates.get_slice(subst::TypeSpace);
+
+    // An earlier version of this code attempted to do this checking
+    // via the traits::fulfill machinery. However, it ran into trouble
+    // since the fulfill machinery merely turns outlives-predicates
+    // 'a:'b and T:'b into region inference constraints. It is simpler
+    // just to look for all the predicates directly.
+
+    assert!(dtor_predicates.predicates.is_empty_in(subst::SelfSpace));
+    assert!(dtor_predicates.predicates.is_empty_in(subst::FnSpace));
+    let predicates = dtor_predicates.predicates.get_slice(subst::TypeSpace);
+    for predicate in predicates {
+        // (We do not need to worry about deep analysis of type
+        // expressions etc because the Drop impls are already forced
+        // to take on a structure that is roughly a alpha-renaming of
+        // the generic parameters of the item definition.)
+
+        // This path now just checks *all* predicates via the direct
+        // lookup, rather than using fulfill machinery.
+        //
+        // However, it may be more efficient in the future to batch
+        // the analysis together via the fulfill , rather than the
+        // repeated `contains` calls.
+
+        if !assumptions_in_impl_context.contains(&predicate) {
+            let item_span = tcx.map.span(self_type_did.node);
+            let req = predicate.user_string(tcx);
+            span_err!(tcx.sess, drop_impl_span, E0367,
+                      "The requirement `{}` is added only by the Drop impl.", req);
+            tcx.sess.span_note(item_span,
+                               "The same requirement must be part of \
+                                the struct/enum definition");
+        }
+    }
 
-use syntax::codemap::Span;
+    if tcx.sess.has_errors() {
+        return Err(());
+    }
+    Ok(())
+}
 
+/// check_safety_of_destructor_if_necessary confirms that the type
+/// expression `typ` conforms to the "Drop Check Rule" from the Sound
+/// Generic Drop (RFC 769).
+///
+/// ----
+///
+/// The Drop Check Rule is the following:
+///
+/// Let `v` be some value (either temporary or named) and 'a be some
+/// lifetime (scope). If the type of `v` owns data of type `D`, where
+///
+///   (1.) `D` has a lifetime- or type-parametric Drop implementation, and
+///   (2.) the structure of `D` can reach a reference of type `&'a _`, and
+///   (3.) either:
+///
+///     (A.) the Drop impl for `D` instantiates `D` at 'a directly,
+///          i.e. `D<'a>`, or,
+///
+///     (B.) the Drop impl for `D` has some type parameter with a
+///          trait bound `T` where `T` is a trait that has at least
+///          one method,
+///
+/// then 'a must strictly outlive the scope of v.
+///
+/// ----
+///
+/// This function is meant to by applied to the type for every
+/// expression in the program.
 pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
                                                      typ: ty::Ty<'tcx>,
                                                      span: Span,
@@ -28,29 +265,98 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
     // types that have been traversed so far by `traverse_type_if_unseen`
     let mut breadcrumbs: Vec<Ty<'tcx>> = Vec::new();
 
-    iterate_over_potentially_unsafe_regions_in_type(
+    let result = iterate_over_potentially_unsafe_regions_in_type(
         rcx,
         &mut breadcrumbs,
+        TypeContext::Root,
         typ,
         span,
         scope,
+        0,
         0);
+    match result {
+        Ok(()) => {}
+        Err(Error::Overflow(ref ctxt, ref detected_on_typ)) => {
+            let tcx = rcx.tcx();
+            span_err!(tcx.sess, span, E0320,
+                      "overflow while adding drop-check rules for {}",
+                      typ.user_string(rcx.tcx()));
+            match *ctxt {
+                TypeContext::Root => {
+                    // no need for an additional note if the overflow
+                    // was somehow on the root.
+                }
+                TypeContext::EnumVariant { def_id, variant, arg_index } => {
+                    // FIXME (pnkfelix): eventually lookup arg_name
+                    // for the given index on struct variants.
+                    span_note!(
+                        rcx.tcx().sess,
+                        span,
+                        "overflowed on enum {} variant {} argument {} type: {}",
+                        ty::item_path_str(tcx, def_id),
+                        variant,
+                        arg_index,
+                        detected_on_typ.user_string(rcx.tcx()));
+                }
+                TypeContext::Struct { def_id, field } => {
+                    span_note!(
+                        rcx.tcx().sess,
+                        span,
+                        "overflowed on struct {} field {} type: {}",
+                        ty::item_path_str(tcx, def_id),
+                        field,
+                        detected_on_typ.user_string(rcx.tcx()));
+                }
+            }
+        }
+    }
+}
+
+enum Error<'tcx> {
+    Overflow(TypeContext, ty::Ty<'tcx>),
 }
 
+enum TypeContext {
+    Root,
+    EnumVariant {
+        def_id: ast::DefId,
+        variant: ast::Name,
+        arg_index: usize,
+    },
+    Struct {
+        def_id: ast::DefId,
+        field: ast::Name,
+    }
+}
+
+// The `depth` counts the number of calls to this function;
+// the `xref_depth` counts the subset of such calls that go
+// across a `Box<T>` or `PhantomData<T>`.
 fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
     rcx: &mut Rcx<'a, 'tcx>,
     breadcrumbs: &mut Vec<Ty<'tcx>>,
+    context: TypeContext,
     ty_root: ty::Ty<'tcx>,
     span: Span,
     scope: region::CodeExtent,
-    depth: uint)
+    depth: usize,
+    xref_depth: usize) -> Result<(), Error<'tcx>>
 {
-    let origin = |&:| infer::SubregionOrigin::SafeDestructor(span);
+    // Issue #22443: Watch out for overflow. While we are careful to
+    // handle regular types properly, non-regular ones cause problems.
+    let recursion_limit = rcx.tcx().sess.recursion_limit.get();
+    if xref_depth >= recursion_limit {
+        return Err(Error::Overflow(context, ty_root))
+    }
+
+    let origin = || infer::SubregionOrigin::SafeDestructor(span);
     let mut walker = ty_root.walk();
     let opt_phantom_data_def_id = rcx.tcx().lang_items.phantom_data();
 
     let destructor_for_type = rcx.tcx().destructor_for_type.borrow();
 
+    let xref_depth_orig = xref_depth;
+
     while let Some(typ) = walker.next() {
         // Avoid recursing forever.
         if breadcrumbs.contains(&typ) {
@@ -61,20 +367,33 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
         // If we encounter `PhantomData<T>`, then we should replace it
         // with `T`, the type it represents as owned by the
         // surrounding context, before doing further analysis.
-        let typ = if let ty::ty_struct(struct_did, substs) = typ.sty {
-            if opt_phantom_data_def_id == Some(struct_did) {
-                let item_type = ty::lookup_item_type(rcx.tcx(), struct_did);
-                let tp_def = item_type.generics.types
-                    .opt_get(subst::TypeSpace, 0).unwrap();
-                let new_typ = substs.type_for_def(tp_def);
-                debug!("replacing phantom {} with {}",
+        let (typ, xref_depth) = match typ.sty {
+            ty::ty_struct(struct_did, substs) => {
+                if opt_phantom_data_def_id == Some(struct_did) {
+                    let item_type = ty::lookup_item_type(rcx.tcx(), struct_did);
+                    let tp_def = item_type.generics.types
+                        .opt_get(subst::TypeSpace, 0).unwrap();
+                    let new_typ = substs.type_for_def(tp_def);
+                    debug!("replacing phantom {} with {}",
+                           typ.repr(rcx.tcx()), new_typ.repr(rcx.tcx()));
+                    (new_typ, xref_depth_orig + 1)
+                } else {
+                    (typ, xref_depth_orig)
+                }
+            }
+
+            // Note: When ty_uniq is removed from compiler, the
+            // definition of `Box<T>` must carry a PhantomData that
+            // puts us into the previous case.
+            ty::ty_uniq(new_typ) => {
+                debug!("replacing ty_uniq {} with {}",
                        typ.repr(rcx.tcx()), new_typ.repr(rcx.tcx()));
-                new_typ
-            } else {
-                typ
+                (new_typ, xref_depth_orig + 1)
+            }
+
+            _ => {
+                (typ, xref_depth_orig)
             }
-        } else {
-            typ
         };
 
         let opt_type_did = match typ.sty {
@@ -87,9 +406,9 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
             opt_type_did.and_then(|did| destructor_for_type.get(&did));
 
         debug!("iterate_over_potentially_unsafe_regions_in_type \
-                {}typ: {} scope: {:?} opt_dtor: {:?}",
+                {}typ: {} scope: {:?} opt_dtor: {:?} xref: {}",
                (0..depth).map(|_| ' ').collect::<String>(),
-               typ.repr(rcx.tcx()), scope, opt_dtor);
+               typ.repr(rcx.tcx()), scope, opt_dtor, xref_depth);
 
         // If `typ` has a destructor, then we must ensure that all
         // borrowed data reachable via `typ` must outlive the parent
@@ -215,8 +534,8 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
                 match rcx.tcx().region_maps.opt_encl_scope(scope) {
                     Some(parent_scope) => ty::ReScope(parent_scope),
                     None => rcx.tcx().sess.span_bug(
-                        span, format!("no enclosing scope found for scope: {:?}",
-                                      scope).as_slice()),
+                        span, &format!("no enclosing scope found for scope: {:?}",
+                                       scope)),
                 };
 
             regionck::type_must_outlive(rcx, origin(), typ, parent_region);
@@ -228,6 +547,8 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
 
             match typ.sty {
                 ty::ty_struct(struct_did, substs) => {
+                    debug!("typ: {} is struct; traverse structure and not type-expression",
+                           typ.repr(rcx.tcx()));
                     // Don't recurse; we extract type's substructure,
                     // so do not process subparts of type expression.
                     walker.skip_current_subtree();
@@ -240,17 +561,24 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
                                                   struct_did,
                                                   field.id,
                                                   substs);
-                        iterate_over_potentially_unsafe_regions_in_type(
+                        try!(iterate_over_potentially_unsafe_regions_in_type(
                             rcx,
                             breadcrumbs,
+                            TypeContext::Struct {
+                                def_id: struct_did,
+                                field: field.name,
+                            },
                             field_type,
                             span,
                             scope,
-                            depth+1)
+                            depth+1,
+                            xref_depth))
                     }
                 }
 
                 ty::ty_enum(enum_did, substs) => {
+                    debug!("typ: {} is enum; traverse structure and not type-expression",
+                           typ.repr(rcx.tcx()));
                     // Don't recurse; we extract type's substructure,
                     // so do not process subparts of type expression.
                     walker.skip_current_subtree();
@@ -260,14 +588,20 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
                                                  enum_did,
                                                  substs);
                     for variant_info in all_variant_info.iter() {
-                        for argument_type in variant_info.args.iter() {
-                            iterate_over_potentially_unsafe_regions_in_type(
+                        for (i, arg_type) in variant_info.args.iter().enumerate() {
+                            try!(iterate_over_potentially_unsafe_regions_in_type(
                                 rcx,
                                 breadcrumbs,
-                                *argument_type,
+                                TypeContext::EnumVariant {
+                                    def_id: enum_did,
+                                    variant: variant_info.name,
+                                    arg_index: i,
+                                },
+                                *arg_type,
                                 span,
                                 scope,
-                                depth+1)
+                                depth+1,
+                                xref_depth));
                         }
                     }
                 }
@@ -290,4 +624,6 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
             // is done.
         }
     }
+
+    return Ok(());
 }
index 4aaaf4ffe5ab3028aa982a204df157ec4d289670..a4a18c7cfdea6722908ec88400c9e15aa050a59f 100644 (file)
@@ -12,7 +12,7 @@
 
 use astconv::object_region_bounds;
 use middle::infer::{InferCtxt, GenericKind};
-use middle::subst::{Substs};
+use middle::subst::Substs;
 use middle::traits;
 use middle::ty::{self, ToPolyTraitRef, Ty};
 use middle::ty_fold::{TypeFoldable, TypeFolder};
@@ -22,6 +22,7 @@ use syntax::ast;
 use syntax::codemap::Span;
 
 use util::common::ErrorReported;
+use util::nodemap::FnvHashSet;
 use util::ppaux::Repr;
 
 // Helper functions related to manipulating region types.
@@ -29,6 +30,7 @@ use util::ppaux::Repr;
 pub enum Implication<'tcx> {
     RegionSubRegion(Option<Ty<'tcx>>, ty::Region, ty::Region),
     RegionSubGeneric(Option<Ty<'tcx>>, ty::Region, GenericKind<'tcx>),
+    RegionSubClosure(Option<Ty<'tcx>>, ty::Region, ast::DefId, &'tcx Substs<'tcx>),
     Predicate(ast::DefId, ty::Predicate<'tcx>),
 }
 
@@ -39,6 +41,7 @@ struct Implicator<'a, 'tcx: 'a> {
     stack: Vec<(ty::Region, Option<Ty<'tcx>>)>,
     span: Span,
     out: Vec<Implication<'tcx>>,
+    visited: FnvHashSet<Ty<'tcx>>,
 }
 
 /// This routine computes the well-formedness constraints that must hold for the type `ty` to
@@ -64,7 +67,8 @@ pub fn implications<'a,'tcx>(
                               body_id: body_id,
                               span: span,
                               stack: stack,
-                              out: Vec::new() };
+                              out: Vec::new(),
+                              visited: FnvHashSet() };
     wf.accumulate_from_ty(ty);
     debug!("implications: out={}", wf.out.repr(closure_typer.tcx()));
     wf.out
@@ -79,6 +83,12 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
         debug!("accumulate_from_ty(ty={})",
                ty.repr(self.tcx()));
 
+        // When expanding out associated types, we can visit a cyclic
+        // set of types. Issue #23003.
+        if !self.visited.insert(ty) {
+            return;
+        }
+
         match ty.sty {
             ty::ty_bool |
             ty::ty_char |
@@ -91,29 +101,9 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
                 // No borrowed content reachable here.
             }
 
-            ty::ty_closure(_, region, _) => {
-                // An "closure type" is basically
-                // modeled here as equivalent to a struct like
-                //
-                //     struct TheClosure<'b> {
-                //         ...
-                //     }
-                //
-                // where the `'b` is the lifetime bound of the
-                // contents (i.e., all contents must outlive 'b).
-                //
-                // Even though closures are glorified structs
-                // of upvars, we do not need to consider them as they
-                // can't generate any new constraints.  The
-                // substitutions on the closure are equal to the free
-                // substitutions of the enclosing parameter
-                // environment.  An upvar captured by value has the
-                // same type as the original local variable which is
-                // already checked for consistency.  If the upvar is
-                // captured by reference it must also outlive the
-                // region bound on the closure, but this is explicitly
-                // handled by logic in regionck.
-                self.push_region_constraint_from_top(*region);
+            ty::ty_closure(def_id, substs) => {
+                let &(r_a, opt_ty) = self.stack.last().unwrap();
+                self.out.push(Implication::RegionSubClosure(opt_ty, r_a, def_id, substs));
             }
 
             ty::ty_trait(ref t) => {
@@ -161,12 +151,6 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
                 //   entering the fn check. We should do this after
                 //   the fn check, then we can call this case a bug().
             }
-
-            ty::ty_open(_) => {
-                self.tcx().sess.bug(
-                    &format!("Unexpected type encountered while doing wf check: {}",
-                            ty.repr(self.tcx()))[]);
-            }
         }
     }
 
@@ -454,6 +438,13 @@ impl<'tcx> Repr<'tcx> for Implication<'tcx> {
                         p.repr(tcx))
             }
 
+            Implication::RegionSubClosure(_, ref a, ref b, ref c) => {
+                format!("RegionSubClosure({}, {}, {})",
+                        a.repr(tcx),
+                        b.repr(tcx),
+                        c.repr(tcx))
+            }
+
             Implication::Predicate(ref def_id, ref p) => {
                 format!("Predicate({}, {})",
                         def_id.repr(tcx),
index dfbfc86c659704db316a77dc8f6cf8347126676a..6aefcf5a47cc6ed5417bd535b9add00974f4482b 100644 (file)
@@ -176,13 +176,13 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
             probe::AutoDeref(num) => {
                 ty::AutoDerefRef {
                     autoderefs: num,
-                    autoref: None
+                    autoref: None,
                 }
             }
             probe::AutoUnsizeLength(autoderefs, len) => {
                 ty::AutoDerefRef {
                     autoderefs: autoderefs,
-                    autoref: Some(ty::AutoUnsize(ty::UnsizeLength(len)))
+                    autoref: Some(ty::AutoUnsize(ty::UnsizeLength(len))),
                 }
             }
             probe::AutoRef(mutability, ref sub_adjustment) => {
@@ -331,7 +331,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
                 self.tcx().sess.span_bug(
                     self.span,
                     &format!("self-type `{}` for ObjectPick never dereferenced to an object",
-                            self_ty.repr(self.tcx()))[])
+                            self_ty.repr(self.tcx())))
             }
         }
     }
@@ -386,7 +386,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
                     &format!(
                         "{} was a subtype of {} but now is not?",
                         self_ty.repr(self.tcx()),
-                        method_self_ty.repr(self.tcx()))[]);
+                        method_self_ty.repr(self.tcx())));
             }
         }
     }
@@ -404,26 +404,9 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
                all_substs.repr(self.tcx()));
 
         // Instantiate the bounds on the method with the
-        // type/early-bound-regions substitutions performed.  The only
-        // late-bound-regions that can appear in bounds are from the
-        // impl, and those were already instantiated above.
-        //
-        // FIXME(DST). Super hack. For a method on a trait object
-        // `Trait`, the generic signature requires that
-        // `Self:Trait`. Since, for an object, we bind `Self` to the
-        // type `Trait`, this leads to an obligation
-        // `Trait:Trait`. Until such time we DST is fully implemented,
-        // that obligation is not necessarily satisfied. (In the
-        // future, it would be.) But we know that the true `Self` DOES implement
-        // the trait. So we just delete this requirement. Hack hack hack.
-        let mut method_predicates = pick.method_ty.predicates.instantiate(self.tcx(), &all_substs);
-        match pick.kind {
-            probe::ObjectPick(..) => {
-                assert_eq!(method_predicates.predicates.get_slice(subst::SelfSpace).len(), 1);
-                method_predicates.predicates.pop(subst::SelfSpace);
-            }
-            _ => { }
-        }
+        // type/early-bound-regions substitutions performed. There can
+        // be no late-bound regions appearing here.
+        let method_predicates = pick.method_ty.predicates.instantiate(self.tcx(), &all_substs);
         let method_predicates = self.fcx.normalize_associated_types_in(self.span,
                                                                        &method_predicates);
 
@@ -651,16 +634,21 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
               target_trait_def_id: ast::DefId)
               -> ty::PolyTraitRef<'tcx>
     {
-        match traits::upcast(self.tcx(), source_trait_ref.clone(), target_trait_def_id) {
-            Some(super_trait_ref) => super_trait_ref,
-            None => {
-                self.tcx().sess.span_bug(
-                    self.span,
-                    &format!("cannot upcast `{}` to `{}`",
-                             source_trait_ref.repr(self.tcx()),
-                             target_trait_def_id.repr(self.tcx())));
-            }
+        let upcast_trait_refs = traits::upcast(self.tcx(),
+                                               source_trait_ref.clone(),
+                                               target_trait_def_id);
+
+        // must be exactly one trait ref or we'd get an ambig error etc
+        if upcast_trait_refs.len() != 1 {
+            self.tcx().sess.span_bug(
+                self.span,
+                &format!("cannot uniquely upcast `{}` to `{}`: `{}`",
+                         source_trait_ref.repr(self.tcx()),
+                         target_trait_def_id.repr(self.tcx()),
+                         upcast_trait_refs.repr(self.tcx())));
         }
+
+        upcast_trait_refs.into_iter().next().unwrap()
     }
 
     fn replace_late_bound_regions_with_fresh_var<T>(&self, value: &ty::Binder<T>) -> T
index ffbc8ad020ab7819af598d980947e4f59a1c295b..677ab56852434802541e68a64f1014b2548085e8 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Method lookup: the secret sauce of Rust. See `doc.rs`.
+//! Method lookup: the secret sauce of Rust. See `README.md`.
 
 use astconv::AstConv;
-use check::{FnCtxt};
+use check::FnCtxt;
 use check::vtable;
 use check::vtable::select_new_fcx_obligations;
+use middle::def;
+use middle::privacy::{AllPublic, DependsOn, LastPrivate, LastMod};
 use middle::subst;
 use middle::traits;
 use middle::ty::*;
@@ -22,7 +24,7 @@ use middle::infer;
 use util::ppaux::Repr;
 
 use std::rc::Rc;
-use syntax::ast::{DefId};
+use syntax::ast::DefId;
 use syntax::ast;
 use syntax::codemap::Span;
 
@@ -50,13 +52,13 @@ pub enum MethodError {
 
 // A pared down enum describing just the places from which a method
 // candidate can arise. Used for error reporting only.
-#[derive(Copy, PartialOrd, Ord, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
 pub enum CandidateSource {
     ImplSource(ast::DefId),
     TraitSource(/* trait id */ ast::DefId),
 }
 
-type MethodIndex = uint; // just for doc purposes
+type MethodIndex = usize; // just for doc purposes
 
 /// Determines whether the type `self_ty` supports a method name `method_name` or not.
 pub fn exists<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
@@ -66,7 +68,8 @@ pub fn exists<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                         call_expr_id: ast::NodeId)
                         -> bool
 {
-    match probe::probe(fcx, span, method_name, self_ty, call_expr_id) {
+    let mode = probe::Mode::MethodCall;
+    match probe::probe(fcx, span, mode, method_name, self_ty, call_expr_id) {
         Ok(..) => true,
         Err(NoMatch(..)) => false,
         Err(Ambiguity(..)) => true,
@@ -103,8 +106,9 @@ pub fn lookup<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
            call_expr.repr(fcx.tcx()),
            self_expr.repr(fcx.tcx()));
 
+    let mode = probe::Mode::MethodCall;
     let self_ty = fcx.infcx().resolve_type_vars_if_possible(&self_ty);
-    let pick = try!(probe::probe(fcx, span, method_name, self_ty, call_expr.id));
+    let pick = try!(probe::probe(fcx, span, mode, method_name, self_ty, call_expr.id));
     Ok(confirm::confirm(fcx, span, self_expr, call_expr, self_ty, pick, supplied_method_types))
 }
 
@@ -272,7 +276,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                 span,
                                 &format!(
                                     "trait method is &self but first arg is: {}",
-                                    transformed_self_ty.repr(fcx.tcx()))[]);
+                                    transformed_self_ty.repr(fcx.tcx())));
                         }
                     }
                 }
@@ -282,7 +286,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                         span,
                         &format!(
                             "unexpected explicit self type in operator method: {:?}",
-                            method_ty.explicit_self)[]);
+                            method_ty.explicit_self));
                 }
             }
         }
@@ -301,13 +305,36 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     Some(callee)
 }
 
+pub fn resolve_ufcs<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                              span: Span,
+                              method_name: ast::Name,
+                              self_ty: Ty<'tcx>,
+                              expr_id: ast::NodeId)
+                              -> Result<(def::Def, LastPrivate), MethodError>
+{
+    let mode = probe::Mode::Path;
+    let pick = try!(probe::probe(fcx, span, mode, method_name, self_ty, expr_id));
+    let def_id = pick.method_ty.def_id;
+    let mut lp = LastMod(AllPublic);
+    let provenance = match pick.kind {
+        probe::InherentImplPick(impl_def_id) => {
+            if pick.method_ty.vis != ast::Public {
+                lp = LastMod(DependsOn(def_id));
+            }
+            def::FromImpl(impl_def_id)
+        }
+        _ => def::FromTrait(pick.method_ty.container.id())
+    };
+    Ok((def::DefMethod(def_id, provenance), lp))
+}
+
 
 /// Find method with name `method_name` defined in `trait_def_id` and return it, along with its
 /// index (or `None`, if no such method).
 fn trait_method<'tcx>(tcx: &ty::ctxt<'tcx>,
                       trait_def_id: ast::DefId,
                       method_name: ast::Name)
-                      -> Option<(uint, Rc<ty::Method<'tcx>>)>
+                      -> Option<(usize, Rc<ty::Method<'tcx>>)>
 {
     let trait_items = ty::trait_items(tcx, trait_def_id);
     trait_items
index 978fbbbcffc33e7dfec2e527fb4bc9dff9e8a030..41eae88158905f3ebc6e0180e351e71e6f9c97a2 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::{MethodError};
+use super::MethodError;
 use super::MethodIndex;
 use super::{CandidateSource,ImplSource,TraitSource};
 use super::suggest;
@@ -37,6 +37,7 @@ pub use self::PickKind::*;
 struct ProbeContext<'a, 'tcx:'a> {
     fcx: &'a FnCtxt<'a, 'tcx>,
     span: Span,
+    mode: Mode,
     method_name: ast::Name,
     steps: Rc<Vec<CandidateStep<'tcx>>>,
     opt_simplified_steps: Option<Vec<fast_reject::SimplifiedType>>,
@@ -59,7 +60,7 @@ struct Candidate<'tcx> {
 
 enum CandidateKind<'tcx> {
     InherentImplCandidate(/* Impl */ ast::DefId, subst::Substs<'tcx>),
-    ObjectCandidate(/* Trait */ ast::DefId, /* method_num */ uint, /* vtable index */ uint),
+    ObjectCandidate(/* Trait */ ast::DefId, /* method_num */ usize, /* vtable index */ usize),
     ExtensionImplCandidate(/* Impl */ ast::DefId, Rc<ty::TraitRef<'tcx>>,
                            subst::Substs<'tcx>, MethodIndex),
     ClosureCandidate(/* Trait */ ast::DefId, MethodIndex),
@@ -76,7 +77,7 @@ pub struct Pick<'tcx> {
 #[derive(Clone,Debug)]
 pub enum PickKind<'tcx> {
     InherentImplPick(/* Impl */ ast::DefId),
-    ObjectPick(/* Trait */ ast::DefId, /* method_num */ uint, /* real_index */ uint),
+    ObjectPick(/* Trait */ ast::DefId, /* method_num */ usize, /* real_index */ usize),
     ExtensionImplPick(/* Impl */ ast::DefId, MethodIndex),
     TraitPick(/* Trait */ ast::DefId, MethodIndex),
     WhereClausePick(/* Trait */ ty::PolyTraitRef<'tcx>, MethodIndex),
@@ -93,14 +94,14 @@ pub enum PickAdjustment {
     // Indicates that the source expression should be autoderef'd N times
     //
     // A = expr | *expr | **expr
-    AutoDeref(uint),
+    AutoDeref(usize),
 
     // Indicates that the source expression should be autoderef'd N
     // times and then "unsized". This should probably eventually go
     // away in favor of just coercing method receivers.
     //
     // A = unsize(expr | *expr | **expr)
-    AutoUnsizeLength(/* number of autoderefs */ uint, /* length*/ uint),
+    AutoUnsizeLength(/* number of autoderefs */ usize, /* length*/ usize),
 
     // Indicates that an autoref is applied after some number of other adjustments
     //
@@ -108,17 +109,30 @@ pub enum PickAdjustment {
     AutoRef(ast::Mutability, Box<PickAdjustment>),
 }
 
+#[derive(PartialEq, Eq, Copy, Clone)]
+pub enum Mode {
+    // An expression of the form `receiver.method_name(...)`.
+    // Autoderefs are performed on `receiver`, lookup is done based on the
+    // `self` argument  of the method, and static methods aren't considered.
+    MethodCall,
+    // An expression of the form `Type::method` or `<T>::method`.
+    // No autoderefs are performed, lookup is done based on the type each
+    // implementation is for, and static methods are included.
+    Path
+}
+
 pub fn probe<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                        span: Span,
+                       mode: Mode,
                        method_name: ast::Name,
                        self_ty: Ty<'tcx>,
-                       call_expr_id: ast::NodeId)
+                       scope_expr_id: ast::NodeId)
                        -> PickResult<'tcx>
 {
-    debug!("probe(self_ty={}, method_name={}, call_expr_id={})",
+    debug!("probe(self_ty={}, method_name={}, scope_expr_id={})",
            self_ty.repr(fcx.tcx()),
            method_name,
-           call_expr_id);
+           scope_expr_id);
 
     // FIXME(#18741) -- right now, creating the steps involves evaluating the
     // `*` operator, which registers obligations that then escape into
@@ -127,9 +141,16 @@ pub fn probe<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     // it ride, although it's really not great, and in fact could I
     // think cause spurious errors. Really though this part should
     // take place in the `fcx.infcx().probe` below.
-    let steps = match create_steps(fcx, span, self_ty) {
-        Some(steps) => steps,
-        None => return Err(MethodError::NoMatch(Vec::new(), Vec::new())),
+    let steps = if mode == Mode::MethodCall {
+        match create_steps(fcx, span, self_ty) {
+            Some(steps) => steps,
+            None => return Err(MethodError::NoMatch(Vec::new(), Vec::new())),
+        }
+    } else {
+        vec![CandidateStep {
+            self_ty: self_ty,
+            adjustment: AutoDeref(0)
+        }]
     };
 
     // Create a list of simplified self types, if we can.
@@ -153,12 +174,15 @@ pub fn probe<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 
     // this creates one big transaction so that all type variables etc
     // that we create during the probe process are removed later
-    let mut dummy = Some((steps, opt_simplified_steps)); // FIXME(#18101) need once closures
     fcx.infcx().probe(|_| {
-        let (steps, opt_simplified_steps) = dummy.take().unwrap();
-        let mut probe_cx = ProbeContext::new(fcx, span, method_name, steps, opt_simplified_steps);
+        let mut probe_cx = ProbeContext::new(fcx,
+                                             span,
+                                             mode,
+                                             method_name,
+                                             steps,
+                                             opt_simplified_steps);
         probe_cx.assemble_inherent_candidates();
-        try!(probe_cx.assemble_extension_candidates_for_traits_in_scope(call_expr_id));
+        try!(probe_cx.assemble_extension_candidates_for_traits_in_scope(scope_expr_id));
         probe_cx.pick()
     })
 }
@@ -198,6 +222,7 @@ fn create_steps<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 impl<'a,'tcx> ProbeContext<'a,'tcx> {
     fn new(fcx: &'a FnCtxt<'a,'tcx>,
            span: Span,
+           mode: Mode,
            method_name: ast::Name,
            steps: Vec<CandidateStep<'tcx>>,
            opt_simplified_steps: Option<Vec<fast_reject::SimplifiedType>>)
@@ -206,6 +231,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         ProbeContext {
             fcx: fcx,
             span: span,
+            mode: mode,
             method_name: method_name,
             inherent_candidates: Vec::new(),
             extension_candidates: Vec::new(),
@@ -252,17 +278,98 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             }
             ty::ty_enum(did, _) |
             ty::ty_struct(did, _) |
-            ty::ty_closure(did, _, _) => {
+            ty::ty_closure(did, _) => {
                 self.assemble_inherent_impl_candidates_for_type(did);
             }
+            ty::ty_uniq(_) => {
+                if let Some(box_did) = self.tcx().lang_items.owned_box() {
+                    self.assemble_inherent_impl_candidates_for_type(box_did);
+                }
+            }
             ty::ty_param(p) => {
                 self.assemble_inherent_candidates_from_param(self_ty, p);
             }
+            ty::ty_char => {
+                let lang_def_id = self.tcx().lang_items.char_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_str => {
+                let lang_def_id = self.tcx().lang_items.str_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_vec(_, None) => {
+                let lang_def_id = self.tcx().lang_items.slice_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_ptr(ty::mt { ty: _, mutbl: ast::MutImmutable }) => {
+                let lang_def_id = self.tcx().lang_items.const_ptr_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_ptr(ty::mt { ty: _, mutbl: ast::MutMutable }) => {
+                let lang_def_id = self.tcx().lang_items.mut_ptr_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_int(ast::TyI8) => {
+                let lang_def_id = self.tcx().lang_items.i8_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_int(ast::TyI16) => {
+                let lang_def_id = self.tcx().lang_items.i16_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_int(ast::TyI32) => {
+                let lang_def_id = self.tcx().lang_items.i32_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_int(ast::TyI64) => {
+                let lang_def_id = self.tcx().lang_items.i64_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_int(ast::TyIs) => {
+                let lang_def_id = self.tcx().lang_items.isize_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_uint(ast::TyU8) => {
+                let lang_def_id = self.tcx().lang_items.u8_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_uint(ast::TyU16) => {
+                let lang_def_id = self.tcx().lang_items.u16_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_uint(ast::TyU32) => {
+                let lang_def_id = self.tcx().lang_items.u32_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_uint(ast::TyU64) => {
+                let lang_def_id = self.tcx().lang_items.u64_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_uint(ast::TyUs) => {
+                let lang_def_id = self.tcx().lang_items.usize_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_float(ast::TyF32) => {
+                let lang_def_id = self.tcx().lang_items.f32_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_float(ast::TyF64) => {
+                let lang_def_id = self.tcx().lang_items.f64_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
             _ => {
             }
         }
     }
 
+    fn assemble_inherent_impl_for_primitive(&mut self, lang_def_id: Option<ast::DefId>) {
+        if let Some(impl_def_id) = lang_def_id {
+            ty::populate_implementations_for_primitive_if_necessary(self.tcx(), impl_def_id);
+
+            self.assemble_inherent_impl_probe(impl_def_id);
+        }
+    }
+
     fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: ast::DefId) {
         // Read the inherent implementation candidates for this type from the
         // metadata if necessary.
@@ -292,11 +399,12 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             return self.record_static_candidate(ImplSource(impl_def_id));
         }
 
-        let impl_substs = self.impl_substs(impl_def_id);
+        let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
+        let impl_ty = self.fcx.instantiate_type_scheme(self.span, &impl_substs, &impl_ty);
 
         // Determine the receiver type that the method itself expects.
         let xform_self_ty =
-            self.xform_self_ty(&method, &impl_substs);
+            self.xform_self_ty(&method, impl_ty, &impl_substs);
 
         self.inherent_candidates.push(Candidate {
             xform_self_ty: xform_self_ty,
@@ -330,7 +438,9 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
                                                           new_trait_ref.def_id,
                                                           method_num);
 
-            let xform_self_ty = this.xform_self_ty(&m, new_trait_ref.substs);
+            let xform_self_ty = this.xform_self_ty(&m,
+                                                   new_trait_ref.self_ty(),
+                                                   new_trait_ref.substs);
 
             this.inherent_candidates.push(Candidate {
                 xform_self_ty: xform_self_ty,
@@ -373,7 +483,9 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
                 this.erase_late_bound_regions(&poly_trait_ref);
 
             let xform_self_ty =
-                this.xform_self_ty(&m, trait_ref.substs);
+                this.xform_self_ty(&m,
+                                   trait_ref.self_ty(),
+                                   trait_ref.substs);
 
             debug!("found match: trait_ref={} substs={} m={}",
                    trait_ref.repr(this.tcx()),
@@ -414,19 +526,13 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             &mut ProbeContext<'b, 'tcx>,
             ty::PolyTraitRef<'tcx>,
             Rc<ty::Method<'tcx>>,
-            uint,
+            usize,
         ),
     {
         debug!("elaborate_bounds(bounds={})", bounds.repr(self.tcx()));
 
         let tcx = self.tcx();
-        let mut cache = HashSet::new();
         for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
-            // Already visited this trait, skip it.
-            if !cache.insert(bound_trait_ref.def_id()) {
-                continue;
-            }
-
             let (pos, method) = match trait_method(tcx,
                                                    bound_trait_ref.def_id(),
                                                    self.method_name) {
@@ -519,7 +625,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
     fn assemble_extension_candidates_for_trait_impls(&mut self,
                                                      trait_def_id: ast::DefId,
                                                      method: Rc<ty::Method<'tcx>>,
-                                                     method_index: uint)
+                                                     method_index: usize)
     {
         ty::populate_implementations_for_trait_if_necessary(self.tcx(),
                                                             trait_def_id);
@@ -540,7 +646,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
                 continue;
             }
 
-            let impl_substs = self.impl_substs(impl_def_id);
+            let (_, impl_substs) = self.impl_ty_and_substs(impl_def_id);
 
             debug!("impl_substs={}", impl_substs.repr(self.tcx()));
 
@@ -553,7 +659,9 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
 
             // Determine the receiver type that the method itself expects.
             let xform_self_ty =
-                self.xform_self_ty(&method, impl_trait_ref.substs);
+                self.xform_self_ty(&method,
+                                   impl_trait_ref.self_ty(),
+                                   impl_trait_ref.substs);
 
             debug!("xform_self_ty={}", xform_self_ty.repr(self.tcx()));
 
@@ -584,7 +692,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
     fn assemble_closure_candidates(&mut self,
                                    trait_def_id: ast::DefId,
                                    method_ty: Rc<ty::Method<'tcx>>,
-                                   method_index: uint)
+                                   method_index: usize)
                                    -> Result<(),MethodError>
     {
         // Check if this is one of the Fn,FnMut,FnOnce traits.
@@ -603,8 +711,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         // If so, add "synthetic impls".
         let steps = self.steps.clone();
         for step in &*steps {
-            let (closure_def_id, _, _) = match step.self_ty.sty {
-                ty::ty_closure(a, b, ref c) => (a, b, c),
+            let closure_def_id = match step.self_ty.sty {
+                ty::ty_closure(a, _) => a,
                 _ => continue,
             };
 
@@ -617,7 +725,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             };
 
             // this closure doesn't implement the right kind of `Fn` trait
-            if closure_kind != kind {
+            if !closure_kind.extends(kind) {
                 continue;
             }
 
@@ -630,7 +738,9 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
                                                              &trait_def.generics,
                                                              step.self_ty);
 
-            let xform_self_ty = self.xform_self_ty(&method_ty, &substs);
+            let xform_self_ty = self.xform_self_ty(&method_ty,
+                                                   step.self_ty,
+                                                   &substs);
             self.inherent_candidates.push(Candidate {
                 xform_self_ty: xform_self_ty,
                 method_ty: method_ty.clone(),
@@ -644,7 +754,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
     fn assemble_projection_candidates(&mut self,
                                       trait_def_id: ast::DefId,
                                       method: Rc<ty::Method<'tcx>>,
-                                      method_index: uint)
+                                      method_index: usize)
     {
         debug!("assemble_projection_candidates(\
                trait_def_id={}, \
@@ -684,7 +794,9 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
                        bound.repr(self.tcx()));
 
                 if self.infcx().can_equate(&step.self_ty, &bound.self_ty()).is_ok() {
-                    let xform_self_ty = self.xform_self_ty(&method, bound.substs);
+                    let xform_self_ty = self.xform_self_ty(&method,
+                                                           bound.self_ty(),
+                                                           bound.substs);
 
                     debug!("assemble_projection_candidates: bound={} xform_self_ty={}",
                            bound.repr(self.tcx()),
@@ -703,7 +815,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
     fn assemble_where_clause_candidates(&mut self,
                                         trait_def_id: ast::DefId,
                                         method_ty: Rc<ty::Method<'tcx>>,
-                                        method_index: uint)
+                                        method_index: usize)
     {
         debug!("assemble_where_clause_candidates(trait_def_id={})",
                trait_def_id.repr(self.tcx()));
@@ -714,7 +826,9 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
                           .filter(|b| b.def_id() == trait_def_id)
         {
             let bound = self.erase_late_bound_regions(&poly_bound);
-            let xform_self_ty = self.xform_self_ty(&method_ty, bound.substs);
+            let xform_self_ty = self.xform_self_ty(&method_ty,
+                                                   bound.self_ty(),
+                                                   bound.substs);
 
             debug!("assemble_where_clause_candidates: bound={} xform_self_ty={}",
                    bound.repr(self.tcx()),
@@ -819,7 +933,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
 
         return self.pick_method(step.self_ty).map(|r| self.adjust(r, adjustment.clone()));
 
-        fn consider_reborrow(ty: Ty, d: uint) -> PickAdjustment {
+        fn consider_reborrow<'tcx>(ty: Ty<'tcx>, d: usize) -> PickAdjustment {
             // Insert a `&*` or `&mut *` if this is a reference type:
             match ty.sty {
                 ty::ty_rptr(_, ref mt) => AutoRef(mt.mutbl, box AutoDeref(d+1)),
@@ -864,7 +978,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
     fn adjust(&mut self,
               result: PickResult<'tcx>,
               adjustment: PickAdjustment)
-              -> PickResult<'tcx> {
+              -> PickResult<'tcx>
+    {
         match result {
             Err(e) => Err(e),
             Ok(mut pick) => {
@@ -878,7 +993,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         debug!("pick_method(self_ty={})", self.infcx().ty_to_string(self_ty));
 
         debug!("searching inherent candidates");
-        match self.consider_candidates(self_ty, &self.inherent_candidates[]) {
+        match self.consider_candidates(self_ty, &self.inherent_candidates) {
             None => {}
             Some(pick) => {
                 return Some(pick);
@@ -886,7 +1001,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         }
 
         debug!("searching extension candidates");
-        self.consider_candidates(self_ty, &self.extension_candidates[])
+        self.consider_candidates(self_ty, &self.extension_candidates)
     }
 
     fn consider_candidates(&self,
@@ -985,7 +1100,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
     /// ```
     /// trait Foo { ... }
     /// impl Foo for Vec<int> { ... }
-    /// impl Foo for Vec<uint> { ... }
+    /// impl Foo for Vec<usize> { ... }
     /// ```
     ///
     /// Now imagine the receiver is `Vec<_>`. It doesn't really matter at this time which impl we
@@ -1015,7 +1130,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
     ///////////////////////////////////////////////////////////////////////////
     // MISCELLANY
 
-    fn make_sub_ty(&self, sub: Ty<'tcx>, sup: Ty<'tcx>) -> infer::ures<'tcx> {
+    fn make_sub_ty(&self, sub: Ty<'tcx>, sup: Ty<'tcx>) -> infer::UnitResult<'tcx> {
         self.infcx().sub_types(false, infer::Misc(DUMMY_SP), sub, sup)
     }
 
@@ -1023,7 +1138,9 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         // "fast track" -- check for usage of sugar
         match method.explicit_self {
             ty::StaticExplicitSelfCategory => {
-                // fallthrough
+                if self.mode == Mode::Path {
+                    return true;
+                }
             }
             ty::ByValueExplicitSelfCategory |
             ty::ByReferenceExplicitSelfCategory(..) |
@@ -1047,11 +1164,13 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
 
     fn xform_self_ty(&self,
                      method: &Rc<ty::Method<'tcx>>,
+                     impl_ty: Ty<'tcx>,
                      substs: &subst::Substs<'tcx>)
                      -> Ty<'tcx>
     {
-        debug!("xform_self_ty(self_ty={}, substs={})",
-               method.fty.sig.0.inputs[0].repr(self.tcx()),
+        debug!("xform_self_ty(impl_ty={}, self_ty={}, substs={})",
+               impl_ty.repr(self.tcx()),
+               method.fty.sig.0.inputs.get(0).repr(self.tcx()),
                substs.repr(self.tcx()));
 
         assert!(!substs.has_escaping_regions());
@@ -1063,6 +1182,11 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         // if there are any.
         assert_eq!(substs.types.len(subst::FnSpace), 0);
         assert_eq!(substs.regions().len(subst::FnSpace), 0);
+
+        if self.mode == Mode::Path {
+            return impl_ty;
+        }
+
         let placeholder;
         let mut substs = substs;
         if
@@ -1094,9 +1218,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
         xform_self_ty
     }
 
-    fn impl_substs(&self,
-                   impl_def_id: ast::DefId)
-                   -> subst::Substs<'tcx>
+    /// Get the type of an impl and generate substitutions with placeholders.
+    fn impl_ty_and_substs(&self,
+                          impl_def_id: ast::DefId)
+                          -> (Ty<'tcx>, subst::Substs<'tcx>)
     {
         let impl_pty = ty::lookup_item_type(self.tcx(), impl_def_id);
 
@@ -1108,7 +1233,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             impl_pty.generics.regions.map(
                 |_| ty::ReStatic); // see erase_late_bound_regions() for an expl of why 'static
 
-        subst::Substs::new(type_vars, region_placeholders)
+        let substs = subst::Substs::new(type_vars, region_placeholders);
+        (impl_pty.ty, substs)
     }
 
     /// Replace late-bound-regions bound by `value` with `'static` using
@@ -1155,7 +1281,7 @@ fn impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
 fn trait_method<'tcx>(tcx: &ty::ctxt<'tcx>,
                       trait_def_id: ast::DefId,
                       method_name: ast::Name)
-                      -> Option<(uint, Rc<ty::Method<'tcx>>)>
+                      -> Option<(usize, Rc<ty::Method<'tcx>>)>
 {
     let trait_items = ty::trait_items(tcx, trait_def_id);
     debug!("trait_method; items: {:?}", trait_items);
@@ -1214,10 +1340,12 @@ impl<'tcx> Candidate<'tcx> {
 
     fn to_trait_data(&self) -> Option<(ast::DefId,MethodIndex)> {
         match self.kind {
-            InherentImplCandidate(..) |
-            ObjectCandidate(..) => {
+            InherentImplCandidate(..) => {
                 None
             }
+            ObjectCandidate(trait_def_id, method_num, _) => {
+                Some((trait_def_id, method_num))
+            }
             ClosureCandidate(trait_def_id, method_num) => {
                 Some((trait_def_id, method_num))
             }
index 1639772103b7aef5f95e7c5b6a6674d99b083152..c5ff8a14bc1cf33be1a294297b2fc5cbddc8b800 100644 (file)
@@ -33,7 +33,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                               span: Span,
                               rcvr_ty: Ty<'tcx>,
                               method_name: ast::Name,
-                              callee_expr: &ast::Expr,
+                              rcvr_expr: Option<&ast::Expr>,
                               error: MethodError)
 {
     // avoid suggestions when we don't know what's going on.
@@ -46,16 +46,6 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             let cx = fcx.tcx();
             let method_ustring = method_name.user_string(cx);
 
-            // True if the type is a struct and contains a field with
-            // the same name as the not-found method
-            let is_field = match rcvr_ty.sty {
-                ty::ty_struct(did, _) =>
-                    ty::lookup_struct_fields(cx, did)
-                        .iter()
-                        .any(|f| f.name.user_string(cx) == method_ustring),
-                _ => false
-            };
-
             fcx.type_error_message(
                 span,
                 |actual| {
@@ -68,10 +58,13 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 None);
 
             // If the method has the name of a field, give a help note
-            if is_field {
-                cx.sess.span_note(span,
-                    &format!("use `(s.{0})(...)` if you meant to call the \
-                            function stored in the `{0}` field", method_ustring)[]);
+            if let (&ty::ty_struct(did, _), Some(_)) = (&rcvr_ty.sty, rcvr_expr) {
+                let fields = ty::lookup_struct_fields(cx, did);
+                if fields.iter().any(|f| f.name == method_name) {
+                    cx.sess.span_note(span,
+                        &format!("use `(s.{0})(...)` if you meant to call the \
+                                 function stored in the `{0}` field", method_ustring));
+                }
             }
 
             if static_sources.len() > 0 {
@@ -82,7 +75,8 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 report_candidates(fcx, span, method_name, static_sources);
             }
 
-            suggest_traits_to_import(fcx, span, rcvr_ty, method_name, out_of_scope_traits)
+            suggest_traits_to_import(fcx, span, rcvr_ty, method_name,
+                                     rcvr_expr, out_of_scope_traits)
         }
 
         MethodError::Ambiguity(sources) => {
@@ -93,15 +87,18 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }
 
         MethodError::ClosureAmbiguity(trait_def_id) => {
-            fcx.sess().span_err(
-                span,
-                &*format!("the `{}` method from the `{}` trait cannot be explicitly \
-                           invoked on this closure as we have not yet inferred what \
-                           kind of closure it is; use overloaded call notation instead \
-                           (e.g., `{}()`)",
-                          method_name.user_string(fcx.tcx()),
-                          ty::item_path_str(fcx.tcx(), trait_def_id),
-                          pprust::expr_to_string(callee_expr)));
+            let msg = format!("the `{}` method from the `{}` trait cannot be explicitly \
+                               invoked on this closure as we have not yet inferred what \
+                               kind of closure it is",
+                               method_name.user_string(fcx.tcx()),
+                               ty::item_path_str(fcx.tcx(), trait_def_id));
+            let msg = if let Some(callee) = rcvr_expr {
+                format!("{}; use overloaded call notation instead (e.g., `{}()`)",
+                        msg, pprust::expr_to_string(callee))
+            } else {
+                msg
+            };
+            fcx.sess().span_err(span, &msg);
         }
     }
 
@@ -156,6 +153,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                       span: Span,
                                       rcvr_ty: Ty<'tcx>,
                                       method_name: ast::Name,
+                                      rcvr_expr: Option<&ast::Expr>,
                                       valid_out_of_scope_traits: Vec<ast::DefId>)
 {
     let tcx = fcx.tcx();
@@ -184,7 +182,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         return
     }
 
-    let type_is_local = type_derefs_to_local(fcx, span, rcvr_ty);
+    let type_is_local = type_derefs_to_local(fcx, span, rcvr_ty, rcvr_expr);
 
     // there's no implemented traits, so lets suggest some traits to
     // implement, by finding ones that have the method name, and are
@@ -233,36 +231,42 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 /// autoderefs of `rcvr_ty`.
 fn type_derefs_to_local<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                   span: Span,
-                                  rcvr_ty: Ty<'tcx>) -> bool {
-    check::autoderef(fcx, span, rcvr_ty, None,
-                     check::UnresolvedTypeAction::Ignore, check::NoPreference,
-                     |&: ty, _| {
-        let is_local = match ty.sty {
+                                  rcvr_ty: Ty<'tcx>,
+                                  rcvr_expr: Option<&ast::Expr>) -> bool {
+    fn is_local(ty: Ty) -> bool {
+        match ty.sty {
             ty::ty_enum(did, _) | ty::ty_struct(did, _) => ast_util::is_local(did),
 
             ty::ty_trait(ref tr) => ast_util::is_local(tr.principal_def_id()),
 
             ty::ty_param(_) => true,
 
-            // the user cannot implement traits for unboxed closures, so
-            // there's no point suggesting anything at all, local or not.
-            ty::ty_closure(..) => return Some(false),
-
             // everything else (primitive types etc.) is effectively
             // non-local (there are "edge" cases, e.g. (LocalType,), but
             // the noise from these sort of types is usually just really
             // annoying, rather than any sort of help).
             _ => false
-        };
-        if is_local {
-            Some(true)
+        }
+    }
+
+    // This occurs for UFCS desugaring of `T::method`, where there is no
+    // receiver expression for the method call, and thus no autoderef.
+    if rcvr_expr.is_none() {
+        return is_local(fcx.resolve_type_vars_if_possible(rcvr_ty));
+    }
+
+    check::autoderef(fcx, span, rcvr_ty, None,
+                     check::UnresolvedTypeAction::Ignore, check::NoPreference,
+                     |ty, _| {
+        if is_local(ty) {
+            Some(())
         } else {
             None
         }
-    }).2.unwrap_or(false)
+    }).2.is_some()
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct TraitInfo {
     pub def_id: ast::DefId,
 }
index e443b4d0e606abd082e45a8fdd9f8b4e8efec526..156fbfede9c98aebf51b120086f56b005bbdd28c 100644 (file)
@@ -79,47 +79,48 @@ type parameter).
 pub use self::LvaluePreference::*;
 pub use self::Expectation::*;
 pub use self::compare_method::compare_impl_method;
-use self::IsBinopAssignment::*;
 use self::TupleArgumentsFlag::*;
 
-use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv};
+use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode};
 use check::_match::pat_ctxt;
 use fmt_macros::{Parser, Piece, Position};
-use middle::{const_eval, def};
+use middle::astconv_util::{check_path_args, NO_TPS, NO_REGIONS};
+use middle::def;
 use middle::infer;
 use middle::mem_categorization as mc;
 use middle::mem_categorization::McResult;
 use middle::pat_util::{self, pat_id_map};
+use middle::privacy::{AllPublic, LastMod};
 use middle::region::{self, CodeExtent};
 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
 use middle::traits;
-use middle::ty::{FnSig, GenericPredicates, VariantInfo, TypeScheme};
+use middle::ty::{FnSig, GenericPredicates, TypeScheme};
 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
-use middle::ty::{self, HasProjectionTypes, RegionEscape, Ty};
+use middle::ty::{self, HasProjectionTypes, RegionEscape, ToPolyTraitRef, Ty};
 use middle::ty::liberate_late_bound_regions;
 use middle::ty::{MethodCall, MethodCallee, MethodMap, ObjectCastMap};
 use middle::ty_fold::{TypeFolder, TypeFoldable};
 use rscope::RegionScope;
 use session::Session;
-use {CrateCtxt, lookup_def_ccx, require_same_types};
+use {CrateCtxt, lookup_full_def, require_same_types};
 use TypeAndSubsts;
 use lint;
-use util::common::{block_query, indenter, loop_query};
+use util::common::{block_query, ErrorReported, indenter, loop_query};
 use util::ppaux::{self, Repr};
 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
 use util::lev_distance::lev_distance;
 
 use std::cell::{Cell, Ref, RefCell};
-use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::mem::replace;
 use std::rc::Rc;
 use std::iter::repeat;
 use std::slice;
 use syntax::{self, abi, attr};
 use syntax::attr::AttrMetaMethods;
-use syntax::ast::{self, ProvidedMethod, RequiredMethod, TypeTraitItem, DefId};
-use syntax::ast_util::{self, local_def, PostExpansionMethod};
+use syntax::ast::{self, DefId, Visibility};
+use syntax::ast_util::{self, local_def};
 use syntax::codemap::{self, Span};
+use syntax::feature_gate;
 use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token;
 use syntax::print::pprust;
@@ -141,6 +142,7 @@ pub mod wf;
 mod closure;
 mod callee;
 mod compare_method;
+mod op;
 
 /// closures defined within the function.  For example:
 ///
@@ -182,6 +184,8 @@ pub struct Inherited<'a, 'tcx: 'a> {
     // def-id of the closure, so that once we decide, we can easily go
     // back and process them.
     deferred_call_resolutions: RefCell<DefIdMap<Vec<DeferredCallResolutionHandler<'tcx>>>>,
+
+    deferred_cast_checks: RefCell<Vec<CastCheck<'tcx>>>,
 }
 
 trait DeferredCallResolution<'tcx> {
@@ -190,10 +194,19 @@ trait DeferredCallResolution<'tcx> {
 
 type DeferredCallResolutionHandler<'tcx> = Box<DeferredCallResolution<'tcx>+'tcx>;
 
+/// Reifies a cast check to be checked once we have full type information for
+/// a function context.
+struct CastCheck<'tcx> {
+    expr: ast::Expr,
+    expr_ty: Ty<'tcx>,
+    cast_ty: Ty<'tcx>,
+    span: Span,
+}
+
 /// When type-checking an expression, we propagate downward
 /// whatever type hint we are able in the form of an `Expectation`.
-#[derive(Copy)]
-enum Expectation<'tcx> {
+#[derive(Copy, Clone)]
+pub enum Expectation<'tcx> {
     /// We know nothing about what type this expression should have.
     NoExpectation,
 
@@ -276,15 +289,6 @@ impl UnsafetyState {
     }
 }
 
-/// Whether `check_binop` is part of an assignment or not.
-/// Used to know whether we allow user overloads and to print
-/// better messages on error.
-#[derive(PartialEq)]
-enum IsBinopAssignment{
-    SimpleBinop,
-    BinopAssignment,
-}
-
 #[derive(Clone)]
 pub struct FnCtxt<'a, 'tcx: 'a> {
     body_id: ast::NodeId,
@@ -297,7 +301,7 @@ pub struct FnCtxt<'a, 'tcx: 'a> {
     // checking this function. On exit, if we find that *more* errors
     // have been reported, we will skip regionck and other work that
     // expects the types within the function to be consistent.
-    err_count_on_creation: uint,
+    err_count_on_creation: usize,
 
     ret_ty: ty::FnOutput<'tcx>,
 
@@ -366,7 +370,7 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
                     substs: &subst::Substs<'tcx>)
                     -> ty::ClosureTy<'tcx>
     {
-        self.inh.closure_tys.borrow()[def_id].subst(self.tcx(), substs)
+        self.inh.closure_tys.borrow().get(&def_id).unwrap().subst(self.tcx(), substs)
     }
 
     fn closure_upvars(&self,
@@ -397,6 +401,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
             fn_sig_map: RefCell::new(NodeMap()),
             fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
             deferred_call_resolutions: RefCell::new(DefIdMap()),
+            deferred_cast_checks: RefCell::new(Vec::new()),
         }
     }
 
@@ -454,7 +459,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> {
     fn visit_ty(&mut self, t: &'tcx ast::Ty) {
         match t.node {
             ast::TyFixedLengthVec(_, ref expr) => {
-                check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.uint);
+                check_const_in_type(self.ccx, &**expr, self.ccx.tcx.types.usize);
             }
             _ => {}
         }
@@ -476,6 +481,20 @@ pub fn check_item_types(ccx: &CrateCtxt) {
     visit::walk_crate(&mut visit, krate);
 
     ccx.tcx.sess.abort_if_errors();
+
+    for drop_method_did in ccx.tcx.destructors.borrow().iter() {
+        if drop_method_did.krate == ast::LOCAL_CRATE {
+            let drop_impl_did = ccx.tcx.map.get_parent_did(drop_method_did.node);
+            match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
+                Ok(()) => {}
+                Err(()) => {
+                    assert!(ccx.tcx.sess.has_errors());
+                }
+            }
+        }
+    }
+
+    ccx.tcx.sess.abort_if_errors();
 }
 
 fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
@@ -506,6 +525,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             vtable::select_all_fcx_obligations_and_apply_defaults(&fcx);
             upvar::closure_analyze_fn(&fcx, fn_id, decl, body);
             vtable::select_all_fcx_obligations_or_error(&fcx);
+            fcx.check_casts();
             regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body);
             writeback::resolve_type_vars_in_fn(&fcx, decl, body);
         }
@@ -547,7 +567,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
         debug!("Local variable {} is assigned type {}",
                self.fcx.pat_to_string(&*local.pat),
                self.fcx.infcx().ty_to_string(
-                   self.fcx.inh.locals.borrow()[local.id].clone()));
+                   self.fcx.inh.locals.borrow().get(&local.id).unwrap().clone()));
         visit::walk_local(self, local);
     }
 
@@ -563,7 +583,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
                 debug!("Pattern binding {} is assigned to {} with type {}",
                        token::get_ident(path1.node),
                        self.fcx.infcx().ty_to_string(
-                           self.fcx.inh.locals.borrow()[p.id].clone()),
+                           self.fcx.inh.locals.borrow().get(&p.id).unwrap().clone()),
                        var_ty.repr(self.fcx.tcx()));
             }
         }
@@ -583,7 +603,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
         match t.node {
             ast::TyFixedLengthVec(ref ty, ref count_expr) => {
                 self.visit_ty(&**ty);
-                check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.uint);
+                check_expr_with_hint(self.fcx, &**count_expr, self.fcx.tcx().types.usize);
             }
             _ => visit::walk_ty(self, t)
         }
@@ -615,7 +635,7 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
     let tcx = ccx.tcx;
     let err_count_on_creation = tcx.sess.err_count();
 
-    let arg_tys = &fn_sig.inputs[];
+    let arg_tys = &fn_sig.inputs;
     let ret_ty = fn_sig.output;
 
     debug!("check_fn(arg_tys={}, ret_ty={}, fn_id={})",
@@ -713,7 +733,7 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
       ast::ItemEnum(ref enum_definition, _) => {
         check_enum_variants(ccx,
                             it.span,
-                            &enum_definition.variants[],
+                            &enum_definition.variants,
                             it.id);
       }
       ast::ItemFn(ref decl, _, _, _, ref body) => {
@@ -737,30 +757,33 @@ pub fn check_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
           }
 
         for impl_item in impl_items {
-            match *impl_item {
-                ast::MethodImplItem(ref m) => {
-                    check_method_body(ccx, &impl_pty.generics, &**m);
+            match impl_item.node {
+                ast::MethodImplItem(ref sig, ref body) => {
+                    check_method_body(ccx, &impl_pty.generics, sig, body,
+                                      impl_item.id, impl_item.span);
                 }
-                ast::TypeImplItem(_) => {
+                ast::TypeImplItem(_) |
+                ast::MacImplItem(_) => {
                     // Nothing to do here.
                 }
             }
         }
 
       }
-      ast::ItemTrait(_, ref generics, _, ref trait_methods) => {
+      ast::ItemTrait(_, ref generics, _, ref trait_items) => {
         check_trait_on_unimplemented(ccx, generics, it);
         let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
-        for trait_method in trait_methods {
-            match *trait_method {
-                RequiredMethod(..) => {
+        for trait_item in trait_items {
+            match trait_item.node {
+                ast::MethodTraitItem(_, None) => {
                     // Nothing to do, since required methods don't have
                     // bodies to check.
                 }
-                ProvidedMethod(ref m) => {
-                    check_method_body(ccx, &trait_def.generics, &**m);
+                ast::MethodTraitItem(ref sig, Some(ref body)) => {
+                    check_method_body(ccx, &trait_def.generics, sig, body,
+                                      trait_item.id, trait_item.span);
                 }
-                TypeTraitItem(_) => {
+                ast::TypeTraitItem(..) => {
                     // Nothing to do.
                 }
             }
@@ -853,28 +876,23 @@ fn check_trait_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 /// * `method`: the method definition
 fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                item_generics: &ty::Generics<'tcx>,
-                               method: &'tcx ast::Method) {
-    debug!("check_method_body(item_generics={}, method.id={})",
-            item_generics.repr(ccx.tcx),
-            method.id);
-    let param_env = ParameterEnvironment::for_item(ccx.tcx, method.id);
-
-    let fty = ty::node_id_to_type(ccx.tcx, method.id);
+                               sig: &'tcx ast::MethodSig,
+                               body: &'tcx ast::Block,
+                               id: ast::NodeId, span: Span) {
+    debug!("check_method_body(item_generics={}, id={})",
+            item_generics.repr(ccx.tcx), id);
+    let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
+
+    let fty = ty::node_id_to_type(ccx.tcx, id);
     debug!("check_method_body: fty={}", fty.repr(ccx.tcx));
 
-    check_bare_fn(ccx,
-                  &*method.pe_fn_decl(),
-                  &*method.pe_body(),
-                  method.id,
-                  method.span,
-                  fty,
-                  param_env);
+    check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
 }
 
 fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                             impl_span: Span,
                                             impl_trait_ref: &ty::TraitRef<'tcx>,
-                                            impl_items: &[ast::ImplItem]) {
+                                            impl_items: &[P<ast::ImplItem>]) {
     // Locate trait methods
     let tcx = ccx.tcx;
     let trait_items = ty::trait_items(tcx, impl_trait_ref.def_id);
@@ -882,9 +900,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     // Check existing impl methods to see if they are both present in trait
     // and compatible with trait signature
     for impl_item in impl_items {
-        match *impl_item {
-            ast::MethodImplItem(ref impl_method) => {
-                let impl_method_def_id = local_def(impl_method.id);
+        match impl_item.node {
+            ast::MethodImplItem(_, ref body) => {
+                let impl_method_def_id = local_def(impl_item.id);
                 let impl_item_ty = ty::impl_or_trait_item(ccx.tcx,
                                                           impl_method_def_id);
 
@@ -900,8 +918,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                              &ty::MethodTraitItem(ref impl_method_ty)) => {
                                 compare_impl_method(ccx.tcx,
                                                     &**impl_method_ty,
-                                                    impl_method.span,
-                                                    impl_method.pe_body().id,
+                                                    impl_item.span,
+                                                    body.id,
                                                     &**trait_method_ty,
                                                     &*impl_trait_ref);
                             }
@@ -909,7 +927,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 // This is span_bug as it should have already been
                                 // caught in resolve.
                                 tcx.sess.span_bug(
-                                    impl_method.span,
+                                    impl_item.span,
                                     &format!("item `{}` is of a different kind from its trait `{}`",
                                              token::get_name(impl_item_ty.name()),
                                              impl_trait_ref.repr(tcx)));
@@ -920,15 +938,15 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                         // This is span_bug as it should have already been
                         // caught in resolve.
                         tcx.sess.span_bug(
-                            impl_method.span,
+                            impl_item.span,
                             &format!("method `{}` is not a member of trait `{}`",
                                      token::get_name(impl_item_ty.name()),
                                      impl_trait_ref.repr(tcx)));
                     }
                 }
             }
-            ast::TypeImplItem(ref typedef) => {
-                let typedef_def_id = local_def(typedef.id);
+            ast::TypeImplItem(_) => {
+                let typedef_def_id = local_def(impl_item.id);
                 let typedef_ty = ty::impl_or_trait_item(ccx.tcx,
                                                         typedef_def_id);
 
@@ -945,7 +963,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 // This is `span_bug` as it should have
                                 // already been caught in resolve.
                                 tcx.sess.span_bug(
-                                    typedef.span,
+                                    impl_item.span,
                                     &format!("item `{}` is of a different kind from its trait `{}`",
                                              token::get_name(typedef_ty.name()),
                                              impl_trait_ref.repr(tcx)));
@@ -956,7 +974,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                         // This is `span_bug` as it should have already been
                         // caught in resolve.
                         tcx.sess.span_bug(
-                            typedef.span,
+                            impl_item.span,
                             &format!(
                                 "associated type `{}` is not a member of \
                                  trait `{}`",
@@ -965,6 +983,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                     }
                 }
             }
+            ast::MacImplItem(_) => tcx.sess.span_bug(impl_item.span,
+                                                     "unexpanded macro")
         }
     }
 
@@ -976,11 +996,12 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             ty::MethodTraitItem(ref trait_method) => {
                 let is_implemented =
                     impl_items.iter().any(|ii| {
-                        match *ii {
-                            ast::MethodImplItem(ref m) => {
-                                m.pe_ident().name == trait_method.name
+                        match ii.node {
+                            ast::MethodImplItem(..) => {
+                                ii.ident.name == trait_method.name
                             }
-                            ast::TypeImplItem(_) => false,
+                            ast::TypeImplItem(_) |
+                            ast::MacImplItem(_) => false,
                         }
                     });
                 let is_provided =
@@ -991,11 +1012,12 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             }
             ty::TypeTraitItem(ref associated_type) => {
                 let is_implemented = impl_items.iter().any(|ii| {
-                    match *ii {
-                        ast::TypeImplItem(ref typedef) => {
-                            typedef.ident.name == associated_type.name
+                    match ii.node {
+                        ast::TypeImplItem(_) => {
+                            ii.ident.name == associated_type.name
                         }
-                        ast::MethodImplItem(_) => false,
+                        ast::MethodImplItem(..) |
+                        ast::MacImplItem(_) => false,
                     }
                 });
                 if !is_implemented {
@@ -1049,11 +1071,7 @@ fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 }
 
 
-fn check_cast_inner<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                              span: Span,
-                              t_1: Ty<'tcx>,
-                              t_e: Ty<'tcx>,
-                              e: &ast::Expr) {
+fn check_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, cast: &CastCheck<'tcx>) {
     fn cast_through_integer_err<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                           span: Span,
                                           t_1: Ty<'tcx>,
@@ -1066,6 +1084,37 @@ fn check_cast_inner<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }, t_e, None);
     }
 
+    let span = cast.span;
+    let e = &cast.expr;
+    let t_e = structurally_resolved_type(fcx, span, cast.expr_ty);
+    let t_1 = structurally_resolved_type(fcx, span, cast.cast_ty);
+
+    // Check for trivial casts.
+    if !ty::type_has_ty_infer(t_1) {
+        if let Ok(()) = coercion::mk_assignty(fcx, e, t_e, t_1) {
+            if ty::type_is_numeric(t_1) && ty::type_is_numeric(t_e) {
+                fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_NUMERIC_CASTS,
+                                        e.id,
+                                        span,
+                                        format!("trivial numeric cast: `{}` as `{}`. Cast can be \
+                                                 replaced by coercion, this might require type \
+                                                 ascription or a temporary variable",
+                                                fcx.infcx().ty_to_string(t_e),
+                                                fcx.infcx().ty_to_string(t_1)));
+            } else {
+                fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_CASTS,
+                                        e.id,
+                                        span,
+                                        format!("trivial cast: `{}` as `{}`. Cast can be \
+                                                 replaced by coercion, this might require type \
+                                                 ascription or a temporary variable",
+                                                fcx.infcx().ty_to_string(t_e),
+                                                fcx.infcx().ty_to_string(t_1)));
+            }
+            return;
+        }
+    }
+
     let t_e_is_bare_fn_item = ty::type_is_bare_fn_item(t_e);
     let t_e_is_scalar = ty::type_is_scalar(t_e);
     let t_e_is_integral = ty::type_is_integral(t_e);
@@ -1081,18 +1130,17 @@ fn check_cast_inner<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     let t_1_is_trivial = t_1_is_scalar && !t_1_is_char && !t_1_is_bare_fn;
 
     if t_e_is_bare_fn_item && t_1_is_bare_fn {
-        demand::coerce(fcx, e.span, t_1, &*e);
+        demand::coerce(fcx, e.span, t_1, &e);
     } else if t_1_is_char {
         let t_e = fcx.infcx().shallow_resolve(t_e);
         if t_e.sty != ty::ty_uint(ast::TyU8) {
             fcx.type_error_message(span, |actual| {
-                format!("only `u8` can be cast as \
-                         `char`, not `{}`", actual)
+                format!("only `u8` can be cast as `char`, not `{}`", actual)
             }, t_e, None);
         }
     } else if t_1.sty == ty::ty_bool {
         span_err!(fcx.tcx().sess, span, E0054,
-            "cannot cast as `bool`, compare with zero instead");
+                  "cannot cast as `bool`, compare with zero instead");
     } else if t_1_is_float && (t_e_is_scalar || t_e_is_c_enum) && !(
         t_e_is_integral || t_e_is_float || t_e.sty == ty::ty_bool) {
         // Casts to float must go through an integer or boolean
@@ -1141,7 +1189,7 @@ fn check_cast_inner<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 /* this case is allowed */
             }
             _ => {
-                demand::coerce(fcx, e.span, t_1, &*e);
+                demand::coerce(fcx, e.span, t_1, &e);
             }
         }
     } else if !(t_e_is_scalar && t_1_is_trivial) {
@@ -1158,64 +1206,65 @@ fn check_cast_inner<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     }
 }
 
-fn check_cast<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
-                       cast_expr: &ast::Expr,
-                       e: &'tcx ast::Expr,
-                       t: &ast::Ty) {
-    let id = cast_expr.id;
-    let span = cast_expr.span;
-
-    // Find the type of `e`. Supply hints based on the type we are casting to,
-    // if appropriate.
-    let t_1 = fcx.to_ty(t);
-    let t_1 = structurally_resolved_type(fcx, span, t_1);
-
-    check_expr_with_expectation(fcx, e, ExpectCastableToType(t_1));
-
-    let t_e = fcx.expr_ty(e);
-
-    debug!("t_1={}", fcx.infcx().ty_to_string(t_1));
-    debug!("t_e={}", fcx.infcx().ty_to_string(t_e));
-
-    if ty::type_is_error(t_e) {
-        fcx.write_error(id);
-        return
-    }
-
-    if !fcx.type_is_known_to_be_sized(t_1, cast_expr.span) {
-        report_cast_to_unsized_type(fcx, span, t.span, e.span, t_1, t_e, id);
-        return
-    }
-
-    if ty::type_is_trait(t_1) {
-        // This will be looked up later on.
-        vtable::check_object_cast(fcx, cast_expr, e, t_1);
-        fcx.write_ty(id, t_1);
-        return
-    }
-
-    let t_1 = structurally_resolved_type(fcx, span, t_1);
-    let t_e = structurally_resolved_type(fcx, span, t_e);
-
-    check_cast_inner(fcx, span, t_1, t_e, e);
-    fcx.write_ty(id, t_1);
-}
-
 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
     fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
 
-    fn get_item_type_scheme(&self, id: ast::DefId) -> ty::TypeScheme<'tcx> {
-        ty::lookup_item_type(self.tcx(), id)
+    fn get_item_type_scheme(&self, _: Span, id: ast::DefId)
+                            -> Result<ty::TypeScheme<'tcx>, ErrorReported>
+    {
+        Ok(ty::lookup_item_type(self.tcx(), id))
     }
 
-    fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef<'tcx>> {
-        ty::lookup_trait_def(self.tcx(), id)
+    fn get_trait_def(&self, _: Span, id: ast::DefId)
+                     -> Result<Rc<ty::TraitDef<'tcx>>, ErrorReported>
+    {
+        Ok(ty::lookup_trait_def(self.tcx(), id))
+    }
+
+    fn ensure_super_predicates(&self, _: Span, _: ast::DefId) -> Result<(), ErrorReported> {
+        // all super predicates are ensured during collect pass
+        Ok(())
     }
 
     fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
         Some(&self.inh.param_env.free_substs)
     }
 
+    fn get_type_parameter_bounds(&self,
+                                 _: Span,
+                                 node_id: ast::NodeId)
+                                 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
+    {
+        let def = self.tcx().type_parameter_def(node_id);
+        let r = self.inh.param_env.caller_bounds
+                                  .iter()
+                                  .filter_map(|predicate| {
+                                      match *predicate {
+                                          ty::Predicate::Trait(ref data) => {
+                                              if data.0.self_ty().is_param(def.space, def.index) {
+                                                  Some(data.to_poly_trait_ref())
+                                              } else {
+                                                  None
+                                              }
+                                          }
+                                          _ => {
+                                              None
+                                          }
+                                      }
+                                  })
+                                  .collect();
+        Ok(r)
+    }
+
+    fn trait_defines_associated_type_named(&self,
+                                           trait_def_id: ast::DefId,
+                                           assoc_name: ast::Name)
+                                           -> bool
+    {
+        let trait_def = ty::lookup_trait_def(self.ccx.tcx, trait_def_id);
+        trait_def.associated_type_names.contains(&assoc_name)
+    }
+
     fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
         self.infcx().next_ty_var()
     }
@@ -1260,7 +1309,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self.tcx().sess
     }
 
-    pub fn err_count_since_creation(&self) -> uint {
+    pub fn err_count_since_creation(&self) -> usize {
         self.ccx.tcx.sess.err_count() - self.err_count_on_creation
     }
 
@@ -1268,14 +1317,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// version, this version will also select obligations if it seems
     /// useful, in an effort to get more type information.
     fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
+        debug!("resolve_type_vars_if_possible(ty={})", ty.repr(self.tcx()));
+
         // No ty::infer()? Nothing needs doing.
         if !ty::type_has_ty_infer(ty) {
+            debug!("resolve_type_vars_if_possible: ty={}", ty.repr(self.tcx()));
             return ty;
         }
 
         // If `ty` is a type variable, see whether we already know what it is.
         ty = self.infcx().resolve_type_vars_if_possible(&ty);
         if !ty::type_has_ty_infer(ty) {
+            debug!("resolve_type_vars_if_possible: ty={}", ty.repr(self.tcx()));
             return ty;
         }
 
@@ -1283,6 +1336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         vtable::select_new_fcx_obligations(self);
         ty = self.infcx().resolve_type_vars_if_possible(&ty);
         if !ty::type_has_ty_infer(ty) {
+            debug!("resolve_type_vars_if_possible: ty={}", ty.repr(self.tcx()));
             return ty;
         }
 
@@ -1291,7 +1345,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // indirect dependencies that don't seem worth tracking
         // precisely.
         vtable::select_fcx_obligations_where_possible(self);
-        self.infcx().resolve_type_vars_if_possible(&ty)
+        ty = self.infcx().resolve_type_vars_if_possible(&ty);
+
+        debug!("resolve_type_vars_if_possible: ty={}", ty.repr(self.tcx()));
+        ty
     }
 
     /// Resolves all type variables in `t` and then, if any were left
@@ -1308,11 +1365,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                        closure_def_id: ast::DefId,
                                        r: DeferredCallResolutionHandler<'tcx>) {
         let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
-        let mut vec = match deferred_call_resolutions.entry(closure_def_id) {
-            Occupied(entry) => entry.into_mut(),
-            Vacant(entry) => entry.insert(Vec::new()),
-        };
-        vec.push(r);
+        deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
     }
 
     fn remove_deferred_call_resolutions(&self,
@@ -1324,17 +1377,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     pub fn tag(&self) -> String {
-        format!("{:?}", self as *const FnCtxt)
+        let self_ptr: *const FnCtxt = self;
+        format!("{:?}", self_ptr)
     }
 
     pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
         match self.inh.locals.borrow().get(&nid) {
             Some(&t) => t,
             None => {
-                self.tcx().sess.span_bug(
+                self.tcx().sess.span_err(
                     span,
-                    &format!("no type for local variable {}",
-                            nid)[]);
+                    &format!("no type for local variable {}", nid));
+                self.tcx().types.err
             }
         }
     }
@@ -1368,14 +1422,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.inh.node_types.borrow_mut().insert(node_id, ty);
     }
 
-    pub fn write_object_cast(&self,
-                             key: ast::NodeId,
-                             trait_ref: ty::PolyTraitRef<'tcx>) {
-        debug!("write_object_cast key={} trait_ref={}",
-               key, trait_ref.repr(self.tcx()));
-        self.inh.object_cast_map.borrow_mut().insert(key, trait_ref);
-    }
-
     pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
         if !substs.substs.is_noop() {
             debug!("write_substs({}, {}) in fcx {}",
@@ -1390,7 +1436,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn write_autoderef_adjustment(&self,
                                       node_id: ast::NodeId,
                                       span: Span,
-                                      derefs: uint) {
+                                      derefs: usize) {
         if derefs == 0 { return; }
         self.write_adjustment(
             node_id,
@@ -1484,8 +1530,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                        span: Span,
                                        adj: &ty::AutoAdjustment<'tcx>) {
         match *adj {
-            ty::AdjustReifyFnPointer(..) => {
-            }
+            ty::AdjustReifyFnPointer(..) => { }
+            ty::AdjustUnsafeFnPointer => { }
             ty::AdjustDerefRef(ref d_r) => {
                 match d_r.autoref {
                     Some(ref a_r) => {
@@ -1544,6 +1590,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                                       code: traits::ObjectCastObligation(self_ty) };
                 self.register_region_obligation(self_ty, ty_trait.bounds.region_bound, cause);
             }
+            ty::UnsizeUpcast(_) => { }
         }
     }
 
@@ -1598,23 +1645,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let ty::TypeScheme { generics, ty: decl_ty } =
             ty::lookup_item_type(tcx, did);
 
-        let wants_params =
-            generics.has_type_params(TypeSpace) || generics.has_region_params(TypeSpace);
-
-        let needs_defaults =
-            wants_params &&
-            path.segments.iter().all(|s| s.parameters.is_empty());
-
-        let substs = if needs_defaults {
-            let tps =
-                self.infcx().next_ty_vars(generics.types.len(TypeSpace));
-            let rps =
-                self.infcx().region_vars_for_defs(path.span,
-                                                  generics.regions.get_slice(TypeSpace));
-            Substs::new_type(tps, rps)
-        } else {
-            astconv::ast_path_substs_for_ty(self, self, &generics, path)
-        };
+        let substs = astconv::ast_path_substs_for_ty(self, self,
+                                                     path.span,
+                                                     PathParamMode::Optional,
+                                                     &generics,
+                                                     path.segments.last().unwrap());
 
         let ty = self.instantiate_type_scheme(path.span, &substs, &decl_ty);
 
@@ -1707,7 +1742,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             Some(&t) => t,
             None => {
                 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
-                                            self.tag())[]);
+                                            self.tag()));
             }
         }
     }
@@ -1739,7 +1774,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.tcx().sess.bug(
                     &format!("no type for node {}: {} in fcx {}",
                             id, self.tcx().map.node_to_string(id),
-                            self.tag())[]);
+                            self.tag()));
             }
         }
     }
@@ -1878,7 +1913,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                span: Span,
                                class_id: ast::DefId,
                                items: &[ty::field_ty],
-                               idx: uint,
+                               idx: usize,
                                substs: &subst::Substs<'tcx>)
                                -> Option<Ty<'tcx>>
     {
@@ -1886,6 +1921,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         o_field.map(|f| ty::lookup_field_type(self.tcx(), class_id, f.id, substs))
                .map(|t| self.normalize_associated_types_in(span, &t))
     }
+
+    fn check_casts(&self) {
+        let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut();
+        for check in deferred_cast_checks.iter() {
+            check_cast(self, check);
+        }
+
+        deferred_cast_checks.clear();
+    }
 }
 
 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
@@ -1900,22 +1944,22 @@ impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
         Some(self.infcx().next_region_var(infer::MiscVariable(span)))
     }
 
-    fn anon_regions(&self, span: Span, count: uint)
-                    -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>> {
+    fn anon_regions(&self, span: Span, count: usize)
+                    -> Result<Vec<ty::Region>, Option<Vec<(String, usize)>>> {
         Ok((0..count).map(|_| {
             self.infcx().next_region_var(infer::MiscVariable(span))
         }).collect())
     }
 }
 
-#[derive(Copy, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub enum LvaluePreference {
     PreferMutLvalue,
     NoPreference
 }
 
 /// Whether `autoderef` requires types to resolve.
-#[derive(Copy, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub enum UnresolvedTypeAction {
     /// Produce an error and return `ty_err` whenever a type cannot
     /// be resolved (i.e. it is `ty_infer`).
@@ -1937,8 +1981,8 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
                                  unresolved_type_action: UnresolvedTypeAction,
                                  mut lvalue_pref: LvaluePreference,
                                  mut should_stop: F)
-                                 -> (Ty<'tcx>, uint, Option<T>)
-    where F: FnMut(Ty<'tcx>, uint) -> Option<T>,
+                                 -> (Ty<'tcx>, usize, Option<T>)
+    where F: FnMut(Ty<'tcx>, usize) -> Option<T>,
 {
     debug!("autoderef(base_ty={}, opt_expr={}, lvalue_pref={:?})",
            base_ty.repr(fcx.tcx()),
@@ -2048,24 +2092,17 @@ fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 {
     match method {
         Some(method) => {
-            let ref_ty = // invoked methods have all LB regions instantiated
-                ty::no_late_bound_regions(
-                    fcx.tcx(), &ty::ty_fn_ret(method.ty)).unwrap();
-            match method_call {
-                Some(method_call) => {
-                    fcx.inh.method_map.borrow_mut().insert(method_call,
-                                                           method);
-                }
-                None => {}
-            }
-            match ref_ty {
-                ty::FnConverging(ref_ty) => {
-                    ty::deref(ref_ty, true)
-                }
-                ty::FnDiverging => {
-                    fcx.tcx().sess.bug("index/deref traits do not define a `!` return")
-                }
+            // extract method method return type, which will be &T;
+            // all LB regions should have been instantiated during method lookup
+            let ret_ty = ty::ty_fn_ret(method.ty);
+            let ret_ty = ty::no_late_bound_regions(fcx.tcx(), &ret_ty).unwrap().unwrap();
+
+            if let Some(method_call) = method_call {
+                fcx.inh.method_map.borrow_mut().insert(method_call, method);
             }
+
+            // method returns &T, but the type as visible to user is T, so deref
+            ty::deref(ret_ty, true)
         }
         None => None,
     }
@@ -2141,10 +2178,10 @@ fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 
     // First, try built-in indexing.
     match (ty::index(adjusted_ty), &index_ty.sty) {
-        (Some(ty), &ty::ty_uint(ast::TyUs(_))) | (Some(ty), &ty::ty_infer(ty::IntVar(_))) => {
+        (Some(ty), &ty::ty_uint(ast::TyUs)) | (Some(ty), &ty::ty_infer(ty::IntVar(_))) => {
             debug!("try_index_step: success, using built-in indexing");
             fcx.write_adjustment(base_expr.id, base_expr.span, ty::AdjustDerefRef(adjustment));
-            return Some((tcx.types.uint, ty));
+            return Some((tcx.types.usize, ty));
         }
         _ => {}
     }
@@ -2194,7 +2231,6 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                          method_fn_ty: Ty<'tcx>,
                                          callee_expr: &'tcx ast::Expr,
                                          args_no_rcvr: &'tcx [P<ast::Expr>],
-                                         autoref_args: AutorefArgs,
                                          tuple_arguments: TupleArgumentsFlag,
                                          expected: Expectation<'tcx>)
                                          -> ty::FnOutput<'tcx> {
@@ -2211,7 +2247,6 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                              &err_inputs[..],
                              &[],
                              args_no_rcvr,
-                             autoref_args,
                              false,
                              tuple_arguments);
         ty::FnConverging(fcx.tcx().types.err)
@@ -2229,7 +2264,6 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                      &fty.sig.0.inputs[1..],
                                      &expected_arg_tys[..],
                                      args_no_rcvr,
-                                     autoref_args,
                                      fty.sig.0.variadic,
                                      tuple_arguments);
                 fty.sig.0.output
@@ -2249,7 +2283,6 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                   fn_inputs: &[Ty<'tcx>],
                                   expected_arg_tys: &[Ty<'tcx>],
                                   args: &'tcx [P<ast::Expr>],
-                                  autoref_args: AutorefArgs,
                                   variadic: bool,
                                   tuple_arguments: TupleArgumentsFlag) {
     let tcx = fcx.ccx.tcx;
@@ -2275,7 +2308,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                         if arg_types.len() == 1 {""} else {"s"},
                         args.len(),
                         if args.len() == 1 {" was"} else {"s were"});
-                    expected_arg_tys = &[][];
+                    expected_arg_tys = &[];
                     err_args(fcx.tcx(), args.len())
                 } else {
                     expected_arg_tys = match expected_arg_tys.get(0) {
@@ -2292,7 +2325,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 span_err!(tcx.sess, sp, E0059,
                     "cannot use call notation; the first type parameter \
                      for the function trait is neither a tuple nor unit");
-                expected_arg_tys = &[][];
+                expected_arg_tys = &[];
                 err_args(fcx.tcx(), args.len())
             }
         }
@@ -2309,7 +2342,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 if expected_arg_count == 1 {""} else {"s"},
                 supplied_arg_count,
                 if supplied_arg_count == 1 {" was"} else {"s were"});
-            expected_arg_tys = &[][];
+            expected_arg_tys = &[];
             err_args(fcx.tcx(), supplied_arg_count)
         }
     } else {
@@ -2319,7 +2352,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             if expected_arg_count == 1 {""} else {"s"},
             supplied_arg_count,
             if supplied_arg_count == 1 {" was"} else {"s were"});
-        expected_arg_tys = &[][];
+        expected_arg_tys = &[];
         err_args(fcx.tcx(), supplied_arg_count)
     };
 
@@ -2362,26 +2395,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 
             if is_block == check_blocks {
                 debug!("checking the argument");
-                let mut formal_ty = formal_tys[i];
-
-                match autoref_args {
-                    AutorefArgs::Yes => {
-                        match formal_ty.sty {
-                            ty::ty_rptr(_, mt) => formal_ty = mt.ty,
-                            ty::ty_err => (),
-                            _ => {
-                                // So we hit this case when one implements the
-                                // operator traits but leaves an argument as
-                                // just T instead of &T. We'll catch it in the
-                                // mismatch impl/trait method phase no need to
-                                // ICE here.
-                                // See: #11450
-                                formal_ty = tcx.types.err;
-                            }
-                        }
-                    }
-                    AutorefArgs::No => {}
-                }
+                let formal_ty = formal_tys[i];
 
                 // The special-cased logic below has three functions:
                 // 1. Provide as good of an expected type as possible.
@@ -2445,7 +2459,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 }
 
 // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
-fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: uint) -> Vec<Ty<'tcx>> {
+fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
     (0..len).map(|_| tcx.types.err).collect()
 }
 
@@ -2468,10 +2482,11 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 
     match lit.node {
         ast::LitStr(..) => ty::mk_str_slice(tcx, tcx.mk_region(ty::ReStatic), ast::MutImmutable),
-        ast::LitBinary(..) => {
-            ty::mk_slice(tcx,
-                         tcx.mk_region(ty::ReStatic),
-                         ty::mt{ ty: tcx.types.u8, mutbl: ast::MutImmutable })
+        ast::LitBinary(ref v) => {
+            ty::mk_rptr(tcx, tcx.mk_region(ty::ReStatic), ty::mt {
+                ty: ty::mk_vec(tcx, tcx.types.u8, Some(v.len())),
+                mutbl: ast::MutImmutable,
+            })
         }
         ast::LitByte(_) => tcx.types.u8,
         ast::LitChar(_) => tcx.types.char,
@@ -2482,8 +2497,8 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 match ty.sty {
                     ty::ty_int(_) | ty::ty_uint(_) => Some(ty),
                     ty::ty_char => Some(tcx.types.u8),
-                    ty::ty_ptr(..) => Some(tcx.types.uint),
-                    ty::ty_bare_fn(..) => Some(tcx.types.uint),
+                    ty::ty_ptr(..) => Some(tcx.types.usize),
+                    ty::ty_bare_fn(..) => Some(tcx.types.usize),
                     _ => None
                 }
             });
@@ -2577,14 +2592,6 @@ pub fn impl_self_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     TypeAndSubsts { substs: substs, ty: substd_ty }
 }
 
-// Controls whether the arguments are automatically referenced. This is useful
-// for overloaded binary and unary operators.
-#[derive(Copy, PartialEq)]
-pub enum AutorefArgs {
-    Yes,
-    No,
-}
-
 /// Controls whether the arguments are tupled. This is used for the call
 /// operator.
 ///
@@ -2592,7 +2599,7 @@ pub enum AutorefArgs {
 /// passed as a single parameter. For example, if tupling is enabled, this
 /// function:
 ///
-///     fn f(x: (int, int))
+///     fn f(x: (isize, isize))
 ///
 /// Can be called as:
 ///
@@ -2698,7 +2705,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
             }
             Err(error) => {
                 method::report_error(fcx, method_name.span, expr_t,
-                                     method_name.node.name, rcvr, error);
+                                     method_name.node.name, Some(rcvr), error);
                 fcx.write_error(expr.id);
                 fcx.tcx().types.err
             }
@@ -2710,7 +2717,6 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                                  fn_ty,
                                                  expr,
                                                  &args[1..],
-                                                 AutorefArgs::No,
                                                  DontTupleArguments,
                                                  expected);
 
@@ -2761,277 +2767,6 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
         fcx.write_ty(id, if_ty);
     }
 
-    fn lookup_op_method<'a, 'tcx, F>(fcx: &'a FnCtxt<'a, 'tcx>,
-                                     op_ex: &'tcx ast::Expr,
-                                     lhs_ty: Ty<'tcx>,
-                                     opname: ast::Name,
-                                     trait_did: Option<ast::DefId>,
-                                     lhs: &'a ast::Expr,
-                                     rhs: Option<&'tcx P<ast::Expr>>,
-                                     unbound_method: F,
-                                     autoref_args: AutorefArgs) -> Ty<'tcx> where
-        F: FnOnce(),
-    {
-        let method = match trait_did {
-            Some(trait_did) => {
-                // We do eager coercions to make using operators
-                // more ergonomic:
-                //
-                // - If the input is of type &'a T (resp. &'a mut T),
-                //   then reborrow it to &'b T (resp. &'b mut T) where
-                //   'b <= 'a.  This makes things like `x == y`, where
-                //   `x` and `y` are both region pointers, work.  We
-                //   could also solve this with variance or different
-                //   traits that don't force left and right to have same
-                //   type.
-                let (adj_ty, adjustment) = match lhs_ty.sty {
-                    ty::ty_rptr(r_in, mt) => {
-                        let r_adj = fcx.infcx().next_region_var(infer::Autoref(lhs.span));
-                        fcx.mk_subr(infer::Reborrow(lhs.span), r_adj, *r_in);
-                        let adjusted_ty = ty::mk_rptr(fcx.tcx(), fcx.tcx().mk_region(r_adj), mt);
-                        let autoptr = ty::AutoPtr(r_adj, mt.mutbl, None);
-                        let adjustment = ty::AutoDerefRef { autoderefs: 1, autoref: Some(autoptr) };
-                        (adjusted_ty, adjustment)
-                    }
-                    _ => {
-                        (lhs_ty, ty::AutoDerefRef { autoderefs: 0, autoref: None })
-                    }
-                };
-
-                debug!("adjusted_ty={} adjustment={:?}",
-                       adj_ty.repr(fcx.tcx()),
-                       adjustment);
-
-                method::lookup_in_trait_adjusted(fcx, op_ex.span, Some(lhs), opname,
-                                                 trait_did, adjustment, adj_ty, None)
-            }
-            None => None
-        };
-        let args = match rhs {
-            Some(rhs) => slice::ref_slice(rhs),
-            None => &[][]
-        };
-        match method {
-            Some(method) => {
-                let method_ty = method.ty;
-                // HACK(eddyb) Fully qualified path to work around a resolve bug.
-                let method_call = ::middle::ty::MethodCall::expr(op_ex.id);
-                fcx.inh.method_map.borrow_mut().insert(method_call, method);
-                match check_method_argument_types(fcx,
-                                                  op_ex.span,
-                                                  method_ty,
-                                                  op_ex,
-                                                  args,
-                                                  autoref_args,
-                                                  DontTupleArguments,
-                                                  NoExpectation) {
-                    ty::FnConverging(result_type) => result_type,
-                    ty::FnDiverging => fcx.tcx().types.err
-                }
-            }
-            None => {
-                unbound_method();
-                // Check the args anyway
-                // so we get all the error messages
-                let expected_ty = fcx.tcx().types.err;
-                check_method_argument_types(fcx,
-                                            op_ex.span,
-                                            expected_ty,
-                                            op_ex,
-                                            args,
-                                            autoref_args,
-                                            DontTupleArguments,
-                                            NoExpectation);
-                fcx.tcx().types.err
-            }
-        }
-    }
-
-    // could be either an expr_binop or an expr_assign_binop
-    fn check_binop<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
-                            expr: &'tcx ast::Expr,
-                            op: ast::BinOp,
-                            lhs: &'tcx ast::Expr,
-                            rhs: &'tcx P<ast::Expr>,
-                            is_binop_assignment: IsBinopAssignment) {
-        let tcx = fcx.ccx.tcx;
-
-        let lvalue_pref = match is_binop_assignment {
-            BinopAssignment => PreferMutLvalue,
-            SimpleBinop => NoPreference
-        };
-        check_expr_with_lvalue_pref(fcx, lhs, lvalue_pref);
-
-        // Callee does bot / err checking
-        let lhs_t =
-            structurally_resolve_type_or_else(fcx, lhs.span, fcx.expr_ty(lhs), || {
-                if ast_util::is_symmetric_binop(op.node) {
-                    // Try RHS first
-                    check_expr(fcx, &**rhs);
-                    fcx.expr_ty(&**rhs)
-                } else {
-                    fcx.tcx().types.err
-                }
-            });
-
-        if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op.node) {
-            // Shift is a special case: rhs must be uint, no matter what lhs is
-            check_expr(fcx, &**rhs);
-            let rhs_ty = fcx.expr_ty(&**rhs);
-            let rhs_ty = structurally_resolved_type(fcx, rhs.span, rhs_ty);
-            if ty::type_is_integral(rhs_ty) {
-                fcx.write_ty(expr.id, lhs_t);
-            } else {
-                fcx.type_error_message(
-                    expr.span,
-                    |actual| {
-                        format!(
-                            "right-hand-side of a shift operation must have integral type, \
-                             not `{}`",
-                            actual)
-                    },
-                    rhs_ty,
-                    None);
-                fcx.write_ty(expr.id, fcx.tcx().types.err);
-            }
-            return;
-        }
-
-        if ty::is_binopable(tcx, lhs_t, op) {
-            let tvar = fcx.infcx().next_ty_var();
-            demand::suptype(fcx, expr.span, tvar, lhs_t);
-            check_expr_has_type(fcx, &**rhs, tvar);
-
-            let result_t = match op.node {
-                ast::BiEq | ast::BiNe | ast::BiLt | ast::BiLe | ast::BiGe |
-                ast::BiGt => {
-                    if ty::type_is_simd(tcx, lhs_t) {
-                        if ty::type_is_fp(ty::simd_type(tcx, lhs_t)) {
-                            fcx.type_error_message(expr.span,
-                                |actual| {
-                                    format!("binary comparison \
-                                             operation `{}` not \
-                                             supported for floating \
-                                             point SIMD vector `{}`",
-                                            ast_util::binop_to_string(op.node),
-                                            actual)
-                                },
-                                lhs_t,
-                                None
-                            );
-                            fcx.tcx().types.err
-                        } else {
-                            lhs_t
-                        }
-                    } else {
-                        fcx.tcx().types.bool
-                    }
-                },
-                _ => lhs_t,
-            };
-
-            fcx.write_ty(expr.id, result_t);
-            return;
-        }
-
-        if op.node == ast::BiOr || op.node == ast::BiAnd {
-            // This is an error; one of the operands must have the wrong
-            // type
-            fcx.write_error(expr.id);
-            fcx.write_error(rhs.id);
-            fcx.type_error_message(expr.span,
-                                   |actual| {
-                    format!("binary operation `{}` cannot be applied \
-                             to type `{}`",
-                            ast_util::binop_to_string(op.node),
-                            actual)
-                },
-                lhs_t,
-                None)
-        }
-
-        // Check for overloaded operators if not an assignment.
-        let result_t = if is_binop_assignment == SimpleBinop {
-            check_user_binop(fcx, expr, lhs, lhs_t, op, rhs)
-        } else {
-            fcx.type_error_message(expr.span,
-                                   |actual| {
-                                        format!("binary assignment \
-                                                 operation `{}=` \
-                                                 cannot be applied to \
-                                                 type `{}`",
-                                                ast_util::binop_to_string(op.node),
-                                                actual)
-                                   },
-                                   lhs_t,
-                                   None);
-            check_expr(fcx, &**rhs);
-            fcx.tcx().types.err
-        };
-
-        fcx.write_ty(expr.id, result_t);
-        if ty::type_is_error(result_t) {
-            fcx.write_ty(rhs.id, result_t);
-        }
-    }
-
-    fn check_user_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                  ex: &'tcx ast::Expr,
-                                  lhs_expr: &'tcx ast::Expr,
-                                  lhs_resolved_t: Ty<'tcx>,
-                                  op: ast::BinOp,
-                                  rhs: &'tcx P<ast::Expr>) -> Ty<'tcx> {
-        let tcx = fcx.ccx.tcx;
-        let lang = &tcx.lang_items;
-        let (name, trait_did) = match op.node {
-            ast::BiAdd => ("add", lang.add_trait()),
-            ast::BiSub => ("sub", lang.sub_trait()),
-            ast::BiMul => ("mul", lang.mul_trait()),
-            ast::BiDiv => ("div", lang.div_trait()),
-            ast::BiRem => ("rem", lang.rem_trait()),
-            ast::BiBitXor => ("bitxor", lang.bitxor_trait()),
-            ast::BiBitAnd => ("bitand", lang.bitand_trait()),
-            ast::BiBitOr => ("bitor", lang.bitor_trait()),
-            ast::BiShl => ("shl", lang.shl_trait()),
-            ast::BiShr => ("shr", lang.shr_trait()),
-            ast::BiLt => ("lt", lang.ord_trait()),
-            ast::BiLe => ("le", lang.ord_trait()),
-            ast::BiGe => ("ge", lang.ord_trait()),
-            ast::BiGt => ("gt", lang.ord_trait()),
-            ast::BiEq => ("eq", lang.eq_trait()),
-            ast::BiNe => ("ne", lang.eq_trait()),
-            ast::BiAnd | ast::BiOr => {
-                check_expr(fcx, &**rhs);
-                return tcx.types.err;
-            }
-        };
-        lookup_op_method(fcx, ex, lhs_resolved_t, token::intern(name),
-                         trait_did, lhs_expr, Some(rhs), || {
-            fcx.type_error_message(ex.span, |actual| {
-                format!("binary operation `{}` cannot be applied to type `{}`",
-                        ast_util::binop_to_string(op.node),
-                        actual)
-            }, lhs_resolved_t, None)
-        }, if ast_util::is_by_value_binop(op.node) { AutorefArgs::No } else { AutorefArgs::Yes })
-    }
-
-    fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                 op_str: &str,
-                                 mname: &str,
-                                 trait_did: Option<ast::DefId>,
-                                 ex: &'tcx ast::Expr,
-                                 rhs_expr: &'tcx ast::Expr,
-                                 rhs_t: Ty<'tcx>,
-                                 op: ast::UnOp) -> Ty<'tcx> {
-       lookup_op_method(fcx, ex, rhs_t, token::intern(mname),
-                        trait_did, rhs_expr, None, || {
-            fcx.type_error_message(ex.span, |actual| {
-                format!("cannot apply unary operator `{}` to type `{}`",
-                        op_str, actual)
-            }, rhs_t, None);
-        }, if ast_util::is_by_value_unop(op) { AutorefArgs::No } else { AutorefArgs::Yes })
-    }
-
     // Check field access expressions
     fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                             expr: &'tcx ast::Expr,
@@ -3078,7 +2813,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                 },
                 expr_t, None);
 
-            tcx.sess.span_help(field.span,
+            tcx.sess.fileline_help(field.span,
                                "maybe a `()` to call it is missing? \
                                If not, try an anonymous function");
         } else {
@@ -3117,6 +2852,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
             if skip.iter().any(|&x| x == n) {
                 continue;
             }
+            // ignore private fields from non-local crates
+            if id.krate != ast::LOCAL_CRATE && elem.vis != Visibility::Public {
+                continue;
+            }
             let dist = lev_distance(n, name);
             if dist < best_dist {
                 best = Some(n);
@@ -3134,7 +2873,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                 expr: &'tcx ast::Expr,
                                 lvalue_pref: LvaluePreference,
                                 base: &'tcx ast::Expr,
-                                idx: codemap::Spanned<uint>) {
+                                idx: codemap::Spanned<usize>) {
         let tcx = fcx.ccx.tcx;
         check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
         let expr_t = structurally_resolved_type(fcx, expr.span,
@@ -3285,7 +3024,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                 let mut missing_fields = Vec::new();
                 for class_field in field_types {
                     let name = class_field.name;
-                    let (_, seen) = class_field_map[name];
+                    let (_, seen) = *class_field_map.get(&name).unwrap();
                     if !seen {
                         missing_fields.push(
                             format!("`{}`", &token::get_name(name)))
@@ -3404,10 +3143,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
 
           let mut checked = false;
           opt_place.as_ref().map(|place| match place.node {
-              ast::ExprPath(ref path) => {
+              ast::ExprPath(None, ref path) => {
                   // FIXME(pcwalton): For now we hardcode the two permissible
                   // places: the exchange heap and the managed heap.
-                  let definition = lookup_def(fcx, path.span, place.id);
+                  let definition = lookup_full_def(tcx, path.span, place.id);
                   let def_id = definition.def_id();
                   let referent_ty = fcx.expr_ty(&**subexpr);
                   if tcx.lang_items.exchange_heap() == Some(def_id) {
@@ -3430,35 +3169,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
         fcx.write_ty(id, typ);
       }
       ast::ExprBinary(op, ref lhs, ref rhs) => {
-        check_binop(fcx, expr, op, &**lhs, rhs, SimpleBinop);
-
-        let lhs_ty = fcx.expr_ty(&**lhs);
-        let rhs_ty = fcx.expr_ty(&**rhs);
-        if ty::type_is_error(lhs_ty) ||
-            ty::type_is_error(rhs_ty) {
-            fcx.write_error(id);
-        }
+        op::check_binop(fcx, expr, op, lhs, rhs);
       }
       ast::ExprAssignOp(op, ref lhs, ref rhs) => {
-        check_binop(fcx, expr, op, &**lhs, rhs, BinopAssignment);
-
-        let lhs_t = fcx.expr_ty(&**lhs);
-        let result_t = fcx.expr_ty(expr);
-        demand::suptype(fcx, expr.span, result_t, lhs_t);
-
-        let tcx = fcx.tcx();
-        if !ty::expr_is_lval(tcx, &**lhs) {
-            span_err!(tcx.sess, lhs.span, E0067, "illegal left-hand side expression");
-        }
-
-        fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
-
-        // Overwrite result of check_binop...this preserves existing behavior
-        // but seems quite dubious with regard to user-defined methods
-        // and so forth. - Niko
-        if !ty::type_is_error(result_t) {
-            fcx.write_nil(expr.id);
-        }
+        op::check_binop_assign(fcx, expr, op, lhs, rhs);
       }
       ast::ExprUnary(unop, ref oprnd) => {
         let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
@@ -3531,9 +3245,9 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                                          oprnd_t);
                     if !(ty::type_is_integral(oprnd_t) ||
                          oprnd_t.sty == ty::ty_bool) {
-                        oprnd_t = check_user_unop(fcx, "!", "not",
-                                                  tcx.lang_items.not_trait(),
-                                                  expr, &**oprnd, oprnd_t, unop);
+                        oprnd_t = op::check_user_unop(fcx, "!", "not",
+                                                      tcx.lang_items.not_trait(),
+                                                      expr, &**oprnd, oprnd_t, unop);
                     }
                 }
                 ast::UnNeg => {
@@ -3541,9 +3255,18 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                                          oprnd_t);
                     if !(ty::type_is_integral(oprnd_t) ||
                          ty::type_is_fp(oprnd_t)) {
-                        oprnd_t = check_user_unop(fcx, "-", "neg",
-                                                  tcx.lang_items.neg_trait(),
-                                                  expr, &**oprnd, oprnd_t, unop);
+                        oprnd_t = op::check_user_unop(fcx, "-", "neg",
+                                                      tcx.lang_items.neg_trait(),
+                                                      expr, &**oprnd, oprnd_t, unop);
+                    }
+                    if let ty::ty_uint(_) = oprnd_t.sty {
+                        if !tcx.sess.features.borrow().negate_unsigned {
+                            feature_gate::emit_feature_err(
+                                &tcx.sess.parse_sess.span_diagnostic,
+                                "negate_unsigned",
+                                expr.span,
+                                "unary negation of unsigned integers may be removed in the future");
+                        }
                     }
                 }
             }
@@ -3597,26 +3320,67 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
         };
         fcx.write_ty(id, oprnd_t);
       }
-      ast::ExprPath(ref path) => {
-          let defn = lookup_def(fcx, path.span, id);
-          let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx, expr.span, defn);
-          instantiate_path(fcx, path, scheme, &predicates, None, defn, expr.span, expr.id);
+      ast::ExprPath(ref maybe_qself, ref path) => {
+          let opt_self_ty = maybe_qself.as_ref().map(|qself| {
+              fcx.to_ty(&qself.ty)
+          });
 
-          // We always require that the type provided as the value for
-          // a type parameter outlives the moment of instantiation.
-          constrain_path_type_parameters(fcx, expr);
-      }
-      ast::ExprQPath(ref qpath) => {
-          // Require explicit type params for the trait.
-          let self_ty = fcx.to_ty(&*qpath.self_type);
-          astconv::instantiate_trait_ref(fcx, fcx, &*qpath.trait_ref, Some(self_ty), None);
-
-          let defn = lookup_def(fcx, expr.span, id);
-          let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx, expr.span, defn);
-          let mut path = qpath.trait_ref.path.clone();
-          path.segments.push(qpath.item_path.clone());
-          instantiate_path(fcx, &path, scheme, &predicates, Some(self_ty),
-                           defn, expr.span, expr.id);
+          let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
+              d
+          } else if let Some(ast::QSelf { position: 0, .. }) = *maybe_qself {
+                // Create some fake resolution that can't possibly be a type.
+                def::PathResolution {
+                    base_def: def::DefMod(local_def(ast::CRATE_NODE_ID)),
+                    last_private: LastMod(AllPublic),
+                    depth: path.segments.len()
+                }
+            } else {
+              tcx.sess.span_bug(expr.span,
+                                &format!("unbound path {}", expr.repr(tcx)))
+          };
+
+          let def = path_res.base_def;
+          if path_res.depth == 0 {
+              let (scheme, predicates) =
+                  type_scheme_and_predicates_for_def(fcx, expr.span, def);
+              instantiate_path(fcx, &path.segments,
+                               scheme, &predicates,
+                               opt_self_ty, def, expr.span, id);
+          } else {
+              let ty_segments = path.segments.init();
+              let base_ty_end = path.segments.len() - path_res.depth;
+              let ty = astconv::finish_resolving_def_to_ty(fcx,
+                                                           fcx,
+                                                           expr.span,
+                                                           PathParamMode::Optional,
+                                                           &def,
+                                                           opt_self_ty,
+                                                           &ty_segments[..base_ty_end],
+                                                           &ty_segments[base_ty_end..]);
+              let method_segment = path.segments.last().unwrap();
+              let method_name = method_segment.identifier.name;
+              match method::resolve_ufcs(fcx, expr.span, method_name, ty, id) {
+                  Ok((def, lp)) => {
+                      // Write back the new resolution.
+                      tcx.def_map.borrow_mut().insert(id, def::PathResolution {
+                          base_def: def,
+                          last_private: path_res.last_private.or(lp),
+                          depth: 0
+                      });
+
+                      let (scheme, predicates) =
+                          type_scheme_and_predicates_for_def(fcx, expr.span, def);
+                      instantiate_path(fcx, slice::ref_slice(method_segment),
+                                       scheme, &predicates,
+                                       Some(ty), def, expr.span, id);
+                  }
+                  Err(error) => {
+                      method::report_error(fcx, expr.span, ty,
+                                           method_name, None, error);
+                      fcx.write_error(id);
+                  }
+              }
+          }
 
           // We always require that the type provided as the value for
           // a type parameter outlives the moment of instantiation.
@@ -3745,9 +3509,35 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
       }
       ast::ExprCast(ref e, ref t) => {
         if let ast::TyFixedLengthVec(_, ref count_expr) = t.node {
-            check_expr_with_hint(fcx, &**count_expr, tcx.types.uint);
+            check_expr_with_hint(fcx, &**count_expr, tcx.types.usize);
+        }
+
+        // Find the type of `e`. Supply hints based on the type we are casting to,
+        // if appropriate.
+        let t_1 = fcx.to_ty(t);
+        let t_1 = structurally_resolved_type(fcx, expr.span, t_1);
+        check_expr_with_expectation(fcx, e, ExpectCastableToType(t_1));
+        let t_e = fcx.expr_ty(e);
+
+        // Eagerly check for some obvious errors.
+        if ty::type_is_error(t_e) {
+            fcx.write_error(id);
+        } else if !fcx.type_is_known_to_be_sized(t_1, expr.span) {
+            report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_1, t_e, id);
+        } else {
+            // Write a type for the whole expression, assuming everything is going
+            // to work out Ok.
+            fcx.write_ty(id, t_1);
+
+            // Defer other checks until we're done type checking.
+            let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
+            deferred_cast_checks.push(CastCheck {
+                expr: (**e).clone(),
+                expr_ty: t_e,
+                cast_ty: t_1,
+                span: expr.span,
+            });
         }
-        check_cast(fcx, expr, &**e, &**t);
       }
       ast::ExprVec(ref args) => {
         let uty = expected.to_option(fcx).and_then(|uty| {
@@ -3776,7 +3566,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
         fcx.write_ty(id, typ);
       }
       ast::ExprRepeat(ref element, ref count_expr) => {
-        check_expr_has_type(fcx, &**count_expr, tcx.types.uint);
+        check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
         let count = ty::eval_repeat_count(fcx.tcx(), &**count_expr);
 
         let uty = match expected {
@@ -3851,14 +3641,14 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
       }
       ast::ExprStruct(ref path, ref fields, ref base_expr) => {
         // Resolve the path.
-        let def = tcx.def_map.borrow().get(&id).cloned();
+        let def = lookup_full_def(tcx, path.span, id);
         let struct_id = match def {
-            Some(def::DefVariant(enum_id, variant_id, true)) => {
+            def::DefVariant(enum_id, variant_id, true) => {
                 check_struct_enum_variant(fcx, id, expr.span, enum_id,
                                           variant_id, &fields[..]);
                 enum_id
             }
-            Some(def::DefTrait(def_id)) => {
+            def::DefTrait(def_id) => {
                 span_err!(tcx.sess, path.span, E0159,
                     "use of trait `{}` as a struct constructor",
                     pprust::path_to_string(path));
@@ -3868,7 +3658,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                              base_expr);
                 def_id
             },
-            Some(def) => {
+            def => {
                 // Verify that this was actually a struct.
                 let typ = ty::lookup_item_type(fcx.ccx.tcx, def.def_id());
                 match typ.ty.sty {
@@ -3893,10 +3683,6 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
 
                 def.def_id()
             }
-            _ => {
-                tcx.sess.span_bug(path.span,
-                                  "structure constructor wasn't resolved")
-            }
         };
 
         // Turn the path into a type and verify that that type unifies with
@@ -3963,9 +3749,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
 
                   match result {
                       Some((index_ty, element_ty)) => {
-                          // FIXME: we've already checked idx above, we should
-                          // probably just demand subtype or something here.
-                          check_expr_has_type(fcx, &**idx, index_ty);
+                          let idx_expr_ty = fcx.expr_ty(idx);
+                          demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
                           fcx.write_ty(id, element_ty);
                       }
                       _ => {
@@ -4088,16 +3873,16 @@ impl<'tcx> Expectation<'tcx> {
     /// is useful in determining the concrete type.
     ///
     /// The primary use case is where the expected type is a fat pointer,
-    /// like `&[int]`. For example, consider the following statement:
+    /// like `&[isize]`. For example, consider the following statement:
     ///
-    ///    let x: &[int] = &[1, 2, 3];
+    ///    let x: &[isize] = &[1, 2, 3];
     ///
     /// In this case, the expected type for the `&[1, 2, 3]` expression is
-    /// `&[int]`. If however we were to say that `[1, 2, 3]` has the
-    /// expectation `ExpectHasType([int])`, that would be too strong --
-    /// `[1, 2, 3]` does not have the type `[int]` but rather `[int; 3]`.
+    /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
+    /// expectation `ExpectHasType([isize])`, that would be too strong --
+    /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
     /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
-    /// to the type `&[int]`. Therefore, we propagate this more limited hint,
+    /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
     /// which still is useful, because it informs integer literals and the like.
     /// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
     /// for examples of where this comes up,.
@@ -4165,11 +3950,27 @@ impl<'tcx> Repr<'tcx> for Expectation<'tcx> {
 }
 
 pub fn check_decl_initializer<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
-                                       nid: ast::NodeId,
+                                       local: &'tcx ast::Local,
                                        init: &'tcx ast::Expr)
 {
-    let local_ty = fcx.local_ty(init.span, nid);
-    check_expr_coercable_to_type(fcx, init, local_ty)
+    let ref_bindings = fcx.tcx().pat_contains_ref_binding(&local.pat);
+
+    let local_ty = fcx.local_ty(init.span, local.id);
+    if !ref_bindings {
+        check_expr_coercable_to_type(fcx, init, local_ty)
+    } else {
+        // Somewhat subtle: if we have a `ref` binding in the pattern,
+        // we want to avoid introducing coercions for the RHS. This is
+        // both because it helps preserve sanity and, in the case of
+        // ref mut, for soundness (issue #23116). In particular, in
+        // the latter case, we need to be clear that the type of the
+        // referent for the reference that results is *equal to* the
+        // type of the lvalue it is referencing, and not some
+        // supertype thereof.
+        check_expr(fcx, init);
+        let init_ty = fcx.expr_ty(init);
+        demand::eqtype(fcx, init.span, init_ty, local_ty);
+    };
 }
 
 pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx ast::Local)  {
@@ -4179,7 +3980,7 @@ pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx ast::Local)
     fcx.write_ty(local.id, t);
 
     if let Some(ref init) = local.init {
-        check_decl_initializer(fcx, local.id, &**init);
+        check_decl_initializer(fcx, local, &**init);
         let init_ty = fcx.expr_ty(&**init);
         if ty::type_is_error(init_ty) {
             fcx.write_ty(local.id, init_ty);
@@ -4351,7 +4152,7 @@ fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
     let inh = static_inherited_fields(ccx);
     let rty = ty::node_id_to_type(ccx.tcx, id);
     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
-    let declty = (*fcx.ccx.tcx.tcache.borrow())[local_def(id)].ty;
+    let declty = fcx.ccx.tcx.tcache.borrow().get(&local_def(id)).unwrap().ty;
     check_const_with_ty(&fcx, sp, e, declty);
 }
 
@@ -4368,6 +4169,7 @@ fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     check_expr_with_hint(fcx, e, declty);
     demand::coerce(fcx, e.span, declty, e);
     vtable::select_all_fcx_obligations_or_error(fcx);
+    fcx.check_casts();
     regionck::regionck_expr(fcx, e);
     writeback::resolve_type_vars_in_expr(fcx, e);
 }
@@ -4421,7 +4223,7 @@ pub fn check_instantiable(tcx: &ty::ctxt,
         span_err!(tcx.sess, sp, E0073,
             "this type cannot be instantiated without an \
              instance of itself");
-        span_help!(tcx.sess, sp, "consider using `Option<{}>`",
+        fileline_help!(tcx.sess, sp, "consider using `Option<{}>`",
             ppaux::ty_to_string(tcx, item_ty));
         false
     } else {
@@ -4472,7 +4274,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                 ast::TyU16 => disr as u16 as Disr == disr,
                 ast::TyU32 => disr as u32 as Disr == disr,
                 ast::TyU64 => disr as u64 as Disr == disr,
-                ast::TyUs(_) => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
+                ast::TyUs => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
             }
         }
         fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
@@ -4481,7 +4283,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                 ast::TyI16 => disr as i16 as Disr == disr,
                 ast::TyI32 => disr as i32 as Disr == disr,
                 ast::TyI64 => disr as i64 as Disr == disr,
-                ast::TyIs(_) => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
+                ast::TyIs => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
             }
         }
         match ty {
@@ -4493,58 +4295,30 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
     fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                           vs: &'tcx [P<ast::Variant>],
                           id: ast::NodeId,
-                          hint: attr::ReprAttr)
-                          -> Vec<Rc<ty::VariantInfo<'tcx>>> {
+                          hint: attr::ReprAttr) {
+        #![allow(trivial_numeric_casts)]
 
         let rty = ty::node_id_to_type(ccx.tcx, id);
-        let mut variants: Vec<Rc<ty::VariantInfo>> = Vec::new();
         let mut disr_vals: Vec<ty::Disr> = Vec::new();
-        let mut prev_disr_val: Option<ty::Disr> = None;
 
+        let inh = static_inherited_fields(ccx);
+        let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
+
+        let (_, repr_type_ty) = ty::enum_repr_type(ccx.tcx, Some(&hint));
         for v in vs {
+            if let Some(ref e) = v.node.disr_expr {
+                check_const_with_ty(&fcx, e.span, e, repr_type_ty);
+            }
+        }
 
-            // If the discriminant value is specified explicitly in the enum check whether the
-            // initialization expression is valid, otherwise use the last value plus one.
-            let mut current_disr_val = match prev_disr_val {
-                Some(prev_disr_val) => prev_disr_val + 1,
-                None => ty::INITIAL_DISCRIMINANT_VALUE
-            };
+        let def_id = local_def(id);
 
-            match v.node.disr_expr {
-                Some(ref e) => {
-                    debug!("disr expr, checking {}", pprust::expr_to_string(&**e));
+        // ty::enum_variants guards against discriminant overflows, so
+        // we need not check for that.
+        let variants = ty::enum_variants(ccx.tcx, def_id);
 
-                    let inh = static_inherited_fields(ccx);
-                    let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
-                    let declty = match hint {
-                        attr::ReprAny | attr::ReprPacked | attr::ReprExtern => fcx.tcx().types.int,
-                        attr::ReprInt(_, attr::SignedInt(ity)) => {
-                            ty::mk_mach_int(fcx.tcx(), ity)
-                        }
-                        attr::ReprInt(_, attr::UnsignedInt(ity)) => {
-                            ty::mk_mach_uint(fcx.tcx(), ity)
-                        },
-                    };
-                    check_const_with_ty(&fcx, e.span, &**e, declty);
-                    // check_expr (from check_const pass) doesn't guarantee
-                    // that the expression is in a form that eval_const_expr can
-                    // handle, so we may still get an internal compiler error
-
-                    match const_eval::eval_const_expr_partial(ccx.tcx, &**e, Some(declty)) {
-                        Ok(const_eval::const_int(val)) => current_disr_val = val as Disr,
-                        Ok(const_eval::const_uint(val)) => current_disr_val = val as Disr,
-                        Ok(_) => {
-                            span_err!(ccx.tcx.sess, e.span, E0079,
-                                "expected signed integer constant");
-                        }
-                        Err(ref err) => {
-                            span_err!(ccx.tcx.sess, e.span, E0080,
-                                "expected constant: {}", *err);
-                        }
-                    }
-                },
-                None => ()
-            };
+        for (v, variant) in vs.iter().zip(variants.iter()) {
+            let current_disr_val = variant.disr_val;
 
             // Check for duplicate discriminant values
             match disr_vals.iter().position(|&x| x == current_disr_val) {
@@ -4572,19 +4346,11 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                 }
             }
             disr_vals.push(current_disr_val);
-
-            let variant_info = Rc::new(VariantInfo::from_ast_variant(ccx.tcx, &**v,
-                                                                     current_disr_val));
-            prev_disr_val = Some(current_disr_val);
-
-            variants.push(variant_info);
         }
-
-        return variants;
     }
 
     let hint = *ty::lookup_repr_hints(ccx.tcx, ast::DefId { krate: ast::LOCAL_CRATE, node: id })
-        [].get(0).unwrap_or(&attr::ReprAny);
+        .get(0).unwrap_or(&attr::ReprAny);
 
     if hint != attr::ReprAny && vs.len() <= 1 {
         if vs.len() == 1 {
@@ -4596,10 +4362,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
         };
     }
 
-    let variants = do_check(ccx, vs, id, hint);
-
-    // cache so that ty::enum_variants won't repeat this work
-    ccx.tcx.enum_var_cache.borrow_mut().insert(local_def(id), Rc::new(variants));
+    do_check(ccx, vs, id, hint);
 
     check_representable(ccx.tcx, sp, id, "enum");
 
@@ -4610,10 +4373,6 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
     check_instantiable(ccx.tcx, sp, id);
 }
 
-pub fn lookup_def(fcx: &FnCtxt, sp: Span, id: ast::NodeId) -> def::Def {
-    lookup_def_ccx(fcx.ccx, sp, id)
-}
-
 // Returns the type parameter count and the type for the given definition.
 fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                 sp: Span,
@@ -4625,7 +4384,7 @@ fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
              ty::GenericPredicates::empty())
         }
-        def::DefFn(id, _) | def::DefStaticMethod(id, _) | def::DefMethod(id, _, _) |
+        def::DefFn(id, _) | def::DefMethod(id, _) |
         def::DefStatic(id, _) | def::DefVariant(_, id, _) |
         def::DefStruct(id) | def::DefConst(id) => {
             (ty::lookup_item_type(fcx.tcx(), id), ty::lookup_predicates(fcx.tcx(), id))
@@ -4633,14 +4392,12 @@ fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         def::DefTrait(_) |
         def::DefTy(..) |
         def::DefAssociatedTy(..) |
-        def::DefAssociatedPath(..) |
         def::DefPrimTy(_) |
         def::DefTyParam(..) |
         def::DefMod(..) |
         def::DefForeignMod(..) |
         def::DefUse(..) |
         def::DefRegion(..) |
-        def::DefTyParamBinder(..) |
         def::DefLabel(..) |
         def::DefSelfTy(..) => {
             fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
@@ -4651,15 +4408,15 @@ fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 // Instantiates the given path, which must refer to an item with the given
 // number of type parameters and type.
 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                  path: &ast::Path,
+                                  segments: &[ast::PathSegment],
                                   type_scheme: TypeScheme<'tcx>,
                                   type_predicates: &ty::GenericPredicates<'tcx>,
                                   opt_self_ty: Option<Ty<'tcx>>,
                                   def: def::Def,
                                   span: Span,
                                   node_id: ast::NodeId) {
-    debug!("instantiate_path(path={}, def={}, node_id={}, type_scheme={})",
-           path.repr(fcx.tcx()),
+    debug!("instantiate_path(path={:?}, def={}, node_id={}, type_scheme={})",
+           segments,
            def.repr(fcx.tcx()),
            node_id,
            type_scheme.repr(fcx.tcx()));
@@ -4723,23 +4480,23 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     //
     // The first step then is to categorize the segments appropriately.
 
-    assert!(path.segments.len() >= 1);
+    assert!(segments.len() >= 1);
+
+    let mut ufcs_method = None;
     let mut segment_spaces: Vec<_>;
     match def {
         // Case 1 and 1b. Reference to a *type* or *enum variant*.
         def::DefSelfTy(..) |
         def::DefStruct(..) |
         def::DefVariant(..) |
-        def::DefTyParamBinder(..) |
         def::DefTy(..) |
         def::DefAssociatedTy(..) |
-        def::DefAssociatedPath(..) |
         def::DefTrait(..) |
         def::DefPrimTy(..) |
         def::DefTyParam(..) => {
             // Everything but the final segment should have no
             // parameters at all.
-            segment_spaces = repeat(None).take(path.segments.len() - 1).collect();
+            segment_spaces = repeat(None).take(segments.len() - 1).collect();
             segment_spaces.push(Some(subst::TypeSpace));
         }
 
@@ -4747,25 +4504,29 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         def::DefFn(..) |
         def::DefConst(..) |
         def::DefStatic(..) => {
-            segment_spaces = repeat(None).take(path.segments.len() - 1).collect();
+            segment_spaces = repeat(None).take(segments.len() - 1).collect();
             segment_spaces.push(Some(subst::FnSpace));
         }
 
         // Case 3. Reference to a method.
-        def::DefStaticMethod(_, providence) |
-        def::DefMethod(_, _, providence) => {
-            assert!(path.segments.len() >= 2);
-
-            match providence {
+        def::DefMethod(_, provenance) => {
+            match provenance {
                 def::FromTrait(trait_did) => {
                     callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
                 }
                 def::FromImpl(_) => {}
             }
 
-            segment_spaces = repeat(None).take(path.segments.len() - 2).collect();
-            segment_spaces.push(Some(subst::TypeSpace));
-            segment_spaces.push(Some(subst::FnSpace));
+            if segments.len() >= 2 {
+                segment_spaces = repeat(None).take(segments.len() - 2).collect();
+                segment_spaces.push(Some(subst::TypeSpace));
+                segment_spaces.push(Some(subst::FnSpace));
+            } else {
+                // `<T>::method` will end up here, and so can `T::method`.
+                let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
+                segment_spaces = vec![Some(subst::FnSpace)];
+                ufcs_method = Some((provenance, self_ty));
+            }
         }
 
         // Other cases. Various nonsense that really shouldn't show up
@@ -4778,10 +4539,15 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         def::DefRegion(..) |
         def::DefLabel(..) |
         def::DefUpvar(..) => {
-            segment_spaces = repeat(None).take(path.segments.len()).collect();
+            segment_spaces = repeat(None).take(segments.len()).collect();
         }
     }
-    assert_eq!(segment_spaces.len(), path.segments.len());
+    assert_eq!(segment_spaces.len(), segments.len());
+
+    // In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
+    // `opt_self_ty` can also be Some for `Foo::method`, where Foo's
+    // type parameters are not mandatory.
+    let require_type_space = opt_self_ty.is_some() && ufcs_method.is_none();
 
     debug!("segment_spaces={:?}", segment_spaces);
 
@@ -4795,16 +4561,17 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     // provided (if any) into their appropriate spaces. We'll also report
     // errors if type parameters are provided in an inappropriate place.
     let mut substs = Substs::empty();
-    for (opt_space, segment) in segment_spaces.iter().zip(path.segments.iter()) {
+    for (opt_space, segment) in segment_spaces.iter().zip(segments.iter()) {
         match *opt_space {
             None => {
-                report_error_if_segment_contains_type_parameters(fcx, segment);
+                check_path_args(fcx.tcx(), slice::ref_slice(segment),
+                                NO_TPS | NO_REGIONS);
             }
 
             Some(space) => {
                 push_explicit_parameters_from_segment_to_substs(fcx,
                                                                 space,
-                                                                path.span,
+                                                                span,
                                                                 type_defs,
                                                                 region_defs,
                                                                 segment,
@@ -4813,9 +4580,9 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }
     }
     if let Some(self_ty) = opt_self_ty {
-        // `<T as Trait>::foo` shouldn't have resolved to a `Self`-less item.
-        assert_eq!(type_defs.len(subst::SelfSpace), 1);
-        substs.types.push(subst::SelfSpace, self_ty);
+        if type_defs.len(subst::SelfSpace) == 1 {
+            substs.types.push(subst::SelfSpace, self_ty);
+        }
     }
 
     // Now we have to compare the types that the user *actually*
@@ -4825,7 +4592,8 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     // to add defaults. If the user provided *too many* types, that's
     // a problem.
     for &space in &ParamSpace::all() {
-        adjust_type_parameters(fcx, span, space, type_defs, &mut substs);
+        adjust_type_parameters(fcx, span, space, type_defs,
+                               require_type_space, &mut substs);
         assert_eq!(substs.types.len(space), type_defs.len(space));
 
         adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
@@ -4848,27 +4616,32 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     // the referenced item.
     let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
 
-    fcx.write_ty(node_id, ty_substituted);
-    fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
-    return;
 
-    fn report_error_if_segment_contains_type_parameters(
-        fcx: &FnCtxt,
-        segment: &ast::PathSegment)
-    {
-        for typ in &segment.parameters.types() {
-            span_err!(fcx.tcx().sess, typ.span, E0085,
-                "type parameters may not appear here");
-            break;
-        }
+    if let Some((def::FromImpl(impl_def_id), self_ty)) = ufcs_method {
+        // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
+        // is inherent, there is no `Self` parameter, instead, the impl needs
+        // type parameters, which we can infer by unifying the provided `Self`
+        // with the substituted impl type.
+        let impl_scheme = ty::lookup_item_type(fcx.tcx(), impl_def_id);
+        assert_eq!(substs.types.len(subst::TypeSpace),
+                   impl_scheme.generics.types.len(subst::TypeSpace));
+        assert_eq!(substs.regions().len(subst::TypeSpace),
+                   impl_scheme.generics.regions.len(subst::TypeSpace));
 
-        for lifetime in &segment.parameters.lifetimes() {
-            span_err!(fcx.tcx().sess, lifetime.span, E0086,
-                "lifetime parameters may not appear here");
-            break;
+        let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
+        if fcx.mk_subty(false, infer::Misc(span), self_ty, impl_ty).is_err() {
+            fcx.tcx().sess.span_bug(span,
+            &format!(
+                "instantiate_path: (UFCS) {} was a subtype of {} but now is not?",
+                self_ty.repr(fcx.tcx()),
+                impl_ty.repr(fcx.tcx())));
         }
     }
 
+    fcx.write_ty(node_id, ty_substituted);
+    fcx.write_substs(node_id, ty::ItemSubsts { substs: substs });
+    return;
+
     /// Finds the parameters that the user provided and adds them to `substs`. If too many
     /// parameters are provided, then reports an error and clears the output vector.
     ///
@@ -5003,6 +4776,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         span: Span,
         space: ParamSpace,
         defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
+        require_type_space: bool,
         substs: &mut Substs<'tcx>)
     {
         let provided_len = substs.types.len(space);
@@ -5025,9 +4799,8 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 
         // Nothing specified at all: supply inference variables for
         // everything.
-        if provided_len == 0 {
-            substs.types.replace(space,
-                                 fcx.infcx().next_ty_vars(desired.len()));
+        if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
+            substs.types.replace(space, fcx.infcx().next_ty_vars(desired.len()));
             return;
         }
 
@@ -5145,22 +4918,19 @@ pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
     // inside the loop?
     (loop_query(&*b, |e| {
         match *e {
-            ast::ExprBreak(_) => true,
+            ast::ExprBreak(None) => true,
             _ => false
         }
     })) ||
-   // Second: is there a labeled break with label
-   // <id> nested anywhere inside the loop?
+    // Second: is there a labeled break with label
+    // <id> nested anywhere inside the loop?
     (block_query(b, |e| {
-        match e.node {
-            ast::ExprBreak(Some(_)) => {
-                match cx.def_map.borrow().get(&e.id) {
-                    Some(&def::DefLabel(loop_id)) if id == loop_id => true,
-                    _ => false,
-                }
-            }
-            _ => false
-        }}))
+        if let ast::ExprBreak(Some(_)) = e.node {
+            lookup_full_def(cx, e.span, e.id) == def::DefLabel(id)
+        } else {
+            false
+        }
+    }))
 }
 
 pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
@@ -5178,7 +4948,7 @@ pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             match t.sty {
                 ty::ty_param(ParamTy {idx, ..}) => {
                     debug!("Found use of ty param num {}", idx);
-                    tps_used[idx as uint] = true;
+                    tps_used[idx as usize] = true;
                 }
                 _ => ()
             }
@@ -5237,8 +5007,8 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
         let (n_tps, inputs, output) = match &name[..] {
             "breakpoint" => (0, Vec::new(), ty::mk_nil(tcx)),
             "size_of" |
-            "pref_align_of" | "min_align_of" => (1, Vec::new(), ccx.tcx.types.uint),
-            "init" => (1, Vec::new(), param(ccx, 0)),
+            "pref_align_of" | "min_align_of" => (1, Vec::new(), ccx.tcx.types.usize),
+            "init" | "init_dropped" => (1, Vec::new(), param(ccx, 0)),
             "uninit" => (1, Vec::new(), param(ccx, 0)),
             "forget" => (1, vec!( param(ccx, 0) ), ty::mk_nil(tcx)),
             "transmute" => (2, vec!( param(ccx, 0) ), param(ccx, 1)),
@@ -5256,17 +5026,8 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
             "needs_drop" => (1, Vec::new(), ccx.tcx.types.bool),
             "owns_managed" => (1, Vec::new(), ccx.tcx.types.bool),
 
-            "get_tydesc" => {
-              let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) {
-                  Ok(t) => t,
-                  Err(s) => { span_fatal!(tcx.sess, it.span, E0240, "{}", &s[..]); }
-              };
-              let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
-                  ty: tydesc_ty,
-                  mutbl: ast::MutImmutable
-              });
-              (1, Vec::new(), td_ptr)
-            }
+            "type_name" => (1, Vec::new(), ty::mk_str_slice(tcx, tcx.mk_region(ty::ReStatic),
+                                                             ast::MutImmutable)),
             "type_id" => (1, Vec::new(), ccx.tcx.types.u64),
             "offset" => {
               (1,
@@ -5275,14 +5036,28 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
                       ty: param(ccx, 0),
                       mutbl: ast::MutImmutable
                   }),
-                  ccx.tcx.types.int
+                  ccx.tcx.types.isize
                ),
                ty::mk_ptr(tcx, ty::mt {
                    ty: param(ccx, 0),
                    mutbl: ast::MutImmutable
                }))
             }
-            "copy_memory" | "copy_nonoverlapping_memory" |
+            "copy" | "copy_nonoverlapping" => {
+              (1,
+               vec!(
+                  ty::mk_ptr(tcx, ty::mt {
+                      ty: param(ccx, 0),
+                      mutbl: ast::MutImmutable
+                  }),
+                  ty::mk_ptr(tcx, ty::mt {
+                      ty: param(ccx, 0),
+                      mutbl: ast::MutMutable
+                  }),
+                  tcx.types.usize,
+               ),
+               ty::mk_nil(tcx))
+            }
             "volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => {
               (1,
                vec!(
@@ -5294,11 +5069,11 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
                       ty: param(ccx, 0),
                       mutbl: ast::MutImmutable
                   }),
-                  tcx.types.uint,
+                  tcx.types.usize,
                ),
                ty::mk_nil(tcx))
             }
-            "set_memory" | "volatile_set_memory" => {
+            "write_bytes" | "volatile_set_memory" => {
               (1,
                vec!(
                   ty::mk_ptr(tcx, ty::mt {
@@ -5306,7 +5081,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
                       mutbl: ast::MutMutable
                   }),
                   tcx.types.u8,
-                  tcx.types.uint,
+                  tcx.types.usize,
                ),
                ty::mk_nil(tcx))
             }
@@ -5425,6 +5200,9 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
                 (0, vec!(tcx.types.u64, tcx.types.u64),
                 ty::mk_tup(tcx, vec!(tcx.types.u64, tcx.types.bool))),
 
+            "overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
+                (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
+
             "return_address" => (0, vec![], ty::mk_imm_ptr(tcx, tcx.types.u8)),
 
             "assume" => (0, vec![tcx.types.bool], ty::mk_nil(tcx)),
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
new file mode 100644 (file)
index 0000000..49e88dc
--- /dev/null
@@ -0,0 +1,481 @@
+// 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.
+
+//! Code related to processing overloaded binary and unary operators.
+
+use super::{
+    check_expr,
+    check_expr_coercable_to_type,
+    check_expr_with_lvalue_pref,
+    demand,
+    method,
+    FnCtxt,
+    PreferMutLvalue,
+    structurally_resolved_type,
+};
+use middle::infer;
+use middle::traits;
+use middle::ty::{self, Ty};
+use syntax::ast;
+use syntax::ast_util;
+use syntax::parse::token;
+use util::ppaux::{Repr, UserString};
+
+/// Check a `a <op>= b`
+pub fn check_binop_assign<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
+                                   expr: &'tcx ast::Expr,
+                                   op: ast::BinOp,
+                                   lhs_expr: &'tcx ast::Expr,
+                                   rhs_expr: &'tcx ast::Expr)
+{
+    let tcx = fcx.ccx.tcx;
+
+    check_expr_with_lvalue_pref(fcx, lhs_expr, PreferMutLvalue);
+    check_expr(fcx, rhs_expr);
+
+    let lhs_ty = structurally_resolved_type(fcx, lhs_expr.span, fcx.expr_ty(lhs_expr));
+    let rhs_ty = structurally_resolved_type(fcx, rhs_expr.span, fcx.expr_ty(rhs_expr));
+
+    if is_builtin_binop(fcx.tcx(), lhs_ty, rhs_ty, op) {
+        enforce_builtin_binop_types(fcx, lhs_expr, lhs_ty, rhs_expr, rhs_ty, op);
+        fcx.write_nil(expr.id);
+    } else {
+        // error types are considered "builtin"
+        assert!(!ty::type_is_error(lhs_ty) || !ty::type_is_error(rhs_ty));
+        span_err!(tcx.sess, lhs_expr.span, E0368,
+                  "binary assignment operation `{}=` cannot be applied to types `{}` and `{}`",
+                  ast_util::binop_to_string(op.node),
+                  lhs_ty.user_string(fcx.tcx()),
+                  rhs_ty.user_string(fcx.tcx()));
+        fcx.write_error(expr.id);
+    }
+
+    let tcx = fcx.tcx();
+    if !ty::expr_is_lval(tcx, lhs_expr) {
+        span_err!(tcx.sess, lhs_expr.span, E0067, "illegal left-hand side expression");
+    }
+
+    fcx.require_expr_have_sized_type(lhs_expr, traits::AssignmentLhsSized);
+}
+
+/// Check a potentially overloaded binary operator.
+pub fn check_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                             expr: &'tcx ast::Expr,
+                             op: ast::BinOp,
+                             lhs_expr: &'tcx ast::Expr,
+                             rhs_expr: &'tcx ast::Expr)
+{
+    let tcx = fcx.ccx.tcx;
+
+    debug!("check_binop(expr.id={}, expr={}, op={:?}, lhs_expr={}, rhs_expr={})",
+           expr.id,
+           expr.repr(tcx),
+           op,
+           lhs_expr.repr(tcx),
+           rhs_expr.repr(tcx));
+
+    check_expr(fcx, lhs_expr);
+    let lhs_ty = fcx.resolve_type_vars_if_possible(fcx.expr_ty(lhs_expr));
+
+    // Annoyingly, SIMD ops don't fit into the PartialEq/PartialOrd
+    // traits, because their return type is not bool. Perhaps this
+    // should change, but for now if LHS is SIMD we go down a
+    // different path that bypassess all traits.
+    if ty::type_is_simd(fcx.tcx(), lhs_ty) {
+        check_expr_coercable_to_type(fcx, rhs_expr, lhs_ty);
+        let rhs_ty = fcx.resolve_type_vars_if_possible(fcx.expr_ty(lhs_expr));
+        let return_ty = enforce_builtin_binop_types(fcx, lhs_expr, lhs_ty, rhs_expr, rhs_ty, op);
+        fcx.write_ty(expr.id, return_ty);
+        return;
+    }
+
+    match BinOpCategory::from(op) {
+        BinOpCategory::Shortcircuit => {
+            // && and || are a simple case.
+            demand::suptype(fcx, lhs_expr.span, ty::mk_bool(tcx), lhs_ty);
+            check_expr_coercable_to_type(fcx, rhs_expr, ty::mk_bool(tcx));
+            fcx.write_ty(expr.id, ty::mk_bool(tcx));
+        }
+        _ => {
+            // Otherwise, we always treat operators as if they are
+            // overloaded. This is the way to be most flexible w/r/t
+            // types that get inferred.
+            let (rhs_ty, return_ty) =
+                check_overloaded_binop(fcx, expr, lhs_expr, lhs_ty, rhs_expr, op);
+
+            // Supply type inference hints if relevant. Probably these
+            // hints should be enforced during select as part of the
+            // `consider_unification_despite_ambiguity` routine, but this
+            // more convenient for now.
+            //
+            // The basic idea is to help type inference by taking
+            // advantage of things we know about how the impls for
+            // scalar types are arranged. This is important in a
+            // scenario like `1_u32 << 2`, because it lets us quickly
+            // deduce that the result type should be `u32`, even
+            // though we don't know yet what type 2 has and hence
+            // can't pin this down to a specific impl.
+            let rhs_ty = fcx.resolve_type_vars_if_possible(rhs_ty);
+            if
+                !ty::type_is_ty_var(lhs_ty) &&
+                !ty::type_is_ty_var(rhs_ty) &&
+                is_builtin_binop(fcx.tcx(), lhs_ty, rhs_ty, op)
+            {
+                let builtin_return_ty =
+                    enforce_builtin_binop_types(fcx, lhs_expr, lhs_ty, rhs_expr, rhs_ty, op);
+                demand::suptype(fcx, expr.span, builtin_return_ty, return_ty);
+            }
+
+            fcx.write_ty(expr.id, return_ty);
+        }
+    }
+}
+
+fn enforce_builtin_binop_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                                         lhs_expr: &'tcx ast::Expr,
+                                         lhs_ty: Ty<'tcx>,
+                                         rhs_expr: &'tcx ast::Expr,
+                                         rhs_ty: Ty<'tcx>,
+                                         op: ast::BinOp)
+                                         -> Ty<'tcx>
+{
+    debug_assert!(is_builtin_binop(fcx.tcx(), lhs_ty, rhs_ty, op));
+
+    let tcx = fcx.tcx();
+    match BinOpCategory::from(op) {
+        BinOpCategory::Shortcircuit => {
+            demand::suptype(fcx, lhs_expr.span, ty::mk_bool(tcx), lhs_ty);
+            demand::suptype(fcx, rhs_expr.span, ty::mk_bool(tcx), rhs_ty);
+            ty::mk_bool(tcx)
+        }
+
+        BinOpCategory::Shift => {
+            // For integers, the shift amount can be of any integral
+            // type. For simd, the type must match exactly.
+            if ty::type_is_simd(tcx, lhs_ty) {
+                demand::suptype(fcx, rhs_expr.span, lhs_ty, rhs_ty);
+            }
+
+            // result type is same as LHS always
+            lhs_ty
+        }
+
+        BinOpCategory::Math |
+        BinOpCategory::Bitwise => {
+            // both LHS and RHS and result will have the same type
+            demand::suptype(fcx, rhs_expr.span, lhs_ty, rhs_ty);
+            lhs_ty
+        }
+
+        BinOpCategory::Comparison => {
+            // both LHS and RHS and result will have the same type
+            demand::suptype(fcx, rhs_expr.span, lhs_ty, rhs_ty);
+
+            // if this is simd, result is same as lhs, else bool
+            if ty::type_is_simd(tcx, lhs_ty) {
+                let unit_ty = ty::simd_type(tcx, lhs_ty);
+                debug!("enforce_builtin_binop_types: lhs_ty={} unit_ty={}",
+                       lhs_ty.repr(tcx),
+                       unit_ty.repr(tcx));
+                if !ty::type_is_integral(unit_ty) {
+                    tcx.sess.span_err(
+                        lhs_expr.span,
+                        &format!("binary comparison operation `{}` not supported \
+                                  for floating point SIMD vector `{}`",
+                                 ast_util::binop_to_string(op.node),
+                                 lhs_ty.user_string(tcx)));
+                    tcx.types.err
+                } else {
+                    lhs_ty
+                }
+            } else {
+                ty::mk_bool(tcx)
+            }
+        }
+    }
+}
+
+fn check_overloaded_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                                    expr: &'tcx ast::Expr,
+                                    lhs_expr: &'tcx ast::Expr,
+                                    lhs_ty: Ty<'tcx>,
+                                    rhs_expr: &'tcx ast::Expr,
+                                    op: ast::BinOp)
+                                    -> (Ty<'tcx>, Ty<'tcx>)
+{
+    debug!("check_overloaded_binop(expr.id={}, lhs_ty={})",
+           expr.id,
+           lhs_ty.repr(fcx.tcx()));
+
+    let (name, trait_def_id) = name_and_trait_def_id(fcx, op);
+
+    // NB: As we have not yet type-checked the RHS, we don't have the
+    // type at hand. Make a variable to represent it. The whole reason
+    // for this indirection is so that, below, we can check the expr
+    // using this variable as the expected type, which sometimes lets
+    // us do better coercions than we would be able to do otherwise,
+    // particularly for things like `String + &String`.
+    let rhs_ty_var = fcx.infcx().next_ty_var();
+
+    let return_ty = match lookup_op_method(fcx, expr, lhs_ty, vec![rhs_ty_var],
+                                           token::intern(name), trait_def_id,
+                                           lhs_expr) {
+        Ok(return_ty) => return_ty,
+        Err(()) => {
+            // error types are considered "builtin"
+            if !ty::type_is_error(lhs_ty) {
+                span_err!(fcx.tcx().sess, lhs_expr.span, E0369,
+                          "binary operation `{}` cannot be applied to type `{}`",
+                          ast_util::binop_to_string(op.node),
+                          lhs_ty.user_string(fcx.tcx()));
+            }
+            fcx.tcx().types.err
+        }
+    };
+
+    // see `NB` above
+    check_expr_coercable_to_type(fcx, rhs_expr, rhs_ty_var);
+
+    (rhs_ty_var, return_ty)
+}
+
+pub fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                                 op_str: &str,
+                                 mname: &str,
+                                 trait_did: Option<ast::DefId>,
+                                 ex: &'tcx ast::Expr,
+                                 operand_expr: &'tcx ast::Expr,
+                                 operand_ty: Ty<'tcx>,
+                                 op: ast::UnOp)
+                                 -> Ty<'tcx>
+{
+    assert!(ast_util::is_by_value_unop(op));
+    match lookup_op_method(fcx, ex, operand_ty, vec![],
+                           token::intern(mname), trait_did,
+                           operand_expr) {
+        Ok(t) => t,
+        Err(()) => {
+            fcx.type_error_message(ex.span, |actual| {
+                format!("cannot apply unary operator `{}` to type `{}`",
+                        op_str, actual)
+            }, operand_ty, None);
+            fcx.tcx().types.err
+        }
+    }
+}
+
+fn name_and_trait_def_id(fcx: &FnCtxt, op: ast::BinOp) -> (&'static str, Option<ast::DefId>) {
+    let lang = &fcx.tcx().lang_items;
+    match op.node {
+        ast::BiAdd => ("add", lang.add_trait()),
+        ast::BiSub => ("sub", lang.sub_trait()),
+        ast::BiMul => ("mul", lang.mul_trait()),
+        ast::BiDiv => ("div", lang.div_trait()),
+        ast::BiRem => ("rem", lang.rem_trait()),
+        ast::BiBitXor => ("bitxor", lang.bitxor_trait()),
+        ast::BiBitAnd => ("bitand", lang.bitand_trait()),
+        ast::BiBitOr => ("bitor", lang.bitor_trait()),
+        ast::BiShl => ("shl", lang.shl_trait()),
+        ast::BiShr => ("shr", lang.shr_trait()),
+        ast::BiLt => ("lt", lang.ord_trait()),
+        ast::BiLe => ("le", lang.ord_trait()),
+        ast::BiGe => ("ge", lang.ord_trait()),
+        ast::BiGt => ("gt", lang.ord_trait()),
+        ast::BiEq => ("eq", lang.eq_trait()),
+        ast::BiNe => ("ne", lang.eq_trait()),
+        ast::BiAnd | ast::BiOr => {
+            fcx.tcx().sess.span_bug(op.span, "&& and || are not overloadable")
+        }
+    }
+}
+
+fn lookup_op_method<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
+                              expr: &'tcx ast::Expr,
+                              lhs_ty: Ty<'tcx>,
+                              other_tys: Vec<Ty<'tcx>>,
+                              opname: ast::Name,
+                              trait_did: Option<ast::DefId>,
+                              lhs_expr: &'a ast::Expr)
+                              -> Result<Ty<'tcx>,()>
+{
+    debug!("lookup_op_method(expr={}, lhs_ty={}, opname={:?}, trait_did={}, lhs_expr={})",
+           expr.repr(fcx.tcx()),
+           lhs_ty.repr(fcx.tcx()),
+           opname,
+           trait_did.repr(fcx.tcx()),
+           lhs_expr.repr(fcx.tcx()));
+
+    let method = match trait_did {
+        Some(trait_did) => {
+            // We do eager coercions to make using operators
+            // more ergonomic:
+            //
+            // - If the input is of type &'a T (resp. &'a mut T),
+            //   then reborrow it to &'b T (resp. &'b mut T) where
+            //   'b <= 'a.  This makes things like `x == y`, where
+            //   `x` and `y` are both region pointers, work.  We
+            //   could also solve this with variance or different
+            //   traits that don't force left and right to have same
+            //   type.
+            let (adj_ty, adjustment) = match lhs_ty.sty {
+                ty::ty_rptr(r_in, mt) => {
+                    let r_adj = fcx.infcx().next_region_var(infer::Autoref(lhs_expr.span));
+                    fcx.mk_subr(infer::Reborrow(lhs_expr.span), r_adj, *r_in);
+                    let adjusted_ty = ty::mk_rptr(fcx.tcx(), fcx.tcx().mk_region(r_adj), mt);
+                    let autoptr = ty::AutoPtr(r_adj, mt.mutbl, None);
+                    let adjustment = ty::AutoDerefRef { autoderefs: 1, autoref: Some(autoptr) };
+                    (adjusted_ty, adjustment)
+                }
+                _ => {
+                    (lhs_ty, ty::AutoDerefRef { autoderefs: 0, autoref: None })
+                }
+            };
+
+            debug!("adjusted_ty={} adjustment={:?}",
+                   adj_ty.repr(fcx.tcx()),
+                   adjustment);
+
+            method::lookup_in_trait_adjusted(fcx, expr.span, Some(lhs_expr), opname,
+                                             trait_did, adjustment, adj_ty, Some(other_tys))
+        }
+        None => None
+    };
+
+    match method {
+        Some(method) => {
+            let method_ty = method.ty;
+
+            // HACK(eddyb) Fully qualified path to work around a resolve bug.
+            let method_call = ::middle::ty::MethodCall::expr(expr.id);
+            fcx.inh.method_map.borrow_mut().insert(method_call, method);
+
+            // extract return type for method; all late bound regions
+            // should have been instantiated by now
+            let ret_ty = ty::ty_fn_ret(method_ty);
+            Ok(ty::no_late_bound_regions(fcx.tcx(), &ret_ty).unwrap().unwrap())
+        }
+        None => {
+            Err(())
+        }
+    }
+}
+
+// Binary operator categories. These categories summarize the behavior
+// with respect to the builtin operationrs supported.
+enum BinOpCategory {
+    /// &&, || -- cannot be overridden
+    Shortcircuit,
+
+    /// <<, >> -- when shifting a single integer, rhs can be any
+    /// integer type. For simd, types must match.
+    Shift,
+
+    /// +, -, etc -- takes equal types, produces same type as input,
+    /// applicable to ints/floats/simd
+    Math,
+
+    /// &, |, ^ -- takes equal types, produces same type as input,
+    /// applicable to ints/floats/simd/bool
+    Bitwise,
+
+    /// ==, !=, etc -- takes equal types, produces bools, except for simd,
+    /// which produce the input type
+    Comparison,
+}
+
+impl BinOpCategory {
+    fn from(op: ast::BinOp) -> BinOpCategory {
+        match op.node {
+            ast::BiShl | ast::BiShr =>
+                BinOpCategory::Shift,
+
+            ast::BiAdd |
+            ast::BiSub |
+            ast::BiMul |
+            ast::BiDiv |
+            ast::BiRem =>
+                BinOpCategory::Math,
+
+            ast::BiBitXor |
+            ast::BiBitAnd |
+            ast::BiBitOr =>
+                BinOpCategory::Bitwise,
+
+            ast::BiEq |
+            ast::BiNe |
+            ast::BiLt |
+            ast::BiLe |
+            ast::BiGe |
+            ast::BiGt =>
+                BinOpCategory::Comparison,
+
+            ast::BiAnd |
+            ast::BiOr =>
+                BinOpCategory::Shortcircuit,
+        }
+    }
+}
+
+/// Returns true if this is a built-in arithmetic operation (e.g. u32
+/// + u32, i16x4 == i16x4) and false if these types would have to be
+/// overloaded to be legal. There are two reasons that we distinguish
+/// builtin operations from overloaded ones (vs trying to drive
+/// everything uniformly through the trait system and intrinsics or
+/// something like that):
+///
+/// 1. Builtin operations can trivially be evaluated in constants.
+/// 2. For comparison operators applied to SIMD types the result is
+///    not of type `bool`. For example, `i16x4==i16x4` yields a
+///    type like `i16x4`. This means that the overloaded trait
+///    `PartialEq` is not applicable.
+///
+/// Reason #2 is the killer. I tried for a while to always use
+/// overloaded logic and just check the types in constants/trans after
+/// the fact, and it worked fine, except for SIMD types. -nmatsakis
+fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>,
+                          lhs: Ty<'tcx>,
+                          rhs: Ty<'tcx>,
+                          op: ast::BinOp)
+                          -> bool
+{
+    match BinOpCategory::from(op) {
+        BinOpCategory::Shortcircuit => {
+            true
+        }
+
+        BinOpCategory::Shift => {
+            ty::type_is_error(lhs) || ty::type_is_error(rhs) ||
+                ty::type_is_integral(lhs) && ty::type_is_integral(rhs) ||
+                ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs)
+        }
+
+        BinOpCategory::Math => {
+            ty::type_is_error(lhs) || ty::type_is_error(rhs) ||
+                ty::type_is_integral(lhs) && ty::type_is_integral(rhs) ||
+                ty::type_is_floating_point(lhs) && ty::type_is_floating_point(rhs) ||
+                ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs)
+        }
+
+        BinOpCategory::Bitwise => {
+            ty::type_is_error(lhs) || ty::type_is_error(rhs) ||
+                ty::type_is_integral(lhs) && ty::type_is_integral(rhs) ||
+                ty::type_is_floating_point(lhs) && ty::type_is_floating_point(rhs) ||
+                ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs) ||
+                ty::type_is_bool(lhs) && ty::type_is_bool(rhs)
+        }
+
+        BinOpCategory::Comparison => {
+            ty::type_is_error(lhs) || ty::type_is_error(rhs) ||
+                ty::type_is_scalar(lhs) && ty::type_is_scalar(rhs) ||
+                ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs)
+        }
+    }
+}
+
index 82abff8c425f42c5aca7d2aa62f73ac9c85a78de..9171367468026a8f9226b4537b22500f4ff51394 100644 (file)
@@ -87,12 +87,11 @@ use check::dropck;
 use check::FnCtxt;
 use check::implicator;
 use check::vtable;
-use middle::def;
 use middle::mem_categorization as mc;
 use middle::region::CodeExtent;
+use middle::subst::Substs;
 use middle::traits;
-use middle::ty::{ReScope};
-use middle::ty::{self, Ty, MethodCall};
+use middle::ty::{self, ClosureTyper, ReScope, Ty, MethodCall};
 use middle::infer::{self, GenericKind};
 use middle::pat_util;
 use util::ppaux::{ty_to_string, Repr};
@@ -179,21 +178,7 @@ pub struct Rcx<'a, 'tcx: 'a> {
 
 }
 
-/// Returns the validity region of `def` -- that is, how long is `def` valid?
-fn region_of_def(fcx: &FnCtxt, def: def::Def) -> ty::Region {
-    let tcx = fcx.tcx();
-    match def {
-        def::DefLocal(node_id) | def::DefUpvar(node_id, _) => {
-            tcx.region_maps.var_region(node_id)
-        }
-        _ => {
-            tcx.sess.bug(&format!("unexpected def in region_of_def: {:?}",
-                                 def)[])
-        }
-    }
-}
-
-struct RepeatingScope(ast::NodeId);
+pub struct RepeatingScope(ast::NodeId);
 pub enum SubjectNode { Subject(ast::NodeId), None }
 
 impl<'a, 'tcx> Rcx<'a, 'tcx> {
@@ -240,7 +225,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
     /// }
     /// ```
     ///
-    /// Here, the region of `b` will be `<R0>`.  `<R0>` is constrainted to be some subregion of the
+    /// Here, the region of `b` will be `<R0>`.  `<R0>` is constrained to be some subregion of the
     /// block B and some superregion of the call.  If we forced it now, we'd choose the smaller
     /// region (the call).  But that would make the *b illegal.  Since we don't resolve, the type
     /// of b will be `&<R0>.int` and then `*b` will require that `<R0>` be bigger than the let and
@@ -288,7 +273,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
             Some(f) => f,
             None => {
                 self.tcx().sess.bug(
-                    &format!("No fn-sig entry for id={}", id)[]);
+                    &format!("No fn-sig entry for id={}", id));
             }
         };
 
@@ -334,7 +319,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
     /// This method populates the region map's `free_region_map`. It walks over the transformed
     /// argument and return types for each function just before we check the body of that function,
     /// looking for types where you have a borrowed pointer to other borrowed data (e.g., `&'a &'b
-    /// [uint]`.  We do not allow references to outlive the things they point at, so we can assume
+    /// [usize]`.  We do not allow references to outlive the things they point at, so we can assume
     /// that `'a <= 'b`. This holds for both the argument and return types, basically because, on
     /// the caller side, the caller is responsible for checking that the type of every expression
     /// (including the actual values for the arguments, as well as the return type of the fn call)
@@ -368,7 +353,15 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
                                                              ty::ReInfer(ty::ReVar(vid_b))) => {
                         self.fcx.inh.infcx.add_given(free_a, vid_b);
                     }
-                    implicator::Implication::RegionSubRegion(..) => {
+                    implicator::Implication::RegionSubGeneric(_, r_a, ref generic_b) => {
+                        debug!("RegionSubGeneric: {} <= {}",
+                               r_a.repr(tcx), generic_b.repr(tcx));
+
+                        self.region_bound_pairs.push((r_a, generic_b.clone()));
+                    }
+                    implicator::Implication::RegionSubRegion(..) |
+                    implicator::Implication::RegionSubClosure(..) |
+                    implicator::Implication::Predicate(..) => {
                         // In principle, we could record (and take
                         // advantage of) every relationship here, but
                         // we are also free not to -- it simply means
@@ -379,13 +372,6 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
                         // relationship that arises here, but
                         // presently we do not.)
                     }
-                    implicator::Implication::RegionSubGeneric(_, r_a, ref generic_b) => {
-                        debug!("RegionSubGeneric: {} <= {}",
-                               r_a.repr(tcx), generic_b.repr(tcx));
-
-                        self.region_bound_pairs.push((r_a, generic_b.clone()));
-                    }
-                    implicator::Implication::Predicate(..) => { }
                 }
             }
         }
@@ -554,8 +540,12 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
                                                                expr.span);
             }
             Err(..) => {
-                rcx.fcx.tcx().sess.span_note(expr.span,
-                                             "cat_expr_unadjusted Errd during dtor check");
+                let tcx = rcx.fcx.tcx();
+                if tcx.sess.has_errors() {
+                    // cannot run dropck; okay b/c in error state anyway.
+                } else {
+                    tcx.sess.span_bug(expr.span, "cat_expr_unadjusted Errd");
+                }
             }
         }
     }
@@ -571,8 +561,12 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             check_safety_of_rvalue_destructor_if_necessary(rcx, head_cmt, expr.span);
         }
         Err(..) => {
-            rcx.fcx.tcx().sess.span_note(expr.span,
-                                         "cat_expr Errd during dtor check");
+            let tcx = rcx.fcx.tcx();
+            if tcx.sess.has_errors() {
+                // cannot run dropck; okay b/c in error state anyway.
+            } else {
+                tcx.sess.span_bug(expr.span, "cat_expr Errd");
+            }
         }
     }
 
@@ -784,124 +778,9 @@ fn constrain_cast(rcx: &mut Rcx,
 fn check_expr_fn_block(rcx: &mut Rcx,
                        expr: &ast::Expr,
                        body: &ast::Block) {
-    let tcx = rcx.fcx.tcx();
-    let function_type = rcx.resolve_node_type(expr.id);
-
-    match function_type.sty {
-        ty::ty_closure(_, region, _) => {
-            ty::with_freevars(tcx, expr.id, |freevars| {
-                constrain_captured_variables(rcx, *region, expr, freevars);
-            })
-        }
-        _ => { }
-    }
-
     let repeating_scope = rcx.set_repeating_scope(body.id);
     visit::walk_expr(rcx, expr);
     rcx.set_repeating_scope(repeating_scope);
-
-    match function_type.sty {
-        ty::ty_closure(_, region, _) => {
-            ty::with_freevars(tcx, expr.id, |freevars| {
-                let bounds = ty::region_existential_bound(*region);
-                ensure_free_variable_types_outlive_closure_bound(rcx, &bounds, expr, freevars);
-            })
-        }
-        _ => {}
-    }
-
-    /// Make sure that the type of all free variables referenced inside a closure/proc outlive the
-    /// closure/proc's lifetime bound. This is just a special case of the usual rules about closed
-    /// over values outliving the object's lifetime bound.
-    fn ensure_free_variable_types_outlive_closure_bound(
-        rcx: &mut Rcx,
-        bounds: &ty::ExistentialBounds,
-        expr: &ast::Expr,
-        freevars: &[ty::Freevar])
-    {
-        let tcx = rcx.fcx.ccx.tcx;
-
-        debug!("ensure_free_variable_types_outlive_closure_bound({}, {})",
-               bounds.region_bound.repr(tcx), expr.repr(tcx));
-
-        for freevar in freevars {
-            let var_node_id = {
-                let def_id = freevar.def.def_id();
-                assert!(def_id.krate == ast::LOCAL_CRATE);
-                def_id.node
-            };
-
-            // Compute the type of the field in the environment that
-            // represents `var_node_id`.  For a by-value closure, this
-            // will be the same as the type of the variable.  For a
-            // by-reference closure, this will be `&T` where `T` is
-            // the type of the variable.
-            let raw_var_ty = rcx.resolve_node_type(var_node_id);
-            let upvar_id = ty::UpvarId { var_id: var_node_id,
-                                         closure_expr_id: expr.id };
-            let var_ty = match rcx.fcx.inh.upvar_capture_map.borrow()[upvar_id] {
-                ty::UpvarCapture::ByRef(ref upvar_borrow) => {
-                    ty::mk_rptr(rcx.tcx(),
-                                rcx.tcx().mk_region(upvar_borrow.region),
-                                ty::mt { mutbl: upvar_borrow.kind.to_mutbl_lossy(),
-                                         ty: raw_var_ty })
-                }
-                ty::UpvarCapture::ByValue => raw_var_ty,
-            };
-
-            // Check that the type meets the criteria of the existential bounds:
-            for builtin_bound in &bounds.builtin_bounds {
-                let code = traits::ClosureCapture(var_node_id, expr.span, builtin_bound);
-                let cause = traits::ObligationCause::new(freevar.span, rcx.fcx.body_id, code);
-                rcx.fcx.register_builtin_bound(var_ty, builtin_bound, cause);
-            }
-
-            type_must_outlive(
-                rcx, infer::FreeVariable(expr.span, var_node_id),
-                var_ty, bounds.region_bound);
-        }
-    }
-
-    /// Make sure that all free variables referenced inside the closure outlive the closure's
-    /// lifetime bound. Also, create an entry in the upvar_borrows map with a region.
-    fn constrain_captured_variables(
-        rcx: &mut Rcx,
-        region_bound: ty::Region,
-        expr: &ast::Expr,
-        freevars: &[ty::Freevar])
-    {
-        let tcx = rcx.fcx.ccx.tcx;
-        debug!("constrain_captured_variables({}, {})",
-               region_bound.repr(tcx), expr.repr(tcx));
-        for freevar in freevars {
-            debug!("constrain_captured_variables: freevar.def={:?}", freevar.def);
-
-            // Identify the variable being closed over and its node-id.
-            let def = freevar.def;
-            let var_node_id = {
-                let def_id = def.def_id();
-                assert!(def_id.krate == ast::LOCAL_CRATE);
-                def_id.node
-            };
-            let upvar_id = ty::UpvarId { var_id: var_node_id,
-                                         closure_expr_id: expr.id };
-
-            match rcx.fcx.inh.upvar_capture_map.borrow()[upvar_id] {
-                ty::UpvarCapture::ByValue => { }
-                ty::UpvarCapture::ByRef(upvar_borrow) => {
-                    rcx.fcx.mk_subr(infer::FreeVariable(freevar.span, var_node_id),
-                                    region_bound, upvar_borrow.region);
-
-                    // Guarantee that the closure does not outlive the variable itself.
-                    let enclosing_region = region_of_def(rcx.fcx, def);
-                    debug!("constrain_captured_variables: enclosing_region = {}",
-                           enclosing_region.repr(tcx));
-                    rcx.fcx.mk_subr(infer::FreeVariable(freevar.span, var_node_id),
-                                    region_bound, enclosing_region);
-                }
-            }
-        }
-    }
 }
 
 fn constrain_callee(rcx: &mut Rcx,
@@ -983,7 +862,7 @@ fn constrain_call<'a, I: Iterator<Item=&'a ast::Expr>>(rcx: &mut Rcx,
 /// dereferenced, the lifetime of the pointer includes the deref expr.
 fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
                                   deref_expr: &ast::Expr,
-                                  derefs: uint,
+                                  derefs: usize,
                                   mut derefd_ty: Ty<'tcx>)
 {
     debug!("constrain_autoderefs(deref_expr={}, derefs={}, derefd_ty={})",
@@ -1013,7 +892,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
                         rcx.tcx().sess.span_bug(
                             deref_expr.span,
                             &format!("bad overloaded deref type {}",
-                                     method.ty.repr(rcx.tcx()))[])
+                                     method.ty.repr(rcx.tcx())))
                     }
                 };
 
@@ -1084,9 +963,9 @@ fn check_safety_of_rvalue_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 't
                     rcx.tcx()
                        .sess
                        .span_bug(span,
-                                 format!("unexpected rvalue region in rvalue \
-                                          destructor safety checking: `{}`",
-                                         region.repr(rcx.tcx())).as_slice());
+                                 &format!("unexpected rvalue region in rvalue \
+                                           destructor safety checking: `{}`",
+                                          region.repr(rcx.tcx())));
                 }
             }
         }
@@ -1239,7 +1118,7 @@ fn link_pattern<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
 /// autoref'd.
 fn link_autoref(rcx: &Rcx,
                 expr: &ast::Expr,
-                autoderefs: uint,
+                autoderefs: usize,
                 autoref: &ty::AutoRef) {
 
     debug!("link_autoref(autoref={:?})", autoref);
@@ -1417,7 +1296,7 @@ fn link_reborrowed_region<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
                     rcx.tcx().sess.span_bug(
                         span,
                         &format!("Illegal upvar id: {}",
-                                upvar_id.repr(rcx.tcx()))[]);
+                                upvar_id.repr(rcx.tcx())));
                 }
             }
         }
@@ -1530,6 +1409,9 @@ pub fn type_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
                 let o1 = infer::ReferenceOutlivesReferent(ty, origin.span());
                 generic_must_outlive(rcx, o1, r_a, generic_b);
             }
+            implicator::Implication::RegionSubClosure(_, r_a, def_id, substs) => {
+                closure_must_outlive(rcx, origin.clone(), r_a, def_id, substs);
+            }
             implicator::Implication::Predicate(def_id, predicate) => {
                 let cause = traits::ObligationCause::new(origin.span(),
                                                          rcx.body_id,
@@ -1541,6 +1423,23 @@ pub fn type_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
     }
 }
 
+fn closure_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
+                                  origin: infer::SubregionOrigin<'tcx>,
+                                  region: ty::Region,
+                                  def_id: ast::DefId,
+                                  substs: &'tcx Substs<'tcx>) {
+    debug!("closure_must_outlive(region={}, def_id={}, substs={})",
+           region.repr(rcx.tcx()), def_id.repr(rcx.tcx()), substs.repr(rcx.tcx()));
+
+    let upvars = rcx.fcx.closure_upvars(def_id, substs).unwrap();
+    for upvar in upvars {
+        let var_id = upvar.def.def_id().local_id();
+        type_must_outlive(
+            rcx, infer::FreeVariable(origin.span(), var_id),
+            upvar.ty, region);
+    }
+}
+
 fn generic_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
                                   origin: infer::SubregionOrigin<'tcx>,
                                   region: ty::Region,
@@ -1562,7 +1461,7 @@ fn generic_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
         GenericKind::Param(..) => { }
         GenericKind::Projection(ref projection_ty) => {
             param_bounds.push_all(
-                &projection_bounds(rcx, origin.span(), projection_ty)[]);
+                &projection_bounds(rcx, origin.span(), projection_ty));
         }
     }
 
@@ -1643,7 +1542,7 @@ fn projection_bounds<'a,'tcx>(rcx: &Rcx<'a, 'tcx>,
             debug!("projection_bounds: outlives={} (2)",
                    outlives.repr(tcx));
 
-            let region_result = infcx.try(|_| {
+            let region_result = infcx.commit_if_ok(|_| {
                 let (outlives, _) =
                     infcx.replace_late_bound_regions_with_fresh_var(
                         span,
index f452c8488ce1c7eb2fe900db03205d06889460ac..340cca7d47e7a395619bb5ae60ce9d1724e800a6 100644 (file)
@@ -294,7 +294,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
 
     /// Indicates that `cmt` is being directly mutated (e.g., assigned
     /// to). If cmt contains any by-ref upvars, this implies that
-    /// those upvars must be borrowed using an `&mut` borow.
+    /// those upvars must be borrowed using an `&mut` borrow.
     fn adjust_upvar_borrow_kind_for_mut(&mut self, cmt: mc::cmt<'tcx>) {
         debug!("adjust_upvar_borrow_kind_for_mut(cmt={})",
                cmt.repr(self.tcx()));
@@ -380,7 +380,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
                 // borrow_kind of the upvar to make sure it
                 // is inferred to mutable if necessary
                 let mut upvar_capture_map = self.fcx.inh.upvar_capture_map.borrow_mut();
-                let ub = &mut upvar_capture_map[upvar_id];
+                let ub = upvar_capture_map.get_mut(&upvar_id).unwrap();
                 self.adjust_upvar_borrow_kind(upvar_id, ub, borrow_kind);
 
                 // also need to be in an FnMut closure since this is not an ImmBorrow
@@ -448,7 +448,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
 
         let closure_def_id = ast_util::local_def(closure_id);
         let mut closure_kinds = self.fcx.inh.closure_kinds.borrow_mut();
-        let existing_kind = closure_kinds[closure_def_id];
+        let existing_kind = *closure_kinds.get(&closure_def_id).unwrap();
 
         debug!("adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}",
                closure_id, existing_kind, new_kind);
@@ -556,5 +556,3 @@ impl<'a,'tcx> euv::Delegate<'tcx> for AdjustBorrowKind<'a,'tcx> {
         self.adjust_upvar_borrow_kind_for_mut(assignee_cmt);
     }
 }
-
-
index 3666b69d1c678ac4cc6a64d60118b794f4bdf449..63c34b65d77841ec2018aa68d55880f9c24f70b9 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use check::{FnCtxt};
-use check::demand;
+use check::FnCtxt;
 use middle::traits::{self, ObjectSafetyViolation, MethodViolationCode};
 use middle::traits::{Obligation, ObligationCause};
 use middle::traits::report_fulfillment_errors;
@@ -19,83 +18,6 @@ use syntax::codemap::Span;
 use util::nodemap::FnvHashSet;
 use util::ppaux::{Repr, UserString};
 
-pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                   cast_expr: &ast::Expr,
-                                   source_expr: &ast::Expr,
-                                   target_object_ty: Ty<'tcx>)
-{
-    let tcx = fcx.tcx();
-    debug!("check_object_cast(cast_expr={}, target_object_ty={})",
-           cast_expr.repr(tcx),
-           target_object_ty.repr(tcx));
-
-    // Look up vtables for the type we're casting to,
-    // passing in the source and target type.  The source
-    // must be a pointer type suitable to the object sigil,
-    // e.g.: `&x as &Trait` or `box x as Box<Trait>`
-
-    // First, construct a fresh type that we can feed into `<expr>`
-    // within `<expr> as <type>` to inform type inference (e.g. to
-    // tell it that we are expecting a `Box<_>` or an `&_`).
-    let fresh_ty = fcx.infcx().next_ty_var();
-    let (object_trait_ty, source_expected_ty) = match target_object_ty.sty {
-        ty::ty_uniq(object_trait_ty) => {
-            (object_trait_ty, ty::mk_uniq(fcx.tcx(), fresh_ty))
-        }
-        ty::ty_rptr(target_region, ty::mt { ty: object_trait_ty,
-                                            mutbl: target_mutbl }) => {
-            (object_trait_ty,
-             ty::mk_rptr(fcx.tcx(),
-                         target_region, ty::mt { ty: fresh_ty,
-                                                 mutbl: target_mutbl }))
-        }
-        _ => {
-            fcx.tcx().sess.span_bug(source_expr.span, "expected object type");
-        }
-    };
-
-    let source_ty = fcx.expr_ty(source_expr);
-    debug!("check_object_cast pre unify source_ty={}", source_ty.repr(tcx));
-
-    // This ensures that the source_ty <: source_expected_ty, which
-    // will ensure e.g. that &'a T <: &'b T when doing `&'a T as &'b Trait`
-    //
-    // FIXME (pnkfelix): do we need to use suptype_with_fn in order to
-    // override the error message emitted when the types do not work
-    // out in the manner desired?
-    demand::suptype(fcx, source_expr.span, source_expected_ty, source_ty);
-
-    debug!("check_object_cast postunify source_ty={}", source_ty.repr(tcx));
-
-    let object_trait = object_trait(&object_trait_ty);
-
-    // Ensure that if Ptr<T> is cast to Ptr<Trait>, then T : Trait.
-    push_cast_obligation(fcx, cast_expr, object_trait, fresh_ty);
-    check_object_safety(tcx, object_trait, source_expr.span);
-
-    fn object_trait<'a, 'tcx>(t: &'a Ty<'tcx>) -> &'a ty::TyTrait<'tcx> {
-        match t.sty {
-            ty::ty_trait(ref ty_trait) => &**ty_trait,
-            _ => panic!("expected ty_trait")
-        }
-    }
-
-    fn push_cast_obligation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                      cast_expr: &ast::Expr,
-                                      object_trait: &ty::TyTrait<'tcx>,
-                                      referent_ty: Ty<'tcx>) {
-        let object_trait_ref =
-            register_object_cast_obligations(fcx,
-                                             cast_expr.span,
-                                             object_trait,
-                                             referent_ty);
-
-        // Finally record the object_trait_ref for use during trans
-        // (it would prob be better not to do this, but it's just kind
-        // of a pain to have to reconstruct it).
-        fcx.write_object_cast(cast_expr.id, object_trait_ref);
-    }
-}
 
 // Check that a trait is 'object-safe'. This should be checked whenever a trait object
 // is created (by casting or coercion, etc.). A trait is object-safe if all its
@@ -106,18 +28,17 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
                                  object_trait: &ty::TyTrait<'tcx>,
                                  span: Span)
 {
-    let object_trait_ref =
-        object_trait.principal_trait_ref_with_self_ty(tcx, tcx.types.err);
+    let trait_def_id = object_trait.principal_def_id();
 
-    if traits::is_object_safe(tcx, object_trait_ref.clone()) {
+    if traits::is_object_safe(tcx, trait_def_id) {
         return;
     }
 
     span_err!(tcx.sess, span, E0038,
               "cannot convert to a trait object because trait `{}` is not object-safe",
-              ty::item_path_str(tcx, object_trait_ref.def_id()));
+              ty::item_path_str(tcx, trait_def_id));
 
-    let violations = traits::object_safety_violations(tcx, object_trait_ref.clone());
+    let violations = traits::object_safety_violations(tcx, trait_def_id);
     for violation in violations {
         match violation {
             ObjectSafetyViolation::SizedSelf => {
@@ -133,14 +54,6 @@ pub fn check_object_safety<'tcx>(tcx: &ty::ctxt<'tcx>,
                      in the supertrait listing");
             }
 
-            ObjectSafetyViolation::Method(method, MethodViolationCode::ByValueSelf) => {
-                tcx.sess.span_note(
-                    span,
-                    &format!("method `{}` has a receiver type of `Self`, \
-                              which cannot be used with a trait object",
-                             method.name.user_string(tcx)));
-            }
-
             ObjectSafetyViolation::Method(method, MethodViolationCode::StaticMethod) => {
                 tcx.sess.span_note(
                     span,
@@ -310,4 +223,3 @@ pub fn select_new_fcx_obligations(fcx: &FnCtxt) {
         Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); }
     }
 }
-
index 2601c4d275291d144762ff46ac1484aee3e3b5eb..a86e2b17c93b839775dc3f13457033c5a215d283 100644 (file)
@@ -22,8 +22,7 @@ use util::ppaux::{Repr, UserString};
 
 use std::collections::HashSet;
 use syntax::ast;
-use syntax::ast_util::{local_def};
-use syntax::attr;
+use syntax::ast_util::local_def;
 use syntax::codemap::Span;
 use syntax::parse::token::{self, special_idents};
 use syntax::visit;
@@ -81,14 +80,17 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
             ast::ItemImpl(_, ast::ImplPolarity::Positive, _, _, _, _) => {
                 self.check_impl(item);
             }
-            ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(ref tref), _, _) => {
-                let trait_ref = ty::node_id_to_trait_ref(ccx.tcx, tref.ref_id);
+            ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(_), _, _) => {
+                let trait_ref = ty::impl_id_to_trait_ref(ccx.tcx, item.id);
+                ty::populate_implementations_for_trait_if_necessary(ccx.tcx, trait_ref.def_id);
                 match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
                     Some(ty::BoundSend) | Some(ty::BoundSync) => {}
                     Some(_) | None => {
-                        span_err!(ccx.tcx.sess, item.span, E0192,
-                            "negative impls are currently \
-                                     allowed just for `Send` and `Sync`")
+                        if !ty::trait_has_default_impl(ccx.tcx, trait_ref.def_id) {
+                            span_err!(ccx.tcx.sess, item.span, E0192,
+                                      "negative impls are only allowed for traits with \
+                                       default impls (e.g., `Send` and `Sync`)")
+                        }
                     }
                 }
             }
@@ -115,7 +117,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
 
                 self.check_variances_for_type_defn(item, ast_generics);
             }
-            ast::ItemTrait(_, ref ast_generics, _, _) => {
+            ast::ItemTrait(_, ref ast_generics, _, ref items) => {
                 let trait_predicates =
                     ty::lookup_predicates(ccx.tcx, local_def(item.id));
                 reject_non_type_param_bounds(
@@ -124,6 +126,14 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
                     &trait_predicates);
                 self.check_variances(item, ast_generics, &trait_predicates,
                                      self.tcx().lang_items.phantom_fn());
+                if ty::trait_has_default_impl(ccx.tcx, local_def(item.id)) {
+                    if !items.is_empty() {
+                        ccx.tcx.sess.span_err(
+                            item.span,
+                            "traits with default impls (`e.g. unsafe impl Trait for ..`) must \
+                            have no methods or associated items")
+                    }
+                }
             }
             _ => {}
         }
@@ -239,27 +249,6 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
                                                         &fcx.inh.param_env.free_substs,
                                                         &trait_ref);
 
-            // There are special rules that apply to drop.
-            if
-                fcx.tcx().lang_items.drop_trait() == Some(trait_ref.def_id) &&
-                !attr::contains_name(&item.attrs, "unsafe_destructor")
-            {
-                match self_ty.sty {
-                    ty::ty_struct(def_id, _) |
-                    ty::ty_enum(def_id, _) => {
-                        check_struct_safe_for_destructor(fcx, item.span, def_id);
-                    }
-                    _ => {
-                        // Coherence already reports an error in this case.
-                    }
-                }
-            }
-
-            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
@@ -278,12 +267,13 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
 
             // Find the supertrait bounds. This will add `int:Bar`.
             let poly_trait_ref = ty::Binder(trait_ref);
-            let predicates = ty::predicates_for_trait_ref(fcx.tcx(), &poly_trait_ref);
+            let predicates = ty::lookup_super_predicates(fcx.tcx(), poly_trait_ref.def_id());
+            let predicates = predicates.instantiate_supertrait(fcx.tcx(), &poly_trait_ref);
             let predicates = {
                 let selcx = &mut traits::SelectionContext::new(fcx.infcx(), fcx);
                 traits::normalize(selcx, cause.clone(), &predicates)
             };
-            for predicate in predicates.value {
+            for predicate in predicates.value.predicates {
                 fcx.register_predicate(traits::Obligation::new(cause.clone(), predicate));
             }
             for obligation in predicates.obligations {
@@ -393,15 +383,15 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
         self.tcx().sess.span_err(
             span,
             &format!("parameter `{}` is never used",
-                     param_name.user_string(self.tcx()))[]);
+                     param_name.user_string(self.tcx())));
 
         match suggested_marker_id {
             Some(def_id) => {
-                self.tcx().sess.span_help(
+                self.tcx().sess.fileline_help(
                     span,
-                    format!("consider removing `{}` or using a marker such as `{}`",
-                            param_name.user_string(self.tcx()),
-                            ty::item_path_str(self.tcx(), def_id)).as_slice());
+                    &format!("consider removing `{}` or using a marker such as `{}`",
+                             param_name.user_string(self.tcx()),
+                             ty::item_path_str(self.tcx(), def_id)));
             }
             None => {
                 // no lang items, no help!
@@ -486,28 +476,24 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
         visit::walk_fn(self, fk, fd, b, span)
     }
 
-    fn visit_trait_item(&mut self, t: &'v ast::TraitItem) {
-        match t {
-            &ast::TraitItem::ProvidedMethod(_) |
-            &ast::TraitItem::TypeTraitItem(_) => {},
-            &ast::TraitItem::RequiredMethod(ref method) => {
-                match ty::impl_or_trait_item(self.tcx(), local_def(method.id)) {
-                    ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
-                        reject_non_type_param_bounds(
-                            self.tcx(),
-                            method.span,
-                            &ty_method.predicates);
-                        reject_shadowing_type_parameters(
-                            self.tcx(),
-                            method.span,
-                            &ty_method.generics);
-                    }
-                    _ => {}
+    fn visit_trait_item(&mut self, trait_item: &'v ast::TraitItem) {
+        if let ast::MethodTraitItem(_, None) = trait_item.node {
+            match ty::impl_or_trait_item(self.tcx(), local_def(trait_item.id)) {
+                ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
+                    reject_non_type_param_bounds(
+                        self.tcx(),
+                        trait_item.span,
+                        &ty_method.predicates);
+                    reject_shadowing_type_parameters(
+                        self.tcx(),
+                        trait_item.span,
+                        &ty_method.generics);
                 }
+                _ => {}
             }
         }
 
-        visit::walk_trait_item(self, t)
+        visit::walk_trait_item(self, trait_item)
     }
 }
 
@@ -520,7 +506,7 @@ pub struct BoundsChecker<'cx,'tcx:'cx> {
     // has left it as a NodeId rather than porting to CodeExtent.
     scope: ast::NodeId,
 
-    binding_count: uint,
+    binding_count: usize,
     cache: Option<&'cx mut HashSet<Ty<'tcx>>>,
 }
 
@@ -753,22 +739,3 @@ fn filter_to_trait_obligations<'tcx>(bounds: ty::InstantiatedPredicates<'tcx>)
     }
     result
 }
-
-///////////////////////////////////////////////////////////////////////////
-// Special drop trait checking
-
-fn check_struct_safe_for_destructor<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                              span: Span,
-                                              struct_did: ast::DefId) {
-    let struct_tpt = ty::lookup_item_type(fcx.tcx(), struct_did);
-    if struct_tpt.generics.has_type_params(subst::TypeSpace)
-        || struct_tpt.generics.has_region_params(subst::TypeSpace)
-    {
-        span_err!(fcx.tcx().sess, span, E0141,
-                  "cannot implement a destructor on a structure \
-                   with type parameters");
-        span_note!(fcx.tcx().sess, span,
-                   "use \"#[unsafe_destructor]\" on the implementation \
-                    to force the compiler to allow this");
-    }
-}
index fca40df7aaa6af71a3a032d8bbbbbaf125d0c6e2..37f43252483aae2fe2ffbad0d43f2f045613ade1 100644 (file)
@@ -26,6 +26,7 @@ use util::ppaux::Repr;
 use std::cell::Cell;
 
 use syntax::ast;
+use syntax::ast_util;
 use syntax::codemap::{DUMMY_SP, Span};
 use syntax::print::pprust::pat_to_string;
 use syntax::visit;
@@ -113,6 +114,31 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> {
             return;
         }
 
+        // Hacky hack: During type-checking, we treat *all* operators
+        // as potentially overloaded. But then, during writeback, if
+        // we observe that something like `a+b` is (known to be)
+        // operating on scalars, we clear the overload.
+        match e.node {
+            ast::ExprBinary(ref op, ref lhs, ref rhs) => {
+                let lhs_ty = self.fcx.expr_ty(lhs);
+                let lhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&lhs_ty);
+                let rhs_ty = self.fcx.expr_ty(rhs);
+                let rhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&rhs_ty);
+                if ty::type_is_scalar(lhs_ty) && ty::type_is_scalar(rhs_ty) {
+                    self.fcx.inh.method_map.borrow_mut().remove(&MethodCall::expr(e.id));
+
+                    // weird but true: the by-ref binops put an
+                    // adjustment on the lhs but not the rhs; the
+                    // adjustment for rhs is kind of baked into the
+                    // system.
+                    if !ast_util::is_by_value_binop(op.node) {
+                        self.fcx.inh.adjustments.borrow_mut().remove(&lhs.id);
+                    }
+                }
+            }
+            _ => { }
+        }
+
         self.visit_node_id(ResolvingExpr(e.span), e.id);
         self.visit_method_map_entry(ResolvingExpr(e.span),
                                     MethodCall::expr(e.id));
@@ -169,7 +195,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> {
         match t.node {
             ast::TyFixedLengthVec(ref ty, ref count_expr) => {
                 self.visit_ty(&**ty);
-                write_ty_to_tcx(self.tcx(), count_expr.id, self.tcx().types.uint);
+                write_ty_to_tcx(self.tcx(), count_expr.id, self.tcx().types.usize);
             }
             _ => visit::walk_ty(self, t)
         }
@@ -265,6 +291,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                         ty::AdjustReifyFnPointer(def_id)
                     }
 
+                    ty::AdjustUnsafeFnPointer => {
+                        ty::AdjustUnsafeFnPointer
+                    }
+
                     ty::AdjustDerefRef(adj) => {
                         for autoderef in 0..adj.autoderefs {
                             let method_call = MethodCall::autoderef(id, autoderef);
@@ -320,7 +350,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
 ///////////////////////////////////////////////////////////////////////////
 // Resolution reason.
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum ResolveReason {
     ResolvingExpr(Span),
     ResolvingLocal(Span),
diff --git a/src/librustc_typeck/coherence/impls.rs b/src/librustc_typeck/coherence/impls.rs
deleted file mode 100644 (file)
index e535b86..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2015 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.
-
-//! Implementations checker: builtin traits and default impls are allowed just
-//! for structs and enums.
-
-use middle::ty;
-use syntax::ast::{Item, ItemImpl};
-use syntax::ast;
-use syntax::visit;
-
-pub fn check(tcx: &ty::ctxt) {
-    let mut impls = ImplsChecker { tcx: tcx };
-    visit::walk_crate(&mut impls, tcx.map.krate());
-}
-
-struct ImplsChecker<'cx, 'tcx:'cx> {
-    tcx: &'cx ty::ctxt<'tcx>
-}
-
-impl<'cx, 'tcx,'v> visit::Visitor<'v> for ImplsChecker<'cx, 'tcx> {
-    fn visit_item(&mut self, item: &'v ast::Item) {
-        match item.node {
-            ast::ItemImpl(_, _, _, Some(ref opt_trait), _, _) => {
-                let trait_ref = ty::node_id_to_trait_ref(self.tcx, opt_trait.ref_id);
-                if let Some(_) = self.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
-                    match trait_ref.self_ty().sty {
-                        ty::ty_struct(..) | ty::ty_enum(..) => {}
-                        _ => {
-                            span_err!(self.tcx.sess, item.span, E0209,
-                                "builtin traits can only be \
-                                          implemented on structs or enums");
-                        }
-                    }
-                }
-            }
-            _ => {}
-        }
-    }
-}
index 1542e74ff81672769a7fc68b8397bfe4f523b409..51d0c18872dc4213b9756cb3585bb5d7a8bc34cd 100644 (file)
@@ -25,15 +25,14 @@ use middle::ty::{ParameterEnvironment, TypeTraitItemId, lookup_item_type};
 use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err};
 use middle::ty::{ty_param, TypeScheme, 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_str, ty_vec, ty_float, ty_infer, ty_int};
 use middle::ty::{ty_uint, ty_closure, ty_uniq, ty_bare_fn};
-use middle::ty::{ty_projection};
+use middle::ty::ty_projection;
 use middle::ty;
 use CrateCtxt;
-use middle::infer::combine::Combine;
 use middle::infer::InferCtxt;
-use middle::infer::{new_infer_ctxt};
-use std::collections::{HashSet};
+use middle::infer::new_infer_ctxt;
+use std::collections::HashSet;
 use std::cell::RefCell;
 use std::rc::Rc;
 use syntax::ast::{Crate, DefId};
@@ -42,14 +41,13 @@ use syntax::ast::{LOCAL_CRATE, TraitRef};
 use syntax::ast;
 use syntax::ast_map::NodeItem;
 use syntax::ast_map;
-use syntax::ast_util::{local_def};
-use syntax::codemap::{Span};
+use syntax::ast_util::local_def;
+use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::visit;
 use util::nodemap::{DefIdMap, FnvHashMap};
 use util::ppaux::Repr;
 
-mod impls;
 mod orphan;
 mod overlap;
 mod unsafety;
@@ -75,7 +73,7 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
 
         ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) |
         ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_tup(..) |
-        ty_param(..) | ty_err | ty_open(..) |
+        ty_param(..) | ty_err |
         ty_ptr(_) | ty_rptr(_, _) | ty_projection(..) => {
             None
         }
@@ -86,7 +84,7 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
             inference_context.tcx.sess.span_bug(
                 span,
                 &format!("coherence encountered unexpected type searching for base type: {}",
-                        ty.repr(inference_context.tcx))[]);
+                        ty.repr(inference_context.tcx)));
         }
     }
 }
@@ -106,19 +104,9 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> {
 
         //debug!("(checking coherence) item '{}'", token::get_ident(item.ident));
 
-        match item.node {
-            ItemImpl(_, _, _, ref opt_trait, _, _) => {
-                match opt_trait.clone() {
-                    Some(opt_trait) => {
-                        self.cc.check_implementation(item, &[opt_trait]);
-                    }
-                    None => self.cc.check_implementation(item, &[])
-                }
-            }
-            _ => {
-                // Nothing to do.
-            }
-        };
+        if let ItemImpl(_, _, _, ref opt_trait, _, _) = item.node {
+            self.cc.check_implementation(item, opt_trait.as_ref())
+        }
 
         visit::walk_item(self, item);
     }
@@ -155,9 +143,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
         self.check_implementations_of_copy();
     }
 
-    fn check_implementation(&self,
-                            item: &Item,
-                            associated_traits: &[TraitRef]) {
+    fn check_implementation(&self, item: &Item, opt_trait: Option<&TraitRef>) {
         let tcx = self.crate_context.tcx;
         let impl_did = local_def(item.id);
         let self_type = ty::lookup_item_type(tcx, impl_did);
@@ -167,9 +153,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
 
         let impl_items = self.create_impl_from_item(item);
 
-        for associated_trait in associated_traits {
-            let trait_ref = ty::node_id_to_trait_ref(self.crate_context.tcx,
-                                                     associated_trait.ref_id);
+        if opt_trait.is_some() {
+            let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx, item.id);
             debug!("(checking implementation) adding impl for trait '{}', item '{}'",
                    trait_ref.repr(self.crate_context.tcx),
                    token::get_ident(item.ident));
@@ -191,7 +176,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
             }
             Some(base_type_def_id) => {
                 // FIXME: Gather up default methods?
-                if associated_traits.len() == 0 {
+                if opt_trait.is_none() {
                     self.add_inherent_impl(base_type_def_id, impl_did);
                 }
             }
@@ -283,34 +268,35 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
 
     fn get_self_type_for_implementation(&self, impl_did: DefId)
                                         -> TypeScheme<'tcx> {
-        self.crate_context.tcx.tcache.borrow()[impl_did].clone()
+        self.crate_context.tcx.tcache.borrow().get(&impl_did).unwrap().clone()
     }
 
     // Converts an implementation in the AST to a vector of items.
     fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
         match item.node {
-            ItemImpl(_, _, _, ref trait_refs, _, ref ast_items) => {
+            ItemImpl(_, _, _, ref opt_trait, _, ref impl_items) => {
                 let mut items: Vec<ImplOrTraitItemId> =
-                        ast_items.iter()
-                                 .map(|ast_item| {
-                            match *ast_item {
-                                ast::MethodImplItem(ref ast_method) => {
-                                    MethodTraitItemId(
-                                        local_def(ast_method.id))
-                                }
-                                ast::TypeImplItem(ref typedef) => {
-                                    TypeTraitItemId(local_def(typedef.id))
-                                }
-                            }
-                        }).collect();
+                        impl_items.iter().map(|impl_item| {
+                    match impl_item.node {
+                        ast::MethodImplItem(..) => {
+                            MethodTraitItemId(local_def(impl_item.id))
+                        }
+                        ast::TypeImplItem(_) => {
+                            TypeTraitItemId(local_def(impl_item.id))
+                        }
+                        ast::MacImplItem(_) => {
+                            self.crate_context.tcx.sess.span_bug(impl_item.span,
+                                                                 "unexpanded macro");
+                        }
+                    }
+                }).collect();
 
-                if let Some(ref trait_ref) = *trait_refs {
-                    let ty_trait_ref = ty::node_id_to_trait_ref(
-                        self.crate_context.tcx,
-                        trait_ref.ref_id);
+                if opt_trait.is_some() {
+                    let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx,
+                                                             item.id);
 
                     self.instantiate_default_methods(local_def(item.id),
-                                                     &*ty_trait_ref,
+                                                     &*trait_ref,
                                                      &mut items);
                 }
 
@@ -400,7 +386,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
         };
 
         for &impl_did in &*trait_impls.borrow() {
-            let items = &(*impl_items)[impl_did];
+            let items = impl_items.get(&impl_did).unwrap();
             if items.len() < 1 {
                 // We'll error out later. For now, just don't ICE.
                 continue;
@@ -411,7 +397,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
             match self_type.ty.sty {
                 ty::ty_enum(type_def_id, _) |
                 ty::ty_struct(type_def_id, _) |
-                ty::ty_closure(type_def_id, _, _) => {
+                ty::ty_closure(type_def_id, _) => {
                     tcx.destructor_for_type
                        .borrow_mut()
                        .insert(type_def_id, method_def_id.def_id());
@@ -538,7 +524,7 @@ fn enforce_trait_manually_implementable(tcx: &ty::ctxt, sp: Span, trait_def_id:
         return // everything OK
     };
     span_err!(tcx.sess, sp, E0183, "manual implementations of `{}` are experimental", trait_name);
-    span_help!(tcx.sess, sp,
+    fileline_help!(tcx.sess, sp,
                "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
 }
 
@@ -597,7 +583,6 @@ pub fn check_coherence(crate_context: &CrateCtxt) {
         inference_context: new_infer_ctxt(crate_context.tcx),
         inherent_impls: RefCell::new(FnvHashMap()),
     }.check(crate_context.tcx.map.krate());
-    impls::check(crate_context.tcx);
     unsafety::check(crate_context.tcx);
     orphan::check(crate_context.tcx);
     overlap::check(crate_context.tcx);
index f43469363cd81f435c03b018bac9cf8d606fd8a7..b450e6b398a6a00d8ef1dd716c198559f829f8a2 100644 (file)
@@ -30,18 +30,38 @@ struct OrphanChecker<'cx, 'tcx:'cx> {
 }
 
 impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
-    fn check_def_id(&self, span: Span, def_id: ast::DefId) {
+    fn check_def_id(&self, item: &ast::Item, def_id: ast::DefId) {
         if def_id.krate != ast::LOCAL_CRATE {
-            span_err!(self.tcx.sess, span, E0116,
+            span_err!(self.tcx.sess, item.span, E0116,
                       "cannot associate methods with a type outside the \
                        crate the type is defined in; define and implement \
                        a trait or new type instead");
         }
     }
-}
 
-impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
-    fn visit_item(&mut self, item: &'v ast::Item) {
+    fn check_primitive_impl(&self,
+                            impl_def_id: ast::DefId,
+                            lang_def_id: Option<ast::DefId>,
+                            lang: &str,
+                            ty: &str,
+                            span: Span) {
+        match lang_def_id {
+            Some(lang_def_id) if lang_def_id == impl_def_id => { /* OK */ },
+            _ => {
+                self.tcx.sess.span_err(
+                    span,
+                    &format!("only a single inherent implementation marked with `#[lang = \"{}\"]` \
+                              is allowed for the `{}` primitive", lang, ty));
+            }
+        }
+    }
+
+    /// Checks exactly one impl for orphan rules and other such
+    /// restrictions.  In this fn, it can happen that multiple errors
+    /// apply to a specific impl, so just return after reporting one
+    /// to prevent inundating the user with a bunch of similar error
+    /// reports.
+    fn check_item(&self, item: &ast::Item) {
         let def_id = ast_util::local_def(item.id);
         match item.node {
             ast::ItemImpl(_, _, _, None, _, _) => {
@@ -52,55 +72,278 @@ impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
                 match self_ty.sty {
                     ty::ty_enum(def_id, _) |
                     ty::ty_struct(def_id, _) => {
-                        self.check_def_id(item.span, def_id);
+                        self.check_def_id(item, def_id);
                     }
                     ty::ty_trait(ref data) => {
-                        self.check_def_id(item.span, data.principal_def_id());
+                        self.check_def_id(item, data.principal_def_id());
                     }
                     ty::ty_uniq(..) => {
-                        self.check_def_id(item.span,
-                                          self.tcx.lang_items.owned_box()
-                                              .unwrap());
+                        self.check_def_id(item, self.tcx.lang_items.owned_box().unwrap());
+                    }
+                    ty::ty_char => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.char_impl(),
+                                                  "char",
+                                                  "char",
+                                                  item.span);
+                    }
+                    ty::ty_str => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.str_impl(),
+                                                  "str",
+                                                  "str",
+                                                  item.span);
+                    }
+                    ty::ty_vec(_, None) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.slice_impl(),
+                                                  "slice",
+                                                  "[T]",
+                                                  item.span);
+                    }
+                    ty::ty_ptr(ty::mt { ty: _, mutbl: ast::MutImmutable }) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.const_ptr_impl(),
+                                                  "const_ptr",
+                                                  "*const T",
+                                                  item.span);
+                    }
+                    ty::ty_ptr(ty::mt { ty: _, mutbl: ast::MutMutable }) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.mut_ptr_impl(),
+                                                  "mut_ptr",
+                                                  "*mut T",
+                                                  item.span);
+                    }
+                    ty::ty_int(ast::TyI8) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.i8_impl(),
+                                                  "i8",
+                                                  "i8",
+                                                  item.span);
+                    }
+                    ty::ty_int(ast::TyI16) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.i16_impl(),
+                                                  "i16",
+                                                  "i16",
+                                                  item.span);
+                    }
+                    ty::ty_int(ast::TyI32) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.i32_impl(),
+                                                  "i32",
+                                                  "i32",
+                                                  item.span);
+                    }
+                    ty::ty_int(ast::TyI64) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.i64_impl(),
+                                                  "i64",
+                                                  "i64",
+                                                  item.span);
+                    }
+                    ty::ty_int(ast::TyIs) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.isize_impl(),
+                                                  "isize",
+                                                  "isize",
+                                                  item.span);
+                    }
+                    ty::ty_uint(ast::TyU8) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.u8_impl(),
+                                                  "u8",
+                                                  "u8",
+                                                  item.span);
+                    }
+                    ty::ty_uint(ast::TyU16) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.u16_impl(),
+                                                  "u16",
+                                                  "u16",
+                                                  item.span);
+                    }
+                    ty::ty_uint(ast::TyU32) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.u32_impl(),
+                                                  "u32",
+                                                  "u32",
+                                                  item.span);
+                    }
+                    ty::ty_uint(ast::TyU64) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.u64_impl(),
+                                                  "u64",
+                                                  "u64",
+                                                  item.span);
+                    }
+                    ty::ty_uint(ast::TyUs) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.usize_impl(),
+                                                  "usize",
+                                                  "usize",
+                                                  item.span);
+                    }
+                    ty::ty_float(ast::TyF32) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.f32_impl(),
+                                                  "f32",
+                                                  "f32",
+                                                  item.span);
+                    }
+                    ty::ty_float(ast::TyF64) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.f64_impl(),
+                                                  "f64",
+                                                  "f64",
+                                                  item.span);
                     }
                     _ => {
                         span_err!(self.tcx.sess, item.span, E0118,
                                   "no base type found for inherent implementation; \
                                    implement a trait or new type instead");
+                        return;
                     }
                 }
             }
             ast::ItemImpl(_, _, _, Some(_), _, _) => {
                 // "Trait" impl
                 debug!("coherence2::orphan check: trait impl {}", item.repr(self.tcx));
-                let trait_def_id = ty::impl_trait_ref(self.tcx, def_id).unwrap().def_id;
+                let trait_ref = ty::impl_trait_ref(self.tcx, def_id).unwrap();
+                let trait_def_id = trait_ref.def_id;
                 match traits::orphan_check(self.tcx, def_id) {
                     Ok(()) => { }
                     Err(traits::OrphanCheckErr::NoLocalInputType) => {
-                        if !ty::has_attr(self.tcx, trait_def_id, "old_orphan_check") {
-                            span_err!(
-                                self.tcx.sess, item.span, E0117,
-                                "the impl does not reference any \
-                                 types defined in this crate; \
-                                 only traits defined in the current crate can be \
-                                 implemented for arbitrary types");
-                        }
+                        span_err!(
+                            self.tcx.sess, item.span, E0117,
+                            "the impl does not reference any \
+                             types defined in this crate; \
+                             only traits defined in the current crate can be \
+                             implemented for arbitrary types");
+                        return;
                     }
                     Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
-                        if !ty::has_attr(self.tcx, trait_def_id, "old_orphan_check") {
-                            span_err!(self.tcx.sess, item.span, E0210,
-                                    "type parameter `{}` must be used as the type parameter for \
-                                     some local type (e.g. `MyStruct<T>`); only traits defined in \
-                                     the current crate can be implemented for a type parameter",
-                                    param_ty.user_string(self.tcx));
+                        span_err!(self.tcx.sess, item.span, E0210,
+                                "type parameter `{}` must be used as the type parameter for \
+                                 some local type (e.g. `MyStruct<T>`); only traits defined in \
+                                 the current crate can be implemented for a type parameter",
+                                param_ty.user_string(self.tcx));
+                        return;
+                    }
+                }
+
+                // In addition to the above rules, we restrict impls of defaulted traits
+                // so that they can only be implemented on structs/enums. To see why this
+                // restriction exists, consider the following example (#22978). Imagine
+                // that crate A defines a defaulted trait `Foo` and a fn that operates
+                // on pairs of types:
+                //
+                // ```
+                // // Crate A
+                // trait Foo { }
+                // impl Foo for .. { }
+                // fn two_foos<A:Foo,B:Foo>(..) {
+                //     one_foo::<(A,B)>(..)
+                // }
+                // fn one_foo<T:Foo>(..) { .. }
+                // ```
+                //
+                // This type-checks fine; in particular the fn
+                // `two_foos` is able to conclude that `(A,B):Foo`
+                // because `A:Foo` and `B:Foo`.
+                //
+                // Now imagine that crate B comes along and does the following:
+                //
+                // ```
+                // struct A { }
+                // struct B { }
+                // impl Foo for A { }
+                // impl Foo for B { }
+                // impl !Send for (A, B) { }
+                // ```
+                //
+                // This final impl is legal according to the orpan
+                // rules, but it invalidates the reasoning from
+                // `two_foos` above.
+                debug!("trait_ref={} trait_def_id={} trait_has_default_impl={}",
+                       trait_ref.repr(self.tcx),
+                       trait_def_id.repr(self.tcx),
+                       ty::trait_has_default_impl(self.tcx, trait_def_id));
+                if
+                    ty::trait_has_default_impl(self.tcx, trait_def_id) &&
+                    trait_def_id.krate != ast::LOCAL_CRATE
+                {
+                    let self_ty = trait_ref.self_ty();
+                    let opt_self_def_id = match self_ty.sty {
+                        ty::ty_struct(self_def_id, _) | ty::ty_enum(self_def_id, _) =>
+                            Some(self_def_id),
+                        ty::ty_uniq(..) =>
+                            self.tcx.lang_items.owned_box(),
+                        _ =>
+                            None
+                    };
+
+                    let msg = match opt_self_def_id {
+                        // We only want to permit structs/enums, but not *all* structs/enums.
+                        // They must be local to the current crate, so that people
+                        // can't do `unsafe impl Send for Rc<SomethingLocal>` or
+                        // `impl !Send for Box<SomethingLocalAndSend>`.
+                        Some(self_def_id) => {
+                            if self_def_id.krate == ast::LOCAL_CRATE {
+                                None
+                            } else {
+                                Some(format!(
+                                    "cross-crate traits with a default impl, like `{}`, \
+                                     can only be implemented for a struct/enum type \
+                                     defined in the current crate",
+                                    ty::item_path_str(self.tcx, trait_def_id)))
+                            }
+                        }
+                        _ => {
+                            Some(format!(
+                                "cross-crate traits with a default impl, like `{}`, \
+                                 can only be implemented for a struct/enum type, \
+                                 not `{}`",
+                                ty::item_path_str(self.tcx, trait_def_id),
+                                self_ty.user_string(self.tcx)))
                         }
+                    };
+
+                    if let Some(msg) = msg {
+                        span_err!(self.tcx.sess, item.span, E0321, "{}", msg);
+                        return;
                     }
                 }
+
+                // Disallow *all* explicit impls of `Sized` for now.
+                if Some(trait_def_id) == self.tcx.lang_items.sized_trait() {
+                    span_err!(self.tcx.sess, item.span, E0322,
+                              "explicit impls for the `Sized` trait are not permitted");
+                    return;
+                }
+            }
+            ast::ItemDefaultImpl(..) => {
+                // "Trait" impl
+                debug!("coherence2::orphan check: default trait impl {}", item.repr(self.tcx));
+                let trait_ref = ty::impl_trait_ref(self.tcx, def_id).unwrap();
+                if trait_ref.def_id.krate != ast::LOCAL_CRATE {
+                    span_err!(self.tcx.sess, item.span, E0318,
+                              "cannot create default implementations for traits outside the \
+                               crate they're defined in; define a new trait instead");
+                    return;
+                }
             }
             _ => {
                 // Not an impl
             }
         }
+    }
+}
 
+impl<'cx, 'tcx,'v> visit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
+    fn visit_item(&mut self, item: &ast::Item) {
+        self.check_item(item);
         visit::walk_item(self, item);
     }
 }
index 403dcf1e25abaa52b4cefba4b6086aa2c413135a..f8ca51b9e496aa164a127c88252f111084ad1156 100644 (file)
 use middle::traits;
 use middle::ty;
 use middle::infer::{self, new_infer_ctxt};
-use syntax::ast::{DefId};
-use syntax::ast::{LOCAL_CRATE};
+use syntax::ast::DefId;
+use syntax::ast::LOCAL_CRATE;
 use syntax::ast;
-use syntax::codemap::{Span};
+use syntax::ast_util;
+use syntax::visit;
+use syntax::codemap::Span;
+use util::nodemap::DefIdMap;
 use util::ppaux::Repr;
 
 pub fn check(tcx: &ty::ctxt) {
-    let overlap = OverlapChecker { tcx: tcx };
+    let mut overlap = OverlapChecker { tcx: tcx, default_impls: DefIdMap() };
     overlap.check_for_overlapping_impls();
+
+    // this secondary walk specifically checks for impls of defaulted
+    // traits, for which additional overlap rules exist
+    visit::walk_crate(&mut overlap, tcx.map.krate());
 }
 
 struct OverlapChecker<'cx, 'tcx:'cx> {
-    tcx: &'cx ty::ctxt<'tcx>
+    tcx: &'cx ty::ctxt<'tcx>,
+
+    // maps from a trait def-id to an impl id
+    default_impls: DefIdMap<ast::NodeId>,
 }
 
 impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
@@ -90,17 +100,28 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
             return;
         }
 
-        span_err!(self.tcx.sess, self.span_of_impl(impl1_def_id), E0119,
+        self.report_overlap_error(trait_def_id, impl1_def_id, impl2_def_id);
+    }
+
+    fn report_overlap_error(&self, trait_def_id: ast::DefId,
+                            impl1: ast::DefId, impl2: ast::DefId) {
+
+        span_err!(self.tcx.sess, self.span_of_impl(impl1), E0119,
                   "conflicting implementations for trait `{}`",
                   ty::item_path_str(self.tcx, trait_def_id));
 
-        if impl2_def_id.krate == ast::LOCAL_CRATE {
-            span_note!(self.tcx.sess, self.span_of_impl(impl2_def_id),
+        self.report_overlap_note(impl1, impl2);
+    }
+
+    fn report_overlap_note(&self, impl1: ast::DefId, impl2: ast::DefId) {
+
+        if impl2.krate == ast::LOCAL_CRATE {
+            span_note!(self.tcx.sess, self.span_of_impl(impl2),
                        "note conflicting implementation here");
         } else {
             let crate_store = &self.tcx.sess.cstore;
-            let cdata = crate_store.get_crate_data(impl2_def_id.krate);
-            span_note!(self.tcx.sess, self.span_of_impl(impl1_def_id),
+            let cdata = crate_store.get_crate_data(impl2.krate);
+            span_note!(self.tcx.sess, self.span_of_impl(impl1),
                        "conflicting implementation in crate `{}`",
                        cdata.name);
         }
@@ -111,3 +132,28 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
         self.tcx.map.span(impl_did.node)
     }
 }
+
+
+impl<'cx, 'tcx,'v> visit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
+    fn visit_item(&mut self, item: &'v ast::Item) {
+        match item.node {
+            ast::ItemDefaultImpl(_, _) => {
+                // look for another default impl; note that due to the
+                // general orphan/coherence rules, it must always be
+                // in this crate.
+                let impl_def_id = ast_util::local_def(item.id);
+                let trait_ref = ty::impl_trait_ref(self.tcx, impl_def_id).unwrap();
+                let prev_default_impl = self.default_impls.insert(trait_ref.def_id, item.id);
+                match prev_default_impl {
+                    Some(prev_id) => {
+                        self.report_overlap_error(trait_ref.def_id,
+                                                  impl_def_id,
+                                                  ast_util::local_def(prev_id));
+                    }
+                    None => { }
+                }
+            }
+            _ => {}
+        }
+    }
+}
index 867dea9588568b515c68d7f699b258505e9da37c..e4926b119d5dbe551808b3e8bb2db99d0afd7d12 100644 (file)
@@ -27,55 +27,66 @@ struct UnsafetyChecker<'cx, 'tcx:'cx> {
     tcx: &'cx ty::ctxt<'tcx>
 }
 
-impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
-    fn visit_item(&mut self, item: &'v ast::Item) {
-        match item.node {
-            ast::ItemImpl(unsafety, polarity, _, _, _, _) => {
-                match ty::impl_trait_ref(self.tcx, ast_util::local_def(item.id)) {
-                    None => {
-                        // Inherent impl.
-                        match unsafety {
-                            ast::Unsafety::Normal => { /* OK */ }
-                            ast::Unsafety::Unsafe => {
-                                span_err!(self.tcx.sess, item.span, E0197,
-                                    "inherent impls cannot be declared as unsafe");
-                            }
-                        }
+impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
+    fn check_unsafety_coherence(&mut self, item: &'v ast::Item,
+                                unsafety: ast::Unsafety,
+                                polarity: ast::ImplPolarity) {
+        match ty::impl_trait_ref(self.tcx, ast_util::local_def(item.id)) {
+            None => {
+                // Inherent impl.
+                match unsafety {
+                    ast::Unsafety::Normal => { /* OK */ }
+                    ast::Unsafety::Unsafe => {
+                        span_err!(self.tcx.sess, item.span, E0197,
+                                  "inherent impls cannot be declared as unsafe");
                     }
+                }
+            }
 
-                    Some(trait_ref) => {
-                        let trait_def = ty::lookup_trait_def(self.tcx, trait_ref.def_id);
-                        match (trait_def.unsafety, unsafety, polarity) {
-                            (ast::Unsafety::Unsafe,
-                             ast::Unsafety::Unsafe, ast::ImplPolarity::Negative) => {
-                                span_err!(self.tcx.sess, item.span, E0198,
-                                    "negative implementations are not unsafe");
-                            }
+            Some(trait_ref) => {
+                let trait_def = ty::lookup_trait_def(self.tcx, trait_ref.def_id);
+                match (trait_def.unsafety, unsafety, polarity) {
+                    (ast::Unsafety::Unsafe,
+                     ast::Unsafety::Unsafe, ast::ImplPolarity::Negative) => {
+                        span_err!(self.tcx.sess, item.span, E0198,
+                                  "negative implementations are not unsafe");
+                    }
 
-                            (ast::Unsafety::Normal, ast::Unsafety::Unsafe, _) => {
-                                span_err!(self.tcx.sess, item.span, E0199,
-                                    "implementing the trait `{}` is not unsafe",
-                                            trait_ref.user_string(self.tcx));
-                            }
+                    (ast::Unsafety::Normal, ast::Unsafety::Unsafe, _) => {
+                        span_err!(self.tcx.sess, item.span, E0199,
+                                  "implementing the trait `{}` is not unsafe",
+                                  trait_ref.user_string(self.tcx));
+                    }
 
-                            (ast::Unsafety::Unsafe,
-                             ast::Unsafety::Normal, ast::ImplPolarity::Positive) => {
-                                span_err!(self.tcx.sess, item.span, E0200,
-                                    "the trait `{}` requires an `unsafe impl` declaration",
-                                            trait_ref.user_string(self.tcx));
-                            }
+                    (ast::Unsafety::Unsafe,
+                     ast::Unsafety::Normal, ast::ImplPolarity::Positive) => {
+                        span_err!(self.tcx.sess, item.span, E0200,
+                                  "the trait `{}` requires an `unsafe impl` declaration",
+                                  trait_ref.user_string(self.tcx));
+                    }
 
-                            (ast::Unsafety::Unsafe,
-                             ast::Unsafety::Normal, ast::ImplPolarity::Negative) |
-                            (ast::Unsafety::Unsafe,
-                             ast::Unsafety::Unsafe, ast::ImplPolarity::Positive) |
-                            (ast::Unsafety::Normal, ast::Unsafety::Normal, _) => {
-                                /* OK */
-                            }
-                        }
+                    (ast::Unsafety::Unsafe,
+                     ast::Unsafety::Normal, ast::ImplPolarity::Negative) |
+                    (ast::Unsafety::Unsafe,
+                     ast::Unsafety::Unsafe, ast::ImplPolarity::Positive) |
+                    (ast::Unsafety::Normal, ast::Unsafety::Normal, _) => {
+                        /* OK */
                     }
                 }
             }
+        }
+    }
+}
+
+impl<'cx, 'tcx,'v> visit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
+    fn visit_item(&mut self, item: &'v ast::Item) {
+        match item.node {
+            ast::ItemDefaultImpl(unsafety, _) => {
+                self.check_unsafety_coherence(item, unsafety, ast::ImplPolarity::Positive);
+            }
+            ast::ItemImpl(unsafety, polarity, _, _, _, _) => {
+                self.check_unsafety_coherence(item, unsafety, polarity);
+            }
             _ => { }
         }
 
index 0b78af18e2617b2869bba2d8431488275e11f620..8f1b8bf109215d6caa2825ce2dc7eac907ef89ed 100644 (file)
@@ -26,35 +26,17 @@ represented by an instance of `ty::TypeScheme`.  This combines the
 core type along with a list of the bounds for each parameter. Type
 parameters themselves are represented as `ty_param()` instances.
 
-The phasing of type conversion is somewhat complicated. There are a
-number of possible cycles that can arise.
-
-Converting types can require:
-
-1. `Foo<X>` where `Foo` is a type alias, or trait requires knowing:
-   - number of region / type parameters
-   - for type parameters, `T:'a` annotations to control defaults for object lifetimes
-   - defaults for type parameters (which are themselves types!)
-2. `Foo<X>` where `Foo` is a type alias requires knowing what `Foo` expands to
-3. Translating `SomeTrait` with no explicit lifetime bound requires knowing
-   - supertraits of `SomeTrait`
-4. Translating `T::X` (vs `<T as Trait>::X`) requires knowing
-   - bounds on `T`
-   - supertraits of those bounds
-
-So as you can see, in general translating types requires knowing the
-trait hierarchy. But this gets a bit tricky because translating the
-trait hierarchy requires converting the types that appear in trait
-references. One potential saving grace is that in general knowing the
-trait hierarchy is only necessary for shorthands like `T::X` or
-handling omitted lifetime bounds on object types. Therefore, if we are
-lazy about expanding out the trait hierachy, users can sever cycles if
-necessary. Lazy expansion is also needed for type aliases.
-
-This system is not perfect yet. Currently, we "convert" types and
-traits in three phases (note that conversion only affects the types of
-items / enum variants / methods; it does not e.g. compute the types of
-individual expressions):
+The phasing of type conversion is somewhat complicated. There is no
+clear set of phases we can enforce (e.g., converting traits first,
+then types, or something like that) because the user can introduce
+arbitrary interdependencies. So instead we generally convert things
+lazilly and on demand, and include logic that checks for cycles.
+Demand is driven by calls to `AstConv::get_item_type_scheme` or
+`AstConv::lookup_trait_def`.
+
+Currently, we "convert" types and traits in three phases (note that
+conversion only affects the types of items / enum variants / methods;
+it does not e.g. compute the types of individual expressions):
 
 0. Intrinsics
 1. Trait definitions
@@ -64,16 +46,13 @@ Conversion itself is done by simply walking each of the items in turn
 and invoking an appropriate function (e.g., `trait_def_of_item` or
 `convert_item`). However, it is possible that while converting an
 item, we may need to compute the *type scheme* or *trait definition*
-for other items. This is a kind of shallow conversion that is
-triggered on demand by calls to `AstConv::get_item_type_scheme` or
-`AstConv::lookup_trait_def`. It is possible for cycles to result from
-this (e.g., `type A = B; type B = A;`), in which case astconv
-(currently) reports the error.
+for other items.
 
 There are some shortcomings in this design:
 
-- Cycles through trait definitions (e.g. supertraits) are not currently
-  detected by astconv. (#12511)
+- Before walking the set of supertraits for a given trait, you must
+  call `ensure_super_predicates` on that trait def-id. Otherwise,
+  `lookup_super_predicates` will result in ICEs.
 - Because the type scheme includes defaults, cycles through type
   parameter defaults are illegal even if those defaults are never
   employed. This is not necessarily a bug.
@@ -91,28 +70,28 @@ use constrained_type_params::identify_constrained_type_params;
 use middle::lang_items::SizedTraitLangItem;
 use middle::region;
 use middle::resolve_lifetime;
-use middle::subst;
-use middle::subst::{Substs, SelfSpace, TypeSpace, VecPerParamSpace};
+use middle::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
 use middle::ty::{AsPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
-use middle::ty::{self, RegionEscape, Ty, TypeScheme};
+use middle::ty::{self, RegionEscape, ToPolyTraitRef, Ty, TypeScheme};
 use middle::ty_fold::{self, TypeFolder, TypeFoldable};
 use middle::infer;
 use rscope::*;
-use util::common::memoized;
+use util::common::{ErrorReported, memoized};
 use util::nodemap::{FnvHashMap, FnvHashSet};
 use util::ppaux;
 use util::ppaux::{Repr,UserString};
 use write_ty_to_tcx;
 
+use std::cell::RefCell;
 use std::collections::HashSet;
 use std::rc::Rc;
 
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{local_def, PostExpansionMethod};
+use syntax::ast_util::local_def;
 use syntax::codemap::Span;
-use syntax::parse::token::{special_idents};
+use syntax::parse::token::special_idents;
 use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::visit;
@@ -121,16 +100,7 @@ use syntax::visit;
 // Main entry point
 
 pub fn collect_item_types(tcx: &ty::ctxt) {
-    let ccx = &CollectCtxt { tcx: tcx };
-
-    match ccx.tcx.lang_items.ty_desc() {
-        Some(id) => { collect_intrinsic_type(ccx, id); }
-        None => {}
-    }
-    match ccx.tcx.lang_items.opaque() {
-        Some(id) => { collect_intrinsic_type(ccx, id); }
-        None => {}
-    }
+    let ccx = &CrateCtxt { tcx: tcx, stack: RefCell::new(Vec::new()) };
 
     let mut visitor = CollectTraitDefVisitor{ ccx: ccx };
     visit::walk_crate(&mut visitor, ccx.tcx.map.krate());
@@ -141,18 +111,36 @@ pub fn collect_item_types(tcx: &ty::ctxt) {
 
 ///////////////////////////////////////////////////////////////////////////
 
-struct CollectCtxt<'a,'tcx:'a> {
+struct CrateCtxt<'a,'tcx:'a> {
     tcx: &'a ty::ctxt<'tcx>,
+
+    // This stack is used to identify cycles in the user's source.
+    // Note that these cycles can cross multiple items.
+    stack: RefCell<Vec<AstConvRequest>>,
 }
 
-///////////////////////////////////////////////////////////////////////////
-// Zeroth phase: collect types of intrinsics
+/// Context specific to some particular item. This is what implements
+/// AstConv. It has information about the predicates that are defined
+/// on the trait. Unfortunately, this predicate information is
+/// available in various different forms at various points in the
+/// process. So we can't just store a pointer to e.g. the AST or the
+/// parsed ty form, we have to be more flexible. To this end, the
+/// `ItemCtxt` is parameterized by a `GetTypeParameterBounds` object
+/// that it uses to satisfy `get_type_parameter_bounds` requests.
+/// This object might draw the information from the AST
+/// (`ast::Generics`) or it might draw from a `ty::GenericPredicates`
+/// or both (a tuple).
+struct ItemCtxt<'a,'tcx:'a> {
+    ccx: &'a CrateCtxt<'a,'tcx>,
+    param_bounds: &'a (GetTypeParameterBounds<'tcx>+'a),
+}
 
-fn collect_intrinsic_type(ccx: &CollectCtxt,
-                          lang_item: ast::DefId) {
-    let ty::TypeScheme { ty, .. } =
-        ccx.get_item_type_scheme(lang_item);
-    ccx.tcx.intrinsic_defs.borrow_mut().insert(lang_item, ty);
+#[derive(Copy, Clone, PartialEq, Eq)]
+enum AstConvRequest {
+    GetItemTypeScheme(ast::DefId),
+    GetTraitDef(ast::DefId),
+    EnsureSuperPredicates(ast::DefId),
+    GetTypeParameterBounds(ast::NodeId),
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -161,7 +149,7 @@ fn collect_intrinsic_type(ccx: &CollectCtxt,
 // know later when parsing field defs.
 
 struct CollectTraitDefVisitor<'a, 'tcx: 'a> {
-    ccx: &'a CollectCtxt<'a, 'tcx>
+    ccx: &'a CrateCtxt<'a, 'tcx>
 }
 
 impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectTraitDefVisitor<'a, 'tcx> {
@@ -182,7 +170,7 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectTraitDefVisitor<'a, 'tcx> {
 // Second phase: collection proper.
 
 struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
-    ccx: &'a CollectCtxt<'a, 'tcx>
+    ccx: &'a CrateCtxt<'a, 'tcx>
 }
 
 impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
@@ -199,42 +187,223 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
 ///////////////////////////////////////////////////////////////////////////
 // Utility types and common code for the above passes.
 
-pub trait ToTy<'tcx> {
-    fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &ast::Ty) -> Ty<'tcx>;
-}
+impl<'a,'tcx> CrateCtxt<'a,'tcx> {
+    fn icx(&'a self, param_bounds: &'a GetTypeParameterBounds<'tcx>) -> ItemCtxt<'a,'tcx> {
+        ItemCtxt { ccx: self, param_bounds: param_bounds }
+    }
 
-impl<'a,'tcx> ToTy<'tcx> for CollectCtxt<'a,'tcx> {
-    fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &ast::Ty) -> Ty<'tcx> {
-        ast_ty_to_ty(self, rs, ast_ty)
+    fn method_ty(&self, method_id: ast::NodeId) -> Rc<ty::Method<'tcx>> {
+        let def_id = local_def(method_id);
+        match *self.tcx.impl_or_trait_items.borrow().get(&def_id).unwrap() {
+            ty::MethodTraitItem(ref mty) => mty.clone(),
+            ty::TypeTraitItem(..) => {
+                self.tcx.sess.bug(&format!("method with id {} has the wrong type", method_id));
+            }
+        }
     }
-}
 
-impl<'a, 'tcx> AstConv<'tcx> for CollectCtxt<'a, 'tcx> {
-    fn tcx(&self) -> &ty::ctxt<'tcx> { self.tcx }
+    fn cycle_check<F,R>(&self,
+                        span: Span,
+                        request: AstConvRequest,
+                        code: F)
+                        -> Result<R,ErrorReported>
+        where F: FnOnce() -> Result<R,ErrorReported>
+    {
+        {
+            let mut stack = self.stack.borrow_mut();
+            match stack.iter().enumerate().rev().find(|&(_, r)| *r == request) {
+                None => { }
+                Some((i, _)) => {
+                    let cycle = &stack[i..];
+                    self.report_cycle(span, cycle);
+                    return Err(ErrorReported);
+                }
+            }
+            stack.push(request);
+        }
 
-    fn get_item_type_scheme(&self, id: ast::DefId) -> ty::TypeScheme<'tcx> {
-        if id.krate != ast::LOCAL_CRATE {
-            return ty::lookup_item_type(self.tcx, id);
+        let result = code();
+
+        self.stack.borrow_mut().pop();
+        result
+    }
+
+    fn report_cycle(&self,
+                    span: Span,
+                    cycle: &[AstConvRequest])
+    {
+        assert!(!cycle.is_empty());
+        let tcx = self.tcx;
+
+        tcx.sess.span_err(
+            span,
+            &format!("unsupported cyclic reference between types/traits detected"));
+
+        match cycle[0] {
+            AstConvRequest::GetItemTypeScheme(def_id) |
+            AstConvRequest::GetTraitDef(def_id) => {
+                tcx.sess.note(
+                    &format!("the cycle begins when processing `{}`...",
+                             ty::item_path_str(tcx, def_id)));
+            }
+            AstConvRequest::EnsureSuperPredicates(def_id) => {
+                tcx.sess.note(
+                    &format!("the cycle begins when computing the supertraits of `{}`...",
+                             ty::item_path_str(tcx, def_id)));
+            }
+            AstConvRequest::GetTypeParameterBounds(id) => {
+                let def = tcx.type_parameter_def(id);
+                tcx.sess.note(
+                    &format!("the cycle begins when computing the bounds \
+                              for type parameter `{}`...",
+                             def.name.user_string(tcx)));
+            }
+        }
+
+        for request in cycle[1..].iter() {
+            match *request {
+                AstConvRequest::GetItemTypeScheme(def_id) |
+                AstConvRequest::GetTraitDef(def_id) => {
+                    tcx.sess.note(
+                        &format!("...which then requires processing `{}`...",
+                                 ty::item_path_str(tcx, def_id)));
+                }
+                AstConvRequest::EnsureSuperPredicates(def_id) => {
+                    tcx.sess.note(
+                        &format!("...which then requires computing the supertraits of `{}`...",
+                                 ty::item_path_str(tcx, def_id)));
+                }
+                AstConvRequest::GetTypeParameterBounds(id) => {
+                    let def = tcx.type_parameter_def(id);
+                    tcx.sess.note(
+                        &format!("...which then requires computing the bounds \
+                                  for type parameter `{}`...",
+                                 def.name.user_string(tcx)));
+                }
+            }
         }
 
-        match self.tcx.map.find(id.node) {
-            Some(ast_map::NodeItem(item)) => {
-                type_scheme_of_item(self, &*item)
+        match cycle[0] {
+            AstConvRequest::GetItemTypeScheme(def_id) |
+            AstConvRequest::GetTraitDef(def_id) => {
+                tcx.sess.note(
+                    &format!("...which then again requires processing `{}`, completing the cycle.",
+                             ty::item_path_str(tcx, def_id)));
             }
-            Some(ast_map::NodeForeignItem(foreign_item)) => {
-                let abi = self.tcx.map.get_foreign_abi(id.node);
-                type_scheme_of_foreign_item(self, &*foreign_item, abi)
+            AstConvRequest::EnsureSuperPredicates(def_id) => {
+                tcx.sess.note(
+                    &format!("...which then again requires computing the supertraits of `{}`, \
+                              completing the cycle.",
+                             ty::item_path_str(tcx, def_id)));
             }
-            x => {
-                self.tcx.sess.bug(&format!("unexpected sort of node \
-                                            in get_item_type_scheme(): {:?}",
-                                           x));
+            AstConvRequest::GetTypeParameterBounds(id) => {
+                let def = tcx.type_parameter_def(id);
+                tcx.sess.note(
+                    &format!("...which then again requires computing the bounds \
+                              for type parameter `{}`, completing the cycle.",
+                             def.name.user_string(tcx)));
             }
         }
     }
 
-    fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef<'tcx>> {
-        get_trait_def(self, id)
+    /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
+    fn get_trait_def(&self, trait_id: ast::DefId)
+                     -> Rc<ty::TraitDef<'tcx>>
+    {
+        let tcx = self.tcx;
+
+        if trait_id.krate != ast::LOCAL_CRATE {
+            return ty::lookup_trait_def(tcx, trait_id)
+        }
+
+        let item = match tcx.map.get(trait_id.node) {
+            ast_map::NodeItem(item) => item,
+            _ => tcx.sess.bug(&format!("get_trait_def({}): not an item", trait_id.repr(tcx)))
+        };
+
+        trait_def_of_item(self, &*item)
+    }
+
+    /// Ensure that the (transitive) super predicates for
+    /// `trait_def_id` are available. This will report a cycle error
+    /// if a trait `X` (transitively) extends itself in some form.
+    fn ensure_super_predicates(&self, span: Span, trait_def_id: ast::DefId)
+                               -> Result<(), ErrorReported>
+    {
+        self.cycle_check(span, AstConvRequest::EnsureSuperPredicates(trait_def_id), || {
+            let def_ids = ensure_super_predicates_step(self, trait_def_id);
+
+            for def_id in def_ids {
+                try!(self.ensure_super_predicates(span, def_id));
+            }
+
+            Ok(())
+        })
+    }
+}
+
+impl<'a,'tcx> ItemCtxt<'a,'tcx> {
+    fn to_ty<RS:RegionScope>(&self, rs: &RS, ast_ty: &ast::Ty) -> Ty<'tcx> {
+        ast_ty_to_ty(self, rs, ast_ty)
+    }
+}
+
+impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
+    fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx }
+
+    fn get_item_type_scheme(&self, span: Span, id: ast::DefId)
+                            -> Result<ty::TypeScheme<'tcx>, ErrorReported>
+    {
+        self.ccx.cycle_check(span, AstConvRequest::GetItemTypeScheme(id), || {
+            Ok(type_scheme_of_def_id(self.ccx, id))
+        })
+    }
+
+    fn get_trait_def(&self, span: Span, id: ast::DefId)
+                     -> Result<Rc<ty::TraitDef<'tcx>>, ErrorReported>
+    {
+        self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
+            Ok(self.ccx.get_trait_def(id))
+        })
+    }
+
+    fn ensure_super_predicates(&self,
+                               span: Span,
+                               trait_def_id: ast::DefId)
+                               -> Result<(), ErrorReported>
+    {
+        debug!("ensure_super_predicates(trait_def_id={})",
+               trait_def_id.repr(self.tcx()));
+
+        self.ccx.ensure_super_predicates(span, trait_def_id)
+    }
+
+
+    fn get_type_parameter_bounds(&self,
+                                 span: Span,
+                                 node_id: ast::NodeId)
+                                 -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
+    {
+        self.ccx.cycle_check(span, AstConvRequest::GetTypeParameterBounds(node_id), || {
+            let v = self.param_bounds.get_type_parameter_bounds(self, span, node_id)
+                                     .into_iter()
+                                     .filter_map(|p| p.to_opt_poly_trait_ref())
+                                     .collect();
+            Ok(v)
+        })
+    }
+
+    fn trait_defines_associated_type_named(&self,
+                                           trait_def_id: ast::DefId,
+                                           assoc_name: ast::Name)
+                                           -> bool
+    {
+        if trait_def_id.krate == ast::LOCAL_CRATE {
+            trait_defines_associated_type_named(self.ccx, trait_def_id.node, assoc_name)
+        } else {
+            let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
+            trait_def.associated_type_names.contains(&assoc_name)
+        }
     }
 
     fn ty_infer(&self, span: Span) -> Ty<'tcx> {
@@ -253,11 +422,151 @@ impl<'a, 'tcx> AstConv<'tcx> for CollectCtxt<'a, 'tcx> {
     }
 }
 
-fn get_enum_variant_types<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
+/// Interface used to find the bounds on a type parameter from within
+/// an `ItemCtxt`. This allows us to use multiple kinds of sources.
+trait GetTypeParameterBounds<'tcx> {
+    fn get_type_parameter_bounds(&self,
+                                 astconv: &AstConv<'tcx>,
+                                 span: Span,
+                                 node_id: ast::NodeId)
+                                 -> Vec<ty::Predicate<'tcx>>;
+}
+
+/// Find bounds from both elements of the tuple.
+impl<'a,'b,'tcx,A,B> GetTypeParameterBounds<'tcx> for (&'a A,&'b B)
+    where A : GetTypeParameterBounds<'tcx>, B : GetTypeParameterBounds<'tcx>
+{
+    fn get_type_parameter_bounds(&self,
+                                 astconv: &AstConv<'tcx>,
+                                 span: Span,
+                                 node_id: ast::NodeId)
+                                 -> Vec<ty::Predicate<'tcx>>
+    {
+        let mut v = self.0.get_type_parameter_bounds(astconv, span, node_id);
+        v.extend(self.1.get_type_parameter_bounds(astconv, span, node_id).into_iter());
+        v
+    }
+}
+
+/// Empty set of bounds.
+impl<'tcx> GetTypeParameterBounds<'tcx> for () {
+    fn get_type_parameter_bounds(&self,
+                                 _astconv: &AstConv<'tcx>,
+                                 _span: Span,
+                                 _node_id: ast::NodeId)
+                                 -> Vec<ty::Predicate<'tcx>>
+    {
+        Vec::new()
+    }
+}
+
+/// Find bounds from the parsed and converted predicates.  This is
+/// used when converting methods, because by that time the predicates
+/// from the trait/impl have been fully converted.
+impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
+    fn get_type_parameter_bounds(&self,
+                                 astconv: &AstConv<'tcx>,
+                                 _span: Span,
+                                 node_id: ast::NodeId)
+                                 -> Vec<ty::Predicate<'tcx>>
+    {
+        let def = astconv.tcx().type_parameter_def(node_id);
+
+        self.predicates
+            .iter()
+            .filter(|predicate| {
+                match **predicate {
+                    ty::Predicate::Trait(ref data) => {
+                        data.skip_binder().self_ty().is_param(def.space, def.index)
+                    }
+                    ty::Predicate::TypeOutlives(ref data) => {
+                        data.skip_binder().0.is_param(def.space, def.index)
+                    }
+                    ty::Predicate::Equate(..) |
+                    ty::Predicate::RegionOutlives(..) |
+                    ty::Predicate::Projection(..) => {
+                        false
+                    }
+                }
+            })
+            .cloned()
+            .collect()
+    }
+}
+
+/// Find bounds from ast::Generics. This requires scanning through the
+/// AST. We do this to avoid having to convert *all* the bounds, which
+/// would create artificial cycles. Instead we can only convert the
+/// bounds for those a type parameter `X` if `X::Foo` is used.
+impl<'tcx> GetTypeParameterBounds<'tcx> for ast::Generics {
+    fn get_type_parameter_bounds(&self,
+                                 astconv: &AstConv<'tcx>,
+                                 _: Span,
+                                 node_id: ast::NodeId)
+                                 -> Vec<ty::Predicate<'tcx>>
+    {
+        // In the AST, bounds can derive from two places. Either
+        // written inline like `<T:Foo>` or in a where clause like
+        // `where T:Foo`.
+
+        let def = astconv.tcx().type_parameter_def(node_id);
+        let ty = ty::mk_param_from_def(astconv.tcx(), &def);
+
+        let from_ty_params =
+            self.ty_params
+                .iter()
+                .filter(|p| p.id == node_id)
+                .flat_map(|p| p.bounds.iter())
+                .flat_map(|b| predicates_from_bound(astconv, ty, b).into_iter());
+
+        let from_where_clauses =
+            self.where_clause
+                .predicates
+                .iter()
+                .filter_map(|wp| match *wp {
+                    ast::WherePredicate::BoundPredicate(ref bp) => Some(bp),
+                    _ => None
+                })
+                .filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id))
+                .flat_map(|bp| bp.bounds.iter())
+                .flat_map(|b| predicates_from_bound(astconv, ty, b).into_iter());
+
+        from_ty_params.chain(from_where_clauses).collect()
+    }
+}
+
+/// Tests whether this is the AST for a reference to the type
+/// parameter with id `param_id`. We use this so as to avoid running
+/// `ast_ty_to_ty`, because we want to avoid triggering an all-out
+/// conversion of the type to avoid inducing unnecessary cycles.
+fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>,
+                  ast_ty: &ast::Ty,
+                  param_id: ast::NodeId)
+                  -> bool
+{
+    if let ast::TyPath(None, _) = ast_ty.node {
+        let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
+        match path_res.base_def {
+            def::DefSelfTy(node_id) =>
+                path_res.depth == 0 && node_id == param_id,
+
+            def::DefTyParam(_, _, def_id, _) =>
+                path_res.depth == 0 && def_id == local_def(param_id),
+
+            _ =>
+                false,
+        }
+    } else {
+        false
+    }
+}
+
+fn get_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                     enum_scheme: ty::TypeScheme<'tcx>,
                                     enum_predicates: ty::GenericPredicates<'tcx>,
                                     variants: &[P<ast::Variant>]) {
     let tcx = ccx.tcx;
+    let icx = ccx.icx(&enum_predicates);
 
     // Create a set of parameter types shared among all the variants.
     for variant in variants {
@@ -268,8 +577,8 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
         let result_ty = match variant.node.kind {
             ast::TupleVariantKind(ref args) if args.len() > 0 => {
                 let rs = ExplicitRscope;
-                let input_tys: Vec<_> = args.iter().map(|va| ccx.to_ty(&rs, &*va.ty)).collect();
-                ty::mk_ctor_fn(tcx, variant_def_id, &input_tys[..], enum_scheme.ty)
+                let input_tys: Vec<_> = args.iter().map(|va| icx.to_ty(&rs, &*va.ty)).collect();
+                ty::mk_ctor_fn(tcx, variant_def_id, &input_tys, enum_scheme.ty)
             }
 
             ast::TupleVariantKind(_) => {
@@ -294,172 +603,62 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
     }
 }
 
-fn collect_trait_methods<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
-                                   trait_id: ast::NodeId,
-                                   trait_def: &ty::TraitDef<'tcx>,
-                                   trait_predicates: &ty::GenericPredicates<'tcx>) {
-    let tcx = ccx.tcx;
-    if let ast_map::NodeItem(item) = tcx.map.get(trait_id) {
-        if let ast::ItemTrait(_, _, _, ref trait_items) = item.node {
-            // For each method, construct a suitable ty::Method and
-            // store it into the `tcx.impl_or_trait_items` table:
-            for trait_item in trait_items {
-                match *trait_item {
-                    ast::RequiredMethod(_) |
-                    ast::ProvidedMethod(_) => {
-                        let ty_method = Rc::new(match *trait_item {
-                            ast::RequiredMethod(ref m) => {
-                                ty_method_of_trait_method(
-                                    ccx,
-                                    trait_id,
-                                    &trait_def.generics,
-                                    &trait_predicates,
-                                    &trait_items[..],
-                                    &m.id,
-                                    &m.ident.name,
-                                    &m.explicit_self,
-                                    m.abi,
-                                    &m.generics,
-                                    &m.unsafety,
-                                    &*m.decl)
-                            }
-                            ast::ProvidedMethod(ref m) => {
-                                ty_method_of_trait_method(
-                                    ccx,
-                                    trait_id,
-                                    &trait_def.generics,
-                                    &trait_predicates,
-                                    &trait_items[..],
-                                    &m.id,
-                                    &m.pe_ident().name,
-                                    m.pe_explicit_self(),
-                                    m.pe_abi(),
-                                    m.pe_generics(),
-                                    &m.pe_unsafety(),
-                                    &*m.pe_fn_decl())
-                            }
-                            ast::TypeTraitItem(ref at) => {
-                                tcx.sess.span_bug(at.ty_param.span,
-                                                  "there shouldn't be a type trait item here")
-                            }
-                        });
-
-                        debug!("ty_method_of_trait_method yielded {} for method {} of trait {}",
-                               ty_method.repr(ccx.tcx),
-                               trait_item.repr(ccx.tcx),
-                               local_def(trait_id).repr(ccx.tcx));
-
-                        make_method_ty(ccx, &*ty_method);
-
-                        tcx.impl_or_trait_items
-                            .borrow_mut()
-                            .insert(ty_method.def_id, ty::MethodTraitItem(ty_method));
-                    }
-                    ast::TypeTraitItem(ref ast_associated_type) => {
-                        let trait_did = local_def(trait_id);
-                        let associated_type = ty::AssociatedType {
-                            name: ast_associated_type.ty_param.ident.name,
-                            vis: ast::Public,
-                            def_id: local_def(ast_associated_type.ty_param.id),
-                            container: TraitContainer(trait_did),
-                        };
-
-                        let trait_item = ty::TypeTraitItem(Rc::new(associated_type));
-                        tcx.impl_or_trait_items
-                            .borrow_mut()
-                            .insert(associated_type.def_id, trait_item);
-                    }
-                }
-            }
-
-            // Add an entry mapping
-            let trait_item_def_ids =
-                Rc::new(trait_items.iter().map(|ti| {
-                    match *ti {
-                        ast::RequiredMethod(ref ty_method) => {
-                            ty::MethodTraitItemId(local_def(ty_method.id))
-                        }
-                        ast::ProvidedMethod(ref method) => {
-                            ty::MethodTraitItemId(local_def(method.id))
-                        }
-                        ast::TypeTraitItem(ref typedef) => {
-                            ty::TypeTraitItemId(local_def(typedef.ty_param.id))
-                        }
-                    }
-                }).collect());
-
-            let trait_def_id = local_def(trait_id);
-            tcx.trait_item_def_ids.borrow_mut().insert(trait_def_id, trait_item_def_ids);
-        }
-    }
+fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
+                            container: ImplOrTraitItemContainer,
+                            sig: &ast::MethodSig,
+                            id: ast::NodeId,
+                            ident: ast::Ident,
+                            vis: ast::Visibility,
+                            untransformed_rcvr_ty: Ty<'tcx>,
+                            rcvr_ty_generics: &ty::Generics<'tcx>,
+                            rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
+    let ty_generics = ty_generics_for_fn(ccx, &sig.generics, rcvr_ty_generics);
+
+    let ty_generic_predicates =
+        ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates);
+
+    let (fty, explicit_self_category) =
+        astconv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
+                              sig, untransformed_rcvr_ty);
+
+    let def_id = local_def(id);
+    let ty_method = ty::Method::new(ident.name,
+                                    ty_generics,
+                                    ty_generic_predicates,
+                                    fty,
+                                    explicit_self_category,
+                                    vis,
+                                    def_id,
+                                    container,
+                                    None);
+
+    let fty = ty::mk_bare_fn(ccx.tcx, Some(def_id),
+                             ccx.tcx.mk_bare_fn(ty_method.fty.clone()));
+    debug!("method {} (id {}) has type {}",
+            ident.repr(ccx.tcx), id, fty.repr(ccx.tcx));
+    ccx.tcx.tcache.borrow_mut().insert(def_id,TypeScheme {
+        generics: ty_method.generics.clone(),
+        ty: fty
+    });
+    ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
 
-    fn make_method_ty<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, m: &ty::Method<'tcx>) {
-        ccx.tcx.tcache.borrow_mut().insert(
-            m.def_id,
-            TypeScheme {
-                generics: m.generics.clone(),
-                ty: ty::mk_bare_fn(ccx.tcx, Some(m.def_id), ccx.tcx.mk_bare_fn(m.fty.clone()))
-            });
-        ccx.tcx.predicates.borrow_mut().insert(
-            m.def_id,
-            m.predicates.clone());
-    }
+    write_ty_to_tcx(ccx.tcx, id, fty);
 
-    fn ty_method_of_trait_method<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
-                                           trait_id: ast::NodeId,
-                                           trait_generics: &ty::Generics<'tcx>,
-                                           trait_bounds: &ty::GenericPredicates<'tcx>,
-                                           _trait_items: &[ast::TraitItem],
-                                           m_id: &ast::NodeId,
-                                           m_name: &ast::Name,
-                                           m_explicit_self: &ast::ExplicitSelf,
-                                           m_abi: abi::Abi,
-                                           m_generics: &ast::Generics,
-                                           m_unsafety: &ast::Unsafety,
-                                           m_decl: &ast::FnDecl)
-                                           -> ty::Method<'tcx> {
-        let ty_generics =
-            ty_generics_for_fn_or_method(ccx,
-                                         m_generics,
-                                         trait_generics.clone());
-
-        let ty_bounds =
-            ty_generic_bounds_for_fn_or_method(ccx,
-                                               m_generics,
-                                               &ty_generics,
-                                               trait_bounds.clone());
-
-        let (fty, explicit_self_category) = {
-            let trait_self_ty = ty::mk_self_type(ccx.tcx);
-            astconv::ty_of_method(ccx,
-                                  *m_unsafety,
-                                  trait_self_ty,
-                                  m_explicit_self,
-                                  m_decl,
-                                  m_abi)
-        };
+    debug!("writing method type: def_id={:?} mty={}",
+            def_id, ty_method.repr(ccx.tcx));
 
-        ty::Method::new(
-            *m_name,
-            ty_generics,
-            ty_bounds,
-            fty,
-            explicit_self_category,
-            // assume public, because this is only invoked on trait methods
-            ast::Public,
-            local_def(*m_id),
-            TraitContainer(local_def(trait_id)),
-            None
-        )
-    }
+    ccx.tcx.impl_or_trait_items.borrow_mut().insert(def_id,
+        ty::MethodTraitItem(Rc::new(ty_method)));
 }
 
-fn convert_field<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
-                                struct_generics: &ty::Generics<'tcx>,
-                                struct_predicates: &ty::GenericPredicates<'tcx>,
-                                v: &ast::StructField,
-                                origin: ast::DefId) -> ty::field_ty {
-    let tt = ccx.to_ty(&ExplicitRscope, &*v.node.ty);
+fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
+                           struct_generics: &ty::Generics<'tcx>,
+                           struct_predicates: &ty::GenericPredicates<'tcx>,
+                           v: &ast::StructField,
+                           origin: ast::DefId)
+                           -> ty::field_ty
+{
+    let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &*v.node.ty);
     write_ty_to_tcx(ccx.tcx, v.node.id, tt);
 
     /* add the field to the tcache */
@@ -491,119 +690,55 @@ fn convert_field<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
     }
 }
 
-fn convert_associated_type<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
-                                     trait_def: &ty::TraitDef<'tcx>,
-                                     associated_type: &ast::AssociatedType)
+fn as_refsociated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
+                                     container: ImplOrTraitItemContainer,
+                                     ident: ast::Ident,
+                                     id: ast::NodeId,
+                                     vis: ast::Visibility)
 {
     let associated_type = Rc::new(ty::AssociatedType {
-        name: associated_type.ty_param.ident.name,
-        vis: ast::Public,
-        def_id: local_def(associated_type.ty_param.id),
-        container: TraitContainer(trait_def.trait_ref.def_id),
+        name: ident.name,
+        vis: vis,
+        def_id: local_def(id),
+        container: container
     });
-    ccx.tcx
-       .impl_or_trait_items
-       .borrow_mut()
-       .insert(associated_type.def_id,
-               ty::TypeTraitItem(associated_type));
+    ccx.tcx.impl_or_trait_items.borrow_mut()
+       .insert(local_def(id), ty::TypeTraitItem(associated_type));
 }
 
-fn convert_methods<'a,'tcx,'i,I>(ccx: &CollectCtxt<'a, 'tcx>,
+fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
                                  container: ImplOrTraitItemContainer,
-                                 ms: I,
+                                 methods: I,
                                  untransformed_rcvr_ty: Ty<'tcx>,
                                  rcvr_ty_generics: &ty::Generics<'tcx>,
-                                 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>,
-                                 rcvr_visibility: ast::Visibility)
-                                 where I: Iterator<Item=&'i ast::Method> {
-    debug!("convert_methods(untransformed_rcvr_ty={}, rcvr_ty_generics={})",
+                                 rcvr_ty_predicates: &ty::GenericPredicates<'tcx>)
+    where I: Iterator<Item=(&'i ast::MethodSig, ast::NodeId, ast::Ident, ast::Visibility, Span)>
+{
+    debug!("convert_methods(untransformed_rcvr_ty={}, rcvr_ty_generics={}, rcvr_ty_predicates={})",
            untransformed_rcvr_ty.repr(ccx.tcx),
-           rcvr_ty_generics.repr(ccx.tcx));
+           rcvr_ty_generics.repr(ccx.tcx),
+           rcvr_ty_predicates.repr(ccx.tcx));
 
     let tcx = ccx.tcx;
     let mut seen_methods = FnvHashSet();
-    for m in ms {
-        if !seen_methods.insert(m.pe_ident().repr(tcx)) {
-            span_err!(tcx.sess, m.span, E0201, "duplicate method in trait impl");
+    for (sig, id, ident, vis, span) in methods {
+        if !seen_methods.insert(ident.name) {
+            span_err!(tcx.sess, span, E0201, "duplicate method");
         }
 
-        let m_def_id = local_def(m.id);
-
-        let mty = Rc::new(ty_of_method(ccx,
-                                       container,
-                                       m,
-                                       untransformed_rcvr_ty,
-                                       rcvr_ty_generics,
-                                       rcvr_ty_predicates,
-                                       rcvr_visibility));
-        let fty = ty::mk_bare_fn(tcx, Some(m_def_id), tcx.mk_bare_fn(mty.fty.clone()));
-        debug!("method {} (id {}) has type {}",
-                m.pe_ident().repr(tcx),
-                m.id,
-                fty.repr(tcx));
-        tcx.tcache.borrow_mut().insert(
-            m_def_id,
-            TypeScheme {
-                generics: mty.generics.clone(),
-                ty: fty
-            });
-        tcx.predicates.borrow_mut().insert(m_def_id, mty.predicates.clone());
-
-        write_ty_to_tcx(tcx, m.id, fty);
-
-        debug!("writing method type: def_id={:?} mty={}",
-               mty.def_id, mty.repr(ccx.tcx));
-
-        tcx.impl_or_trait_items
-           .borrow_mut()
-           .insert(mty.def_id, ty::MethodTraitItem(mty));
-    }
-
-    fn ty_of_method<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
-                              container: ImplOrTraitItemContainer,
-                              m: &ast::Method,
-                              untransformed_rcvr_ty: Ty<'tcx>,
-                              rcvr_ty_generics: &ty::Generics<'tcx>,
-                              rcvr_ty_predicates: &ty::GenericPredicates<'tcx>,
-                              rcvr_visibility: ast::Visibility)
-                              -> ty::Method<'tcx> {
-        let m_ty_generics =
-            ty_generics_for_fn_or_method(ccx,
-                                         m.pe_generics(),
-                                         rcvr_ty_generics.clone());
-
-        let m_ty_bounds =
-            ty_generic_bounds_for_fn_or_method(ccx,
-                                               m.pe_generics(),
-                                               &m_ty_generics,
-                                               rcvr_ty_predicates.clone());
-
-        let (fty, explicit_self_category) = astconv::ty_of_method(ccx,
-                                                                  m.pe_unsafety(),
-                                                                  untransformed_rcvr_ty,
-                                                                  m.pe_explicit_self(),
-                                                                  &*m.pe_fn_decl(),
-                                                                  m.pe_abi());
-
-        // if the method specifies a visibility, use that, otherwise
-        // inherit the visibility from the impl (so `foo` in `pub impl
-        // { fn foo(); }` is public, but private in `priv impl { fn
-        // foo(); }`).
-        let method_vis = m.pe_vis().inherit_from(rcvr_visibility);
-
-        ty::Method::new(m.pe_ident().name,
-                        m_ty_generics,
-                        m_ty_bounds,
-                        fty,
-                        explicit_self_category,
-                        method_vis,
-                        local_def(m.id),
-                        container,
-                        None)
+        convert_method(ccx,
+                       container,
+                       sig,
+                       id,
+                       ident,
+                       vis,
+                       untransformed_rcvr_ty,
+                       rcvr_ty_generics,
+                       rcvr_ty_predicates);
     }
 }
 
-fn ensure_no_ty_param_bounds(ccx: &CollectCtxt,
+fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
                                  span: Span,
                                  generics: &ast::Generics,
                                  thing: &'static str) {
@@ -632,7 +767,7 @@ fn ensure_no_ty_param_bounds(ccx: &CollectCtxt,
     }
 }
 
-fn convert_item(ccx: &CollectCtxt, it: &ast::Item) {
+fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
     let tcx = ccx.tcx;
     debug!("convert: item {} with id {}", token::get_ident(it.ident), it.id);
     match it.node {
@@ -648,6 +783,17 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) {
                                    predicates,
                                    &enum_definition.variants);
         },
+        ast::ItemDefaultImpl(_, ref ast_trait_ref) => {
+            let trait_ref =
+                astconv::instantiate_mono_trait_ref(&ccx.icx(&()),
+                                                    &ExplicitRscope,
+                                                    ast_trait_ref,
+                                                    None);
+
+            ty::record_trait_has_default_impl(tcx, trait_ref.def_id);
+
+            tcx.impl_trait_refs.borrow_mut().insert(it.id, trait_ref);
+        }
         ast::ItemImpl(_, _,
                       ref generics,
                       ref opt_trait_ref,
@@ -657,11 +803,11 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) {
 
             debug!("convert: ast_generics={:?}", generics);
             let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
-            let ty_predicates = ty_generic_bounds_for_type_or_impl(ccx, &ty_generics, generics);
+            let ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
 
             debug!("convert: impl_bounds={:?}", ty_predicates);
 
-            let selfty = ccx.to_ty(&ExplicitRscope, &**selfty);
+            let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty);
             write_ty_to_tcx(tcx, it.id, selfty);
 
             tcx.tcache.borrow_mut().insert(local_def(it.id),
@@ -681,119 +827,148 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) {
                 it.vis
             };
 
-            let mut methods = Vec::new();
+            // Convert all the associated types.
             for impl_item in impl_items {
-                match *impl_item {
-                    ast::MethodImplItem(ref method) => {
-                        let body_id = method.pe_body().id;
-                        check_method_self_type(ccx,
-                                               &BindingRscope::new(),
-                                               selfty,
-                                               method.pe_explicit_self(),
-                                               body_id);
-                        methods.push(&**method);
-                    }
-                    ast::TypeImplItem(ref typedef) => {
+                match impl_item.node {
+                    ast::TypeImplItem(ref ty) => {
                         if opt_trait_ref.is_none() {
-                            span_err!(tcx.sess, typedef.span, E0202,
+                            span_err!(tcx.sess, impl_item.span, E0202,
                                               "associated items are not allowed in inherent impls");
                         }
 
-                        let typ = ccx.to_ty(&ExplicitRscope, &*typedef.typ);
-                        tcx.tcache.borrow_mut().insert(local_def(typedef.id),
+                        as_refsociated_type(ccx, ImplContainer(local_def(it.id)),
+                                                impl_item.ident, impl_item.id, impl_item.vis);
+
+                        let typ = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, ty);
+                        tcx.tcache.borrow_mut().insert(local_def(impl_item.id),
                                                        TypeScheme {
                                                            generics: ty::Generics::empty(),
                                                            ty: typ,
                                                        });
-                        tcx.predicates.borrow_mut().insert(local_def(typedef.id),
+                        tcx.predicates.borrow_mut().insert(local_def(impl_item.id),
                                                            ty::GenericPredicates::empty());
-                        write_ty_to_tcx(tcx, typedef.id, typ);
-
-                        let associated_type = Rc::new(ty::AssociatedType {
-                            name: typedef.ident.name,
-                            vis: typedef.vis,
-                            def_id: local_def(typedef.id),
-                            container: ty::ImplContainer(local_def(it.id)),
-                        });
-                        tcx.impl_or_trait_items
-                           .borrow_mut()
-                           .insert(local_def(typedef.id),
-                                   ty::TypeTraitItem(associated_type));
+                        write_ty_to_tcx(tcx, impl_item.id, typ);
                     }
+                    ast::MethodImplItem(..) |
+                    ast::MacImplItem(_) => {}
                 }
             }
 
+            let methods = impl_items.iter().filter_map(|ii| {
+                match ii.node {
+                    ast::MethodImplItem(ref sig, _) => {
+                        // if the method specifies a visibility, use that, otherwise
+                        // inherit the visibility from the impl (so `foo` in `pub impl
+                        // { fn foo(); }` is public, but private in `priv impl { fn
+                        // foo(); }`).
+                        let method_vis = ii.vis.inherit_from(parent_visibility);
+                        Some((sig, ii.id, ii.ident, method_vis, ii.span))
+                    }
+                    ast::TypeImplItem(_) |
+                    ast::MacImplItem(_) => None
+                }
+            });
             convert_methods(ccx,
                             ImplContainer(local_def(it.id)),
-                            methods.into_iter(),
+                            methods,
                             selfty,
                             &ty_generics,
-                            &ty_predicates,
-                            parent_visibility);
-
-            if let Some(ref trait_ref) = *opt_trait_ref {
-                astconv::instantiate_trait_ref(ccx,
-                                               &ExplicitRscope,
-                                               trait_ref,
-                                               Some(selfty),
-                                               None);
+                            &ty_predicates);
+
+            for impl_item in impl_items {
+                match impl_item.node {
+                    ast::MethodImplItem(ref sig, ref body) => {
+                        let body_id = body.id;
+                        check_method_self_type(ccx,
+                                               &BindingRscope::new(),
+                                               ccx.method_ty(impl_item.id),
+                                               selfty,
+                                               &sig.explicit_self,
+                                               body_id);
+                    }
+                    ast::TypeImplItem(_) |
+                    ast::MacImplItem(_) => {}
+                }
+            }
+
+            if let Some(ref ast_trait_ref) = *opt_trait_ref {
+                let trait_ref =
+                    astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
+                                                        &ExplicitRscope,
+                                                        ast_trait_ref,
+                                                        Some(selfty));
+
+                tcx.impl_trait_refs.borrow_mut().insert(it.id, trait_ref);
             }
 
             enforce_impl_ty_params_are_constrained(tcx,
                                                    generics,
                                                    local_def(it.id));
         },
-        ast::ItemTrait(_, _, _, ref trait_methods) => {
+        ast::ItemTrait(_, _, _, ref trait_items) => {
             let trait_def = trait_def_of_item(ccx, it);
+            let _: Result<(), ErrorReported> = // any error is already reported, can ignore
+                ccx.ensure_super_predicates(it.span, local_def(it.id));
             convert_trait_predicates(ccx, it);
-            let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(it.id));
+            let trait_predicates = ty::lookup_predicates(tcx, local_def(it.id));
 
             debug!("convert: trait_bounds={:?}", trait_predicates);
 
-            for trait_method in trait_methods {
-                let self_type = ty::mk_self_type(tcx);
-                match *trait_method {
-                    ast::RequiredMethod(ref type_method) => {
-                        let rscope = BindingRscope::new();
-                        check_method_self_type(ccx,
-                                               &rscope,
-                                               self_type,
-                                               &type_method.explicit_self,
-                                               it.id)
-                    }
-                    ast::ProvidedMethod(ref method) => {
-                        check_method_self_type(ccx,
-                                               &BindingRscope::new(),
-                                               self_type,
-                                               method.pe_explicit_self(),
-                                               it.id)
-                    }
-                    ast::TypeTraitItem(ref associated_type) => {
-                        convert_associated_type(ccx,
-                                                &*trait_def,
-                                                &**associated_type);
+            // Convert all the associated types.
+            for trait_item in trait_items {
+                match trait_item.node {
+                    ast::MethodTraitItem(..) => {}
+                    ast::TypeTraitItem(..) => {
+                        as_refsociated_type(ccx, TraitContainer(local_def(it.id)),
+                                                trait_item.ident, trait_item.id, ast::Public);
                     }
                 }
-            }
+            };
+
+            let methods = trait_items.iter().filter_map(|ti| {
+                let sig = match ti.node {
+                    ast::MethodTraitItem(ref sig, _) => sig,
+                    ast::TypeTraitItem(..) => return None,
+                };
+                Some((sig, ti.id, ti.ident, ast::Inherited, ti.span))
+            });
 
-            // Run convert_methods on the provided methods.
-            let untransformed_rcvr_ty = ty::mk_self_type(tcx);
+            // Run convert_methods on the trait methods.
             convert_methods(ccx,
                             TraitContainer(local_def(it.id)),
-                            trait_methods.iter().filter_map(|m| match *m {
-                                ast::RequiredMethod(_) => None,
-                                ast::ProvidedMethod(ref m) => Some(&**m),
-                                ast::TypeTraitItem(_) => None,
-                            }),
-                            untransformed_rcvr_ty,
+                            methods,
+                            ty::mk_self_type(tcx),
                             &trait_def.generics,
-                            &trait_predicates,
-                            it.vis);
+                            &trait_predicates);
 
-            // We need to do this *after* converting methods, since
-            // convert_methods produces a tcache entry that is wrong for
-            // static trait methods. This is somewhat unfortunate.
-            collect_trait_methods(ccx, it.id, &*trait_def, &trait_predicates);
+            // Add an entry mapping
+            let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| {
+                let def_id = local_def(trait_item.id);
+                match trait_item.node {
+                    ast::MethodTraitItem(..) => {
+                        ty::MethodTraitItemId(def_id)
+                    }
+                    ast::TypeTraitItem(..) => {
+                        ty::TypeTraitItemId(def_id)
+                    }
+                }
+            }).collect());
+            tcx.trait_item_def_ids.borrow_mut().insert(local_def(it.id), trait_item_def_ids);
+
+            // This must be done after `collect_trait_methods` so that
+            // we have a method type stored for every method.
+            for trait_item in trait_items {
+                let sig = match trait_item.node {
+                    ast::MethodTraitItem(ref sig, _) => sig,
+                    ast::TypeTraitItem(..) => continue
+                };
+                check_method_self_type(ccx,
+                                       &BindingRscope::new(),
+                                       ccx.method_ty(trait_item.id),
+                                       ty::mk_self_type(tcx),
+                                       &sig.explicit_self,
+                                       it.id)
+            }
         },
         ast::ItemStruct(ref struct_def, _) => {
             // Write the class type.
@@ -816,7 +991,7 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) {
     }
 }
 
-fn convert_struct<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
+fn convert_struct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                             struct_def: &ast::StructDef,
                             scheme: ty::TypeScheme<'tcx>,
                             predicates: ty::GenericPredicates<'tcx>,
@@ -867,9 +1042,13 @@ fn convert_struct<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
                 tcx.predicates.borrow_mut().insert(local_def(ctor_id), predicates);
             } else if struct_def.fields[0].node.kind.is_unnamed() {
                 // Tuple-like.
-                let inputs: Vec<_> = struct_def.fields.iter().map(
-                        |field| (*tcx.tcache.borrow())[
-                            local_def(field.node.id)].ty).collect();
+                let inputs: Vec<_> =
+                    struct_def.fields
+                              .iter()
+                              .map(|field| tcx.tcache.borrow().get(&local_def(field.node.id))
+                                                              .unwrap()
+                                                              .ty)
+                              .collect();
                 let ctor_fn_ty = ty::mk_ctor_fn(tcx,
                                                 local_def(ctor_id),
                                                 &inputs[..],
@@ -886,25 +1065,92 @@ fn convert_struct<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
     }
 }
 
-fn get_trait_def<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
-                           trait_id: ast::DefId)
-                           -> Rc<ty::TraitDef<'tcx>> {
+/// Ensures that the super-predicates of the trait with def-id
+/// trait_def_id are converted and stored. This does NOT ensure that
+/// the transitive super-predicates are converted; that is the job of
+/// the `ensure_super_predicates()` method in the `AstConv` impl
+/// above. Returns a list of trait def-ids that must be ensured as
+/// well to guarantee that the transitive superpredicates are
+/// converted.
+fn ensure_super_predicates_step(ccx: &CrateCtxt,
+                                trait_def_id: ast::DefId)
+                                -> Vec<ast::DefId>
+{
     let tcx = ccx.tcx;
 
-    if trait_id.krate != ast::LOCAL_CRATE {
-        return ty::lookup_trait_def(tcx, trait_id)
-    }
+    debug!("ensure_super_predicates_step(trait_def_id={})", trait_def_id.repr(tcx));
 
-    match tcx.map.get(trait_id.node) {
-        ast_map::NodeItem(item) => trait_def_of_item(ccx, &*item),
-        _ => {
-            tcx.sess.bug(&format!("get_trait_def({}): not an item",
-                                  trait_id.node)[])
-        }
+    if trait_def_id.krate != ast::LOCAL_CRATE {
+        // If this trait comes from an external crate, then all of the
+        // supertraits it may depend on also must come from external
+        // crates, and hence all of them already have their
+        // super-predicates "converted" (and available from crate
+        // meta-data), so there is no need to transitively test them.
+        return Vec::new();
     }
+
+    let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
+    let superpredicates = superpredicates.unwrap_or_else(|| {
+        let trait_node_id = trait_def_id.node;
+
+        let item = match ccx.tcx.map.get(trait_node_id) {
+            ast_map::NodeItem(item) => item,
+            _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
+        };
+
+        let (generics, bounds) = match item.node {
+            ast::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
+            _ => tcx.sess.span_bug(item.span,
+                                   "ensure_super_predicates_step invoked on non-trait"),
+        };
+
+        // In-scope when converting the superbounds for `Trait` are
+        // that `Self:Trait` as well as any bounds that appear on the
+        // generic types:
+        let trait_def = trait_def_of_item(ccx, item);
+        let self_predicate = ty::GenericPredicates {
+            predicates: VecPerParamSpace::new(vec![],
+                                              vec![trait_def.trait_ref.as_predicate()],
+                                              vec![])
+        };
+        let scope = &(generics, &self_predicate);
+
+        // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
+        let self_param_ty = ty::mk_self_type(tcx);
+        let superbounds1 = compute_bounds(&ccx.icx(scope), self_param_ty, bounds,
+                                          SizedByDefault::No, item.span);
+        let superbounds1 = ty::predicates(tcx, self_param_ty, &superbounds1);
+
+        // Convert any explicit superbounds in the where clause,
+        // e.g. `trait Foo where Self : Bar`:
+        let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
+
+        // Combine the two lists to form the complete set of superbounds:
+        let superbounds = superbounds1.into_iter().chain(superbounds2.into_iter()).collect();
+        let superpredicates = ty::GenericPredicates {
+            predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
+        };
+        debug!("superpredicates for trait {} = {}",
+               local_def(item.id).repr(ccx.tcx),
+               superpredicates.repr(ccx.tcx));
+
+        tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
+
+        superpredicates
+    });
+
+    let def_ids: Vec<_> = superpredicates.predicates
+                                         .iter()
+                                         .filter_map(|p| p.to_opt_poly_trait_ref())
+                                         .map(|tr| tr.def_id())
+                                         .collect();
+
+    debug!("ensure_super_predicates_step: def_ids={}", def_ids.repr(tcx));
+
+    def_ids
 }
 
-fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
+fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                it: &ast::Item)
                                -> Rc<ty::TraitDef<'tcx>>
 {
@@ -915,18 +1161,9 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
         return def.clone();
     }
 
-    let (unsafety, generics, bounds, items) = match it.node {
-        ast::ItemTrait(unsafety,
-                       ref generics,
-                       ref supertraits,
-                       ref items) => {
-            (unsafety, generics, supertraits, items)
-        }
-        ref s => {
-            tcx.sess.span_bug(
-                it.span,
-                &format!("trait_def_of_item invoked on {:?}", s)[]);
-        }
+    let (unsafety, generics, items) = match it.node {
+        ast::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
+        _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
     };
 
     let paren_sugar = ty::has_attr(tcx, def_id, "rustc_paren_sugar");
@@ -935,7 +1172,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
             it.span,
             "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
              which traits can use parenthetical notation");
-        span_help!(ccx.tcx.sess, it.span,
+        fileline_help!(ccx.tcx.sess, it.span,
                    "add `#![feature(unboxed_closures)]` to \
                     the crate attributes to use it");
     }
@@ -944,24 +1181,12 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
 
     let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
 
-    let self_param_ty = ty::ParamTy::for_self().to_ty(ccx.tcx);
-
-    // supertraits:
-    let bounds = compute_bounds(ccx,
-                                self_param_ty,
-                                bounds,
-                                SizedByDefault::No,
-                                it.span);
-
-    let associated_type_names: Vec<_> =
-        items.iter()
-             .filter_map(|item| {
-                 match *item {
-                     ast::RequiredMethod(_) | ast::ProvidedMethod(_) => None,
-                     ast::TypeTraitItem(ref data) => Some(data.ty_param.ident.name),
-                 }
-             })
-             .collect();
+    let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
+        match trait_item.node {
+            ast::MethodTraitItem(..) => None,
+            ast::TypeTraitItem(..) => Some(trait_item.ident.name),
+        }
+    }).collect();
 
     let trait_ref = Rc::new(ty::TraitRef {
         def_id: def_id,
@@ -972,7 +1197,6 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
         paren_sugar: paren_sugar,
         unsafety: unsafety,
         generics: ty_generics,
-        bounds: bounds,
         trait_ref: trait_ref,
         associated_type_names: associated_type_names,
     });
@@ -981,9 +1205,9 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
 
     return trait_def;
 
-    fn mk_trait_substs<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
+    fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                  generics: &ast::Generics)
-                                 -> subst::Substs<'tcx>
+                                 -> Substs<'tcx>
     {
         let tcx = ccx.tcx;
 
@@ -993,7 +1217,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
                     .iter()
                     .enumerate()
                     .map(|(i, def)| ty::ReEarlyBound(def.lifetime.id,
-                                                     subst::TypeSpace,
+                                                     TypeSpace,
                                                      i as u32,
                                                      def.lifetime.name))
                     .collect();
@@ -1003,18 +1227,41 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
             generics.ty_params
                     .iter()
                     .enumerate()
-                    .map(|(i, def)| ty::mk_param(tcx, subst::TypeSpace,
+                    .map(|(i, def)| ty::mk_param(tcx, TypeSpace,
                                                  i as u32, def.ident.name))
                     .collect();
 
         // ...and also create the `Self` parameter.
         let self_ty = ty::mk_self_type(tcx);
 
-        subst::Substs::new_trait(types, regions, self_ty)
+        Substs::new_trait(types, regions, self_ty)
     }
 }
 
-fn convert_trait_predicates<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, it: &ast::Item) {
+fn trait_defines_associated_type_named(ccx: &CrateCtxt,
+                                       trait_node_id: ast::NodeId,
+                                       assoc_name: ast::Name)
+                                       -> bool
+{
+    let item = match ccx.tcx.map.get(trait_node_id) {
+        ast_map::NodeItem(item) => item,
+        _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
+    };
+
+    let trait_items = match item.node {
+        ast::ItemTrait(_, _, _, ref trait_items) => trait_items,
+        _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
+    };
+
+    trait_items.iter().any(|trait_item| {
+        match trait_item.node {
+            ast::TypeTraitItem(..) => trait_item.ident.name == assoc_name,
+            ast::MethodTraitItem(..) => false,
+        }
+    })
+}
+
+fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) {
     let tcx = ccx.tcx;
     let trait_def = trait_def_of_item(ccx, it);
 
@@ -1025,77 +1272,95 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, it: &ast::Ite
         ref s => {
             tcx.sess.span_bug(
                 it.span,
-                &format!("trait_def_of_item invoked on {:?}", s)[]);
+                &format!("trait_def_of_item invoked on {:?}", s));
         }
     };
 
-    let self_param_ty = ty::ParamTy::for_self().to_ty(ccx.tcx);
+    let super_predicates = ty::lookup_super_predicates(ccx.tcx, def_id);
 
-    let super_predicates = ty::predicates(ccx.tcx, self_param_ty, &trait_def.bounds);
-
-    let assoc_predicates = predicates_for_associated_types(ccx, &trait_def.trait_ref, items);
-
-    // `ty_generic_bounds` below will consider the bounds on the type
+    // `ty_generic_predicates` below will consider the bounds on the type
     // parameters (including `Self`) and the explicit where-clauses,
     // but to get the full set of predicates on a trait we need to add
     // in the supertrait bounds and anything declared on the
     // associated types.
-    let mut base_predicates =
-        ty::GenericPredicates {
-            predicates: VecPerParamSpace::new(super_predicates, vec![], vec![])
-        };
-    base_predicates.predicates.extend(subst::TypeSpace, assoc_predicates.into_iter());
+    let mut base_predicates = super_predicates;
 
-    let self_bounds = &trait_def.generics.types.get_self().unwrap().bounds;
-    base_predicates.predicates.extend(
-        subst::SelfSpace,
-        ty::predicates(ccx.tcx, self_param_ty, self_bounds).into_iter());
+    // Add in a predicate that `Self:Trait` (where `Trait` is the
+    // current trait).  This is needed for builtin bounds.
+    let self_predicate = trait_def.trait_ref.to_poly_trait_ref().as_predicate();
+    base_predicates.predicates.push(SelfSpace, self_predicate);
 
     // add in the explicit where-clauses
-    let trait_predicates =
-        ty_generic_bounds(ccx,
-                          subst::TypeSpace,
-                          &trait_def.generics,
-                          base_predicates,
-                          &generics.where_clause);
+    let mut trait_predicates =
+        ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
+
+    let assoc_predicates = predicates_for_associated_types(ccx,
+                                                           generics,
+                                                           &trait_predicates,
+                                                           &trait_def.trait_ref,
+                                                           items);
+    trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
 
     let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
     assert!(prev_predicates.is_none());
 
     return;
 
-    fn predicates_for_associated_types<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
+    fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
+                                                 ast_generics: &ast::Generics,
+                                                 trait_predicates: &ty::GenericPredicates<'tcx>,
                                                  self_trait_ref: &Rc<ty::TraitRef<'tcx>>,
-                                                 trait_items: &[ast::TraitItem])
+                                                 trait_items: &[P<ast::TraitItem>])
                                                  -> Vec<ty::Predicate<'tcx>>
     {
-        trait_items
-            .iter()
-            .flat_map(|trait_item| {
-                let assoc_type_def = match *trait_item {
-                    ast::TypeTraitItem(ref assoc_type) => &assoc_type.ty_param,
-                    ast::RequiredMethod(..) | ast::ProvidedMethod(..) => {
-                        return vec!().into_iter();
-                    }
-                };
+        trait_items.iter().flat_map(|trait_item| {
+            let bounds = match trait_item.node {
+                ast::TypeTraitItem(ref bounds, _) => bounds,
+                ast::MethodTraitItem(..) => {
+                    return vec!().into_iter();
+                }
+            };
 
-                let assoc_ty = ty::mk_projection(ccx.tcx,
-                                                 self_trait_ref.clone(),
-                                                 assoc_type_def.ident.name);
+            let assoc_ty = ty::mk_projection(ccx.tcx,
+                                             self_trait_ref.clone(),
+                                             trait_item.ident.name);
 
-                let bounds = compute_bounds(ccx,
-                                            assoc_ty,
-                                            &*assoc_type_def.bounds,
-                                            SizedByDefault::Yes,
-                                            assoc_type_def.span);
+            let bounds = compute_bounds(&ccx.icx(&(ast_generics, trait_predicates)),
+                                        assoc_ty,
+                                        bounds,
+                                        SizedByDefault::Yes,
+                                        trait_item.span);
 
-                ty::predicates(ccx.tcx, assoc_ty, &bounds).into_iter()
-            })
-            .collect()
+            ty::predicates(ccx.tcx, assoc_ty, &bounds).into_iter()
+        }).collect()
     }
 }
 
-fn type_scheme_of_item<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
+fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
+                                  def_id: ast::DefId)
+                                  -> ty::TypeScheme<'tcx>
+{
+    if def_id.krate != ast::LOCAL_CRATE {
+        return ty::lookup_item_type(ccx.tcx, def_id);
+    }
+
+    match ccx.tcx.map.find(def_id.node) {
+        Some(ast_map::NodeItem(item)) => {
+            type_scheme_of_item(ccx, &*item)
+        }
+        Some(ast_map::NodeForeignItem(foreign_item)) => {
+            let abi = ccx.tcx.map.get_foreign_abi(def_id.node);
+            type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
+        }
+        x => {
+            ccx.tcx.sess.bug(&format!("unexpected sort of node \
+                                            in get_item_type_scheme(): {:?}",
+                                       x));
+        }
+    }
+}
+
+fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                 it: &ast::Item)
                                 -> ty::TypeScheme<'tcx>
 {
@@ -1104,28 +1369,25 @@ fn type_scheme_of_item<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
              |_| compute_type_scheme_of_item(ccx, it))
 }
 
-
-fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
-                                              it: &ast::Item)
-                                              -> ty::TypeScheme<'tcx>
+fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
+                                        it: &ast::Item)
+                                        -> ty::TypeScheme<'tcx>
 {
     let tcx = ccx.tcx;
     match it.node {
         ast::ItemStatic(ref t, _, _) | ast::ItemConst(ref t, _) => {
-            let ty = ccx.to_ty(&ExplicitRscope, &**t);
+            let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
             ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
         }
         ast::ItemFn(ref decl, unsafety, abi, ref generics, _) => {
-            let ty_generics = ty_generics_for_fn_or_method(ccx,
-                                                           generics,
-                                                           ty::Generics::empty());
-            let tofd = astconv::ty_of_bare_fn(ccx, unsafety, abi, &**decl);
+            let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
+            let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
             let ty = ty::mk_bare_fn(tcx, Some(local_def(it.id)), tcx.mk_bare_fn(tofd));
             ty::TypeScheme { ty: ty, generics: ty_generics }
         }
         ast::ItemTy(ref t, ref generics) => {
-            let ty = ccx.to_ty(&ExplicitRscope, &**t);
             let ty_generics = ty_generics_for_type_or_impl(ccx, generics);
+            let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &**t);
             ty::TypeScheme { ty: ty, generics: ty_generics }
         }
         ast::ItemEnum(_, ref generics) => {
@@ -1141,6 +1403,7 @@ fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
             let t = ty::mk_struct(tcx, local_def(it.id), tcx.mk_substs(substs));
             ty::TypeScheme { ty: t, generics: ty_generics }
         }
+        ast::ItemDefaultImpl(..) |
         ast::ItemTrait(..) |
         ast::ItemImpl(..) |
         ast::ItemMod(..) |
@@ -1150,13 +1413,13 @@ fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
         ast::ItemMac(..) => {
             tcx.sess.span_bug(
                 it.span,
-                format!("compute_type_scheme_of_item: unexpected item type: {:?}",
-                        it.node).as_slice());
+                &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
+                         it.node));
         }
     }
 }
 
-fn convert_typed_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
+fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 it: &ast::Item)
                                 -> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
 {
@@ -1169,20 +1432,18 @@ fn convert_typed_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
             ty::GenericPredicates::empty()
         }
         ast::ItemFn(_, _, _, ref ast_generics, _) => {
-            ty_generic_bounds_for_fn_or_method(ccx,
-                                               ast_generics,
-                                               &scheme.generics,
-                                               ty::GenericPredicates::empty())
+            ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
         }
         ast::ItemTy(_, ref generics) => {
-            ty_generic_bounds_for_type_or_impl(ccx, &scheme.generics, generics)
+            ty_generic_predicates_for_type_or_impl(ccx, generics)
         }
         ast::ItemEnum(_, ref generics) => {
-            ty_generic_bounds_for_type_or_impl(ccx, &scheme.generics, generics)
+            ty_generic_predicates_for_type_or_impl(ccx, generics)
         }
         ast::ItemStruct(_, ref generics) => {
-            ty_generic_bounds_for_type_or_impl(ccx, &scheme.generics, generics)
+            ty_generic_predicates_for_type_or_impl(ccx, generics)
         }
+        ast::ItemDefaultImpl(..) |
         ast::ItemTrait(..) |
         ast::ItemExternCrate(..) |
         ast::ItemUse(..) |
@@ -1192,8 +1453,8 @@ fn convert_typed_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
         ast::ItemMac(..) => {
             tcx.sess.span_bug(
                 it.span,
-                format!("compute_type_scheme_of_item: unexpected item type: {:?}",
-                        it.node).as_slice());
+                &format!("compute_type_scheme_of_item: unexpected item type: {:?}",
+                         it.node));
         }
     };
 
@@ -1209,7 +1470,7 @@ fn convert_typed_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
                                      Some(ty::ObjectLifetimeDefault::Specific(r)) =>
                                          r.user_string(tcx),
                                      d =>
-                                         d.repr(ccx.tcx()),
+                                         d.repr(ccx.tcx),
                                  })
                                  .collect::<Vec<String>>()
                                  .connect(",");
@@ -1221,18 +1482,18 @@ fn convert_typed_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
 }
 
 fn type_scheme_of_foreign_item<'a, 'tcx>(
-    ccx: &CollectCtxt<'a, 'tcx>,
+    ccx: &CrateCtxt<'a, 'tcx>,
     it: &ast::ForeignItem,
     abi: abi::Abi)
     -> ty::TypeScheme<'tcx>
 {
-    memoized(&ccx.tcx().tcache,
+    memoized(&ccx.tcx.tcache,
              local_def(it.id),
              |_| compute_type_scheme_of_foreign_item(ccx, it, abi))
 }
 
 fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
-    ccx: &CollectCtxt<'a, 'tcx>,
+    ccx: &CrateCtxt<'a, 'tcx>,
     it: &ast::ForeignItem,
     abi: abi::Abi)
     -> ty::TypeScheme<'tcx>
@@ -1244,13 +1505,13 @@ fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
         ast::ForeignItemStatic(ref t, _) => {
             ty::TypeScheme {
                 generics: ty::Generics::empty(),
-                ty: ast_ty_to_ty(ccx, &ExplicitRscope, t)
+                ty: ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
             }
         }
     }
 }
 
-fn convert_foreign_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
+fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                   it: &ast::ForeignItem)
 {
     // For reasons I cannot fully articulate, I do so hate the AST
@@ -1265,10 +1526,7 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
 
     let predicates = match it.node {
         ast::ForeignItemFn(_, ref generics) => {
-            ty_generic_bounds_for_fn_or_method(ccx,
-                                               generics,
-                                               &scheme.generics,
-                                               ty::GenericPredicates::empty())
+            ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
         }
         ast::ForeignItemStatic(..) => {
             ty::GenericPredicates::empty()
@@ -1279,45 +1537,29 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
     assert!(prev_predicates.is_none());
 }
 
-fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
+fn ty_generics_for_type_or_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                           generics: &ast::Generics)
                                           -> ty::Generics<'tcx> {
-    ty_generics(ccx,
-                subst::TypeSpace,
-                &generics.lifetimes[],
-                &generics.ty_params[],
-                &generics.where_clause,
-                ty::Generics::empty())
+    ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty())
 }
 
-fn ty_generic_bounds_for_type_or_impl<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
-                                               ty_generics: &ty::Generics<'tcx>,
-                                               generics: &ast::Generics)
-                                               -> ty::GenericPredicates<'tcx>
+fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
+                                                   generics: &ast::Generics)
+                                                   -> ty::GenericPredicates<'tcx>
 {
-    ty_generic_bounds(ccx,
-                      subst::TypeSpace,
-                      ty_generics,
-                      ty::GenericPredicates::empty(),
-                      &generics.where_clause)
+    ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
 }
 
-fn ty_generics_for_trait<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
+fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                    trait_id: ast::NodeId,
-                                   substs: &'tcx subst::Substs<'tcx>,
+                                   substs: &'tcx Substs<'tcx>,
                                    ast_generics: &ast::Generics)
                                    -> ty::Generics<'tcx>
 {
     debug!("ty_generics_for_trait(trait_id={}, substs={})",
            local_def(trait_id).repr(ccx.tcx), substs.repr(ccx.tcx));
 
-    let mut generics =
-        ty_generics(ccx,
-                    subst::TypeSpace,
-                    &ast_generics.lifetimes[],
-                    &ast_generics.ty_params[],
-                    &ast_generics.where_clause,
-                    ty::Generics::empty());
+    let mut generics = ty_generics_for_type_or_impl(ccx, ast_generics);
 
     // Add in the self type parameter.
     //
@@ -1325,65 +1567,46 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
     // the node id for the Self type parameter.
     let param_id = trait_id;
 
-    let self_trait_ref =
-        Rc::new(ty::TraitRef { def_id: local_def(trait_id),
-                               substs: substs });
-
     let def = ty::TypeParameterDef {
-        space: subst::SelfSpace,
+        space: SelfSpace,
         index: 0,
         name: special_idents::type_self.name,
         def_id: local_def(param_id),
-        bounds: ty::ParamBounds {
-            region_bounds: vec!(),
-            builtin_bounds: ty::empty_builtin_bounds(),
-            trait_bounds: vec!(ty::Binder(self_trait_ref.clone())),
-            projection_bounds: vec!(),
-        },
         default: None,
         object_lifetime_default: None,
     };
 
     ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
 
-    generics.types.push(subst::SelfSpace, def);
+    generics.types.push(SelfSpace, def);
 
     return generics;
 }
 
-fn ty_generics_for_fn_or_method<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
-                                         generics: &ast::Generics,
-                                         base_generics: ty::Generics<'tcx>)
-                                         -> ty::Generics<'tcx>
+fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
+                               generics: &ast::Generics,
+                               base_generics: &ty::Generics<'tcx>)
+                               -> ty::Generics<'tcx>
 {
-    let early_lifetimes = resolve_lifetime::early_bound_lifetimes(generics);
-    ty_generics(ccx,
-                subst::FnSpace,
-                &early_lifetimes[..],
-                &generics.ty_params[],
-                &generics.where_clause,
-                base_generics)
+    ty_generics(ccx, FnSpace, generics, base_generics)
 }
 
-fn ty_generic_bounds_for_fn_or_method<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
-                                               generics: &ast::Generics,
-                                               ty_generics: &ty::Generics<'tcx>,
-                                               base: ty::GenericPredicates<'tcx>)
-                                               -> ty::GenericPredicates<'tcx>
+fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
+                                         generics: &ast::Generics,
+                                         base_predicates: &ty::GenericPredicates<'tcx>)
+                                         -> ty::GenericPredicates<'tcx>
 {
-    ty_generic_bounds(ccx,
-                      subst::FnSpace,
-                      ty_generics,
-                      base,
-                      &generics.where_clause)
+    ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
 }
 
 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
-fn add_unsized_bound<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
-                              bounds: &mut ty::BuiltinBounds,
-                              ast_bounds: &[ast::TyParamBound],
-                              span: Span)
+fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx>,
+                           bounds: &mut ty::BuiltinBounds,
+                           ast_bounds: &[ast::TyParamBound],
+                           span: Span)
 {
+    let tcx = astconv.tcx();
+
     // Try to find an unbound in bounds.
     let mut unbound = None;
     for ab in ast_bounds {
@@ -1392,80 +1615,108 @@ fn add_unsized_bound<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
                 assert!(ptr.bound_lifetimes.is_empty());
                 unbound = Some(ptr.trait_ref.clone());
             } else {
-                span_err!(ccx.tcx.sess, span, E0203,
+                span_err!(tcx.sess, span, E0203,
                           "type parameter has more than one relaxed default \
                                                 bound, only one is supported");
             }
         }
     }
 
-    let kind_id = ccx.tcx.lang_items.require(SizedTraitLangItem);
+    let kind_id = tcx.lang_items.require(SizedTraitLangItem);
     match unbound {
         Some(ref tpb) => {
             // FIXME(#8559) currently requires the unbound to be built-in.
-            let trait_def_id = ty::trait_ref_to_def_id(ccx.tcx, tpb);
+            let trait_def_id = ty::trait_ref_to_def_id(tcx, tpb);
             match kind_id {
                 Ok(kind_id) if trait_def_id != kind_id => {
-                    ccx.tcx.sess.span_warn(span,
-                                              "default bound relaxed for a type parameter, but \
-                                               this does nothing because the given bound is not \
-                                               a default. Only `?Sized` is supported");
-                    ty::try_add_builtin_trait(ccx.tcx,
-                                              kind_id,
-                                              bounds);
+                    tcx.sess.span_warn(span,
+                                       "default bound relaxed for a type parameter, but \
+                                       this does nothing because the given bound is not \
+                                       a default. Only `?Sized` is supported");
+                    ty::try_add_builtin_trait(tcx, kind_id, bounds);
                 }
                 _ => {}
             }
         }
         _ if kind_id.is_ok() => {
-            ty::try_add_builtin_trait(ccx.tcx, kind_id.unwrap(), bounds);
+            ty::try_add_builtin_trait(tcx, kind_id.unwrap(), bounds);
         }
         // No lang item for Sized, so we can't add it as a bound.
         None => {}
     }
 }
 
-fn ty_generic_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
-                              space: subst::ParamSpace,
-                              generics: &ty::Generics<'tcx>,
-                              base: ty::GenericPredicates<'tcx>,
-                              where_clause: &ast::WhereClause)
-                              -> ty::GenericPredicates<'tcx>
+/// Returns the early-bound lifetimes declared in this generics
+/// listing.  For anything other than fns/methods, this is just all
+/// the lifetimes that are declared. For fns or methods, we have to
+/// screen out those that do not appear in any where-clauses etc using
+/// `resolve_lifetime::early_bound_lifetimes`.
+fn early_bound_lifetimes_from_generics(space: ParamSpace,
+                                       ast_generics: &ast::Generics)
+                                       -> Vec<ast::LifetimeDef>
+{
+    match space {
+        SelfSpace | TypeSpace => ast_generics.lifetimes.to_vec(),
+        FnSpace => resolve_lifetime::early_bound_lifetimes(ast_generics),
+    }
+}
+
+fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
+                                  space: ParamSpace,
+                                  ast_generics: &ast::Generics,
+                                  base_predicates: &ty::GenericPredicates<'tcx>)
+                                  -> ty::GenericPredicates<'tcx>
 {
     let tcx = ccx.tcx;
-    let mut result = base;
-
-    // For now, scrape the bounds out of parameters from Generics. This is not great.
-    for def in generics.regions.get_slice(space) {
-        let r_a = def.to_early_bound_region();
-        for &r_b in &def.bounds {
-            let outlives = ty::Binder(ty::OutlivesPredicate(r_a, r_b));
-            result.predicates.push(def.space, ty::Predicate::RegionOutlives(outlives));
-        }
+    let mut result = base_predicates.clone();
+
+    // Collect the predicates that were written inline by the user on each
+    // type parameter (e.g., `<T:Foo>`).
+    for (index, param) in ast_generics.ty_params.iter().enumerate() {
+        let index = index as u32;
+        let param_ty = ty::ParamTy::new(space, index, param.ident.name).to_ty(ccx.tcx);
+        let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
+                                    param_ty,
+                                    &param.bounds,
+                                    SizedByDefault::Yes,
+                                    param.span);
+        let predicates = ty::predicates(ccx.tcx, param_ty, &bounds);
+        result.predicates.extend(space, predicates.into_iter());
     }
-    for def in generics.types.get_slice(space) {
-        let t = ty::mk_param_from_def(ccx.tcx, def);
-        result.predicates.extend(def.space, ty::predicates(ccx.tcx, t, &def.bounds).into_iter());
+
+    // Collect the region predicates that were declared inline as
+    // well. In the case of parameters declared on a fn or method, we
+    // have to be careful to only iterate over early-bound regions.
+    let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
+    for (index, param) in early_lifetimes.iter().enumerate() {
+        let index = index as u32;
+        let region = ty::ReEarlyBound(param.lifetime.id, space, index, param.lifetime.name);
+        for bound in &param.bounds {
+            let bound_region = ast_region_to_region(ccx.tcx, bound);
+            let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
+            result.predicates.push(space, outlives.as_predicate());
+        }
     }
 
-    // Add the bounds not associated with a type parameter
+    // Add in the bounds that appear in the where-clause
+    let where_clause = &ast_generics.where_clause;
     for predicate in &where_clause.predicates {
         match predicate {
             &ast::WherePredicate::BoundPredicate(ref bound_pred) => {
-                let ty = ast_ty_to_ty(ccx, &ExplicitRscope, &*bound_pred.bounded_ty);
+                let ty = ast_ty_to_ty(&ccx.icx(&(base_predicates, ast_generics)),
+                                      &ExplicitRscope,
+                                      &*bound_pred.bounded_ty);
 
                 for bound in &*bound_pred.bounds {
                     match bound {
                         &ast::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
                             let mut projections = Vec::new();
 
-                            let trait_ref = astconv::instantiate_poly_trait_ref(
-                                ccx,
-                                &ExplicitRscope,
-                                poly_trait_ref,
-                                Some(ty),
-                                &mut projections,
-                            );
+                            let trait_ref =
+                                conv_poly_trait_ref(&ccx.icx(&(base_predicates, ast_generics)),
+                                                    ty,
+                                                    poly_trait_ref,
+                                                    &mut projections);
 
                             result.predicates.push(space, trait_ref.as_predicate());
 
@@ -1504,18 +1755,17 @@ fn ty_generic_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
     return result;
 }
 
-fn ty_generics<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
-                        space: subst::ParamSpace,
-                        lifetime_defs: &[ast::LifetimeDef],
-                        types: &[ast::TyParam],
-                        where_clause: &ast::WhereClause,
-                        base_generics: ty::Generics<'tcx>)
+fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
+                        space: ParamSpace,
+                        ast_generics: &ast::Generics,
+                        base_generics: &ty::Generics<'tcx>)
                         -> ty::Generics<'tcx>
 {
     let tcx = ccx.tcx;
-    let mut result = base_generics;
+    let mut result = base_generics.clone();
 
-    for (i, l) in lifetime_defs.iter().enumerate() {
+    let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
+    for (i, l) in early_lifetimes.iter().enumerate() {
         let bounds = l.bounds.iter()
                              .map(|l| ast_region_to_region(tcx, l))
                              .collect();
@@ -1524,16 +1774,14 @@ fn ty_generics<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
                                            index: i as u32,
                                            def_id: local_def(l.lifetime.id),
                                            bounds: bounds };
-        // debug!("ty_generics: def for region param: {:?}",
-        //        def.repr(tcx));
         result.regions.push(space, def);
     }
 
     assert!(result.types.is_empty_in(space));
 
     // Now create the real type parameters.
-    for (i, param) in types.iter().enumerate() {
-        let def = get_or_create_type_parameter_def(ccx, space, param, i as u32, where_clause);
+    for i in 0..ast_generics.ty_params.len() {
+        let def = get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32);
         debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
         result.types.push(space, def);
     }
@@ -1541,29 +1789,24 @@ fn ty_generics<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
     result
 }
 
-fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
-                                             space: subst::ParamSpace,
-                                             param: &ast::TyParam,
-                                             index: u32,
-                                             where_clause: &ast::WhereClause)
+fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
+                                             ast_generics: &ast::Generics,
+                                             space: ParamSpace,
+                                             index: u32)
                                              -> ty::TypeParameterDef<'tcx>
 {
+    let param = &ast_generics.ty_params[index as usize];
+
     let tcx = ccx.tcx;
     match tcx.ty_param_defs.borrow().get(&param.id) {
         Some(d) => { return d.clone(); }
         None => { }
     }
 
-    let param_ty = ty::ParamTy::new(space, index, param.ident.name);
-    let bounds = compute_bounds(ccx,
-                                param_ty.to_ty(ccx.tcx),
-                                &param.bounds[],
-                                SizedByDefault::Yes,
-                                param.span);
     let default = match param.default {
         None => None,
         Some(ref path) => {
-            let ty = ast_ty_to_ty(ccx, &ExplicitRscope, &**path);
+            let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &**path);
             let cur_idx = index;
 
             ty::walk_ty(ty, |t| {
@@ -1582,14 +1825,14 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
     };
 
     let object_lifetime_default =
-        compute_object_lifetime_default(ccx, space, index, &param.bounds, where_clause);
+        compute_object_lifetime_default(ccx, param.id,
+                                        &param.bounds, &ast_generics.where_clause);
 
     let def = ty::TypeParameterDef {
         space: space,
         index: index,
         name: param.ident.name,
         def_id: local_def(param.id),
-        bounds: bounds,
         default: default,
         object_lifetime_default: object_lifetime_default,
     };
@@ -1605,15 +1848,14 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
 /// intentionally avoid just asking astconv to convert all the where
 /// clauses into a `ty::Predicate`. This is because that could induce
 /// artificial cycles.
-fn compute_object_lifetime_default<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
-                                            space: subst::ParamSpace,
-                                            index: u32,
+fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
+                                            param_id: ast::NodeId,
                                             param_bounds: &[ast::TyParamBound],
                                             where_clause: &ast::WhereClause)
                                             -> Option<ty::ObjectLifetimeDefault>
 {
     let inline_bounds = from_bounds(ccx, param_bounds);
-    let where_bounds = from_predicates(ccx, space, index, &where_clause.predicates);
+    let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
     let all_bounds: HashSet<_> = inline_bounds.into_iter()
                                               .chain(where_bounds.into_iter())
                                               .collect();
@@ -1625,7 +1867,7 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
                   .map(ty::ObjectLifetimeDefault::Specific)
     };
 
-    fn from_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
+    fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                             bounds: &[ast::TyParamBound])
                             -> Vec<ty::Region>
     {
@@ -1635,15 +1877,14 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
                       ast::TraitTyParamBound(..) =>
                           None,
                       ast::RegionTyParamBound(ref lifetime) =>
-                          Some(astconv::ast_region_to_region(ccx.tcx(), lifetime)),
+                          Some(astconv::ast_region_to_region(ccx.tcx, lifetime)),
                   }
               })
               .collect()
     }
 
-    fn from_predicates<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
-                                space: subst::ParamSpace,
-                                index: u32,
+    fn from_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
+                                param_id: ast::NodeId,
                                 predicates: &[ast::WherePredicate])
                                 -> Vec<ty::Region>
     {
@@ -1652,7 +1893,7 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
                       match *predicate {
                           ast::WherePredicate::BoundPredicate(ref data) => {
                               if data.bound_lifetimes.len() == 0 &&
-                                  is_param(ccx, &data.bounded_ty, space, index)
+                                  is_param(ccx.tcx, &data.bounded_ty, param_id)
                               {
                                   from_bounds(ccx, &data.bounds).into_iter()
                               } else {
@@ -1667,58 +1908,30 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
                   })
                   .collect()
     }
-
-    fn is_param(ccx: &CollectCtxt,
-                ast_ty: &ast::Ty,
-                space: subst::ParamSpace,
-                index: u32)
-                -> bool
-    {
-        match ast_ty.node {
-            ast::TyPath(_, id) => {
-                match ccx.tcx.def_map.borrow()[id] {
-                    def::DefTyParam(s, i, _, _) => {
-                        space == s && index == i
-                    }
-                    _ => {
-                        false
-                    }
-                }
-            }
-            _ => {
-                false
-            }
-        }
-    }
 }
 
-enum SizedByDefault { Yes, No }
+enum SizedByDefault { Yes, No, }
 
 /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
 /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
 /// built-in trait (formerly known as kind): Send.
-fn compute_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
-                           param_ty: ty::Ty<'tcx>,
-                           ast_bounds: &[ast::TyParamBound],
-                           sized_by_default: SizedByDefault,
-                           span: Span)
-                           -> ty::ParamBounds<'tcx>
+fn compute_bounds<'tcx>(astconv: &AstConv<'tcx>,
+                        param_ty: ty::Ty<'tcx>,
+                        ast_bounds: &[ast::TyParamBound],
+                        sized_by_default: SizedByDefault,
+                        span: Span)
+                        -> ty::ParamBounds<'tcx>
 {
-    let mut param_bounds = conv_param_bounds(ccx,
+    let mut param_bounds = conv_param_bounds(astconv,
                                              span,
                                              param_ty,
                                              ast_bounds);
 
     if let SizedByDefault::Yes = sized_by_default {
-        add_unsized_bound(ccx,
+        add_unsized_bound(astconv,
                           &mut param_bounds.builtin_bounds,
                           ast_bounds,
                           span);
-
-        check_bounds_compatible(ccx,
-                                param_ty,
-                                &param_bounds,
-                                span);
     }
 
     param_bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
@@ -1726,57 +1939,75 @@ fn compute_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
     param_bounds
 }
 
-fn check_bounds_compatible<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
-                                    param_ty: Ty<'tcx>,
-                                    param_bounds: &ty::ParamBounds<'tcx>,
-                                    span: Span) {
-    if !param_bounds.builtin_bounds.contains(&ty::BoundSized) {
-        ty::each_bound_trait_and_supertraits(
-            ccx.tcx,
-            &param_bounds.trait_bounds[],
-            |trait_ref| {
-                let trait_def = ccx.get_trait_def(trait_ref.def_id());
-                if trait_def.bounds.builtin_bounds.contains(&ty::BoundSized) {
-                    span_err!(ccx.tcx.sess, span, E0129,
-                              "incompatible bounds on `{}`, \
-                               bound `{}` does not allow unsized type",
-                              param_ty.user_string(ccx.tcx),
-                              trait_ref.user_string(ccx.tcx));
-                }
-                true
-            });
+/// Converts a specific TyParamBound from the AST into a set of
+/// predicates that apply to the self-type. A vector is returned
+/// because this can be anywhere from 0 predicates (`T:?Sized` adds no
+/// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
+/// and `<T as Bar>::X == i32`).
+fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
+                               param_ty: Ty<'tcx>,
+                               bound: &ast::TyParamBound)
+                               -> Vec<ty::Predicate<'tcx>>
+{
+    match *bound {
+        ast::TraitTyParamBound(ref tr, ast::TraitBoundModifier::None) => {
+            let mut projections = Vec::new();
+            let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
+            projections.into_iter()
+                       .map(|p| p.as_predicate())
+                       .chain(Some(pred.as_predicate()).into_iter())
+                       .collect()
+        }
+        ast::RegionTyParamBound(ref lifetime) => {
+            let region = ast_region_to_region(astconv.tcx(), lifetime);
+            let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
+            vec![ty::Predicate::TypeOutlives(pred)]
+        }
+        ast::TraitTyParamBound(_, ast::TraitBoundModifier::Maybe) => {
+            Vec::new()
+        }
     }
 }
 
-fn conv_param_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
+fn conv_poly_trait_ref<'tcx>(astconv: &AstConv<'tcx>,
+                             param_ty: Ty<'tcx>,
+                             trait_ref: &ast::PolyTraitRef,
+                             projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
+                             -> ty::PolyTraitRef<'tcx>
+{
+    astconv::instantiate_poly_trait_ref(astconv,
+                                        &ExplicitRscope,
+                                        trait_ref,
+                                        Some(param_ty),
+                                        projections)
+}
+
+fn conv_param_bounds<'a,'tcx>(astconv: &AstConv<'tcx>,
                               span: Span,
                               param_ty: ty::Ty<'tcx>,
                               ast_bounds: &[ast::TyParamBound])
                               -> ty::ParamBounds<'tcx>
 {
-    let tcx = ccx.tcx;
+    let tcx = astconv.tcx();
     let astconv::PartitionedBounds {
         builtin_bounds,
         trait_bounds,
         region_bounds
-    } = astconv::partition_bounds(tcx, span, ast_bounds.as_slice());
+    } = astconv::partition_bounds(tcx, span, &ast_bounds);
 
     let mut projection_bounds = Vec::new();
 
     let trait_bounds: Vec<ty::PolyTraitRef> =
-        trait_bounds.into_iter()
-        .map(|bound| {
-            astconv::instantiate_poly_trait_ref(ccx,
-                                                &ExplicitRscope,
-                                                bound,
-                                                Some(param_ty),
-                                                &mut projection_bounds)
-        })
-    .collect();
+        trait_bounds.iter()
+                    .map(|bound| conv_poly_trait_ref(astconv,
+                                                     param_ty,
+                                                     *bound,
+                                                     &mut projection_bounds))
+                    .collect();
 
     let region_bounds: Vec<ty::Region> =
         region_bounds.into_iter()
-                     .map(|r| ast_region_to_region(ccx.tcx, r))
+                     .map(|r| ast_region_to_region(tcx, r))
                      .collect();
 
     ty::ParamBounds {
@@ -1788,7 +2019,7 @@ fn conv_param_bounds<'a,'tcx>(ccx: &CollectCtxt<'a,'tcx>,
 }
 
 fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
-    ccx: &CollectCtxt<'a, 'tcx>,
+    ccx: &CrateCtxt<'a, 'tcx>,
     decl: &ast::FnDecl,
     ast_generics: &ast::Generics,
     abi: abi::Abi)
@@ -1805,17 +2036,17 @@ fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
         }
     }
 
-    let ty_generics = ty_generics_for_fn_or_method(ccx, ast_generics, ty::Generics::empty());
+    let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
 
     let rb = BindingRscope::new();
     let input_tys = decl.inputs
                         .iter()
-                        .map(|a| ty_of_arg(ccx, &rb, a, None))
+                        .map(|a| ty_of_arg(&ccx.icx(ast_generics), &rb, a, None))
                         .collect();
 
     let output = match decl.output {
         ast::Return(ref ty) =>
-            ty::FnConverging(ast_ty_to_ty(ccx, &rb, &**ty)),
+            ty::FnConverging(ast_ty_to_ty(&ccx.icx(ast_generics), &rb, &**ty)),
         ast::DefaultReturn(..) =>
             ty::FnConverging(ty::mk_nil(ccx.tcx)),
         ast::NoReturn(..) =>
@@ -1839,9 +2070,9 @@ fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
     }
 }
 
-fn mk_item_substs<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
+fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                             ty_generics: &ty::Generics<'tcx>)
-                            -> subst::Substs<'tcx>
+                            -> Substs<'tcx>
 {
     let types =
         ty_generics.types.map(
@@ -1851,7 +2082,7 @@ fn mk_item_substs<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
         ty_generics.regions.map(
             |def| def.to_early_bound_region());
 
-    subst::Substs::new(types, regions)
+    Substs::new(types, regions)
 }
 
 /// Verifies that the explicit self type of a method matches the impl
@@ -1861,15 +2092,16 @@ fn mk_item_substs<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>,
 /// comes back to check after the fact that explicit type the user
 /// wrote actually matches what the pre-defined option said.
 fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
-    ccx: &CollectCtxt<'a, 'tcx>,
+    ccx: &CrateCtxt<'a, 'tcx>,
     rs: &RS,
+    method_type: Rc<ty::Method<'tcx>>,
     required_type: Ty<'tcx>,
     explicit_self: &ast::ExplicitSelf,
     body_id: ast::NodeId)
 {
     let tcx = ccx.tcx;
     if let ast::SelfExplicit(ref ast_type, _) = explicit_self.node {
-        let typ = ccx.to_ty(rs, &**ast_type);
+        let typ = ccx.icx(&method_type.predicates).to_ty(rs, &**ast_type);
         let base_type = match typ.sty {
             ty::ty_ptr(tm) | ty::ty_rptr(_, tm) => tm.ty,
             ty::ty_uniq(typ) => typ,
@@ -1976,18 +2208,10 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
                                      idx: index as u32,
                                      name: ty_param.ident.name };
         if !input_parameters.contains(&param_ty) {
-            if ty::has_attr(tcx, impl_def_id, "old_impl_check") {
-                tcx.sess.span_warn(
-                    ty_param.span,
-                    &format!("the type parameter `{}` is not constrained by the \
-                              impl trait, self type, or predicates",
-                             param_ty.user_string(tcx)));
-            } else {
-                span_err!(tcx.sess, ty_param.span, E0207,
-                    "the type parameter `{}` is not constrained by the \
-                             impl trait, self type, or predicates",
-                            param_ty.user_string(tcx));
-            }
+            span_err!(tcx.sess, ty_param.span, E0207,
+                "the type parameter `{}` is not constrained by the \
+                         impl trait, self type, or predicates",
+                        param_ty.user_string(tcx));
         }
     }
 }
index 17cf92d39d8f542d332f7fab010e401280c7f3fd..a8d93c8bd111a054b8a49bfc9f97c3de14913fd8 100644 (file)
@@ -51,8 +51,6 @@ register_diagnostics! {
     E0075,
     E0076,
     E0077,
-    E0079,
-    E0080,
     E0081,
     E0082,
     E0083,
@@ -80,6 +78,7 @@ register_diagnostics! {
     E0120,
     E0121,
     E0122,
+    E0123,
     E0124,
     E0127,
     E0128,
@@ -171,8 +170,16 @@ register_diagnostics! {
     E0247, // found module name used as a type
     E0248, // found value name used as a type
     E0249, // expected constant expr for array length
-    E0250  // expected constant expr for array length
+    E0250, // expected constant expr for array length
+    E0318, // can't create default impls for traits outside their crates
+    E0319, // trait impls for defaulted traits allowed just for structs/enums
+    E0320, // recursive overflow during dropck
+    E0321, // extended coherence rules for defaulted traits violated
+    E0322, // cannot implement Sized explicitly
+    E0366, // dropck forbid specialization to concrete type or region
+    E0367, // dropck forbid specialization to predicate not in struct/enum
+    E0368, // binary operation `<op>=` cannot be applied to types
+    E0369  // binary operation `<op>` cannot be applied to types
 }
 
 __build_diagnostic_array! { DIAGNOSTICS }
-
index b5dca0bd4f6f42348e2981d23bf079541b91986b..9d6c04b1ad49d90957a2f373b6685f4a4ae15693 100644 (file)
@@ -62,7 +62,8 @@ independently:
 This API is completely unstable and subject to change.
 
 */
-
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rustc_typeck"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
@@ -78,8 +79,6 @@ This API is completely unstable and subject to change.
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(int_uint)]
-#![feature(std_misc)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
@@ -127,12 +126,12 @@ mod constrained_type_params;
 mod coherence;
 mod variance;
 
-struct TypeAndSubsts<'tcx> {
+pub struct TypeAndSubsts<'tcx> {
     pub substs: subst::Substs<'tcx>,
     pub ty: Ty<'tcx>,
 }
 
-struct CrateCtxt<'a, 'tcx: 'a> {
+pub struct CrateCtxt<'a, 'tcx: 'a> {
     // A mapping from method call sites to traits that have that method.
     trait_map: ty::TraitMap,
     /// A vector of every trait accessible in the whole crate
@@ -147,7 +146,7 @@ struct CrateCtxt<'a, 'tcx: 'a> {
 fn write_ty_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>, node_id: ast::NodeId, ty: Ty<'tcx>) {
     debug!("write_ty_to_tcx({}, {})", node_id, ppaux::ty_to_string(tcx, ty));
     assert!(!ty::type_needs_infer(ty));
-    tcx.node_types.borrow_mut().insert(node_id, ty);
+    tcx.node_type_insert(node_id, ty);
 }
 
 fn write_substs_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>,
@@ -163,20 +162,16 @@ fn write_substs_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>,
         tcx.item_substs.borrow_mut().insert(node_id, item_substs);
     }
 }
-fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> def::Def {
+
+fn lookup_full_def(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) -> def::Def {
     match tcx.def_map.borrow().get(&id) {
-        Some(x) => x.clone(),
-        _ => {
+        Some(x) => x.full_def(),
+        None => {
             span_fatal!(tcx.sess, sp, E0242, "internal error looking up a definition")
         }
     }
 }
 
-fn lookup_def_ccx(ccx: &CrateCtxt, sp: Span, id: ast::NodeId)
-                   -> def::Def {
-    lookup_def_tcx(ccx.tcx, sp, id)
-}
-
 fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>,
                                    maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>,
                                    t1_is_expected: bool,
@@ -253,7 +248,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
                               &format!("main has a non-function type: found \
                                        `{}`",
                                       ppaux::ty_to_string(tcx,
-                                                       main_t))[]);
+                                                       main_t)));
         }
     }
 }
@@ -285,10 +280,10 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
                 abi: abi::Rust,
                 sig: ty::Binder(ty::FnSig {
                     inputs: vec!(
-                        tcx.types.int,
+                        tcx.types.isize,
                         ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, tcx.types.u8))
                     ),
-                    output: ty::FnConverging(tcx.types.int),
+                    output: ty::FnConverging(tcx.types.isize),
                     variadic: false,
                 }),
             }));
@@ -304,7 +299,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
             tcx.sess.span_bug(start_span,
                               &format!("start has a non-function type: found \
                                        `{}`",
-                                      ppaux::ty_to_string(tcx, start_t))[]);
+                                      ppaux::ty_to_string(tcx, start_t)));
         }
     }
 }
index b591209a6383a8685ff78d550650c43c1cf55001..c908e21626e56eaa33c616f1ed044210a3ebdc3d 100644 (file)
@@ -29,8 +29,8 @@ use syntax::codemap::Span;
 pub trait RegionScope {
     fn anon_regions(&self,
                     span: Span,
-                    count: uint)
-                    -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>;
+                    count: usize)
+                    -> Result<Vec<ty::Region>, Option<Vec<(String, usize)>>>;
 
     /// If an object omits any explicit lifetime bound, and none can
     /// be derived from the object traits, what should we use? If
@@ -40,7 +40,7 @@ pub trait RegionScope {
 
 // A scope in which all regions must be explicitly named. This is used
 // for types that appear in structs and so on.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct ExplicitRscope;
 
 impl RegionScope for ExplicitRscope {
@@ -50,17 +50,17 @@ impl RegionScope for ExplicitRscope {
 
     fn anon_regions(&self,
                     _span: Span,
-                    _count: uint)
-                    -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>> {
+                    _count: usize)
+                    -> Result<Vec<ty::Region>, Option<Vec<(String, usize)>>> {
         Err(None)
     }
 }
 
 // Same as `ExplicitRscope`, but provides some extra information for diagnostics
-pub struct UnelidableRscope(Vec<(String, uint)>);
+pub struct UnelidableRscope(Vec<(String, usize)>);
 
 impl UnelidableRscope {
-    pub fn new(v: Vec<(String, uint)>) -> UnelidableRscope {
+    pub fn new(v: Vec<(String, usize)>) -> UnelidableRscope {
         UnelidableRscope(v)
     }
 }
@@ -72,8 +72,8 @@ impl RegionScope for UnelidableRscope {
 
     fn anon_regions(&self,
                     _span: Span,
-                    _count: uint)
-                    -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>> {
+                    _count: usize)
+                    -> Result<Vec<ty::Region>, Option<Vec<(String, usize)>>> {
         let UnelidableRscope(ref v) = *self;
         Err(Some(v.clone()))
     }
@@ -103,8 +103,8 @@ impl RegionScope for ElidableRscope {
 
     fn anon_regions(&self,
                     _span: Span,
-                    count: uint)
-                    -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
+                    count: usize)
+                    -> Result<Vec<ty::Region>, Option<Vec<(String, usize)>>>
     {
         Ok(repeat(self.default).take(count).collect())
     }
@@ -140,8 +140,8 @@ impl RegionScope for BindingRscope {
 
     fn anon_regions(&self,
                     _: Span,
-                    count: uint)
-                    -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
+                    count: usize)
+                    -> Result<Vec<ty::Region>, Option<Vec<(String, usize)>>>
     {
         Ok((0..count).map(|_| self.next_region()).collect())
     }
@@ -176,8 +176,8 @@ impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> {
 
     fn anon_regions(&self,
                     span: Span,
-                    count: uint)
-                    -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
+                    count: usize)
+                    -> Result<Vec<ty::Region>, Option<Vec<(String, usize)>>>
     {
         self.base_scope.anon_regions(span, count)
     }
@@ -203,8 +203,8 @@ impl<'r> RegionScope for ShiftedRscope<'r> {
 
     fn anon_regions(&self,
                     span: Span,
-                    count: uint)
-                    -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
+                    count: usize)
+                    -> Result<Vec<ty::Region>, Option<Vec<(String, usize)>>>
     {
         match self.base_scope.anon_regions(span, count) {
             Ok(mut v) => {
index 1adcf133bf3e0788490204a73c62a4e120497526..b83d8fc6af7fafe60871137dc864d67a66b91e7d 100644 (file)
 //! failure, but rather because the target type `Foo<Y>` is itself just
 //! not well-formed. Basically we get to assume well-formedness of all
 //! types involved before considering variance.
+//!
+//! ### Associated types
+//!
+//! Any trait with an associated type is invariant with respect to all
+//! of its inputs. To see why this makes sense, consider what
+//! subtyping for a trait reference means:
+//!
+//!    <T as Trait> <: <U as Trait>
+//!
+//! means that if I know that `T as Trait`,
+//! I also know that `U as
+//! Trait`. Moreover, if you think of it as
+//! dictionary passing style, it means that
+//! a dictionary for `<T as Trait>` is safe
+//! to use where a dictionary for `<U as
+//! Trait>` is expected.
+//!
+//! The problem is that when you can
+//! project types out from `<T as Trait>`,
+//! the relationship to types projected out
+//! of `<U as Trait>` is completely unknown
+//! unless `T==U` (see #21726 for more
+//! details). Making `Trait` invariant
+//! ensures that this is true.
+//!
+//! *Historical note: we used to preserve this invariant another way,
+//! by tweaking the subtyping rules and requiring that when a type `T`
+//! appeared as part of a projection, that was considered an invariant
+//! location, but this version does away with the need for those
+//! somewhat "special-case-feeling" rules.*
+//!
+//! Another related reason is that if we didn't make traits with
+//! associated types invariant, then projection is no longer a
+//! function with a single result. Consider:
+//!
+//! ```
+//! trait Identity { type Out; fn foo(&self); }
+//! impl<T> Identity for T { type Out = T; ... }
+//! ```
+//!
+//! Now if I have `<&'static () as Identity>::Out`, this can be
+//! validly derived as `&'a ()` for any `'a`:
+//!
+//!    <&'a () as Identity> <: <&'static () as Identity>
+//!    if &'static () < : &'a ()   -- Identity is contravariant in Self
+//!    if 'static : 'a             -- Subtyping rules for relations
+//!
+//! This change otoh means that `<'static () as Identity>::Out` is
+//! always `&'static ()` (which might then be upcast to `'a ()`,
+//! separately). This was helpful in solving #21750.
 
 use self::VarianceTerm::*;
 use self::ParamKind::*;
@@ -245,10 +295,10 @@ pub fn infer_variance(tcx: &ty::ctxt) {
 
 type VarianceTermPtr<'a> = &'a VarianceTerm<'a>;
 
-#[derive(Copy, Debug)]
-struct InferredIndex(uint);
+#[derive(Copy, Clone, Debug)]
+struct InferredIndex(usize);
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum VarianceTerm<'a> {
     ConstantTerm(ty::Variance),
     TransformTerm(VarianceTermPtr<'a>, VarianceTermPtr<'a>),
@@ -286,7 +336,7 @@ struct TermsContext<'a, 'tcx: 'a> {
     inferred_infos: Vec<InferredInfo<'a>> ,
 }
 
-#[derive(Copy, Debug, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 enum ParamKind {
     TypeParam,
     RegionParam,
@@ -296,7 +346,7 @@ struct InferredInfo<'a> {
     item_id: ast::NodeId,
     kind: ParamKind,
     space: ParamSpace,
-    index: uint,
+    index: usize,
     param_id: ast::NodeId,
     term: VarianceTermPtr<'a>,
 
@@ -407,7 +457,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
                     item_id: ast::NodeId,
                     kind: ParamKind,
                     space: ParamSpace,
-                    index: uint,
+                    index: usize,
                     param_id: ast::NodeId) {
         let inf_index = InferredIndex(self.inferred_infos.len());
         let term = self.arena.alloc(InferredTerm(inf_index));
@@ -438,7 +488,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
     fn pick_initial_variance(&self,
                              item_id: ast::NodeId,
                              space: ParamSpace,
-                             index: uint)
+                             index: usize)
                              -> ty::Variance
     {
         match space {
@@ -455,7 +505,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
         }
     }
 
-    fn num_inferred(&self) -> uint {
+    fn num_inferred(&self) -> usize {
         self.inferred_infos.len()
     }
 }
@@ -476,6 +526,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
 
             ast::ItemExternCrate(_) |
             ast::ItemUse(_) |
+            ast::ItemDefaultImpl(..) |
             ast::ItemImpl(..) |
             ast::ItemStatic(..) |
             ast::ItemConst(..) |
@@ -509,7 +560,7 @@ struct ConstraintContext<'a, 'tcx: 'a> {
 
 /// Declares that the variable `decl_id` appears in a location with
 /// variance `variance`.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Constraint<'a> {
     inferred: InferredIndex,
     variance: &'a VarianceTerm<'a>,
@@ -593,9 +644,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
 
             ast::ItemTrait(..) => {
                 let trait_def = ty::lookup_trait_def(tcx, did);
-                let predicates = ty::predicates(tcx, ty::mk_self_type(tcx), &trait_def.bounds);
+                let predicates = ty::lookup_super_predicates(tcx, did);
                 self.add_constraints_from_predicates(&trait_def.generics,
-                                                     &predicates[],
+                                                     predicates.predicates.as_slice(),
                                                      self.covariant);
 
                 let trait_items = ty::trait_items(tcx, did);
@@ -612,7 +663,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
                                 &method.fty.sig,
                                 self.covariant);
                         }
-                        ty::TypeTraitItem(_) => {}
+                        ty::TypeTraitItem(ref data) => {
+                            // Any trait with an associated type is
+                            // invariant with respect to all of its
+                            // inputs. See length discussion in the comment
+                            // on this module.
+                            let projection_ty = ty::mk_projection(tcx,
+                                                                  trait_def.trait_ref.clone(),
+                                                                  data.name);
+                            self.add_constraints_from_ty(&trait_def.generics,
+                                                         projection_ty,
+                                                         self.invariant);
+                        }
                     }
                 }
             }
@@ -626,6 +688,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
             ast::ItemForeignMod(..) |
             ast::ItemTy(..) |
             ast::ItemImpl(..) |
+            ast::ItemDefaultImpl(..) |
             ast::ItemMac(..) => {
             }
         }
@@ -652,7 +715,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
             None => {
                 self.tcx().sess.bug(&format!(
                         "no inferred index entry for {}",
-                        self.tcx().map.node_to_string(param_id))[]);
+                        self.tcx().map.node_to_string(param_id)));
             }
         }
     }
@@ -728,7 +791,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                          item_def_id: ast::DefId,
                          kind: ParamKind,
                          space: ParamSpace,
-                         index: uint)
+                         index: usize)
                          -> VarianceTermPtr<'a> {
         assert_eq!(param_def_id.krate, item_def_id.krate);
 
@@ -847,7 +910,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 self.add_constraints_from_mt(generics, mt, variance);
             }
 
-            ty::ty_uniq(typ) | ty::ty_vec(typ, _) | ty::ty_open(typ) => {
+            ty::ty_uniq(typ) | ty::ty_vec(typ, _) => {
                 self.add_constraints_from_ty(generics, typ, variance);
             }
 
@@ -891,7 +954,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                     trait_def.generics.types.as_slice(),
                     trait_def.generics.regions.as_slice(),
                     trait_ref.substs,
-                    self.invariant);
+                    variance);
             }
 
             ty::ty_trait(ref data) => {
@@ -914,7 +977,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
             }
 
             ty::ty_param(ref data) => {
-                let def_id = generics.types.get(data.space, data.idx as uint).def_id;
+                let def_id = generics.types.get(data.space, data.idx as usize).def_id;
                 assert_eq!(def_id.krate, ast::LOCAL_CRATE);
                 match self.terms_cx.inferred_map.get(&def_id.node) {
                     Some(&index) => {
@@ -941,7 +1004,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 self.tcx().sess.bug(
                     &format!("unexpected type encountered in \
                             variance inference: {}",
-                            ty.repr(self.tcx()))[]);
+                            ty.repr(self.tcx())));
             }
         }
     }
@@ -964,9 +1027,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
         for p in type_param_defs {
             let variance_decl =
                 self.declared_variance(p.def_id, def_id, TypeParam,
-                                       p.space, p.index as uint);
+                                       p.space, p.index as usize);
             let variance_i = self.xform(variance, variance_decl);
-            let substs_ty = *substs.types.get(p.space, p.index as uint);
+            let substs_ty = *substs.types.get(p.space, p.index as usize);
             debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}",
                    variance_decl, variance_i);
             self.add_constraints_from_ty(generics, substs_ty, variance_i);
@@ -975,9 +1038,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
         for p in region_param_defs {
             let variance_decl =
                 self.declared_variance(p.def_id, def_id,
-                                       RegionParam, p.space, p.index as uint);
+                                       RegionParam, p.space, p.index as usize);
             let variance_i = self.xform(variance, variance_decl);
-            let substs_r = *substs.regions().get(p.space, p.index as uint);
+            let substs_r = *substs.regions().get(p.space, p.index as usize);
             self.add_constraints_from_region(generics, substs_r, variance_i);
         }
     }
@@ -996,14 +1059,29 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 }
 
                 ty::Predicate::Equate(ty::Binder(ref data)) => {
-                    self.add_constraints_from_ty(generics, data.0, variance);
-                    self.add_constraints_from_ty(generics, data.1, variance);
+                    // A == B is only true if A and B are the same
+                    // types, not subtypes of one another, so this is
+                    // an invariant position:
+                    self.add_constraints_from_ty(generics, data.0, self.invariant);
+                    self.add_constraints_from_ty(generics, data.1, self.invariant);
                 }
 
                 ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
-                    self.add_constraints_from_ty(generics, data.0, variance);
+                    // Why contravariant on both? Let's consider:
+                    //
+                    // Under what conditions is `(T:'t) <: (U:'u)`,
+                    // meaning that `(T:'t) => (U:'u)`. The answer is
+                    // if `U <: T` or `'u <= 't`. Let's see some examples:
+                    //
+                    //   (T: 'big) => (T: 'small)
+                    //   where 'small <= 'big
+                    //
+                    //   (&'small Foo: 't) => (&'big Foo: 't)
+                    //   where 'small <= 'big
+                    //   note that &'big Foo <: &'small Foo
 
                     let variance_r = self.xform(variance, self.contravariant);
+                    self.add_constraints_from_ty(generics, data.0, variance_r);
                     self.add_constraints_from_region(generics, data.1, variance_r);
                 }
 
@@ -1021,6 +1099,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                                                         &*data.projection_ty.trait_ref,
                                                         variance);
 
+                    // as the equality predicate above, a binder is a
+                    // type equality relation, not a subtyping
+                    // relation
                     self.add_constraints_from_ty(generics, data.ty, self.invariant);
                 }
             }
@@ -1071,7 +1152,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                     .sess
                     .bug(&format!("unexpected region encountered in variance \
                                   inference: {}",
-                                 region.repr(self.tcx()))[]);
+                                 region.repr(self.tcx())));
             }
         }
     }
@@ -1287,4 +1368,3 @@ fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
         (x, ty::Bivariant) | (ty::Bivariant, x) => x,
     }
 }
-
index d1283d6f46bd842ed3a945f5ef3668df9af1e2d8..aa17bf20d74bbe782e0896277a93106ee2225f93 100644 (file)
@@ -46,7 +46,7 @@ pub fn try_inline(cx: &DocContext, id: ast::NodeId, into: Option<ast::Ident>)
         None => return None,
     };
     let def = match tcx.def_map.borrow().get(&id) {
-        Some(def) => *def,
+        Some(d) => d.full_def(),
         None => return None,
     };
     let did = def.def_id();
@@ -147,32 +147,14 @@ pub fn record_extern_fqn(cx: &DocContext, did: ast::DefId, kind: clean::TypeKind
 
 pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt,
                             did: ast::DefId) -> clean::Trait {
-    use clean::TraitMethod;
-
     let def = ty::lookup_trait_def(tcx, did);
     let trait_items = ty::trait_items(tcx, did).clean(cx);
-    let provided = ty::provided_trait_methods(tcx, did);
-    let items = trait_items.into_iter().map(|trait_item| {
-        match trait_item.inner {
-            clean::TyMethodItem(_) => {
-                if provided.iter().any(|a| a.def_id == trait_item.def_id) {
-                    TraitMethod::ProvidedMethod(trait_item)
-                } else {
-                    TraitMethod::RequiredMethod(trait_item)
-                }
-            },
-            clean::AssociatedTypeItem(_) => TraitMethod::TypeTraitItem(trait_item),
-            _ => unreachable!()
-        }
-    });
-    let trait_def = ty::lookup_trait_def(tcx, did);
     let predicates = ty::lookup_predicates(tcx, did);
-    let bounds = trait_def.bounds.clean(cx);
     clean::Trait {
         unsafety: def.unsafety,
         generics: (&def.generics, &predicates, subst::TypeSpace).clean(cx),
-        items: items.collect(),
-        bounds: bounds,
+        items: trait_items,
+        bounds: vec![], // supertraits can be found in the list of predicates
     }
 }
 
@@ -277,26 +259,43 @@ fn build_impls(cx: &DocContext, tcx: &ty::ctxt,
     impls.into_iter().filter_map(|a| a).collect()
 }
 
-fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
+fn build_impl(cx: &DocContext,
+              tcx: &ty::ctxt,
               did: ast::DefId) -> Option<clean::Item> {
     if !cx.inlined.borrow_mut().as_mut().unwrap().insert(did) {
         return None
     }
 
+    let attrs = load_attrs(cx, tcx, did);
     let associated_trait = csearch::get_impl_trait(tcx, did);
-    // If this is an impl for a #[doc(hidden)] trait, be sure to not inline it.
-    match associated_trait {
-        Some(ref t) => {
-            let trait_attrs = load_attrs(cx, tcx, t.def_id);
-            if trait_attrs.iter().any(|a| is_doc_hidden(a)) {
-                return None
-            }
+    if let Some(ref t) = associated_trait {
+        // If this is an impl for a #[doc(hidden)] trait, be sure to not inline
+        let trait_attrs = load_attrs(cx, tcx, t.def_id);
+        if trait_attrs.iter().any(|a| is_doc_hidden(a)) {
+            return None
         }
-        None => {}
     }
 
-    let attrs = load_attrs(cx, tcx, did);
-    let ty = ty::lookup_item_type(tcx, did);
+    // If this is a defaulted impl, then bail out early here
+    if csearch::is_default_impl(&tcx.sess.cstore, did) {
+        return Some(clean::Item {
+            inner: clean::DefaultImplItem(clean::DefaultImpl {
+                // FIXME: this should be decoded
+                unsafety: ast::Unsafety::Normal,
+                trait_: match associated_trait.as_ref().unwrap().clean(cx) {
+                    clean::TraitBound(polyt, _) => polyt.trait_,
+                    clean::RegionBound(..) => unreachable!(),
+                },
+            }),
+            source: clean::Span::empty(),
+            name: None,
+            attrs: attrs,
+            visibility: Some(ast::Inherited),
+            stability: stability::lookup(tcx, did).clean(cx),
+            def_id: did,
+        });
+    }
+
     let predicates = ty::lookup_predicates(tcx, did);
     let trait_items = csearch::get_impl_items(&tcx.sess.cstore, did)
             .iter()
@@ -308,6 +307,9 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
                 if method.vis != ast::Public && associated_trait.is_none() {
                     return None
                 }
+                if method.provided_source.is_some() {
+                    return None
+                }
                 let mut item = method.clean(cx);
                 item.inner = match item.inner.clone() {
                     clean::TyMethodItem(clean::TyMethod {
@@ -345,8 +347,10 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
         }
     }).collect();
     let polarity = csearch::get_impl_polarity(tcx, did);
+    let ty = ty::lookup_item_type(tcx, did);
     return Some(clean::Item {
         inner: clean::ImplItem(clean::Impl {
+            unsafety: ast::Unsafety::Normal, // FIXME: this should be decoded
             derived: clean::detect_derived(&attrs),
             trait_: associated_trait.clean(cx).map(|bound| {
                 match bound {
index 7ef48378af183415d595255c30b3541896a698b3..e0ed83f401945b11d07bfbaf5992fde6b75a3cff 100644 (file)
@@ -11,7 +11,6 @@
 //! This module contains the "cleaned" pieces of the AST, and the functions
 //! that clean them.
 
-pub use self::ImplMethod::*;
 pub use self::Type::*;
 pub use self::PrimitiveType::*;
 pub use self::TypeKind::*;
@@ -24,13 +23,11 @@ pub use self::Attribute::*;
 pub use self::TyParamBound::*;
 pub use self::SelfTy::*;
 pub use self::FunctionRetTy::*;
-pub use self::TraitMethod::*;
 
 use syntax;
 use syntax::abi;
 use syntax::ast;
 use syntax::ast_util;
-use syntax::ast_util::PostExpansionMethod;
 use syntax::attr;
 use syntax::attr::{AttributeMethods, AttrMetaMethods};
 use syntax::codemap;
@@ -49,7 +46,7 @@ use rustc::middle::stability;
 
 use std::rc::Rc;
 use std::u32;
-use std::old_path::Path as FsPath; // Conflicts with Path struct
+use std::path::PathBuf;
 
 use core::DocContext;
 use doctree;
@@ -70,7 +67,7 @@ pub trait Clean<T> {
     fn clean(&self, cx: &DocContext) -> T;
 }
 
-impl<T: Clean<U>, U> Clean<Vec<U>> for Vec<T> {
+impl<T: Clean<U>, U> Clean<Vec<U>> for [T] {
     fn clean(&self, cx: &DocContext) -> Vec<U> {
         self.iter().map(|x| x.clean(cx)).collect()
     }
@@ -118,7 +115,7 @@ impl<T: Clean<U>, U> Clean<Vec<U>> for syntax::owned_slice::OwnedSlice<T> {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Crate {
     pub name: String,
-    pub src: FsPath,
+    pub src: PathBuf,
     pub module: Option<Item>,
     pub externs: Vec<(ast::CrateNum, ExternalCrate)>,
     pub primitives: Vec<PrimitiveType>,
@@ -191,7 +188,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
 
         let src = match cx.input {
             Input::File(ref path) => path.clone(),
-            Input::Str(_) => FsPath::new("") // FIXME: this is wrong
+            Input::Str(_) => PathBuf::new() // FIXME: this is wrong
         };
 
         Crate {
@@ -339,7 +336,8 @@ pub enum ItemEnum {
     ForeignStaticItem(Static),
     MacroItem(Macro),
     PrimitiveItem(PrimitiveType),
-    AssociatedTypeItem(TyParam),
+    AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
+    DefaultImplItem(DefaultImpl),
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@@ -370,6 +368,7 @@ impl Clean<Item> for doctree::Module {
         items.extend(self.traits.iter().map(|x| x.clean(cx)));
         items.extend(self.impls.iter().map(|x| x.clean(cx)));
         items.extend(self.macros.iter().map(|x| x.clean(cx)));
+        items.extend(self.def_traits.iter().map(|x| x.clean(cx)));
 
         // determine if we should display the inner contents or
         // the outer `mod` item for the source code.
@@ -479,11 +478,10 @@ impl<'tcx> Clean<TyParam> for ty::TypeParameterDef<'tcx> {
     fn clean(&self, cx: &DocContext) -> TyParam {
         cx.external_typarams.borrow_mut().as_mut().unwrap()
           .insert(self.def_id, self.name.clean(cx));
-        let bounds = self.bounds.clean(cx);
         TyParam {
             name: self.name.clean(cx),
             did: self.def_id,
-            bounds: bounds,
+            bounds: vec![], // these are filled in from the where-clauses
             default: self.default.clean(cx),
         }
     }
@@ -892,9 +890,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
         // Bounds in the type_params and lifetimes fields are repeated in the predicates
         // field (see rustc_typeck::collect::ty_generics), so remove them.
         let stripped_typarams = gens.types.get_slice(space).iter().map(|tp| {
-            let mut stp = tp.clone();
-            stp.bounds = ty::ParamBounds::empty();
-            stp.clean(cx)
+            tp.clean(cx)
         }).collect::<Vec<_>>();
         let stripped_lifetimes = gens.regions.get_slice(space).iter().map(|rp| {
             let mut srp = rp.clone();
@@ -954,34 +950,26 @@ pub struct Method {
     pub abi: abi::Abi
 }
 
-impl Clean<Item> for ast::Method {
-    fn clean(&self, cx: &DocContext) -> Item {
-        let all_inputs = &self.pe_fn_decl().inputs;
-        let inputs = match self.pe_explicit_self().node {
+impl Clean<Method> for ast::MethodSig {
+    fn clean(&self, cx: &DocContext) -> Method {
+        let all_inputs = &self.decl.inputs;
+        let inputs = match self.explicit_self.node {
             ast::SelfStatic => &**all_inputs,
             _ => &all_inputs[1..]
         };
         let decl = FnDecl {
             inputs: Arguments {
-                values: inputs.iter().map(|x| x.clean(cx)).collect(),
+                values: inputs.clean(cx),
             },
-            output: self.pe_fn_decl().output.clean(cx),
+            output: self.decl.output.clean(cx),
             attrs: Vec::new()
         };
-        Item {
-            name: Some(self.pe_ident().clean(cx)),
-            attrs: self.attrs.clean(cx),
-            source: self.span.clean(cx),
-            def_id: ast_util::local_def(self.id),
-            visibility: self.pe_vis().clean(cx),
-            stability: get_stability(cx, ast_util::local_def(self.id)),
-            inner: MethodItem(Method {
-                generics: self.pe_generics().clean(cx),
-                self_: self.pe_explicit_self().node.clean(cx),
-                unsafety: self.pe_unsafety().clone(),
-                decl: decl,
-                abi: self.pe_abi()
-            }),
+        Method {
+            generics: self.generics.clean(cx),
+            self_: self.explicit_self.node.clean(cx),
+            unsafety: self.unsafety.clone(),
+            decl: decl,
+            abi: self.abi
         }
     }
 }
@@ -995,33 +983,25 @@ pub struct TyMethod {
     pub abi: abi::Abi
 }
 
-impl Clean<Item> for ast::TypeMethod {
-    fn clean(&self, cx: &DocContext) -> Item {
+impl Clean<TyMethod> for ast::MethodSig {
+    fn clean(&self, cx: &DocContext) -> TyMethod {
         let inputs = match self.explicit_self.node {
             ast::SelfStatic => &*self.decl.inputs,
             _ => &self.decl.inputs[1..]
         };
         let decl = FnDecl {
             inputs: Arguments {
-                values: inputs.iter().map(|x| x.clean(cx)).collect(),
+                values: inputs.clean(cx),
             },
             output: self.decl.output.clean(cx),
             attrs: Vec::new()
         };
-        Item {
-            name: Some(self.ident.clean(cx)),
-            attrs: self.attrs.clean(cx),
-            source: self.span.clean(cx),
-            def_id: ast_util::local_def(self.id),
-            visibility: None,
-            stability: get_stability(cx, ast_util::local_def(self.id)),
-            inner: TyMethodItem(TyMethod {
-                unsafety: self.unsafety.clone(),
-                decl: decl,
-                self_: self.explicit_self.node.clean(cx),
-                generics: self.generics.clean(cx),
-                abi: self.abi
-            }),
+        TyMethod {
+            unsafety: self.unsafety.clone(),
+            decl: decl,
+            self_: self.explicit_self.node.clean(cx),
+            generics: self.generics.clean(cx),
+            abi: self.abi
         }
     }
 }
@@ -1169,7 +1149,7 @@ impl Clean<FunctionRetTy> for ast::FunctionRetTy {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Trait {
     pub unsafety: ast::Unsafety,
-    pub items: Vec<TraitMethod>,
+    pub items: Vec<Item>,
     pub generics: Generics,
     pub bounds: Vec<TyParamBound>,
 }
@@ -1208,64 +1188,59 @@ impl Clean<PolyTrait> for ast::PolyTraitRef {
     }
 }
 
-/// An item belonging to a trait, whether a method or associated. Could be named
-/// TraitItem except that's already taken by an exported enum variant.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub enum TraitMethod {
-    RequiredMethod(Item),
-    ProvidedMethod(Item),
-    TypeTraitItem(Item), // an associated type
-}
-
-impl TraitMethod {
-    pub fn is_req(&self) -> bool {
-        match self {
-            &RequiredMethod(..) => true,
-            _ => false,
-        }
-    }
-    pub fn is_def(&self) -> bool {
-        match self {
-            &ProvidedMethod(..) => true,
-            _ => false,
-        }
-    }
-    pub fn is_type(&self) -> bool {
-        match self {
-            &TypeTraitItem(..) => true,
-            _ => false,
-        }
-    }
-    pub fn item<'a>(&'a self) -> &'a Item {
-        match *self {
-            RequiredMethod(ref item) => item,
-            ProvidedMethod(ref item) => item,
-            TypeTraitItem(ref item) => item,
-        }
-    }
-}
-
-impl Clean<TraitMethod> for ast::TraitItem {
-    fn clean(&self, cx: &DocContext) -> TraitMethod {
-        match self {
-            &ast::RequiredMethod(ref t) => RequiredMethod(t.clean(cx)),
-            &ast::ProvidedMethod(ref t) => ProvidedMethod(t.clean(cx)),
-            &ast::TypeTraitItem(ref t) => TypeTraitItem(t.clean(cx)),
+impl Clean<Item> for ast::TraitItem {
+    fn clean(&self, cx: &DocContext) -> Item {
+        let inner = match self.node {
+            ast::MethodTraitItem(ref sig, Some(_)) => {
+                MethodItem(sig.clean(cx))
+            }
+            ast::MethodTraitItem(ref sig, None) => {
+                TyMethodItem(sig.clean(cx))
+            }
+            ast::TypeTraitItem(ref bounds, ref default) => {
+                AssociatedTypeItem(bounds.clean(cx), default.clean(cx))
+            }
+        };
+        Item {
+            name: Some(self.ident.clean(cx)),
+            attrs: self.attrs.clean(cx),
+            source: self.span.clean(cx),
+            def_id: ast_util::local_def(self.id),
+            visibility: None,
+            stability: get_stability(cx, ast_util::local_def(self.id)),
+            inner: inner
         }
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub enum ImplMethod {
-    MethodImplItem(Item),
-    TypeImplItem(Item),
-}
-
-impl Clean<ImplMethod> for ast::ImplItem {
-    fn clean(&self, cx: &DocContext) -> ImplMethod {
-        match self {
-            &ast::MethodImplItem(ref t) => MethodImplItem(t.clean(cx)),
-            &ast::TypeImplItem(ref t) => TypeImplItem(t.clean(cx)),
+impl Clean<Item> for ast::ImplItem {
+    fn clean(&self, cx: &DocContext) -> Item {
+        let inner = match self.node {
+            ast::MethodImplItem(ref sig, _) => {
+                MethodItem(sig.clean(cx))
+            }
+            ast::TypeImplItem(ref ty) => TypedefItem(Typedef {
+                type_: ty.clean(cx),
+                generics: Generics {
+                    lifetimes: Vec::new(),
+                    type_params: Vec::new(),
+                    where_predicates: Vec::new()
+                },
+            }),
+            ast::MacImplItem(_) => {
+                MacroItem(Macro {
+                    source: self.span.to_src(cx),
+                })
+            }
+        };
+        Item {
+            name: Some(self.ident.clean(cx)),
+            source: self.span.clean(cx),
+            attrs: self.attrs.clean(cx),
+            def_id: ast_util::local_def(self.id),
+            visibility: self.vis.clean(cx),
+            stability: get_stability(cx, ast_util::local_def(self.id)),
+            inner: inner
         }
     }
 }
@@ -1344,12 +1319,11 @@ pub enum Type {
         typarams: Option<Vec<TyParamBound>>,
         did: ast::DefId,
     },
-    // I have no idea how to usefully use this.
-    TyParamBinder(ast::NodeId),
     /// For parameterized types, so the consumer of the JSON don't go
     /// looking for types which don't exist anywhere.
     Generic(String),
-    /// Primitives are just the fixed-size numeric types (plus int/uint/float), and char.
+    /// Primitives are the fixed-size numeric types (plus int/usize/float), char,
+    /// arrays, slices, and tuples.
     Primitive(PrimitiveType),
     /// extern "ABI" fn
     BareFunction(Box<BareFunctionDecl>),
@@ -1389,6 +1363,7 @@ pub enum PrimitiveType {
     Bool,
     Str,
     Slice,
+    Array,
     PrimitiveTuple,
 }
 
@@ -1408,12 +1383,12 @@ pub enum TypeKind {
 impl PrimitiveType {
     fn from_str(s: &str) -> Option<PrimitiveType> {
         match s {
-            "isize" | "int" => Some(Isize),
+            "isize" => Some(Isize),
             "i8" => Some(I8),
             "i16" => Some(I16),
             "i32" => Some(I32),
             "i64" => Some(I64),
-            "usize" | "uint" => Some(Usize),
+            "usize" => Some(Usize),
             "u8" => Some(U8),
             "u16" => Some(U16),
             "u32" => Some(U32),
@@ -1423,6 +1398,7 @@ impl PrimitiveType {
             "str" => Some(Str),
             "f32" => Some(F32),
             "f64" => Some(F64),
+            "array" => Some(Array),
             "slice" => Some(Slice),
             "tuple" => Some(PrimitiveTuple),
             _ => None,
@@ -1467,6 +1443,7 @@ impl PrimitiveType {
             Str => "str",
             Bool => "bool",
             Char => "char",
+            Array => "array",
             Slice => "slice",
             PrimitiveTuple => "tuple",
         }
@@ -1496,8 +1473,17 @@ impl Clean<Type> for ast::Ty {
             TyFixedLengthVec(ref ty, ref e) => FixedVector(box ty.clean(cx),
                                                            e.span.to_src(cx)),
             TyTup(ref tys) => Tuple(tys.clean(cx)),
-            TyPath(ref p, id) => {
-                resolve_type(cx, p.clean(cx), id)
+            TyPath(None, ref p) => {
+                resolve_type(cx, p.clean(cx), self.id)
+            }
+            TyPath(Some(ref qself), ref p) => {
+                let mut trait_path = p.clone();
+                trait_path.segments.pop();
+                Type::QPath {
+                    name: p.segments.last().unwrap().identifier.clean(cx),
+                    self_type: box qself.ty.clean(cx),
+                    trait_: box resolve_type(cx, trait_path.clean(cx), self.id)
+                }
             }
             TyObjectSum(ref lhs, ref bounds) => {
                 let lhs_ty = lhs.clean(cx);
@@ -1512,7 +1498,6 @@ impl Clean<Type> for ast::Ty {
             }
             TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
             TyParen(ref ty) => ty.clean(cx),
-            TyQPath(ref qp) => qp.clean(cx),
             TyPolyTraitRef(ref bounds) => {
                 PolyTraitRef(bounds.clean(cx))
             },
@@ -1531,12 +1516,12 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
         match self.sty {
             ty::ty_bool => Primitive(Bool),
             ty::ty_char => Primitive(Char),
-            ty::ty_int(ast::TyIs(_)) => Primitive(Isize),
+            ty::ty_int(ast::TyIs) => Primitive(Isize),
             ty::ty_int(ast::TyI8) => Primitive(I8),
             ty::ty_int(ast::TyI16) => Primitive(I16),
             ty::ty_int(ast::TyI32) => Primitive(I32),
             ty::ty_int(ast::TyI64) => Primitive(I64),
-            ty::ty_uint(ast::TyUs(_)) => Primitive(Usize),
+            ty::ty_uint(ast::TyUs) => Primitive(Usize),
             ty::ty_uint(ast::TyU8) => Primitive(U8),
             ty::ty_uint(ast::TyU16) => Primitive(U16),
             ty::ty_uint(ast::TyU32) => Primitive(U32),
@@ -1619,22 +1604,11 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
             ty::ty_closure(..) => Tuple(vec![]), // FIXME(pcwalton)
 
             ty::ty_infer(..) => panic!("ty_infer"),
-            ty::ty_open(..) => panic!("ty_open"),
             ty::ty_err => panic!("ty_err"),
         }
     }
 }
 
-impl Clean<Type> for ast::QPath {
-    fn clean(&self, cx: &DocContext) -> Type {
-        Type::QPath {
-            name: self.item_path.identifier.clean(cx),
-            self_type: box self.self_type.clean(cx),
-            trait_: box self.trait_ref.clean(cx)
-        }
-    }
-}
-
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum StructField {
     HiddenStructField, // inserted later by strip passes
@@ -1859,10 +1833,10 @@ impl Clean<VariantKind> for ast::VariantKind {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Span {
     pub filename: String,
-    pub loline: uint,
-    pub locol: uint,
-    pub hiline: uint,
-    pub hicol: uint,
+    pub loline: usize,
+    pub locol: usize,
+    pub hiline: usize,
+    pub hicol: usize,
 }
 
 impl Span {
@@ -2111,6 +2085,7 @@ impl Clean<ImplPolarity> for ast::ImplPolarity {
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Impl {
+    pub unsafety: ast::Unsafety,
     pub generics: Generics,
     pub trait_: Option<Type>,
     pub for_: Type,
@@ -2133,15 +2108,11 @@ impl Clean<Item> for doctree::Impl {
             visibility: self.vis.clean(cx),
             stability: self.stab.clean(cx),
             inner: ImplItem(Impl {
+                unsafety: self.unsafety,
                 generics: self.generics.clean(cx),
                 trait_: self.trait_.clean(cx),
                 for_: self.for_.clean(cx),
-                items: self.items.clean(cx).into_iter().map(|ti| {
-                        match ti {
-                            MethodImplItem(i) => i,
-                            TypeImplItem(i) => i,
-                        }
-                    }).collect(),
+                items: self.items.clean(cx),
                 derived: detect_derived(&self.attrs),
                 polarity: Some(self.polarity.clean(cx)),
             }),
@@ -2149,6 +2120,29 @@ impl Clean<Item> for doctree::Impl {
     }
 }
 
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+pub struct DefaultImpl {
+    pub unsafety: ast::Unsafety,
+    pub trait_: Type,
+}
+
+impl Clean<Item> for doctree::DefaultImpl {
+    fn clean(&self, cx: &DocContext) -> Item {
+        Item {
+            name: None,
+            attrs: self.attrs.clean(cx),
+            source: self.whence.clean(cx),
+            def_id: ast_util::local_def(self.id),
+            visibility: Some(ast::Public),
+            stability: None,
+            inner: DefaultImplItem(DefaultImpl {
+                unsafety: self.unsafety,
+                trait_: self.trait_.clean(cx),
+            }),
+        }
+    }
+}
+
 impl Clean<Item> for doctree::ExternCrate {
     fn clean(&self, cx: &DocContext) -> Item {
         Item {
@@ -2169,7 +2163,7 @@ impl Clean<Vec<Item>> for doctree::Import {
         // forcefully don't inline if this is not public or if the
         // #[doc(no_inline)] attribute is present.
         let denied = self.vis != ast::Public || self.attrs.iter().any(|a| {
-            &a.name()[] == "doc" && match a.meta_item_list() {
+            &a.name()[..] == "doc" && match a.meta_item_list() {
                 Some(l) => attr::contains_name(l, "no_inline"),
                 None => false,
             }
@@ -2393,24 +2387,24 @@ fn resolve_type(cx: &DocContext,
     };
     debug!("searching for {} in defmap", id);
     let def = match tcx.def_map.borrow().get(&id) {
-        Some(&k) => k,
+        Some(k) => k.full_def(),
         None => panic!("unresolved id not in defmap")
     };
 
     match def {
-        def::DefSelfTy(..) => {
+        def::DefSelfTy(..) if path.segments.len() == 1 => {
             return Generic(token::get_name(special_idents::type_self.name).to_string());
         }
         def::DefPrimTy(p) => match p {
             ast::TyStr => return Primitive(Str),
             ast::TyBool => return Primitive(Bool),
             ast::TyChar => return Primitive(Char),
-            ast::TyInt(ast::TyIs(_)) => return Primitive(Isize),
+            ast::TyInt(ast::TyIs) => return Primitive(Isize),
             ast::TyInt(ast::TyI8) => return Primitive(I8),
             ast::TyInt(ast::TyI16) => return Primitive(I16),
             ast::TyInt(ast::TyI32) => return Primitive(I32),
             ast::TyInt(ast::TyI64) => return Primitive(I64),
-            ast::TyUint(ast::TyUs(_)) => return Primitive(Usize),
+            ast::TyUint(ast::TyUs) => return Primitive(Usize),
             ast::TyUint(ast::TyU8) => return Primitive(U8),
             ast::TyUint(ast::TyU16) => return Primitive(U16),
             ast::TyUint(ast::TyU32) => return Primitive(U32),
@@ -2418,8 +2412,9 @@ fn resolve_type(cx: &DocContext,
             ast::TyFloat(ast::TyF32) => return Primitive(F32),
             ast::TyFloat(ast::TyF64) => return Primitive(F64),
         },
-        def::DefTyParam(_, _, _, n) => return Generic(token::get_name(n).to_string()),
-        def::DefTyParamBinder(i) => return TyParamBinder(i),
+        def::DefTyParam(_, _, _, n) => {
+            return Generic(token::get_name(n).to_string())
+        }
         _ => {}
     };
     let did = register_def(&*cx, def);
@@ -2460,7 +2455,7 @@ fn resolve_use_source(cx: &DocContext, path: Path, id: ast::NodeId) -> ImportSou
 
 fn resolve_def(cx: &DocContext, id: ast::NodeId) -> Option<ast::DefId> {
     cx.tcx_opt().and_then(|tcx| {
-        tcx.def_map.borrow().get(&id).map(|&def| register_def(cx, def))
+        tcx.def_map.borrow().get(&id).map(|d| register_def(cx, d.full_def()))
     })
 }
 
@@ -2509,37 +2504,15 @@ impl Clean<Stability> for attr::Stability {
     }
 }
 
-impl Clean<Item> for ast::AssociatedType {
-    fn clean(&self, cx: &DocContext) -> Item {
-        Item {
-            source: self.ty_param.span.clean(cx),
-            name: Some(self.ty_param.ident.clean(cx)),
-            attrs: self.attrs.clean(cx),
-            inner: AssociatedTypeItem(self.ty_param.clean(cx)),
-            visibility: None,
-            def_id: ast_util::local_def(self.ty_param.id),
-            stability: None,
-        }
-    }
-}
-
 impl Clean<Item> for ty::AssociatedType {
     fn clean(&self, cx: &DocContext) -> Item {
         Item {
             source: DUMMY_SP.clean(cx),
             name: Some(self.name.clean(cx)),
             attrs: Vec::new(),
-            inner: AssociatedTypeItem(TyParam {
-                name: self.name.clean(cx),
-                did: ast::DefId {
-                    krate: 0,
-                    node: ast::DUMMY_NODE_ID
-                },
-                // FIXME(#20727): bounds are missing and need to be filled in from the
-                // predicates on the trait itself
-                bounds: vec![],
-                default: None,
-            }),
+            // FIXME(#20727): bounds are missing and need to be filled in from the
+            // predicates on the trait itself
+            inner: AssociatedTypeItem(vec![], None),
             visibility: None,
             def_id: self.def_id,
             stability: None,
@@ -2547,27 +2520,6 @@ impl Clean<Item> for ty::AssociatedType {
     }
 }
 
-impl Clean<Item> for ast::Typedef {
-    fn clean(&self, cx: &DocContext) -> Item {
-        Item {
-            source: self.span.clean(cx),
-            name: Some(self.ident.clean(cx)),
-            attrs: self.attrs.clean(cx),
-            inner: TypedefItem(Typedef {
-                type_: self.typ.clean(cx),
-                generics: Generics {
-                    lifetimes: Vec::new(),
-                    type_params: Vec::new(),
-                    where_predicates: Vec::new()
-                },
-            }),
-            visibility: None,
-            def_id: ast_util::local_def(self.id),
-            stability: None,
-        }
-    }
-}
-
 impl<'a> Clean<Typedef> for (ty::TypeScheme<'a>, ty::GenericPredicates<'a>, ParamSpace) {
     fn clean(&self, cx: &DocContext) -> Typedef {
         let (ref ty_scheme, ref predicates, ps) = *self;
index f862970446c14909dd0a2a6568b0c923a3b1fa25..113a622b07ae47cd2430288adc66c86313c02730 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 pub use self::MaybeTyped::*;
 
+use rustc_lint;
 use rustc_driver::driver;
 use rustc::session::{self, config};
 use rustc::session::config::UnstableFeatures;
@@ -114,6 +115,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
 
     let sess = session::build_session_(sessopts, cpath,
                                        span_diagnostic_handler);
+    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
     let cfg = config::build_configuration(&sess);
 
index ba5df56f4fb5655d44762548fe8f53eaf83db88c..c6d8b9428c5751c26a97f79c3b310c2d0fa4693f 100644 (file)
@@ -39,6 +39,7 @@ pub struct Module {
     pub vis: ast::Visibility,
     pub stab: Option<attr::Stability>,
     pub impls: Vec<Impl>,
+    pub def_traits: Vec<DefaultImpl>,
     pub foreigns: Vec<ast::ForeignMod>,
     pub macros: Vec<Macro>,
     pub is_crate: bool,
@@ -65,6 +66,7 @@ impl Module {
             constants  : Vec::new(),
             traits     : Vec::new(),
             impls      : Vec::new(),
+            def_traits : Vec::new(),
             foreigns   : Vec::new(),
             macros     : Vec::new(),
             is_crate   : false,
@@ -172,7 +174,7 @@ pub struct Constant {
 pub struct Trait {
     pub unsafety: ast::Unsafety,
     pub name: Ident,
-    pub items: Vec<ast::TraitItem>, //should be TraitItem
+    pub items: Vec<P<ast::TraitItem>>, //should be TraitItem
     pub generics: ast::Generics,
     pub bounds: Vec<ast::TyParamBound>,
     pub attrs: Vec<ast::Attribute>,
@@ -188,7 +190,7 @@ pub struct Impl {
     pub generics: ast::Generics,
     pub trait_: Option<ast::TraitRef>,
     pub for_: P<ast::Ty>,
-    pub items: Vec<ast::ImplItem>,
+    pub items: Vec<P<ast::ImplItem>>,
     pub attrs: Vec<ast::Attribute>,
     pub whence: Span,
     pub vis: ast::Visibility,
@@ -196,6 +198,14 @@ pub struct Impl {
     pub id: ast::NodeId,
 }
 
+pub struct DefaultImpl {
+    pub unsafety: ast::Unsafety,
+    pub trait_: ast::TraitRef,
+    pub id: ast::NodeId,
+    pub attrs: Vec<ast::Attribute>,
+    pub whence: Span,
+}
+
 pub struct Macro {
     pub name: Ident,
     pub id: ast::NodeId,
index 942aec7d22f2c0bff99a4faaab2fce803e7cb477..57cb87e1b2d011fb7a4c08147bfc1a491e687f8c 100644 (file)
@@ -8,7 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::{old_io, str};
+use std::fs::File;
+use std::io::prelude::*;
+use std::io;
+use std::path::{PathBuf, Path};
+use std::str;
 
 #[derive(Clone)]
 pub struct ExternalHtml{
@@ -33,24 +37,25 @@ impl ExternalHtml {
     }
 }
 
-pub fn load_string(input: &Path) -> old_io::IoResult<Option<String>> {
-    let mut f = try!(old_io::File::open(input));
-    let d = try!(f.read_to_end());
+pub fn load_string(input: &Path) -> io::Result<Option<String>> {
+    let mut f = try!(File::open(input));
+    let mut d = Vec::new();
+    try!(f.read_to_end(&mut d));
     Ok(str::from_utf8(&d).map(|s| s.to_string()).ok())
 }
 
 macro_rules! load_or_return {
     ($input: expr, $cant_read: expr, $not_utf8: expr) => {
         {
-            let input = Path::new($input);
+            let input = PathBuf::from(&$input[..]);
             match ::externalfiles::load_string(&input) {
                 Err(e) => {
-                    let _ = writeln!(&mut old_io::stderr(),
+                    let _ = writeln!(&mut io::stderr(),
                                      "error reading `{}`: {}", input.display(), e);
                     return $cant_read;
                 }
                 Ok(None) => {
-                    let _ = writeln!(&mut old_io::stderr(),
+                    let _ = writeln!(&mut io::stderr(),
                                      "error reading `{}`: not UTF-8", input.display());
                     return $not_utf8;
                 }
index ad91c3cb2c35b60e4b023c655ef8486403ebfd12..760fa329fd9866808f68a7570a4bd2ba48b19c99 100644 (file)
@@ -20,9 +20,11 @@ pub use self::imp::Lock;
 
 #[cfg(unix)]
 mod imp {
-    use std::ffi::CString;
+    use std::ffi::{CString, OsStr};
+    use std::os::unix::prelude::*;
+    use std::path::Path;
+    use std::io;
     use libc;
-    use std::os as stdos;
 
     #[cfg(target_os = "linux")]
     mod os {
@@ -64,7 +66,9 @@ mod imp {
         pub const F_SETLKW: libc::c_int = 13;
     }
 
-    #[cfg(any(target_os = "dragonfly", target_os = "openbsd"))]
+    #[cfg(any(target_os = "dragonfly",
+              target_os = "bitrig",
+              target_os = "openbsd"))]
     mod os {
         use libc;
 
@@ -112,13 +116,14 @@ mod imp {
 
     impl Lock {
         pub fn new(p: &Path) -> Lock {
-            let buf = CString::new(p.as_vec()).unwrap();
+            let os: &OsStr = p.as_ref();
+            let buf = CString::new(os.as_bytes()).unwrap();
             let fd = unsafe {
                 libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT,
                            libc::S_IRWXU)
             };
-            assert!(fd > 0, "failed to open lockfile: [{}] {}",
-                    stdos::errno(), stdos::last_os_error());
+            assert!(fd > 0, "failed to open lockfile: {}",
+                    io::Error::last_os_error());
             let flock = os::flock {
                 l_start: 0,
                 l_len: 0,
@@ -131,10 +136,9 @@ mod imp {
                 libc::fcntl(fd, os::F_SETLKW, &flock)
             };
             if ret == -1 {
-                let errno = stdos::errno();
+                let err = io::Error::last_os_error();
                 unsafe { libc::close(fd); }
-                panic!("could not lock `{}`: [{}] {}", p.display(),
-                       errno, stdos::error_string(errno))
+                panic!("could not lock `{}`: {}", p.display(), err);
             }
             Lock { fd: fd }
         }
@@ -161,11 +165,14 @@ mod imp {
 #[cfg(windows)]
 mod imp {
     use libc;
+    use std::io;
     use std::mem;
-    use std::os;
+    use std::ffi::OsStr;
+    use std::os::windows::prelude::*;
+    use std::path::Path;
     use std::ptr;
 
-    static LOCKFILE_EXCLUSIVE_LOCK: libc::DWORD = 0x00000002;
+    const LOCKFILE_EXCLUSIVE_LOCK: libc::DWORD = 0x00000002;
 
     #[allow(non_snake_case)]
     extern "system" {
@@ -188,7 +195,8 @@ mod imp {
 
     impl Lock {
         pub fn new(p: &Path) -> Lock {
-            let mut p_16: Vec<u16> = p.as_str().unwrap().utf16_units().collect();
+            let os: &OsStr = p.as_ref();
+            let mut p_16: Vec<_> = os.encode_wide().collect();
             p_16.push(0);
             let handle = unsafe {
                 libc::CreateFileW(p_16.as_ptr(),
@@ -203,8 +211,7 @@ mod imp {
                                   ptr::null_mut())
             };
             if handle == libc::INVALID_HANDLE_VALUE {
-                panic!("create file error: [{}] {}",
-                       os::errno(), os::last_os_error());
+                panic!("create file error: {}", io::Error::last_os_error());
             }
             let mut overlapped: libc::OVERLAPPED = unsafe { mem::zeroed() };
             let ret = unsafe {
@@ -212,10 +219,9 @@ mod imp {
                            &mut overlapped)
             };
             if ret == 0 {
-                let errno = os::errno();
+                let err = io::Error::last_os_error();
                 unsafe { libc::CloseHandle(handle); }
-                panic!("could not lock `{}`: [{}] {}", p.display(),
-                       errno, os::error_string(errno));
+                panic!("could not lock `{}`: {}", p.display(), err);
             }
             Lock { handle: handle }
         }
index 4f277cc868a1a04873ed3abbcbc2a04e57e689ae..cdeeacfb78397f0d6bc9028ebbeb093e1bfc6795 100644 (file)
@@ -40,37 +40,13 @@ pub trait DocFolder : Sized {
                 EnumItem(i)
             },
             TraitItem(mut i) => {
-                fn vtrm<T: DocFolder>(this: &mut T, trm: TraitMethod)
-                        -> Option<TraitMethod> {
-                    match trm {
-                        RequiredMethod(it) => {
-                            match this.fold_item(it) {
-                                Some(x) => return Some(RequiredMethod(x)),
-                                None => return None,
-                            }
-                        },
-                        ProvidedMethod(it) => {
-                            match this.fold_item(it) {
-                                Some(x) => return Some(ProvidedMethod(x)),
-                                None => return None,
-                            }
-                        },
-                        TypeTraitItem(it) => {
-                            match this.fold_item(it) {
-                                Some(x) => return Some(TypeTraitItem(x)),
-                                None => return None,
-                            }
-                        }
-                    }
-                }
                 let mut foo = Vec::new(); swap(&mut foo, &mut i.items);
-                i.items.extend(foo.into_iter().filter_map(|x| vtrm(self, x)));
+                i.items.extend(foo.into_iter().filter_map(|x| self.fold_item(x)));
                 TraitItem(i)
             },
             ImplItem(mut i) => {
                 let mut foo = Vec::new(); swap(&mut foo, &mut i.items);
-                i.items.extend(foo.into_iter()
-                                  .filter_map(|x| self.fold_item(x)));
+                i.items.extend(foo.into_iter().filter_map(|x| self.fold_item(x)));
                 ImplItem(i)
             },
             VariantItem(i) => {
index ed7f051408c45894303ab703902b7d49a155d1a6..ed37b973f787ec16e4d9f9497f89732351789657 100644 (file)
@@ -25,23 +25,24 @@ use clean;
 use stability_summary::ModuleSummary;
 use html::item_type::ItemType;
 use html::render;
+use html::escape::Escape;
 use html::render::{cache, CURRENT_LOCATION_KEY};
 
 /// Helper to render an optional visibility with a space after it (if the
 /// visibility is preset)
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct VisSpace(pub Option<ast::Visibility>);
 /// Similarly to VisSpace, this structure is used to render a function style with a
 /// space after it.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct UnsafetySpace(pub ast::Unsafety);
 /// Wrapper struct for properly emitting a method declaration.
 pub struct Method<'a>(pub &'a clean::SelfTy, pub &'a clean::FnDecl);
 /// Similar to VisSpace, but used for mutability
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct MutableSpace(pub clean::Mutability);
 /// Similar to VisSpace, but used for mutability
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct RawMutableSpace(pub clean::Mutability);
 /// Wrapper struct for properly emitting the stability level.
 pub struct Stability<'a>(pub &'a Option<clean::Stability>);
@@ -289,7 +290,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: ast::DefId, p: &clean::Path,
             if ast_util::is_local(did) || cache.inlined.contains(&did) {
                 Some(repeat("../").take(loc.len()).collect::<String>())
             } else {
-                match cache.extern_locations[did.krate] {
+                match cache.extern_locations[&did.krate] {
                     render::Remote(ref s) => Some(s.to_string()),
                     render::Local => {
                         Some(repeat("../").take(loc.len()).collect::<String>())
@@ -403,11 +404,11 @@ fn primitive_link(f: &mut fmt::Formatter,
             needs_termination = true;
         }
         Some(&cnum) => {
-            let path = &m.paths[ast::DefId {
+            let path = &m.paths[&ast::DefId {
                 krate: cnum,
                 node: ast::CRATE_NODE_ID,
             }];
-            let loc = match m.extern_locations[cnum] {
+            let loc = match m.extern_locations[&cnum] {
                 render::Remote(ref s) => Some(s.to_string()),
                 render::Local => {
                     let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len());
@@ -453,9 +454,6 @@ fn tybounds(w: &mut fmt::Formatter,
 impl fmt::Display for clean::Type {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
-            clean::TyParamBinder(id) => {
-                f.write_str(&cache().typarams[ast_util::local_def(id)])
-            }
             clean::Generic(ref name) => {
                 f.write_str(name)
             }
@@ -488,7 +486,7 @@ impl fmt::Display for clean::Type {
                 primitive_link(f, clean::Slice, &format!("[{}]", **t))
             }
             clean::FixedVector(ref t, ref s) => {
-                primitive_link(f, clean::Slice,
+                primitive_link(f, clean::PrimitiveType::Array,
                                &format!("[{}; {}]", **t, *s))
             }
             clean::Bottom => f.write_str("!"),
@@ -710,13 +708,14 @@ impl<'a> fmt::Display for Stability<'a> {
         let Stability(stab) = *self;
         match *stab {
             Some(ref stability) => {
+                let lvl = if stability.deprecated_since.is_empty() {
+                    format!("{}", stability.level)
+                } else {
+                    "Deprecated".to_string()
+                };
                 write!(f, "<a class='stability {lvl}' title='{reason}'>{lvl}</a>",
-                       lvl = if stability.deprecated_since.is_empty() {
-                           format!("{}", stability.level)
-                       } else {
-                           "Deprecated".to_string()
-                       },
-                       reason = stability.reason)
+                       lvl = Escape(&*lvl),
+                       reason = Escape(&*stability.reason))
             }
             None => Ok(())
         }
@@ -728,14 +727,15 @@ impl<'a> fmt::Display for ConciseStability<'a> {
         let ConciseStability(stab) = *self;
         match *stab {
             Some(ref stability) => {
+                let lvl = if stability.deprecated_since.is_empty() {
+                    format!("{}", stability.level)
+                } else {
+                    "Deprecated".to_string()
+                };
                 write!(f, "<a class='stability {lvl}' title='{lvl}{colon}{reason}'></a>",
-                       lvl = if stability.deprecated_since.is_empty() {
-                           format!("{}", stability.level)
-                       } else {
-                           "Deprecated".to_string()
-                       },
+                       lvl = Escape(&*lvl),
                        colon = if stability.reason.len() > 0 { ": " } else { "" },
-                       reason = stability.reason)
+                       reason = Escape(&*stability.reason))
             }
             None => {
                 write!(f, "<a class='stability Unmarked' title='No stability level'></a>")
index 44c0acda66fba8e8c3c0384ae763d970b488fadd..d19ccabed478efdb392b7830ad67def89cbf81f3 100644 (file)
@@ -15,7 +15,8 @@
 
 use html::escape::Escape;
 
-use std::old_io;
+use std::io;
+use std::io::prelude::*;
 use syntax::parse::lexer;
 use syntax::parse::token;
 use syntax::parse;
@@ -46,7 +47,7 @@ pub fn highlight(src: &str, class: Option<&str>, id: Option<&str>) -> String {
 /// source.
 fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
         class: Option<&str>, id: Option<&str>,
-        out: &mut Writer) -> old_io::IoResult<()> {
+        out: &mut Write) -> io::Result<()> {
     use syntax::parse::lexer::Reader;
 
     try!(write!(out, "<pre "));
@@ -142,7 +143,7 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
 
             // keywords are also included in the identifier set
             token::Ident(ident, _is_mod_sep) => {
-                match &token::get_ident(ident)[] {
+                match &token::get_ident(ident)[..] {
                     "ref" | "mut" => "kw-2",
 
                     "self" => "self",
index 356be2ffeb04cf4bebaa3dc22425d8d0a282f509..d2385702a73d2c2c35fc85453890a3c56f7be2c5 100644 (file)
@@ -64,6 +64,7 @@ impl ItemType {
             clean::MacroItem(..)           => ItemType::Macro,
             clean::PrimitiveItem(..)       => ItemType::Primitive,
             clean::AssociatedTypeItem(..)  => ItemType::AssociatedType,
+            clean::DefaultImplItem(..)     => ItemType::Impl,
         }
     }
 
@@ -110,4 +111,3 @@ impl fmt::Display for ItemType {
         self.to_static_str().fmt(f)
     }
 }
-
index c537e370723d7ca2526e0fc2cbbac25c9f7eeb19..3acd17dedd59d986503814984c474860e70d2f78 100644 (file)
@@ -9,7 +9,8 @@
 // except according to those terms.
 
 use std::fmt;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
 
 use externalfiles::ExternalHtml;
 
@@ -31,8 +32,8 @@ pub struct Page<'a> {
 }
 
 pub fn render<T: fmt::Display, S: fmt::Display>(
-    dst: &mut old_io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
-    -> old_io::IoResult<()>
+    dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T)
+    -> io::Result<()>
 {
     write!(dst,
 r##"<!DOCTYPE html>
@@ -159,7 +160,7 @@ r##"<!DOCTYPE html>
     )
 }
 
-pub fn redirect(dst: &mut old_io::Writer, url: &str) -> old_io::IoResult<()> {
+pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
     // <script> triggers a redirect before refresh, so this is fine.
     write!(dst,
 r##"<!DOCTYPE html>
index 7ea5bd569e1996df853eeccd1e550b3a6309e49e..afc434eb2dfdaf62dd6afc7281b669fd73d11972 100644 (file)
@@ -185,7 +185,7 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> {
     }
 }
 
-thread_local!(static USED_HEADER_MAP: RefCell<HashMap<String, uint>> = {
+thread_local!(static USED_HEADER_MAP: RefCell<HashMap<String, usize>> = {
     RefCell::new(HashMap::new())
 });
 
@@ -230,7 +230,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
                         stripped_filtered_line(l).unwrap_or(l)
                     }).collect::<Vec<&str>>().connect("\n");
                     let krate = krate.as_ref().map(|s| &**s);
-                    let test = test::maketest(&test, krate, false, false);
+                    let test = test::maketest(&test, krate, false, false, true);
                     s.push_str(&format!("<span class='rusttest'>{}</span>", Escape(&test)));
                 });
                 s.push_str(&highlight::highlight(&text,
@@ -308,8 +308,8 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
         };
         (*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque
                 = &mut opaque as *mut _ as *mut libc::c_void;
-        (*renderer).blockcode = Some(block as blockcodefn);
-        (*renderer).header = Some(header as headerfn);
+        (*renderer).blockcode = Some(block);
+        (*renderer).header = Some(header);
 
         let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
         hoedown_document_render(document, ob, s.as_ptr(),
@@ -356,7 +356,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
             });
             let text = lines.collect::<Vec<&str>>().connect("\n");
             tests.add_test(text.to_string(),
-                           block_info.should_fail, block_info.no_run,
+                           block_info.should_panic, block_info.no_run,
                            block_info.ignore, block_info.test_harness);
         }
     }
@@ -380,8 +380,8 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
     unsafe {
         let ob = hoedown_buffer_new(DEF_OUNIT);
         let renderer = hoedown_html_renderer_new(0, 0);
-        (*renderer).blockcode = Some(block as blockcodefn);
-        (*renderer).header = Some(header as headerfn);
+        (*renderer).blockcode = Some(block);
+        (*renderer).header = Some(header);
         (*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque
                 = tests as *mut _ as *mut libc::c_void;
 
@@ -397,7 +397,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
 
 #[derive(Eq, PartialEq, Clone, Debug)]
 struct LangString {
-    should_fail: bool,
+    should_panic: bool,
     no_run: bool,
     ignore: bool,
     rust: bool,
@@ -407,7 +407,7 @@ struct LangString {
 impl LangString {
     fn all_false() -> LangString {
         LangString {
-            should_fail: false,
+            should_panic: false,
             no_run: false,
             ignore: false,
             rust: true,  // NB This used to be `notrust = false`
@@ -427,7 +427,7 @@ impl LangString {
         for token in tokens {
             match token {
                 "" => {},
-                "should_fail" => { data.should_fail = true; seen_rust_tags = true; },
+                "should_panic" => { data.should_panic = true; seen_rust_tags = true; },
                 "no_run" => { data.no_run = true; seen_rust_tags = true; },
                 "ignore" => { data.ignore = true; seen_rust_tags = true; },
                 "rust" => { data.rust = true; seen_rust_tags = true; },
@@ -501,10 +501,10 @@ pub fn plain_summary_line(md: &str) -> String {
     unsafe {
         let ob = hoedown_buffer_new(DEF_OUNIT);
         let mut plain_renderer: hoedown_renderer = ::std::mem::zeroed();
-        let renderer = &mut plain_renderer as *mut hoedown_renderer;
+        let renderer: *mut hoedown_renderer = &mut plain_renderer;
         (*renderer).opaque = ob as *mut libc::c_void;
-        (*renderer).link = Some(link as linkfn);
-        (*renderer).normal_text = Some(normal_text as normaltextfn);
+        (*renderer).link = Some(link);
+        (*renderer).normal_text = Some(normal_text);
 
         let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
         hoedown_document_render(document, ob, md.as_ptr(),
@@ -528,9 +528,9 @@ mod tests {
     #[test]
     fn test_lang_string_parse() {
         fn t(s: &str,
-            should_fail: bool, no_run: bool, ignore: bool, rust: bool, test_harness: bool) {
+            should_panic: bool, no_run: bool, ignore: bool, rust: bool, test_harness: bool) {
             assert_eq!(LangString::parse(s), LangString {
-                should_fail: should_fail,
+                should_panic: should_panic,
                 no_run: no_run,
                 ignore: ignore,
                 rust: rust,
@@ -538,16 +538,16 @@ mod tests {
             })
         }
 
-        // marker                | should_fail | no_run | ignore | rust | test_harness
+        // marker                | should_panic| no_run | ignore | rust | test_harness
         t("",                      false,        false,   false,   true,  false);
         t("rust",                  false,        false,   false,   true,  false);
         t("sh",                    false,        false,   false,   false, false);
         t("ignore",                false,        false,   true,    true,  false);
-        t("should_fail",           true,         false,   false,   true,  false);
+        t("should_panic",          true,         false,   false,   true,  false);
         t("no_run",                false,        true,    false,   true,  false);
         t("test_harness",          false,        false,   false,   true,  true);
         t("{.no_run .example}",    false,        true,    false,   true,  false);
-        t("{.sh .should_fail}",    true,         false,   false,   true,  false);
+        t("{.sh .should_panic}",   true,         false,   false,   true,  false);
         t("{.example .rust}",      false,        false,   false,   true,  false);
         t("{.test_harness .rust}", false,        false,   false,   true,  true);
     }
index fc3c87389917abebacff1d984cebd20078a43e3a..ac097d051b28673aad0bf492abf01a75a4a05778 100644 (file)
 //! both occur before the crate is rendered.
 pub use self::ExternalLocation::*;
 
+use std::ascii::OwnedAsciiExt;
 use std::cell::RefCell;
 use std::cmp::Ordering;
 use std::collections::{HashMap, HashSet};
 use std::default::Default;
 use std::fmt;
-use std::old_io::fs::PathExtensions;
-use std::old_io::{fs, File, BufferedWriter, BufferedReader};
-use std::old_io;
+use std::fs::{self, File};
+use std::io::prelude::*;
+use std::io::{self, BufWriter, BufReader};
 use std::iter::repeat;
+use std::path::{PathBuf, Path};
 use std::str;
 use std::sync::Arc;
 
@@ -65,12 +67,10 @@ use html::item_type::ItemType;
 use html::layout;
 use html::markdown::Markdown;
 use html::markdown;
-use html::escape::Escape;
 use stability_summary;
 
 /// A pair of name and its optional document.
-#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
-pub struct NameDoc(String, Option<String>);
+pub type NameDoc = (String, Option<String>);
 
 /// Major driving force in all rustdoc rendering. This contains information
 /// about where in the tree-like hierarchy rendering is occurring and controls
@@ -89,19 +89,13 @@ pub struct Context {
     pub root_path: String,
     /// The path to the crate root source minus the file name.
     /// Used for simplifying paths to the highlighted source code files.
-    pub src_root: Path,
+    pub src_root: PathBuf,
     /// The current destination folder of where HTML artifacts should be placed.
     /// This changes as the context descends into the module hierarchy.
-    pub dst: Path,
+    pub dst: PathBuf,
     /// This describes the layout of each page, and is not modified after
     /// creation of the context (contains info like the favicon and added html).
     pub layout: layout::Layout,
-    /// This map is a list of what should be displayed on the sidebar of the
-    /// current page. The key is the section header (traits, modules,
-    /// functions), and the value is the list of containers belonging to this
-    /// header. This map will change depending on the surrounding context of the
-    /// page.
-    pub sidebar: HashMap<String, Vec<NameDoc>>,
     /// This flag indicates whether [src] links should be generated or not. If
     /// the source files are present in the html rendering, then this will be
     /// `true`.
@@ -131,6 +125,7 @@ pub struct Implementor {
     pub trait_: clean::Type,
     pub for_: clean::Type,
     pub stability: Option<clean::Stability>,
+    pub polarity: Option<clean::ImplPolarity>,
 }
 
 /// Metadata about implementations for a type.
@@ -220,7 +215,7 @@ struct SourceCollector<'a> {
     /// Processed source-file paths
     seen: HashSet<String>,
     /// Root destination to place all HTML output into
-    dst: Path,
+    dst: PathBuf,
 }
 
 /// Wrapper struct to render the source code of a file. This will do things like
@@ -230,7 +225,7 @@ struct Source<'a>(&'a str);
 // Helper structs for rendering items/sidebars and carrying along contextual
 // information
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Item<'a> {
     cx: &'a Context,
     item: &'a clean::Item,
@@ -246,6 +241,51 @@ struct IndexItem {
     path: String,
     desc: String,
     parent: Option<ast::DefId>,
+    search_type: Option<IndexItemFunctionType>,
+}
+
+/// A type used for the search index.
+struct Type {
+    name: Option<String>,
+}
+
+impl fmt::Display for Type {
+    /// Formats type as {name: $name}.
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // Wrapping struct fmt should never call us when self.name is None,
+        // but just to be safe we write `null` in that case.
+        match self.name {
+            Some(ref n) => write!(f, "{{\"name\":\"{}\"}}", n),
+            None => write!(f, "null")
+        }
+    }
+}
+
+/// Full type of functions/methods in the search index.
+struct IndexItemFunctionType {
+    inputs: Vec<Type>,
+    output: Option<Type>
+}
+
+impl fmt::Display for IndexItemFunctionType {
+    /// Formats a full fn type as a JSON {inputs: [Type], outputs: Type/null}.
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // If we couldn't figure out a type, just write `null`.
+        if self.inputs.iter().any(|ref i| i.name.is_none()) ||
+           (self.output.is_some() && self.output.as_ref().unwrap().name.is_none()) {
+            return write!(f, "null")
+        }
+
+        let inputs: Vec<String> = self.inputs.iter().map(|ref t| format!("{}", t)).collect();
+        try!(write!(f, "{{\"inputs\":[{}],\"output\":", inputs.connect(",")));
+
+        match self.output {
+            Some(ref t) => try!(write!(f, "{}", t)),
+            None => try!(write!(f, "null"))
+        };
+
+        Ok(try!(write!(f, "}}")))
+    }
 }
 
 // TLS keys used to carry information around during rendering.
@@ -257,15 +297,18 @@ thread_local!(pub static CURRENT_LOCATION_KEY: RefCell<Vec<String>> =
 /// Generates the documentation for `crate` into the directory `dst`
 pub fn run(mut krate: clean::Crate,
            external_html: &ExternalHtml,
-           dst: Path,
-           passes: HashSet<String>) -> old_io::IoResult<()> {
+           dst: PathBuf,
+           passes: HashSet<String>) -> io::Result<()> {
+    let src_root = match krate.src.parent() {
+        Some(p) => p.to_path_buf(),
+        None => PathBuf::new(),
+    };
     let mut cx = Context {
         dst: dst,
-        src_root: krate.src.dir_path(),
+        src_root: src_root,
         passes: passes,
         current: Vec::new(),
         root_path: String::new(),
-        sidebar: HashMap::new(),
         layout: layout::Layout {
             logo: "".to_string(),
             favicon: "".to_string(),
@@ -392,7 +435,7 @@ pub fn run(mut krate: clean::Crate,
     cx.krate(krate, summary)
 }
 
-fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<String> {
+fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::Result<String> {
     // Build the search index from the collected metadata
     let mut nodeid_to_pathid = HashMap::new();
     let mut pathid_to_nodeid = Vec::new();
@@ -411,8 +454,9 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<Stri
                         ty: shortty(item),
                         name: item.name.clone().unwrap(),
                         path: fqp[..fqp.len() - 1].connect("::"),
-                        desc: shorter(item.doc_value()).to_string(),
+                        desc: shorter(item.doc_value()),
                         parent: Some(did),
+                        search_type: None,
                     });
                 },
                 None => {}
@@ -437,7 +481,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<Stri
     }
 
     // Collect the index into a string
-    let mut w = Vec::new();
+    let mut w = io::Cursor::new(Vec::new());
     try!(write!(&mut w, r#"searchIndex['{}'] = {{"items":["#, krate.name));
 
     let mut lastpath = "".to_string();
@@ -455,14 +499,18 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<Stri
             try!(write!(&mut w, ","));
         }
         try!(write!(&mut w, r#"[{},"{}","{}",{}"#,
-                    item.ty as uint, item.name, path,
+                    item.ty as usize, item.name, path,
                     item.desc.to_json().to_string()));
         match item.parent {
             Some(nodeid) => {
                 let pathid = *nodeid_to_pathid.get(&nodeid).unwrap();
                 try!(write!(&mut w, ",{}", pathid));
             }
-            None => {}
+            None => try!(write!(&mut w, ",null"))
+        }
+        match item.search_type {
+            Some(ref t) => try!(write!(&mut w, ",{}", t)),
+            None => try!(write!(&mut w, ",null"))
         }
         try!(write!(&mut w, "]"));
     }
@@ -475,18 +523,18 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<Stri
             try!(write!(&mut w, ","));
         }
         try!(write!(&mut w, r#"[{},"{}"]"#,
-                    short as uint, *fqp.last().unwrap()));
+                    short as usize, *fqp.last().unwrap()));
     }
 
     try!(write!(&mut w, "]}};"));
 
-    Ok(String::from_utf8(w).unwrap())
+    Ok(String::from_utf8(w.into_inner()).unwrap())
 }
 
 fn write_shared(cx: &Context,
                 krate: &clean::Crate,
                 cache: &Cache,
-                search_index: String) -> old_io::IoResult<()> {
+                search_index: String) -> io::Result<()> {
     // Write out the shared files. Note that these are shared among all rustdoc
     // docs placed in the output directory, so this needs to be a synchronized
     // operation with respect to all other rustdocs running around.
@@ -518,10 +566,10 @@ fn write_shared(cx: &Context,
                include_bytes!("static/SourceCodePro-Semibold.woff")));
 
     fn collect(path: &Path, krate: &str,
-               key: &str) -> old_io::IoResult<Vec<String>> {
+               key: &str) -> io::Result<Vec<String>> {
         let mut ret = Vec::new();
         if path.exists() {
-            for line in BufferedReader::new(File::open(path)).lines() {
+            for line in BufReader::new(try!(File::open(path))).lines() {
                 let line = try!(line);
                 if !line.starts_with(key) {
                     continue
@@ -567,14 +615,14 @@ fn write_shared(cx: &Context,
             mydst.push(part);
             try!(mkdir(&mydst));
         }
-        mydst.push(format!("{}.{}.js",
-                           remote_item_type.to_static_str(),
-                           remote_path[remote_path.len() - 1]));
+        mydst.push(&format!("{}.{}.js",
+                            remote_item_type.to_static_str(),
+                            remote_path[remote_path.len() - 1]));
         let all_implementors = try!(collect(&mydst, &krate.name,
                                             "implementors"));
 
-        try!(mkdir(&mydst.dir_path()));
-        let mut f = BufferedWriter::new(try!(File::create(&mydst)));
+        try!(mkdir(mydst.parent().unwrap()));
+        let mut f = BufWriter::new(try!(File::create(&mydst)));
         try!(writeln!(&mut f, "(function() {{var implementors = {{}};"));
 
         for implementor in &all_implementors {
@@ -588,9 +636,11 @@ fn write_shared(cx: &Context,
             // going on). If they're in different crates then the crate defining
             // the trait will be interested in our implementation.
             if imp.def_id.krate == did.krate { continue }
-            try!(write!(&mut f, r#""{}impl{} {} for {}","#,
+            try!(write!(&mut f, r#""{}impl{} {}{} for {}","#,
                         ConciseStability(&imp.stability),
-                        imp.generics, imp.trait_, imp.for_));
+                        imp.generics,
+                        if imp.polarity == Some(clean::ImplPolarity::Negative) { "!" } else { "" },
+                        imp.trait_, imp.for_));
         }
         try!(writeln!(&mut f, r"];"));
         try!(writeln!(&mut f, "{}", r"
@@ -606,7 +656,7 @@ fn write_shared(cx: &Context,
 }
 
 fn render_sources(cx: &mut Context,
-                  krate: clean::Crate) -> old_io::IoResult<clean::Crate> {
+                  krate: clean::Crate) -> io::Result<clean::Crate> {
     info!("emitting source files");
     let dst = cx.dst.join("src");
     try!(mkdir(&dst));
@@ -624,15 +674,15 @@ fn render_sources(cx: &mut Context,
 
 /// Writes the entire contents of a string to a destination, not attempting to
 /// catch any errors.
-fn write(dst: Path, contents: &[u8]) -> old_io::IoResult<()> {
-    File::create(&dst).write_all(contents)
+fn write(dst: PathBuf, contents: &[u8]) -> io::Result<()> {
+    try!(File::create(&dst)).write_all(contents)
 }
 
 /// Makes a directory on the filesystem, failing the task if an error occurs and
 /// skipping if the directory already exists.
-fn mkdir(path: &Path) -> old_io::IoResult<()> {
+fn mkdir(path: &Path) -> io::Result<()> {
     if !path.exists() {
-        fs::mkdir(path, old_io::USER_RWX)
+        fs::create_dir(path)
     } else {
         Ok(())
     }
@@ -645,24 +695,27 @@ fn shortty(item: &clean::Item) -> ItemType {
 
 /// Takes a path to a source file and cleans the path to it. This canonicalizes
 /// things like ".." to components which preserve the "top down" hierarchy of a
-/// static HTML tree.
+/// static HTML tree. Each component in the cleaned path will be passed as an
+/// argument to `f`. The very last component of the path (ie the file name) will
+/// be passed to `f` if `keep_filename` is true, and ignored otherwise.
 // FIXME (#9639): The closure should deal with &[u8] instead of &str
 // FIXME (#9639): This is too conservative, rejecting non-UTF-8 paths
-fn clean_srcpath<F>(src_root: &Path, src: &[u8], mut f: F) where
+fn clean_srcpath<F>(src_root: &Path, p: &Path, keep_filename: bool, mut f: F) where
     F: FnMut(&str),
 {
-    let p = Path::new(src);
-
     // make it relative, if possible
-    let p = p.path_relative_from(src_root).unwrap_or(p);
+    let p = p.relative_from(src_root).unwrap_or(p);
 
-    if p.as_vec() != b"." {
-        for c in p.str_components().map(|x|x.unwrap()) {
-            if ".." == c {
-                f("up");
-            } else {
-                f(c)
-            }
+    let mut iter = p.iter().map(|x| x.to_str().unwrap()).peekable();
+    while let Some(c) = iter.next() {
+        if !keep_filename && iter.peek().is_none() {
+            break;
+        }
+
+        if ".." == c {
+            f("up");
+        } else {
+            f(c)
         }
     }
 }
@@ -733,13 +786,14 @@ impl<'a> DocFolder for SourceCollector<'a> {
 
 impl<'a> SourceCollector<'a> {
     /// Renders the given filename into its corresponding HTML source file.
-    fn emit_source(&mut self, filename: &str) -> old_io::IoResult<()> {
-        let p = Path::new(filename);
+    fn emit_source(&mut self, filename: &str) -> io::Result<()> {
+        let p = PathBuf::from(filename);
 
         // If we couldn't open this file, then just returns because it
         // probably means that it's some standard library macro thing and we
         // can't have the source to it anyway.
-        let contents = match File::open(&p).read_to_end() {
+        let mut contents = Vec::new();
+        match File::open(&p).and_then(|mut f| f.read_to_end(&mut contents)) {
             Ok(r) => r,
             // macros from other libraries get special filenames which we can
             // safely ignore
@@ -759,18 +813,20 @@ impl<'a> SourceCollector<'a> {
         // Create the intermediate directories
         let mut cur = self.dst.clone();
         let mut root_path = String::from_str("../../");
-        clean_srcpath(&self.cx.src_root, p.dirname(), |component| {
+        clean_srcpath(&self.cx.src_root, &p, false, |component| {
             cur.push(component);
             mkdir(&cur).unwrap();
             root_path.push_str("../");
         });
 
-        let mut fname = p.filename().expect("source has no filename").to_vec();
-        fname.extend(".html".bytes());
-        cur.push(fname);
-        let mut w = BufferedWriter::new(try!(File::create(&cur)));
+        let mut fname = p.file_name().expect("source has no filename")
+                         .to_os_string();
+        fname.push(".html");
+        cur.push(&fname[..]);
+        let mut w = BufWriter::new(try!(File::create(&cur)));
 
-        let title = format!("{} -- source", cur.filename_display());
+        let title = format!("{} -- source", cur.file_name().unwrap()
+                                               .to_string_lossy());
         let desc = format!("Source to the Rust file `{}`.", filename);
         let page = layout::Page {
             title: &title,
@@ -779,7 +835,7 @@ impl<'a> SourceCollector<'a> {
             description: &desc,
             keywords: get_basic_keywords(),
         };
-        try!(layout::render(&mut w as &mut Writer, &self.cx.layout,
+        try!(layout::render(&mut w, &self.cx.layout,
                             &page, &(""), &Source(contents)));
         try!(w.flush());
         return Ok(());
@@ -823,14 +879,13 @@ impl DocFolder for Cache {
         if let clean::ImplItem(ref i) = item.inner {
             match i.trait_ {
                 Some(clean::ResolvedPath{ did, .. }) => {
-                    let v = self.implementors.entry(did).get().unwrap_or_else(
-                        |vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
-                    v.push(Implementor {
+                    self.implementors.entry(did).or_insert(vec![]).push(Implementor {
                         def_id: item.def_id,
                         generics: i.generics.clone(),
                         trait_: i.trait_.as_ref().unwrap().clone(),
                         for_: i.for_.clone(),
                         stability: item.stability.clone(),
+                        polarity: i.polarity.clone(),
                     });
                 }
                 Some(..) | None => {}
@@ -877,12 +932,21 @@ impl DocFolder for Cache {
 
             match parent {
                 (parent, Some(path)) if is_method || (!self.privmod && !hidden_field) => {
+                    // Needed to determine `self` type.
+                    let parent_basename = self.parent_stack.first().and_then(|parent| {
+                        match self.paths.get(parent) {
+                            Some(&(ref fqp, _)) => Some(fqp[fqp.len() - 1].clone()),
+                            _ => None
+                        }
+                    });
+
                     self.search_index.push(IndexItem {
                         ty: shortty(&item),
                         name: s.to_string(),
                         path: path.connect("::").to_string(),
-                        desc: shorter(item.doc_value()).to_string(),
+                        desc: shorter(item.doc_value()),
                         parent: parent,
+                        search_type: get_index_search_type(&item, parent_basename),
                     });
                 }
                 (Some(parent), None) if is_method || (!self.privmod && !hidden_field)=> {
@@ -964,7 +1028,8 @@ impl DocFolder for Cache {
                 match item {
                     clean::Item{ attrs, inner: clean::ImplItem(i), .. } => {
                         use clean::{Primitive, Vector, ResolvedPath, BorrowedRef};
-                        use clean::{FixedVector, Slice, Tuple, PrimitiveTuple};
+                        use clean::PrimitiveType::{Array, Slice, PrimitiveTuple};
+                        use clean::{FixedVector, Tuple};
 
                         // extract relevant documentation for this impl
                         let dox = match attrs.into_iter().find(|a| {
@@ -994,12 +1059,16 @@ impl DocFolder for Cache {
                                 Some(ast_util::local_def(p.to_node_id()))
                             }
 
-                            // In a DST world, we may only need
-                            // Vector/FixedVector, but for now we also pick up
-                            // borrowed references
-                            Vector(..) | FixedVector(..) |
-                                BorrowedRef{ type_: box Vector(..), ..  } |
-                                BorrowedRef{ type_: box FixedVector(..), .. } =>
+                            FixedVector(..) |
+                                BorrowedRef { type_: box FixedVector(..), .. } =>
+                            {
+                                Some(ast_util::local_def(Array.to_node_id()))
+                            }
+
+                            // In a DST world, we may only need Vector, but for now we
+                            // also pick up borrowed references
+                            Vector(..) |
+                                BorrowedRef{ type_: box Vector(..), ..  } =>
                             {
                                 Some(ast_util::local_def(Slice.to_node_id()))
                             }
@@ -1013,9 +1082,7 @@ impl DocFolder for Cache {
                         };
 
                         if let Some(did) = did {
-                            let v = self.impls.entry(did).get().unwrap_or_else(
-                                |vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
-                            v.push(Impl {
+                            self.impls.entry(did).or_insert(vec![]).push(Impl {
                                 impl_: i,
                                 dox: dox,
                                 stability: item.stability.clone(),
@@ -1081,7 +1148,7 @@ impl Context {
     /// This currently isn't parallelized, but it'd be pretty easy to add
     /// parallelization to this function.
     fn krate(mut self, mut krate: clean::Crate,
-             stability: stability_summary::ModuleSummary) -> old_io::IoResult<()> {
+             stability: stability_summary::ModuleSummary) -> io::Result<()> {
         let mut item = match krate.module.take() {
             Some(i) => i,
             None => return Ok(())
@@ -1091,7 +1158,7 @@ impl Context {
         // render stability dashboard
         try!(self.recurse(stability.name.clone(), |this| {
             let json_dst = &this.dst.join("stability.json");
-            let mut json_out = BufferedWriter::new(try!(File::create(json_dst)));
+            let mut json_out = BufWriter::new(try!(File::create(json_dst)));
             try!(write!(&mut json_out, "{}", json::as_json(&stability)));
 
             let mut title = stability.name.clone();
@@ -1106,7 +1173,7 @@ impl Context {
                 keywords: get_basic_keywords(),
             };
             let html_dst = &this.dst.join("stability.html");
-            let mut html_out = BufferedWriter::new(try!(File::create(html_dst)));
+            let mut html_out = BufWriter::new(try!(File::create(html_dst)));
             layout::render(&mut html_out, &this.layout, &page,
                            &Sidebar{ cx: this, item: &item },
                            &stability)
@@ -1131,12 +1198,12 @@ impl Context {
     /// all sub-items which need to be rendered.
     ///
     /// The rendering driver uses this closure to queue up more work.
-    fn item<F>(&mut self, item: clean::Item, mut f: F) -> old_io::IoResult<()> where
+    fn item<F>(&mut self, item: clean::Item, mut f: F) -> io::Result<()> where
         F: FnMut(&mut Context, clean::Item),
     {
-        fn render(w: old_io::File, cx: &Context, it: &clean::Item,
-                  pushname: bool) -> old_io::IoResult<()> {
-            info!("Rendering an item to {}", w.path().display());
+        fn render(w: File, cx: &Context, it: &clean::Item,
+                  pushname: bool) -> io::Result<()> {
+            info!("Rendering an item to {}", w.path().unwrap().display());
             // A little unfortunate that this is done like this, but it sure
             // does make formatting *a lot* nicer.
             CURRENT_LOCATION_KEY.with(|slot| {
@@ -1177,7 +1244,7 @@ impl Context {
             // We have a huge number of calls to write, so try to alleviate some
             // of the pain by using a buffered writer instead of invoking the
             // write syscall all the time.
-            let mut writer = BufferedWriter::new(w);
+            let mut writer = BufWriter::new(w);
             if !cx.render_redirect_pages {
                 try!(layout::render(&mut writer, &cx.layout, &page,
                                     &Sidebar{ cx: cx, item: it },
@@ -1227,7 +1294,16 @@ impl Context {
                         clean::ModuleItem(m) => m,
                         _ => unreachable!()
                     };
-                    this.sidebar = this.build_sidebar(&m);
+
+                    // render sidebar-items.js used throughout this module
+                    {
+                        let items = this.build_sidebar_items(&m);
+                        let js_dst = this.dst.join("sidebar-items.js");
+                        let mut js_out = BufWriter::new(try!(File::create(&js_dst)));
+                        try!(write!(&mut js_out, "initSidebarItems({});",
+                                    json::as_json(&items)));
+                    }
+
                     for item in m.items {
                         f(this,item);
                     }
@@ -1238,7 +1314,7 @@ impl Context {
             // Things which don't have names (like impls) don't get special
             // pages dedicated to them.
             _ if item.name.is_some() => {
-                let dst = self.dst.join(item_path(&item));
+                let dst = self.dst.join(&item_path(&item));
                 let dst = try!(File::create(&dst));
                 render(dst, self, &item, true)
             }
@@ -1247,24 +1323,19 @@ impl Context {
         }
     }
 
-    fn build_sidebar(&self, m: &clean::Module) -> HashMap<String, Vec<NameDoc>> {
+    fn build_sidebar_items(&self, m: &clean::Module) -> HashMap<String, Vec<NameDoc>> {
         let mut map = HashMap::new();
         for item in &m.items {
             if self.ignore_private_item(item) { continue }
 
-            // avoid putting foreign items to the sidebar.
-            if let &clean::ForeignFunctionItem(..) = &item.inner { continue }
-            if let &clean::ForeignStaticItem(..) = &item.inner { continue }
-
             let short = shortty(item).to_static_str();
             let myname = match item.name {
                 None => continue,
                 Some(ref s) => s.to_string(),
             };
             let short = short.to_string();
-            let v = map.entry(short).get().unwrap_or_else(
-                |vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
-            v.push(NameDoc(myname, Some(shorter_line(item.doc_value()))));
+            map.entry(short).or_insert(vec![])
+                .push((myname, Some(plain_summary_line(item.doc_value()))));
         }
 
         for (_, items) in &mut map {
@@ -1307,8 +1378,8 @@ impl<'a> Item<'a> {
         // has anchors for the line numbers that we're linking to.
         if ast_util::is_local(self.item.def_id) {
             let mut path = Vec::new();
-            clean_srcpath(&cx.src_root, self.item.source.filename.as_bytes(),
-                          |component| {
+            clean_srcpath(&cx.src_root, Path::new(&self.item.source.filename),
+                          true, |component| {
                 path.push(component.to_string());
             });
             let href = if self.item.source.loline == self.item.source.hiline {
@@ -1337,8 +1408,8 @@ impl<'a> Item<'a> {
         // located, then we return `None`.
         } else {
             let cache = cache();
-            let path = &cache.external_paths[self.item.def_id];
-            let root = match cache.extern_locations[self.item.def_id.krate] {
+            let path = &cache.external_paths[&self.item.def_id];
+            let root = match cache.extern_locations[&self.item.def_id.krate] {
                 Remote(ref s) => s.to_string(),
                 Local => self.cx.root_path.clone(),
                 Unknown => return None,
@@ -1467,19 +1538,21 @@ fn full_path(cx: &Context, item: &clean::Item) -> String {
     return s
 }
 
-fn shorter<'a>(s: Option<&'a str>) -> &'a str {
+fn shorter<'a>(s: Option<&'a str>) -> String {
     match s {
-        Some(s) => match s.find_str("\n\n") {
-            Some(pos) => &s[..pos],
-            None => s,
-        },
-        None => ""
+        Some(s) => s.lines().take_while(|line|{
+            (*line).chars().any(|chr|{
+                !chr.is_whitespace()
+            })
+        }).collect::<Vec<_>>().connect("\n"),
+        None => "".to_string()
     }
 }
 
 #[inline]
-fn shorter_line(s: Option<&str>) -> String {
-    shorter(s).replace("\n", " ")
+fn plain_summary_line(s: Option<&str>) -> String {
+    let line = shorter(s).replace("\n", " ");
+    markdown::plain_summary_line(&line[..])
 }
 
 fn document(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result {
@@ -1498,7 +1571,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
 
     let mut indices = (0..items.len()).filter(|i| {
         !cx.ignore_private_item(&items[*i])
-    }).collect::<Vec<uint>>();
+    }).collect::<Vec<usize>>();
 
     // the order of item types in the listing
     fn reorder(ty: ItemType) -> u8 {
@@ -1519,7 +1592,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
         }
     }
 
-    fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering {
+    fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering {
         let ty1 = shortty(i1);
         let ty2 = shortty(i2);
         if ty1 == ty2 {
@@ -1602,7 +1675,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
                     </tr>
                 ",
                 *myitem.name.as_ref().unwrap(),
-                Markdown(shorter(myitem.doc_value())),
+                Markdown(&shorter(myitem.doc_value())[..]),
                 class = shortty(myitem),
                 href = item_path(myitem),
                 title = full_path(cx, myitem),
@@ -1684,9 +1757,15 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                   bounds,
                   WhereClause(&t.generics)));
 
-    let types = t.items.iter().filter(|m| m.is_type()).collect::<Vec<_>>();
-    let required = t.items.iter().filter(|m| m.is_req()).collect::<Vec<_>>();
-    let provided = t.items.iter().filter(|m| m.is_def()).collect::<Vec<_>>();
+    let types = t.items.iter().filter(|m| {
+        match m.inner { clean::AssociatedTypeItem(..) => true, _ => false }
+    }).collect::<Vec<_>>();
+    let required = t.items.iter().filter(|m| {
+        match m.inner { clean::TyMethodItem(_) => true, _ => false }
+    }).collect::<Vec<_>>();
+    let provided = t.items.iter().filter(|m| {
+        match m.inner { clean::MethodItem(_) => true, _ => false }
+    }).collect::<Vec<_>>();
 
     if t.items.len() == 0 {
         try!(write!(w, "{{ }}"));
@@ -1694,7 +1773,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
         try!(write!(w, "{{\n"));
         for t in &types {
             try!(write!(w, "    "));
-            try!(render_method(w, t.item()));
+            try!(render_method(w, t));
             try!(write!(w, ";\n"));
         }
         if types.len() > 0 && required.len() > 0 {
@@ -1702,7 +1781,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
         }
         for m in &required {
             try!(write!(w, "    "));
-            try!(render_method(w, m.item()));
+            try!(render_method(w, m));
             try!(write!(w, ";\n"));
         }
         if required.len() > 0 && provided.len() > 0 {
@@ -1710,7 +1789,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
         }
         for m in &provided {
             try!(write!(w, "    "));
-            try!(render_method(w, m.item()));
+            try!(render_method(w, m));
             try!(write!(w, " {{ ... }}\n"));
         }
         try!(write!(w, "}}"));
@@ -1720,15 +1799,15 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
     // Trait documentation
     try!(document(w, it));
 
-    fn trait_item(w: &mut fmt::Formatter, m: &clean::TraitMethod)
+    fn trait_item(w: &mut fmt::Formatter, m: &clean::Item)
                   -> fmt::Result {
         try!(write!(w, "<h3 id='{}.{}' class='method'>{}<code>",
-                    shortty(m.item()),
-                    *m.item().name.as_ref().unwrap(),
-                    ConciseStability(&m.item().stability)));
-        try!(render_method(w, m.item()));
+                    shortty(m),
+                    *m.name.as_ref().unwrap(),
+                    ConciseStability(&m.stability)));
+        try!(render_method(w, m));
         try!(write!(w, "</code></h3>"));
-        try!(document(w, m.item()));
+        try!(document(w, m));
         Ok(())
     }
 
@@ -1788,7 +1867,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                 path = if ast_util::is_local(it.def_id) {
                     cx.current.connect("/")
                 } else {
-                    let path = &cache.external_paths[it.def_id];
+                    let path = &cache.external_paths[&it.def_id];
                     path[..path.len() - 1].connect("/")
                 },
                 ty = shortty(it).to_static_str(),
@@ -1797,12 +1876,14 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
 }
 
 fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item,
-              typ: &clean::TyParam) -> fmt::Result {
+              bounds: &Vec<clean::TyParamBound>,
+              default: &Option<clean::Type>)
+              -> fmt::Result {
     try!(write!(w, "type {}", it.name.as_ref().unwrap()));
-    if typ.bounds.len() > 0 {
-        try!(write!(w, ": {}", TyParamBounds(&*typ.bounds)))
+    if bounds.len() > 0 {
+        try!(write!(w, ": {}", TyParamBounds(bounds)))
     }
-    if let Some(ref default) = typ.default {
+    if let Some(ref default) = *default {
         try!(write!(w, " = {}", default));
     }
     Ok(())
@@ -1838,8 +1919,8 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result {
         clean::MethodItem(ref m) => {
             method(w, meth, m.unsafety, m.abi, &m.generics, &m.self_, &m.decl)
         }
-        clean::AssociatedTypeItem(ref typ) => {
-            assoc_type(w, meth, typ)
+        clean::AssociatedTypeItem(ref bounds, ref default) => {
+            assoc_type(w, meth, bounds, default)
         }
         _ => panic!("render_method called on non-method")
     }
@@ -2137,13 +2218,13 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
                 try!(write!(w, "type {} = {}", name, tydef.type_));
                 try!(write!(w, "</code></h4>\n"));
             }
-            clean::AssociatedTypeItem(ref typaram) => {
+            clean::AssociatedTypeItem(ref bounds, ref default) => {
                 let name = item.name.as_ref().unwrap();
                 try!(write!(w, "<h4 id='assoc_type.{}' class='{}'>{}<code>",
                             *name,
                             shortty(item),
                             ConciseStability(&item.stability)));
-                try!(assoc_type(w, item, typaram));
+                try!(assoc_type(w, item, bounds, default));
                 try!(write!(w, "</code></h4>\n"));
             }
             _ => panic!("can't make docs for trait item with name {:?}", item.name)
@@ -2166,13 +2247,13 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result {
                               t: &clean::Trait,
                               i: &clean::Impl) -> fmt::Result {
         for trait_item in &t.items {
-            let n = trait_item.item().name.clone();
+            let n = trait_item.name.clone();
             match i.items.iter().find(|m| { m.name == n }) {
                 Some(..) => continue,
                 None => {}
             }
 
-            try!(doctraititem(w, trait_item.item(), false));
+            try!(doctraititem(w, trait_item, false));
         }
         Ok(())
     }
@@ -2211,9 +2292,18 @@ impl<'a> fmt::Display for Sidebar<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let cx = self.cx;
         let it = self.item;
+        let parentlen = cx.current.len() - if it.is_mod() {1} else {0};
+
+        // the sidebar is designed to display sibling functions, modules and
+        // other miscellaneous informations. since there are lots of sibling
+        // items (and that causes quadratic growth in large modules),
+        // we refactor common parts into a shared JavaScript file per module.
+        // still, we don't move everything into JS because we want to preserve
+        // as much HTML as possible in order to allow non-JS-enabled browsers
+        // to navigate the documentation (though slightly inefficiently).
+
         try!(write!(fmt, "<p class='location'>"));
-        let len = cx.current.len() - if it.is_mod() {1} else {0};
-        for (i, name) in cx.current.iter().take(len).enumerate() {
+        for (i, name) in cx.current.iter().take(parentlen).enumerate() {
             if i > 0 {
                 try!(write!(fmt, "::<wbr>"));
             }
@@ -2223,40 +2313,25 @@ impl<'a> fmt::Display for Sidebar<'a> {
         }
         try!(write!(fmt, "</p>"));
 
-        fn block(w: &mut fmt::Formatter, short: &str, longty: &str,
-                 cur: &clean::Item, cx: &Context) -> fmt::Result {
-            let items = match cx.sidebar.get(short) {
-                Some(items) => items,
-                None => return Ok(())
-            };
-            try!(write!(w, "<div class='block {}'><h2>{}</h2>", short, longty));
-            for &NameDoc(ref name, ref doc) in items {
-                let curty = shortty(cur).to_static_str();
-                let class = if cur.name.as_ref().unwrap() == name &&
-                               short == curty { "current" } else { "" };
-                try!(write!(w, "<a class='{ty} {class}' href='{href}{path}' \
-                                title='{title}'>{name}</a>",
-                       ty = short,
-                       class = class,
-                       href = if curty == "mod" {"../"} else {""},
-                       path = if short == "mod" {
-                           format!("{}/index.html", name)
-                       } else {
-                           format!("{}.{}.html", short, name)
-                       },
-                       title = Escape(doc.as_ref().unwrap()),
-                       name = name));
-            }
-            try!(write!(w, "</div>"));
-            Ok(())
+        // sidebar refers to the enclosing module, not this module
+        let relpath = if shortty(it) == ItemType::Module { "../" } else { "" };
+        try!(write!(fmt,
+                    "<script>window.sidebarCurrent = {{\
+                        name: '{name}', \
+                        ty: '{ty}', \
+                        relpath: '{path}'\
+                     }};</script>",
+                    name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""),
+                    ty = shortty(it).to_static_str(),
+                    path = relpath));
+        if parentlen == 0 {
+            // there is no sidebar-items.js beyond the crate root path
+            // FIXME maybe dynamic crate loading can be merged here
+        } else {
+            try!(write!(fmt, "<script defer src=\"{path}sidebar-items.js\"></script>",
+                        path = relpath));
         }
 
-        try!(block(fmt, "mod", "Modules", it, cx));
-        try!(block(fmt, "struct", "Structs", it, cx));
-        try!(block(fmt, "enum", "Enums", it, cx));
-        try!(block(fmt, "trait", "Traits", it, cx));
-        try!(block(fmt, "fn", "Functions", it, cx));
-        try!(block(fmt, "macro", "Macros", it, cx));
         Ok(())
     }
 }
@@ -2304,6 +2379,52 @@ fn make_item_keywords(it: &clean::Item) -> String {
     format!("{}, {}", get_basic_keywords(), it.name.as_ref().unwrap())
 }
 
+fn get_index_search_type(item: &clean::Item,
+                         parent: Option<String>) -> Option<IndexItemFunctionType> {
+    let decl = match item.inner {
+        clean::FunctionItem(ref f) => &f.decl,
+        clean::MethodItem(ref m) => &m.decl,
+        clean::TyMethodItem(ref m) => &m.decl,
+        _ => return None
+    };
+
+    let mut inputs = Vec::new();
+
+    // Consider `self` an argument as well.
+    if let Some(name) = parent {
+        inputs.push(Type { name: Some(name.into_ascii_lowercase()) });
+    }
+
+    inputs.extend(&mut decl.inputs.values.iter().map(|arg| {
+        get_index_type(&arg.type_)
+    }));
+
+    let output = match decl.output {
+        clean::FunctionRetTy::Return(ref return_type) => Some(get_index_type(return_type)),
+        _ => None
+    };
+
+    Some(IndexItemFunctionType { inputs: inputs, output: output })
+}
+
+fn get_index_type(clean_type: &clean::Type) -> Type {
+    Type { name: get_index_type_name(clean_type).map(|s| s.into_ascii_lowercase()) }
+}
+
+fn get_index_type_name(clean_type: &clean::Type) -> Option<String> {
+    match *clean_type {
+        clean::ResolvedPath { ref path, .. } => {
+            let segments = &path.segments;
+            Some(segments[segments.len() - 1].name.clone())
+        },
+        clean::Generic(ref s) => Some(s.clone()),
+        clean::Primitive(ref p) => Some(format!("{:?}", p)),
+        clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_),
+        // FIXME: add all from clean::Type.
+        _ => None
+    }
+}
+
 pub fn cache() -> Arc<Cache> {
     CACHE_KEY.with(|c| c.borrow().clone())
 }
index 9693dc1db2df3f054da1bcac6f8e5e977bf73419..dd85e40e64548e19b4571c86ec4ec1111bad4401 100644 (file)
@@ -1,7 +1,7 @@
 Copyright 1989, 1991 Adobe Systems Incorporated. All rights reserved.
 Utopia is either a registered trademark or trademark of Adobe Systems
 Incorporated in the United States and/or other countries. Used under
-license. 
+license.
 
 Copyright 2006 Han The Thanh, Vntopia font family, http://vntex.sf.net
 
@@ -26,7 +26,7 @@ with others.
 
 The OFL allows the licensed fonts to be used, studied, modified and
 redistributed freely as long as they are not sold by themselves. The
-fonts, including any derivative works, can be bundled, embedded, 
+fonts, including any derivative works, can be bundled, embedded,
 redistributed and/or sold with any software provided that any reserved
 names are not used by derivative works. The fonts and derivatives,
 however, cannot be released under any other type of license. The
index 1177330426de9f788fedeae13dfe6a195a06d3b2..07542572e33bdc15739d047cc3b72da24d71ccef 100644 (file)
@@ -18,7 +18,7 @@ with others.
 
 The OFL allows the licensed fonts to be used, studied, modified and
 redistributed freely as long as they are not sold by themselves. The
-fonts, including any derivative works, can be bundled, embedded, 
+fonts, including any derivative works, can be bundled, embedded,
 redistributed and/or sold with any software provided that any reserved
 names are not used by derivative works. The fonts and derivatives,
 however, cannot be released under any other type of license. The
index 14b54813758d00a4be93954b8fb9ec52be7f90a6..b77d653ad4f0dd68026dc96e5b1be332a56e6bd9 100644 (file)
@@ -18,7 +18,7 @@ with others.
 
 The OFL allows the licensed fonts to be used, studied, modified and
 redistributed freely as long as they are not sold by themselves. The
-fonts, including any derivative works, can be bundled, embedded, 
+fonts, including any derivative works, can be bundled, embedded,
 redistributed and/or sold with any software provided that any reserved
 names are not used by derivative works. The fonts and derivatives,
 however, cannot be released under any other type of license. The
index 2f0755ecb898a0bf17b04cdd9b3641eb6b21f752..2af20ce59da57d718ad9fd5821adf5851f00ea21 100644 (file)
@@ -83,7 +83,7 @@ h2 {
 h3 {
     font-size: 1.3em;
 }
-h1, h2, h3:not(.impl):not(.method):not(.type), h4:not(.method):not(.type) {
+h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {
     color: black;
     font-weight: 500;
     margin: 20px 0 15px 0;
@@ -93,7 +93,7 @@ h1.fqn {
     border-bottom: 1px dashed #D5D5D5;
     margin-top: 0;
 }
-h2, h3:not(.impl):not(.method):not(.type), h4:not(.method):not(.type) {
+h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) {
     border-bottom: 1px solid #DDDDDD;
 }
 h3.impl, h3.method, h4.method, h3.type, h4.type {
@@ -374,8 +374,14 @@ a {
     color: #000;
     background: transparent;
 }
-.docblock a { color: #4e8bca; }
-.docblock a:hover { text-decoration: underline; }
+
+.docblock a {
+    color: #4e8bca;
+}
+
+.docblock a:hover {
+    text-decoration: underline;
+}
 
 .content span.trait, .content a.trait, .block a.current.trait { color: #ed9603; }
 .content span.mod, .content a.mod, block a.current.mod { color: #4d76ae; }
@@ -487,6 +493,10 @@ h1 .stability {
 .stability.Locked { border-color: #0084B6; color: #00668c; }
 .stability.Unmarked { border-color: #BBBBBB; }
 
+td.summary-column {
+    width: 100%;
+}
+
 .summary {
     padding-right: 0px;
 }
@@ -529,10 +539,19 @@ pre.rust { position: relative; }
     margin: 0 0 -5px;
     padding: 0;
 }
+
 .section-header:hover a:after {
     content: '\2002\00a7\2002';
 }
 
+.section-header:hover a {
+    text-decoration: none;
+}
+
+.section-header a {
+    color: inherit;
+}
+
 .collapse-toggle {
     font-weight: 300;
     position: absolute;
index aac3985f0cc9cd967115c98c7381b696f1e43eb6..ca6d9441957777a4e187703df16167fe78a9a84b 100644 (file)
     "use strict";
     var resizeTimeout, interval;
 
+    // This mapping table should match the discriminants of
+    // `rustdoc::html::item_type::ItemType` type in Rust.
+    var itemTypes = ["mod",
+                     "externcrate",
+                     "import",
+                     "struct",
+                     "enum",
+                     "fn",
+                     "type",
+                     "static",
+                     "trait",
+                     "impl",
+                     "tymethod",
+                     "method",
+                     "structfield",
+                     "variant",
+                     "macro",
+                     "primitive",
+                     "associatedtype",
+                     "constant"];
+
     $('.js-only').removeClass('js-only');
 
     function getQueryStringParams() {
         return window.history && typeof window.history.pushState === "function";
     }
 
-    function resizeShortBlocks() {
-        if (resizeTimeout) {
-            clearTimeout(resizeTimeout);
-        }
-        resizeTimeout = setTimeout(function() {
-            var contentWidth = $('.content').width();
-            $('.docblock.short').width(function() {
-                return contentWidth - 40 - $(this).prev().width();
-            }).addClass('nowrap');
-            $('.summary-column').width(function() {
-                return contentWidth - 40 - $(this).prev().width();
-            })
-        }, 150);
-    }
-    resizeShortBlocks();
-    $(window).on('resize', resizeShortBlocks);
-
     function highlightSourceLines(ev) {
         var i, from, to, match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
         if (match) {
                         break;
                     }
                 }
+            // searching by type
+            } else if (val.search("->") > -1) {
+                var trimmer = function (s) { return s.trim(); };
+                var parts = val.split("->").map(trimmer);
+                var input = parts[0];
+                // sort inputs so that order does not matter
+                var inputs = input.split(",").map(trimmer).sort();
+                var output = parts[1];
+
+                for (var i = 0; i < nSearchWords; ++i) {
+                    var type = searchIndex[i].type;
+                    if (!type) {
+                        continue;
+                    }
+
+                    // sort index inputs so that order does not matter
+                    var typeInputs = type.inputs.map(function (input) {
+                        return input.name;
+                    }).sort();
+
+                    // allow searching for void (no output) functions as well
+                    var typeOutput = type.output ? type.output.name : "";
+                    if (inputs.toString() === typeInputs.toString() &&
+                        output == typeOutput) {
+                        results.push({id: i, index: -1, dontValidate: true});
+                    }
+                }
             } else {
                 // gather matching search results up to a certain maximum
                 val = val.replace(/\_/g, "");
                     path = result.item.path.toLowerCase(),
                     parent = result.item.parent;
 
+                // this validation does not make sense when searching by types
+                if (result.dontValidate) {
+                    continue;
+                }
+
                 var valid = validateResult(name, path, split, parent);
                 if (!valid) {
                     result.id = -1;
             showResults(results);
         }
 
-        // This mapping table should match the discriminants of
-        // `rustdoc::html::item_type::ItemType` type in Rust.
-        var itemTypes = ["mod",
-                         "externcrate",
-                         "import",
-                         "struct",
-                         "enum",
-                         "fn",
-                         "type",
-                         "static",
-                         "trait",
-                         "impl",
-                         "tymethod",
-                         "method",
-                         "structfield",
-                         "variant",
-                         "macro",
-                         "primitive",
-                         "associatedtype",
-                         "constant"];
-
         function itemTypeFromName(typename) {
             for (var i = 0; i < itemTypes.length; ++i) {
                 if (itemTypes[i] === typename) return i;
                 //              (String) name,
                 //              (String) full path or empty string for previous path,
                 //              (String) description,
-                //              (optional Number) the parent path index to `paths`]
+                //              (Number | null) the parent path index to `paths`]
+                //              (Object | null) the type of the function (if any)
                 var items = rawSearchIndex[crate].items;
                 // an array of [(Number) item type,
                 //              (String) name]
                     var rawRow = items[i];
                     var row = {crate: crate, ty: rawRow[0], name: rawRow[1],
                                path: rawRow[2] || lastPath, desc: rawRow[3],
-                               parent: paths[rawRow[4]]};
+                               parent: paths[rawRow[4]], type: rawRow[5]};
                     searchIndex.push(row);
                     if (typeof row.name === "string") {
                         var word = row.name.toLowerCase();
 
     window.initSearch = initSearch;
 
+    // delayed sidebar rendering.
+    function initSidebarItems(items) {
+        var sidebar = $('.sidebar');
+        var current = window.sidebarCurrent;
+
+        function block(shortty, longty) {
+            var filtered = items[shortty];
+            if (!filtered) return;
+
+            var div = $('<div>').attr('class', 'block ' + shortty);
+            div.append($('<h2>').text(longty));
+
+            for (var i = 0; i < filtered.length; ++i) {
+                var item = filtered[i];
+                var name = item[0];
+                var desc = item[1]; // can be null
+
+                var klass = shortty;
+                if (name === current.name && shortty == current.ty) {
+                    klass += ' current';
+                }
+                var path;
+                if (shortty === 'mod') {
+                    path = name + '/index.html';
+                } else {
+                    path = shortty + '.' + name + '.html';
+                }
+                div.append($('<a>', {'href': current.relpath + path,
+                                     'title': desc,
+                                     'class': klass}).text(name));
+            }
+            sidebar.append(div);
+        }
+
+        block("mod", "Modules");
+        block("struct", "Structs");
+        block("enum", "Enums");
+        block("trait", "Traits");
+        block("fn", "Functions");
+        block("macro", "Macros");
+    }
+
+    window.initSidebarItems = initSidebarItems;
+
     window.register_implementors = function(imp) {
         var list = $('#implementors-list');
         var libs = Object.getOwnPropertyNames(imp);
index 687f764f02077a10cc0df749585984d9e08030b7..06b3c4e42d6334c3f7e962dd6aa12de0c1ff1198 100644 (file)
@@ -15,7 +15,7 @@
     if (window.playgroundUrl) {
         $('pre.rust').hover(function() {
             var a = $('<a>').text('⇱').attr('class', 'test-arrow');
-            var code = $(this).siblings(".rusttest").text();
+            var code = $(this).prev(".rusttest").text();
             a.attr('href', window.playgroundUrl + '?code=' +
                            encodeURIComponent(code));
             a.attr('target', '_blank');
@@ -25,4 +25,3 @@
         });
     }
 }());
-
index ecef4c9bf7226c182aa08dee218074609a6387d1..78feb6c77c45451f8f2df38420c850651825923c 100644 (file)
@@ -33,7 +33,7 @@ pub struct Toc {
 }
 
 impl Toc {
-    fn count_entries_with_level(&self, level: u32) -> uint {
+    fn count_entries_with_level(&self, level: u32) -> usize {
         self.entries.iter().filter(|e| e.level == level).count()
     }
 }
index f9e0948d7bc8a0ee6d707bb349d71d3592bf32f4..d1dcfc26008686624e92cdd22ce8085caf612980 100644 (file)
@@ -8,32 +8,34 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rustdoc"]
 #![unstable(feature = "rustdoc")]
 #![staged_api]
 #![crate_type = "dylib"]
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
-       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/nightly/",
-       html_playground_url = "http://play.rust-lang.org/")]
+   html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+   html_root_url = "http://doc.rust-lang.org/nightly/",
+   html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(collections)]
-#![feature(core)]
-#![feature(env)]
-#![feature(int_uint)]
-#![feature(old_io)]
+#![feature(exit_status)]
+#![feature(set_stdio)]
 #![feature(libc)]
-#![feature(os)]
-#![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(std_misc)]
 #![feature(test)]
 #![feature(unicode)]
 #![feature(str_words)]
+#![feature(file_path)]
+#![feature(path_ext)]
+#![feature(path_relative_from)]
+#![feature(slice_patterns)]
 
 extern crate arena;
 extern crate getopts;
@@ -42,20 +44,25 @@ extern crate rustc;
 extern crate rustc_trans;
 extern crate rustc_driver;
 extern crate rustc_resolve;
+extern crate rustc_lint;
+extern crate rustc_back;
 extern crate serialize;
 extern crate syntax;
-extern crate "test" as testing;
+extern crate test as testing;
+extern crate unicode;
 #[macro_use] extern crate log;
 
-extern crate "serialize" as rustc_serialize; // used by deriving
+extern crate serialize as rustc_serialize; // used by deriving
 
 use std::cell::RefCell;
 use std::collections::HashMap;
 use std::env;
-use std::old_io::File;
-use std::old_io;
+use std::fs::File;
+use std::io::{self, Read, Write};
+use std::path::PathBuf;
 use std::rc::Rc;
 use std::sync::mpsc::channel;
+
 use externalfiles::ExternalHtml;
 use serialize::Decodable;
 use serialize::json::{self, Json};
@@ -93,7 +100,7 @@ type Pass = (&'static str,                                      // name
              fn(clean::Crate) -> plugins::PluginResult,         // fn
              &'static str);                                     // description
 
-static PASSES: &'static [Pass] = &[
+const PASSES: &'static [Pass] = &[
     ("strip-hidden", passes::strip_hidden,
      "strips all doc(hidden) items from the output"),
     ("unindent-comments", passes::unindent_comments,
@@ -104,7 +111,7 @@ static PASSES: &'static [Pass] = &[
      "strips all private items from a crate which cannot be seen externally"),
 ];
 
-static DEFAULT_PASSES: &'static [&'static str] = &[
+const DEFAULT_PASSES: &'static [&'static str] = &[
     "strip-hidden",
     "strip-private",
     "collapse-docs",
@@ -183,7 +190,7 @@ pub fn usage(argv0: &str) {
                             &opts()));
 }
 
-pub fn main_args(args: &[String]) -> int {
+pub fn main_args(args: &[String]) -> isize {
     let matches = match getopts::getopts(args.tail(), &opts()) {
         Ok(m) => m,
         Err(err) => {
@@ -241,7 +248,7 @@ pub fn main_args(args: &[String]) -> int {
     let should_test = matches.opt_present("test");
     let markdown_input = input.ends_with(".md") || input.ends_with(".markdown");
 
-    let output = matches.opt_str("o").map(|s| Path::new(s));
+    let output = matches.opt_str("o").map(|s| PathBuf::from(&s));
     let cfgs = matches.opt_strs("cfg");
 
     let external_html = match ExternalHtml::load(
@@ -260,7 +267,8 @@ pub fn main_args(args: &[String]) -> int {
         (true, false) => {
             return test::run(input, cfgs, libs, externs, test_args, crate_name)
         }
-        (false, true) => return markdown::render(input, output.unwrap_or(Path::new("doc")),
+        (false, true) => return markdown::render(input,
+                                                 output.unwrap_or(PathBuf::from("doc")),
                                                  &matches, &external_html,
                                                  !matches.opt_present("markdown-no-toc")),
         (false, false) => {}
@@ -277,7 +285,8 @@ pub fn main_args(args: &[String]) -> int {
     info!("going to format");
     match matches.opt_str("w").as_ref().map(|s| &**s) {
         Some("html") | None => {
-            match html::render::run(krate, &external_html, output.unwrap_or(Path::new("doc")),
+            match html::render::run(krate, &external_html,
+                                    output.unwrap_or(PathBuf::from("doc")),
                                     passes.into_iter().collect()) {
                 Ok(()) => {}
                 Err(e) => panic!("failed to generate documentation: {}", e),
@@ -285,7 +294,7 @@ pub fn main_args(args: &[String]) -> int {
         }
         Some("json") => {
             match json_output(krate, json_plugins,
-                              output.unwrap_or(Path::new("doc.json"))) {
+                              output.unwrap_or(PathBuf::from("doc.json"))) {
                 Ok(()) => {}
                 Err(e) => panic!("failed to write json: {}", e),
             }
@@ -324,7 +333,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") {
-        let mut parts = arg.splitn(1, '=');
+        let mut parts = arg.splitn(2, '=');
         let name = match parts.next() {
             Some(s) => s,
             None => {
@@ -338,9 +347,7 @@ fn parse_externs(matches: &getopts::Matches) -> Result<core::Externs, String> {
             }
         };
         let name = name.to_string();
-        let locs = externs.entry(name).get().unwrap_or_else(
-            |vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
-        locs.push(location.to_string());
+        externs.entry(name).or_insert(vec![]).push(location.to_string());
     }
     Ok(externs)
 }
@@ -350,6 +357,7 @@ fn parse_externs(matches: &getopts::Matches) -> Result<core::Externs, String> {
 /// generated from the cleaned AST of the crate.
 ///
 /// This form of input will run all of the plug/cleaning passes
+#[allow(deprecated)] // for old Path in plugin manager
 fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matches) -> Output {
     let mut default_passes = !matches.opt_present("no-defaults");
     let mut passes = matches.opt_strs("passes");
@@ -363,15 +371,15 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
     let cfgs = matches.opt_strs("cfg");
     let triple = matches.opt_str("target");
 
-    let cr = Path::new(cratefile);
+    let cr = PathBuf::from(cratefile);
     info!("starting to run rustc");
 
     let (tx, rx) = channel();
     std::thread::spawn(move || {
         use rustc::session::config::Input;
 
-        let cr = cr;
-        tx.send(core::run_core(paths, cfgs, externs, Input::File(cr), triple)).unwrap();
+        tx.send(core::run_core(paths, cfgs, externs, Input::File(cr),
+                               triple)).unwrap();
     }).join().map_err(|_| "rustc failed").unwrap();
     let (mut krate, analysis) = rx.recv().unwrap();
     info!("finished with rustc");
@@ -422,7 +430,7 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
     // Load all plugins/passes into a PluginManager
     let path = matches.opt_str("plugin-path")
                       .unwrap_or("/tmp/rustdoc/plugins".to_string());
-    let mut pm = plugins::PluginManager::new(Path::new(path));
+    let mut pm = plugins::PluginManager::new(PathBuf::from(path));
     for pass in &passes {
         let plugin = match PASSES.iter()
                                  .position(|&(p, _, _)| {
@@ -450,13 +458,12 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
 /// This input format purely deserializes the json output file. No passes are
 /// run over the deserialized output.
 fn json_input(input: &str) -> Result<Output, String> {
-    let mut input = match File::open(&Path::new(input)) {
-        Ok(f) => f,
-        Err(e) => {
-            return Err(format!("couldn't open {}: {}", input, e))
-        }
+    let mut bytes = Vec::new();
+    match File::open(input).and_then(|mut f| f.read_to_end(&mut bytes)) {
+        Ok(_) => {}
+        Err(e) => return Err(format!("couldn't open {}: {}", input, e)),
     };
-    match json::from_reader(&mut input) {
+    match json::from_reader(&mut &bytes[..]) {
         Err(s) => Err(format!("{:?}", s)),
         Ok(Json::Object(obj)) => {
             let mut obj = obj;
@@ -494,7 +501,7 @@ fn json_input(input: &str) -> Result<Output, String> {
 /// Outputs the crate/plugin json as a giant json blob at the specified
 /// destination.
 fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
-               dst: Path) -> old_io::IoResult<()> {
+               dst: PathBuf) -> io::Result<()> {
     // {
     //   "schema": version,
     //   "crate": { parsed crate ... },
index d64d9becc0c7c459f2ac2ebcb9e6132bc834bcb7..a84da60b01831da1b6e7733ef105539a7d0dec0c 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::old_io;
+use std::fs::File;
+use std::io;
+use std::io::prelude::*;
+use std::path::{PathBuf, Path};
 
 use core;
 use getopts;
@@ -40,10 +43,10 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
 
 /// Render `input` (e.g. "foo.md") into an HTML file in `output`
 /// (e.g. output = "bar" => "bar/foo.html").
-pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
-              external_html: &ExternalHtml, include_toc: bool) -> int {
+pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
+              external_html: &ExternalHtml, include_toc: bool) -> isize {
     let input_p = Path::new(input);
-    output.push(input_p.filestem().unwrap());
+    output.push(input_p.file_stem().unwrap());
     output.set_extension("html");
 
     let mut css = String::new();
@@ -59,9 +62,9 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
     }
     let playground = playground.unwrap_or("".to_string());
 
-    let mut out = match old_io::File::create(&output) {
+    let mut out = match File::create(&output) {
         Err(e) => {
-            let _ = writeln!(&mut old_io::stderr(),
+            let _ = writeln!(&mut io::stderr(),
                              "error opening `{}` for writing: {}",
                              output.display(), e);
             return 4;
@@ -71,7 +74,7 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
 
     let (metadata, text) = extract_leading_metadata(&input_str);
     if metadata.len() == 0 {
-        let _ = writeln!(&mut old_io::stderr(),
+        let _ = writeln!(&mut io::stderr(),
                          "invalid markdown file: expecting initial line with `% ...TITLE...`");
         return 5;
     }
@@ -126,7 +129,7 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
 
     match err {
         Err(e) => {
-            let _ = writeln!(&mut old_io::stderr(),
+            let _ = writeln!(&mut io::stderr(),
                              "error writing to `{}`: {}",
                              output.display(), e);
             6
@@ -137,10 +140,10 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
 
 /// Run any tests/code examples in the markdown file `input`.
 pub fn test(input: &str, libs: SearchPaths, externs: core::Externs,
-            mut test_args: Vec<String>) -> int {
+            mut test_args: Vec<String>) -> isize {
     let input_str = load_or_return!(input, 1, 2);
 
-    let mut collector = Collector::new(input.to_string(), libs, externs, true);
+    let mut collector = Collector::new(input.to_string(), libs, externs, true, false);
     find_testable_code(&input_str, &mut collector);
     test_args.insert(0, "rustdoctest".to_string());
     testing::test_main(&test_args, collector.tests);
index 722f14fa6d4c7b0dcff44ad75f8d7f7bfa8686c2..953b442bb3ceb3d81b18a209153b6525affd5672 100644 (file)
@@ -176,7 +176,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
                     return None;
                 }
             }
-            clean::ImplItem(..) => {}
+            clean::DefaultImplItem(..) | clean::ImplItem(..) => {}
 
             // tymethods/macros have no control over privacy
             clean::MacroItem(..) | clean::TyMethodItem(..) => {}
index b65b2841aa0e5ce0ad6c874b17288fcef9a70057..d4d214f449d5921733ca9c2c9c9140e23b02fd9b 100644 (file)
@@ -8,12 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(deprecated)] // old path, used for compatibility with dynamic lib
+
 use clean;
 
 use std::dynamic_lib as dl;
 use serialize::json;
 use std::mem;
 use std::string::String;
+use std::path::PathBuf;
 
 pub type PluginJson = Option<(String, json::Json)>;
 pub type PluginResult = (clean::Crate, PluginJson);
@@ -24,12 +27,12 @@ pub struct PluginManager {
     dylibs: Vec<dl::DynamicLibrary> ,
     callbacks: Vec<PluginCallback> ,
     /// The directory plugins will be loaded from
-    pub prefix: Path,
+    pub prefix: PathBuf,
 }
 
 impl PluginManager {
     /// Create a new plugin manager
-    pub fn new(prefix: Path) -> PluginManager {
+    pub fn new(prefix: PathBuf) -> PluginManager {
         PluginManager {
             dylibs: Vec::new(),
             callbacks: Vec::new(),
index 47918ba78a270f060a4c684dd6d4adb91d275936..3e4f6896ee68db2181121dd351b79ae33ee65ed2 100644 (file)
@@ -20,14 +20,14 @@ use syntax::attr::{Unstable, Stable};
 use syntax::ast::Public;
 
 use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
-use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod};
-use clean::{TypeTraitItem, ExternCrateItem, ImportItem, PrimitiveItem, Stability};
+use clean::{ImplItem, Impl, Trait, TraitItem};
+use clean::{ExternCrateItem, ImportItem, PrimitiveItem, Stability};
 
 use html::render::cache;
 
 #[derive(RustcEncodable, RustcDecodable, PartialEq, Eq)]
 /// The counts for each stability level.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Counts {
     pub deprecated: u64,
     pub unstable: u64,
@@ -86,7 +86,7 @@ impl Ord for ModuleSummary {
     }
 }
 
-// is the item considered publically visible?
+// is the item considered publicly visible?
 fn visible(item: &Item) -> bool {
     match item.inner {
         ImplItem(_) => true,
@@ -140,11 +140,11 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
     // considered to have no children.
     match item.inner {
         // Require explicit `pub` to be visible
-        ImplItem(Impl { items: ref subitems, trait_: None, .. }) => {
-            let subcounts = subitems.iter().filter(|i| visible(*i))
-                                           .map(summarize_item)
-                                           .map(|s| s.0)
-                                           .fold(Counts::zero(), |acc, x| acc + x);
+        ImplItem(Impl { ref items, trait_: None, .. }) => {
+            let subcounts = items.iter().filter(|i| visible(*i))
+                                        .map(summarize_item)
+                                        .map(|s| s.0)
+                                        .fold(Counts::zero(), |acc, x| acc + x);
             (subcounts, None)
         }
         // `pub` automatically
@@ -154,22 +154,10 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
                                            .fold(Counts::zero(), |acc, x| acc + x);
             (item_counts + subcounts, None)
         }
-        TraitItem(Trait {
-            items: ref trait_items,
-            ..
-        }) => {
-            fn extract_item<'a>(trait_item: &'a TraitMethod) -> &'a Item {
-                match *trait_item {
-                    ProvidedMethod(ref item) |
-                    RequiredMethod(ref item) |
-                    TypeTraitItem(ref item) => item
-                }
-            }
-            let subcounts = trait_items.iter()
-                                       .map(extract_item)
-                                       .map(summarize_item)
-                                       .map(|s| s.0)
-                                       .fold(Counts::zero(), |acc, x| acc + x);
+        TraitItem(Trait { ref items, .. }) => {
+            let subcounts = items.iter().map(summarize_item)
+                                        .map(|s| s.0)
+                                        .fold(Counts::zero(), |acc, x| acc + x);
             (item_counts + subcounts, None)
         }
         ModuleItem(Module { ref items, .. }) => {
index bf14b86ebd1e39e21189cd0097dff9072a15fcd7..f5bee6240d46c80dc5ee321742b500cb958ec3c0 100644 (file)
@@ -9,20 +9,23 @@
 // except according to those terms.
 
 use std::cell::RefCell;
-use std::sync::mpsc::channel;
+use std::collections::{HashSet, HashMap};
 use std::dynamic_lib::DynamicLibrary;
-use std::old_io::{Command, TempDir};
-use std::old_io;
 use std::env;
+use std::ffi::OsString;
+use std::io::prelude::*;
+use std::io;
+use std::path::PathBuf;
+use std::process::Command;
 use std::str;
-use std::thread;
-use std::thunk::Thunk;
+use std::sync::{Arc, Mutex};
 
-use std::collections::{HashSet, HashMap};
 use testing;
+use rustc_lint;
 use rustc::session::{self, config};
 use rustc::session::config::get_unstable_features_setting;
 use rustc::session::search_paths::{SearchPaths, PathKind};
+use rustc_back::tempdir::TempDir;
 use rustc_driver::{driver, Compilation};
 use syntax::codemap::CodeMap;
 use syntax::diagnostic;
@@ -41,12 +44,13 @@ pub fn run(input: &str,
            externs: core::Externs,
            mut test_args: Vec<String>,
            crate_name: Option<String>)
-           -> int {
-    let input_path = Path::new(input);
+           -> isize {
+    let input_path = PathBuf::from(input);
     let input = config::Input::File(input_path.clone());
 
     let sessopts = config::Options {
-        maybe_sysroot: Some(env::current_exe().unwrap().dir_path().dir_path()),
+        maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap()
+                                              .parent().unwrap().to_path_buf()),
         search_paths: libs.clone(),
         crate_types: vec!(config::CrateTypeDylib),
         externs: externs.clone(),
@@ -62,6 +66,7 @@ pub fn run(input: &str,
     let sess = session::build_session_(sessopts,
                                       Some(input_path.clone()),
                                       span_diagnostic_handler);
+    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
     let mut cfg = config::build_configuration(&sess);
     cfg.extend(config::parse_cfgspecs(cfgs).into_iter());
@@ -70,6 +75,8 @@ pub fn run(input: &str,
                                                      "rustdoc-test", None)
         .expect("phase_2_configure_and_expand aborted in rustdoc!");
 
+    let inject_crate = should_inject_crate(&krate);
+
     let ctx = core::DocContext {
         krate: &krate,
         maybe_typed: core::NotTyped(sess),
@@ -94,7 +101,8 @@ pub fn run(input: &str,
     let mut collector = Collector::new(krate.name.to_string(),
                                        libs,
                                        externs,
-                                       false);
+                                       false,
+                                       inject_crate);
     collector.fold_crate(krate);
 
     test_args.insert(0, "rustdoctest".to_string());
@@ -104,16 +112,47 @@ pub fn run(input: &str,
     0
 }
 
+// Look for #![doc(test(no_crate_inject))], used by crates in the std facade
+fn should_inject_crate(krate: &::syntax::ast::Crate) -> bool {
+    use syntax::attr::AttrMetaMethods;
+
+    let mut inject_crate = true;
+
+    for attr in &krate.attrs {
+        if attr.check_name("doc") {
+            for list in attr.meta_item_list().into_iter() {
+                for attr in list {
+                    if attr.check_name("test") {
+                        for list in attr.meta_item_list().into_iter() {
+                            for attr in list {
+                                if attr.check_name("no_crate_inject") {
+                                    inject_crate = false;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return inject_crate;
+}
+
+#[allow(deprecated)]
 fn runtest(test: &str, cratename: &str, libs: SearchPaths,
            externs: core::Externs,
-           should_fail: bool, no_run: bool, as_test_harness: bool) {
+           should_panic: bool, no_run: bool, as_test_harness: bool,
+           inject_crate: bool) {
     // the test harness wants its own `main` & top level functions, so
     // never wrap the test in `fn main() { ... }`
-    let test = maketest(test, Some(cratename), true, as_test_harness);
+    let test = maketest(test, Some(cratename), true, as_test_harness,
+                        inject_crate);
     let input = config::Input::Str(test.to_string());
 
     let sessopts = config::Options {
-        maybe_sysroot: Some(env::current_exe().unwrap().dir_path().dir_path()),
+        maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap()
+                                              .parent().unwrap().to_path_buf()),
         search_paths: libs,
         crate_types: vec!(config::CrateTypeExecutable),
         output_types: vec!(config::OutputTypeExe),
@@ -131,30 +170,29 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
     // an explicit handle into rustc to collect output messages, but we also
     // want to catch the error message that rustc prints when it fails.
     //
-    // We take our task-local stderr (likely set by the test runner), and move
-    // it into another task. This helper task then acts as a sink for both the
-    // stderr of this task and stderr of rustc itself, copying all the info onto
-    // the stderr channel we originally started with.
+    // We take our task-local stderr (likely set by the test runner) and replace
+    // it with a sink that is also passed to rustc itself. When this function
+    // returns the output of the sink is copied onto the output of our own task.
     //
     // The basic idea is to not use a default_handler() for rustc, and then also
     // not print things by default to the actual stderr.
-    let (tx, rx) = channel();
-    let w1 = old_io::ChanWriter::new(tx);
-    let w2 = w1.clone();
-    let old = old_io::stdio::set_stderr(box w1);
-    thread::spawn(move || {
-        let mut p = old_io::ChanReader::new(rx);
-        let mut err = match old {
-            Some(old) => {
-                // Chop off the `Send` bound.
-                let old: Box<Writer> = old;
-                old
-            }
-            None => box old_io::stderr() as Box<Writer>,
-        };
-        old_io::util::copy(&mut p, &mut err).unwrap();
-    });
-    let emitter = diagnostic::EmitterWriter::new(box w2, None);
+    struct Sink(Arc<Mutex<Vec<u8>>>);
+    impl Write for Sink {
+        fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+            Write::write(&mut *self.0.lock().unwrap(), data)
+        }
+        fn flush(&mut self) -> io::Result<()> { Ok(()) }
+    }
+    struct Bomb(Arc<Mutex<Vec<u8>>>, Box<Write+Send>);
+    impl Drop for Bomb {
+        fn drop(&mut self) {
+            let _ = self.1.write_all(&self.0.lock().unwrap());
+        }
+    }
+    let data = Arc::new(Mutex::new(Vec::new()));
+    let emitter = diagnostic::EmitterWriter::new(box Sink(data.clone()), None);
+    let old = io::set_panic(box Sink(data.clone()));
+    let _bomb = Bomb(data, old.unwrap_or(box io::stdout()));
 
     // Compile the code
     let codemap = CodeMap::new();
@@ -165,9 +203,10 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
     let sess = session::build_session_(sessopts,
                                        None,
                                        span_diagnostic_handler);
+    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
     let outdir = TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir");
-    let out = Some(outdir.path().clone());
+    let out = Some(outdir.path().to_path_buf());
     let cfg = config::build_configuration(&sess);
     let libdir = sess.target_filesearch(PathKind::All).get_lib_path();
     let mut control = driver::CompileController::basic();
@@ -184,32 +223,43 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
     // environment to ensure that the target loads the right libraries at
     // runtime. It would be a sad day if the *host* libraries were loaded as a
     // mistake.
-    let mut cmd = Command::new(outdir.path().join("rust-out"));
+    let mut cmd = Command::new(&outdir.path().join("rust_out"));
+    let var = DynamicLibrary::envvar();
     let newpath = {
-        let mut path = DynamicLibrary::search_path();
+        let path = env::var_os(var).unwrap_or(OsString::new());
+        let mut path = env::split_paths(&path).collect::<Vec<_>>();
         path.insert(0, libdir.clone());
-        DynamicLibrary::create_path(&path)
+        env::join_paths(path.iter()).unwrap()
     };
-    cmd.env(DynamicLibrary::envvar(), newpath);
+    cmd.env(var, &newpath);
 
     match cmd.output() {
         Err(e) => panic!("couldn't run the test: {}{}", e,
-                        if e.kind == old_io::PermissionDenied {
+                        if e.kind() == io::ErrorKind::PermissionDenied {
                             " - maybe your tempdir is mounted with noexec?"
                         } else { "" }),
         Ok(out) => {
-            if should_fail && out.status.success() {
+            if should_panic && out.status.success() {
                 panic!("test executable succeeded when it should have failed");
-            } else if !should_fail && !out.status.success() {
-                panic!("test executable failed:\n{:?}",
-                      str::from_utf8(&out.error));
+            } else if !should_panic && !out.status.success() {
+                panic!("test executable failed:\n{}\n{}",
+                       str::from_utf8(&out.stdout).unwrap_or(""),
+                       str::from_utf8(&out.stderr).unwrap_or(""));
             }
         }
     }
 }
 
-pub fn maketest(s: &str, cratename: Option<&str>, lints: bool, dont_insert_main: bool) -> String {
+pub fn maketest(s: &str, cratename: Option<&str>, lints: bool,
+                dont_insert_main: bool, inject_crate: bool) -> String {
+    let (crate_attrs, everything_else) = partition_source(s);
+
     let mut prog = String::new();
+
+    // First push any outer attributes from the example, assuming they
+    // are intended to be crate attributes.
+    prog.push_str(&crate_attrs);
+
     if lints {
         prog.push_str(r"
 #![allow(unused_variables, unused_assignments, unused_mut, unused_attributes, dead_code)]
@@ -218,7 +268,7 @@ pub fn maketest(s: &str, cratename: Option<&str>, lints: bool, dont_insert_main:
 
     // Don't inject `extern crate std` because it's already injected by the
     // compiler.
-    if !s.contains("extern crate") && cratename != Some("std") {
+    if !s.contains("extern crate") && inject_crate {
         match cratename {
             Some(cratename) => {
                 if s.contains(cratename) {
@@ -230,30 +280,57 @@ pub fn maketest(s: &str, cratename: Option<&str>, lints: bool, dont_insert_main:
         }
     }
     if dont_insert_main || s.contains("fn main") {
-        prog.push_str(s);
+        prog.push_str(&everything_else);
     } else {
         prog.push_str("fn main() {\n    ");
-        prog.push_str(&s.replace("\n", "\n    "));
+        prog.push_str(&everything_else.replace("\n", "\n    "));
         prog.push_str("\n}");
     }
 
+    info!("final test program: {}", prog);
+
     return prog
 }
 
+fn partition_source(s: &str) -> (String, String) {
+    use unicode::str::UnicodeStr;
+
+    let mut after_header = false;
+    let mut before = String::new();
+    let mut after = String::new();
+
+    for line in s.lines() {
+        let trimline = line.trim();
+        let header = trimline.is_whitespace() ||
+            trimline.starts_with("#![feature");
+        if !header || after_header {
+            after_header = true;
+            after.push_str(line);
+            after.push_str("\n");
+        } else {
+            before.push_str(line);
+            before.push_str("\n");
+        }
+    }
+
+    return (before, after);
+}
+
 pub struct Collector {
     pub tests: Vec<testing::TestDescAndFn>,
     names: Vec<String>,
     libs: SearchPaths,
     externs: core::Externs,
-    cnt: uint,
+    cnt: usize,
     use_headers: bool,
     current_header: Option<String>,
     cratename: String,
+    inject_crate: bool
 }
 
 impl Collector {
     pub fn new(cratename: String, libs: SearchPaths, externs: core::Externs,
-               use_headers: bool) -> Collector {
+               use_headers: bool, inject_crate: bool) -> Collector {
         Collector {
             tests: Vec::new(),
             names: Vec::new(),
@@ -263,11 +340,13 @@ impl Collector {
             use_headers: use_headers,
             current_header: None,
             cratename: cratename,
+            inject_crate: inject_crate
         }
     }
 
     pub fn add_test(&mut self, test: String,
-                    should_fail: bool, no_run: bool, should_ignore: bool, as_test_harness: bool) {
+                    should_panic: bool, no_run: bool, should_ignore: bool,
+                    as_test_harness: bool) {
         let name = if self.use_headers {
             let s = self.current_header.as_ref().map(|s| &**s).unwrap_or("");
             format!("{}_{}", s, self.cnt)
@@ -278,21 +357,23 @@ impl Collector {
         let libs = self.libs.clone();
         let externs = self.externs.clone();
         let cratename = self.cratename.to_string();
+        let inject_crate = self.inject_crate;
         debug!("Creating test {}: {}", name, test);
         self.tests.push(testing::TestDescAndFn {
             desc: testing::TestDesc {
                 name: testing::DynTestName(name),
                 ignore: should_ignore,
-                should_fail: testing::ShouldFail::No, // compiler failures are test failures
+                should_panic: testing::ShouldPanic::No, // compiler failures are test failures
             },
-            testfn: testing::DynTestFn(Thunk::new(move|| {
+            testfn: testing::DynTestFn(Box::new(move|| {
                 runtest(&test,
                         &cratename,
                         libs,
                         externs,
-                        should_fail,
+                        should_panic,
                         no_run,
-                        as_test_harness);
+                        as_test_harness,
+                        inject_crate);
             }))
         });
     }
index c52b0bab1fa8b800129e3688e7423bca40dba82d..3f813b30ecc1d748aad6cf52d173a93adc861de7 100644 (file)
@@ -196,7 +196,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             Some(tcx) => tcx,
             None => return false
         };
-        let def = (*tcx.def_map.borrow())[id].def_id();
+        let def = tcx.def_map.borrow()[&id].def_id();
         if !ast_util::is_local(def) { return false }
         let analysis = match self.analysis {
             Some(analysis) => analysis, None => return false
@@ -237,7 +237,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             ast::ItemExternCrate(ref p) => {
                 let path = match *p {
                     None => None,
-                    Some((ref x, _)) => Some(x.to_string()),
+                    Some(x) => Some(x.to_string()),
                 };
                 om.extern_crates.push(ExternCrate {
                     name: name,
@@ -253,7 +253,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     let please_inline = item.attrs.iter().any(|item| {
                         match item.meta_item_list() {
                             Some(list) => {
-                                list.iter().any(|i| &i.name()[] == "inline")
+                                list.iter().any(|i| &i.name()[..] == "inline")
                             }
                             None => false,
                         }
@@ -358,6 +358,16 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 };
                 om.impls.push(i);
             },
+            ast::ItemDefaultImpl(unsafety, ref trait_ref) => {
+                let i = DefaultImpl {
+                    unsafety: unsafety,
+                    trait_: trait_ref.clone(),
+                    id: item.id,
+                    attrs: item.attrs.clone(),
+                    whence: item.span,
+                };
+                om.def_traits.push(i);
+            }
             ast::ItemForeignMod(ref fm) => {
                 om.foreigns.push(fm.clone());
             }
index 10cf02f85e818579e5ed811acaa424ee4e65b251..e7430f698e9c962e5bdec559d7a18ec3ba70004b 100644 (file)
@@ -13,7 +13,6 @@
 use std::usize;
 use std::default::Default;
 use std::hash::Hash;
-#[cfg(stage0)] use std::hash::Hasher;
 use std::collections::hash_state::HashState;
 
 use {Decodable, Encodable, Decoder, Encoder};
@@ -158,26 +157,6 @@ impl<
     }
 }
 
-#[cfg(stage0)]
-impl<K, V, S> Encodable for HashMap<K, V, S>
-    where K: Encodable + Hash< <S as HashState>::Hasher> + Eq,
-          V: Encodable,
-          S: HashState,
-          <S as HashState>::Hasher: Hasher<Output=u64>
-{
-    fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
-        e.emit_map(self.len(), |e| {
-            let mut i = 0;
-            for (key, val) in self {
-                try!(e.emit_map_elt_key(i, |e| key.encode(e)));
-                try!(e.emit_map_elt_val(i, |e| val.encode(e)));
-                i += 1;
-            }
-            Ok(())
-        })
-    }
-}
-#[cfg(not(stage0))]
 impl<K, V, S> Encodable for HashMap<K, V, S>
     where K: Encodable + Hash + Eq,
           V: Encodable,
@@ -196,27 +175,6 @@ impl<K, V, S> Encodable for HashMap<K, V, S>
     }
 }
 
-#[cfg(stage0)]
-impl<K, V, S> Decodable for HashMap<K, V, S>
-    where K: Decodable + Hash< <S as HashState>::Hasher> + Eq,
-          V: Decodable,
-          S: HashState + Default,
-          <S as HashState>::Hasher: Hasher<Output=u64>
-{
-    fn decode<D: Decoder>(d: &mut D) -> Result<HashMap<K, V, S>, D::Error> {
-        d.read_map(|d, len| {
-            let state = Default::default();
-            let mut map = HashMap::with_capacity_and_hash_state(len, state);
-            for i in 0..len {
-                let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
-                let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
-                map.insert(key, val);
-            }
-            Ok(map)
-        })
-    }
-}
-#[cfg(not(stage0))]
 impl<K, V, S> Decodable for HashMap<K, V, S>
     where K: Decodable + Hash + Eq,
           V: Decodable,
@@ -236,24 +194,6 @@ impl<K, V, S> Decodable for HashMap<K, V, S>
     }
 }
 
-#[cfg(stage0)]
-impl<T, S> Encodable for HashSet<T, S>
-    where T: Encodable + Hash< <S as HashState>::Hasher> + Eq,
-          S: HashState,
-          <S as HashState>::Hasher: Hasher<Output=u64>
-{
-    fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
-        s.emit_seq(self.len(), |s| {
-            let mut i = 0;
-            for e in self {
-                try!(s.emit_seq_elt(i, |s| e.encode(s)));
-                i += 1;
-            }
-            Ok(())
-        })
-    }
-}
-#[cfg(not(stage0))]
 impl<T, S> Encodable for HashSet<T, S>
     where T: Encodable + Hash + Eq,
           S: HashState,
@@ -270,24 +210,6 @@ impl<T, S> Encodable for HashSet<T, S>
     }
 }
 
-#[cfg(stage0)]
-impl<T, S> Decodable for HashSet<T, S>
-    where T: Decodable + Hash< <S as HashState>::Hasher> + Eq,
-          S: HashState + Default,
-          <S as HashState>::Hasher: Hasher<Output=u64>
-{
-    fn decode<D: Decoder>(d: &mut D) -> Result<HashSet<T, S>, D::Error> {
-        d.read_seq(|d, len| {
-            let state = Default::default();
-            let mut set = HashSet::with_capacity_and_hash_state(len, state);
-            for i in 0..len {
-                set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
-            }
-            Ok(set)
-        })
-    }
-}
-#[cfg(not(stage0))]
 impl<T, S> Decodable for HashSet<T, S>
     where T: Decodable + Hash + Eq,
           S: HashState + Default,
index a3cc2d6b935d9fab31d9bea4d38968ea822132e1..0676edf81696f5647048681cccddb38ad175c81c 100644 (file)
@@ -24,14 +24,15 @@ pub trait ToHex {
     fn to_hex(&self) -> String;
 }
 
-static CHARS: &'static[u8] = b"0123456789abcdef";
+const CHARS: &'static [u8] = b"0123456789abcdef";
 
 impl ToHex for [u8] {
     /// Turn a vector of `u8` bytes into a hexadecimal string.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(rustc_private)]
     /// extern crate serialize;
     /// use serialize::hex::ToHex;
     ///
@@ -43,8 +44,8 @@ impl ToHex for [u8] {
     fn to_hex(&self) -> String {
         let mut v = Vec::with_capacity(self.len() * 2);
         for &byte in self {
-            v.push(CHARS[(byte >> 4) as uint]);
-            v.push(CHARS[(byte & 0xf) as uint]);
+            v.push(CHARS[(byte >> 4) as usize]);
+            v.push(CHARS[(byte & 0xf) as usize]);
         }
 
         unsafe {
@@ -61,10 +62,10 @@ pub trait FromHex {
 }
 
 /// Errors that can occur when decoding a hex encoded string
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum FromHexError {
     /// The input contained a character not part of the hex format
-    InvalidHexCharacter(char, uint),
+    InvalidHexCharacter(char, usize),
     /// The input had an invalid length
     InvalidHexLength,
 }
@@ -96,11 +97,12 @@ impl FromHex for str {
     /// You can use the `String::from_utf8` function to turn a
     /// `Vec<u8>` into a string with characters corresponding to those values.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// This converts a string literal to hexadecimal and back.
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(rustc_private)]
     /// extern crate serialize;
     /// use serialize::hex::{FromHex, ToHex};
     ///
@@ -117,7 +119,7 @@ impl FromHex for str {
         // This may be an overestimate if there is any whitespace
         let mut b = Vec::with_capacity(self.len() / 2);
         let mut modulus = 0;
-        let mut buf = 0u8;
+        let mut buf = 0;
 
         for (idx, byte) in self.bytes().enumerate() {
             buf <<= 4;
@@ -186,7 +188,7 @@ mod tests {
     #[test]
     pub fn test_to_hex_all_bytes() {
         for i in 0..256 {
-            assert_eq!([i as u8].to_hex(), format!("{:02x}", i as uint));
+            assert_eq!([i as u8].to_hex(), format!("{:02x}", i as usize));
         }
     }
 
@@ -194,10 +196,10 @@ mod tests {
     pub fn test_from_hex_all_bytes() {
         for i in 0..256 {
             let ii: &[u8] = &[i as u8];
-            assert_eq!(format!("{:02x}", i as uint).from_hex()
+            assert_eq!(format!("{:02x}", i as usize).from_hex()
                                                    .unwrap(),
                        ii);
-            assert_eq!(format!("{:02X}", i as uint).from_hex()
+            assert_eq!(format!("{:02X}", i as usize).from_hex()
                                                    .unwrap(),
                        ii);
         }
index a0f42815b439611b61fd1e07a748b69adaa2cef4..5890bdec8c1bcdbcc66524c324095a7ceb91fd77 100644 (file)
 //!     let encoded = json::encode(&object).unwrap();
 //!
 //!     // Deserialize using `json::decode`
-//!     let decoded: TestStruct = json::decode(encoded.as_slice()).unwrap();
+//!     let decoded: TestStruct = json::decode(&encoded[..]).unwrap();
 //! }
 //! ```
 //!
 //!     let json_str: String = json_obj.to_string();
 //!
 //!     // Deserialize like before
-//!     let decoded: TestStruct = json::decode(json_str.as_slice()).unwrap();
+//!     let decoded: TestStruct = json::decode(json_str)).unwrap();
 //! }
 //! ```
 
@@ -199,15 +199,18 @@ use self::DecoderError::*;
 use self::ParserState::*;
 use self::InternalStackElement::*;
 
-use std;
 use std::collections::{HashMap, BTreeMap};
-use std::{char, f64, fmt, old_io, num, str};
-use std::mem::{swap};
-use std::num::{Float, Int};
+use std::io::prelude::*;
+use std::io;
+use std::mem::swap;
 use std::num::FpCategory as Fp;
+#[allow(deprecated)]
+use std::num::wrapping::WrappingOps;
+use std::ops::Index;
 use std::str::FromStr;
 use std::string;
-use std::ops::Index;
+use std::{char, f64, fmt, num, str};
+use std;
 use unicode::str as unicode_str;
 use unicode::str::Utf16Item;
 
@@ -232,7 +235,7 @@ pub type Object = BTreeMap<string::String, Json>;
 pub struct PrettyJson<'a> { inner: &'a Json }
 
 pub struct AsJson<'a, T: 'a> { inner: &'a T }
-pub struct AsPrettyJson<'a, T: 'a> { inner: &'a T, indent: Option<uint> }
+pub struct AsPrettyJson<'a, T: 'a> { inner: &'a T, indent: Option<usize> }
 
 /// The errors that can arise while parsing a JSON stream.
 #[derive(Clone, Copy, PartialEq, Debug)]
@@ -256,11 +259,11 @@ pub enum ErrorCode {
     NotUtf8,
 }
 
-#[derive(Clone, Copy, PartialEq, Debug)]
+#[derive(Clone, PartialEq, Debug)]
 pub enum ParserError {
     /// msg, line, col
-    SyntaxError(ErrorCode, uint, uint),
-    IoError(old_io::IoErrorKind, &'static str),
+    SyntaxError(ErrorCode, usize, usize),
+    IoError(io::ErrorKind, String),
 }
 
 // Builder and Parser have the same errors.
@@ -275,7 +278,7 @@ pub enum DecoderError {
     ApplicationError(string::String)
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum EncoderError {
     FmtError(fmt::Error),
     BadHashmapKey,
@@ -331,8 +334,8 @@ impl fmt::Display for ErrorCode {
     }
 }
 
-fn io_error_to_error(io: old_io::IoError) -> ParserError {
-    IoError(io.kind, io.desc)
+fn io_error_to_error(io: io::Error) -> ParserError {
+    IoError(io.kind(), io.to_string())
 }
 
 impl fmt::Display for ParserError {
@@ -364,8 +367,8 @@ impl std::error::Error for EncoderError {
     fn description(&self) -> &str { "encoder error" }
 }
 
-impl std::error::FromError<fmt::Error> for EncoderError {
-    fn from_error(err: fmt::Error) -> EncoderError { EncoderError::FmtError(err) }
+impl From<fmt::Error> for EncoderError {
+    fn from(err: fmt::Error) -> EncoderError { EncoderError::FmtError(err) }
 }
 
 pub type EncodeResult = Result<(), EncoderError>;
@@ -440,7 +443,7 @@ fn escape_char(writer: &mut fmt::Write, v: char) -> EncodeResult {
     escape_str(writer, buf)
 }
 
-fn spaces(wr: &mut fmt::Write, mut n: uint) -> EncodeResult {
+fn spaces(wr: &mut fmt::Write, mut n: usize) -> EncodeResult {
     const BUF: &'static str = "                ";
 
     while n >= BUF.len() {
@@ -497,13 +500,13 @@ impl<'a> ::Encoder for Encoder<'a> {
         Ok(())
     }
 
-    fn emit_uint(&mut self, v: uint) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
+    fn emit_uint(&mut self, v: usize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_u64(&mut self, v: u64) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_u32(&mut self, v: u32) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_u16(&mut self, v: u16) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_u8(&mut self, v: u8) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
 
-    fn emit_int(&mut self, v: int) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
+    fn emit_int(&mut self, v: isize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_i64(&mut self, v: i64) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_i32(&mut self, v: i32) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_i16(&mut self, v: i16) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
@@ -541,8 +544,8 @@ impl<'a> ::Encoder for Encoder<'a> {
 
     fn emit_enum_variant<F>(&mut self,
                             name: &str,
-                            _id: uint,
-                            cnt: uint,
+                            _id: usize,
+                            cnt: usize,
                             f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
@@ -562,7 +565,7 @@ impl<'a> ::Encoder for Encoder<'a> {
         }
     }
 
-    fn emit_enum_variant_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+    fn emit_enum_variant_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -574,8 +577,8 @@ impl<'a> ::Encoder for Encoder<'a> {
 
     fn emit_enum_struct_variant<F>(&mut self,
                                    name: &str,
-                                   id: uint,
-                                   cnt: uint,
+                                   id: usize,
+                                   cnt: usize,
                                    f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
@@ -585,7 +588,7 @@ impl<'a> ::Encoder for Encoder<'a> {
 
     fn emit_enum_struct_variant_field<F>(&mut self,
                                          _: &str,
-                                         idx: uint,
+                                         idx: usize,
                                          f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
@@ -593,7 +596,7 @@ impl<'a> ::Encoder for Encoder<'a> {
         self.emit_enum_variant_arg(idx, f)
     }
 
-    fn emit_struct<F>(&mut self, _: &str, _: uint, f: F) -> EncodeResult where
+    fn emit_struct<F>(&mut self, _: &str, _: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -603,7 +606,7 @@ impl<'a> ::Encoder for Encoder<'a> {
         Ok(())
     }
 
-    fn emit_struct_field<F>(&mut self, name: &str, idx: uint, f: F) -> EncodeResult where
+    fn emit_struct_field<F>(&mut self, name: &str, idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -613,26 +616,26 @@ impl<'a> ::Encoder for Encoder<'a> {
         f(self)
     }
 
-    fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
+    fn emit_tuple<F>(&mut self, len: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
         self.emit_seq(len, f)
     }
-    fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
         self.emit_seq_elt(idx, f)
     }
 
-    fn emit_tuple_struct<F>(&mut self, _name: &str, len: uint, f: F) -> EncodeResult where
+    fn emit_tuple_struct<F>(&mut self, _name: &str, len: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
         self.emit_seq(len, f)
     }
-    fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+    fn emit_tuple_struct_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -656,7 +659,7 @@ impl<'a> ::Encoder for Encoder<'a> {
         f(self)
     }
 
-    fn emit_seq<F>(&mut self, _len: uint, f: F) -> EncodeResult where
+    fn emit_seq<F>(&mut self, _len: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -666,7 +669,7 @@ impl<'a> ::Encoder for Encoder<'a> {
         Ok(())
     }
 
-    fn emit_seq_elt<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -676,7 +679,7 @@ impl<'a> ::Encoder for Encoder<'a> {
         f(self)
     }
 
-    fn emit_map<F>(&mut self, _len: uint, f: F) -> EncodeResult where
+    fn emit_map<F>(&mut self, _len: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -686,7 +689,7 @@ impl<'a> ::Encoder for Encoder<'a> {
         Ok(())
     }
 
-    fn emit_map_elt_key<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -697,7 +700,7 @@ impl<'a> ::Encoder for Encoder<'a> {
         Ok(())
     }
 
-    fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
+    fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -710,8 +713,8 @@ impl<'a> ::Encoder for Encoder<'a> {
 /// compact data
 pub struct PrettyEncoder<'a> {
     writer: &'a mut (fmt::Write+'a),
-    curr_indent: uint,
-    indent: uint,
+    curr_indent: usize,
+    indent: usize,
     is_emitting_map_key: bool,
 }
 
@@ -728,7 +731,7 @@ impl<'a> PrettyEncoder<'a> {
 
     /// Set the number of spaces to indent for each level.
     /// This is safe to set during encoding.
-    pub fn set_indent(&mut self, indent: uint) {
+    pub fn set_indent(&mut self, indent: usize) {
         // self.indent very well could be 0 so we need to use checked division.
         let level = self.curr_indent.checked_div(self.indent).unwrap_or(0);
         self.indent = indent;
@@ -745,13 +748,13 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
         Ok(())
     }
 
-    fn emit_uint(&mut self, v: uint) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
+    fn emit_uint(&mut self, v: usize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_u64(&mut self, v: u64) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_u32(&mut self, v: u32) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_u16(&mut self, v: u16) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_u8(&mut self, v: u8) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
 
-    fn emit_int(&mut self, v: int) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
+    fn emit_int(&mut self, v: isize) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_i64(&mut self, v: i64) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_i32(&mut self, v: i32) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
     fn emit_i16(&mut self, v: i16) -> EncodeResult { emit_enquoted_if_mapkey!(self, v) }
@@ -789,8 +792,8 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
 
     fn emit_enum_variant<F>(&mut self,
                             name: &str,
-                            _id: uint,
-                            cnt: uint,
+                            _id: usize,
+                            cnt: usize,
                             f: F)
                             -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
@@ -820,7 +823,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
         }
     }
 
-    fn emit_enum_variant_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+    fn emit_enum_variant_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -833,8 +836,8 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
 
     fn emit_enum_struct_variant<F>(&mut self,
                                    name: &str,
-                                   id: uint,
-                                   cnt: uint,
+                                   id: usize,
+                                   cnt: usize,
                                    f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
@@ -844,7 +847,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
 
     fn emit_enum_struct_variant_field<F>(&mut self,
                                          _: &str,
-                                         idx: uint,
+                                         idx: usize,
                                          f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
@@ -853,7 +856,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
     }
 
 
-    fn emit_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
+    fn emit_struct<F>(&mut self, _: &str, len: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -871,7 +874,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
         Ok(())
     }
 
-    fn emit_struct_field<F>(&mut self, name: &str, idx: uint, f: F) -> EncodeResult where
+    fn emit_struct_field<F>(&mut self, name: &str, idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -886,26 +889,26 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
         f(self)
     }
 
-    fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
+    fn emit_tuple<F>(&mut self, len: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
         self.emit_seq(len, f)
     }
-    fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
         self.emit_seq_elt(idx, f)
     }
 
-    fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
+    fn emit_tuple_struct<F>(&mut self, _: &str, len: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
         self.emit_seq(len, f)
     }
-    fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+    fn emit_tuple_struct_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -929,7 +932,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
         f(self)
     }
 
-    fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where
+    fn emit_seq<F>(&mut self, len: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -947,7 +950,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
         Ok(())
     }
 
-    fn emit_seq_elt<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -960,7 +963,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
         f(self)
     }
 
-    fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where
+    fn emit_map<F>(&mut self, len: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -978,7 +981,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
         Ok(())
     }
 
-    fn emit_map_elt_key<F>(&mut self, idx: uint, f: F) -> EncodeResult where
+    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -994,7 +997,7 @@ impl<'a> ::Encoder for PrettyEncoder<'a> {
         Ok(())
     }
 
-    fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
+    fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> EncodeResult where
         F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult,
     {
         if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); }
@@ -1220,18 +1223,18 @@ impl Json {
 impl<'a> Index<&'a str>  for Json {
     type Output = Json;
 
-    fn index(&self, idx: & &str) -> &Json {
-        self.find(*idx).unwrap()
+    fn index(&self, idx: &'a str) -> &Json {
+        self.find(idx).unwrap()
     }
 }
 
-impl Index<uint> for Json {
+impl Index<usize> for Json {
     type Output = Json;
 
-    fn index<'a>(&'a self, idx: &uint) -> &'a Json {
+    fn index<'a>(&'a self, idx: usize) -> &'a Json {
         match self {
-            &Json::Array(ref v) => &v[*idx],
-            _ => panic!("can only index Json with uint if it is an array")
+            &Json::Array(ref v) => &v[idx],
+            _ => panic!("can only index Json with usize if it is an array")
         }
     }
 }
@@ -1302,7 +1305,7 @@ impl Stack {
     }
 
     /// Returns The number of elements in the Stack.
-    pub fn len(&self) -> uint { self.stack.len() }
+    pub fn len(&self) -> usize { self.stack.len() }
 
     /// Returns true if the stack is empty.
     pub fn is_empty(&self) -> bool { self.stack.is_empty() }
@@ -1310,12 +1313,12 @@ impl Stack {
     /// Provides access to the StackElement at a given index.
     /// lower indices are at the bottom of the stack while higher indices are
     /// at the top.
-    pub fn get<'l>(&'l self, idx: uint) -> StackElement<'l> {
+    pub fn get<'l>(&'l self, idx: usize) -> StackElement<'l> {
         match self.stack[idx] {
             InternalIndex(i) => StackElement::Index(i),
             InternalKey(start, size) => {
                 StackElement::Key(str::from_utf8(
-                    &self.str_buffer[start as uint .. start as uint + size as uint])
+                    &self.str_buffer[start as usize .. start as usize + size as usize])
                         .unwrap())
             }
         }
@@ -1358,7 +1361,7 @@ impl Stack {
             Some(&InternalIndex(i)) => Some(StackElement::Index(i)),
             Some(&InternalKey(start, size)) => {
                 Some(StackElement::Key(str::from_utf8(
-                    &self.str_buffer[start as uint .. (start+size) as uint]
+                    &self.str_buffer[start as usize .. (start+size) as usize]
                 ).unwrap()))
             }
         }
@@ -1382,7 +1385,7 @@ impl Stack {
         assert!(!self.is_empty());
         match *self.stack.last().unwrap() {
             InternalKey(_, sz) => {
-                let new_size = self.str_buffer.len() - sz as uint;
+                let new_size = self.str_buffer.len() - sz as usize;
                 self.str_buffer.truncate(new_size);
             }
             InternalIndex(_) => {}
@@ -1415,8 +1418,8 @@ impl Stack {
 pub struct Parser<T> {
     rdr: T,
     ch: Option<char>,
-    line: uint,
-    col: uint,
+    line: usize,
+    col: usize,
     // We maintain a stack representing where we are in the logical structure
     // of the JSON stream.
     stack: Stack,
@@ -1551,6 +1554,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
         }
     }
 
+    #[allow(deprecated)] // possible resolve bug is mapping these to traits
     fn parse_u64(&mut self) -> Result<u64, ParserError> {
         let mut accum = 0;
         let last_accum = 0; // necessary to detect overflow.
@@ -1569,8 +1573,8 @@ impl<T: Iterator<Item=char>> Parser<T> {
                 while !self.eof() {
                     match self.ch_or_null() {
                         c @ '0' ... '9' => {
-                            accum *= 10;
-                            accum += (c as u64) - ('0' as u64);
+                            accum = accum.wrapping_mul(10);
+                            accum = accum.wrapping_add((c as u64) - ('0' as u64));
 
                             // Detect overflow by comparing to the last value.
                             if accum <= last_accum { return self.error(InvalidNumber); }
@@ -1601,7 +1605,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
             match self.ch_or_null() {
                 c @ '0' ... '9' => {
                     dec /= 10.0;
-                    res += (((c as int) - ('0' as int)) as f64) * dec;
+                    res += (((c as isize) - ('0' as isize)) as f64) * dec;
                     self.bump();
                 }
                 _ => break,
@@ -1633,7 +1637,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
             match self.ch_or_null() {
                 c @ '0' ... '9' => {
                     exp *= 10;
-                    exp += (c as uint) - ('0' as uint);
+                    exp += (c as usize) - ('0' as usize);
 
                     self.bump();
                 }
@@ -1653,7 +1657,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
 
     fn decode_hex_escape(&mut self) -> Result<u16, ParserError> {
         let mut i = 0;
-        let mut n = 0u16;
+        let mut n = 0;
         while i < 4 && !self.eof() {
             self.bump();
             n = match self.ch_or_null() {
@@ -1745,7 +1749,7 @@ impl<T: Iterator<Item=char>> Parser<T> {
     // information to return a JsonEvent.
     // Manages an internal state so that parsing can be interrupted and resumed.
     // Also keeps track of the position in the logical structure of the json
-    // stream int the form of a stack that can be queried by the user using the
+    // stream isize the form of a stack that can be queried by the user using the
     // stack() method.
     fn parse(&mut self) -> JsonEvent {
         loop {
@@ -1982,7 +1986,7 @@ impl<T: Iterator<Item=char>> Builder<T> {
         self.bump();
         match self.token {
             None => {}
-            Some(Error(e)) => { return Err(e); }
+            Some(Error(ref e)) => { return Err(e.clone()); }
             ref tok => { panic!("unexpected token {:?}", tok.clone()); }
         }
         result
@@ -2004,7 +2008,7 @@ impl<T: Iterator<Item=char>> Builder<T> {
                 swap(s, &mut temp);
                 Ok(Json::String(temp))
             }
-            Some(Error(e)) => Err(e),
+            Some(Error(ref e)) => Err(e.clone()),
             Some(ArrayStart) => self.build_array(),
             Some(ObjectStart) => self.build_object(),
             Some(ObjectEnd) => self.parser.error(InvalidSyntax),
@@ -2037,7 +2041,7 @@ impl<T: Iterator<Item=char>> Builder<T> {
         loop {
             match self.token {
                 Some(ObjectEnd) => { return Ok(Json::Object(values)); }
-                Some(Error(e)) => { return Err(e); }
+                Some(Error(ref e)) => { return Err(e.clone()); }
                 None => { break; }
                 _ => {}
             }
@@ -2056,8 +2060,9 @@ impl<T: Iterator<Item=char>> Builder<T> {
 }
 
 /// Decodes a json value from an `&mut old_io::Reader`
-pub fn from_reader(rdr: &mut old_io::Reader) -> Result<Json, BuilderError> {
-    let contents = match rdr.read_to_end() {
+pub fn from_reader(rdr: &mut Read) -> Result<Json, BuilderError> {
+    let mut contents = Vec::new();
+    match rdr.read_to_end(&mut contents) {
         Ok(c)  => c,
         Err(e) => return Err(io_error_to_error(e))
     };
@@ -2125,7 +2130,7 @@ macro_rules! read_primitive {
                     None => Err(ExpectedError("Number".to_string(), format!("{}", f))),
                 },
                 Json::F64(f) => Err(ExpectedError("Integer".to_string(), format!("{}", f))),
-                // re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
+                // re: #12967.. a type w/ numeric keys (ie HashMap<usize, V> etc)
                 // is going to have a string here, as per JSON spec.
                 Json::String(s) => match s.parse().ok() {
                     Some(f) => Ok(f),
@@ -2144,12 +2149,12 @@ impl ::Decoder for Decoder {
         expect!(self.pop(), Null)
     }
 
-    read_primitive! { read_uint, uint }
+    read_primitive! { read_uint, usize }
     read_primitive! { read_u8, u8 }
     read_primitive! { read_u16, u16 }
     read_primitive! { read_u32, u32 }
     read_primitive! { read_u64, u64 }
-    read_primitive! { read_int, int }
+    read_primitive! { read_int, isize }
     read_primitive! { read_i8, i8 }
     read_primitive! { read_i16, i16 }
     read_primitive! { read_i32, i32 }
@@ -2163,7 +2168,7 @@ impl ::Decoder for Decoder {
             Json::U64(f) => Ok(f as f64),
             Json::F64(f) => Ok(f),
             Json::String(s) => {
-                // re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
+                // re: #12967.. a type w/ numeric keys (ie HashMap<usize, V> etc)
                 // is going to have a string here, as per JSON spec.
                 match s.parse().ok() {
                     Some(f) => Ok(f),
@@ -2204,7 +2209,7 @@ impl ::Decoder for Decoder {
 
     fn read_enum_variant<T, F>(&mut self, names: &[&str],
                                mut f: F) -> DecodeResult<T>
-        where F: FnMut(&mut Decoder, uint) -> DecodeResult<T>,
+        where F: FnMut(&mut Decoder, usize) -> DecodeResult<T>,
     {
         let name = match self.pop() {
             Json::String(s) => s,
@@ -2244,14 +2249,14 @@ impl ::Decoder for Decoder {
         f(self, idx)
     }
 
-    fn read_enum_variant_arg<T, F>(&mut self, _idx: uint, f: F) -> DecodeResult<T> where
+    fn read_enum_variant_arg<T, F>(&mut self, _idx: usize, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
         f(self)
     }
 
     fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> DecodeResult<T> where
-        F: FnMut(&mut Decoder, uint) -> DecodeResult<T>,
+        F: FnMut(&mut Decoder, usize) -> DecodeResult<T>,
     {
         self.read_enum_variant(names, f)
     }
@@ -2259,7 +2264,7 @@ impl ::Decoder for Decoder {
 
     fn read_enum_struct_variant_field<T, F>(&mut self,
                                          _name: &str,
-                                         idx: uint,
+                                         idx: usize,
                                          f: F)
                                          -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
@@ -2267,7 +2272,7 @@ impl ::Decoder for Decoder {
         self.read_enum_variant_arg(idx, f)
     }
 
-    fn read_struct<T, F>(&mut self, _name: &str, _len: uint, f: F) -> DecodeResult<T> where
+    fn read_struct<T, F>(&mut self, _name: &str, _len: usize, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
         let value = try!(f(self));
@@ -2277,7 +2282,7 @@ impl ::Decoder for Decoder {
 
     fn read_struct_field<T, F>(&mut self,
                                name: &str,
-                               _idx: uint,
+                               _idx: usize,
                                f: F)
                                -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
@@ -2303,7 +2308,7 @@ impl ::Decoder for Decoder {
         Ok(value)
     }
 
-    fn read_tuple<T, F>(&mut self, tuple_len: uint, f: F) -> DecodeResult<T> where
+    fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
         self.read_seq(move |d, len| {
@@ -2315,7 +2320,7 @@ impl ::Decoder for Decoder {
         })
     }
 
-    fn read_tuple_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
+    fn read_tuple_arg<T, F>(&mut self, idx: usize, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
         self.read_seq_elt(idx, f)
@@ -2323,7 +2328,7 @@ impl ::Decoder for Decoder {
 
     fn read_tuple_struct<T, F>(&mut self,
                                _name: &str,
-                               len: uint,
+                               len: usize,
                                f: F)
                                -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
@@ -2332,7 +2337,7 @@ impl ::Decoder for Decoder {
     }
 
     fn read_tuple_struct_arg<T, F>(&mut self,
-                                   idx: uint,
+                                   idx: usize,
                                    f: F)
                                    -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
@@ -2350,7 +2355,7 @@ impl ::Decoder for Decoder {
     }
 
     fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T> where
-        F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder, usize) -> DecodeResult<T>,
     {
         let array = try!(expect!(self.pop(), Array));
         let len = array.len();
@@ -2360,14 +2365,14 @@ impl ::Decoder for Decoder {
         f(self, len)
     }
 
-    fn read_seq_elt<T, F>(&mut self, _idx: uint, f: F) -> DecodeResult<T> where
+    fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> DecodeResult<T> where
         F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
         f(self)
     }
 
     fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T> where
-        F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>,
+        F: FnOnce(&mut Decoder, usize) -> DecodeResult<T>,
     {
         let obj = try!(expect!(self.pop(), Object));
         let len = obj.len();
@@ -2378,13 +2383,13 @@ impl ::Decoder for Decoder {
         f(self, len)
     }
 
-    fn read_map_elt_key<T, F>(&mut self, _idx: uint, f: F) -> DecodeResult<T> where
+    fn read_map_elt_key<T, F>(&mut self, _idx: usize, f: F) -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
         f(self)
     }
 
-    fn read_map_elt_val<T, F>(&mut self, _idx: uint, f: F) -> DecodeResult<T> where
+    fn read_map_elt_val<T, F>(&mut self, _idx: usize, f: F) -> DecodeResult<T> where
        F: FnOnce(&mut Decoder) -> DecodeResult<T>,
     {
         f(self)
@@ -2404,22 +2409,26 @@ pub trait ToJson {
 macro_rules! to_json_impl_i64 {
     ($($t:ty), +) => (
         $(impl ToJson for $t {
-            fn to_json(&self) -> Json { Json::I64(*self as i64) }
+            fn to_json(&self) -> Json {
+                Json::I64(*self as i64)
+            }
         })+
     )
 }
 
-to_json_impl_i64! { int, i8, i16, i32, i64 }
+to_json_impl_i64! { isize, i8, i16, i32, i64 }
 
 macro_rules! to_json_impl_u64 {
     ($($t:ty), +) => (
         $(impl ToJson for $t {
-            fn to_json(&self) -> Json { Json::U64(*self as u64) }
+            fn to_json(&self) -> Json {
+                Json::U64(*self as u64)
+            }
         })+
     )
 }
 
-to_json_impl_u64! { uint, u8, u16, u32, u64 }
+to_json_impl_u64! { usize, u8, u16, u32, u64 }
 
 impl ToJson for Json {
     fn to_json(&self) -> Json { self.clone() }
@@ -2574,7 +2583,7 @@ impl<'a, T: Encodable> fmt::Display for AsJson<'a, T> {
 
 impl<'a, T> AsPrettyJson<'a, T> {
     /// Set the indentation level for the emitted JSON
-    pub fn indent(mut self, indent: uint) -> AsPrettyJson<'a, T> {
+    pub fn indent(mut self, indent: usize) -> AsPrettyJson<'a, T> {
         self.indent = Some(indent);
         self
     }
@@ -2619,12 +2628,12 @@ mod tests {
                 StackElement, Stack, Decoder, Encoder, EncoderError};
     use std::{i64, u64, f32, f64};
     use std::collections::BTreeMap;
-    use std::num::Float;
     use std::string;
+    use std::old_io::Writer;
 
     #[derive(RustcDecodable, Eq, PartialEq, Debug)]
     struct OptionData {
-        opt: Option<uint>,
+        opt: Option<usize>,
     }
 
     #[test]
@@ -2652,13 +2661,13 @@ mod tests {
     #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
     enum Animal {
         Dog,
-        Frog(string::String, int)
+        Frog(string::String, isize)
     }
 
     #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
     struct Inner {
         a: (),
-        b: uint,
+        b: usize,
         c: Vec<string::String>,
     }
 
@@ -3074,38 +3083,38 @@ mod tests {
     #[test]
     fn test_decode_array() {
         let v: Vec<()> = super::decode("[]").unwrap();
-        assert_eq!(v, vec![]);
+        assert_eq!(v, []);
 
         let v: Vec<()> = super::decode("[null]").unwrap();
-        assert_eq!(v, vec![()]);
+        assert_eq!(v, [()]);
 
         let v: Vec<bool> = super::decode("[true]").unwrap();
-        assert_eq!(v, vec![true]);
+        assert_eq!(v, [true]);
 
-        let v: Vec<int> = super::decode("[3, 1]").unwrap();
-        assert_eq!(v, vec![3, 1]);
+        let v: Vec<isize> = super::decode("[3, 1]").unwrap();
+        assert_eq!(v, [3, 1]);
 
-        let v: Vec<Vec<uint>> = super::decode("[[3], [1, 2]]").unwrap();
-        assert_eq!(v, vec![vec![3], vec![1, 2]]);
+        let v: Vec<Vec<usize>> = super::decode("[[3], [1, 2]]").unwrap();
+        assert_eq!(v, [vec![3], vec![1, 2]]);
     }
 
     #[test]
     fn test_decode_tuple() {
-        let t: (uint, uint, uint) = super::decode("[1, 2, 3]").unwrap();
+        let t: (usize, usize, usize) = super::decode("[1, 2, 3]").unwrap();
         assert_eq!(t, (1, 2, 3));
 
-        let t: (uint, string::String) = super::decode("[1, \"two\"]").unwrap();
+        let t: (usize, string::String) = super::decode("[1, \"two\"]").unwrap();
         assert_eq!(t, (1, "two".to_string()));
     }
 
     #[test]
     fn test_decode_tuple_malformed_types() {
-        assert!(super::decode::<(uint, string::String)>("[1, 2]").is_err());
+        assert!(super::decode::<(usize, string::String)>("[1, 2]").is_err());
     }
 
     #[test]
     fn test_decode_tuple_malformed_length() {
-        assert!(super::decode::<(uint, uint)>("[1, 2, 3]").is_err());
+        assert!(super::decode::<(usize, usize)>("[1, 2, 3]").is_err());
     }
 
     #[test]
@@ -3457,7 +3466,7 @@ mod tests {
         use std::str::from_utf8;
         use std::old_io::Writer;
         use std::collections::HashMap;
-        let mut hm: HashMap<uint, bool> = HashMap::new();
+        let mut hm: HashMap<usize, bool> = HashMap::new();
         hm.insert(1, true);
         let mut mem_buf = Vec::new();
         write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap();
@@ -3473,7 +3482,7 @@ mod tests {
         use std::str::from_utf8;
         use std::old_io::Writer;
         use std::collections::HashMap;
-        let mut hm: HashMap<uint, bool> = HashMap::new();
+        let mut hm: HashMap<usize, bool> = HashMap::new();
         hm.insert(1, true);
         let mut mem_buf = Vec::new();
         write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap();
@@ -3506,7 +3515,7 @@ mod tests {
         );
 
         // Helper function for counting indents
-        fn indents(source: &str) -> uint {
+        fn indents(source: &str) -> usize {
             let trimmed = source.trim_left_matches(' ');
             source.len() - trimmed.len()
         }
@@ -3564,7 +3573,7 @@ mod tests {
             Ok(o) => o
         };
         let mut decoder = Decoder::new(json_obj);
-        let _hm: HashMap<uint, bool> = Decodable::decode(&mut decoder).unwrap();
+        let _hm: HashMap<usize, bool> = Decodable::decode(&mut decoder).unwrap();
     }
 
     #[test]
@@ -3577,7 +3586,7 @@ mod tests {
             Ok(o) => o
         };
         let mut decoder = Decoder::new(json_obj);
-        let result: Result<HashMap<uint, bool>, DecoderError> = Decodable::decode(&mut decoder);
+        let result: Result<HashMap<usize, bool>, DecoderError> = Decodable::decode(&mut decoder);
         assert_eq!(result, Err(ExpectedError("Number".to_string(), "a".to_string())));
     }
 
@@ -3940,16 +3949,14 @@ mod tests {
         assert_eq!(hash_map.to_json(), object);
         assert_eq!(Some(15).to_json(), I64(15));
         assert_eq!(Some(15 as usize).to_json(), U64(15));
-        assert_eq!(None::<int>.to_json(), Null);
+        assert_eq!(None::<isize>.to_json(), Null);
     }
 
     #[test]
     fn test_encode_hashmap_with_arbitrary_key() {
-        use std::old_io::Writer;
         use std::collections::HashMap;
-        use std::fmt;
         #[derive(PartialEq, Eq, Hash, RustcEncodable)]
-        struct ArbitraryType(uint);
+        struct ArbitraryType(usize);
         let mut hm: HashMap<ArbitraryType, bool> = HashMap::new();
         hm.insert(ArbitraryType(1), true);
         let mut mem_buf = string::String::new();
index d476fd72abc3b03ea2f8cc8b729f8182fa78fad6..2e86712c9bccf66cb24f1d45c0ff3884d5e2526b 100644 (file)
@@ -14,6 +14,8 @@
 Core encoding and decoding interfaces.
 */
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "serialize"]
 #![unstable(feature = "rustc_private",
             reason = "deprecated in favor of rustc-serialize on crates.io")]
@@ -28,14 +30,13 @@ Core encoding and decoding interfaces.
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(int_uint)]
-#![feature(old_io)]
 #![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(std_misc)]
 #![feature(unicode)]
-#![cfg_attr(test, feature(test))]
+#![feature(str_char)]
+#![cfg_attr(test, feature(test, old_io))]
 
 // test harness access
 #[cfg(test)] extern crate test;
index 70f0ba4bb23af013d1429e4d5fcdb2e882a85bac..81b5d4c5818b659d48b216d703f78c09fa3b4e56 100644 (file)
@@ -14,7 +14,9 @@
 Core encoding and decoding interfaces.
 */
 
-use std::old_path;
+#[allow(deprecated)]
+use std::old_path::{self, GenericPath};
+use std::path;
 use std::rc::Rc;
 use std::cell::{Cell, RefCell};
 use std::sync::Arc;
@@ -24,12 +26,12 @@ pub trait Encoder {
 
     // Primitive types:
     fn emit_nil(&mut self) -> Result<(), Self::Error>;
-    fn emit_uint(&mut self, v: uint) -> Result<(), Self::Error>;
+    fn emit_uint(&mut self, v: usize) -> Result<(), Self::Error>;
     fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error>;
     fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error>;
     fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error>;
     fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error>;
-    fn emit_int(&mut self, v: int) -> Result<(), Self::Error>;
+    fn emit_int(&mut self, v: isize) -> Result<(), Self::Error>;
     fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error>;
     fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error>;
     fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error>;
@@ -45,41 +47,41 @@ pub trait Encoder {
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
 
     fn emit_enum_variant<F>(&mut self, v_name: &str,
-                            v_id: uint,
-                            len: uint,
+                            v_id: usize,
+                            len: usize,
                             f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
-    fn emit_enum_variant_arg<F>(&mut self, a_idx: uint, f: F)
+    fn emit_enum_variant_arg<F>(&mut self, a_idx: usize, f: F)
                                 -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
 
     fn emit_enum_struct_variant<F>(&mut self, v_name: &str,
-                                   v_id: uint,
-                                   len: uint,
+                                   v_id: usize,
+                                   len: usize,
                                    f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
     fn emit_enum_struct_variant_field<F>(&mut self,
                                          f_name: &str,
-                                         f_idx: uint,
+                                         f_idx: usize,
                                          f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
 
-    fn emit_struct<F>(&mut self, name: &str, len: uint, f: F)
+    fn emit_struct<F>(&mut self, name: &str, len: usize, f: F)
                       -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
-    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: uint, f: F)
+    fn emit_struct_field<F>(&mut self, f_name: &str, f_idx: usize, f: F)
                             -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
 
-    fn emit_tuple<F>(&mut self, len: uint, f: F) -> Result<(), Self::Error>
+    fn emit_tuple<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
-    fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> Result<(), Self::Error>
+    fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
 
-    fn emit_tuple_struct<F>(&mut self, name: &str, len: uint, f: F)
+    fn emit_tuple_struct<F>(&mut self, name: &str, len: usize, f: F)
                             -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
-    fn emit_tuple_struct_arg<F>(&mut self, f_idx: uint, f: F)
+    fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F)
                                 -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
 
@@ -90,16 +92,16 @@ pub trait Encoder {
     fn emit_option_some<F>(&mut self, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
 
-    fn emit_seq<F>(&mut self, len: uint, f: F) -> Result<(), Self::Error>
+    fn emit_seq<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
-    fn emit_seq_elt<F>(&mut self, idx: uint, f: F) -> Result<(), Self::Error>
+    fn emit_seq_elt<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
 
-    fn emit_map<F>(&mut self, len: uint, f: F) -> Result<(), Self::Error>
+    fn emit_map<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
-    fn emit_map_elt_key<F>(&mut self, idx: uint, f: F) -> Result<(), Self::Error>
+    fn emit_map_elt_key<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
-    fn emit_map_elt_val<F>(&mut self, idx: uint, f: F) -> Result<(), Self::Error>
+    fn emit_map_elt_val<F>(&mut self, idx: usize, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>;
 }
 
@@ -108,12 +110,12 @@ pub trait Decoder {
 
     // Primitive types:
     fn read_nil(&mut self) -> Result<(), Self::Error>;
-    fn read_uint(&mut self) -> Result<uint, Self::Error>;
+    fn read_uint(&mut self) -> Result<usize, Self::Error>;
     fn read_u64(&mut self) -> Result<u64, Self::Error>;
     fn read_u32(&mut self) -> Result<u32, Self::Error>;
     fn read_u16(&mut self) -> Result<u16, Self::Error>;
     fn read_u8(&mut self) -> Result<u8, Self::Error>;
-    fn read_int(&mut self) -> Result<int, Self::Error>;
+    fn read_int(&mut self) -> Result<isize, Self::Error>;
     fn read_i64(&mut self) -> Result<i64, Self::Error>;
     fn read_i32(&mut self) -> Result<i32, Self::Error>;
     fn read_i16(&mut self) -> Result<i16, Self::Error>;
@@ -130,41 +132,41 @@ pub trait Decoder {
 
     fn read_enum_variant<T, F>(&mut self, names: &[&str], f: F)
                                -> Result<T, Self::Error>
-        where F: FnMut(&mut Self, uint) -> Result<T, Self::Error>;
-    fn read_enum_variant_arg<T, F>(&mut self, a_idx: uint, f: F)
+        where F: FnMut(&mut Self, usize) -> Result<T, Self::Error>;
+    fn read_enum_variant_arg<T, F>(&mut self, a_idx: usize, f: F)
                                    -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
 
     fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F)
                                       -> Result<T, Self::Error>
-        where F: FnMut(&mut Self, uint) -> Result<T, Self::Error>;
+        where F: FnMut(&mut Self, usize) -> Result<T, Self::Error>;
     fn read_enum_struct_variant_field<T, F>(&mut self,
                                             &f_name: &str,
-                                            f_idx: uint,
+                                            f_idx: usize,
                                             f: F)
                                             -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
 
-    fn read_struct<T, F>(&mut self, s_name: &str, len: uint, f: F)
+    fn read_struct<T, F>(&mut self, s_name: &str, len: usize, f: F)
                          -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
     fn read_struct_field<T, F>(&mut self,
                                f_name: &str,
-                               f_idx: uint,
+                               f_idx: usize,
                                f: F)
                                -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
 
-    fn read_tuple<T, F>(&mut self, len: uint, f: F) -> Result<T, Self::Error>
+    fn read_tuple<T, F>(&mut self, len: usize, f: F) -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
-    fn read_tuple_arg<T, F>(&mut self, a_idx: uint, f: F)
+    fn read_tuple_arg<T, F>(&mut self, a_idx: usize, f: F)
                             -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
 
-    fn read_tuple_struct<T, F>(&mut self, s_name: &str, len: uint, f: F)
+    fn read_tuple_struct<T, F>(&mut self, s_name: &str, len: usize, f: F)
                                -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
-    fn read_tuple_struct_arg<T, F>(&mut self, a_idx: uint, f: F)
+    fn read_tuple_struct_arg<T, F>(&mut self, a_idx: usize, f: F)
                                    -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
 
@@ -173,16 +175,16 @@ pub trait Decoder {
         where F: FnMut(&mut Self, bool) -> Result<T, Self::Error>;
 
     fn read_seq<T, F>(&mut self, f: F) -> Result<T, Self::Error>
-        where F: FnOnce(&mut Self, uint) -> Result<T, Self::Error>;
-    fn read_seq_elt<T, F>(&mut self, idx: uint, f: F) -> Result<T, Self::Error>
+        where F: FnOnce(&mut Self, usize) -> Result<T, Self::Error>;
+    fn read_seq_elt<T, F>(&mut self, idx: usize, f: F) -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
 
     fn read_map<T, F>(&mut self, f: F) -> Result<T, Self::Error>
-        where F: FnOnce(&mut Self, uint) -> Result<T, Self::Error>;
-    fn read_map_elt_key<T, F>(&mut self, idx: uint, f: F)
+        where F: FnOnce(&mut Self, usize) -> Result<T, Self::Error>;
+    fn read_map_elt_key<T, F>(&mut self, idx: usize, f: F)
                               -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
-    fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F)
+    fn read_map_elt_val<T, F>(&mut self, idx: usize, f: F)
                               -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
 
@@ -198,14 +200,14 @@ pub trait Decodable {
     fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error>;
 }
 
-impl Encodable for uint {
+impl Encodable for usize {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_uint(*self)
     }
 }
 
-impl Decodable for uint {
-    fn decode<D: Decoder>(d: &mut D) -> Result<uint, D::Error> {
+impl Decodable for usize {
+    fn decode<D: Decoder>(d: &mut D) -> Result<usize, D::Error> {
         d.read_uint()
     }
 }
@@ -258,14 +260,14 @@ impl Decodable for u64 {
     }
 }
 
-impl Encodable for int {
+impl Encodable for isize {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_int(*self)
     }
 }
 
-impl Decodable for int {
-    fn decode<D: Decoder>(d: &mut D) -> Result<int, D::Error> {
+impl Decodable for isize {
+    fn decode<D: Decoder>(d: &mut D) -> Result<isize, D::Error> {
         d.read_int()
     }
 }
@@ -508,7 +510,7 @@ macro_rules! tuple {
         impl<$($name:Decodable),*> Decodable for ($($name,)*) {
             #[allow(non_snake_case)]
             fn decode<D: Decoder>(d: &mut D) -> Result<($($name,)*), D::Error> {
-                let len: uint = count_idents!($($name,)*);
+                let len: usize = count_idents!($($name,)*);
                 d.read_tuple(len, |d| {
                     let mut i = 0;
                     let ret = ($(try!(d.read_tuple_arg({ i+=1; i-1 },
@@ -538,12 +540,14 @@ macro_rules! tuple {
 
 tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
 
+#[allow(deprecated)]
 impl Encodable for old_path::posix::Path {
     fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
         self.as_vec().encode(e)
     }
 }
 
+#[allow(deprecated)]
 impl Decodable for old_path::posix::Path {
     fn decode<D: Decoder>(d: &mut D) -> Result<old_path::posix::Path, D::Error> {
         let bytes: Vec<u8> = try!(Decodable::decode(d));
@@ -551,12 +555,14 @@ impl Decodable for old_path::posix::Path {
     }
 }
 
+#[allow(deprecated)]
 impl Encodable for old_path::windows::Path {
     fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
         self.as_vec().encode(e)
     }
 }
 
+#[allow(deprecated)]
 impl Decodable for old_path::windows::Path {
     fn decode<D: Decoder>(d: &mut D) -> Result<old_path::windows::Path, D::Error> {
         let bytes: Vec<u8> = try!(Decodable::decode(d));
@@ -564,6 +570,19 @@ impl Decodable for old_path::windows::Path {
     }
 }
 
+impl Encodable for path::PathBuf {
+    fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
+        self.to_str().unwrap().encode(e)
+    }
+}
+
+impl Decodable for path::PathBuf {
+    fn decode<D: Decoder>(d: &mut D) -> Result<path::PathBuf, D::Error> {
+        let bytes: String = try!(Decodable::decode(d));
+        Ok(path::PathBuf::from(bytes))
+    }
+}
+
 impl<T: Encodable + Copy> Encodable for Cell<T> {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         self.get().encode(s)
diff --git a/src/libstd/array.rs b/src/libstd/array.rs
new file mode 100644 (file)
index 0000000..a6b8cd7
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2015 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.
+
+//! The fixed-size array type (`[T; n]`).
+
+#![doc(primitive = "array")]
index 4d38d17576ddb2a15ee7fe13624ff1a993a979e6..20ad71a4bf8c854ef1144a9ba91356d131d12c60 100644 (file)
@@ -16,8 +16,8 @@
 
 use prelude::v1::*;
 
+use ops::Range;
 use mem;
-use iter::Range;
 
 /// Extension methods for ASCII-subset only operations on owned strings
 #[unstable(feature = "std_misc",
@@ -34,43 +34,124 @@ pub trait OwnedAsciiExt {
     fn into_ascii_lowercase(self) -> Self;
 }
 
-/// Extension methods for ASCII-subset only operations on string slices
+/// Extension methods for ASCII-subset only operations on string slices.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait AsciiExt {
+    /// Container type for copied ASCII characters.
     #[stable(feature = "rust1", since = "1.0.0")]
     type Owned;
 
     /// Check if within the ASCII range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ascii::AsciiExt;
+    ///
+    /// let ascii = 'a';
+    /// let utf8 = '❤';
+    ///
+    /// assert_eq!(true, ascii.is_ascii());
+    /// assert_eq!(false, utf8.is_ascii())
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn is_ascii(&self) -> bool;
 
-    /// Makes a copy of the string in ASCII upper case:
+    /// Makes a copy of the string in ASCII upper case.
+    ///
     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
     /// but non-ASCII letters are unchanged.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ascii::AsciiExt;
+    ///
+    /// let ascii = 'a';
+    /// let utf8 = '❤';
+    ///
+    /// assert_eq!('A', ascii.to_ascii_uppercase());
+    /// assert_eq!('❤', utf8.to_ascii_uppercase());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn to_ascii_uppercase(&self) -> Self::Owned;
 
-    /// Makes a copy of the string in ASCII lower case:
+    /// Makes a copy of the string in ASCII lower case.
+    ///
     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
     /// but non-ASCII letters are unchanged.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ascii::AsciiExt;
+    ///
+    /// let ascii = 'A';
+    /// let utf8 = '❤';
+    ///
+    /// assert_eq!('a', ascii.to_ascii_lowercase());
+    /// assert_eq!('❤', utf8.to_ascii_lowercase());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn to_ascii_lowercase(&self) -> Self::Owned;
 
     /// Check that two strings are an ASCII case-insensitive match.
+    ///
     /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
     /// but without allocating and copying temporary strings.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ascii::AsciiExt;
+    ///
+    /// let ascii1 = 'A';
+    /// let ascii2 = 'a';
+    /// let ascii3 = 'A';
+    /// let ascii4 = 'z';
+    ///
+    /// assert_eq!(true, ascii1.eq_ignore_ascii_case(&ascii2));
+    /// assert_eq!(true, ascii1.eq_ignore_ascii_case(&ascii3));
+    /// assert_eq!(false, ascii1.eq_ignore_ascii_case(&ascii4));
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn eq_ignore_ascii_case(&self, other: &Self) -> bool;
 
     /// Convert this type to its ASCII upper case equivalent in-place.
     ///
     /// See `to_ascii_uppercase` for more information.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(ascii)]
+    /// use std::ascii::AsciiExt;
+    ///
+    /// let mut ascii = 'a';
+    ///
+    /// ascii.make_ascii_uppercase();
+    ///
+    /// assert_eq!('A', ascii);
+    /// ```
     #[unstable(feature = "ascii")]
     fn make_ascii_uppercase(&mut self);
 
     /// Convert this type to its ASCII lower case equivalent in-place.
     ///
     /// See `to_ascii_lowercase` for more information.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(ascii)]
+    /// use std::ascii::AsciiExt;
+    ///
+    /// let mut ascii = 'A';
+    ///
+    /// ascii.make_ascii_lowercase();
+    ///
+    /// assert_eq!('a', ascii);
+    /// ```
     #[unstable(feature = "ascii")]
     fn make_ascii_lowercase(&mut self);
 }
@@ -185,7 +266,7 @@ impl OwnedAsciiExt for Vec<u8> {
 impl AsciiExt for u8 {
     type Owned = u8;
     #[inline]
-    fn is_ascii(&self) -> bool { *self & 128 == 0u8 }
+    fn is_ascii(&self) -> bool { *self & 128 == 0 }
     #[inline]
     fn to_ascii_uppercase(&self) -> u8 { ASCII_UPPERCASE_MAP[*self as usize] }
     #[inline]
@@ -245,7 +326,7 @@ pub struct EscapeDefault {
     data: [u8; 4],
 }
 
-/// Returns a 'default' ASCII and C++11-like literal escape of a `u8`
+/// Returns an iterator that produces an escaped version of a `u8`.
 ///
 /// The default is chosen with a bias toward producing literals that are
 /// legal in a variety of languages, including C++11 and similar C-family
@@ -256,6 +337,20 @@ pub struct EscapeDefault {
 /// - Any other chars in the range [0x20,0x7e] are not escaped.
 /// - Any other chars are given hex escapes of the form '\xNN'.
 /// - Unicode escapes are never generated by this function.
+///
+/// # Examples
+///
+/// ```
+/// use std::ascii;
+///
+/// let escaped = ascii::escape_default(b'0').next().unwrap();
+/// assert_eq!(b'0', escaped);
+///
+/// let mut escaped = ascii::escape_default(b'\t');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b't', escaped.next().unwrap());
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn escape_default(c: u8) -> EscapeDefault {
     let (data, len) = match c {
@@ -269,7 +364,7 @@ pub fn escape_default(c: u8) -> EscapeDefault {
         _ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
     };
 
-    return EscapeDefault { range: range(0, len), data: data };
+    return EscapeDefault { range: (0.. len), data: data };
 
     fn hexify(b: u8) -> u8 {
         match b {
@@ -397,7 +492,7 @@ mod tests {
         assert_eq!("url()URL()uRl()ürl".to_ascii_uppercase(), "URL()URL()URL()üRL");
         assert_eq!("hıKß".to_ascii_uppercase(), "HıKß");
 
-        for i in 0u32..501 {
+        for i in 0..501 {
             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().to_ascii_uppercase(),
@@ -411,7 +506,7 @@ mod tests {
         // Dotted capital I, Kelvin sign, Sharp S.
         assert_eq!("HİKß".to_ascii_lowercase(), "hİKß");
 
-        for i in 0u32..501 {
+        for i in 0..501 {
             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().to_ascii_lowercase(),
@@ -425,7 +520,7 @@ mod tests {
                    "URL()URL()URL()üRL".to_string());
         assert_eq!(("hıKß".to_string()).into_ascii_uppercase(), "HıKß");
 
-        for i in 0u32..501 {
+        for i in 0..501 {
             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().into_ascii_uppercase(),
@@ -440,7 +535,7 @@ mod tests {
         // Dotted capital I, Kelvin sign, Sharp S.
         assert_eq!(("HİKß".to_string()).into_ascii_lowercase(), "hİKß");
 
-        for i in 0u32..501 {
+        for i in 0..501 {
             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().into_ascii_lowercase(),
@@ -458,7 +553,7 @@ mod tests {
         assert!(!"K".eq_ignore_ascii_case("k"));
         assert!(!"ß".eq_ignore_ascii_case("s"));
 
-        for i in 0u32..501 {
+        for i in 0..501 {
             let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
                         else { i };
             assert!((from_u32(i).unwrap()).to_string().eq_ignore_ascii_case(
index 0d8b233a1697d72f264a09526e50c18f62384888..df703b3e43e32768e40a2ba60fc961b96b8aa4c5 100644 (file)
@@ -12,4 +12,3 @@
 
 #![doc(primitive = "bool")]
 #![stable(feature = "rust1", since = "1.0.0")]
-
index ca506e8c36f50a7111063c15c152eacd226f25e1..ac21ae0f0aa146ca98e2e15a084b160281cfcb1c 100644 (file)
@@ -14,7 +14,7 @@ extern crate test;
 use prelude::v1::*;
 
 use self::test::Bencher;
-use iter::{range_inclusive};
+use iter::range_inclusive;
 
 #[bench]
 fn new_drop(b : &mut Bencher) {
index ade4f1f0533ee73abdb388bab488ac4a9a2d0452..a636c1a812ddcbf2df4c3b5b009b36be5a072955 100644 (file)
@@ -20,11 +20,10 @@ use cmp::{max, Eq, PartialEq};
 use default::Default;
 use fmt::{self, Debug};
 use hash::{Hash, SipHasher};
-use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map};
+use iter::{self, Iterator, ExactSizeIterator, IntoIterator, FromIterator, Extend, Map};
 use marker::Sized;
 use mem::{self, replace};
-use num::{Int, UnsignedInt};
-use ops::{Deref, FnMut, Index, IndexMut};
+use ops::{Deref, FnMut, FnOnce, Index};
 use option::Option::{self, Some, None};
 use rand::{self, Rng};
 use result::Result::{self, Ok, Err};
@@ -88,7 +87,6 @@ impl DefaultResizePolicy {
 
 #[test]
 fn test_resize_policy() {
-    use prelude::v1::*;
     let rp = DefaultResizePolicy;
     for n in 0..1000 {
         assert!(rp.min_capacity(rp.usable_capacity(n)) <= n);
@@ -204,7 +202,7 @@ fn test_resize_policy() {
 // produces identical results to a linear naive reinsertion from the same
 // element.
 //
-// FIXME(Gankro, pczarn): review the proof and put it all in a separate doc.rs
+// FIXME(Gankro, pczarn): review the proof and put it all in a separate README.md
 
 /// A hash map implementation which uses linear probing with Robin
 /// Hood bucket stealing.
@@ -216,7 +214,19 @@ fn test_resize_policy() {
 /// overridden with one of the constructors.
 ///
 /// It is required that the keys implement the `Eq` and `Hash` traits, although
-/// this can frequently be achieved by using `#[derive(Eq, Hash)]`.
+/// this can frequently be achieved by using `#[derive(Eq, Hash)]`. If you
+/// implement these yourself, it is important that the following property holds:
+///
+/// ```text
+/// k1 == k2 -> hash(k1) == hash(k2)
+/// ```
+///
+/// In other words, if two keys are equal, their hashes must be equal.
+///
+/// It is a logic error for a key to be modified in such a way that the key's
+/// hash, as determined by the `Hash` trait, or its equality, as determined by
+/// the `Eq` trait, changes while it is in the map. This is normally only
+/// possible through `Cell`, `RefCell`, global state, I/O, or unsafe code.
 ///
 /// Relevant papers/articles:
 ///
@@ -226,7 +236,7 @@ fn test_resize_policy() {
 /// 3. Emmanuel Goossaert. ["Robin Hood hashing: backward shift
 ///    deletion"](http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/)
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// use std::collections::HashMap;
@@ -315,6 +325,13 @@ fn search_hashed<K, V, M, F>(table: M,
     M: Deref<Target=RawTable<K, V>>,
     F: FnMut(&K) -> bool,
 {
+    // This is the only function where capacity can be zero. To avoid
+    // undefined behaviour when Bucket::new gets the raw bucket in this
+    // case, immediately return the appropriate search result.
+    if table.capacity() == 0 {
+        return TableRef(table);
+    }
+
     let size = table.size();
     let mut probe = Bucket::new(table, hash);
     let ib = probe.index();
@@ -491,11 +508,11 @@ impl<K, V, S> HashMap<K, V, S>
 impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
     /// Create an empty HashMap.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
-    /// let mut map: HashMap<&str, int> = HashMap::new();
+    /// let mut map: HashMap<&str, isize> = HashMap::new();
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -505,11 +522,11 @@ impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
 
     /// Creates an empty hash map with the given initial capacity.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
-    /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10);
+    /// let mut map: HashMap<&str, isize> = HashMap::with_capacity(10);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -525,9 +542,10 @@ impl<K, V, S> HashMap<K, V, S>
     ///
     /// The creates map has the default initial capacity.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::collections::HashMap;
     /// use std::collections::hash_map::RandomState;
     ///
@@ -553,9 +571,10 @@ impl<K, V, S> HashMap<K, V, S>
     /// cause many collisions and very poor performance. Setting it
     /// manually using this function can expose a DoS attack vector.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::collections::HashMap;
     /// use std::collections::hash_map::RandomState;
     ///
@@ -580,11 +599,11 @@ impl<K, V, S> HashMap<K, V, S>
 
     /// Returns the number of elements the map can hold without reallocating.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
-    /// let map: HashMap<int, int> = HashMap::with_capacity(100);
+    /// let map: HashMap<isize, isize> = HashMap::with_capacity(100);
     /// assert!(map.capacity() >= 100);
     /// ```
     #[inline]
@@ -601,11 +620,11 @@ impl<K, V, S> HashMap<K, V, S>
     ///
     /// Panics if the new allocation size overflows `usize`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
-    /// let mut map: HashMap<&str, int> = HashMap::new();
+    /// let mut map: HashMap<&str, isize> = HashMap::new();
     /// map.reserve(10);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -708,12 +727,12 @@ impl<K, V, S> HashMap<K, V, S>
     /// down as much as possible while maintaining the internal rules
     /// and possibly leaving some space in accordance with the resize policy.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
     ///
-    /// let mut map: HashMap<int, int> = HashMap::with_capacity(100);
+    /// let mut map: HashMap<isize, isize> = HashMap::with_capacity(100);
     /// map.insert(1, 2);
     /// map.insert(3, 4);
     /// assert!(map.capacity() >= 100);
@@ -785,9 +804,9 @@ impl<K, V, S> HashMap<K, V, S>
                 }
             }
 
-            let robin_ib = bucket.index() as int - bucket.distance() as int;
+            let robin_ib = bucket.index() as isize - bucket.distance() as isize;
 
-            if (ib as int) < robin_ib {
+            if (ib as isize) < robin_ib {
                 // Found a luckier bucket than me. Better steal his spot.
                 return robin_hood(bucket, robin_ib as usize, hash, k, v);
             }
@@ -800,7 +819,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// An iterator visiting all keys in arbitrary order.
     /// Iterator element type is `&'a K`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -825,7 +844,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// An iterator visiting all values in arbitrary order.
     /// Iterator element type is `&'a V`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -850,7 +869,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// An iterator visiting all key-value pairs in arbitrary order.
     /// Iterator element type is `(&'a K, &'a V)`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -873,7 +892,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// with mutable references to the values.
     /// Iterator element type is `(&'a K, &'a mut V)`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -901,7 +920,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// pair out of the map in arbitrary order. The map cannot be used after
     /// calling this.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -912,7 +931,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// map.insert("c", 3);
     ///
     /// // Not possible with .iter()
-    /// let vec: Vec<(&str, int)> = map.into_iter().collect();
+    /// let vec: Vec<(&str, isize)> = map.into_iter().collect();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_iter(self) -> IntoIter<K, V> {
@@ -936,7 +955,7 @@ impl<K, V, S> HashMap<K, V, S>
 
     /// Returns the number of elements in the map.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -951,7 +970,7 @@ impl<K, V, S> HashMap<K, V, S>
 
     /// Returns true if the map contains no elements.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -968,9 +987,10 @@ impl<K, V, S> HashMap<K, V, S>
     /// Clears the map, returning all key-value pairs as an iterator. Keeps the
     /// allocated memory for reuse.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::collections::HashMap;
     ///
     /// let mut a = HashMap::new();
@@ -999,7 +1019,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// Clears the map, removing all key-value pairs. Keeps the allocated memory
     /// for reuse.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -1021,7 +1041,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// `Hash` and `Eq` on the borrowed form *must* match those for
     /// the key type.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -1044,7 +1064,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// `Hash` and `Eq` on the borrowed form *must* match those for
     /// the key type.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -1067,7 +1087,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// `Hash` and `Eq` on the borrowed form *must* match those for
     /// the key type.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -1078,7 +1098,7 @@ impl<K, V, S> HashMap<K, V, S>
     ///     Some(x) => *x = "b",
     ///     None => (),
     /// }
-    /// assert_eq!(map[1], "b");
+    /// assert_eq!(map[&1], "b");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
@@ -1090,7 +1110,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// Inserts a key-value pair from the map. If the key already had a value
     /// present in the map, that value is returned. Otherwise, `None` is returned.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -1101,7 +1121,7 @@ impl<K, V, S> HashMap<K, V, S>
     ///
     /// map.insert(37, "b");
     /// assert_eq!(map.insert(37, "c"), Some("b"));
-    /// assert_eq!(map[37], "c");
+    /// assert_eq!(map[&37], "c");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn insert(&mut self, k: K, v: V) -> Option<V> {
@@ -1122,7 +1142,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// `Hash` and `Eq` on the borrowed form *must* match those for
     /// the key type.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashMap;
@@ -1175,9 +1195,9 @@ fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHas
             }
         }
 
-        let robin_ib = bucket.index() as int - bucket.distance() as int;
+        let robin_ib = bucket.index() as isize - bucket.distance() as isize;
 
-        if (ib as int) < robin_ib {
+        if (ib as isize) < robin_ib {
             // Found a luckier bucket than me. Better steal his spot.
             return Vacant(VacantEntry {
                 hash: hash,
@@ -1213,14 +1233,7 @@ impl<K, V, S> Debug for HashMap<K, V, S>
     where K: Eq + Hash + Debug, V: Debug, S: HashState
 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "HashMap {{"));
-
-        for (i, (k, v)) in self.iter().enumerate() {
-            if i != 0 { try!(write!(f, ", ")); }
-            try!(write!(f, "{:?}: {:?}", *k, *v));
-        }
-
-        write!(f, "}}")
+        self.iter().fold(f.debug_map(), |b, (k, v)| b.entry(k, v)).finish()
     }
 }
 
@@ -1235,7 +1248,7 @@ impl<K, V, S> Default for HashMap<K, V, S>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<K, Q: ?Sized, V, S> Index<Q> for HashMap<K, V, S>
+impl<'a, K, Q: ?Sized, V, S> Index<&'a Q> for HashMap<K, V, S>
     where K: Eq + Hash + Borrow<Q>,
           Q: Eq + Hash,
           S: HashState,
@@ -1243,23 +1256,11 @@ impl<K, Q: ?Sized, V, S> Index<Q> for HashMap<K, V, S>
     type Output = V;
 
     #[inline]
-    fn index<'a>(&'a self, index: &Q) -> &'a V {
+    fn index(&self, index: &Q) -> &V {
         self.get(index).expect("no entry found for key")
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, Q: ?Sized> IndexMut<Q> for HashMap<K, V, S>
-    where K: Eq + Hash + Borrow<Q>,
-          Q: Eq + Hash,
-          S: HashState,
-{
-    #[inline]
-    fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V {
-        self.get_mut(index).expect("no entry found for key")
-    }
-}
-
 /// HashMap iterator.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a, K: 'a, V: 'a> {
@@ -1325,15 +1326,13 @@ pub struct Drain<'a, K: 'a, V: 'a> {
 }
 
 /// A view into a single occupied location in a HashMap.
-#[unstable(feature = "std_misc",
-           reason = "precise API still being fleshed out")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
     elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
 }
 
 /// A view into a single empty location in a HashMap.
-#[unstable(feature = "std_misc",
-           reason = "precise API still being fleshed out")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct VacantEntry<'a, K: 'a, V: 'a> {
     hash: SafeHash,
     key: K,
@@ -1341,12 +1340,14 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> {
 }
 
 /// A view into a single location in a map, which may be vacant or occupied.
-#[unstable(feature = "std_misc",
-           reason = "precise API still being fleshed out")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub enum Entry<'a, K: 'a, V: 'a> {
     /// An occupied Entry.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Occupied(OccupiedEntry<'a, K, V>),
+
     /// A vacant Entry.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Vacant(VacantEntry<'a, K, V>),
 }
 
@@ -1467,16 +1468,39 @@ impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
     #[inline] fn len(&self) -> usize { self.inner.len() }
 }
 
-#[unstable(feature = "std_misc",
-           reason = "matches collection reform v2 specification, waiting for dust to settle")]
 impl<'a, K, V> Entry<'a, K, V> {
     /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant.
+    #[unstable(feature = "std_misc",
+               reason = "will soon be replaced by or_insert")]
+    #[deprecated(since = "1.0",
+                reason = "replaced with more ergonomic `or_insert` and `or_insert_with`")]
+    /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
     pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> {
         match self {
             Occupied(entry) => Ok(entry.into_mut()),
             Vacant(entry) => Err(entry),
         }
     }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    /// Ensures a value is in the entry by inserting the default if empty, and returns
+    /// a mutable reference to the value in the entry.
+    pub fn or_insert(self, default: V) -> &'a mut V {
+        match self {
+            Occupied(entry) => entry.into_mut(),
+            Vacant(entry) => entry.insert(default),
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    /// Ensures a value is in the entry by inserting the result of the default function if empty,
+    /// and returns a mutable reference to the value in the entry.
+    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
+        match self {
+            Occupied(entry) => entry.into_mut(),
+            Vacant(entry) => entry.insert(default()),
+        }
+    }
 }
 
 impl<'a, K, V> OccupiedEntry<'a, K, V> {
@@ -1631,7 +1655,7 @@ mod test_map {
         assert_eq!(*m.get(&2).unwrap(), 4);
     }
 
-    thread_local! { static DROP_VECTOR: RefCell<Vec<int>> = RefCell::new(Vec::new()) }
+    thread_local! { static DROP_VECTOR: RefCell<Vec<isize>> = RefCell::new(Vec::new()) }
 
     #[derive(Hash, PartialEq, Eq)]
     struct Dropable {
@@ -1788,7 +1812,7 @@ mod test_map {
 
     #[test]
     fn test_empty_pop() {
-        let mut m: HashMap<int, bool> = HashMap::new();
+        let mut m: HashMap<isize, bool> = HashMap::new();
         assert_eq!(m.remove(&0), None);
     }
 
@@ -2000,9 +2024,9 @@ mod test_map {
 
         let map_str = format!("{:?}", map);
 
-        assert!(map_str == "HashMap {1: 2, 3: 4}" ||
-                map_str == "HashMap {3: 4, 1: 2}");
-        assert_eq!(format!("{:?}", empty), "HashMap {}");
+        assert!(map_str == "{1: 2, 3: 4}" ||
+                map_str == "{3: 4, 1: 2}");
+        assert_eq!(format!("{:?}", empty), "{}");
     }
 
     #[test]
@@ -2187,11 +2211,11 @@ mod test_map {
         map.insert(2, 1);
         map.insert(3, 4);
 
-        assert_eq!(map[2], 1);
+        assert_eq!(map[&2], 1);
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_index_nonexistent() {
         let mut map = HashMap::new();
 
@@ -2199,7 +2223,7 @@ mod test_map {
         map.insert(2, 1);
         map.insert(3, 4);
 
-        map[4];
+        map[&4];
     }
 
     #[test]
@@ -2256,6 +2280,7 @@ mod test_map {
 
     #[test]
     fn test_entry_take_doesnt_corrupt() {
+        #![allow(deprecated)] //rand
         // Test for #19292
         fn check(m: &HashMap<isize, ()>) {
             for k in m.keys() {
diff --git a/src/libstd/collections/hash/map_stage0.rs b/src/libstd/collections/hash/map_stage0.rs
deleted file mode 100644 (file)
index f9e5044..0000000
+++ /dev/null
@@ -1,2330 +0,0 @@
-// Copyright 2014-2015 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.
-//
-// ignore-lexer-test FIXME #15883
-
-use self::Entry::*;
-use self::SearchResult::*;
-use self::VacantEntryState::*;
-
-use borrow::Borrow;
-use clone::Clone;
-use cmp::{max, Eq, PartialEq};
-use default::Default;
-use fmt::{self, Debug};
-use hash::{self, Hash, SipHasher};
-use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map};
-use marker::Sized;
-use mem::{self, replace};
-use num::{Int, UnsignedInt};
-use ops::{Deref, FnMut, Index, IndexMut};
-use option::Option::{self, Some, None};
-use rand::{self, Rng};
-use result::Result::{self, Ok, Err};
-
-use super::table::{
-    self,
-    Bucket,
-    EmptyBucket,
-    FullBucket,
-    FullBucketImm,
-    FullBucketMut,
-    RawTable,
-    SafeHash
-};
-use super::table::BucketState::{
-    Empty,
-    Full,
-};
-use super::state::HashState;
-
-const INITIAL_LOG2_CAP: usize = 5;
-#[unstable(feature = "std_misc")]
-pub const INITIAL_CAPACITY: usize = 1 << INITIAL_LOG2_CAP; // 2^5
-
-/// The default behavior of HashMap implements a load factor of 90.9%.
-/// This behavior is characterized by the following condition:
-///
-/// - if size > 0.909 * capacity: grow the map
-#[derive(Clone)]
-struct DefaultResizePolicy;
-
-impl DefaultResizePolicy {
-    fn new() -> DefaultResizePolicy {
-        DefaultResizePolicy
-    }
-
-    #[inline]
-    fn min_capacity(&self, usable_size: usize) -> usize {
-        // Here, we are rephrasing the logic by specifying the lower limit
-        // on capacity:
-        //
-        // - if `cap < size * 1.1`: grow the map
-        usable_size * 11 / 10
-    }
-
-    /// An inverse of `min_capacity`, approximately.
-    #[inline]
-    fn usable_capacity(&self, cap: usize) -> usize {
-        // As the number of entries approaches usable capacity,
-        // min_capacity(size) must be smaller than the internal capacity,
-        // so that the map is not resized:
-        // `min_capacity(usable_capacity(x)) <= x`.
-        // The left-hand side can only be smaller due to flooring by integer
-        // division.
-        //
-        // This doesn't have to be checked for overflow since allocation size
-        // in bytes will overflow earlier than multiplication by 10.
-        cap * 10 / 11
-    }
-}
-
-#[test]
-fn test_resize_policy() {
-    use prelude::v1::*;
-    let rp = DefaultResizePolicy;
-    for n in 0..1000 {
-        assert!(rp.min_capacity(rp.usable_capacity(n)) <= n);
-        assert!(rp.usable_capacity(rp.min_capacity(n)) <= n);
-    }
-}
-
-// The main performance trick in this hashmap is called Robin Hood Hashing.
-// It gains its excellent performance from one essential operation:
-//
-//    If an insertion collides with an existing element, and that element's
-//    "probe distance" (how far away the element is from its ideal location)
-//    is higher than how far we've already probed, swap the elements.
-//
-// This massively lowers variance in probe distance, and allows us to get very
-// high load factors with good performance. The 90% load factor I use is rather
-// conservative.
-//
-// > Why a load factor of approximately 90%?
-//
-// In general, all the distances to initial buckets will converge on the mean.
-// At a load factor of α, the odds of finding the target bucket after k
-// probes is approximately 1-α^k. If we set this equal to 50% (since we converge
-// on the mean) and set k=8 (64-byte cache line / 8-byte hash), α=0.92. I round
-// this down to make the math easier on the CPU and avoid its FPU.
-// Since on average we start the probing in the middle of a cache line, this
-// strategy pulls in two cache lines of hashes on every lookup. I think that's
-// pretty good, but if you want to trade off some space, it could go down to one
-// cache line on average with an α of 0.84.
-//
-// > Wait, what? Where did you get 1-α^k from?
-//
-// On the first probe, your odds of a collision with an existing element is α.
-// The odds of doing this twice in a row is approximately α^2. For three times,
-// α^3, etc. Therefore, the odds of colliding k times is α^k. The odds of NOT
-// colliding after k tries is 1-α^k.
-//
-// The paper from 1986 cited below mentions an implementation which keeps track
-// of the distance-to-initial-bucket histogram. This approach is not suitable
-// for modern architectures because it requires maintaining an internal data
-// structure. This allows very good first guesses, but we are most concerned
-// with guessing entire cache lines, not individual indexes. Furthermore, array
-// accesses are no longer linear and in one direction, as we have now. There
-// is also memory and cache pressure that this would entail that would be very
-// difficult to properly see in a microbenchmark.
-//
-// ## Future Improvements (FIXME!)
-//
-// Allow the load factor to be changed dynamically and/or at initialization.
-//
-// Also, would it be possible for us to reuse storage when growing the
-// underlying table? This is exactly the use case for 'realloc', and may
-// be worth exploring.
-//
-// ## Future Optimizations (FIXME!)
-//
-// Another possible design choice that I made without any real reason is
-// parameterizing the raw table over keys and values. Technically, all we need
-// is the size and alignment of keys and values, and the code should be just as
-// efficient (well, we might need one for power-of-two size and one for not...).
-// This has the potential to reduce code bloat in rust executables, without
-// really losing anything except 4 words (key size, key alignment, val size,
-// val alignment) which can be passed in to every call of a `RawTable` function.
-// This would definitely be an avenue worth exploring if people start complaining
-// about the size of rust executables.
-//
-// Annotate exceedingly likely branches in `table::make_hash`
-// and `search_hashed` to reduce instruction cache pressure
-// and mispredictions once it becomes possible (blocked on issue #11092).
-//
-// Shrinking the table could simply reallocate in place after moving buckets
-// to the first half.
-//
-// The growth algorithm (fragment of the Proof of Correctness)
-// --------------------
-//
-// The growth algorithm is basically a fast path of the naive reinsertion-
-// during-resize algorithm. Other paths should never be taken.
-//
-// Consider growing a robin hood hashtable of capacity n. Normally, we do this
-// by allocating a new table of capacity `2n`, and then individually reinsert
-// each element in the old table into the new one. This guarantees that the
-// new table is a valid robin hood hashtable with all the desired statistical
-// properties. Remark that the order we reinsert the elements in should not
-// matter. For simplicity and efficiency, we will consider only linear
-// reinsertions, which consist of reinserting all elements in the old table
-// into the new one by increasing order of index. However we will not be
-// starting our reinsertions from index 0 in general. If we start from index
-// i, for the purpose of reinsertion we will consider all elements with real
-// index j < i to have virtual index n + j.
-//
-// Our hash generation scheme consists of generating a 64-bit hash and
-// truncating the most significant bits. When moving to the new table, we
-// simply introduce a new bit to the front of the hash. Therefore, if an
-// elements has ideal index i in the old table, it can have one of two ideal
-// locations in the new table. If the new bit is 0, then the new ideal index
-// is i. If the new bit is 1, then the new ideal index is n + i. Intuitively,
-// we are producing two independent tables of size n, and for each element we
-// independently choose which table to insert it into with equal probability.
-// However the rather than wrapping around themselves on overflowing their
-// indexes, the first table overflows into the first, and the first into the
-// second. Visually, our new table will look something like:
-//
-// [yy_xxx_xxxx_xxx|xx_yyy_yyyy_yyy]
-//
-// Where x's are elements inserted into the first table, y's are elements
-// inserted into the second, and _'s are empty sections. We now define a few
-// key concepts that we will use later. Note that this is a very abstract
-// perspective of the table. A real resized table would be at least half
-// empty.
-//
-// Theorem: A linear robin hood reinsertion from the first ideal element
-// produces identical results to a linear naive reinsertion from the same
-// element.
-//
-// FIXME(Gankro, pczarn): review the proof and put it all in a separate doc.rs
-
-/// A hash map implementation which uses linear probing with Robin
-/// Hood bucket stealing.
-///
-/// The hashes are all keyed by the task-local random number generator
-/// on creation by default. This means that the ordering of the keys is
-/// randomized, but makes the tables more resistant to
-/// denial-of-service attacks (Hash DoS). This behaviour can be
-/// overridden with one of the constructors.
-///
-/// It is required that the keys implement the `Eq` and `Hash` traits, although
-/// this can frequently be achieved by using `#[derive(Eq, Hash)]`.
-///
-/// Relevant papers/articles:
-///
-/// 1. Pedro Celis. ["Robin Hood Hashing"](https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf)
-/// 2. Emmanuel Goossaert. ["Robin Hood
-///    hashing"](http://codecapsule.com/2013/11/11/robin-hood-hashing/)
-/// 3. Emmanuel Goossaert. ["Robin Hood hashing: backward shift
-///    deletion"](http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/)
-///
-/// # Example
-///
-/// ```
-/// use std::collections::HashMap;
-///
-/// // type inference lets us omit an explicit type signature (which
-/// // would be `HashMap<&str, &str>` in this example).
-/// let mut book_reviews = HashMap::new();
-///
-/// // review some books.
-/// book_reviews.insert("Adventures of Huckleberry Finn",    "My favorite book.");
-/// book_reviews.insert("Grimms' Fairy Tales",               "Masterpiece.");
-/// book_reviews.insert("Pride and Prejudice",               "Very enjoyable.");
-/// book_reviews.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot.");
-///
-/// // check for a specific one.
-/// if !book_reviews.contains_key(&("Les Misérables")) {
-///     println!("We've got {} reviews, but Les Misérables ain't one.",
-///              book_reviews.len());
-/// }
-///
-/// // oops, this review has a lot of spelling mistakes, let's delete it.
-/// book_reviews.remove(&("The Adventures of Sherlock Holmes"));
-///
-/// // look up the values associated with some keys.
-/// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
-/// for book in to_find.iter() {
-///     match book_reviews.get(book) {
-///         Some(review) => println!("{}: {}", *book, *review),
-///         None => println!("{} is unreviewed.", *book)
-///     }
-/// }
-///
-/// // iterate over everything.
-/// for (book, review) in book_reviews.iter() {
-///     println!("{}: \"{}\"", *book, *review);
-/// }
-/// ```
-///
-/// The easiest way to use `HashMap` with a custom type as key is to derive `Eq` and `Hash`.
-/// We must also derive `PartialEq`.
-///
-/// ```
-/// use std::collections::HashMap;
-///
-/// #[derive(Hash, Eq, PartialEq, Debug)]
-/// struct Viking {
-///     name: String,
-///     country: String,
-/// }
-///
-/// impl Viking {
-///     /// Create a new Viking.
-///     fn new(name: &str, country: &str) -> Viking {
-///         Viking { name: name.to_string(), country: country.to_string() }
-///     }
-/// }
-///
-/// // Use a HashMap to store the vikings' health points.
-/// let mut vikings = HashMap::new();
-///
-/// vikings.insert(Viking::new("Einar", "Norway"), 25);
-/// vikings.insert(Viking::new("Olaf", "Denmark"), 24);
-/// vikings.insert(Viking::new("Harald", "Iceland"), 12);
-///
-/// // Use derived implementation to print the status of the vikings.
-/// for (viking, health) in vikings.iter() {
-///     println!("{:?} has {} hp", viking, health);
-/// }
-/// ```
-#[derive(Clone)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct HashMap<K, V, S = RandomState> {
-    // All hashes are keyed on these values, to prevent hash collision attacks.
-    hash_state: S,
-
-    table: RawTable<K, V>,
-
-    resize_policy: DefaultResizePolicy,
-}
-
-/// Search for a pre-hashed key.
-fn search_hashed<K, V, M, F>(table: M,
-                             hash: SafeHash,
-                             mut is_match: F)
-                             -> SearchResult<K, V, M> where
-    M: Deref<Target=RawTable<K, V>>,
-    F: FnMut(&K) -> bool,
-{
-    let size = table.size();
-    let mut probe = Bucket::new(table, hash);
-    let ib = probe.index();
-
-    while probe.index() != ib + size {
-        let full = match probe.peek() {
-            Empty(b) => return TableRef(b.into_table()), // hit an empty bucket
-            Full(b) => b
-        };
-
-        if full.distance() + ib < full.index() {
-            // We can finish the search early if we hit any bucket
-            // with a lower distance to initial bucket than we've probed.
-            return TableRef(full.into_table());
-        }
-
-        // If the hash doesn't match, it can't be this one..
-        if hash == full.hash() {
-            // If the key doesn't match, it can't be this one..
-            if is_match(full.read().0) {
-                return FoundExisting(full);
-            }
-        }
-
-        probe = full.next();
-    }
-
-    TableRef(probe.into_table())
-}
-
-fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> (K, V) {
-    let (empty, retkey, retval) = starting_bucket.take();
-    let mut gap = match empty.gap_peek() {
-        Some(b) => b,
-        None => return (retkey, retval)
-    };
-
-    while gap.full().distance() != 0 {
-        gap = match gap.shift() {
-            Some(b) => b,
-            None => break
-        };
-    }
-
-    // Now we've done all our shifting. Return the value we grabbed earlier.
-    (retkey, retval)
-}
-
-/// Perform robin hood bucket stealing at the given `bucket`. You must
-/// also pass the position of that bucket's initial bucket so we don't have
-/// to recalculate it.
-///
-/// `hash`, `k`, and `v` are the elements to "robin hood" into the hashtable.
-fn robin_hood<'a, K: 'a, V: 'a>(mut bucket: FullBucketMut<'a, K, V>,
-                        mut ib: usize,
-                        mut hash: SafeHash,
-                        mut k: K,
-                        mut v: V)
-                        -> &'a mut V {
-    let starting_index = bucket.index();
-    let size = {
-        let table = bucket.table(); // FIXME "lifetime too short".
-        table.size()
-    };
-    // There can be at most `size - dib` buckets to displace, because
-    // in the worst case, there are `size` elements and we already are
-    // `distance` buckets away from the initial one.
-    let idx_end = starting_index + size - bucket.distance();
-
-    loop {
-        let (old_hash, old_key, old_val) = bucket.replace(hash, k, v);
-        loop {
-            let probe = bucket.next();
-            assert!(probe.index() != idx_end);
-
-            let full_bucket = match probe.peek() {
-                Empty(bucket) => {
-                    // Found a hole!
-                    let b = bucket.put(old_hash, old_key, old_val);
-                    // Now that it's stolen, just read the value's pointer
-                    // right out of the table!
-                    return Bucket::at_index(b.into_table(), starting_index)
-                               .peek()
-                               .expect_full()
-                               .into_mut_refs()
-                               .1;
-                },
-                Full(bucket) => bucket
-            };
-
-            let probe_ib = full_bucket.index() - full_bucket.distance();
-
-            bucket = full_bucket;
-
-            // Robin hood! Steal the spot.
-            if ib < probe_ib {
-                ib = probe_ib;
-                hash = old_hash;
-                k = old_key;
-                v = old_val;
-                break;
-            }
-        }
-    }
-}
-
-/// A result that works like Option<FullBucket<..>> but preserves
-/// the reference that grants us access to the table in any case.
-enum SearchResult<K, V, M> {
-    // This is an entry that holds the given key:
-    FoundExisting(FullBucket<K, V, M>),
-
-    // There was no such entry. The reference is given back:
-    TableRef(M)
-}
-
-impl<K, V, M> SearchResult<K, V, M> {
-    fn into_option(self) -> Option<FullBucket<K, V, M>> {
-        match self {
-            FoundExisting(bucket) => Some(bucket),
-            TableRef(_) => None
-        }
-    }
-}
-
-impl<K, V, S, H> HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    fn make_hash<X: ?Sized>(&self, x: &X) -> SafeHash where X: Hash<H> {
-        table::make_hash(&self.hash_state, x)
-    }
-
-    /// Search for a key, yielding the index if it's found in the hashtable.
-    /// If you already have the hash for the key lying around, use
-    /// search_hashed.
-    fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option<FullBucketImm<'a, K, V>>
-        where K: Borrow<Q>, Q: Eq + Hash<H>
-    {
-        let hash = self.make_hash(q);
-        search_hashed(&self.table, hash, |k| q.eq(k.borrow()))
-            .into_option()
-    }
-
-    fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> Option<FullBucketMut<'a, K, V>>
-        where K: Borrow<Q>, Q: Eq + Hash<H>
-    {
-        let hash = self.make_hash(q);
-        search_hashed(&mut self.table, hash, |k| q.eq(k.borrow()))
-            .into_option()
-    }
-
-    // The caller should ensure that invariants by Robin Hood Hashing hold.
-    fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) {
-        let cap = self.table.capacity();
-        let mut buckets = Bucket::new(&mut self.table, hash);
-        let ib = buckets.index();
-
-        while buckets.index() != ib + cap {
-            // We don't need to compare hashes for value swap.
-            // Not even DIBs for Robin Hood.
-            buckets = match buckets.peek() {
-                Empty(empty) => {
-                    empty.put(hash, k, v);
-                    return;
-                }
-                Full(b) => b.into_bucket()
-            };
-            buckets.next();
-        }
-        panic!("Internal HashMap error: Out of space.");
-    }
-}
-
-impl<K: Hash<Hasher> + Eq, V> HashMap<K, V, RandomState> {
-    /// Create an empty HashMap.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    /// let mut map: HashMap<&str, int> = HashMap::new();
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> HashMap<K, V, RandomState> {
-        Default::default()
-    }
-
-    /// Creates an empty hash map with the given initial capacity.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10);
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn with_capacity(capacity: usize) -> HashMap<K, V, RandomState> {
-        HashMap::with_capacity_and_hash_state(capacity, Default::default())
-    }
-}
-
-impl<K, V, S, H> HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    /// Creates an empty hashmap which will use the given hasher to hash keys.
-    ///
-    /// The creates map has the default initial capacity.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    /// use std::collections::hash_map::RandomState;
-    ///
-    /// let s = RandomState::new();
-    /// let mut map = HashMap::with_hash_state(s);
-    /// map.insert(1, 2);
-    /// ```
-    #[inline]
-    #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")]
-    pub fn with_hash_state(hash_state: S) -> HashMap<K, V, S> {
-        HashMap {
-            hash_state:    hash_state,
-            resize_policy: DefaultResizePolicy::new(),
-            table:         RawTable::new(0),
-        }
-    }
-
-    /// Create an empty HashMap with space for at least `capacity`
-    /// elements, using `hasher` to hash the keys.
-    ///
-    /// Warning: `hasher` is normally randomly generated, and
-    /// is designed to allow HashMaps to be resistant to attacks that
-    /// cause many collisions and very poor performance. Setting it
-    /// manually using this function can expose a DoS attack vector.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    /// use std::collections::hash_map::RandomState;
-    ///
-    /// let s = RandomState::new();
-    /// let mut map = HashMap::with_capacity_and_hash_state(10, s);
-    /// map.insert(1, 2);
-    /// ```
-    #[inline]
-    #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")]
-    pub fn with_capacity_and_hash_state(capacity: usize, hash_state: S)
-                                        -> HashMap<K, V, S> {
-        let resize_policy = DefaultResizePolicy::new();
-        let min_cap = max(INITIAL_CAPACITY, resize_policy.min_capacity(capacity));
-        let internal_cap = min_cap.checked_next_power_of_two().expect("capacity overflow");
-        assert!(internal_cap >= capacity, "capacity overflow");
-        HashMap {
-            hash_state:    hash_state,
-            resize_policy: resize_policy,
-            table:         RawTable::new(internal_cap),
-        }
-    }
-
-    /// Returns the number of elements the map can hold without reallocating.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    /// let map: HashMap<int, int> = HashMap::with_capacity(100);
-    /// assert!(map.capacity() >= 100);
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn capacity(&self) -> usize {
-        self.resize_policy.usable_capacity(self.table.capacity())
-    }
-
-    /// Reserves capacity for at least `additional` more elements to be inserted
-    /// in the `HashMap`. The collection may reserve more space to avoid
-    /// frequent reallocations.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the new allocation size overflows `usize`.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    /// let mut map: HashMap<&str, int> = HashMap::new();
-    /// map.reserve(10);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn reserve(&mut self, additional: usize) {
-        let new_size = self.len().checked_add(additional).expect("capacity overflow");
-        let min_cap = self.resize_policy.min_capacity(new_size);
-
-        // An invalid value shouldn't make us run out of space. This includes
-        // an overflow check.
-        assert!(new_size <= min_cap);
-
-        if self.table.capacity() < min_cap {
-            let new_capacity = max(min_cap.next_power_of_two(), INITIAL_CAPACITY);
-            self.resize(new_capacity);
-        }
-    }
-
-    /// Resizes the internal vectors to a new capacity. It's your responsibility to:
-    ///   1) Make sure the new capacity is enough for all the elements, accounting
-    ///      for the load factor.
-    ///   2) Ensure new_capacity is a power of two or zero.
-    fn resize(&mut self, new_capacity: usize) {
-        assert!(self.table.size() <= new_capacity);
-        assert!(new_capacity.is_power_of_two() || new_capacity == 0);
-
-        let mut old_table = replace(&mut self.table, RawTable::new(new_capacity));
-        let old_size = old_table.size();
-
-        if old_table.capacity() == 0 || old_table.size() == 0 {
-            return;
-        }
-
-        // Grow the table.
-        // Specialization of the other branch.
-        let mut bucket = Bucket::first(&mut old_table);
-
-        // "So a few of the first shall be last: for many be called,
-        // but few chosen."
-        //
-        // We'll most likely encounter a few buckets at the beginning that
-        // have their initial buckets near the end of the table. They were
-        // placed at the beginning as the probe wrapped around the table
-        // during insertion. We must skip forward to a bucket that won't
-        // get reinserted too early and won't unfairly steal others spot.
-        // This eliminates the need for robin hood.
-        loop {
-            bucket = match bucket.peek() {
-                Full(full) => {
-                    if full.distance() == 0 {
-                        // This bucket occupies its ideal spot.
-                        // It indicates the start of another "cluster".
-                        bucket = full.into_bucket();
-                        break;
-                    }
-                    // Leaving this bucket in the last cluster for later.
-                    full.into_bucket()
-                }
-                Empty(b) => {
-                    // Encountered a hole between clusters.
-                    b.into_bucket()
-                }
-            };
-            bucket.next();
-        }
-
-        // This is how the buckets might be laid out in memory:
-        // ($ marks an initialized bucket)
-        //  ________________
-        // |$$$_$$$$$$_$$$$$|
-        //
-        // But we've skipped the entire initial cluster of buckets
-        // and will continue iteration in this order:
-        //  ________________
-        //     |$$$$$$_$$$$$
-        //                  ^ wrap around once end is reached
-        //  ________________
-        //  $$$_____________|
-        //    ^ exit once table.size == 0
-        loop {
-            bucket = match bucket.peek() {
-                Full(bucket) => {
-                    let h = bucket.hash();
-                    let (b, k, v) = bucket.take();
-                    self.insert_hashed_ordered(h, k, v);
-                    {
-                        let t = b.table(); // FIXME "lifetime too short".
-                        if t.size() == 0 { break }
-                    };
-                    b.into_bucket()
-                }
-                Empty(b) => b.into_bucket()
-            };
-            bucket.next();
-        }
-
-        assert_eq!(self.table.size(), old_size);
-    }
-
-    /// Shrinks the capacity of the map as much as possible. It will drop
-    /// down as much as possible while maintaining the internal rules
-    /// and possibly leaving some space in accordance with the resize policy.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map: HashMap<int, int> = HashMap::with_capacity(100);
-    /// map.insert(1, 2);
-    /// map.insert(3, 4);
-    /// assert!(map.capacity() >= 100);
-    /// map.shrink_to_fit();
-    /// assert!(map.capacity() >= 2);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn shrink_to_fit(&mut self) {
-        let min_capacity = self.resize_policy.min_capacity(self.len());
-        let min_capacity = max(min_capacity.next_power_of_two(), INITIAL_CAPACITY);
-
-        // An invalid value shouldn't make us run out of space.
-        debug_assert!(self.len() <= min_capacity);
-
-        if self.table.capacity() != min_capacity {
-            let old_table = replace(&mut self.table, RawTable::new(min_capacity));
-            let old_size = old_table.size();
-
-            // Shrink the table. Naive algorithm for resizing:
-            for (h, k, v) in old_table.into_iter() {
-                self.insert_hashed_nocheck(h, k, v);
-            }
-
-            debug_assert_eq!(self.table.size(), old_size);
-        }
-    }
-
-    /// Insert a pre-hashed key-value pair, without first checking
-    /// that there's enough room in the buckets. Returns a reference to the
-    /// newly insert value.
-    ///
-    /// If the key already exists, the hashtable will be returned untouched
-    /// and a reference to the existing element will be returned.
-    fn insert_hashed_nocheck(&mut self, hash: SafeHash, k: K, v: V) -> &mut V {
-        self.insert_or_replace_with(hash, k, v, |_, _, _| ())
-    }
-
-    fn insert_or_replace_with<'a, F>(&'a mut self,
-                                     hash: SafeHash,
-                                     k: K,
-                                     v: V,
-                                     mut found_existing: F)
-                                     -> &'a mut V where
-        F: FnMut(&mut K, &mut V, V),
-    {
-        // Worst case, we'll find one empty bucket among `size + 1` buckets.
-        let size = self.table.size();
-        let mut probe = Bucket::new(&mut self.table, hash);
-        let ib = probe.index();
-
-        loop {
-            let mut bucket = match probe.peek() {
-                Empty(bucket) => {
-                    // Found a hole!
-                    return bucket.put(hash, k, v).into_mut_refs().1;
-                }
-                Full(bucket) => bucket
-            };
-
-            // hash matches?
-            if bucket.hash() == hash {
-                // key matches?
-                if k == *bucket.read_mut().0 {
-                    let (bucket_k, bucket_v) = bucket.into_mut_refs();
-                    debug_assert!(k == *bucket_k);
-                    // Key already exists. Get its reference.
-                    found_existing(bucket_k, bucket_v, v);
-                    return bucket_v;
-                }
-            }
-
-            let robin_ib = bucket.index() as int - bucket.distance() as int;
-
-            if (ib as int) < robin_ib {
-                // Found a luckier bucket than me. Better steal his spot.
-                return robin_hood(bucket, robin_ib as usize, hash, k, v);
-            }
-
-            probe = bucket.next();
-            assert!(probe.index() != ib + size + 1);
-        }
-    }
-
-    /// An iterator visiting all keys in arbitrary order.
-    /// Iterator element type is `&'a K`.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert("a", 1);
-    /// map.insert("b", 2);
-    /// map.insert("c", 3);
-    ///
-    /// for key in map.keys() {
-    ///     println!("{}", key);
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
-        fn first<A, B>((a, _): (A, B)) -> A { a }
-        let first: fn((&'a K,&'a V)) -> &'a K = first; // coerce to fn ptr
-
-        Keys { inner: self.iter().map(first) }
-    }
-
-    /// An iterator visiting all values in arbitrary order.
-    /// Iterator element type is `&'a V`.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert("a", 1);
-    /// map.insert("b", 2);
-    /// map.insert("c", 3);
-    ///
-    /// for val in map.values() {
-    ///     println!("{}", val);
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn values<'a>(&'a self) -> Values<'a, K, V> {
-        fn second<A, B>((_, b): (A, B)) -> B { b }
-        let second: fn((&'a K,&'a V)) -> &'a V = second; // coerce to fn ptr
-
-        Values { inner: self.iter().map(second) }
-    }
-
-    /// An iterator visiting all key-value pairs in arbitrary order.
-    /// Iterator element type is `(&'a K, &'a V)`.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert("a", 1);
-    /// map.insert("b", 2);
-    /// map.insert("c", 3);
-    ///
-    /// for (key, val) in map.iter() {
-    ///     println!("key: {} val: {}", key, val);
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn iter(&self) -> Iter<K, V> {
-        Iter { inner: self.table.iter() }
-    }
-
-    /// An iterator visiting all key-value pairs in arbitrary order,
-    /// with mutable references to the values.
-    /// Iterator element type is `(&'a K, &'a mut V)`.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert("a", 1);
-    /// map.insert("b", 2);
-    /// map.insert("c", 3);
-    ///
-    /// // Update all values
-    /// for (_, val) in map.iter_mut() {
-    ///     *val *= 2;
-    /// }
-    ///
-    /// for (key, val) in map.iter() {
-    ///     println!("key: {} val: {}", key, val);
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn iter_mut(&mut self) -> IterMut<K, V> {
-        IterMut { inner: self.table.iter_mut() }
-    }
-
-    /// Creates a consuming iterator, that is, one that moves each key-value
-    /// pair out of the map in arbitrary order. The map cannot be used after
-    /// calling this.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert("a", 1);
-    /// map.insert("b", 2);
-    /// map.insert("c", 3);
-    ///
-    /// // Not possible with .iter()
-    /// let vec: Vec<(&str, int)> = map.into_iter().collect();
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<K, V> {
-        fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
-        let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two;
-
-        IntoIter {
-            inner: self.table.into_iter().map(last_two)
-        }
-    }
-
-    /// Gets the given key's corresponding entry in the map for in-place manipulation.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn entry(&mut self, key: K) -> Entry<K, V> {
-        // Gotta resize now.
-        self.reserve(1);
-
-        let hash = self.make_hash(&key);
-        search_entry_hashed(&mut self.table, hash, key)
-    }
-
-    /// Returns the number of elements in the map.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut a = HashMap::new();
-    /// assert_eq!(a.len(), 0);
-    /// a.insert(1, "a");
-    /// assert_eq!(a.len(), 1);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn len(&self) -> usize { self.table.size() }
-
-    /// Returns true if the map contains no elements.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut a = HashMap::new();
-    /// assert!(a.is_empty());
-    /// a.insert(1, "a");
-    /// assert!(!a.is_empty());
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_empty(&self) -> bool { self.len() == 0 }
-
-    /// Clears the map, returning all key-value pairs as an iterator. Keeps the
-    /// allocated memory for reuse.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut a = HashMap::new();
-    /// a.insert(1, "a");
-    /// a.insert(2, "b");
-    ///
-    /// for (k, v) in a.drain().take(1) {
-    ///     assert!(k == 1 || k == 2);
-    ///     assert!(v == "a" || v == "b");
-    /// }
-    ///
-    /// assert!(a.is_empty());
-    /// ```
-    #[inline]
-    #[unstable(feature = "std_misc",
-               reason = "matches collection reform specification, waiting for dust to settle")]
-    pub fn drain(&mut self) -> Drain<K, V> {
-        fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
-        let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two; // coerce to fn pointer
-
-        Drain {
-            inner: self.table.drain().map(last_two),
-        }
-    }
-
-    /// Clears the map, removing all key-value pairs. Keeps the allocated memory
-    /// for reuse.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut a = HashMap::new();
-    /// a.insert(1, "a");
-    /// a.clear();
-    /// assert!(a.is_empty());
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[inline]
-    pub fn clear(&mut self) {
-        self.drain();
-    }
-
-    /// Returns a reference to the value corresponding to the key.
-    ///
-    /// The key may be any borrowed form of the map's key type, but
-    /// `Hash` and `Eq` on the borrowed form *must* match those for
-    /// the key type.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert(1, "a");
-    /// assert_eq!(map.get(&1), Some(&"a"));
-    /// assert_eq!(map.get(&2), None);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
-        where K: Borrow<Q>, Q: Hash<H> + Eq
-    {
-        self.search(k).map(|bucket| bucket.into_refs().1)
-    }
-
-    /// Returns true if the map contains a value for the specified key.
-    ///
-    /// The key may be any borrowed form of the map's key type, but
-    /// `Hash` and `Eq` on the borrowed form *must* match those for
-    /// the key type.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert(1, "a");
-    /// assert_eq!(map.contains_key(&1), true);
-    /// assert_eq!(map.contains_key(&2), false);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
-        where K: Borrow<Q>, Q: Hash<H> + Eq
-    {
-        self.search(k).is_some()
-    }
-
-    /// Returns a mutable reference to the value corresponding to the key.
-    ///
-    /// The key may be any borrowed form of the map's key type, but
-    /// `Hash` and `Eq` on the borrowed form *must* match those for
-    /// the key type.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert(1, "a");
-    /// match map.get_mut(&1) {
-    ///     Some(x) => *x = "b",
-    ///     None => (),
-    /// }
-    /// assert_eq!(map[1], "b");
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
-        where K: Borrow<Q>, Q: Hash<H> + Eq
-    {
-        self.search_mut(k).map(|bucket| bucket.into_mut_refs().1)
-    }
-
-    /// Inserts a key-value pair from the map. If the key already had a value
-    /// present in the map, that value is returned. Otherwise, `None` is returned.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// assert_eq!(map.insert(37, "a"), None);
-    /// assert_eq!(map.is_empty(), false);
-    ///
-    /// map.insert(37, "b");
-    /// assert_eq!(map.insert(37, "c"), Some("b"));
-    /// assert_eq!(map[37], "c");
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
-        let hash = self.make_hash(&k);
-        self.reserve(1);
-
-        let mut retval = None;
-        self.insert_or_replace_with(hash, k, v, |_, val_ref, val| {
-            retval = Some(replace(val_ref, val));
-        });
-        retval
-    }
-
-    /// Removes a key from the map, returning the value at the key if the key
-    /// was previously in the map.
-    ///
-    /// The key may be any borrowed form of the map's key type, but
-    /// `Hash` and `Eq` on the borrowed form *must* match those for
-    /// the key type.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert(1, "a");
-    /// assert_eq!(map.remove(&1), Some("a"));
-    /// assert_eq!(map.remove(&1), None);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
-        where K: Borrow<Q>, Q: Hash<H> + Eq
-    {
-        if self.table.size() == 0 {
-            return None
-        }
-
-        self.search_mut(k).map(|bucket| pop_internal(bucket).1)
-    }
-}
-
-fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHash, k: K)
-        -> Entry<'a, K, V>
-{
-    // Worst case, we'll find one empty bucket among `size + 1` buckets.
-    let size = table.size();
-    let mut probe = Bucket::new(table, hash);
-    let ib = probe.index();
-
-    loop {
-        let bucket = match probe.peek() {
-            Empty(bucket) => {
-                // Found a hole!
-                return Vacant(VacantEntry {
-                    hash: hash,
-                    key: k,
-                    elem: NoElem(bucket),
-                });
-            },
-            Full(bucket) => bucket
-        };
-
-        // hash matches?
-        if bucket.hash() == hash {
-            // key matches?
-            if k == *bucket.read().0 {
-                return Occupied(OccupiedEntry{
-                    elem: bucket,
-                });
-            }
-        }
-
-        let robin_ib = bucket.index() as int - bucket.distance() as int;
-
-        if (ib as int) < robin_ib {
-            // Found a luckier bucket than me. Better steal his spot.
-            return Vacant(VacantEntry {
-                hash: hash,
-                key: k,
-                elem: NeqElem(bucket, robin_ib as usize),
-            });
-        }
-
-        probe = bucket.next();
-        assert!(probe.index() != ib + size + 1);
-    }
-}
-
-impl<K, V, S, H> PartialEq for HashMap<K, V, S>
-    where K: Eq + Hash<H>, V: PartialEq,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    fn eq(&self, other: &HashMap<K, V, S>) -> bool {
-        if self.len() != other.len() { return false; }
-
-        self.iter().all(|(key, value)|
-            other.get(key).map_or(false, |v| *value == *v)
-        )
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H> Eq for HashMap<K, V, S>
-    where K: Eq + Hash<H>, V: Eq,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H> Debug for HashMap<K, V, S>
-    where K: Eq + Hash<H> + Debug, V: Debug,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "HashMap {{"));
-
-        for (i, (k, v)) in self.iter().enumerate() {
-            if i != 0 { try!(write!(f, ", ")); }
-            try!(write!(f, "{:?}: {:?}", *k, *v));
-        }
-
-        write!(f, "}}")
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H> Default for HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
-{
-    fn default() -> HashMap<K, V, S> {
-        HashMap::with_hash_state(Default::default())
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K, Q: ?Sized, V, S, H> Index<Q> for HashMap<K, V, S>
-    where K: Eq + Hash<H> + Borrow<Q>,
-          Q: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    type Output = V;
-
-    #[inline]
-    fn index<'a>(&'a self, index: &Q) -> &'a V {
-        self.get(index).expect("no entry found for key")
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H, Q: ?Sized> IndexMut<Q> for HashMap<K, V, S>
-    where K: Eq + Hash<H> + Borrow<Q>,
-          Q: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    #[inline]
-    fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V {
-        self.get_mut(index).expect("no entry found for key")
-    }
-}
-
-/// HashMap iterator.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Iter<'a, K: 'a, V: 'a> {
-    inner: table::Iter<'a, K, V>
-}
-
-// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
-impl<'a, K, V> Clone for Iter<'a, K, V> {
-    fn clone(&self) -> Iter<'a, K, V> {
-        Iter {
-            inner: self.inner.clone()
-        }
-    }
-}
-
-/// HashMap mutable values iterator.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct IterMut<'a, K: 'a, V: 'a> {
-    inner: table::IterMut<'a, K, V>
-}
-
-/// HashMap move iterator.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct IntoIter<K, V> {
-    inner: iter::Map<table::IntoIter<K, V>, fn((SafeHash, K, V)) -> (K, V)>
-}
-
-/// HashMap keys iterator.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Keys<'a, K: 'a, V: 'a> {
-    inner: Map<Iter<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>
-}
-
-// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
-impl<'a, K, V> Clone for Keys<'a, K, V> {
-    fn clone(&self) -> Keys<'a, K, V> {
-        Keys {
-            inner: self.inner.clone()
-        }
-    }
-}
-
-/// HashMap values iterator.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Values<'a, K: 'a, V: 'a> {
-    inner: Map<Iter<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>
-}
-
-// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
-impl<'a, K, V> Clone for Values<'a, K, V> {
-    fn clone(&self) -> Values<'a, K, V> {
-        Values {
-            inner: self.inner.clone()
-        }
-    }
-}
-
-/// HashMap drain iterator.
-#[unstable(feature = "std_misc",
-           reason = "matches collection reform specification, waiting for dust to settle")]
-pub struct Drain<'a, K: 'a, V: 'a> {
-    inner: iter::Map<table::Drain<'a, K, V>, fn((SafeHash, K, V)) -> (K, V)>
-}
-
-/// A view into a single occupied location in a HashMap.
-#[unstable(feature = "std_misc",
-           reason = "precise API still being fleshed out")]
-pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
-    elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
-}
-
-/// A view into a single empty location in a HashMap.
-#[unstable(feature = "std_misc",
-           reason = "precise API still being fleshed out")]
-pub struct VacantEntry<'a, K: 'a, V: 'a> {
-    hash: SafeHash,
-    key: K,
-    elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>,
-}
-
-/// A view into a single location in a map, which may be vacant or occupied.
-#[unstable(feature = "std_misc",
-           reason = "precise API still being fleshed out")]
-pub enum Entry<'a, K: 'a, V: 'a> {
-    /// An occupied Entry.
-    Occupied(OccupiedEntry<'a, K, V>),
-    /// A vacant Entry.
-    Vacant(VacantEntry<'a, K, V>),
-}
-
-/// Possible states of a VacantEntry.
-enum VacantEntryState<K, V, M> {
-    /// The index is occupied, but the key to insert has precedence,
-    /// and will kick the current one out on insertion.
-    NeqElem(FullBucket<K, V, M>, usize),
-    /// The index is genuinely vacant.
-    NoElem(EmptyBucket<K, V, M>),
-}
-
-impl<'a, K, V, S, H> IntoIterator for &'a HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    type Item = (&'a K, &'a V);
-    type IntoIter = Iter<'a, K, V>;
-
-    fn into_iter(self) -> Iter<'a, K, V> {
-        self.iter()
-    }
-}
-
-impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    type Item = (&'a K, &'a mut V);
-    type IntoIter = IterMut<'a, K, V>;
-
-    fn into_iter(mut self) -> IterMut<'a, K, V> {
-        self.iter_mut()
-    }
-}
-
-impl<K, V, S, H> IntoIterator for HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    type Item = (K, V);
-    type IntoIter = IntoIter<K, V>;
-
-    fn into_iter(self) -> IntoIter<K, V> {
-        self.into_iter()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K, V> Iterator for Iter<'a, K, V> {
-    type Item = (&'a K, &'a V);
-
-    #[inline] fn next(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next() }
-    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
-    #[inline] fn len(&self) -> usize { self.inner.len() }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K, V> Iterator for IterMut<'a, K, V> {
-    type Item = (&'a K, &'a mut V);
-
-    #[inline] fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next() }
-    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
-    #[inline] fn len(&self) -> usize { self.inner.len() }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V> Iterator for IntoIter<K, V> {
-    type Item = (K, V);
-
-    #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
-    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V> ExactSizeIterator for IntoIter<K, V> {
-    #[inline] fn len(&self) -> usize { self.inner.len() }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K, V> Iterator for Keys<'a, K, V> {
-    type Item = &'a K;
-
-    #[inline] fn next(&mut self) -> Option<(&'a K)> { self.inner.next() }
-    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {
-    #[inline] fn len(&self) -> usize { self.inner.len() }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K, V> Iterator for Values<'a, K, V> {
-    type Item = &'a V;
-
-    #[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next() }
-    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
-    #[inline] fn len(&self) -> usize { self.inner.len() }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K, V> Iterator for Drain<'a, K, V> {
-    type Item = (K, V);
-
-    #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
-    #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
-    #[inline] fn len(&self) -> usize { self.inner.len() }
-}
-
-#[unstable(feature = "std_misc",
-           reason = "matches collection reform v2 specification, waiting for dust to settle")]
-impl<'a, K, V> Entry<'a, K, V> {
-    /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant.
-    pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> {
-        match self {
-            Occupied(entry) => Ok(entry.into_mut()),
-            Vacant(entry) => Err(entry),
-        }
-    }
-}
-
-impl<'a, K, V> OccupiedEntry<'a, K, V> {
-    /// Gets a reference to the value in the entry.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get(&self) -> &V {
-        self.elem.read().1
-    }
-
-    /// Gets a mutable reference to the value in the entry.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get_mut(&mut self) -> &mut V {
-        self.elem.read_mut().1
-    }
-
-    /// Converts the OccupiedEntry into a mutable reference to the value in the entry
-    /// with a lifetime bound to the map itself
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_mut(self) -> &'a mut V {
-        self.elem.into_mut_refs().1
-    }
-
-    /// Sets the value of the entry, and returns the entry's old value
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn insert(&mut self, mut value: V) -> V {
-        let old_value = self.get_mut();
-        mem::swap(&mut value, old_value);
-        value
-    }
-
-    /// Takes the value out of the entry, and returns it
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn remove(self) -> V {
-        pop_internal(self.elem).1
-    }
-}
-
-impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
-    /// Sets the value of the entry with the VacantEntry's key,
-    /// and returns a mutable reference to it
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn insert(self, value: V) -> &'a mut V {
-        match self.elem {
-            NeqElem(bucket, ib) => {
-                robin_hood(bucket, ib, self.hash, self.key, value)
-            }
-            NoElem(bucket) => {
-                bucket.put(self.hash, self.key, value).into_mut_refs().1
-            }
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H> FromIterator<(K, V)> for HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
-{
-    fn from_iter<T: IntoIterator<Item=(K, V)>>(iter: T) -> HashMap<K, V, S> {
-        let iter = iter.into_iter();
-        let lower = iter.size_hint().0;
-        let mut map = HashMap::with_capacity_and_hash_state(lower,
-                                                            Default::default());
-        map.extend(iter);
-        map
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K, V, S, H> Extend<(K, V)> for HashMap<K, V, S>
-    where K: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    fn extend<T: IntoIterator<Item=(K, V)>>(&mut self, iter: T) {
-        for (k, v) in iter {
-            self.insert(k, v);
-        }
-    }
-}
-
-
-/// `RandomState` is the default state for `HashMap` types.
-///
-/// A particular instance `RandomState` will create the same instances of
-/// `Hasher`, but the hashers created by two different `RandomState`
-/// instances are unlikely to produce the same result for the same values.
-#[derive(Clone)]
-#[unstable(feature = "std_misc",
-           reason = "hashing an hash maps may be altered")]
-pub struct RandomState {
-    k0: u64,
-    k1: u64,
-}
-
-#[unstable(feature = "std_misc",
-           reason = "hashing an hash maps may be altered")]
-impl RandomState {
-    /// Construct a new `RandomState` that is initialized with random keys.
-    #[inline]
-    #[allow(deprecated)]
-    pub fn new() -> RandomState {
-        let mut r = rand::thread_rng();
-        RandomState { k0: r.gen(), k1: r.gen() }
-    }
-}
-
-#[unstable(feature = "std_misc",
-           reason = "hashing an hash maps may be altered")]
-impl HashState for RandomState {
-    type Hasher = Hasher;
-    fn hasher(&self) -> Hasher {
-        Hasher { inner: SipHasher::new_with_keys(self.k0, self.k1) }
-    }
-}
-
-#[unstable(feature = "std_misc",
-           reason = "hashing an hash maps may be altered")]
-impl Default for RandomState {
-    #[inline]
-    fn default() -> RandomState {
-        RandomState::new()
-    }
-}
-
-/// A hasher implementation which is generated from `RandomState` instances.
-///
-/// This is the default hasher used in a `HashMap` to hash keys. Types do not
-/// typically declare an ability to explicitly hash into this particular type,
-/// but rather in a `H: hash::Writer` type parameter.
-#[unstable(feature = "std_misc",
-           reason = "hashing an hash maps may be altered")]
-pub struct Hasher { inner: SipHasher }
-
-impl hash::Writer for Hasher {
-    fn write(&mut self, data: &[u8]) {
-        hash::Writer::write(&mut self.inner, data)
-    }
-}
-
-impl hash::Hasher for Hasher {
-    type Output = u64;
-    fn reset(&mut self) { hash::Hasher::reset(&mut self.inner) }
-    fn finish(&self) -> u64 { self.inner.finish() }
-}
-
-#[cfg(test)]
-mod test_map {
-    use prelude::v1::*;
-
-    use super::HashMap;
-    use super::Entry::{Occupied, Vacant};
-    use iter::{range_inclusive, range_step_inclusive, repeat};
-    use cell::RefCell;
-    use rand::{weak_rng, Rng};
-
-    #[test]
-    fn test_create_capacity_zero() {
-        let mut m = HashMap::with_capacity(0);
-
-        assert!(m.insert(1, 1).is_none());
-
-        assert!(m.contains_key(&1));
-        assert!(!m.contains_key(&0));
-    }
-
-    #[test]
-    fn test_insert() {
-        let mut m = HashMap::new();
-        assert_eq!(m.len(), 0);
-        assert!(m.insert(1, 2).is_none());
-        assert_eq!(m.len(), 1);
-        assert!(m.insert(2, 4).is_none());
-        assert_eq!(m.len(), 2);
-        assert_eq!(*m.get(&1).unwrap(), 2);
-        assert_eq!(*m.get(&2).unwrap(), 4);
-    }
-
-    thread_local! { static DROP_VECTOR: RefCell<Vec<int>> = RefCell::new(Vec::new()) }
-
-    #[derive(Hash, PartialEq, Eq)]
-    struct Dropable {
-        k: usize
-    }
-
-    impl Dropable {
-        fn new(k: usize) -> Dropable {
-            DROP_VECTOR.with(|slot| {
-                slot.borrow_mut()[k] += 1;
-            });
-
-            Dropable { k: k }
-        }
-    }
-
-    impl Drop for Dropable {
-        fn drop(&mut self) {
-            DROP_VECTOR.with(|slot| {
-                slot.borrow_mut()[self.k] -= 1;
-            });
-        }
-    }
-
-    impl Clone for Dropable {
-        fn clone(&self) -> Dropable {
-            Dropable::new(self.k)
-        }
-    }
-
-    #[test]
-    fn test_drops() {
-        DROP_VECTOR.with(|slot| {
-            *slot.borrow_mut() = repeat(0).take(200).collect();
-        });
-
-        {
-            let mut m = HashMap::new();
-
-            DROP_VECTOR.with(|v| {
-                for i in 0..200 {
-                    assert_eq!(v.borrow()[i], 0);
-                }
-            });
-
-            for i in 0..100 {
-                let d1 = Dropable::new(i);
-                let d2 = Dropable::new(i+100);
-                m.insert(d1, d2);
-            }
-
-            DROP_VECTOR.with(|v| {
-                for i in 0..200 {
-                    assert_eq!(v.borrow()[i], 1);
-                }
-            });
-
-            for i in 0..50 {
-                let k = Dropable::new(i);
-                let v = m.remove(&k);
-
-                assert!(v.is_some());
-
-                DROP_VECTOR.with(|v| {
-                    assert_eq!(v.borrow()[i], 1);
-                    assert_eq!(v.borrow()[i+100], 1);
-                });
-            }
-
-            DROP_VECTOR.with(|v| {
-                for i in 0..50 {
-                    assert_eq!(v.borrow()[i], 0);
-                    assert_eq!(v.borrow()[i+100], 0);
-                }
-
-                for i in 50..100 {
-                    assert_eq!(v.borrow()[i], 1);
-                    assert_eq!(v.borrow()[i+100], 1);
-                }
-            });
-        }
-
-        DROP_VECTOR.with(|v| {
-            for i in 0..200 {
-                assert_eq!(v.borrow()[i], 0);
-            }
-        });
-    }
-
-    #[test]
-    fn test_move_iter_drops() {
-        DROP_VECTOR.with(|v| {
-            *v.borrow_mut() = repeat(0).take(200).collect();
-        });
-
-        let hm = {
-            let mut hm = HashMap::new();
-
-            DROP_VECTOR.with(|v| {
-                for i in 0..200 {
-                    assert_eq!(v.borrow()[i], 0);
-                }
-            });
-
-            for i in 0..100 {
-                let d1 = Dropable::new(i);
-                let d2 = Dropable::new(i+100);
-                hm.insert(d1, d2);
-            }
-
-            DROP_VECTOR.with(|v| {
-                for i in 0..200 {
-                    assert_eq!(v.borrow()[i], 1);
-                }
-            });
-
-            hm
-        };
-
-        // By the way, ensure that cloning doesn't screw up the dropping.
-        drop(hm.clone());
-
-        {
-            let mut half = hm.into_iter().take(50);
-
-            DROP_VECTOR.with(|v| {
-                for i in 0..200 {
-                    assert_eq!(v.borrow()[i], 1);
-                }
-            });
-
-            for _ in half.by_ref() {}
-
-            DROP_VECTOR.with(|v| {
-                let nk = (0..100).filter(|&i| {
-                    v.borrow()[i] == 1
-                }).count();
-
-                let nv = (0..100).filter(|&i| {
-                    v.borrow()[i+100] == 1
-                }).count();
-
-                assert_eq!(nk, 50);
-                assert_eq!(nv, 50);
-            });
-        };
-
-        DROP_VECTOR.with(|v| {
-            for i in 0..200 {
-                assert_eq!(v.borrow()[i], 0);
-            }
-        });
-    }
-
-    #[test]
-    fn test_empty_pop() {
-        let mut m: HashMap<int, bool> = HashMap::new();
-        assert_eq!(m.remove(&0), None);
-    }
-
-    #[test]
-    fn test_lots_of_insertions() {
-        let mut m = HashMap::new();
-
-        // Try this a few times to make sure we never screw up the hashmap's
-        // internal state.
-        for _ in 0..10 {
-            assert!(m.is_empty());
-
-            for i in range_inclusive(1, 1000) {
-                assert!(m.insert(i, i).is_none());
-
-                for j in range_inclusive(1, i) {
-                    let r = m.get(&j);
-                    assert_eq!(r, Some(&j));
-                }
-
-                for j in range_inclusive(i+1, 1000) {
-                    let r = m.get(&j);
-                    assert_eq!(r, None);
-                }
-            }
-
-            for i in range_inclusive(1001, 2000) {
-                assert!(!m.contains_key(&i));
-            }
-
-            // remove forwards
-            for i in range_inclusive(1, 1000) {
-                assert!(m.remove(&i).is_some());
-
-                for j in range_inclusive(1, i) {
-                    assert!(!m.contains_key(&j));
-                }
-
-                for j in range_inclusive(i+1, 1000) {
-                    assert!(m.contains_key(&j));
-                }
-            }
-
-            for i in range_inclusive(1, 1000) {
-                assert!(!m.contains_key(&i));
-            }
-
-            for i in range_inclusive(1, 1000) {
-                assert!(m.insert(i, i).is_none());
-            }
-
-            // remove backwards
-            for i in range_step_inclusive(1000, 1, -1) {
-                assert!(m.remove(&i).is_some());
-
-                for j in range_inclusive(i, 1000) {
-                    assert!(!m.contains_key(&j));
-                }
-
-                for j in range_inclusive(1, i-1) {
-                    assert!(m.contains_key(&j));
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_find_mut() {
-        let mut m = HashMap::new();
-        assert!(m.insert(1, 12).is_none());
-        assert!(m.insert(2, 8).is_none());
-        assert!(m.insert(5, 14).is_none());
-        let new = 100;
-        match m.get_mut(&5) {
-            None => panic!(), Some(x) => *x = new
-        }
-        assert_eq!(m.get(&5), Some(&new));
-    }
-
-    #[test]
-    fn test_insert_overwrite() {
-        let mut m = HashMap::new();
-        assert!(m.insert(1, 2).is_none());
-        assert_eq!(*m.get(&1).unwrap(), 2);
-        assert!(!m.insert(1, 3).is_none());
-        assert_eq!(*m.get(&1).unwrap(), 3);
-    }
-
-    #[test]
-    fn test_insert_conflicts() {
-        let mut m = HashMap::with_capacity(4);
-        assert!(m.insert(1, 2).is_none());
-        assert!(m.insert(5, 3).is_none());
-        assert!(m.insert(9, 4).is_none());
-        assert_eq!(*m.get(&9).unwrap(), 4);
-        assert_eq!(*m.get(&5).unwrap(), 3);
-        assert_eq!(*m.get(&1).unwrap(), 2);
-    }
-
-    #[test]
-    fn test_conflict_remove() {
-        let mut m = HashMap::with_capacity(4);
-        assert!(m.insert(1, 2).is_none());
-        assert_eq!(*m.get(&1).unwrap(), 2);
-        assert!(m.insert(5, 3).is_none());
-        assert_eq!(*m.get(&1).unwrap(), 2);
-        assert_eq!(*m.get(&5).unwrap(), 3);
-        assert!(m.insert(9, 4).is_none());
-        assert_eq!(*m.get(&1).unwrap(), 2);
-        assert_eq!(*m.get(&5).unwrap(), 3);
-        assert_eq!(*m.get(&9).unwrap(), 4);
-        assert!(m.remove(&1).is_some());
-        assert_eq!(*m.get(&9).unwrap(), 4);
-        assert_eq!(*m.get(&5).unwrap(), 3);
-    }
-
-    #[test]
-    fn test_is_empty() {
-        let mut m = HashMap::with_capacity(4);
-        assert!(m.insert(1, 2).is_none());
-        assert!(!m.is_empty());
-        assert!(m.remove(&1).is_some());
-        assert!(m.is_empty());
-    }
-
-    #[test]
-    fn test_pop() {
-        let mut m = HashMap::new();
-        m.insert(1, 2);
-        assert_eq!(m.remove(&1), Some(2));
-        assert_eq!(m.remove(&1), None);
-    }
-
-    #[test]
-    fn test_iterate() {
-        let mut m = HashMap::with_capacity(4);
-        for i in 0..32 {
-            assert!(m.insert(i, i*2).is_none());
-        }
-        assert_eq!(m.len(), 32);
-
-        let mut observed: u32 = 0;
-
-        for (k, v) in &m {
-            assert_eq!(*v, *k * 2);
-            observed |= 1 << *k;
-        }
-        assert_eq!(observed, 0xFFFF_FFFF);
-    }
-
-    #[test]
-    fn test_keys() {
-        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
-        let map: HashMap<_, _> = vec.into_iter().collect();
-        let keys: Vec<_> = map.keys().cloned().collect();
-        assert_eq!(keys.len(), 3);
-        assert!(keys.contains(&1));
-        assert!(keys.contains(&2));
-        assert!(keys.contains(&3));
-    }
-
-    #[test]
-    fn test_values() {
-        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
-        let map: HashMap<_, _> = vec.into_iter().collect();
-        let values: Vec<_> = map.values().cloned().collect();
-        assert_eq!(values.len(), 3);
-        assert!(values.contains(&'a'));
-        assert!(values.contains(&'b'));
-        assert!(values.contains(&'c'));
-    }
-
-    #[test]
-    fn test_find() {
-        let mut m = HashMap::new();
-        assert!(m.get(&1).is_none());
-        m.insert(1, 2);
-        match m.get(&1) {
-            None => panic!(),
-            Some(v) => assert_eq!(*v, 2)
-        }
-    }
-
-    #[test]
-    fn test_eq() {
-        let mut m1 = HashMap::new();
-        m1.insert(1, 2);
-        m1.insert(2, 3);
-        m1.insert(3, 4);
-
-        let mut m2 = HashMap::new();
-        m2.insert(1, 2);
-        m2.insert(2, 3);
-
-        assert!(m1 != m2);
-
-        m2.insert(3, 4);
-
-        assert_eq!(m1, m2);
-    }
-
-    #[test]
-    fn test_show() {
-        let mut map = HashMap::new();
-        let empty: HashMap<i32, i32> = HashMap::new();
-
-        map.insert(1, 2);
-        map.insert(3, 4);
-
-        let map_str = format!("{:?}", map);
-
-        assert!(map_str == "HashMap {1: 2, 3: 4}" ||
-                map_str == "HashMap {3: 4, 1: 2}");
-        assert_eq!(format!("{:?}", empty), "HashMap {}");
-    }
-
-    #[test]
-    fn test_expand() {
-        let mut m = HashMap::new();
-
-        assert_eq!(m.len(), 0);
-        assert!(m.is_empty());
-
-        let mut i = 0;
-        let old_cap = m.table.capacity();
-        while old_cap == m.table.capacity() {
-            m.insert(i, i);
-            i += 1;
-        }
-
-        assert_eq!(m.len(), i);
-        assert!(!m.is_empty());
-    }
-
-    #[test]
-    fn test_behavior_resize_policy() {
-        let mut m = HashMap::new();
-
-        assert_eq!(m.len(), 0);
-        assert_eq!(m.table.capacity(), 0);
-        assert!(m.is_empty());
-
-        m.insert(0, 0);
-        m.remove(&0);
-        assert!(m.is_empty());
-        let initial_cap = m.table.capacity();
-        m.reserve(initial_cap);
-        let cap = m.table.capacity();
-
-        assert_eq!(cap, initial_cap * 2);
-
-        let mut i = 0;
-        for _ in 0..cap * 3 / 4 {
-            m.insert(i, i);
-            i += 1;
-        }
-        // three quarters full
-
-        assert_eq!(m.len(), i);
-        assert_eq!(m.table.capacity(), cap);
-
-        for _ in 0..cap / 4 {
-            m.insert(i, i);
-            i += 1;
-        }
-        // half full
-
-        let new_cap = m.table.capacity();
-        assert_eq!(new_cap, cap * 2);
-
-        for _ in 0..cap / 2 - 1 {
-            i -= 1;
-            m.remove(&i);
-            assert_eq!(m.table.capacity(), new_cap);
-        }
-        // A little more than one quarter full.
-        m.shrink_to_fit();
-        assert_eq!(m.table.capacity(), cap);
-        // again, a little more than half full
-        for _ in 0..cap / 2 - 1 {
-            i -= 1;
-            m.remove(&i);
-        }
-        m.shrink_to_fit();
-
-        assert_eq!(m.len(), i);
-        assert!(!m.is_empty());
-        assert_eq!(m.table.capacity(), initial_cap);
-    }
-
-    #[test]
-    fn test_reserve_shrink_to_fit() {
-        let mut m = HashMap::new();
-        m.insert(0, 0);
-        m.remove(&0);
-        assert!(m.capacity() >= m.len());
-        for i in 0..128 {
-            m.insert(i, i);
-        }
-        m.reserve(256);
-
-        let usable_cap = m.capacity();
-        for i in 128..(128 + 256) {
-            m.insert(i, i);
-            assert_eq!(m.capacity(), usable_cap);
-        }
-
-        for i in 100..(128 + 256) {
-            assert_eq!(m.remove(&i), Some(i));
-        }
-        m.shrink_to_fit();
-
-        assert_eq!(m.len(), 100);
-        assert!(!m.is_empty());
-        assert!(m.capacity() >= m.len());
-
-        for i in 0..100 {
-            assert_eq!(m.remove(&i), Some(i));
-        }
-        m.shrink_to_fit();
-        m.insert(0, 0);
-
-        assert_eq!(m.len(), 1);
-        assert!(m.capacity() >= m.len());
-        assert_eq!(m.remove(&0), Some(0));
-    }
-
-    #[test]
-    fn test_from_iter() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let map: HashMap<_, _> = xs.iter().cloned().collect();
-
-        for &(k, v) in &xs {
-            assert_eq!(map.get(&k), Some(&v));
-        }
-    }
-
-    #[test]
-    fn test_size_hint() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let map: HashMap<_, _>  = xs.iter().cloned().collect();
-
-        let mut iter = map.iter();
-
-        for _ in iter.by_ref().take(3) {}
-
-        assert_eq!(iter.size_hint(), (3, Some(3)));
-    }
-
-    #[test]
-    fn test_iter_len() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let map: HashMap<_, _>  = xs.iter().cloned().collect();
-
-        let mut iter = map.iter();
-
-        for _ in iter.by_ref().take(3) {}
-
-        assert_eq!(iter.len(), 3);
-    }
-
-    #[test]
-    fn test_mut_size_hint() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let mut map: HashMap<_, _>  = xs.iter().cloned().collect();
-
-        let mut iter = map.iter_mut();
-
-        for _ in iter.by_ref().take(3) {}
-
-        assert_eq!(iter.size_hint(), (3, Some(3)));
-    }
-
-    #[test]
-    fn test_iter_mut_len() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let mut map: HashMap<_, _>  = xs.iter().cloned().collect();
-
-        let mut iter = map.iter_mut();
-
-        for _ in iter.by_ref().take(3) {}
-
-        assert_eq!(iter.len(), 3);
-    }
-
-    #[test]
-    fn test_index() {
-        let mut map = HashMap::new();
-
-        map.insert(1, 2);
-        map.insert(2, 1);
-        map.insert(3, 4);
-
-        assert_eq!(map[2], 1);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_index_nonexistent() {
-        let mut map = HashMap::new();
-
-        map.insert(1, 2);
-        map.insert(2, 1);
-        map.insert(3, 4);
-
-        map[4];
-    }
-
-    #[test]
-    fn test_entry(){
-        let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
-
-        let mut map: HashMap<_, _> = xs.iter().cloned().collect();
-
-        // Existing key (insert)
-        match map.entry(1) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                assert_eq!(view.get(), &10);
-                assert_eq!(view.insert(100), 10);
-            }
-        }
-        assert_eq!(map.get(&1).unwrap(), &100);
-        assert_eq!(map.len(), 6);
-
-
-        // Existing key (update)
-        match map.entry(2) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                let v = view.get_mut();
-                let new_v = (*v) * 10;
-                *v = new_v;
-            }
-        }
-        assert_eq!(map.get(&2).unwrap(), &200);
-        assert_eq!(map.len(), 6);
-
-        // Existing key (take)
-        match map.entry(3) {
-            Vacant(_) => unreachable!(),
-            Occupied(view) => {
-                assert_eq!(view.remove(), 30);
-            }
-        }
-        assert_eq!(map.get(&3), None);
-        assert_eq!(map.len(), 5);
-
-
-        // Inexistent key (insert)
-        match map.entry(10) {
-            Occupied(_) => unreachable!(),
-            Vacant(view) => {
-                assert_eq!(*view.insert(1000), 1000);
-            }
-        }
-        assert_eq!(map.get(&10).unwrap(), &1000);
-        assert_eq!(map.len(), 6);
-    }
-
-    #[test]
-    fn test_entry_take_doesnt_corrupt() {
-        // Test for #19292
-        fn check(m: &HashMap<isize, ()>) {
-            for k in m.keys() {
-                assert!(m.contains_key(k),
-                        "{} is in keys() but not in the map?", k);
-            }
-        }
-
-        let mut m = HashMap::new();
-        let mut rng = weak_rng();
-
-        // Populate the map with some items.
-        for _ in 0..50 {
-            let x = rng.gen_range(-10, 10);
-            m.insert(x, ());
-        }
-
-        for i in 0..1000 {
-            let x = rng.gen_range(-10, 10);
-            match m.entry(x) {
-                Vacant(_) => {},
-                Occupied(e) => {
-                    println!("{}: remove {}", i, x);
-                    e.remove();
-                },
-            }
-
-            check(&m);
-        }
-    }
-}
index 39c1458b720019cd84f52245f7e7204f085cfe88..47e300af26981da7cd395a6b361bf63704358cb6 100644 (file)
 
 mod bench;
 mod table;
-#[cfg(stage0)]
-#[path = "map_stage0.rs"]
 pub mod map;
-#[cfg(not(stage0))]
-pub mod map;
-#[cfg(stage0)]
-#[path = "set_stage0.rs"]
-pub mod set;
-#[cfg(not(stage0))]
 pub mod set;
 pub mod state;
index e0631a64d44b127048402f0667195daed7e4ffc6..5fbc21797ab5a0442d82ebd5fc2254f54219b9fb 100644 (file)
@@ -18,9 +18,7 @@ use default::Default;
 use fmt::Debug;
 use fmt;
 use hash::Hash;
-use iter::{
-    Iterator, IntoIterator, ExactSizeIterator, IteratorExt, FromIterator, Map, Chain, Extend,
-};
+use iter::{Iterator, IntoIterator, ExactSizeIterator, FromIterator, Map, Chain, Extend};
 use ops::{BitOr, BitAnd, BitXor, Sub};
 use option::Option::{Some, None, self};
 
@@ -36,9 +34,24 @@ use super::state::HashState;
 
 /// An implementation of a hash set using the underlying representation of a
 /// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
-/// requires that the elements implement the `Eq` and `Hash` traits.
+/// requires that the elements implement the `Eq` and `Hash` traits. This can
+/// frequently be achieved by using `#[derive(Eq, Hash)]`. If you implement
+/// these yourself, it is important that the following property holds:
+///
+/// ```text
+/// k1 == k2 -> hash(k1) == hash(k2)
+/// ```
+///
+/// In other words, if two keys are equal, their hashes must be equal.
 ///
-/// # Example
+///
+/// It is a logic error for an item to be modified in such a way that the
+/// item's hash, as determined by the `Hash` trait, or its equality, as
+/// determined by the `Eq` trait, changes while it is in the set. This is
+/// normally only possible through `Cell`, `RefCell`, global state, I/O, or
+/// unsafe code.
+///
+/// # Examples
 ///
 /// ```
 /// use std::collections::HashSet;
@@ -100,7 +113,7 @@ pub struct HashSet<T, S = RandomState> {
 impl<T: Hash + Eq> HashSet<T, RandomState> {
     /// Create an empty HashSet.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashSet;
@@ -115,7 +128,7 @@ impl<T: Hash + Eq> HashSet<T, RandomState> {
     /// Create an empty HashSet with space for at least `n` elements in
     /// the hash table.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashSet;
@@ -136,9 +149,10 @@ impl<T, S> HashSet<T, S>
     ///
     /// The hash set is also created with the default initial capacity.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::collections::HashSet;
     /// use std::collections::hash_map::RandomState;
     ///
@@ -160,9 +174,10 @@ impl<T, S> HashSet<T, S>
     /// cause many collisions and very poor performance. Setting it
     /// manually using this function can expose a DoS attack vector.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::collections::HashSet;
     /// use std::collections::hash_map::RandomState;
     ///
@@ -181,7 +196,7 @@ impl<T, S> HashSet<T, S>
 
     /// Returns the number of elements the set can hold without reallocating.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashSet;
@@ -202,7 +217,7 @@ impl<T, S> HashSet<T, S>
     ///
     /// Panics if the new allocation size overflows `usize`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashSet;
@@ -218,7 +233,7 @@ impl<T, S> HashSet<T, S>
     /// down as much as possible while maintaining the internal rules
     /// and possibly leaving some space in accordance with the resize policy.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashSet;
@@ -238,7 +253,7 @@ impl<T, S> HashSet<T, S>
     /// An iterator visiting all elements in arbitrary order.
     /// Iterator element type is &'a T.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashSet;
@@ -260,7 +275,7 @@ impl<T, S> HashSet<T, S>
     /// of the set in arbitrary order. The set cannot be used after calling
     /// this.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashSet;
@@ -286,9 +301,10 @@ impl<T, S> HashSet<T, S>
 
     /// Visit the values representing the difference.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::HashSet;
     /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
     /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
@@ -316,9 +332,10 @@ impl<T, S> HashSet<T, S>
 
     /// Visit the values representing the symmetric difference.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::HashSet;
     /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
     /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
@@ -342,9 +359,10 @@ impl<T, S> HashSet<T, S>
 
     /// Visit the values representing the intersection.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::HashSet;
     /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
     /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
@@ -367,9 +385,10 @@ impl<T, S> HashSet<T, S>
 
     /// Visit the values representing the union.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::HashSet;
     /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
     /// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
@@ -389,7 +408,7 @@ impl<T, S> HashSet<T, S>
 
     /// Return the number of elements in the set
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashSet;
@@ -404,7 +423,7 @@ impl<T, S> HashSet<T, S>
 
     /// Returns true if the set contains no elements
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashSet;
@@ -430,7 +449,7 @@ impl<T, S> HashSet<T, S>
 
     /// Clears the set, removing all values.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashSet;
@@ -449,9 +468,10 @@ impl<T, S> HashSet<T, S>
     /// `Hash` and `Eq` on the borrowed form *must* match those for
     /// the value type.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::HashSet;
     ///
     /// let set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
@@ -468,9 +488,10 @@ impl<T, S> HashSet<T, S>
     /// Returns `true` if the set has no elements in common with `other`.
     /// This is equivalent to checking for an empty intersection.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::HashSet;
     ///
     /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
@@ -489,9 +510,10 @@ impl<T, S> HashSet<T, S>
 
     /// Returns `true` if the set is a subset of another.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::HashSet;
     ///
     /// let sup: HashSet<_> = [1, 2, 3].iter().cloned().collect();
@@ -510,9 +532,10 @@ impl<T, S> HashSet<T, S>
 
     /// Returns `true` if the set is a superset of another.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::collections::HashSet;
     ///
     /// let sub: HashSet<_> = [1, 2].iter().cloned().collect();
@@ -536,7 +559,7 @@ impl<T, S> HashSet<T, S>
     /// Adds a value to the set. Returns `true` if the value was not already
     /// present in the set.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashSet;
@@ -557,7 +580,7 @@ impl<T, S> HashSet<T, S>
     /// `Hash` and `Eq` on the borrowed form *must* match those for
     /// the value type.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::collections::HashSet;
@@ -598,14 +621,7 @@ impl<T, S> fmt::Debug for HashSet<T, S>
           S: HashState
 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "HashSet {{"));
-
-        for (i, x) in self.iter().enumerate() {
-            if i != 0 { try!(write!(f, ", ")); }
-            try!(write!(f, "{:?}", *x));
-        }
-
-        write!(f, "}}")
+        self.iter().fold(f.debug_set(), |b, e| b.entry(e)).finish()
     }
 }
 
@@ -847,6 +863,9 @@ impl<T, S> IntoIterator for HashSet<T, S>
     }
 }
 
+impl<'a, K> Clone for Iter<'a, K> {
+    fn clone(&self) -> Iter<'a, K> { Iter { iter: self.iter.clone() } }
+}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, K> Iterator for Iter<'a, K> {
     type Item = &'a K;
@@ -883,6 +902,12 @@ impl<'a, K> ExactSizeIterator for Drain<'a, K> {
     fn len(&self) -> usize { self.iter.len() }
 }
 
+impl<'a, T, S> Clone for Intersection<'a, T, S> {
+    fn clone(&self) -> Intersection<'a, T, S> {
+        Intersection { iter: self.iter.clone(), ..*self }
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T, S> Iterator for Intersection<'a, T, S>
     where T: Eq + Hash, S: HashState
@@ -906,6 +931,12 @@ impl<'a, T, S> Iterator for Intersection<'a, T, S>
     }
 }
 
+impl<'a, T, S> Clone for Difference<'a, T, S> {
+    fn clone(&self) -> Difference<'a, T, S> {
+        Difference { iter: self.iter.clone(), ..*self }
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T, S> Iterator for Difference<'a, T, S>
     where T: Eq + Hash, S: HashState
@@ -929,6 +960,12 @@ impl<'a, T, S> Iterator for Difference<'a, T, S>
     }
 }
 
+impl<'a, T, S> Clone for SymmetricDifference<'a, T, S> {
+    fn clone(&self) -> SymmetricDifference<'a, T, S> {
+        SymmetricDifference { iter: self.iter.clone() }
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S>
     where T: Eq + Hash, S: HashState
@@ -939,6 +976,10 @@ impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S>
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
 }
 
+impl<'a, T, S> Clone for Union<'a, T, S> {
+    fn clone(&self) -> Union<'a, T, S> { Union { iter: self.iter.clone() } }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T, S> Iterator for Union<'a, T, S>
     where T: Eq + Hash, S: HashState
@@ -1151,7 +1192,7 @@ mod test_set {
         };
 
         let v = hs.into_iter().collect::<Vec<char>>();
-        assert!(['a', 'b'] == v || ['b', 'a'] == v);
+        assert!(v == ['a', 'b'] || v == ['b', 'a']);
     }
 
     #[test]
@@ -1186,8 +1227,8 @@ mod test_set {
 
         let set_str = format!("{:?}", set);
 
-        assert!(set_str == "HashSet {1, 2}" || set_str == "HashSet {2, 1}");
-        assert_eq!(format!("{:?}", empty), "HashSet {}");
+        assert!(set_str == "{1, 2}" || set_str == "{2, 1}");
+        assert_eq!(format!("{:?}", empty), "{}");
     }
 
     #[test]
diff --git a/src/libstd/collections/hash/set_stage0.rs b/src/libstd/collections/hash/set_stage0.rs
deleted file mode 100644 (file)
index 68c9e02..0000000
+++ /dev/null
@@ -1,1252 +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.
-//
-// ignore-lexer-test FIXME #15883
-
-use borrow::Borrow;
-use clone::Clone;
-use cmp::{Eq, PartialEq};
-use core::marker::Sized;
-use default::Default;
-use fmt::Debug;
-use fmt;
-use hash::{self, Hash};
-use iter::{
-    Iterator, IntoIterator, ExactSizeIterator, IteratorExt, FromIterator, Map, Chain, Extend,
-};
-use ops::{BitOr, BitAnd, BitXor, Sub};
-use option::Option::{Some, None, self};
-
-use super::map::{self, HashMap, Keys, INITIAL_CAPACITY, RandomState, Hasher};
-use super::state::HashState;
-
-// Future Optimization (FIXME!)
-// =============================
-//
-// Iteration over zero sized values is a noop. There is no need
-// for `bucket.val` in the case of HashSet. I suppose we would need HKT
-// to get rid of it properly.
-
-/// An implementation of a hash set using the underlying representation of a
-/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
-/// requires that the elements implement the `Eq` and `Hash` traits.
-///
-/// # Example
-///
-/// ```
-/// use std::collections::HashSet;
-/// // Type inference lets us omit an explicit type signature (which
-/// // would be `HashSet<&str>` in this example).
-/// let mut books = HashSet::new();
-///
-/// // Add some books.
-/// books.insert("A Dance With Dragons");
-/// books.insert("To Kill a Mockingbird");
-/// books.insert("The Odyssey");
-/// books.insert("The Great Gatsby");
-///
-/// // Check for a specific one.
-/// if !books.contains(&("The Winds of Winter")) {
-///     println!("We have {} books, but The Winds of Winter ain't one.",
-///              books.len());
-/// }
-///
-/// // Remove a book.
-/// books.remove(&"The Odyssey");
-///
-/// // Iterate over everything.
-/// for book in books.iter() {
-///     println!("{}", *book);
-/// }
-/// ```
-///
-/// The easiest way to use `HashSet` with a custom type is to derive
-/// `Eq` and `Hash`. We must also derive `PartialEq`, this will in the
-/// future be implied by `Eq`.
-///
-/// ```
-/// use std::collections::HashSet;
-/// #[derive(Hash, Eq, PartialEq, Debug)]
-/// struct Viking<'a> {
-///     name: &'a str,
-///     power: usize,
-/// }
-///
-/// let mut vikings = HashSet::new();
-///
-/// vikings.insert(Viking { name: "Einar", power: 9 });
-/// vikings.insert(Viking { name: "Einar", power: 9 });
-/// vikings.insert(Viking { name: "Olaf", power: 4 });
-/// vikings.insert(Viking { name: "Harald", power: 8 });
-///
-/// // Use derived implementation to print the vikings.
-/// for x in vikings.iter() {
-///     println!("{:?}", x);
-/// }
-/// ```
-#[derive(Clone)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct HashSet<T, S = RandomState> {
-    map: HashMap<T, (), S>
-}
-
-impl<T: Hash<Hasher> + Eq> HashSet<T, RandomState> {
-    /// Create an empty HashSet.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// let mut set: HashSet<int> = HashSet::new();
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> HashSet<T, RandomState> {
-        HashSet::with_capacity(INITIAL_CAPACITY)
-    }
-
-    /// Create an empty HashSet with space for at least `n` elements in
-    /// the hash table.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// let mut set: HashSet<int> = HashSet::with_capacity(10);
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> {
-        HashSet { map: HashMap::with_capacity(capacity) }
-    }
-}
-
-impl<T, S, H> HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    /// Creates a new empty hash set which will use the given hasher to hash
-    /// keys.
-    ///
-    /// The hash set is also created with the default initial capacity.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// use std::collections::hash_map::RandomState;
-    ///
-    /// let s = RandomState::new();
-    /// let mut set = HashSet::with_hash_state(s);
-    /// set.insert(2);
-    /// ```
-    #[inline]
-    #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")]
-    pub fn with_hash_state(hash_state: S) -> HashSet<T, S> {
-        HashSet::with_capacity_and_hash_state(INITIAL_CAPACITY, hash_state)
-    }
-
-    /// Create an empty HashSet with space for at least `capacity`
-    /// elements in the hash table, using `hasher` to hash the keys.
-    ///
-    /// Warning: `hasher` is normally randomly generated, and
-    /// is designed to allow `HashSet`s to be resistant to attacks that
-    /// cause many collisions and very poor performance. Setting it
-    /// manually using this function can expose a DoS attack vector.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// use std::collections::hash_map::RandomState;
-    ///
-    /// let s = RandomState::new();
-    /// let mut set = HashSet::with_capacity_and_hash_state(10, s);
-    /// set.insert(1);
-    /// ```
-    #[inline]
-    #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")]
-    pub fn with_capacity_and_hash_state(capacity: usize, hash_state: S)
-                                        -> HashSet<T, S> {
-        HashSet {
-            map: HashMap::with_capacity_and_hash_state(capacity, hash_state),
-        }
-    }
-
-    /// Returns the number of elements the set can hold without reallocating.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// let set: HashSet<int> = HashSet::with_capacity(100);
-    /// assert!(set.capacity() >= 100);
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn capacity(&self) -> usize {
-        self.map.capacity()
-    }
-
-    /// Reserves capacity for at least `additional` more elements to be inserted
-    /// in the `HashSet`. The collection may reserve more space to avoid
-    /// frequent reallocations.
-    ///
-    /// # Panics
-    ///
-    /// Panics if the new allocation size overflows `usize`.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// let mut set: HashSet<int> = HashSet::new();
-    /// set.reserve(10);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn reserve(&mut self, additional: usize) {
-        self.map.reserve(additional)
-    }
-
-    /// Shrinks the capacity of the set as much as possible. It will drop
-    /// down as much as possible while maintaining the internal rules
-    /// and possibly leaving some space in accordance with the resize policy.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let mut set: HashSet<int> = HashSet::with_capacity(100);
-    /// set.insert(1);
-    /// set.insert(2);
-    /// assert!(set.capacity() >= 100);
-    /// set.shrink_to_fit();
-    /// assert!(set.capacity() >= 2);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn shrink_to_fit(&mut self) {
-        self.map.shrink_to_fit()
-    }
-
-    /// An iterator visiting all elements in arbitrary order.
-    /// Iterator element type is &'a T.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// let mut set = HashSet::new();
-    /// set.insert("a");
-    /// set.insert("b");
-    ///
-    /// // Will print in an arbitrary order.
-    /// for x in set.iter() {
-    ///     println!("{}", x);
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn iter(&self) -> Iter<T> {
-        Iter { iter: self.map.keys() }
-    }
-
-    /// Creates a consuming iterator, that is, one that moves each value out
-    /// of the set in arbitrary order. The set cannot be used after calling
-    /// this.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// let mut set = HashSet::new();
-    /// set.insert("a".to_string());
-    /// set.insert("b".to_string());
-    ///
-    /// // Not possible to collect to a Vec<String> with a regular `.iter()`.
-    /// let v: Vec<String> = set.into_iter().collect();
-    ///
-    /// // Will print in an arbitrary order.
-    /// for x in v.iter() {
-    ///     println!("{}", x);
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_iter(self) -> IntoIter<T> {
-        fn first<A, B>((a, _): (A, B)) -> A { a }
-        let first: fn((T, ())) -> T = first;
-
-        IntoIter { iter: self.map.into_iter().map(first) }
-    }
-
-    /// Visit the values representing the difference.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// let a: HashSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
-    /// let b: HashSet<int> = [4, 2, 3, 4].iter().map(|&x| x).collect();
-    ///
-    /// // Can be seen as `a - b`.
-    /// for x in a.difference(&b) {
-    ///     println!("{}", x); // Print 1
-    /// }
-    ///
-    /// let diff: HashSet<int> = a.difference(&b).map(|&x| x).collect();
-    /// assert_eq!(diff, [1].iter().map(|&x| x).collect());
-    ///
-    /// // Note that difference is not symmetric,
-    /// // and `b - a` means something else:
-    /// let diff: HashSet<int> = b.difference(&a).map(|&x| x).collect();
-    /// assert_eq!(diff, [4].iter().map(|&x| x).collect());
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn difference<'a>(&'a self, other: &'a HashSet<T, S>) -> Difference<'a, T, S> {
-        Difference {
-            iter: self.iter(),
-            other: other,
-        }
-    }
-
-    /// Visit the values representing the symmetric difference.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// let a: HashSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
-    /// let b: HashSet<int> = [4, 2, 3, 4].iter().map(|&x| x).collect();
-    ///
-    /// // Print 1, 4 in arbitrary order.
-    /// for x in a.symmetric_difference(&b) {
-    ///     println!("{}", x);
-    /// }
-    ///
-    /// let diff1: HashSet<int> = a.symmetric_difference(&b).map(|&x| x).collect();
-    /// let diff2: HashSet<int> = b.symmetric_difference(&a).map(|&x| x).collect();
-    ///
-    /// assert_eq!(diff1, diff2);
-    /// assert_eq!(diff1, [1, 4].iter().map(|&x| x).collect());
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, S>)
-        -> SymmetricDifference<'a, T, S> {
-        SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) }
-    }
-
-    /// Visit the values representing the intersection.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// let a: HashSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
-    /// let b: HashSet<int> = [4, 2, 3, 4].iter().map(|&x| x).collect();
-    ///
-    /// // Print 2, 3 in arbitrary order.
-    /// for x in a.intersection(&b) {
-    ///     println!("{}", x);
-    /// }
-    ///
-    /// let diff: HashSet<int> = a.intersection(&b).map(|&x| x).collect();
-    /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect());
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S>) -> Intersection<'a, T, S> {
-        Intersection {
-            iter: self.iter(),
-            other: other,
-        }
-    }
-
-    /// Visit the values representing the union.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    /// let a: HashSet<int> = [1, 2, 3].iter().map(|&x| x).collect();
-    /// let b: HashSet<int> = [4, 2, 3, 4].iter().map(|&x| x).collect();
-    ///
-    /// // Print 1, 2, 3, 4 in arbitrary order.
-    /// for x in a.union(&b) {
-    ///     println!("{}", x);
-    /// }
-    ///
-    /// let diff: HashSet<int> = a.union(&b).map(|&x| x).collect();
-    /// assert_eq!(diff, [1, 2, 3, 4].iter().map(|&x| x).collect());
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> {
-        Union { iter: self.iter().chain(other.difference(self)) }
-    }
-
-    /// Return the number of elements in the set
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let mut v = HashSet::new();
-    /// assert_eq!(v.len(), 0);
-    /// v.insert(1);
-    /// assert_eq!(v.len(), 1);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn len(&self) -> usize { self.map.len() }
-
-    /// Returns true if the set contains no elements
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let mut v = HashSet::new();
-    /// assert!(v.is_empty());
-    /// v.insert(1);
-    /// assert!(!v.is_empty());
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_empty(&self) -> bool { self.map.len() == 0 }
-
-    /// Clears the set, returning all elements in an iterator.
-    #[inline]
-    #[unstable(feature = "std_misc",
-               reason = "matches collection reform specification, waiting for dust to settle")]
-    pub fn drain(&mut self) -> Drain<T> {
-        fn first<A, B>((a, _): (A, B)) -> A { a }
-        let first: fn((T, ())) -> T = first; // coerce to fn pointer
-
-        Drain { iter: self.map.drain().map(first) }
-    }
-
-    /// Clears the set, removing all values.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let mut v = HashSet::new();
-    /// v.insert(1);
-    /// v.clear();
-    /// assert!(v.is_empty());
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn clear(&mut self) { self.map.clear() }
-
-    /// Returns `true` if the set contains a value.
-    ///
-    /// The value may be any borrowed form of the set's value type, but
-    /// `Hash` and `Eq` on the borrowed form *must* match those for
-    /// the value type.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
-    /// assert_eq!(set.contains(&1), true);
-    /// assert_eq!(set.contains(&4), false);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
-        where T: Borrow<Q>, Q: Hash<H> + Eq
-    {
-        self.map.contains_key(value)
-    }
-
-    /// Returns `true` if the set has no elements in common with `other`.
-    /// This is equivalent to checking for an empty intersection.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let a: HashSet<_> = [1, 2, 3].iter().cloned().collect();
-    /// let mut b = HashSet::new();
-    ///
-    /// assert_eq!(a.is_disjoint(&b), true);
-    /// b.insert(4);
-    /// assert_eq!(a.is_disjoint(&b), true);
-    /// b.insert(1);
-    /// assert_eq!(a.is_disjoint(&b), false);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_disjoint(&self, other: &HashSet<T, S>) -> bool {
-        self.iter().all(|v| !other.contains(v))
-    }
-
-    /// Returns `true` if the set is a subset of another.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let sup: HashSet<_> = [1, 2, 3].iter().cloned().collect();
-    /// let mut set = HashSet::new();
-    ///
-    /// assert_eq!(set.is_subset(&sup), true);
-    /// set.insert(2);
-    /// assert_eq!(set.is_subset(&sup), true);
-    /// set.insert(4);
-    /// assert_eq!(set.is_subset(&sup), false);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_subset(&self, other: &HashSet<T, S>) -> bool {
-        self.iter().all(|v| other.contains(v))
-    }
-
-    /// Returns `true` if the set is a superset of another.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let sub: HashSet<_> = [1, 2].iter().cloned().collect();
-    /// let mut set = HashSet::new();
-    ///
-    /// assert_eq!(set.is_superset(&sub), false);
-    ///
-    /// set.insert(0);
-    /// set.insert(1);
-    /// assert_eq!(set.is_superset(&sub), false);
-    ///
-    /// set.insert(2);
-    /// assert_eq!(set.is_superset(&sub), true);
-    /// ```
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_superset(&self, other: &HashSet<T, S>) -> bool {
-        other.is_subset(self)
-    }
-
-    /// Adds a value to the set. Returns `true` if the value was not already
-    /// present in the set.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let mut set = HashSet::new();
-    ///
-    /// assert_eq!(set.insert(2), true);
-    /// assert_eq!(set.insert(2), false);
-    /// assert_eq!(set.len(), 1);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() }
-
-    /// Removes a value from the set. Returns `true` if the value was
-    /// present in the set.
-    ///
-    /// The value may be any borrowed form of the set's value type, but
-    /// `Hash` and `Eq` on the borrowed form *must* match those for
-    /// the value type.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let mut set = HashSet::new();
-    ///
-    /// set.insert(2);
-    /// assert_eq!(set.remove(&2), true);
-    /// assert_eq!(set.remove(&2), false);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
-        where T: Borrow<Q>, Q: Hash<H> + Eq
-    {
-        self.map.remove(value).is_some()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> PartialEq for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    fn eq(&self, other: &HashSet<T, S>) -> bool {
-        if self.len() != other.len() { return false; }
-
-        self.iter().all(|key| other.contains(key))
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> Eq for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> fmt::Debug for HashSet<T, S>
-    where T: Eq + Hash<H> + fmt::Debug,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "HashSet {{"));
-
-        for (i, x) in self.iter().enumerate() {
-            if i != 0 { try!(write!(f, ", ")); }
-            try!(write!(f, "{:?}", *x));
-        }
-
-        write!(f, "}}")
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> FromIterator<T> for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
-{
-    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> HashSet<T, S> {
-        let iter = iter.into_iter();
-        let lower = iter.size_hint().0;
-        let mut set = HashSet::with_capacity_and_hash_state(lower, Default::default());
-        set.extend(iter);
-        set
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> Extend<T> for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) {
-        for k in iter {
-            self.insert(k);
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, S, H> Default for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
-{
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn default() -> HashSet<T, S> {
-        HashSet::with_hash_state(Default::default())
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b, T, S, H> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S>
-    where T: Eq + Hash<H> + Clone,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
-{
-    type Output = HashSet<T, S>;
-
-    /// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
-    /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
-    ///
-    /// let set = &a | &b;
-    ///
-    /// let mut i = 0;
-    /// let expected = [1, 2, 3, 4, 5];
-    /// for x in set.iter() {
-    ///     assert!(expected.contains(x));
-    ///     i += 1;
-    /// }
-    /// assert_eq!(i, expected.len());
-    /// ```
-    fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
-        self.union(rhs).cloned().collect()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b, T, S, H> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S>
-    where T: Eq + Hash<H> + Clone,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
-{
-    type Output = HashSet<T, S>;
-
-    /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
-    /// let b: HashSet<_> = vec![2, 3, 4].into_iter().collect();
-    ///
-    /// let set = &a & &b;
-    ///
-    /// let mut i = 0;
-    /// let expected = [2, 3];
-    /// for x in set.iter() {
-    ///     assert!(expected.contains(x));
-    ///     i += 1;
-    /// }
-    /// assert_eq!(i, expected.len());
-    /// ```
-    fn bitand(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
-        self.intersection(rhs).cloned().collect()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b, T, S, H> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S>
-    where T: Eq + Hash<H> + Clone,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
-{
-    type Output = HashSet<T, S>;
-
-    /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
-    /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
-    ///
-    /// let set = &a ^ &b;
-    ///
-    /// let mut i = 0;
-    /// let expected = [1, 2, 4, 5];
-    /// for x in set.iter() {
-    ///     assert!(expected.contains(x));
-    ///     i += 1;
-    /// }
-    /// assert_eq!(i, expected.len());
-    /// ```
-    fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
-        self.symmetric_difference(rhs).cloned().collect()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b, T, S, H> Sub<&'b HashSet<T, S>> for &'a HashSet<T, S>
-    where T: Eq + Hash<H> + Clone,
-          S: HashState<Hasher=H> + Default,
-          H: hash::Hasher<Output=u64>
-{
-    type Output = HashSet<T, S>;
-
-    /// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
-    /// let b: HashSet<_> = vec![3, 4, 5].into_iter().collect();
-    ///
-    /// let set = &a - &b;
-    ///
-    /// let mut i = 0;
-    /// let expected = [1, 2];
-    /// for x in set.iter() {
-    ///     assert!(expected.contains(x));
-    ///     i += 1;
-    /// }
-    /// assert_eq!(i, expected.len());
-    /// ```
-    fn sub(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
-        self.difference(rhs).cloned().collect()
-    }
-}
-
-/// HashSet iterator
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Iter<'a, K: 'a> {
-    iter: Keys<'a, K, ()>
-}
-
-/// HashSet move iterator
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct IntoIter<K> {
-    iter: Map<map::IntoIter<K, ()>, fn((K, ())) -> K>
-}
-
-/// HashSet drain iterator
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Drain<'a, K: 'a> {
-    iter: Map<map::Drain<'a, K, ()>, fn((K, ())) -> K>,
-}
-
-/// Intersection iterator
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Intersection<'a, T: 'a, S: 'a> {
-    // iterator of the first set
-    iter: Iter<'a, T>,
-    // the second set
-    other: &'a HashSet<T, S>,
-}
-
-/// Difference iterator
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Difference<'a, T: 'a, S: 'a> {
-    // iterator of the first set
-    iter: Iter<'a, T>,
-    // the second set
-    other: &'a HashSet<T, S>,
-}
-
-/// Symmetric difference iterator.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct SymmetricDifference<'a, T: 'a, S: 'a> {
-    iter: Chain<Difference<'a, T, S>, Difference<'a, T, S>>
-}
-
-/// Set union iterator.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Union<'a, T: 'a, S: 'a> {
-    iter: Chain<Iter<'a, T>, Difference<'a, T, S>>
-}
-
-impl<'a, T, S, H> IntoIterator for &'a HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    type Item = &'a T;
-    type IntoIter = Iter<'a, T>;
-
-    fn into_iter(self) -> Iter<'a, T> {
-        self.iter()
-    }
-}
-
-impl<T, S, H> IntoIterator for HashSet<T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    type Item = T;
-    type IntoIter = IntoIter<T>;
-
-    fn into_iter(self) -> IntoIter<T> {
-        self.into_iter()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K> Iterator for Iter<'a, K> {
-    type Item = &'a K;
-
-    fn next(&mut self) -> Option<&'a K> { self.iter.next() }
-    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K> ExactSizeIterator for Iter<'a, K> {
-    fn len(&self) -> usize { self.iter.len() }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K> Iterator for IntoIter<K> {
-    type Item = K;
-
-    fn next(&mut self) -> Option<K> { self.iter.next() }
-    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<K> ExactSizeIterator for IntoIter<K> {
-    fn len(&self) -> usize { self.iter.len() }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K> Iterator for Drain<'a, K> {
-    type Item = K;
-
-    fn next(&mut self) -> Option<K> { self.iter.next() }
-    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, K> ExactSizeIterator for Drain<'a, K> {
-    fn len(&self) -> usize { self.iter.len() }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, S, H> Iterator for Intersection<'a, T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    type Item = &'a T;
-
-    fn next(&mut self) -> Option<&'a T> {
-        loop {
-            match self.iter.next() {
-                None => return None,
-                Some(elt) => if self.other.contains(elt) {
-                    return Some(elt)
-                },
-            }
-        }
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let (_, upper) = self.iter.size_hint();
-        (0, upper)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, S, H> Iterator for Difference<'a, T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    type Item = &'a T;
-
-    fn next(&mut self) -> Option<&'a T> {
-        loop {
-            match self.iter.next() {
-                None => return None,
-                Some(elt) => if !self.other.contains(elt) {
-                    return Some(elt)
-                },
-            }
-        }
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let (_, upper) = self.iter.size_hint();
-        (0, upper)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    type Item = &'a T;
-
-    fn next(&mut self) -> Option<&'a T> { self.iter.next() }
-    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, S, H> Iterator for Union<'a, T, S>
-    where T: Eq + Hash<H>,
-          S: HashState<Hasher=H>,
-          H: hash::Hasher<Output=u64>
-{
-    type Item = &'a T;
-
-    fn next(&mut self) -> Option<&'a T> { self.iter.next() }
-    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
-}
-
-#[cfg(test)]
-mod test_set {
-    use prelude::v1::*;
-
-    use super::HashSet;
-
-    #[test]
-    fn test_disjoint() {
-        let mut xs = HashSet::new();
-        let mut ys = HashSet::new();
-        assert!(xs.is_disjoint(&ys));
-        assert!(ys.is_disjoint(&xs));
-        assert!(xs.insert(5));
-        assert!(ys.insert(11));
-        assert!(xs.is_disjoint(&ys));
-        assert!(ys.is_disjoint(&xs));
-        assert!(xs.insert(7));
-        assert!(xs.insert(19));
-        assert!(xs.insert(4));
-        assert!(ys.insert(2));
-        assert!(ys.insert(-11));
-        assert!(xs.is_disjoint(&ys));
-        assert!(ys.is_disjoint(&xs));
-        assert!(ys.insert(7));
-        assert!(!xs.is_disjoint(&ys));
-        assert!(!ys.is_disjoint(&xs));
-    }
-
-    #[test]
-    fn test_subset_and_superset() {
-        let mut a = HashSet::new();
-        assert!(a.insert(0));
-        assert!(a.insert(5));
-        assert!(a.insert(11));
-        assert!(a.insert(7));
-
-        let mut b = HashSet::new();
-        assert!(b.insert(0));
-        assert!(b.insert(7));
-        assert!(b.insert(19));
-        assert!(b.insert(250));
-        assert!(b.insert(11));
-        assert!(b.insert(200));
-
-        assert!(!a.is_subset(&b));
-        assert!(!a.is_superset(&b));
-        assert!(!b.is_subset(&a));
-        assert!(!b.is_superset(&a));
-
-        assert!(b.insert(5));
-
-        assert!(a.is_subset(&b));
-        assert!(!a.is_superset(&b));
-        assert!(!b.is_subset(&a));
-        assert!(b.is_superset(&a));
-    }
-
-    #[test]
-    fn test_iterate() {
-        let mut a = HashSet::new();
-        for i in 0..32 {
-            assert!(a.insert(i));
-        }
-        let mut observed: u32 = 0;
-        for k in &a {
-            observed |= 1 << *k;
-        }
-        assert_eq!(observed, 0xFFFF_FFFF);
-    }
-
-    #[test]
-    fn test_intersection() {
-        let mut a = HashSet::new();
-        let mut b = HashSet::new();
-
-        assert!(a.insert(11));
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(77));
-        assert!(a.insert(103));
-        assert!(a.insert(5));
-        assert!(a.insert(-5));
-
-        assert!(b.insert(2));
-        assert!(b.insert(11));
-        assert!(b.insert(77));
-        assert!(b.insert(-9));
-        assert!(b.insert(-42));
-        assert!(b.insert(5));
-        assert!(b.insert(3));
-
-        let mut i = 0;
-        let expected = [3, 5, 11, 77];
-        for x in a.intersection(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_difference() {
-        let mut a = HashSet::new();
-        let mut b = HashSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(9));
-        assert!(a.insert(11));
-
-        assert!(b.insert(3));
-        assert!(b.insert(9));
-
-        let mut i = 0;
-        let expected = [1, 5, 11];
-        for x in a.difference(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_symmetric_difference() {
-        let mut a = HashSet::new();
-        let mut b = HashSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(9));
-        assert!(a.insert(11));
-
-        assert!(b.insert(-2));
-        assert!(b.insert(3));
-        assert!(b.insert(9));
-        assert!(b.insert(14));
-        assert!(b.insert(22));
-
-        let mut i = 0;
-        let expected = [-2, 1, 5, 11, 14, 22];
-        for x in a.symmetric_difference(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_union() {
-        let mut a = HashSet::new();
-        let mut b = HashSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(9));
-        assert!(a.insert(11));
-        assert!(a.insert(16));
-        assert!(a.insert(19));
-        assert!(a.insert(24));
-
-        assert!(b.insert(-2));
-        assert!(b.insert(1));
-        assert!(b.insert(5));
-        assert!(b.insert(9));
-        assert!(b.insert(13));
-        assert!(b.insert(19));
-
-        let mut i = 0;
-        let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
-        for x in a.union(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_from_iter() {
-        let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
-
-        let set: HashSet<_> = xs.iter().cloned().collect();
-
-        for x in &xs {
-            assert!(set.contains(x));
-        }
-    }
-
-    #[test]
-    fn test_move_iter() {
-        let hs = {
-            let mut hs = HashSet::new();
-
-            hs.insert('a');
-            hs.insert('b');
-
-            hs
-        };
-
-        let v = hs.into_iter().collect::<Vec<char>>();
-        assert!(['a', 'b'] == v || ['b', 'a'] == v);
-    }
-
-    #[test]
-    fn test_eq() {
-        // These constants once happened to expose a bug in insert().
-        // I'm keeping them around to prevent a regression.
-        let mut s1 = HashSet::new();
-
-        s1.insert(1);
-        s1.insert(2);
-        s1.insert(3);
-
-        let mut s2 = HashSet::new();
-
-        s2.insert(1);
-        s2.insert(2);
-
-        assert!(s1 != s2);
-
-        s2.insert(3);
-
-        assert_eq!(s1, s2);
-    }
-
-    #[test]
-    fn test_show() {
-        let mut set = HashSet::new();
-        let empty = HashSet::<i32>::new();
-
-        set.insert(1);
-        set.insert(2);
-
-        let set_str = format!("{:?}", set);
-
-        assert!(set_str == "HashSet {1, 2}" || set_str == "HashSet {2, 1}");
-        assert_eq!(format!("{:?}", empty), "HashSet {}");
-    }
-
-    #[test]
-    fn test_trivial_drain() {
-        let mut s = HashSet::<i32>::new();
-        for _ in s.drain() {}
-        assert!(s.is_empty());
-        drop(s);
-
-        let mut s = HashSet::<i32>::new();
-        drop(s.drain());
-        assert!(s.is_empty());
-    }
-
-    #[test]
-    fn test_drain() {
-        let mut s: HashSet<_> = (1..100).collect();
-
-        // try this a bunch of times to make sure we don't screw up internal state.
-        for _ in 0..20 {
-            assert_eq!(s.len(), 99);
-
-            {
-                let mut last_i = 0;
-                let mut d = s.drain();
-                for (i, x) in d.by_ref().take(50).enumerate() {
-                    last_i = i;
-                    assert!(x != 0);
-                }
-                assert_eq!(last_i, 49);
-            }
-
-            for _ in &s { panic!("s should be empty!"); }
-
-            // reset to try again.
-            s.extend(1..100);
-        }
-    }
-}
index 7e6dd45b51e48f69f553388787dc490f1f843e03..3a06d2d03bf3f7046ec7c74479f9936abb704be8 100644 (file)
@@ -27,6 +27,7 @@ use marker;
 /// to `Default` when asked to create a hasher.
 #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")]
 pub trait HashState {
+    /// Type of the hasher that will be created.
     type Hasher: hash::Hasher;
 
     /// Creates a new hasher based on the given state of this object.
index f301f6db92f96a7bf96d2ee545128212db7c9de7..dec6d1e2209ad9b982f695ce6f06b2efb50ecd32 100644 (file)
@@ -15,19 +15,19 @@ use self::BucketState::*;
 use clone::Clone;
 use cmp;
 use hash::{Hash, Hasher};
-use iter::{Iterator, IteratorExt, ExactSizeIterator, count};
+use iter::{Iterator, ExactSizeIterator};
 use marker::{Copy, Send, Sync, Sized, self};
 use mem::{min_align_of, size_of};
 use mem;
-use num::{Int, UnsignedInt};
+use num::wrapping::{OverflowingOps, WrappingOps};
 use ops::{Deref, DerefMut, Drop};
 use option::Option;
 use option::Option::{Some, None};
-use ptr::{self, PtrExt, copy_nonoverlapping_memory, Unique, zero_memory};
+use ptr::{self, Unique};
 use rt::heap::{allocate, deallocate, EMPTY};
 use collections::hash_state::HashState;
 
-const EMPTY_BUCKET: u64 = 0u64;
+const EMPTY_BUCKET: u64 = 0;
 
 /// The raw hashtable, providing safe-ish access to the unzipped and highly
 /// optimized arrays of hashes, keys, and values.
@@ -87,6 +87,9 @@ struct RawBucket<K, V> {
 }
 
 impl<K,V> Copy for RawBucket<K,V> {}
+impl<K,V> Clone for RawBucket<K,V> {
+    fn clone(&self) -> RawBucket<K, V> { *self }
+}
 
 pub struct Bucket<K, V, M> {
     raw:   RawBucket<K, V>,
@@ -95,6 +98,9 @@ pub struct Bucket<K, V, M> {
 }
 
 impl<K,V,M:Copy> Copy for Bucket<K,V,M> {}
+impl<K,V,M:Copy> Clone for Bucket<K,V,M> {
+    fn clone(&self) -> Bucket<K,V,M> { *self }
+}
 
 pub struct EmptyBucket<K, V, M> {
     raw:   RawBucket<K, V>,
@@ -129,7 +135,7 @@ struct GapThenFull<K, V, M> {
 
 /// A hash that is not zero, since we use a hash of zero to represent empty
 /// buckets.
-#[derive(PartialEq, Copy)]
+#[derive(PartialEq, Copy, Clone)]
 pub struct SafeHash {
     hash: u64,
 }
@@ -143,31 +149,12 @@ impl SafeHash {
 /// We need to remove hashes of 0. That's reserved for empty buckets.
 /// This function wraps up `hash_keyed` to be the only way outside this
 /// module to generate a SafeHash.
-#[cfg(stage0)]
-pub fn make_hash<T: ?Sized, S, H>(hash_state: &S, t: &T) -> SafeHash
-    where T: Hash<H>,
-          S: HashState<Hasher=H>,
-          H: Hasher<Output=u64>
-{
-    let mut state = hash_state.hasher();
-    t.hash(&mut state);
-    // We need to avoid 0u64 in order to prevent collisions with
-    // EMPTY_HASH. We can maintain our precious uniform distribution
-    // of initial indexes by unconditionally setting the MSB,
-    // effectively reducing 64-bits hashes to 63 bits.
-    SafeHash { hash: 0x8000_0000_0000_0000 | state.finish() }
-}
-
-/// We need to remove hashes of 0. That's reserved for empty buckets.
-/// This function wraps up `hash_keyed` to be the only way outside this
-/// module to generate a SafeHash.
-#[cfg(not(stage0))]
 pub fn make_hash<T: ?Sized, S>(hash_state: &S, t: &T) -> SafeHash
     where T: Hash, S: HashState
 {
     let mut state = hash_state.hasher();
     t.hash(&mut state);
-    // We need to avoid 0u64 in order to prevent collisions with
+    // We need to avoid 0 in order to prevent collisions with
     // EMPTY_HASH. We can maintain our precious uniform distribution
     // of initial indexes by unconditionally setting the MSB,
     // effectively reducing 64-bits hashes to 63 bits.
@@ -243,6 +230,9 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> {
     }
 
     pub fn at_index(table: M, ib_index: usize) -> Bucket<K, V, M> {
+        // if capacity is 0, then the RawBucket will be populated with bogus pointers.
+        // This is an uncommon case though, so avoid it in release builds.
+        debug_assert!(table.capacity() > 0, "Table should have capacity at this point");
         let ib_index = ib_index & (table.capacity() - 1);
         Bucket {
             raw: unsafe {
@@ -390,7 +380,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> FullBucket<K, V, M> {
         // Calculates the distance one has to travel when going from
         // `hash mod capacity` onwards to `idx mod capacity`, wrapping around
         // if the destination is not reached before the end of the table.
-        (self.idx - self.hash().inspect() as usize) & (self.table.capacity() - 1)
+        (self.idx.wrapping_sub(self.hash().inspect() as usize)) & (self.table.capacity() - 1)
     }
 
     #[inline]
@@ -496,8 +486,8 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> GapThenFull<K, V, M> {
     pub fn shift(mut self) -> Option<GapThenFull<K, V, M>> {
         unsafe {
             *self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET);
-            copy_nonoverlapping_memory(self.gap.raw.key, self.full.raw.key, 1);
-            copy_nonoverlapping_memory(self.gap.raw.val, self.full.raw.val, 1);
+            ptr::copy_nonoverlapping(self.full.raw.key, self.gap.raw.key, 1);
+            ptr::copy_nonoverlapping(self.full.raw.val, self.gap.raw.val, 1);
         }
 
         let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full;
@@ -543,13 +533,13 @@ fn test_rounding() {
 fn calculate_offsets(hashes_size: usize,
                      keys_size: usize, keys_align: usize,
                      vals_align: usize)
-                     -> (usize, usize) {
+                     -> (usize, usize, bool) {
     let keys_offset = round_up_to_next(hashes_size, keys_align);
-    let end_of_keys = keys_offset + keys_size;
+    let (end_of_keys, oflo) = keys_offset.overflowing_add(keys_size);
 
     let vals_offset = round_up_to_next(end_of_keys, vals_align);
 
-    (keys_offset, vals_offset)
+    (keys_offset, vals_offset, oflo)
 }
 
 // Returns a tuple of (minimum required malloc alignment, hash_offset,
@@ -557,26 +547,26 @@ fn calculate_offsets(hashes_size: usize,
 fn calculate_allocation(hash_size: usize, hash_align: usize,
                         keys_size: usize, keys_align: usize,
                         vals_size: usize, vals_align: usize)
-                        -> (usize, usize, usize) {
+                        -> (usize, usize, usize, bool) {
     let hash_offset = 0;
-    let (_, vals_offset) = calculate_offsets(hash_size,
-                                             keys_size, keys_align,
-                                                        vals_align);
-    let end_of_vals = vals_offset + vals_size;
+    let (_, vals_offset, oflo) = calculate_offsets(hash_size,
+                                                   keys_size, keys_align,
+                                                              vals_align);
+    let (end_of_vals, oflo2) = vals_offset.overflowing_add(vals_size);
 
     let min_align = cmp::max(hash_align, cmp::max(keys_align, vals_align));
 
-    (min_align, hash_offset, end_of_vals)
+    (min_align, hash_offset, end_of_vals, oflo || oflo2)
 }
 
 #[test]
 fn test_offset_calculation() {
-    assert_eq!(calculate_allocation(128, 8, 15, 1, 4,  4), (8, 0, 148));
-    assert_eq!(calculate_allocation(3,   1, 2,  1, 1,  1), (1, 0, 6));
-    assert_eq!(calculate_allocation(6,   2, 12, 4, 24, 8), (8, 0, 48));
-    assert_eq!(calculate_offsets(128, 15, 1, 4), (128, 144));
-    assert_eq!(calculate_offsets(3,   2,  1, 1), (3,   5));
-    assert_eq!(calculate_offsets(6,   12, 4, 8), (8,   24));
+    assert_eq!(calculate_allocation(128, 8, 15, 1, 4,  4), (8, 0, 148, false));
+    assert_eq!(calculate_allocation(3,   1, 2,  1, 1,  1), (1, 0, 6, false));
+    assert_eq!(calculate_allocation(6,   2, 12, 4, 24, 8), (8, 0, 48, false));
+    assert_eq!(calculate_offsets(128, 15, 1, 4), (128, 144, false));
+    assert_eq!(calculate_offsets(3,   2,  1, 1), (3,   5, false));
+    assert_eq!(calculate_offsets(6,   12, 4, 8), (8,   24, false));
 }
 
 impl<K, V> RawTable<K, V> {
@@ -606,12 +596,14 @@ impl<K, V> RawTable<K, V> {
         // This is great in theory, but in practice getting the alignment
         // right is a little subtle. Therefore, calculating offsets has been
         // factored out into a different function.
-        let (malloc_alignment, hash_offset, size) =
+        let (malloc_alignment, hash_offset, size, oflo) =
             calculate_allocation(
                 hashes_size, min_align_of::<u64>(),
                 keys_size,   min_align_of::< K >(),
                 vals_size,   min_align_of::< V >());
 
+        assert!(!oflo, "capacity overflow");
+
         // One check for overflow that covers calculation and rounding of size.
         let size_of_bucket = size_of::<u64>().checked_add(size_of::<K>()).unwrap()
                                              .checked_add(size_of::<V>()).unwrap();
@@ -637,10 +629,11 @@ impl<K, V> RawTable<K, V> {
         let keys_size = self.capacity * size_of::<K>();
 
         let buffer = *self.hashes as *mut u8;
-        let (keys_offset, vals_offset) = calculate_offsets(hashes_size,
-                                                           keys_size, min_align_of::<K>(),
-                                                           min_align_of::<V>());
-
+        let (keys_offset, vals_offset, oflo) =
+            calculate_offsets(hashes_size,
+                              keys_size, min_align_of::<K>(),
+                              min_align_of::<V>());
+        debug_assert!(!oflo, "capacity overflow");
         unsafe {
             RawBucket {
                 hash: *self.hashes,
@@ -656,7 +649,7 @@ impl<K, V> RawTable<K, V> {
     pub fn new(capacity: usize) -> RawTable<K, V> {
         unsafe {
             let ret = RawTable::new_uninitialized(capacity);
-            zero_memory(*ret.hashes, capacity);
+            ptr::write_bytes(*ret.hashes, 0, capacity);
             ret
         }
     }
@@ -998,7 +991,7 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
 #[unsafe_destructor]
 impl<K, V> Drop for RawTable<K, V> {
     fn drop(&mut self) {
-        if self.capacity == 0 {
+        if self.capacity == 0 || self.capacity == mem::POST_DROP_USIZE {
             return;
         }
 
@@ -1014,9 +1007,12 @@ impl<K, V> Drop for RawTable<K, V> {
         let hashes_size = self.capacity * size_of::<u64>();
         let keys_size = self.capacity * size_of::<K>();
         let vals_size = self.capacity * size_of::<V>();
-        let (align, _, size) = calculate_allocation(hashes_size, min_align_of::<u64>(),
-                                                    keys_size, min_align_of::<K>(),
-                                                    vals_size, min_align_of::<V>());
+        let (align, _, size, oflo) =
+            calculate_allocation(hashes_size, min_align_of::<u64>(),
+                                 keys_size, min_align_of::<K>(),
+                                 vals_size, min_align_of::<V>());
+
+        debug_assert!(!oflo, "should be impossible");
 
         unsafe {
             deallocate(*self.hashes as *mut u8, size, align);
index 0e64370df60ecbdc8b24ff51abc1a506ba83b8a2..0ac97b71298b85df6c737c6bec041bb512522544 100644 (file)
@@ -23,9 +23,9 @@
 //!
 //! Rust's collections can be grouped into four major categories:
 //!
-//! * Sequences: `Vec`, `VecDeque`, `LinkedList`, `BitV`
+//! * Sequences: `Vec`, `VecDeque`, `LinkedList`, `BitVec`
 //! * Maps: `HashMap`, `BTreeMap`, `VecMap`
-//! * Sets: `HashSet`, `BTreeSet`, `BitVSet`
+//! * Sets: `HashSet`, `BTreeSet`, `BitSet`
 //! * Misc: `BinaryHeap`
 //!
 //! # When Should You Use Which Collection?
 //! * There is no meaningful value to associate with your keys.
 //! * You just want a set.
 //!
-//! ### Use a `BitV` when:
+//! ### Use a `BitVec` when:
 //! * You want to store an unbounded number of booleans in a small space.
 //! * You want a bit vector.
 //!
-//! ### Use a `BitVSet` when:
-//! * You want a `VecSet`.
+//! ### Use a `BitSet` when:
+//! * You want a `BitVec`, but want `Set` properties
 //!
 //! ### Use a `BinaryHeap` when:
 //! * You want to store a bunch of elements, but only ever want to process the "biggest"
@@ -89,7 +89,8 @@
 //!
 //! Choosing the right collection for the job requires an understanding of what each collection
 //! is good at. Here we briefly summarize the performance of different collections for certain
-//! important operations. For further details, see each type's documentation.
+//! important operations. For further details, see each type's documentation, and note that the
+//! names of actual methods may differ from the tables below on certain collections.
 //!
 //! Throughout the documentation, we will follow a few conventions. For all operations,
 //! the collection's size is denoted by n. If another collection is involved in the operation, it
 //! a variant of the `Entry` enum.
 //!
 //! If a `Vacant(entry)` is yielded, then the key *was not* found. In this case the
-//! only valid operation is to `set` the value of the entry. When this is done,
+//! only valid operation is to `insert` a value into the entry. When this is done,
 //! the vacant entry is consumed and converted into a mutable reference to the
 //! the value that was inserted. This allows for further manipulation of the value
 //! beyond the lifetime of the search itself. This is useful if complex logic needs to
 //! be performed on the value regardless of whether the value was just inserted.
 //!
 //! If an `Occupied(entry)` is yielded, then the key *was* found. In this case, the user
-//! has several options: they can `get`, `set`, or `take` the value of the occupied
+//! has several options: they can `get`, `insert`, or `remove` the value of the occupied
 //! entry. Additionally, they can convert the occupied entry into a mutable reference
-//! to its value, providing symmetry to the vacant `set` case.
+//! to its value, providing symmetry to the vacant `insert` case.
 //!
 //! ### Examples
 //!
 //! #### Counting the number of times each character in a string occurs
 //!
 //! ```
+//! # #![feature(collections)]
 //! use std::collections::btree_map::{BTreeMap, Entry};
 //!
 //! let mut count = BTreeMap::new();
 //! let message = "she sells sea shells by the sea shore";
 //!
 //! for c in message.chars() {
-//!     match count.entry(c) {
-//!         Entry::Vacant(entry) => { entry.insert(1); },
-//!         Entry::Occupied(mut entry) => *entry.get_mut() += 1,
-//!     }
+//!     *count.entry(c).or_insert(0) += 1;
 //! }
 //!
 //! assert_eq!(count.get(&'s'), Some(&8));
 //! #### Tracking the inebriation of customers at a bar
 //!
 //! ```
+//! # #![feature(collections)]
 //! use std::collections::btree_map::{BTreeMap, Entry};
 //!
 //! // A client of the bar. They have an id and a blood alcohol level.
-//! struct Person { id: u32, blood_alcohol: f32 };
+//! struct Person { id: u32, blood_alcohol: f32 }
 //!
 //! // All the orders made to the bar, by client id.
 //! let orders = vec![1,2,1,2,3,4,1,2,2,3,4,1,1,1];
 //! for id in orders.into_iter() {
 //!     // If this is the first time we've seen this customer, initialize them
 //!     // with no blood alcohol. Otherwise, just retrieve them.
-//!     let person = match blood_alcohol.entry(id) {
-//!         Entry::Vacant(entry) => entry.insert(Person{id: id, blood_alcohol: 0.0}),
-//!         Entry::Occupied(entry) => entry.into_mut(),
-//!     };
+//!     let person = blood_alcohol.entry(id).or_insert(Person{id: id, blood_alcohol: 0.0});
 //!
 //!     // Reduce their blood alcohol level. It takes time to order and drink a beer!
 //!     person.blood_alcohol *= 0.9;
index b0fb9c29403511d13e42b274030523c50efbbf67..e76d5460eb0c4218317461061e587fca3de7ddf5 100644 (file)
 
 use prelude::v1::*;
 
-use ffi::CString;
-use mem;
 use env;
-use str;
+use ffi::{CString, OsString};
+use mem;
+use path::{Path, PathBuf};
 
 pub struct DynamicLibrary {
     handle: *mut u8
@@ -51,7 +51,7 @@ impl DynamicLibrary {
     /// Lazily open a dynamic library. When passed None it gives a
     /// handle to the calling process
     pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
-        let maybe_library = dl::open(filename.map(|path| path.as_vec()));
+        let maybe_library = dl::open(filename.map(|path| path.as_os_str()));
 
         // The dynamic library must not be constructed if there is
         // an error opening the library so the destructor does not
@@ -65,19 +65,17 @@ impl DynamicLibrary {
     /// Prepends a path to this process's search path for dynamic libraries
     pub fn prepend_search_path(path: &Path) {
         let mut search_path = DynamicLibrary::search_path();
-        search_path.insert(0, path.clone());
-        let newval = DynamicLibrary::create_path(&search_path);
-        env::set_var(DynamicLibrary::envvar(),
-                     str::from_utf8(&newval).unwrap());
+        search_path.insert(0, path.to_path_buf());
+        env::set_var(DynamicLibrary::envvar(), &DynamicLibrary::create_path(&search_path));
     }
 
     /// From a slice of paths, create a new vector which is suitable to be an
     /// environment variable for this platforms dylib search path.
-    pub fn create_path(path: &[Path]) -> Vec<u8> {
-        let mut newvar = Vec::new();
+    pub fn create_path(path: &[PathBuf]) -> OsString {
+        let mut newvar = OsString::new();
         for (i, path) in path.iter().enumerate() {
             if i > 0 { newvar.push(DynamicLibrary::separator()); }
-            newvar.push_all(path.as_vec());
+            newvar.push(path);
         }
         return newvar;
     }
@@ -94,13 +92,13 @@ impl DynamicLibrary {
         }
     }
 
-    fn separator() -> u8 {
-        if cfg!(windows) {b';'} else {b':'}
+    fn separator() -> &'static str {
+        if cfg!(windows) { ";" } else { ":" }
     }
 
     /// Returns the current search path for dynamic libraries being used by this
     /// process
-    pub fn search_path() -> Vec<Path> {
+    pub fn search_path() -> Vec<PathBuf> {
         match env::var_os(DynamicLibrary::envvar()) {
             Some(var) => env::split_paths(&var).collect(),
             None => Vec::new(),
@@ -132,14 +130,14 @@ mod test {
     use prelude::v1::*;
     use libc;
     use mem;
+    use path::Path;
 
     #[test]
     #[cfg_attr(any(windows, target_os = "android"), ignore)] // FIXME #8818, #10379
     fn test_loading_cosine() {
         // The math library does not need to be loaded since it is already
         // statically linked in
-        let none: Option<&Path> = None; // appease the typechecker
-        let libm = match DynamicLibrary::open(none) {
+        let libm = match DynamicLibrary::open(None) {
             Err(error) => panic!("Could not load self as module: {}", error),
             Ok(libm) => libm
         };
@@ -165,6 +163,7 @@ mod test {
               target_os = "macos",
               target_os = "freebsd",
               target_os = "dragonfly",
+              target_os = "bitrig",
               target_os = "openbsd"))]
     fn test_errors_do_not_crash() {
         // Open /dev/null as a library to get an error, and make sure
@@ -183,16 +182,17 @@ mod test {
           target_os = "ios",
           target_os = "freebsd",
           target_os = "dragonfly",
+          target_os = "bitrig",
           target_os = "openbsd"))]
 mod dl {
     use prelude::v1::*;
 
-    use ffi::{CString, CStr};
+    use ffi::{CStr, OsStr};
     use str;
     use libc;
     use ptr;
 
-    pub fn open(filename: Option<&[u8]>) -> Result<*mut u8, String> {
+    pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
         check_for_errors_in(|| {
             unsafe {
                 match filename {
@@ -205,8 +205,8 @@ mod dl {
 
     const LAZY: libc::c_int = 1;
 
-    unsafe fn open_external(filename: &[u8]) -> *mut u8 {
-        let s = CString::new(filename).unwrap();
+    unsafe fn open_external(filename: &OsStr) -> *mut u8 {
+        let s = filename.to_cstring().unwrap();
         dlopen(s.as_ptr(), LAZY) as *mut u8
     }
 
@@ -259,23 +259,22 @@ mod dl {
 
 #[cfg(target_os = "windows")]
 mod dl {
-    use iter::IteratorExt;
+    use ffi::OsStr;
+    use iter::Iterator;
     use libc;
     use libc::consts::os::extra::ERROR_CALL_NOT_IMPLEMENTED;
     use ops::FnOnce;
-    use os;
+    use sys::os;
+    use os::windows::prelude::*;
     use option::Option::{self, Some, None};
     use ptr;
     use result::Result;
     use result::Result::{Ok, Err};
-    use slice::SliceExt;
-    use str::StrExt;
-    use str;
     use string::String;
     use vec::Vec;
     use sys::c::compat::kernel32::SetThreadErrorMode;
 
-    pub fn open(filename: Option<&[u8]>) -> Result<*mut u8, String> {
+    pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
         // disable "dll load failed" error dialog.
         let mut use_thread_mode = true;
         let prev_error_mode = unsafe {
@@ -288,10 +287,11 @@ mod dl {
                 let err = os::errno();
                 if err as libc::c_int == ERROR_CALL_NOT_IMPLEMENTED {
                     use_thread_mode = false;
-                    // SetThreadErrorMode not found. use fallback solution: SetErrorMode()
-                    // Note that SetErrorMode is process-wide so this can cause race condition!
-                    // However, since even Windows APIs do not care of such problem (#20650),
-                    // we just assume SetErrorMode race is not a great deal.
+                    // SetThreadErrorMode not found. use fallback solution:
+                    // SetErrorMode() Note that SetErrorMode is process-wide so
+                    // this can cause race condition!  However, since even
+                    // Windows APIs do not care of such problem (#20650), we
+                    // just assume SetErrorMode race is not a great deal.
                     prev_error_mode = SetErrorMode(new_error_mode);
                 }
             }
@@ -304,9 +304,8 @@ mod dl {
 
         let result = match filename {
             Some(filename) => {
-                let filename_str = str::from_utf8(filename).unwrap();
-                let mut filename_str: Vec<u16> = filename_str.utf16_units().collect();
-                filename_str.push(0);
+                let filename_str: Vec<_> =
+                    filename.encode_wide().chain(Some(0).into_iter()).collect();
                 let result = unsafe {
                     LoadLibraryW(filename_str.as_ptr() as *const libc::c_void)
                 };
index 8676586e7dc2a7e32971773e026af9537bdbea25..931cf46a58f2266ee822e6b6eb60a656e460f6ca 100644 (file)
 //! environment varibles, process arguments, the current directory, and various
 //! other important directories.
 
-#![unstable(feature = "env", reason = "recently added via RFC 578")]
+#![stable(feature = "env", since = "1.0.0")]
 
 use prelude::v1::*;
 
+use iter::IntoIterator;
 use error::Error;
-use ffi::{OsString, AsOsStr};
+use ffi::{OsStr, OsString};
 use fmt;
-use old_io::IoResult;
+use io;
+use path::{Path, PathBuf};
 use sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT, Ordering};
 use sync::{StaticMutex, MUTEX_INIT};
 use sys::os as os_imp;
@@ -37,34 +39,36 @@ use sys::os as os_imp;
 /// * There are insufficient permissions to access the current directory.
 /// * The internal buffer is not large enough to hold the path.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
 ///
 /// // We assume that we are in a valid directory.
 /// let p = env::current_dir().unwrap();
 /// println!("The current directory is {}", p.display());
 /// ```
-pub fn current_dir() -> IoResult<Path> {
+#[stable(feature = "env", since = "1.0.0")]
+pub fn current_dir() -> io::Result<PathBuf> {
     os_imp::getcwd()
 }
 
 /// Changes the current working directory to the specified path, returning
 /// whether the change was completed successfully or not.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
-/// use std::old_path::Path;
+/// use std::path::Path;
 ///
 /// let root = Path::new("/");
 /// assert!(env::set_current_dir(&root).is_ok());
 /// println!("Successfully changed working directory to {}!", root.display());
 /// ```
-pub fn set_current_dir(p: &Path) -> IoResult<()> {
-    os_imp::chdir(p)
+#[stable(feature = "env", since = "1.0.0")]
+pub fn set_current_dir<P: AsRef<Path> + ?Sized>(p: &P) -> io::Result<()> {
+    os_imp::chdir(p.as_ref())
 }
 
 static ENV_LOCK: StaticMutex = MUTEX_INIT;
@@ -73,12 +77,14 @@ static ENV_LOCK: StaticMutex = MUTEX_INIT;
 ///
 /// This iterator is created through `std::env::vars()` and yields `(String,
 /// String)` pairs.
+#[stable(feature = "env", since = "1.0.0")]
 pub struct Vars { inner: VarsOs }
 
 /// An iterator over a snapshot of the environment variables of this process.
 ///
 /// This iterator is created through `std::env::vars_os()` and yields
 /// `(OsString, OsString)` pairs.
+#[stable(feature = "env", since = "1.0.0")]
 pub struct VarsOs { inner: os_imp::Env }
 
 /// Returns an iterator of (variable, value) pairs of strings, for all the
@@ -94,9 +100,9 @@ pub struct VarsOs { inner: os_imp::Env }
 /// environment is not valid unicode. If this is not desired, consider using the
 /// `env::vars_os` function.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
 ///
 /// // We will iterate through the references to the element returned by
@@ -105,6 +111,7 @@ pub struct VarsOs { inner: os_imp::Env }
 ///     println!("{}: {}", key, value);
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn vars() -> Vars {
     Vars { inner: vars_os() }
 }
@@ -116,9 +123,9 @@ pub fn vars() -> Vars {
 /// variables at the time of this invocation, modifications to environment
 /// variables afterwards will not be reflected in the returned iterator.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
 ///
 /// // We will iterate through the references to the element returned by
@@ -127,11 +134,13 @@ pub fn vars() -> Vars {
 ///     println!("{:?}: {:?}", key, value);
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn vars_os() -> VarsOs {
     let _g = ENV_LOCK.lock();
     VarsOs { inner: os_imp::env() }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl Iterator for Vars {
     type Item = (String, String);
     fn next(&mut self) -> Option<(String, String)> {
@@ -142,6 +151,7 @@ impl Iterator for Vars {
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl Iterator for VarsOs {
     type Item = (OsString, OsString);
     fn next(&mut self) -> Option<(OsString, OsString)> { self.inner.next() }
@@ -154,9 +164,9 @@ impl Iterator for VarsOs {
 /// valid unicode. If the environment variable is not present, or it is not
 /// valid unicode, then `Err` will be returned.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
 ///
 /// let key = "HOME";
@@ -165,7 +175,8 @@ impl Iterator for VarsOs {
 ///     Err(e) => println!("couldn't interpret {}: {}", key, e),
 /// }
 /// ```
-pub fn var<K: ?Sized>(key: &K) -> Result<String, VarError> where K: AsOsStr {
+#[stable(feature = "env", since = "1.0.0")]
+pub fn var<K: ?Sized>(key: &K) -> Result<String, VarError> where K: AsRef<OsStr> {
     match var_os(key) {
         Some(s) => s.into_string().map_err(VarError::NotUnicode),
         None => Err(VarError::NotPresent)
@@ -175,9 +186,9 @@ pub fn var<K: ?Sized>(key: &K) -> Result<String, VarError> where K: AsOsStr {
 /// Fetches the environment variable `key` from the current process, returning
 /// None if the variable isn't set.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
 ///
 /// let key = "HOME";
@@ -186,24 +197,29 @@ pub fn var<K: ?Sized>(key: &K) -> Result<String, VarError> where K: AsOsStr {
 ///     None => println!("{} is not defined in the environment.", key)
 /// }
 /// ```
-pub fn var_os<K: ?Sized>(key: &K) -> Option<OsString> where K: AsOsStr {
+#[stable(feature = "env", since = "1.0.0")]
+pub fn var_os<K: ?Sized>(key: &K) -> Option<OsString> where K: AsRef<OsStr> {
     let _g = ENV_LOCK.lock();
-    os_imp::getenv(key.as_os_str())
+    os_imp::getenv(key.as_ref())
 }
 
 /// Possible errors from the `env::var` method.
 #[derive(Debug, PartialEq, Eq, Clone)]
+#[stable(feature = "env", since = "1.0.0")]
 pub enum VarError {
     /// The specified environment variable was not present in the current
     /// process's environment.
+    #[stable(feature = "env", since = "1.0.0")]
     NotPresent,
 
     /// The specified environment variable was found, but it did not contain
     /// valid unicode data. The found data is returned as a payload of this
     /// variant.
+    #[stable(feature = "env", since = "1.0.0")]
     NotUnicode(OsString),
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl fmt::Display for VarError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
@@ -215,6 +231,7 @@ impl fmt::Display for VarError {
     }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl Error for VarError {
     fn description(&self) -> &str {
         match *self {
@@ -227,32 +244,48 @@ impl Error for VarError {
 /// Sets the environment variable `k` to the value `v` for the currently running
 /// process.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
 ///
 /// let key = "KEY";
 /// env::set_var(key, "VALUE");
 /// assert_eq!(env::var(key), Ok("VALUE".to_string()));
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn set_var<K: ?Sized, V: ?Sized>(k: &K, v: &V)
-    where K: AsOsStr, V: AsOsStr
+    where K: AsRef<OsStr>, V: AsRef<OsStr>
 {
     let _g = ENV_LOCK.lock();
-    os_imp::setenv(k.as_os_str(), v.as_os_str())
+    os_imp::setenv(k.as_ref(), v.as_ref())
 }
 
-/// Remove a variable from the environment entirely.
-pub fn remove_var<K: ?Sized>(k: &K) where K: AsOsStr {
+/// Remove an environment variable from the environment of the currently running process.
+///
+/// # Examples
+///
+/// ```
+/// use std::env;
+///
+/// let key = "KEY";
+/// env::set_var(key, "VALUE");
+/// assert_eq!(env::var(key), Ok("VALUE".to_string()));
+///
+/// env::remove_var(key);
+/// assert!(env::var(key).is_err());
+/// ```
+#[stable(feature = "env", since = "1.0.0")]
+pub fn remove_var<K: ?Sized>(k: &K) where K: AsRef<OsStr> {
     let _g = ENV_LOCK.lock();
-    os_imp::unsetenv(k.as_os_str())
+    os_imp::unsetenv(k.as_ref())
 }
 
 /// An iterator over `Path` instances for parsing an environment variable
 /// according to platform-specific conventions.
 ///
 /// This structure is returned from `std::env::split_paths`.
+#[stable(feature = "env", since = "1.0.0")]
 pub struct SplitPaths<'a> { inner: os_imp::SplitPaths<'a> }
 
 /// Parses input according to platform conventions for the `PATH`
@@ -260,9 +293,9 @@ pub struct SplitPaths<'a> { inner: os_imp::SplitPaths<'a> }
 ///
 /// Returns an iterator over the paths contained in `unparsed`.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
 ///
 /// let key = "PATH";
@@ -275,19 +308,22 @@ pub struct SplitPaths<'a> { inner: os_imp::SplitPaths<'a> }
 ///     None => println!("{} is not defined in the environment.", key)
 /// }
 /// ```
-pub fn split_paths<T: AsOsStr + ?Sized>(unparsed: &T) -> SplitPaths {
-    SplitPaths { inner: os_imp::split_paths(unparsed.as_os_str()) }
+#[stable(feature = "env", since = "1.0.0")]
+pub fn split_paths<T: AsRef<OsStr> + ?Sized>(unparsed: &T) -> SplitPaths {
+    SplitPaths { inner: os_imp::split_paths(unparsed.as_ref()) }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl<'a> Iterator for SplitPaths<'a> {
-    type Item = Path;
-    fn next(&mut self) -> Option<Path> { self.inner.next() }
+    type Item = PathBuf;
+    fn next(&mut self) -> Option<PathBuf> { self.inner.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
 
 /// Error type returned from `std::env::join_paths` when paths fail to be
 /// joined.
 #[derive(Debug)]
+#[stable(feature = "env", since = "1.0.0")]
 pub struct JoinPathsError {
     inner: os_imp::JoinPathsError
 }
@@ -301,32 +337,36 @@ pub struct JoinPathsError {
 /// `Path`s contains an invalid character for constructing the `PATH`
 /// variable (a double quote on Windows or a colon on Unix).
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
+/// use std::path::PathBuf;
 ///
 /// if let Some(path) = env::var_os("PATH") {
 ///     let mut paths = env::split_paths(&path).collect::<Vec<_>>();
-///     paths.push(Path::new("/home/xyz/bin"));
+///     paths.push(PathBuf::from("/home/xyz/bin"));
 ///     let new_path = env::join_paths(paths.iter()).unwrap();
 ///     env::set_var("PATH", &new_path);
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
-    where I: Iterator<Item=T>, T: AsOsStr
+    where I: IntoIterator<Item=T>, T: AsRef<OsStr>
 {
-    os_imp::join_paths(paths).map_err(|e| {
+    os_imp::join_paths(paths.into_iter()).map_err(|e| {
         JoinPathsError { inner: e }
     })
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl fmt::Display for JoinPathsError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.inner.fmt(f)
     }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl Error for JoinPathsError {
     fn description(&self) -> &str { self.inner.description() }
 }
@@ -345,9 +385,9 @@ impl Error for JoinPathsError {
 /// 'USERPROFILE' environment variable if it is set and not equal to the empty
 /// string.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
 ///
 /// match env::home_dir() {
@@ -355,7 +395,8 @@ impl Error for JoinPathsError {
 ///     None => println!("Impossible to get your home dir!")
 /// }
 /// ```
-pub fn home_dir() -> Option<Path> {
+#[stable(feature = "env", since = "1.0.0")]
+pub fn home_dir() -> Option<PathBuf> {
     os_imp::home_dir()
 }
 
@@ -369,7 +410,21 @@ pub fn home_dir() -> Option<Path> {
 /// On Windows, returns the value of, in order, the 'TMP', 'TEMP',
 /// 'USERPROFILE' environment variable  if any are set and not the empty
 /// string. Otherwise, tmpdir returns the path to the Windows directory.
-pub fn temp_dir() -> Path {
+///
+/// ```
+/// use std::env;
+/// use std::fs::File;
+///
+/// # fn foo() -> std::io::Result<()> {
+/// let mut dir = env::temp_dir();
+/// dir.push("foo.txt");
+///
+/// let f = try!(File::create(dir));
+/// # Ok(())
+/// # }
+/// ```
+#[stable(feature = "env", since = "1.0.0")]
+pub fn temp_dir() -> PathBuf {
     os_imp::temp_dir()
 }
 
@@ -387,7 +442,7 @@ pub fn temp_dir() -> Path {
 ///
 /// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
 ///
 /// match env::current_exe() {
@@ -396,7 +451,8 @@ pub fn temp_dir() -> Path {
 ///     Err(e) => println!("failed to get current exe path: {}", e),
 /// };
 /// ```
-pub fn current_exe() -> IoResult<Path> {
+#[stable(feature = "env", since = "1.0.0")]
+pub fn current_exe() -> io::Result<PathBuf> {
     os_imp::current_exe()
 }
 
@@ -410,26 +466,30 @@ static EXIT_STATUS: AtomicIsize = ATOMIC_ISIZE_INIT;
 /// ignored and the process exits with the default panic status.
 ///
 /// Note that this is not synchronized against modifications of other threads.
+#[unstable(feature = "exit_status", reason = "managing the exit status may change")]
 pub fn set_exit_status(code: i32) {
     EXIT_STATUS.store(code as isize, Ordering::SeqCst)
 }
 
 /// Fetches the process's current exit code. This defaults to 0 and can change
 /// by calling `set_exit_status`.
+#[unstable(feature = "exit_status", reason = "managing the exit status may change")]
 pub fn get_exit_status() -> i32 {
     EXIT_STATUS.load(Ordering::SeqCst) as i32
 }
 
-/// An iterator over the arguments of a process, yielding an `String` value
+/// An iterator over the arguments of a process, yielding a `String` value
 /// for each argument.
 ///
 /// This structure is created through the `std::env::args` method.
+#[stable(feature = "env", since = "1.0.0")]
 pub struct Args { inner: ArgsOs }
 
 /// An iterator over the arguments of a process, yielding an `OsString` value
 /// for each argument.
 ///
 /// This structure is created through the `std::env::args_os` method.
+#[stable(feature = "env", since = "1.0.0")]
 pub struct ArgsOs { inner: os_imp::Args }
 
 /// Returns the arguments which this program was started with (normally passed
@@ -445,9 +505,9 @@ pub struct ArgsOs { inner: os_imp::Args }
 /// process is not valid unicode. If this is not desired it is recommended to
 /// use the `args_os` function instead.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
 ///
 /// // Prints each argument on a separate line
@@ -455,6 +515,7 @@ pub struct ArgsOs { inner: os_imp::Args }
 ///     println!("{}", argument);
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn args() -> Args {
     Args { inner: args_os() }
 }
@@ -466,9 +527,9 @@ pub fn args() -> Args {
 /// set to arbitrary text, and it may not even exist, so this property should
 /// not be relied upon for security purposes.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::env;
 ///
 /// // Prints each argument on a separate line
@@ -476,10 +537,12 @@ pub fn args() -> Args {
 ///     println!("{:?}", argument);
 /// }
 /// ```
+#[stable(feature = "env", since = "1.0.0")]
 pub fn args_os() -> ArgsOs {
     ArgsOs { inner: os_imp::args() }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl Iterator for Args {
     type Item = String;
     fn next(&mut self) -> Option<String> {
@@ -488,301 +551,204 @@ impl Iterator for Args {
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl ExactSizeIterator for Args {
     fn len(&self) -> usize { self.inner.len() }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl Iterator for ArgsOs {
     type Item = OsString;
     fn next(&mut self) -> Option<OsString> { self.inner.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
 
+#[stable(feature = "env", since = "1.0.0")]
 impl ExactSizeIterator for ArgsOs {
     fn len(&self) -> usize { self.inner.len() }
 }
 
 /// Returns the page size of the current architecture in bytes.
+#[unstable(feature = "page_size", reason = "naming and/or location may change")]
 pub fn page_size() -> usize {
     os_imp::page_size()
 }
 
 /// Constants associated with the current target
-#[cfg(target_os = "linux")]
+#[stable(feature = "env", since = "1.0.0")]
 pub mod consts {
-    pub use super::arch_consts::ARCH;
+    /// A string describing the architecture of the CPU that this is currently
+    /// in use.
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const ARCH: &'static str = super::arch::ARCH;
 
-    pub const FAMILY: &'static str = "unix";
+    /// The family of the operating system. In this case, `unix`.
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const FAMILY: &'static str = super::os::FAMILY;
 
     /// A string describing the specific operating system in use: in this
     /// case, `linux`.
-    pub const OS: &'static str = "linux";
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const OS: &'static str = super::os::OS;
 
     /// Specifies the filename prefix used for shared libraries on this
     /// platform: in this case, `lib`.
-    pub const DLL_PREFIX: &'static str = "lib";
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const DLL_PREFIX: &'static str = super::os::DLL_PREFIX;
 
     /// Specifies the filename suffix used for shared libraries on this
     /// platform: in this case, `.so`.
-    pub const DLL_SUFFIX: &'static str = ".so";
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const DLL_SUFFIX: &'static str = super::os::DLL_SUFFIX;
 
     /// Specifies the file extension used for shared libraries on this
     /// platform that goes after the dot: in this case, `so`.
-    pub const DLL_EXTENSION: &'static str = "so";
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const DLL_EXTENSION: &'static str = super::os::DLL_EXTENSION;
 
     /// Specifies the filename suffix used for executable binaries on this
     /// platform: in this case, the empty string.
-    pub const EXE_SUFFIX: &'static str = "";
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const EXE_SUFFIX: &'static str = super::os::EXE_SUFFIX;
 
     /// Specifies the file extension, if any, used for executable binaries
     /// on this platform: in this case, the empty string.
+    #[stable(feature = "env", since = "1.0.0")]
+    pub const EXE_EXTENSION: &'static str = super::os::EXE_EXTENSION;
+
+}
+
+#[cfg(target_os = "linux")]
+mod os {
+    pub const FAMILY: &'static str = "unix";
+    pub const OS: &'static str = "linux";
+    pub const DLL_PREFIX: &'static str = "lib";
+    pub const DLL_SUFFIX: &'static str = ".so";
+    pub const DLL_EXTENSION: &'static str = "so";
+    pub const EXE_SUFFIX: &'static str = "";
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "macos")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `macos`.
     pub const OS: &'static str = "macos";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
     pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.dylib`.
     pub const DLL_SUFFIX: &'static str = ".dylib";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `dylib`.
     pub const DLL_EXTENSION: &'static str = "dylib";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
     pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "ios")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `ios`.
     pub const OS: &'static str = "ios";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
+    pub const DLL_PREFIX: &'static str = "lib";
+    pub const DLL_SUFFIX: &'static str = ".dylib";
+    pub const DLL_EXTENSION: &'static str = "dylib";
     pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "freebsd")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `freebsd`.
     pub const OS: &'static str = "freebsd";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
     pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
     pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
     pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
     pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "dragonfly")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `dragonfly`.
     pub const OS: &'static str = "dragonfly";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
     pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
     pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
     pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
     pub const EXE_SUFFIX: &'static str = "";
+    pub const EXE_EXTENSION: &'static str = "";
+}
 
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
+#[cfg(target_os = "bitrig")]
+mod os {
+    pub const FAMILY: &'static str = "unix";
+    pub const OS: &'static str = "bitrig";
+    pub const DLL_PREFIX: &'static str = "lib";
+    pub const DLL_SUFFIX: &'static str = ".so";
+    pub const DLL_EXTENSION: &'static str = "so";
+    pub const EXE_SUFFIX: &'static str = "";
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "openbsd")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `dragonfly`.
     pub const OS: &'static str = "openbsd";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
     pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
     pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
     pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
     pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "android")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `android`.
     pub const OS: &'static str = "android";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
     pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
     pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
     pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
     pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-/// Constants associated with the current target
 #[cfg(target_os = "windows")]
-pub mod consts {
-    pub use super::arch_consts::ARCH;
-
+mod os {
     pub const FAMILY: &'static str = "windows";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `windows`.
     pub const OS: &'static str = "windows";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, the empty string.
     pub const DLL_PREFIX: &'static str = "";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.dll`.
     pub const DLL_SUFFIX: &'static str = ".dll";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `dll`.
     pub const DLL_EXTENSION: &'static str = "dll";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, `.exe`.
     pub const EXE_SUFFIX: &'static str = ".exe";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, `exe`.
     pub const EXE_EXTENSION: &'static str = "exe";
 }
 
 #[cfg(target_arch = "x86")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "x86";
 }
 
 #[cfg(target_arch = "x86_64")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "x86_64";
 }
 
 #[cfg(target_arch = "arm")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "arm";
 }
 
 #[cfg(target_arch = "aarch64")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "aarch64";
 }
 
 #[cfg(target_arch = "mips")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "mips";
 }
 
 #[cfg(target_arch = "mipsel")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "mipsel";
 }
 
 #[cfg(target_arch = "powerpc")]
-mod arch_consts {
+mod arch {
     pub const ARCH: &'static str = "powerpc";
 }
 
@@ -790,15 +756,17 @@ mod arch_consts {
 mod tests {
     use prelude::v1::*;
     use super::*;
+
     use iter::repeat;
     use rand::{self, Rng};
     use ffi::{OsString, OsStr};
+    use path::{Path, PathBuf};
 
     fn make_rand_name() -> OsString {
         let mut rng = rand::thread_rng();
         let n = format!("TEST{}", rng.gen_ascii_chars().take(10)
                                      .collect::<String>());
-        let n = OsString::from_string(n);
+        let n = OsString::from(n);
         assert!(var_os(&n).is_none());
         n
     }
@@ -841,8 +809,8 @@ mod tests {
             i += 1;
         }
         let n = make_rand_name();
-        set_var(&n, s.as_slice());
-        eq(var_os(&n), Some(s.as_slice()));
+        set_var(&n, &s);
+        eq(var_os(&n), Some(&s));
     }
 
     #[test]
@@ -860,7 +828,7 @@ mod tests {
         let n = make_rand_name();
         let s = repeat("x").take(10000).collect::<String>();
         set_var(&n, &s);
-        eq(var_os(&n), Some(s.as_slice()));
+        eq(var_os(&n), Some(&s));
         remove_var(&n);
         eq(var_os(&n), None);
     }
@@ -892,7 +860,7 @@ mod tests {
     fn split_paths_windows() {
         fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
             split_paths(unparsed).collect::<Vec<_>>() ==
-                parsed.iter().map(|s| Path::new(*s)).collect::<Vec<_>>()
+                parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
         }
 
         assert!(check_parse("", &mut [""]));
@@ -912,7 +880,7 @@ mod tests {
     fn split_paths_unix() {
         fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
             split_paths(unparsed).collect::<Vec<_>>() ==
-                parsed.iter().map(|s| Path::new(*s)).collect::<Vec<_>>()
+                parsed.iter().map(|s| PathBuf::from(*s)).collect::<Vec<_>>()
         }
 
         assert!(check_parse("", &mut [""]));
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
new file mode 100644 (file)
index 0000000..150ffcd
--- /dev/null
@@ -0,0 +1,152 @@
+// 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.
+
+//! Traits for working with Errors.
+//!
+//! # The `Error` trait
+//!
+//! `Error` is a trait representing the basic expectations for error values,
+//! i.e. values of type `E` in `Result<T, E>`. At a minimum, errors must provide
+//! a description, but they may optionally provide additional detail (via
+//! `Display`) and cause chain information:
+//!
+//! ```
+//! use std::fmt::Display;
+//!
+//! trait Error: Display {
+//!     fn description(&self) -> &str;
+//!
+//!     fn cause(&self) -> Option<&Error> { None }
+//! }
+//! ```
+//!
+//! The `cause` method is generally used when errors cross "abstraction
+//! boundaries", i.e.  when a one module must report an error that is "caused"
+//! by an error from a lower-level module. This setup makes it possible for the
+//! high-level module to provide its own errors that do not commit to any
+//! particular implementation, but also reveal some of its implementation for
+//! debugging via `cause` chains.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+// A note about crates and the facade:
+//
+// Originally, the `Error` trait was defined in libcore, and the impls
+// were scattered about. However, coherence objected to this
+// arrangement, because to create the blanket impls for `Box` required
+// knowing that `&str: !Error`, and we have no means to deal with that
+// sort of conflict just now. Therefore, for the time being, we have
+// moved the `Error` trait into libstd. As we evolve a sol'n to the
+// coherence challenge (e.g., specialization, neg impls, etc) we can
+// reconsider what crate these items belong in.
+
+use boxed::Box;
+use convert::From;
+use fmt::{self, Debug, Display};
+use marker::Send;
+use num;
+use option::Option;
+use option::Option::None;
+use str;
+use string::{self, String};
+
+/// Base functionality for all errors in Rust.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Error: Debug + Display {
+    /// A short description of the error.
+    ///
+    /// The description should not contain newlines or sentence-ending
+    /// punctuation, to facilitate embedding in larger user-facing
+    /// strings.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn description(&self) -> &str;
+
+    /// The lower-level cause of this error, if any.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn cause(&self) -> Option<&Error> { None }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
+    fn from(err: E) -> Box<Error + 'a> {
+        Box::new(err)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, E: Error + Send + 'a> From<E> for Box<Error + Send + 'a> {
+    fn from(err: E) -> Box<Error + Send + 'a> {
+        Box::new(err)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, 'b> From<&'b str> for Box<Error + Send + 'a> {
+    fn from(err: &'b str) -> Box<Error + Send + 'a> {
+        #[derive(Debug)]
+        struct StringError(String);
+
+        impl Error for StringError {
+            fn description(&self) -> &str { &self.0 }
+        }
+
+        impl Display for StringError {
+            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                Display::fmt(&self.0, f)
+            }
+        }
+
+        Box::new(StringError(String::from_str(err)))
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for str::ParseBoolError {
+    fn description(&self) -> &str { "failed to parse bool" }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for str::Utf8Error {
+    fn description(&self) -> &str {
+        match *self {
+            str::Utf8Error::TooShort => "invalid utf-8: not enough bytes",
+            str::Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents",
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for num::ParseIntError {
+    fn description(&self) -> &str {
+        self.description()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for num::ParseFloatError {
+    fn description(&self) -> &str {
+        self.description()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for string::FromUtf8Error {
+    fn description(&self) -> &str {
+        "invalid utf-8"
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for string::FromUtf16Error {
+    fn description(&self) -> &str {
+        "invalid utf-16"
+    }
+}
+
index 8976813d3f91e9681a84f48d8ca552733319ff6c..de91e5f32683939d5bee102c8739c14a0d6b5e25 100644 (file)
@@ -8,19 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![unstable(feature = "std_misc")]
+
+use convert::{Into, From};
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
-use error::{Error, FromError};
+use error::Error;
 use fmt;
 use io;
-use iter::IteratorExt;
+use iter::Iterator;
 use libc;
 use mem;
+#[allow(deprecated)]
 use old_io;
 use ops::Deref;
 use option::Option::{self, Some, None};
 use result::Result::{self, Ok, Err};
-use slice::{self, SliceExt};
-use str::StrExt;
+use slice;
 use string::String;
 use vec::Vec;
 
@@ -39,9 +42,10 @@ use vec::Vec;
 /// a `CString` do *not* contain the trailing nul terminator unless otherwise
 /// specified.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```no_run
+/// # #![feature(libc)]
 /// # extern crate libc;
 /// # fn main() {
 /// use std::ffi::CString;
@@ -51,7 +55,7 @@ use vec::Vec;
 ///     fn my_printer(s: *const libc::c_char);
 /// }
 ///
-/// let to_print = b"Hello, world!";
+/// let to_print = &b"Hello, world!"[..];
 /// let c_to_print = CString::new(to_print).unwrap();
 /// unsafe {
 ///     my_printer(c_to_print.as_ptr());
@@ -59,6 +63,7 @@ use vec::Vec;
 /// # }
 /// ```
 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct CString {
     inner: Vec<u8>,
 }
@@ -79,6 +84,7 @@ pub struct CString {
 /// Inspecting a foreign C string
 ///
 /// ```no_run
+/// # #![feature(libc)]
 /// extern crate libc;
 /// use std::ffi::CStr;
 ///
@@ -95,6 +101,7 @@ pub struct CString {
 /// Passing a Rust-originating C string
 ///
 /// ```no_run
+/// # #![feature(libc)]
 /// extern crate libc;
 /// use std::ffi::{CString, CStr};
 ///
@@ -110,22 +117,21 @@ pub struct CString {
 /// }
 /// ```
 #[derive(Hash)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct CStr {
+    // FIXME: this should not be represented with a DST slice but rather with
+    //        just a raw `libc::c_char` along with some form of marker to make
+    //        this an unsized type. Essentially `sizeof(&CStr)` should be the
+    //        same as `sizeof(&c_char)` but `CStr` should be an unsized type.
     inner: [libc::c_char]
 }
 
 /// An error returned from `CString::new` to indicate that a nul byte was found
 /// in the vector provided.
 #[derive(Clone, PartialEq, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct NulError(usize, Vec<u8>);
 
-/// A conversion trait used by the constructor of `CString` for types that can
-/// be converted to a vector of bytes.
-pub trait IntoBytes {
-    /// Consumes this container, returning a vector of bytes.
-    fn into_bytes(self) -> Vec<u8>;
-}
-
 impl CString {
     /// Create a new C-compatible string from a container of bytes.
     ///
@@ -135,6 +141,7 @@ impl CString {
     /// # Examples
     ///
     /// ```no_run
+    /// # #![feature(libc)]
     /// extern crate libc;
     /// use std::ffi::CString;
     ///
@@ -153,69 +160,21 @@ impl CString {
     /// This function will return an error if the bytes yielded contain an
     /// internal 0 byte. The error returned will contain the bytes as well as
     /// the position of the nul byte.
-    pub fn new<T: IntoBytes>(t: T) -> Result<CString, NulError> {
-        let bytes = t.into_bytes();
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
+        let bytes = t.into();
         match bytes.iter().position(|x| *x == 0) {
             Some(i) => Err(NulError(i, bytes)),
             None => Ok(unsafe { CString::from_vec_unchecked(bytes) }),
         }
     }
 
-    /// Create a new C-compatible string from a byte slice.
-    ///
-    /// This method will copy the data of the slice provided into a new
-    /// allocation, ensuring that there is a trailing 0 byte.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// extern crate libc;
-    /// use std::ffi::CString;
-    ///
-    /// extern { fn puts(s: *const libc::c_char); }
-    ///
-    /// fn main() {
-    ///     let to_print = CString::new("Hello!").unwrap();
-    ///     unsafe {
-    ///         puts(to_print.as_ptr());
-    ///     }
-    /// }
-    /// ```
-    ///
-    /// # Panics
-    ///
-    /// This function will panic if the provided slice contains any
-    /// interior nul bytes.
-    #[unstable(feature = "std_misc")]
-    #[deprecated(since = "1.0.0", reason = "use CString::new instead")]
-    #[allow(deprecated)]
-    pub fn from_slice(v: &[u8]) -> CString {
-        CString::from_vec(v.to_vec())
-    }
-
-    /// Create a C-compatible string from a byte vector.
-    ///
-    /// This method will consume ownership of the provided vector, appending a 0
-    /// byte to the end after verifying that there are no interior 0 bytes.
-    ///
-    /// # Panics
-    ///
-    /// This function will panic if the provided slice contains any
-    /// interior nul bytes.
-    #[unstable(feature = "std_misc")]
-    #[deprecated(since = "1.0.0", reason = "use CString::new instead")]
-    pub fn from_vec(v: Vec<u8>) -> CString {
-        match v.iter().position(|x| *x == 0) {
-            Some(i) => panic!("null byte found in slice at: {}", i),
-            None => unsafe { CString::from_vec_unchecked(v) },
-        }
-    }
-
     /// Create a C-compatible string from a byte vector without checking for
     /// interior 0 bytes.
     ///
     /// This method is equivalent to `from_vec` except that no runtime assertion
     /// is made that `v` contains no 0 bytes.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
         v.push(0);
         CString { inner: v }
@@ -224,18 +183,21 @@ impl CString {
     /// Returns the contents of this `CString` as a slice of bytes.
     ///
     /// The returned slice does **not** contain the trailing nul separator and
-    /// it is guaranteet to not have any interior nul bytes.
+    /// it is guaranteed to not have any interior nul bytes.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_bytes(&self) -> &[u8] {
         &self.inner[..self.inner.len() - 1]
     }
 
     /// Equivalent to the `as_bytes` function except that the returned slice
     /// includes the trailing nul byte.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_bytes_with_nul(&self) -> &[u8] {
         &self.inner
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Deref for CString {
     type Target = CStr;
 
@@ -254,32 +216,39 @@ impl fmt::Debug for CString {
 impl NulError {
     /// Returns the position of the nul byte in the slice that was provided to
     /// `CString::from_vec`.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn nul_position(&self) -> usize { self.0 }
 
     /// Consumes this error, returning the underlying vector of bytes which
     /// generated the error in the first place.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_vec(self) -> Vec<u8> { self.1 }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Error for NulError {
     fn description(&self) -> &str { "nul byte found in data" }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for NulError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "nul byte found in provided data at position: {}", self.0)
     }
 }
 
-impl FromError<NulError> for io::Error {
-    fn from_error(_: NulError) -> io::Error {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl From<NulError> for io::Error {
+    fn from(_: NulError) -> io::Error {
         io::Error::new(io::ErrorKind::InvalidInput,
-                       "data provided contains a nul byte", None)
+                       "data provided contains a nul byte")
     }
 }
 
-impl FromError<NulError> for old_io::IoError {
-    fn from_error(_: NulError) -> old_io::IoError {
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
+impl From<NulError> for old_io::IoError {
+    fn from(_: NulError) -> old_io::IoError {
         old_io::IoError {
             kind: old_io::IoErrorKind::InvalidInput,
             desc: "data provided contains a nul byte",
@@ -305,9 +274,10 @@ impl CStr {
     /// > currently implemented with an up-front calculation of the length of
     /// > the string. This is not guaranteed to always be the case.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```no_run
+    /// # #![feature(libc)]
     /// # extern crate libc;
     /// # fn main() {
     /// use std::ffi::CStr;
@@ -325,6 +295,7 @@ impl CStr {
     /// }
     /// # }
     /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub unsafe fn from_ptr<'a>(ptr: *const libc::c_char) -> &'a CStr {
         let len = libc::strlen(ptr);
         mem::transmute(slice::from_raw_parts(ptr, len as usize + 1))
@@ -333,8 +304,9 @@ impl CStr {
     /// Return the inner pointer to this C string.
     ///
     /// The returned pointer will be valid for as long as `self` is and points
-    /// to a continguous region of memory terminated with a 0 byte to represent
+    /// to a contiguous region of memory terminated with a 0 byte to represent
     /// the end of the string.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_ptr(&self) -> *const libc::c_char {
         self.inner.as_ptr()
     }
@@ -351,6 +323,7 @@ impl CStr {
     /// > **Note**: This method is currently implemented as a 0-cost cast, but
     /// > it is planned to alter its definition in the future to perform the
     /// > length calculation whenever this method is called.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_bytes(&self) -> &[u8] {
         let bytes = self.to_bytes_with_nul();
         &bytes[..bytes.len() - 1]
@@ -364,86 +337,59 @@ impl CStr {
     /// > **Note**: This method is currently implemented as a 0-cost cast, but
     /// > it is planned to alter its definition in the future to perform the
     /// > length calculation whenever this method is called.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_bytes_with_nul(&self) -> &[u8] {
         unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.inner) }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq for CStr {
     fn eq(&self, other: &CStr) -> bool {
-        self.to_bytes().eq(&other.to_bytes())
+        self.to_bytes().eq(other.to_bytes())
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Eq for CStr {}
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialOrd for CStr {
     fn partial_cmp(&self, other: &CStr) -> Option<Ordering> {
         self.to_bytes().partial_cmp(&other.to_bytes())
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Ord for CStr {
     fn cmp(&self, other: &CStr) -> Ordering {
         self.to_bytes().cmp(&other.to_bytes())
     }
 }
 
-/// Deprecated in favor of `CStr`
-#[unstable(feature = "std_misc")]
-#[deprecated(since = "1.0.0", reason = "use CStr::from_ptr(p).to_bytes() instead")]
-pub unsafe fn c_str_to_bytes<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
-    let len = libc::strlen(*raw);
-    slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize)
-}
-
-/// Deprecated in favor of `CStr`
-#[unstable(feature = "std_misc")]
-#[deprecated(since = "1.0.0",
-             reason = "use CStr::from_ptr(p).to_bytes_with_nul() instead")]
-pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char)
-                                          -> &'a [u8] {
-    let len = libc::strlen(*raw) + 1;
-    slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize)
-}
-
-impl<'a> IntoBytes for &'a str {
-    fn into_bytes(self) -> Vec<u8> { self.as_bytes().to_vec() }
-}
-impl<'a> IntoBytes for &'a [u8] {
-    fn into_bytes(self) -> Vec<u8> { self.to_vec() }
-}
-impl IntoBytes for String {
-    fn into_bytes(self) -> Vec<u8> { self.into_bytes() }
-}
-impl IntoBytes for Vec<u8> {
-    fn into_bytes(self) -> Vec<u8> { self }
-}
-
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
     use super::*;
     use libc;
-    use mem;
 
     #[test]
     fn c_to_rust() {
         let data = b"123\0";
         let ptr = data.as_ptr() as *const libc::c_char;
         unsafe {
-            assert_eq!(c_str_to_bytes(&ptr), b"123");
-            assert_eq!(c_str_to_bytes_with_nul(&ptr), b"123\0");
+            assert_eq!(CStr::from_ptr(ptr).to_bytes(), b"123");
+            assert_eq!(CStr::from_ptr(ptr).to_bytes_with_nul(), b"123\0");
         }
     }
 
     #[test]
     fn simple() {
-        let s = CString::new(b"1234").unwrap();
+        let s = CString::new("1234").unwrap();
         assert_eq!(s.as_bytes(), b"1234");
         assert_eq!(s.as_bytes_with_nul(), b"1234\0");
     }
 
     #[test]
     fn build_with_zero1() {
-        assert!(CString::new(b"\0").is_err());
+        assert!(CString::new(&b"\0"[..]).is_err());
     }
     #[test]
     fn build_with_zero2() {
@@ -460,7 +406,7 @@ mod tests {
 
     #[test]
     fn formatted() {
-        let s = CString::new(b"12").unwrap();
+        let s = CString::new(&b"12"[..]).unwrap();
         assert_eq!(format!("{:?}", s), "\"12\"");
     }
 
index 1bff6afb776079b0e5102ad2b0e92541d089263c..1b7e913d46cbf49120c0f2798a5135477dec53ff 100644 (file)
 
 //! Utilities related to FFI bindings.
 
-#![unstable(feature = "std_misc",
-            reason = "module just underwent fairly large reorganization and the dust \
-                      still needs to settle")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
-pub use self::c_str::{CString, CStr, NulError, IntoBytes};
-#[allow(deprecated)]
-pub use self::c_str::c_str_to_bytes;
-#[allow(deprecated)]
-pub use self::c_str::c_str_to_bytes_with_nul;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::c_str::{CString, CStr, NulError};
 
-pub use self::os_str::OsString;
-pub use self::os_str::OsStr;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::os_str::{OsString, OsStr};
 
 mod c_str;
 mod os_str;
 
 // FIXME (#21670): these should be defined in the os_str module
 /// Freely convertible to an `&OsStr` slice.
+#[unstable(feature = "std_misc")]
 pub trait AsOsStr {
     /// Convert to an `&OsStr` slice.
     fn as_os_str(&self) -> &OsStr;
index 84149a2eb8e43353a1d9857c8a19cdecd65f379e..ab20efe25eb19da63db8ffd9e5f2020c41d674ce 100644 (file)
 //! for conversion to/from various other string types. Eventually these types
 //! will offer a full-fledged string API.
 
-#![unstable(feature = "os",
+#![unstable(feature = "os_str",
             reason = "recently added as part of path/io reform")]
 
 use core::prelude::*;
 
-use borrow::{Borrow, ToOwned};
+use borrow::{Borrow, Cow, ToOwned};
+use ffi::CString;
 use fmt::{self, Debug};
 use mem;
-use string::{String, CowString};
+use string::String;
 use ops;
 use cmp;
 use hash::{Hash, Hasher};
-#[cfg(stage0)] use hash::Writer;
 use old_path::{Path, GenericPath};
+use vec::Vec;
 
 use sys::os_str::{Buf, Slice};
 use sys_common::{AsInner, IntoInner, FromInner};
@@ -50,55 +51,95 @@ use super::AsOsStr;
 
 /// Owned, mutable OS strings.
 #[derive(Clone)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct OsString {
     inner: Buf
 }
 
 /// Slices into OS strings.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct OsStr {
     inner: Slice
 }
 
 impl OsString {
-    /// Constructs an `OsString` at no cost by consuming a `String`.
-    pub fn from_string(s: String) -> OsString {
-        OsString { inner: Buf::from_string(s) }
-    }
-
-    /// Constructs an `OsString` by copying from a `&str` slice.
-    ///
-    /// Equivalent to: `OsString::from_string(String::from_str(s))`.
-    pub fn from_str(s: &str) -> OsString {
-        OsString { inner: Buf::from_str(s) }
-    }
-
     /// Constructs a new empty `OsString`.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new() -> OsString {
         OsString { inner: Buf::from_string(String::new()) }
     }
 
+    /// Construct an `OsString` from a byte sequence.
+    ///
+    /// # Platform behavior
+    ///
+    /// On Unix systems, any byte sequence can be successfully
+    /// converted into an `OsString`.
+    ///
+    /// On Windows system, only UTF-8 byte sequences will successfully
+    /// convert; non UTF-8 data will produce `None`.
+    #[unstable(feature = "convert", reason = "recently added")]
+    pub fn from_bytes<B>(bytes: B) -> Option<OsString> where B: Into<Vec<u8>> {
+        #[cfg(unix)]
+        fn from_bytes_inner(vec: Vec<u8>) -> Option<OsString> {
+            use os::unix::ffi::OsStringExt;
+            Some(OsString::from_vec(vec))
+        }
+
+        #[cfg(windows)]
+        fn from_bytes_inner(vec: Vec<u8>) -> Option<OsString> {
+            String::from_utf8(vec).ok().map(OsString::from)
+        }
+
+        from_bytes_inner(bytes.into())
+    }
+
+    /// Convert to an `OsStr` slice.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn as_os_str(&self) -> &OsStr {
+        self
+    }
+
     /// Convert the `OsString` into a `String` if it contains valid Unicode data.
     ///
     /// On failure, ownership of the original `OsString` is returned.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_string(self) -> Result<String, OsString> {
         self.inner.into_string().map_err(|buf| OsString { inner: buf} )
     }
 
     /// Extend the string with the given `&OsStr` slice.
-    pub fn push_os_str(&mut self, s: &OsStr) {
-        self.inner.push_slice(&s.inner)
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
+        self.inner.push_slice(&s.as_ref().inner)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl From<String> for OsString {
+    fn from(s: String) -> OsString {
+        OsString { inner: Buf::from_string(s) }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for OsString {
+    fn from(s: &'a T) -> OsString {
+        s.as_ref().to_os_string()
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl ops::Index<ops::RangeFull> for OsString {
     type Output = OsStr;
 
     #[inline]
-    fn index(&self, _index: &ops::RangeFull) -> &OsStr {
+    fn index(&self, _index: ops::RangeFull) -> &OsStr {
         unsafe { mem::transmute(self.inner.as_slice()) }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl ops::Deref for OsString {
     type Target = OsStr;
 
@@ -108,32 +149,38 @@ impl ops::Deref for OsString {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Debug for OsString {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
         fmt::Debug::fmt(&**self, formatter)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq for OsString {
     fn eq(&self, other: &OsString) -> bool {
         &**self == &**other
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq<str> for OsString {
     fn eq(&self, other: &str) -> bool {
         &**self == other
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq<OsString> for str {
     fn eq(&self, other: &OsString) -> bool {
         &**other == self
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Eq for OsString {}
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialOrd for OsString {
     #[inline]
     fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
@@ -149,6 +196,7 @@ impl PartialOrd for OsString {
     fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialOrd<str> for OsString {
     #[inline]
     fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
@@ -156,6 +204,7 @@ impl PartialOrd<str> for OsString {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Ord for OsString {
     #[inline]
     fn cmp(&self, other: &OsString) -> cmp::Ordering {
@@ -163,14 +212,6 @@ impl Ord for OsString {
     }
 }
 
-#[cfg(stage0)]
-impl<'a, S: Hasher + Writer> Hash<S> for OsString {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (&**self).hash(state)
-    }
-}
-#[cfg(not(stage0))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Hash for OsString {
     #[inline]
@@ -180,7 +221,16 @@ impl Hash for OsString {
 }
 
 impl OsStr {
+    /// Coerce into an `OsStr` slice.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
+        s.as_ref()
+    }
+
     /// Coerce directly from a `&str` slice to a `&OsStr` slice.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `OsStr::new` instead")]
     pub fn from_str(s: &str) -> &OsStr {
         unsafe { mem::transmute(Slice::from_str(s)) }
     }
@@ -188,22 +238,55 @@ impl OsStr {
     /// Yield a `&str` slice if the `OsStr` is valid unicode.
     ///
     /// This conversion may entail doing a check for UTF-8 validity.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_str(&self) -> Option<&str> {
         self.inner.to_str()
     }
 
-    /// Convert an `OsStr` to a `CowString`.
+    /// Convert an `OsStr` to a `Cow<str>`.
     ///
     /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
-    pub fn to_string_lossy(&self) -> CowString {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn to_string_lossy(&self) -> Cow<str> {
         self.inner.to_string_lossy()
     }
 
     /// Copy the slice into an owned `OsString`.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_os_string(&self) -> OsString {
         OsString { inner: self.inner.to_owned() }
     }
 
+    /// Yield this `OsStr` as a byte slice.
+    ///
+    /// # Platform behavior
+    ///
+    /// On Unix systems, this is a no-op.
+    ///
+    /// On Windows systems, this returns `None` unless the `OsStr` is
+    /// valid unicode, in which case it produces UTF-8-encoded
+    /// data. This may entail checking validity.
+    #[unstable(feature = "convert", reason = "recently added")]
+    pub fn to_bytes(&self) -> Option<&[u8]> {
+        if cfg!(windows) {
+            self.to_str().map(|s| s.as_bytes())
+        } else {
+            Some(self.bytes())
+        }
+    }
+
+    /// Create a `CString` containing this `OsStr` data.
+    ///
+    /// Fails if the `OsStr` contains interior nulls.
+    ///
+    /// This is a convenience for creating a `CString` from
+    /// `self.to_bytes()`, and inherits the platform behavior of the
+    /// `to_bytes` method.
+    #[unstable(feature = "convert", reason = "recently added")]
+    pub fn to_cstring(&self) -> Option<CString> {
+        self.to_bytes().and_then(|b| CString::new(b).ok())
+    }
+
     /// Get the underlying byte representation.
     ///
     /// Note: it is *crucial* that this API is private, to avoid
@@ -213,26 +296,31 @@ impl OsStr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq for OsStr {
     fn eq(&self, other: &OsStr) -> bool {
         self.bytes().eq(other.bytes())
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq<str> for OsStr {
     fn eq(&self, other: &str) -> bool {
-        *self == *OsStr::from_str(other)
+        *self == *OsStr::new(other)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq<OsStr> for str {
     fn eq(&self, other: &OsStr) -> bool {
-        *other == *OsStr::from_str(self)
+        *other == *OsStr::new(self)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Eq for OsStr {}
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialOrd for OsStr {
     #[inline]
     fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
@@ -248,29 +336,23 @@ impl PartialOrd for OsStr {
     fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialOrd<str> for OsStr {
     #[inline]
     fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
-        self.partial_cmp(OsStr::from_str(other))
+        self.partial_cmp(OsStr::new(other))
     }
 }
 
 // FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
 // have more flexible coherence rules.
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Ord for OsStr {
     #[inline]
     fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
 }
 
-#[cfg(stage0)]
-impl<'a, S: Hasher + Writer> Hash<S> for OsStr {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        self.bytes().hash(state)
-    }
-}
-#[cfg(not(stage0))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Hash for OsStr {
     #[inline]
@@ -279,60 +361,101 @@ impl Hash for OsStr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Debug for OsStr {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
         self.inner.fmt(formatter)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Borrow<OsStr> for OsString {
     fn borrow(&self) -> &OsStr { &self[..] }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl ToOwned for OsStr {
     type Owned = OsString;
     fn to_owned(&self) -> OsString { self.to_os_string() }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
 impl<'a, T: AsOsStr + ?Sized> AsOsStr for &'a T {
     fn as_os_str(&self) -> &OsStr {
         (*self).as_os_str()
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
 impl AsOsStr for OsStr {
     fn as_os_str(&self) -> &OsStr {
         self
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
 impl AsOsStr for OsString {
     fn as_os_str(&self) -> &OsStr {
         &self[..]
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
 impl AsOsStr for str {
     fn as_os_str(&self) -> &OsStr {
-        OsStr::from_str(self)
+        unsafe { mem::transmute(Slice::from_str(self)) }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
 impl AsOsStr for String {
     fn as_os_str(&self) -> &OsStr {
-        OsStr::from_str(&self[..])
+        unsafe { mem::transmute(Slice::from_str(self)) }
     }
 }
 
-#[cfg(unix)]
-impl AsOsStr for Path {
-    fn as_os_str(&self) -> &OsStr {
-        unsafe { mem::transmute(self.as_vec()) }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<OsStr> for OsStr {
+    fn as_ref(&self) -> &OsStr {
+        self
     }
 }
 
-#[cfg(windows)]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<OsStr> for OsString {
+    fn as_ref(&self) -> &OsStr {
+        self
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<OsStr> for str {
+    fn as_ref(&self) -> &OsStr {
+        unsafe { mem::transmute(Slice::from_str(self)) }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<OsStr> for String {
+    fn as_ref(&self) -> &OsStr {
+        unsafe { mem::transmute(Slice::from_str(self)) }
+    }
+}
+
+#[allow(deprecated)]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
 impl AsOsStr for Path {
+    #[cfg(unix)]
+    fn as_os_str(&self) -> &OsStr {
+        unsafe { mem::transmute(self.as_vec()) }
+    }
+    #[cfg(windows)]
     fn as_os_str(&self) -> &OsStr {
         // currently .as_str() is actually infallible on windows
         OsStr::from_str(self.as_str().unwrap())
index 69791084e2f9fa77fa24301c9947e27bcdaa622b..eabc51beb1285214c0ce5ba6a03395e5d1cd116a 100644 (file)
 //! operations. Extra platform-specific functionality can be found in the
 //! extension traits of `std::os::$platform`.
 
-#![unstable(feature = "fs")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
 use core::prelude::*;
 
 use io::{self, Error, ErrorKind, SeekFrom, Seek, Read, Write};
-use path::{AsPath, Path, PathBuf};
+use path::{Path, PathBuf};
 use sys::fs2 as fs_imp;
 use sys_common::{AsInnerMut, FromInner, AsInner};
 use vec::Vec;
@@ -31,7 +31,7 @@ use vec::Vec;
 /// it was opened with. Files also implement `Seek` to alter the logical cursor
 /// that the file contains internally.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```no_run
 /// use std::io::prelude::*;
@@ -48,9 +48,10 @@ use vec::Vec;
 /// # Ok(())
 /// # }
 /// ```
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct File {
     inner: fs_imp::File,
-    path: PathBuf,
+    path: Option<PathBuf>,
 }
 
 /// Metadata information about a file.
@@ -58,6 +59,7 @@ pub struct File {
 /// This structure is returned from the `metadata` function or method and
 /// represents known metadata about a file such as its permissions, size,
 /// modification times, etc.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Metadata(fs_imp::FileAttr);
 
 /// Iterator over the entries in a directory.
@@ -66,6 +68,12 @@ pub struct Metadata(fs_imp::FileAttr);
 /// will yield instances of `io::Result<DirEntry>`. Through a `DirEntry`
 /// information like the entry's path and possibly other metadata can be
 /// learned.
+///
+/// # Failure
+///
+/// This `io::Result` will be an `Err` if there's some sort of intermittent
+/// IO error during iteration.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct ReadDir(fs_imp::ReadDir);
 
 /// Entries returned by the `ReadDir` iterator.
@@ -73,9 +81,14 @@ pub struct ReadDir(fs_imp::ReadDir);
 /// An instance of `DirEntry` represents an entry inside of a directory on the
 /// filesystem. Each entry can be inspected via methods to learn about the full
 /// path or possibly other metadata through per-platform extension traits.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct DirEntry(fs_imp::DirEntry);
 
 /// An iterator that recursively walks over the contents of a directory.
+#[unstable(feature = "fs_walk",
+           reason = "the precise semantics and defaults for a recursive walk \
+                     may change and this may end up accounting for files such \
+                     as symlinks differently")]
 pub struct WalkDir {
     cur: Option<ReadDir>,
     stack: Vec<io::Result<ReadDir>>,
@@ -88,6 +101,7 @@ pub struct WalkDir {
 /// `File::create` methods are aliases for commonly used options using this
 /// builder.
 #[derive(Clone)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct OpenOptions(fs_imp::OpenOptions);
 
 /// Representation of the various permissions on a file.
@@ -97,6 +111,7 @@ pub struct OpenOptions(fs_imp::OpenOptions);
 /// functionality, such as mode bits, is available through the
 /// `os::unix::PermissionsExt` trait.
 #[derive(Clone, PartialEq, Eq, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Permissions(fs_imp::FilePermissions);
 
 impl File {
@@ -108,7 +123,19 @@ impl File {
     ///
     /// This function will return an error if `path` does not already exist.
     /// Other errors may also be returned according to `OpenOptions::open`.
-    pub fn open<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// let mut f = try!(File::open("foo.txt"));
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
         OpenOptions::new().read(true).open(path)
     }
 
@@ -118,19 +145,50 @@ impl File {
     /// and will truncate it if it does.
     ///
     /// See the `OpenOptions::open` function for more details.
-    pub fn create<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// let mut f = try!(File::create("foo.txt"));
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn create<P: AsRef<Path>>(path: P) -> io::Result<File> {
         OpenOptions::new().write(true).create(true).truncate(true).open(path)
     }
 
     /// Returns the original path that was used to open this file.
+    #[unstable(feature = "file_path",
+               reason = "this abstraction is imposed by this library instead \
+                         of the underlying OS and may be removed")]
     pub fn path(&self) -> Option<&Path> {
-        Some(&self.path)
+        self.path.as_ref().map(|p| &**p)
     }
 
     /// Attempt to sync all OS-internal metadata to disk.
     ///
     /// This function will attempt to ensure that all in-core data reaches the
     /// filesystem before returning.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    /// use std::io::prelude::*;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// let mut f = try!(File::create("foo.txt"));
+    /// try!(f.write_all(b"Hello, world!"));
+    ///
+    /// try!(f.sync_all());
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn sync_all(&self) -> io::Result<()> {
         self.inner.fsync()
     }
@@ -144,6 +202,22 @@ impl File {
     ///
     /// Note that some platforms may simply implement this in terms of
     /// `sync_all`.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    /// use std::io::prelude::*;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// let mut f = try!(File::create("foo.txt"));
+    /// try!(f.write_all(b"Hello, world!"));
+    ///
+    /// try!(f.sync_data());
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn sync_data(&self) -> io::Result<()> {
         self.inner.datasync()
     }
@@ -155,11 +229,37 @@ impl File {
     /// be shrunk. If it is greater than the current file's size, then the file
     /// will be extended to `size` and have all of the intermediate data filled
     /// in with 0s.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// let mut f = try!(File::open("foo.txt"));
+    /// try!(f.set_len(0));
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn set_len(&self, size: u64) -> io::Result<()> {
         self.inner.truncate(size)
     }
 
-    /// Queries information about the underlying file.
+    /// Queries metadata about the underlying file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// let mut f = try!(File::open("foo.txt"));
+    /// let metadata = try!(f.metadata());
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn metadata(&self) -> io::Result<Metadata> {
         self.inner.file_attr().map(Metadata)
     }
@@ -168,33 +268,45 @@ impl File {
 impl AsInner<fs_imp::File> for File {
     fn as_inner(&self) -> &fs_imp::File { &self.inner }
 }
+impl FromInner<fs_imp::File> for File {
+    fn from_inner(f: fs_imp::File) -> File {
+        File { inner: f, path: None }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Read for File {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Write for File {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.write(buf)
     }
     fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Seek for File {
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         self.inner.seek(pos)
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Read for &'a File {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for &'a File {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.write(buf)
     }
     fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Seek for &'a File {
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         self.inner.seek(pos)
@@ -205,6 +317,7 @@ impl OpenOptions {
     /// Creates a blank net set of options ready for configuration.
     ///
     /// All options are initially set to `false`.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new() -> OpenOptions {
         OpenOptions(fs_imp::OpenOptions::new())
     }
@@ -213,6 +326,7 @@ impl OpenOptions {
     ///
     /// This option, when true, will indicate that the file should be
     /// `read`-able if opened.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn read(&mut self, read: bool) -> &mut OpenOptions {
         self.0.read(read); self
     }
@@ -221,6 +335,7 @@ impl OpenOptions {
     ///
     /// This option, when true, will indicate that the file should be
     /// `write`-able if opened.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn write(&mut self, write: bool) -> &mut OpenOptions {
         self.0.write(write); self
     }
@@ -229,6 +344,7 @@ impl OpenOptions {
     ///
     /// This option, when true, means that writes will append to a file instead
     /// of overwriting previous contents.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn append(&mut self, append: bool) -> &mut OpenOptions {
         self.0.append(append); self
     }
@@ -237,6 +353,7 @@ impl OpenOptions {
     ///
     /// If a file is successfully opened with this option set it will truncate
     /// the file to 0 length if it already exists.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions {
         self.0.truncate(truncate); self
     }
@@ -245,6 +362,7 @@ impl OpenOptions {
     ///
     /// This option indicates whether a new file will be created if the file
     /// does not yet already exist.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn create(&mut self, create: bool) -> &mut OpenOptions {
         self.0.create(create); self
     }
@@ -260,37 +378,33 @@ impl OpenOptions {
     /// * Attempting to open a file with access that the user lacks
     ///   permissions for
     /// * Filesystem-level errors (full disk, etc)
-    pub fn open<P: AsPath + ?Sized>(&self, path: &P) -> io::Result<File> {
-        let path = path.as_path();
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
+        let path = path.as_ref();
         let inner = try!(fs_imp::File::open(path, &self.0));
-
-        // On *BSD systems, we can open a directory as a file and read from
-        // it: fd=open("/tmp", O_RDONLY); read(fd, buf, N); due to an old
-        // tradition before the introduction of opendir(3).  We explicitly
-        // reject it because there are few use cases.
-        if cfg!(not(any(target_os = "linux", target_os = "android"))) &&
-           try!(inner.file_attr()).is_dir() {
-            Err(Error::new(ErrorKind::InvalidInput, "is a directory", None))
-        } else {
-            Ok(File { path: path.to_path_buf(), inner: inner })
-        }
+        Ok(File { path: Some(path.to_path_buf()), inner: inner })
     }
 }
+
 impl AsInnerMut<fs_imp::OpenOptions> for OpenOptions {
     fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions { &mut self.0 }
 }
 
 impl Metadata {
     /// Returns whether this metadata is for a directory.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_dir(&self) -> bool { self.0.is_dir() }
 
     /// Returns whether this metadata is for a regular file.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_file(&self) -> bool { self.0.is_file() }
 
     /// Returns the size of the file, in bytes, this metadata is for.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn len(&self) -> u64 { self.0.size() }
 
     /// Returns the permissions of the file this metadata is for.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn permissions(&self) -> Permissions {
         Permissions(self.0.perm())
     }
@@ -298,22 +412,32 @@ impl Metadata {
     /// Returns the most recent access time for a file.
     ///
     /// The return value is in milliseconds since the epoch.
+    #[unstable(feature = "fs_time",
+               reason = "the return type of u64 is not quite appropriate for \
+                         this method and may change if the standard library \
+                         gains a type to represent a moment in time")]
     pub fn accessed(&self) -> u64 { self.0.accessed() }
 
     /// Returns the most recent modification time for a file.
     ///
     /// The return value is in milliseconds since the epoch.
+    #[unstable(feature = "fs_time",
+               reason = "the return type of u64 is not quite appropriate for \
+                         this method and may change if the standard library \
+                         gains a type to represent a moment in time")]
     pub fn modified(&self) -> u64 { self.0.modified() }
 }
 
 impl Permissions {
     /// Returns whether these permissions describe a readonly file.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn readonly(&self) -> bool { self.0.readonly() }
 
     /// Modify the readonly flag for this set of permissions.
     ///
     /// This operation does **not** modify the filesystem. To modify the
     /// filesystem use the `fs::set_permissions` function.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn set_readonly(&mut self, readonly: bool) {
         self.0.set_readonly(readonly)
     }
@@ -325,6 +449,11 @@ impl FromInner<fs_imp::FilePermissions> for Permissions {
     }
 }
 
+impl AsInner<fs_imp::FilePermissions> for Permissions {
+    fn as_inner(&self) -> &fs_imp::FilePermissions { &self.0 }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Iterator for ReadDir {
     type Item = io::Result<DirEntry>;
 
@@ -333,17 +462,19 @@ impl Iterator for ReadDir {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl DirEntry {
     /// Returns the full path to the file that this entry represents.
     ///
     /// The full path is created by joining the original path to `read_dir` or
     /// `walk_dir` with the filename of this entry.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn path(&self) -> PathBuf { self.0.path() }
 }
 
 /// Remove a file from the underlying filesystem.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```rust,no_run
 /// use std::fs;
@@ -360,31 +491,9 @@ impl DirEntry {
 /// This function will return an error if `path` points to a directory, if the
 /// user lacks permissions to remove the file, or if some other filesystem-level
 /// error occurs.
-pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
-    let path = path.as_path();
-    let e = match fs_imp::unlink(path) {
-        Ok(()) => return Ok(()),
-        Err(e) => e,
-    };
-    if !cfg!(windows) { return Err(e) }
-
-    // On unix, a readonly file can be successfully removed. On windows,
-    // however, it cannot. To keep the two platforms in line with
-    // respect to their behavior, catch this case on windows, attempt to
-    // change it to read-write, and then remove the file.
-    if e.kind() != ErrorKind::PermissionDenied { return Err(e) }
-
-    let attr = match metadata(path) { Ok(a) => a, Err(..) => return Err(e) };
-    let mut perms = attr.permissions();
-    if !perms.readonly() { return Err(e) }
-    perms.set_readonly(false);
-
-    if set_permissions(path, perms).is_err() { return Err(e) }
-    if fs_imp::unlink(path).is_ok() { return Ok(()) }
-
-    // Oops, try to put things back the way we found it
-    let _ = set_permissions(path, attr.permissions());
-    Err(e)
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
+    fs_imp::unlink(path.as_ref())
 }
 
 /// Given a path, query the file system to get information about a file,
@@ -393,7 +502,7 @@ pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
 /// This function will traverse soft links to query information about the
 /// destination file.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```rust,no_run
 /// # fn foo() -> std::io::Result<()> {
@@ -410,13 +519,14 @@ pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
 /// This function will return an error if the user lacks the requisite
 /// permissions to perform a `metadata` call on the given `path` or if there
 /// is no entry in the filesystem at the provided path.
-pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<Metadata> {
-    fs_imp::stat(path.as_path()).map(Metadata)
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
+    fs_imp::stat(path.as_ref()).map(Metadata)
 }
 
 /// Rename a file or directory to a new name.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```rust,no_run
 /// use std::fs;
@@ -430,9 +540,9 @@ pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<Metadata> {
 /// the process lacks permissions to view the contents, if `from` and `to`
 /// reside on separate filesystems, or if some other intermittent I/O error
 /// occurs.
-pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
-                                                      -> io::Result<()> {
-    fs_imp::rename(from.as_path(), to.as_path())
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
+    fs_imp::rename(from.as_ref(), to.as_ref())
 }
 
 /// Copies the contents of one file to another. This function will also
@@ -443,9 +553,9 @@ pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
 /// Note that if `from` and `to` both point to the same file, then the file
 /// will likely get truncated by this operation.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::fs;
 ///
 /// fs::copy("foo.txt", "bar.txt");
@@ -460,13 +570,13 @@ pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
 /// * The `from` file does not exist
 /// * The current process does not have the permission rights to access
 ///   `from` or write `to`
-pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
-                                                    -> io::Result<u64> {
-    let from = from.as_path();
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
+    let from = from.as_ref();
+    let to = to.as_ref();
     if !from.is_file() {
-        return Err(Error::new(ErrorKind::MismatchedFileTypeForOperation,
-                              "the source path is not an existing file",
-                              None))
+        return Err(Error::new(ErrorKind::InvalidInput,
+                              "the source path is not an existing file"))
     }
 
     let mut reader = try!(File::open(from));
@@ -482,17 +592,17 @@ pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
 ///
 /// The `dst` path will be a link pointing to the `src` path. Note that systems
 /// often require these two paths to both be located on the same filesystem.
-pub fn hard_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
-                                                         -> io::Result<()> {
-    fs_imp::link(src.as_path(), dst.as_path())
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
+    fs_imp::link(src.as_ref(), dst.as_ref())
 }
 
 /// Creates a new soft link on the filesystem.
 ///
 /// The `dst` path will be a soft link pointing to the `src` path.
-pub fn soft_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
-                                                         -> io::Result<()> {
-    fs_imp::symlink(src.as_path(), dst.as_path())
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
+    fs_imp::symlink(src.as_ref(), dst.as_ref())
 }
 
 /// Reads a soft link, returning the file that the link points to.
@@ -502,15 +612,16 @@ pub fn soft_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
 /// This function will return an error on failure. Failure conditions include
 /// reading a file that does not exist or reading a file that is not a soft
 /// link.
-pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> {
-    fs_imp::readlink(path.as_path())
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
+    fs_imp::readlink(path.as_ref())
 }
 
 /// Create a new, empty directory at the provided path
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::fs;
 ///
 /// fs::create_dir("/some/dir");
@@ -520,8 +631,9 @@ pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> {
 ///
 /// This function will return an error if the user lacks permissions to make a
 /// new directory at the provided `path`, or if the directory already exists.
-pub fn create_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
-    fs_imp::mkdir(path.as_path())
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
+    fs_imp::mkdir(path.as_ref())
 }
 
 /// Recursively create a directory and all of its parent components if they
@@ -533,21 +645,19 @@ pub fn create_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
 /// does not already exist and it could not be created otherwise. The specific
 /// error conditions for when a directory is being created (after it is
 /// determined to not exist) are outlined by `fs::create_dir`.
-pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
-    let path = path.as_path();
-    if path.is_dir() { return Ok(()) }
-    match path.parent() {
-        Some(p) if p != path => try!(create_dir_all(p)),
-        _ => {}
-    }
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
+    let path = path.as_ref();
+    if path == Path::new("") || path.is_dir() { return Ok(()) }
+    if let Some(p) = path.parent() { try!(create_dir_all(p)) }
     create_dir(path)
 }
 
 /// Remove an existing, empty directory
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::fs;
 ///
 /// fs::remove_dir("/some/dir");
@@ -557,8 +667,9 @@ pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
 ///
 /// This function will return an error if the user lacks permissions to remove
 /// the directory at the provided `path`, or if the directory isn't empty.
-pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
-    fs_imp::rmdir(path.as_path())
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
+    fs_imp::rmdir(path.as_ref())
 }
 
 /// Removes a directory at this path, after removing all its contents. Use
@@ -570,8 +681,9 @@ pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
 /// # Errors
 ///
 /// See `file::remove_file` and `fs::remove_dir`
-pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
-    let path = path.as_path();
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
+    let path = path.as_ref();
     for child in try!(read_dir(path)) {
         let child = try!(child).path();
         let stat = try!(lstat(&*child));
@@ -594,9 +706,10 @@ pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
 /// The iterator will yield instances of `io::Result<DirEntry>`. New errors may
 /// be encountered after an iterator is initially constructed.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(path_ext)]
 /// use std::io;
 /// use std::fs::{self, PathExt, DirEntry};
 /// use std::path::Path;
@@ -622,8 +735,9 @@ pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
 /// This function will return an error if the provided `path` doesn't exist, if
 /// the process lacks permissions to view the contents or if the `path` points
 /// at a non-directory file
-pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<ReadDir> {
-    fs_imp::readdir(path.as_path()).map(ReadDir)
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
+    fs_imp::readdir(path.as_ref()).map(ReadDir)
 }
 
 /// Returns an iterator that will recursively walk the directory structure
@@ -634,11 +748,16 @@ pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<ReadDir> {
 ///
 /// The iterator will yield instances of `io::Result<DirEntry>`. New errors may
 /// be encountered after an iterator is initially constructed.
-pub fn walk_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<WalkDir> {
+#[unstable(feature = "fs_walk",
+           reason = "the precise semantics and defaults for a recursive walk \
+                     may change and this may end up accounting for files such \
+                     as symlinks differently")]
+pub fn walk_dir<P: AsRef<Path>>(path: P) -> io::Result<WalkDir> {
     let start = try!(read_dir(path));
     Ok(WalkDir { cur: Some(start), stack: Vec::new() })
 }
 
+#[unstable(feature = "fs_walk")]
 impl Iterator for WalkDir {
     type Item = io::Result<DirEntry>;
 
@@ -668,6 +787,9 @@ impl Iterator for WalkDir {
 }
 
 /// Utility methods for paths.
+#[unstable(feature = "path_ext",
+           reason = "the precise set of methods exposed on this trait may \
+                     change and some methods may be removed")]
 pub trait PathExt {
     /// Get information on the file, directory, etc at this path.
     ///
@@ -712,16 +834,21 @@ impl PathExt for Path {
 /// The file at the path specified will have its last access time set to
 /// `atime` and its modification time set to `mtime`. The times specified should
 /// be in milliseconds.
-pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64,
-                                          modified: u64) -> io::Result<()> {
-    fs_imp::utimes(path.as_path(), accessed, modified)
+#[unstable(feature = "fs_time",
+           reason = "the argument type of u64 is not quite appropriate for \
+                     this function and may change if the standard library \
+                     gains a type to represent a moment in time")]
+pub fn set_file_times<P: AsRef<Path>>(path: P, accessed: u64,
+                                 modified: u64) -> io::Result<()> {
+    fs_imp::utimes(path.as_ref(), accessed, modified)
 }
 
 /// Changes the permissions found on a file or a directory.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
+/// # #![feature(fs)]
 /// # fn foo() -> std::io::Result<()> {
 /// use std::fs;
 ///
@@ -737,16 +864,22 @@ pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64,
 /// This function will return an error if the provided `path` doesn't exist, if
 /// the process lacks permissions to change the attributes of the file, or if
 /// some other I/O error is encountered.
-pub fn set_permissions<P: AsPath + ?Sized>(path: &P, perm: Permissions)
-                                           -> io::Result<()> {
-    fs_imp::set_perm(path.as_path(), perm.0)
+#[unstable(feature = "fs",
+           reason = "a more granual ability to set specific permissions may \
+                     be exposed on the Permissions structure itself and this \
+                     method may not always exist")]
+pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions) -> io::Result<()> {
+    fs_imp::set_perm(path.as_ref(), perm.0)
 }
 
 #[cfg(test)]
 mod tests {
+    #![allow(deprecated)] //rand
+
     use prelude::v1::*;
     use io::prelude::*;
 
+    use env;
     use fs::{self, File, OpenOptions};
     use io::{ErrorKind, SeekFrom};
     use path::PathBuf;
@@ -765,7 +898,7 @@ mod tests {
     macro_rules! error { ($e:expr, $s:expr) => (
         match $e {
             Ok(_) => panic!("Unexpected success. Should've been: {:?}", $s),
-            Err(ref err) => assert!(err.to_string().contains($s.as_slice()),
+            Err(ref err) => assert!(err.to_string().contains($s),
                                     format!("`{}` did not contain `{}`", err, $s))
         }
     ) }
@@ -794,8 +927,7 @@ mod tests {
     }
 
     pub fn tmpdir() -> TempDir {
-        let s = os::tmpdir();
-        let p = Path2::new(s.as_str().unwrap());
+        let p = env::temp_dir();
         let ret = p.join(&format!("rust-{}", rand::random::<u32>()));
         check!(fs::create_dir(&ret));
         TempDir(ret)
@@ -814,10 +946,10 @@ mod tests {
             let mut read_stream = check!(File::open(filename));
             let mut read_buf = [0; 1028];
             let read_str = match check!(read_stream.read(&mut read_buf)) {
-                -1|0 => panic!("shouldn't happen"),
+                0 => panic!("shouldn't happen"),
                 n => str::from_utf8(&read_buf[..n]).unwrap().to_string()
             };
-            assert_eq!(read_str.as_slice(), message);
+            assert_eq!(read_str, message);
         }
         check!(fs::remove_file(filename));
     }
@@ -1028,15 +1160,15 @@ mod tests {
         let dir = &tmpdir.join("di_readdir");
         check!(fs::create_dir(dir));
         let prefix = "foo";
-        for n in range(0, 3) {
+        for n in 0..3 {
             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_bytes();
             check!(w.write(msg));
         }
-        let mut files = check!(fs::read_dir(dir));
-        let mut mem = [0u8; 4];
+        let files = check!(fs::read_dir(dir));
+        let mut mem = [0; 4];
         for f in files {
             let f = f.unwrap().path();
             {
@@ -1044,7 +1176,7 @@ mod tests {
                 check!(check!(File::open(&f)).read(&mut mem));
                 let read_str = str::from_utf8(&mem).unwrap();
                 let expected = format!("{}{}", prefix, n.to_str().unwrap());
-                assert_eq!(expected.as_slice(), read_str);
+                assert_eq!(expected, read_str);
             }
             check!(fs::remove_file(&f));
         }
@@ -1065,8 +1197,8 @@ mod tests {
         check!(fs::create_dir_all(dir2));
         check!(File::create(&dir2.join("14")));
 
-        let mut files = check!(fs::walk_dir(dir));
-        let mut cur = [0u8; 2];
+        let files = check!(fs::walk_dir(dir));
+        let mut cur = [0; 2];
         for f in files {
             let f = f.unwrap().path();
             let stem = f.file_stem().unwrap().to_str().unwrap();
@@ -1085,7 +1217,7 @@ mod tests {
         let dir = &tmpdir.join("mkdir_error_twice");
         check!(fs::create_dir(dir));
         let e = fs::create_dir(dir).err().unwrap();
-        assert_eq!(e.kind(), ErrorKind::PathAlreadyExists);
+        assert_eq!(e.kind(), ErrorKind::AlreadyExists);
     }
 
     #[test]
@@ -1195,7 +1327,7 @@ mod tests {
         check!(fs::copy(&input, &out));
         let mut v = Vec::new();
         check!(check!(File::open(&out)).read_to_end(&mut v));
-        assert_eq!(v.as_slice(), b"hello");
+        assert_eq!(v, b"hello");
 
         assert_eq!(check!(input.metadata()).permissions(),
                    check!(out.metadata()).permissions());
@@ -1250,6 +1382,8 @@ mod tests {
         check!(fs::set_permissions(&input, p));
         check!(fs::copy(&input, &out));
         assert!(check!(out.metadata()).permissions().readonly());
+        check!(fs::set_permissions(&input, attr.permissions()));
+        check!(fs::set_permissions(&out, attr.permissions()));
     }
 
     #[cfg(not(windows))] // FIXME(#10264) operation not permitted?
@@ -1333,10 +1467,13 @@ mod tests {
         let attr = check!(fs::metadata(&file));
         assert!(attr.permissions().readonly());
 
-        match fs::set_permissions(&tmpdir.join("foo"), p) {
-            Ok(..) => panic!("wanted a panic"),
+        match fs::set_permissions(&tmpdir.join("foo"), p.clone()) {
+            Ok(..) => panic!("wanted an error"),
             Err(..) => {}
         }
+
+        p.set_readonly(false);
+        check!(fs::set_permissions(&file, p));
     }
 
     #[test]
@@ -1374,7 +1511,7 @@ mod tests {
         assert_eq!(v, b"foobar\0\0\0\0".to_vec());
 
         // Truncate to a smaller length, don't seek, and then write something.
-        // Ensure that the intermediate zeroes are all filled in (we're seeked
+        // Ensure that the intermediate zeroes are all filled in (we have `seek`ed
         // past the end of the file).
         check!(file.set_len(2));
         assert_eq!(check!(file.metadata()).len(), 2);
@@ -1478,17 +1615,18 @@ mod tests {
     #[test]
     fn binary_file() {
         let mut bytes = [0; 1024];
-        StdRng::new().ok().unwrap().fill_bytes(&mut bytes);
+        StdRng::new().unwrap().fill_bytes(&mut bytes);
 
         let tmpdir = tmpdir();
 
         check!(check!(File::create(&tmpdir.join("test"))).write(&bytes));
         let mut v = Vec::new();
         check!(check!(File::open(&tmpdir.join("test"))).read_to_end(&mut v));
-        assert!(v == bytes.as_slice());
+        assert!(v == &bytes[..]);
     }
 
     #[test]
+    #[cfg(not(windows))]
     fn unlink_readonly() {
         let tmpdir = tmpdir();
         let path = tmpdir.join("file");
@@ -1498,4 +1636,11 @@ mod tests {
         check!(fs::set_permissions(&path, perm));
         check!(fs::remove_file(&path));
     }
+
+    #[test]
+    fn mkdir_trailing_slash() {
+        let tmpdir = tmpdir();
+        let path = tmpdir.join("file");
+        check!(fs::create_dir_all(&path.join("a/")));
+    }
 }
index e9a8dbb4098afb3f15340725b35894ae409cf20b..6fe35614a85b6da4e61be246ba0ab116cae70854 100644 (file)
@@ -16,11 +16,11 @@ use prelude::v1::*;
 use io::prelude::*;
 
 use cmp;
-use error::Error as StdError;
-use error::FromError;
+use error;
 use fmt;
-use io::{self, Cursor, DEFAULT_BUF_SIZE, Error, ErrorKind};
+use io::{self, DEFAULT_BUF_SIZE, Error, ErrorKind};
 use ptr;
+use iter;
 
 /// Wraps a `Read` and buffers input from it
 ///
@@ -28,79 +28,95 @@ use ptr;
 /// For example, every call to `read` on `TcpStream` results in a system call.
 /// A `BufReader` performs large, infrequent reads on the underlying `Read`
 /// and maintains an in-memory buffer of the results.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct BufReader<R> {
     inner: R,
-    buf: Cursor<Vec<u8>>,
+    buf: Vec<u8>,
+    pos: usize,
+    cap: usize,
 }
 
 impl<R: Read> BufReader<R> {
     /// Creates a new `BufReader` with a default buffer capacity
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: R) -> BufReader<R> {
         BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
     }
 
     /// Creates a new `BufReader` with the specified buffer capacity
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(cap: usize, inner: R) -> BufReader<R> {
+        let mut buf = Vec::with_capacity(cap);
+        buf.extend(iter::repeat(0).take(cap));
         BufReader {
             inner: inner,
-            buf: Cursor::new(Vec::with_capacity(cap)),
+            buf: buf,
+            pos: 0,
+            cap: 0,
         }
     }
 
     /// Gets a reference to the underlying reader.
-    pub fn get_ref<'a>(&self) -> &R { &self.inner }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get_ref(&self) -> &R { &self.inner }
 
     /// Gets a mutable reference to the underlying reader.
     ///
     /// # Warning
     ///
     /// It is inadvisable to directly read from the underlying reader.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut R { &mut self.inner }
 
     /// Unwraps this `BufReader`, returning the underlying reader.
     ///
     /// Note that any leftover data in the internal buffer is lost.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> R { self.inner }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<R: Read> Read for BufReader<R> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         // If we don't have any buffered data and we're doing a massive read
         // (larger than our internal buffer), bypass our internal buffer
         // entirely.
-        if self.buf.get_ref().len() == self.buf.position() as usize &&
-            buf.len() >= self.buf.get_ref().capacity() {
+        if self.pos == self.cap && buf.len() >= self.buf.len() {
             return self.inner.read(buf);
         }
-        try!(self.fill_buf());
-        self.buf.read(buf)
+        let nread = {
+            let mut rem = try!(self.fill_buf());
+            try!(rem.read(buf))
+        };
+        self.consume(nread);
+        Ok(nread)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<R: Read> BufRead for BufReader<R> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> {
         // If we've reached the end of our internal buffer then we need to fetch
         // some more data from the underlying reader.
-        if self.buf.position() as usize == self.buf.get_ref().len() {
-            self.buf.set_position(0);
-            let v = self.buf.get_mut();
-            v.truncate(0);
-            let inner = &mut self.inner;
-            try!(super::with_end_to_cap(v, |b| inner.read(b)));
+        if self.pos == self.cap {
+            self.cap = try!(self.inner.read(&mut self.buf));
+            self.pos = 0;
         }
-        self.buf.fill_buf()
+        Ok(&self.buf[self.pos..self.cap])
     }
 
-    fn consume(&mut self, amt: uint) {
-        self.buf.consume(amt)
+    fn consume(&mut self, amt: usize) {
+        self.pos = cmp::min(self.pos + amt, self.cap);
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<R> fmt::Debug for BufReader<R> where R: fmt::Debug {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        write!(fmt, "BufReader {{ reader: {:?}, buffer: {}/{} }}",
-               self.inner, self.buf.position(), self.buf.get_ref().len())
+        fmt.debug_struct("BufReader")
+            .field("reader", &self.inner)
+            .field("buffer", &format_args!("{}/{}", self.cap - self.pos, self.buf.len()))
+            .finish()
     }
 }
 
@@ -111,24 +127,29 @@ impl<R> fmt::Debug for BufReader<R> where R: fmt::Debug {
 /// `BufWriter` keeps an in memory buffer of data and writes it to the
 /// underlying `Write` in large, infrequent batches.
 ///
-/// This writer will be flushed when it is dropped.
-pub struct BufWriter<W> {
+/// The buffer will be written out when the writer is dropped.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct BufWriter<W: Write> {
     inner: Option<W>,
     buf: Vec<u8>,
 }
 
-/// An error returned by `into_inner` which indicates whether a flush error
-/// happened or not.
+/// An error returned by `into_inner` which combines an error that
+/// happened while writing out the buffer, and the buffered writer object
+/// which may be used to recover from the condition.
 #[derive(Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoInnerError<W>(W, Error);
 
 impl<W: Write> BufWriter<W> {
     /// Creates a new `BufWriter` with a default buffer capacity
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: W) -> BufWriter<W> {
         BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
     }
 
     /// Creates a new `BufWriter` with the specified buffer capacity
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(cap: usize, inner: W) -> BufWriter<W> {
         BufWriter {
             inner: Some(inner),
@@ -144,10 +165,11 @@ impl<W: Write> BufWriter<W> {
             match self.inner.as_mut().unwrap().write(&self.buf[written..]) {
                 Ok(0) => {
                     ret = Err(Error::new(ErrorKind::WriteZero,
-                                         "failed to flush", None));
+                                         "failed to write the buffered data"));
                     break;
                 }
                 Ok(n) => written += n,
+                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
                 Err(e) => { ret = Err(e); break }
 
             }
@@ -155,9 +177,9 @@ impl<W: Write> BufWriter<W> {
         if written > 0 {
             // NB: would be better expressed as .remove(0..n) if it existed
             unsafe {
-                ptr::copy_memory(self.buf.as_mut_ptr(),
-                                 self.buf.as_ptr().offset(written as isize),
-                                 len - written);
+                ptr::copy(self.buf.as_ptr().offset(written as isize),
+                          self.buf.as_mut_ptr(),
+                          len - written);
             }
         }
         self.buf.truncate(len - written);
@@ -165,6 +187,7 @@ impl<W: Write> BufWriter<W> {
     }
 
     /// Gets a reference to the underlying writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
 
     /// Gets a mutable reference to the underlying write.
@@ -172,11 +195,13 @@ impl<W: Write> BufWriter<W> {
     /// # Warning
     ///
     /// It is inadvisable to directly read from the underlying writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut W { self.inner.as_mut().unwrap() }
 
     /// Unwraps this `BufWriter`, returning the underlying writer.
     ///
-    /// The buffer is flushed before returning the writer.
+    /// The buffer is written out before returning the writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
         match self.flush_buf() {
             Err(e) => Err(IntoInnerError(self, e)),
@@ -185,6 +210,7 @@ impl<W: Write> BufWriter<W> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<W: Write> Write for BufWriter<W> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         if self.buf.len() + buf.len() > self.buf.capacity() {
@@ -203,10 +229,12 @@ impl<W: Write> Write for BufWriter<W> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W> fmt::Debug for BufWriter<W> where W: fmt::Debug {
+impl<W: Write> fmt::Debug for BufWriter<W> where W: fmt::Debug {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        write!(fmt, "BufWriter {{ writer: {:?}, buffer: {}/{} }}",
-               self.inner.as_ref().unwrap(), self.buf.len(), self.buf.capacity())
+        fmt.debug_struct("BufWriter")
+            .field("writer", &self.inner.as_ref().unwrap())
+            .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
+            .finish()
     }
 }
 
@@ -223,24 +251,31 @@ impl<W: Write> Drop for BufWriter<W> {
 impl<W> IntoInnerError<W> {
     /// Returns the error which caused the call to `into_inner` to fail.
     ///
-    /// This error was returned when attempting to flush the internal buffer.
+    /// This error was returned when attempting to write the internal buffer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn error(&self) -> &Error { &self.1 }
 
-    /// Returns the underlying `BufWriter` instance which generated the error.
+    /// Returns the buffered writer instance which generated the error.
     ///
-    /// The returned object can be used to retry a flush or re-inspect the
-    /// buffer.
+    /// The returned object can be used for error recovery, such as
+    /// re-inspecting the buffer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> W { self.0 }
 }
 
-impl<W> FromError<IntoInnerError<W>> for Error {
-    fn from_error(iie: IntoInnerError<W>) -> Error { iie.1 }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<W> From<IntoInnerError<W>> for Error {
+    fn from(iie: IntoInnerError<W>) -> Error { iie.1 }
 }
 
-impl<W> StdError for IntoInnerError<W> {
-    fn description(&self) -> &str { self.error().description() }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<W: Send + fmt::Debug> error::Error for IntoInnerError<W> {
+    fn description(&self) -> &str {
+        error::Error::description(self.error())
+    }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<W> fmt::Display for IntoInnerError<W> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.error().fmt(f)
@@ -250,27 +285,42 @@ impl<W> fmt::Display for IntoInnerError<W> {
 /// Wraps a Writer and buffers output to it, flushing whenever a newline
 /// (`0x0a`, `'\n'`) is detected.
 ///
-/// This writer will be flushed when it is dropped.
-pub struct LineWriter<W> {
+/// The buffer will be written out when the writer is dropped.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct LineWriter<W: Write> {
     inner: BufWriter<W>,
 }
 
 impl<W: Write> LineWriter<W> {
     /// Creates a new `LineWriter`
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: W) -> LineWriter<W> {
         // Lines typically aren't that long, don't use a giant buffer
-        LineWriter { inner: BufWriter::with_capacity(1024, inner) }
+        LineWriter::with_capacity(1024, inner)
+    }
+
+    /// Creates a new `LineWriter` with a specified capacity for the internal
+    /// buffer.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn with_capacity(cap: usize, inner: W) -> LineWriter<W> {
+        LineWriter { inner: BufWriter::with_capacity(cap, inner) }
     }
 
     /// Gets a reference to the underlying writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get_ref(&self) -> &W { self.inner.get_ref() }
+
+    /// Gets a mutable reference to the underlying writer.
     ///
-    /// This type does not expose the ability to get a mutable reference to the
-    /// underlying reader because that could possibly corrupt the buffer.
-    pub fn get_ref<'a>(&'a self) -> &'a W { self.inner.get_ref() }
+    /// Caution must be taken when calling methods on the mutable reference
+    /// returned as extra writes could corrupt the output stream.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn get_mut(&mut self) -> &mut W { self.inner.get_mut() }
 
     /// Unwraps this `LineWriter`, returning the underlying writer.
     ///
-    /// The internal buffer is flushed before returning the writer.
+    /// The internal buffer is written out before returning the writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> Result<W, IntoInnerError<LineWriter<W>>> {
         self.inner.into_inner().map_err(|IntoInnerError(buf, e)| {
             IntoInnerError(LineWriter { inner: buf }, e)
@@ -278,6 +328,7 @@ impl<W: Write> LineWriter<W> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<W: Write> Write for LineWriter<W> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         match buf.rposition_elem(&b'\n') {
@@ -295,24 +346,26 @@ impl<W: Write> Write for LineWriter<W> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W> fmt::Debug for LineWriter<W> where W: fmt::Debug {
+impl<W: Write> fmt::Debug for LineWriter<W> where W: fmt::Debug {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        write!(fmt, "LineWriter {{ writer: {:?}, buffer: {}/{} }}",
-               self.inner.inner, self.inner.buf.len(),
-               self.inner.buf.capacity())
+        fmt.debug_struct("LineWriter")
+            .field("writer", &self.inner.inner)
+            .field("buffer",
+                   &format_args!("{}/{}", self.inner.buf.len(), self.inner.buf.capacity()))
+            .finish()
     }
 }
 
-struct InternalBufWriter<W>(BufWriter<W>);
+struct InternalBufWriter<W: Write>(BufWriter<W>);
 
-impl<W> InternalBufWriter<W> {
+impl<W: Read + Write> InternalBufWriter<W> {
     fn get_mut(&mut self) -> &mut BufWriter<W> {
         let InternalBufWriter(ref mut w) = *self;
         return w;
     }
 }
 
-impl<W: Read> Read for InternalBufWriter<W> {
+impl<W: Read + Write> Read for InternalBufWriter<W> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.get_mut().inner.as_mut().unwrap().read(buf)
     }
@@ -320,19 +373,21 @@ impl<W: Read> Read for InternalBufWriter<W> {
 
 /// Wraps a Stream and buffers input and output to and from it.
 ///
-/// It can be excessively inefficient to work directly with a `Stream`. For
+/// It can be excessively inefficient to work directly with a `Read+Write`. For
 /// example, every call to `read` or `write` on `TcpStream` results in a system
 /// call. A `BufStream` keeps in memory buffers of data, making large,
-/// infrequent calls to `read` and `write` on the underlying `Stream`.
+/// infrequent calls to `read` and `write` on the underlying `Read+Write`.
 ///
-/// The output half will be flushed when this stream is dropped.
-pub struct BufStream<S> {
+/// The output buffer will be written out when this stream is dropped.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct BufStream<S: Write> {
     inner: BufReader<InternalBufWriter<S>>
 }
 
 impl<S: Read + Write> BufStream<S> {
     /// Creates a new buffered stream with explicitly listed capacities for the
     /// reader/writer buffer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacities(reader_cap: usize, writer_cap: usize, inner: S)
                            -> BufStream<S> {
         let writer = BufWriter::with_capacity(writer_cap, inner);
@@ -343,11 +398,13 @@ impl<S: Read + Write> BufStream<S> {
 
     /// Creates a new buffered stream with the default reader/writer buffer
     /// capacities.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: S) -> BufStream<S> {
         BufStream::with_capacities(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE, inner)
     }
 
     /// Gets a reference to the underlying stream.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_ref(&self) -> &S {
         let InternalBufWriter(ref w) = self.inner.inner;
         w.get_ref()
@@ -359,6 +416,7 @@ impl<S: Read + Write> BufStream<S> {
     ///
     /// It is inadvisable to read directly from or write directly to the
     /// underlying stream.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut S {
         let InternalBufWriter(ref mut w) = self.inner.inner;
         w.get_mut()
@@ -366,29 +424,33 @@ impl<S: Read + Write> BufStream<S> {
 
     /// Unwraps this `BufStream`, returning the underlying stream.
     ///
-    /// The internal buffer is flushed before returning the stream. Any leftover
-    /// data in the read buffer is lost.
+    /// The internal write buffer is written out before returning the stream.
+    /// Any leftover data in the read buffer is lost.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> Result<S, IntoInnerError<BufStream<S>>> {
-        let BufReader { inner: InternalBufWriter(w), buf } = self.inner;
+        let BufReader { inner: InternalBufWriter(w), buf, pos, cap } = self.inner;
         w.into_inner().map_err(|IntoInnerError(w, e)| {
             IntoInnerError(BufStream {
-                inner: BufReader { inner: InternalBufWriter(w), buf: buf },
+                inner: BufReader { inner: InternalBufWriter(w), buf: buf, pos: pos, cap: cap },
             }, e)
         })
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<S: Read + Write> BufRead for BufStream<S> {
     fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
-    fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
+    fn consume(&mut self, amt: usize) { self.inner.consume(amt) }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<S: Read + Write> Read for BufStream<S> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<S: Read + Write> Write for BufStream<S> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.inner.get_mut().write(buf)
@@ -399,14 +461,16 @@ impl<S: Read + Write> Write for BufStream<S> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<S> fmt::Debug for BufStream<S> where S: fmt::Debug {
+impl<S: Write> fmt::Debug for BufStream<S> where S: fmt::Debug {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let reader = &self.inner;
         let writer = &self.inner.inner.0;
-        write!(fmt, "BufStream {{ stream: {:?}, write_buffer: {}/{}, read_buffer: {}/{} }}",
-               writer.inner,
-               writer.buf.len(), writer.buf.capacity(),
-               reader.buf.position(), reader.buf.get_ref().len())
+        fmt.debug_struct("BufStream")
+            .field("stream", &writer.inner)
+            .field("write_buffer", &format_args!("{}/{}", writer.buf.len(), writer.buf.capacity()))
+            .field("read_buffer",
+                   &format_args!("{}/{}", reader.cap - reader.pos, reader.buf.len()))
+            .finish()
     }
 }
 
@@ -439,34 +503,34 @@ mod tests {
 
         let mut buf = [0, 0, 0];
         let nread = reader.read(&mut buf);
-        assert_eq!(Ok(3), nread);
+        assert_eq!(nread.unwrap(), 3);
         let b: &[_] = &[5, 6, 7];
         assert_eq!(buf, b);
 
         let mut buf = [0, 0];
         let nread = reader.read(&mut buf);
-        assert_eq!(Ok(2), nread);
+        assert_eq!(nread.unwrap(), 2);
         let b: &[_] = &[0, 1];
         assert_eq!(buf, b);
 
         let mut buf = [0];
         let nread = reader.read(&mut buf);
-        assert_eq!(Ok(1), nread);
+        assert_eq!(nread.unwrap(), 1);
         let b: &[_] = &[2];
         assert_eq!(buf, b);
 
         let mut buf = [0, 0, 0];
         let nread = reader.read(&mut buf);
-        assert_eq!(Ok(1), nread);
+        assert_eq!(nread.unwrap(), 1);
         let b: &[_] = &[3, 0, 0];
         assert_eq!(buf, b);
 
         let nread = reader.read(&mut buf);
-        assert_eq!(Ok(1), nread);
+        assert_eq!(nread.unwrap(), 1);
         let b: &[_] = &[4, 0, 0];
         assert_eq!(buf, b);
 
-        assert_eq!(reader.read(&mut buf), Ok(0));
+        assert_eq!(reader.read(&mut buf).unwrap(), 0);
     }
 
     #[test]
@@ -497,7 +561,6 @@ mod tests {
         assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]);
 
         writer.write(&[9, 10, 11]).unwrap();
-        let a: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
         assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
 
         writer.flush().unwrap();
@@ -529,7 +592,7 @@ mod tests {
         }
 
         let mut stream = BufStream::new(S);
-        assert_eq!(stream.read(&mut [0; 10]), Ok(0));
+        assert_eq!(stream.read(&mut [0; 10]).unwrap(), 0);
         stream.write(&[0; 10]).unwrap();
         stream.flush().unwrap();
     }
@@ -574,7 +637,7 @@ mod tests {
 
     #[test]
     fn test_read_line() {
-        let in_buf = b"a\nb\nc";
+        let in_buf: &[u8] = b"a\nb\nc";
         let mut reader = BufReader::with_capacity(2, in_buf);
         let mut s = String::new();
         reader.read_line(&mut s).unwrap();
@@ -592,13 +655,13 @@ mod tests {
 
     #[test]
     fn test_lines() {
-        let in_buf = b"a\nb\nc";
-        let mut reader = BufReader::with_capacity(2, in_buf);
+        let in_buf: &[u8] = b"a\nb\nc";
+        let reader = BufReader::with_capacity(2, in_buf);
         let mut it = reader.lines();
-        assert_eq!(it.next(), Some(Ok("a".to_string())));
-        assert_eq!(it.next(), Some(Ok("b".to_string())));
-        assert_eq!(it.next(), Some(Ok("c".to_string())));
-        assert_eq!(it.next(), None);
+        assert_eq!(it.next().unwrap().unwrap(), "a".to_string());
+        assert_eq!(it.next().unwrap().unwrap(), "b".to_string());
+        assert_eq!(it.next().unwrap().unwrap(), "c".to_string());
+        assert!(it.next().is_none());
     }
 
     #[test]
@@ -606,34 +669,34 @@ mod tests {
         let inner = ShortReader{lengths: vec![0, 1, 2, 0, 1, 0]};
         let mut reader = BufReader::new(inner);
         let mut buf = [0, 0];
-        assert_eq!(reader.read(&mut buf), Ok(0));
-        assert_eq!(reader.read(&mut buf), Ok(1));
-        assert_eq!(reader.read(&mut buf), Ok(2));
-        assert_eq!(reader.read(&mut buf), Ok(0));
-        assert_eq!(reader.read(&mut buf), Ok(1));
-        assert_eq!(reader.read(&mut buf), Ok(0));
-        assert_eq!(reader.read(&mut buf), Ok(0));
+        assert_eq!(reader.read(&mut buf).unwrap(), 0);
+        assert_eq!(reader.read(&mut buf).unwrap(), 1);
+        assert_eq!(reader.read(&mut buf).unwrap(), 2);
+        assert_eq!(reader.read(&mut buf).unwrap(), 0);
+        assert_eq!(reader.read(&mut buf).unwrap(), 1);
+        assert_eq!(reader.read(&mut buf).unwrap(), 0);
+        assert_eq!(reader.read(&mut buf).unwrap(), 0);
     }
 
     #[test]
     fn read_char_buffered() {
-        let buf = [195u8, 159u8];
-        let mut reader = BufReader::with_capacity(1, &buf[..]);
-        assert_eq!(reader.chars().next(), Some(Ok('ß')));
+        let buf = [195, 159];
+        let reader = BufReader::with_capacity(1, &buf[..]);
+        assert_eq!(reader.chars().next().unwrap().unwrap(), 'ß');
     }
 
     #[test]
     fn test_chars() {
-        let buf = [195u8, 159u8, b'a'];
-        let mut reader = BufReader::with_capacity(1, &buf[..]);
+        let buf = [195, 159, b'a'];
+        let reader = BufReader::with_capacity(1, &buf[..]);
         let mut it = reader.chars();
-        assert_eq!(it.next(), Some(Ok('ß')));
-        assert_eq!(it.next(), Some(Ok('a')));
-        assert_eq!(it.next(), None);
+        assert_eq!(it.next().unwrap().unwrap(), 'ß');
+        assert_eq!(it.next().unwrap().unwrap(), 'a');
+        assert!(it.next().is_none());
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn dont_panic_in_drop_on_panicked_flush() {
         struct FailFlushWriter;
 
index f6cb4a8c9f36988f3b834b55261f1394eda32e70..6433c29bb9d6e456d0701828cd576c58d2afe591 100644 (file)
@@ -8,30 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(missing_copy_implementations)]
-
 use prelude::v1::*;
 use io::prelude::*;
 
 use cmp;
 use io::{self, SeekFrom, Error, ErrorKind};
 use iter::repeat;
-use num::Int;
 use slice;
 
-/// A `Cursor` is a type which wraps another I/O object to provide a `Seek`
+/// A `Cursor` is a type which wraps a non-I/O object to provide a `Seek`
 /// implementation.
 ///
-/// Cursors are currently typically used with memory buffer objects in order to
-/// allow `Seek` plus `Read` and `Write` implementations. For example, common
-/// cursor types include:
-///
-/// * `Cursor<Vec<u8>>`
-/// * `Cursor<&[u8]>`
+/// Cursors are typically used with memory buffer objects in order to allow
+/// `Seek`, `Read`, and `Write` implementations. For example, common cursor types
+/// include `Cursor<Vec<u8>>` and `Cursor<&[u8]>`.
 ///
-/// Implementations of the I/O traits for `Cursor<T>` are not currently generic
+/// Implementations of the I/O traits for `Cursor<T>` are currently not generic
 /// over `T` itself. Instead, specific implementations are provided for various
 /// in-memory buffer types like `Vec<u8>` and `&[u8]`.
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Clone, Debug)]
 pub struct Cursor<T> {
     inner: T,
     pos: u64,
@@ -39,26 +35,32 @@ pub struct Cursor<T> {
 
 impl<T> Cursor<T> {
     /// Create a new cursor wrapping the provided underlying I/O object.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(inner: T) -> Cursor<T> {
         Cursor { pos: 0, inner: inner }
     }
 
     /// Consume this cursor, returning the underlying value.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_inner(self) -> T { self.inner }
 
     /// Get a reference to the underlying value in this cursor.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_ref(&self) -> &T { &self.inner }
 
     /// Get a mutable reference to the underlying value in this cursor.
     ///
     /// Care should be taken to avoid modifying the internal I/O state of the
     /// underlying value as it may corrupt this cursor's position.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut T { &mut self.inner }
 
     /// Returns the current value of this cursor
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn position(&self) -> u64 { self.pos }
 
     /// Sets the value of this cursor
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn set_position(&mut self, pos: u64) { self.pos = pos; }
 }
 
@@ -73,8 +75,7 @@ macro_rules! seek {
 
             if pos < 0 {
                 Err(Error::new(ErrorKind::InvalidInput,
-                               "invalid seek to a negative position",
-                               None))
+                               "invalid seek to a negative position"))
             } else {
                 self.pos = pos as u64;
                 Ok(self.pos)
@@ -83,8 +84,11 @@ macro_rules! seek {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> io::Seek for Cursor<&'a [u8]> { seek!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> io::Seek for Cursor<&'a mut [u8]> { seek!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl io::Seek for Cursor<Vec<u8>> { seek!(); }
 
 macro_rules! read {
@@ -97,8 +101,11 @@ macro_rules! read {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Read for Cursor<&'a [u8]> { read!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Read for Cursor<&'a mut [u8]> { read!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Read for Cursor<Vec<u8>> { read!(); }
 
 macro_rules! buffer {
@@ -111,10 +118,14 @@ macro_rules! buffer {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> BufRead for Cursor<&'a [u8]> { buffer!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> BufRead for Cursor<&'a mut [u8]> { buffer!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> BufRead for Cursor<Vec<u8>> { buffer!(); }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for Cursor<&'a mut [u8]> {
     fn write(&mut self, data: &[u8]) -> io::Result<usize> {
         let pos = cmp::min(self.pos, self.inner.len() as u64);
@@ -125,6 +136,7 @@ impl<'a> Write for Cursor<&'a mut [u8]> {
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Write for Cursor<Vec<u8>> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         // Make sure the internal buffer is as least as big as where we
@@ -137,7 +149,7 @@ impl Write for Cursor<Vec<u8>> {
         // there (left), and what will be appended on the end (right)
         let space = self.inner.len() - pos as usize;
         let (left, right) = buf.split_at(cmp::min(space, buf.len()));
-        slice::bytes::copy_memory(&mut self.inner[(pos as usize)..], left);
+        slice::bytes::copy_memory(left, &mut self.inner[(pos as usize)..]);
         self.inner.push_all(right);
 
         // Bump us forward
@@ -159,9 +171,9 @@ mod tests {
     #[test]
     fn test_vec_writer() {
         let mut writer = Vec::new();
-        assert_eq!(writer.write(&[0]), Ok(1));
-        assert_eq!(writer.write(&[1, 2, 3]), Ok(3));
-        assert_eq!(writer.write(&[4, 5, 6, 7]), Ok(4));
+        assert_eq!(writer.write(&[0]).unwrap(), 1);
+        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
         let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
         assert_eq!(writer, b);
     }
@@ -169,11 +181,11 @@ mod tests {
     #[test]
     fn test_mem_writer() {
         let mut writer = Cursor::new(Vec::new());
-        assert_eq!(writer.write(&[0]), Ok(1));
-        assert_eq!(writer.write(&[1, 2, 3]), Ok(3));
-        assert_eq!(writer.write(&[4, 5, 6, 7]), Ok(4));
+        assert_eq!(writer.write(&[0]).unwrap(), 1);
+        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
         let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
     }
 
     #[test]
@@ -182,16 +194,16 @@ mod tests {
         {
             let mut writer = Cursor::new(&mut buf[..]);
             assert_eq!(writer.position(), 0);
-            assert_eq!(writer.write(&[0]), Ok(1));
+            assert_eq!(writer.write(&[0]).unwrap(), 1);
             assert_eq!(writer.position(), 1);
-            assert_eq!(writer.write(&[1, 2, 3]), Ok(3));
-            assert_eq!(writer.write(&[4, 5, 6, 7]), Ok(4));
+            assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+            assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
             assert_eq!(writer.position(), 8);
-            assert_eq!(writer.write(&[]), Ok(0));
+            assert_eq!(writer.write(&[]).unwrap(), 0);
             assert_eq!(writer.position(), 8);
 
-            assert_eq!(writer.write(&[8, 9]), Ok(1));
-            assert_eq!(writer.write(&[10]), Ok(0));
+            assert_eq!(writer.write(&[8, 9]).unwrap(), 1);
+            assert_eq!(writer.write(&[10]).unwrap(), 0);
         }
         let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8];
         assert_eq!(buf, b);
@@ -203,22 +215,22 @@ mod tests {
         {
             let mut writer = Cursor::new(&mut buf[..]);
             assert_eq!(writer.position(), 0);
-            assert_eq!(writer.write(&[1]), Ok(1));
+            assert_eq!(writer.write(&[1]).unwrap(), 1);
             assert_eq!(writer.position(), 1);
 
-            assert_eq!(writer.seek(SeekFrom::Start(2)), Ok(2));
+            assert_eq!(writer.seek(SeekFrom::Start(2)).unwrap(), 2);
             assert_eq!(writer.position(), 2);
-            assert_eq!(writer.write(&[2]), Ok(1));
+            assert_eq!(writer.write(&[2]).unwrap(), 1);
             assert_eq!(writer.position(), 3);
 
-            assert_eq!(writer.seek(SeekFrom::Current(-2)), Ok(1));
+            assert_eq!(writer.seek(SeekFrom::Current(-2)).unwrap(), 1);
             assert_eq!(writer.position(), 1);
-            assert_eq!(writer.write(&[3]), Ok(1));
+            assert_eq!(writer.write(&[3]).unwrap(), 1);
             assert_eq!(writer.position(), 2);
 
-            assert_eq!(writer.seek(SeekFrom::End(-1)), Ok(7));
+            assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7);
             assert_eq!(writer.position(), 7);
-            assert_eq!(writer.write(&[4]), Ok(1));
+            assert_eq!(writer.write(&[4]).unwrap(), 1);
             assert_eq!(writer.position(), 8);
 
         }
@@ -230,100 +242,100 @@ mod tests {
     fn test_buf_writer_error() {
         let mut buf = [0 as u8; 2];
         let mut writer = Cursor::new(&mut buf[..]);
-        assert_eq!(writer.write(&[0]), Ok(1));
-        assert_eq!(writer.write(&[0, 0]), Ok(1));
-        assert_eq!(writer.write(&[0, 0]), Ok(0));
+        assert_eq!(writer.write(&[0]).unwrap(), 1);
+        assert_eq!(writer.write(&[0, 0]).unwrap(), 1);
+        assert_eq!(writer.write(&[0, 0]).unwrap(), 0);
     }
 
     #[test]
     fn test_mem_reader() {
-        let mut reader = Cursor::new(vec!(0u8, 1, 2, 3, 4, 5, 6, 7));
+        let mut reader = Cursor::new(vec!(0, 1, 2, 3, 4, 5, 6, 7));
         let mut buf = [];
-        assert_eq!(reader.read(&mut buf), Ok(0));
+        assert_eq!(reader.read(&mut buf).unwrap(), 0);
         assert_eq!(reader.position(), 0);
         let mut buf = [0];
-        assert_eq!(reader.read(&mut buf), Ok(1));
+        assert_eq!(reader.read(&mut buf).unwrap(), 1);
         assert_eq!(reader.position(), 1);
         let b: &[_] = &[0];
         assert_eq!(buf, b);
         let mut buf = [0; 4];
-        assert_eq!(reader.read(&mut buf), Ok(4));
+        assert_eq!(reader.read(&mut buf).unwrap(), 4);
         assert_eq!(reader.position(), 5);
         let b: &[_] = &[1, 2, 3, 4];
         assert_eq!(buf, b);
-        assert_eq!(reader.read(&mut buf), Ok(3));
+        assert_eq!(reader.read(&mut buf).unwrap(), 3);
         let b: &[_] = &[5, 6, 7];
         assert_eq!(&buf[..3], b);
-        assert_eq!(reader.read(&mut buf), Ok(0));
+        assert_eq!(reader.read(&mut buf).unwrap(), 0);
     }
 
     #[test]
     fn read_to_end() {
-        let mut reader = Cursor::new(vec!(0u8, 1, 2, 3, 4, 5, 6, 7));
+        let mut reader = Cursor::new(vec!(0, 1, 2, 3, 4, 5, 6, 7));
         let mut v = Vec::new();
-        reader.read_to_end(&mut v).ok().unwrap();
+        reader.read_to_end(&mut v).unwrap();
         assert_eq!(v, [0, 1, 2, 3, 4, 5, 6, 7]);
     }
 
     #[test]
     fn test_slice_reader() {
-        let in_buf = vec![0u8, 1, 2, 3, 4, 5, 6, 7];
-        let mut reader = &mut in_buf.as_slice();
+        let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
+        let mut reader = &mut &in_buf[..];
         let mut buf = [];
-        assert_eq!(reader.read(&mut buf), Ok(0));
+        assert_eq!(reader.read(&mut buf).unwrap(), 0);
         let mut buf = [0];
-        assert_eq!(reader.read(&mut buf), Ok(1));
+        assert_eq!(reader.read(&mut buf).unwrap(), 1);
         assert_eq!(reader.len(), 7);
         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.read(&mut buf).unwrap(), 4);
         assert_eq!(reader.len(), 3);
         let b: &[_] = &[1, 2, 3, 4];
-        assert_eq!(buf.as_slice(), b);
-        assert_eq!(reader.read(&mut buf), Ok(3));
+        assert_eq!(&buf[..], b);
+        assert_eq!(reader.read(&mut buf).unwrap(), 3);
         let b: &[_] = &[5, 6, 7];
         assert_eq!(&buf[..3], b);
-        assert_eq!(reader.read(&mut buf), Ok(0));
+        assert_eq!(reader.read(&mut buf).unwrap(), 0);
     }
 
     #[test]
     fn test_buf_reader() {
-        let in_buf = vec![0u8, 1, 2, 3, 4, 5, 6, 7];
-        let mut reader = Cursor::new(in_buf.as_slice());
+        let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
+        let mut reader = Cursor::new(&in_buf[..]);
         let mut buf = [];
-        assert_eq!(reader.read(&mut buf), Ok(0));
+        assert_eq!(reader.read(&mut buf).unwrap(), 0);
         assert_eq!(reader.position(), 0);
         let mut buf = [0];
-        assert_eq!(reader.read(&mut buf), Ok(1));
+        assert_eq!(reader.read(&mut buf).unwrap(), 1);
         assert_eq!(reader.position(), 1);
         let b: &[_] = &[0];
         assert_eq!(buf, b);
         let mut buf = [0; 4];
-        assert_eq!(reader.read(&mut buf), Ok(4));
+        assert_eq!(reader.read(&mut buf).unwrap(), 4);
         assert_eq!(reader.position(), 5);
         let b: &[_] = &[1, 2, 3, 4];
         assert_eq!(buf, b);
-        assert_eq!(reader.read(&mut buf), Ok(3));
+        assert_eq!(reader.read(&mut buf).unwrap(), 3);
         let b: &[_] = &[5, 6, 7];
         assert_eq!(&buf[..3], b);
-        assert_eq!(reader.read(&mut buf), Ok(0));
+        assert_eq!(reader.read(&mut buf).unwrap(), 0);
     }
 
     #[test]
     fn test_read_char() {
-        let b = b"Vi\xE1\xBB\x87t";
+        let b = &b"Vi\xE1\xBB\x87t"[..];
         let mut c = Cursor::new(b).chars();
-        assert_eq!(c.next(), Some(Ok('V')));
-        assert_eq!(c.next(), Some(Ok('i')));
-        assert_eq!(c.next(), Some(Ok('ệ')));
-        assert_eq!(c.next(), Some(Ok('t')));
-        assert_eq!(c.next(), None);
+        assert_eq!(c.next().unwrap().unwrap(), 'V');
+        assert_eq!(c.next().unwrap().unwrap(), 'i');
+        assert_eq!(c.next().unwrap().unwrap(), 'ệ');
+        assert_eq!(c.next().unwrap().unwrap(), 't');
+        assert!(c.next().is_none());
     }
 
     #[test]
     fn test_read_bad_char() {
-        let b = b"\x80";
+        let b = &b"\x80"[..];
         let mut c = Cursor::new(b).chars();
         assert!(c.next().unwrap().is_err());
     }
@@ -332,26 +344,26 @@ mod tests {
     fn seek_past_end() {
         let buf = [0xff];
         let mut r = Cursor::new(&buf[..]);
-        assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10));
-        assert_eq!(r.read(&mut [0]), Ok(0));
+        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
+        assert_eq!(r.read(&mut [0]).unwrap(), 0);
 
-        let mut r = Cursor::new(vec!(10u8));
-        assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10));
-        assert_eq!(r.read(&mut [0]), Ok(0));
+        let mut r = Cursor::new(vec!(10));
+        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
+        assert_eq!(r.read(&mut [0]).unwrap(), 0);
 
         let mut buf = [0];
         let mut r = Cursor::new(&mut buf[..]);
-        assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10));
-        assert_eq!(r.write(&[3]), Ok(0));
+        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
+        assert_eq!(r.write(&[3]).unwrap(), 0);
     }
 
     #[test]
     fn seek_before_0() {
-        let buf = [0xff_u8];
+        let buf = [0xff];
         let mut r = Cursor::new(&buf[..]);
         assert!(r.seek(SeekFrom::End(-2)).is_err());
 
-        let mut r = Cursor::new(vec!(10u8));
+        let mut r = Cursor::new(vec!(10));
         assert!(r.seek(SeekFrom::End(-2)).is_err());
 
         let mut buf = [0];
@@ -363,41 +375,41 @@ mod tests {
     fn test_seekable_mem_writer() {
         let mut writer = Cursor::new(Vec::<u8>::new());
         assert_eq!(writer.position(), 0);
-        assert_eq!(writer.write(&[0]), Ok(1));
+        assert_eq!(writer.write(&[0]).unwrap(), 1);
         assert_eq!(writer.position(), 1);
-        assert_eq!(writer.write(&[1, 2, 3]), Ok(3));
-        assert_eq!(writer.write(&[4, 5, 6, 7]), Ok(4));
+        assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3);
+        assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4);
         assert_eq!(writer.position(), 8);
         let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
 
-        assert_eq!(writer.seek(SeekFrom::Start(0)), Ok(0));
+        assert_eq!(writer.seek(SeekFrom::Start(0)).unwrap(), 0);
         assert_eq!(writer.position(), 0);
-        assert_eq!(writer.write(&[3, 4]), Ok(2));
+        assert_eq!(writer.write(&[3, 4]).unwrap(), 2);
         let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
 
-        assert_eq!(writer.seek(SeekFrom::Current(1)), Ok(3));
-        assert_eq!(writer.write(&[0, 1]), Ok(2));
+        assert_eq!(writer.seek(SeekFrom::Current(1)).unwrap(), 3);
+        assert_eq!(writer.write(&[0, 1]).unwrap(), 2);
         let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
 
-        assert_eq!(writer.seek(SeekFrom::End(-1)), Ok(7));
-        assert_eq!(writer.write(&[1, 2]), Ok(2));
+        assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7);
+        assert_eq!(writer.write(&[1, 2]).unwrap(), 2);
         let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
 
-        assert_eq!(writer.seek(SeekFrom::End(1)), Ok(10));
-        assert_eq!(writer.write(&[1]), Ok(1));
+        assert_eq!(writer.seek(SeekFrom::End(1)).unwrap(), 10);
+        assert_eq!(writer.write(&[1]).unwrap(), 1);
         let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
     }
 
     #[test]
     fn vec_seek_past_end() {
         let mut r = Cursor::new(Vec::new());
-        assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10));
-        assert_eq!(r.write(&[3]), Ok(1));
+        assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10);
+        assert_eq!(r.write(&[3]).unwrap(), 1);
     }
 
     #[test]
index 9f3cd8c8b15deb4b68978d0df8c8343fe8486831..b84dcb8fb620616f256927c8d68e69b8567ba0e9 100644 (file)
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 use boxed::Box;
-use clone::Clone;
-use error::Error as StdError;
+use convert::Into;
+use error;
 use fmt;
+use marker::Send;
 use option::Option::{self, Some, None};
 use result;
-use string::String;
 use sys;
 
 /// A type for results generated by I/O related functions where the `Err` type
@@ -22,6 +22,7 @@ use sys;
 ///
 /// This typedef is generally used to avoid writing out `io::Error` directly and
 /// is otherwise a direct mapping to `std::result::Result`.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub type Result<T> = result::Result<T, Error>;
 
 /// The error type for I/O operations of the `Read`, `Write`, `Seek`, and
@@ -30,56 +31,72 @@ pub type Result<T> = result::Result<T, Error>;
 /// Errors mostly originate from the underlying OS, but custom instances of
 /// `Error` can be created with crafted error messages and a particular value of
 /// `ErrorKind`.
-#[derive(PartialEq, Eq, Clone, Debug)]
+#[derive(Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Error {
     repr: Repr,
 }
 
-#[derive(PartialEq, Eq, Clone, Debug)]
+#[derive(Debug)]
 enum Repr {
     Os(i32),
     Custom(Box<Custom>),
 }
 
-#[derive(PartialEq, Eq, Clone, Debug)]
+#[derive(Debug)]
 struct Custom {
     kind: ErrorKind,
-    desc: &'static str,
-    detail: Option<String>
+    error: Box<error::Error+Send>,
 }
 
 /// A list specifying general categories of I/O error.
+///
+/// This list is intended to grow over time and it is not recommended to
+/// exhaustively match against it.
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub enum ErrorKind {
-    /// The file was not found.
-    FileNotFound,
-    /// The file permissions disallowed access to this file.
+    /// An entity was not found, often a file.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    NotFound,
+    /// The operation lacked the necessary privileges to complete.
+    #[stable(feature = "rust1", since = "1.0.0")]
     PermissionDenied,
     /// The connection was refused by the remote server.
+    #[stable(feature = "rust1", since = "1.0.0")]
     ConnectionRefused,
     /// The connection was reset by the remote server.
+    #[stable(feature = "rust1", since = "1.0.0")]
     ConnectionReset,
     /// The connection was aborted (terminated) by the remote server.
+    #[stable(feature = "rust1", since = "1.0.0")]
     ConnectionAborted,
     /// The network operation failed because it was not connected yet.
+    #[stable(feature = "rust1", since = "1.0.0")]
     NotConnected,
+    /// A socket address could not be bound because the address is already in
+    /// use elsewhere.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    AddrInUse,
+    /// A nonexistent interface was requested or the requested address was not
+    /// local.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    AddrNotAvailable,
     /// The operation failed because a pipe was closed.
+    #[stable(feature = "rust1", since = "1.0.0")]
     BrokenPipe,
-    /// A file already existed with that name.
-    PathAlreadyExists,
-    /// No file exists at that location.
-    PathDoesntExist,
-    /// The path did not specify the type of file that this operation required.
-    /// For example, attempting to copy a directory with the `fs::copy()`
-    /// operation will fail with this error.
-    MismatchedFileTypeForOperation,
-    /// The operation temporarily failed (for example, because a signal was
-    /// received), and retrying may succeed.
-    ResourceUnavailable,
-    /// A parameter was incorrect in a way that caused an I/O error not part of
-    /// this list.
+    /// An entity already exists, often a file.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    AlreadyExists,
+    /// The operation needs to block to complete, but the blocking operation was
+    /// requested to not occur.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    WouldBlock,
+    /// A parameter was incorrect.
+    #[stable(feature = "rust1", since = "1.0.0")]
     InvalidInput,
     /// The I/O operation's timeout expired, causing it to be canceled.
+    #[stable(feature = "rust1", since = "1.0.0")]
     TimedOut,
     /// An error returned when an operation could not be completed because a
     /// call to `write` returned `Ok(0)`.
@@ -87,23 +104,54 @@ pub enum ErrorKind {
     /// This typically means that an operation could only succeed if it wrote a
     /// particular number of bytes but only a smaller number of bytes could be
     /// written.
+    #[stable(feature = "rust1", since = "1.0.0")]
     WriteZero,
-    /// This operation was interrupted
+    /// This operation was interrupted.
+    ///
+    /// Interrupted operations can typically be retried.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Interrupted,
     /// Any I/O error not part of this list.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Other,
+
+    /// Any I/O error not part of this list.
+    #[unstable(feature = "std_misc",
+               reason = "better expressed through extensible enums that this \
+                         enum cannot be exhaustively matched against")]
+    #[doc(hidden)]
+    __Nonexhaustive,
 }
 
 impl Error {
-    /// Creates a new custom error from a specified kind/description/detail.
-    pub fn new(kind: ErrorKind,
-               description: &'static str,
-               detail: Option<String>) -> Error {
+    /// Creates a new I/O error from a known kind of error as well as an
+    /// arbitrary error payload.
+    ///
+    /// This function is used to generically create I/O errors which do not
+    /// originate from the OS itself. The `error` argument is an arbitrary
+    /// payload which will be contained in this `Error`. Accessors as well as
+    /// downcasting will soon be added to this type as well to access the custom
+    /// information.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{Error, ErrorKind};
+    ///
+    /// // errors can be created from strings
+    /// let custom_error = Error::new(ErrorKind::Other, "oh no!");
+    ///
+    /// // errors can also be created from other errors
+    /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new<E>(kind: ErrorKind, error: E) -> Error
+        where E: Into<Box<error::Error+Send>>
+    {
         Error {
             repr: Repr::Custom(Box::new(Custom {
                 kind: kind,
-                desc: description,
-                detail: detail,
+                error: error.into(),
             }))
         }
     }
@@ -113,40 +161,41 @@ impl Error {
     /// This function reads the value of `errno` for the target platform (e.g.
     /// `GetLastError` on Windows) and will return a corresponding instance of
     /// `Error` for the error code.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn last_os_error() -> Error {
         Error::from_os_error(sys::os::errno() as i32)
     }
 
     /// Creates a new instance of an `Error` from a particular OS error code.
+    #[unstable(feature = "io",
+               reason = "unclear whether this function is necessary")]
     pub fn from_os_error(code: i32) -> Error {
         Error { repr: Repr::Os(code) }
     }
 
-    /// Return the corresponding `ErrorKind` for this error.
-    pub fn kind(&self) -> ErrorKind {
-        match self.repr {
-            Repr::Os(code) => sys::decode_error_kind(code),
-            Repr::Custom(ref c) => c.kind,
-        }
-    }
-
-    /// Returns a short description for this error message
-    pub fn description(&self) -> &str {
+    /// Returns the OS error that this error represents (if any).
+    ///
+    /// If this `Error` was constructed via `last_os_error` then this function
+    /// will return `Some`, otherwise it will return `None`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn raw_os_error(&self) -> Option<i32> {
         match self.repr {
-            Repr::Os(..) => "os error",
-            Repr::Custom(ref c) => c.desc,
+            Repr::Os(i) => Some(i),
+            Repr::Custom(..) => None,
         }
     }
 
-    /// Returns a detailed error message for this error (if one is available)
-    pub fn detail(&self) -> Option<String> {
+    /// Return the corresponding `ErrorKind` for this error.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn kind(&self) -> ErrorKind {
         match self.repr {
-            Repr::Os(code) => Some(sys::os::error_string(code)),
-            Repr::Custom(ref s) => s.detail.clone(),
+            Repr::Os(code) => sys::decode_error_kind(code),
+            Repr::Custom(ref c) => c.kind,
         }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for Error {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         match self.repr {
@@ -154,30 +203,17 @@ impl fmt::Display for Error {
                 let detail = sys::os::error_string(code);
                 write!(fmt, "{} (os error {})", detail, code)
             }
-            Repr::Custom(ref c) => {
-                match **c {
-                    Custom {
-                        kind: ErrorKind::Other,
-                        desc: "unknown error",
-                        detail: Some(ref detail)
-                    } => {
-                        write!(fmt, "{}", detail)
-                    }
-                    Custom { detail: None, desc, .. } =>
-                        write!(fmt, "{}", desc),
-                    Custom { detail: Some(ref detail), desc, .. } =>
-                        write!(fmt, "{} ({})", desc, detail)
-                }
-            }
+            Repr::Custom(ref c) => c.error.fmt(fmt),
         }
     }
 }
 
-impl StdError for Error {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl error::Error for Error {
     fn description(&self) -> &str {
         match self.repr {
             Repr::Os(..) => "os error",
-            Repr::Custom(ref c) => c.desc,
+            Repr::Custom(ref c) => c.error.description(),
         }
     }
 }
index 7f3ce7924c1caaa0fe8bfefdcf4968c80e95d201..67bc45d3b62a1fd4d514b238786ccab5be086af8 100644 (file)
@@ -12,77 +12,259 @@ use core::prelude::*;
 
 use boxed::Box;
 use cmp;
-use io::{self, SeekFrom, Read, Write, Seek, BufRead};
+use io::{self, SeekFrom, Read, Write, Seek, BufRead, Error, ErrorKind};
+use fmt;
 use mem;
 use slice;
+use string::String;
 use vec::Vec;
 
 // =============================================================================
 // Forwarding implementations
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, R: Read + ?Sized> Read for &'a mut R {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) }
+    #[inline]
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        (**self).read(buf)
+    }
+
+    #[inline]
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        (**self).read_to_end(buf)
+    }
+
+    #[inline]
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
+        (**self).read_to_string(buf)
+    }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, W: Write + ?Sized> Write for &'a mut W {
+    #[inline]
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
+
+    #[inline]
     fn flush(&mut self) -> io::Result<()> { (**self).flush() }
+
+    #[inline]
+    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+        (**self).write_all(buf)
+    }
+
+    #[inline]
+    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
+        (**self).write_fmt(fmt)
+    }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, S: Seek + ?Sized> Seek for &'a mut S {
+    #[inline]
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B {
+    #[inline]
     fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
+
+    #[inline]
     fn consume(&mut self, amt: usize) { (**self).consume(amt) }
+
+    #[inline]
+    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
+        (**self).read_until(byte, buf)
+    }
+
+    #[inline]
+    fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
+        (**self).read_line(buf)
+    }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<R: Read + ?Sized> Read for Box<R> {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) }
+    #[inline]
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        (**self).read(buf)
+    }
+
+    #[inline]
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        (**self).read_to_end(buf)
+    }
+
+    #[inline]
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
+        (**self).read_to_string(buf)
+    }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<W: Write + ?Sized> Write for Box<W> {
+    #[inline]
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
+
+    #[inline]
     fn flush(&mut self) -> io::Result<()> { (**self).flush() }
+
+    #[inline]
+    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+        (**self).write_all(buf)
+    }
+
+    #[inline]
+    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
+        (**self).write_fmt(fmt)
+    }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<S: Seek + ?Sized> Seek for Box<S> {
+    #[inline]
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<B: BufRead + ?Sized> BufRead for Box<B> {
+    #[inline]
     fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
+
+    #[inline]
     fn consume(&mut self, amt: usize) { (**self).consume(amt) }
+
+    #[inline]
+    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
+        (**self).read_until(byte, buf)
+    }
+
+    #[inline]
+    fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
+        (**self).read_line(buf)
+    }
 }
 
 // =============================================================================
 // In-memory buffer implementations
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Read for &'a [u8] {
+    #[inline]
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         let amt = cmp::min(buf.len(), self.len());
         let (a, b) = self.split_at(amt);
-        slice::bytes::copy_memory(buf, a);
+        slice::bytes::copy_memory(a, buf);
         *self = b;
         Ok(amt)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> BufRead for &'a [u8] {
+    #[inline]
     fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) }
+
+    #[inline]
     fn consume(&mut self, amt: usize) { *self = &self[amt..]; }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for &'a mut [u8] {
+    #[inline]
     fn write(&mut self, data: &[u8]) -> io::Result<usize> {
         let amt = cmp::min(data.len(), self.len());
         let (a, b) = mem::replace(self, &mut []).split_at_mut(amt);
-        slice::bytes::copy_memory(a, &data[..amt]);
+        slice::bytes::copy_memory(&data[..amt], a);
         *self = b;
         Ok(amt)
     }
+
+    #[inline]
+    fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
+        if try!(self.write(data)) == data.len() {
+            Ok(())
+        } else {
+            Err(Error::new(ErrorKind::WriteZero, "failed to write whole buffer"))
+        }
+    }
+
+    #[inline]
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Write for Vec<u8> {
+    #[inline]
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.push_all(buf);
         Ok(buf.len())
     }
+
+    #[inline]
+    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+        self.push_all(buf);
+        Ok(())
+    }
+
+    #[inline]
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
 }
+
+#[cfg(test)]
+mod tests {
+    use io::prelude::*;
+    use vec::Vec;
+    use test;
+
+    #[bench]
+    fn bench_read_slice(b: &mut test::Bencher) {
+        let buf = [5; 1024];
+        let mut dst = [0; 128];
+
+        b.iter(|| {
+            let mut rd = &buf[..];
+            for _ in (0 .. 8) {
+                let _ = rd.read(&mut dst);
+                test::black_box(&dst);
+            }
+        })
+    }
+
+    #[bench]
+    fn bench_write_slice(b: &mut test::Bencher) {
+        let mut buf = [0; 1024];
+        let src = [5; 128];
+
+        b.iter(|| {
+            let mut wr = &mut buf[..];
+            for _ in (0 .. 8) {
+                let _ = wr.write_all(&src);
+                test::black_box(&wr);
+            }
+        })
+    }
+
+    #[bench]
+    fn bench_read_vec(b: &mut test::Bencher) {
+        let buf = vec![5; 1024];
+        let mut dst = [0; 128];
+
+        b.iter(|| {
+            let mut rd = &buf[..];
+            for _ in (0 .. 8) {
+                let _ = rd.read(&mut dst);
+                test::black_box(&dst);
+            }
+        })
+    }
+
+    #[bench]
+    fn bench_write_vec(b: &mut test::Bencher) {
+        let mut buf = Vec::with_capacity(1024);
+        let src = [5; 128];
+
+        b.iter(|| {
+            let mut wr = &mut buf[..];
+            for _ in (0 .. 8) {
+                let _ = wr.write_all(&src);
+                test::black_box(&wr);
+            }
+        })
+    }
+}
diff --git a/src/libstd/io/lazy.rs b/src/libstd/io/lazy.rs
new file mode 100644 (file)
index 0000000..df280da
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright 2015 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 prelude::v1::*;
+
+use boxed;
+use cell::UnsafeCell;
+use rt;
+use sync::{StaticMutex, Arc};
+
+pub struct Lazy<T> {
+    pub lock: StaticMutex,
+    pub ptr: UnsafeCell<*mut Arc<T>>,
+    pub init: fn() -> Arc<T>,
+}
+
+unsafe impl<T> Sync for Lazy<T> {}
+
+macro_rules! lazy_init {
+    ($init:expr) => (::io::lazy::Lazy {
+        lock: ::sync::MUTEX_INIT,
+        ptr: ::cell::UnsafeCell { value: 0 as *mut _ },
+        init: $init,
+    })
+}
+
+impl<T: Send + Sync + 'static> Lazy<T> {
+    pub fn get(&'static self) -> Option<Arc<T>> {
+        let _g = self.lock.lock();
+        unsafe {
+            let ptr = *self.ptr.get();
+            if ptr.is_null() {
+                Some(self.init())
+            } else if ptr as usize == 1 {
+                None
+            } else {
+                Some((*ptr).clone())
+            }
+        }
+    }
+
+    unsafe fn init(&'static self) -> Arc<T> {
+        // If we successfully register an at exit handler, then we cache the
+        // `Arc` allocation in our own internal box (it will get deallocated by
+        // the at exit handler). Otherwise we just return the freshly allocated
+        // `Arc`.
+        let registered = rt::at_exit(move || {
+            let g = self.lock.lock();
+            let ptr = *self.ptr.get();
+            *self.ptr.get() = 1 as *mut _;
+            drop(g);
+            drop(Box::from_raw(ptr))
+        });
+        let ret = (self.init)();
+        if registered.is_ok() {
+            *self.ptr.get() = boxed::into_raw(Box::new(ret.clone()));
+        }
+        return ret
+    }
+}
index c38d52161c96e8484ab8e656b224d29f7f9595e8..c6335015d7251d67d73bd1cf5dc90ac03a57e31a 100644 (file)
@@ -9,29 +9,21 @@
 // except according to those terms.
 
 //! Traits, helpers, and type definitions for core I/O functionality.
-//!
-//! > **NOTE**: This module is very much a work in progress and is under active
-//! > development. At this time it is still recommended to use the `old_io`
-//! > module while the details of this module shake out.
 
-#![unstable(feature = "io",
-            reason = "this new I/O module is still under active deveopment and \
-                      APIs are subject to tweaks fairly regularly")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
 use cmp;
 use unicode::str as core_str;
-use error::Error as StdError;
+use error as std_error;
 use fmt;
-use iter::Iterator;
+use iter::{self, Iterator, Extend};
 use marker::Sized;
 use ops::{Drop, FnOnce};
 use option::Option::{self, Some, None};
-use ptr::PtrExt;
 use result::Result::{Ok, Err};
 use result;
-use slice::{self, SliceExt};
 use string::String;
-use str::{self, StrExt};
+use str;
 use vec::Vec;
 
 pub use self::buffered::{BufReader, BufWriter, BufStream, LineWriter};
@@ -39,6 +31,12 @@ pub use self::buffered::IntoInnerError;
 pub use self::cursor::Cursor;
 pub use self::error::{Result, Error, ErrorKind};
 pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat};
+pub use self::stdio::{stdin, stdout, stderr, _print, Stdin, Stdout, Stderr};
+pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
+#[doc(no_inline, hidden)]
+pub use self::stdio::{set_panic, set_print};
+
+#[macro_use] mod lazy;
 
 pub mod prelude;
 mod buffered;
@@ -46,48 +44,10 @@ mod cursor;
 mod error;
 mod impls;
 mod util;
+mod stdio;
 
 const DEFAULT_BUF_SIZE: usize = 64 * 1024;
 
-// Acquires a slice of the vector `v` from its length to its capacity
-// (uninitialized data), reads into it, and then updates the length.
-//
-// This function is leveraged to efficiently read some bytes into a destination
-// vector without extra copying and taking advantage of the space that's already
-// in `v`.
-//
-// The buffer we're passing down, however, is pointing at uninitialized data
-// (the end of a `Vec`), and many operations will be *much* faster if we don't
-// have to zero it out. In order to prevent LLVM from generating an `undef`
-// value when reads happen from this uninitialized memory, we force LLVM to
-// think it's initialized by sending it through a black box. This should prevent
-// actual undefined behavior after optimizations.
-fn with_end_to_cap<F>(v: &mut Vec<u8>, f: F) -> Result<usize>
-    where F: FnOnce(&mut [u8]) -> Result<usize>
-{
-    unsafe {
-        let n = try!(f({
-            let base = v.as_mut_ptr().offset(v.len() as isize);
-            black_box(slice::from_raw_parts_mut(base,
-                                                v.capacity() - v.len()))
-        }));
-
-        // If the closure (typically a `read` implementation) reported that it
-        // read a larger number of bytes than the vector actually has, we need
-        // to be sure to clamp the vector to at most its capacity.
-        let new_len = cmp::min(v.capacity(), v.len() + n);
-        v.set_len(new_len);
-        return Ok(n);
-    }
-
-    // Semi-hack used to prevent LLVM from retaining any assumptions about
-    // `dummy` over this function call
-    unsafe fn black_box<T>(mut dummy: T) -> T {
-        asm!("" :: "r"(&mut dummy) : "memory");
-        dummy
-    }
-}
-
 // A few methods below (read_to_string, read_line) will append data into a
 // `String` buffer, but we need to be pretty careful when doing this. The
 // implementation will just call `.as_mut_vec()` and then delegate to a
@@ -106,8 +66,8 @@ fn with_end_to_cap<F>(v: &mut Vec<u8>, f: F) -> Result<usize>
 // 2. We're passing a raw buffer to the function `f`, and it is expected that
 //    the function only *appends* bytes to the buffer. We'll get undefined
 //    behavior if existing bytes are overwritten to have non-UTF-8 data.
-fn append_to_string<F>(buf: &mut String, f: F) -> Result<()>
-    where F: FnOnce(&mut Vec<u8>) -> Result<()>
+fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
+    where F: FnOnce(&mut Vec<u8>) -> Result<usize>
 {
     struct Guard<'a> { s: &'a mut Vec<u8>, len: usize }
     #[unsafe_destructor]
@@ -121,9 +81,9 @@ fn append_to_string<F>(buf: &mut String, f: F) -> Result<()>
         let mut g = Guard { len: buf.len(), s: buf.as_mut_vec() };
         let ret = f(g.s);
         if str::from_utf8(&g.s[g.len..]).is_err() {
-            ret.and_then(|()| {
+            ret.and_then(|_| {
                 Err(Error::new(ErrorKind::InvalidInput,
-                               "stream did not contain valid UTF-8", None))
+                               "stream did not contain valid UTF-8"))
             })
         } else {
             g.len = g.s.len();
@@ -132,18 +92,41 @@ fn append_to_string<F>(buf: &mut String, f: F) -> Result<()>
     }
 }
 
-fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<()> {
+// This uses an adaptive system to extend the vector when it fills. We want to
+// avoid paying to allocate and zero a huge chunk of memory if the reader only
+// has 4 bytes while still making large reads if the reader does have a ton
+// of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every
+// time is 4,500 times (!) slower than this if the reader has a very small
+// amount of data to return.
+fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
+    let start_len = buf.len();
+    let mut len = start_len;
+    let mut new_write_size = 16;
+    let ret;
     loop {
-        if buf.capacity() == buf.len() {
-            buf.reserve(DEFAULT_BUF_SIZE);
+        if len == buf.len() {
+            if new_write_size < DEFAULT_BUF_SIZE {
+                new_write_size *= 2;
+            }
+            buf.extend(iter::repeat(0).take(new_write_size));
         }
-        match with_end_to_cap(buf, |b| r.read(b)) {
-            Ok(0) => return Ok(()),
-            Ok(_) => {}
+
+        match r.read(&mut buf[len..]) {
+            Ok(0) => {
+                ret = Ok(len - start_len);
+                break;
+            }
+            Ok(n) => len += n,
             Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
-            Err(e) => return Err(e),
+            Err(e) => {
+                ret = Err(e);
+                break;
+            }
         }
     }
+
+    buf.truncate(len);
+    ret
 }
 
 /// A trait for objects which are byte-oriented sources.
@@ -154,6 +137,7 @@ fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<()> {
 /// Readers are intended to be composable with one another. Many objects
 /// throughout the I/O and related libraries take and provide types which
 /// implement the `Read` trait.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Read {
     /// Pull some bytes from this source into the specified buffer, returning
     /// how many bytes were read.
@@ -182,6 +166,7 @@ pub trait Read {
     /// If this function encounters any form of I/O or other error, an error
     /// variant will be returned. If an error is returned then it must be
     /// guaranteed that no bytes were read.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
 
     /// Read all bytes until EOF in this source, placing them into `buf`.
@@ -193,7 +178,8 @@ pub trait Read {
     /// 2. Returns an error which is not of the kind `ErrorKind::Interrupted`.
     ///
     /// Until one of these conditions is met the function will continuously
-    /// invoke `read` to append more data to `buf`.
+    /// invoke `read` to append more data to `buf`. If successful, this function
+    /// will return the total number of bytes read.
     ///
     /// # Errors
     ///
@@ -204,19 +190,24 @@ pub trait Read {
     /// If any other read error is encountered then this function immediately
     /// returns. Any bytes which have already been read will be appended to
     /// `buf`.
-    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<()> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
         read_to_end(self, buf)
     }
 
     /// Read all bytes until EOF in this source, placing them into `buf`.
     ///
+    /// If successful, this function returns the number of bytes which were read
+    /// and appended to `buf`.
+    ///
     /// # Errors
     ///
     /// If the data in this stream is *not* valid UTF-8 then an error is
     /// returned and `buf` is unchanged.
     ///
     /// See `read_to_end` for other error semantics.
-    fn read_to_string(&mut self, buf: &mut String) -> Result<()> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
         // Note that we do *not* call `.read_to_end()` here. We are passing
         // `&mut Vec<u8>` (the raw contents of `buf`) into the `read_to_end`
         // method to fill it up. An arbitrary implementation could overwrite the
@@ -228,16 +219,13 @@ pub trait Read {
         // know is guaranteed to only read data into the end of the buffer.
         append_to_string(buf, |b| read_to_end(self, b))
     }
-}
 
-/// Extension methods for all instances of `Read`, typically imported through
-/// `std::io::prelude::*`.
-pub trait ReadExt: Read + Sized {
     /// Create a "by reference" adaptor for this instance of `Read`.
     ///
     /// The returned adaptor also implements `Read` and will simply borrow this
     /// current reader.
-    fn by_ref(&mut self) -> &mut Self { self }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
 
     /// Transform this `Read` instance to an `Iterator` over its bytes.
     ///
@@ -245,7 +233,8 @@ pub trait ReadExt: Read + Sized {
     /// R::Err>`.  The yielded item is `Ok` if a byte was successfully read and
     /// `Err` otherwise for I/O errors. EOF is mapped to returning `None` from
     /// this iterator.
-    fn bytes(self) -> Bytes<Self> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn bytes(self) -> Bytes<Self> where Self: Sized {
         Bytes { inner: self }
     }
 
@@ -259,7 +248,10 @@ pub trait ReadExt: Read + Sized {
     ///
     /// Currently this adaptor will discard intermediate data read, and should
     /// be avoided if this is not desired.
-    fn chars(self) -> Chars<Self> {
+    #[unstable(feature = "io", reason = "the semantics of a partial read/write \
+                                         of where errors happen is currently \
+                                         unclear and may change")]
+    fn chars(self) -> Chars<Self> where Self: Sized {
         Chars { inner: self }
     }
 
@@ -268,7 +260,8 @@ pub trait ReadExt: Read + Sized {
     /// The returned `Read` instance will first read all bytes from this object
     /// until EOF is encountered. Afterwards the output is equivalent to the
     /// output of `next`.
-    fn chain<R: Read>(self, next: R) -> Chain<Self, R> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn chain<R: Read>(self, next: R) -> Chain<Self, R> where Self: Sized {
         Chain { first: self, second: next, done_first: false }
     }
 
@@ -278,7 +271,8 @@ pub trait ReadExt: Read + Sized {
     /// `limit` bytes, after which it will always return EOF (`Ok(0)`). Any
     /// read errors will not count towards the number of bytes read and future
     /// calls to `read` may succeed.
-    fn take(self, limit: u64) -> Take<Self> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn take(self, limit: u64) -> Take<Self> where Self: Sized {
         Take { inner: self, limit: limit }
     }
 
@@ -288,13 +282,14 @@ pub trait ReadExt: Read + Sized {
     /// Whenever the returned `Read` instance is read it will write the read
     /// data to `out`. The current semantics of this implementation imply that
     /// a `write` error will not report how much data was initially read.
-    fn tee<W: Write>(self, out: W) -> Tee<Self, W> {
+    #[unstable(feature = "io", reason = "the semantics of a partial read/write \
+                                         of where errors happen is currently \
+                                         unclear and may change")]
+    fn tee<W: Write>(self, out: W) -> Tee<Self, W> where Self: Sized {
         Tee { reader: self, writer: out }
     }
 }
 
-impl<T: Read> ReadExt for T {}
-
 /// A trait for objects which are byte-oriented sinks.
 ///
 /// The `write` method will attempt to write some data into the object,
@@ -306,6 +301,7 @@ impl<T: Read> ReadExt for T {}
 /// Writers are intended to be composable with one another. Many objects
 /// throughout the I/O and related libraries take and provide types which
 /// implement the `Write` trait.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Write {
     /// Write a buffer into this object, returning how many bytes were written.
     ///
@@ -331,6 +327,7 @@ pub trait Write {
     ///
     /// It is **not** considered an error if the entire buffer could not be
     /// written to this writer.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn write(&mut self, buf: &[u8]) -> Result<usize>;
 
     /// Flush this output stream, ensuring that all intermediately buffered
@@ -340,6 +337,7 @@ pub trait Write {
     ///
     /// It is considered an error if not all bytes could be written due to
     /// I/O errors or EOF being reached.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn flush(&mut self) -> Result<()>;
 
     /// Attempts to write an entire buffer into this write.
@@ -352,12 +350,12 @@ pub trait Write {
     /// # Errors
     ///
     /// This function will return the first error that `write` returns.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
         while buf.len() > 0 {
             match self.write(buf) {
                 Ok(0) => return Err(Error::new(ErrorKind::WriteZero,
-                                               "failed to write whole buffer",
-                                               None)),
+                                               "failed to write whole buffer")),
                 Ok(n) => buf = &buf[n..],
                 Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
                 Err(e) => return Err(e),
@@ -380,6 +378,7 @@ pub trait Write {
     /// # Errors
     ///
     /// This function will return any I/O error reported while formatting.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<()> {
         // Create a shim which translates a Write to a fmt::Write and saves
         // off I/O errors. instead of discarding them
@@ -406,16 +405,13 @@ pub trait Write {
             Err(..) => output.error
         }
     }
-}
 
-/// Extension methods for all instances of `Write`, typically imported through
-/// `std::io::prelude::*`.
-pub trait WriteExt: Write + Sized {
     /// Create a "by reference" adaptor for this instance of `Write`.
     ///
     /// The returned adaptor also implements `Write` and will simply borrow this
     /// current writer.
-    fn by_ref(&mut self) -> &mut Self { self }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
 
     /// Creates a new writer which will write all data to both this writer and
     /// another writer.
@@ -425,18 +421,22 @@ pub trait WriteExt: Write + Sized {
     /// implementation do not precisely track where errors happen. For example
     /// an error on the second call to `write` will not report that the first
     /// call to `write` succeeded.
-    fn broadcast<W: Write>(self, other: W) -> Broadcast<Self, W> {
+    #[unstable(feature = "io", reason = "the semantics of a partial read/write \
+                                         of where errors happen is currently \
+                                         unclear and may change")]
+    fn broadcast<W: Write>(self, other: W) -> Broadcast<Self, W>
+        where Self: Sized
+    {
         Broadcast { first: self, second: other }
     }
 }
 
-impl<T: Write> WriteExt for T {}
-
 /// 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 or the current offset.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait Seek {
     /// Seek to an offset, in bytes, in a stream
     ///
@@ -452,13 +452,16 @@ pub trait Seek {
     /// # Errors
     ///
     /// Seeking to a negative offset is considered an error
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn seek(&mut self, pos: SeekFrom) -> Result<u64>;
 }
 
 /// Enumeration of possible methods to seek within an I/O object.
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub enum SeekFrom {
     /// Set the offset to the provided number of bytes.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Start(u64),
 
     /// Set the offset to the size of this object plus the specified number of
@@ -466,6 +469,7 @@ pub enum SeekFrom {
     ///
     /// It is possible to seek beyond the end of an object, but is an error to
     /// seek before byte 0.
+    #[stable(feature = "rust1", since = "1.0.0")]
     End(i64),
 
     /// Set the offset to the current position plus the specified number of
@@ -473,11 +477,13 @@ pub enum SeekFrom {
     ///
     /// It is possible to seek beyond the end of an object, but is an error to
     /// seek before byte 0.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Current(i64),
 }
 
 fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
-                                   -> Result<()> {
+                                   -> Result<usize> {
+    let mut read = 0;
     loop {
         let (done, used) = {
             let available = match r.fill_buf() {
@@ -497,8 +503,9 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
             }
         };
         r.consume(used);
+        read += used;
         if done || used == 0 {
-            return Ok(());
+            return Ok(read);
         }
     }
 }
@@ -508,6 +515,7 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
 ///
 /// This type extends the `Read` trait with a few methods that are not
 /// possible to reasonably implement with purely a read interface.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait BufRead: Read {
     /// Fills the internal buffer of this object, returning the buffer contents.
     ///
@@ -524,10 +532,22 @@ pub trait BufRead: Read {
     ///
     /// This function will return an I/O error if the underlying reader was
     /// read, but returned an error.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn fill_buf(&mut self) -> Result<&[u8]>;
 
     /// Tells this buffer that `amt` bytes have been consumed from the buffer,
     /// so they should no longer be returned in calls to `read`.
+    ///
+    /// This function does not perform any I/O, it simply informs this object
+    /// that some amount of its buffer, returned from `fill_buf`, has been
+    /// consumed and should no longer be returned.
+    ///
+    /// This function is used to tell the buffer how many bytes you've consumed
+    /// from the return value of `fill_buf`, and so may do odd things if
+    /// `fill_buf` isn't called before calling this.
+    ///
+    /// The `amt` must be `<=` the number of bytes in the buffer returned by `fill_buf`.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn consume(&mut self, amt: usize);
 
     /// Read all bytes until the delimiter `byte` is reached.
@@ -538,7 +558,8 @@ pub trait BufRead: Read {
     /// `buf`.
     ///
     /// If this buffered reader is currently at EOF, then this function will not
-    /// place any more bytes into `buf` and will return `Ok(())`.
+    /// place any more bytes into `buf` and will return `Ok(n)` where `n` is the
+    /// number of bytes which were read.
     ///
     /// # Errors
     ///
@@ -547,11 +568,13 @@ pub trait BufRead: Read {
     ///
     /// If an I/O error is encountered then all bytes read so far will be
     /// present in `buf` and its length will have been adjusted appropriately.
-    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<()> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
         read_until(self, byte, buf)
     }
 
-    /// Read all bytes until a newline byte (the 0xA byte) is reached.
+    /// Read all bytes until a newline byte (the 0xA byte) is reached, and
+    /// append them to the provided buffer.
     ///
     /// This function will continue to read (and buffer) bytes from the
     /// underlying stream until the newline delimiter (the 0xA byte) or EOF is
@@ -559,7 +582,8 @@ pub trait BufRead: Read {
     /// found) will be appended to `buf`.
     ///
     /// If this reader is currently at EOF then this function will not modify
-    /// `buf` and will return `Ok(())`.
+    /// `buf` and will return `Ok(n)` where `n` is the number of bytes which
+    /// were read.
     ///
     /// # Errors
     ///
@@ -567,17 +591,14 @@ pub trait BufRead: Read {
     /// return an error if the read bytes are not valid UTF-8. If an I/O error
     /// is encountered then `buf` may contain some bytes already read in the
     /// event that all data read so far was valid UTF-8.
-    fn read_line(&mut self, buf: &mut String) -> Result<()> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn read_line(&mut self, buf: &mut String) -> Result<usize> {
         // Note that we are not calling the `.read_until` method here, but
         // rather our hardcoded implementation. For more details as to why, see
         // the comments in `read_to_end`.
         append_to_string(buf, |b| read_until(self, b'\n', b))
     }
-}
 
-/// Extension methods for all instances of `BufRead`, typically imported through
-/// `std::io::prelude::*`.
-pub trait BufReadExt: BufRead + Sized {
     /// Returns an iterator over the contents of this reader split on the byte
     /// `byte`.
     ///
@@ -587,7 +608,8 @@ pub trait BufReadExt: BufRead + Sized {
     ///
     /// This function will yield errors whenever `read_until` would have also
     /// yielded an error.
-    fn split(self, byte: u8) -> Split<Self> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn split(self, byte: u8) -> Split<Self> where Self: Sized {
         Split { buf: self, delim: byte }
     }
 
@@ -599,21 +621,22 @@ pub trait BufReadExt: BufRead + Sized {
     ///
     /// This function will yield errors whenever `read_string` would have also
     /// yielded an error.
-    fn lines(self) -> Lines<Self> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn lines(self) -> Lines<Self> where Self: Sized {
         Lines { buf: self }
     }
 }
 
-impl<T: BufRead> BufReadExt for T {}
-
 /// A `Write` adaptor which will write data to multiple locations.
 ///
-/// For more information, see `WriteExt::broadcast`.
+/// For more information, see `Write::broadcast`.
+#[unstable(feature = "io", reason = "awaiting stability of Write::broadcast")]
 pub struct Broadcast<T, U> {
     first: T,
     second: U,
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of Write::broadcast")]
 impl<T: Write, U: Write> Write for Broadcast<T, U> {
     fn write(&mut self, data: &[u8]) -> Result<usize> {
         let n = try!(self.first.write(data));
@@ -629,13 +652,15 @@ impl<T: Write, U: Write> Write for Broadcast<T, U> {
 
 /// Adaptor to chain together two instances of `Read`.
 ///
-/// For more information, see `ReadExt::chain`.
+/// For more information, see `Read::chain`.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Chain<T, U> {
     first: T,
     second: U,
     done_first: bool,
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Read, U: Read> Read for Chain<T, U> {
     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
         if !self.done_first {
@@ -650,12 +675,14 @@ impl<T: Read, U: Read> Read for Chain<T, U> {
 
 /// Reader adaptor which limits the bytes read from an underlying reader.
 ///
-/// For more information, see `ReadExt::take`.
+/// For more information, see `Read::take`.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Take<T> {
     inner: T,
     limit: u64,
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Take<T> {
     /// Returns the number of bytes that can be read before this instance will
     /// return EOF.
@@ -664,11 +691,18 @@ impl<T> Take<T> {
     ///
     /// This instance may reach EOF after reading fewer bytes than indicated by
     /// this method if the underlying `Read` instance reaches EOF.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn limit(&self) -> u64 { self.limit }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Read> Read for Take<T> {
     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
+        // Don't call into inner reader at all at EOF because it may still block
+        if self.limit == 0 {
+            return Ok(0);
+        }
+
         let max = cmp::min(buf.len() as u64, self.limit) as usize;
         let n = try!(self.inner.read(&mut buf[..max]));
         self.limit -= n as u64;
@@ -676,14 +710,32 @@ impl<T: Read> Read for Take<T> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: BufRead> BufRead for Take<T> {
+    fn fill_buf(&mut self) -> Result<&[u8]> {
+        let buf = try!(self.inner.fill_buf());
+        let cap = cmp::min(buf.len() as u64, self.limit) as usize;
+        Ok(&buf[..cap])
+    }
+
+    fn consume(&mut self, amt: usize) {
+        // Don't let callers reset the limit by passing an overlarge value
+        let amt = cmp::min(amt as u64, self.limit) as usize;
+        self.limit -= amt as u64;
+        self.inner.consume(amt);
+    }
+}
+
 /// An adaptor which will emit all read data to a specified writer as well.
 ///
-/// For more information see `ReadExt::tee`
+/// For more information see `Read::tee`
+#[unstable(feature = "io", reason = "awaiting stability of Read::tee")]
 pub struct Tee<R, W> {
     reader: R,
     writer: W,
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of Read::tee")]
 impl<R: Read, W: Write> Read for Tee<R, W> {
     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
         let n = try!(self.reader.read(buf));
@@ -695,11 +747,13 @@ impl<R: Read, W: Write> Read for Tee<R, W> {
 
 /// A bridge from implementations of `Read` to an `Iterator` of `u8`.
 ///
-/// See `ReadExt::bytes` for more information.
+/// See `Read::bytes` for more information.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Bytes<R> {
     inner: R,
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<R: Read> Iterator for Bytes<R> {
     type Item = Result<u8>;
 
@@ -715,14 +769,16 @@ impl<R: Read> Iterator for Bytes<R> {
 
 /// A bridge from implementations of `Read` to an `Iterator` of `char`.
 ///
-/// See `ReadExt::chars` for more information.
+/// See `Read::chars` for more information.
+#[unstable(feature = "io", reason = "awaiting stability of Read::chars")]
 pub struct Chars<R> {
     inner: R,
 }
 
 /// An enumeration of possible errors that can be generated from the `Chars`
 /// adapter.
-#[derive(PartialEq, Clone, Debug)]
+#[derive(Debug)]
+#[unstable(feature = "io", reason = "awaiting stability of Read::chars")]
 pub enum CharsError {
     /// Variant representing that the underlying stream was read successfully
     /// but it did not contain valid utf8 data.
@@ -732,6 +788,7 @@ pub enum CharsError {
     Other(Error),
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of Read::chars")]
 impl<R: Read> Iterator for Chars<R> {
     type Item = result::Result<char, CharsError>;
 
@@ -763,14 +820,15 @@ impl<R: Read> Iterator for Chars<R> {
     }
 }
 
-impl StdError for CharsError {
+#[unstable(feature = "io", reason = "awaiting stability of Read::chars")]
+impl std_error::Error for CharsError {
     fn description(&self) -> &str {
         match *self {
             CharsError::NotUtf8 => "invalid utf8 encoding",
-            CharsError::Other(ref e) => e.description(),
+            CharsError::Other(ref e) => std_error::Error::description(e),
         }
     }
-    fn cause(&self) -> Option<&StdError> {
+    fn cause(&self) -> Option<&std_error::Error> {
         match *self {
             CharsError::NotUtf8 => None,
             CharsError::Other(ref e) => e.cause(),
@@ -778,6 +836,7 @@ impl StdError for CharsError {
     }
 }
 
+#[unstable(feature = "io", reason = "awaiting stability of Read::chars")]
 impl fmt::Display for CharsError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
@@ -793,19 +852,21 @@ impl fmt::Display for CharsError {
 /// particular byte.
 ///
 /// See `BufReadExt::split` for more information.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Split<B> {
     buf: B,
     delim: u8,
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<B: BufRead> Iterator for Split<B> {
     type Item = Result<Vec<u8>>;
 
     fn next(&mut self) -> Option<Result<Vec<u8>>> {
         let mut buf = Vec::new();
         match self.buf.read_until(self.delim, &mut buf) {
-            Ok(()) if buf.len() == 0 => None,
-            Ok(()) => {
+            Ok(0) => None,
+            Ok(_n) => {
                 if buf[buf.len() - 1] == self.delim {
                     buf.pop();
                 }
@@ -820,18 +881,20 @@ impl<B: BufRead> Iterator for Split<B> {
 /// byte.
 ///
 /// See `BufReadExt::lines` for more information.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Lines<B> {
     buf: B,
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<B: BufRead> Iterator for Lines<B> {
     type Item = Result<String>;
 
     fn next(&mut self) -> Option<Result<String>> {
         let mut buf = String::new();
         match self.buf.read_line(&mut buf) {
-            Ok(()) if buf.len() == 0 => None,
-            Ok(()) => {
+            Ok(0) => None,
+            Ok(_n) => {
                 if buf.ends_with("\n") {
                     buf.pop();
                 }
@@ -846,101 +909,116 @@ impl<B: BufRead> Iterator for Lines<B> {
 mod tests {
     use prelude::v1::*;
     use io::prelude::*;
+    use io;
     use super::Cursor;
 
     #[test]
     fn read_until() {
-        let mut buf = Cursor::new(b"12");
+        let mut buf = Cursor::new(&b"12"[..]);
         let mut v = Vec::new();
-        assert_eq!(buf.read_until(b'3', &mut v), Ok(()));
+        assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 2);
         assert_eq!(v, b"12");
 
-        let mut buf = Cursor::new(b"1233");
+        let mut buf = Cursor::new(&b"1233"[..]);
         let mut v = Vec::new();
-        assert_eq!(buf.read_until(b'3', &mut v), Ok(()));
+        assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 3);
         assert_eq!(v, b"123");
         v.truncate(0);
-        assert_eq!(buf.read_until(b'3', &mut v), Ok(()));
+        assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 1);
         assert_eq!(v, b"3");
         v.truncate(0);
-        assert_eq!(buf.read_until(b'3', &mut v), Ok(()));
+        assert_eq!(buf.read_until(b'3', &mut v).unwrap(), 0);
         assert_eq!(v, []);
     }
 
     #[test]
     fn split() {
-        let mut buf = Cursor::new(b"12");
+        let buf = Cursor::new(&b"12"[..]);
         let mut s = buf.split(b'3');
-        assert_eq!(s.next(), Some(Ok(vec![b'1', b'2'])));
-        assert_eq!(s.next(), None);
+        assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']);
+        assert!(s.next().is_none());
 
-        let mut buf = Cursor::new(b"1233");
+        let buf = Cursor::new(&b"1233"[..]);
         let mut s = buf.split(b'3');
-        assert_eq!(s.next(), Some(Ok(vec![b'1', b'2'])));
-        assert_eq!(s.next(), Some(Ok(vec![])));
-        assert_eq!(s.next(), None);
+        assert_eq!(s.next().unwrap().unwrap(), vec![b'1', b'2']);
+        assert_eq!(s.next().unwrap().unwrap(), vec![]);
+        assert!(s.next().is_none());
     }
 
     #[test]
     fn read_line() {
-        let mut buf = Cursor::new(b"12");
+        let mut buf = Cursor::new(&b"12"[..]);
         let mut v = String::new();
-        assert_eq!(buf.read_line(&mut v), Ok(()));
+        assert_eq!(buf.read_line(&mut v).unwrap(), 2);
         assert_eq!(v, "12");
 
-        let mut buf = Cursor::new(b"12\n\n");
+        let mut buf = Cursor::new(&b"12\n\n"[..]);
         let mut v = String::new();
-        assert_eq!(buf.read_line(&mut v), Ok(()));
+        assert_eq!(buf.read_line(&mut v).unwrap(), 3);
         assert_eq!(v, "12\n");
         v.truncate(0);
-        assert_eq!(buf.read_line(&mut v), Ok(()));
+        assert_eq!(buf.read_line(&mut v).unwrap(), 1);
         assert_eq!(v, "\n");
         v.truncate(0);
-        assert_eq!(buf.read_line(&mut v), Ok(()));
+        assert_eq!(buf.read_line(&mut v).unwrap(), 0);
         assert_eq!(v, "");
     }
 
     #[test]
     fn lines() {
-        let mut buf = Cursor::new(b"12");
+        let buf = Cursor::new(&b"12"[..]);
         let mut s = buf.lines();
-        assert_eq!(s.next(), Some(Ok("12".to_string())));
-        assert_eq!(s.next(), None);
+        assert_eq!(s.next().unwrap().unwrap(), "12".to_string());
+        assert!(s.next().is_none());
 
-        let mut buf = Cursor::new(b"12\n\n");
+        let buf = Cursor::new(&b"12\n\n"[..]);
         let mut s = buf.lines();
-        assert_eq!(s.next(), Some(Ok("12".to_string())));
-        assert_eq!(s.next(), Some(Ok(String::new())));
-        assert_eq!(s.next(), None);
+        assert_eq!(s.next().unwrap().unwrap(), "12".to_string());
+        assert_eq!(s.next().unwrap().unwrap(), "".to_string());
+        assert!(s.next().is_none());
     }
 
     #[test]
     fn read_to_end() {
-        let mut c = Cursor::new(b"");
+        let mut c = Cursor::new(&b""[..]);
         let mut v = Vec::new();
-        assert_eq!(c.read_to_end(&mut v), Ok(()));
+        assert_eq!(c.read_to_end(&mut v).unwrap(), 0);
         assert_eq!(v, []);
 
-        let mut c = Cursor::new(b"1");
+        let mut c = Cursor::new(&b"1"[..]);
         let mut v = Vec::new();
-        assert_eq!(c.read_to_end(&mut v), Ok(()));
+        assert_eq!(c.read_to_end(&mut v).unwrap(), 1);
         assert_eq!(v, b"1");
     }
 
     #[test]
     fn read_to_string() {
-        let mut c = Cursor::new(b"");
+        let mut c = Cursor::new(&b""[..]);
         let mut v = String::new();
-        assert_eq!(c.read_to_string(&mut v), Ok(()));
+        assert_eq!(c.read_to_string(&mut v).unwrap(), 0);
         assert_eq!(v, "");
 
-        let mut c = Cursor::new(b"1");
+        let mut c = Cursor::new(&b"1"[..]);
         let mut v = String::new();
-        assert_eq!(c.read_to_string(&mut v), Ok(()));
+        assert_eq!(c.read_to_string(&mut v).unwrap(), 1);
         assert_eq!(v, "1");
 
-        let mut c = Cursor::new(b"\xff");
+        let mut c = Cursor::new(&b"\xff"[..]);
         let mut v = String::new();
         assert!(c.read_to_string(&mut v).is_err());
     }
+
+    #[test]
+    fn take_eof() {
+        struct R;
+
+        impl Read for R {
+            fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
+                Err(io::Error::new(io::ErrorKind::Other, ""))
+            }
+        }
+
+        let mut buf = [0; 1];
+        assert_eq!(0, R.take(0).read(&mut buf).unwrap());
+    }
 }
index 637b1950985fd79f2e9e5c278192aead8c048157..333ae8f26a0d7fa028429ebedeca4218b96cb6a6 100644 (file)
 //! ```
 //!
 //! This module contains reexports of many core I/O traits such as `Read`,
-//! `Write`, `ReadExt`, and `WriteExt`. Structures and functions are not
+//! `Write` and `BufRead`. Structures and functions are not
 //! contained in this module.
 
-pub use super::{Read, ReadExt, Write, WriteExt, BufRead, BufReadExt};
-pub use fs::PathExt;
+#![stable(feature = "rust1", since = "1.0.0")]
 
-// FIXME: pub use as `Seek` when the name isn't in the actual prelude any more
-pub use super::Seek as NewSeek;
+pub use super::{Read, Write, BufRead, Seek};
+pub use fs::PathExt;
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
new file mode 100644 (file)
index 0000000..d361f17
--- /dev/null
@@ -0,0 +1,432 @@
+// Copyright 2015 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 prelude::v1::*;
+use io::prelude::*;
+
+use cell::{RefCell, BorrowState};
+use cmp;
+use fmt;
+use io::lazy::Lazy;
+use io::{self, BufReader, LineWriter};
+use sync::{Arc, Mutex, MutexGuard};
+use sys::stdio;
+
+/// Stdout used by print! and println! macros
+thread_local! {
+    static LOCAL_STDOUT: RefCell<Option<Box<Write + Send>>> = {
+        RefCell::new(None)
+    }
+}
+
+/// A handle to a raw instance of the standard input stream of this process.
+///
+/// This handle is not synchronized or buffered in any fashion. Constructed via
+/// the `std::io::stdio::stdin_raw` function.
+struct StdinRaw(stdio::Stdin);
+
+/// A handle to a raw instance of the standard output stream of this process.
+///
+/// This handle is not synchronized or buffered in any fashion. Constructed via
+/// the `std::io::stdio::stdout_raw` function.
+struct StdoutRaw(stdio::Stdout);
+
+/// A handle to a raw instance of the standard output stream of this process.
+///
+/// This handle is not synchronized or buffered in any fashion. Constructed via
+/// the `std::io::stdio::stderr_raw` function.
+struct StderrRaw(stdio::Stderr);
+
+/// Construct a new raw handle to the standard input of this process.
+///
+/// The returned handle does not interact with any other handles created nor
+/// handles returned by `std::io::stdin`. Data buffered by the `std::io::stdin`
+/// handles is **not** available to raw handles returned from this function.
+///
+/// The returned handle has no external synchronization or buffering.
+fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }
+
+/// Construct a new raw handle to the standard input stream of this process.
+///
+/// The returned handle does not interact with any other handles created nor
+/// handles returned by `std::io::stdout`. Note that data is buffered by the
+/// `std::io::stdin` handles so writes which happen via this raw handle may
+/// appear before previous writes.
+///
+/// The returned handle has no external synchronization or buffering layered on
+/// top.
+fn stdout_raw() -> StdoutRaw { StdoutRaw(stdio::Stdout::new()) }
+
+/// Construct a new raw handle to the standard input stream of this process.
+///
+/// The returned handle does not interact with any other handles created nor
+/// handles returned by `std::io::stdout`.
+///
+/// The returned handle has no external synchronization or buffering layered on
+/// top.
+fn stderr_raw() -> StderrRaw { StderrRaw(stdio::Stderr::new()) }
+
+impl Read for StdinRaw {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
+}
+impl Write for StdoutRaw {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+impl Write for StderrRaw {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+
+/// A handle to the standard input stream of a process.
+///
+/// Each handle is a shared reference to a global buffer of input data to this
+/// process. A handle can be `lock`'d to gain full access to `BufRead` methods
+/// (e.g. `.lines()`). Writes to this handle are otherwise locked with respect
+/// to other writes.
+///
+/// This handle implements the `Read` trait, but beware that concurrent reads
+/// of `Stdin` must be executed with care.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Stdin {
+    inner: Arc<Mutex<BufReader<StdinRaw>>>,
+}
+
+/// A locked reference to the a `Stdin` handle.
+///
+/// This handle implements both the `Read` and `BufRead` traits and is
+/// constructed via the `lock` method on `Stdin`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct StdinLock<'a> {
+    inner: MutexGuard<'a, BufReader<StdinRaw>>,
+}
+
+/// Create a new handle to the global standard input stream of this process.
+///
+/// The handle returned refers to a globally shared buffer between all threads.
+/// Access is synchronized and can be explicitly controlled with the `lock()`
+/// method.
+///
+/// The `Read` trait is implemented for the returned value but the `BufRead`
+/// trait is not due to the global nature of the standard input stream. The
+/// locked version, `StdinLock`, implements both `Read` and `BufRead`, however.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn stdin() -> Stdin {
+    static INSTANCE: Lazy<Mutex<BufReader<StdinRaw>>> = lazy_init!(stdin_init);
+    return Stdin {
+        inner: INSTANCE.get().expect("cannot access stdin during shutdown"),
+    };
+
+    fn stdin_init() -> Arc<Mutex<BufReader<StdinRaw>>> {
+        // The default buffer capacity is 64k, but apparently windows
+        // doesn't like 64k reads on stdin. See #13304 for details, but the
+        // idea is that on windows we use a slightly smaller buffer that's
+        // been seen to be acceptable.
+        Arc::new(Mutex::new(if cfg!(windows) {
+            BufReader::with_capacity(8 * 1024, stdin_raw())
+        } else {
+            BufReader::new(stdin_raw())
+        }))
+    }
+}
+
+impl Stdin {
+    /// Lock this handle to the standard input stream, returning a readable
+    /// guard.
+    ///
+    /// The lock is released when the returned lock goes out of scope. The
+    /// returned guard also implements the `Read` and `BufRead` traits for
+    /// accessing the underlying data.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn lock(&self) -> StdinLock {
+        StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
+    }
+
+    /// Locks this handle and reads a line of input into the specified buffer.
+    ///
+    /// For detailed semantics of this method, see the documentation on
+    /// `BufRead::read_line`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
+        self.lock().read_line(buf)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Read for Stdin {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        self.lock().read(buf)
+    }
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        self.lock().read_to_end(buf)
+    }
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
+        self.lock().read_to_string(buf)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> Read for StdinLock<'a> {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        self.inner.read(buf)
+    }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> BufRead for StdinLock<'a> {
+    fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
+    fn consume(&mut self, n: usize) { self.inner.consume(n) }
+}
+
+// As with stdin on windows, stdout often can't handle writes of large
+// sizes. For an example, see #14940. For this reason, don't try to
+// write the entire output buffer on windows. On unix we can just
+// write the whole buffer all at once.
+//
+// For some other references, it appears that this problem has been
+// encountered by others [1] [2]. We choose the number 8KB just because
+// libuv does the same.
+//
+// [1]: https://tahoe-lafs.org/trac/tahoe-lafs/ticket/1232
+// [2]: http://www.mail-archive.com/log4net-dev@logging.apache.org/msg00661.html
+#[cfg(windows)]
+const OUT_MAX: usize = 8192;
+#[cfg(unix)]
+const OUT_MAX: usize = ::usize::MAX;
+
+/// A handle to the global standard output stream of the current process.
+///
+/// Each handle shares a global buffer of data to be written to the standard
+/// output stream. Access is also synchronized via a lock and explicit control
+/// over locking is available via the `lock` method.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Stdout {
+    // FIXME: this should be LineWriter or BufWriter depending on the state of
+    //        stdout (tty or not). Note that if this is not line buffered it
+    //        should also flush-on-panic or some form of flush-on-abort.
+    inner: Arc<Mutex<LineWriter<StdoutRaw>>>,
+}
+
+/// A locked reference to the a `Stdout` handle.
+///
+/// This handle implements the `Write` trait and is constructed via the `lock`
+/// method on `Stdout`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct StdoutLock<'a> {
+    inner: MutexGuard<'a, LineWriter<StdoutRaw>>,
+}
+
+/// Constructs a new reference to the standard output of the current process.
+///
+/// Each handle returned is a reference to a shared global buffer whose access
+/// is synchronized via a mutex. Explicit control over synchronization is
+/// provided via the `lock` method.
+///
+/// The returned handle implements the `Write` trait.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn stdout() -> Stdout {
+    static INSTANCE: Lazy<Mutex<LineWriter<StdoutRaw>>> = lazy_init!(stdout_init);
+    return Stdout {
+        inner: INSTANCE.get().expect("cannot access stdout during shutdown"),
+    };
+
+    fn stdout_init() -> Arc<Mutex<LineWriter<StdoutRaw>>> {
+        Arc::new(Mutex::new(LineWriter::new(stdout_raw())))
+    }
+}
+
+impl Stdout {
+    /// Lock this handle to the standard output stream, returning a writable
+    /// guard.
+    ///
+    /// The lock is released when the returned lock goes out of scope. The
+    /// returned guard also implements the `Write` trait for writing data.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn lock(&self) -> StdoutLock {
+        StdoutLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Write for Stdout {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.lock().write(buf)
+    }
+    fn flush(&mut self) -> io::Result<()> {
+        self.lock().flush()
+    }
+    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+        self.lock().write_all(buf)
+    }
+    // Don't override write_fmt as it's possible to run arbitrary code during a
+    // write_fmt, allowing the possibility of a recursive lock (aka deadlock)
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> Write for StdoutLock<'a> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
+    }
+    fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
+}
+
+/// A handle to the standard error stream of a process.
+///
+/// For more information, see `stderr`
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Stderr {
+    inner: Arc<Mutex<StderrRaw>>,
+}
+
+/// A locked reference to the a `Stderr` handle.
+///
+/// This handle implements the `Write` trait and is constructed via the `lock`
+/// method on `Stderr`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct StderrLock<'a> {
+    inner: MutexGuard<'a, StderrRaw>,
+}
+
+/// Constructs a new reference to the standard error stream of a process.
+///
+/// Each returned handle is synchronized amongst all other handles created from
+/// this function. No handles are buffered, however.
+///
+/// The returned handle implements the `Write` trait.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn stderr() -> Stderr {
+    static INSTANCE: Lazy<Mutex<StderrRaw>> = lazy_init!(stderr_init);
+    return Stderr {
+        inner: INSTANCE.get().expect("cannot access stderr during shutdown"),
+    };
+
+    fn stderr_init() -> Arc<Mutex<StderrRaw>> {
+        Arc::new(Mutex::new(stderr_raw()))
+    }
+}
+
+impl Stderr {
+    /// Lock this handle to the standard error stream, returning a writable
+    /// guard.
+    ///
+    /// The lock is released when the returned lock goes out of scope. The
+    /// returned guard also implements the `Write` trait for writing data.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn lock(&self) -> StderrLock {
+        StderrLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Write for Stderr {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.lock().write(buf)
+    }
+    fn flush(&mut self) -> io::Result<()> {
+        self.lock().flush()
+    }
+    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+        self.lock().write_all(buf)
+    }
+    // Don't override write_fmt for the same reasons as Stdout
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> Write for StderrLock<'a> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
+    }
+    fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
+}
+
+/// Resets the task-local stderr handle to the specified writer
+///
+/// This will replace the current task's stderr handle, returning the old
+/// handle. All future calls to `panic!` and friends will emit their output to
+/// this specified handle.
+///
+/// Note that this does not need to be called for all new tasks; the default
+/// output handle is to the process's stderr stream.
+#[unstable(feature = "set_stdio",
+           reason = "this function may disappear completely or be replaced \
+                     with a more general mechanism")]
+#[doc(hidden)]
+pub fn set_panic(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
+    use panicking::LOCAL_STDERR;
+    use mem;
+    LOCAL_STDERR.with(move |slot| {
+        mem::replace(&mut *slot.borrow_mut(), Some(sink))
+    }).and_then(|mut s| {
+        let _ = s.flush();
+        Some(s)
+    })
+}
+
+/// Resets the task-local stdout handle to the specified writer
+///
+/// This will replace the current task's stdout handle, returning the old
+/// handle. All future calls to `print!` and friends will emit their output to
+/// this specified handle.
+///
+/// Note that this does not need to be called for all new tasks; the default
+/// output handle is to the process's stdout stream.
+#[unstable(feature = "set_stdio",
+           reason = "this function may disappear completely or be replaced \
+                     with a more general mechanism")]
+#[doc(hidden)]
+pub fn set_print(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
+    use mem;
+    LOCAL_STDOUT.with(move |slot| {
+        mem::replace(&mut *slot.borrow_mut(), Some(sink))
+    }).and_then(|mut s| {
+        let _ = s.flush();
+        Some(s)
+    })
+}
+
+#[unstable(feature = "print",
+           reason = "implementation detail which may disappear or be replaced at any time")]
+#[doc(hidden)]
+pub fn _print(args: fmt::Arguments) {
+    let result = LOCAL_STDOUT.with(|s| {
+        if s.borrow_state() == BorrowState::Unused {
+            if let Some(w) = s.borrow_mut().as_mut() {
+                return w.write_fmt(args);
+            }
+        }
+        stdout().write_fmt(args)
+    });
+    if let Err(e) = result {
+        panic!("failed printing to stdout: {}", e);
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use thread;
+    use super::*;
+
+    #[test]
+    fn panic_doesnt_poison() {
+        thread::spawn(|| {
+            let _a = stdin();
+            let _a = _a.lock();
+            let _a = stdout();
+            let _a = _a.lock();
+            let _a = stderr();
+            let _a = _a.lock();
+            panic!();
+        }).join().unwrap_err();
+
+        let _a = stdin();
+        let _a = _a.lock();
+        let _a = stdout();
+        let _a = _a.lock();
+        let _a = stderr();
+        let _a = _a.lock();
+    }
+}
index 3d342137c62ddd3d3a340811384d1dc2e166efd8..c82f9515e8d52813ba494a6b0a48b0b71bc27a65 100644 (file)
@@ -12,7 +12,7 @@
 
 use prelude::v1::*;
 
-use io::{self, Read, Write, ErrorKind};
+use io::{self, Read, Write, ErrorKind, BufRead};
 
 /// Copies the entire contents of a reader into a writer.
 ///
@@ -27,6 +27,7 @@ use io::{self, Read, Write, ErrorKind};
 /// This function will return an error immediately if any call to `read` or
 /// `write` returns an error. All instances of `ErrorKind::Interrupted` are
 /// handled by this function and the underlying operation is retried.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn copy<R: Read, W: Write>(r: &mut R, w: &mut W) -> io::Result<u64> {
     let mut buf = [0; super::DEFAULT_BUF_SIZE];
     let mut written = 0;
@@ -43,26 +44,37 @@ pub fn copy<R: Read, W: Write>(r: &mut R, w: &mut W) -> io::Result<u64> {
 }
 
 /// A reader which is always at EOF.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Empty { _priv: () }
 
 /// Creates an instance of an empty reader.
 ///
 /// All reads from the returned reader will return `Ok(0)`.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn empty() -> Empty { Empty { _priv: () } }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Read for Empty {
     fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl BufRead for Empty {
+    fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
+    fn consume(&mut self, _n: usize) {}
+}
 
 /// A reader which infinitely yields one byte.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Repeat { byte: u8 }
 
 /// Creates an instance of a reader that infinitely repeats one byte.
 ///
 /// All reads from this reader will succeed by filling the specified buffer with
 /// the given byte.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Read for Repeat {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         for slot in buf.iter_mut() {
@@ -73,14 +85,17 @@ impl Read for Repeat {
 }
 
 /// A writer which will move data into the void.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Sink { _priv: () }
 
 /// Creates an instance of a writer which will successfully consume all data.
 ///
 /// All calls to `write` on the returned instance will return `Ok(buf.len())`
 /// and the contents of the buffer will not be inspected.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn sink() -> Sink { Sink { _priv: () } }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Write for Sink {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
@@ -96,33 +111,33 @@ mod test {
     #[test]
     fn sink_sinks() {
         let mut s = sink();
-        assert_eq!(s.write(&[]), Ok(0));
-        assert_eq!(s.write(&[0]), Ok(1));
-        assert_eq!(s.write(&[0; 1024]), Ok(1024));
-        assert_eq!(s.by_ref().write(&[0; 1024]), Ok(1024));
+        assert_eq!(s.write(&[]).unwrap(), 0);
+        assert_eq!(s.write(&[0]).unwrap(), 1);
+        assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
+        assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
     }
 
     #[test]
     fn empty_reads() {
         let mut e = empty();
-        assert_eq!(e.read(&mut []), Ok(0));
-        assert_eq!(e.read(&mut [0]), Ok(0));
-        assert_eq!(e.read(&mut [0; 1024]), Ok(0));
-        assert_eq!(e.by_ref().read(&mut [0; 1024]), Ok(0));
+        assert_eq!(e.read(&mut []).unwrap(), 0);
+        assert_eq!(e.read(&mut [0]).unwrap(), 0);
+        assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
+        assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
     }
 
     #[test]
     fn repeat_repeats() {
         let mut r = repeat(4);
         let mut b = [0; 1024];
-        assert_eq!(r.read(&mut b), Ok(1024));
+        assert_eq!(r.read(&mut b).unwrap(), 1024);
         assert!(b.iter().all(|b| *b == 4));
     }
 
     #[test]
     fn take_some_bytes() {
         assert_eq!(repeat(4).take(100).bytes().count(), 100);
-        assert_eq!(repeat(4).take(100).bytes().next(), Some(Ok(4)));
+        assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
         assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20);
     }
 
@@ -131,7 +146,7 @@ mod test {
         let mut buf = [0; 10];
         {
             let mut ptr: &mut [u8] = &mut buf;
-            assert_eq!(repeat(4).tee(&mut ptr).take(5).read(&mut [0; 10]), Ok(5));
+            assert_eq!(repeat(4).tee(&mut ptr).take(5).read(&mut [0; 10]).unwrap(), 5);
         }
         assert_eq!(buf, [4, 4, 4, 4, 4, 0, 0, 0, 0, 0]);
     }
@@ -145,7 +160,7 @@ mod test {
             let mut ptr2: &mut [u8] = &mut buf2;
 
             assert_eq!((&mut ptr1).broadcast(&mut ptr2)
-                                  .write(&[1, 2, 3]), Ok(3));
+                                  .write(&[1, 2, 3]).unwrap(), 3);
         }
         assert_eq!(buf1, buf2);
         assert_eq!(buf1, [1, 2, 3, 0, 0, 0, 0, 0, 0, 0]);
index fbd403ea593b8a970b0218f876a193d4cc71f778..5c9ff544fa3e8f3380b0876f87bf8e6495a4ef5e 100644 (file)
 //!
 //! ## Vectors, slices and strings
 //!
-//! The common container type, `Vec`, a growable vector backed by an
-//! array, lives in the [`vec`](vec/index.html) module. References to
-//! arrays, `&[T]`, more commonly called "slices", are built-in types
-//! for which the [`slice`](slice/index.html) module defines many
-//! methods.
+//! The common container type, `Vec`, a growable vector backed by an array,
+//! lives in the [`vec`](vec/index.html) module. Contiguous, unsized regions
+//! of memory, `[T]`, commonly called "slices", and their borrowed versions,
+//! `&[T]`, commonly called "borrowed slices", are built-in types for which the
+//! [`slice`](slice/index.html) module defines many methods.
 //!
 //! `&str`, a UTF-8 string, is a built-in type, and the standard library
 //! defines methods for it on a variety of traits in the
 //! module encapsulates the platform-specific rules for dealing
 //! with file paths.
 //!
-//! `std` also includes modules for interoperating with the
-//! C language: [`c_str`](c_str/index.html) and
-//! [`c_vec`](c_vec/index.html).
+//! `std` also includes the [`ffi`](ffi/index.html) module for interoperating
+//! with the C language.
 //!
 //! ## Concurrency, I/O, and the runtime
 //!
-//! The [`thread`](thread/index.html) module contains Rust's threading abstractions,
-//! while [`comm`](comm/index.html) contains the channel types for message
-//! passing. [`sync`](sync/index.html) contains further, primitive, shared
-//! memory types, including [`atomic`](sync/atomic/index.html).
+//! The [`thread`](thread/index.html) module contains Rust's threading abstractions.
+//! [`sync`](sync/index.html) contains further, primitive, shared memory types,
+//! including [`atomic`](sync/atomic/index.html), and [`mpsc`](sync/mpsc/index.html),
+//! which contains the channel types for message passing.
 //!
 //! Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets,
 //! timers, and process spawning, are defined in the
@@ -94,7 +93,8 @@
 //! to all code by default. [`macros`](macros/index.html) contains
 //! all the standard macros, such as `assert!`, `panic!`, `println!`,
 //! and `format!`, also available to all Rust code.
-
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "std"]
 #![stable(feature = "rust1", since = "1.0.0")]
 #![staged_api]
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
+#![doc(test(no_crate_inject))]
 
 #![feature(alloc)]
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(hash)]
-#![feature(int_uint)]
 #![feature(lang_items)]
 #![feature(libc)]
 #![feature(linkage, thread_local, asm)]
-#![feature(old_impl_check)]
 #![feature(optin_builtin_traits)]
 #![feature(rand)]
 #![feature(staged_api)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
 #![feature(unsafe_destructor)]
-#![feature(unsafe_no_drop_flag)]
+#![feature(unsafe_no_drop_flag, filling_drop)]
 #![feature(macro_reexport)]
-#![cfg_attr(test, feature(test))]
+#![feature(unique)]
+#![feature(allow_internal_unstable)]
+#![feature(str_char)]
+#![feature(into_cow)]
+#![feature(std_misc)]
+#![feature(slice_patterns)]
+#![feature(debug_builders)]
+#![cfg_attr(test, feature(test, rustc_private, std_misc))]
 
 // Don't link to std. We are std.
 #![feature(no_std)]
 #![no_std]
 
+#![allow(trivial_casts)]
 #![deny(missing_docs)]
 
 #[cfg(test)] extern crate test;
@@ -141,9 +147,9 @@ extern crate core;
 
 #[macro_use]
 #[macro_reexport(vec, format)]
-extern crate "collections" as core_collections;
+extern crate collections as core_collections;
 
-#[allow(deprecated)] extern crate "rand" as core_rand;
+#[allow(deprecated)] extern crate rand as core_rand;
 extern crate alloc;
 extern crate unicode;
 extern crate libc;
@@ -151,7 +157,7 @@ extern crate libc;
 #[macro_use] #[no_link] extern crate rustc_bitflags;
 
 // Make std testable by not duplicating lang items. See #2912
-#[cfg(test)] extern crate "std" as realstd;
+#[cfg(test)] extern crate std as realstd;
 #[cfg(test)] pub use realstd::marker;
 #[cfg(test)] pub use realstd::ops;
 #[cfg(test)] pub use realstd::cmp;
@@ -164,9 +170,8 @@ pub use core::any;
 pub use core::cell;
 pub use core::clone;
 #[cfg(not(test))] pub use core::cmp;
+pub use core::convert;
 pub use core::default;
-#[allow(deprecated)]
-pub use core::finally;
 pub use core::hash;
 pub use core::intrinsics;
 pub use core::iter;
@@ -178,7 +183,7 @@ pub use core::raw;
 pub use core::simd;
 pub use core::result;
 pub use core::option;
-pub use core::error;
+pub mod error;
 
 #[cfg(not(test))] pub use alloc::boxed;
 pub use alloc::rc;
@@ -207,6 +212,9 @@ pub mod prelude;
 
 /* Primitive types */
 
+// NB: slice and str are primitive types too, but their module docs + primitive doc pages
+// are inlined from the public re-exports of core_collections::{slice, str} above.
+
 #[path = "num/float_macros.rs"]
 #[macro_use]
 mod float_macros;
@@ -219,14 +227,12 @@ mod int_macros;
 #[macro_use]
 mod uint_macros;
 
-#[path = "num/int.rs"]  pub mod int;
 #[path = "num/isize.rs"]  pub mod isize;
 #[path = "num/i8.rs"]   pub mod i8;
 #[path = "num/i16.rs"]  pub mod i16;
 #[path = "num/i32.rs"]  pub mod i32;
 #[path = "num/i64.rs"]  pub mod i64;
 
-#[path = "num/uint.rs"] pub mod uint;
 #[path = "num/usize.rs"] pub mod usize;
 #[path = "num/u8.rs"]   pub mod u8;
 #[path = "num/u16.rs"]  pub mod u16;
@@ -237,6 +243,7 @@ mod uint_macros;
 #[path = "num/f64.rs"]   pub mod f64;
 
 pub mod ascii;
+
 pub mod thunk;
 
 /* Common traits */
@@ -246,43 +253,38 @@ pub mod num;
 /* Runtime and platform support */
 
 #[macro_use]
-pub mod thread_local;
+pub mod thread;
 
+pub mod collections;
 pub mod dynamic_lib;
+pub mod env;
 pub mod ffi;
-pub mod old_io;
-pub mod io;
 pub mod fs;
+pub mod io;
 pub mod net;
+pub mod old_io;
+pub mod old_path;
 pub mod os;
-pub mod env;
 pub mod path;
-pub mod old_path;
 pub mod process;
 pub mod rand;
+pub mod sync;
 pub mod time;
 
-/* Common data structures */
-
-pub mod collections;
-
-/* Threads and communication */
-
-pub mod thread;
-pub mod sync;
+#[macro_use]
+#[path = "sys/common/mod.rs"] mod sys_common;
 
 #[cfg(unix)]
 #[path = "sys/unix/mod.rs"] mod sys;
 #[cfg(windows)]
 #[path = "sys/windows/mod.rs"] mod sys;
 
-#[path = "sys/common/mod.rs"] mod sys_common;
-
 pub mod rt;
 mod panicking;
 
-// Documentation for primitive types
+// Modules that exist purely to document + host impl docs for primitive types
 
+mod array;
 mod bool;
 mod unit;
 mod tuple;
@@ -295,12 +297,13 @@ mod std {
     pub use sync; // used for select!()
     pub use error; // used for try!()
     pub use fmt; // used for any formatting strings
+    #[allow(deprecated)]
     pub use old_io; // used for println!()
     pub use option; // used for bitflags!{}
     pub use rt; // used for panic!()
     pub use vec; // used for vec![]
     pub use cell; // used for tls!
-    pub use thread_local; // used for thread_local!
+    pub use thread; // used for thread_local!
     pub use marker;  // used for tls!
     pub use ops; // used for bitflags!
 
index 00bb7f86b170cf47b536ed5bdfac11b0405dd590..b3d1adb44218a7e302037dd466640ece8a2039e0 100644 (file)
@@ -26,9 +26,9 @@
 /// The multi-argument form of this macro panics with a string and has the
 /// `format!` syntax for building a string.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```should_fail
+/// ```should_panic
 /// # #![allow(unreachable_code)]
 /// panic!();
 /// panic!("this is a terrible mistake!");
@@ -44,7 +44,7 @@ macro_rules! panic {
     ($msg:expr) => ({
         $crate::rt::begin_unwind($msg, {
             // static requires less code at runtime, more constant data
-            static _FILE_LINE: (&'static str, usize) = (file!(), line!());
+            static _FILE_LINE: (&'static str, usize) = (file!(), line!() as usize);
             &_FILE_LINE
         })
     });
@@ -54,27 +54,33 @@ macro_rules! panic {
             // used inside a dead function. Just `#[allow(dead_code)]` is
             // insufficient, since the user may have
             // `#[forbid(dead_code)]` and which cannot be overridden.
-            static _FILE_LINE: (&'static str, usize) = (file!(), line!());
+            static _FILE_LINE: (&'static str, usize) = (file!(), line!() as usize);
             &_FILE_LINE
         })
     });
 }
 
+/// Macro for printing to the standard output.
+///
 /// Equivalent to the `println!` macro except that a newline is not printed at
 /// the end of the message.
+///
+/// Note that stdout is frequently line-buffered by default so it may be
+/// necessary to use `io::stdout().flush()` to ensure the output is emitted
+/// immediately.
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow_internal_unstable]
 macro_rules! print {
-    ($($arg:tt)*) => ($crate::old_io::stdio::print_args(format_args!($($arg)*)))
+    ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
 }
 
-/// Macro for printing to a task's stdout handle.
+/// Macro for printing to the standard output.
 ///
-/// Each task can override its stdout handle via `std::old_io::stdio::set_stdout`.
-/// The syntax of this macro is the same as that used for `format!`. For more
-/// information, see `std::fmt` and `std::old_io::stdio`.
+/// Use the `format!` syntax to write data to the standard output.
+/// See `std::fmt` for more information.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// println!("hello there!");
@@ -83,19 +89,19 @@ macro_rules! print {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! println {
-    ($($arg:tt)*) => ($crate::old_io::stdio::println_args(format_args!($($arg)*)))
+    ($fmt:expr) => (print!(concat!($fmt, "\n")));
+    ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
 }
 
 /// Helper macro for unwrapping `Result` values while returning early with an
-/// error if the value of the expression is `Err`. For more information, see
-/// `std::io`.
+/// error if the value of the expression is `Err`.
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! try {
     ($expr:expr) => (match $expr {
         $crate::result::Result::Ok(val) => val,
         $crate::result::Result::Err(err) => {
-            return $crate::result::Result::Err($crate::error::FromError::from_error(err))
+            return $crate::result::Result::Err($crate::convert::From::from(err))
         }
     })
 }
@@ -109,6 +115,7 @@ macro_rules! try {
 /// # Examples
 ///
 /// ```
+/// # #![feature(std_misc)]
 /// use std::thread;
 /// use std::sync::mpsc;
 ///
@@ -177,9 +184,9 @@ pub mod builtin {
     ///
     /// For more information, see the documentation in `std::fmt`.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::fmt;
     ///
     /// let s = fmt::format(format_args!("hello {}", "world"));
@@ -200,9 +207,9 @@ pub mod builtin {
     /// will be emitted.  To not emit a compile error, use the `option_env!`
     /// macro instead.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let path: &'static str = env!("PATH");
     /// println!("the $PATH variable at the time of compiling was: {}", path);
     /// ```
@@ -219,9 +226,9 @@ pub mod builtin {
     /// A compile time error is never emitted when using this macro regardless
     /// of whether the environment variable is present or not.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let key: Option<&'static str> = option_env!("SECRET_KEY");
     /// println!("the secret key might be: {:?}", key);
     /// ```
@@ -263,7 +270,7 @@ pub mod builtin {
     /// Integer and floating point literals are stringified in order to be
     /// concatenated.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let s = concat!("test", 10, 'b', true);
@@ -278,7 +285,7 @@ pub mod builtin {
     /// the invocation of the `line!()` macro itself, but rather the first macro
     /// invocation leading up to the invocation of the `line!()` macro.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let current_line = line!();
@@ -293,7 +300,7 @@ pub mod builtin {
     /// the invocation of the `column!()` macro itself, but rather the first macro
     /// invocation leading up to the invocation of the `column!()` macro.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let current_col = column!();
@@ -309,7 +316,7 @@ pub mod builtin {
     /// first macro invocation leading up to the invocation of the `file!()`
     /// macro.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let this_file = file!();
@@ -324,7 +331,7 @@ pub mod builtin {
     /// stringification of all the tokens passed to the macro. No restrictions
     /// are placed on the syntax of the macro invocation itself.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// let one_plus_one = stringify!(1 + 1);
@@ -339,7 +346,7 @@ pub mod builtin {
     /// contents of the filename specified. The file is located relative to the
     /// current file (similarly to how modules are found),
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```rust,ignore
     /// let secret_key = include_str!("secret-key.ascii");
@@ -353,7 +360,7 @@ pub mod builtin {
     /// the contents of the filename specified. The file is located relative to
     /// the current file (similarly to how modules are found),
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```rust,ignore
     /// let secret_key = include_bytes!("secret-key.bin");
@@ -367,9 +374,9 @@ pub mod builtin {
     /// leading back up to the crate root. The first component of the path
     /// returned is the name of the crate currently being compiled.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// mod test {
     ///     pub fn foo() {
     ///         assert!(module_path!().ends_with("test"));
@@ -390,9 +397,9 @@ pub mod builtin {
     /// The syntax given to this macro is the same syntax as the `cfg`
     /// attribute.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// let my_directory = if cfg!(windows) {
     ///     "windows-specific-directory"
     /// } else {
@@ -401,4 +408,18 @@ pub mod builtin {
     /// ```
     #[macro_export]
     macro_rules! cfg { ($cfg:tt) => ({ /* compiler built-in */ }) }
+
+    /// Parse the current given file as an expression.
+    ///
+    /// This is generally a bad idea, because it's going to behave unhygenically.
+    ///
+    /// # Examples
+    ///
+    /// ```ignore
+    /// fn foo() {
+    ///     include!("/path/to/a/file")
+    /// }
+    /// ```
+    #[macro_export]
+    macro_rules! include { ($cfg:tt) => ({ /* compiler built-in */ }) }
 }
index 51944adf3b40395f7adb88b57943ce2fb21a5b3d..886f252fb192672b086bc347b87f8b0acae2d130 100644 (file)
@@ -15,165 +15,238 @@ use hash;
 use io;
 use libc::{self, socklen_t, sa_family_t};
 use mem;
-use net::{IpAddr, lookup_host, ntoh, hton};
+use net::{lookup_host, ntoh, hton, IpAddr, Ipv4Addr, Ipv6Addr};
 use option;
 use sys_common::{FromInner, AsInner, IntoInner};
 use vec;
 
-/// Representation of a socket address for networking applications
+/// Representation of a socket address for networking applications.
 ///
-/// A socket address consists of at least an (ip, port) pair and may also
-/// contain other information depending on the protocol.
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct SocketAddr {
-    repr: Repr,
+/// A socket address can either represent the IPv4 or IPv6 protocol and is
+/// paired with at least a port number as well. Each protocol may have more
+/// specific information about the address available to it as well.
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum SocketAddr {
+    /// An IPv4 socket address which is a (ip, port) combination.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    V4(SocketAddrV4),
+    /// An IPv6 socket address
+    #[stable(feature = "rust1", since = "1.0.0")]
+    V6(SocketAddrV6),
 }
 
+/// An IPv4 socket address which is a (ip, port) combination.
 #[derive(Copy)]
-enum Repr {
-    V4(libc::sockaddr_in),
-    V6(libc::sockaddr_in6),
-}
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct SocketAddrV4 { inner: libc::sockaddr_in }
+
+/// An IPv6 socket address
+#[derive(Copy)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct SocketAddrV6 { inner: libc::sockaddr_in6 }
 
 impl SocketAddr {
     /// Creates a new socket address from the (ip, port) pair.
+    #[unstable(feature = "ip_addr", reason = "recent addition")]
     pub fn new(ip: IpAddr, port: u16) -> SocketAddr {
-        let repr = match ip {
-            IpAddr::V4(ref ip) => {
-                Repr::V4(libc::sockaddr_in {
-                    sin_family: libc::AF_INET as sa_family_t,
-                    sin_port: hton(port),
-                    sin_addr: *ip.as_inner(),
-                    .. unsafe { mem::zeroed() }
-                })
-            }
-            IpAddr::V6(ref ip) => {
-                Repr::V6(libc::sockaddr_in6 {
-                    sin6_family: libc::AF_INET6 as sa_family_t,
-                    sin6_port: hton(port),
-                    sin6_addr: *ip.as_inner(),
-                    .. unsafe { mem::zeroed() }
-                })
-            }
-        };
-        SocketAddr { repr: repr }
+        match ip {
+            IpAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a, port)),
+            IpAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)),
+        }
     }
 
     /// Gets the IP address associated with this socket address.
+    #[unstable(feature = "ip_addr", reason = "recent addition")]
     pub fn ip(&self) -> IpAddr {
-        match self.repr {
-            Repr::V4(ref sa) => IpAddr::V4(FromInner::from_inner(sa.sin_addr)),
-            Repr::V6(ref sa) => IpAddr::V6(FromInner::from_inner(sa.sin6_addr)),
+        match *self {
+            SocketAddr::V4(ref a) => IpAddr::V4(*a.ip()),
+            SocketAddr::V6(ref a) => IpAddr::V6(*a.ip()),
         }
     }
 
     /// Gets the port number associated with this socket address
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn port(&self) -> u16 {
-        match self.repr {
-            Repr::V4(ref sa) => ntoh(sa.sin_port),
-            Repr::V6(ref sa) => ntoh(sa.sin6_port),
+        match *self {
+            SocketAddr::V4(ref a) => a.port(),
+            SocketAddr::V6(ref a) => a.port(),
         }
     }
+}
 
-    fn set_port(&mut self, port: u16) {
-        match self.repr {
-            Repr::V4(ref mut sa) => sa.sin_port = hton(port),
-            Repr::V6(ref mut sa) => sa.sin6_port = hton(port),
+impl SocketAddrV4 {
+    /// Creates a new socket address from the (ip, port) pair.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
+        SocketAddrV4 {
+            inner: libc::sockaddr_in {
+                sin_family: libc::AF_INET as sa_family_t,
+                sin_port: hton(port),
+                sin_addr: *ip.as_inner(),
+                .. unsafe { mem::zeroed() }
+            },
         }
     }
+
+    /// Gets the IP address associated with this socket address.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn ip(&self) -> &Ipv4Addr {
+        unsafe {
+            &*(&self.inner.sin_addr as *const libc::in_addr as *const Ipv4Addr)
+        }
+    }
+
+    /// Gets the port number associated with this socket address
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn port(&self) -> u16 { ntoh(self.inner.sin_port) }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for SocketAddr {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match self.repr {
-            Repr::V4(_) => write!(f, "{}:{}", self.ip(), self.port()),
-            Repr::V6(_) => write!(f, "[{}]:{}", self.ip(), self.port()),
+impl SocketAddrV6 {
+    /// Creates a new socket address from the ip/port/flowinfo/scope_id
+    /// components.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32)
+               -> SocketAddrV6 {
+        SocketAddrV6 {
+            inner: libc::sockaddr_in6 {
+                sin6_family: libc::AF_INET6 as sa_family_t,
+                sin6_port: hton(port),
+                sin6_addr: *ip.as_inner(),
+                sin6_flowinfo: hton(flowinfo),
+                sin6_scope_id: hton(scope_id),
+                .. unsafe { mem::zeroed() }
+            },
         }
     }
+
+    /// Gets the IP address associated with this socket address.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn ip(&self) -> &Ipv6Addr {
+        unsafe {
+            &*(&self.inner.sin6_addr as *const libc::in6_addr as *const Ipv6Addr)
+        }
+    }
+
+    /// Gets the port number associated with this socket address
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn port(&self) -> u16 { ntoh(self.inner.sin6_port) }
+
+    /// Gets scope ID associated with this address, corresponding to the
+    /// `sin6_flowinfo` field in C.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn flowinfo(&self) -> u32 { ntoh(self.inner.sin6_flowinfo) }
+
+    /// Gets scope ID associated with this address, corresponding to the
+    /// `sin6_scope_id` field in C.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn scope_id(&self) -> u32 { ntoh(self.inner.sin6_scope_id) }
 }
 
-impl FromInner<libc::sockaddr_in> for SocketAddr {
-    fn from_inner(addr: libc::sockaddr_in) -> SocketAddr {
-        SocketAddr { repr: Repr::V4(addr) }
+impl FromInner<libc::sockaddr_in> for SocketAddrV4 {
+    fn from_inner(addr: libc::sockaddr_in) -> SocketAddrV4 {
+        SocketAddrV4 { inner: addr }
     }
 }
 
-impl FromInner<libc::sockaddr_in6> for SocketAddr {
-    fn from_inner(addr: libc::sockaddr_in6) -> SocketAddr {
-        SocketAddr { repr: Repr::V6(addr) }
+impl FromInner<libc::sockaddr_in6> for SocketAddrV6 {
+    fn from_inner(addr: libc::sockaddr_in6) -> SocketAddrV6 {
+        SocketAddrV6 { inner: addr }
     }
 }
 
 impl<'a> IntoInner<(*const libc::sockaddr, socklen_t)> for &'a SocketAddr {
     fn into_inner(self) -> (*const libc::sockaddr, socklen_t) {
-        match self.repr {
-            Repr::V4(ref a) => {
+        match *self {
+            SocketAddr::V4(ref a) => {
                 (a as *const _ as *const _, mem::size_of_val(a) as socklen_t)
             }
-            Repr::V6(ref a) => {
+            SocketAddr::V6(ref a) => {
                 (a as *const _ as *const _, mem::size_of_val(a) as socklen_t)
             }
         }
     }
 }
 
-impl fmt::Debug for SocketAddr {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for SocketAddr {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            SocketAddr::V4(ref a) => a.fmt(f),
+            SocketAddr::V6(ref a) => a.fmt(f),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for SocketAddrV4 {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}:{}", self.ip(), self.port())
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Debug for SocketAddrV4 {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(self, fmt)
     }
 }
 
-impl Clone for Repr {
-    fn clone(&self) -> Repr { *self }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for SocketAddrV6 {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "[{}]:{}", self.ip(), self.port())
+    }
 }
 
-impl PartialEq for Repr {
-    fn eq(&self, other: &Repr) -> bool {
-        match (*self, *other) {
-            (Repr::V4(ref a), Repr::V4(ref b)) => {
-                a.sin_port == b.sin_port &&
-                    a.sin_addr.s_addr == b.sin_addr.s_addr
-            }
-            (Repr::V6(ref a), Repr::V6(ref b)) => {
-                a.sin6_port == b.sin6_port &&
-                    a.sin6_addr.s6_addr == b.sin6_addr.s6_addr &&
-                    a.sin6_flowinfo == b.sin6_flowinfo &&
-                    a.sin6_scope_id == b.sin6_scope_id
-            }
-            _ => false,
-        }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Debug for SocketAddrV6 {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(self, fmt)
     }
 }
-impl Eq for Repr {}
 
-#[cfg(stage0)]
-impl<S: hash::Hasher + hash::Writer> hash::Hash<S> for Repr {
-    fn hash(&self, s: &mut S) {
-        match *self {
-            Repr::V4(ref a) => {
-                (a.sin_family, a.sin_port, a.sin_addr.s_addr).hash(s)
-            }
-            Repr::V6(ref a) => {
-                (a.sin6_family, a.sin6_port, &a.sin6_addr.s6_addr,
-                 a.sin6_flowinfo, a.sin6_scope_id).hash(s)
-            }
-        }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Clone for SocketAddrV4 {
+    fn clone(&self) -> SocketAddrV4 { *self }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Clone for SocketAddrV6 {
+    fn clone(&self) -> SocketAddrV6 { *self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl PartialEq for SocketAddrV4 {
+    fn eq(&self, other: &SocketAddrV4) -> bool {
+        self.inner.sin_port == other.inner.sin_port &&
+            self.inner.sin_addr.s_addr == other.inner.sin_addr.s_addr
+    }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl PartialEq for SocketAddrV6 {
+    fn eq(&self, other: &SocketAddrV6) -> bool {
+        self.inner.sin6_port == other.inner.sin6_port &&
+            self.inner.sin6_addr.s6_addr == other.inner.sin6_addr.s6_addr &&
+            self.inner.sin6_flowinfo == other.inner.sin6_flowinfo &&
+            self.inner.sin6_scope_id == other.inner.sin6_scope_id
     }
 }
-#[cfg(not(stage0))]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl hash::Hash for Repr {
+impl Eq for SocketAddrV4 {}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Eq for SocketAddrV6 {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl hash::Hash for SocketAddrV4 {
     fn hash<H: hash::Hasher>(&self, s: &mut H) {
-        match *self {
-            Repr::V4(ref a) => {
-                (a.sin_family, a.sin_port, a.sin_addr.s_addr).hash(s)
-            }
-            Repr::V6(ref a) => {
-                (a.sin6_family, a.sin6_port, &a.sin6_addr.s6_addr,
-                 a.sin6_flowinfo, a.sin6_scope_id).hash(s)
-            }
-        }
+        (self.inner.sin_port, self.inner.sin_addr.s_addr).hash(s)
+    }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl hash::Hash for SocketAddrV6 {
+    fn hash<H: hash::Hasher>(&self, s: &mut H) {
+        (self.inner.sin6_port, &self.inner.sin6_addr.s6_addr,
+         self.inner.sin6_flowinfo, self.inner.sin6_scope_id).hash(s)
     }
 }
 
@@ -183,12 +256,13 @@ impl hash::Hash for Repr {
 /// This trait is used for generic address resolution when constructing network
 /// objects.  By default it is implemented for the following types:
 ///
-///  * `SocketAddr` - `to_socket_addrs` is identity function.
+///  * `SocketAddr`, `SocketAddrV4`, `SocketAddrV6` - `to_socket_addrs` is
+///    identity function.
 ///
-///  * `(IpAddr, u16)` - `to_socket_addrs` constructs `SocketAddr` trivially.
+///  * `(IpvNAddr, u16)` - `to_socket_addrs` constructs `SocketAddr` trivially.
 ///
 ///  * `(&str, u16)` - the string should be either a string representation of an
-///    IP address expected by `FromStr` implementation for `IpAddr` or a host
+///    IP address expected by `FromStr` implementation for `IpvNAddr` or a host
 ///    name.
 ///
 ///  * `&str` - the string should be either a string representation of a
@@ -207,18 +281,19 @@ impl hash::Hash for Repr {
 /// Some examples:
 ///
 /// ```no_run
-/// use std::net::{IpAddr, SocketAddr, TcpStream, UdpSocket, TcpListener};
+/// # #![feature(net)]
+/// use std::net::{SocketAddrV4, TcpStream, UdpSocket, TcpListener, Ipv4Addr};
 ///
 /// fn main() {
-///     let ip = IpAddr::new_v4(127, 0, 0, 1);
+///     let ip = Ipv4Addr::new(127, 0, 0, 1);
 ///     let port = 12345;
 ///
 ///     // The following lines are equivalent modulo possible "localhost" name
 ///     // resolution differences
-///     let tcp_s = TcpStream::connect(&SocketAddr::new(ip, port));
-///     let tcp_s = TcpStream::connect(&(ip, port));
-///     let tcp_s = TcpStream::connect(&("127.0.0.1", port));
-///     let tcp_s = TcpStream::connect(&("localhost", port));
+///     let tcp_s = TcpStream::connect(SocketAddrV4::new(ip, port));
+///     let tcp_s = TcpStream::connect((ip, port));
+///     let tcp_s = TcpStream::connect(("127.0.0.1", port));
+///     let tcp_s = TcpStream::connect(("localhost", port));
 ///     let tcp_s = TcpStream::connect("127.0.0.1:12345");
 ///     let tcp_s = TcpStream::connect("localhost:12345");
 ///
@@ -226,13 +301,15 @@ impl hash::Hash for Repr {
 ///     // behave similarly
 ///     let tcp_l = TcpListener::bind("localhost:12345");
 ///
-///     let mut udp_s = UdpSocket::bind(&("127.0.0.1", port)).unwrap();
-///     udp_s.send_to(&[7], &(ip, 23451));
+///     let mut udp_s = UdpSocket::bind(("127.0.0.1", port)).unwrap();
+///     udp_s.send_to(&[7], (ip, 23451));
 /// }
 /// ```
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait ToSocketAddrs {
     /// Returned iterator over socket addresses which this type may correspond
     /// to.
+    #[stable(feature = "rust1", since = "1.0.0")]
     type Iter: Iterator<Item=SocketAddr>;
 
     /// Converts this object to an iterator of resolved `SocketAddr`s.
@@ -246,9 +323,11 @@ pub trait ToSocketAddrs {
     /// # Errors
     ///
     /// Any errors encountered during resolution will be returned as an `Err`.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn to_socket_addrs(&self) -> io::Result<Self::Iter>;
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl ToSocketAddrs for SocketAddr {
     type Iter = option::IntoIter<SocketAddr>;
     fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
@@ -256,31 +335,84 @@ impl ToSocketAddrs for SocketAddr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ToSocketAddrs for SocketAddrV4 {
+    type Iter = option::IntoIter<SocketAddr>;
+    fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
+        SocketAddr::V4(*self).to_socket_addrs()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ToSocketAddrs for SocketAddrV6 {
+    type Iter = option::IntoIter<SocketAddr>;
+    fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
+        SocketAddr::V6(*self).to_socket_addrs()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl ToSocketAddrs for (IpAddr, u16) {
     type Iter = option::IntoIter<SocketAddr>;
     fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
         let (ip, port) = *self;
-        Ok(Some(SocketAddr::new(ip, port)).into_iter())
+        match ip {
+            IpAddr::V4(ref a) => (*a, port).to_socket_addrs(),
+            IpAddr::V6(ref a) => (*a, port).to_socket_addrs(),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ToSocketAddrs for (Ipv4Addr, u16) {
+    type Iter = option::IntoIter<SocketAddr>;
+    fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
+        let (ip, port) = *self;
+        SocketAddrV4::new(ip, port).to_socket_addrs()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ToSocketAddrs for (Ipv6Addr, u16) {
+    type Iter = option::IntoIter<SocketAddr>;
+    fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
+        let (ip, port) = *self;
+        SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs()
     }
 }
 
 fn resolve_socket_addr(s: &str, p: u16) -> io::Result<vec::IntoIter<SocketAddr>> {
     let ips = try!(lookup_host(s));
     let v: Vec<_> = try!(ips.map(|a| {
-        a.map(|mut a| { a.set_port(p); a })
+        a.map(|a| {
+            match a {
+                SocketAddr::V4(ref a) => {
+                    SocketAddr::V4(SocketAddrV4::new(*a.ip(), p))
+                }
+                SocketAddr::V6(ref a) => {
+                    SocketAddr::V6(SocketAddrV6::new(*a.ip(), p, a.flowinfo(),
+                                                     a.scope_id()))
+                }
+            }
+        })
     }).collect());
     Ok(v.into_iter())
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> ToSocketAddrs for (&'a str, u16) {
     type Iter = vec::IntoIter<SocketAddr>;
     fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
         let (host, port) = *self;
 
-        // try to parse the host as a regular IpAddr first
-        match host.parse().ok() {
-            Some(addr) => return Ok(vec![SocketAddr::new(addr, port)].into_iter()),
-            None => {}
+        // try to parse the host as a regular IP address first
+        if let Ok(addr) = host.parse::<Ipv4Addr>() {
+            let addr = SocketAddrV4::new(addr, port);
+            return Ok(vec![SocketAddr::V4(addr)].into_iter())
+        }
+        if let Ok(addr) = host.parse::<Ipv6Addr>() {
+            let addr = SocketAddrV6::new(addr, port, 0, 0);
+            return Ok(vec![SocketAddr::V6(addr)].into_iter())
         }
 
         resolve_socket_addr(host, port)
@@ -288,6 +420,7 @@ impl<'a> ToSocketAddrs for (&'a str, u16) {
 }
 
 // accepts strings like 'localhost:12345'
+#[stable(feature = "rust1", since = "1.0.0")]
 impl ToSocketAddrs for str {
     type Iter = vec::IntoIter<SocketAddr>;
     fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
@@ -302,7 +435,7 @@ impl ToSocketAddrs for str {
                 match $e {
                     Some(r) => r,
                     None => return Err(io::Error::new(io::ErrorKind::InvalidInput,
-                                                      $msg, None)),
+                                                      $msg)),
                 }
             )
         }
@@ -337,16 +470,16 @@ mod tests {
         assert_eq!(Ok(Ipv4Addr::new(0, 0, 0, 0)), "0.0.0.0".parse());
 
         // out of range
-        let none: Option<IpAddr> = "256.0.0.1".parse().ok();
+        let none: Option<Ipv4Addr> = "256.0.0.1".parse().ok();
         assert_eq!(None, none);
         // too short
-        let none: Option<IpAddr> = "255.0.0".parse().ok();
+        let none: Option<Ipv4Addr> = "255.0.0".parse().ok();
         assert_eq!(None, none);
         // too long
-        let none: Option<IpAddr> = "255.0.0.1.2".parse().ok();
+        let none: Option<Ipv4Addr> = "255.0.0.1.2".parse().ok();
         assert_eq!(None, none);
         // no number between dots
-        let none: Option<IpAddr> = "255.0..1".parse().ok();
+        let none: Option<Ipv4Addr> = "255.0..1".parse().ok();
         assert_eq!(None, none);
     }
 
@@ -362,19 +495,19 @@ mod tests {
                 "2a02:6b8::11:11".parse());
 
         // too long group
-        let none: Option<IpAddr> = "::00000".parse().ok();
+        let none: Option<Ipv6Addr> = "::00000".parse().ok();
         assert_eq!(None, none);
         // too short
-        let none: Option<IpAddr> = "1:2:3:4:5:6:7".parse().ok();
+        let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7".parse().ok();
         assert_eq!(None, none);
         // too long
-        let none: Option<IpAddr> = "1:2:3:4:5:6:7:8:9".parse().ok();
+        let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7:8:9".parse().ok();
         assert_eq!(None, none);
         // triple colon
-        let none: Option<IpAddr> = "1:2:::6:7:8".parse().ok();
+        let none: Option<Ipv6Addr> = "1:2:::6:7:8".parse().ok();
         assert_eq!(None, none);
         // two double colons
-        let none: Option<IpAddr> = "1:2::6::8".parse().ok();
+        let none: Option<Ipv6Addr> = "1:2::6::8".parse().ok();
         assert_eq!(None, none);
     }
 
@@ -390,24 +523,24 @@ mod tests {
                 "2001:db8:122:c000:2:2100:192.0.2.33".parse());
 
         // colon after v4
-        let none: Option<IpAddr> = "::127.0.0.1:".parse().ok();
+        let none: Option<Ipv4Addr> = "::127.0.0.1:".parse().ok();
         assert_eq!(None, none);
         // not enough groups
-        let none: Option<IpAddr> = "1.2.3.4.5:127.0.0.1".parse().ok();
+        let none: Option<Ipv6Addr> = "1.2.3.4.5:127.0.0.1".parse().ok();
         assert_eq!(None, none);
         // too many groups
-        let none: Option<IpAddr> = "1.2.3.4.5:6:7:127.0.0.1".parse().ok();
+        let none: Option<Ipv6Addr> = "1.2.3.4.5:6:7:127.0.0.1".parse().ok();
         assert_eq!(None, none);
     }
 
     #[test]
     fn test_from_str_socket_addr() {
-        assert_eq!(Ok(SocketAddr::new(IpAddr::new_v4(77, 88, 21, 11), 80)),
-                "77.88.21.11:80".parse());
-        assert_eq!(Ok(SocketAddr::new(IpAddr::new_v6(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53)),
-                "[2a02:6b8:0:1::1]:53".parse());
-        assert_eq!(Ok(SocketAddr::new(IpAddr::new_v6(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22)),
-                "[::127.0.0.1]:22".parse());
+        assert_eq!(Ok(sa4(Ipv4Addr::new(77, 88, 21, 11), 80)),
+                   "77.88.21.11:80".parse());
+        assert_eq!(Ok(sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53)),
+                   "[2a02:6b8:0:1::1]:53".parse());
+        assert_eq!(Ok(sa6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22)),
+                   "[::127.0.0.1]:22".parse());
 
         // without port
         let none: Option<SocketAddr> = "127.0.0.1".parse().ok();
@@ -515,7 +648,7 @@ mod tests {
                  unique_local: bool, global: bool,
                  u_link_local: bool, u_site_local: bool, u_global: bool,
                  m_scope: Option<Ipv6MulticastScope>) {
-            let ip: Ipv6Addr = str_addr.parse().ok().unwrap();
+            let ip: Ipv6Addr = str_addr.parse().unwrap();
             assert_eq!(str_addr, ip.to_string());
 
             assert_eq!(ip.is_unspecified(), unspec);
@@ -564,45 +697,62 @@ mod tests {
               false, false, false, true,  false, false, false, Some(Global));
     }
 
-    fn tsa<A: ToSocketAddrs>(a: A) -> io::Result<Vec<SocketAddr>> {
-        Ok(try!(a.to_socket_addrs()).collect())
+    fn tsa<A: ToSocketAddrs>(a: A) -> Result<Vec<SocketAddr>, String> {
+        match a.to_socket_addrs() {
+            Ok(a) => Ok(a.collect()),
+            Err(e) => Err(e.to_string()),
+        }
     }
 
     #[test]
     fn to_socket_addr_socketaddr() {
-        let a = SocketAddr::new(IpAddr::new_v4(77, 88, 21, 11), 12345);
+        let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 12345);
         assert_eq!(Ok(vec![a]), tsa(a));
     }
 
+    fn sa4(a: Ipv4Addr, p: u16) -> SocketAddr {
+        SocketAddr::V4(SocketAddrV4::new(a, p))
+    }
+
+    fn sa6(a: Ipv6Addr, p: u16) -> SocketAddr {
+        SocketAddr::V6(SocketAddrV6::new(a, p, 0, 0))
+    }
+
     #[test]
     fn to_socket_addr_ipaddr_u16() {
-        let a = IpAddr::new_v4(77, 88, 21, 11);
-        let p = 12345u16;
-        let e = SocketAddr::new(a, p);
+        let a = Ipv4Addr::new(77, 88, 21, 11);
+        let p = 12345;
+        let e = SocketAddr::V4(SocketAddrV4::new(a, p));
         assert_eq!(Ok(vec![e]), tsa((a, p)));
     }
 
     #[test]
     fn to_socket_addr_str_u16() {
-        let a = SocketAddr::new(IpAddr::new_v4(77, 88, 21, 11), 24352);
-        assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352u16)));
+        let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
+        assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352)));
 
-        let a = SocketAddr::new(IpAddr::new_v6(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
+        let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
         assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53)));
 
-        let a = SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1), 23924);
-        assert!(tsa(("localhost", 23924u16)).unwrap().contains(&a));
+        let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
+        assert!(tsa(("localhost", 23924)).unwrap().contains(&a));
     }
 
     #[test]
     fn to_socket_addr_str() {
-        let a = SocketAddr::new(IpAddr::new_v4(77, 88, 21, 11), 24352);
+        let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
         assert_eq!(Ok(vec![a]), tsa("77.88.21.11:24352"));
 
-        let a = SocketAddr::new(IpAddr::new_v6(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
+        let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
         assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53"));
 
-        let a = SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1), 23924);
+        let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
         assert!(tsa("localhost:23924").unwrap().contains(&a));
     }
+
+    #[test]
+    #[cfg(not(windows))]
+    fn to_socket_addr_str_bad() {
+        assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err());
+    }
 }
index 571a1b03ef07fbd879a1e98c7caafe1838506d87..c8b1928747705765c1cc1923b8a2ea6a60b0d6d1 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![unstable(feature = "ip", reason = "extra functionality has not been \
+                                      scrutinized to the level that it should \
+                                      be stable")]
+
 use prelude::v1::*;
 
 use cmp::Ordering;
@@ -17,14 +21,26 @@ use libc;
 use sys_common::{AsInner, FromInner};
 use net::{hton, ntoh};
 
+/// An IP address, either a IPv4 or IPv6 address.
+#[unstable(feature = "ip_addr", reason = "recent addition")]
+#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
+pub enum IpAddr {
+    /// Representation of an IPv4 address.
+    V4(Ipv4Addr),
+    /// Representation of an IPv6 address.
+    V6(Ipv6Addr),
+}
+
 /// Representation of an IPv4 address.
 #[derive(Copy)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Ipv4Addr {
     inner: libc::in_addr,
 }
 
 /// Representation of an IPv6 address.
 #[derive(Copy)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Ipv6Addr {
     inner: libc::in6_addr,
 }
@@ -41,46 +57,11 @@ pub enum Ipv6MulticastScope {
     Global
 }
 
-/// Enumeration of possible IP addresses
-#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug)]
-pub enum IpAddr {
-    /// An IPv4 address.
-    V4(Ipv4Addr),
-    /// An IPv6 address.
-    V6(Ipv6Addr)
-}
-
-impl IpAddr {
-    /// Create a new IpAddr that contains an IPv4 address.
-    ///
-    /// The result will represent the IP address a.b.c.d
-    pub fn new_v4(a: u8, b: u8, c: u8, d: u8) -> IpAddr {
-        IpAddr::V4(Ipv4Addr::new(a, b, c, d))
-    }
-
-    /// Create a new IpAddr that contains an IPv6 address.
-    ///
-    /// The result will represent the IP address a:b:c:d:e:f
-    pub fn new_v6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16,
-                  h: u16) -> IpAddr {
-        IpAddr::V6(Ipv6Addr::new(a, b, c, d, e, f, g, h))
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for IpAddr {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            IpAddr::V4(v4) => v4.fmt(f),
-            IpAddr::V6(v6) => v6.fmt(f)
-        }
-    }
-}
-
 impl Ipv4Addr {
     /// Create a new IPv4 address from four eight-bit octets.
     ///
     /// The result will represent the IP address a.b.c.d
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
         Ipv4Addr {
             inner: libc::in_addr {
@@ -93,6 +74,7 @@ impl Ipv4Addr {
     }
 
     /// Returns the four eight-bit integers that make up this address
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn octets(&self) -> [u8; 4] {
         let bits = ntoh(self.inner.s_addr);
         [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
@@ -148,6 +130,7 @@ impl Ipv4Addr {
     /// Convert this address to an IPv4-compatible IPv6 address
     ///
     /// a.b.c.d becomes ::a.b.c.d
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_ipv6_compatible(&self) -> Ipv6Addr {
         Ipv6Addr::new(0, 0, 0, 0, 0, 0,
                       ((self.octets()[0] as u16) << 8) | self.octets()[1] as u16,
@@ -157,6 +140,7 @@ impl Ipv4Addr {
     /// Convert this address to an IPv4-mapped IPv6 address
     ///
     /// a.b.c.d becomes ::ffff:a.b.c.d
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_ipv6_mapped(&self) -> Ipv6Addr {
         Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff,
                       ((self.octets()[0] as u16) << 8) | self.octets()[1] as u16,
@@ -165,6 +149,17 @@ impl Ipv4Addr {
 
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for IpAddr {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            IpAddr::V4(ref a) => a.fmt(fmt),
+            IpAddr::V6(ref a) => a.fmt(fmt),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for Ipv4Addr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let octets = self.octets();
@@ -172,30 +167,28 @@ impl fmt::Display for Ipv4Addr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Debug for Ipv4Addr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(self, fmt)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Clone for Ipv4Addr {
     fn clone(&self) -> Ipv4Addr { *self }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq for Ipv4Addr {
     fn eq(&self, other: &Ipv4Addr) -> bool {
         self.inner.s_addr == other.inner.s_addr
     }
 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Eq for Ipv4Addr {}
 
-#[cfg(stage0)]
-impl<S: hash::Hasher + hash::Writer> hash::Hash<S> for Ipv4Addr {
-    fn hash(&self, s: &mut S) {
-        self.inner.s_addr.hash(s)
-    }
-}
-#[cfg(not(stage0))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl hash::Hash for Ipv4Addr {
     fn hash<H: hash::Hasher>(&self, s: &mut H) {
@@ -203,12 +196,14 @@ impl hash::Hash for Ipv4Addr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialOrd for Ipv4Addr {
     fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
         Some(self.cmp(other))
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Ord for Ipv4Addr {
     fn cmp(&self, other: &Ipv4Addr) -> Ordering {
         self.inner.s_addr.cmp(&other.inner.s_addr)
@@ -227,7 +222,8 @@ impl FromInner<libc::in_addr> for Ipv4Addr {
 impl Ipv6Addr {
     /// Create a new IPv6 address from eight 16-bit segments.
     ///
-    /// The result will represent the IP address a:b:c:d:e:f
+    /// The result will represent the IP address a:b:c:d:e:f:g:h
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16,
                h: u16) -> Ipv6Addr {
         Ipv6Addr {
@@ -239,6 +235,7 @@ impl Ipv6Addr {
     }
 
     /// Return the eight 16-bit segments that make up this address
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn segments(&self) -> [u16; 8] {
         [ntoh(self.inner.s6_addr[0]),
          ntoh(self.inner.s6_addr[1]),
@@ -331,6 +328,7 @@ impl Ipv6Addr {
     /// neither IPv4-compatible or IPv4-mapped.
     ///
     /// ::a.b.c.d and ::ffff:a.b.c.d become a.b.c.d
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_ipv4(&self) -> Option<Ipv4Addr> {
         match self.segments() {
             [0, 0, 0, 0, 0, f, g, h] if f == 0 || f == 0xffff => {
@@ -342,6 +340,7 @@ impl Ipv6Addr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for Ipv6Addr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         match self.segments() {
@@ -366,7 +365,7 @@ impl fmt::Display for Ipv6Addr {
                     let mut cur_span_len = 0;
                     let mut cur_span_at = 0;
 
-                    for i in range(0, 8) {
+                    for i in 0..8 {
                         if segments[i] == 0 {
                             if cur_span_len == 0 {
                                 cur_span_at = i;
@@ -395,7 +394,6 @@ impl fmt::Display for Ipv6Addr {
                             .iter()
                             .map(|&seg| format!("{:x}", seg))
                             .collect::<Vec<String>>()
-                            .as_slice()
                             .connect(":")
                     }
 
@@ -412,30 +410,28 @@ impl fmt::Display for Ipv6Addr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Debug for Ipv6Addr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(self, fmt)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Clone for Ipv6Addr {
     fn clone(&self) -> Ipv6Addr { *self }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq for Ipv6Addr {
     fn eq(&self, other: &Ipv6Addr) -> bool {
         self.inner.s6_addr == other.inner.s6_addr
     }
 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Eq for Ipv6Addr {}
 
-#[cfg(stage0)]
-impl<S: hash::Hasher + hash::Writer> hash::Hash<S> for Ipv6Addr {
-    fn hash(&self, s: &mut S) {
-        self.inner.s6_addr.hash(s)
-    }
-}
-#[cfg(not(stage0))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl hash::Hash for Ipv6Addr {
     fn hash<H: hash::Hasher>(&self, s: &mut H) {
@@ -443,12 +439,14 @@ impl hash::Hash for Ipv6Addr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialOrd for Ipv6Addr {
     fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
         Some(self.cmp(other))
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Ord for Ipv6Addr {
     fn cmp(&self, other: &Ipv6Addr) -> Ordering {
         self.inner.s6_addr.cmp(&other.inner.s6_addr)
index d73c06a2549e10970294d356aa07754ac8f73658..a152b98822a0bead2e9c337d927ca36d21a8fb02 100644 (file)
 //! Networking primitives for TCP/UDP communication
 //!
 //! > **NOTE**: This module is very much a work in progress and is under active
-//! > development. At this time it is still recommended to use the `old_io`
-//! > module while the details of this module shake out.
+//! > development.
 
-#![unstable(feature = "net")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
 use prelude::v1::*;
 
 use io::{self, Error, ErrorKind};
+#[allow(deprecated)] // Int
 use num::Int;
 use sys_common::net2 as net_imp;
 
 pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
-pub use self::addr::{SocketAddr, ToSocketAddrs};
+pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
 pub use self::tcp::{TcpStream, TcpListener};
 pub use self::udp::UdpSocket;
+pub use self::parser::AddrParseError;
 
 mod ip;
 mod addr;
@@ -37,23 +38,29 @@ mod parser;
 /// Possible values which can be passed to the `shutdown` method of `TcpStream`
 /// and `UdpSocket`.
 #[derive(Copy, Clone, PartialEq)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub enum Shutdown {
     /// Indicates that the reading portion of this stream/socket should be shut
     /// down. All currently blocked and future reads will return `Ok(0)`.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Read,
     /// Indicates that the writing portion of this stream/socket should be shut
     /// down. All currently blocked and future writes will return an error.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Write,
     /// Shut down both the reading and writing portions of this stream.
     ///
     /// See `Shutdown::Read` and `Shutdown::Write` for more information.
-    Both
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Both,
 }
 
+#[allow(deprecated)] // Int
 fn hton<I: Int>(i: I) -> I { i.to_be() }
+#[allow(deprecated)] // Int
 fn ntoh<I: Int>(i: I) -> I { Int::from_be(i) }
 
-fn each_addr<A: ToSocketAddrs + ?Sized, F, T>(addr: &A, mut f: F) -> io::Result<T>
+fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
     where F: FnMut(&SocketAddr) -> io::Result<T>
 {
     let mut last_err = None;
@@ -65,13 +72,19 @@ fn each_addr<A: ToSocketAddrs + ?Sized, F, T>(addr: &A, mut f: F) -> io::Result<
     }
     Err(last_err.unwrap_or_else(|| {
         Error::new(ErrorKind::InvalidInput,
-                   "could not resolve to any addresses", None)
+                   "could not resolve to any addresses")
     }))
 }
 
 /// An iterator over `SocketAddr` values returned from a host lookup operation.
+#[unstable(feature = "lookup_host", reason = "unsure about the returned \
+                                              iterator and returning socket \
+                                              addresses")]
 pub struct LookupHost(net_imp::LookupHost);
 
+#[unstable(feature = "lookup_host", reason = "unsure about the returned \
+                                              iterator and returning socket \
+                                              addresses")]
 impl Iterator for LookupHost {
     type Item = io::Result<SocketAddr>;
     fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next() }
@@ -82,9 +95,10 @@ impl Iterator for LookupHost {
 /// This method may perform a DNS query to resolve `host` and may also inspect
 /// system configuration to resolve the specified hostname.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```no_run
+/// # #![feature(lookup_host)]
 /// use std::net;
 ///
 /// # fn foo() -> std::io::Result<()> {
@@ -94,6 +108,19 @@ impl Iterator for LookupHost {
 /// # Ok(())
 /// # }
 /// ```
+#[unstable(feature = "lookup_host", reason = "unsure about the returned \
+                                              iterator and returning socket \
+                                              addresses")]
 pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
     net_imp::lookup_host(host).map(LookupHost)
 }
+
+/// Resolve the given address to a hostname.
+///
+/// This function may perform a DNS query to resolve `addr` and may also inspect
+/// system configuration to resolve the specified address. If the address
+/// cannot be resolved, it is returned in string format.
+#[unstable(feature = "lookup_addr", reason = "recent addition")]
+pub fn lookup_addr(addr: &IpAddr) -> io::Result<String> {
+    net_imp::lookup_addr(addr)
+}
index e82dc88cddd7b7036989232092f2e781f43a4617..7c1667a603f65f7e8bcaf2cf3891f79320a32b0c 100644 (file)
@@ -16,7 +16,7 @@
 use prelude::v1::*;
 
 use str::FromStr;
-use net::{Ipv4Addr, Ipv6Addr, IpAddr, SocketAddr};
+use net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
 
 struct Parser<'a> {
     // parsing as ASCII, so can use byte array
@@ -136,7 +136,7 @@ impl<'a> Parser<'a> {
     }
 
     fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
-        let mut r = 0u32;
+        let mut r = 0;
         let mut digit_count = 0;
         loop {
             match self.read_digit(radix) {
@@ -164,7 +164,7 @@ impl<'a> Parser<'a> {
     }
 
     fn read_ipv4_addr_impl(&mut self) -> Option<Ipv4Addr> {
-        let mut bs = [0u8; 4];
+        let mut bs = [0; 4];
         let mut i = 0;
         while i < 4 {
             if i != 0 && self.read_given_char('.').is_none() {
@@ -189,7 +189,7 @@ impl<'a> Parser<'a> {
     fn read_ipv6_addr_impl(&mut self) -> Option<Ipv6Addr> {
         fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> Ipv6Addr {
             assert!(head.len() + tail.len() <= 8);
-            let mut gs = [0u16; 8];
+            let mut gs = [0; 8];
             gs.clone_from_slice(head);
             gs[(8 - tail.len()) .. 8].clone_from_slice(tail);
             Ipv6Addr::new(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7])
@@ -231,7 +231,7 @@ impl<'a> Parser<'a> {
             (i, false)
         }
 
-        let mut head = [0u16; 8];
+        let mut head = [0; 8];
         let (head_size, head_ipv4) = read_groups(self, &mut head, 8);
 
         if head_size == 8 {
@@ -250,7 +250,7 @@ impl<'a> Parser<'a> {
             return None;
         }
 
-        let mut tail = [0u16; 8];
+        let mut tail = [0; 8];
         let (tail_size, _) = read_groups(self, &mut tail, 8 - head_size);
         Some(ipv6_addr_from_head_tail(&head[..head_size], &tail[..tail_size]))
     }
@@ -281,50 +281,61 @@ impl<'a> Parser<'a> {
         let port  = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
 
         // host, colon, port
-        self.read_seq_3::<IpAddr, char, u16, _, _, _>(ip_addr, colon, port)
-                .map(|t| match t { (ip, _, port) => SocketAddr::new(ip, port) })
+        self.read_seq_3(ip_addr, colon, port).map(|t| {
+            let (ip, _, port): (IpAddr, char, u16) = t;
+            match ip {
+                IpAddr::V4(ip) => SocketAddr::V4(SocketAddrV4::new(ip, port)),
+                IpAddr::V6(ip) => SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0)),
+            }
+        })
     }
 }
 
+#[unstable(feature = "ip_addr", reason = "recent addition")]
 impl FromStr for IpAddr {
-    type Err = ParseError;
-    fn from_str(s: &str) -> Result<IpAddr, ParseError> {
+    type Err = AddrParseError;
+    fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
         match Parser::new(s).read_till_eof(|p| p.read_ip_addr()) {
             Some(s) => Ok(s),
-            None => Err(ParseError),
+            None => Err(AddrParseError(()))
         }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl FromStr for Ipv4Addr {
-    type Err = ParseError;
-    fn from_str(s: &str) -> Result<Ipv4Addr, ParseError> {
+    type Err = AddrParseError;
+    fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
         match Parser::new(s).read_till_eof(|p| p.read_ipv4_addr()) {
             Some(s) => Ok(s),
-            None => Err(ParseError)
+            None => Err(AddrParseError(()))
         }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl FromStr for Ipv6Addr {
-    type Err = ParseError;
-    fn from_str(s: &str) -> Result<Ipv6Addr, ParseError> {
+    type Err = AddrParseError;
+    fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> {
         match Parser::new(s).read_till_eof(|p| p.read_ipv6_addr()) {
             Some(s) => Ok(s),
-            None => Err(ParseError)
+            None => Err(AddrParseError(()))
         }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl FromStr for SocketAddr {
-    type Err = ParseError;
-    fn from_str(s: &str) -> Result<SocketAddr, ParseError> {
+    type Err = AddrParseError;
+    fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
         match Parser::new(s).read_till_eof(|p| p.read_socket_addr()) {
             Some(s) => Ok(s),
-            None => Err(ParseError),
+            None => Err(AddrParseError(())),
         }
     }
 }
 
-#[derive(Debug, Clone, PartialEq, Copy)]
-pub struct ParseError;
+/// An error returned when parsing an IP address or a socket address.
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Debug, Clone, PartialEq)]
+pub struct AddrParseError(());
index b861b74947eeb20961995bc8a48450ccc3efe25c..04d1013af1faec67fd37be4cd91415bad249241f 100644 (file)
@@ -8,22 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![unstable(feature = "tcp", reason = "remaining functions have not been \
+                                       scrutinized enough to be stabilized")]
+
 use prelude::v1::*;
 use io::prelude::*;
 
 use io;
 use net::{ToSocketAddrs, SocketAddr, Shutdown};
 use sys_common::net2 as net_imp;
-use sys_common::AsInner;
+use sys_common::{AsInner, FromInner};
 
 /// A structure which represents a TCP stream between a local socket and a
 /// remote socket.
 ///
 /// The socket will be closed when the value is dropped.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```no_run
+/// # #![feature(net)]
 /// use std::io::prelude::*;
 /// use std::net::TcpStream;
 ///
@@ -35,6 +39,7 @@ use sys_common::AsInner;
 ///     let _ = stream.read(&mut [0; 128]); // ignore here too
 /// } // the stream is closed here
 /// ```
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct TcpStream(net_imp::TcpStream);
 
 /// A structure representing a socket server.
@@ -42,6 +47,7 @@ pub struct TcpStream(net_imp::TcpStream);
 /// # Examples
 ///
 /// ```no_run
+/// # #![feature(net)]
 /// use std::net::{TcpListener, TcpStream};
 /// use std::thread;
 ///
@@ -67,12 +73,14 @@ pub struct TcpStream(net_imp::TcpStream);
 /// // close the socket server
 /// drop(listener);
 /// ```
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct TcpListener(net_imp::TcpListener);
 
 /// An infinite iterator over the connections from a `TcpListener`.
 ///
 /// This iterator will infinitely yield `Some` of the accepted connections. It
 /// is equivalent to calling `accept` in a loop.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Incoming<'a> { listener: &'a TcpListener }
 
 impl TcpStream {
@@ -81,17 +89,20 @@ impl TcpStream {
     /// `addr` is an address of the remote host. Anything which implements
     /// `ToSocketAddrs` trait can be supplied for the address; see this trait
     /// documentation for concrete examples.
-    pub fn connect<A: ToSocketAddrs + ?Sized>(addr: &A) -> io::Result<TcpStream> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
         super::each_addr(addr, net_imp::TcpStream::connect).map(TcpStream)
     }
 
     /// Returns the socket address of the remote peer of this TCP connection.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         self.0.peer_addr()
     }
 
     /// Returns the socket address of the local half of this TCP connection.
-    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
         self.0.socket_addr()
     }
 
@@ -100,6 +111,7 @@ impl TcpStream {
     /// This function will cause all pending and future I/O on the specified
     /// portions to return immediately with an appropriate value (see the
     /// documentation of `Shutdown`).
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
         self.0.shutdown(how)
     }
@@ -110,6 +122,7 @@ impl TcpStream {
     /// object references. Both handles will read and write the same stream of
     /// data, and options set on one stream will be propagated to the other
     /// stream.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_clone(&self) -> io::Result<TcpStream> {
         self.0.duplicate().map(TcpStream)
     }
@@ -129,16 +142,20 @@ impl TcpStream {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Read for TcpStream {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Write for TcpStream {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Read for &'a TcpStream {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for &'a TcpStream {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
@@ -148,6 +165,10 @@ impl AsInner<net_imp::TcpStream> for TcpStream {
     fn as_inner(&self) -> &net_imp::TcpStream { &self.0 }
 }
 
+impl FromInner<net_imp::TcpStream> for TcpStream {
+    fn from_inner(inner: net_imp::TcpStream) -> TcpStream { TcpStream(inner) }
+}
+
 impl TcpListener {
     /// Creates a new `TcpListener` which will be bound to the specified
     /// address.
@@ -160,12 +181,14 @@ impl TcpListener {
     ///
     /// The address type can be any implementer of `ToSocketAddrs` trait. See
     /// its documentation for concrete examples.
-    pub fn bind<A: ToSocketAddrs + ?Sized>(addr: &A) -> io::Result<TcpListener> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
         super::each_addr(addr, net_imp::TcpListener::bind).map(TcpListener)
     }
 
     /// Returns the local socket address of this listener.
-    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
         self.0.socket_addr()
     }
 
@@ -174,6 +197,7 @@ impl TcpListener {
     /// The returned `TcpListener` is a reference to the same socket that this
     /// object references. Both handles can be used to accept incoming
     /// connections and options set on one listener will affect the other.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_clone(&self) -> io::Result<TcpListener> {
         self.0.duplicate().map(TcpListener)
     }
@@ -183,6 +207,7 @@ impl TcpListener {
     /// This function will block the calling thread until a new TCP connection
     /// is established. When established, the corresponding `TcpStream` and the
     /// remote peer's address will be returned.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
         self.0.accept().map(|(a, b)| (TcpStream(a), b))
     }
@@ -192,11 +217,13 @@ impl TcpListener {
     ///
     /// The returned iterator will never returned `None` and will also not yield
     /// the peer's `SocketAddr` structure.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn incoming(&self) -> Incoming {
         Incoming { listener: self }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Iterator for Incoming<'a> {
     type Item = io::Result<TcpStream>;
     fn next(&mut self) -> Option<io::Result<TcpStream>> {
@@ -208,6 +235,12 @@ impl AsInner<net_imp::TcpListener> for TcpListener {
     fn as_inner(&self) -> &net_imp::TcpListener { &self.0 }
 }
 
+impl FromInner<net_imp::TcpListener> for TcpListener {
+    fn from_inner(inner: net_imp::TcpListener) -> TcpListener {
+        TcpListener(inner)
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
@@ -233,13 +266,12 @@ mod tests {
         }
     }
 
-    // FIXME #11530 this fails on android because tests are run as root
-    #[cfg_attr(any(windows, target_os = "android"), ignore)]
     #[test]
     fn bind_error() {
-        match TcpListener::bind("0.0.0.0:1") {
+        match TcpListener::bind("1.1.1.1:9999") {
             Ok(..) => panic!(),
-            Err(e) => assert_eq!(e.kind(), ErrorKind::PermissionDenied),
+            Err(e) =>
+                assert_eq!(e.kind(), ErrorKind::AddrNotAvailable),
         }
     }
 
@@ -247,8 +279,11 @@ mod tests {
     fn connect_error() {
         match TcpStream::connect("0.0.0.0:1") {
             Ok(..) => panic!(),
-            Err(e) => assert!((e.kind() == ErrorKind::ConnectionRefused)
-                              || (e.kind() == ErrorKind::InvalidInput)),
+            Err(e) => assert!(e.kind() == ErrorKind::ConnectionRefused ||
+                              e.kind() == ErrorKind::InvalidInput ||
+                              e.kind() == ErrorKind::AddrInUse ||
+                              e.kind() == ErrorKind::AddrNotAvailable,
+                              "bad error: {} {:?}", e, e.kind()),
         }
     }
 
@@ -310,7 +345,7 @@ mod tests {
             let _t = thread::spawn(move|| {
                 let mut stream = t!(TcpStream::connect(&addr));
                 t!(stream.write(&[99]));
-                tx.send(t!(stream.socket_addr())).unwrap();
+                tx.send(t!(stream.local_addr())).unwrap();
             });
 
             let (mut stream, addr) = t!(acceptor.accept());
@@ -425,7 +460,7 @@ mod tests {
 
     #[test]
     fn multiple_connect_interleaved_lazy_schedule_ip4() {
-        static MAX: usize = 10;
+        const MAX: usize = 10;
         each_ip(&mut |addr| {
             let acceptor = t!(TcpListener::bind(&addr));
 
@@ -456,17 +491,11 @@ mod tests {
         }
     }
 
-    pub fn socket_name(addr: SocketAddr) {
-    }
-
-    pub fn peer_name(addr: SocketAddr) {
-    }
-
     #[test]
     fn socket_and_peer_name_ip4() {
         each_ip(&mut |addr| {
             let listener = t!(TcpListener::bind(&addr));
-            let so_name = t!(listener.socket_addr());
+            let so_name = t!(listener.local_addr());
             assert_eq!(addr, so_name);
             let _t = thread::spawn(move|| {
                 t!(listener.accept());
@@ -492,7 +521,7 @@ mod tests {
 
             let mut c = t!(TcpStream::connect(&addr));
             let mut b = [0; 10];
-            assert_eq!(c.read(&mut b), Ok(1));
+            assert_eq!(c.read(&mut b).unwrap(), 1);
             t!(c.write(&[1]));
             rx.recv().unwrap();
         })
@@ -506,7 +535,8 @@ mod tests {
                 Ok(..) => panic!(),
                 Err(e) => {
                     assert!(e.kind() == ErrorKind::ConnectionRefused ||
-                            e.kind() == ErrorKind::Other,
+                            e.kind() == ErrorKind::Other ||
+                            e.kind() == ErrorKind::AddrInUse,
                             "unknown error: {} {:?}", e, e.kind());
                 }
             }
@@ -536,7 +566,7 @@ mod tests {
             let _t = thread::spawn(move|| {
                 let mut s = t!(TcpStream::connect(&addr));
                 let mut buf = [0, 0];
-                assert_eq!(s.read(&mut buf), Ok(1));
+                assert_eq!(s.read(&mut buf).unwrap(), 1);
                 assert_eq!(buf[0], 1);
                 t!(s.write(&[2]));
             });
@@ -554,7 +584,7 @@ mod tests {
             });
             tx1.send(()).unwrap();
             let mut buf = [0, 0];
-            assert_eq!(s1.read(&mut buf), Ok(1));
+            assert_eq!(s1.read(&mut buf).unwrap(), 1);
             rx2.recv().unwrap();
         })
     }
@@ -627,7 +657,7 @@ mod tests {
             let _t = thread::spawn(move|| {
                 let mut c = t!(a.accept()).0;
                 let mut b = [0];
-                assert_eq!(c.read(&mut b), Ok(0));
+                assert_eq!(c.read(&mut b).unwrap(), 0);
                 t!(c.write(&[1]));
             });
 
@@ -658,16 +688,16 @@ mod tests {
             t!(s.shutdown(Shutdown::Write));
             assert!(s.write(&[0]).is_err());
             t!(s.shutdown(Shutdown::Read));
-            assert_eq!(s.read(&mut b), Ok(0));
+            assert_eq!(s.read(&mut b).unwrap(), 0);
 
             // closing should affect previous handles
             assert!(s2.write(&[0]).is_err());
-            assert_eq!(s2.read(&mut b), Ok(0));
+            assert_eq!(s2.read(&mut b).unwrap(), 0);
 
             // closing should affect new handles
             let mut s3 = t!(s.try_clone());
             assert!(s3.write(&[0]).is_err());
-            assert_eq!(s3.read(&mut b), Ok(0));
+            assert_eq!(s3.read(&mut b).unwrap(), 0);
 
             // make sure these don't die
             let _ = s2.shutdown(Shutdown::Read);
index 971fb4b69c8ef5ee6df1cd5ef3700d2c248f2ebf..3d42472f0fc424caa1e93d4a2b2c5a7b73de9790 100644 (file)
 use prelude::v1::*;
 
 use env;
-use net::{SocketAddr, IpAddr};
+use net::{SocketAddr, SocketAddrV4, SocketAddrV6, Ipv4Addr, Ipv6Addr};
 use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 
+static PORT: AtomicUsize = ATOMIC_USIZE_INIT;
+
 pub fn next_test_ip4() -> SocketAddr {
-    static PORT: AtomicUsize = ATOMIC_USIZE_INIT;
-    SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1),
-                    PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port())
+    let port = PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port();
+    SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), port))
 }
 
 pub fn next_test_ip6() -> SocketAddr {
-    static PORT: AtomicUsize = ATOMIC_USIZE_INIT;
-    SocketAddr::new(IpAddr::new_v6(0, 0, 0, 0, 0, 0, 0, 1),
-                    PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port())
+    let port = PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port();
+    SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
+                                     port, 0, 0))
 }
 
 // The bots run multiple builds at the same time, and these builds
@@ -33,7 +34,7 @@ fn base_port() -> u16 {
     let cwd = env::current_dir().unwrap();
     let dirs = ["32-opt", "32-nopt", "64-opt", "64-nopt", "64-opt-vg",
                 "all-opt", "snap3", "dist"];
-    dirs.iter().enumerate().find(|&(i, dir)| {
-        cwd.as_str().unwrap().contains(dir)
+    dirs.iter().enumerate().find(|&(_, dir)| {
+        cwd.to_str().unwrap().contains(dir)
     }).map(|p| p.0).unwrap_or(0) as u16 * 1000 + 19600
 }
index 92f00599826dd14d1e603cae5a68988a6ee55d9d..7b14e4dbea6788420954a43731d8853ddb154a66 100644 (file)
@@ -8,12 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![unstable(feature = "udp", reason = "remaining functions have not been \
+                                       scrutinized enough to be stabilized")]
+
 use prelude::v1::*;
 
 use io::{self, Error, ErrorKind};
 use net::{ToSocketAddrs, SocketAddr, IpAddr};
 use sys_common::net2 as net_imp;
-use sys_common::AsInner;
+use sys_common::{AsInner, FromInner};
 
 /// A User Datagram Protocol socket.
 ///
@@ -21,9 +24,10 @@ use sys_common::AsInner;
 /// IPv6 addresses, and there is no corresponding notion of a server because UDP
 /// is a datagram protocol.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```no_run
+/// # #![feature(net)]
 /// use std::net::UdpSocket;
 ///
 /// # fn foo() -> std::io::Result<()> {
@@ -41,6 +45,7 @@ use sys_common::AsInner;
 /// # Ok(())
 /// # }
 /// ```
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct UdpSocket(net_imp::UdpSocket);
 
 impl UdpSocket {
@@ -48,12 +53,14 @@ impl UdpSocket {
     ///
     /// Address type can be any implementor of `ToSocketAddr` trait. See its
     /// documentation for concrete examples.
-    pub fn bind<A: ToSocketAddrs + ?Sized>(addr: &A) -> io::Result<UdpSocket> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
         super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket)
     }
 
     /// Receives data from the socket. On success, returns the number of bytes
     /// read and the address from whence the data came.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
         self.0.recv_from(buf)
     }
@@ -63,17 +70,19 @@ impl UdpSocket {
     ///
     /// Address type can be any implementor of `ToSocketAddrs` trait. See its
     /// documentation for concrete examples.
-    pub fn send_to<A: ToSocketAddrs + ?Sized>(&self, buf: &[u8], addr: &A)
-                                              -> io::Result<usize> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A)
+                                     -> io::Result<usize> {
         match try!(addr.to_socket_addrs()).next() {
             Some(addr) => self.0.send_to(buf, &addr),
             None => Err(Error::new(ErrorKind::InvalidInput,
-                                   "no addresses to send data to", None)),
+                                   "no addresses to send data to")),
         }
     }
 
     /// Returns the socket address that this socket was created from.
-    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
         self.0.socket_addr()
     }
 
@@ -82,6 +91,7 @@ impl UdpSocket {
     /// The returned `UdpSocket` is a reference to the same socket that this
     /// object references. Both handles will read and write the same port, and
     /// options set on one socket will be propagated to the other.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_clone(&self) -> io::Result<UdpSocket> {
         self.0.duplicate().map(UdpSocket)
     }
@@ -123,6 +133,10 @@ impl AsInner<net_imp::UdpSocket> for UdpSocket {
     fn as_inner(&self) -> &net_imp::UdpSocket { &self.0 }
 }
 
+impl FromInner<net_imp::UdpSocket> for UdpSocket {
+    fn from_inner(inner: net_imp::UdpSocket) -> UdpSocket { UdpSocket(inner) }
+}
+
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
@@ -151,7 +165,7 @@ mod tests {
     #[cfg_attr(any(windows, target_os = "android"), ignore)]
     #[test]
     fn bind_error() {
-        let addr = SocketAddr::new(IpAddr::new_v4(0, 0, 0, 0), 1);
+        let addr = SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 1);
         match UdpSocket::bind(&addr) {
             Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind(), ErrorKind::PermissionDenied),
@@ -186,7 +200,7 @@ mod tests {
     fn socket_name_ip4() {
         each_ip(&mut |addr, _| {
             let server = t!(UdpSocket::bind(&addr));
-            assert_eq!(addr, t!(server.socket_addr()));
+            assert_eq!(addr, t!(server.local_addr()));
         })
     }
 
@@ -198,7 +212,7 @@ mod tests {
 
             let _t = thread::spawn(move|| {
                 let mut buf = [0, 0];
-                assert_eq!(sock2.recv_from(&mut buf), Ok((1, addr1)));
+                assert_eq!(sock2.recv_from(&mut buf).unwrap(), (1, addr1));
                 assert_eq!(buf[0], 1);
                 t!(sock2.send_to(&[2], &addr1));
             });
@@ -214,7 +228,7 @@ mod tests {
             });
             tx1.send(()).unwrap();
             let mut buf = [0, 0];
-            assert_eq!(sock1.recv_from(&mut buf), Ok((1, addr2)));
+            assert_eq!(sock1.recv_from(&mut buf).unwrap(), (1, addr2));
             rx2.recv().unwrap();
         })
     }
index 7d15a16309e5b3f481a52440fa1df25b44d614da..0ae4d3c5bd66b13f269729986f6d510911187bed 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -75,6 +75,7 @@ mod cmath {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
 impl Float for f32 {
     #[inline]
     fn nan() -> f32 { num::Float::nan() }
@@ -91,27 +92,27 @@ impl Float for f32 {
 
     #[allow(deprecated)]
     #[inline]
-    fn mantissa_digits(unused_self: Option<f32>) -> uint {
+    fn mantissa_digits(unused_self: Option<f32>) -> usize {
         num::Float::mantissa_digits(unused_self)
     }
     #[allow(deprecated)]
     #[inline]
-    fn digits(unused_self: Option<f32>) -> uint { num::Float::digits(unused_self) }
+    fn digits(unused_self: Option<f32>) -> usize { num::Float::digits(unused_self) }
     #[allow(deprecated)]
     #[inline]
     fn epsilon() -> f32 { num::Float::epsilon() }
     #[allow(deprecated)]
     #[inline]
-    fn min_exp(unused_self: Option<f32>) -> int { num::Float::min_exp(unused_self) }
+    fn min_exp(unused_self: Option<f32>) -> isize { num::Float::min_exp(unused_self) }
     #[allow(deprecated)]
     #[inline]
-    fn max_exp(unused_self: Option<f32>) -> int { num::Float::max_exp(unused_self) }
+    fn max_exp(unused_self: Option<f32>) -> isize { num::Float::max_exp(unused_self) }
     #[allow(deprecated)]
     #[inline]
-    fn min_10_exp(unused_self: Option<f32>) -> int { num::Float::min_10_exp(unused_self) }
+    fn min_10_exp(unused_self: Option<f32>) -> isize { num::Float::min_10_exp(unused_self) }
     #[allow(deprecated)]
     #[inline]
-    fn max_10_exp(unused_self: Option<f32>) -> int { num::Float::max_10_exp(unused_self) }
+    fn max_10_exp(unused_self: Option<f32>) -> isize { num::Float::max_10_exp(unused_self) }
     #[allow(deprecated)]
     #[inline]
     fn min_value() -> f32 { num::Float::min_value() }
@@ -191,8 +192,8 @@ impl Float for f32 {
     /// Constructs a floating point number by multiplying `x` by 2 raised to the
     /// power of `exp`
     #[inline]
-    fn ldexp(x: f32, exp: int) -> f32 {
-        unsafe { cmath::ldexpf(x, exp as c_int) }
+    fn ldexp(self, exp: isize) -> f32 {
+        unsafe { cmath::ldexpf(self, exp as c_int) }
     }
 
     /// Breaks the number into a normalized fraction and a base-2 exponent,
@@ -201,11 +202,11 @@ impl Float for f32 {
     /// - `self = x * pow(2, exp)`
     /// - `0.5 <= abs(x) < 1.0`
     #[inline]
-    fn frexp(self) -> (f32, int) {
+    fn frexp(self) -> (f32, isize) {
         unsafe {
             let mut exp = 0;
             let x = cmath::frexpf(self, &mut exp);
-            (x, exp as int)
+            (x, exp as isize)
         }
     }
 
@@ -357,209 +358,1516 @@ impl Float for f32 {
     }
 }
 
-//
-// Section: String Conversions
-//
-
-/// Converts a float to a string
-///
-/// # Arguments
-///
-/// * num - The float value
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_string(num: f32) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigAll, ExpNone, false);
-    r
-}
+#[cfg(not(test))]
+#[lang = "f32"]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl f32 {
+    /// Returns `true` if this value is `NaN` and false otherwise.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let nan = f32::NAN;
+    /// let f = 7.0_f32;
+    ///
+    /// assert!(nan.is_nan());
+    /// assert!(!f.is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_nan(self) -> bool { num::Float::is_nan(self) }
 
-/// Converts a float to a string in hexadecimal format
-///
-/// # Arguments
-///
-/// * num - The float value
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_hex(num: f32) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 16, true, SignNeg, DigAll, ExpNone, false);
-    r
-}
+    /// Returns `true` if this value is positive infinity or negative infinity and
+    /// false otherwise.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let f = 7.0f32;
+    /// let inf = f32::INFINITY;
+    /// let neg_inf = f32::NEG_INFINITY;
+    /// let nan = f32::NAN;
+    ///
+    /// assert!(!f.is_infinite());
+    /// assert!(!nan.is_infinite());
+    ///
+    /// assert!(inf.is_infinite());
+    /// assert!(neg_inf.is_infinite());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_infinite(self) -> bool { num::Float::is_infinite(self) }
 
-/// Converts a float to a string in a given radix, and a flag indicating
-/// whether it's a special value
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * radix - The base to use
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_radix_special(num: f32, rdx: u32) -> (String, bool) {
-    strconv::float_to_str_common(num, rdx, true, SignNeg, DigAll, ExpNone, false)
-}
+    /// Returns `true` if this number is neither infinite nor `NaN`.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let f = 7.0f32;
+    /// let inf = f32::INFINITY;
+    /// let neg_inf = f32::NEG_INFINITY;
+    /// let nan = f32::NAN;
+    ///
+    /// assert!(f.is_finite());
+    ///
+    /// assert!(!nan.is_finite());
+    /// assert!(!inf.is_finite());
+    /// assert!(!neg_inf.is_finite());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_finite(self) -> bool { num::Float::is_finite(self) }
 
-/// Converts a float to a string with exactly the number of
-/// provided significant digits
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of significant digits
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_exact(num: f32, dig: uint) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigExact(dig), ExpNone, false);
-    r
-}
+    /// Returns `true` if the number is neither zero, infinite,
+    /// [subnormal][subnormal], or `NaN`.
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// use std::f32;
+    ///
+    /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
+    /// let max = f32::MAX;
+    /// let lower_than_min = 1.0e-40_f32;
+    /// let zero = 0.0_f32;
+    ///
+    /// assert!(min.is_normal());
+    /// assert!(max.is_normal());
+    ///
+    /// assert!(!zero.is_normal());
+    /// assert!(!f32::NAN.is_normal());
+    /// assert!(!f32::INFINITY.is_normal());
+    /// // Values between `0` and `min` are Subnormal.
+    /// assert!(!lower_than_min.is_normal());
+    /// ```
+    /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_normal(self) -> bool { num::Float::is_normal(self) }
+
+    /// Returns the floating point category of the number. If only one property
+    /// is going to be tested, it is generally faster to use the specific
+    /// predicate instead.
+    ///
+    /// ```
+    /// use std::num::FpCategory;
+    /// use std::f32;
+    ///
+    /// let num = 12.4_f32;
+    /// let inf = f32::INFINITY;
+    ///
+    /// assert_eq!(num.classify(), FpCategory::Normal);
+    /// assert_eq!(inf.classify(), FpCategory::Infinite);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn classify(self) -> FpCategory { num::Float::classify(self) }
 
-/// Converts a float to a string with a maximum number of
-/// significant digits
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of significant digits
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_digits(num: f32, dig: uint) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigMax(dig), ExpNone, false);
-    r
-}
+    /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
+    /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
+    /// The floating point encoding is documented in the [Reference][floating-point].
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// use std::f32;
+    ///
+    /// let num = 2.0f32;
+    ///
+    /// // (8388608, -22, 1)
+    /// let (mantissa, exponent, sign) = num.integer_decode();
+    /// let sign_f = sign as f32;
+    /// let mantissa_f = mantissa as f32;
+    /// let exponent_f = num.powf(exponent as f32);
+    ///
+    /// // 1 * 8388608 * 2^(-22) == 2
+    /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    /// [floating-point]: ../../../../../reference.html#machine-types
+    #[unstable(feature = "std_misc", reason = "signature is undecided")]
+    #[inline]
+    pub fn integer_decode(self) -> (u64, i16, i8) { num::Float::integer_decode(self) }
 
-/// Converts a float to a string using the exponential notation with exactly the number of
-/// provided digits after the decimal point in the significand
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of digits after the decimal point
-/// * upper - Use `E` instead of `e` for the exponent sign
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_exp_exact(num: f32, dig: uint, upper: bool) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigExact(dig), ExpDec, upper);
-    r
-}
+    /// Returns the largest integer less than or equal to a number.
+    ///
+    /// ```
+    /// let f = 3.99_f32;
+    /// let g = 3.0_f32;
+    ///
+    /// assert_eq!(f.floor(), 3.0);
+    /// assert_eq!(g.floor(), 3.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn floor(self) -> f32 { num::Float::floor(self) }
 
-/// Converts a float to a string using the exponential notation with the maximum number of
-/// digits after the decimal point in the significand
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of digits after the decimal point
-/// * upper - Use `E` instead of `e` for the exponent sign
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_exp_digits(num: f32, dig: uint, upper: bool) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigMax(dig), ExpDec, upper);
-    r
-}
+    /// Returns the smallest integer greater than or equal to a number.
+    ///
+    /// ```
+    /// let f = 3.01_f32;
+    /// let g = 4.0_f32;
+    ///
+    /// assert_eq!(f.ceil(), 4.0);
+    /// assert_eq!(g.ceil(), 4.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn ceil(self) -> f32 { num::Float::ceil(self) }
 
-#[cfg(test)]
-mod tests {
-    use f32::*;
-    use num::*;
-    use num::FpCategory as Fp;
+    /// Returns the nearest integer to a number. Round half-way cases away from
+    /// `0.0`.
+    ///
+    /// ```
+    /// let f = 3.3_f32;
+    /// let g = -3.3_f32;
+    ///
+    /// assert_eq!(f.round(), 3.0);
+    /// assert_eq!(g.round(), -3.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn round(self) -> f32 { num::Float::round(self) }
 
-    #[test]
-    fn test_min_nan() {
-        assert_eq!(NAN.min(2.0), 2.0);
-        assert_eq!(2.0f32.min(NAN), 2.0);
-    }
+    /// Return the integer part of a number.
+    ///
+    /// ```
+    /// let f = 3.3_f32;
+    /// let g = -3.7_f32;
+    ///
+    /// assert_eq!(f.trunc(), 3.0);
+    /// assert_eq!(g.trunc(), -3.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn trunc(self) -> f32 { num::Float::trunc(self) }
 
-    #[test]
-    fn test_max_nan() {
-        assert_eq!(NAN.max(2.0), 2.0);
-        assert_eq!(2.0f32.max(NAN), 2.0);
-    }
+    /// Returns the fractional part of a number.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let x = 3.5_f32;
+    /// let y = -3.5_f32;
+    /// let abs_difference_x = (x.fract() - 0.5).abs();
+    /// let abs_difference_y = (y.fract() - (-0.5)).abs();
+    ///
+    /// assert!(abs_difference_x <= f32::EPSILON);
+    /// assert!(abs_difference_y <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn fract(self) -> f32 { num::Float::fract(self) }
 
-    #[test]
-    fn test_num_f32() {
-        test_num(10f32, 2f32);
-    }
+    /// Computes the absolute value of `self`. Returns `NAN` if the
+    /// number is `NAN`.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let x = 3.5_f32;
+    /// let y = -3.5_f32;
+    ///
+    /// let abs_difference_x = (x.abs() - x).abs();
+    /// let abs_difference_y = (y.abs() - (-y)).abs();
+    ///
+    /// assert!(abs_difference_x <= f32::EPSILON);
+    /// assert!(abs_difference_y <= f32::EPSILON);
+    ///
+    /// assert!(f32::NAN.abs().is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn abs(self) -> f32 { num::Float::abs(self) }
 
-    #[test]
-    fn test_floor() {
-        assert_approx_eq!(1.0f32.floor(), 1.0f32);
-        assert_approx_eq!(1.3f32.floor(), 1.0f32);
-        assert_approx_eq!(1.5f32.floor(), 1.0f32);
-        assert_approx_eq!(1.7f32.floor(), 1.0f32);
-        assert_approx_eq!(0.0f32.floor(), 0.0f32);
-        assert_approx_eq!((-0.0f32).floor(), -0.0f32);
-        assert_approx_eq!((-1.0f32).floor(), -1.0f32);
-        assert_approx_eq!((-1.3f32).floor(), -2.0f32);
-        assert_approx_eq!((-1.5f32).floor(), -2.0f32);
-        assert_approx_eq!((-1.7f32).floor(), -2.0f32);
-    }
+    /// Returns a number that represents the sign of `self`.
+    ///
+    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
+    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
+    /// - `NAN` if the number is `NAN`
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let f = 3.5_f32;
+    ///
+    /// assert_eq!(f.signum(), 1.0);
+    /// assert_eq!(f32::NEG_INFINITY.signum(), -1.0);
+    ///
+    /// assert!(f32::NAN.signum().is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn signum(self) -> f32 { num::Float::signum(self) }
 
-    #[test]
-    fn test_ceil() {
-        assert_approx_eq!(1.0f32.ceil(), 1.0f32);
-        assert_approx_eq!(1.3f32.ceil(), 2.0f32);
-        assert_approx_eq!(1.5f32.ceil(), 2.0f32);
-        assert_approx_eq!(1.7f32.ceil(), 2.0f32);
-        assert_approx_eq!(0.0f32.ceil(), 0.0f32);
-        assert_approx_eq!((-0.0f32).ceil(), -0.0f32);
-        assert_approx_eq!((-1.0f32).ceil(), -1.0f32);
-        assert_approx_eq!((-1.3f32).ceil(), -1.0f32);
-        assert_approx_eq!((-1.5f32).ceil(), -1.0f32);
-        assert_approx_eq!((-1.7f32).ceil(), -1.0f32);
-    }
+    /// Returns `true` if `self`'s sign bit is positive, including
+    /// `+0.0` and `INFINITY`.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let nan = f32::NAN;
+    /// let f = 7.0_f32;
+    /// let g = -7.0_f32;
+    ///
+    /// assert!(f.is_sign_positive());
+    /// assert!(!g.is_sign_positive());
+    /// // Requires both tests to determine if is `NaN`
+    /// assert!(!nan.is_sign_positive() && !nan.is_sign_negative());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_sign_positive(self) -> bool { num::Float::is_positive(self) }
 
-    #[test]
-    fn test_round() {
-        assert_approx_eq!(1.0f32.round(), 1.0f32);
-        assert_approx_eq!(1.3f32.round(), 1.0f32);
-        assert_approx_eq!(1.5f32.round(), 2.0f32);
-        assert_approx_eq!(1.7f32.round(), 2.0f32);
-        assert_approx_eq!(0.0f32.round(), 0.0f32);
-        assert_approx_eq!((-0.0f32).round(), -0.0f32);
-        assert_approx_eq!((-1.0f32).round(), -1.0f32);
-        assert_approx_eq!((-1.3f32).round(), -1.0f32);
-        assert_approx_eq!((-1.5f32).round(), -2.0f32);
-        assert_approx_eq!((-1.7f32).round(), -2.0f32);
-    }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[deprecated(since = "1.0.0", reason = "renamed to is_sign_positive")]
+    #[inline]
+    pub fn is_positive(self) -> bool { num::Float::is_positive(self) }
 
-    #[test]
-    fn test_trunc() {
-        assert_approx_eq!(1.0f32.trunc(), 1.0f32);
-        assert_approx_eq!(1.3f32.trunc(), 1.0f32);
-        assert_approx_eq!(1.5f32.trunc(), 1.0f32);
-        assert_approx_eq!(1.7f32.trunc(), 1.0f32);
-        assert_approx_eq!(0.0f32.trunc(), 0.0f32);
-        assert_approx_eq!((-0.0f32).trunc(), -0.0f32);
-        assert_approx_eq!((-1.0f32).trunc(), -1.0f32);
-        assert_approx_eq!((-1.3f32).trunc(), -1.0f32);
-        assert_approx_eq!((-1.5f32).trunc(), -1.0f32);
-        assert_approx_eq!((-1.7f32).trunc(), -1.0f32);
-    }
+    /// Returns `true` if `self`'s sign is negative, including `-0.0`
+    /// and `NEG_INFINITY`.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let nan = f32::NAN;
+    /// let f = 7.0f32;
+    /// let g = -7.0f32;
+    ///
+    /// assert!(!f.is_sign_negative());
+    /// assert!(g.is_sign_negative());
+    /// // Requires both tests to determine if is `NaN`.
+    /// assert!(!nan.is_sign_positive() && !nan.is_sign_negative());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_sign_negative(self) -> bool { num::Float::is_negative(self) }
 
-    #[test]
-    fn test_fract() {
-        assert_approx_eq!(1.0f32.fract(), 0.0f32);
-        assert_approx_eq!(1.3f32.fract(), 0.3f32);
-        assert_approx_eq!(1.5f32.fract(), 0.5f32);
-        assert_approx_eq!(1.7f32.fract(), 0.7f32);
-        assert_approx_eq!(0.0f32.fract(), 0.0f32);
-        assert_approx_eq!((-0.0f32).fract(), -0.0f32);
-        assert_approx_eq!((-1.0f32).fract(), -0.0f32);
-        assert_approx_eq!((-1.3f32).fract(), -0.3f32);
-        assert_approx_eq!((-1.5f32).fract(), -0.5f32);
-        assert_approx_eq!((-1.7f32).fract(), -0.7f32);
-    }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[deprecated(since = "1.0.0", reason = "renamed to is_sign_negative")]
+    #[inline]
+    pub fn is_negative(self) -> bool { num::Float::is_negative(self) }
 
-    #[test]
-    fn test_exp() {
-        assert_eq!(1.0, 0.0f32.exp());
-        assert_approx_eq!(2.718282, 1.0f32.exp());
-        assert_approx_eq!(148.413162, 5.0f32.exp());
+    /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
+    /// error. This produces a more accurate result with better performance than
+    /// a separate multiplication operation followed by an add.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let m = 10.0_f32;
+    /// let x = 4.0_f32;
+    /// let b = 60.0_f32;
+    ///
+    /// // 100.0
+    /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn mul_add(self, a: f32, b: f32) -> f32 { num::Float::mul_add(self, a, b) }
+
+    /// Take the reciprocal (inverse) of a number, `1/x`.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let x = 2.0_f32;
+    /// let abs_difference = (x.recip() - (1.0/x)).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn recip(self) -> f32 { num::Float::recip(self) }
+
+    /// Raise a number to an integer power.
+    ///
+    /// Using this function is generally faster than using `powf`
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let x = 2.0_f32;
+    /// let abs_difference = (x.powi(2) - x*x).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn powi(self, n: i32) -> f32 { num::Float::powi(self, n) }
+
+    /// Raise a number to a floating point power.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let x = 2.0_f32;
+    /// let abs_difference = (x.powf(2.0) - x*x).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn powf(self, n: f32) -> f32 { num::Float::powf(self, n) }
+
+    /// Take the square root of a number.
+    ///
+    /// Returns NaN if `self` is a negative number.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let positive = 4.0_f32;
+    /// let negative = -4.0_f32;
+    ///
+    /// let abs_difference = (positive.sqrt() - 2.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(negative.sqrt().is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sqrt(self) -> f32 { num::Float::sqrt(self) }
+
+    /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// use std::f32;
+    ///
+    /// let f = 4.0f32;
+    ///
+    /// let abs_difference = (f.rsqrt() - 0.5).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[deprecated(since = "1.0.0", reason = "use self.sqrt().recip() instead")]
+    #[inline]
+    pub fn rsqrt(self) -> f32 { num::Float::rsqrt(self) }
+
+    /// Returns `e^(self)`, (the exponential function).
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let one = 1.0f32;
+    /// // e^1
+    /// let e = one.exp();
+    ///
+    /// // ln(e) - 1 == 0
+    /// let abs_difference = (e.ln() - 1.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn exp(self) -> f32 { num::Float::exp(self) }
+
+    /// Returns `2^(self)`.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let f = 2.0f32;
+    ///
+    /// // 2^2 - 4 == 0
+    /// let abs_difference = (f.exp2() - 4.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn exp2(self) -> f32 { num::Float::exp2(self) }
+
+    /// Returns the natural logarithm of the number.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let one = 1.0f32;
+    /// // e^1
+    /// let e = one.exp();
+    ///
+    /// // ln(e) - 1 == 0
+    /// let abs_difference = (e.ln() - 1.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn ln(self) -> f32 { num::Float::ln(self) }
+
+    /// Returns the logarithm of the number with respect to an arbitrary base.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let ten = 10.0f32;
+    /// let two = 2.0f32;
+    ///
+    /// // log10(10) - 1 == 0
+    /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs();
+    ///
+    /// // log2(2) - 1 == 0
+    /// let abs_difference_2 = (two.log(2.0) - 1.0).abs();
+    ///
+    /// assert!(abs_difference_10 <= f32::EPSILON);
+    /// assert!(abs_difference_2 <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn log(self, base: f32) -> f32 { num::Float::log(self, base) }
+
+    /// Returns the base 2 logarithm of the number.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let two = 2.0f32;
+    ///
+    /// // log2(2) - 1 == 0
+    /// let abs_difference = (two.log2() - 1.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn log2(self) -> f32 { num::Float::log2(self) }
+
+    /// Returns the base 10 logarithm of the number.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let ten = 10.0f32;
+    ///
+    /// // log10(10) - 1 == 0
+    /// let abs_difference = (ten.log10() - 1.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn log10(self) -> f32 { num::Float::log10(self) }
+
+    /// Convert radians to degrees.
+    ///
+    /// ```
+    /// # #![feature(std_misc, core)]
+    /// use std::f32::{self, consts};
+    ///
+    /// let angle = consts::PI;
+    ///
+    /// let abs_difference = (angle.to_degrees() - 180.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "desirability is unclear")]
+    #[inline]
+    pub fn to_degrees(self) -> f32 { num::Float::to_degrees(self) }
+
+    /// Convert degrees to radians.
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// use std::f32::{self, consts};
+    ///
+    /// let angle = 180.0f32;
+    ///
+    /// let abs_difference = (angle.to_radians() - consts::PI).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "desirability is unclear")]
+    #[inline]
+    pub fn to_radians(self) -> f32 { num::Float::to_radians(self) }
+
+    /// Constructs a floating point number of `x*2^exp`.
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// use std::f32;
+    /// // 3*2^2 - 12 == 0
+    /// let abs_difference = (f32::ldexp(3.0, 2) - 12.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "pending integer conventions")]
+    #[inline]
+    pub fn ldexp(x: f32, exp: isize) -> f32 {
+        unsafe { cmath::ldexpf(x, exp as c_int) }
+    }
+
+    /// Breaks the number into a normalized fraction and a base-2 exponent,
+    /// satisfying:
+    ///
+    ///  * `self = x * 2^exp`
+    ///  * `0.5 <= abs(x) < 1.0`
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// use std::f32;
+    ///
+    /// let x = 4.0f32;
+    ///
+    /// // (1/2)*2^3 -> 1 * 8/2 -> 4.0
+    /// let f = x.frexp();
+    /// let abs_difference_0 = (f.0 - 0.5).abs();
+    /// let abs_difference_1 = (f.1 as f32 - 3.0).abs();
+    ///
+    /// assert!(abs_difference_0 <= f32::EPSILON);
+    /// assert!(abs_difference_1 <= f32::EPSILON);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "pending integer conventions")]
+    #[inline]
+    pub fn frexp(self) -> (f32, isize) {
+        unsafe {
+            let mut exp = 0;
+            let x = cmath::frexpf(self, &mut exp);
+            (x, exp as isize)
+        }
+    }
+
+    /// Returns the next representable floating-point value in the direction of
+    /// `other`.
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// use std::f32;
+    ///
+    /// let x = 1.0f32;
+    ///
+    /// let abs_diff = (x.next_after(2.0) - 1.00000011920928955078125_f32).abs();
+    ///
+    /// assert!(abs_diff <= f32::EPSILON);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn next_after(self, other: f32) -> f32 {
+        unsafe { cmath::nextafterf(self, other) }
+    }
+
+    /// Returns the maximum of the two numbers.
+    ///
+    /// ```
+    /// let x = 1.0f32;
+    /// let y = 2.0f32;
+    ///
+    /// assert_eq!(x.max(y), y);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn max(self, other: f32) -> f32 {
+        unsafe { cmath::fmaxf(self, other) }
+    }
+
+    /// Returns the minimum of the two numbers.
+    ///
+    /// ```
+    /// let x = 1.0f32;
+    /// let y = 2.0f32;
+    ///
+    /// assert_eq!(x.min(y), x);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn min(self, other: f32) -> f32 {
+        unsafe { cmath::fminf(self, other) }
+    }
+
+    /// The positive difference of two numbers.
+    ///
+    /// * If `self <= other`: `0:0`
+    /// * Else: `self - other`
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// use std::f32;
+    ///
+    /// let x = 3.0f32;
+    /// let y = -3.0f32;
+    ///
+    /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs();
+    /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs();
+    ///
+    /// assert!(abs_difference_x <= f32::EPSILON);
+    /// assert!(abs_difference_y <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn abs_sub(self, other: f32) -> f32 {
+        unsafe { cmath::fdimf(self, other) }
+    }
+
+    /// Take the cubic root of a number.
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// use std::f32;
+    ///
+    /// let x = 8.0f32;
+    ///
+    /// // x^(1/3) - 2 == 0
+    /// let abs_difference = (x.cbrt() - 2.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn cbrt(self) -> f32 {
+        unsafe { cmath::cbrtf(self) }
+    }
+
+    /// Calculate the length of the hypotenuse of a right-angle triangle given
+    /// legs of length `x` and `y`.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let x = 2.0f32;
+    /// let y = 3.0f32;
+    ///
+    /// // sqrt(x^2 + y^2)
+    /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn hypot(self, other: f32) -> f32 {
+        unsafe { cmath::hypotf(self, other) }
+    }
+
+    /// Computes the sine of a number (in radians).
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let x = f32::consts::PI/2.0;
+    ///
+    /// let abs_difference = (x.sin() - 1.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sin(self) -> f32 {
+        unsafe { intrinsics::sinf32(self) }
+    }
+
+    /// Computes the cosine of a number (in radians).
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let x = 2.0*f32::consts::PI;
+    ///
+    /// let abs_difference = (x.cos() - 1.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn cos(self) -> f32 {
+        unsafe { intrinsics::cosf32(self) }
+    }
+
+    /// Computes the tangent of a number (in radians).
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/4.0;
+    /// let abs_difference = (x.tan() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn tan(self) -> f32 {
+        unsafe { cmath::tanf(self) }
+    }
+
+    /// Computes the arcsine of a number. Return value is in radians in
+    /// the range [-pi/2, pi/2] or NaN if the number is outside the range
+    /// [-1, 1].
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let f = f32::consts::PI / 2.0;
+    ///
+    /// // asin(sin(pi/2))
+    /// let abs_difference = f.sin().asin().abs_sub(f32::consts::PI / 2.0);
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn asin(self) -> f32 {
+        unsafe { cmath::asinf(self) }
+    }
+
+    /// Computes the arccosine of a number. Return value is in radians in
+    /// the range [0, pi] or NaN if the number is outside the range
+    /// [-1, 1].
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let f = f32::consts::PI / 4.0;
+    ///
+    /// // acos(cos(pi/4))
+    /// let abs_difference = f.cos().acos().abs_sub(f32::consts::PI / 4.0);
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn acos(self) -> f32 {
+        unsafe { cmath::acosf(self) }
+    }
+
+    /// Computes the arctangent of a number. Return value is in radians in the
+    /// range [-pi/2, pi/2];
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let f = 1.0f32;
+    ///
+    /// // atan(tan(1))
+    /// let abs_difference = f.tan().atan().abs_sub(1.0);
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn atan(self) -> f32 {
+        unsafe { cmath::atanf(self) }
+    }
+
+    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
+    ///
+    /// * `x = 0`, `y = 0`: `0`
+    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
+    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
+    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let pi = f32::consts::PI;
+    /// // All angles from horizontal right (+x)
+    /// // 45 deg counter-clockwise
+    /// let x1 = 3.0f32;
+    /// let y1 = -3.0f32;
+    ///
+    /// // 135 deg clockwise
+    /// let x2 = -3.0f32;
+    /// let y2 = 3.0f32;
+    ///
+    /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
+    ///
+    /// assert!(abs_difference_1 <= f32::EPSILON);
+    /// assert!(abs_difference_2 <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn atan2(self, other: f32) -> f32 {
+        unsafe { cmath::atan2f(self, other) }
+    }
+
+    /// Simultaneously computes the sine and cosine of the number, `x`. Returns
+    /// `(sin(x), cos(x))`.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let x = f32::consts::PI/4.0;
+    /// let f = x.sin_cos();
+    ///
+    /// let abs_difference_0 = (f.0 - x.sin()).abs();
+    /// let abs_difference_1 = (f.1 - x.cos()).abs();
+    ///
+    /// assert!(abs_difference_0 <= f32::EPSILON);
+    /// assert!(abs_difference_0 <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sin_cos(self) -> (f32, f32) {
+        (self.sin(), self.cos())
+    }
+
+    /// Returns `e^(self) - 1` in a way that is accurate even if the
+    /// number is close to zero.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let x = 7.0f64;
+    ///
+    /// // e^(ln(7)) - 1
+    /// let abs_difference = x.ln().exp_m1().abs_sub(6.0);
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn exp_m1(self) -> f32 {
+        unsafe { cmath::expm1f(self) }
+    }
+
+    /// Returns `ln(1+n)` (natural logarithm) more accurately than if
+    /// the operations were performed separately.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let x = f32::consts::E - 1.0;
+    ///
+    /// // ln(1 + (e - 1)) == ln(e) == 1
+    /// let abs_difference = (x.ln_1p() - 1.0).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn ln_1p(self) -> f32 {
+        unsafe { cmath::log1pf(self) }
+    }
+
+    /// Hyperbolic sine function.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let e = f32::consts::E;
+    /// let x = 1.0f32;
+    ///
+    /// let f = x.sinh();
+    /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
+    /// let g = (e*e - 1.0)/(2.0*e);
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sinh(self) -> f32 {
+        unsafe { cmath::sinhf(self) }
+    }
+
+    /// Hyperbolic cosine function.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let e = f32::consts::E;
+    /// let x = 1.0f32;
+    /// let f = x.cosh();
+    /// // Solving cosh() at 1 gives this result
+    /// let g = (e*e + 1.0)/(2.0*e);
+    /// let abs_difference = f.abs_sub(g);
+    ///
+    /// // Same result
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn cosh(self) -> f32 {
+        unsafe { cmath::coshf(self) }
+    }
+
+    /// Hyperbolic tangent function.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let e = f32::consts::E;
+    /// let x = 1.0f32;
+    ///
+    /// let f = x.tanh();
+    /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
+    /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn tanh(self) -> f32 {
+        unsafe { cmath::tanhf(self) }
+    }
+
+    /// Inverse hyperbolic sine function.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let x = 1.0f32;
+    /// let f = x.sinh().asinh();
+    ///
+    /// let abs_difference = (f - x).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn asinh(self) -> f32 {
+        match self {
+            NEG_INFINITY => NEG_INFINITY,
+            x => (x + ((x * x) + 1.0).sqrt()).ln(),
+        }
+    }
+
+    /// Inverse hyperbolic cosine function.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let x = 1.0f32;
+    /// let f = x.cosh().acosh();
+    ///
+    /// let abs_difference = (f - x).abs();
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn acosh(self) -> f32 {
+        match self {
+            x if x < 1.0 => Float::nan(),
+            x => (x + ((x * x) - 1.0).sqrt()).ln(),
+        }
+    }
+
+    /// Inverse hyperbolic tangent function.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let e = f32::consts::E;
+    /// let f = e.tanh().atanh();
+    ///
+    /// let abs_difference = f.abs_sub(e);
+    ///
+    /// assert!(abs_difference <= f32::EPSILON);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn atanh(self) -> f32 {
+        0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
+    }
+}
+
+//
+// Section: String Conversions
+//
+
+/// Converts a float to a string
+///
+/// # Arguments
+///
+/// * num - The float value
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+#[deprecated(since = "1.0.0", reason = "use the ToString trait instead")]
+pub fn to_string(num: f32) -> String {
+    let (r, _) = strconv::float_to_str_common(
+        num, 10, true, SignNeg, DigAll, ExpNone, false);
+    r
+}
+
+/// Converts a float to a string in hexadecimal format
+///
+/// # Arguments
+///
+/// * num - The float value
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+#[deprecated(since = "1.0.0", reason = "use format! instead")]
+pub fn to_str_hex(num: f32) -> String {
+    let (r, _) = strconv::float_to_str_common(
+        num, 16, true, SignNeg, DigAll, ExpNone, false);
+    r
+}
+
+/// Converts a float to a string in a given radix, and a flag indicating
+/// whether it's a special value
+///
+/// # Arguments
+///
+/// * num - The float value
+/// * radix - The base to use
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+#[deprecated(since = "1.0.0", reason = "use format! instead")]
+pub fn to_str_radix_special(num: f32, rdx: u32) -> (String, bool) {
+    strconv::float_to_str_common(num, rdx, true, SignNeg, DigAll, ExpNone, false)
+}
+
+/// Converts a float to a string with exactly the number of
+/// provided significant digits
+///
+/// # Arguments
+///
+/// * num - The float value
+/// * digits - The number of significant digits
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+pub fn to_str_exact(num: f32, dig: usize) -> String {
+    let (r, _) = strconv::float_to_str_common(
+        num, 10, true, SignNeg, DigExact(dig), ExpNone, false);
+    r
+}
+
+/// Converts a float to a string with a maximum number of
+/// significant digits
+///
+/// # Arguments
+///
+/// * num - The float value
+/// * digits - The number of significant digits
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+pub fn to_str_digits(num: f32, dig: usize) -> String {
+    let (r, _) = strconv::float_to_str_common(
+        num, 10, true, SignNeg, DigMax(dig), ExpNone, false);
+    r
+}
+
+/// Converts a float to a string using the exponential notation with exactly the number of
+/// provided digits after the decimal point in the significand
+///
+/// # Arguments
+///
+/// * num - The float value
+/// * digits - The number of digits after the decimal point
+/// * upper - Use `E` instead of `e` for the exponent sign
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+pub fn to_str_exp_exact(num: f32, dig: usize, upper: bool) -> String {
+    let (r, _) = strconv::float_to_str_common(
+        num, 10, true, SignNeg, DigExact(dig), ExpDec, upper);
+    r
+}
+
+/// Converts a float to a string using the exponential notation with the maximum number of
+/// digits after the decimal point in the significand
+///
+/// # Arguments
+///
+/// * num - The float value
+/// * digits - The number of digits after the decimal point
+/// * upper - Use `E` instead of `e` for the exponent sign
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+pub fn to_str_exp_digits(num: f32, dig: usize, upper: bool) -> String {
+    let (r, _) = strconv::float_to_str_common(
+        num, 10, true, SignNeg, DigMax(dig), ExpDec, upper);
+    r
+}
+
+#[cfg(test)]
+mod tests {
+    use f32::*;
+    use num::*;
+    use num::FpCategory as Fp;
+
+    #[test]
+    fn test_num_f32() {
+        test_num(10f32, 2f32);
+    }
+
+    #[test]
+    fn test_min_nan() {
+        assert_eq!(NAN.min(2.0), 2.0);
+        assert_eq!(2.0f32.min(NAN), 2.0);
+    }
+
+    #[test]
+    fn test_max_nan() {
+        assert_eq!(NAN.max(2.0), 2.0);
+        assert_eq!(2.0f32.max(NAN), 2.0);
+    }
+
+    #[test]
+    fn test_nan() {
+        let nan: f32 = Float::nan();
+        assert!(nan.is_nan());
+        assert!(!nan.is_infinite());
+        assert!(!nan.is_finite());
+        assert!(!nan.is_normal());
+        assert!(!nan.is_sign_positive());
+        assert!(!nan.is_sign_negative());
+        assert_eq!(Fp::Nan, nan.classify());
+    }
+
+    #[test]
+    fn test_infinity() {
+        let inf: f32 = Float::infinity();
+        assert!(inf.is_infinite());
+        assert!(!inf.is_finite());
+        assert!(inf.is_sign_positive());
+        assert!(!inf.is_sign_negative());
+        assert!(!inf.is_nan());
+        assert!(!inf.is_normal());
+        assert_eq!(Fp::Infinite, inf.classify());
+    }
+
+    #[test]
+    fn test_neg_infinity() {
+        let neg_inf: f32 = Float::neg_infinity();
+        assert!(neg_inf.is_infinite());
+        assert!(!neg_inf.is_finite());
+        assert!(!neg_inf.is_sign_positive());
+        assert!(neg_inf.is_sign_negative());
+        assert!(!neg_inf.is_nan());
+        assert!(!neg_inf.is_normal());
+        assert_eq!(Fp::Infinite, neg_inf.classify());
+    }
+
+    #[test]
+    fn test_zero() {
+        let zero: f32 = Float::zero();
+        assert_eq!(0.0, zero);
+        assert!(!zero.is_infinite());
+        assert!(zero.is_finite());
+        assert!(zero.is_sign_positive());
+        assert!(!zero.is_sign_negative());
+        assert!(!zero.is_nan());
+        assert!(!zero.is_normal());
+        assert_eq!(Fp::Zero, zero.classify());
+    }
+
+    #[test]
+    fn test_neg_zero() {
+        let neg_zero: f32 = Float::neg_zero();
+        assert_eq!(0.0, neg_zero);
+        assert!(!neg_zero.is_infinite());
+        assert!(neg_zero.is_finite());
+        assert!(!neg_zero.is_sign_positive());
+        assert!(neg_zero.is_sign_negative());
+        assert!(!neg_zero.is_nan());
+        assert!(!neg_zero.is_normal());
+        assert_eq!(Fp::Zero, neg_zero.classify());
+    }
+
+    #[test]
+    fn test_one() {
+        let one: f32 = Float::one();
+        assert_eq!(1.0, one);
+        assert!(!one.is_infinite());
+        assert!(one.is_finite());
+        assert!(one.is_sign_positive());
+        assert!(!one.is_sign_negative());
+        assert!(!one.is_nan());
+        assert!(one.is_normal());
+        assert_eq!(Fp::Normal, one.classify());
+    }
+
+    #[test]
+    fn test_is_nan() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert!(nan.is_nan());
+        assert!(!0.0f32.is_nan());
+        assert!(!5.3f32.is_nan());
+        assert!(!(-10.732f32).is_nan());
+        assert!(!inf.is_nan());
+        assert!(!neg_inf.is_nan());
+    }
+
+    #[test]
+    fn test_is_infinite() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert!(!nan.is_infinite());
+        assert!(inf.is_infinite());
+        assert!(neg_inf.is_infinite());
+        assert!(!0.0f32.is_infinite());
+        assert!(!42.8f32.is_infinite());
+        assert!(!(-109.2f32).is_infinite());
+    }
+
+    #[test]
+    fn test_is_finite() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert!(!nan.is_finite());
+        assert!(!inf.is_finite());
+        assert!(!neg_inf.is_finite());
+        assert!(0.0f32.is_finite());
+        assert!(42.8f32.is_finite());
+        assert!((-109.2f32).is_finite());
+    }
+
+    #[test]
+    fn test_is_normal() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let zero: f32 = Float::zero();
+        let neg_zero: f32 = Float::neg_zero();
+        assert!(!nan.is_normal());
+        assert!(!inf.is_normal());
+        assert!(!neg_inf.is_normal());
+        assert!(!zero.is_normal());
+        assert!(!neg_zero.is_normal());
+        assert!(1f32.is_normal());
+        assert!(1e-37f32.is_normal());
+        assert!(!1e-38f32.is_normal());
+    }
+
+    #[test]
+    fn test_classify() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let zero: f32 = Float::zero();
+        let neg_zero: f32 = Float::neg_zero();
+        assert_eq!(nan.classify(), Fp::Nan);
+        assert_eq!(inf.classify(), Fp::Infinite);
+        assert_eq!(neg_inf.classify(), Fp::Infinite);
+        assert_eq!(zero.classify(), Fp::Zero);
+        assert_eq!(neg_zero.classify(), Fp::Zero);
+        assert_eq!(1f32.classify(), Fp::Normal);
+        assert_eq!(1e-37f32.classify(), Fp::Normal);
+        assert_eq!(1e-38f32.classify(), Fp::Subnormal);
+    }
+
+    #[test]
+    fn test_integer_decode() {
+        assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
+        assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
+        assert_eq!(2f32.powf(100.0).integer_decode(), (8388608, 77, 1));
+        assert_eq!(0f32.integer_decode(), (0, -150, 1));
+        assert_eq!((-0f32).integer_decode(), (0, -150, -1));
+        assert_eq!(INFINITY.integer_decode(), (8388608, 105, 1));
+        assert_eq!(NEG_INFINITY.integer_decode(), (8388608, 105, -1));
+        assert_eq!(NAN.integer_decode(), (12582912, 105, 1));
+    }
+
+    #[test]
+    fn test_floor() {
+        assert_approx_eq!(1.0f32.floor(), 1.0f32);
+        assert_approx_eq!(1.3f32.floor(), 1.0f32);
+        assert_approx_eq!(1.5f32.floor(), 1.0f32);
+        assert_approx_eq!(1.7f32.floor(), 1.0f32);
+        assert_approx_eq!(0.0f32.floor(), 0.0f32);
+        assert_approx_eq!((-0.0f32).floor(), -0.0f32);
+        assert_approx_eq!((-1.0f32).floor(), -1.0f32);
+        assert_approx_eq!((-1.3f32).floor(), -2.0f32);
+        assert_approx_eq!((-1.5f32).floor(), -2.0f32);
+        assert_approx_eq!((-1.7f32).floor(), -2.0f32);
+    }
+
+    #[test]
+    fn test_ceil() {
+        assert_approx_eq!(1.0f32.ceil(), 1.0f32);
+        assert_approx_eq!(1.3f32.ceil(), 2.0f32);
+        assert_approx_eq!(1.5f32.ceil(), 2.0f32);
+        assert_approx_eq!(1.7f32.ceil(), 2.0f32);
+        assert_approx_eq!(0.0f32.ceil(), 0.0f32);
+        assert_approx_eq!((-0.0f32).ceil(), -0.0f32);
+        assert_approx_eq!((-1.0f32).ceil(), -1.0f32);
+        assert_approx_eq!((-1.3f32).ceil(), -1.0f32);
+        assert_approx_eq!((-1.5f32).ceil(), -1.0f32);
+        assert_approx_eq!((-1.7f32).ceil(), -1.0f32);
+    }
+
+    #[test]
+    fn test_round() {
+        assert_approx_eq!(1.0f32.round(), 1.0f32);
+        assert_approx_eq!(1.3f32.round(), 1.0f32);
+        assert_approx_eq!(1.5f32.round(), 2.0f32);
+        assert_approx_eq!(1.7f32.round(), 2.0f32);
+        assert_approx_eq!(0.0f32.round(), 0.0f32);
+        assert_approx_eq!((-0.0f32).round(), -0.0f32);
+        assert_approx_eq!((-1.0f32).round(), -1.0f32);
+        assert_approx_eq!((-1.3f32).round(), -1.0f32);
+        assert_approx_eq!((-1.5f32).round(), -2.0f32);
+        assert_approx_eq!((-1.7f32).round(), -2.0f32);
+    }
+
+    #[test]
+    fn test_trunc() {
+        assert_approx_eq!(1.0f32.trunc(), 1.0f32);
+        assert_approx_eq!(1.3f32.trunc(), 1.0f32);
+        assert_approx_eq!(1.5f32.trunc(), 1.0f32);
+        assert_approx_eq!(1.7f32.trunc(), 1.0f32);
+        assert_approx_eq!(0.0f32.trunc(), 0.0f32);
+        assert_approx_eq!((-0.0f32).trunc(), -0.0f32);
+        assert_approx_eq!((-1.0f32).trunc(), -1.0f32);
+        assert_approx_eq!((-1.3f32).trunc(), -1.0f32);
+        assert_approx_eq!((-1.5f32).trunc(), -1.0f32);
+        assert_approx_eq!((-1.7f32).trunc(), -1.0f32);
+    }
+
+    #[test]
+    fn test_fract() {
+        assert_approx_eq!(1.0f32.fract(), 0.0f32);
+        assert_approx_eq!(1.3f32.fract(), 0.3f32);
+        assert_approx_eq!(1.5f32.fract(), 0.5f32);
+        assert_approx_eq!(1.7f32.fract(), 0.7f32);
+        assert_approx_eq!(0.0f32.fract(), 0.0f32);
+        assert_approx_eq!((-0.0f32).fract(), -0.0f32);
+        assert_approx_eq!((-1.0f32).fract(), -0.0f32);
+        assert_approx_eq!((-1.3f32).fract(), -0.3f32);
+        assert_approx_eq!((-1.5f32).fract(), -0.5f32);
+        assert_approx_eq!((-1.7f32).fract(), -0.7f32);
+    }
+
+    #[test]
+    fn test_abs() {
+        assert_eq!(INFINITY.abs(), INFINITY);
+        assert_eq!(1f32.abs(), 1f32);
+        assert_eq!(0f32.abs(), 0f32);
+        assert_eq!((-0f32).abs(), 0f32);
+        assert_eq!((-1f32).abs(), 1f32);
+        assert_eq!(NEG_INFINITY.abs(), INFINITY);
+        assert_eq!((1f32/NEG_INFINITY).abs(), 0f32);
+        assert!(NAN.abs().is_nan());
+    }
+
+    #[test]
+    fn test_signum() {
+        assert_eq!(INFINITY.signum(), 1f32);
+        assert_eq!(1f32.signum(), 1f32);
+        assert_eq!(0f32.signum(), 1f32);
+        assert_eq!((-0f32).signum(), -1f32);
+        assert_eq!((-1f32).signum(), -1f32);
+        assert_eq!(NEG_INFINITY.signum(), -1f32);
+        assert_eq!((1f32/NEG_INFINITY).signum(), -1f32);
+        assert!(NAN.signum().is_nan());
+    }
+
+    #[test]
+    fn test_is_sign_positive() {
+        assert!(INFINITY.is_sign_positive());
+        assert!(1f32.is_sign_positive());
+        assert!(0f32.is_sign_positive());
+        assert!(!(-0f32).is_sign_positive());
+        assert!(!(-1f32).is_sign_positive());
+        assert!(!NEG_INFINITY.is_sign_positive());
+        assert!(!(1f32/NEG_INFINITY).is_sign_positive());
+        assert!(!NAN.is_sign_positive());
+    }
+
+    #[test]
+    fn test_is_sign_negative() {
+        assert!(!INFINITY.is_sign_negative());
+        assert!(!1f32.is_sign_negative());
+        assert!(!0f32.is_sign_negative());
+        assert!((-0f32).is_sign_negative());
+        assert!((-1f32).is_sign_negative());
+        assert!(NEG_INFINITY.is_sign_negative());
+        assert!((1f32/NEG_INFINITY).is_sign_negative());
+        assert!(!NAN.is_sign_negative());
+    }
+
+    #[test]
+    fn test_mul_add() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_approx_eq!(12.3f32.mul_add(4.5, 6.7), 62.05);
+        assert_approx_eq!((-12.3f32).mul_add(-4.5, -6.7), 48.65);
+        assert_approx_eq!(0.0f32.mul_add(8.9, 1.2), 1.2);
+        assert_approx_eq!(3.4f32.mul_add(-0.0, 5.6), 5.6);
+        assert!(nan.mul_add(7.8, 9.0).is_nan());
+        assert_eq!(inf.mul_add(7.8, 9.0), inf);
+        assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
+        assert_eq!(8.9f32.mul_add(inf, 3.2), inf);
+        assert_eq!((-3.2f32).mul_add(2.4, neg_inf), neg_inf);
+    }
+
+    #[test]
+    fn test_recip() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(1.0f32.recip(), 1.0);
+        assert_eq!(2.0f32.recip(), 0.5);
+        assert_eq!((-0.4f32).recip(), -2.5);
+        assert_eq!(0.0f32.recip(), inf);
+        assert!(nan.recip().is_nan());
+        assert_eq!(inf.recip(), 0.0);
+        assert_eq!(neg_inf.recip(), 0.0);
+    }
+
+    #[test]
+    fn test_powi() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(1.0f32.powi(1), 1.0);
+        assert_approx_eq!((-3.1f32).powi(2), 9.61);
+        assert_approx_eq!(5.9f32.powi(-2), 0.028727);
+        assert_eq!(8.3f32.powi(0), 1.0);
+        assert!(nan.powi(2).is_nan());
+        assert_eq!(inf.powi(3), inf);
+        assert_eq!(neg_inf.powi(2), inf);
+    }
+
+    #[test]
+    fn test_powf() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(1.0f32.powf(1.0), 1.0);
+        assert_approx_eq!(3.4f32.powf(4.5), 246.408218);
+        assert_approx_eq!(2.7f32.powf(-3.2), 0.041652);
+        assert_approx_eq!((-3.1f32).powf(2.0), 9.61);
+        assert_approx_eq!(5.9f32.powf(-2.0), 0.028727);
+        assert_eq!(8.3f32.powf(0.0), 1.0);
+        assert!(nan.powf(2.0).is_nan());
+        assert_eq!(inf.powf(2.0), inf);
+        assert_eq!(neg_inf.powf(3.0), neg_inf);
+    }
+
+    #[test]
+    fn test_sqrt_domain() {
+        assert!(NAN.sqrt().is_nan());
+        assert!(NEG_INFINITY.sqrt().is_nan());
+        assert!((-1.0f32).sqrt().is_nan());
+        assert_eq!((-0.0f32).sqrt(), -0.0);
+        assert_eq!(0.0f32.sqrt(), 0.0);
+        assert_eq!(1.0f32.sqrt(), 1.0);
+        assert_eq!(INFINITY.sqrt(), INFINITY);
+    }
+
+    #[test]
+    fn test_rsqrt() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert!(nan.rsqrt().is_nan());
+        assert_eq!(inf.rsqrt(), 0.0);
+        assert!(neg_inf.rsqrt().is_nan());
+        assert!((-1.0f32).rsqrt().is_nan());
+        assert_eq!((-0.0f32).rsqrt(), neg_inf);
+        assert_eq!(0.0f32.rsqrt(), inf);
+        assert_eq!(1.0f32.rsqrt(), 1.0);
+        assert_eq!(4.0f32.rsqrt(), 0.5);
+    }
+
+    #[test]
+    fn test_exp() {
+        assert_eq!(1.0, 0.0f32.exp());
+        assert_approx_eq!(2.718282, 1.0f32.exp());
+        assert_approx_eq!(148.413162, 5.0f32.exp());
 
         let inf: f32 = Float::infinity();
         let neg_inf: f32 = Float::neg_infinity();
@@ -582,6 +1890,172 @@ mod tests {
         assert!(nan.exp2().is_nan());
     }
 
+    #[test]
+    fn test_ln() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_approx_eq!(1.0f32.exp().ln(), 1.0);
+        assert!(nan.ln().is_nan());
+        assert_eq!(inf.ln(), inf);
+        assert!(neg_inf.ln().is_nan());
+        assert!((-2.3f32).ln().is_nan());
+        assert_eq!((-0.0f32).ln(), neg_inf);
+        assert_eq!(0.0f32.ln(), neg_inf);
+        assert_approx_eq!(4.0f32.ln(), 1.386294);
+    }
+
+    #[test]
+    fn test_log() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(10.0f32.log(10.0), 1.0);
+        assert_approx_eq!(2.3f32.log(3.5), 0.664858);
+        assert_eq!(1.0f32.exp().log(1.0.exp()), 1.0);
+        assert!(1.0f32.log(1.0).is_nan());
+        assert!(1.0f32.log(-13.9).is_nan());
+        assert!(nan.log(2.3).is_nan());
+        assert_eq!(inf.log(10.0), inf);
+        assert!(neg_inf.log(8.8).is_nan());
+        assert!((-2.3f32).log(0.1).is_nan());
+        assert_eq!((-0.0f32).log(2.0), neg_inf);
+        assert_eq!(0.0f32.log(7.0), neg_inf);
+    }
+
+    #[test]
+    fn test_log2() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_approx_eq!(10.0f32.log2(), 3.321928);
+        assert_approx_eq!(2.3f32.log2(), 1.201634);
+        assert_approx_eq!(1.0f32.exp().log2(), 1.442695);
+        assert!(nan.log2().is_nan());
+        assert_eq!(inf.log2(), inf);
+        assert!(neg_inf.log2().is_nan());
+        assert!((-2.3f32).log2().is_nan());
+        assert_eq!((-0.0f32).log2(), neg_inf);
+        assert_eq!(0.0f32.log2(), neg_inf);
+    }
+
+    #[test]
+    fn test_log10() {
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(10.0f32.log10(), 1.0);
+        assert_approx_eq!(2.3f32.log10(), 0.361728);
+        assert_approx_eq!(1.0f32.exp().log10(), 0.434294);
+        assert_eq!(1.0f32.log10(), 0.0);
+        assert!(nan.log10().is_nan());
+        assert_eq!(inf.log10(), inf);
+        assert!(neg_inf.log10().is_nan());
+        assert!((-2.3f32).log10().is_nan());
+        assert_eq!((-0.0f32).log10(), neg_inf);
+        assert_eq!(0.0f32.log10(), neg_inf);
+    }
+
+    #[test]
+    fn test_to_degrees() {
+        let pi: f32 = consts::PI;
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(0.0f32.to_degrees(), 0.0);
+        assert_approx_eq!((-5.8f32).to_degrees(), -332.315521);
+        assert_eq!(pi.to_degrees(), 180.0);
+        assert!(nan.to_degrees().is_nan());
+        assert_eq!(inf.to_degrees(), inf);
+        assert_eq!(neg_inf.to_degrees(), neg_inf);
+    }
+
+    #[test]
+    fn test_to_radians() {
+        let pi: f32 = consts::PI;
+        let nan: f32 = Float::nan();
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        assert_eq!(0.0f32.to_radians(), 0.0);
+        assert_approx_eq!(154.6f32.to_radians(), 2.698279);
+        assert_approx_eq!((-332.31f32).to_radians(), -5.799903);
+        assert_eq!(180.0f32.to_radians(), pi);
+        assert!(nan.to_radians().is_nan());
+        assert_eq!(inf.to_radians(), inf);
+        assert_eq!(neg_inf.to_radians(), neg_inf);
+    }
+
+    #[test]
+    fn test_ldexp() {
+        // We have to use from_str until base-2 exponents
+        // are supported in floating-point literals
+        let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
+        let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
+        let f3: f32 = FromStrRadix::from_str_radix("1.Cp-12", 16).unwrap();
+        assert_eq!(1f32.ldexp(-123), f1);
+        assert_eq!(1f32.ldexp(-111), f2);
+        assert_eq!(Float::ldexp(1.75f32, -12), f3);
+
+        assert_eq!(Float::ldexp(0f32, -123), 0f32);
+        assert_eq!(Float::ldexp(-0f32, -123), -0f32);
+
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = Float::nan();
+        assert_eq!(Float::ldexp(inf, -123), inf);
+        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
+        assert!(Float::ldexp(nan, -123).is_nan());
+    }
+
+    #[test]
+    fn test_frexp() {
+        // We have to use from_str until base-2 exponents
+        // are supported in floating-point literals
+        let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
+        let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
+        let f3: f32 = FromStrRadix::from_str_radix("1.Cp-123", 16).unwrap();
+        let (x1, exp1) = f1.frexp();
+        let (x2, exp2) = f2.frexp();
+        let (x3, exp3) = f3.frexp();
+        assert_eq!((x1, exp1), (0.5f32, -122));
+        assert_eq!((x2, exp2), (0.5f32, -110));
+        assert_eq!((x3, exp3), (0.875f32, -122));
+        assert_eq!(Float::ldexp(x1, exp1), f1);
+        assert_eq!(Float::ldexp(x2, exp2), f2);
+        assert_eq!(Float::ldexp(x3, exp3), f3);
+
+        assert_eq!(0f32.frexp(), (0f32, 0));
+        assert_eq!((-0f32).frexp(), (-0f32, 0));
+    }
+
+    #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
+    fn test_frexp_nowin() {
+        let inf: f32 = Float::infinity();
+        let neg_inf: f32 = Float::neg_infinity();
+        let nan: f32 = Float::nan();
+        assert_eq!(match inf.frexp() { (x, _) => x }, inf);
+        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
+        assert!(match nan.frexp() { (x, _) => x.is_nan() })
+    }
+
+    #[test]
+    fn test_abs_sub() {
+        assert_eq!((-1f32).abs_sub(1f32), 0f32);
+        assert_eq!(1f32.abs_sub(1f32), 0f32);
+        assert_eq!(1f32.abs_sub(0f32), 1f32);
+        assert_eq!(1f32.abs_sub(-1f32), 2f32);
+        assert_eq!(NEG_INFINITY.abs_sub(0f32), 0f32);
+        assert_eq!(INFINITY.abs_sub(1f32), INFINITY);
+        assert_eq!(0f32.abs_sub(NEG_INFINITY), INFINITY);
+        assert_eq!(0f32.abs_sub(INFINITY), 0f32);
+    }
+
+    #[test]
+    fn test_abs_sub_nowin() {
+        assert!(NAN.abs_sub(-1f32).is_nan());
+        assert!(1f32.abs_sub(NAN).is_nan());
+    }
+
     #[test]
     fn test_asinh() {
         assert_eq!(0.0f32.asinh(), 0.0f32);
@@ -674,174 +2148,4 @@ mod tests {
         assert_approx_eq!(ln_2, 2f32.ln());
         assert_approx_eq!(ln_10, 10f32.ln());
     }
-
-    #[test]
-    pub fn test_abs() {
-        assert_eq!(INFINITY.abs(), INFINITY);
-        assert_eq!(1f32.abs(), 1f32);
-        assert_eq!(0f32.abs(), 0f32);
-        assert_eq!((-0f32).abs(), 0f32);
-        assert_eq!((-1f32).abs(), 1f32);
-        assert_eq!(NEG_INFINITY.abs(), INFINITY);
-        assert_eq!((1f32/NEG_INFINITY).abs(), 0f32);
-        assert!(NAN.abs().is_nan());
-    }
-
-    #[test]
-    fn test_abs_sub() {
-        assert_eq!((-1f32).abs_sub(1f32), 0f32);
-        assert_eq!(1f32.abs_sub(1f32), 0f32);
-        assert_eq!(1f32.abs_sub(0f32), 1f32);
-        assert_eq!(1f32.abs_sub(-1f32), 2f32);
-        assert_eq!(NEG_INFINITY.abs_sub(0f32), 0f32);
-        assert_eq!(INFINITY.abs_sub(1f32), INFINITY);
-        assert_eq!(0f32.abs_sub(NEG_INFINITY), INFINITY);
-        assert_eq!(0f32.abs_sub(INFINITY), 0f32);
-    }
-
-    #[test]
-    fn test_abs_sub_nowin() {
-        assert!(NAN.abs_sub(-1f32).is_nan());
-        assert!(1f32.abs_sub(NAN).is_nan());
-    }
-
-    #[test]
-    fn test_signum() {
-        assert_eq!(INFINITY.signum(), 1f32);
-        assert_eq!(1f32.signum(), 1f32);
-        assert_eq!(0f32.signum(), 1f32);
-        assert_eq!((-0f32).signum(), -1f32);
-        assert_eq!((-1f32).signum(), -1f32);
-        assert_eq!(NEG_INFINITY.signum(), -1f32);
-        assert_eq!((1f32/NEG_INFINITY).signum(), -1f32);
-        assert!(NAN.signum().is_nan());
-    }
-
-    #[test]
-    fn test_is_positive() {
-        assert!(INFINITY.is_positive());
-        assert!(1f32.is_positive());
-        assert!(0f32.is_positive());
-        assert!(!(-0f32).is_positive());
-        assert!(!(-1f32).is_positive());
-        assert!(!NEG_INFINITY.is_positive());
-        assert!(!(1f32/NEG_INFINITY).is_positive());
-        assert!(!NAN.is_positive());
-    }
-
-    #[test]
-    fn test_is_negative() {
-        assert!(!INFINITY.is_negative());
-        assert!(!1f32.is_negative());
-        assert!(!0f32.is_negative());
-        assert!((-0f32).is_negative());
-        assert!((-1f32).is_negative());
-        assert!(NEG_INFINITY.is_negative());
-        assert!((1f32/NEG_INFINITY).is_negative());
-        assert!(!NAN.is_negative());
-    }
-
-    #[test]
-    fn test_is_normal() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let zero: f32 = Float::zero();
-        let neg_zero: f32 = Float::neg_zero();
-        assert!(!nan.is_normal());
-        assert!(!inf.is_normal());
-        assert!(!neg_inf.is_normal());
-        assert!(!zero.is_normal());
-        assert!(!neg_zero.is_normal());
-        assert!(1f32.is_normal());
-        assert!(1e-37f32.is_normal());
-        assert!(!1e-38f32.is_normal());
-    }
-
-    #[test]
-    fn test_classify() {
-        let nan: f32 = Float::nan();
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let zero: f32 = Float::zero();
-        let neg_zero: f32 = Float::neg_zero();
-        assert_eq!(nan.classify(), Fp::Nan);
-        assert_eq!(inf.classify(), Fp::Infinite);
-        assert_eq!(neg_inf.classify(), Fp::Infinite);
-        assert_eq!(zero.classify(), Fp::Zero);
-        assert_eq!(neg_zero.classify(), Fp::Zero);
-        assert_eq!(1f32.classify(), Fp::Normal);
-        assert_eq!(1e-37f32.classify(), Fp::Normal);
-        assert_eq!(1e-38f32.classify(), Fp::Subnormal);
-    }
-
-    #[test]
-    fn test_ldexp() {
-        // We have to use from_str until base-2 exponents
-        // are supported in floating-point literals
-        let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
-        let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
-        assert_eq!(Float::ldexp(1f32, -123), f1);
-        assert_eq!(Float::ldexp(1f32, -111), f2);
-
-        assert_eq!(Float::ldexp(0f32, -123), 0f32);
-        assert_eq!(Float::ldexp(-0f32, -123), -0f32);
-
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let nan: f32 = Float::nan();
-        assert_eq!(Float::ldexp(inf, -123), inf);
-        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
-        assert!(Float::ldexp(nan, -123).is_nan());
-    }
-
-    #[test]
-    fn test_frexp() {
-        // We have to use from_str until base-2 exponents
-        // are supported in floating-point literals
-        let f1: f32 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
-        let f2: f32 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
-        let (x1, exp1) = f1.frexp();
-        let (x2, exp2) = f2.frexp();
-        assert_eq!((x1, exp1), (0.5f32, -122));
-        assert_eq!((x2, exp2), (0.5f32, -110));
-        assert_eq!(Float::ldexp(x1, exp1), f1);
-        assert_eq!(Float::ldexp(x2, exp2), f2);
-
-        assert_eq!(0f32.frexp(), (0f32, 0));
-        assert_eq!((-0f32).frexp(), (-0f32, 0));
-    }
-
-    #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
-    fn test_frexp_nowin() {
-        let inf: f32 = Float::infinity();
-        let neg_inf: f32 = Float::neg_infinity();
-        let nan: f32 = Float::nan();
-        assert_eq!(match inf.frexp() { (x, _) => x }, inf);
-        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
-        assert!(match nan.frexp() { (x, _) => x.is_nan() })
-    }
-
-    #[test]
-    fn test_integer_decode() {
-        assert_eq!(3.14159265359f32.integer_decode(), (13176795u64, -22i16, 1i8));
-        assert_eq!((-8573.5918555f32).integer_decode(), (8779358u64, -10i16, -1i8));
-        assert_eq!(2f32.powf(100.0).integer_decode(), (8388608u64, 77i16, 1i8));
-        assert_eq!(0f32.integer_decode(), (0u64, -150i16, 1i8));
-        assert_eq!((-0f32).integer_decode(), (0u64, -150i16, -1i8));
-        assert_eq!(INFINITY.integer_decode(), (8388608u64, 105i16, 1i8));
-        assert_eq!(NEG_INFINITY.integer_decode(), (8388608u64, 105i16, -1i8));
-        assert_eq!(NAN.integer_decode(), (12582912u64, 105i16, 1i8));
-    }
-
-    #[test]
-    fn test_sqrt_domain() {
-        assert!(NAN.sqrt().is_nan());
-        assert!(NEG_INFINITY.sqrt().is_nan());
-        assert!((-1.0f32).sqrt().is_nan());
-        assert_eq!((-0.0f32).sqrt(), -0.0);
-        assert_eq!(0.0f32.sqrt(), 0.0);
-        assert_eq!(1.0f32.sqrt(), 1.0);
-        assert_eq!(INFINITY.sqrt(), INFINITY);
-    }
 }
index 0ce56371c77e544733a9dfc3a72a4ca2809b1e79..794853f6f709863f4237391e0bd6f22211ec2212 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -83,6 +83,7 @@ mod cmath {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
 impl Float for f64 {
     // inlined methods from `num::Float`
     #[inline]
@@ -101,27 +102,27 @@ impl Float for f64 {
 
     #[allow(deprecated)]
     #[inline]
-    fn mantissa_digits(unused_self: Option<f64>) -> uint {
+    fn mantissa_digits(unused_self: Option<f64>) -> usize {
         num::Float::mantissa_digits(unused_self)
     }
     #[allow(deprecated)]
     #[inline]
-    fn digits(unused_self: Option<f64>) -> uint { num::Float::digits(unused_self) }
+    fn digits(unused_self: Option<f64>) -> usize { num::Float::digits(unused_self) }
     #[allow(deprecated)]
     #[inline]
     fn epsilon() -> f64 { num::Float::epsilon() }
     #[allow(deprecated)]
     #[inline]
-    fn min_exp(unused_self: Option<f64>) -> int { num::Float::min_exp(unused_self) }
+    fn min_exp(unused_self: Option<f64>) -> isize { num::Float::min_exp(unused_self) }
     #[allow(deprecated)]
     #[inline]
-    fn max_exp(unused_self: Option<f64>) -> int { num::Float::max_exp(unused_self) }
+    fn max_exp(unused_self: Option<f64>) -> isize { num::Float::max_exp(unused_self) }
     #[allow(deprecated)]
     #[inline]
-    fn min_10_exp(unused_self: Option<f64>) -> int { num::Float::min_10_exp(unused_self) }
+    fn min_10_exp(unused_self: Option<f64>) -> isize { num::Float::min_10_exp(unused_self) }
     #[allow(deprecated)]
     #[inline]
-    fn max_10_exp(unused_self: Option<f64>) -> int { num::Float::max_10_exp(unused_self) }
+    fn max_10_exp(unused_self: Option<f64>) -> isize { num::Float::max_10_exp(unused_self) }
     #[allow(deprecated)]
     #[inline]
     fn min_value() -> f64 { num::Float::min_value() }
@@ -200,8 +201,8 @@ impl Float for f64 {
     fn to_radians(self) -> f64 { num::Float::to_radians(self) }
 
     #[inline]
-    fn ldexp(x: f64, exp: int) -> f64 {
-        unsafe { cmath::ldexp(x, exp as c_int) }
+    fn ldexp(self, exp: isize) -> f64 {
+        unsafe { cmath::ldexp(self, exp as c_int) }
     }
 
     /// Breaks the number into a normalized fraction and a base-2 exponent,
@@ -210,11 +211,11 @@ impl Float for f64 {
     /// - `self = x * pow(2, exp)`
     /// - `0.5 <= abs(x) < 1.0`
     #[inline]
-    fn frexp(self) -> (f64, int) {
+    fn frexp(self) -> (f64, isize) {
         unsafe {
             let mut exp = 0;
             let x = cmath::frexp(self, &mut exp);
-            (x, exp as int)
+            (x, exp as isize)
         }
     }
 
@@ -366,211 +367,1468 @@ impl Float for f64 {
     }
 }
 
-//
-// Section: String Conversions
-//
-
-/// Converts a float to a string
-///
-/// # Arguments
-///
-/// * num - The float value
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_string(num: f64) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigAll, ExpNone, false);
-    r
-}
+#[cfg(not(test))]
+#[lang = "f64"]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl f64 {
+    /// Returns `true` if this value is `NaN` and false otherwise.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let nan = f64::NAN;
+    /// let f = 7.0_f64;
+    ///
+    /// assert!(nan.is_nan());
+    /// assert!(!f.is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_nan(self) -> bool { num::Float::is_nan(self) }
 
-/// Converts a float to a string in hexadecimal format
-///
-/// # Arguments
-///
-/// * num - The float value
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_hex(num: f64) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 16, true, SignNeg, DigAll, ExpNone, false);
-    r
-}
+    /// Returns `true` if this value is positive infinity or negative infinity and
+    /// false otherwise.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let f = 7.0f64;
+    /// let inf = f64::INFINITY;
+    /// let neg_inf = f64::NEG_INFINITY;
+    /// let nan = f64::NAN;
+    ///
+    /// assert!(!f.is_infinite());
+    /// assert!(!nan.is_infinite());
+    ///
+    /// assert!(inf.is_infinite());
+    /// assert!(neg_inf.is_infinite());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_infinite(self) -> bool { num::Float::is_infinite(self) }
 
-/// Converts a float to a string in a given radix, and a flag indicating
-/// whether it's a special value
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * radix - The base to use
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_radix_special(num: f64, rdx: u32) -> (String, bool) {
-    strconv::float_to_str_common(num, rdx, true, SignNeg, DigAll, ExpNone, false)
-}
+    /// Returns `true` if this number is neither infinite nor `NaN`.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let f = 7.0f64;
+    /// let inf: f64 = f64::INFINITY;
+    /// let neg_inf: f64 = f64::NEG_INFINITY;
+    /// let nan: f64 = f64::NAN;
+    ///
+    /// assert!(f.is_finite());
+    ///
+    /// assert!(!nan.is_finite());
+    /// assert!(!inf.is_finite());
+    /// assert!(!neg_inf.is_finite());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_finite(self) -> bool { num::Float::is_finite(self) }
 
-/// Converts a float to a string with exactly the number of
-/// provided significant digits
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of significant digits
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_exact(num: f64, dig: uint) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigExact(dig), ExpNone, false);
-    r
-}
+    /// Returns `true` if the number is neither zero, infinite,
+    /// [subnormal][subnormal], or `NaN`.
+    ///
+    /// ```
+    /// use std::f32;
+    ///
+    /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f64
+    /// let max = f32::MAX;
+    /// let lower_than_min = 1.0e-40_f32;
+    /// let zero = 0.0f32;
+    ///
+    /// assert!(min.is_normal());
+    /// assert!(max.is_normal());
+    ///
+    /// assert!(!zero.is_normal());
+    /// assert!(!f32::NAN.is_normal());
+    /// assert!(!f32::INFINITY.is_normal());
+    /// // Values between `0` and `min` are Subnormal.
+    /// assert!(!lower_than_min.is_normal());
+    /// ```
+    /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_normal(self) -> bool { num::Float::is_normal(self) }
+
+    /// Returns the floating point category of the number. If only one property
+    /// is going to be tested, it is generally faster to use the specific
+    /// predicate instead.
+    ///
+    /// ```
+    /// use std::num::FpCategory;
+    /// use std::f64;
+    ///
+    /// let num = 12.4_f64;
+    /// let inf = f64::INFINITY;
+    ///
+    /// assert_eq!(num.classify(), FpCategory::Normal);
+    /// assert_eq!(inf.classify(), FpCategory::Infinite);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn classify(self) -> FpCategory { num::Float::classify(self) }
 
-/// Converts a float to a string with a maximum number of
-/// significant digits
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of significant digits
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_digits(num: f64, dig: uint) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigMax(dig), ExpNone, false);
-    r
-}
+    /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
+    /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
+    /// The floating point encoding is documented in the [Reference][floating-point].
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// let num = 2.0f64;
+    ///
+    /// // (8388608, -22, 1)
+    /// let (mantissa, exponent, sign) = num.integer_decode();
+    /// let sign_f = sign as f64;
+    /// let mantissa_f = mantissa as f64;
+    /// let exponent_f = num.powf(exponent as f64);
+    ///
+    /// // 1 * 8388608 * 2^(-22) == 2
+    /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    /// [floating-point]: ../../../../../reference.html#machine-types
+    #[unstable(feature = "std_misc", reason = "signature is undecided")]
+    #[inline]
+    pub fn integer_decode(self) -> (u64, i16, i8) { num::Float::integer_decode(self) }
 
-/// Converts a float to a string using the exponential notation with exactly the number of
-/// provided digits after the decimal point in the significand
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of digits after the decimal point
-/// * upper - Use `E` instead of `e` for the exponent sign
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_exp_exact(num: f64, dig: uint, upper: bool) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigExact(dig), ExpDec, upper);
-    r
-}
+    /// Returns the largest integer less than or equal to a number.
+    ///
+    /// ```
+    /// let f = 3.99_f64;
+    /// let g = 3.0_f64;
+    ///
+    /// assert_eq!(f.floor(), 3.0);
+    /// assert_eq!(g.floor(), 3.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn floor(self) -> f64 { num::Float::floor(self) }
 
-/// Converts a float to a string using the exponential notation with the maximum number of
-/// digits after the decimal point in the significand
-///
-/// # Arguments
-///
-/// * num - The float value
-/// * digits - The number of digits after the decimal point
-/// * upper - Use `E` instead of `e` for the exponent sign
-#[inline]
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
-pub fn to_str_exp_digits(num: f64, dig: uint, upper: bool) -> String {
-    let (r, _) = strconv::float_to_str_common(
-        num, 10, true, SignNeg, DigMax(dig), ExpDec, upper);
-    r
-}
+    /// Returns the smallest integer greater than or equal to a number.
+    ///
+    /// ```
+    /// let f = 3.01_f64;
+    /// let g = 4.0_f64;
+    ///
+    /// assert_eq!(f.ceil(), 4.0);
+    /// assert_eq!(g.ceil(), 4.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn ceil(self) -> f64 { num::Float::ceil(self) }
 
-#[cfg(test)]
-mod tests {
-    use f64::*;
-    use num::*;
-    use num::FpCategory as Fp;
+    /// Returns the nearest integer to a number. Round half-way cases away from
+    /// `0.0`.
+    ///
+    /// ```
+    /// let f = 3.3_f64;
+    /// let g = -3.3_f64;
+    ///
+    /// assert_eq!(f.round(), 3.0);
+    /// assert_eq!(g.round(), -3.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn round(self) -> f64 { num::Float::round(self) }
 
-    #[test]
-    fn test_min_nan() {
-        assert_eq!(NAN.min(2.0), 2.0);
-        assert_eq!(2.0f64.min(NAN), 2.0);
-    }
+    /// Return the integer part of a number.
+    ///
+    /// ```
+    /// let f = 3.3_f64;
+    /// let g = -3.7_f64;
+    ///
+    /// assert_eq!(f.trunc(), 3.0);
+    /// assert_eq!(g.trunc(), -3.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn trunc(self) -> f64 { num::Float::trunc(self) }
 
-    #[test]
-    fn test_max_nan() {
-        assert_eq!(NAN.max(2.0), 2.0);
-        assert_eq!(2.0f64.max(NAN), 2.0);
-    }
+    /// Returns the fractional part of a number.
+    ///
+    /// ```
+    /// let x = 3.5_f64;
+    /// let y = -3.5_f64;
+    /// let abs_difference_x = (x.fract() - 0.5).abs();
+    /// let abs_difference_y = (y.fract() - (-0.5)).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn fract(self) -> f64 { num::Float::fract(self) }
 
-    #[test]
-    fn test_num_f64() {
-        test_num(10f64, 2f64);
-    }
+    /// Computes the absolute value of `self`. Returns `NAN` if the
+    /// number is `NAN`.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let x = 3.5_f64;
+    /// let y = -3.5_f64;
+    ///
+    /// let abs_difference_x = (x.abs() - x).abs();
+    /// let abs_difference_y = (y.abs() - (-y)).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    ///
+    /// assert!(f64::NAN.abs().is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn abs(self) -> f64 { num::Float::abs(self) }
 
-    #[test]
-    fn test_floor() {
-        assert_approx_eq!(1.0f64.floor(), 1.0f64);
-        assert_approx_eq!(1.3f64.floor(), 1.0f64);
-        assert_approx_eq!(1.5f64.floor(), 1.0f64);
-        assert_approx_eq!(1.7f64.floor(), 1.0f64);
-        assert_approx_eq!(0.0f64.floor(), 0.0f64);
-        assert_approx_eq!((-0.0f64).floor(), -0.0f64);
-        assert_approx_eq!((-1.0f64).floor(), -1.0f64);
-        assert_approx_eq!((-1.3f64).floor(), -2.0f64);
-        assert_approx_eq!((-1.5f64).floor(), -2.0f64);
-        assert_approx_eq!((-1.7f64).floor(), -2.0f64);
-    }
+    /// Returns a number that represents the sign of `self`.
+    ///
+    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
+    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
+    /// - `NAN` if the number is `NAN`
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let f = 3.5_f64;
+    ///
+    /// assert_eq!(f.signum(), 1.0);
+    /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
+    ///
+    /// assert!(f64::NAN.signum().is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn signum(self) -> f64 { num::Float::signum(self) }
 
-    #[test]
-    fn test_ceil() {
-        assert_approx_eq!(1.0f64.ceil(), 1.0f64);
-        assert_approx_eq!(1.3f64.ceil(), 2.0f64);
-        assert_approx_eq!(1.5f64.ceil(), 2.0f64);
-        assert_approx_eq!(1.7f64.ceil(), 2.0f64);
-        assert_approx_eq!(0.0f64.ceil(), 0.0f64);
-        assert_approx_eq!((-0.0f64).ceil(), -0.0f64);
-        assert_approx_eq!((-1.0f64).ceil(), -1.0f64);
-        assert_approx_eq!((-1.3f64).ceil(), -1.0f64);
-        assert_approx_eq!((-1.5f64).ceil(), -1.0f64);
-        assert_approx_eq!((-1.7f64).ceil(), -1.0f64);
-    }
+    /// Returns `true` if `self`'s sign bit is positive, including
+    /// `+0.0` and `INFINITY`.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let nan: f64 = f64::NAN;
+    ///
+    /// let f = 7.0_f64;
+    /// let g = -7.0_f64;
+    ///
+    /// assert!(f.is_sign_positive());
+    /// assert!(!g.is_sign_positive());
+    /// // Requires both tests to determine if is `NaN`
+    /// assert!(!nan.is_sign_positive() && !nan.is_sign_negative());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_sign_positive(self) -> bool { num::Float::is_positive(self) }
 
-    #[test]
-    fn test_round() {
-        assert_approx_eq!(1.0f64.round(), 1.0f64);
-        assert_approx_eq!(1.3f64.round(), 1.0f64);
-        assert_approx_eq!(1.5f64.round(), 2.0f64);
-        assert_approx_eq!(1.7f64.round(), 2.0f64);
-        assert_approx_eq!(0.0f64.round(), 0.0f64);
-        assert_approx_eq!((-0.0f64).round(), -0.0f64);
-        assert_approx_eq!((-1.0f64).round(), -1.0f64);
-        assert_approx_eq!((-1.3f64).round(), -1.0f64);
-        assert_approx_eq!((-1.5f64).round(), -2.0f64);
-        assert_approx_eq!((-1.7f64).round(), -2.0f64);
-    }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[deprecated(since = "1.0.0", reason = "renamed to is_sign_positive")]
+    #[inline]
+    pub fn is_positive(self) -> bool { num::Float::is_positive(self) }
 
-    #[test]
-    fn test_trunc() {
-        assert_approx_eq!(1.0f64.trunc(), 1.0f64);
-        assert_approx_eq!(1.3f64.trunc(), 1.0f64);
-        assert_approx_eq!(1.5f64.trunc(), 1.0f64);
-        assert_approx_eq!(1.7f64.trunc(), 1.0f64);
-        assert_approx_eq!(0.0f64.trunc(), 0.0f64);
-        assert_approx_eq!((-0.0f64).trunc(), -0.0f64);
-        assert_approx_eq!((-1.0f64).trunc(), -1.0f64);
-        assert_approx_eq!((-1.3f64).trunc(), -1.0f64);
-        assert_approx_eq!((-1.5f64).trunc(), -1.0f64);
-        assert_approx_eq!((-1.7f64).trunc(), -1.0f64);
-    }
+    /// Returns `true` if `self`'s sign is negative, including `-0.0`
+    /// and `NEG_INFINITY`.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let nan = f64::NAN;
+    ///
+    /// let f = 7.0_f64;
+    /// let g = -7.0_f64;
+    ///
+    /// assert!(!f.is_sign_negative());
+    /// assert!(g.is_sign_negative());
+    /// // Requires both tests to determine if is `NaN`.
+    /// assert!(!nan.is_sign_positive() && !nan.is_sign_negative());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_sign_negative(self) -> bool { num::Float::is_negative(self) }
 
-    #[test]
-    fn test_fract() {
-        assert_approx_eq!(1.0f64.fract(), 0.0f64);
-        assert_approx_eq!(1.3f64.fract(), 0.3f64);
-        assert_approx_eq!(1.5f64.fract(), 0.5f64);
-        assert_approx_eq!(1.7f64.fract(), 0.7f64);
-        assert_approx_eq!(0.0f64.fract(), 0.0f64);
-        assert_approx_eq!((-0.0f64).fract(), -0.0f64);
-        assert_approx_eq!((-1.0f64).fract(), -0.0f64);
-        assert_approx_eq!((-1.3f64).fract(), -0.3f64);
-        assert_approx_eq!((-1.5f64).fract(), -0.5f64);
-        assert_approx_eq!((-1.7f64).fract(), -0.7f64);
-    }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[deprecated(since = "1.0.0", reason = "renamed to is_sign_negative")]
+    #[inline]
+    pub fn is_negative(self) -> bool { num::Float::is_negative(self) }
 
-    #[test]
-    fn test_exp() {
-        assert_eq!(1.0, 0.0f64.exp());
-        assert_approx_eq!(2.718282, 1.0f64.exp());
-        assert_approx_eq!(148.413159, 5.0f64.exp());
+    /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
+    /// error. This produces a more accurate result with better performance than
+    /// a separate multiplication operation followed by an add.
+    ///
+    /// ```
+    /// let m = 10.0_f64;
+    /// let x = 4.0_f64;
+    /// let b = 60.0_f64;
+    ///
+    /// // 100.0
+    /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn mul_add(self, a: f64, b: f64) -> f64 { num::Float::mul_add(self, a, b) }
 
-        let inf: f64 = Float::infinity();
+    /// Take the reciprocal (inverse) of a number, `1/x`.
+    ///
+    /// ```
+    /// let x = 2.0_f64;
+    /// let abs_difference = (x.recip() - (1.0/x)).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn recip(self) -> f64 { num::Float::recip(self) }
+
+    /// Raise a number to an integer power.
+    ///
+    /// Using this function is generally faster than using `powf`
+    ///
+    /// ```
+    /// let x = 2.0_f64;
+    /// let abs_difference = (x.powi(2) - x*x).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn powi(self, n: i32) -> f64 { num::Float::powi(self, n) }
+
+    /// Raise a number to a floating point power.
+    ///
+    /// ```
+    /// let x = 2.0_f64;
+    /// let abs_difference = (x.powf(2.0) - x*x).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn powf(self, n: f64) -> f64 { num::Float::powf(self, n) }
+
+    /// Take the square root of a number.
+    ///
+    /// Returns NaN if `self` is a negative number.
+    ///
+    /// ```
+    /// let positive = 4.0_f64;
+    /// let negative = -4.0_f64;
+    ///
+    /// let abs_difference = (positive.sqrt() - 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// assert!(negative.sqrt().is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sqrt(self) -> f64 { num::Float::sqrt(self) }
+
+    /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// let f = 4.0_f64;
+    ///
+    /// let abs_difference = (f.rsqrt() - 0.5).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[deprecated(since = "1.0.0", reason = "use self.sqrt().recip() instead")]
+    #[inline]
+    pub fn rsqrt(self) -> f64 { num::Float::rsqrt(self) }
+
+    /// Returns `e^(self)`, (the exponential function).
+    ///
+    /// ```
+    /// let one = 1.0_f64;
+    /// // e^1
+    /// let e = one.exp();
+    ///
+    /// // ln(e) - 1 == 0
+    /// let abs_difference = (e.ln() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn exp(self) -> f64 { num::Float::exp(self) }
+
+    /// Returns `2^(self)`.
+    ///
+    /// ```
+    /// let f = 2.0_f64;
+    ///
+    /// // 2^2 - 4 == 0
+    /// let abs_difference = (f.exp2() - 4.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn exp2(self) -> f64 { num::Float::exp2(self) }
+
+    /// Returns the natural logarithm of the number.
+    ///
+    /// ```
+    /// let one = 1.0_f64;
+    /// // e^1
+    /// let e = one.exp();
+    ///
+    /// // ln(e) - 1 == 0
+    /// let abs_difference = (e.ln() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn ln(self) -> f64 { num::Float::ln(self) }
+
+    /// Returns the logarithm of the number with respect to an arbitrary base.
+    ///
+    /// ```
+    /// let ten = 10.0_f64;
+    /// let two = 2.0_f64;
+    ///
+    /// // log10(10) - 1 == 0
+    /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs();
+    ///
+    /// // log2(2) - 1 == 0
+    /// let abs_difference_2 = (two.log(2.0) - 1.0).abs();
+    ///
+    /// assert!(abs_difference_10 < 1e-10);
+    /// assert!(abs_difference_2 < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn log(self, base: f64) -> f64 { num::Float::log(self, base) }
+
+    /// Returns the base 2 logarithm of the number.
+    ///
+    /// ```
+    /// let two = 2.0_f64;
+    ///
+    /// // log2(2) - 1 == 0
+    /// let abs_difference = (two.log2() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn log2(self) -> f64 { num::Float::log2(self) }
+
+    /// Returns the base 10 logarithm of the number.
+    ///
+    /// ```
+    /// let ten = 10.0_f64;
+    ///
+    /// // log10(10) - 1 == 0
+    /// let abs_difference = (ten.log10() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn log10(self) -> f64 { num::Float::log10(self) }
+
+    /// Convert radians to degrees.
+    ///
+    /// ```
+    /// use std::f64::consts;
+    ///
+    /// let angle = consts::PI;
+    ///
+    /// let abs_difference = (angle.to_degrees() - 180.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn to_degrees(self) -> f64 { num::Float::to_degrees(self) }
+
+    /// Convert degrees to radians.
+    ///
+    /// ```
+    /// use std::f64::consts;
+    ///
+    /// let angle = 180.0_f64;
+    ///
+    /// let abs_difference = (angle.to_radians() - consts::PI).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn to_radians(self) -> f64 { num::Float::to_radians(self) }
+
+    /// Constructs a floating point number of `x*2^exp`.
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// // 3*2^2 - 12 == 0
+    /// let abs_difference = (f64::ldexp(3.0, 2) - 12.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "pending integer conventions")]
+    #[inline]
+    pub fn ldexp(x: f64, exp: isize) -> f64 {
+        unsafe { cmath::ldexp(x, exp as c_int) }
+    }
+
+    /// Breaks the number into a normalized fraction and a base-2 exponent,
+    /// satisfying:
+    ///
+    ///  * `self = x * 2^exp`
+    ///  * `0.5 <= abs(x) < 1.0`
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    /// let x = 4.0_f64;
+    ///
+    /// // (1/2)*2^3 -> 1 * 8/2 -> 4.0
+    /// let f = x.frexp();
+    /// let abs_difference_0 = (f.0 - 0.5).abs();
+    /// let abs_difference_1 = (f.1 as f64 - 3.0).abs();
+    ///
+    /// assert!(abs_difference_0 < 1e-10);
+    /// assert!(abs_difference_1 < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "pending integer conventions")]
+    #[inline]
+    pub fn frexp(self) -> (f64, isize) {
+        unsafe {
+            let mut exp = 0;
+            let x = cmath::frexp(self, &mut exp);
+            (x, exp as isize)
+        }
+    }
+
+    /// Returns the next representable floating-point value in the direction of
+    /// `other`.
+    ///
+    /// ```
+    /// # #![feature(std_misc)]
+    ///
+    /// let x = 1.0f32;
+    ///
+    /// let abs_diff = (x.next_after(2.0) - 1.00000011920928955078125_f32).abs();
+    ///
+    /// assert!(abs_diff < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn next_after(self, other: f64) -> f64 {
+        unsafe { cmath::nextafter(self, other) }
+    }
+
+    /// Returns the maximum of the two numbers.
+    ///
+    /// ```
+    /// let x = 1.0_f64;
+    /// let y = 2.0_f64;
+    ///
+    /// assert_eq!(x.max(y), y);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn max(self, other: f64) -> f64 {
+        unsafe { cmath::fmax(self, other) }
+    }
+
+    /// Returns the minimum of the two numbers.
+    ///
+    /// ```
+    /// let x = 1.0_f64;
+    /// let y = 2.0_f64;
+    ///
+    /// assert_eq!(x.min(y), x);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn min(self, other: f64) -> f64 {
+        unsafe { cmath::fmin(self, other) }
+    }
+
+    /// The positive difference of two numbers.
+    ///
+    /// * If `self <= other`: `0:0`
+    /// * Else: `self - other`
+    ///
+    /// ```
+    /// let x = 3.0_f64;
+    /// let y = -3.0_f64;
+    ///
+    /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs();
+    /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn abs_sub(self, other: f64) -> f64 {
+        unsafe { cmath::fdim(self, other) }
+    }
+
+    /// Take the cubic root of a number.
+    ///
+    /// ```
+    /// let x = 8.0_f64;
+    ///
+    /// // x^(1/3) - 2 == 0
+    /// let abs_difference = (x.cbrt() - 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn cbrt(self) -> f64 {
+        unsafe { cmath::cbrt(self) }
+    }
+
+    /// Calculate the length of the hypotenuse of a right-angle triangle given
+    /// legs of length `x` and `y`.
+    ///
+    /// ```
+    /// let x = 2.0_f64;
+    /// let y = 3.0_f64;
+    ///
+    /// // sqrt(x^2 + y^2)
+    /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn hypot(self, other: f64) -> f64 {
+        unsafe { cmath::hypot(self, other) }
+    }
+
+    /// Computes the sine of a number (in radians).
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/2.0;
+    ///
+    /// let abs_difference = (x.sin() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sin(self) -> f64 {
+        unsafe { intrinsics::sinf64(self) }
+    }
+
+    /// Computes the cosine of a number (in radians).
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let x = 2.0*f64::consts::PI;
+    ///
+    /// let abs_difference = (x.cos() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn cos(self) -> f64 {
+        unsafe { intrinsics::cosf64(self) }
+    }
+
+    /// Computes the tangent of a number (in radians).
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/4.0;
+    /// let abs_difference = (x.tan() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-14);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn tan(self) -> f64 {
+        unsafe { cmath::tan(self) }
+    }
+
+    /// Computes the arcsine of a number. Return value is in radians in
+    /// the range [-pi/2, pi/2] or NaN if the number is outside the range
+    /// [-1, 1].
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let f = f64::consts::PI / 2.0;
+    ///
+    /// // asin(sin(pi/2))
+    /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn asin(self) -> f64 {
+        unsafe { cmath::asin(self) }
+    }
+
+    /// Computes the arccosine of a number. Return value is in radians in
+    /// the range [0, pi] or NaN if the number is outside the range
+    /// [-1, 1].
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let f = f64::consts::PI / 4.0;
+    ///
+    /// // acos(cos(pi/4))
+    /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn acos(self) -> f64 {
+        unsafe { cmath::acos(self) }
+    }
+
+    /// Computes the arctangent of a number. Return value is in radians in the
+    /// range [-pi/2, pi/2];
+    ///
+    /// ```
+    /// let f = 1.0_f64;
+    ///
+    /// // atan(tan(1))
+    /// let abs_difference = (f.tan().atan() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn atan(self) -> f64 {
+        unsafe { cmath::atan(self) }
+    }
+
+    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
+    ///
+    /// * `x = 0`, `y = 0`: `0`
+    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
+    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
+    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let pi = f64::consts::PI;
+    /// // All angles from horizontal right (+x)
+    /// // 45 deg counter-clockwise
+    /// let x1 = 3.0_f64;
+    /// let y1 = -3.0_f64;
+    ///
+    /// // 135 deg clockwise
+    /// let x2 = -3.0_f64;
+    /// let y2 = 3.0_f64;
+    ///
+    /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
+    ///
+    /// assert!(abs_difference_1 < 1e-10);
+    /// assert!(abs_difference_2 < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn atan2(self, other: f64) -> f64 {
+        unsafe { cmath::atan2(self, other) }
+    }
+
+    /// Simultaneously computes the sine and cosine of the number, `x`. Returns
+    /// `(sin(x), cos(x))`.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/4.0;
+    /// let f = x.sin_cos();
+    ///
+    /// let abs_difference_0 = (f.0 - x.sin()).abs();
+    /// let abs_difference_1 = (f.1 - x.cos()).abs();
+    ///
+    /// assert!(abs_difference_0 < 1e-10);
+    /// assert!(abs_difference_0 < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sin_cos(self) -> (f64, f64) {
+        (self.sin(), self.cos())
+    }
+
+    /// Returns `e^(self) - 1` in a way that is accurate even if the
+    /// number is close to zero.
+    ///
+    /// ```
+    /// let x = 7.0_f64;
+    ///
+    /// // e^(ln(7)) - 1
+    /// let abs_difference = (x.ln().exp_m1() - 6.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn exp_m1(self) -> f64 {
+        unsafe { cmath::expm1(self) }
+    }
+
+    /// Returns `ln(1+n)` (natural logarithm) more accurately than if
+    /// the operations were performed separately.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::E - 1.0;
+    ///
+    /// // ln(1 + (e - 1)) == ln(e) == 1
+    /// let abs_difference = (x.ln_1p() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn ln_1p(self) -> f64 {
+        unsafe { cmath::log1p(self) }
+    }
+
+    /// Hyperbolic sine function.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0_f64;
+    ///
+    /// let f = x.sinh();
+    /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
+    /// let g = (e*e - 1.0)/(2.0*e);
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sinh(self) -> f64 {
+        unsafe { cmath::sinh(self) }
+    }
+
+    /// Hyperbolic cosine function.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0_f64;
+    /// let f = x.cosh();
+    /// // Solving cosh() at 1 gives this result
+    /// let g = (e*e + 1.0)/(2.0*e);
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// // Same result
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn cosh(self) -> f64 {
+        unsafe { cmath::cosh(self) }
+    }
+
+    /// Hyperbolic tangent function.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0_f64;
+    ///
+    /// let f = x.tanh();
+    /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
+    /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn tanh(self) -> f64 {
+        unsafe { cmath::tanh(self) }
+    }
+
+    /// Inverse hyperbolic sine function.
+    ///
+    /// ```
+    /// let x = 1.0_f64;
+    /// let f = x.sinh().asinh();
+    ///
+    /// let abs_difference = (f - x).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn asinh(self) -> f64 {
+        match self {
+            NEG_INFINITY => NEG_INFINITY,
+            x => (x + ((x * x) + 1.0).sqrt()).ln(),
+        }
+    }
+
+    /// Inverse hyperbolic cosine function.
+    ///
+    /// ```
+    /// let x = 1.0_f64;
+    /// let f = x.cosh().acosh();
+    ///
+    /// let abs_difference = (f - x).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn acosh(self) -> f64 {
+        match self {
+            x if x < 1.0 => Float::nan(),
+            x => (x + ((x * x) - 1.0).sqrt()).ln(),
+        }
+    }
+
+    /// Inverse hyperbolic tangent function.
+    ///
+    /// ```
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let f = e.tanh().atanh();
+    ///
+    /// let abs_difference = (f - e).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn atanh(self) -> f64 {
+        0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
+    }
+}
+
+//
+// Section: String Conversions
+//
+
+/// Converts a float to a string
+///
+/// # Arguments
+///
+/// * num - The float value
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+#[deprecated(since = "1.0.0", reason = "use the ToString trait instead")]
+pub fn to_string(num: f64) -> String {
+    let (r, _) = strconv::float_to_str_common(
+        num, 10, true, SignNeg, DigAll, ExpNone, false);
+    r
+}
+
+/// Converts a float to a string in hexadecimal format
+///
+/// # Arguments
+///
+/// * num - The float value
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+#[deprecated(since = "1.0.0", reason = "use format! instead")]
+pub fn to_str_hex(num: f64) -> String {
+    let (r, _) = strconv::float_to_str_common(
+        num, 16, true, SignNeg, DigAll, ExpNone, false);
+    r
+}
+
+/// Converts a float to a string in a given radix, and a flag indicating
+/// whether it's a special value
+///
+/// # Arguments
+///
+/// * num - The float value
+/// * radix - The base to use
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+#[deprecated(since = "1.0.0", reason = "use format! instead")]
+pub fn to_str_radix_special(num: f64, rdx: u32) -> (String, bool) {
+    strconv::float_to_str_common(num, rdx, true, SignNeg, DigAll, ExpNone, false)
+}
+
+/// Converts a float to a string with exactly the number of
+/// provided significant digits
+///
+/// # Arguments
+///
+/// * num - The float value
+/// * digits - The number of significant digits
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+pub fn to_str_exact(num: f64, dig: usize) -> String {
+    let (r, _) = strconv::float_to_str_common(
+        num, 10, true, SignNeg, DigExact(dig), ExpNone, false);
+    r
+}
+
+/// Converts a float to a string with a maximum number of
+/// significant digits
+///
+/// # Arguments
+///
+/// * num - The float value
+/// * digits - The number of significant digits
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+pub fn to_str_digits(num: f64, dig: usize) -> String {
+    let (r, _) = strconv::float_to_str_common(
+        num, 10, true, SignNeg, DigMax(dig), ExpNone, false);
+    r
+}
+
+/// Converts a float to a string using the exponential notation with exactly the number of
+/// provided digits after the decimal point in the significand
+///
+/// # Arguments
+///
+/// * num - The float value
+/// * digits - The number of digits after the decimal point
+/// * upper - Use `E` instead of `e` for the exponent sign
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+pub fn to_str_exp_exact(num: f64, dig: usize, upper: bool) -> String {
+    let (r, _) = strconv::float_to_str_common(
+        num, 10, true, SignNeg, DigExact(dig), ExpDec, upper);
+    r
+}
+
+/// Converts a float to a string using the exponential notation with the maximum number of
+/// digits after the decimal point in the significand
+///
+/// # Arguments
+///
+/// * num - The float value
+/// * digits - The number of digits after the decimal point
+/// * upper - Use `E` instead of `e` for the exponent sign
+#[inline]
+#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+pub fn to_str_exp_digits(num: f64, dig: usize, upper: bool) -> String {
+    let (r, _) = strconv::float_to_str_common(
+        num, 10, true, SignNeg, DigMax(dig), ExpDec, upper);
+    r
+}
+
+#[cfg(test)]
+mod tests {
+    use f64::*;
+    use num::*;
+    use num::FpCategory as Fp;
+
+    #[test]
+    fn test_num_f64() {
+        test_num(10f64, 2f64);
+    }
+
+    #[test]
+    fn test_min_nan() {
+        assert_eq!(NAN.min(2.0), 2.0);
+        assert_eq!(2.0f64.min(NAN), 2.0);
+    }
+
+    #[test]
+    fn test_max_nan() {
+        assert_eq!(NAN.max(2.0), 2.0);
+        assert_eq!(2.0f64.max(NAN), 2.0);
+    }
+
+    #[test]
+    fn test_nan() {
+        let nan: f64 = Float::nan();
+        assert!(nan.is_nan());
+        assert!(!nan.is_infinite());
+        assert!(!nan.is_finite());
+        assert!(!nan.is_normal());
+        assert!(!nan.is_sign_positive());
+        assert!(!nan.is_sign_negative());
+        assert_eq!(Fp::Nan, nan.classify());
+    }
+
+    #[test]
+    fn test_infinity() {
+        let inf: f64 = Float::infinity();
+        assert!(inf.is_infinite());
+        assert!(!inf.is_finite());
+        assert!(inf.is_sign_positive());
+        assert!(!inf.is_sign_negative());
+        assert!(!inf.is_nan());
+        assert!(!inf.is_normal());
+        assert_eq!(Fp::Infinite, inf.classify());
+    }
+
+    #[test]
+    fn test_neg_infinity() {
+        let neg_inf: f64 = Float::neg_infinity();
+        assert!(neg_inf.is_infinite());
+        assert!(!neg_inf.is_finite());
+        assert!(!neg_inf.is_sign_positive());
+        assert!(neg_inf.is_sign_negative());
+        assert!(!neg_inf.is_nan());
+        assert!(!neg_inf.is_normal());
+        assert_eq!(Fp::Infinite, neg_inf.classify());
+    }
+
+    #[test]
+    fn test_zero() {
+        let zero: f64 = Float::zero();
+        assert_eq!(0.0, zero);
+        assert!(!zero.is_infinite());
+        assert!(zero.is_finite());
+        assert!(zero.is_sign_positive());
+        assert!(!zero.is_sign_negative());
+        assert!(!zero.is_nan());
+        assert!(!zero.is_normal());
+        assert_eq!(Fp::Zero, zero.classify());
+    }
+
+    #[test]
+    fn test_neg_zero() {
+        let neg_zero: f64 = Float::neg_zero();
+        assert_eq!(0.0, neg_zero);
+        assert!(!neg_zero.is_infinite());
+        assert!(neg_zero.is_finite());
+        assert!(!neg_zero.is_sign_positive());
+        assert!(neg_zero.is_sign_negative());
+        assert!(!neg_zero.is_nan());
+        assert!(!neg_zero.is_normal());
+        assert_eq!(Fp::Zero, neg_zero.classify());
+    }
+
+    #[test]
+    fn test_one() {
+        let one: f64 = Float::one();
+        assert_eq!(1.0, one);
+        assert!(!one.is_infinite());
+        assert!(one.is_finite());
+        assert!(one.is_sign_positive());
+        assert!(!one.is_sign_negative());
+        assert!(!one.is_nan());
+        assert!(one.is_normal());
+        assert_eq!(Fp::Normal, one.classify());
+    }
+
+    #[test]
+    fn test_is_nan() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert!(nan.is_nan());
+        assert!(!0.0f64.is_nan());
+        assert!(!5.3f64.is_nan());
+        assert!(!(-10.732f64).is_nan());
+        assert!(!inf.is_nan());
+        assert!(!neg_inf.is_nan());
+    }
+
+    #[test]
+    fn test_is_infinite() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert!(!nan.is_infinite());
+        assert!(inf.is_infinite());
+        assert!(neg_inf.is_infinite());
+        assert!(!0.0f64.is_infinite());
+        assert!(!42.8f64.is_infinite());
+        assert!(!(-109.2f64).is_infinite());
+    }
+
+    #[test]
+    fn test_is_finite() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert!(!nan.is_finite());
+        assert!(!inf.is_finite());
+        assert!(!neg_inf.is_finite());
+        assert!(0.0f64.is_finite());
+        assert!(42.8f64.is_finite());
+        assert!((-109.2f64).is_finite());
+    }
+
+    #[test]
+    fn test_is_normal() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let zero: f64 = Float::zero();
+        let neg_zero: f64 = Float::neg_zero();
+        assert!(!nan.is_normal());
+        assert!(!inf.is_normal());
+        assert!(!neg_inf.is_normal());
+        assert!(!zero.is_normal());
+        assert!(!neg_zero.is_normal());
+        assert!(1f64.is_normal());
+        assert!(1e-307f64.is_normal());
+        assert!(!1e-308f64.is_normal());
+    }
+
+    #[test]
+    fn test_classify() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let zero: f64 = Float::zero();
+        let neg_zero: f64 = Float::neg_zero();
+        assert_eq!(nan.classify(), Fp::Nan);
+        assert_eq!(inf.classify(), Fp::Infinite);
+        assert_eq!(neg_inf.classify(), Fp::Infinite);
+        assert_eq!(zero.classify(), Fp::Zero);
+        assert_eq!(neg_zero.classify(), Fp::Zero);
+        assert_eq!(1e-307f64.classify(), Fp::Normal);
+        assert_eq!(1e-308f64.classify(), Fp::Subnormal);
+    }
+
+    #[test]
+    fn test_integer_decode() {
+        assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
+        assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
+        assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496, 48, 1));
+        assert_eq!(0f64.integer_decode(), (0, -1075, 1));
+        assert_eq!((-0f64).integer_decode(), (0, -1075, -1));
+        assert_eq!(INFINITY.integer_decode(), (4503599627370496, 972, 1));
+        assert_eq!(NEG_INFINITY.integer_decode(), (4503599627370496, 972, -1));
+        assert_eq!(NAN.integer_decode(), (6755399441055744, 972, 1));
+    }
+
+    #[test]
+    fn test_floor() {
+        assert_approx_eq!(1.0f64.floor(), 1.0f64);
+        assert_approx_eq!(1.3f64.floor(), 1.0f64);
+        assert_approx_eq!(1.5f64.floor(), 1.0f64);
+        assert_approx_eq!(1.7f64.floor(), 1.0f64);
+        assert_approx_eq!(0.0f64.floor(), 0.0f64);
+        assert_approx_eq!((-0.0f64).floor(), -0.0f64);
+        assert_approx_eq!((-1.0f64).floor(), -1.0f64);
+        assert_approx_eq!((-1.3f64).floor(), -2.0f64);
+        assert_approx_eq!((-1.5f64).floor(), -2.0f64);
+        assert_approx_eq!((-1.7f64).floor(), -2.0f64);
+    }
+
+    #[test]
+    fn test_ceil() {
+        assert_approx_eq!(1.0f64.ceil(), 1.0f64);
+        assert_approx_eq!(1.3f64.ceil(), 2.0f64);
+        assert_approx_eq!(1.5f64.ceil(), 2.0f64);
+        assert_approx_eq!(1.7f64.ceil(), 2.0f64);
+        assert_approx_eq!(0.0f64.ceil(), 0.0f64);
+        assert_approx_eq!((-0.0f64).ceil(), -0.0f64);
+        assert_approx_eq!((-1.0f64).ceil(), -1.0f64);
+        assert_approx_eq!((-1.3f64).ceil(), -1.0f64);
+        assert_approx_eq!((-1.5f64).ceil(), -1.0f64);
+        assert_approx_eq!((-1.7f64).ceil(), -1.0f64);
+    }
+
+    #[test]
+    fn test_round() {
+        assert_approx_eq!(1.0f64.round(), 1.0f64);
+        assert_approx_eq!(1.3f64.round(), 1.0f64);
+        assert_approx_eq!(1.5f64.round(), 2.0f64);
+        assert_approx_eq!(1.7f64.round(), 2.0f64);
+        assert_approx_eq!(0.0f64.round(), 0.0f64);
+        assert_approx_eq!((-0.0f64).round(), -0.0f64);
+        assert_approx_eq!((-1.0f64).round(), -1.0f64);
+        assert_approx_eq!((-1.3f64).round(), -1.0f64);
+        assert_approx_eq!((-1.5f64).round(), -2.0f64);
+        assert_approx_eq!((-1.7f64).round(), -2.0f64);
+    }
+
+    #[test]
+    fn test_trunc() {
+        assert_approx_eq!(1.0f64.trunc(), 1.0f64);
+        assert_approx_eq!(1.3f64.trunc(), 1.0f64);
+        assert_approx_eq!(1.5f64.trunc(), 1.0f64);
+        assert_approx_eq!(1.7f64.trunc(), 1.0f64);
+        assert_approx_eq!(0.0f64.trunc(), 0.0f64);
+        assert_approx_eq!((-0.0f64).trunc(), -0.0f64);
+        assert_approx_eq!((-1.0f64).trunc(), -1.0f64);
+        assert_approx_eq!((-1.3f64).trunc(), -1.0f64);
+        assert_approx_eq!((-1.5f64).trunc(), -1.0f64);
+        assert_approx_eq!((-1.7f64).trunc(), -1.0f64);
+    }
+
+    #[test]
+    fn test_fract() {
+        assert_approx_eq!(1.0f64.fract(), 0.0f64);
+        assert_approx_eq!(1.3f64.fract(), 0.3f64);
+        assert_approx_eq!(1.5f64.fract(), 0.5f64);
+        assert_approx_eq!(1.7f64.fract(), 0.7f64);
+        assert_approx_eq!(0.0f64.fract(), 0.0f64);
+        assert_approx_eq!((-0.0f64).fract(), -0.0f64);
+        assert_approx_eq!((-1.0f64).fract(), -0.0f64);
+        assert_approx_eq!((-1.3f64).fract(), -0.3f64);
+        assert_approx_eq!((-1.5f64).fract(), -0.5f64);
+        assert_approx_eq!((-1.7f64).fract(), -0.7f64);
+    }
+
+    #[test]
+    fn test_abs() {
+        assert_eq!(INFINITY.abs(), INFINITY);
+        assert_eq!(1f64.abs(), 1f64);
+        assert_eq!(0f64.abs(), 0f64);
+        assert_eq!((-0f64).abs(), 0f64);
+        assert_eq!((-1f64).abs(), 1f64);
+        assert_eq!(NEG_INFINITY.abs(), INFINITY);
+        assert_eq!((1f64/NEG_INFINITY).abs(), 0f64);
+        assert!(NAN.abs().is_nan());
+    }
+
+    #[test]
+    fn test_signum() {
+        assert_eq!(INFINITY.signum(), 1f64);
+        assert_eq!(1f64.signum(), 1f64);
+        assert_eq!(0f64.signum(), 1f64);
+        assert_eq!((-0f64).signum(), -1f64);
+        assert_eq!((-1f64).signum(), -1f64);
+        assert_eq!(NEG_INFINITY.signum(), -1f64);
+        assert_eq!((1f64/NEG_INFINITY).signum(), -1f64);
+        assert!(NAN.signum().is_nan());
+    }
+
+    #[test]
+    fn test_is_sign_positive() {
+        assert!(INFINITY.is_sign_positive());
+        assert!(1f64.is_sign_positive());
+        assert!(0f64.is_sign_positive());
+        assert!(!(-0f64).is_sign_positive());
+        assert!(!(-1f64).is_sign_positive());
+        assert!(!NEG_INFINITY.is_sign_positive());
+        assert!(!(1f64/NEG_INFINITY).is_sign_positive());
+        assert!(!NAN.is_sign_positive());
+    }
+
+    #[test]
+    fn test_is_sign_negative() {
+        assert!(!INFINITY.is_sign_negative());
+        assert!(!1f64.is_sign_negative());
+        assert!(!0f64.is_sign_negative());
+        assert!((-0f64).is_sign_negative());
+        assert!((-1f64).is_sign_negative());
+        assert!(NEG_INFINITY.is_sign_negative());
+        assert!((1f64/NEG_INFINITY).is_sign_negative());
+        assert!(!NAN.is_sign_negative());
+    }
+
+    #[test]
+    fn test_mul_add() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_approx_eq!(12.3f64.mul_add(4.5, 6.7), 62.05);
+        assert_approx_eq!((-12.3f64).mul_add(-4.5, -6.7), 48.65);
+        assert_approx_eq!(0.0f64.mul_add(8.9, 1.2), 1.2);
+        assert_approx_eq!(3.4f64.mul_add(-0.0, 5.6), 5.6);
+        assert!(nan.mul_add(7.8, 9.0).is_nan());
+        assert_eq!(inf.mul_add(7.8, 9.0), inf);
+        assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
+        assert_eq!(8.9f64.mul_add(inf, 3.2), inf);
+        assert_eq!((-3.2f64).mul_add(2.4, neg_inf), neg_inf);
+    }
+
+    #[test]
+    fn test_recip() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(1.0f64.recip(), 1.0);
+        assert_eq!(2.0f64.recip(), 0.5);
+        assert_eq!((-0.4f64).recip(), -2.5);
+        assert_eq!(0.0f64.recip(), inf);
+        assert!(nan.recip().is_nan());
+        assert_eq!(inf.recip(), 0.0);
+        assert_eq!(neg_inf.recip(), 0.0);
+    }
+
+    #[test]
+    fn test_powi() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(1.0f64.powi(1), 1.0);
+        assert_approx_eq!((-3.1f64).powi(2), 9.61);
+        assert_approx_eq!(5.9f64.powi(-2), 0.028727);
+        assert_eq!(8.3f64.powi(0), 1.0);
+        assert!(nan.powi(2).is_nan());
+        assert_eq!(inf.powi(3), inf);
+        assert_eq!(neg_inf.powi(2), inf);
+    }
+
+    #[test]
+    fn test_powf() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(1.0f64.powf(1.0), 1.0);
+        assert_approx_eq!(3.4f64.powf(4.5), 246.408183);
+        assert_approx_eq!(2.7f64.powf(-3.2), 0.041652);
+        assert_approx_eq!((-3.1f64).powf(2.0), 9.61);
+        assert_approx_eq!(5.9f64.powf(-2.0), 0.028727);
+        assert_eq!(8.3f64.powf(0.0), 1.0);
+        assert!(nan.powf(2.0).is_nan());
+        assert_eq!(inf.powf(2.0), inf);
+        assert_eq!(neg_inf.powf(3.0), neg_inf);
+    }
+
+    #[test]
+    fn test_sqrt_domain() {
+        assert!(NAN.sqrt().is_nan());
+        assert!(NEG_INFINITY.sqrt().is_nan());
+        assert!((-1.0f64).sqrt().is_nan());
+        assert_eq!((-0.0f64).sqrt(), -0.0);
+        assert_eq!(0.0f64.sqrt(), 0.0);
+        assert_eq!(1.0f64.sqrt(), 1.0);
+        assert_eq!(INFINITY.sqrt(), INFINITY);
+    }
+
+    #[test]
+    fn test_rsqrt() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert!(nan.rsqrt().is_nan());
+        assert_eq!(inf.rsqrt(), 0.0);
+        assert!(neg_inf.rsqrt().is_nan());
+        assert!((-1.0f64).rsqrt().is_nan());
+        assert_eq!((-0.0f64).rsqrt(), neg_inf);
+        assert_eq!(0.0f64.rsqrt(), inf);
+        assert_eq!(1.0f64.rsqrt(), 1.0);
+        assert_eq!(4.0f64.rsqrt(), 0.5);
+    }
+
+    #[test]
+    fn test_exp() {
+        assert_eq!(1.0, 0.0f64.exp());
+        assert_approx_eq!(2.718282, 1.0f64.exp());
+        assert_approx_eq!(148.413159, 5.0f64.exp());
+
+        let inf: f64 = Float::infinity();
         let neg_inf: f64 = Float::neg_infinity();
         let nan: f64 = Float::nan();
         assert_eq!(inf, inf.exp());
@@ -591,6 +1849,172 @@ mod tests {
         assert!(nan.exp2().is_nan());
     }
 
+    #[test]
+    fn test_ln() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_approx_eq!(1.0f64.exp().ln(), 1.0);
+        assert!(nan.ln().is_nan());
+        assert_eq!(inf.ln(), inf);
+        assert!(neg_inf.ln().is_nan());
+        assert!((-2.3f64).ln().is_nan());
+        assert_eq!((-0.0f64).ln(), neg_inf);
+        assert_eq!(0.0f64.ln(), neg_inf);
+        assert_approx_eq!(4.0f64.ln(), 1.386294);
+    }
+
+    #[test]
+    fn test_log() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(10.0f64.log(10.0), 1.0);
+        assert_approx_eq!(2.3f64.log(3.5), 0.664858);
+        assert_eq!(1.0f64.exp().log(1.0.exp()), 1.0);
+        assert!(1.0f64.log(1.0).is_nan());
+        assert!(1.0f64.log(-13.9).is_nan());
+        assert!(nan.log(2.3).is_nan());
+        assert_eq!(inf.log(10.0), inf);
+        assert!(neg_inf.log(8.8).is_nan());
+        assert!((-2.3f64).log(0.1).is_nan());
+        assert_eq!((-0.0f64).log(2.0), neg_inf);
+        assert_eq!(0.0f64.log(7.0), neg_inf);
+    }
+
+    #[test]
+    fn test_log2() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_approx_eq!(10.0f64.log2(), 3.321928);
+        assert_approx_eq!(2.3f64.log2(), 1.201634);
+        assert_approx_eq!(1.0f64.exp().log2(), 1.442695);
+        assert!(nan.log2().is_nan());
+        assert_eq!(inf.log2(), inf);
+        assert!(neg_inf.log2().is_nan());
+        assert!((-2.3f64).log2().is_nan());
+        assert_eq!((-0.0f64).log2(), neg_inf);
+        assert_eq!(0.0f64.log2(), neg_inf);
+    }
+
+    #[test]
+    fn test_log10() {
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(10.0f64.log10(), 1.0);
+        assert_approx_eq!(2.3f64.log10(), 0.361728);
+        assert_approx_eq!(1.0f64.exp().log10(), 0.434294);
+        assert_eq!(1.0f64.log10(), 0.0);
+        assert!(nan.log10().is_nan());
+        assert_eq!(inf.log10(), inf);
+        assert!(neg_inf.log10().is_nan());
+        assert!((-2.3f64).log10().is_nan());
+        assert_eq!((-0.0f64).log10(), neg_inf);
+        assert_eq!(0.0f64.log10(), neg_inf);
+    }
+
+    #[test]
+    fn test_to_degrees() {
+        let pi: f64 = consts::PI;
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(0.0f64.to_degrees(), 0.0);
+        assert_approx_eq!((-5.8f64).to_degrees(), -332.315521);
+        assert_eq!(pi.to_degrees(), 180.0);
+        assert!(nan.to_degrees().is_nan());
+        assert_eq!(inf.to_degrees(), inf);
+        assert_eq!(neg_inf.to_degrees(), neg_inf);
+    }
+
+    #[test]
+    fn test_to_radians() {
+        let pi: f64 = consts::PI;
+        let nan: f64 = Float::nan();
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        assert_eq!(0.0f64.to_radians(), 0.0);
+        assert_approx_eq!(154.6f64.to_radians(), 2.698279);
+        assert_approx_eq!((-332.31f64).to_radians(), -5.799903);
+        assert_eq!(180.0f64.to_radians(), pi);
+        assert!(nan.to_radians().is_nan());
+        assert_eq!(inf.to_radians(), inf);
+        assert_eq!(neg_inf.to_radians(), neg_inf);
+    }
+
+    #[test]
+    fn test_ldexp() {
+        // We have to use from_str until base-2 exponents
+        // are supported in floating-point literals
+        let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
+        let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
+        let f3: f64 = FromStrRadix::from_str_radix("1.Cp-12", 16).unwrap();
+        assert_eq!(1f64.ldexp(-123), f1);
+        assert_eq!(1f64.ldexp(-111), f2);
+        assert_eq!(Float::ldexp(1.75f64, -12), f3);
+
+        assert_eq!(Float::ldexp(0f64, -123), 0f64);
+        assert_eq!(Float::ldexp(-0f64, -123), -0f64);
+
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = Float::nan();
+        assert_eq!(Float::ldexp(inf, -123), inf);
+        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
+        assert!(Float::ldexp(nan, -123).is_nan());
+    }
+
+    #[test]
+    fn test_frexp() {
+        // We have to use from_str until base-2 exponents
+        // are supported in floating-point literals
+        let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
+        let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
+        let f3: f64 = FromStrRadix::from_str_radix("1.Cp-123", 16).unwrap();
+        let (x1, exp1) = f1.frexp();
+        let (x2, exp2) = f2.frexp();
+        let (x3, exp3) = f3.frexp();
+        assert_eq!((x1, exp1), (0.5f64, -122));
+        assert_eq!((x2, exp2), (0.5f64, -110));
+        assert_eq!((x3, exp3), (0.875f64, -122));
+        assert_eq!(Float::ldexp(x1, exp1), f1);
+        assert_eq!(Float::ldexp(x2, exp2), f2);
+        assert_eq!(Float::ldexp(x3, exp3), f3);
+
+        assert_eq!(0f64.frexp(), (0f64, 0));
+        assert_eq!((-0f64).frexp(), (-0f64, 0));
+    }
+
+    #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
+    fn test_frexp_nowin() {
+        let inf: f64 = Float::infinity();
+        let neg_inf: f64 = Float::neg_infinity();
+        let nan: f64 = Float::nan();
+        assert_eq!(match inf.frexp() { (x, _) => x }, inf);
+        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
+        assert!(match nan.frexp() { (x, _) => x.is_nan() })
+    }
+
+    #[test]
+    fn test_abs_sub() {
+        assert_eq!((-1f64).abs_sub(1f64), 0f64);
+        assert_eq!(1f64.abs_sub(1f64), 0f64);
+        assert_eq!(1f64.abs_sub(0f64), 1f64);
+        assert_eq!(1f64.abs_sub(-1f64), 2f64);
+        assert_eq!(NEG_INFINITY.abs_sub(0f64), 0f64);
+        assert_eq!(INFINITY.abs_sub(1f64), INFINITY);
+        assert_eq!(0f64.abs_sub(NEG_INFINITY), INFINITY);
+        assert_eq!(0f64.abs_sub(INFINITY), 0f64);
+    }
+
+    #[test]
+    fn test_abs_sub_nowin() {
+        assert!(NAN.abs_sub(-1f64).is_nan());
+        assert!(1f64.abs_sub(NAN).is_nan());
+    }
+
     #[test]
     fn test_asinh() {
         assert_eq!(0.0f64.asinh(), 0.0f64);
@@ -677,173 +2101,4 @@ mod tests {
         assert_approx_eq!(ln_2, 2f64.ln());
         assert_approx_eq!(ln_10, 10f64.ln());
     }
-
-    #[test]
-    pub fn test_abs() {
-        assert_eq!(INFINITY.abs(), INFINITY);
-        assert_eq!(1f64.abs(), 1f64);
-        assert_eq!(0f64.abs(), 0f64);
-        assert_eq!((-0f64).abs(), 0f64);
-        assert_eq!((-1f64).abs(), 1f64);
-        assert_eq!(NEG_INFINITY.abs(), INFINITY);
-        assert_eq!((1f64/NEG_INFINITY).abs(), 0f64);
-        assert!(NAN.abs().is_nan());
-    }
-
-    #[test]
-    fn test_abs_sub() {
-        assert_eq!((-1f64).abs_sub(1f64), 0f64);
-        assert_eq!(1f64.abs_sub(1f64), 0f64);
-        assert_eq!(1f64.abs_sub(0f64), 1f64);
-        assert_eq!(1f64.abs_sub(-1f64), 2f64);
-        assert_eq!(NEG_INFINITY.abs_sub(0f64), 0f64);
-        assert_eq!(INFINITY.abs_sub(1f64), INFINITY);
-        assert_eq!(0f64.abs_sub(NEG_INFINITY), INFINITY);
-        assert_eq!(0f64.abs_sub(INFINITY), 0f64);
-    }
-
-    #[test]
-    fn test_abs_sub_nowin() {
-        assert!(NAN.abs_sub(-1f64).is_nan());
-        assert!(1f64.abs_sub(NAN).is_nan());
-    }
-
-    #[test]
-    fn test_signum() {
-        assert_eq!(INFINITY.signum(), 1f64);
-        assert_eq!(1f64.signum(), 1f64);
-        assert_eq!(0f64.signum(), 1f64);
-        assert_eq!((-0f64).signum(), -1f64);
-        assert_eq!((-1f64).signum(), -1f64);
-        assert_eq!(NEG_INFINITY.signum(), -1f64);
-        assert_eq!((1f64/NEG_INFINITY).signum(), -1f64);
-        assert!(NAN.signum().is_nan());
-    }
-
-    #[test]
-    fn test_is_positive() {
-        assert!(INFINITY.is_positive());
-        assert!(1f64.is_positive());
-        assert!(0f64.is_positive());
-        assert!(!(-0f64).is_positive());
-        assert!(!(-1f64).is_positive());
-        assert!(!NEG_INFINITY.is_positive());
-        assert!(!(1f64/NEG_INFINITY).is_positive());
-        assert!(!NAN.is_positive());
-    }
-
-    #[test]
-    fn test_is_negative() {
-        assert!(!INFINITY.is_negative());
-        assert!(!1f64.is_negative());
-        assert!(!0f64.is_negative());
-        assert!((-0f64).is_negative());
-        assert!((-1f64).is_negative());
-        assert!(NEG_INFINITY.is_negative());
-        assert!((1f64/NEG_INFINITY).is_negative());
-        assert!(!NAN.is_negative());
-    }
-
-    #[test]
-    fn test_is_normal() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let zero: f64 = Float::zero();
-        let neg_zero: f64 = Float::neg_zero();
-        assert!(!nan.is_normal());
-        assert!(!inf.is_normal());
-        assert!(!neg_inf.is_normal());
-        assert!(!zero.is_normal());
-        assert!(!neg_zero.is_normal());
-        assert!(1f64.is_normal());
-        assert!(1e-307f64.is_normal());
-        assert!(!1e-308f64.is_normal());
-    }
-
-    #[test]
-    fn test_classify() {
-        let nan: f64 = Float::nan();
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let zero: f64 = Float::zero();
-        let neg_zero: f64 = Float::neg_zero();
-        assert_eq!(nan.classify(), Fp::Nan);
-        assert_eq!(inf.classify(), Fp::Infinite);
-        assert_eq!(neg_inf.classify(), Fp::Infinite);
-        assert_eq!(zero.classify(), Fp::Zero);
-        assert_eq!(neg_zero.classify(), Fp::Zero);
-        assert_eq!(1e-307f64.classify(), Fp::Normal);
-        assert_eq!(1e-308f64.classify(), Fp::Subnormal);
-    }
-
-    #[test]
-    fn test_ldexp() {
-        // We have to use from_str until base-2 exponents
-        // are supported in floating-point literals
-        let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
-        let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
-        assert_eq!(Float::ldexp(1f64, -123), f1);
-        assert_eq!(Float::ldexp(1f64, -111), f2);
-
-        assert_eq!(Float::ldexp(0f64, -123), 0f64);
-        assert_eq!(Float::ldexp(-0f64, -123), -0f64);
-
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let nan: f64 = Float::nan();
-        assert_eq!(Float::ldexp(inf, -123), inf);
-        assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
-        assert!(Float::ldexp(nan, -123).is_nan());
-    }
-
-    #[test]
-    fn test_frexp() {
-        // We have to use from_str until base-2 exponents
-        // are supported in floating-point literals
-        let f1: f64 = FromStrRadix::from_str_radix("1p-123", 16).unwrap();
-        let f2: f64 = FromStrRadix::from_str_radix("1p-111", 16).unwrap();
-        let (x1, exp1) = f1.frexp();
-        let (x2, exp2) = f2.frexp();
-        assert_eq!((x1, exp1), (0.5f64, -122));
-        assert_eq!((x2, exp2), (0.5f64, -110));
-        assert_eq!(Float::ldexp(x1, exp1), f1);
-        assert_eq!(Float::ldexp(x2, exp2), f2);
-
-        assert_eq!(0f64.frexp(), (0f64, 0));
-        assert_eq!((-0f64).frexp(), (-0f64, 0));
-    }
-
-    #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
-    fn test_frexp_nowin() {
-        let inf: f64 = Float::infinity();
-        let neg_inf: f64 = Float::neg_infinity();
-        let nan: f64 = Float::nan();
-        assert_eq!(match inf.frexp() { (x, _) => x }, inf);
-        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
-        assert!(match nan.frexp() { (x, _) => x.is_nan() })
-    }
-
-    #[test]
-    fn test_integer_decode() {
-        assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906u64, -51i16, 1i8));
-        assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931u64, -39i16, -1i8));
-        assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496u64, 48i16, 1i8));
-        assert_eq!(0f64.integer_decode(), (0u64, -1075i16, 1i8));
-        assert_eq!((-0f64).integer_decode(), (0u64, -1075i16, -1i8));
-        assert_eq!(INFINITY.integer_decode(), (4503599627370496u64, 972i16, 1i8));
-        assert_eq!(NEG_INFINITY.integer_decode(), (4503599627370496, 972, -1));
-        assert_eq!(NAN.integer_decode(), (6755399441055744u64, 972i16, 1i8));
-    }
-
-    #[test]
-    fn test_sqrt_domain() {
-        assert!(NAN.sqrt().is_nan());
-        assert!(NEG_INFINITY.sqrt().is_nan());
-        assert!((-1.0f64).sqrt().is_nan());
-        assert_eq!((-0.0f64).sqrt(), -0.0);
-        assert_eq!(0.0f64.sqrt(), 0.0);
-        assert_eq!(1.0f64.sqrt(), 1.0);
-        assert_eq!(INFINITY.sqrt(), INFINITY);
-    }
 }
index 2b730cd6f9ad81e8755db53e25b420bbef9b1643..60a548b596b1c60f719659e828fa58ca646620c6 100644 (file)
@@ -13,7 +13,6 @@
 
 macro_rules! assert_approx_eq {
     ($a:expr, $b:expr) => ({
-        use num::Float;
         let (a, b) = (&$a, &$b);
         assert!((*a - *b).abs() < 1.0e-6,
                 "{} is not approximately equal to {}", *a, *b);
diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs
deleted file mode 100644 (file)
index 669952e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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.
-//
-// 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.
-
-//! Deprecated: replaced by `isize`.
-//!
-//! The rollout of the new type will gradually take place over the
-//! alpha cycle along with the development of clearer conventions
-//! around integer types.
-
-#![unstable(feature = "std_misc")]
-#![deprecated(since = "1.0.0", reason = "replaced by isize")]
-
-pub use core::int::{BITS, BYTES, MIN, MAX};
-
-int_module! { int }
index c94c16498332924e2fd5348fc12e317983c792e3..2de03e2e72d664c41b3bde2324c33f9659a7b00e 100644 (file)
 //! Numeric traits and functions for generic mathematics
 //!
 //! These are implemented for the primitive numeric types in `std::{u8, u16,
-//! u32, u64, uint, i8, i16, i32, i64, int, f32, f64}`.
+//! u32, u64, usize, i8, i16, i32, i64, isize, f32, f64}`.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
+#![allow(deprecated)]
 
 #[cfg(test)] use fmt::Debug;
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
@@ -23,21 +24,24 @@ use marker::Copy;
 use clone::Clone;
 use cmp::{PartialOrd, PartialEq};
 
-pub use core::num::{Int, SignedInt, UnsignedInt};
+pub use core::num::{Int, SignedInt, Zero, One};
 pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive};
 pub use core::num::{from_int, from_i8, from_i16, from_i32, from_i64};
 pub use core::num::{from_uint, from_u8, from_u16, from_u32, from_u64};
 pub use core::num::{from_f32, from_f64};
 pub use core::num::{FromStrRadix, from_str_radix};
 pub use core::num::{FpCategory, ParseIntError, ParseFloatError};
+pub use core::num::{wrapping, Wrapping};
 
 use option::Option;
 
-#[unstable(feature = "std_misc", reason = "may be removed or relocated")]
+#[unstable(feature = "std_misc", reason = "likely to be removed")]
 pub mod strconv;
 
 /// Mathematical operations on primitive floating point numbers.
 #[stable(feature = "rust1", since = "1.0.0")]
+#[deprecated(since = "1.0.0",
+             reason = "replaced by inherent methods; use rust-lang/num for generics")]
 pub trait Float
     : Copy + Clone
     + NumCast
@@ -54,6 +58,7 @@ pub trait Float
     /// Returns the `NaN` value.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let nan: f32 = Float::nan();
@@ -66,6 +71,7 @@ pub trait Float
     /// Returns the infinite value.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     /// use std::f32;
     ///
@@ -81,6 +87,7 @@ pub trait Float
     /// Returns the negative infinite value.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     /// use std::f32;
     ///
@@ -96,6 +103,7 @@ pub trait Float
     /// Returns `0.0`.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let inf: f32 = Float::infinity();
@@ -112,6 +120,7 @@ pub trait Float
     /// Returns `-0.0`.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let inf: f32 = Float::infinity();
@@ -128,6 +137,7 @@ pub trait Float
     /// Returns `1.0`.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let one: f32 = Float::one();
@@ -146,12 +156,12 @@ pub trait Float
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MANTISSA_DIGITS` or \
                            `std::f64::MANTISSA_DIGITS` as appropriate")]
-    fn mantissa_digits(unused_self: Option<Self>) -> uint;
+    fn mantissa_digits(unused_self: Option<Self>) -> usize;
     /// Deprecated: use `std::f32::DIGITS` or `std::f64::DIGITS` instead.
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate")]
-    fn digits(unused_self: Option<Self>) -> uint;
+    fn digits(unused_self: Option<Self>) -> usize;
     /// Deprecated: use `std::f32::EPSILON` or `std::f64::EPSILON` instead.
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
@@ -161,26 +171,27 @@ pub trait Float
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate")]
-    fn min_exp(unused_self: Option<Self>) -> int;
+    fn min_exp(unused_self: Option<Self>) -> isize;
     /// Deprecated: use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` instead.
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate")]
-    fn max_exp(unused_self: Option<Self>) -> int;
+    fn max_exp(unused_self: Option<Self>) -> isize;
     /// Deprecated: use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` instead.
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate")]
-    fn min_10_exp(unused_self: Option<Self>) -> int;
+    fn min_10_exp(unused_self: Option<Self>) -> isize;
     /// Deprecated: use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` instead.
     #[unstable(feature = "std_misc")]
     #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate")]
-    fn max_10_exp(unused_self: Option<Self>) -> int;
+    fn max_10_exp(unused_self: Option<Self>) -> isize;
 
     /// Returns the smallest finite value that this type can represent.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -198,6 +209,7 @@ pub trait Float
     /// Returns the largest finite value that this type can represent.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -210,6 +222,7 @@ pub trait Float
     /// Returns `true` if this value is `NaN` and false otherwise.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -225,6 +238,7 @@ pub trait Float
     /// false otherwise.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     /// use std::f32;
     ///
@@ -244,6 +258,7 @@ pub trait Float
     /// Returns `true` if this number is neither infinite nor `NaN`.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     /// use std::f32;
     ///
@@ -260,10 +275,12 @@ pub trait Float
     /// ```
     #[unstable(feature = "std_misc", reason = "position is undecided")]
     fn is_finite(self) -> bool;
+
     /// Returns `true` if the number is neither zero, infinite,
     /// [subnormal][subnormal], or `NaN`.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     /// use std::f32;
     ///
@@ -290,6 +307,7 @@ pub trait Float
     /// predicate instead.
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::{Float, FpCategory};
     /// use std::f32;
     ///
@@ -307,11 +325,12 @@ pub trait Float
     /// The floating point encoding is documented in the [Reference][floating-point].
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let num = 2.0f32;
     ///
-    /// // (8388608u64, -22i16, 1i8)
+    /// // (8388608, -22, 1)
     /// let (mantissa, exponent, sign) = num.integer_decode();
     /// let sign_f = sign as f32;
     /// let mantissa_f = mantissa as f32;
@@ -398,6 +417,7 @@ pub trait Float
     /// number is `Float::nan()`.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -421,6 +441,7 @@ pub trait Float
     /// - `Float::nan()` if the number is `Float::nan()`
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -477,6 +498,7 @@ pub trait Float
     /// a separate multiplication operation followed by an add.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let m = 10.0;
@@ -494,6 +516,7 @@ pub trait Float
     /// Take the reciprocal (inverse) of a number, `1/x`.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let x = 2.0;
@@ -536,6 +559,7 @@ pub trait Float
     /// Returns NaN if `self` is a negative number.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let positive = 4.0;
@@ -552,6 +576,7 @@ pub trait Float
     /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let f = 4.0;
@@ -661,6 +686,7 @@ pub trait Float
     /// Convert radians to degrees.
     ///
     /// ```
+    /// # #![feature(std_misc, core)]
     /// use std::num::Float;
     /// use std::f64::consts;
     ///
@@ -675,6 +701,7 @@ pub trait Float
     /// Convert degrees to radians.
     ///
     /// ```
+    /// # #![feature(std_misc, core)]
     /// use std::num::Float;
     /// use std::f64::consts;
     ///
@@ -689,6 +716,7 @@ pub trait Float
     /// Constructs a floating point number of `x*2^exp`.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// // 3*2^2 - 12 == 0
@@ -698,7 +726,7 @@ pub trait Float
     /// ```
     #[unstable(feature = "std_misc",
                reason = "pending integer conventions")]
-    fn ldexp(x: Self, exp: int) -> Self;
+    fn ldexp(self, exp: isize) -> Self;
     /// Breaks the number into a normalized fraction and a base-2 exponent,
     /// satisfying:
     ///
@@ -706,6 +734,7 @@ pub trait Float
     ///  * `0.5 <= abs(x) < 1.0`
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let x = 4.0;
@@ -720,11 +749,12 @@ pub trait Float
     /// ```
     #[unstable(feature = "std_misc",
                reason = "pending integer conventions")]
-    fn frexp(self) -> (Self, int);
+    fn frexp(self) -> (Self, isize);
     /// Returns the next representable floating-point value in the direction of
     /// `other`.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let x = 1.0f32;
@@ -768,6 +798,7 @@ pub trait Float
     /// * Else: `self - other`
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let x = 3.0;
@@ -784,6 +815,7 @@ pub trait Float
     /// Take the cubic root of a number.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let x = 8.0;
@@ -799,6 +831,7 @@ pub trait Float
     /// legs of length `x` and `y`.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let x = 2.0;
@@ -816,6 +849,7 @@ pub trait Float
     /// Computes the sine of a number (in radians).
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -830,6 +864,7 @@ pub trait Float
     /// Computes the cosine of a number (in radians).
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -844,6 +879,7 @@ pub trait Float
     /// Computes the tangent of a number (in radians).
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -859,6 +895,7 @@ pub trait Float
     /// [-1, 1].
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -876,6 +913,7 @@ pub trait Float
     /// [-1, 1].
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -911,6 +949,7 @@ pub trait Float
     /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -936,6 +975,7 @@ pub trait Float
     /// `(sin(x), cos(x))`.
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -955,6 +995,7 @@ pub trait Float
     /// number is close to zero.
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::num::Float;
     ///
     /// let x = 7.0;
@@ -970,6 +1011,7 @@ pub trait Float
     /// the operations were performed separately.
     ///
     /// ```
+    /// # #![feature(std_misc, core)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -986,6 +1028,7 @@ pub trait Float
     /// Hyperbolic sine function.
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -1004,6 +1047,7 @@ pub trait Float
     /// Hyperbolic cosine function.
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -1022,6 +1066,7 @@ pub trait Float
     /// Hyperbolic tangent function.
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -1068,6 +1113,7 @@ pub trait Float
     /// Inverse hyperbolic tangent function.
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Float;
     /// use std::f64;
     ///
@@ -1106,18 +1152,19 @@ pub fn test_num<T>(ten: T, two: T) where
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
+    use core::prelude::*;
     use super::*;
     use i8;
     use i16;
     use i32;
     use i64;
-    use int;
+    use isize;
     use u8;
     use u16;
     use u32;
     use u64;
-    use uint;
+    use usize;
+    use string::ToString;
 
     macro_rules! test_cast_20 {
         ($_20:expr) => ({
@@ -1179,25 +1226,25 @@ mod tests {
 
     #[test]
     fn test_cast_range_int_min() {
-        assert_eq!(int::MIN.to_int(),  Some(int::MIN as int));
-        assert_eq!(int::MIN.to_i8(),   None);
-        assert_eq!(int::MIN.to_i16(),  None);
-        // int::MIN.to_i32() is word-size specific
-        assert_eq!(int::MIN.to_i64(),  Some(int::MIN as i64));
-        assert_eq!(int::MIN.to_uint(), None);
-        assert_eq!(int::MIN.to_u8(),   None);
-        assert_eq!(int::MIN.to_u16(),  None);
-        assert_eq!(int::MIN.to_u32(),  None);
-        assert_eq!(int::MIN.to_u64(),  None);
+        assert_eq!(isize::MIN.to_int(),  Some(isize::MIN as isize));
+        assert_eq!(isize::MIN.to_i8(),   None);
+        assert_eq!(isize::MIN.to_i16(),  None);
+        // isize::MIN.to_i32() is word-size specific
+        assert_eq!(isize::MIN.to_i64(),  Some(isize::MIN as i64));
+        assert_eq!(isize::MIN.to_uint(), None);
+        assert_eq!(isize::MIN.to_u8(),   None);
+        assert_eq!(isize::MIN.to_u16(),  None);
+        assert_eq!(isize::MIN.to_u32(),  None);
+        assert_eq!(isize::MIN.to_u64(),  None);
 
         #[cfg(target_pointer_width = "32")]
         fn check_word_size() {
-            assert_eq!(int::MIN.to_i32(), Some(int::MIN as i32));
+            assert_eq!(isize::MIN.to_i32(), Some(isize::MIN as i32));
         }
 
         #[cfg(target_pointer_width = "64")]
         fn check_word_size() {
-            assert_eq!(int::MIN.to_i32(), None);
+            assert_eq!(isize::MIN.to_i32(), None);
         }
 
         check_word_size();
@@ -1205,7 +1252,7 @@ mod tests {
 
     #[test]
     fn test_cast_range_i8_min() {
-        assert_eq!(i8::MIN.to_int(),  Some(i8::MIN as int));
+        assert_eq!(i8::MIN.to_int(),  Some(i8::MIN as isize));
         assert_eq!(i8::MIN.to_i8(),   Some(i8::MIN as i8));
         assert_eq!(i8::MIN.to_i16(),  Some(i8::MIN as i16));
         assert_eq!(i8::MIN.to_i32(),  Some(i8::MIN as i32));
@@ -1219,7 +1266,7 @@ mod tests {
 
     #[test]
     fn test_cast_range_i16_min() {
-        assert_eq!(i16::MIN.to_int(),  Some(i16::MIN as int));
+        assert_eq!(i16::MIN.to_int(),  Some(i16::MIN as isize));
         assert_eq!(i16::MIN.to_i8(),   None);
         assert_eq!(i16::MIN.to_i16(),  Some(i16::MIN as i16));
         assert_eq!(i16::MIN.to_i32(),  Some(i16::MIN as i32));
@@ -1233,7 +1280,7 @@ mod tests {
 
     #[test]
     fn test_cast_range_i32_min() {
-        assert_eq!(i32::MIN.to_int(),  Some(i32::MIN as int));
+        assert_eq!(i32::MIN.to_int(),  Some(i32::MIN as isize));
         assert_eq!(i32::MIN.to_i8(),   None);
         assert_eq!(i32::MIN.to_i16(),  None);
         assert_eq!(i32::MIN.to_i32(),  Some(i32::MIN as i32));
@@ -1265,7 +1312,7 @@ mod tests {
 
         #[cfg(target_pointer_width = "64")]
         fn check_word_size() {
-            assert_eq!(i64::MIN.to_int(), Some(i64::MIN as int));
+            assert_eq!(i64::MIN.to_int(), Some(i64::MIN as isize));
         }
 
         check_word_size();
@@ -1273,26 +1320,26 @@ mod tests {
 
     #[test]
     fn test_cast_range_int_max() {
-        assert_eq!(int::MAX.to_int(),  Some(int::MAX as int));
-        assert_eq!(int::MAX.to_i8(),   None);
-        assert_eq!(int::MAX.to_i16(),  None);
-        // int::MAX.to_i32() is word-size specific
-        assert_eq!(int::MAX.to_i64(),  Some(int::MAX as i64));
-        assert_eq!(int::MAX.to_u8(),   None);
-        assert_eq!(int::MAX.to_u16(),  None);
-        // int::MAX.to_u32() is word-size specific
-        assert_eq!(int::MAX.to_u64(),  Some(int::MAX as u64));
+        assert_eq!(isize::MAX.to_int(),  Some(isize::MAX as isize));
+        assert_eq!(isize::MAX.to_i8(),   None);
+        assert_eq!(isize::MAX.to_i16(),  None);
+        // isize::MAX.to_i32() is word-size specific
+        assert_eq!(isize::MAX.to_i64(),  Some(isize::MAX as i64));
+        assert_eq!(isize::MAX.to_u8(),   None);
+        assert_eq!(isize::MAX.to_u16(),  None);
+        // isize::MAX.to_u32() is word-size specific
+        assert_eq!(isize::MAX.to_u64(),  Some(isize::MAX as u64));
 
         #[cfg(target_pointer_width = "32")]
         fn check_word_size() {
-            assert_eq!(int::MAX.to_i32(), Some(int::MAX as i32));
-            assert_eq!(int::MAX.to_u32(), Some(int::MAX as u32));
+            assert_eq!(isize::MAX.to_i32(), Some(isize::MAX as i32));
+            assert_eq!(isize::MAX.to_u32(), Some(isize::MAX as u32));
         }
 
         #[cfg(target_pointer_width = "64")]
         fn check_word_size() {
-            assert_eq!(int::MAX.to_i32(), None);
-            assert_eq!(int::MAX.to_u32(), None);
+            assert_eq!(isize::MAX.to_i32(), None);
+            assert_eq!(isize::MAX.to_u32(), None);
         }
 
         check_word_size();
@@ -1300,12 +1347,12 @@ mod tests {
 
     #[test]
     fn test_cast_range_i8_max() {
-        assert_eq!(i8::MAX.to_int(),  Some(i8::MAX as int));
+        assert_eq!(i8::MAX.to_int(),  Some(i8::MAX as isize));
         assert_eq!(i8::MAX.to_i8(),   Some(i8::MAX as i8));
         assert_eq!(i8::MAX.to_i16(),  Some(i8::MAX as i16));
         assert_eq!(i8::MAX.to_i32(),  Some(i8::MAX as i32));
         assert_eq!(i8::MAX.to_i64(),  Some(i8::MAX as i64));
-        assert_eq!(i8::MAX.to_uint(), Some(i8::MAX as uint));
+        assert_eq!(i8::MAX.to_uint(), Some(i8::MAX as usize));
         assert_eq!(i8::MAX.to_u8(),   Some(i8::MAX as u8));
         assert_eq!(i8::MAX.to_u16(),  Some(i8::MAX as u16));
         assert_eq!(i8::MAX.to_u32(),  Some(i8::MAX as u32));
@@ -1314,12 +1361,12 @@ mod tests {
 
     #[test]
     fn test_cast_range_i16_max() {
-        assert_eq!(i16::MAX.to_int(),  Some(i16::MAX as int));
+        assert_eq!(i16::MAX.to_int(),  Some(i16::MAX as isize));
         assert_eq!(i16::MAX.to_i8(),   None);
         assert_eq!(i16::MAX.to_i16(),  Some(i16::MAX as i16));
         assert_eq!(i16::MAX.to_i32(),  Some(i16::MAX as i32));
         assert_eq!(i16::MAX.to_i64(),  Some(i16::MAX as i64));
-        assert_eq!(i16::MAX.to_uint(), Some(i16::MAX as uint));
+        assert_eq!(i16::MAX.to_uint(), Some(i16::MAX as usize));
         assert_eq!(i16::MAX.to_u8(),   None);
         assert_eq!(i16::MAX.to_u16(),  Some(i16::MAX as u16));
         assert_eq!(i16::MAX.to_u32(),  Some(i16::MAX as u32));
@@ -1328,12 +1375,12 @@ mod tests {
 
     #[test]
     fn test_cast_range_i32_max() {
-        assert_eq!(i32::MAX.to_int(),  Some(i32::MAX as int));
+        assert_eq!(i32::MAX.to_int(),  Some(i32::MAX as isize));
         assert_eq!(i32::MAX.to_i8(),   None);
         assert_eq!(i32::MAX.to_i16(),  None);
         assert_eq!(i32::MAX.to_i32(),  Some(i32::MAX as i32));
         assert_eq!(i32::MAX.to_i64(),  Some(i32::MAX as i64));
-        assert_eq!(i32::MAX.to_uint(), Some(i32::MAX as uint));
+        assert_eq!(i32::MAX.to_uint(), Some(i32::MAX as usize));
         assert_eq!(i32::MAX.to_u8(),   None);
         assert_eq!(i32::MAX.to_u16(),  None);
         assert_eq!(i32::MAX.to_u32(),  Some(i32::MAX as u32));
@@ -1361,8 +1408,8 @@ mod tests {
 
         #[cfg(target_pointer_width = "64")]
         fn check_word_size() {
-            assert_eq!(i64::MAX.to_int(),  Some(i64::MAX as int));
-            assert_eq!(i64::MAX.to_uint(), Some(i64::MAX as uint));
+            assert_eq!(i64::MAX.to_int(),  Some(i64::MAX as isize));
+            assert_eq!(i64::MAX.to_uint(), Some(i64::MAX as usize));
         }
 
         check_word_size();
@@ -1370,26 +1417,26 @@ mod tests {
 
     #[test]
     fn test_cast_range_uint_min() {
-        assert_eq!(uint::MIN.to_int(),  Some(uint::MIN as int));
-        assert_eq!(uint::MIN.to_i8(),   Some(uint::MIN as i8));
-        assert_eq!(uint::MIN.to_i16(),  Some(uint::MIN as i16));
-        assert_eq!(uint::MIN.to_i32(),  Some(uint::MIN as i32));
-        assert_eq!(uint::MIN.to_i64(),  Some(uint::MIN as i64));
-        assert_eq!(uint::MIN.to_uint(), Some(uint::MIN as uint));
-        assert_eq!(uint::MIN.to_u8(),   Some(uint::MIN as u8));
-        assert_eq!(uint::MIN.to_u16(),  Some(uint::MIN as u16));
-        assert_eq!(uint::MIN.to_u32(),  Some(uint::MIN as u32));
-        assert_eq!(uint::MIN.to_u64(),  Some(uint::MIN as u64));
+        assert_eq!(usize::MIN.to_int(),  Some(usize::MIN as isize));
+        assert_eq!(usize::MIN.to_i8(),   Some(usize::MIN as i8));
+        assert_eq!(usize::MIN.to_i16(),  Some(usize::MIN as i16));
+        assert_eq!(usize::MIN.to_i32(),  Some(usize::MIN as i32));
+        assert_eq!(usize::MIN.to_i64(),  Some(usize::MIN as i64));
+        assert_eq!(usize::MIN.to_uint(), Some(usize::MIN as usize));
+        assert_eq!(usize::MIN.to_u8(),   Some(usize::MIN as u8));
+        assert_eq!(usize::MIN.to_u16(),  Some(usize::MIN as u16));
+        assert_eq!(usize::MIN.to_u32(),  Some(usize::MIN as u32));
+        assert_eq!(usize::MIN.to_u64(),  Some(usize::MIN as u64));
     }
 
     #[test]
     fn test_cast_range_u8_min() {
-        assert_eq!(u8::MIN.to_int(),  Some(u8::MIN as int));
+        assert_eq!(u8::MIN.to_int(),  Some(u8::MIN as isize));
         assert_eq!(u8::MIN.to_i8(),   Some(u8::MIN as i8));
         assert_eq!(u8::MIN.to_i16(),  Some(u8::MIN as i16));
         assert_eq!(u8::MIN.to_i32(),  Some(u8::MIN as i32));
         assert_eq!(u8::MIN.to_i64(),  Some(u8::MIN as i64));
-        assert_eq!(u8::MIN.to_uint(), Some(u8::MIN as uint));
+        assert_eq!(u8::MIN.to_uint(), Some(u8::MIN as usize));
         assert_eq!(u8::MIN.to_u8(),   Some(u8::MIN as u8));
         assert_eq!(u8::MIN.to_u16(),  Some(u8::MIN as u16));
         assert_eq!(u8::MIN.to_u32(),  Some(u8::MIN as u32));
@@ -1398,12 +1445,12 @@ mod tests {
 
     #[test]
     fn test_cast_range_u16_min() {
-        assert_eq!(u16::MIN.to_int(),  Some(u16::MIN as int));
+        assert_eq!(u16::MIN.to_int(),  Some(u16::MIN as isize));
         assert_eq!(u16::MIN.to_i8(),   Some(u16::MIN as i8));
         assert_eq!(u16::MIN.to_i16(),  Some(u16::MIN as i16));
         assert_eq!(u16::MIN.to_i32(),  Some(u16::MIN as i32));
         assert_eq!(u16::MIN.to_i64(),  Some(u16::MIN as i64));
-        assert_eq!(u16::MIN.to_uint(), Some(u16::MIN as uint));
+        assert_eq!(u16::MIN.to_uint(), Some(u16::MIN as usize));
         assert_eq!(u16::MIN.to_u8(),   Some(u16::MIN as u8));
         assert_eq!(u16::MIN.to_u16(),  Some(u16::MIN as u16));
         assert_eq!(u16::MIN.to_u32(),  Some(u16::MIN as u32));
@@ -1412,12 +1459,12 @@ mod tests {
 
     #[test]
     fn test_cast_range_u32_min() {
-        assert_eq!(u32::MIN.to_int(),  Some(u32::MIN as int));
+        assert_eq!(u32::MIN.to_int(),  Some(u32::MIN as isize));
         assert_eq!(u32::MIN.to_i8(),   Some(u32::MIN as i8));
         assert_eq!(u32::MIN.to_i16(),  Some(u32::MIN as i16));
         assert_eq!(u32::MIN.to_i32(),  Some(u32::MIN as i32));
         assert_eq!(u32::MIN.to_i64(),  Some(u32::MIN as i64));
-        assert_eq!(u32::MIN.to_uint(), Some(u32::MIN as uint));
+        assert_eq!(u32::MIN.to_uint(), Some(u32::MIN as usize));
         assert_eq!(u32::MIN.to_u8(),   Some(u32::MIN as u8));
         assert_eq!(u32::MIN.to_u16(),  Some(u32::MIN as u16));
         assert_eq!(u32::MIN.to_u32(),  Some(u32::MIN as u32));
@@ -1426,12 +1473,12 @@ mod tests {
 
     #[test]
     fn test_cast_range_u64_min() {
-        assert_eq!(u64::MIN.to_int(),  Some(u64::MIN as int));
+        assert_eq!(u64::MIN.to_int(),  Some(u64::MIN as isize));
         assert_eq!(u64::MIN.to_i8(),   Some(u64::MIN as i8));
         assert_eq!(u64::MIN.to_i16(),  Some(u64::MIN as i16));
         assert_eq!(u64::MIN.to_i32(),  Some(u64::MIN as i32));
         assert_eq!(u64::MIN.to_i64(),  Some(u64::MIN as i64));
-        assert_eq!(u64::MIN.to_uint(), Some(u64::MIN as uint));
+        assert_eq!(u64::MIN.to_uint(), Some(u64::MIN as usize));
         assert_eq!(u64::MIN.to_u8(),   Some(u64::MIN as u8));
         assert_eq!(u64::MIN.to_u16(),  Some(u64::MIN as u16));
         assert_eq!(u64::MIN.to_u32(),  Some(u64::MIN as u32));
@@ -1440,26 +1487,26 @@ mod tests {
 
     #[test]
     fn test_cast_range_uint_max() {
-        assert_eq!(uint::MAX.to_int(),  None);
-        assert_eq!(uint::MAX.to_i8(),   None);
-        assert_eq!(uint::MAX.to_i16(),  None);
-        assert_eq!(uint::MAX.to_i32(),  None);
-        // uint::MAX.to_i64() is word-size specific
-        assert_eq!(uint::MAX.to_u8(),   None);
-        assert_eq!(uint::MAX.to_u16(),  None);
-        // uint::MAX.to_u32() is word-size specific
-        assert_eq!(uint::MAX.to_u64(),  Some(uint::MAX as u64));
+        assert_eq!(usize::MAX.to_int(),  None);
+        assert_eq!(usize::MAX.to_i8(),   None);
+        assert_eq!(usize::MAX.to_i16(),  None);
+        assert_eq!(usize::MAX.to_i32(),  None);
+        // usize::MAX.to_i64() is word-size specific
+        assert_eq!(usize::MAX.to_u8(),   None);
+        assert_eq!(usize::MAX.to_u16(),  None);
+        // usize::MAX.to_u32() is word-size specific
+        assert_eq!(usize::MAX.to_u64(),  Some(usize::MAX as u64));
 
         #[cfg(target_pointer_width = "32")]
         fn check_word_size() {
-            assert_eq!(uint::MAX.to_u32(), Some(uint::MAX as u32));
-            assert_eq!(uint::MAX.to_i64(), Some(uint::MAX as i64));
+            assert_eq!(usize::MAX.to_u32(), Some(usize::MAX as u32));
+            assert_eq!(usize::MAX.to_i64(), Some(usize::MAX as i64));
         }
 
         #[cfg(target_pointer_width = "64")]
         fn check_word_size() {
-            assert_eq!(uint::MAX.to_u32(), None);
-            assert_eq!(uint::MAX.to_i64(), None);
+            assert_eq!(usize::MAX.to_u32(), None);
+            assert_eq!(usize::MAX.to_i64(), None);
         }
 
         check_word_size();
@@ -1467,12 +1514,12 @@ mod tests {
 
     #[test]
     fn test_cast_range_u8_max() {
-        assert_eq!(u8::MAX.to_int(),  Some(u8::MAX as int));
+        assert_eq!(u8::MAX.to_int(),  Some(u8::MAX as isize));
         assert_eq!(u8::MAX.to_i8(),   None);
         assert_eq!(u8::MAX.to_i16(),  Some(u8::MAX as i16));
         assert_eq!(u8::MAX.to_i32(),  Some(u8::MAX as i32));
         assert_eq!(u8::MAX.to_i64(),  Some(u8::MAX as i64));
-        assert_eq!(u8::MAX.to_uint(), Some(u8::MAX as uint));
+        assert_eq!(u8::MAX.to_uint(), Some(u8::MAX as usize));
         assert_eq!(u8::MAX.to_u8(),   Some(u8::MAX as u8));
         assert_eq!(u8::MAX.to_u16(),  Some(u8::MAX as u16));
         assert_eq!(u8::MAX.to_u32(),  Some(u8::MAX as u32));
@@ -1481,12 +1528,12 @@ mod tests {
 
     #[test]
     fn test_cast_range_u16_max() {
-        assert_eq!(u16::MAX.to_int(),  Some(u16::MAX as int));
+        assert_eq!(u16::MAX.to_int(),  Some(u16::MAX as isize));
         assert_eq!(u16::MAX.to_i8(),   None);
         assert_eq!(u16::MAX.to_i16(),  None);
         assert_eq!(u16::MAX.to_i32(),  Some(u16::MAX as i32));
         assert_eq!(u16::MAX.to_i64(),  Some(u16::MAX as i64));
-        assert_eq!(u16::MAX.to_uint(), Some(u16::MAX as uint));
+        assert_eq!(u16::MAX.to_uint(), Some(u16::MAX as usize));
         assert_eq!(u16::MAX.to_u8(),   None);
         assert_eq!(u16::MAX.to_u16(),  Some(u16::MAX as u16));
         assert_eq!(u16::MAX.to_u32(),  Some(u16::MAX as u32));
@@ -1500,7 +1547,7 @@ mod tests {
         assert_eq!(u32::MAX.to_i16(),  None);
         assert_eq!(u32::MAX.to_i32(),  None);
         assert_eq!(u32::MAX.to_i64(),  Some(u32::MAX as i64));
-        assert_eq!(u32::MAX.to_uint(), Some(u32::MAX as uint));
+        assert_eq!(u32::MAX.to_uint(), Some(u32::MAX as usize));
         assert_eq!(u32::MAX.to_u8(),   None);
         assert_eq!(u32::MAX.to_u16(),  None);
         assert_eq!(u32::MAX.to_u32(),  Some(u32::MAX as u32));
@@ -1513,7 +1560,7 @@ mod tests {
 
         #[cfg(target_pointer_width = "64")]
         fn check_word_size() {
-            assert_eq!(u32::MAX.to_int(),  Some(u32::MAX as int));
+            assert_eq!(u32::MAX.to_int(),  Some(u32::MAX as isize));
         }
 
         check_word_size();
@@ -1539,7 +1586,7 @@ mod tests {
 
         #[cfg(target_pointer_width = "64")]
         fn check_word_size() {
-            assert_eq!(u64::MAX.to_uint(), Some(u64::MAX as uint));
+            assert_eq!(u64::MAX.to_uint(), Some(u64::MAX as usize));
         }
 
         check_word_size();
@@ -1547,7 +1594,7 @@ mod tests {
 
     #[test]
     fn test_saturating_add_uint() {
-        use uint::MAX;
+        use usize::MAX;
         assert_eq!(3_usize.saturating_add(5_usize), 8_usize);
         assert_eq!(3_usize.saturating_add(MAX-1), MAX);
         assert_eq!(MAX.saturating_add(MAX), MAX);
@@ -1556,7 +1603,7 @@ mod tests {
 
     #[test]
     fn test_saturating_sub_uint() {
-        use uint::MAX;
+        use usize::MAX;
         assert_eq!(5_usize.saturating_sub(3_usize), 2_usize);
         assert_eq!(3_usize.saturating_sub(5_usize), 0_usize);
         assert_eq!(0_usize.saturating_sub(1_usize), 0_usize);
@@ -1565,7 +1612,7 @@ mod tests {
 
     #[test]
     fn test_saturating_add_int() {
-        use int::{MIN,MAX};
+        use isize::{MIN,MAX};
         assert_eq!(3.saturating_add(5), 8);
         assert_eq!(3.saturating_add(MAX-1), MAX);
         assert_eq!(MAX.saturating_add(MAX), MAX);
@@ -1577,7 +1624,7 @@ mod tests {
 
     #[test]
     fn test_saturating_sub_int() {
-        use int::{MIN,MAX};
+        use isize::{MIN,MAX};
         assert_eq!(3.saturating_sub(5), -2);
         assert_eq!(MIN.saturating_sub(1), MIN);
         assert_eq!((-2).saturating_sub(MAX), MIN);
@@ -1589,13 +1636,13 @@ mod tests {
 
     #[test]
     fn test_checked_add() {
-        let five_less = uint::MAX - 5;
-        assert_eq!(five_less.checked_add(0), Some(uint::MAX - 5));
-        assert_eq!(five_less.checked_add(1), Some(uint::MAX - 4));
-        assert_eq!(five_less.checked_add(2), Some(uint::MAX - 3));
-        assert_eq!(five_less.checked_add(3), Some(uint::MAX - 2));
-        assert_eq!(five_less.checked_add(4), Some(uint::MAX - 1));
-        assert_eq!(five_less.checked_add(5), Some(uint::MAX));
+        let five_less = usize::MAX - 5;
+        assert_eq!(five_less.checked_add(0), Some(usize::MAX - 5));
+        assert_eq!(five_less.checked_add(1), Some(usize::MAX - 4));
+        assert_eq!(five_less.checked_add(2), Some(usize::MAX - 3));
+        assert_eq!(five_less.checked_add(3), Some(usize::MAX - 2));
+        assert_eq!(five_less.checked_add(4), Some(usize::MAX - 1));
+        assert_eq!(five_less.checked_add(5), Some(usize::MAX));
         assert_eq!(five_less.checked_add(6), None);
         assert_eq!(five_less.checked_add(7), None);
     }
@@ -1614,7 +1661,7 @@ mod tests {
 
     #[test]
     fn test_checked_mul() {
-        let third = uint::MAX / 3;
+        let third = usize::MAX / 3;
         assert_eq!(third.checked_mul(0), Some(0));
         assert_eq!(third.checked_mul(1), Some(third));
         assert_eq!(third.checked_mul(2), Some(third * 2));
@@ -1632,7 +1679,7 @@ mod tests {
                 assert_eq!((3 as $T).is_power_of_two(), false);
                 assert_eq!((4 as $T).is_power_of_two(), true);
                 assert_eq!((5 as $T).is_power_of_two(), false);
-                assert!(($T::MAX / 2 + 1).is_power_of_two(), true);
+                assert_eq!(($T::MAX / 2 + 1).is_power_of_two(), true);
             }
         )
     }
@@ -1641,7 +1688,7 @@ mod tests {
     test_is_power_of_two!{ test_is_power_of_two_u16, u16 }
     test_is_power_of_two!{ test_is_power_of_two_u32, u32 }
     test_is_power_of_two!{ test_is_power_of_two_u64, u64 }
-    test_is_power_of_two!{ test_is_power_of_two_uint, uint }
+    test_is_power_of_two!{ test_is_power_of_two_uint, usize }
 
     macro_rules! test_next_power_of_two {
         ($test_name:ident, $T:ident) => (
@@ -1649,7 +1696,7 @@ mod tests {
                 #![test]
                 assert_eq!((0 as $T).next_power_of_two(), 1);
                 let mut next_power = 1;
-                for i in range::<$T>(1, 40) {
+                for i in 1 as $T..40 {
                      assert_eq!(i.next_power_of_two(), next_power);
                      if i == next_power { next_power *= 2 }
                 }
@@ -1661,7 +1708,7 @@ mod tests {
     test_next_power_of_two! { test_next_power_of_two_u16, u16 }
     test_next_power_of_two! { test_next_power_of_two_u32, u32 }
     test_next_power_of_two! { test_next_power_of_two_u64, u64 }
-    test_next_power_of_two! { test_next_power_of_two_uint, uint }
+    test_next_power_of_two! { test_next_power_of_two_uint, usize }
 
     macro_rules! test_checked_next_power_of_two {
         ($test_name:ident, $T:ident) => (
@@ -1672,7 +1719,7 @@ mod tests {
                 assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None);
                 assert_eq!($T::MAX.checked_next_power_of_two(), None);
                 let mut next_power = 1;
-                for i in range::<$T>(1, 40) {
+                for i in 1 as $T..40 {
                      assert_eq!(i.checked_next_power_of_two(), Some(next_power));
                      if i == next_power { next_power *= 2 }
                 }
@@ -1684,10 +1731,10 @@ mod tests {
     test_checked_next_power_of_two! { test_checked_next_power_of_two_u16, u16 }
     test_checked_next_power_of_two! { test_checked_next_power_of_two_u32, u32 }
     test_checked_next_power_of_two! { test_checked_next_power_of_two_u64, u64 }
-    test_checked_next_power_of_two! { test_checked_next_power_of_two_uint, uint }
+    test_checked_next_power_of_two! { test_checked_next_power_of_two_uint, usize }
 
     #[derive(PartialEq, Debug)]
-    struct Value { x: int }
+    struct Value { x: isize }
 
     impl ToPrimitive for Value {
         fn to_i64(&self) -> Option<i64> { self.x.to_i64() }
@@ -1695,8 +1742,8 @@ mod tests {
     }
 
     impl FromPrimitive for Value {
-        fn from_i64(n: i64) -> Option<Value> { Some(Value { x: n as int }) }
-        fn from_u64(n: u64) -> Option<Value> { Some(Value { x: n as int }) }
+        fn from_i64(n: i64) -> Option<Value> { Some(Value { x: n as isize }) }
+        fn from_u64(n: u64) -> Option<Value> { Some(Value { x: n as isize }) }
     }
 
     #[test]
@@ -1734,7 +1781,7 @@ mod tests {
 
     #[test]
     fn test_pow() {
-        fn naive_pow<T: Int>(base: T, exp: uint) -> T {
+        fn naive_pow<T: Int>(base: T, exp: usize) -> T {
             let one: T = Int::one();
             (0..exp).fold(one, |acc, _| acc * base)
         }
@@ -1751,6 +1798,72 @@ mod tests {
         assert_pow!((8,     3 ) => 512);
         assert_pow!((2u64,   50) => 1125899906842624);
     }
+
+    #[test]
+    fn test_uint_to_str_overflow() {
+        let mut u8_val: u8 = 255;
+        assert_eq!(u8_val.to_string(), "255");
+
+        u8_val = u8_val.wrapping_add(1);
+        assert_eq!(u8_val.to_string(), "0");
+
+        let mut u16_val: u16 = 65_535;
+        assert_eq!(u16_val.to_string(), "65535");
+
+        u16_val = u16_val.wrapping_add(1);
+        assert_eq!(u16_val.to_string(), "0");
+
+        let mut u32_val: u32 = 4_294_967_295;
+        assert_eq!(u32_val.to_string(), "4294967295");
+
+        u32_val = u32_val.wrapping_add(1);
+        assert_eq!(u32_val.to_string(), "0");
+
+        let mut u64_val: u64 = 18_446_744_073_709_551_615;
+        assert_eq!(u64_val.to_string(), "18446744073709551615");
+
+        u64_val = u64_val.wrapping_add(1);
+        assert_eq!(u64_val.to_string(), "0");
+    }
+
+    fn from_str<T: ::str::FromStr>(t: &str) -> Option<T> {
+        ::str::FromStr::from_str(t).ok()
+    }
+
+    #[test]
+    fn test_uint_from_str_overflow() {
+        let mut u8_val: u8 = 255;
+        assert_eq!(from_str::<u8>("255"), Some(u8_val));
+        assert_eq!(from_str::<u8>("256"), None);
+
+        u8_val = u8_val.wrapping_add(1);
+        assert_eq!(from_str::<u8>("0"), Some(u8_val));
+        assert_eq!(from_str::<u8>("-1"), None);
+
+        let mut u16_val: u16 = 65_535;
+        assert_eq!(from_str::<u16>("65535"), Some(u16_val));
+        assert_eq!(from_str::<u16>("65536"), None);
+
+        u16_val = u16_val.wrapping_add(1);
+        assert_eq!(from_str::<u16>("0"), Some(u16_val));
+        assert_eq!(from_str::<u16>("-1"), None);
+
+        let mut u32_val: u32 = 4_294_967_295;
+        assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
+        assert_eq!(from_str::<u32>("4294967296"), None);
+
+        u32_val = u32_val.wrapping_add(1);
+        assert_eq!(from_str::<u32>("0"), Some(u32_val));
+        assert_eq!(from_str::<u32>("-1"), None);
+
+        let mut u64_val: u64 = 18_446_744_073_709_551_615;
+        assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
+        assert_eq!(from_str::<u64>("18446744073709551616"), None);
+
+        u64_val = u64_val.wrapping_add(1);
+        assert_eq!(from_str::<u64>("0"), Some(u64_val));
+        assert_eq!(from_str::<u64>("-1"), None);
+    }
 }
 
 
@@ -1764,6 +1877,6 @@ mod bench {
     #[bench]
     fn bench_pow_function(b: &mut Bencher) {
         let v = (0..1024).collect::<Vec<_>>();
-        b.iter(|| {v.iter().fold(0, |old, new| old.pow(*new));});
+        b.iter(|| {v.iter().fold(0, |old, new| old.pow(*new as u32));});
     }
 }
index f6d05f961e1736efc5e54908730b70c37ba99463..ea869ebae100a9ca15294e1ed3da6d0d0b32f482 100644 (file)
 // ignore-lexer-test FIXME #15679
 
 #![allow(missing_docs)]
+#![allow(deprecated)]
 
 use self::ExponentFormat::*;
 use self::SignificantDigits::*;
 use self::SignFormat::*;
 
-use char::{self, CharExt};
+use char;
 use num::{self, Int, Float, ToPrimitive};
 use num::FpCategory as Fp;
 use ops::FnMut;
-use slice::SliceExt;
-use str::StrExt;
 use string::String;
 use vec::Vec;
 
 /// A flag that specifies whether to use exponential (scientific) notation.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum ExponentFormat {
     /// Do not use exponential notation.
     ExpNone,
@@ -41,7 +40,7 @@ pub enum ExponentFormat {
 
 /// The number of digits used for emitting the fractional part of a number, if
 /// any.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum SignificantDigits {
     /// All calculable digits will be printed.
     ///
@@ -51,14 +50,14 @@ pub enum SignificantDigits {
 
     /// At most the given number of digits will be printed, truncating any
     /// trailing zeroes.
-    DigMax(uint),
+    DigMax(usize),
 
     /// Precisely the given number of digits will be printed.
-    DigExact(uint)
+    DigExact(usize)
 }
 
 /// How to emit the sign of a number.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum SignFormat {
     /// No sign will be printed. The exponent sign will also be emitted.
     SignNone,
@@ -89,7 +88,7 @@ pub enum SignFormat {
 /// # Panics
 ///
 /// - Panics if `radix` < 2 or `radix` > 36.
-fn int_to_str_bytes_common<T, F>(num: T, radix: uint, sign: SignFormat, mut f: F) where
+fn int_to_str_bytes_common<T, F>(num: T, radix: usize, sign: SignFormat, mut f: F) where
     T: Int,
     F: FnMut(u8),
 {
@@ -104,7 +103,7 @@ fn int_to_str_bytes_common<T, F>(num: T, radix: uint, sign: SignFormat, mut f: F
     // This is just for integral types, the largest of which is a u64. The
     // smallest base that we can have is 2, so the most number of digits we're
     // ever going to have is 64
-    let mut buf = [0u8; 64];
+    let mut buf = [0; 64];
     let mut cur = 0;
 
     // Loop at least once to make sure at least a `0` gets emitted.
@@ -218,13 +217,13 @@ pub fn float_to_str_bytes_common<T: Float>(
 
     let neg = num < _0 || (negative_zero && _1 / num == Float::neg_infinity());
     let mut buf = Vec::new();
-    let radix_gen: T = num::cast(radix as int).unwrap();
+    let radix_gen: T = num::cast(radix as isize).unwrap();
 
     let (num, exp) = match exp_format {
-        ExpNone => (num, 0i32),
+        ExpNone => (num, 0),
         ExpDec | ExpBin => {
             if num == _0 {
-                (num, 0i32)
+                (num, 0)
             } else {
                 let (exp, exp_base) = match exp_format {
                     ExpDec => (num.abs().log10().floor(), num::cast::<f64, T>(10.0f64).unwrap()),
@@ -253,7 +252,7 @@ pub fn float_to_str_bytes_common<T: Float>(
         deccum = deccum / radix_gen;
         deccum = deccum.trunc();
 
-        buf.push(char::from_digit(current_digit.to_int().unwrap() as u32, radix)
+        buf.push(char::from_digit(current_digit.to_isize().unwrap() as u32, radix)
              .unwrap() as u8);
 
         // No more digits to calculate for the non-fractional part -> break
@@ -310,7 +309,7 @@ pub fn float_to_str_bytes_common<T: Float>(
             let current_digit = deccum.trunc().abs();
 
             buf.push(char::from_digit(
-                current_digit.to_int().unwrap() as u32, radix).unwrap() as u8);
+                current_digit.to_isize().unwrap() as u32, radix).unwrap() as u8);
 
             // Decrease the deccumulator one fractional digit at a time
             deccum = deccum.fract();
@@ -330,28 +329,28 @@ pub fn float_to_str_bytes_common<T: Float>(
 
             let extra_digit = ascii2value(buf.pop().unwrap());
             if extra_digit >= radix / 2 { // -> need to round
-                let mut i: int = buf.len() as int - 1;
+                let mut i: isize = buf.len() as isize - 1;
                 loop {
                     // If reached left end of number, have to
                     // insert additional digit:
                     if i < 0
-                    || buf[i as uint] == b'-'
-                    || buf[i as uint] == b'+' {
-                        buf.insert((i + 1) as uint, value2ascii(1));
+                    || buf[i as usize] == b'-'
+                    || buf[i as usize] == b'+' {
+                        buf.insert((i + 1) as usize, value2ascii(1));
                         break;
                     }
 
                     // Skip the '.'
-                    if buf[i as uint] == b'.' { i -= 1; continue; }
+                    if buf[i as usize] == b'.' { i -= 1; continue; }
 
                     // Either increment the digit,
                     // or set to 0 if max and carry the 1.
-                    let current_digit = ascii2value(buf[i as uint]);
+                    let current_digit = ascii2value(buf[i as usize]);
                     if current_digit < (radix - 1) {
-                        buf[i as uint] = value2ascii(current_digit+1);
+                        buf[i as usize] = value2ascii(current_digit+1);
                         break;
                     } else {
-                        buf[i as uint] = value2ascii(0);
+                        buf[i as usize] = value2ascii(0);
                         i -= 1;
                     }
                 }
@@ -422,37 +421,38 @@ pub fn float_to_str_common<T: Float>(
 
 // Some constants for from_str_bytes_common's input validation,
 // they define minimum radix values for which the character is a valid digit.
-static DIGIT_P_RADIX: u32 = ('p' as u32) - ('a' as u32) + 11;
-static DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
+const DIGIT_P_RADIX: u32 = ('p' as u32) - ('a' as u32) + 11;
+const DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
 
 #[cfg(test)]
 mod tests {
+    use core::num::wrapping::WrappingOps;
     use string::ToString;
 
     #[test]
     fn test_int_to_str_overflow() {
-        let mut i8_val: i8 = 127_i8;
+        let mut i8_val: i8 = 127;
         assert_eq!(i8_val.to_string(), "127");
 
-        i8_val += 1 as i8;
+        i8_val = i8_val.wrapping_add(1);
         assert_eq!(i8_val.to_string(), "-128");
 
-        let mut i16_val: i16 = 32_767_i16;
+        let mut i16_val: i16 = 32_767;
         assert_eq!(i16_val.to_string(), "32767");
 
-        i16_val += 1 as i16;
+        i16_val = i16_val.wrapping_add(1);
         assert_eq!(i16_val.to_string(), "-32768");
 
-        let mut i32_val: i32 = 2_147_483_647_i32;
+        let mut i32_val: i32 = 2_147_483_647;
         assert_eq!(i32_val.to_string(), "2147483647");
 
-        i32_val += 1 as i32;
+        i32_val = i32_val.wrapping_add(1);
         assert_eq!(i32_val.to_string(), "-2147483648");
 
-        let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
+        let mut i64_val: i64 = 9_223_372_036_854_775_807;
         assert_eq!(i64_val.to_string(), "9223372036854775807");
 
-        i64_val += 1 as i64;
+        i64_val = i64_val.wrapping_add(1);
         assert_eq!(i64_val.to_string(), "-9223372036854775808");
     }
 }
@@ -462,85 +462,85 @@ mod bench {
     #![allow(deprecated)] // rand
     extern crate test;
 
-    mod uint {
+    mod usize {
         use super::test::Bencher;
         use rand::{weak_rng, Rng};
         use std::fmt;
 
         #[inline]
-        fn to_string(x: uint, base: u8) {
+        fn to_string(x: usize, base: u8) {
             format!("{}", fmt::radix(x, base));
         }
 
         #[bench]
         fn to_str_bin(b: &mut Bencher) {
             let mut rng = weak_rng();
-            b.iter(|| { to_string(rng.gen::<uint>(), 2); })
+            b.iter(|| { to_string(rng.gen::<usize>(), 2); })
         }
 
         #[bench]
         fn to_str_oct(b: &mut Bencher) {
             let mut rng = weak_rng();
-            b.iter(|| { to_string(rng.gen::<uint>(), 8); })
+            b.iter(|| { to_string(rng.gen::<usize>(), 8); })
         }
 
         #[bench]
         fn to_str_dec(b: &mut Bencher) {
             let mut rng = weak_rng();
-            b.iter(|| { to_string(rng.gen::<uint>(), 10); })
+            b.iter(|| { to_string(rng.gen::<usize>(), 10); })
         }
 
         #[bench]
         fn to_str_hex(b: &mut Bencher) {
             let mut rng = weak_rng();
-            b.iter(|| { to_string(rng.gen::<uint>(), 16); })
+            b.iter(|| { to_string(rng.gen::<usize>(), 16); })
         }
 
         #[bench]
         fn to_str_base_36(b: &mut Bencher) {
             let mut rng = weak_rng();
-            b.iter(|| { to_string(rng.gen::<uint>(), 36); })
+            b.iter(|| { to_string(rng.gen::<usize>(), 36); })
         }
     }
 
-    mod int {
+    mod isize {
         use super::test::Bencher;
         use rand::{weak_rng, Rng};
         use std::fmt;
 
         #[inline]
-        fn to_string(x: int, base: u8) {
+        fn to_string(x: isize, base: u8) {
             format!("{}", fmt::radix(x, base));
         }
 
         #[bench]
         fn to_str_bin(b: &mut Bencher) {
             let mut rng = weak_rng();
-            b.iter(|| { to_string(rng.gen::<int>(), 2); })
+            b.iter(|| { to_string(rng.gen::<isize>(), 2); })
         }
 
         #[bench]
         fn to_str_oct(b: &mut Bencher) {
             let mut rng = weak_rng();
-            b.iter(|| { to_string(rng.gen::<int>(), 8); })
+            b.iter(|| { to_string(rng.gen::<isize>(), 8); })
         }
 
         #[bench]
         fn to_str_dec(b: &mut Bencher) {
             let mut rng = weak_rng();
-            b.iter(|| { to_string(rng.gen::<int>(), 10); })
+            b.iter(|| { to_string(rng.gen::<isize>(), 10); })
         }
 
         #[bench]
         fn to_str_hex(b: &mut Bencher) {
             let mut rng = weak_rng();
-            b.iter(|| { to_string(rng.gen::<int>(), 16); })
+            b.iter(|| { to_string(rng.gen::<isize>(), 16); })
         }
 
         #[bench]
         fn to_str_base_36(b: &mut Bencher) {
             let mut rng = weak_rng();
-            b.iter(|| { to_string(rng.gen::<int>(), 36); })
+            b.iter(|| { to_string(rng.gen::<isize>(), 36); })
         }
     }
 
diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs
deleted file mode 100644 (file)
index c7b4913..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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.
-//
-// 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.
-
-//! Deprecated: replaced by `usize`.
-//!
-//! The rollout of the new type will gradually take place over the
-//! alpha cycle along with the development of clearer conventions
-//! around integer types.
-
-#![unstable(feature = "std_misc")]
-#![deprecated(since = "1.0.0", reason = "replaced by usize")]
-
-pub use core::uint::{BITS, BYTES, MIN, MAX};
-
-uint_module! { uint }
index 8d4f0344beb62b767bc92927bceb3306ce63708f..c9e6a8f66d1d25cb01e50a4a67c9f20873cdfbbb 100644 (file)
@@ -48,68 +48,6 @@ mod tests {
         assert_eq!(FromStrRadix::from_str_radix("Z", 10).ok(), None::<$T>);
         assert_eq!(FromStrRadix::from_str_radix("_", 2).ok(), None::<$T>);
     }
-
-    #[test]
-    fn test_uint_to_str_overflow() {
-        let mut u8_val: u8 = 255_u8;
-        assert_eq!(u8_val.to_string(), "255");
-
-        u8_val += 1 as u8;
-        assert_eq!(u8_val.to_string(), "0");
-
-        let mut u16_val: u16 = 65_535_u16;
-        assert_eq!(u16_val.to_string(), "65535");
-
-        u16_val += 1 as u16;
-        assert_eq!(u16_val.to_string(), "0");
-
-        let mut u32_val: u32 = 4_294_967_295_u32;
-        assert_eq!(u32_val.to_string(), "4294967295");
-
-        u32_val += 1 as u32;
-        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");
-
-        u64_val += 1 as u64;
-        assert_eq!(u64_val.to_string(), "0");
-    }
-
-    #[test]
-    fn test_uint_from_str_overflow() {
-        let mut u8_val: u8 = 255_u8;
-        assert_eq!(from_str::<u8>("255"), Some(u8_val));
-        assert_eq!(from_str::<u8>("256"), None);
-
-        u8_val += 1 as u8;
-        assert_eq!(from_str::<u8>("0"), Some(u8_val));
-        assert_eq!(from_str::<u8>("-1"), None);
-
-        let mut u16_val: u16 = 65_535_u16;
-        assert_eq!(from_str::<u16>("65535"), Some(u16_val));
-        assert_eq!(from_str::<u16>("65536"), None);
-
-        u16_val += 1 as u16;
-        assert_eq!(from_str::<u16>("0"), Some(u16_val));
-        assert_eq!(from_str::<u16>("-1"), None);
-
-        let mut u32_val: u32 = 4_294_967_295_u32;
-        assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
-        assert_eq!(from_str::<u32>("4294967296"), None);
-
-        u32_val += 1 as u32;
-        assert_eq!(from_str::<u32>("0"), Some(u32_val));
-        assert_eq!(from_str::<u32>("-1"), None);
-
-        let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
-        assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
-        assert_eq!(from_str::<u64>("18446744073709551616"), None);
-
-        u64_val += 1 as u64;
-        assert_eq!(from_str::<u64>("0"), Some(u64_val));
-        assert_eq!(from_str::<u64>("-1"), None);
-    }
 }
 
 ) }
index 2d2d0d8b33a4c9e68ef0bf00e7f2511b878d7b22..68aa7e4770f067e3cada0738e0256ac7381d242a 100644 (file)
 use cmp;
 use fmt;
 use old_io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
-use iter::{IteratorExt, ExactSizeIterator, repeat};
+use iter::{Iterator, ExactSizeIterator, repeat};
 use ops::Drop;
 use option::Option;
 use option::Option::{Some, None};
 use result::Result::Ok;
-use slice::{SliceExt};
 use slice;
 use vec::Vec;
 
@@ -31,10 +30,12 @@ use vec::Vec;
 /// `BufferedReader` performs large, infrequent reads on the underlying
 /// `Reader` and maintains an in-memory buffer of the results.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
-/// use std::old_io::{BufferedReader, File};
+/// ```
+/// # #![feature(old_io, old_path)]
+/// use std::old_io::*;
+/// use std::old_path::Path;
 ///
 /// let file = File::open(&Path::new("message.txt"));
 /// let mut reader = BufferedReader::new(file);
@@ -48,8 +49,8 @@ use vec::Vec;
 pub struct BufferedReader<R> {
     inner: R,
     buf: Vec<u8>,
-    pos: uint,
-    cap: uint,
+    pos: usize,
+    cap: usize,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -62,7 +63,7 @@ impl<R> fmt::Debug for BufferedReader<R> where R: fmt::Debug {
 
 impl<R: Reader> BufferedReader<R> {
     /// Creates a new `BufferedReader` with the specified buffer capacity
-    pub fn with_capacity(cap: uint, inner: R) -> BufferedReader<R> {
+    pub fn with_capacity(cap: usize, inner: R) -> BufferedReader<R> {
         BufferedReader {
             inner: inner,
             // We can't use the same trick here as we do for BufferedWriter,
@@ -103,21 +104,21 @@ impl<R: Reader> Buffer for BufferedReader<R> {
         Ok(&self.buf[self.pos..self.cap])
     }
 
-    fn consume(&mut self, amt: uint) {
+    fn consume(&mut self, amt: usize) {
         self.pos += amt;
         assert!(self.pos <= self.cap);
     }
 }
 
 impl<R: Reader> Reader for BufferedReader<R> {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         if self.pos == self.cap && buf.len() >= self.buf.len() {
             return self.inner.read(buf);
         }
         let nread = {
             let available = try!(self.fill_buf());
             let nread = cmp::min(available.len(), buf.len());
-            slice::bytes::copy_memory(buf, &available[..nread]);
+            slice::bytes::copy_memory(&available[..nread], buf);
             nread
         };
         self.pos += nread;
@@ -134,10 +135,12 @@ impl<R: Reader> Reader for BufferedReader<R> {
 ///
 /// This writer will be flushed when it is dropped.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
-/// use std::old_io::{BufferedWriter, File};
+/// ```
+/// # #![feature(old_io, old_path)]
+/// use std::old_io::*;
+/// use std::old_path::Path;
 ///
 /// let file = File::create(&Path::new("message.txt")).unwrap();
 /// let mut writer = BufferedWriter::new(file);
@@ -145,14 +148,14 @@ impl<R: Reader> Reader for BufferedReader<R> {
 /// writer.write_str("hello, world").unwrap();
 /// writer.flush().unwrap();
 /// ```
-pub struct BufferedWriter<W> {
+pub struct BufferedWriter<W: Writer> {
     inner: Option<W>,
     buf: Vec<u8>,
-    pos: uint
+    pos: usize
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W> fmt::Debug for BufferedWriter<W> where W: fmt::Debug {
+impl<W: Writer> fmt::Debug for BufferedWriter<W> where W: fmt::Debug {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         write!(fmt, "BufferedWriter {{ writer: {:?}, buffer: {}/{} }}",
                self.inner.as_ref().unwrap(), self.pos, self.buf.len())
@@ -161,7 +164,7 @@ impl<W> fmt::Debug for BufferedWriter<W> where W: fmt::Debug {
 
 impl<W: Writer> BufferedWriter<W> {
     /// Creates a new `BufferedWriter` with the specified buffer capacity
-    pub fn with_capacity(cap: uint, inner: W) -> BufferedWriter<W> {
+    pub fn with_capacity(cap: usize, inner: W) -> BufferedWriter<W> {
         // It's *much* faster to create an uninitialized buffer than it is to
         // fill everything in with 0. This buffer is entirely an implementation
         // detail and is never exposed, so we're safe to not initialize
@@ -222,7 +225,7 @@ impl<W: Writer> Writer for BufferedWriter<W> {
             self.inner.as_mut().unwrap().write_all(buf)
         } else {
             let dst = &mut self.buf[self.pos..];
-            slice::bytes::copy_memory(dst, buf);
+            slice::bytes::copy_memory(buf, dst);
             self.pos += buf.len();
             Ok(())
         }
@@ -247,12 +250,12 @@ impl<W: Writer> Drop for BufferedWriter<W> {
 /// `'\n'`) is detected.
 ///
 /// This writer will be flushed when it is dropped.
-pub struct LineBufferedWriter<W> {
+pub struct LineBufferedWriter<W: Writer> {
     inner: BufferedWriter<W>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<W> fmt::Debug for LineBufferedWriter<W> where W: fmt::Debug {
+impl<W: Writer> fmt::Debug for LineBufferedWriter<W> where W: fmt::Debug {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         write!(fmt, "LineBufferedWriter {{ writer: {:?}, buffer: {}/{} }}",
                self.inner.inner, self.inner.pos, self.inner.buf.len())
@@ -296,17 +299,17 @@ impl<W: Writer> Writer for LineBufferedWriter<W> {
     fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
 }
 
-struct InternalBufferedWriter<W>(BufferedWriter<W>);
+struct InternalBufferedWriter<W: Writer>(BufferedWriter<W>);
 
-impl<W> InternalBufferedWriter<W> {
+impl<W: Writer> InternalBufferedWriter<W> {
     fn get_mut<'a>(&'a mut self) -> &'a mut BufferedWriter<W> {
         let InternalBufferedWriter(ref mut w) = *self;
         return w;
     }
 }
 
-impl<W: Reader> Reader for InternalBufferedWriter<W> {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+impl<W: Reader + Writer> Reader for InternalBufferedWriter<W> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         self.get_mut().inner.as_mut().unwrap().read(buf)
     }
 }
@@ -320,11 +323,13 @@ impl<W: Reader> Reader for InternalBufferedWriter<W> {
 ///
 /// The output half will be flushed when this stream is dropped.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(old_io, old_path)]
 /// # #![allow(unused_must_use)]
-/// use std::old_io::{BufferedStream, File};
+/// use std::old_io::*;
+/// use std::old_path::Path;
 ///
 /// let file = File::open(&Path::new("message.txt"));
 /// let mut stream = BufferedStream::new(file);
@@ -338,12 +343,12 @@ impl<W: Reader> Reader for InternalBufferedWriter<W> {
 ///     Err(e) => println!("error reading: {}", e)
 /// }
 /// ```
-pub struct BufferedStream<S> {
+pub struct BufferedStream<S: Writer> {
     inner: BufferedReader<InternalBufferedWriter<S>>
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<S> fmt::Debug for BufferedStream<S> where S: fmt::Debug {
+impl<S: Writer> fmt::Debug for BufferedStream<S> where S: fmt::Debug {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let reader = &self.inner;
         let writer = &self.inner.inner.0;
@@ -357,7 +362,7 @@ impl<S> fmt::Debug for BufferedStream<S> where S: fmt::Debug {
 impl<S: Stream> BufferedStream<S> {
     /// Creates a new buffered stream with explicitly listed capacities for the
     /// reader/writer buffer.
-    pub fn with_capacities(reader_cap: uint, writer_cap: uint, inner: S)
+    pub fn with_capacities(reader_cap: usize, writer_cap: usize, inner: S)
                            -> BufferedStream<S> {
         let writer = BufferedWriter::with_capacity(writer_cap, inner);
         let internal_writer = InternalBufferedWriter(writer);
@@ -402,11 +407,11 @@ impl<S: Stream> BufferedStream<S> {
 
 impl<S: Stream> Buffer for BufferedStream<S> {
     fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
-    fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
+    fn consume(&mut self, amt: usize) { self.inner.consume(amt) }
 }
 
 impl<S: Stream> Reader for BufferedStream<S> {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         self.inner.read(buf)
     }
 }
@@ -423,7 +428,7 @@ impl<S: Stream> Writer for BufferedStream<S> {
 #[cfg(test)]
 mod test {
     extern crate test;
-    use old_io;
+    use old_io::{self, Reader, Writer, Buffer, BufferPrelude};
     use prelude::v1::*;
     use super::*;
     use super::super::{IoResult, EndOfFile};
@@ -437,7 +442,7 @@ mod test {
     pub struct NullStream;
 
     impl Reader for NullStream {
-        fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<uint> {
+        fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
             Err(old_io::standard_error(old_io::EndOfFile))
         }
     }
@@ -448,11 +453,11 @@ mod test {
 
     /// A dummy reader intended at testing short-reads propagation.
     pub struct ShortReader {
-        lengths: Vec<uint>,
+        lengths: Vec<usize>,
     }
 
     impl Reader for ShortReader {
-        fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<uint> {
+        fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
             if self.lengths.is_empty() {
                 Err(old_io::standard_error(old_io::EndOfFile))
             } else {
@@ -505,37 +510,37 @@ mod test {
 
         writer.write_all(&[0, 1]).unwrap();
         let b: &[_] = &[];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
 
         writer.write_all(&[2]).unwrap();
         let b: &[_] = &[0, 1];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
 
         writer.write_all(&[3]).unwrap();
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
 
         writer.flush().unwrap();
         let a: &[_] = &[0, 1, 2, 3];
-        assert_eq!(a, &writer.get_ref()[]);
+        assert_eq!(a, &writer.get_ref()[..]);
 
         writer.write_all(&[4]).unwrap();
         writer.write_all(&[5]).unwrap();
-        assert_eq!(a, &writer.get_ref()[]);
+        assert_eq!(a, &writer.get_ref()[..]);
 
         writer.write_all(&[6]).unwrap();
         let a: &[_] = &[0, 1, 2, 3, 4, 5];
-        assert_eq!(a, &writer.get_ref()[]);
+        assert_eq!(a, &writer.get_ref()[..]);
 
         writer.write_all(&[7, 8]).unwrap();
         let a: &[_] = &[0, 1, 2, 3, 4, 5, 6];
-        assert_eq!(a, &writer.get_ref()[]);
+        assert_eq!(a, &writer.get_ref()[..]);
 
         writer.write_all(&[9, 10, 11]).unwrap();
         let a: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
-        assert_eq!(a, &writer.get_ref()[]);
+        assert_eq!(a, &writer.get_ref()[..]);
 
         writer.flush().unwrap();
-        assert_eq!(a, &writer.get_ref()[]);
+        assert_eq!(a, &writer.get_ref()[..]);
     }
 
     #[test]
@@ -543,7 +548,7 @@ mod test {
         let mut w = BufferedWriter::with_capacity(3, Vec::new());
         w.write_all(&[0, 1]).unwrap();
         let a: &[_] = &[];
-        assert_eq!(a, &w.get_ref()[]);
+        assert_eq!(&w.get_ref()[..], a);
         let w = w.into_inner();
         let a: &[_] = &[0, 1];
         assert_eq!(a, &w[..]);
@@ -560,7 +565,7 @@ mod test {
         }
 
         impl old_io::Reader for S {
-            fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<uint> {
+            fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
                 Err(old_io::standard_error(old_io::EndOfFile))
             }
         }
@@ -588,21 +593,21 @@ mod test {
         let mut writer = LineBufferedWriter::new(Vec::new());
         writer.write_all(&[0]).unwrap();
         let b: &[_] = &[];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
         writer.write_all(&[1]).unwrap();
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
         writer.flush().unwrap();
         let b: &[_] = &[0, 1];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
         writer.write_all(&[0, b'\n', 1, b'\n', 2]).unwrap();
         let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n'];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
         writer.flush().unwrap();
         let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n', 2];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
         writer.write_all(&[3, b'\n']).unwrap();
         let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n'];
-        assert_eq!(&writer.get_ref()[], b);
+        assert_eq!(&writer.get_ref()[..], b);
     }
 
     #[test]
@@ -642,14 +647,14 @@ mod test {
 
     #[test]
     fn read_char_buffered() {
-        let buf = [195u8, 159u8];
+        let buf = [195, 159];
         let mut reader = BufferedReader::with_capacity(1, &buf[..]);
         assert_eq!(reader.read_char(), Ok('ß'));
     }
 
     #[test]
     fn test_chars() {
-        let buf = [195u8, 159u8, b'a'];
+        let buf = [195, 159, b'a'];
         let mut reader = BufferedReader::with_capacity(1, &buf[..]);
         let mut it = reader.chars();
         assert_eq!(it.next(), Some(Ok('ß')));
@@ -658,7 +663,7 @@ mod test {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn dont_panic_in_drop_on_panicked_flush() {
         struct FailFlushWriter;
 
index 207d3d39167660b929225e667725357d166a1b63..5ebf931e95c375f60f2358faae6b3112b756c3a8 100644 (file)
@@ -14,23 +14,24 @@ use sync::mpsc::{Sender, Receiver};
 use old_io;
 use option::Option::{None, Some};
 use result::Result::{Ok, Err};
-use slice::{bytes, SliceExt};
+use slice::bytes;
 use super::{Buffer, Reader, Writer, IoResult};
 use vec::Vec;
 
 /// Allows reading from a rx.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
+/// # #![feature(old_io)]
 /// use std::sync::mpsc::channel;
-/// use std::old_io::ChanReader;
+/// use std::old_io::*;
 ///
 /// let (tx, rx) = channel();
 /// # drop(tx);
 /// let mut reader = ChanReader::new(rx);
 ///
-/// let mut buf = [0u8; 100];
+/// let mut buf = [0; 100];
 /// match reader.read(&mut buf) {
 ///     Ok(nread) => println!("Read {} bytes", nread),
 ///     Err(e) => println!("read error: {}", e),
@@ -38,7 +39,7 @@ use vec::Vec;
 /// ```
 pub struct ChanReader {
     buf: Vec<u8>,          // A buffer of bytes received but not consumed.
-    pos: uint,             // How many of the buffered bytes have already be consumed.
+    pos: usize,             // How many of the buffered bytes have already be consumed.
     rx: Receiver<Vec<u8>>, // The Receiver to pull data from.
     closed: bool,          // Whether the channel this Receiver connects to has been closed.
 }
@@ -76,21 +77,21 @@ impl Buffer for ChanReader {
         }
     }
 
-    fn consume(&mut self, amt: uint) {
+    fn consume(&mut self, amt: usize) {
         self.pos += amt;
         assert!(self.pos <= self.buf.len());
     }
 }
 
 impl Reader for ChanReader {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         let mut num_read = 0;
         loop {
             let count = match self.fill_buf().ok() {
                 Some(src) => {
                     let dst = &mut buf[num_read..];
                     let count = cmp::min(src.len(), dst.len());
-                    bytes::copy_memory(dst, &src[..count]);
+                    bytes::copy_memory(&src[..count], dst);
                     count
                 },
                 None => 0,
@@ -111,12 +112,13 @@ impl Reader for ChanReader {
 
 /// Allows writing to a tx.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
+/// # #![feature(old_io, io)]
 /// # #![allow(unused_must_use)]
 /// use std::sync::mpsc::channel;
-/// use std::old_io::ChanWriter;
+/// use std::old_io::*;
 ///
 /// let (tx, rx) = channel();
 /// # drop(rx);
@@ -160,22 +162,22 @@ mod test {
 
     use sync::mpsc::channel;
     use super::*;
-    use old_io;
+    use old_io::{self, Reader, Writer, Buffer};
     use thread;
 
     #[test]
     fn test_rx_reader() {
         let (tx, rx) = channel();
         thread::spawn(move|| {
-          tx.send(vec![1u8, 2u8]).unwrap();
+          tx.send(vec![1, 2]).unwrap();
           tx.send(vec![]).unwrap();
-          tx.send(vec![3u8, 4u8]).unwrap();
-          tx.send(vec![5u8, 6u8]).unwrap();
-          tx.send(vec![7u8, 8u8]).unwrap();
+          tx.send(vec![3, 4]).unwrap();
+          tx.send(vec![5, 6]).unwrap();
+          tx.send(vec![78]).unwrap();
         });
 
         let mut reader = ChanReader::new(rx);
-        let mut buf = [0u8; 3];
+        let mut buf = [0; 3];
 
         assert_eq!(Ok(0), reader.read(&mut []));
 
@@ -233,7 +235,7 @@ mod test {
         let mut writer = ChanWriter::new(tx);
         writer.write_be_u32(42).unwrap();
 
-        let wanted = vec![0u8, 0u8, 0u8, 42u8];
+        let wanted = vec![0, 0, 0, 42];
         let got = thread::scoped(move|| { rx.recv().unwrap() }).join();
         assert_eq!(wanted, got);
 
index c2a6c515acc70b2978fdcd1f494884127549bc25..73973d0db282d26c92c8adc059d46bb0f1c5dc96 100644 (file)
 //! Utility mixins that apply to all Readers and Writers
 
 #![allow(missing_docs)]
+#![unstable(feature = "old_io")]
+#![deprecated(since = "1.0.0",
+              reason = "functionality will be removed with no immediate \
+                        replacement")]
 
 // FIXME: Not sure how this should be structured
 // FIXME: Iteration should probably be considered separately
@@ -22,9 +26,7 @@ use num::Int;
 use ops::FnOnce;
 use option::Option;
 use option::Option::{Some, None};
-use ptr::PtrExt;
 use result::Result::{Ok, Err};
-use slice::SliceExt;
 
 /// An iterator that reads a single byte on each iteration,
 /// until `.read_byte()` returns `EndOfFile`.
@@ -79,7 +81,7 @@ impl<'r, R: Reader> Iterator for Bytes<'r, R> {
 /// * `f`: A callback that receives the value.
 ///
 /// This function returns the value returned by the callback, for convenience.
-pub fn u64_to_le_bytes<T, F>(n: u64, size: uint, f: F) -> T where
+pub fn u64_to_le_bytes<T, F>(n: u64, size: usize, f: F) -> T where
     F: FnOnce(&[u8]) -> T,
 {
     use mem::transmute;
@@ -97,7 +99,7 @@ pub fn u64_to_le_bytes<T, F>(n: u64, size: uint, f: F) -> T where
         let mut i = size;
         let mut n = n;
         while i > 0 {
-            bytes.push((n & 255_u64) as u8);
+            bytes.push((n & 255) as u8);
             n >>= 8;
             i -= 1;
         }
@@ -120,7 +122,7 @@ pub fn u64_to_le_bytes<T, F>(n: u64, size: uint, f: F) -> T where
 /// * `f`: A callback that receives the value.
 ///
 /// This function returns the value returned by the callback, for convenience.
-pub fn u64_to_be_bytes<T, F>(n: u64, size: uint, f: F) -> T where
+pub fn u64_to_be_bytes<T, F>(n: u64, size: usize, f: F) -> T where
     F: FnOnce(&[u8]) -> T,
 {
     use mem::transmute;
@@ -156,9 +158,8 @@ pub fn u64_to_be_bytes<T, F>(n: u64, size: uint, f: F) -> T where
 ///           less, or task panic occurs. If this is less than 8, then only
 ///           that many bytes are parsed. For example, if `size` is 4, then a
 ///           32-bit value is parsed.
-pub fn u64_from_be_bytes(data: &[u8], start: uint, size: uint) -> u64 {
-    use ptr::{copy_nonoverlapping_memory};
-    use slice::SliceExt;
+pub fn u64_from_be_bytes(data: &[u8], start: usize, size: usize) -> u64 {
+    use ptr::{copy_nonoverlapping};
 
     assert!(size <= 8);
 
@@ -166,11 +167,11 @@ pub fn u64_from_be_bytes(data: &[u8], start: uint, size: uint) -> u64 {
         panic!("index out of bounds");
     }
 
-    let mut buf = [0u8; 8];
+    let mut buf = [0; 8];
     unsafe {
-        let ptr = data.as_ptr().offset(start as int);
+        let ptr = data.as_ptr().offset(start as isize);
         let out = buf.as_mut_ptr();
-        copy_nonoverlapping_memory(out.offset((8 - size) as int), ptr, size);
+        copy_nonoverlapping(ptr, out.offset((8 - size) as isize), size);
         (*(out as *const u64)).to_be()
     }
 }
@@ -178,15 +179,15 @@ pub fn u64_from_be_bytes(data: &[u8], start: uint, size: uint) -> u64 {
 #[cfg(test)]
 mod test {
     use prelude::v1::*;
-    use old_io;
+    use old_io::{self, Reader, Writer};
     use old_io::{MemReader, BytesReader};
 
     struct InitialZeroByteReader {
-        count: int,
+        count: isize,
     }
 
     impl Reader for InitialZeroByteReader {
-        fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
+        fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<usize> {
             if self.count == 0 {
                 self.count = 1;
                 Ok(0)
@@ -200,7 +201,7 @@ mod test {
     struct EofReader;
 
     impl Reader for EofReader {
-        fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<uint> {
+        fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
             Err(old_io::standard_error(old_io::EndOfFile))
         }
     }
@@ -208,17 +209,17 @@ mod test {
     struct ErroringReader;
 
     impl Reader for ErroringReader {
-        fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<uint> {
+        fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
             Err(old_io::standard_error(old_io::InvalidInput))
         }
     }
 
     struct PartialReader {
-        count: int,
+        count: isize,
     }
 
     impl Reader for PartialReader {
-        fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
+        fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<usize> {
             if self.count == 0 {
                 self.count = 1;
                 buf[0] = 10;
@@ -233,11 +234,11 @@ mod test {
     }
 
     struct ErroringLaterReader {
-        count: int,
+        count: isize,
     }
 
     impl Reader for ErroringLaterReader {
-        fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
+        fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<usize> {
             if self.count == 0 {
                 self.count = 1;
                 buf[0] = 10;
@@ -249,11 +250,11 @@ mod test {
     }
 
     struct ThreeChunkReader {
-        count: int,
+        count: isize,
     }
 
     impl Reader for ThreeChunkReader {
-        fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
+        fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<usize> {
             if self.count == 0 {
                 self.count = 1;
                 buf[0] = 10;
@@ -328,7 +329,7 @@ mod test {
     fn read_bytes() {
         let mut reader = MemReader::new(vec!(10, 11, 12, 13));
         let bytes = reader.read_exact(4).unwrap();
-        assert!(bytes == vec!(10, 11, 12, 13));
+        assert_eq!(bytes, [10, 11, 12, 13]);
     }
 
     #[test]
@@ -337,7 +338,7 @@ mod test {
             count: 0,
         };
         let bytes = reader.read_exact(4).unwrap();
-        assert!(bytes == vec!(10, 11, 12, 13));
+        assert_eq!(bytes, [10, 11, 12, 13]);
     }
 
     #[test]
@@ -351,7 +352,7 @@ mod test {
         let mut reader = MemReader::new(vec![10, 11, 12, 13]);
         let mut buf = vec![8, 9];
         assert!(reader.push_at_least(4, 4, &mut buf).is_ok());
-        assert!(buf == vec![8, 9, 10, 11, 12, 13]);
+        assert_eq!(buf, [8, 9, 10, 11, 12, 13]);
     }
 
     #[test]
@@ -361,7 +362,7 @@ mod test {
         };
         let mut buf = vec![8, 9];
         assert!(reader.push_at_least(4, 4, &mut buf).is_ok());
-        assert!(buf == vec![8, 9, 10, 11, 12, 13]);
+        assert_eq!(buf, [8, 9, 10, 11, 12, 13]);
     }
 
     #[test]
@@ -369,7 +370,7 @@ mod test {
         let mut reader = MemReader::new(vec![10, 11]);
         let mut buf = vec![8, 9];
         assert!(reader.push_at_least(4, 4, &mut buf).is_err());
-        assert!(buf == vec![8, 9, 10, 11]);
+        assert_eq!(buf, [8, 9, 10, 11]);
     }
 
     #[test]
@@ -379,7 +380,7 @@ mod test {
         };
         let mut buf = vec![8, 9];
         assert!(reader.push_at_least(4, 4, &mut buf).is_err());
-        assert!(buf == vec![8, 9, 10]);
+        assert_eq!(buf, [8, 9, 10]);
     }
 
     #[test]
@@ -388,17 +389,17 @@ mod test {
             count: 0,
         };
         let buf = reader.read_to_end().unwrap();
-        assert!(buf == vec!(10, 11, 12, 13));
+        assert_eq!(buf, [10, 11, 12, 13]);
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn read_to_end_error() {
         let mut reader = ThreeChunkReader {
             count: 0,
         };
         let buf = reader.read_to_end().unwrap();
-        assert!(buf == vec!(10, 11));
+        assert_eq!(buf, [10, 11]);
     }
 
     #[test]
@@ -518,8 +519,9 @@ mod bench {
         ({
             use super::u64_from_be_bytes;
 
-            let data = (0u8..$stride*100+$start_index).collect::<Vec<_>>();
-            let mut sum = 0u64;
+            let len = ($stride as u8).wrapping_mul(100).wrapping_add($start_index);
+            let data = (0..len).collect::<Vec<_>>();
+            let mut sum = 0;
             $b.iter(|| {
                 let mut i = $start_index;
                 while i < data.len() {
index 4e9c1b360552c4ee21d69146e72cf6261ac2bd9e..509daa46ef3be1b509d54da638c27590b8d2dff5 100644 (file)
 //! the metadata of a file. This includes getting the `stat` information,
 //! reading off particular bits of it, etc.
 //!
-//! # Example
+//! # Examples
 //!
 //! ```rust
+//! # #![feature(old_io, io, old_path)]
 //! # #![allow(unused_must_use)]
 //! use std::old_io::fs::PathExtensions;
-//! use std::old_io::{File, fs};
+//! use std::old_io::*;
+//! use std::old_path::Path;
 //!
 //! let path = Path::new("foo.txt");
 //!
@@ -64,7 +66,6 @@ use option::Option::{Some, None};
 use old_path::{Path, GenericPath};
 use old_path;
 use result::Result::{Err, Ok};
-use slice::SliceExt;
 use string::String;
 use vec::Vec;
 
@@ -82,10 +83,12 @@ use sys_common;
 /// attempted against it for which its underlying file descriptor was not
 /// configured at creation time, via the `FileAccess` parameter to
 /// `File::open_mode()`.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::File")]
+#[unstable(feature = "old_io")]
 pub struct File {
     fd: fs_imp::FileDesc,
     path: Path,
-    last_nread: int,
+    last_nread: isize,
 }
 
 impl sys_common::AsInner<fs_imp::FileDesc> for File {
@@ -94,14 +97,18 @@ impl sys_common::AsInner<fs_imp::FileDesc> for File {
     }
 }
 
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+#[unstable(feature = "old_io")]
 impl File {
     /// Open a file at `path` in the mode specified by the `mode` and `access`
     /// arguments
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust,should_fail
-    /// use std::old_io::{File, Open, ReadWrite};
+    /// ```rust,should_panic
+    /// # #![feature(old_io, old_path)]
+    /// use std::old_io::*;
+    /// use std::old_path::Path;
     ///
     /// let p = Path::new("/some/file/path.txt");
     ///
@@ -133,6 +140,8 @@ impl File {
     /// * Attempting to open a file with a `FileAccess` that the user lacks
     ///   permissions for
     /// * Filesystem-level errors (full disk, etc)
+    #[deprecated(since = "1.0.0", reason = "replaced with std::fs::OpenOptions")]
+    #[unstable(feature = "old_io")]
     pub fn open_mode(path: &Path,
                      mode: FileMode,
                      access: FileAccess) -> IoResult<File> {
@@ -167,13 +176,17 @@ impl File {
     ///
     /// For more information, see the `File::open_mode` function.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
-    /// use std::old_io::File;
+    /// ```
+    /// # #![feature(old_io, old_path)]
+    /// use std::old_io::*;
+    /// use std::old_path::Path;
     ///
     /// let contents = File::open(&Path::new("foo.txt")).read_to_end();
     /// ```
+    #[deprecated(since = "1.0.0", reason = "replaced with std::fs::File::open")]
+    #[unstable(feature = "old_io")]
     pub fn open(path: &Path) -> IoResult<File> {
         File::open_mode(path, Open, Read)
     }
@@ -184,23 +197,29 @@ impl File {
     ///
     /// For more information, see the `File::open_mode` function.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(old_io, old_path, io)]
     /// # #![allow(unused_must_use)]
-    /// use std::old_io::File;
+    /// use std::old_io::*;
+    /// use std::old_path::Path;
     ///
     /// let mut f = File::create(&Path::new("foo.txt"));
     /// f.write(b"This is a sample file");
     /// # drop(f);
     /// # ::std::old_io::fs::unlink(&Path::new("foo.txt"));
     /// ```
+    #[deprecated(since = "1.0.0", reason = "replaced with std::fs::File::create")]
+    #[unstable(feature = "old_io")]
     pub fn create(path: &Path) -> IoResult<File> {
         File::open_mode(path, Truncate, Write)
              .update_desc("couldn't create file")
     }
 
     /// Returns the original path that was used to open this file.
+    #[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+    #[unstable(feature = "old_io")]
     pub fn path<'a>(&'a self) -> &'a Path {
         &self.path
     }
@@ -208,6 +227,8 @@ impl File {
     /// Synchronizes all modifications to this file to its permanent storage
     /// device. This will flush any internal buffers necessary to perform this
     /// operation.
+    #[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+    #[unstable(feature = "old_io")]
     pub fn fsync(&mut self) -> IoResult<()> {
         self.fd.fsync()
             .update_err("couldn't fsync file",
@@ -218,6 +239,8 @@ impl File {
     /// file metadata to the filesystem. This is intended for use cases that
     /// must synchronize content, but don't need the metadata on disk. The goal
     /// of this method is to reduce disk operations.
+    #[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+    #[unstable(feature = "old_io")]
     pub fn datasync(&mut self) -> IoResult<()> {
         self.fd.datasync()
             .update_err("couldn't datasync file",
@@ -232,6 +255,8 @@ impl File {
     /// be shrunk. If it is greater than the current file's size, then the file
     /// will be extended to `size` and have all of the intermediate data filled
     /// in with 0s.
+    #[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+    #[unstable(feature = "old_io")]
     pub fn truncate(&mut self, size: i64) -> IoResult<()> {
         self.fd.truncate(size)
             .update_err("couldn't truncate file", |e|
@@ -247,11 +272,15 @@ impl File {
     /// until you have attempted to read past the end of the file, so if
     /// you've read _exactly_ the number of bytes in the file, this will
     /// return `false`, not `true`.
+    #[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+    #[unstable(feature = "old_io")]
     pub fn eof(&self) -> bool {
         self.last_nread == 0
     }
 
     /// Queries information about the underlying file.
+    #[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+    #[unstable(feature = "old_io")]
     pub fn stat(&self) -> IoResult<FileStat> {
         self.fd.fstat()
             .update_err("couldn't fstat file", |e|
@@ -261,11 +290,13 @@ impl File {
 
 /// Unlink a file from the underlying filesystem.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(old_io, old_path)]
 /// # #![allow(unused_must_use)]
-/// use std::old_io::fs;
+/// use std::old_io::*;
+/// use std::old_path::Path;
 ///
 /// let p = Path::new("/some/file/path.txt");
 /// fs::unlink(&p);
@@ -280,6 +311,8 @@ impl File {
 /// This function will return an error if `path` points to a directory, if the
 /// user lacks permissions to remove the file, or if some other filesystem-level
 /// error occurs.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_file")]
+#[unstable(feature = "old_io")]
 pub fn unlink(path: &Path) -> IoResult<()> {
     fs_imp::unlink(path)
            .update_err("couldn't unlink path", |e|
@@ -290,10 +323,12 @@ pub fn unlink(path: &Path) -> IoResult<()> {
 /// directory, etc. This function will traverse symlinks to query
 /// information about the destination file.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
-/// use std::old_io::fs;
+/// ```
+/// # #![feature(old_io, old_path)]
+/// use std::old_io::*;
+/// use std::old_path::Path;
 ///
 /// let p = Path::new("/some/file/path.txt");
 /// match fs::stat(&p) {
@@ -307,6 +342,8 @@ pub fn unlink(path: &Path) -> IoResult<()> {
 /// This function will return an error if the user lacks the requisite permissions
 /// to perform a `stat` call on the given `path` or if there is no entry in the
 /// filesystem at the provided path.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::metadata")]
+#[unstable(feature = "old_io")]
 pub fn stat(path: &Path) -> IoResult<FileStat> {
     fs_imp::stat(path)
            .update_err("couldn't stat path", |e|
@@ -321,6 +358,7 @@ pub fn stat(path: &Path) -> IoResult<FileStat> {
 /// # Error
 ///
 /// See `stat`
+#[unstable(feature = "old_fs")]
 pub fn lstat(path: &Path) -> IoResult<FileStat> {
     fs_imp::lstat(path)
            .update_err("couldn't lstat path", |e|
@@ -329,11 +367,13 @@ pub fn lstat(path: &Path) -> IoResult<FileStat> {
 
 /// Rename a file or directory to a new name.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(old_io, old_path)]
 /// # #![allow(unused_must_use)]
-/// use std::old_io::fs;
+/// use std::old_io::*;
+/// use std::old_path::Path;
 ///
 /// fs::rename(&Path::new("foo"), &Path::new("bar"));
 /// ```
@@ -343,6 +383,8 @@ pub fn lstat(path: &Path) -> IoResult<FileStat> {
 /// This function will return an error if the provided `from` doesn't exist, if
 /// the process lacks permissions to view the contents, or if some other
 /// intermittent I/O error occurs.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::rename")]
+#[unstable(feature = "old_io")]
 pub fn rename(from: &Path, to: &Path) -> IoResult<()> {
     fs_imp::rename(from, to)
            .update_err("couldn't rename path", |e|
@@ -355,11 +397,13 @@ pub fn rename(from: &Path, to: &Path) -> IoResult<()> {
 /// Note that if `from` and `to` both point to the same file, then the file
 /// will likely get truncated by this operation.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(old_io, old_path)]
 /// # #![allow(unused_must_use)]
-/// use std::old_io::fs;
+/// use std::old_io::*;
+/// use std::old_path::Path;
 ///
 /// fs::copy(&Path::new("foo.txt"), &Path::new("bar.txt"));
 /// ```
@@ -377,6 +421,8 @@ pub fn rename(from: &Path, to: &Path) -> IoResult<()> {
 /// Note that this copy is not atomic in that once the destination is
 /// ensured to not exist, there is nothing preventing the destination from
 /// being created and then destroyed by this operation.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::copy")]
+#[unstable(feature = "old_io")]
 pub fn copy(from: &Path, to: &Path) -> IoResult<()> {
     fn update_err<T>(result: IoResult<T>, from: &Path, to: &Path) -> IoResult<T> {
         result.update_err("couldn't copy path", |e| {
@@ -403,12 +449,14 @@ pub fn copy(from: &Path, to: &Path) -> IoResult<()> {
 /// Changes the permission mode bits found on a file or a directory. This
 /// function takes a mask from the `io` module
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(old_io, old_path)]
 /// # #![allow(unused_must_use)]
 /// use std::old_io;
-/// use std::old_io::fs;
+/// use std::old_io::*;
+/// use std::old_path::Path;
 ///
 /// fs::chmod(&Path::new("file.txt"), old_io::USER_FILE);
 /// fs::chmod(&Path::new("file.txt"), old_io::USER_READ | old_io::USER_WRITE);
@@ -421,14 +469,17 @@ pub fn copy(from: &Path, to: &Path) -> IoResult<()> {
 /// This function will return an error if the provided `path` doesn't exist, if
 /// the process lacks permissions to change the attributes of the file, or if
 /// some other I/O error is encountered.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::set_permissions")]
+#[unstable(feature = "old_io")]
 pub fn chmod(path: &Path, mode: old_io::FilePermission) -> IoResult<()> {
-    fs_imp::chmod(path, mode.bits() as uint)
+    fs_imp::chmod(path, mode.bits() as usize)
            .update_err("couldn't chmod path", |e|
                format!("{}; path={}; mode={:?}", e, path.display(), mode))
 }
 
 /// Change the user and group owners of a file at the specified path.
-pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> {
+#[unstable(feature = "old_fs")]
+pub fn chown(path: &Path, uid: isize, gid: isize) -> IoResult<()> {
     fs_imp::chown(path, uid, gid)
            .update_err("couldn't chown path", |e|
                format!("{}; path={}; uid={}; gid={}", e, path.display(), uid, gid))
@@ -437,6 +488,8 @@ pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> {
 /// Creates a new hard link on the filesystem. The `dst` path will be a
 /// link pointing to the `src` path. Note that systems often require these
 /// two paths to both be located on the same filesystem.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::hard_link")]
+#[unstable(feature = "old_io")]
 pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
     fs_imp::link(src, dst)
            .update_err("couldn't link path", |e|
@@ -445,6 +498,8 @@ pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
 
 /// Creates a new symbolic link on the filesystem. The `dst` path will be a
 /// symlink pointing to the `src` path.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::soft_link")]
+#[unstable(feature = "old_io")]
 pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
     fs_imp::symlink(src, dst)
            .update_err("couldn't symlink path", |e|
@@ -457,6 +512,8 @@ pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
 ///
 /// This function will return an error on failure. Failure conditions include
 /// reading a file that does not exist or reading a file that is not a symlink.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::read_link")]
+#[unstable(feature = "old_io")]
 pub fn readlink(path: &Path) -> IoResult<Path> {
     fs_imp::readlink(path)
            .update_err("couldn't resolve symlink for path", |e|
@@ -465,12 +522,14 @@ pub fn readlink(path: &Path) -> IoResult<Path> {
 
 /// Create a new, empty directory at the provided path
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(old_io, old_path, old_fs)]
 /// # #![allow(unused_must_use)]
 /// use std::old_io;
-/// use std::old_io::fs;
+/// use std::old_io::*;
+/// use std::old_path::Path;
 ///
 /// let p = Path::new("/some/dir");
 /// fs::mkdir(&p, old_io::USER_RWX);
@@ -480,19 +539,22 @@ pub fn readlink(path: &Path) -> IoResult<Path> {
 ///
 /// This function will return an error if the user lacks permissions to make a
 /// new directory at the provided `path`, or if the directory already exists.
+#[unstable(feature = "old_fs")]
 pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> {
-    fs_imp::mkdir(path, mode.bits() as uint)
+    fs_imp::mkdir(path, mode.bits() as usize)
            .update_err("couldn't create directory", |e|
                format!("{}; path={}; mode={}", e, path.display(), mode))
 }
 
 /// Remove an existing, empty directory
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(old_io, old_path)]
 /// # #![allow(unused_must_use)]
-/// use std::old_io::fs;
+/// use std::old_io::*;
+/// use std::old_path::Path;
 ///
 /// let p = Path::new("/some/dir");
 /// fs::rmdir(&p);
@@ -502,6 +564,8 @@ pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> {
 ///
 /// This function will return an error if the user lacks permissions to remove
 /// the directory at the provided `path`, or if the directory isn't empty.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_dir")]
+#[unstable(feature = "old_io")]
 pub fn rmdir(path: &Path) -> IoResult<()> {
     fs_imp::rmdir(path)
            .update_err("couldn't remove directory", |e|
@@ -510,12 +574,14 @@ pub fn rmdir(path: &Path) -> IoResult<()> {
 
 /// Retrieve a vector containing all entries within a provided directory
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(old_io, old_path)]
 /// use std::old_io::fs::PathExtensions;
-/// use std::old_io::fs;
 /// use std::old_io;
+/// use std::old_io::*;
+/// use std::old_path::Path;
 ///
 /// // one possible implementation of fs::walk_dir only visiting files
 /// fn visit_dirs<F>(dir: &Path, cb: &mut F) -> old_io::IoResult<()> where
@@ -542,6 +608,8 @@ pub fn rmdir(path: &Path) -> IoResult<()> {
 /// This function will return an error if the provided `path` doesn't exist, if
 /// the process lacks permissions to view the contents or if the `path` points
 /// at a non-directory file
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::read_dir")]
+#[unstable(feature = "old_io")]
 pub fn readdir(path: &Path) -> IoResult<Vec<Path>> {
     fs_imp::readdir(path)
            .update_err("couldn't read directory",
@@ -552,6 +620,8 @@ pub fn readdir(path: &Path) -> IoResult<Vec<Path>> {
 /// rooted at `path`. The path given will not be iterated over, and this will
 /// perform iteration in some top-down order.  The contents of unreadable
 /// subdirectories are ignored.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::walk_dir")]
+#[unstable(feature = "old_io")]
 pub fn walk_dir(path: &Path) -> IoResult<Directories> {
     Ok(Directories {
         stack: try!(readdir(path).update_err("couldn't walk directory",
@@ -561,6 +631,8 @@ pub fn walk_dir(path: &Path) -> IoResult<Directories> {
 
 /// An iterator that walks over a directory
 #[derive(Clone)]
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::ReadDir")]
+#[unstable(feature = "old_io")]
 pub struct Directories {
     stack: Vec<Path>,
 }
@@ -590,6 +662,7 @@ impl Iterator for Directories {
 /// # Error
 ///
 /// See `fs::mkdir`.
+#[unstable(feature = "old_fs")]
 pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> {
     // tjc: if directory exists but with different permissions,
     // should we return false?
@@ -627,6 +700,8 @@ pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> {
 /// # Error
 ///
 /// See `file::unlink` and `fs::readdir`
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_dir_all")]
+#[unstable(feature = "old_io")]
 pub fn rmdir_recursive(path: &Path) -> IoResult<()> {
     let mut rm_stack = Vec::new();
     rm_stack.push(path.clone());
@@ -689,6 +764,8 @@ pub fn rmdir_recursive(path: &Path) -> IoResult<()> {
 /// `atime` and its modification time set to `mtime`. The times specified should
 /// be in milliseconds.
 // FIXME(#10301) these arguments should not be u64
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::set_file_times")]
+#[unstable(feature = "old_io")]
 pub fn change_file_times(path: &Path, atime: u64, mtime: u64) -> IoResult<()> {
     fs_imp::utime(path, atime, mtime)
            .update_err("couldn't change_file_times", |e|
@@ -696,7 +773,7 @@ pub fn change_file_times(path: &Path, atime: u64, mtime: u64) -> IoResult<()> {
 }
 
 impl Reader for File {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         fn update_err<T>(result: IoResult<T>, file: &File) -> IoResult<T> {
             result.update_err("couldn't read file",
                               |e| format!("{}; path={}",
@@ -707,10 +784,10 @@ impl Reader for File {
 
         match result {
             Ok(read) => {
-                self.last_nread = read as int;
+                self.last_nread = read as isize;
                 match read {
                     0 => update_err(Err(standard_error(old_io::EndOfFile)), self),
-                    _ => Ok(read as uint)
+                    _ => Ok(read as usize)
                 }
             },
             Err(e) => Err(e)
@@ -748,6 +825,8 @@ impl Seek for File {
 }
 
 /// Utility methods for paths.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::PathExt")]
+#[unstable(feature = "old_io")]
 pub trait PathExtensions {
     /// Get information on the file, directory, etc at this path.
     ///
@@ -826,7 +905,8 @@ fn access_string(access: FileAccess) -> &'static str {
 mod test {
     use prelude::v1::*;
     use old_io::{SeekSet, SeekCur, SeekEnd, Read, Open, ReadWrite, FileType};
-    use old_io;
+    use old_io::{self, Reader, Writer, Seek};
+    use old_path::{Path, GenericPath};
     use str;
     use old_io::fs::*;
 
@@ -871,7 +951,8 @@ mod test {
     pub fn tmpdir() -> TempDir {
         use os;
         use rand;
-        let ret = os::tmpdir().join(format!("rust-{}", rand::random::<u32>()));
+        let temp = Path::new(::env::temp_dir().to_str().unwrap());
+        let ret = temp.join(format!("rust-{}", rand::random::<u32>()));
         check!(old_io::fs::mkdir(&ret, old_io::USER_RWX));
         TempDir(ret)
     }
@@ -889,7 +970,7 @@ mod test {
             let mut read_stream = File::open_mode(filename, Open, Read);
             let mut read_buf = [0; 1028];
             let read_str = match check!(read_stream.read(&mut read_buf)) {
-                -1|0 => panic!("shouldn't happen"),
+                0 => panic!("shouldn't happen"),
                 n => str::from_utf8(&read_buf[..n]).unwrap().to_string()
             };
             assert_eq!(read_str, message);
@@ -1110,7 +1191,7 @@ mod test {
             check!(w.write(msg));
         }
         let files = check!(readdir(dir));
-        let mut mem = [0u8; 4];
+        let mut mem = [0; 4];
         for f in &files {
             {
                 let n = f.filestem_str();
@@ -1142,13 +1223,13 @@ mod test {
         check!(File::create(&dir2.join("14")));
 
         let mut files = check!(walk_dir(dir));
-        let mut cur = [0u8; 2];
+        let mut cur = [0; 2];
         for f in files {
             let stem = f.filestem_str().unwrap();
             let root = stem.as_bytes()[0] - b'0';
             let name = stem.as_bytes()[1] - b'0';
-            assert!(cur[root as uint] < name);
-            cur[root as uint] = name;
+            assert!(cur[root as usize] < name);
+            cur[root as usize] = name;
         }
 
         check!(rmdir_recursive(dir));
@@ -1452,7 +1533,7 @@ mod test {
                    b"foobar\0\0\0\0".to_vec());
 
         // Truncate to a smaller length, don't seek, and then write something.
-        // Ensure that the intermediate zeroes are all filled in (we're seeked
+        // Ensure that the intermediate zeroes are all filled in (we have `seek`ed
         // past the end of the file).
         check!(file.truncate(2));
         assert_eq!(check!(file.stat()).size, 2);
@@ -1553,13 +1634,13 @@ mod test {
         use rand::{StdRng, Rng};
 
         let mut bytes = [0; 1024];
-        StdRng::new().ok().unwrap().fill_bytes(&mut bytes);
+        StdRng::new().unwrap().fill_bytes(&mut bytes);
 
         let tmpdir = tmpdir();
 
         check!(File::create(&tmpdir.join("test")).write(&bytes));
         let actual = check!(File::open(&tmpdir.join("test")).read_to_end());
-        assert!(actual == bytes.as_slice());
+        assert!(actual == &bytes[..]);
     }
 
     #[test]
index 1fd527014a3d62d4e6fcdac2a6df7b20c26c424d..c92e74fbc565e10b3a84aa46c67b86a630d816d8 100644 (file)
@@ -17,12 +17,12 @@ use option::Option::None;
 use result::Result::{Err, Ok};
 use old_io;
 use old_io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult};
-use slice::{self, SliceExt};
+use slice;
 use vec::Vec;
 
-const BUF_CAPACITY: uint = 128;
+const BUF_CAPACITY: usize = 128;
 
-fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64> {
+fn combine(seek: SeekStyle, cur: usize, end: usize, offset: i64) -> IoResult<u64> {
     // compute offset as signed and clamp to prevent overflow
     let pos = match seek {
         old_io::SeekSet => 0,
@@ -51,16 +51,17 @@ impl Writer for Vec<u8> {
 
 /// Writes to an owned, growable byte vector
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(old_io, io)]
 /// # #![allow(unused_must_use)]
-/// use std::old_io::MemWriter;
+/// use std::old_io::*;
 ///
 /// let mut w = MemWriter::new();
 /// w.write(&[0, 1, 2]);
 ///
-/// assert_eq!(w.into_inner(), vec!(0, 1, 2));
+/// assert_eq!(w.into_inner(), [0, 1, 2]);
 /// ```
 #[unstable(feature = "io")]
 #[deprecated(since = "1.0.0",
@@ -81,7 +82,7 @@ impl MemWriter {
     /// Create a new `MemWriter`, allocating at least `n` bytes for
     /// the internal buffer.
     #[inline]
-    pub fn with_capacity(n: uint) -> MemWriter {
+    pub fn with_capacity(n: usize) -> MemWriter {
         MemWriter::from_vec(Vec::with_capacity(n))
     }
     /// Create a new `MemWriter` that will append to an existing `Vec`.
@@ -102,6 +103,7 @@ impl MemWriter {
 
 impl Writer for MemWriter {
     #[inline]
+    #[allow(deprecated)]
     fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
         self.buf.push_all(buf);
         Ok(())
@@ -110,19 +112,20 @@ impl Writer for MemWriter {
 
 /// Reads from an owned byte vector
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(old_io)]
 /// # #![allow(unused_must_use)]
-/// use std::old_io::MemReader;
+/// use std::old_io::*;
 ///
 /// let mut r = MemReader::new(vec!(0, 1, 2));
 ///
-/// assert_eq!(r.read_to_end().unwrap(), vec!(0, 1, 2));
+/// assert_eq!(r.read_to_end().unwrap(), [0, 1, 2]);
 /// ```
 pub struct MemReader {
     buf: Vec<u8>,
-    pos: uint
+    pos: usize
 }
 
 impl MemReader {
@@ -157,7 +160,7 @@ impl MemReader {
 
 impl Reader for MemReader {
     #[inline]
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         if self.eof() { return Err(old_io::standard_error(old_io::EndOfFile)) }
 
         let write_len = min(buf.len(), self.buf.len() - self.pos);
@@ -165,7 +168,7 @@ impl Reader for MemReader {
             let input = &self.buf[self.pos.. self.pos + write_len];
             let output = &mut buf[..write_len];
             assert_eq!(input.len(), output.len());
-            slice::bytes::copy_memory(output, input);
+            slice::bytes::copy_memory(input, output);
         }
         self.pos += write_len;
         assert!(self.pos <= self.buf.len());
@@ -181,7 +184,7 @@ impl Seek for MemReader {
     #[inline]
     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
         let new = try!(combine(style, self.pos, self.buf.len(), pos));
-        self.pos = new as uint;
+        self.pos = new as usize;
         Ok(())
     }
 }
@@ -197,19 +200,19 @@ impl Buffer for MemReader {
     }
 
     #[inline]
-    fn consume(&mut self, amt: uint) { self.pos += amt; }
+    fn consume(&mut self, amt: usize) { self.pos += amt; }
 }
 
 impl<'a> Reader for &'a [u8] {
     #[inline]
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         if self.is_empty() { return Err(old_io::standard_error(old_io::EndOfFile)); }
 
         let write_len = min(buf.len(), self.len());
         {
             let input = &self[..write_len];
             let output = &mut buf[.. write_len];
-            slice::bytes::copy_memory(output, input);
+            slice::bytes::copy_memory(input, output);
         }
 
         *self = &self[write_len..];
@@ -229,7 +232,7 @@ impl<'a> Buffer for &'a [u8] {
     }
 
     #[inline]
-    fn consume(&mut self, amt: uint) {
+    fn consume(&mut self, amt: usize) {
         *self = &self[amt..];
     }
 }
@@ -240,11 +243,12 @@ impl<'a> Buffer for &'a [u8] {
 /// If a write will not fit in the buffer, it returns an error and does not
 /// write any data.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(old_io, io)]
 /// # #![allow(unused_must_use)]
-/// use std::old_io::BufWriter;
+/// use std::old_io::*;
 ///
 /// let mut buf = [0; 4];
 /// {
@@ -255,7 +259,7 @@ impl<'a> Buffer for &'a [u8] {
 /// ```
 pub struct BufWriter<'a> {
     buf: &'a mut [u8],
-    pos: uint
+    pos: usize
 }
 
 impl<'a> BufWriter<'a> {
@@ -283,13 +287,13 @@ impl<'a> Writer for BufWriter<'a> {
         let src_len = src.len();
 
         if dst_len >= src_len {
-            slice::bytes::copy_memory(dst, src);
+            slice::bytes::copy_memory(src, dst);
 
             self.pos += src_len;
 
             Ok(())
         } else {
-            slice::bytes::copy_memory(dst, &src[..dst_len]);
+            slice::bytes::copy_memory(&src[..dst_len], dst);
 
             self.pos += dst_len;
 
@@ -305,27 +309,28 @@ impl<'a> Seek for BufWriter<'a> {
     #[inline]
     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
         let new = try!(combine(style, self.pos, self.buf.len(), pos));
-        self.pos = min(new as uint, self.buf.len());
+        self.pos = min(new as usize, self.buf.len());
         Ok(())
     }
 }
 
 /// Reads from a fixed-size byte slice
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(old_io)]
 /// # #![allow(unused_must_use)]
-/// use std::old_io::BufReader;
+/// use std::old_io::*;
 ///
 /// let buf = [0, 1, 2, 3];
 /// let mut r = BufReader::new(&buf);
 ///
-/// assert_eq!(r.read_to_end().unwrap(), vec![0, 1, 2, 3]);
+/// assert_eq!(r.read_to_end().unwrap(), [0, 1, 2, 3]);
 /// ```
 pub struct BufReader<'a> {
     buf: &'a [u8],
-    pos: uint
+    pos: usize
 }
 
 impl<'a> BufReader<'a> {
@@ -347,7 +352,7 @@ impl<'a> BufReader<'a> {
 
 impl<'a> Reader for BufReader<'a> {
     #[inline]
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         if self.eof() { return Err(old_io::standard_error(old_io::EndOfFile)) }
 
         let write_len = min(buf.len(), self.buf.len() - self.pos);
@@ -355,7 +360,7 @@ impl<'a> Reader for BufReader<'a> {
             let input = &self.buf[self.pos.. self.pos + write_len];
             let output = &mut buf[..write_len];
             assert_eq!(input.len(), output.len());
-            slice::bytes::copy_memory(output, input);
+            slice::bytes::copy_memory(input, output);
         }
         self.pos += write_len;
         assert!(self.pos <= self.buf.len());
@@ -371,7 +376,7 @@ impl<'a> Seek for BufReader<'a> {
     #[inline]
     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
         let new = try!(combine(style, self.pos, self.buf.len(), pos));
-        self.pos = new as uint;
+        self.pos = new as usize;
         Ok(())
     }
 }
@@ -387,15 +392,15 @@ impl<'a> Buffer for BufReader<'a> {
     }
 
     #[inline]
-    fn consume(&mut self, amt: uint) { self.pos += amt; }
+    fn consume(&mut self, amt: usize) { self.pos += amt; }
 }
 
 #[cfg(test)]
 mod test {
-    extern crate "test" as test_crate;
-    use old_io::{SeekSet, SeekCur, SeekEnd, Reader, Writer, Seek};
-    use prelude::v1::{Ok, Err, range,  Vec, Buffer,  AsSlice, SliceExt};
-    use prelude::v1::IteratorExt;
+    extern crate test as test_crate;
+    use old_io::{SeekSet, SeekCur, SeekEnd, Reader, Writer, Seek, Buffer};
+    use prelude::v1::{Ok, Err, Vec};
+    use prelude::v1::Iterator;
     use old_io;
     use iter::repeat;
     use self::test_crate::Bencher;
@@ -504,8 +509,8 @@ mod test {
         assert_eq!(&buf[..3], b);
         assert!(reader.read(&mut buf).is_err());
         let mut reader = MemReader::new(vec!(0, 1, 2, 3, 4, 5, 6, 7));
-        assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3));
-        assert_eq!(reader.read_until(3).unwrap(), vec!(4, 5, 6, 7));
+        assert_eq!(reader.read_until(3).unwrap(), [0, 1, 2, 3]);
+        assert_eq!(reader.read_until(3).unwrap(), [4, 5, 6, 7]);
         assert!(reader.read(&mut buf).is_err());
     }
 
@@ -530,8 +535,8 @@ mod test {
         assert_eq!(&buf[..3], b);
         assert!(reader.read(&mut buf).is_err());
         let mut reader = &mut &*in_buf;
-        assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3));
-        assert_eq!(reader.read_until(3).unwrap(), vec!(4, 5, 6, 7));
+        assert_eq!(reader.read_until(3).unwrap(), [0, 1, 2, 3]);
+        assert_eq!(reader.read_until(3).unwrap(), [4, 5, 6, 7]);
         assert!(reader.read(&mut buf).is_err());
     }
 
@@ -557,8 +562,8 @@ mod test {
         assert_eq!(&buf[..3], b);
         assert!(reader.read(&mut buf).is_err());
         let mut reader = BufReader::new(&in_buf);
-        assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3));
-        assert_eq!(reader.read_until(3).unwrap(), vec!(4, 5, 6, 7));
+        assert_eq!(reader.read_until(3).unwrap(), [0, 1, 2, 3]);
+        assert_eq!(reader.read_until(3).unwrap(), [4, 5, 6, 7]);
         assert!(reader.read(&mut buf).is_err());
     }
 
@@ -658,7 +663,7 @@ mod test {
         assert_eq!(buf, b);
     }
 
-    fn do_bench_mem_writer(b: &mut Bencher, times: uint, len: uint) {
+    fn do_bench_mem_writer(b: &mut Bencher, times: usize, len: usize) {
         let src: Vec<u8> = repeat(5).take(len).collect();
 
         b.bytes = (times * len) as u64;
@@ -739,7 +744,7 @@ mod test {
                     wr.write(&[5; 10]).unwrap();
                 }
             }
-            assert_eq!(buf.as_slice(), [5; 100].as_slice());
+            assert_eq!(&buf[..], &[5; 100][..]);
         });
     }
 
index fc3deb67f41ec97148e6a2639964129193006150..98ff6e82c6f7f1437014d2968f8d19389fd73fac 100644 (file)
@@ -48,7 +48,9 @@
 //! * Read lines from stdin
 //!
 //!     ```rust
+//!     # #![feature(old_io, old_path)]
 //!     use std::old_io as io;
+//!     use std::old_io::*;
 //!
 //!     let mut stdin = io::stdin();
 //!     for line in stdin.lock().lines() {
@@ -59,7 +61,9 @@
 //! * Read a complete file
 //!
 //!     ```rust
-//!     use std::old_io::File;
+//!     # #![feature(old_io, old_path)]
+//!     use std::old_io::*;
+//!     use std::old_path::Path;
 //!
 //!     let contents = File::open(&Path::new("message.txt")).read_to_end();
 //!     ```
 //! * Write a line to a file
 //!
 //!     ```rust
+//!     # #![feature(old_io, old_path)]
 //!     # #![allow(unused_must_use)]
-//!     use std::old_io::File;
+//!     use std::old_io::*;
+//!     use std::old_path::Path;
 //!
 //!     let mut file = File::create(&Path::new("message.txt"));
 //!     file.write_all(b"hello, file!\n");
@@ -79,8 +85,9 @@
 //! * Iterate over the lines of a file
 //!
 //!     ```rust,no_run
-//!     use std::old_io::BufferedReader;
-//!     use std::old_io::File;
+//!     # #![feature(old_io, old_path)]
+//!     use std::old_io::*;
+//!     use std::old_path::Path;
 //!
 //!     let path = Path::new("message.txt");
 //!     let mut file = BufferedReader::new(File::open(&path));
@@ -92,8 +99,9 @@
 //! * Pull the lines of a file into a vector of strings
 //!
 //!     ```rust,no_run
-//!     use std::old_io::BufferedReader;
-//!     use std::old_io::File;
+//!     # #![feature(old_io, old_path)]
+//!     use std::old_io::*;
+//!     use std::old_path::Path;
 //!
 //!     let path = Path::new("message.txt");
 //!     let mut file = BufferedReader::new(File::open(&path));
 //! * Make a simple TCP client connection and request
 //!
 //!     ```rust
+//!     # #![feature(old_io)]
 //!     # #![allow(unused_must_use)]
-//!     use std::old_io::TcpStream;
+//!     use std::old_io::*;
 //!
 //!     # // connection doesn't fail if a server is running on 8080
 //!     # // locally, we still want to be type checking this code, so lets
 //! * Make a simple TCP server
 //!
 //!     ```rust
+//!     # #![feature(old_io)]
 //!     # fn main() { }
 //!     # fn foo() {
 //!     # #![allow(dead_code)]
-//!     use std::old_io::{TcpListener, TcpStream};
-//!     use std::old_io::{Acceptor, Listener};
+//!     use std::old_io::*;
 //!     use std::thread;
 //!
 //!     let listener = TcpListener::bind("127.0.0.1:80");
 //! If you wanted to handle the error though you might write:
 //!
 //! ```rust
+//! # #![feature(old_io, old_path)]
 //! # #![allow(unused_must_use)]
-//! use std::old_io::File;
+//! use std::old_io::*;
+//! use std::old_path::Path;
 //!
 //! match File::create(&Path::new("diary.txt")).write_all(b"Met a girl.\n") {
 //!     Ok(()) => (), // succeeded
 //! If you wanted to read several `u32`s from a file and return their product:
 //!
 //! ```rust
-//! use std::old_io::{File, IoResult};
+//! # #![feature(old_io, old_path)]
+//! use std::old_io::*;
+//! use std::old_path::Path;
 //!
 //! fn file_product(p: &Path) -> IoResult<u32> {
 //!     let mut f = File::open(p);
 
 #![unstable(feature = "old_io")]
 #![deny(unused_must_use)]
+#![allow(deprecated)] // seriously this is all deprecated
+#![allow(unused_imports)]
+#![deprecated(since = "1.0.0",
+              reasons = "APIs have been replaced with new I/O modules such as \
+                         std::{io, fs, net, process}")]
 
 pub use self::SeekStyle::*;
 pub use self::FileMode::*;
 pub use self::FileAccess::*;
 pub use self::IoErrorKind::*;
 
-use char::CharExt;
 use default::Default;
 use error::Error;
 use fmt;
 use isize;
-use iter::{Iterator, IteratorExt};
+use iter::Iterator;
 use marker::{PhantomFn, Sized};
 use mem::transmute;
 use ops::FnOnce;
 use option::Option;
 use option::Option::{Some, None};
-use os;
+use sys::os;
 use boxed::Box;
 use result::Result;
 use result::Result::{Ok, Err};
 use sys;
-use slice::SliceExt;
-use str::StrExt;
 use str;
 use string::String;
 use usize;
@@ -311,7 +326,7 @@ pub mod test;
 /// The default buffer size for various I/O operations
 // libuv recommends 64k buffers to maximize throughput
 // https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
-const DEFAULT_BUF_SIZE: uint = 1024 * 64;
+const DEFAULT_BUF_SIZE: usize = 1024 * 64;
 
 /// A convenient typedef of the return value of any I/O action.
 pub type IoResult<T> = Result<T, IoError>;
@@ -341,8 +356,7 @@ impl IoError {
     pub fn from_errno(errno: i32, detail: bool) -> IoError {
         let mut err = sys::decode_error(errno as i32);
         if detail && err.kind == OtherIoError {
-            err.detail = Some(os::error_string(errno).chars()
-                                 .map(|c| c.to_lowercase()).collect())
+            err.detail = Some(os::error_string(errno).to_lowercase());
         }
         err
     }
@@ -377,7 +391,7 @@ impl Error for IoError {
 }
 
 /// A list specifying general categories of I/O error.
-#[derive(Copy, PartialEq, Eq, Clone, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum IoErrorKind {
     /// Any I/O error not part of this list.
     OtherIoError,
@@ -427,7 +441,7 @@ pub enum IoErrorKind {
     ///
     /// The payload contained as part of this variant is the number of bytes
     /// which are known to have been successfully written.
-    ShortWrite(uint),
+    ShortWrite(usize),
     /// The Reader returned 0 bytes from `read()` too many times.
     NoProgress,
 }
@@ -469,7 +483,7 @@ impl<T> UpdateIoError for IoResult<T> {
     }
 }
 
-static NO_PROGRESS_LIMIT: uint = 1000;
+static NO_PROGRESS_LIMIT: usize = 1000;
 
 /// A trait for objects which are byte-oriented streams. Readers are defined by
 /// one method, `read`. This function will block until data is available,
@@ -497,7 +511,7 @@ pub trait Reader {
     ///
     /// When implementing this method on a new Reader, you are strongly encouraged
     /// not to return 0 if you can avoid it.
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize>;
 
     // Convenient helper methods based on the above methods
 
@@ -512,7 +526,7 @@ pub trait Reader {
     ///
     /// If an error occurs at any point, that error is returned, and no further
     /// bytes are read.
-    fn read_at_least(&mut self, min: uint, buf: &mut [u8]) -> IoResult<uint> {
+    fn read_at_least(&mut self, min: usize, buf: &mut [u8]) -> IoResult<usize> {
         if min > buf.len() {
             return Err(IoError {
                 detail: Some(String::from_str("the buffer is too short")),
@@ -556,7 +570,7 @@ pub trait Reader {
     ///
     /// If an error occurs during this I/O operation, then it is returned
     /// as `Err(IoError)`. See `read()` for more details.
-    fn push(&mut self, len: uint, buf: &mut Vec<u8>) -> IoResult<uint> {
+    fn push(&mut self, len: usize, buf: &mut Vec<u8>) -> IoResult<usize> {
         let start_len = buf.len();
         buf.reserve(len);
 
@@ -580,7 +594,7 @@ pub trait Reader {
     ///
     /// If an error occurs at any point, that error is returned, and no further
     /// bytes are read.
-    fn push_at_least(&mut self, min: uint, len: uint, buf: &mut Vec<u8>) -> IoResult<uint> {
+    fn push_at_least(&mut self, min: usize, len: usize, buf: &mut Vec<u8>) -> IoResult<usize> {
         if min > len {
             return Err(IoError {
                 detail: Some(String::from_str("the buffer is too short")),
@@ -615,7 +629,7 @@ pub trait Reader {
     /// have already been consumed from the underlying reader, and they are lost
     /// (not returned as part of the error). If this is unacceptable, then it is
     /// recommended to use the `push_at_least` or `read` methods.
-    fn read_exact(&mut self, len: uint) -> IoResult<Vec<u8>> {
+    fn read_exact(&mut self, len: usize) -> IoResult<Vec<u8>> {
         let mut buf = Vec::with_capacity(len);
         match self.push_at_least(len, len, &mut buf) {
             Ok(_) => Ok(buf),
@@ -665,10 +679,10 @@ pub trait Reader {
     /// Reads `n` little-endian unsigned integer bytes.
     ///
     /// `n` must be between 1 and 8, inclusive.
-    fn read_le_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
+    fn read_le_uint_n(&mut self, nbytes: usize) -> IoResult<u64> {
         assert!(nbytes > 0 && nbytes <= 8);
 
-        let mut val = 0u64;
+        let mut val = 0;
         let mut pos = 0;
         let mut i = nbytes;
         while i > 0 {
@@ -682,17 +696,17 @@ pub trait Reader {
     /// Reads `n` little-endian signed integer bytes.
     ///
     /// `n` must be between 1 and 8, inclusive.
-    fn read_le_int_n(&mut self, nbytes: uint) -> IoResult<i64> {
+    fn read_le_int_n(&mut self, nbytes: usize) -> IoResult<i64> {
         self.read_le_uint_n(nbytes).map(|i| extend_sign(i, nbytes))
     }
 
     /// Reads `n` big-endian unsigned integer bytes.
     ///
     /// `n` must be between 1 and 8, inclusive.
-    fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
+    fn read_be_uint_n(&mut self, nbytes: usize) -> IoResult<u64> {
         assert!(nbytes > 0 && nbytes <= 8);
 
-        let mut val = 0u64;
+        let mut val = 0;
         let mut i = nbytes;
         while i > 0 {
             i -= 1;
@@ -704,36 +718,36 @@ pub trait Reader {
     /// Reads `n` big-endian signed integer bytes.
     ///
     /// `n` must be between 1 and 8, inclusive.
-    fn read_be_int_n(&mut self, nbytes: uint) -> IoResult<i64> {
+    fn read_be_int_n(&mut self, nbytes: usize) -> IoResult<i64> {
         self.read_be_uint_n(nbytes).map(|i| extend_sign(i, nbytes))
     }
 
     /// Reads a little-endian unsigned integer.
     ///
     /// The number of bytes returned is system-dependent.
-    fn read_le_uint(&mut self) -> IoResult<uint> {
-        self.read_le_uint_n(usize::BYTES).map(|i| i as uint)
+    fn read_le_uint(&mut self) -> IoResult<usize> {
+        self.read_le_uint_n(usize::BYTES as usize).map(|i| i as usize)
     }
 
     /// Reads a little-endian integer.
     ///
     /// The number of bytes returned is system-dependent.
-    fn read_le_int(&mut self) -> IoResult<int> {
-        self.read_le_int_n(isize::BYTES).map(|i| i as int)
+    fn read_le_int(&mut self) -> IoResult<isize> {
+        self.read_le_int_n(isize::BYTES as usize).map(|i| i as isize)
     }
 
     /// Reads a big-endian unsigned integer.
     ///
     /// The number of bytes returned is system-dependent.
-    fn read_be_uint(&mut self) -> IoResult<uint> {
-        self.read_be_uint_n(usize::BYTES).map(|i| i as uint)
+    fn read_be_uint(&mut self) -> IoResult<usize> {
+        self.read_be_uint_n(usize::BYTES as usize).map(|i| i as usize)
     }
 
     /// Reads a big-endian integer.
     ///
     /// The number of bytes returned is system-dependent.
-    fn read_be_int(&mut self) -> IoResult<int> {
-        self.read_be_int_n(isize::BYTES).map(|i| i as int)
+    fn read_be_int(&mut self) -> IoResult<isize> {
+        self.read_be_int_n(isize::BYTES as usize).map(|i| i as isize)
     }
 
     /// Reads a big-endian `u64`.
@@ -905,14 +919,14 @@ impl<T: Reader> BytesReader for T {
 }
 
 impl<'a> Reader for Box<Reader+'a> {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         let reader: &mut Reader = &mut **self;
         reader.read(buf)
     }
 }
 
 impl<'a> Reader for &'a mut (Reader+'a) {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { (*self).read(buf) }
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> { (*self).read(buf) }
 }
 
 /// Returns a slice of `v` between `start` and `end`.
@@ -926,16 +940,15 @@ impl<'a> Reader for &'a mut (Reader+'a) {
 /// `start` > `end`.
 // Private function here because we aren't sure if we want to expose this as
 // API yet. If so, it should be a method on Vec.
-unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -> &'a mut [T] {
-    use raw::Slice;
-    use ptr::PtrExt;
+unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: usize, end: usize) -> &'a mut [T] {
+    use slice;
 
     assert!(start <= end);
     assert!(end <= v.capacity());
-    transmute(Slice {
-        data: v.as_ptr().offset(start as int),
-        len: end - start
-    })
+    slice::from_raw_parts_mut(
+        v.as_mut_ptr().offset(start as isize),
+        end - start
+    )
 }
 
 /// A `RefReader` is a struct implementing `Reader` which contains a reference
@@ -944,8 +957,9 @@ unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -
 /// # Examples
 ///
 /// ```
+/// # #![feature(old_io)]
 /// use std::old_io as io;
-/// use std::old_io::ByRefReader;
+/// use std::old_io::*;
 /// use std::old_io::util::LimitReader;
 ///
 /// fn process_input<R: Reader>(r: R) {}
@@ -966,15 +980,15 @@ pub struct RefReader<'a, R:'a> {
 }
 
 impl<'a, R: Reader> Reader for RefReader<'a, R> {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.inner.read(buf) }
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> { self.inner.read(buf) }
 }
 
 impl<'a, R: Buffer> Buffer for RefReader<'a, R> {
     fn fill_buf(&mut self) -> IoResult<&[u8]> { self.inner.fill_buf() }
-    fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
+    fn consume(&mut self, amt: usize) { self.inner.consume(amt) }
 }
 
-fn extend_sign(val: u64, nbytes: uint) -> i64 {
+fn extend_sign(val: u64, nbytes: usize) -> i64 {
     let shift = (8 - nbytes) * 8;
     (val << shift) as i64 >> shift
 }
@@ -1076,45 +1090,45 @@ pub trait Writer {
     /// Write a single char, encoded as UTF-8.
     #[inline]
     fn write_char(&mut self, c: char) -> IoResult<()> {
-        let mut buf = [0u8; 4];
+        let mut buf = [0; 4];
         let n = c.encode_utf8(&mut buf).unwrap_or(0);
         self.write_all(&buf[..n])
     }
 
-    /// Write the result of passing n through `int::to_str_bytes`.
+    /// Write the result of passing n through `isize::to_str_bytes`.
     #[inline]
-    fn write_int(&mut self, n: int) -> IoResult<()> {
+    fn write_int(&mut self, n: isize) -> IoResult<()> {
         write!(self, "{}", n)
     }
 
-    /// Write the result of passing n through `uint::to_str_bytes`.
+    /// Write the result of passing n through `usize::to_str_bytes`.
     #[inline]
-    fn write_uint(&mut self, n: uint) -> IoResult<()> {
+    fn write_uint(&mut self, n: usize) -> IoResult<()> {
         write!(self, "{}", n)
     }
 
-    /// Write a little-endian uint (number of bytes depends on system).
+    /// Write a little-endian usize (number of bytes depends on system).
     #[inline]
-    fn write_le_uint(&mut self, n: uint) -> IoResult<()> {
-        extensions::u64_to_le_bytes(n as u64, usize::BYTES, |v| self.write_all(v))
+    fn write_le_uint(&mut self, n: usize) -> IoResult<()> {
+        extensions::u64_to_le_bytes(n as u64, usize::BYTES as usize, |v| self.write_all(v))
     }
 
-    /// Write a little-endian int (number of bytes depends on system).
+    /// Write a little-endian isize (number of bytes depends on system).
     #[inline]
-    fn write_le_int(&mut self, n: int) -> IoResult<()> {
-        extensions::u64_to_le_bytes(n as u64, isize::BYTES, |v| self.write_all(v))
+    fn write_le_int(&mut self, n: isize) -> IoResult<()> {
+        extensions::u64_to_le_bytes(n as u64, isize::BYTES as usize, |v| self.write_all(v))
     }
 
-    /// Write a big-endian uint (number of bytes depends on system).
+    /// Write a big-endian usize (number of bytes depends on system).
     #[inline]
-    fn write_be_uint(&mut self, n: uint) -> IoResult<()> {
-        extensions::u64_to_be_bytes(n as u64, usize::BYTES, |v| self.write_all(v))
+    fn write_be_uint(&mut self, n: usize) -> IoResult<()> {
+        extensions::u64_to_be_bytes(n as u64, usize::BYTES as usize, |v| self.write_all(v))
     }
 
-    /// Write a big-endian int (number of bytes depends on system).
+    /// Write a big-endian isize (number of bytes depends on system).
     #[inline]
-    fn write_be_int(&mut self, n: int) -> IoResult<()> {
-        extensions::u64_to_be_bytes(n as u64, isize::BYTES, |v| self.write_all(v))
+    fn write_be_int(&mut self, n: isize) -> IoResult<()> {
+        extensions::u64_to_be_bytes(n as u64, isize::BYTES as usize, |v| self.write_all(v))
     }
 
     /// Write a big-endian u64 (8 bytes).
@@ -1275,11 +1289,12 @@ impl<'a> Writer for &'a mut (Writer+'a) {
 /// A `RefWriter` is a struct implementing `Writer` which contains a reference
 /// to another writer. This is often useful when composing streams.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
+/// # #![feature(old_io)]
 /// use std::old_io::util::TeeReader;
-/// use std::old_io::{stdin, ByRefWriter};
+/// use std::old_io::*;
 ///
 /// fn process_input<R: Reader>(r: R) {}
 ///
@@ -1394,16 +1409,17 @@ pub trait Buffer: Reader {
 
     /// Tells this buffer that `amt` bytes have been consumed from the buffer,
     /// so they should no longer be returned in calls to `read`.
-    fn consume(&mut self, amt: uint);
+    fn consume(&mut self, amt: usize);
 
     /// Reads the next line of input, interpreted as a sequence of UTF-8
     /// encoded Unicode codepoints. If a newline is encountered, then the
     /// newline is contained in the returned string.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
-    /// use std::old_io::BufReader;
+    /// ```
+    /// # #![feature(old_io)]
+    /// use std::old_io::*;
     ///
     /// let mut reader = BufReader::new(b"hello\nworld");
     /// assert_eq!("hello\n", &*reader.read_line().unwrap());
@@ -1537,7 +1553,7 @@ impl<T: Buffer> BufferPrelude for T {
 
 /// When seeking, the resulting cursor is offset from a base by the offset given
 /// to the `seek` function. The base used is specified by this enumeration.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum SeekStyle {
     /// Seek from the beginning of the stream
     SeekSet,
@@ -1572,9 +1588,7 @@ pub trait Seek {
 /// connections.
 ///
 /// Doing so produces some sort of Acceptor.
-pub trait Listener<T, A: Acceptor<T>>
-    : PhantomFn<T,T> // FIXME should be an assoc type anyhow
-{
+pub trait Listener<A: Acceptor> {
     /// Spin up the listener and start queuing incoming connections
     ///
     /// # Error
@@ -1585,13 +1599,16 @@ pub trait Listener<T, A: Acceptor<T>>
 }
 
 /// An acceptor is a value that presents incoming connections
-pub trait Acceptor<T> {
+pub trait Acceptor {
+    /// Type of connection that is accepted by this acceptor.
+    type Connection;
+
     /// Wait for and accept an incoming connection
     ///
     /// # Error
     ///
     /// Returns `Err` if an I/O error is encountered.
-    fn accept(&mut self) -> IoResult<T>;
+    fn accept(&mut self) -> IoResult<Self::Connection>;
 
     /// Create an iterator over incoming connection attempts.
     ///
@@ -1612,11 +1629,10 @@ pub struct IncomingConnections<'a, A: ?Sized +'a> {
     inc: &'a mut A,
 }
 
-#[old_impl_check]
-impl<'a, T, A: ?Sized + Acceptor<T>> Iterator for IncomingConnections<'a, A> {
-    type Item = IoResult<T>;
+impl<'a, A: ?Sized + Acceptor> Iterator for IncomingConnections<'a, A> {
+    type Item = IoResult<A::Connection>;
 
-    fn next(&mut self) -> Option<IoResult<T>> {
+    fn next(&mut self) -> Option<IoResult<A::Connection>> {
         Some(self.inc.accept())
     }
 }
@@ -1624,9 +1640,10 @@ impl<'a, T, A: ?Sized + Acceptor<T>> Iterator for IncomingConnections<'a, A> {
 /// Creates a standard error for a commonly used flavor of error. The `detail`
 /// field of the returned error will always be `None`.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
+/// # #![feature(old_io)]
 /// use std::old_io as io;
 ///
 /// let eof = io::standard_error(io::EndOfFile);
@@ -1715,8 +1732,10 @@ pub enum FileType {
 /// # Examples
 ///
 /// ```no_run
+/// # #![feature(old_io, old_path)]
 ///
 /// use std::old_io::fs::PathExtensions;
+/// use std::old_path::Path;
 ///
 /// let info = match Path::new("foo.txt").stat() {
 ///     Ok(stat) => stat,
@@ -1725,7 +1744,7 @@ pub enum FileType {
 ///
 /// println!("byte size: {}", info.size);
 /// ```
-#[derive(Copy, Hash)]
+#[derive(Copy, Clone, Hash)]
 pub struct FileStat {
     /// The size of the file, in bytes
     pub size: u64,
@@ -1764,7 +1783,7 @@ pub struct FileStat {
 /// structure. This information is not necessarily platform independent, and may
 /// have different meanings or no meaning at all on some platforms.
 #[unstable(feature = "io")]
-#[derive(Copy, Hash)]
+#[derive(Copy, Clone, Hash)]
 pub struct UnstableFileStat {
     /// The ID of the device containing the file.
     pub device: u64,
@@ -1845,13 +1864,14 @@ impl fmt::Display for FilePermission {
 mod tests {
     use self::BadReaderBehavior::*;
     use super::{IoResult, Reader, MemReader, NoProgress, InvalidInput, Writer};
-    use prelude::v1::{Ok, Vec, Buffer, SliceExt};
+    use super::Buffer;
+    use prelude::v1::{Ok, Vec};
     use usize;
 
     #[derive(Clone, PartialEq, Debug)]
     enum BadReaderBehavior {
-        GoodBehavior(uint),
-        BadBehavior(uint)
+        GoodBehavior(usize),
+        BadBehavior(usize)
     }
 
     struct BadReader<T> {
@@ -1866,7 +1886,7 @@ mod tests {
     }
 
     impl<T: Reader> Reader for BadReader<T> {
-        fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+        fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
             let BadReader { ref mut behavior, ref mut r } = *self;
             loop {
                 if behavior.is_empty() {
@@ -1894,7 +1914,7 @@ mod tests {
     fn test_read_at_least() {
         let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()),
                                    vec![GoodBehavior(usize::MAX)]);
-        let buf = &mut [0u8; 5];
+        let buf = &mut [0; 5];
         assert!(r.read_at_least(1, buf).unwrap() >= 1);
         assert!(r.read_exact(5).unwrap().len() == 5); // read_exact uses read_at_least
         assert!(r.read_at_least(0, buf).is_ok());
index 2b7506b5c34a3f6edef804b3d0cf4abf30d29c0a..c5fa775ab4e6f11a5f49103de549fa6db5fc2e00 100644 (file)
@@ -19,8 +19,8 @@ pub use self::SocketType::*;
 pub use self::Flag::*;
 pub use self::Protocol::*;
 
-use iter::IteratorExt;
-use old_io::{IoResult};
+use iter::Iterator;
+use old_io::IoResult;
 use old_io::net::ip::{SocketAddr, IpAddr};
 use option::Option;
 use option::Option::{Some, None};
@@ -29,7 +29,7 @@ use sys;
 use vec::Vec;
 
 /// Hints to the types of sockets that are desired when looking up hosts
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum SocketType {
     Stream, Datagram, Raw
 }
@@ -38,7 +38,7 @@ pub enum SocketType {
 /// to manipulate how a query is performed.
 ///
 /// The meaning of each of these flags can be found with `man -s 3 getaddrinfo`
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum Flag {
     AddrConfig,
     All,
@@ -51,7 +51,7 @@ pub enum Flag {
 
 /// A transport protocol associated with either a hint or a return value of
 /// `lookup`
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum Protocol {
     TCP, UDP
 }
@@ -61,21 +61,21 @@ pub enum Protocol {
 ///
 /// For details on these fields, see their corresponding definitions via
 /// `man -s 3 getaddrinfo`
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub struct Hint {
-    pub family: uint,
+    pub family: usize,
     pub socktype: Option<SocketType>,
     pub protocol: Option<Protocol>,
-    pub flags: uint,
+    pub flags: usize,
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub struct Info {
     pub address: SocketAddr,
-    pub family: uint,
+    pub family: usize,
     pub socktype: Option<SocketType>,
     pub protocol: Option<Protocol>,
-    pub flags: uint,
+    pub flags: usize,
 }
 
 /// Easy name resolution. Given a hostname, returns the list of IP addresses for
index 9c89c943994630f46c1b7633ec24cabe5dc8fb6a..099fe657f2602b761d74e3cffb955240b54a4434 100644 (file)
@@ -21,13 +21,12 @@ use boxed::Box;
 use fmt;
 use old_io::{self, IoResult, IoError};
 use old_io::net;
-use iter::{Iterator, IteratorExt};
+use iter::Iterator;
 use ops::{FnOnce, FnMut};
 use option::Option;
 use option::Option::{None, Some};
 use result::Result::{self, Ok, Err};
-use slice::SliceExt;
-use str::{FromStr, StrExt};
+use str::FromStr;
 use vec::Vec;
 
 pub type Port = u16;
@@ -83,7 +82,7 @@ impl fmt::Display for SocketAddr {
 struct Parser<'a> {
     // parsing as ASCII, so can use byte array
     s: &'a [u8],
-    pos: uint,
+    pos: usize,
 }
 
 impl<'a> Parser<'a> {
@@ -198,7 +197,7 @@ impl<'a> Parser<'a> {
     }
 
     fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
-        let mut r = 0u32;
+        let mut r = 0;
         let mut digit_count = 0;
         loop {
             match self.read_digit(radix) {
@@ -226,7 +225,7 @@ impl<'a> Parser<'a> {
     }
 
     fn read_ipv4_addr_impl(&mut self) -> Option<IpAddr> {
-        let mut bs = [0u8; 4];
+        let mut bs = [0; 4];
         let mut i = 0;
         while i < 4 {
             if i != 0 && self.read_given_char('.').is_none() {
@@ -251,13 +250,13 @@ impl<'a> Parser<'a> {
     fn read_ipv6_addr_impl(&mut self) -> Option<IpAddr> {
         fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> IpAddr {
             assert!(head.len() + tail.len() <= 8);
-            let mut gs = [0u16; 8];
+            let mut gs = [0; 8];
             gs.clone_from_slice(head);
             gs[(8 - tail.len()) .. 8].clone_from_slice(tail);
             Ipv6Addr(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7])
         }
 
-        fn read_groups(p: &mut Parser, groups: &mut [u16; 8], limit: uint) -> (uint, bool) {
+        fn read_groups(p: &mut Parser, groups: &mut [u16; 8], limit: usize) -> (usize, bool) {
             let mut i = 0;
             while i < limit {
                 if i < limit - 1 {
@@ -294,7 +293,7 @@ impl<'a> Parser<'a> {
             (i, false)
         }
 
-        let mut head = [0u16; 8];
+        let mut head = [0; 8];
         let (head_size, head_ipv4) = read_groups(self, &mut head, 8);
 
         if head_size == 8 {
@@ -313,7 +312,7 @@ impl<'a> Parser<'a> {
             return None;
         }
 
-        let mut tail = [0u16; 8];
+        let mut tail = [0; 8];
         let (tail_size, _) = read_groups(self, &mut tail, 8 - head_size);
         Some(ipv6_addr_from_head_tail(&head[..head_size], &tail[..tail_size]))
     }
@@ -323,22 +322,22 @@ impl<'a> Parser<'a> {
     }
 
     fn read_ip_addr(&mut self) -> Option<IpAddr> {
-        let ipv4_addr = |p: &mut Parser| p.read_ipv4_addr();
-        let ipv6_addr = |p: &mut Parser| p.read_ipv6_addr();
-        self.read_or(&mut [box ipv4_addr, box ipv6_addr])
+        let ipv4_addr: Box<_> = box |p: &mut Parser| p.read_ipv4_addr();
+        let ipv6_addr: Box<_> = box |p: &mut Parser| p.read_ipv6_addr();
+        self.read_or(&mut [ipv4_addr, ipv6_addr])
     }
 
     fn read_socket_addr(&mut self) -> Option<SocketAddr> {
         let ip_addr = |p: &mut Parser| {
-            let ipv4_p = |p: &mut Parser| p.read_ip_addr();
-            let ipv6_p = |p: &mut Parser| {
+            let ipv4_p: Box<_> = box |p: &mut Parser| p.read_ip_addr();
+            let ipv6_p: Box<_> = box |p: &mut Parser| {
                 let open_br = |p: &mut Parser| p.read_given_char('[');
                 let ip_addr = |p: &mut Parser| p.read_ipv6_addr();
                 let clos_br = |p: &mut Parser| p.read_given_char(']');
                 p.read_seq_3::<char, IpAddr, char, _, _, _>(open_br, ip_addr, clos_br)
                         .map(|t| match t { (_, ip, _) => ip })
             };
-            p.read_or(&mut [box ipv4_p, box ipv6_p])
+            p.read_or(&mut [ipv4_p, ipv6_p])
         };
         let colon = |p: &mut Parser| p.read_given_char(':');
         let port  = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
@@ -415,6 +414,7 @@ pub struct ParseError;
 /// Some examples:
 ///
 /// ```rust,no_run
+/// # #![feature(old_io, core, convert)]
 /// # #![allow(unused_must_use)]
 ///
 /// use std::old_io::{TcpStream, TcpListener};
@@ -425,17 +425,17 @@ pub struct ParseError;
 ///     // The following lines are equivalent modulo possible "localhost" name resolution
 ///     // differences
 ///     let tcp_s = TcpStream::connect(SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 12345 });
-///     let tcp_s = TcpStream::connect((Ipv4Addr(127, 0, 0, 1), 12345u16));
-///     let tcp_s = TcpStream::connect(("127.0.0.1", 12345u16));
-///     let tcp_s = TcpStream::connect(("localhost", 12345u16));
+///     let tcp_s = TcpStream::connect((Ipv4Addr(127, 0, 0, 1), 12345));
+///     let tcp_s = TcpStream::connect(("127.0.0.1", 12345));
+///     let tcp_s = TcpStream::connect(("localhost", 12345));
 ///     let tcp_s = TcpStream::connect("127.0.0.1:12345");
 ///     let tcp_s = TcpStream::connect("localhost:12345");
 ///
 ///     // TcpListener::bind(), UdpSocket::bind() and UdpSocket::send_to() behave similarly
 ///     let tcp_l = TcpListener::bind("localhost:12345");
 ///
-///     let mut udp_s = UdpSocket::bind(("127.0.0.1", 23451u16)).unwrap();
-///     udp_s.send_to([7u8, 7u8, 7u8].as_slice(), (Ipv4Addr(127, 0, 0, 1), 23451u16));
+///     let mut udp_s = UdpSocket::bind(("127.0.0.1", 23451)).unwrap();
+///     udp_s.send_to([7, 7, 7].as_ref(), (Ipv4Addr(127, 0, 0, 1), 23451));
 /// }
 /// ```
 pub trait ToSocketAddr {
@@ -674,7 +674,7 @@ mod test {
     #[test]
     fn to_socket_addr_ipaddr_u16() {
         let a = Ipv4Addr(77, 88, 21, 11);
-        let p = 12345u16;
+        let p = 12345;
         let e = SocketAddr { ip: a, port: p };
         assert_eq!(Ok(e), (a, p).to_socket_addr());
         assert_eq!(Ok(vec![e]), (a, p).to_socket_addr_all());
@@ -683,15 +683,15 @@ mod test {
     #[test]
     fn to_socket_addr_str_u16() {
         let a = SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 24352 };
-        assert_eq!(Ok(a), ("77.88.21.11", 24352u16).to_socket_addr());
-        assert_eq!(Ok(vec![a]), ("77.88.21.11", 24352u16).to_socket_addr_all());
+        assert_eq!(Ok(a), ("77.88.21.11", 24352).to_socket_addr());
+        assert_eq!(Ok(vec![a]), ("77.88.21.11", 24352).to_socket_addr_all());
 
         let a = SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 };
         assert_eq!(Ok(a), ("2a02:6b8:0:1::1", 53).to_socket_addr());
         assert_eq!(Ok(vec![a]), ("2a02:6b8:0:1::1", 53).to_socket_addr_all());
 
         let a = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 23924 };
-        assert!(("localhost", 23924u16).to_socket_addr_all().unwrap().contains(&a));
+        assert!(("localhost", 23924).to_socket_addr_all().unwrap().contains(&a));
     }
 
     #[test]
index bbe3a71dcc0d17a12057884758c81e22de430900..a3567290b0e16395a83003ed874f3301bb469e50 100644 (file)
 
 //! Networking I/O
 
+#![deprecated(since = "1.0.0",
+              reason = "replaced with new I/O primitives in `std::net`")]
+#![unstable(feature = "old_io")]
+
 use old_io::{IoError, IoResult, InvalidInput};
 use ops::FnMut;
 use option::Option::None;
index d05669d32b8cfc0d7f3b8b411b2bce5adc0cb471..3a071e832af64baa01133cc934eb18ae775becd2 100644 (file)
 //! instances as clients.
 
 #![allow(missing_docs)]
+#![deprecated(since = "1.0.0",
+              reason = "will be removed to be reintroduced at a later date; \
+                        in the meantime consider using the `unix_socket` crate \
+                        for unix sockets; there is currently no replacement \
+                        for named pipes")]
+#![unstable(feature = "old_io")]
 
 use prelude::v1::*;
 
 use ffi::CString;
 use old_path::BytesContainer;
 use old_io::{Listener, Acceptor, IoResult, TimedOut, standard_error};
+use old_io::{Reader, Writer};
 use sys::pipe::UnixAcceptor as UnixAcceptorImp;
 use sys::pipe::UnixListener as UnixListenerImp;
 use sys::pipe::UnixStream as UnixStreamImp;
@@ -44,11 +51,14 @@ impl UnixStream {
     ///
     /// The returned stream will be closed when the object falls out of scope.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(old_io, old_path, io)]
     /// # #![allow(unused_must_use)]
     /// use std::old_io::net::pipe::UnixStream;
+    /// use std::old_io::*;
+    /// use std::old_path::Path;
     ///
     /// let server = Path::new("path/to/my/socket");
     /// let mut stream = UnixStream::connect(&server);
@@ -140,7 +150,7 @@ impl Clone for UnixStream {
 }
 
 impl Reader for UnixStream {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         self.inner.read(buf)
     }
 }
@@ -169,12 +179,14 @@ impl UnixListener {
     ///
     /// This listener will be closed when it falls out of scope.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_io, io, old_path)]
     /// # fn foo() {
     /// use std::old_io::net::pipe::UnixListener;
-    /// use std::old_io::{Listener, Acceptor};
+    /// use std::old_io::*;
+    /// use std::old_path::Path;
     ///
     /// let server = Path::new("/path/to/my/socket");
     /// let stream = UnixListener::bind(&server);
@@ -190,7 +202,7 @@ impl UnixListener {
     }
 }
 
-impl Listener<UnixStream, UnixAcceptor> for UnixListener {
+impl Listener<UnixAcceptor> for UnixListener {
     fn listen(self) -> IoResult<UnixAcceptor> {
         self.inner.listen()
             .map(|inner| UnixAcceptor { inner: inner })
@@ -238,7 +250,8 @@ impl UnixAcceptor {
     }
 }
 
-impl Acceptor<UnixStream> for UnixAcceptor {
+impl Acceptor for UnixAcceptor {
+    type Connection = UnixStream;
     fn accept(&mut self) -> IoResult<UnixStream> {
         self.inner.accept().map(|s| {
             UnixStream { inner: s }
@@ -279,6 +292,7 @@ mod tests {
     use old_io::{EndOfFile, TimedOut, ShortWrite, IoError, ConnectionReset};
     use old_io::{NotConnected, BrokenPipe, FileNotFound, InvalidInput, OtherIoError};
     use old_io::{PermissionDenied, Acceptor, Listener};
+    use old_io::{Reader, Writer};
     use old_io::test::*;
     use super::*;
     use sync::mpsc::channel;
index 19a6f6e3defa7be42a677cea30cfdc75df58081d..7fc460c16efca2454a61b7e48bb5d606c62741cf 100644 (file)
@@ -38,10 +38,11 @@ use sys_common;
 ///
 /// The socket will be closed when the value is dropped.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```no_run
-/// use std::old_io::TcpStream;
+/// # #![feature(old_io, io)]
+/// use std::old_io::*;
 ///
 /// {
 ///     let mut stream = TcpStream::connect("127.0.0.1:34254");
@@ -121,7 +122,7 @@ impl TcpStream {
     /// this connection. Otherwise, the keepalive timeout will be set to the
     /// specified time, in seconds.
     #[unstable(feature = "io")]
-    pub fn set_keepalive(&mut self, delay_in_seconds: Option<uint>) -> IoResult<()> {
+    pub fn set_keepalive(&mut self, delay_in_seconds: Option<usize>) -> IoResult<()> {
         self.inner.set_keepalive(delay_in_seconds)
     }
 
@@ -130,12 +131,12 @@ impl TcpStream {
     /// This method will close the reading portion of this connection, causing
     /// all pending and future reads to immediately return with an error.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```no_run
+    /// # #![feature(old_io, std_misc)]
     /// # #![allow(unused_must_use)]
-    /// use std::old_io::timer;
-    /// use std::old_io::TcpStream;
+    /// use std::old_io::*;
     /// use std::time::Duration;
     /// use std::thread;
     ///
@@ -256,7 +257,7 @@ impl Clone for TcpStream {
 }
 
 impl Reader for TcpStream {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         self.inner.read(buf)
     }
 }
@@ -279,9 +280,9 @@ impl sys_common::AsInner<TcpStreamImp> for TcpStream {
 /// # Examples
 ///
 /// ```
+/// # #![feature(old_io)]
 /// # fn foo() {
-/// use std::old_io::{TcpListener, TcpStream};
-/// use std::old_io::{Acceptor, Listener};
+/// use std::old_io::*;
 /// use std::thread;
 ///
 /// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
@@ -337,7 +338,7 @@ impl TcpListener {
     }
 }
 
-impl Listener<TcpStream, TcpAcceptor> for TcpListener {
+impl Listener<TcpAcceptor> for TcpListener {
     fn listen(self) -> IoResult<TcpAcceptor> {
         self.inner.listen(128).map(|a| TcpAcceptor { inner: a })
     }
@@ -373,11 +374,11 @@ impl TcpAcceptor {
     /// regardless of whether the timeout has expired or not (the accept will
     /// not block in this case).
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```no_run
-    /// use std::old_io::TcpListener;
-    /// use std::old_io::{Listener, Acceptor, TimedOut};
+    /// # #![feature(old_io, io)]
+    /// use std::old_io::*;
     ///
     /// let mut a = TcpListener::bind("127.0.0.1:8482").listen().unwrap();
     ///
@@ -417,10 +418,11 @@ impl TcpAcceptor {
     /// This is useful for waking up a thread in an accept loop to indicate that
     /// it should exit.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
-    /// use std::old_io::{TcpListener, Listener, Acceptor, EndOfFile};
+    /// # #![feature(old_io, io)]
+    /// use std::old_io::*;
     /// use std::thread;
     ///
     /// let mut a = TcpListener::bind("127.0.0.1:8482").listen().unwrap();
@@ -451,7 +453,8 @@ impl TcpAcceptor {
     }
 }
 
-impl Acceptor<TcpStream> for TcpAcceptor {
+impl Acceptor for TcpAcceptor {
+    type Connection = TcpStream;
     fn accept(&mut self) -> IoResult<TcpStream> {
         self.inner.accept().map(TcpStream::new)
     }
@@ -496,6 +499,7 @@ mod test {
     use old_io::{ConnectionReset, NotConnected, PermissionDenied, OtherIoError};
     use old_io::{InvalidInput};
     use old_io::{Acceptor, Listener};
+    use old_io::{Reader, Writer};
 
     // FIXME #11530 this fails on android because tests are run as root
     #[cfg_attr(any(windows, target_os = "android"), ignore)]
@@ -786,12 +790,12 @@ mod test {
     #[test]
     fn multiple_connect_interleaved_greedy_schedule_ip4() {
         let addr = next_test_ip4();
-        static MAX: int = 10;
+        static MAX: isize = 10;
         let acceptor = TcpListener::bind(addr).listen();
 
         let _t = thread::spawn(move|| {
             let mut acceptor = acceptor;
-            for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
+            for (i, stream) in acceptor.incoming().enumerate().take(MAX as usize) {
                 // Start another task to handle the connection
                 let _t = thread::spawn(move|| {
                     let mut stream = stream;
@@ -805,7 +809,7 @@ mod test {
 
         connect(0, addr);
 
-        fn connect(i: int, addr: SocketAddr) {
+        fn connect(i: isize, addr: SocketAddr) {
             if i == MAX { return }
 
             let _t = thread::spawn(move|| {
@@ -822,12 +826,12 @@ mod test {
     #[test]
     fn multiple_connect_interleaved_greedy_schedule_ip6() {
         let addr = next_test_ip6();
-        static MAX: int = 10;
+        static MAX: isize = 10;
         let acceptor = TcpListener::bind(addr).listen();
 
         let _t = thread::spawn(move|| {
             let mut acceptor = acceptor;
-            for (i, stream) in acceptor.incoming().enumerate().take(MAX as uint) {
+            for (i, stream) in acceptor.incoming().enumerate().take(MAX as usize) {
                 // Start another task to handle the connection
                 let _t = thread::spawn(move|| {
                     let mut stream = stream;
@@ -841,7 +845,7 @@ mod test {
 
         connect(0, addr);
 
-        fn connect(i: int, addr: SocketAddr) {
+        fn connect(i: isize, addr: SocketAddr) {
             if i == MAX { return }
 
             let _t = thread::spawn(move|| {
@@ -857,13 +861,13 @@ mod test {
 
     #[test]
     fn multiple_connect_interleaved_lazy_schedule_ip4() {
-        static MAX: int = 10;
+        static MAX: isize = 10;
         let addr = next_test_ip4();
         let acceptor = TcpListener::bind(addr).listen();
 
         let _t = thread::spawn(move|| {
             let mut acceptor = acceptor;
-            for stream in acceptor.incoming().take(MAX as uint) {
+            for stream in acceptor.incoming().take(MAX as usize) {
                 // Start another task to handle the connection
                 let _t = thread::spawn(move|| {
                     let mut stream = stream;
@@ -877,7 +881,7 @@ mod test {
 
         connect(0, addr);
 
-        fn connect(i: int, addr: SocketAddr) {
+        fn connect(i: isize, addr: SocketAddr) {
             if i == MAX { return }
 
             let _t = thread::spawn(move|| {
@@ -893,13 +897,13 @@ mod test {
 
     #[test]
     fn multiple_connect_interleaved_lazy_schedule_ip6() {
-        static MAX: int = 10;
+        static MAX: isize = 10;
         let addr = next_test_ip6();
         let acceptor = TcpListener::bind(addr).listen();
 
         let _t = thread::spawn(move|| {
             let mut acceptor = acceptor;
-            for stream in acceptor.incoming().take(MAX as uint) {
+            for stream in acceptor.incoming().take(MAX as usize) {
                 // Start another task to handle the connection
                 let _t = thread::spawn(move|| {
                     let mut stream = stream;
@@ -913,7 +917,7 @@ mod test {
 
         connect(0, addr);
 
-        fn connect(i: int, addr: SocketAddr) {
+        fn connect(i: isize, addr: SocketAddr) {
             if i == MAX { return }
 
             let _t = thread::spawn(move|| {
@@ -1162,7 +1166,7 @@ mod test {
                 tx.send(TcpStream::connect(addr).unwrap()).unwrap();
             });
             let _l = rx.recv().unwrap();
-            for i in 0i32..1001 {
+            for i in 0..1001 {
                 match a.accept() {
                     Ok(..) => break,
                     Err(ref e) if e.kind == TimedOut => {}
@@ -1262,7 +1266,7 @@ mod test {
         assert_eq!(s.read(&mut [0]).err().unwrap().kind, TimedOut);
 
         s.set_timeout(Some(20));
-        for i in 0i32..1001 {
+        for i in 0..1001 {
             match s.write(&[0; 128 * 1024]) {
                 Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
                 Err(IoError { kind: TimedOut, .. }) => break,
@@ -1320,7 +1324,7 @@ mod test {
 
         let mut s = a.accept().unwrap();
         s.set_write_timeout(Some(20));
-        for i in 0i32..1001 {
+        for i in 0..1001 {
             match s.write(&[0; 128 * 1024]) {
                 Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
                 Err(IoError { kind: TimedOut, .. }) => break,
index 67b57b250860f961c61cb8a1d47165f602335ab1..196447d71efbf8ff598cf6fa4bb564365aa790b1 100644 (file)
@@ -28,9 +28,10 @@ use sys_common;
 /// IPv6 addresses, and there is no corresponding notion of a server because UDP
 /// is a datagram protocol.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```rust,no_run
+/// # #![feature(old_io)]
 /// # #![allow(unused_must_use)]
 ///
 /// use std::old_io::net::udp::UdpSocket;
@@ -72,7 +73,7 @@ impl UdpSocket {
 
     /// Receives data from the socket. On success, returns the number of bytes
     /// read and the address from whence the data came.
-    pub fn recv_from(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)> {
+    pub fn recv_from(&mut self, buf: &mut [u8]) -> IoResult<(usize, SocketAddr)> {
         self.inner.recv_from(buf)
     }
 
@@ -112,13 +113,13 @@ impl UdpSocket {
 
     /// Sets the multicast TTL
     #[unstable(feature = "io")]
-    pub fn set_multicast_ttl(&mut self, ttl: int) -> IoResult<()> {
+    pub fn set_multicast_ttl(&mut self, ttl: isize) -> IoResult<()> {
         self.inner.multicast_time_to_live(ttl)
     }
 
     /// Sets this socket's TTL
     #[unstable(feature = "io")]
-    pub fn set_ttl(&mut self, ttl: int) -> IoResult<()> {
+    pub fn set_ttl(&mut self, ttl: isize) -> IoResult<()> {
         self.inner.time_to_live(ttl)
     }
 
index b7b626db034e1648076fc250b22ff4284ce30afe..fd1df49473e586d4bd6c40b8a497bf1a1937d963 100644 (file)
@@ -17,7 +17,7 @@
 
 use prelude::v1::*;
 
-use old_io::IoResult;
+use old_io::{IoResult, Reader, Writer};
 use libc;
 use sync::Arc;
 
@@ -43,13 +43,14 @@ impl PipeStream {
     /// This operation consumes ownership of the file descriptor and it will be
     /// closed once the object is deallocated.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```{rust,no_run}
+    /// # #![feature(old_io, libc, io)]
     /// # #![allow(unused_must_use)]
     /// extern crate libc;
     ///
-    /// use std::old_io::pipe::PipeStream;
+    /// use std::old_io::*;
     ///
     /// fn main() {
     ///     let mut pipe = PipeStream::open(libc::STDERR_FILENO);
@@ -99,7 +100,7 @@ impl Clone for PipeStream {
 }
 
 impl Reader for PipeStream {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         self.inner.read(buf)
     }
 }
@@ -114,6 +115,7 @@ impl Writer for PipeStream {
 mod test {
     use prelude::v1::*;
 
+    use old_io::{Writer, Reader};
     use sync::mpsc::channel;
     use thread;
 
@@ -122,9 +124,9 @@ mod test {
         use os;
         use old_io::pipe::PipeStream;
 
-        let os::Pipe { reader, writer } = unsafe { os::pipe().unwrap() };
-        let out = PipeStream::open(writer);
-        let mut input = PipeStream::open(reader);
+        let (reader, writer) = unsafe { ::sys::os::pipe().unwrap() };
+        let out = PipeStream::open(writer.unwrap());
+        let mut input = PipeStream::open(reader.unwrap());
         let (tx, rx) = channel();
         let _t = thread::spawn(move|| {
             let mut out = out;
index c803cfbcb7d85db2b9a77b33955b1ebce56c67a8..ad2d5b4681978c99e5231f20cacdaad5eb4ee7c8 100644 (file)
@@ -11,6 +11,9 @@
 //! Bindings for executing child processes
 
 #![allow(non_upper_case_globals)]
+#![unstable(feature = "old_io")]
+#![deprecated(since = "1.0.0",
+              reason = "replaced with the std::process module")]
 
 pub use self::StdioContainer::*;
 pub use self::ProcessExit::*;
@@ -21,8 +24,9 @@ use collections::HashMap;
 use ffi::CString;
 use fmt;
 use old_io::pipe::{PipeStream, PipePair};
-use old_io::{IoResult, IoError};
+use old_io::{IoResult, IoError, Reader, Writer};
 use old_io;
+use old_path::{Path, GenericPath};
 use libc;
 use os;
 use old_path::BytesContainer;
@@ -37,16 +41,16 @@ use thread;
 
 /// Signal a process to exit, without forcibly killing it. Corresponds to
 /// SIGTERM on unix platforms.
-#[cfg(windows)] pub const PleaseExitSignal: int = 15;
+#[cfg(windows)] pub const PleaseExitSignal: isize = 15;
 /// Signal a process to exit immediately, forcibly killing it. Corresponds to
 /// SIGKILL on unix platforms.
-#[cfg(windows)] pub const MustDieSignal: int = 9;
+#[cfg(windows)] pub const MustDieSignal: isize = 9;
 /// Signal a process to exit, without forcibly killing it. Corresponds to
 /// SIGTERM on unix platforms.
-#[cfg(not(windows))] pub const PleaseExitSignal: int = libc::SIGTERM as int;
+#[cfg(not(windows))] pub const PleaseExitSignal: isize = libc::SIGTERM as isize;
 /// Signal a process to exit immediately, forcibly killing it. Corresponds to
 /// SIGKILL on unix platforms.
-#[cfg(not(windows))] pub const MustDieSignal: int = libc::SIGKILL as int;
+#[cfg(not(windows))] pub const MustDieSignal: isize = libc::SIGKILL as isize;
 
 /// Representation of a running or exited child process.
 ///
@@ -54,10 +58,11 @@ use thread;
 /// process is created via the `Command` struct, which configures the spawning
 /// process and can itself be constructed using a builder-style interface.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```should_fail
-/// use std::old_io::Command;
+/// ```should_panic
+/// # #![feature(old_io)]
+/// use std::old_io::*;
 ///
 /// let mut child = match Command::new("/bin/cat").arg("file.txt").spawn() {
 ///     Ok(child) => child,
@@ -75,7 +80,7 @@ pub struct Process {
     exit_code: Option<ProcessExit>,
 
     /// Manually delivered signal
-    exit_signal: Option<int>,
+    exit_signal: Option<isize>,
 
     /// Deadline after which wait() will return
     deadline: u64,
@@ -104,25 +109,14 @@ struct EnvKey(CString);
 #[derive(Eq, Clone, Debug)]
 struct EnvKey(CString);
 
-#[cfg(all(windows, stage0))]
-impl<H: hash::Writer + hash::Hasher> hash::Hash<H> for EnvKey {
-    fn hash(&self, state: &mut H) {
-        let &EnvKey(ref x) = self;
-        match str::from_utf8(x.as_bytes()) {
-            Ok(s) => for ch in s.chars() {
-                (ch as u8 as char).to_lowercase().hash(state);
-            },
-            Err(..) => x.hash(state)
-        }
-    }
-}
-#[cfg(all(windows, not(stage0)))]
+#[cfg(windows)]
 impl hash::Hash for EnvKey {
     fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        use ascii::AsciiExt;
         let &EnvKey(ref x) = self;
         match str::from_utf8(x.as_bytes()) {
             Ok(s) => for ch in s.chars() {
-                (ch as u8 as char).to_lowercase().hash(state);
+                ch.to_ascii_lowercase().hash(state);
             },
             Err(..) => x.hash(state)
         }
@@ -132,6 +126,7 @@ impl hash::Hash for EnvKey {
 #[cfg(windows)]
 impl PartialEq for EnvKey {
     fn eq(&self, other: &EnvKey) -> bool {
+        use ascii::AsciiExt;
         let &EnvKey(ref x) = self;
         let &EnvKey(ref y) = other;
         match (str::from_utf8(x.as_bytes()), str::from_utf8(y.as_bytes())) {
@@ -140,7 +135,7 @@ impl PartialEq for EnvKey {
                     return false
                 } else {
                     for (xch, ych) in xs.chars().zip(ys.chars()) {
-                        if xch.to_lowercase() != ych.to_lowercase() {
+                        if xch.to_ascii_lowercase() != ych.to_ascii_lowercase() {
                             return false;
                         }
                     }
@@ -170,7 +165,8 @@ pub type EnvMap = HashMap<EnvKey, CString>;
 /// to be changed (for example, by adding arguments) prior to spawning:
 ///
 /// ```
-/// use std::old_io::Command;
+/// # #![feature(old_io)]
+/// use std::old_io::*;
 ///
 /// let mut process = match Command::new("sh").arg("-c").arg("echo hello").spawn() {
 ///   Ok(p) => p,
@@ -190,8 +186,8 @@ pub struct Command {
     stdin: StdioContainer,
     stdout: StdioContainer,
     stderr: StdioContainer,
-    uid: Option<uint>,
-    gid: Option<uint>,
+    uid: Option<usize>,
+    gid: Option<usize>,
     detach: bool,
 }
 
@@ -250,7 +246,7 @@ impl Command {
             None => {
                 // 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)| {
+                self.env = Some(::env::vars().map(|(k, v)| {
                     (EnvKey(CString::new(k).unwrap()),
                      CString::new(v).unwrap())
                 }).collect());
@@ -325,14 +321,14 @@ impl Command {
     /// the child process. Setting this value on windows will cause the spawn to
     /// fail. Failure in the `setuid` call on unix will also cause the spawn to
     /// fail.
-    pub fn uid<'a>(&'a mut self, id: uint) -> &'a mut Command {
+    pub fn uid<'a>(&'a mut self, id: usize) -> &'a mut Command {
         self.uid = Some(id);
         self
     }
 
     /// Similar to `uid`, but sets the group id of the child process. This has
     /// the same semantics as the `uid` field.
-    pub fn gid<'a>(&'a mut self, id: uint) -> &'a mut Command {
+    pub fn gid<'a>(&'a mut self, id: usize) -> &'a mut Command {
         self.gid = Some(id);
         self
     }
@@ -368,9 +364,10 @@ impl Command {
     /// Executes the command as a child process, waiting for it to finish and
     /// collecting all of its output.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_io, core, convert)]
     /// use std::old_io::Command;
     ///
     /// let output = match Command::new("cat").arg("foot.txt").output() {
@@ -379,8 +376,8 @@ impl Command {
     /// };
     ///
     /// println!("status: {}", output.status);
-    /// println!("stdout: {}", String::from_utf8_lossy(output.output.as_slice()));
-    /// println!("stderr: {}", String::from_utf8_lossy(output.error.as_slice()));
+    /// println!("stdout: {}", String::from_utf8_lossy(output.output.as_ref()));
+    /// println!("stderr: {}", String::from_utf8_lossy(output.error.as_ref()));
     /// ```
     pub fn output(&self) -> IoResult<ProcessOutput> {
         self.spawn().and_then(|p| p.wait_with_output())
@@ -389,9 +386,10 @@ impl Command {
     /// Executes a command as a child process, waiting for it to finish and
     /// collecting its exit status.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_io)]
     /// use std::old_io::Command;
     ///
     /// let status = match Command::new("ls").status() {
@@ -460,10 +458,10 @@ impl sys::process::ProcessConfig<EnvKey, CString> for Command {
     fn cwd(&self) -> Option<&CString> {
         self.cwd.as_ref()
     }
-    fn uid(&self) -> Option<uint> {
+    fn uid(&self) -> Option<usize> {
         self.uid.clone()
     }
-    fn gid(&self) -> Option<uint> {
+    fn gid(&self) -> Option<usize> {
         self.gid.clone()
     }
     fn detach(&self) -> bool {
@@ -509,10 +507,10 @@ pub enum StdioContainer {
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 pub enum ProcessExit {
     /// Normal termination with an exit status.
-    ExitStatus(int),
+    ExitStatus(isize),
 
     /// Termination by signal, with the signal number.
-    ExitSignal(int),
+    ExitSignal(isize),
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -535,7 +533,7 @@ impl ProcessExit {
 
     /// Checks whether this ProcessExit matches the given exit status.
     /// Termination by signal will never match an exit code.
-    pub fn matches_exit_status(&self, wanted: int) -> bool {
+    pub fn matches_exit_status(&self, wanted: isize) -> bool {
         *self == ExitStatus(wanted)
     }
 }
@@ -551,7 +549,7 @@ impl Process {
     /// process. Note, though, that on some platforms signals will continue to
     /// be successfully delivered if the child has exited, but not yet been
     /// reaped.
-    pub fn kill(id: libc::pid_t, signal: int) -> IoResult<()> {
+    pub fn kill(id: libc::pid_t, signal: isize) -> IoResult<()> {
         unsafe { ProcessImp::killpid(id, signal) }
     }
 
@@ -573,7 +571,7 @@ impl Process {
     /// # Errors
     ///
     /// If the signal delivery fails, the corresponding error is returned.
-    pub fn signal(&mut self, signal: int) -> IoResult<()> {
+    pub fn signal(&mut self, signal: isize) -> IoResult<()> {
         #[cfg(unix)] fn collect_status(p: &mut Process) {
             // On Linux (and possibly other unices), a process that has exited will
             // continue to accept signals because it is "defunct". The delivery of
@@ -663,9 +661,10 @@ impl Process {
     /// A value of `None` will clear any previous timeout, and a value of `Some`
     /// will override any previously set timeout.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```no_run
+    /// # #![feature(old_io, io)]
     /// use std::old_io::{Command, IoResult};
     /// use std::old_io::process::ProcessExit;
     ///
@@ -765,10 +764,10 @@ impl Drop for Process {
 
 #[cfg(test)]
 mod tests {
+    use prelude::v1::*;
     use old_io::{Truncate, Write, TimedOut, timer, process, FileNotFound};
-    use prelude::v1::{Ok, Err, range, drop, Some, None, Vec};
-    use prelude::v1::{Path, String, Reader, Writer, Clone};
-    use prelude::v1::{SliceExt, Str, StrExt, AsSlice, ToString, GenericPath};
+    use old_io::{Reader, Writer};
+    use old_path::{GenericPath, Path};
     use old_io::fs::PathExtensions;
     use old_io::timer::*;
     use rt::running_on_valgrind;
@@ -887,8 +886,8 @@ mod tests {
         use libc;
         let mut p = Command::new("/bin/sh")
                             .arg("-c").arg("true")
-                            .uid(unsafe { libc::getuid() as uint })
-                            .gid(unsafe { libc::getgid() as uint })
+                            .uid(unsafe { libc::getuid() as usize })
+                            .gid(unsafe { libc::getgid() as usize })
                             .spawn().unwrap();
         assert!(p.wait().unwrap().success());
     }
@@ -1002,7 +1001,7 @@ mod tests {
         let prog = pwd_cmd().spawn().unwrap();
 
         let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
-        let parent_dir = os::getcwd().unwrap();
+        let parent_dir = Path::new(::env::current_dir().unwrap().to_str().unwrap());
         let child_dir = Path::new(output.trim());
 
         let parent_stat = parent_dir.stat().unwrap();
@@ -1017,7 +1016,7 @@ mod tests {
         use os;
         // test changing to the parent of os::getcwd() because we know
         // the path exists (and os::getcwd() is not expected to be root)
-        let parent_dir = os::getcwd().unwrap().dir_path();
+        let parent_dir = Path::new(::env::current_dir().unwrap().to_str().unwrap());
         let prog = pwd_cmd().cwd(&parent_dir).spawn().unwrap();
 
         let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
@@ -1057,11 +1056,11 @@ mod tests {
         let prog = env_cmd().spawn().unwrap();
         let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
 
-        let r = os::env();
-        for &(ref k, ref v) in &r {
+        let r = ::env::vars();
+        for (k, v) in r {
             // don't check windows magical empty-named variables
             assert!(k.is_empty() ||
-                    output.contains(&format!("{}={}", *k, *v)),
+                    output.contains(&format!("{}={}", k, v)),
                     "output doesn't contain `{}={}`\n{}",
                     k, v, output);
         }
@@ -1075,16 +1074,12 @@ mod tests {
         let mut prog = env_cmd().spawn().unwrap();
         let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
 
-        let r = os::env();
-        for &(ref k, ref v) in &r {
+        let r = ::env::vars();
+        for (k, v) in r {
             // don't check android RANDOM variables
-            if *k != "RANDOM".to_string() {
-                assert!(output.contains(&format!("{}={}",
-                                                 *k,
-                                                 *v)) ||
-                        output.contains(&format!("{}=\'{}\'",
-                                                 *k,
-                                                 *v)));
+            if k != "RANDOM".to_string() {
+                assert!(output.contains(&format!("{}={}", k, v)) ||
+                        output.contains(&format!("{}=\'{}\'", k, v)));
             }
         }
     }
@@ -1099,9 +1094,9 @@ mod tests {
         // PATH to our sub-process.
         let path_val: String;
         let mut new_env = vec![("RUN_TEST_NEW_ENV", "123")];
-        match os::getenv("PATH") {
-            None => {}
-            Some(val) => {
+        match ::env::var("PATH") {
+            Err(..) => {}
+            Ok(val) => {
                 path_val = val;
                 new_env.push(("PATH", &path_val))
             }
@@ -1238,7 +1233,7 @@ mod tests {
         cmd.env("path", "foo");
         cmd.env("Path", "bar");
         let env = &cmd.env.unwrap();
-        let val = env.get(&EnvKey(CString::new(b"PATH").unwrap()));
-        assert!(val.unwrap() == &CString::new(b"bar").unwrap());
+        let val = env.get(&EnvKey(CString::new("PATH").unwrap()));
+        assert!(val.unwrap() == &CString::new("bar").unwrap());
     }
 }
index f42cb6ce8c97bf4d9c9f93d1b5ef9a2b5273945a..e1037f26b7fcf575bf61f50a0905745125ceb6da 100644 (file)
@@ -35,7 +35,7 @@ impl<W: Writer> Writer for IoResult<W> {
 }
 
 impl<R: Reader> Reader for IoResult<R> {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         match *self {
             Ok(ref mut reader) => reader.read(buf),
             Err(ref e) => Err(e.clone()),
@@ -58,7 +58,7 @@ impl<S: Seek> Seek for IoResult<S> {
     }
 }
 
-impl<T, A: Acceptor<T>, L: Listener<T, A>> Listener<T, A> for IoResult<L> {
+impl<A: Acceptor, L: Listener<A>> Listener<A> for IoResult<L> {
     fn listen(self) -> IoResult<A> {
         match self {
             Ok(listener) => listener.listen(),
@@ -67,8 +67,9 @@ impl<T, A: Acceptor<T>, L: Listener<T, A>> Listener<T, A> for IoResult<L> {
     }
 }
 
-impl<T, A: Acceptor<T>> Acceptor<T> for IoResult<A> {
-    fn accept(&mut self) -> IoResult<T> {
+impl<A: Acceptor> Acceptor for IoResult<A> {
+    type Connection = A::Connection;
+    fn accept(&mut self) -> IoResult<A::Connection> {
         match *self {
             Ok(ref mut acceptor) => acceptor.accept(),
             Err(ref e) => Err(e.clone()),
@@ -80,14 +81,14 @@ impl<T, A: Acceptor<T>> Acceptor<T> for IoResult<A> {
 mod test {
     use prelude::v1::*;
     use super::super::mem::*;
-    use old_io;
+    use old_io::{self, Reader, Writer};
 
     #[test]
     fn test_option_writer() {
         let mut writer: old_io::IoResult<Vec<u8>> = Ok(Vec::new());
         writer.write_all(&[0, 1, 2]).unwrap();
         writer.flush().unwrap();
-        assert_eq!(writer.unwrap(), vec!(0, 1, 2));
+        assert_eq!(writer.unwrap(), [0, 1, 2]);
     }
 
     #[test]
index e3d0232684fcc3a9b57c25735973550c8a00b607..b4924c7b78b753112d6e58ff59b9b8872fe4c28c 100644 (file)
 //! inspected for information about terminal dimensions or for related information
 //! about the stream or terminal to which it is attached.
 //!
-//! # Example
+//! # Examples
 //!
 //! ```rust
+//! # #![feature(old_io)]
 //! # #![allow(unused_must_use)]
 //! use std::old_io;
+//! use std::old_io::*;
 //!
 //! let mut out = old_io::stdout();
 //! out.write_all(b"Hello, world!");
 
 use self::StdSource::*;
 
+use boxed;
 use boxed::Box;
 use cell::RefCell;
 use clone::Clone;
-use panicking::LOCAL_STDERR;
 use fmt;
 use old_io::{Reader, Writer, IoResult, IoError, OtherIoError, Buffer,
-         standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
+             standard_error, EndOfFile, LineBufferedWriter, BufferedReader};
 use marker::{Sync, Send};
 use libc;
 use mem;
@@ -43,8 +45,6 @@ use ops::{Deref, DerefMut, FnOnce};
 use ptr;
 use result::Result::{Ok, Err};
 use rt;
-use slice::SliceExt;
-use str::StrExt;
 use string::String;
 use sys::{fs, tty};
 use sync::{Arc, Mutex, MutexGuard, Once, ONCE_INIT};
@@ -140,8 +140,10 @@ impl StdinReader {
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(old_io)]
     /// use std::old_io;
+    /// use std::old_io::*;
     ///
     /// let mut stdin = old_io::stdin();
     /// for line in stdin.lock().lines() {
@@ -180,7 +182,7 @@ impl StdinReader {
 }
 
 impl Reader for StdinReader {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         self.inner.lock().unwrap().0.read(buf)
     }
 
@@ -188,11 +190,11 @@ impl Reader for StdinReader {
     // read more than once and we don't want those calls to interleave (or
     // incur the costs of repeated locking).
 
-    fn read_at_least(&mut self, min: uint, buf: &mut [u8]) -> IoResult<uint> {
+    fn read_at_least(&mut self, min: usize, buf: &mut [u8]) -> IoResult<usize> {
         self.inner.lock().unwrap().0.read_at_least(min, buf)
     }
 
-    fn push_at_least(&mut self, min: uint, len: uint, buf: &mut Vec<u8>) -> IoResult<uint> {
+    fn push_at_least(&mut self, min: usize, len: usize, buf: &mut Vec<u8>) -> IoResult<usize> {
         self.inner.lock().unwrap().0.push_at_least(min, len, buf)
     }
 
@@ -200,11 +202,11 @@ impl Reader for StdinReader {
         self.inner.lock().unwrap().0.read_to_end()
     }
 
-    fn read_le_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
+    fn read_le_uint_n(&mut self, nbytes: usize) -> IoResult<u64> {
         self.inner.lock().unwrap().0.read_le_uint_n(nbytes)
     }
 
-    fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
+    fn read_be_uint_n(&mut self, nbytes: usize) -> IoResult<u64> {
         self.inner.lock().unwrap().0.read_be_uint_n(nbytes)
     }
 }
@@ -218,15 +220,15 @@ impl Reader for StdinReader {
 /// See `stdout()` for more notes about this function.
 pub fn stdin() -> StdinReader {
     // We're following the same strategy as kimundi's lazy_static library
-    static mut STDIN: *const StdinReader = 0 as *const StdinReader;
+    static mut STDIN: *mut StdinReader = 0 as *mut StdinReader;
     static ONCE: Once = ONCE_INIT;
 
     unsafe {
         ONCE.call_once(|| {
-            // The default buffer capacity is 64k, but apparently windows doesn't like
-            // 64k reads on stdin. See #13304 for details, but the idea is that on
-            // windows we use a slightly smaller buffer that's been seen to be
-            // acceptable.
+            // The default buffer capacity is 64k, but apparently windows
+            // doesn't like 64k reads on stdin. See #13304 for details, but the
+            // idea is that on windows we use a slightly smaller buffer that's
+            // been seen to be acceptable.
             let stdin = if cfg!(windows) {
                 BufferedReader::with_capacity(8 * 1024, stdin_raw())
             } else {
@@ -235,12 +237,12 @@ pub fn stdin() -> StdinReader {
             let stdin = StdinReader {
                 inner: Arc::new(Mutex::new(RaceBox(stdin)))
             };
-            STDIN = mem::transmute(box stdin);
+            STDIN = boxed::into_raw(box stdin);
 
             // Make sure to free it at exit
-            rt::at_exit(|| {
-                mem::transmute::<_, Box<StdinReader>>(STDIN);
-                STDIN = ptr::null();
+            let _ = rt::at_exit(|| {
+                Box::from_raw(STDIN);
+                STDIN = ptr::null_mut();
             });
         });
 
@@ -318,14 +320,10 @@ pub fn set_stdout(stdout: Box<Writer + Send>) -> Option<Box<Writer + Send>> {
 ///
 /// Note that this does not need to be called for all new tasks; the default
 /// output handle is to the process's stderr stream.
-pub fn set_stderr(stderr: Box<Writer + Send>) -> Option<Box<Writer + Send>> {
-    let mut new = Some(stderr);
-    LOCAL_STDERR.with(|slot| {
-        mem::replace(&mut *slot.borrow_mut(), new.take())
-    }).and_then(|mut s| {
-        let _ = s.flush();
-        Some(s)
-    })
+#[unstable(feature = "old_io")]
+#[deprecated(since = "1.0.0", reason = "replaced with std::io::set_panic")]
+pub fn set_stderr(_stderr: Box<Writer + Send>) -> Option<Box<Writer + Send>> {
+    None
 }
 
 // Helper to access the local task's stdout handle
@@ -339,10 +337,10 @@ pub fn set_stderr(stderr: Box<Writer + Send>) -> Option<Box<Writer + Send>> {
 //      })
 //  })
 fn with_task_stdout<F>(f: F) where F: FnOnce(&mut Writer) -> IoResult<()> {
-    let mut my_stdout = LOCAL_STDOUT.with(|slot| {
+    let mut my_stdout: Box<Writer + Send> = LOCAL_STDOUT.with(|slot| {
         slot.borrow_mut().take()
     }).unwrap_or_else(|| {
-        box stdout() as Box<Writer + Send>
+        box stdout()
     });
     let result = f(&mut *my_stdout);
     let mut var = Some(my_stdout);
@@ -412,16 +410,16 @@ impl StdReader {
 }
 
 impl Reader for StdReader {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         let ret = match self.inner {
             TTY(ref mut tty) => {
                 // Flush the task-local stdout so that weird issues like a
                 // print!'d prompt not being shown until after the user hits
                 // enter.
                 flush();
-                tty.read(buf).map(|i| i as uint)
+                tty.read(buf).map(|i| i as usize)
             },
-            File(ref mut file) => file.read(buf).map(|i| i as uint),
+            File(ref mut file) => file.read(buf).map(|i| i as usize),
         };
         match ret {
             // When reading a piped stdin, libuv will return 0-length reads when
@@ -454,7 +452,7 @@ impl StdWriter {
     ///
     /// This function will return an error if the output stream is not actually
     /// connected to a TTY instance, or if querying the TTY instance fails.
-    pub fn winsize(&mut self) -> IoResult<(int, int)> {
+    pub fn winsize(&mut self) -> IoResult<(isize, isize)> {
         match self.inner {
             TTY(ref mut tty) => {
                 tty.get_winsize()
@@ -539,31 +537,4 @@ mod tests {
         stdout();
         stderr();
     }
-
-    #[test]
-    fn capture_stdout() {
-        use old_io::{ChanReader, ChanWriter};
-
-        let (tx, rx) = channel();
-        let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
-        let _t = thread::spawn(move|| {
-            set_stdout(box w);
-            println!("hello!");
-        });
-        assert_eq!(r.read_to_string().unwrap(), "hello!\n");
-    }
-
-    #[test]
-    fn capture_stderr() {
-        use old_io::{ChanReader, ChanWriter, Reader};
-
-        let (tx, rx) = channel();
-        let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
-        let _t = thread::spawn(move || -> () {
-            set_stderr(box w);
-            panic!("my special message");
-        });
-        let s = r.read_to_string().unwrap();
-        assert!(s.contains("my special message"));
-    }
 }
index 42317c7a2d4316be452817d5b0988bc00a667cad..94faa5540bb30d538945a8e27b8c239a61345aee 100644 (file)
@@ -12,7 +12,7 @@
 #![allow(deprecated)] // rand
 
 use env;
-use iter::{IteratorExt};
+use iter::Iterator;
 use old_io::{fs, IoError, IoErrorKind, IoResult};
 use old_io;
 use ops::Drop;
@@ -21,7 +21,6 @@ use option::Option;
 use old_path::{Path, GenericPath};
 use rand::{Rng, thread_rng};
 use result::Result::{Ok, Err};
-use str::StrExt;
 use string::String;
 
 /// A wrapper for a path to temporary directory implementing automatic
@@ -30,7 +29,9 @@ use string::String;
 /// # Examples
 ///
 /// ```no_run
-/// use std::old_io::TempDir;
+/// # #![feature(old_io, old_path)]
+/// use std::old_io::*;
+/// use std::old_path::{Path, GenericPath};
 ///
 /// {
 ///     // create a temporary directory
@@ -88,7 +89,7 @@ const NUM_RETRIES: u32 = 1 << 31;
 // be enough to dissuade an attacker from trying to preemptively create names
 // of that length, but not so huge that we unnecessarily drain the random number
 // generator of entropy.
-const NUM_RAND_CHARS: uint = 12;
+const NUM_RAND_CHARS: usize = 12;
 
 impl TempDir {
     /// Attempts to make a temporary directory inside of `tmpdir` whose name
@@ -96,9 +97,11 @@ impl TempDir {
     /// deleted once the returned wrapper is destroyed.
     ///
     /// If no directory can be created, `Err` is returned.
+    #[allow(deprecated)]
     pub fn new_in(tmpdir: &Path, prefix: &str) -> IoResult<TempDir> {
         if !tmpdir.is_absolute() {
-            let cur_dir = try!(env::current_dir());
+            let cur_dir = ::env::current_dir().unwrap();
+            let cur_dir = Path::new(cur_dir.to_str().unwrap());
             return TempDir::new_in(&cur_dir.join(tmpdir), prefix);
         }
 
@@ -132,8 +135,10 @@ impl TempDir {
     /// deleted once the returned wrapper is destroyed.
     ///
     /// If no directory can be created, `Err` is returned.
+    #[allow(deprecated)]
     pub fn new(prefix: &str) -> IoResult<TempDir> {
-        TempDir::new_in(&env::temp_dir(), prefix)
+        let tmp = Path::new(::env::temp_dir().to_str().unwrap());
+        TempDir::new_in(&tmp, prefix)
     }
 
     /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper.
index ee72beccfa8488f61fa0f997809ea11b8bc8c3fa..312e1c814dc58e730c588e446da5dbcd877879ce 100644 (file)
@@ -14,7 +14,8 @@ use prelude::v1::*;
 
 use env;
 use libc;
-use std::old_io::net::ip::*;
+use old_io::net::ip::*;
+use old_path::{Path, GenericPath};
 use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 
 /// Get a port number, starting at 9600, for use in tests
@@ -38,10 +39,11 @@ fn next_test_unix_socket() -> String {
 
 /// Get a temporary path which could be the location of a unix socket
 #[cfg(not(target_os = "ios"))]
+#[allow(deprecated)]
 pub fn next_test_unix() -> Path {
     let string = next_test_unix_socket();
     if cfg!(unix) {
-        env::temp_dir().join(string)
+        Path::new(::env::temp_dir().to_str().unwrap()).join(string)
     } else {
         Path::new(format!("{}{}", r"\\.\pipe\", string))
     }
@@ -72,8 +74,8 @@ it is running in and assigns a port range based on it.
 */
 fn base_port() -> u16 {
 
-    let base = 9600u16;
-    let range = 1000u16;
+    let base = 9600;
+    let range = 1000;
 
     let bases = [
         ("32-opt", base + range * 1),
@@ -88,7 +90,7 @@ fn base_port() -> u16 {
 
     // FIXME (#9639): This needs to handle non-utf8 paths
     let path = env::current_dir().unwrap();
-    let path_s = path.as_str().unwrap();
+    let path_s = path.to_str().unwrap();
 
     let mut final_base = base;
 
@@ -139,7 +141,7 @@ mod darwin_fd_limit {
         // sysctl value, and bump the soft resource limit for maxfiles up to the sysctl value.
         use ptr::null_mut;
         use mem::size_of_val;
-        use os::last_os_error;
+        use io;
 
         // Fetch the kern.maxfilesperproc value
         let mut mib: [libc::c_int; 2] = [CTL_KERN, KERN_MAXFILESPERPROC];
@@ -147,14 +149,14 @@ mod darwin_fd_limit {
         let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
         if sysctl(&mut mib[0], 2, &mut maxfiles as *mut libc::c_int as *mut libc::c_void, &mut size,
                   null_mut(), 0) != 0 {
-            let err = last_os_error();
+            let err = io::Error::last_os_error();
             panic!("raise_fd_limit: error calling sysctl: {}", err);
         }
 
         // Fetch the current resource limits
         let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0};
         if getrlimit(RLIMIT_NOFILE, &mut rlim) != 0 {
-            let err = last_os_error();
+            let err = io::Error::last_os_error();
             panic!("raise_fd_limit: error calling getrlimit: {}", err);
         }
 
@@ -163,7 +165,7 @@ mod darwin_fd_limit {
 
         // Set our newly-increased resource limit
         if setrlimit(RLIMIT_NOFILE, &rlim) != 0 {
-            let err = last_os_error();
+            let err = io::Error::last_os_error();
             panic!("raise_fd_limit: error calling setrlimit: {}", err);
         }
     }
index 1f2ef50fcae453627b63568cf7e0b92697cac72b..f8cba0444433175b02a141ed88cdd62b234b81c5 100644 (file)
@@ -15,6 +15,7 @@
 
 // FIXME: These functions take Durations but only pass ms to the backend impls.
 
+use boxed::Box;
 use sync::mpsc::{Receiver, Sender, channel};
 use time::Duration;
 use old_io::IoResult;
@@ -30,6 +31,7 @@ use sys::timer::Timer as TimerImp;
 /// # Examples
 ///
 /// ```
+/// # #![feature(old_io, std_misc)]
 /// # fn foo() {
 /// use std::old_io::Timer;
 /// use std::time::Duration;
@@ -53,6 +55,7 @@ use sys::timer::Timer as TimerImp;
 /// the `old_io::timer` module.
 ///
 /// ```
+/// # #![feature(old_io, std_misc)]
 /// # fn foo() {
 /// use std::old_io::timer;
 /// use std::time::Duration;
@@ -112,9 +115,10 @@ impl Timer {
     /// invalidated at the end of that statement, and all `recv` calls will
     /// fail.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(old_io, std_misc)]
     /// use std::old_io::Timer;
     /// use std::time::Duration;
     ///
@@ -127,7 +131,8 @@ impl Timer {
     /// ten_milliseconds.recv().unwrap();
     /// ```
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(old_io, std_misc)]
     /// use std::old_io::Timer;
     /// use std::time::Duration;
     ///
@@ -143,7 +148,7 @@ impl Timer {
         let (tx, rx) = channel();
         // Short-circuit the timer backend for 0 duration
         if in_ms_u64(duration) != 0 {
-            self.inner.oneshot(in_ms_u64(duration), box TimerCallback { tx: tx });
+            self.inner.oneshot(in_ms_u64(duration), Box::new(TimerCallback { tx: tx }));
         } else {
             tx.send(()).unwrap();
         }
@@ -164,9 +169,10 @@ impl Timer {
     /// invalidated at the end of that statement, and all `recv` calls will
     /// fail.
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(old_io, std_misc)]
     /// use std::old_io::Timer;
     /// use std::time::Duration;
     ///
@@ -185,7 +191,8 @@ impl Timer {
     /// ten_milliseconds.recv().unwrap();
     /// ```
     ///
-    /// ```rust
+    /// ```
+    /// # #![feature(old_io, std_misc)]
     /// use std::old_io::Timer;
     /// use std::time::Duration;
     ///
@@ -204,7 +211,7 @@ impl Timer {
         // not clear what use a 0ms period is anyway...
         let ms = if ms == 0 { 1 } else { ms };
         let (tx, rx) = channel();
-        self.inner.period(ms, box TimerCallback { tx: tx });
+        self.inner.period(ms, Box::new(TimerCallback { tx: tx }));
         return rx
     }
 }
@@ -332,7 +339,7 @@ mod test {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn oneshot_fail() {
         let mut timer = Timer::new().unwrap();
         let _rx = timer.oneshot(Duration::milliseconds(1));
@@ -340,7 +347,7 @@ mod test {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn period_fail() {
         let mut timer = Timer::new().unwrap();
         let _rx = timer.periodic(Duration::milliseconds(1));
@@ -348,7 +355,7 @@ mod test {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn normal_fail() {
         let _timer = Timer::new().unwrap();
         panic!();
index 5ae239014d188145e55a2014b36be610b3f03dba..818c8e76d6087aff50dbe3ae3e3675159bc5b0dd 100644 (file)
 
 //! Utility implementations of Reader and Writer
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 use cmp;
-use old_io;
+use old_io::{self, Reader, Writer, Buffer};
 use slice::bytes::MutableByteVector;
 
 /// Wraps a `Reader`, limiting the number of bytes that can be read from it.
 #[derive(Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::Take")]
+#[unstable(feature = "old_io")]
 pub struct LimitReader<R> {
-    limit: uint,
+    limit: usize,
     inner: R
 }
 
+#[deprecated(since = "1.0.0", reason = "use std::io::Take")]
+#[unstable(feature = "old_io")]
 impl<R: Reader> LimitReader<R> {
     /// Creates a new `LimitReader`
-    pub fn new(r: R, limit: uint) -> LimitReader<R> {
+    #[deprecated(since = "1.0.0", reason = "use std::io's take method instead")]
+    #[unstable(feature = "old_io")]
+    pub fn new(r: R, limit: usize) -> LimitReader<R> {
         LimitReader { limit: limit, inner: r }
     }
 
@@ -38,11 +46,13 @@ impl<R: Reader> LimitReader<R> {
     ///
     /// The reader may reach EOF after reading fewer bytes than indicated by
     /// this method if the underlying reader reaches EOF.
-    pub fn limit(&self) -> uint { self.limit }
+    pub fn limit(&self) -> usize { self.limit }
 }
 
+#[deprecated(since = "1.0.0", reason = "use std::io's take method instead")]
+#[unstable(feature = "old_io")]
 impl<R: Reader> Reader for LimitReader<R> {
-    fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<usize> {
         if self.limit == 0 {
             return Err(old_io::standard_error(old_io::EndOfFile));
         }
@@ -57,6 +67,8 @@ impl<R: Reader> Reader for LimitReader<R> {
     }
 }
 
+#[deprecated(since = "1.0.0", reason = "use std::io's take method instead")]
+#[unstable(feature = "old_io")]
 impl<R: Buffer> Buffer for LimitReader<R> {
     fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> {
         let amt = try!(self.inner.fill_buf());
@@ -68,7 +80,7 @@ impl<R: Buffer> Buffer for LimitReader<R> {
         }
     }
 
-    fn consume(&mut self, amt: uint) {
+    fn consume(&mut self, amt: usize) {
         // Don't let callers reset the limit by passing an overlarge value
         let amt = cmp::min(amt, self.limit);
         self.limit -= amt;
@@ -78,51 +90,67 @@ impl<R: Buffer> Buffer for LimitReader<R> {
 }
 
 /// A `Writer` which ignores bytes written to it, like /dev/null.
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")]
+#[unstable(feature = "old_io")]
 pub struct NullWriter;
 
+#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")]
+#[unstable(feature = "old_io")]
 impl Writer for NullWriter {
     #[inline]
     fn write_all(&mut self, _buf: &[u8]) -> old_io::IoResult<()> { Ok(()) }
 }
 
 /// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")]
+#[unstable(feature = "old_io")]
 pub struct ZeroReader;
 
+#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")]
+#[unstable(feature = "old_io")]
 impl Reader for ZeroReader {
     #[inline]
-    fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<usize> {
         buf.set_memory(0);
         Ok(buf.len())
     }
 }
 
+#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")]
+#[unstable(feature = "old_io")]
 impl Buffer for ZeroReader {
     fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> {
         static DATA: [u8; 64] = [0; 64];
         Ok(&DATA)
     }
 
-    fn consume(&mut self, _amt: uint) {}
+    fn consume(&mut self, _amt: usize) {}
 }
 
 /// A `Reader` which is always at EOF, like /dev/null.
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")]
+#[unstable(feature = "old_io")]
 pub struct NullReader;
 
+#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")]
+#[unstable(feature = "old_io")]
 impl Reader for NullReader {
     #[inline]
-    fn read(&mut self, _buf: &mut [u8]) -> old_io::IoResult<uint> {
+    fn read(&mut self, _buf: &mut [u8]) -> old_io::IoResult<usize> {
         Err(old_io::standard_error(old_io::EndOfFile))
     }
 }
 
+#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")]
+#[unstable(feature = "old_io")]
 impl Buffer for NullReader {
     fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> {
         Err(old_io::standard_error(old_io::EndOfFile))
     }
-    fn consume(&mut self, _amt: uint) {}
+    fn consume(&mut self, _amt: usize) {}
 }
 
 /// A `Writer` which multiplexes writes to a set of `Writer`s.
@@ -130,17 +158,23 @@ impl Buffer for NullReader {
 /// The `Writer`s are delegated to in order. If any `Writer` returns an error,
 /// that error is returned immediately and remaining `Writer`s are not called.
 #[derive(Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")]
+#[unstable(feature = "old_io")]
 pub struct MultiWriter<W> {
     writers: Vec<W>
 }
 
 impl<W> MultiWriter<W> where W: Writer {
     /// Creates a new `MultiWriter`
+    #[deprecated(since = "1.0.0", reason = "use std::io's broadcast method instead")]
+    #[unstable(feature = "old_io")]
     pub fn new(writers: Vec<W>) -> MultiWriter<W> {
         MultiWriter { writers: writers }
     }
 }
 
+#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")]
+#[unstable(feature = "old_io")]
 impl<W> Writer for MultiWriter<W> where W: Writer {
     #[inline]
     fn write_all(&mut self, buf: &[u8]) -> old_io::IoResult<()> {
@@ -162,6 +196,8 @@ impl<W> Writer for MultiWriter<W> where W: Writer {
 /// A `Reader` which chains input from multiple `Reader`s, reading each to
 /// completion before moving onto the next.
 #[derive(Clone, Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")]
+#[unstable(feature = "old_io")]
 pub struct ChainedReader<I, R> {
     readers: I,
     cur_reader: Option<R>,
@@ -169,14 +205,18 @@ pub struct ChainedReader<I, R> {
 
 impl<R: Reader, I: Iterator<Item=R>> ChainedReader<I, R> {
     /// Creates a new `ChainedReader`
+    #[deprecated(since = "1.0.0", reason = "use std::io's chain method instead")]
+    #[unstable(feature = "old_io")]
     pub fn new(mut readers: I) -> ChainedReader<I, R> {
         let r = readers.next();
         ChainedReader { readers: readers, cur_reader: r }
     }
 }
 
+#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")]
+#[unstable(feature = "old_io")]
 impl<R: Reader, I: Iterator<Item=R>> Reader for ChainedReader<I, R> {
-    fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<usize> {
         loop {
             let err = match self.cur_reader {
                 Some(ref mut r) => {
@@ -201,13 +241,19 @@ impl<R: Reader, I: Iterator<Item=R>> Reader for ChainedReader<I, R> {
 /// A `Reader` which forwards input from another `Reader`, passing it along to
 /// a `Writer` as well. Similar to the `tee(1)` command.
 #[derive(Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")]
+#[unstable(feature = "old_io")]
 pub struct TeeReader<R, W> {
     reader: R,
     writer: W,
 }
 
+#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")]
+#[unstable(feature = "old_io")]
 impl<R: Reader, W: Writer> TeeReader<R, W> {
     /// Creates a new `TeeReader`
+    #[deprecated(since = "1.0.0", reason = "use std::io's tee method instead")]
+    #[unstable(feature = "old_io")]
     pub fn new(r: R, w: W) -> TeeReader<R, W> {
         TeeReader { reader: r, writer: w }
     }
@@ -220,8 +266,10 @@ impl<R: Reader, W: Writer> TeeReader<R, W> {
     }
 }
 
+#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")]
+#[unstable(feature = "old_io")]
 impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
-    fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<usize> {
         self.reader.read(buf).and_then(|len| {
             self.writer.write_all(&mut buf[..len]).map(|()| len)
         })
@@ -229,6 +277,8 @@ impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
 }
 
 /// Copies all data from a `Reader` to a `Writer`.
+#[deprecated(since = "1.0.0", reason = "use std::io's copy function instead")]
+#[unstable(feature = "old_io")]
 pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> old_io::IoResult<()> {
     let mut buf = [0; super::DEFAULT_BUF_SIZE];
     loop {
@@ -257,7 +307,7 @@ impl<T: Iterator<Item=u8>> IterReader<T> {
 
 impl<T: Iterator<Item=u8>> Reader for IterReader<T> {
     #[inline]
-    fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<usize> {
         let mut len = 0;
         for (slot, elt) in buf.iter_mut().zip(self.iter.by_ref()) {
             *slot = elt;
@@ -275,7 +325,7 @@ impl<T: Iterator<Item=u8>> Reader for IterReader<T> {
 mod test {
     use prelude::v1::*;
 
-    use old_io::{MemReader, ByRefReader};
+    use old_io::{MemReader, ByRefReader, Reader, Writer, Buffer};
     use old_io;
     use super::*;
 
@@ -284,7 +334,7 @@ mod test {
         let mut r = MemReader::new(vec!(0, 1, 2));
         {
             let mut r = LimitReader::new(r.by_ref(), 4);
-            assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
+            assert_eq!(r.read_to_end().unwrap(), [0, 1, 2]);
         }
     }
 
@@ -293,9 +343,9 @@ mod test {
         let mut r = MemReader::new(vec!(0, 1, 2));
         {
             let mut r = LimitReader::new(r.by_ref(), 2);
-            assert_eq!(vec!(0, 1), r.read_to_end().unwrap());
+            assert_eq!(r.read_to_end().unwrap(), [0, 1]);
         }
-        assert_eq!(vec!(2), r.read_to_end().unwrap());
+        assert_eq!(r.read_to_end().unwrap(), [2]);
     }
 
     #[test]
@@ -305,7 +355,7 @@ mod test {
         assert_eq!(3, r.limit());
         assert_eq!(0, r.read_byte().unwrap());
         assert_eq!(2, r.limit());
-        assert_eq!(vec!(1, 2), r.read_to_end().unwrap());
+        assert_eq!(r.read_to_end().unwrap(), [1, 2]);
         assert_eq!(0, r.limit());
     }
 
@@ -314,7 +364,7 @@ mod test {
         let mut r = MemReader::new(vec![0, 1, 2, 3, 4, 5]);
         let mut r = LimitReader::new(r.by_ref(), 1);
         r.consume(2);
-        assert_eq!(vec![], r.read_to_end().unwrap());
+        assert_eq!(r.read_to_end().unwrap(), []);
     }
 
     #[test]
@@ -330,7 +380,7 @@ mod test {
         let mut s = ZeroReader;
         let mut buf = vec![1, 2, 3];
         assert_eq!(s.read(&mut buf), Ok(3));
-        assert_eq!(vec![0, 0, 0], buf);
+        assert_eq!(buf, [0, 0, 0]);
     }
 
     #[test]
@@ -342,8 +392,8 @@ mod test {
 
     #[test]
     fn test_multi_writer() {
-        static mut writes: uint = 0;
-        static mut flushes: uint = 0;
+        static mut writes: usize = 0;
+        static mut flushes: usize = 0;
 
         struct TestWriter;
         impl Writer for TestWriter {
@@ -373,16 +423,16 @@ mod test {
         let rs = vec!(MemReader::new(vec!(0, 1)), MemReader::new(vec!()),
                       MemReader::new(vec!(2, 3)));
         let mut r = ChainedReader::new(rs.into_iter());
-        assert_eq!(vec!(0, 1, 2, 3), r.read_to_end().unwrap());
+        assert_eq!(r.read_to_end().unwrap(), [0, 1, 2, 3]);
     }
 
     #[test]
     fn test_tee_reader() {
         let mut r = TeeReader::new(MemReader::new(vec!(0, 1, 2)),
                                    Vec::new());
-        assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap());
+        assert_eq!(r.read_to_end().unwrap(), [0, 1, 2]);
         let (_, w) = r.into_inner();
-        assert_eq!(vec!(0, 1, 2), w);
+        assert_eq!(w, [0, 1, 2]);
     }
 
     #[test]
@@ -390,12 +440,13 @@ mod test {
         let mut r = MemReader::new(vec!(0, 1, 2, 3, 4));
         let mut w = Vec::new();
         copy(&mut r, &mut w).unwrap();
-        assert_eq!(vec!(0, 1, 2, 3, 4), w);
+        assert_eq!(w, [0, 1, 2, 3, 4]);
     }
 
     #[test]
     fn limit_reader_buffer() {
-        let r = &mut b"0123456789\n0123456789\n";
+        let mut r: &[u8] = b"0123456789\n0123456789\n";
+        let r = &mut r;
         {
             let mut r = LimitReader::new(r.by_ref(), 3);
             assert_eq!(r.read_line(), Ok("012".to_string()));
@@ -418,7 +469,7 @@ mod test {
 
     #[test]
     fn test_iter_reader() {
-        let mut r = IterReader::new(0u8..8);
+        let mut r = IterReader::new(0..8);
         let mut buf = [0, 0, 0];
         let len = r.read(&mut buf).unwrap();
         assert_eq!(len, 3);
@@ -437,7 +488,7 @@ mod test {
 
     #[test]
     fn iter_reader_zero_length() {
-        let mut r = IterReader::new(0u8..8);
+        let mut r = IterReader::new(0..8);
         let mut buf = [];
         assert_eq!(Ok(0), r.read(&mut buf));
     }
index e9005aa22bcfbebc37cbb051a1bcde0c412d3180..9c88533d3bac605cb55b328b7265b8cb98a9ab5b 100644 (file)
 //! suitable for passing to any API that actually operates on the path; it is only intended for
 //! display.
 //!
-//! ## Example
+//! ## Examples
 //!
 //! ```rust
+//! # #![feature(old_path, old_io)]
 //! use std::old_io::fs::PathExtensions;
+//! use std::old_path::{Path, GenericPath};
 //!
 //! let mut path = Path::new("/tmp/path");
 //! println!("path: {}", path.display());
 //! ```
 
 #![unstable(feature = "old_path")]
+#![deprecated(since = "1.0.0", reason = "use std::path instead")]
+#![allow(deprecated)] // seriously this is all deprecated
+#![allow(unused_imports)]
 
 use core::marker::Sized;
 use ffi::CString;
 use clone::Clone;
+use borrow::Cow;
 use fmt;
-use iter::IteratorExt;
+use iter::Iterator;
 use option::Option;
 use option::Option::{None, Some};
 use str;
-use str::StrExt;
-use string::{String, CowString};
-use slice::SliceExt;
+use string::String;
 use vec::Vec;
 
 /// Typedef for POSIX file paths.
@@ -138,9 +142,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Creates a new Path from a byte vector or string.
     /// The resulting Path will always be normalized.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -162,9 +168,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Creates a new Path from a byte vector or string, if possible.
     /// The resulting Path will always be normalized.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -184,9 +192,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Returns the path as a string, if possible.
     /// If the path is not representable in utf-8, this returns None.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -201,9 +211,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
 
     /// Returns the path as a byte vector
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -215,9 +227,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
 
     /// Converts the Path into an owned byte vector
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -230,9 +244,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
 
     /// Returns an object that implements `Display` for printing paths
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -248,9 +264,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     ///
     /// If there is no filename, nothing will be printed.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -265,9 +283,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Returns the directory component of `self`, as a byte vector (with no trailing separator).
     /// If `self` has no directory component, returns ['.'].
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -280,9 +300,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Returns the directory component of `self`, as a string, if possible.
     /// See `dirname` for details.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -299,14 +321,16 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// If `self` represents the root of the file hierarchy, returns None.
     /// If `self` is "." or "..", returns None.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
     /// let p = Path::new("abc/def/ghi");
-    /// assert_eq!(p.filename(), Some(b"ghi"));
+    /// assert_eq!(p.filename(), Some(&b"ghi"[..]));
     /// # }
     /// ```
     fn filename<'a>(&'a self) -> Option<&'a [u8]>;
@@ -314,9 +338,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Returns the file component of `self`, as a string, if possible.
     /// See `filename` for details.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -333,14 +359,16 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// The stem is the portion of the filename just before the last '.'.
     /// If there is no '.', the entire filename is returned.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
     /// let p = Path::new("/abc/def.txt");
-    /// assert_eq!(p.filestem(), Some(b"def"));
+    /// assert_eq!(p.filestem(), Some(&b"def"[..]));
     /// # }
     /// ```
     fn filestem<'a>(&'a self) -> Option<&'a [u8]> {
@@ -360,9 +388,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Returns the stem of the filename of `self`, as a string, if possible.
     /// See `filestem` for details.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -380,14 +410,16 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// If there is no extension, None is returned.
     /// If the filename ends in '.', the empty vector is returned.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
     /// let p = Path::new("abc/def.txt");
-    /// assert_eq!(p.extension(), Some(b"txt"));
+    /// assert_eq!(p.extension(), Some(&b"txt"[..]));
     /// # }
     /// ```
     fn extension<'a>(&'a self) -> Option<&'a [u8]> {
@@ -407,9 +439,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Returns the extension of the filename of `self`, as a string, if possible.
     /// See `extension` for details.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -425,9 +459,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Replaces the filename portion of the path with the given byte vector or string.
     /// If the replacement name is [], this is equivalent to popping the path.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -451,9 +487,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// If the argument is [] or "", this removes the extension.
     /// If `self` has no filename, this is a no-op.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -501,9 +539,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// byte vector or string.
     /// See `set_filename` for details.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -526,9 +566,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// byte vector or string.
     /// See `set_extension` for details.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -550,9 +592,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Returns the directory component of `self`, as a Path.
     /// If `self` represents the root of the filesystem hierarchy, returns `self`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -569,9 +613,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     ///
     /// If `self` is not absolute, or vol/cwd-relative in the case of Windows, this returns None.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -584,9 +630,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Pushes a path (as a byte vector or string) onto `self`.
     /// If the argument represents an absolute path, it replaces `self`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -608,9 +656,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Pushes multiple paths (as byte vectors or strings) onto `self`.
     /// See `push` for details.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -637,9 +687,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// Returns `true` if the receiver was modified, or `false` if it already
     /// represented the root of the file hierarchy.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -654,9 +706,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// (as a byte vector or string).
     /// If the given path is absolute, the new Path will represent just that.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -679,9 +733,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// (as byte vectors or strings).
     /// See `join` for details.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -701,9 +757,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// An absolute path is defined as one that, when joined to another path, will
     /// yield back the same absolute path.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -718,9 +776,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// But for Windows paths, it also means the path is not volume-relative or
     /// relative to the current working directory.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -736,9 +796,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// If both paths are relative, they are compared as though they are relative
     /// to the same parent path.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -755,9 +817,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// If `self` is absolute and `base` is relative, or on Windows if both
     /// paths refer to separate drives, an absolute path is returned.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -771,9 +835,11 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
 
     /// Returns whether the relative path `child` is a suffix of `self`.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// # foo();
     /// # #[cfg(windows)] fn foo() {}
     /// # #[cfg(unix)] fn foo() {
@@ -842,7 +908,7 @@ impl<'a, P: GenericPath> Display<'a, P> {
     /// If the path is not UTF-8, invalid sequences will be replaced with the
     /// Unicode replacement char. This involves allocation.
     #[inline]
-    pub fn as_cow(&self) -> CowString<'a> {
+    pub fn as_cow(&self) -> Cow<'a, str> {
         String::from_utf8_lossy(if self.filename {
             match self.path.filename() {
                 None => {
index 15eee9e4a0c02d3c2fa0360319a9cab81dec737c..c517fab257f9574678d813ff07b0e20c63da59f9 100644 (file)
@@ -16,12 +16,12 @@ use fmt;
 use hash;
 use old_io::Writer;
 use iter::{AdditiveIterator, Extend};
-use iter::{Iterator, IteratorExt, Map};
+use iter::{Iterator, Map};
 use marker::Sized;
 use option::Option::{self, Some, None};
 use result::Result::{self, Ok, Err};
-use slice::{AsSlice, Split, SliceExt, SliceConcatExt};
-use str::{self, FromStr, StrExt};
+use slice::{Split, SliceConcatExt};
+use str::{self, FromStr};
 use vec::Vec;
 
 use super::{BytesContainer, GenericPath, GenericPathUnsafe};
@@ -37,7 +37,7 @@ pub type StrComponents<'a> =
 #[derive(Clone)]
 pub struct Path {
     repr: Vec<u8>, // assumed to never be empty or contain NULs
-    sepidx: Option<uint> // index of the final separator in repr
+    sepidx: Option<usize> // index of the final separator in repr
 }
 
 /// The standard path separator character
@@ -100,14 +100,6 @@ impl FromStr for Path {
 #[derive(Debug, Clone, PartialEq, Copy)]
 pub struct ParsePathError;
 
-#[cfg(stage0)]
-impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        self.repr.hash(state)
-    }
-}
-#[cfg(not(stage0))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl hash::Hash for Path {
     #[inline]
@@ -134,7 +126,7 @@ impl GenericPathUnsafe for 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 => {
+            None if self.repr == b".." => {
                 let mut v = Vec::with_capacity(3 + filename.len());
                 v.push_all(dot_dot_static);
                 v.push(SEP_BYTE);
@@ -194,7 +186,7 @@ impl GenericPath for Path {
 
     fn dirname<'a>(&'a self) -> &'a [u8] {
         match self.sepidx {
-            None if b".." == self.repr => &self.repr,
+            None if self.repr == b".." => &self.repr,
             None => dot_static,
             Some(0) => &self.repr[..1],
             Some(idx) if &self.repr[idx+1..] == b".." => &self.repr,
@@ -204,8 +196,7 @@ impl GenericPath for Path {
 
     fn filename<'a>(&'a self) -> Option<&'a [u8]> {
         match self.sepidx {
-            None if b"." == self.repr ||
-                b".." == self.repr => None,
+            None if self.repr == b"." || self.repr == b".." => None,
             None => Some(&self.repr),
             Some(idx) if &self.repr[idx+1..] == b".." => None,
             Some(0) if self.repr[1..].is_empty() => None,
@@ -215,13 +206,13 @@ impl GenericPath for Path {
 
     fn pop(&mut self) -> bool {
         match self.sepidx {
-            None if b"." == self.repr => false,
+            None if self.repr == b"." => false,
             None => {
                 self.repr = vec![b'.'];
                 self.sepidx = None;
                 true
             }
-            Some(0) if b"/" == self.repr => false,
+            Some(0) if self.repr == b"/" => false,
             Some(idx) => {
                 if idx == 0 {
                     self.repr.truncate(idx+1);
@@ -253,7 +244,7 @@ impl GenericPath for Path {
         } else {
             let mut ita = self.components();
             let mut itb = other.components();
-            if b"." == self.repr {
+            if self.repr == b"." {
                 return match itb.next() {
                     None => true,
                     Some(b) => b != b".."
@@ -347,11 +338,11 @@ impl Path {
 
     /// Returns a normalized byte vector representation of a path, by removing all empty
     /// components, and unnecessary . and .. components.
-    fn normalize<V: ?Sized + AsSlice<u8>>(v: &V) -> Vec<u8> {
+    fn normalize(v: &[u8]) -> Vec<u8> {
         // borrowck is being very picky
         let val = {
-            let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == SEP_BYTE;
-            let v_ = if is_abs { &v.as_slice()[1..] } else { v.as_slice() };
+            let is_abs = !v.is_empty() && v[0] == SEP_BYTE;
+            let v_ = if is_abs { &v[1..] } else { v };
             let comps = normalize_helper(v_, is_abs);
             match comps {
                 None => None,
@@ -379,7 +370,7 @@ impl Path {
             }
         };
         match val {
-            None => v.as_slice().to_vec(),
+            None => v.to_vec(),
             Some(val) => val
         }
     }
@@ -452,13 +443,12 @@ mod tests {
     use super::*;
 
     use clone::Clone;
-    use iter::IteratorExt;
     use option::Option::{self, Some, None};
     use old_path::GenericPath;
-    use slice::{AsSlice, SliceExt};
-    use str::{self, Str, StrExt};
+    use str;
     use string::ToString;
     use vec::Vec;
+    use iter::Iterator;
 
     macro_rules! t {
         (s: $path:expr, $exp:expr) => (
@@ -479,11 +469,11 @@ mod tests {
     fn test_paths() {
         let empty: &[u8] = &[];
         t!(v: Path::new(empty), b".");
-        t!(v: Path::new(b"/"), b"/");
-        t!(v: Path::new(b"a/b/c"), b"a/b/c");
-        t!(v: Path::new(b"a/b/c\xFF"), b"a/b/c\xFF");
-        t!(v: Path::new(b"\xFF/../foo\x80"), b"foo\x80");
-        let p = Path::new(b"a/b/c\xFF");
+        t!(v: Path::new(&b"/"[..]), b"/");
+        t!(v: Path::new(&b"a/b/c"[..]), b"a/b/c");
+        t!(v: Path::new(&b"a/b/c\xFF"[..]), b"a/b/c\xFF");
+        t!(v: Path::new(&b"\xFF/../foo\x80"[..]), b"foo\x80");
+        let p = Path::new(&b"a/b/c\xFF"[..]);
         assert!(p.as_str().is_none());
 
         t!(s: Path::new(""), ".");
@@ -509,18 +499,18 @@ mod tests {
         t!(s: Path::new("foo/../../.."), "../..");
         t!(s: Path::new("foo/../../bar"), "../bar");
 
-        assert_eq!(Path::new(b"foo/bar").into_vec(), b"foo/bar");
-        assert_eq!(Path::new(b"/foo/../../bar").into_vec(),
+        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");
+        let p = Path::new(&b"foo/bar\x80"[..]);
         assert!(p.as_str().is_none());
     }
 
     #[test]
     fn test_opt_paths() {
-        assert!(Path::new_opt(b"foo/bar\0").is_none());
-        t!(v: Path::new_opt(b"foo/bar").unwrap(), b"foo/bar");
+        assert!(Path::new_opt(&b"foo/bar\0"[..]).is_none());
+        t!(v: Path::new_opt(&b"foo/bar"[..]).unwrap(), b"foo/bar");
         assert!(Path::new_opt("foo/bar\0").is_none());
         t!(s: Path::new_opt("foo/bar").unwrap(), "foo/bar");
     }
@@ -529,17 +519,17 @@ mod tests {
     fn test_null_byte() {
         use thread;
         let result = thread::spawn(move|| {
-            Path::new(b"foo/bar\0");
+            Path::new(&b"foo/bar\0"[..]);
         }).join();
         assert!(result.is_err());
 
         let result = thread::spawn(move|| {
-            Path::new("test").set_filename(b"f\0o")
+            Path::new("test").set_filename(&b"f\0o"[..])
         }).join();
         assert!(result.is_err());
 
         let result = thread::spawn(move|| {
-            Path::new("test").push(b"f\0o");
+            Path::new("test").push(&b"f\0o"[..]);
         }).join();
         assert!(result.is_err());
     }
@@ -555,11 +545,11 @@ mod tests {
             )
         }
         t!("foo", display, "foo");
-        t!(b"foo\x80", display, "foo\u{FFFD}");
-        t!(b"foo\xFFbar", display, "foo\u{FFFD}bar");
-        t!(b"foo\xFF/bar", filename_display, "bar");
-        t!(b"foo/\xFFbar", filename_display, "\u{FFFD}bar");
-        t!(b"/", filename_display, "");
+        t!(&b"foo\x80"[..], display, "foo\u{FFFD}");
+        t!(&b"foo\xFFbar"[..], display, "foo\u{FFFD}bar");
+        t!(&b"foo\xFF/bar"[..], filename_display, "bar");
+        t!(&b"foo/\xFFbar"[..], filename_display, "\u{FFFD}bar");
+        t!(&b"/"[..], filename_display, "");
 
         macro_rules! t {
             ($path:expr, $exp:expr) => (
@@ -579,11 +569,11 @@ mod tests {
         }
 
         t!("foo", "foo");
-        t!(b"foo\x80", "foo\u{FFFD}");
-        t!(b"foo\xFFbar", "foo\u{FFFD}bar");
-        t!(b"foo\xFF/bar", "bar", filename);
-        t!(b"foo/\xFFbar", "\u{FFFD}bar", filename);
-        t!(b"/", "", filename);
+        t!(&b"foo\x80"[..], "foo\u{FFFD}");
+        t!(&b"foo\xFFbar"[..], "foo\u{FFFD}bar");
+        t!(&b"foo\xFF/bar"[..], "bar", filename);
+        t!(&b"foo/\xFFbar"[..], "\u{FFFD}bar", filename);
+        t!(&b"/"[..], "", filename);
     }
 
     #[test]
@@ -600,13 +590,13 @@ mod tests {
             )
         }
 
-        t!(b"foo", "foo", "foo");
-        t!(b"foo/bar", "foo/bar", "bar");
-        t!(b"/", "/", "");
-        t!(b"foo\xFF", "foo\u{FFFD}", "foo\u{FFFD}");
-        t!(b"foo\xFF/bar", "foo\u{FFFD}/bar", "bar");
-        t!(b"foo/\xFFbar", "foo/\u{FFFD}bar", "\u{FFFD}bar");
-        t!(b"\xFFfoo/bar\xFF", "\u{FFFD}foo/bar\u{FFFD}", "bar\u{FFFD}");
+        t!(&b"foo"[..], "foo", "foo");
+        t!(&b"foo/bar"[..], "foo/bar", "bar");
+        t!(&b"/"[..], "/", "");
+        t!(&b"foo\xFF"[..], "foo\u{FFFD}", "foo\u{FFFD}");
+        t!(&b"foo\xFF/bar"[..], "foo\u{FFFD}/bar", "bar");
+        t!(&b"foo/\xFFbar"[..], "foo/\u{FFFD}bar", "\u{FFFD}bar");
+        t!(&b"\xFFfoo/bar\xFF"[..], "\u{FFFD}foo/bar\u{FFFD}", "bar\u{FFFD}");
     }
 
     #[test]
@@ -634,9 +624,9 @@ mod tests {
             );
         }
 
-        t!(v: b"a/b/c", filename, Some(b"c"));
-        t!(v: b"a/b/c\xFF", filename, Some(b"c\xFF"));
-        t!(v: b"a/b\xFF/c", filename, Some(b"c"));
+        t!(v: &b"a/b/c"[..], filename, Some(&b"c"[..]));
+        t!(v: &b"a/b/c\xFF"[..], filename, Some(&b"c\xFF"[..]));
+        t!(v: &b"a/b\xFF/c"[..], filename, Some(&b"c"[..]));
         t!(s: "a/b/c", filename, Some("c"), opt);
         t!(s: "/a/b/c", filename, Some("c"), opt);
         t!(s: "a", filename, Some("a"), opt);
@@ -646,9 +636,9 @@ mod tests {
         t!(s: "..", filename, None, opt);
         t!(s: "../..", filename, None, opt);
 
-        t!(v: b"a/b/c", dirname, b"a/b");
-        t!(v: b"a/b/c\xFF", dirname, b"a/b");
-        t!(v: b"a/b\xFF/c", dirname, b"a/b\xFF");
+        t!(v: &b"a/b/c"[..], dirname, b"a/b");
+        t!(v: &b"a/b/c\xFF"[..], dirname, b"a/b");
+        t!(v: &b"a/b\xFF/c"[..], dirname, b"a/b\xFF");
         t!(s: "a/b/c", dirname, "a/b");
         t!(s: "/a/b/c", dirname, "/a/b");
         t!(s: "a", dirname, ".");
@@ -658,9 +648,9 @@ mod tests {
         t!(s: "..", dirname, "..");
         t!(s: "../..", dirname, "../..");
 
-        t!(v: b"hi/there.txt", filestem, Some(b"there"));
-        t!(v: b"hi/there\x80.txt", filestem, Some(b"there\x80"));
-        t!(v: b"hi/there.t\x80xt", filestem, Some(b"there"));
+        t!(v: &b"hi/there.txt"[..], filestem, Some(&b"there"[..]));
+        t!(v: &b"hi/there\x80.txt"[..], filestem, Some(&b"there\x80"[..]));
+        t!(v: &b"hi/there.t\x80xt"[..], filestem, Some(&b"there"[..]));
         t!(s: "hi/there.txt", filestem, Some("there"), opt);
         t!(s: "hi/there", filestem, Some("there"), opt);
         t!(s: "there.txt", filestem, Some("there"), opt);
@@ -674,11 +664,11 @@ mod tests {
         t!(s: "..", filestem, None, opt);
         t!(s: "../..", filestem, None, opt);
 
-        t!(v: b"hi/there.txt", extension, Some(b"txt"));
-        t!(v: b"hi/there\x80.txt", extension, Some(b"txt"));
-        t!(v: b"hi/there.t\x80xt", extension, Some(b"t\x80xt"));
-        t!(v: b"hi/there", extension, None);
-        t!(v: b"hi/there\x80", extension, None);
+        t!(v: &b"hi/there.txt"[..], extension, Some(&b"txt"[..]));
+        t!(v: &b"hi/there\x80.txt"[..], extension, Some(&b"txt"[..]));
+        t!(v: &b"hi/there.t\x80xt"[..], extension, Some(&b"t\x80xt"[..]));
+        t!(v: &b"hi/there"[..], extension, None);
+        t!(v: &b"hi/there\x80"[..], extension, None);
         t!(s: "hi/there.txt", extension, Some("txt"), opt);
         t!(s: "hi/there", extension, None, opt);
         t!(s: "there.txt", extension, Some("txt"), opt);
@@ -758,9 +748,9 @@ mod tests {
         t!(s: "a/b/c", ["d", "/e"], "/e");
         t!(s: "a/b/c", ["d", "/e", "f"], "/e/f");
         t!(s: "a/b/c", ["d".to_string(), "e".to_string()], "a/b/c/d/e");
-        t!(v: b"a/b/c", [b"d", b"e"], b"a/b/c/d/e");
-        t!(v: b"a/b/c", [b"d", b"/e", b"f"], b"/e/f");
-        t!(v: b"a/b/c", [b"d".to_vec(), b"e".to_vec()], b"a/b/c/d/e");
+        t!(v: &b"a/b/c"[..], [&b"d"[..], &b"e"[..]], b"a/b/c/d/e");
+        t!(v: &b"a/b/c"[..], [&b"d"[..], &b"/e"[..], &b"f"[..]], b"/e/f");
+        t!(v: &b"a/b/c"[..], [b"d".to_vec(), b"e".to_vec()], b"a/b/c/d/e");
     }
 
     #[test]
@@ -784,15 +774,15 @@ mod tests {
             )
         }
 
-        t!(b: b"a/b/c", b"a/b", true);
-        t!(b: b"a", b".", true);
-        t!(b: b".", b".", false);
-        t!(b: b"/a", b"/", true);
-        t!(b: b"/", b"/", false);
-        t!(b: b"a/b/c\x80", b"a/b", true);
-        t!(b: b"a/b\x80/c", b"a/b\x80", true);
-        t!(b: b"\xFF", b".", true);
-        t!(b: b"/\xFF", b"/", true);
+        t!(b: &b"a/b/c"[..], b"a/b", true);
+        t!(b: &b"a"[..], b".", true);
+        t!(b: &b"."[..], b".", false);
+        t!(b: &b"/a"[..], b"/", true);
+        t!(b: &b"/"[..], b"/", false);
+        t!(b: &b"a/b/c\x80"[..], b"a/b", true);
+        t!(b: &b"a/b\x80/c"[..], b"a/b\x80", true);
+        t!(b: &b"\xFF"[..], b".", true);
+        t!(b: &b"/\xFF"[..], b"/", true);
         t!(s: "a/b/c", "a/b", true);
         t!(s: "a", ".", true);
         t!(s: ".", ".", false);
@@ -802,15 +792,15 @@ mod tests {
 
     #[test]
     fn test_root_path() {
-        assert_eq!(Path::new(b"a/b/c").root_path(), None);
-        assert_eq!(Path::new(b"/a/b/c").root_path(), Some(Path::new("/")));
+        assert_eq!(Path::new(&b"a/b/c"[..]).root_path(), None);
+        assert_eq!(Path::new(&b"/a/b/c"[..]).root_path(), Some(Path::new("/")));
     }
 
     #[test]
     fn test_join() {
-        t!(v: Path::new(b"a/b/c").join(b".."), b"a/b");
-        t!(v: Path::new(b"/a/b/c").join(b"d"), b"/a/b/c/d");
-        t!(v: Path::new(b"a/\x80/c").join(b"\xFF"), b"a/\x80/c/\xFF");
+        t!(v: Path::new(&b"a/b/c"[..]).join(&b".."[..]), b"a/b");
+        t!(v: Path::new(&b"/a/b/c"[..]).join(&b"d"[..]), b"/a/b/c/d");
+        t!(v: Path::new(&b"a/\x80/c"[..]).join(&b"\xFF"[..]), b"a/\x80/c/\xFF");
         t!(s: Path::new("a/b/c").join(".."), "a/b");
         t!(s: Path::new("/a/b/c").join("d"), "/a/b/c/d");
         t!(s: Path::new("a/b").join("c/d"), "a/b/c/d");
@@ -863,17 +853,17 @@ mod tests {
         t!(s: "a/b/c", ["..", "d"], "a/b/d");
         t!(s: "a/b/c", ["d", "/e", "f"], "/e/f");
         t!(s: "a/b/c", ["d".to_string(), "e".to_string()], "a/b/c/d/e");
-        t!(v: b"a/b/c", [b"d", b"e"], b"a/b/c/d/e");
-        t!(v: b"a/b/c", [b"d".to_vec(), b"e".to_vec()], b"a/b/c/d/e");
+        t!(v: &b"a/b/c"[..], [&b"d"[..], &b"e"[..]], b"a/b/c/d/e");
+        t!(v: &b"a/b/c"[..], [b"d".to_vec(), b"e".to_vec()], b"a/b/c/d/e");
     }
 
     #[test]
     fn test_with_helpers() {
         let empty: &[u8] = &[];
 
-        t!(v: Path::new(b"a/b/c").with_filename(b"d"), b"a/b/d");
-        t!(v: Path::new(b"a/b/c\xFF").with_filename(b"\x80"), b"a/b/\x80");
-        t!(v: Path::new(b"/\xFF/foo").with_filename(b"\xCD"),
+        t!(v: Path::new(&b"a/b/c"[..]).with_filename(&b"d"[..]), b"a/b/d");
+        t!(v: Path::new(&b"a/b/c\xFF"[..]).with_filename(&b"\x80"[..]), b"a/b/\x80");
+        t!(v: Path::new(&b"/\xFF/foo"[..]).with_filename(&b"\xCD"[..]),
               b"/\xFF/\xCD");
         t!(s: Path::new("a/b/c").with_filename("d"), "a/b/d");
         t!(s: Path::new(".").with_filename("foo"), "foo");
@@ -895,13 +885,13 @@ mod tests {
         t!(s: Path::new("..").with_filename(""), "..");
         t!(s: Path::new("../..").with_filename(""), "../..");
 
-        t!(v: Path::new(b"hi/there\x80.txt").with_extension(b"exe"),
+        t!(v: Path::new(&b"hi/there\x80.txt"[..]).with_extension(&b"exe"[..]),
               b"hi/there\x80.exe");
-        t!(v: Path::new(b"hi/there.txt\x80").with_extension(b"\xFF"),
+        t!(v: Path::new(&b"hi/there.txt\x80"[..]).with_extension(&b"\xFF"[..]),
               b"hi/there.\xFF");
-        t!(v: Path::new(b"hi/there\x80").with_extension(b"\xFF"),
+        t!(v: Path::new(&b"hi/there\x80"[..]).with_extension(&b"\xFF"[..]),
               b"hi/there\x80.\xFF");
-        t!(v: Path::new(b"hi/there.\xFF").with_extension(empty), b"hi/there");
+        t!(v: Path::new(&b"hi/there.\xFF"[..]).with_extension(empty), b"hi/there");
         t!(s: Path::new("hi/there.txt").with_extension("exe"), "hi/there.exe");
         t!(s: Path::new("hi/there.txt").with_extension(""), "hi/there");
         t!(s: Path::new("hi/there.txt").with_extension("."), "hi/there..");
@@ -943,17 +933,17 @@ mod tests {
             )
         }
 
-        t!(v: b"a/b/c", set_filename, with_filename, b"d");
-        t!(v: b"/", set_filename, with_filename, b"foo");
-        t!(v: b"\x80", set_filename, with_filename, b"\xFF");
+        t!(v: &b"a/b/c"[..], set_filename, with_filename, &b"d"[..]);
+        t!(v: &b"/"[..], set_filename, with_filename, &b"foo"[..]);
+        t!(v: &b"\x80"[..], set_filename, with_filename, &b"\xFF"[..]);
         t!(s: "a/b/c", set_filename, with_filename, "d");
         t!(s: "/", set_filename, with_filename, "foo");
         t!(s: ".", set_filename, with_filename, "foo");
         t!(s: "a/b", set_filename, with_filename, "");
         t!(s: "a", set_filename, with_filename, "");
 
-        t!(v: b"hi/there.txt", set_extension, with_extension, b"exe");
-        t!(v: b"hi/there.t\x80xt", set_extension, with_extension, b"exe\xFF");
+        t!(v: &b"hi/there.txt"[..], set_extension, with_extension, &b"exe"[..]);
+        t!(v: &b"hi/there.t\x80xt"[..], set_extension, with_extension, &b"exe\xFF"[..]);
         t!(s: "hi/there.txt", set_extension, with_extension, "exe");
         t!(s: "hi/there.", set_extension, with_extension, "txt");
         t!(s: "hi/there", set_extension, with_extension, "txt");
@@ -985,10 +975,10 @@ mod tests {
             )
         }
 
-        t!(v: Path::new(b"a/b/c"), Some(b"c"), b"a/b", Some(b"c"), None);
-        t!(v: Path::new(b"a/b/\xFF"), Some(b"\xFF"), b"a/b", Some(b"\xFF"), None);
-        t!(v: Path::new(b"hi/there.\xFF"), Some(b"there.\xFF"), b"hi",
-              Some(b"there"), Some(b"\xFF"));
+        t!(v: Path::new(&b"a/b/c"[..]), Some(&b"c"[..]), b"a/b", Some(&b"c"[..]), None);
+        t!(v: Path::new(&b"a/b/\xFF"[..]), Some(&b"\xFF"[..]), b"a/b", Some(&b"\xFF"[..]), None);
+        t!(v: Path::new(&b"hi/there.\xFF"[..]), Some(&b"there.\xFF"[..]), b"hi",
+              Some(&b"there"[..]), Some(&b"\xFF"[..]));
         t!(s: Path::new("a/b/c"), Some("c"), Some("a/b"), Some("c"), None);
         t!(s: Path::new("."), None, Some("."), None, None);
         t!(s: Path::new("/"), None, Some("/"), None, None);
@@ -1002,16 +992,16 @@ mod tests {
         t!(s: Path::new("hi/.there"), Some(".there"), Some("hi"), Some(".there"), None);
         t!(s: Path::new("hi/..there"), Some("..there"), Some("hi"),
               Some("."), Some("there"));
-        t!(s: Path::new(b"a/b/\xFF"), None, Some("a/b"), None, None);
-        t!(s: Path::new(b"a/b/\xFF.txt"), None, Some("a/b"), None, Some("txt"));
-        t!(s: Path::new(b"a/b/c.\x80"), None, Some("a/b"), Some("c"), None);
-        t!(s: Path::new(b"\xFF/b"), Some("b"), None, Some("b"), None);
+        t!(s: Path::new(&b"a/b/\xFF"[..]), None, Some("a/b"), None, None);
+        t!(s: Path::new(&b"a/b/\xFF.txt"[..]), None, Some("a/b"), None, Some("txt"));
+        t!(s: Path::new(&b"a/b/c.\x80"[..]), None, Some("a/b"), Some("c"), None);
+        t!(s: Path::new(&b"\xFF/b"[..]), Some("b"), None, Some("b"), None);
     }
 
     #[test]
     fn test_dir_path() {
-        t!(v: Path::new(b"hi/there\x80").dir_path(), b"hi");
-        t!(v: Path::new(b"hi\xFF/there").dir_path(), b"hi\xFF");
+        t!(v: Path::new(&b"hi/there\x80"[..]).dir_path(), b"hi");
+        t!(v: Path::new(&b"hi\xFF/there"[..]).dir_path(), b"hi\xFF");
         t!(s: Path::new("hi/there").dir_path(), "hi");
         t!(s: Path::new("hi").dir_path(), ".");
         t!(s: Path::new("/hi").dir_path(), "/");
@@ -1109,9 +1099,9 @@ mod tests {
         t!(s: "/a/b/c", "d/e/f", false);
         t!(s: "a/b/c", "a/b", false);
         t!(s: "a/b/c", "b", false);
-        t!(v: b"a/b/c", b"b/c", true);
-        t!(v: b"a/b/\xFF", b"\xFF", true);
-        t!(v: b"a/b/\xFF", b"b/\xFF", true);
+        t!(v: &b"a/b/c"[..], &b"b/c"[..], true);
+        t!(v: &b"a/b/\xFF"[..], &b"\xFF"[..], true);
+        t!(v: &b"a/b/\xFF"[..], &b"b/\xFF"[..], true);
     }
 
     #[test]
@@ -1187,9 +1177,9 @@ mod tests {
             )
         }
 
-        t!(b: b"a/b/c", [b"a", b"b", b"c"]);
-        t!(b: b"/\xFF/a/\x80", [b"\xFF", b"a", b"\x80"]);
-        t!(b: b"../../foo\xCDbar", [b"..", b"..", b"foo\xCDbar"]);
+        t!(b: &b"a/b/c"[..], [b"a", b"b", b"c"]);
+        t!(b: &b"/\xFF/a/\x80"[..], [b"\xFF", b"a", b"\x80"]);
+        t!(b: &b"../../foo\xCDbar"[..], [b"..", b"..", b"foo\xCDbar"]);
         t!(s: "a/b/c", ["a", "b", "c"]);
         t!(s: "a/b/d", ["a", "b", "d"]);
         t!(s: "a/b/cd", ["a", "b", "cd"]);
@@ -1219,9 +1209,9 @@ mod tests {
             )
         }
 
-        t!(b: b"a/b/c", [Some("a"), Some("b"), Some("c")]);
-        t!(b: b"/\xFF/a/\x80", [None, Some("a"), None]);
-        t!(b: b"../../foo\xCDbar", [Some(".."), Some(".."), None]);
+        t!(b: &b"a/b/c"[..], [Some("a"), Some("b"), Some("c")]);
+        t!(b: &b"/\xFF/a/\x80"[..], [None, Some("a"), None]);
+        t!(b: &b"../../foo\xCDbar"[..], [Some(".."), Some(".."), None]);
         // str_components is a wrapper around components, so no need to do
         // the full set of tests
     }
@@ -1232,7 +1222,8 @@ mod bench {
     extern crate test;
     use self::test::Bencher;
     use super::*;
-    use prelude::v1::{Clone, GenericPath};
+    use old_path::GenericPath;
+    use prelude::v1::Clone;
 
     #[bench]
     fn join_home_dir(b: &mut Bencher) {
index 887dc804c7af3da57949f4ea87c1fa249c46e751..0b88f368b3952aa9985839ec42636dc40e88f70c 100644 (file)
 use self::PathPrefix::*;
 
 use ascii::AsciiExt;
-use char::CharExt;
 use clone::Clone;
 use cmp::{Ordering, Eq, Ord, PartialEq, PartialOrd};
 use fmt;
 use hash;
 use old_io::Writer;
 use iter::{AdditiveIterator, Extend};
-use iter::{Iterator, IteratorExt, Map, repeat};
+use iter::{Iterator, Map, repeat};
 use mem;
 use option::Option::{self, Some, None};
 use result::Result::{self, Ok, Err};
-use slice::{SliceExt, SliceConcatExt};
-use str::{SplitTerminator, FromStr, StrExt};
+use slice::SliceConcatExt;
+use str::{SplitTerminator, FromStr};
 use string::{String, ToString};
 use vec::Vec;
 
@@ -82,7 +81,7 @@ pub type Components<'a> =
 pub struct Path {
     repr: String, // assumed to never be empty
     prefix: Option<PathPrefix>,
-    sepidx: Option<uint> // index of the final separator in the non-prefix portion of repr
+    sepidx: Option<usize> // index of the final separator in the non-prefix portion of repr
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -127,21 +126,6 @@ impl FromStr for Path {
 #[derive(Debug, Clone, PartialEq, Copy)]
 pub struct ParsePathError;
 
-#[cfg(stage0)]
-impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path {
-    #[cfg(not(test))]
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        self.repr.hash(state)
-    }
-
-    #[cfg(test)]
-    #[inline]
-    fn hash(&self, _: &mut S) {
-        // No-op because the `hash` implementation will be wrong.
-    }
-}
-#[cfg(not(stage0))]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl hash::Hash for Path {
     #[cfg(not(test))]
@@ -522,7 +506,7 @@ impl GenericPath for Path {
 
     fn path_relative_from(&self, base: &Path) -> Option<Path> {
         fn comp_requires_verbatim(s: &str) -> bool {
-            s == "." || s == ".." || s.contains_char(SEP2)
+            s == "." || s == ".." || s.contains(SEP2)
         }
 
         if !self.equiv_prefix(base) {
@@ -618,9 +602,11 @@ impl Path {
     ///
     /// Panics if the vector contains a `NUL`, or if it contains invalid UTF-8.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// println!("{}", Path::new(r"C:\some\path").display());
     /// ```
     #[inline]
@@ -632,9 +618,11 @@ impl Path {
     ///
     /// Returns `None` if the vector contains a `NUL`, or if it contains invalid UTF-8.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
+    /// # #![feature(old_path)]
+    /// use std::old_path::{Path, GenericPath};
     /// let path = Path::new_opt(r"C:\some\path");
     ///
     /// match path {
@@ -761,7 +749,7 @@ impl Path {
                     if prefix.is_some() && comps.is_empty() {
                         match prefix.unwrap() {
                             DiskPrefix => {
-                                let len = prefix_len(prefix) + is_abs as uint;
+                                let len = prefix_len(prefix) + is_abs as usize;
                                 let mut s = String::from_str(&s[..len]);
                                 unsafe {
                                     let v = s.as_mut_vec();
@@ -776,7 +764,7 @@ impl Path {
                                 Some(s)
                             }
                             VerbatimDiskPrefix => {
-                                let len = prefix_len(prefix) + is_abs as uint;
+                                let len = prefix_len(prefix) + is_abs as usize;
                                 let mut s = String::from_str(&s[..len]);
                                 unsafe {
                                     let v = s.as_mut_vec();
@@ -850,7 +838,7 @@ impl Path {
         self.sepidx = idx.and_then(|x| if x < prefixlen { None } else { Some(x) });
     }
 
-    fn prefix_len(&self) -> uint {
+    fn prefix_len(&self) -> usize {
         prefix_len(self.prefix)
     }
 
@@ -859,7 +847,7 @@ impl Path {
     // end is the length of the string, normally, or the index of the final character if it is
     // a non-semantic trailing separator in a verbatim string.
     // If the prefix is considered the separator, before and after are the same.
-    fn sepidx_or_prefix_len(&self) -> Option<(uint,uint,uint)> {
+    fn sepidx_or_prefix_len(&self) -> Option<(usize,usize,usize)> {
         match self.sepidx {
             None => match self.prefix_len() { 0 => None, x => Some((x,x,self.repr.len())) },
             Some(x) => {
@@ -985,16 +973,16 @@ pub fn is_sep_byte_verbatim(u: &u8) -> bool {
 /// Prefix types for Path
 #[derive(Copy, PartialEq, Clone, Debug)]
 pub enum PathPrefix {
-    /// Prefix `\\?\`, uint is the length of the following component
-    VerbatimPrefix(uint),
+    /// Prefix `\\?\`, usize is the length of the following component
+    VerbatimPrefix(usize),
     /// Prefix `\\?\UNC\`, uints are the lengths of the UNC components
-    VerbatimUNCPrefix(uint, uint),
+    VerbatimUNCPrefix(usize, usize),
     /// Prefix `\\?\C:\` (for any alphabetic character)
     VerbatimDiskPrefix,
-    /// Prefix `\\.\`, uint is the length of the following component
-    DeviceNSPrefix(uint),
+    /// Prefix `\\.\`, usize is the length of the following component
+    DeviceNSPrefix(usize),
     /// UNC prefix `\\server\share`, uints are the lengths of the server/share
-    UNCPrefix(uint, uint),
+    UNCPrefix(usize, usize),
     /// Prefix `C:` for any alphabetic character
     DiskPrefix
 }
@@ -1049,7 +1037,7 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
     }
     return None;
 
-    fn parse_two_comps(mut path: &str, f: fn(char) -> bool) -> Option<(uint, uint)> {
+    fn parse_two_comps(mut path: &str, f: fn(char) -> bool) -> Option<(usize, usize)> {
         let idx_a = match path.find(f) {
             None => return None,
             Some(x) => x
@@ -1119,7 +1107,7 @@ fn prefix_is_verbatim(p: Option<PathPrefix>) -> bool {
     }
 }
 
-fn prefix_len(p: Option<PathPrefix>) -> uint {
+fn prefix_len(p: Option<PathPrefix>) -> usize {
     match p {
         None => 0,
         Some(VerbatimPrefix(x)) => 4 + x,
@@ -1138,11 +1126,9 @@ mod tests {
     use super::*;
 
     use clone::Clone;
-    use iter::IteratorExt;
+    use iter::Iterator;
     use option::Option::{self, Some, None};
     use old_path::GenericPath;
-    use slice::{AsSlice, SliceExt};
-    use str::Str;
     use string::ToString;
     use vec::Vec;
 
@@ -1225,8 +1211,8 @@ mod tests {
     fn test_paths() {
         let empty: &[u8] = &[];
         t!(v: Path::new(empty), b".");
-        t!(v: Path::new(b"\\"), b"\\");
-        t!(v: Path::new(b"a\\b\\c"), b"a\\b\\c");
+        t!(v: Path::new(&b"\\"[..]), b"\\");
+        t!(v: Path::new(&b"a\\b\\c"[..]), b"a\\b\\c");
 
         t!(s: Path::new(""), ".");
         t!(s: Path::new("\\"), "\\");
@@ -1258,8 +1244,8 @@ mod tests {
         t!(s: Path::new("foo\\..\\..\\.."), "..\\..");
         t!(s: Path::new("foo\\..\\..\\bar"), "..\\bar");
 
-        assert_eq!(Path::new(b"foo\\bar").into_vec(), b"foo\\bar");
-        assert_eq!(Path::new(b"\\foo\\..\\..\\bar").into_vec(), 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");
@@ -1312,9 +1298,9 @@ mod tests {
 
     #[test]
     fn test_opt_paths() {
-        assert!(Path::new_opt(b"foo\\bar\0") == None);
-        assert!(Path::new_opt(b"foo\\bar\x80") == None);
-        t!(v: Path::new_opt(b"foo\\bar").unwrap(), b"foo\\bar");
+        assert!(Path::new_opt(&b"foo\\bar\0"[..]) == None);
+        assert!(Path::new_opt(&b"foo\\bar\x80"[..]) == None);
+        t!(v: Path::new_opt(&b"foo\\bar"[..]).unwrap(), b"foo\\bar");
         assert!(Path::new_opt("foo\\bar\0") == None);
         t!(s: Path::new_opt("foo\\bar").unwrap(), "foo\\bar");
     }
@@ -1323,38 +1309,38 @@ mod tests {
     fn test_null_byte() {
         use thread;
         let result = thread::spawn(move|| {
-            Path::new(b"foo/bar\0");
+            Path::new(&b"foo/bar\0"[..]);
         }).join();
         assert!(result.is_err());
 
         let result = thread::spawn(move|| {
-            Path::new("test").set_filename(b"f\0o")
+            Path::new("test").set_filename(&b"f\0o"[..])
         }).join();
         assert!(result.is_err());
 
         let result = thread::spawn(move || {
-            Path::new("test").push(b"f\0o");
+            Path::new("test").push(&b"f\0o"[..]);
         }).join();
         assert!(result.is_err());
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_not_utf8_panics() {
-        Path::new(b"hello\x80.txt");
+        Path::new(&b"hello\x80.txt"[..]);
     }
 
     #[test]
     fn test_display_str() {
         let path = Path::new("foo");
         assert_eq!(path.display().to_string(), "foo");
-        let path = Path::new(b"\\");
+        let path = Path::new(&b"\\"[..]);
         assert_eq!(path.filename_display().to_string(), "");
 
         let path = Path::new("foo");
         let mo = path.display().as_cow();
         assert_eq!(mo, "foo");
-        let path = Path::new(b"\\");
+        let path = Path::new(&b"\\"[..]);
         let mo = path.filename_display().as_cow();
         assert_eq!(mo, "");
     }
@@ -1405,7 +1391,7 @@ mod tests {
             )
         }
 
-        t!(v: b"a\\b\\c", filename, Some(b"c"));
+        t!(v: &b"a\\b\\c"[..], filename, Some(&b"c"[..]));
         t!(s: "a\\b\\c", filename_str, "c");
         t!(s: "\\a\\b\\c", filename_str, "c");
         t!(s: "a", filename_str, "a");
@@ -1438,7 +1424,7 @@ mod tests {
         t!(s: "\\\\.\\", filename_str, None, opt);
         t!(s: "\\\\?\\a\\b\\", filename_str, "b");
 
-        t!(v: b"a\\b\\c", dirname, b"a\\b");
+        t!(v: &b"a\\b\\c"[..], dirname, b"a\\b");
         t!(s: "a\\b\\c", dirname_str, "a\\b");
         t!(s: "\\a\\b\\c", dirname_str, "\\a\\b");
         t!(s: "a", dirname_str, ".");
@@ -1469,7 +1455,7 @@ mod tests {
         t!(s: "\\\\.\\foo", dirname_str, "\\\\.\\foo");
         t!(s: "\\\\?\\a\\b\\", dirname_str, "\\\\?\\a");
 
-        t!(v: b"hi\\there.txt", filestem, Some(b"there"));
+        t!(v: &b"hi\\there.txt"[..], filestem, Some(&b"there"[..]));
         t!(s: "hi\\there.txt", filestem_str, "there");
         t!(s: "hi\\there", filestem_str, "there");
         t!(s: "there.txt", filestem_str, "there");
@@ -1484,8 +1470,8 @@ mod tests {
         t!(s: "..\\..", filestem_str, None, opt);
         // filestem is based on filename, so we don't need the full set of prefix tests
 
-        t!(v: b"hi\\there.txt", extension, Some(b"txt"));
-        t!(v: b"hi\\there", extension, None);
+        t!(v: &b"hi\\there.txt"[..], extension, Some(&b"txt"[..]));
+        t!(v: &b"hi\\there"[..], extension, None);
         t!(s: "hi\\there.txt", extension_str, Some("txt"), opt);
         t!(s: "hi\\there", extension_str, None, opt);
         t!(s: "there.txt", extension_str, Some("txt"), opt);
@@ -1611,9 +1597,9 @@ mod tests {
         t!(s: "a\\b\\c", ["d", "\\e"], "\\e");
         t!(s: "a\\b\\c", ["d", "\\e", "f"], "\\e\\f");
         t!(s: "a\\b\\c", ["d".to_string(), "e".to_string()], "a\\b\\c\\d\\e");
-        t!(v: b"a\\b\\c", [b"d", b"e"], b"a\\b\\c\\d\\e");
-        t!(v: b"a\\b\\c", [b"d", b"\\e", b"f"], b"\\e\\f");
-        t!(v: b"a\\b\\c", [b"d".to_vec(), b"e".to_vec()],
+        t!(v: &b"a\\b\\c"[..], [&b"d"[..], &b"e"[..]], b"a\\b\\c\\d\\e");
+        t!(v: &b"a\\b\\c"[..], [&b"d"[..], &b"\\e"[..], &b"f"[..]], b"\\e\\f");
+        t!(v: &b"a\\b\\c"[..], [b"d".to_vec(), b"e".to_vec()],
            b"a\\b\\c\\d\\e");
     }
 
@@ -1645,11 +1631,11 @@ mod tests {
         t!(s: ".", ".", false);
         t!(s: "\\a", "\\", true);
         t!(s: "\\", "\\", false);
-        t!(b: b"a\\b\\c", b"a\\b", true);
-        t!(b: b"a", b".", true);
-        t!(b: b".", b".", false);
-        t!(b: b"\\a", b"\\", true);
-        t!(b: b"\\", b"\\", false);
+        t!(b: &b"a\\b\\c"[..], b"a\\b", true);
+        t!(b: &b"a"[..], b".", true);
+        t!(b: &b"."[..], b".", false);
+        t!(b: &b"\\a"[..], b"\\", true);
+        t!(b: &b"\\"[..], b"\\", false);
 
         t!(s: "C:\\a\\b", "C:\\a", true);
         t!(s: "C:\\a", "C:\\", true);
@@ -1698,8 +1684,8 @@ mod tests {
         t!(s: Path::new("a\\b").join("\\c\\d"), "\\c\\d");
         t!(s: Path::new(".").join("a\\b"), "a\\b");
         t!(s: Path::new("\\").join("a\\b"), "\\a\\b");
-        t!(v: Path::new(b"a\\b\\c").join(b".."), b"a\\b");
-        t!(v: Path::new(b"\\a\\b\\c").join(b"d"), b"\\a\\b\\c\\d");
+        t!(v: Path::new(&b"a\\b\\c"[..]).join(&b".."[..]), b"a\\b");
+        t!(v: Path::new(&b"\\a\\b\\c"[..]).join(&b"d"[..]), b"\\a\\b\\c\\d");
         // full join testing is covered under test_push_path, so no need for
         // the full set of prefix tests
     }
@@ -1750,8 +1736,8 @@ mod tests {
         t!(s: "a\\b\\c", ["..", "d"], "a\\b\\d");
         t!(s: "a\\b\\c", ["d", "\\e", "f"], "\\e\\f");
         t!(s: "a\\b\\c", ["d".to_string(), "e".to_string()], "a\\b\\c\\d\\e");
-        t!(v: b"a\\b\\c", [b"d", b"e"], b"a\\b\\c\\d\\e");
-        t!(v: b"a\\b\\c", [b"d".to_vec(), b"e".to_vec()],
+        t!(v: &b"a\\b\\c"[..], [&b"d"[..], &b"e"[..]], b"a\\b\\c\\d\\e");
+        t!(v: &b"a\\b\\c"[..], [b"d".to_vec(), b"e".to_vec()],
            b"a\\b\\c\\d\\e");
     }
 
@@ -1863,15 +1849,15 @@ mod tests {
             )
         }
 
-        t!(v: b"a\\b\\c", set_filename, with_filename, b"d");
-        t!(v: b"\\", set_filename, with_filename, b"foo");
+        t!(v: &b"a\\b\\c"[..], set_filename, with_filename, &b"d"[..]);
+        t!(v: &b"\\"[..], set_filename, with_filename, &b"foo"[..]);
         t!(s: "a\\b\\c", set_filename, with_filename, "d");
         t!(s: "\\", set_filename, with_filename, "foo");
         t!(s: ".", set_filename, with_filename, "foo");
         t!(s: "a\\b", set_filename, with_filename, "");
         t!(s: "a", set_filename, with_filename, "");
 
-        t!(v: b"hi\\there.txt", set_extension, with_extension, b"exe");
+        t!(v: &b"hi\\there.txt"[..], set_extension, with_extension, &b"exe"[..]);
         t!(s: "hi\\there.txt", set_extension, with_extension, "exe");
         t!(s: "hi\\there.", set_extension, with_extension, "txt");
         t!(s: "hi\\there", set_extension, with_extension, "txt");
@@ -1906,7 +1892,7 @@ mod tests {
             )
         }
 
-        t!(v: Path::new(b"a\\b\\c"), Some(b"c"), b"a\\b", Some(b"c"), None);
+        t!(v: Path::new(&b"a\\b\\c"[..]), Some(&b"c"[..]), b"a\\b", Some(&b"c"[..]), None);
         t!(s: Path::new("a\\b\\c"), Some("c"), Some("a\\b"), Some("c"), None);
         t!(s: Path::new("."), None, Some("."), None, None);
         t!(s: Path::new("\\"), None, Some("\\"), None, None);
@@ -2248,7 +2234,7 @@ mod tests {
             );
         }
 
-        t!(s: b"a\\b\\c", ["a", "b", "c"]);
+        t!(s: &b"a\\b\\c"[..], ["a", "b", "c"]);
         t!(s: "a\\b\\c", ["a", "b", "c"]);
         t!(s: "a\\b\\d", ["a", "b", "d"]);
         t!(s: "a\\b\\cd", ["a", "b", "cd"]);
index f181fc5df5759b557ae5f9099ff12fd6061754b7..ee0f04cb9911cc8ccf55bd53e262b8cf5d0ccebf 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Higher-level interfaces to libc::* functions and operating system services.
-//!
-//! In general these take and return rust types, use rust idioms (enums,
-//! closures, vectors) rather than C idioms, and do more extensive safety
-//! checks.
-//!
-//! This module is not meant to only contain 1:1 mappings to libc entries; any
-//! os-interface code that is reasonably useful and broadly applicable can go
-//! here. Including utility routines that merely build on other os code.
-//!
-//! We assume the general case is that users do not care, and do not want to be
-//! made to care, which operating system they are on. While they may want to
-//! special case various special cases -- and so we will not _hide_ the facts of
-//! which OS the user is on -- they should be given the opportunity to write
-//! OS-ignorant code by default.
+//! OS-specific functionality
 
-#![unstable(feature = "os")]
-
-#![allow(missing_docs)]
-#![allow(non_snake_case)]
-#![allow(unused_imports)]
-
-use self::MemoryMapKind::*;
-use self::MapOption::*;
-use self::MapError::*;
-
-use boxed::Box;
-use clone::Clone;
-use env;
-use error::{FromError, Error};
-use ffi::{OsString, OsStr};
-use fmt;
-use iter::{Iterator, IteratorExt};
-use libc::{c_void, c_int, c_char};
-use libc;
-use marker::{Copy, Send};
-use old_io::{IoResult, IoError};
-use ops::{Drop, FnOnce};
-use option::Option::{Some, None};
-use option::Option;
-use old_path::{Path, GenericPath, BytesContainer};
-use ptr::PtrExt;
-use ptr;
-use result::Result::{Err, Ok};
-use result::Result;
-use slice::{AsSlice, SliceExt};
-use str::{Str, StrExt};
-use str;
-use string::{String, ToString};
-use sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT, Ordering};
-use sys::os as os_imp;
-use sys;
-use vec::Vec;
-
-#[cfg(unix)] use ffi::{self, CString};
+#![stable(feature = "os", since = "1.0.0")]
 
 #[cfg(unix)] pub use sys::ext as unix;
 #[cfg(windows)] pub use sys::ext as windows;
-
-/// Get the number of cores available
-pub fn num_cpus() -> uint {
-    unsafe {
-        return rust_get_num_cpus() as uint;
-    }
-
-    extern {
-        fn rust_get_num_cpus() -> libc::uintptr_t;
-    }
-}
-
-pub const TMPBUF_SZ : uint = 1000;
-
-/// Returns the current working directory as a `Path`.
-///
-/// # Errors
-///
-/// Returns an `Err` if the current working directory value is invalid.
-/// Possible cases:
-///
-/// * Current directory does not exist.
-/// * There are insufficient permissions to access the current directory.
-/// * The internal buffer is not large enough to hold the path.
-///
-/// # Example
-///
-/// ```rust
-/// use std::os;
-///
-/// // We assume that we are in a valid directory.
-/// let current_working_directory = os::getcwd().unwrap();
-/// println!("The current directory is {:?}", current_working_directory.display());
-/// ```
-#[deprecated(since = "1.0.0", reason = "renamed to std::env::current_dir")]
-#[unstable(feature = "os")]
-pub fn getcwd() -> IoResult<Path> {
-    env::current_dir()
-}
-
-/// Returns a vector of (variable, value) pairs, for all the environment
-/// variables of the current process.
-///
-/// Invalid UTF-8 bytes are replaced with \uFFFD. See `String::from_utf8_lossy()`
-/// for details.
-///
-/// # Example
-///
-/// ```rust
-/// use std::os;
-///
-/// // We will iterate through the references to the element returned by os::env();
-/// for &(ref key, ref value) in os::env().iter() {
-///     println!("'{}': '{}'", key, value );
-/// }
-/// ```
-#[deprecated(since = "1.0.0", reason = "use env::vars instead")]
-#[unstable(feature = "os")]
-pub fn env() -> Vec<(String,String)> {
-    env::vars_os().map(|(k, v)| {
-        (k.to_string_lossy().into_owned(), v.to_string_lossy().into_owned())
-    }).collect()
-}
-
-/// Returns a vector of (variable, value) byte-vector pairs for all the
-/// environment variables of the current process.
-#[deprecated(since = "1.0.0", reason = "use env::vars_os instead")]
-#[unstable(feature = "os")]
-pub fn env_as_bytes() -> Vec<(Vec<u8>, Vec<u8>)> {
-    env::vars_os().map(|(k, v)| (byteify(k), byteify(v))).collect()
-}
-
-/// Fetches the environment variable `n` from the current process, returning
-/// None if the variable isn't set.
-///
-/// Any invalid UTF-8 bytes in the value are replaced by \uFFFD. See
-/// `String::from_utf8_lossy()` for details.
-///
-/// # Panics
-///
-/// Panics if `n` has any interior NULs.
-///
-/// # Example
-///
-/// ```rust
-/// use std::os;
-///
-/// let key = "HOME";
-/// match os::getenv(key) {
-///     Some(val) => println!("{}: {}", key, val),
-///     None => println!("{} is not defined in the environment.", key)
-/// }
-/// ```
-#[deprecated(since = "1.0.0", reason = "use env::var instead")]
-#[unstable(feature = "os")]
-pub fn getenv(n: &str) -> Option<String> {
-    env::var(n).ok()
-}
-
-/// Fetches the environment variable `n` byte vector from the current process,
-/// returning None if the variable isn't set.
-///
-/// # Panics
-///
-/// Panics if `n` has any interior NULs.
-#[deprecated(since = "1.0.0", reason = "use env::var_os instead")]
-#[unstable(feature = "os")]
-pub fn getenv_as_bytes(n: &str) -> Option<Vec<u8>> {
-    env::var_os(n).map(byteify)
-}
-
-#[cfg(unix)]
-fn byteify(s: OsString) -> Vec<u8> {
-    use os::unix::*;
-    s.into_vec()
-}
-#[cfg(windows)]
-fn byteify(s: OsString) -> Vec<u8> {
-    s.to_string_lossy().as_bytes().to_vec()
-}
-
-/// Sets the environment variable `n` to the value `v` for the currently running
-/// process.
-///
-/// # Example
-///
-/// ```rust
-/// use std::os;
-///
-/// let key = "KEY";
-/// os::setenv(key, "VALUE");
-/// match os::getenv(key) {
-///     Some(ref val) => println!("{}: {}", key, val),
-///     None => println!("{} is not defined in the environment.", key)
-/// }
-/// ```
-#[deprecated(since = "1.0.0", reason = "renamed to env::set_var")]
-#[unstable(feature = "os")]
-pub fn setenv<T: BytesContainer>(n: &str, v: T) {
-    #[cfg(unix)]
-    fn _setenv(n: &str, v: &[u8]) {
-        use os::unix::*;
-        let v: OsString = OsStringExt::from_vec(v.to_vec());
-        env::set_var(n, &v)
-    }
-
-    #[cfg(windows)]
-    fn _setenv(n: &str, v: &[u8]) {
-        let v = str::from_utf8(v).unwrap();
-        env::set_var(n, v)
-    }
-
-    _setenv(n, v.container_as_bytes())
-}
-
-/// Remove a variable from the environment entirely.
-#[deprecated(since = "1.0.0", reason = "renamed to env::remove_var")]
-#[unstable(feature = "os")]
-pub fn unsetenv(n: &str) {
-    env::remove_var(n)
-}
-
-/// Parses input according to platform conventions for the `PATH`
-/// environment variable.
-///
-/// # Example
-/// ```rust
-/// use std::os;
-///
-/// let key = "PATH";
-/// match os::getenv_as_bytes(key) {
-///     Some(paths) => {
-///         for path in os::split_paths(paths).iter() {
-///             println!("'{}'", path.display());
-///         }
-///     }
-///     None => println!("{} is not defined in the environment.", key)
-/// }
-/// ```
-#[deprecated(since = "1.0.0", reason = "renamed to env::split_paths")]
-#[unstable(feature = "os")]
-pub fn split_paths<T: BytesContainer>(unparsed: T) -> Vec<Path> {
-    let b = unparsed.container_as_bytes();
-    let s = str::from_utf8(b).unwrap();
-    env::split_paths(s).collect()
-}
-
-/// Joins a collection of `Path`s appropriately for the `PATH`
-/// environment variable.
-///
-/// Returns a `Vec<u8>` on success, since `Path`s are not utf-8
-/// encoded on all platforms.
-///
-/// Returns an `Err` (containing an error message) if one of the input
-/// `Path`s contains an invalid character for constructing the `PATH`
-/// variable (a double quote on Windows or a colon on Unix).
-///
-/// # Example
-///
-/// ```rust
-/// use std::os;
-/// use std::old_path::Path;
-///
-/// let key = "PATH";
-/// let mut paths = os::getenv_as_bytes(key).map_or(Vec::new(), os::split_paths);
-/// paths.push(Path::new("/home/xyz/bin"));
-/// os::setenv(key, os::join_paths(paths.as_slice()).unwrap());
-/// ```
-#[deprecated(since = "1.0.0", reason = "renamed to env::join_paths")]
-#[unstable(feature = "os")]
-pub fn join_paths<T: BytesContainer>(paths: &[T]) -> Result<Vec<u8>, &'static str> {
-    env::join_paths(paths.iter().map(|s| {
-        str::from_utf8(s.container_as_bytes()).unwrap()
-    })).map(|s| {
-        s.to_string_lossy().into_owned().into_bytes()
-    }).map_err(|_| "failed to join paths")
-}
-
-/// A low-level OS in-memory pipe.
-#[derive(Copy)]
-pub struct Pipe {
-    /// A file descriptor representing the reading end of the pipe. Data written
-    /// on the `out` file descriptor can be read from this file descriptor.
-    pub reader: c_int,
-    /// A file descriptor representing the write end of the pipe. Data written
-    /// to this file descriptor can be read from the `input` file descriptor.
-    pub writer: c_int,
-}
-
-/// Creates a new low-level OS in-memory pipe.
-///
-/// This function can fail to succeed if there are no more resources available
-/// to allocate a pipe.
-///
-/// This function is also unsafe as there is no destructor associated with the
-/// `Pipe` structure will return. If it is not arranged for the returned file
-/// descriptors to be closed, the file descriptors will leak. For safe handling
-/// of this scenario, use `std::old_io::PipeStream` instead.
-pub unsafe fn pipe() -> IoResult<Pipe> {
-    let (reader, writer) = try!(sys::os::pipe());
-    Ok(Pipe {
-        reader: reader.unwrap(),
-        writer: writer.unwrap(),
-    })
-}
-
-/// Returns the proper dll filename for the given basename of a file
-/// as a String.
-#[cfg(not(target_os="ios"))]
-#[deprecated(since = "1.0.0", reason = "this function will be removed, use the constants directly")]
-#[unstable(feature = "os")]
-#[allow(deprecated)]
-pub fn dll_filename(base: &str) -> String {
-    format!("{}{}{}", consts::DLL_PREFIX, base, consts::DLL_SUFFIX)
-}
-
-/// Optionally returns the filesystem path to the current executable which is
-/// running but with the executable name.
-///
-/// # Examples
-///
-/// ```rust
-/// use std::os;
-///
-/// match os::self_exe_name() {
-///     Some(exe_path) => println!("Path of this executable is: {}", exe_path.display()),
-///     None => println!("Unable to get the path of this executable!")
-/// };
-/// ```
-#[deprecated(since = "1.0.0", reason = "renamed to env::current_exe")]
-#[unstable(feature = "os")]
-pub fn self_exe_name() -> Option<Path> {
-    env::current_exe().ok()
-}
-
-/// Optionally returns the filesystem path to the current executable which is
-/// running.
-///
-/// Like self_exe_name() but without the binary's name.
-///
-/// # Example
-///
-/// ```rust
-/// use std::os;
-///
-/// match os::self_exe_path() {
-///     Some(exe_path) => println!("Executable's Path is: {}", exe_path.display()),
-///     None => println!("Impossible to fetch the path of this executable.")
-/// };
-/// ```
-#[deprecated(since = "1.0.0", reason = "use env::current_exe + dir_path/pop")]
-#[unstable(feature = "os")]
-pub fn self_exe_path() -> Option<Path> {
-    env::current_exe().ok().map(|mut p| { p.pop(); p })
-}
-
-/// Optionally returns the path to the current user's home directory if known.
-///
-/// # Unix
-///
-/// Returns the value of the 'HOME' environment variable if it is set
-/// and not equal to the empty string.
-///
-/// # Windows
-///
-/// Returns the value of the 'HOME' environment variable if it is
-/// set and not equal to the empty string. Otherwise, returns the value of the
-/// 'USERPROFILE' environment variable if it is set and not equal to the empty
-/// string.
-///
-/// # Example
-///
-/// ```rust
-/// use std::os;
-///
-/// match os::homedir() {
-///     Some(ref p) => println!("{}", p.display()),
-///     None => println!("Impossible to get your home dir!")
-/// }
-/// ```
-#[deprecated(since = "1.0.0", reason = "renamed to env::home_dir")]
-#[allow(deprecated)]
-#[unstable(feature = "os")]
-pub fn homedir() -> Option<Path> {
-    #[inline]
-    #[cfg(unix)]
-    fn _homedir() -> Option<Path> {
-        aux_homedir("HOME")
-    }
-
-    #[inline]
-    #[cfg(windows)]
-    fn _homedir() -> Option<Path> {
-        aux_homedir("HOME").or(aux_homedir("USERPROFILE"))
-    }
-
-    #[inline]
-    fn aux_homedir(home_name: &str) -> Option<Path> {
-        match getenv_as_bytes(home_name) {
-            Some(p)  => {
-                if p.is_empty() { None } else { Path::new_opt(p) }
-            },
-            _ => None
-        }
-    }
-    _homedir()
-}
-
-/// Returns the path to a temporary directory.
-///
-/// On Unix, returns the value of the 'TMPDIR' environment variable if it is
-/// set, otherwise for non-Android it returns '/tmp'. If Android, since there
-/// is no global temporary folder (it is usually allocated per-app), we return
-/// '/data/local/tmp'.
-///
-/// On Windows, returns the value of, in order, the 'TMP', 'TEMP',
-/// 'USERPROFILE' environment variable  if any are set and not the empty
-/// string. Otherwise, tmpdir returns the path to the Windows directory.
-#[deprecated(since = "1.0.0", reason = "renamed to env::temp_dir")]
-#[allow(deprecated)]
-#[unstable(feature = "os")]
-pub fn tmpdir() -> Path {
-    return lookup();
-
-    fn getenv_nonempty(v: &str) -> Option<Path> {
-        match getenv(v) {
-            Some(x) =>
-                if x.is_empty() {
-                    None
-                } else {
-                    Path::new_opt(x)
-                },
-            _ => None
-        }
-    }
-
-    #[cfg(unix)]
-    fn lookup() -> Path {
-        let default = if cfg!(target_os = "android") {
-            Path::new("/data/local/tmp")
-        } else {
-            Path::new("/tmp")
-        };
-
-        getenv_nonempty("TMPDIR").unwrap_or(default)
-    }
-
-    #[cfg(windows)]
-    fn lookup() -> Path {
-        getenv_nonempty("TMP").or(
-            getenv_nonempty("TEMP").or(
-                getenv_nonempty("USERPROFILE").or(
-                   getenv_nonempty("WINDIR")))).unwrap_or(Path::new("C:\\Windows"))
-    }
-}
-
-/// Convert a relative path to an absolute path
-///
-/// If the given path is relative, return it prepended with the current working
-/// directory. If the given path is already an absolute path, return it
-/// as is.
-///
-/// # Example
-/// ```rust
-/// use std::os;
-/// use std::old_path::Path;
-///
-/// // Assume we're in a path like /home/someuser
-/// let rel_path = Path::new("..");
-/// let abs_path = os::make_absolute(&rel_path).unwrap();
-/// println!("The absolute path is {}", abs_path.display());
-/// // Prints "The absolute path is /home"
-/// ```
-// NB: this is here rather than in path because it is a form of environment
-// querying; what it does depends on the process working directory, not just
-// the input paths.
-#[deprecated(since = "1.0.0", reason = "use env::current_dir + .join directly")]
-#[unstable(feature = "os")]
-pub fn make_absolute(p: &Path) -> IoResult<Path> {
-    if p.is_absolute() {
-        Ok(p.clone())
-    } else {
-        env::current_dir().map(|mut cwd| {
-            cwd.push(p);
-            cwd
-        })
-    }
-}
-
-/// Changes the current working directory to the specified path, returning
-/// whether the change was completed successfully or not.
-///
-/// # Example
-/// ```rust
-/// use std::os;
-/// use std::old_path::Path;
-///
-/// let root = Path::new("/");
-/// assert!(os::change_dir(&root).is_ok());
-/// println!("Successfully changed working directory to {}!", root.display());
-/// ```
-#[deprecated(since = "1.0.0", reason = "renamed to env::set_current_dir")]
-#[unstable(feature = "os")]
-pub fn change_dir(p: &Path) -> IoResult<()> {
-    return sys::os::chdir(p);
-}
-
-/// Returns the platform-specific value of errno
-pub fn errno() -> i32 {
-    sys::os::errno() as i32
-}
-
-/// Return the string corresponding to an `errno()` value of `errnum`.
-///
-/// # Example
-/// ```rust
-/// use std::os;
-///
-/// // Same as println!("{}", last_os_error());
-/// println!("{}", os::error_string(os::errno() as i32));
-/// ```
-pub fn error_string(errnum: i32) -> String {
-    return sys::os::error_string(errnum);
-}
-
-/// Get a string representing the platform-dependent last error
-pub fn last_os_error() -> String {
-    error_string(errno())
-}
-
-/// Sets the process exit code
-///
-/// Sets the exit code returned by the process if all supervised tasks
-/// terminate successfully (without panicking). If the current root task panics
-/// and is supervised by the scheduler then any user-specified exit status is
-/// ignored and the process exits with the default panic status.
-///
-/// Note that this is not synchronized against modifications of other threads.
-#[deprecated(since = "1.0.0", reason = "renamed to env::set_exit_status")]
-#[unstable(feature = "os")]
-pub fn set_exit_status(code: int) {
-    env::set_exit_status(code as i32)
-}
-
-/// Fetches the process's current exit code. This defaults to 0 and can change
-/// by calling `set_exit_status`.
-#[deprecated(since = "1.0.0", reason = "renamed to env::get_exit_status")]
-#[unstable(feature = "os")]
-pub fn get_exit_status() -> int {
-    env::get_exit_status() as isize
-}
-
-#[cfg(target_os = "macos")]
-unsafe fn load_argc_and_argv(argc: int,
-                             argv: *const *const c_char) -> Vec<Vec<u8>> {
-    use ffi::CStr;
-    use iter::range;
-
-    (0..argc).map(|i| {
-        CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec()
-    }).collect()
-}
-
-/// Returns the command line arguments
-///
-/// Returns a list of the command line arguments.
-#[cfg(target_os = "macos")]
-fn real_args_as_bytes() -> Vec<Vec<u8>> {
-    unsafe {
-        let (argc, argv) = (*_NSGetArgc() as int,
-                            *_NSGetArgv() as *const *const c_char);
-        load_argc_and_argv(argc, argv)
-    }
-}
-
-// As _NSGetArgc and _NSGetArgv aren't mentioned in iOS docs
-// and use underscores in their names - they're most probably
-// are considered private and therefore should be avoided
-// Here is another way to get arguments using Objective C
-// runtime
-//
-// In general it looks like:
-// res = Vec::new()
-// let args = [[NSProcessInfo processInfo] arguments]
-// for i in 0..[args count]
-//      res.push([args objectAtIndex:i])
-// res
-#[cfg(target_os = "ios")]
-fn real_args_as_bytes() -> Vec<Vec<u8>> {
-    use ffi::c_str_to_bytes;
-    use iter::range;
-    use mem;
-
-    #[link(name = "objc")]
-    extern {
-        fn sel_registerName(name: *const libc::c_uchar) -> Sel;
-        fn objc_msgSend(obj: NsId, sel: Sel, ...) -> NsId;
-        fn objc_getClass(class_name: *const libc::c_uchar) -> NsId;
-    }
-
-    #[link(name = "Foundation", kind = "framework")]
-    extern {}
-
-    type Sel = *const libc::c_void;
-    type NsId = *const libc::c_void;
-
-    let mut res = Vec::new();
-
-    unsafe {
-        let processInfoSel = sel_registerName("processInfo\0".as_ptr());
-        let argumentsSel = sel_registerName("arguments\0".as_ptr());
-        let utf8Sel = sel_registerName("UTF8String\0".as_ptr());
-        let countSel = sel_registerName("count\0".as_ptr());
-        let objectAtSel = sel_registerName("objectAtIndex:\0".as_ptr());
-
-        let klass = objc_getClass("NSProcessInfo\0".as_ptr());
-        let info = objc_msgSend(klass, processInfoSel);
-        let args = objc_msgSend(info, argumentsSel);
-
-        let cnt: int = mem::transmute(objc_msgSend(args, countSel));
-        for i in 0..cnt {
-            let tmp = objc_msgSend(args, objectAtSel, i);
-            let utf_c_str: *const libc::c_char =
-                mem::transmute(objc_msgSend(tmp, utf8Sel));
-            res.push(c_str_to_bytes(&utf_c_str).to_vec());
-        }
-    }
-
-    res
-}
-
-#[cfg(any(target_os = "linux",
-          target_os = "android",
-          target_os = "freebsd",
-          target_os = "dragonfly",
-          target_os = "openbsd"))]
-fn real_args_as_bytes() -> Vec<Vec<u8>> {
-    use rt;
-    rt::args::clone().unwrap_or_else(|| vec![])
-}
-
-#[cfg(not(windows))]
-fn real_args() -> Vec<String> {
-    real_args_as_bytes().into_iter()
-                        .map(|v| {
-                            String::from_utf8_lossy(&v).into_owned()
-                        }).collect()
-}
-
-#[cfg(windows)]
-fn real_args() -> Vec<String> {
-    use slice;
-    use iter::range;
-
-    let mut nArgs: c_int = 0;
-    let lpArgCount: *mut c_int = &mut nArgs;
-    let lpCmdLine = unsafe { GetCommandLineW() };
-    let szArgList = unsafe { CommandLineToArgvW(lpCmdLine, lpArgCount) };
-
-    let args: Vec<_> = (0..nArgs as uint).map(|i| unsafe {
-        // Determine the length of this argument.
-        let ptr = *szArgList.offset(i as int);
-        let mut len = 0;
-        while *ptr.offset(len as int) != 0 { len += 1; }
-
-        // Push it onto the list.
-        let ptr = ptr as *const u16;
-        let buf = slice::from_raw_parts(ptr, len);
-        let opt_s = String::from_utf16(sys::truncate_utf16_at_nul(buf));
-        opt_s.ok().expect("CommandLineToArgvW returned invalid UTF-16")
-    }).collect();
-
-    unsafe {
-        LocalFree(szArgList as *mut c_void);
-    }
-
-    return args
-}
-
-#[cfg(windows)]
-fn real_args_as_bytes() -> Vec<Vec<u8>> {
-    real_args().into_iter().map(|s| s.into_bytes()).collect()
-}
-
-type LPCWSTR = *const u16;
-
-#[cfg(windows)]
-#[link_name="kernel32"]
-extern "system" {
-    fn GetCommandLineW() -> LPCWSTR;
-    fn LocalFree(ptr: *mut c_void);
-}
-
-#[cfg(windows)]
-#[link_name="shell32"]
-extern "system" {
-    fn CommandLineToArgvW(lpCmdLine: LPCWSTR,
-                          pNumArgs: *mut c_int) -> *mut *mut u16;
-}
-
-/// Returns the arguments which this program was started with (normally passed
-/// via the command line).
-///
-/// The first element is traditionally the path to the executable, but it can be
-/// set to arbitrary text, and it may not even exist, so this property should not
-/// be relied upon for security purposes.
-///
-/// The arguments are interpreted as utf-8, with invalid bytes replaced with \uFFFD.
-/// See `String::from_utf8_lossy` for details.
-/// # Example
-///
-/// ```rust
-/// use std::os;
-///
-/// // Prints each argument on a separate line
-/// for argument in os::args().iter() {
-///     println!("{}", argument);
-/// }
-/// ```
-#[deprecated(since = "1.0.0", reason = "use std::env::args() instead")]
-#[unstable(feature = "os")]
-pub fn args() -> Vec<String> {
-    real_args()
-}
-
-/// Returns the arguments which this program was started with (normally passed
-/// via the command line) as byte vectors.
-#[deprecated(since = "1.0.0", reason = "use env::args_os instead")]
-#[unstable(feature = "os")]
-pub fn args_as_bytes() -> Vec<Vec<u8>> {
-    real_args_as_bytes()
-}
-
-#[cfg(target_os = "macos")]
-extern {
-    // These functions are in crt_externs.h.
-    fn _NSGetArgc() -> *mut c_int;
-    fn _NSGetArgv() -> *mut *mut *mut c_char;
-}
-
-/// Returns the page size of the current architecture in bytes.
-#[deprecated(since = "1.0.0", reason = "renamed to env::page_size")]
-#[unstable(feature = "os")]
-pub fn page_size() -> uint {
-    sys::os::page_size()
-}
-
-/// A memory mapped file or chunk of memory. This is a very system-specific
-/// interface to the OS's memory mapping facilities (`mmap` on POSIX,
-/// `VirtualAlloc`/`CreateFileMapping` on Windows). It makes no attempt at
-/// abstracting platform differences, besides in error values returned. Consider
-/// yourself warned.
-///
-/// The memory map is released (unmapped) when the destructor is run, so don't
-/// let it leave scope by accident if you want it to stick around.
-pub struct MemoryMap {
-    data: *mut u8,
-    len: uint,
-    kind: MemoryMapKind,
-}
-
-/// Type of memory map
-#[allow(raw_pointer_derive)]
-#[derive(Copy)]
-pub enum MemoryMapKind {
-    /// Virtual memory map. Usually used to change the permissions of a given
-    /// chunk of memory.  Corresponds to `VirtualAlloc` on Windows.
-    MapFile(*const u8),
-    /// Virtual memory map. Usually used to change the permissions of a given
-    /// chunk of memory, or for allocation. Corresponds to `VirtualAlloc` on
-    /// Windows.
-    MapVirtual
-}
-
-/// Options the memory map is created with
-#[allow(raw_pointer_derive)]
-#[derive(Copy)]
-pub enum MapOption {
-    /// The memory should be readable
-    MapReadable,
-    /// The memory should be writable
-    MapWritable,
-    /// The memory should be executable
-    MapExecutable,
-    /// 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.
-    MapOffset(uint),
-    /// On POSIX, this can be used to specify the default flags passed to
-    /// `mmap`. By default it uses `MAP_PRIVATE` and, if not using `MapFd`,
-    /// `MAP_ANON`. This will override both of those. This is platform-specific
-    /// (the exact values used) and ignored on Windows.
-    MapNonStandardFlags(c_int),
-}
-
-/// Possible errors when creating a map.
-#[derive(Copy, Debug)]
-pub enum MapError {
-    /// # The following are POSIX-specific
-    ///
-    /// fd was not open for reading or, if using `MapWritable`, was not open for
-    /// writing.
-    ErrFdNotAvail,
-    /// fd was not valid
-    ErrInvalidFd,
-    /// Either the address given by `MapAddr` or offset given by `MapOffset` was
-    /// not a multiple of `MemoryMap::granularity` (unaligned to page size).
-    ErrUnaligned,
-    /// With `MapFd`, the fd does not support mapping.
-    ErrNoMapSupport,
-    /// If using `MapAddr`, the address + `min_len` was outside of the process's
-    /// address space. If using `MapFd`, the target of the fd didn't have enough
-    /// resources to fulfill the request.
-    ErrNoMem,
-    /// A zero-length map was requested. This is invalid according to
-    /// [POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html).
-    /// Not all platforms obey this, but this wrapper does.
-    ErrZeroLength,
-    /// Unrecognized error. The inner value is the unrecognized errno.
-    ErrUnknown(int),
-    /// # The following are Windows-specific
-    ///
-    /// Unsupported combination of protection flags
-    /// (`MapReadable`/`MapWritable`/`MapExecutable`).
-    ErrUnsupProt,
-    /// When using `MapFd`, `MapOffset` was given (Windows does not support this
-    /// at all)
-    ErrUnsupOffset,
-    /// When using `MapFd`, there was already a mapping to the file.
-    ErrAlreadyExists,
-    /// Unrecognized error from `VirtualAlloc`. The inner value is the return
-    /// value of GetLastError.
-    ErrVirtualAlloc(i32),
-    /// Unrecognized error from `CreateFileMapping`. The inner value is the
-    /// return value of `GetLastError`.
-    ErrCreateFileMappingW(i32),
-    /// Unrecognized error from `MapViewOfFile`. The inner value is the return
-    /// value of `GetLastError`.
-    ErrMapViewOfFile(i32)
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for MapError {
-    fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
-        let str = match *self {
-            ErrFdNotAvail => "fd not available for reading or writing",
-            ErrInvalidFd => "Invalid fd",
-            ErrUnaligned => {
-                "Unaligned address, invalid flags, negative length or \
-                 unaligned offset"
-            }
-            ErrNoMapSupport=> "File doesn't support mapping",
-            ErrNoMem => "Invalid address, or not enough available memory",
-            ErrUnsupProt => "Protection mode unsupported",
-            ErrUnsupOffset => "Offset in virtual memory mode is unsupported",
-            ErrAlreadyExists => "File mapping for specified file already exists",
-            ErrZeroLength => "Zero-length mapping not allowed",
-            ErrUnknown(code) => {
-                return write!(out, "Unknown error = {}", code)
-            },
-            ErrVirtualAlloc(code) => {
-                return write!(out, "VirtualAlloc failure = {}", code)
-            },
-            ErrCreateFileMappingW(code) => {
-                return write!(out, "CreateFileMappingW failure = {}", code)
-            },
-            ErrMapViewOfFile(code) => {
-                return write!(out, "MapViewOfFile failure = {}", code)
-            }
-        };
-        write!(out, "{}", str)
-    }
-}
-
-impl Error for MapError {
-    fn description(&self) -> &str { "memory map error" }
-}
-
-// Round up `from` to be divisible by `to`
-fn round_up(from: uint, to: uint) -> uint {
-    let r = if from % to == 0 {
-        from
-    } else {
-        from + to - (from % to)
-    };
-    if r == 0 {
-        to
-    } else {
-        r
-    }
-}
-
-#[cfg(unix)]
-impl MemoryMap {
-    /// Create a new mapping with the given `options`, at least `min_len` bytes
-    /// long. `min_len` must be greater than zero; see the note on
-    /// `ErrZeroLength`.
-    pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError> {
-        use libc::off_t;
-
-        if min_len == 0 {
-            return Err(ErrZeroLength)
-        }
-        let mut addr: *const u8 = ptr::null();
-        let mut prot = 0;
-        let mut flags = libc::MAP_PRIVATE;
-        let mut fd = -1;
-        let mut offset = 0;
-        let mut custom_flags = false;
-        let len = round_up(min_len, env::page_size());
-
-        for &o in options {
-            match o {
-                MapReadable => { prot |= libc::PROT_READ; },
-                MapWritable => { prot |= libc::PROT_WRITE; },
-                MapExecutable => { prot |= libc::PROT_EXEC; },
-                MapAddr(addr_) => {
-                    flags |= libc::MAP_FIXED;
-                    addr = addr_;
-                },
-                MapFd(fd_) => {
-                    flags |= libc::MAP_FILE;
-                    fd = fd_;
-                },
-                MapOffset(offset_) => { offset = offset_ as off_t; },
-                MapNonStandardFlags(f) => { custom_flags = true; flags = f },
-            }
-        }
-        if fd == -1 && !custom_flags { flags |= libc::MAP_ANON; }
-
-        let r = unsafe {
-            libc::mmap(addr as *mut c_void, len as libc::size_t, prot, flags,
-                       fd, offset)
-        };
-        if r == libc::MAP_FAILED {
-            Err(match errno() as c_int {
-                libc::EACCES => ErrFdNotAvail,
-                libc::EBADF => ErrInvalidFd,
-                libc::EINVAL => ErrUnaligned,
-                libc::ENODEV => ErrNoMapSupport,
-                libc::ENOMEM => ErrNoMem,
-                code => ErrUnknown(code as int)
-            })
-        } else {
-            Ok(MemoryMap {
-               data: r as *mut u8,
-               len: len,
-               kind: if fd == -1 {
-                   MapVirtual
-               } else {
-                   MapFile(ptr::null())
-               }
-            })
-        }
-    }
-
-    /// Granularity that the offset or address must be for `MapOffset` and
-    /// `MapAddr` respectively.
-    pub fn granularity() -> uint {
-        env::page_size()
-    }
-}
-
-#[cfg(unix)]
-impl Drop for MemoryMap {
-    /// Unmap the mapping. Panics the task if `munmap` panics.
-    fn drop(&mut self) {
-        if self.len == 0 { /* workaround for dummy_stack */ return; }
-
-        unsafe {
-            // `munmap` only panics due to logic errors
-            libc::munmap(self.data as *mut c_void, self.len as libc::size_t);
-        }
-    }
-}
-
-#[cfg(windows)]
-impl MemoryMap {
-    /// Create a new mapping with the given `options`, at least `min_len` bytes long.
-    pub fn new(min_len: uint, options: &[MapOption]) -> Result<MemoryMap, MapError> {
-        use libc::types::os::arch::extra::{LPVOID, DWORD, SIZE_T, HANDLE};
-
-        let mut lpAddress: LPVOID = ptr::null_mut();
-        let mut readable = false;
-        let mut writable = false;
-        let mut executable = false;
-        let mut handle: HANDLE = libc::INVALID_HANDLE_VALUE;
-        let mut offset: uint = 0;
-        let len = round_up(min_len, env::page_size());
-
-        for &o in options {
-            match o {
-                MapReadable => { readable = true; },
-                MapWritable => { writable = true; },
-                MapExecutable => { executable = true; }
-                MapAddr(addr_) => { lpAddress = addr_ as LPVOID; },
-                MapFd(handle_) => { handle = handle_; },
-                MapOffset(offset_) => { offset = offset_; },
-                MapNonStandardFlags(..) => {}
-            }
-        }
-
-        let flProtect = match (executable, readable, writable) {
-            (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 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 handle == libc::INVALID_HANDLE_VALUE {
-            if offset != 0 {
-                return Err(ErrUnsupOffset);
-            }
-            let r = unsafe {
-                libc::VirtualAlloc(lpAddress,
-                                   len as SIZE_T,
-                                   libc::MEM_COMMIT | libc::MEM_RESERVE,
-                                   flProtect)
-            };
-            match r as uint {
-                0 => Err(ErrVirtualAlloc(errno())),
-                _ => Ok(MemoryMap {
-                   data: r as *mut u8,
-                   len: len,
-                   kind: MapVirtual
-                })
-            }
-        } else {
-            let dwDesiredAccess = match (executable, readable, writable) {
-                (false, true, false) => libc::FILE_MAP_READ,
-                (false, true, true) => libc::FILE_MAP_WRITE,
-                (true, true, false) => libc::FILE_MAP_READ | libc::FILE_MAP_EXECUTE,
-                (true, true, true) => libc::FILE_MAP_WRITE | libc::FILE_MAP_EXECUTE,
-                _ => return Err(ErrUnsupProt) // Actually, because of the check above,
-                                              // we should never get here.
-            };
-            unsafe {
-                let hFile = handle;
-                let mapping = libc::CreateFileMappingW(hFile,
-                                                       ptr::null_mut(),
-                                                       flProtect,
-                                                       0,
-                                                       0,
-                                                       ptr::null());
-                if mapping == ptr::null_mut() {
-                    return Err(ErrCreateFileMappingW(errno()));
-                }
-                if errno() as c_int == libc::ERROR_ALREADY_EXISTS {
-                    return Err(ErrAlreadyExists);
-                }
-                let r = libc::MapViewOfFile(mapping,
-                                            dwDesiredAccess,
-                                            ((len as u64) >> 32) as DWORD,
-                                            (offset & 0xffff_ffff) as DWORD,
-                                            0);
-                match r as uint {
-                    0 => Err(ErrMapViewOfFile(errno())),
-                    _ => Ok(MemoryMap {
-                       data: r as *mut u8,
-                       len: len,
-                       kind: MapFile(mapping as *const u8)
-                    })
-                }
-            }
-        }
-    }
-
-    /// Granularity of MapAddr() and MapOffset() parameter values.
-    /// This may be greater than the value returned by page_size().
-    pub fn granularity() -> uint {
-        use mem;
-        unsafe {
-            let mut info = mem::zeroed();
-            libc::GetSystemInfo(&mut info);
-
-            return info.dwAllocationGranularity as uint;
-        }
-    }
-}
-
-#[cfg(windows)]
-impl Drop for MemoryMap {
-    /// Unmap the mapping. Panics the task if any of `VirtualFree`,
-    /// `UnmapViewOfFile`, or `CloseHandle` fail.
-    fn drop(&mut self) {
-        use libc::types::os::arch::extra::{LPCVOID, HANDLE};
-        use libc::consts::os::extra::FALSE;
-        if self.len == 0 { return }
-
-        unsafe {
-            match self.kind {
-                MapVirtual => {
-                    if libc::VirtualFree(self.data as *mut c_void, 0,
-                                         libc::MEM_RELEASE) == 0 {
-                        println!("VirtualFree failed: {}", errno());
-                    }
-                },
-                MapFile(mapping) => {
-                    if libc::UnmapViewOfFile(self.data as LPCVOID) == FALSE {
-                        println!("UnmapViewOfFile failed: {}", errno());
-                    }
-                    if libc::CloseHandle(mapping as HANDLE) == FALSE {
-                        println!("CloseHandle failed: {}", errno());
-                    }
-                }
-            }
-        }
-    }
-}
-
-impl MemoryMap {
-    /// Returns the pointer to the memory created or modified by this map.
-    pub fn data(&self) -> *mut u8 { self.data }
-    /// Returns the number of bytes this map applies to.
-    pub fn len(&self) -> uint { self.len }
-    /// Returns the type of mapping this represents.
-    pub fn kind(&self) -> MemoryMapKind { self.kind }
-}
-
-#[cfg(target_os = "linux")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
-    pub use os::arch_consts::ARCH;
-
-    pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `linux`.
-    pub const SYSNAME: &'static str = "linux";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
-    pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
-    pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
-    pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
-    pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
-    pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "macos")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
-    pub use os::arch_consts::ARCH;
-
-    pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `macos`.
-    pub const SYSNAME: &'static str = "macos";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
-    pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.dylib`.
-    pub const DLL_SUFFIX: &'static str = ".dylib";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `dylib`.
-    pub const DLL_EXTENSION: &'static str = "dylib";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
-    pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
-    pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "ios")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
-    pub use os::arch_consts::ARCH;
-
-    pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `ios`.
-    pub const SYSNAME: &'static str = "ios";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
-    pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
-    pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "freebsd")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
-    pub use os::arch_consts::ARCH;
-
-    pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `freebsd`.
-    pub const SYSNAME: &'static str = "freebsd";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
-    pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
-    pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
-    pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
-    pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
-    pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "dragonfly")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
-    pub use os::arch_consts::ARCH;
-
-    pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `dragonfly`.
-    pub const SYSNAME: &'static str = "dragonfly";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
-    pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
-    pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
-    pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
-    pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
-    pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "openbsd")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
-    pub use os::arch_consts::ARCH;
-
-    pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `openbsd`.
-    pub const SYSNAME: &'static str = "openbsd";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
-    pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
-    pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
-    pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
-    pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
-    pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "android")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
-    pub use os::arch_consts::ARCH;
-
-    pub const FAMILY: &'static str = "unix";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `android`.
-    pub const SYSNAME: &'static str = "android";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, `lib`.
-    pub const DLL_PREFIX: &'static str = "lib";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.so`.
-    pub const DLL_SUFFIX: &'static str = ".so";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `so`.
-    pub const DLL_EXTENSION: &'static str = "so";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, the empty string.
-    pub const EXE_SUFFIX: &'static str = "";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, the empty string.
-    pub const EXE_EXTENSION: &'static str = "";
-}
-
-#[cfg(target_os = "windows")]
-#[deprecated(since = "1.0.0", reason = "renamed to env::consts")]
-#[unstable(feature = "os")]
-pub mod consts {
-    pub use os::arch_consts::ARCH;
-
-    pub const FAMILY: &'static str = "windows";
-
-    /// A string describing the specific operating system in use: in this
-    /// case, `windows`.
-    pub const SYSNAME: &'static str = "windows";
-
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform: in this case, the empty string.
-    pub const DLL_PREFIX: &'static str = "";
-
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform: in this case, `.dll`.
-    pub const DLL_SUFFIX: &'static str = ".dll";
-
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot: in this case, `dll`.
-    pub const DLL_EXTENSION: &'static str = "dll";
-
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform: in this case, `.exe`.
-    pub const EXE_SUFFIX: &'static str = ".exe";
-
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform: in this case, `exe`.
-    pub const EXE_EXTENSION: &'static str = "exe";
-}
-
-#[cfg(target_arch = "x86")]
-mod arch_consts {
-    pub const ARCH: &'static str = "x86";
-}
-
-#[cfg(target_arch = "x86_64")]
-mod arch_consts {
-    pub const ARCH: &'static str = "x86_64";
-}
-
-#[cfg(target_arch = "arm")]
-mod arch_consts {
-    pub const ARCH: &'static str = "arm";
-}
-
-#[cfg(target_arch = "aarch64")]
-mod arch_consts {
-    pub const ARCH: &'static str = "aarch64";
-}
-
-#[cfg(target_arch = "mips")]
-mod arch_consts {
-    pub const ARCH: &'static str = "mips";
-}
-
-#[cfg(target_arch = "mipsel")]
-mod arch_consts {
-    pub const ARCH: &'static str = "mipsel";
-}
-
-#[cfg(target_arch = "powerpc")]
-mod arch_consts {
-    pub const ARCH: &'static str = "powerpc";
-}
-
-#[cfg(test)]
-mod tests {
-    #![allow(deprecated)] // rand
-
-    use prelude::v1::*;
-
-    use iter::repeat;
-    use os::{env, getcwd, getenv, make_absolute};
-    use os::{split_paths, join_paths, setenv, unsetenv};
-    use os;
-    use rand::Rng;
-    use rand;
-
-    #[test]
-    pub fn last_os_error() {
-        debug!("{}", os::last_os_error());
-    }
-
-    fn make_rand_name() -> String {
-        let mut rng = rand::thread_rng();
-        let n = format!("TEST{}", rng.gen_ascii_chars().take(10)
-                                     .collect::<String>());
-        assert!(getenv(&n).is_none());
-        n
-    }
-
-    #[test]
-    fn test_num_cpus() {
-        assert!(os::num_cpus() > 0);
-    }
-
-    #[test]
-    fn test_setenv() {
-        let n = make_rand_name();
-        setenv(&n, "VALUE");
-        assert_eq!(getenv(&n), Some("VALUE".to_string()));
-    }
-
-    #[test]
-    fn test_unsetenv() {
-        let n = make_rand_name();
-        setenv(&n, "VALUE");
-        unsetenv(&n);
-        assert_eq!(getenv(&n), None);
-    }
-
-    #[test]
-    #[ignore]
-    fn test_setenv_overwrite() {
-        let n = make_rand_name();
-        setenv(&n, "1");
-        setenv(&n, "2");
-        assert_eq!(getenv(&n), Some("2".to_string()));
-        setenv(&n, "");
-        assert_eq!(getenv(&n), Some("".to_string()));
-    }
-
-    // Windows GetEnvironmentVariable requires some extra work to make sure
-    // the buffer the variable is copied into is the right size
-    #[test]
-    #[ignore]
-    fn test_getenv_big() {
-        let mut s = "".to_string();
-        let mut i = 0;
-        while i < 100 {
-            s.push_str("aaaaaaaaaa");
-            i += 1;
-        }
-        let n = make_rand_name();
-        setenv(&n, &s);
-        debug!("{}", s.clone());
-        assert_eq!(getenv(&n), Some(s));
-    }
-
-    #[test]
-    fn test_self_exe_name() {
-        let path = os::self_exe_name();
-        assert!(path.is_some());
-        let path = path.unwrap();
-        debug!("{}", path.display());
-
-        // Hard to test this function
-        assert!(path.is_absolute());
-    }
-
-    #[test]
-    fn test_self_exe_path() {
-        let path = os::self_exe_path();
-        assert!(path.is_some());
-        let path = path.unwrap();
-        debug!("{}", path.display());
-
-        // Hard to test this function
-        assert!(path.is_absolute());
-    }
-
-    #[test]
-    #[ignore]
-    fn test_env_getenv() {
-        let e = env();
-        assert!(e.len() > 0);
-        for p in &e {
-            let (n, v) = (*p).clone();
-            debug!("{}", n);
-            let v2 = getenv(&n);
-            // MingW seems to set some funky environment variables like
-            // "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned
-            // from env() but not visible from getenv().
-            assert!(v2.is_none() || v2 == Some(v));
-        }
-    }
-
-    #[test]
-    fn test_env_set_get_huge() {
-        let n = make_rand_name();
-        let s = repeat("x").take(10000).collect::<String>();
-        setenv(&n, &s);
-        assert_eq!(getenv(&n), Some(s));
-        unsetenv(&n);
-        assert_eq!(getenv(&n), None);
-    }
-
-    #[test]
-    fn test_env_setenv() {
-        let n = make_rand_name();
-
-        let mut e = env();
-        setenv(&n, "VALUE");
-        assert!(!e.contains(&(n.clone(), "VALUE".to_string())));
-
-        e = env();
-        assert!(e.contains(&(n, "VALUE".to_string())));
-    }
-
-    #[test]
-    fn test() {
-        assert!((!Path::new("test-path").is_absolute()));
-
-        let cwd = getcwd().unwrap();
-        debug!("Current working directory: {}", cwd.display());
-
-        debug!("{}", make_absolute(&Path::new("test-path")).unwrap().display());
-        debug!("{}", make_absolute(&Path::new("/usr/bin")).unwrap().display());
-    }
-
-    #[test]
-    #[cfg(unix)]
-    fn homedir() {
-        let oldhome = getenv("HOME");
-
-        setenv("HOME", "/home/MountainView");
-        assert!(os::homedir() == Some(Path::new("/home/MountainView")));
-
-        setenv("HOME", "");
-        assert!(os::homedir().is_none());
-
-        if let Some(s) = oldhome {
-            setenv("HOME", s);
-        }
-    }
-
-    #[test]
-    #[cfg(windows)]
-    fn homedir() {
-
-        let oldhome = getenv("HOME");
-        let olduserprofile = getenv("USERPROFILE");
-
-        setenv("HOME", "");
-        setenv("USERPROFILE", "");
-
-        assert!(os::homedir().is_none());
-
-        setenv("HOME", "/home/MountainView");
-        assert!(os::homedir() == Some(Path::new("/home/MountainView")));
-
-        setenv("HOME", "");
-
-        setenv("USERPROFILE", "/home/MountainView");
-        assert!(os::homedir() == Some(Path::new("/home/MountainView")));
-
-        setenv("HOME", "/home/MountainView");
-        setenv("USERPROFILE", "/home/PaloAlto");
-        assert!(os::homedir() == Some(Path::new("/home/MountainView")));
-
-        if let Some(s) = oldhome {
-            setenv("HOME", &s);
-        }
-        if let Some(s) = olduserprofile {
-            setenv("USERPROFILE", &s);
-        }
-    }
-
-    #[test]
-    fn memory_map_rw() {
-        use result::Result::{Ok, Err};
-
-        let chunk = match os::MemoryMap::new(16, &[
-            os::MapOption::MapReadable,
-            os::MapOption::MapWritable
-        ]) {
-            Ok(chunk) => chunk,
-            Err(msg) => panic!("{:?}", msg)
-        };
-        assert!(chunk.len >= 16);
-
-        unsafe {
-            *chunk.data = 0xBE;
-            assert!(*chunk.data == 0xBE);
-        }
-    }
-
-    #[test]
-    fn memory_map_file() {
-        use libc;
-        use os::*;
-        use old_io::fs::{File, unlink};
-        use old_io::SeekStyle::SeekSet;
-        use old_io::FileMode::Open;
-        use old_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 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).unwrap();
-        file.write_u8(0).unwrap();
-
-        let chunk = MemoryMap::new(size / 2, &[
-            MapOption::MapReadable,
-            MapOption::MapWritable,
-            MapOption::MapFd(get_fd(&file)),
-            MapOption::MapOffset(size / 2)
-        ]).unwrap();
-        assert!(chunk.len > 0);
-
-        unsafe {
-            *chunk.data = 0xbe;
-            assert!(*chunk.data == 0xbe);
-        }
-        drop(chunk);
-
-        unlink(&path).unwrap();
-    }
-
-    #[test]
-    #[cfg(windows)]
-    fn split_paths_windows() {
-        fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
-            split_paths(unparsed) ==
-                parsed.iter().map(|s| Path::new(*s)).collect::<Vec<_>>()
-        }
-
-        assert!(check_parse("", &mut [""]));
-        assert!(check_parse(r#""""#, &mut [""]));
-        assert!(check_parse(";;", &mut ["", "", ""]));
-        assert!(check_parse(r"c:\", &mut [r"c:\"]));
-        assert!(check_parse(r"c:\;", &mut [r"c:\", ""]));
-        assert!(check_parse(r"c:\;c:\Program Files\",
-                            &mut [r"c:\", r"c:\Program Files\"]));
-        assert!(check_parse(r#"c:\;c:\"foo"\"#, &mut [r"c:\", r"c:\foo\"]));
-        assert!(check_parse(r#"c:\;c:\"foo;bar"\;c:\baz"#,
-                            &mut [r"c:\", r"c:\foo;bar\", r"c:\baz"]));
-    }
-
-    #[test]
-    #[cfg(unix)]
-    fn split_paths_unix() {
-        fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
-            split_paths(unparsed) ==
-                parsed.iter().map(|s| Path::new(*s)).collect::<Vec<_>>()
-        }
-
-        assert!(check_parse("", &mut [""]));
-        assert!(check_parse("::", &mut ["", "", ""]));
-        assert!(check_parse("/", &mut ["/"]));
-        assert!(check_parse("/:", &mut ["/", ""]));
-        assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"]));
-    }
-
-    #[test]
-    #[cfg(unix)]
-    fn join_paths_unix() {
-        fn test_eq(input: &[&str], output: &str) -> bool {
-            join_paths(input).unwrap() == output.as_bytes()
-        }
-
-        assert!(test_eq(&[], ""));
-        assert!(test_eq(&["/bin", "/usr/bin", "/usr/local/bin"],
-                         "/bin:/usr/bin:/usr/local/bin"));
-        assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""],
-                         ":/bin:::/usr/bin:"));
-        assert!(join_paths(&["/te:st"]).is_err());
-    }
-
-    #[test]
-    #[cfg(windows)]
-    fn join_paths_windows() {
-        fn test_eq(input: &[&str], output: &str) -> bool {
-            join_paths(input).unwrap() == output.as_bytes()
-        }
-
-        assert!(test_eq(&[], ""));
-        assert!(test_eq(&[r"c:\windows", r"c:\"],
-                        r"c:\windows;c:\"));
-        assert!(test_eq(&["", r"c:\windows", "", "", r"c:\", ""],
-                        r";c:\windows;;;c:\;"));
-        assert!(test_eq(&[r"c:\te;st", r"c:\"],
-                        r#""c:\te;st";c:\"#));
-        assert!(join_paths(&[r#"c:\te"st"#]).is_err());
-    }
-
-    // More recursive_mkdir tests are in extra::tempfile
-}
index 2e05f6d974e3ed9492917d5e8335413261e9c6bc..3e0584d9ab4f538a0016bb267825dec440b2ace3 100644 (file)
 #![unstable(feature = "std_misc")]
 
 use prelude::v1::*;
+use io::prelude::*;
 
 use any::Any;
 use cell::RefCell;
-use old_io::IoResult;
 use rt::{backtrace, unwind};
-use rt::util::{Stderr, Stdio};
+use sys::stdio::Stderr;
 use thread;
 
 // Defined in this module instead of old_io::stdio so that the unwinding
 thread_local! {
-    pub static LOCAL_STDERR: RefCell<Option<Box<Writer + Send>>> = {
+    pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
         RefCell::new(None)
     }
 }
 
-impl Writer for Stdio {
-    fn write_all(&mut self, bytes: &[u8]) -> IoResult<()> {
-        let _ = self.write_bytes(bytes);
-        Ok(())
-    }
-}
-
-pub fn on_panic(obj: &(Any+Send), file: &'static str, line: uint) {
+pub fn on_panic(obj: &(Any+Send), file: &'static str, line: usize) {
     let msg = match obj.downcast_ref::<&'static str>() {
         Some(s) => *s,
         None => match obj.downcast_ref::<String>() {
@@ -41,7 +34,7 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: uint) {
             None => "Box<Any>",
         }
     };
-    let mut err = Stderr;
+    let mut err = Stderr::new();
     let thread = thread::current();
     let name = thread.name().unwrap_or("<unnamed>");
     let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take());
old mode 100755 (executable)
new mode 100644 (file)
index 49a5efe..4471b5a
@@ -17,7 +17,7 @@
 //!
 //! ## Simple usage
 //!
-//! Path manipulation involves both parsing components from slices and building
+//! Path manipulation includes both parsing components from slices and building
 //! new owned paths.
 //!
 //! To parse a path, you can create a `Path` slice from a `str`
@@ -37,7 +37,7 @@
 //! ```rust
 //! use std::path::PathBuf;
 //!
-//! let mut path = PathBuf::new("c:\\");
+//! let mut path = PathBuf::from("c:\\");
 //! path.push("windows");
 //! path.push("system32");
 //! path.set_extension("dll");
@@ -50,9 +50,9 @@
 //! `\`). The APIs for path parsing are largely specified in terms of the path's
 //! components, so it's important to clearly understand how those are determined.
 //!
-//! A path can always be reconstructed into an equivalent path by putting
-//! together its components via `push`. Syntactically, the paths may differ by
-//! the normalization described below.
+//! A path can always be reconstructed into an *equivalent* path by
+//! putting together its components via `push`. Syntactically, the
+//! paths may differ by the normalization described below.
 //!
 //! ### Component types
 //!
 //! directories. The path `a/b` has two normal components, `a` and `b`.
 //!
 //! * Current directory components represent the `.` character. For example,
-//! `a/.` has a normal component `a` and a current directory component.
+//! `./a` has a current directory component and a normal component `a`.
 //!
 //! * The root directory component represents a separator that designates
 //!   starting from root. For example, `/a/b` has a root directory component
 //!   followed by normal components `a` and `b`.
 //!
-//! On Windows, two additional component types come into play:
+//! On Windows, an additional component type comes into play:
 //!
 //! * Prefix components, of which there is a large variety. For example, `C:`
 //! and `\\server\share` are prefixes. The path `C:windows` has a prefix
 //! prefix component `C:`, a root directory component, and a normal component
 //! `windows`.
 //!
-//! * Empty components, a special case for so-called "verbatim" paths where very
-//! little normalization is allowed. For example, `\\?\C:\` has a "verbatim"
-//! prefix `\\?\C:`, a root component, and an empty component (as a way of
-//! representing the trailing `\`. Such a trailing `\` is in fact the only
-//! situation in which an empty component is produced.
-//!
 //! ### Normalization
 //!
 //! Aside from splitting on the separator(s), there is a small amount of
 //! * Repeated separators are ignored: `a/b` and `a//b` both have components `a`
 //!   and `b`.
 //!
-//! * Paths ending in a separator are treated as if they has a current directory
-//!   component at the end (or, in verbatim paths, an empty component).  For
-//!   example, while `a/b` has components `a` and `b`, the paths `a/b/` and
-//!   `a/b/.` both have components `a`, `b`, and `.` (current directory).  The
-//!   reason for this normalization is that `a/b` and `a/b/` are treated
-//!   differently in some contexts, but `a/b/` and `a/b/.` are always treated
-//!   the same.
+//! * Occurrences of `.` are normalized away, *except* if they are at
+//! the beginning of the path (in which case they are often meaningful
+//! in terms of path searching). So, for example, `a/./b`, `a/b/`,
+//! `/a/b/.` and `a/b` all have components `a` and `b`, but `./a/b`
+//! has a leading current directory component.
 //!
-//! No other normalization takes place by default. In particular, `a/./b/` and
-//! `a/b` are treated distinctly in terms of components, as are `a/c` and
-//! `a/b/../c`. Further normalization is possible to build on top of the
-//! components APIs, and will be included in this library very soon.
+//! No other normalization takes place by default. In particular,
+//! `a/c` and `a/b/../c` are distinct, to account for the possibility
+//! that `b` is a symbolic link (so its parent isn't `a`). Further
+//! normalization is possible to build on top of the components APIs,
+//! and will be included in this library in the near future.
 
-#![unstable(feature = "path")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
 use core::prelude::*;
 
 use ascii::*;
-use borrow::{Borrow, ToOwned, Cow};
+use borrow::{Borrow, IntoCow, ToOwned, Cow};
 use cmp;
 use iter::{self, IntoIterator};
 use mem;
 use ops::{self, Deref};
+use string::String;
 use vec::Vec;
 use fmt;
 
@@ -166,7 +160,6 @@ mod platform {
     use core::prelude::*;
     use ascii::*;
 
-    use char::CharExt as UnicodeCharExt;
     use super::{os_str_as_u8_slice, u8_slice_as_os_str, Prefix};
     use ffi::OsStr;
 
@@ -270,23 +263,30 @@ mod platform {
 /// `/` is *not* treated as a separator and essentially no normalization is
 /// performed.
 #[derive(Copy, Clone, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub enum Prefix<'a> {
     /// Prefix `\\?\`, together with the given component immediately following it.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Verbatim(&'a OsStr),
 
     /// Prefix `\\?\UNC\`, with the "server" and "share" components following it.
+    #[stable(feature = "rust1", since = "1.0.0")]
     VerbatimUNC(&'a OsStr, &'a OsStr),
 
     /// Prefix like `\\?\C:\`, for the given drive letter
+    #[stable(feature = "rust1", since = "1.0.0")]
     VerbatimDisk(u8),
 
     /// Prefix `\\.\`, together with the given component immediately following it.
+    #[stable(feature = "rust1", since = "1.0.0")]
     DeviceNS(&'a OsStr),
 
     /// Prefix `\\server\share`, with the given "server" and "share" components.
+    #[stable(feature = "rust1", since = "1.0.0")]
     UNC(&'a OsStr, &'a OsStr),
 
     /// Prefix `C:` for the given disk drive.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Disk(u8),
 }
 
@@ -314,6 +314,7 @@ impl<'a> Prefix<'a> {
 
     /// Determine if the prefix is verbatim, i.e. begins `\\?\`.
     #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_verbatim(&self) -> bool {
         use self::Prefix::*;
         match *self {
@@ -342,12 +343,23 @@ impl<'a> Prefix<'a> {
 
 /// Determine whether the character is one of the permitted path
 /// separators for the current platform.
+///
+/// # Examples
+///
+/// ```
+/// use std::path;
+///
+/// assert!(path::is_separator('/'));
+/// assert!(!path::is_separator('❤'));
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn is_separator(c: char) -> bool {
     use ascii::*;
     c.is_ascii() && is_sep_byte(c as u8)
 }
 
 /// The primary sperator for the current platform
+#[stable(feature = "rust1", since = "1.0.0")]
 pub const MAIN_SEPARATOR: char = platform::MAIN_SEP;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -383,37 +395,15 @@ unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// Cross-platform parsing
+// Cross-platform, iterator-independent parsing
 ////////////////////////////////////////////////////////////////////////////////
 
-/// Says whether the path ends in a separator character and therefore needs to
-/// be treated as if it ended with an additional `.`
-fn has_suffix(s: &[u8], prefix: Option<Prefix>) -> bool {
-    let (prefix_len, verbatim) = if let Some(p) = prefix {
-        (p.len(), p.is_verbatim())
-    } else { (0, false) };
-    if prefix_len > 0 && prefix_len == s.len() && !verbatim { return true; }
-    let mut splits = s[prefix_len..].split(|b| is_sep_byte(*b));
-    let last = splits.next_back().unwrap();
-    let more = splits.next_back().is_some();
-    more && last == b""
-}
-
 /// Says whether the first byte after the prefix is a separator.
 fn has_physical_root(s: &[u8], prefix: Option<Prefix>) -> bool {
     let path = if let Some(p) = prefix { &s[p.len()..] } else { s };
     path.len() > 0 && is_sep_byte(path[0])
 }
 
-fn parse_single_component(comp: &[u8]) -> Option<Component> {
-    match comp {
-        b"." => Some(Component::CurDir),
-        b".." => Some(Component::ParentDir),
-        b"" => None,
-        _ => Some(Component::Normal(unsafe { u8_slice_as_os_str(comp) }))
-    }
-}
-
 // basic workhorse for splitting stem and extension
 #[allow(unused_unsafe)] // FIXME
 fn split_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
@@ -425,7 +415,7 @@ fn split_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
         // contents of the encoding and (2) new &OsStr values are produced
         // only from ASCII-bounded slices of existing &OsStr values.
 
-        let mut iter = os_str_as_u8_slice(file).rsplitn(1, |b| *b == b'.');
+        let mut iter = os_str_as_u8_slice(file).rsplitn(2, |b| *b == b'.');
         let after = iter.next();
         let before = iter.next();
         if before == Some(b"") {
@@ -445,16 +435,62 @@ fn split_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
 /// front and back of the path each keep track of what parts of the path have
 /// been consumed so far.
 ///
-/// Going front to back, a path is made up of a prefix, a root component, a body
-/// (of normal components), and a suffix/emptycomponent (normalized `.` or ``
-/// for a path ending with the separator)
+/// Going front to back, a path is made up of a prefix, a starting
+/// directory component, and a body (of normal components)
 #[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
 enum State {
     Prefix = 0,         // c:
-    Root = 1,           // /
+    StartDir = 1,       // / or . or nothing
     Body = 2,           // foo/bar/baz
-    Suffix = 3,         // .
-    Done = 4,
+    Done = 3,
+}
+
+/// A Windows path prefix, e.g. `C:` or `\server\share`.
+///
+/// Does not occur on Unix.
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Copy, Clone, Eq, Hash, Debug)]
+pub struct PrefixComponent<'a> {
+    /// The prefix as an unparsed `OsStr` slice.
+    raw: &'a OsStr,
+
+    /// The parsed prefix data.
+    parsed: Prefix<'a>,
+}
+
+impl<'a> PrefixComponent<'a> {
+    /// The parsed prefix data.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn kind(&self) -> Prefix<'a> {
+        self.parsed
+    }
+
+    /// The raw `OsStr` slice for this prefix.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn as_os_str(&self) -> &'a OsStr {
+        self.raw
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> cmp::PartialEq for PrefixComponent<'a> {
+    fn eq(&self, other: &PrefixComponent<'a>) -> bool {
+        cmp::PartialEq::eq(&self.parsed, &other.parsed)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> cmp::PartialOrd for PrefixComponent<'a> {
+    fn partial_cmp(&self, other: &PrefixComponent<'a>) -> Option<cmp::Ordering> {
+        cmp::PartialOrd::partial_cmp(&self.parsed, &other.parsed)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> cmp::Ord for PrefixComponent<'a> {
+    fn cmp(&self, other: &PrefixComponent<'a>) -> cmp::Ordering {
+        cmp::Ord::cmp(&self.parsed, &other.parsed)
+    }
 }
 
 /// A single component of a path.
@@ -462,55 +498,70 @@ enum State {
 /// See the module documentation for an in-depth explanation of components and
 /// their role in the API.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub enum Component<'a> {
     /// A Windows path prefix, e.g. `C:` or `\server\share`.
     ///
     /// Does not occur on Unix.
-    Prefix {
-        /// The prefix as an unparsed `OsStr` slice.
-        raw: &'a OsStr,
-
-        /// The parsed prefix data.
-        parsed: Prefix<'a>
-    },
-
-    /// An empty component. Only used on Windows for the last component of
-    /// verbatim paths ending with a separator (e.g. the last component of
-    /// `\\?\C:\windows\` but not `\\?\C:\windows` or `C:\windows`).
-    Empty,
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Prefix(PrefixComponent<'a>),
 
     /// The root directory component, appears after any prefix and before anything else
+    #[stable(feature = "rust1", since = "1.0.0")]
     RootDir,
 
     /// A reference to the current directory, i.e. `.`
+    #[stable(feature = "rust1", since = "1.0.0")]
     CurDir,
 
     /// A reference to the parent directory, i.e. `..`
+    #[stable(feature = "rust1", since = "1.0.0")]
     ParentDir,
 
     /// A normal component, i.e. `a` and `b` in `a/b`
+    #[stable(feature = "rust1", since = "1.0.0")]
     Normal(&'a OsStr),
 }
 
 impl<'a> Component<'a> {
     /// Extract the underlying `OsStr` slice
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_os_str(self) -> &'a OsStr {
         match self {
-            Component::Prefix { raw, .. } => &raw,
-            Component::Empty => OsStr::from_str(""),
-            Component::RootDir => OsStr::from_str(MAIN_SEP_STR),
-            Component::CurDir => OsStr::from_str("."),
-            Component::ParentDir => OsStr::from_str(".."),
+            Component::Prefix(p) => p.as_os_str(),
+            Component::RootDir => OsStr::new(MAIN_SEP_STR),
+            Component::CurDir => OsStr::new("."),
+            Component::ParentDir => OsStr::new(".."),
             Component::Normal(path) => path,
         }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> AsRef<OsStr> for Component<'a> {
+    fn as_ref(&self) -> &OsStr {
+        self.as_os_str()
+    }
+}
+
 /// The core iterator giving the components of a path.
 ///
 /// See the module documentation for an in-depth explanation of components and
 /// their role in the API.
+///
+/// # Examples
+///
+/// ```
+/// use std::path::Path;
+///
+/// let path = Path::new("/tmp/foo/bar.txt");
+///
+/// for component in path.components() {
+///     println!("{:?}", component);
+/// }
+/// ```
 #[derive(Clone)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Components<'a> {
     // The path left to parse components from
     path: &'a [u8],
@@ -531,6 +582,7 @@ pub struct Components<'a> {
 
 /// An iterator over the components of a path, as `OsStr` slices.
 #[derive(Clone)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a> {
     inner: Components<'a>
 }
@@ -554,9 +606,12 @@ impl<'a> Components<'a> {
         else { 0 }
     }
 
-    fn prefix_and_root(&self) -> usize {
-        let root = if self.front <= State::Root && self.has_physical_root { 1 } else { 0 };
-        self.prefix_remaining() + root
+    // Given the iteration so far, how much of the pre-State::Body path is left?
+    #[inline]
+    fn len_before_body(&self) -> usize {
+        let root = if self.front <= State::StartDir && self.has_physical_root { 1 } else { 0 };
+        let cur_dir = if self.front <= State::StartDir && self.include_cur_dir() { 1 } else { 0 };
+        self.prefix_remaining() + root + cur_dir
     }
 
     // is the iteration complete?
@@ -575,15 +630,22 @@ impl<'a> Components<'a> {
     }
 
     /// Extract a slice corresponding to the portion of the path remaining for iteration.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp/foo/bar.txt");
+    ///
+    /// println!("{:?}", path.components().as_path());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_path(&self) -> &'a Path {
         let mut comps = self.clone();
         if comps.front == State::Body { comps.trim_left(); }
         if comps.back == State::Body { comps.trim_right(); }
-        if comps.path.is_empty() && comps.front < comps.back && comps.back == State::Suffix {
-            Path::new(".")
-        } else {
-            unsafe { Path::from_u8_slice(comps.path) }
-        }
+        unsafe { Path::from_u8_slice(comps.path) }
     }
 
     /// Is the *original* path rooted?
@@ -595,6 +657,30 @@ impl<'a> Components<'a> {
         false
     }
 
+    /// Should the normalized path include a leading . ?
+    fn include_cur_dir(&self) -> bool {
+        if self.has_root() { return false }
+        let mut iter = self.path[self.prefix_len()..].iter();
+        match (iter.next(), iter.next()) {
+            (Some(&b'.'), None) => true,
+            (Some(&b'.'), Some(&b)) => self.is_sep_byte(b),
+            _ => false
+        }
+    }
+
+    // parse a given byte sequence into the corresponding path component
+    fn parse_single_component<'b>(&self, comp: &'b [u8]) -> Option<Component<'b>> {
+        match comp {
+            b"." if self.prefix_verbatim() => Some(Component::CurDir),
+            b"." => None, // . components are normalized away, except at
+                          // the beginning of a path, which is treated
+                          // separately via `include_cur_dir`
+            b".." => Some(Component::ParentDir),
+            b"" => None,
+            _ => Some(Component::Normal(unsafe { u8_slice_as_os_str(comp) }))
+        }
+    }
+
     // parse a component from the left, saying how many bytes to consume to
     // remove the component
     fn parse_next_component(&self) -> (usize, Option<Component<'a>>) {
@@ -603,19 +689,19 @@ impl<'a> Components<'a> {
             None => (0, self.path),
             Some(i) => (1, &self.path[.. i]),
         };
-        (comp.len() + extra, parse_single_component(comp))
+        (comp.len() + extra, self.parse_single_component(comp))
     }
 
     // parse a component from the right, saying how many bytes to consume to
     // remove the component
     fn parse_next_component_back(&self) -> (usize, Option<Component<'a>>) {
         debug_assert!(self.back == State::Body);
-        let start = self.prefix_and_root();
+        let start = self.len_before_body();
         let (extra, comp) = match self.path[start..].iter().rposition(|b| self.is_sep_byte(*b)) {
             None => (0, &self.path[start ..]),
             Some(i) => (1, &self.path[start + i + 1 ..]),
         };
-        (comp.len() + extra, parse_single_component(comp))
+        (comp.len() + extra, self.parse_single_component(comp))
     }
 
     // trim away repeated separators (i.e. emtpy components) on the left
@@ -632,7 +718,7 @@ impl<'a> Components<'a> {
 
     // trim away repeated separators (i.e. emtpy components) on the right
     fn trim_right(&mut self) {
-        while self.path.len() > self.prefix_and_root() {
+        while self.path.len() > self.len_before_body() {
             let (size, comp) = self.parse_next_component_back();
             if comp.is_some() {
                 return;
@@ -643,18 +729,49 @@ impl<'a> Components<'a> {
     }
 
     /// Examine the next component without consuming it.
+    #[unstable(feature = "path_components_peek")]
     pub fn peek(&self) -> Option<Component<'a>> {
         self.clone().next()
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> AsRef<Path> for Components<'a> {
+    fn as_ref(&self) -> &Path {
+        self.as_path()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> AsRef<OsStr> for Components<'a> {
+    fn as_ref(&self) -> &OsStr {
+        self.as_path().as_os_str()
+    }
+}
+
 impl<'a> Iter<'a> {
     /// Extract a slice corresponding to the portion of the path remaining for iteration.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_path(&self) -> &'a Path {
         self.inner.as_path()
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> AsRef<Path> for Iter<'a> {
+    fn as_ref(&self) -> &Path {
+        self.as_path()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> AsRef<OsStr> for Iter<'a> {
+    fn as_ref(&self) -> &OsStr {
+        self.as_path().as_os_str()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Iterator for Iter<'a> {
     type Item = &'a OsStr;
 
@@ -663,12 +780,14 @@ impl<'a> Iterator for Iter<'a> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> DoubleEndedIterator for Iter<'a> {
     fn next_back(&mut self) -> Option<&'a OsStr> {
         self.inner.next_back().map(Component::as_os_str)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Iterator for Components<'a> {
     type Item = Component<'a>;
 
@@ -676,19 +795,19 @@ impl<'a> Iterator for Components<'a> {
         while !self.finished() {
             match self.front {
                 State::Prefix if self.prefix_len() > 0 => {
-                    self.front = State::Root;
+                    self.front = State::StartDir;
                     debug_assert!(self.prefix_len() <= self.path.len());
                     let raw = &self.path[.. self.prefix_len()];
                     self.path = &self.path[self.prefix_len() .. ];
-                    return Some(Component::Prefix {
+                    return Some(Component::Prefix(PrefixComponent {
                         raw: unsafe { u8_slice_as_os_str(raw) },
                         parsed: self.prefix.unwrap()
-                    })
+                    }))
                 }
                 State::Prefix => {
-                    self.front = State::Root;
+                    self.front = State::StartDir;
                 }
-                State::Root => {
+                State::StartDir => {
                     self.front = State::Body;
                     if self.has_physical_root {
                         debug_assert!(self.path.len() > 0);
@@ -698,6 +817,10 @@ impl<'a> Iterator for Components<'a> {
                         if p.has_implicit_root() && !p.is_verbatim() {
                             return Some(Component::RootDir)
                         }
+                    } else if self.include_cur_dir() {
+                        debug_assert!(self.path.len() > 0);
+                        self.path = &self.path[1..];
+                        return Some(Component::CurDir)
                     }
                 }
                 State::Body if !self.path.is_empty() => {
@@ -706,15 +829,7 @@ impl<'a> Iterator for Components<'a> {
                     if comp.is_some() { return comp }
                 }
                 State::Body => {
-                    self.front = State::Suffix;
-                }
-                State::Suffix => {
                     self.front = State::Done;
-                    if self.prefix_verbatim() {
-                        return Some(Component::Empty)
-                    } else {
-                        return Some(Component::CurDir)
-                    }
                 }
                 State::Done => unreachable!()
             }
@@ -723,27 +838,20 @@ impl<'a> Iterator for Components<'a> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> DoubleEndedIterator for Components<'a> {
     fn next_back(&mut self) -> Option<Component<'a>> {
         while !self.finished() {
             match self.back {
-                State::Suffix => {
-                    self.back = State::Body;
-                    if self.prefix_verbatim() {
-                        return Some(Component::Empty)
-                    } else {
-                        return Some(Component::CurDir)
-                    }
-                }
-                State::Body if self.path.len() > self.prefix_and_root() => {
+                State::Body if self.path.len() > self.len_before_body() => {
                     let (size, comp) = self.parse_next_component_back();
                     self.path = &self.path[.. self.path.len() - size];
                     if comp.is_some() { return comp }
                 }
                 State::Body => {
-                    self.back = State::Root;
+                    self.back = State::StartDir;
                 }
-                State::Root => {
+                State::StartDir => {
                     self.back = State::Prefix;
                     if self.has_physical_root {
                         self.path = &self.path[.. self.path.len() - 1];
@@ -752,14 +860,17 @@ impl<'a> DoubleEndedIterator for Components<'a> {
                         if p.has_implicit_root() && !p.is_verbatim() {
                             return Some(Component::RootDir)
                         }
+                    } else if self.include_cur_dir() {
+                        self.path = &self.path[.. self.path.len() - 1];
+                        return Some(Component::CurDir)
                     }
                 }
                 State::Prefix if self.prefix_len() > 0 => {
                     self.back = State::Done;
-                    return Some(Component::Prefix {
+                    return Some(Component::Prefix(PrefixComponent {
                         raw: unsafe { u8_slice_as_os_str(self.path) },
                         parsed: self.prefix.unwrap()
-                    })
+                    }))
                 }
                 State::Prefix => {
                     self.back = State::Done;
@@ -772,24 +883,24 @@ impl<'a> DoubleEndedIterator for Components<'a> {
     }
 }
 
-fn optional_path(path: &Path) -> Option<&Path> {
-    if path.as_u8_slice().is_empty() { None } else { Some(path) }
-}
-
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> cmp::PartialEq for Components<'a> {
     fn eq(&self, other: &Components<'a>) -> bool {
         iter::order::eq(self.clone(), other.clone())
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> cmp::Eq for Components<'a> {}
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> cmp::PartialOrd for Components<'a> {
     fn partial_cmp(&self, other: &Components<'a>) -> Option<cmp::Ordering> {
         iter::order::partial_cmp(self.clone(), other.clone())
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> cmp::Ord for Components<'a> {
     fn cmp(&self, other: &Components<'a>) -> cmp::Ordering {
         iter::order::cmp(self.clone(), other.clone())
@@ -809,17 +920,18 @@ impl<'a> cmp::Ord for Components<'a> {
 /// More details about the overall approach can be found in
 /// the module documentation.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::path::PathBuf;
 ///
-/// let mut path = PathBuf::new("c:\\");
+/// let mut path = PathBuf::from("c:\\");
 /// path.push("windows");
 /// path.push("system32");
 /// path.set_extension("dll");
 /// ```
 #[derive(Clone, Hash)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct PathBuf {
     inner: OsString
 }
@@ -829,10 +941,16 @@ impl PathBuf {
         unsafe { mem::transmute(self) }
     }
 
-    /// Allocate a `PathBuf` with initial contents given by the
-    /// argument.
-    pub fn new<S: ?Sized + AsOsStr>(s: &S) -> PathBuf {
-        PathBuf { inner: s.as_os_str().to_os_string() }
+    /// Allocate an empty `PathBuf`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new() -> PathBuf {
+        PathBuf { inner: OsString::new() }
+    }
+
+    /// Coerce to a `Path` slice.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn as_path(&self) -> &Path {
+        self
     }
 
     /// Extend `self` with `path`.
@@ -844,7 +962,10 @@ impl PathBuf {
     /// * if `path` has a root but no prefix (e.g. `\windows`), it
     ///   replaces everything except for the prefix (if any) of `self`.
     /// * if `path` has a prefix but no root, it replaces `self.
-    pub fn push<P: ?Sized>(&mut self, path: &P) where P: AsPath {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn push<P: AsRef<Path>>(&mut self, path: P) {
+        let path = path.as_ref();
+
         // in general, a separator is needed if the rightmost byte is not a separator
         let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep_byte(*c)).unwrap_or(false);
 
@@ -859,8 +980,6 @@ impl PathBuf {
             }
         }
 
-        let path = path.as_path();
-
         // absolute `path` replaces `self`
         if path.is_absolute() || path.prefix().is_some() {
             self.as_mut_vec().truncate(0);
@@ -872,16 +991,17 @@ impl PathBuf {
 
         // `path` is a pure relative path
         } else if need_sep {
-            self.inner.push_os_str(OsStr::from_str(MAIN_SEP_STR));
+            self.inner.push(MAIN_SEP_STR);
         }
 
-        self.inner.push_os_str(path.as_os_str());
+        self.inner.push(path);
     }
 
     /// Truncate `self` to `self.parent()`.
     ///
-    /// Returns `false` and does nothing if `self.parent()` is `None`.
+    /// Returns false and does nothing if `self.file_name()` is `None`.
     /// Otherwise, returns `true`.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn pop(&mut self) -> bool {
         match self.parent().map(|p| p.as_u8_slice().len()) {
             Some(len) => {
@@ -899,26 +1019,24 @@ impl PathBuf {
     ///
     /// # Examples
     ///
-    /// ```rust
-    /// use std::path::{Path, PathBuf};
+    /// ```
+    /// use std::path::PathBuf;
     ///
-    /// let mut buf = PathBuf::new("/foo/");
+    /// let mut buf = PathBuf::from("/");
     /// assert!(buf.file_name() == None);
     /// buf.set_file_name("bar");
-    /// assert!(buf == PathBuf::new("/foo/bar"));
+    /// assert!(buf == PathBuf::from("/bar"));
     /// assert!(buf.file_name().is_some());
     /// buf.set_file_name("baz.txt");
-    /// assert!(buf == PathBuf::new("/foo/baz.txt"));
+    /// assert!(buf == PathBuf::from("/baz.txt"));
     /// ```
-    pub fn set_file_name<S: ?Sized>(&mut self, file_name: &S) where S: AsOsStr {
-        if self.file_name().is_some() && !self.pop() {
-            // Given that there is a file name, this is reachable only for
-            // Windows paths like c:file or paths like `foo`, but not `c:\` or
-            // `/`.
-            let prefix_len = self.components().prefix_remaining();
-            self.as_mut_vec().truncate(prefix_len);
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn set_file_name<S: AsRef<OsStr>>(&mut self, file_name: S) {
+        if self.file_name().is_some() {
+            let popped = self.pop();
+            debug_assert!(popped);
         }
-        self.push(file_name.as_os_str());
+        self.push(file_name.as_ref());
     }
 
     /// Updates `self.extension()` to `extension`.
@@ -927,18 +1045,19 @@ impl PathBuf {
     ///
     /// Otherwise, returns `true`; if `self.extension()` is `None`, the extension
     /// is added; otherwise it is replaced.
-    pub fn set_extension<S: ?Sized + AsOsStr>(&mut self, extension: &S) -> bool {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn set_extension<S: AsRef<OsStr>>(&mut self, extension: S) -> bool {
         if self.file_name().is_none() { return false; }
 
         let mut stem = match self.file_stem() {
             Some(stem) => stem.to_os_string(),
-            None => OsString::from_str(""),
+            None => OsString::new(),
         };
 
-        let extension = extension.as_os_str();
+        let extension = extension.as_ref();
         if os_str_as_u8_slice(extension).len() > 0 {
-            stem.push_os_str(OsStr::from_str("."));
-            stem.push_os_str(extension.as_os_str());
+            stem.push(".");
+            stem.push(extension);
         }
         self.set_file_name(&stem);
 
@@ -946,33 +1065,59 @@ impl PathBuf {
     }
 
     /// Consume the `PathBuf`, yielding its internal `OsString` storage
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_os_string(self) -> OsString {
         self.inner
     }
 }
 
-impl<'a, P: ?Sized + 'a> iter::FromIterator<&'a P> for PathBuf where P: AsPath {
-    fn from_iter<I: IntoIterator<Item = &'a P>>(iter: I) -> PathBuf {
-        let mut buf = PathBuf::new("");
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for PathBuf {
+    fn from(s: &'a T) -> PathBuf {
+        PathBuf::from(s.as_ref().to_os_string())
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl From<OsString> for PathBuf {
+    fn from(s: OsString) -> PathBuf {
+        PathBuf { inner: s }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl From<String> for PathBuf {
+    fn from(s: String) -> PathBuf {
+        PathBuf::from(OsString::from(s))
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<P: AsRef<Path>> iter::FromIterator<P> for PathBuf {
+    fn from_iter<I: IntoIterator<Item = P>>(iter: I) -> PathBuf {
+        let mut buf = PathBuf::new();
         buf.extend(iter);
         buf
     }
 }
 
-impl<'a, P: ?Sized + 'a> iter::Extend<&'a P> for PathBuf where P: AsPath {
-    fn extend<I: IntoIterator<Item = &'a P>>(&mut self, iter: I) {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<P: AsRef<Path>> iter::Extend<P> for PathBuf {
+    fn extend<I: IntoIterator<Item = P>>(&mut self, iter: I) {
         for p in iter {
             self.push(p)
         }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Debug for PathBuf {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
         fmt::Debug::fmt(&**self, formatter)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl ops::Deref for PathBuf {
     type Target = Path;
 
@@ -981,43 +1126,79 @@ impl ops::Deref for PathBuf {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Borrow<Path> for PathBuf {
     fn borrow(&self) -> &Path {
         self.deref()
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl IntoCow<'static, Path> for PathBuf {
+    fn into_cow(self) -> Cow<'static, Path> {
+        Cow::Owned(self)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> IntoCow<'a, Path> for &'a Path {
+    fn into_cow(self) -> Cow<'a, Path> {
+        Cow::Borrowed(self)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl ToOwned for Path {
     type Owned = PathBuf;
     fn to_owned(&self) -> PathBuf { self.to_path_buf() }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl cmp::PartialEq for PathBuf {
     fn eq(&self, other: &PathBuf) -> bool {
         self.components() == other.components()
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl cmp::Eq for PathBuf {}
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl cmp::PartialOrd for PathBuf {
     fn partial_cmp(&self, other: &PathBuf) -> Option<cmp::Ordering> {
         self.components().partial_cmp(&other.components())
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl cmp::Ord for PathBuf {
     fn cmp(&self, other: &PathBuf) -> cmp::Ordering {
         self.components().cmp(&other.components())
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<OsStr> for PathBuf {
+    fn as_ref(&self) -> &OsStr {
+        &self.inner[..]
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
 impl AsOsStr for PathBuf {
     fn as_os_str(&self) -> &OsStr {
         &self.inner[..]
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Into<OsString> for PathBuf {
+    fn into(self) -> OsString {
+        self.inner
+    }
+}
+
 /// A slice of a path (akin to `str`).
 ///
 /// This type supports a number of operations for inspecting a path, including
@@ -1029,9 +1210,9 @@ impl AsOsStr for PathBuf {
 /// This is an *unsized* type, meaning that it must always be used with behind a
 /// pointer like `&` or `Box`.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::path::Path;
 ///
 /// let path = Path::new("/tmp/foo/bar.txt");
@@ -1041,6 +1222,7 @@ impl AsOsStr for PathBuf {
 /// ```
 ///
 #[derive(Hash)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Path {
     inner: OsStr
 }
@@ -1059,13 +1241,45 @@ impl Path {
     /// Directly wrap a string slice as a `Path` slice.
     ///
     /// This is a cost-free conversion.
-    pub fn new<S: ?Sized + AsOsStr>(s: &S) -> &Path {
-        unsafe { mem::transmute(s.as_os_str()) }
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// Path::new("foo.txt");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &Path {
+        unsafe { mem::transmute(s.as_ref()) }
+    }
+
+    /// Yield the underlying `OsStr` slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let os_str = Path::new("foo.txt").as_os_str();
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn as_os_str(&self) -> &OsStr {
+        &self.inner
     }
 
     /// Yield a `&str` slice if the `Path` is valid unicode.
     ///
     /// This conversion may entail doing a check for UTF-8 validity.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path_str = Path::new("foo.txt").to_str();
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_str(&self) -> Option<&str> {
         self.inner.to_str()
     }
@@ -1073,13 +1287,31 @@ impl Path {
     /// Convert a `Path` to a `Cow<str>`.
     ///
     /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path_str = Path::new("foo.txt").to_string_lossy();
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_string_lossy(&self) -> Cow<str> {
         self.inner.to_string_lossy()
     }
 
     /// Convert a `Path` to an owned `PathBuf`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path_str = Path::new("foo.txt").to_path_buf();
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_path_buf(&self) -> PathBuf {
-        PathBuf::new(self)
+        PathBuf::from(self.inner.to_os_string())
     }
 
     /// A path is *absolute* if it is independent of the current directory.
@@ -1090,12 +1322,30 @@ impl Path {
     /// * On Windows, a path is absolute if it has a prefix and starts with the
     /// root: `c:\windows` is absolute, while `c:temp` and `\temp` are not. In
     /// other words, `path.is_absolute() == path.prefix().is_some() && path.has_root()`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// assert_eq!(false, Path::new("foo.txt").is_absolute());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_absolute(&self) -> bool {
         self.has_root() &&
             (cfg!(unix) || self.prefix().is_some())
     }
 
     /// A path is *relative* if it is not absolute.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// assert!(Path::new("foo.txt").is_relative());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_relative(&self) -> bool {
         !self.is_absolute()
     }
@@ -1105,12 +1355,9 @@ impl Path {
     /// Prefixes are relevant only for Windows paths, and consist of volumes
     /// like `C:`, UNC prefixes like `\\server`, and others described in more
     /// detail in `std::os::windows::PathExt`.
-    pub fn prefix(&self) -> Option<&Path> {
-        let iter = self.components();
-        optional_path(unsafe {
-            Path::from_u8_slice(
-                &self.as_u8_slice()[.. iter.prefix_remaining()])
-        })
+    #[unstable(feature = "path_prefix", reason = "uncertain whether to expose this convenience")]
+    pub fn prefix(&self) -> Option<Prefix> {
+        self.components().prefix
     }
 
     /// A path has a root if the body of the path begins with the directory separator.
@@ -1121,69 +1368,113 @@ impl Path {
     ///     * has no prefix and begins with a separator, e.g. `\\windows`
     ///     * has a prefix followed by a separator, e.g. `c:\windows` but not `c:windows`
     ///     * has any non-disk prefix, e.g. `\\server\share`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// assert!(Path::new("/etc/passwd").has_root());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn has_root(&self) -> bool {
          self.components().has_root()
     }
 
-    /// The path without its final component.
+    /// The path without its final component, if any.
     ///
-    /// Does nothing, returning `None` if the path consists of just a prefix
-    /// and/or root directory reference.
+    /// Returns `None` if the path terminates in a root or prefix.
     ///
     /// # Examples
     ///
-    /// ```rust
+    /// ```
     /// use std::path::Path;
     ///
     /// let path = Path::new("/foo/bar");
     /// let foo = path.parent().unwrap();
+    ///
     /// assert!(foo == Path::new("/foo"));
+    ///
     /// let root = foo.parent().unwrap();
+    ///
     /// assert!(root == Path::new("/"));
     /// assert!(root.parent() == None);
     /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn parent(&self) -> Option<&Path> {
         let mut comps = self.components();
         let comp = comps.next_back();
-        let rest = optional_path(comps.as_path());
-
-        match (comp, comps.next_back()) {
-            (Some(Component::CurDir), Some(Component::RootDir)) => None,
-            (Some(Component::CurDir), Some(Component::Prefix { .. })) => None,
-            (Some(Component::Empty), Some(Component::RootDir)) => None,
-            (Some(Component::Empty), Some(Component::Prefix { .. })) => None,
-            (Some(Component::Prefix { .. }), None) => None,
-            (Some(Component::RootDir), Some(Component::Prefix { .. })) => None,
-            _ => rest
-        }
+        comp.and_then(|p| match p {
+            Component::Normal(_) |
+            Component::CurDir |
+            Component::ParentDir => Some(comps.as_path()),
+            _ => None
+        })
     }
 
     /// The final component of the path, if it is a normal file.
     ///
     /// If the path terminates in `.`, `..`, or consists solely or a root of
-    /// prefix, `file` will return `None`.
+    /// prefix, `file_name` will return `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("hello_world.rs");
+    /// let filename = "hello_world.rs";
+    ///
+    /// assert_eq!(filename, path.file_name().unwrap());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn file_name(&self) -> Option<&OsStr> {
         self.components().next_back().and_then(|p| match p {
-            Component::Normal(p) => Some(p.as_os_str()),
+            Component::Normal(p) => Some(p.as_ref()),
             _ => None
         })
     }
 
     /// Returns a path that, when joined onto `base`, yields `self`.
-    pub fn relative_from<'a, P: ?Sized>(&'a self, base: &'a P) -> Option<&Path> where
-        P: AsPath
+    ///
+    /// If `base` is not a prefix of `self` (i.e. `starts_with`
+    /// returns false), then `relative_from` returns `None`.
+    #[unstable(feature = "path_relative_from", reason = "see #23284")]
+    pub fn relative_from<'a, P: ?Sized + AsRef<Path>>(&'a self, base: &'a P) -> Option<&Path>
     {
-        iter_after(self.components(), base.as_path().components()).map(|c| c.as_path())
+        iter_after(self.components(), base.as_ref().components()).map(|c| c.as_path())
     }
 
     /// Determines whether `base` is a prefix of `self`.
-    pub fn starts_with<P: ?Sized>(&self, base: &P) -> bool where P: AsPath {
-        iter_after(self.components(), base.as_path().components()).is_some()
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/etc/passwd");
+    ///
+    /// assert!(path.starts_with("/etc"));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn starts_with<P: AsRef<Path>>(&self, base: P) -> bool {
+        iter_after(self.components(), base.as_ref().components()).is_some()
     }
 
-    /// Determines whether `base` is a suffix of `self`.
-    pub fn ends_with<P: ?Sized>(&self, child: &P) -> bool where P: AsPath {
-        iter_after(self.components().rev(), child.as_path().components().rev()).is_some()
+    /// Determines whether `child` is a suffix of `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/etc/passwd");
+    ///
+    /// assert!(path.ends_with("passwd"));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn ends_with<P: AsRef<Path>>(&self, child: P) -> bool {
+        iter_after(self.components().rev(), child.as_ref().components().rev()).is_some()
     }
 
     /// Extract the stem (non-extension) portion of `self.file()`.
@@ -1194,6 +1485,17 @@ impl Path {
     /// * The entire file name if there is no embedded `.`;
     /// * The entire file name if the file name begins with `.` and has no other `.`s within;
     /// * Otherwise, the portion of the file name before the final `.`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("foo.rs");
+    ///
+    /// assert_eq!("foo", path.file_stem().unwrap());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn file_stem(&self) -> Option<&OsStr> {
         self.file_name().map(split_file_at_dot).and_then(|(before, after)| before.or(after))
     }
@@ -1206,6 +1508,17 @@ impl Path {
     /// * None, if there is no embedded `.`;
     /// * None, if the file name begins with `.` and has no other `.`s within;
     /// * Otherwise, the portion of the file name after the final `.`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("foo.rs");
+    ///
+    /// assert_eq!("rs", path.extension().unwrap());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn extension(&self) -> Option<&OsStr> {
         self.file_name().map(split_file_at_dot).and_then(|(before, after)| before.and(after))
     }
@@ -1213,7 +1526,18 @@ impl Path {
     /// Creates an owned `PathBuf` with `path` adjoined to `self`.
     ///
     /// See `PathBuf::push` for more details on what it means to adjoin a path.
-    pub fn join<P: ?Sized>(&self, path: &P) -> PathBuf where P: AsPath {
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp");
+    ///
+    /// let new_path = path.join("foo");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn join<P: AsRef<Path>>(&self, path: P) -> PathBuf {
         let mut buf = self.to_path_buf();
         buf.push(path);
         buf
@@ -1222,7 +1546,18 @@ impl Path {
     /// Creates an owned `PathBuf` like `self` but with the given file name.
     ///
     /// See `PathBuf::set_file_name` for more details.
-    pub fn with_file_name<S: ?Sized>(&self, file_name: &S) -> PathBuf where S: AsOsStr {
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp/foo.rs");
+    ///
+    /// let new_path = path.with_file_name("bar.rs");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn with_file_name<S: AsRef<OsStr>>(&self, file_name: S) -> PathBuf {
         let mut buf = self.to_path_buf();
         buf.set_file_name(file_name);
         buf
@@ -1231,13 +1566,37 @@ impl Path {
     /// Creates an owned `PathBuf` like `self` but with the given extension.
     ///
     /// See `PathBuf::set_extension` for more details.
-    pub fn with_extension<S: ?Sized>(&self, extension: &S) -> PathBuf where S: AsOsStr {
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp/foo.rs");
+    ///
+    /// let new_path = path.with_extension("foo.txt");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn with_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
         let mut buf = self.to_path_buf();
         buf.set_extension(extension);
         buf
     }
 
     /// Produce an iterator over the components of the path.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp/foo.rs");
+    ///
+    /// for component in path.components() {
+    ///     println!("{:?}", component);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn components(&self) -> Components {
         let prefix = parse_prefix(self.as_os_str());
         Components {
@@ -1245,29 +1604,62 @@ impl Path {
             prefix: prefix,
             has_physical_root: has_physical_root(self.as_u8_slice(), prefix),
             front: State::Prefix,
-            back: if has_suffix(self.as_u8_slice(), prefix) { State::Suffix }
-                  else { State::Body },
+            back: State::Body,
         }
     }
 
     /// Produce an iterator over the path's components viewed as `OsStr` slices.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp/foo.rs");
+    ///
+    /// for component in path.iter() {
+    ///     println!("{:?}", component);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter(&self) -> Iter {
         Iter { inner: self.components() }
     }
 
     /// Returns an object that implements `Display` for safely printing paths
     /// that may contain non-Unicode data.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let path = Path::new("/tmp/foo.rs");
+    ///
+    /// println!("{}", path.display());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn display(&self) -> Display {
         Display { path: self }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<OsStr> for Path {
+    fn as_ref(&self) -> &OsStr {
+        &self.inner
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
 impl AsOsStr for Path {
     fn as_os_str(&self) -> &OsStr {
         &self.inner
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Debug for Path {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
         self.inner.fmt(formatter)
@@ -1275,36 +1667,43 @@ impl fmt::Debug for Path {
 }
 
 /// Helper struct for safely printing paths with `format!()` and `{}`
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Display<'a> {
     path: &'a Path
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> fmt::Debug for Display<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Debug::fmt(&self.path.to_string_lossy(), f)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> fmt::Display for Display<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(&self.path.to_string_lossy(), f)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl cmp::PartialEq for Path {
     fn eq(&self, other: &Path) -> bool {
         iter::order::eq(self.components(), other.components())
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl cmp::Eq for Path {}
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl cmp::PartialOrd for Path {
     fn partial_cmp(&self, other: &Path) -> Option<cmp::Ordering> {
         self.components().partial_cmp(&other.components())
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl cmp::Ord for Path {
     fn cmp(&self, other: &Path) -> cmp::Ordering {
         self.components().cmp(&other.components())
@@ -1312,19 +1711,54 @@ impl cmp::Ord for Path {
 }
 
 /// Freely convertible to a `Path`.
+#[unstable(feature = "std_misc")]
+#[deprecated(since = "1.0.0", reason = "use std::convert::AsRef<Path> instead")]
 pub trait AsPath {
     /// Convert to a `Path`.
+    #[unstable(feature = "std_misc")]
     fn as_path(&self) -> &Path;
 }
 
+#[unstable(feature = "std_misc")]
+#[deprecated(since = "1.0.0", reason = "use std::convert::AsRef<Path> instead")]
+#[allow(deprecated)]
 impl<T: AsOsStr + ?Sized> AsPath for T {
     fn as_path(&self) -> &Path { Path::new(self.as_os_str()) }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<Path> for Path {
+    fn as_ref(&self) -> &Path { self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<Path> for OsStr {
+    fn as_ref(&self) -> &Path { Path::new(self) }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<Path> for OsString {
+    fn as_ref(&self) -> &Path { Path::new(self) }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<Path> for str {
+    fn as_ref(&self) -> &Path { Path::new(self) }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<Path> for String {
+    fn as_ref(&self) -> &Path { Path::new(self) }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRef<Path> for PathBuf {
+    fn as_ref(&self) -> &Path { self }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
-    use ffi::OsStr;
     use core::prelude::*;
     use string::{ToString, String};
     use vec::Vec;
@@ -1412,6 +1846,26 @@ mod tests {
         );
     );
 
+    #[test]
+    fn into_cow() {
+        use borrow::{Cow, IntoCow};
+
+        let static_path = Path::new("/home/foo");
+        let static_cow_path: Cow<'static, Path> = static_path.into_cow();
+        let pathbuf = PathBuf::from("/home/foo");
+
+        {
+            let path: &Path = &pathbuf;
+            let borrowed_cow_path: Cow<Path> = path.into_cow();
+
+            assert_eq!(static_cow_path, borrowed_cow_path);
+        }
+
+        let owned_cow_path: Cow<'static, Path> = pathbuf.into_cow();
+
+        assert_eq!(static_cow_path, owned_cow_path);
+    }
+
     #[test]
     #[cfg(unix)]
     pub fn test_decompositions_unix() {
@@ -1429,14 +1883,14 @@ mod tests {
            iter: ["foo"],
            has_root: false,
            is_absolute: false,
-           parent: None,
+           parent: Some(""),
            file_name: Some("foo"),
            file_stem: Some("foo"),
            extension: None
            );
 
         t!("/",
-           iter: ["/", "."],
+           iter: ["/"],
            has_root: true,
            is_absolute: true,
            parent: None,
@@ -1456,22 +1910,22 @@ mod tests {
            );
 
         t!("foo/",
-           iter: ["foo", "."],
+           iter: ["foo"],
            has_root: false,
            is_absolute: false,
-           parent: Some("foo"),
-           file_name: None,
-           file_stem: None,
+           parent: Some(""),
+           file_name: Some("foo"),
+           file_stem: Some("foo"),
            extension: None
            );
 
         t!("/foo/",
-           iter: ["/", "foo", "."],
+           iter: ["/", "foo"],
            has_root: true,
            is_absolute: true,
-           parent: Some("/foo"),
-           file_name: None,
-           file_stem: None,
+           parent: Some("/"),
+           file_name: Some("foo"),
+           file_stem: Some("foo"),
            extension: None
            );
 
@@ -1496,12 +1950,12 @@ mod tests {
            );
 
         t!("///foo///",
-           iter: ["/", "foo", "."],
+           iter: ["/", "foo"],
            has_root: true,
            is_absolute: true,
-           parent: Some("///foo"),
-           file_name: None,
-           file_stem: None,
+           parent: Some("/"),
+           file_name: Some("foo"),
+           file_stem: Some("foo"),
            extension: None
            );
 
@@ -1516,20 +1970,10 @@ mod tests {
            );
 
         t!("./.",
-           iter: [".", "."],
-           has_root: false,
-           is_absolute: false,
-           parent: Some("."),
-           file_name: None,
-           file_stem: None,
-           extension: None
-           );
-
-        t!("./.",
-           iter: [".", "."],
+           iter: ["."],
            has_root: false,
            is_absolute: false,
-           parent: Some("."),
+           parent: Some(""),
            file_name: None,
            file_stem: None,
            extension: None
@@ -1546,22 +1990,22 @@ mod tests {
            );
 
         t!("../",
-           iter: ["..", "."],
+           iter: [".."],
            has_root: false,
            is_absolute: false,
-           parent: Some(".."),
+           parent: Some(""),
            file_name: None,
            file_stem: None,
            extension: None
            );
 
         t!("foo/.",
-           iter: ["foo", "."],
+           iter: ["foo"],
            has_root: false,
            is_absolute: false,
-           parent: Some("foo"),
-           file_name: None,
-           file_stem: None,
+           parent: Some(""),
+           file_name: Some("foo"),
+           file_stem: Some("foo"),
            extension: None
            );
 
@@ -1576,30 +2020,30 @@ mod tests {
            );
 
         t!("foo/./",
-           iter: ["foo", ".", "."],
+           iter: ["foo"],
            has_root: false,
            is_absolute: false,
-           parent: Some("foo/."),
-           file_name: None,
-           file_stem: None,
+           parent: Some(""),
+           file_name: Some("foo"),
+           file_stem: Some("foo"),
            extension: None
            );
 
         t!("foo/./bar",
-           iter: ["foo", ".", "bar"],
+           iter: ["foo", "bar"],
            has_root: false,
            is_absolute: false,
-           parent: Some("foo/."),
+           parent: Some("foo"),
            file_name: Some("bar"),
            file_stem: Some("bar"),
            extension: None
            );
 
         t!("foo/../",
-           iter: ["foo", "..", "."],
+           iter: ["foo", ".."],
            has_root: false,
            is_absolute: false,
-           parent: Some("foo/.."),
+           parent: Some("foo"),
            file_name: None,
            file_stem: None,
            extension: None
@@ -1629,17 +2073,17 @@ mod tests {
            iter: ["."],
            has_root: false,
            is_absolute: false,
-           parent: None,
+           parent: Some(""),
            file_name: None,
            file_stem: None,
            extension: None
            );
 
         t!("./",
-           iter: [".", "."],
+           iter: ["."],
            has_root: false,
            is_absolute: false,
-           parent: Some("."),
+           parent: Some(""),
            file_name: None,
            file_stem: None,
            extension: None
@@ -1666,10 +2110,10 @@ mod tests {
            );
 
         t!("a/./b",
-           iter: ["a", ".", "b"],
+           iter: ["a", "b"],
            has_root: false,
            is_absolute: false,
-           parent: Some("a/."),
+           parent: Some("a"),
            file_name: Some("b"),
            file_stem: Some("b"),
            extension: None
@@ -1684,6 +2128,16 @@ mod tests {
            file_stem: Some("c"),
            extension: None
            );
+
+        t!(".foo",
+           iter: [".foo"],
+           has_root: false,
+           is_absolute: false,
+           parent: Some(""),
+           file_name: Some(".foo"),
+           file_stem: Some(".foo"),
+           extension: None
+           );
     }
 
     #[test]
@@ -1703,14 +2157,14 @@ mod tests {
            iter: ["foo"],
            has_root: false,
            is_absolute: false,
-           parent: None,
+           parent: Some(""),
            file_name: Some("foo"),
            file_stem: Some("foo"),
            extension: None
            );
 
         t!("/",
-           iter: ["\\", "."],
+           iter: ["\\"],
            has_root: true,
            is_absolute: false,
            parent: None,
@@ -1720,7 +2174,7 @@ mod tests {
            );
 
         t!("\\",
-           iter: ["\\", "."],
+           iter: ["\\"],
            has_root: true,
            is_absolute: false,
            parent: None,
@@ -1730,7 +2184,7 @@ mod tests {
            );
 
         t!("c:",
-           iter: ["c:", "."],
+           iter: ["c:"],
            has_root: false,
            is_absolute: false,
            parent: None,
@@ -1740,17 +2194,7 @@ mod tests {
            );
 
         t!("c:\\",
-           iter: ["c:", "\\", "."],
-           has_root: true,
-           is_absolute: true,
-           parent: None,
-           file_name: None,
-           file_stem: None,
-           extension: None
-           );
-
-        t!("c:\\",
-           iter: ["c:", "\\", "."],
+           iter: ["c:", "\\"],
            has_root: true,
            is_absolute: true,
            parent: None,
@@ -1760,7 +2204,7 @@ mod tests {
            );
 
         t!("c:/",
-           iter: ["c:", "\\", "."],
+           iter: ["c:", "\\"],
            has_root: true,
            is_absolute: true,
            parent: None,
@@ -1780,22 +2224,22 @@ mod tests {
            );
 
         t!("foo/",
-           iter: ["foo", "."],
+           iter: ["foo"],
            has_root: false,
            is_absolute: false,
-           parent: Some("foo"),
-           file_name: None,
-           file_stem: None,
+           parent: Some(""),
+           file_name: Some("foo"),
+           file_stem: Some("foo"),
            extension: None
            );
 
         t!("/foo/",
-           iter: ["\\", "foo", "."],
+           iter: ["\\", "foo"],
            has_root: true,
            is_absolute: false,
-           parent: Some("/foo"),
-           file_name: None,
-           file_stem: None,
+           parent: Some("/"),
+           file_name: Some("foo"),
+           file_stem: Some("foo"),
            extension: None
            );
 
@@ -1820,12 +2264,12 @@ mod tests {
            );
 
         t!("///foo///",
-           iter: ["\\", "foo", "."],
+           iter: ["\\", "foo"],
            has_root: true,
            is_absolute: false,
-           parent: Some("///foo"),
-           file_name: None,
-           file_stem: None,
+           parent: Some("/"),
+           file_name: Some("foo"),
+           file_stem: Some("foo"),
            extension: None
            );
 
@@ -1840,20 +2284,10 @@ mod tests {
            );
 
         t!("./.",
-           iter: [".", "."],
-           has_root: false,
-           is_absolute: false,
-           parent: Some("."),
-           file_name: None,
-           file_stem: None,
-           extension: None
-           );
-
-        t!("./.",
-           iter: [".", "."],
+           iter: ["."],
            has_root: false,
            is_absolute: false,
-           parent: Some("."),
+           parent: Some(""),
            file_name: None,
            file_stem: None,
            extension: None
@@ -1870,22 +2304,22 @@ mod tests {
            );
 
         t!("../",
-           iter: ["..", "."],
+           iter: [".."],
            has_root: false,
            is_absolute: false,
-           parent: Some(".."),
+           parent: Some(""),
            file_name: None,
            file_stem: None,
            extension: None
            );
 
         t!("foo/.",
-           iter: ["foo", "."],
+           iter: ["foo"],
            has_root: false,
            is_absolute: false,
-           parent: Some("foo"),
-           file_name: None,
-           file_stem: None,
+           parent: Some(""),
+           file_name: Some("foo"),
+           file_stem: Some("foo"),
            extension: None
            );
 
@@ -1900,30 +2334,30 @@ mod tests {
            );
 
         t!("foo/./",
-           iter: ["foo", ".", "."],
+           iter: ["foo"],
            has_root: false,
            is_absolute: false,
-           parent: Some("foo/."),
-           file_name: None,
-           file_stem: None,
+           parent: Some(""),
+           file_name: Some("foo"),
+           file_stem: Some("foo"),
            extension: None
            );
 
         t!("foo/./bar",
-           iter: ["foo", ".", "bar"],
+           iter: ["foo", "bar"],
            has_root: false,
            is_absolute: false,
-           parent: Some("foo/."),
+           parent: Some("foo"),
            file_name: Some("bar"),
            file_stem: Some("bar"),
            extension: None
            );
 
         t!("foo/../",
-           iter: ["foo", "..", "."],
+           iter: ["foo", ".."],
            has_root: false,
            is_absolute: false,
-           parent: Some("foo/.."),
+           parent: Some("foo"),
            file_name: None,
            file_stem: None,
            extension: None
@@ -1953,17 +2387,17 @@ mod tests {
            iter: ["."],
            has_root: false,
            is_absolute: false,
-           parent: None,
+           parent: Some(""),
            file_name: None,
            file_stem: None,
            extension: None
            );
 
         t!("./",
-           iter: [".", "."],
+           iter: ["."],
            has_root: false,
            is_absolute: false,
-           parent: Some("."),
+           parent: Some(""),
            file_name: None,
            file_stem: None,
            extension: None
@@ -1990,10 +2424,10 @@ mod tests {
            );
 
         t!("a/./b",
-           iter: ["a", ".", "b"],
+           iter: ["a", "b"],
            has_root: false,
            is_absolute: false,
-           parent: Some("a/."),
+           parent: Some("a"),
            file_name: Some("b"),
            file_stem: Some("b"),
            extension: None
@@ -2049,7 +2483,7 @@ mod tests {
            );
 
         t!("\\\\server\\share",
-           iter: ["\\\\server\\share", "\\", "."],
+           iter: ["\\\\server\\share", "\\"],
            has_root: true,
            is_absolute: true,
            parent: None,
@@ -2140,7 +2574,7 @@ mod tests {
 
 
         t!("\\\\?\\C:\\",
-           iter: ["\\\\?\\C:", "\\", ""],
+           iter: ["\\\\?\\C:", "\\"],
            has_root: true,
            is_absolute: true,
            parent: None,
@@ -2195,7 +2629,7 @@ mod tests {
 
 
         t!("\\\\.\\foo",
-           iter: ["\\\\.\\foo", "\\", "."],
+           iter: ["\\\\.\\foo", "\\"],
            has_root: true,
            is_absolute: true,
            parent: None,
@@ -2206,7 +2640,7 @@ mod tests {
 
 
         t!("\\\\.\\foo/bar",
-           iter: ["\\\\.\\foo/bar", "\\", "."],
+           iter: ["\\\\.\\foo/bar", "\\"],
            has_root: true,
            is_absolute: true,
            parent: None,
@@ -2228,7 +2662,7 @@ mod tests {
 
 
         t!("\\\\.\\",
-           iter: ["\\\\.\\", "\\", "."],
+           iter: ["\\\\.\\", "\\"],
            has_root: true,
            is_absolute: true,
            parent: None,
@@ -2238,12 +2672,12 @@ mod tests {
            );
 
         t!("\\\\?\\a\\b\\",
-           iter: ["\\\\?\\a", "\\", "b", ""],
+           iter: ["\\\\?\\a", "\\", "b"],
            has_root: true,
            is_absolute: true,
-           parent: Some("\\\\?\\a\\b"),
-           file_name: None,
-           file_stem: None,
+           parent: Some("\\\\?\\a\\"),
+           file_name: Some("b"),
+           file_stem: Some("b"),
            extension: None
            );
     }
@@ -2300,7 +2734,7 @@ mod tests {
     pub fn test_push() {
         macro_rules! tp(
             ($path:expr, $push:expr, $expected:expr) => ( {
-                let mut actual = PathBuf::new($path);
+                let mut actual = PathBuf::from($path);
                 actual.push($push);
                 assert!(actual.to_str() == Some($expected),
                         "pushing {:?} onto {:?}: Expected {:?}, got {:?}",
@@ -2388,7 +2822,7 @@ mod tests {
     pub fn test_pop() {
         macro_rules! tp(
             ($path:expr, $expected:expr, $output:expr) => ( {
-                let mut actual = PathBuf::new($path);
+                let mut actual = PathBuf::from($path);
                 let output = actual.pop();
                 assert!(actual.to_str() == Some($expected) && output == $output,
                         "popping from {:?}: Expected {:?}/{:?}, got {:?}/{:?}",
@@ -2399,12 +2833,12 @@ mod tests {
 
         tp!("", "", false);
         tp!("/", "/", false);
-        tp!("foo", "foo", false);
-        tp!(".", ".", false);
+        tp!("foo", "", true);
+        tp!(".", "", true);
         tp!("/foo", "/", true);
         tp!("/foo/bar", "/foo", true);
         tp!("foo/bar", "foo", true);
-        tp!("foo/.", "foo", true);
+        tp!("foo/.", "", true);
         tp!("foo//bar", "foo", true);
 
         if cfg!(windows) {
@@ -2434,7 +2868,7 @@ mod tests {
             tp!("\\\\.\\a\\b", "\\\\.\\a\\", true);
             tp!("\\\\.\\a", "\\\\.\\a", false);
 
-            tp!("\\\\?\\a\\b\\", "\\\\?\\a\\b", true);
+            tp!("\\\\?\\a\\b\\", "\\\\?\\a\\", true);
         }
     }
 
@@ -2442,7 +2876,7 @@ mod tests {
     pub fn test_set_file_name() {
         macro_rules! tfn(
                 ($path:expr, $file:expr, $expected:expr) => ( {
-                let mut p = PathBuf::new($path);
+                let mut p = PathBuf::from($path);
                 p.set_file_name($file);
                 assert!(p.to_str() == Some($expected),
                         "setting file name of {:?} to {:?}: Expected {:?}, got {:?}",
@@ -2457,15 +2891,15 @@ mod tests {
         tfn!("", "foo", "foo");
         if cfg!(unix) {
             tfn!(".", "foo", "./foo");
-            tfn!("foo/", "bar", "foo/bar");
-            tfn!("foo/.", "bar", "foo/./bar");
+            tfn!("foo/", "bar", "bar");
+            tfn!("foo/.", "bar", "bar");
             tfn!("..", "foo", "../foo");
             tfn!("foo/..", "bar", "foo/../bar");
             tfn!("/", "foo", "/foo");
         } else {
             tfn!(".", "foo", r".\foo");
-            tfn!(r"foo\", "bar", r"foo\bar");
-            tfn!(r"foo\.", "bar", r"foo\.\bar");
+            tfn!(r"foo\", "bar", r"bar");
+            tfn!(r"foo\.", "bar", r"bar");
             tfn!("..", "foo", r"..\foo");
             tfn!(r"foo\..", "bar", r"foo\..\bar");
             tfn!(r"\", "foo", r"\foo");
@@ -2476,7 +2910,7 @@ mod tests {
     pub fn test_set_extension() {
         macro_rules! tfe(
                 ($path:expr, $ext:expr, $expected:expr, $output:expr) => ( {
-                let mut p = PathBuf::new($path);
+                let mut p = PathBuf::from($path);
                 let output = p.set_extension($ext);
                 assert!(p.to_str() == Some($expected) && output == $output,
                         "setting extension of {:?} to {:?}: Expected {:?}/{:?}, got {:?}/{:?}",
@@ -2493,8 +2927,8 @@ mod tests {
         tfe!("foo", "", "foo", true);
         tfe!("", "foo", "", false);
         tfe!(".", "foo", ".", false);
-        tfe!("foo/", "bar", "foo/", false);
-        tfe!("foo/.", "bar", "foo/.", false);
+        tfe!("foo/", "bar", "foo.bar", true);
+        tfe!("foo/.", "bar", "foo.bar", true);
         tfe!("..", "foo", "..",  false);
         tfe!("foo/..", "bar", "foo/..", false);
         tfe!("/", "foo", "/", false);
@@ -2560,10 +2994,10 @@ mod tests {
             );
 
         tc!("foo/", "foo",
-            eq: false,
+            eq: true,
             starts_with: true,
-            ends_with: false,
-            relative_from: Some(".")
+            ends_with: true,
+            relative_from: Some("")
             );
 
         tc!("foo/bar", "foo",
@@ -2590,8 +3024,25 @@ mod tests {
         tc!("./foo/bar/", ".",
             eq: false,
             starts_with: true,
-            ends_with: true,
-            relative_from: Some("foo/bar/")
+            ends_with: false,
+            relative_from: Some("foo/bar")
             );
+
+        if cfg!(windows) {
+            tc!(r"C:\src\rust\cargo-test\test\Cargo.toml",
+                r"c:\src\rust\cargo-test\test",
+                eq: false,
+                starts_with: true,
+                ends_with: false,
+                relative_from: Some("Cargo.toml")
+                );
+
+            tc!(r"c:\foo", r"C:\foo",
+                eq: true,
+                starts_with: true,
+                ends_with: true,
+                relative_from: Some("")
+                );
+        }
     }
 }
index d2dc33451200f5f866973f03939eecf2523613c5..84a450867675c814c96eff49d0873a0735ffc338 100644 (file)
 #[doc(no_inline)] pub use mem::drop;
 
 // Reexported types and traits
-
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use boxed::Box;
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use char::CharExt;
-#[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use clone::Clone;
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
+#[unstable(feature = "convert")]
+#[doc(no_inline)] pub use convert::{AsRef, AsMut, Into, From};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use iter::DoubleEndedIterator;
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use iter::ExactSizeIterator;
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use iter::{Iterator, IteratorExt, Extend};
+#[doc(no_inline)] pub use iter::{Iterator, Extend};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use option::Option::{self, Some, None};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use ptr::{PtrExt, MutPtrExt};
-#[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use result::Result::{self, Ok, Err};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use slice::AsSlice;
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use slice::{SliceExt, SliceConcatExt};
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)] pub use str::{Str, StrExt};
+#[doc(no_inline)] pub use slice::SliceConcatExt;
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use string::{String, ToString};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use vec::Vec;
 
-// NB: remove when path reform lands
-#[doc(no_inline)] pub use old_path::{Path, GenericPath};
-// NB: remove when I/O reform lands
-#[doc(no_inline)] pub use old_io::{Buffer, Writer, Reader, Seek, BufferPrelude};
-// NB: remove when range syntax lands
-#[doc(no_inline)] pub use iter::range;
+#[allow(deprecated)] pub use slice::AsSlice;
+#[allow(deprecated)] pub use str::Str;
index 5baa095d35985c7b44aed14c10f4d49359f113ce..52f5965db809a76c5168a5d8985d006569e1aaf6 100644 (file)
 
 //! Working with processes.
 
-#![unstable(feature = "process", reason = "recently added via RFC 579")]
+#![stable(feature = "process", since = "1.0.0")]
 #![allow(non_upper_case_globals)]
 
 use prelude::v1::*;
 use io::prelude::*;
 
-use ffi::AsOsStr;
+use ffi::OsStr;
 use fmt;
 use io::{self, Error, ErrorKind};
-use path::AsPath;
 use libc;
+use path;
 use sync::mpsc::{channel, Receiver};
 use sys::pipe2::{self, AnonPipe};
-use sys::process2::Process as ProcessImp;
 use sys::process2::Command as CommandImp;
+use sys::process2::Process as ProcessImp;
 use sys::process2::ExitStatus as ExitStatusImp;
 use sys_common::{AsInner, AsInnerMut};
 use thread;
@@ -35,9 +35,9 @@ use thread;
 /// process is created via the `Command` struct, which configures the spawning
 /// process and can itself be constructed using a builder-style interface.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```should_fail
+/// ```should_panic
 /// # #![feature(process)]
 ///
 /// use std::process::Command;
@@ -48,6 +48,7 @@ use thread;
 /// let contents = output.stdout;
 /// assert!(output.status.success());
 /// ```
+#[stable(feature = "process", since = "1.0.0")]
 pub struct Child {
     handle: ProcessImp,
 
@@ -55,20 +56,25 @@ pub struct Child {
     status: Option<ExitStatusImp>,
 
     /// The handle for writing to the child's stdin, if it has been captured
+    #[stable(feature = "process", since = "1.0.0")]
     pub stdin: Option<ChildStdin>,
 
     /// The handle for reading from the child's stdout, if it has been captured
+    #[stable(feature = "process", since = "1.0.0")]
     pub stdout: Option<ChildStdout>,
 
     /// The handle for reading from the child's stderr, if it has been captured
+    #[stable(feature = "process", since = "1.0.0")]
     pub stderr: Option<ChildStderr>,
 }
 
 /// A handle to a child procesess's stdin
+#[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStdin {
     inner: AnonPipe
 }
 
+#[stable(feature = "process", since = "1.0.0")]
 impl Write for ChildStdin {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.write(buf)
@@ -80,10 +86,12 @@ impl Write for ChildStdin {
 }
 
 /// A handle to a child procesess's stdout
+#[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStdout {
     inner: AnonPipe
 }
 
+#[stable(feature = "process", since = "1.0.0")]
 impl Read for ChildStdout {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
@@ -91,10 +99,12 @@ impl Read for ChildStdout {
 }
 
 /// A handle to a child procesess's stderr
+#[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStderr {
     inner: AnonPipe
 }
 
+#[stable(feature = "process", since = "1.0.0")]
 impl Read for ChildStderr {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
@@ -108,8 +118,6 @@ impl Read for ChildStderr {
 /// to be changed (for example, by adding arguments) prior to spawning:
 ///
 /// ```
-/// # #![feature(process)]
-///
 /// use std::process::Command;
 ///
 /// let output = Command::new("sh").arg("-c").arg("echo hello").output().unwrap_or_else(|e| {
@@ -117,6 +125,7 @@ impl Read for ChildStderr {
 /// });
 /// let hello = output.stdout;
 /// ```
+#[stable(feature = "process", since = "1.0.0")]
 pub struct Command {
     inner: CommandImp,
 
@@ -137,9 +146,10 @@ impl Command {
     ///
     /// Builder methods are provided to change these defaults and
     /// otherwise configure the process.
-    pub fn new<S: AsOsStr + ?Sized>(program: &S) -> Command {
+    #[stable(feature = "process", since = "1.0.0")]
+    pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
         Command {
-            inner: CommandImp::new(program.as_os_str()),
+            inner: CommandImp::new(program.as_ref()),
             stdin: None,
             stdout: None,
             stderr: None,
@@ -147,14 +157,16 @@ impl Command {
     }
 
     /// Add an argument to pass to the program.
-    pub fn arg<S: AsOsStr + ?Sized>(&mut self, arg: &S) -> &mut Command {
-        self.inner.arg(arg.as_os_str());
+    #[stable(feature = "process", since = "1.0.0")]
+    pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
+        self.inner.arg(arg.as_ref());
         self
     }
 
     /// Add multiple arguments to pass to the program.
-    pub fn args<S: AsOsStr>(&mut self, args: &[S]) -> &mut Command {
-        self.inner.args(args.iter().map(AsOsStr::as_os_str));
+    #[stable(feature = "process", since = "1.0.0")]
+    pub fn args<S: AsRef<OsStr>>(&mut self, args: &[S]) -> &mut Command {
+        self.inner.args(args.iter().map(AsRef::as_ref));
         self
     }
 
@@ -162,33 +174,38 @@ impl Command {
     ///
     /// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
     /// and case-sensitive on all other platforms.
-    pub fn env<S: ?Sized, T: ?Sized>(&mut self, key: &S, val: &T) -> &mut Command where
-        S: AsOsStr, T: AsOsStr
+    #[stable(feature = "process", since = "1.0.0")]
+    pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
+        where K: AsRef<OsStr>, V: AsRef<OsStr>
     {
-        self.inner.env(key.as_os_str(), val.as_os_str());
+        self.inner.env(key.as_ref(), val.as_ref());
         self
     }
 
     /// Removes an environment variable mapping.
-    pub fn env_remove<S: ?Sized + AsOsStr>(&mut self, key: &S) -> &mut Command {
-        self.inner.env_remove(key.as_os_str());
+    #[stable(feature = "process", since = "1.0.0")]
+    pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
+        self.inner.env_remove(key.as_ref());
         self
     }
 
     /// Clears the entire environment map for the child process.
+    #[stable(feature = "process", since = "1.0.0")]
     pub fn env_clear(&mut self) -> &mut Command {
         self.inner.env_clear();
         self
     }
 
     /// Set the working directory for the child process.
-    pub fn current_dir<P: AsPath + ?Sized>(&mut self, dir: &P) -> &mut Command {
-        self.inner.cwd(dir.as_path().as_os_str());
+    #[stable(feature = "process", since = "1.0.0")]
+    pub fn current_dir<P: AsRef<path::Path>>(&mut self, dir: P) -> &mut Command {
+        self.inner.cwd(dir.as_ref().as_ref());
         self
     }
 
     /// Configuration for the child process's stdin handle (file descriptor 0).
     /// Defaults to `CreatePipe(true, false)` so the input can be written to.
+    #[stable(feature = "process", since = "1.0.0")]
     pub fn stdin(&mut self, cfg: Stdio) -> &mut Command {
         self.stdin = Some(cfg.0);
         self
@@ -196,6 +213,7 @@ impl Command {
 
     /// Configuration for the child process's stdout handle (file descriptor 1).
     /// Defaults to `CreatePipe(false, true)` so the output can be collected.
+    #[stable(feature = "process", since = "1.0.0")]
     pub fn stdout(&mut self, cfg: Stdio) -> &mut Command {
         self.stdout = Some(cfg.0);
         self
@@ -203,6 +221,7 @@ impl Command {
 
     /// Configuration for the child process's stderr handle (file descriptor 2).
     /// Defaults to `CreatePipe(false, true)` so the output can be collected.
+    #[stable(feature = "process", since = "1.0.0")]
     pub fn stderr(&mut self, cfg: Stdio) -> &mut Command {
         self.stderr = Some(cfg.0);
         self
@@ -234,6 +253,7 @@ impl Command {
     /// Executes the command as a child process, returning a handle to it.
     ///
     /// By default, stdin, stdout and stderr are inherited by the parent.
+    #[stable(feature = "process", since = "1.0.0")]
     pub fn spawn(&mut self) -> io::Result<Child> {
         self.spawn_inner(StdioImp::Inherit)
     }
@@ -244,7 +264,7 @@ impl Command {
     /// By default, stdin, stdout and stderr are captured (and used to
     /// provide the resulting output).
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// # #![feature(process)]
@@ -255,11 +275,12 @@ impl Command {
     /// });
     ///
     /// println!("status: {}", output.status);
-    /// println!("stdout: {}", String::from_utf8_lossy(output.stdout.as_slice()));
-    /// println!("stderr: {}", String::from_utf8_lossy(output.stderr.as_slice()));
+    /// println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
+    /// println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
     /// ```
+    #[stable(feature = "process", since = "1.0.0")]
     pub fn output(&mut self) -> io::Result<Output> {
-        self.spawn_inner(StdioImp::Capture).and_then(|p| p.wait_with_output())
+        self.spawn_inner(StdioImp::Piped).and_then(|p| p.wait_with_output())
     }
 
     /// Executes a command as a child process, waiting for it to finish and
@@ -267,7 +288,7 @@ impl Command {
     ///
     /// By default, stdin, stdout and stderr are inherited by the parent.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// # #![feature(process)]
@@ -279,6 +300,7 @@ impl Command {
     ///
     /// println!("process exited with: {}", status);
     /// ```
+    #[stable(feature = "process", since = "1.0.0")]
     pub fn status(&mut self) -> io::Result<ExitStatus> {
         self.spawn().and_then(|mut p| p.wait())
     }
@@ -317,7 +339,7 @@ fn setup_io(io: &StdioImp, fd: libc::c_int, readable: bool)
         Inherit => {
             (Some(AnonPipe::from_fd(fd)), None)
         }
-        Capture => {
+        Piped => {
             let (reader, writer) = try!(unsafe { pipe2::anon_pipe() });
             if readable {
                 (Some(reader), Some(writer))
@@ -330,45 +352,55 @@ fn setup_io(io: &StdioImp, fd: libc::c_int, readable: bool)
 
 /// The output of a finished process.
 #[derive(PartialEq, Eq, Clone)]
+#[stable(feature = "process", since = "1.0.0")]
 pub struct Output {
     /// The status (exit code) of the process.
+    #[stable(feature = "process", since = "1.0.0")]
     pub status: ExitStatus,
     /// The data that the process wrote to stdout.
+    #[stable(feature = "process", since = "1.0.0")]
     pub stdout: Vec<u8>,
     /// The data that the process wrote to stderr.
+    #[stable(feature = "process", since = "1.0.0")]
     pub stderr: Vec<u8>,
 }
 
 /// Describes what to do with a standard io stream for a child process.
+#[stable(feature = "process", since = "1.0.0")]
 pub struct Stdio(StdioImp);
 
 // The internal enum for stdio setup; see below for descriptions.
 #[derive(Clone)]
 enum StdioImp {
-    Capture,
+    Piped,
     Inherit,
     Null,
 }
 
 impl Stdio {
     /// A new pipe should be arranged to connect the parent and child processes.
-    pub fn capture() -> Stdio { Stdio(StdioImp::Capture) }
+    #[stable(feature = "process", since = "1.0.0")]
+    pub fn piped() -> Stdio { Stdio(StdioImp::Piped) }
 
     /// The child inherits from the corresponding parent descriptor.
-    pub fn inherit() -> Stdio { Stdio(StdioImp::Capture) }
+    #[stable(feature = "process", since = "1.0.0")]
+    pub fn inherit() -> Stdio { Stdio(StdioImp::Inherit) }
 
     /// This stream will be ignored. This is the equivalent of attaching the
     /// stream to `/dev/null`
-    pub fn null() -> Stdio { Stdio(StdioImp::Capture) }
+    #[stable(feature = "process", since = "1.0.0")]
+    pub fn null() -> Stdio { Stdio(StdioImp::Null) }
 }
 
 /// Describes the result of a process after it has terminated.
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[stable(feature = "process", since = "1.0.0")]
 pub struct ExitStatus(ExitStatusImp);
 
 impl ExitStatus {
     /// Was termination successful? Signal termination not considered a success,
     /// and success is defined as a zero exit status.
+    #[stable(feature = "process", since = "1.0.0")]
     pub fn success(&self) -> bool {
         self.0.success()
     }
@@ -378,6 +410,7 @@ impl ExitStatus {
     /// On Unix, this will return `None` if the process was terminated
     /// by a signal; `std::os::unix` provides an extension trait for
     /// extracting the signal and other details from the `ExitStatus`.
+    #[stable(feature = "process", since = "1.0.0")]
     pub fn code(&self) -> Option<i32> {
         self.0.code()
     }
@@ -387,6 +420,7 @@ impl AsInner<ExitStatusImp> for ExitStatus {
     fn as_inner(&self) -> &ExitStatusImp { &self.0 }
 }
 
+#[stable(feature = "process", since = "1.0.0")]
 impl fmt::Display for ExitStatus {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.0.fmt(f)
@@ -396,6 +430,7 @@ impl fmt::Display for ExitStatus {
 impl Child {
     /// Forces the child to exit. This is equivalent to sending a
     /// SIGKILL on unix platforms.
+    #[stable(feature = "process", since = "1.0.0")]
     pub fn kill(&mut self) -> io::Result<()> {
         #[cfg(unix)] fn collect_status(p: &mut Child) {
             // On Linux (and possibly other unices), a process that has exited will
@@ -421,7 +456,6 @@ impl Child {
             return Err(Error::new(
                 ErrorKind::InvalidInput,
                 "invalid argument: can't kill an exited process",
-                None
             ))
         }
 
@@ -436,6 +470,7 @@ impl Child {
     /// before waiting. This helps avoid deadlock: it ensures that the
     /// child does not block waiting for input from the parent, while
     /// the parent waits for the child to exit.
+    #[stable(feature = "process", since = "1.0.0")]
     pub fn wait(&mut self) -> io::Result<ExitStatus> {
         drop(self.stdin.take());
         match self.status {
@@ -456,6 +491,7 @@ impl Child {
     /// before waiting. This helps avoid deadlock: it ensures that the
     /// child does not block waiting for input from the parent, while
     /// the parent waits for the child to exit.
+    #[stable(feature = "process", since = "1.0.0")]
     pub fn wait_with_output(mut self) -> io::Result<Output> {
         drop(self.stdin.take());
         fn read<T: Read + Send + 'static>(stream: Option<T>) -> Receiver<io::Result<Vec<u8>>> {
@@ -485,22 +521,33 @@ impl Child {
     }
 }
 
+/// Terminates the current process with the specified exit code.
+///
+/// This function will never return and will immediately terminate the current
+/// process. The exit code is passed through to the underlying OS and will be
+/// available for consumption by another process.
+///
+/// Note that because this function never returns, and that it terminates the
+/// process, no destructors on the current stack or any other thread's stack
+/// will be run. If a clean shutdown is needed it is recommended to only call
+/// this function at a known point where there are no more destructors left
+/// to run.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn exit(code: i32) -> ! {
+    ::sys::os::exit(code)
+}
+
 #[cfg(test)]
 mod tests {
-    use io::ErrorKind;
+    use prelude::v1::*;
     use io::prelude::*;
-    use prelude::v1::{Ok, Err, range, drop, Some, None, Vec};
-    use prelude::v1::{String, Clone};
-    use prelude::v1::{SliceExt, Str, StrExt, AsSlice, ToString, GenericPath};
-    use path::Path;
-    use old_path;
+
+    use io::ErrorKind;
+    use old_path::{self, GenericPath};
     use old_io::fs::PathExtensions;
     use rt::running_on_valgrind;
     use str;
-    use super::{Child, Command, Output, ExitStatus, Stdio};
-    use sync::mpsc::channel;
-    use thread;
-    use time::Duration;
+    use super::{Command, Output, Stdio};
 
     // FIXME(#10380) these tests should not all be ignored on android.
 
@@ -529,13 +576,13 @@ mod tests {
         assert!(p.is_ok());
         let mut p = p.unwrap();
         assert!(p.wait().unwrap().code() == Some(1));
-        drop(p.wait().clone());
+        drop(p.wait());
     }
 
     #[cfg(all(unix, not(target_os="android")))]
     #[test]
     fn signal_reported_right() {
-        use os::unix::ExitStatusExt;
+        use os::unix::process::ExitStatusExt;
 
         let p = Command::new("/bin/sh").arg("-c").arg("kill -9 $$").spawn();
         assert!(p.is_ok());
@@ -561,7 +608,7 @@ mod tests {
     #[test]
     fn stdout_works() {
         let mut cmd = Command::new("echo");
-        cmd.arg("foobar").stdout(Stdio::capture());
+        cmd.arg("foobar").stdout(Stdio::piped());
         assert_eq!(run_output(cmd), "foobar\n");
     }
 
@@ -571,7 +618,7 @@ mod tests {
         let mut cmd = Command::new("/bin/sh");
         cmd.arg("-c").arg("pwd")
            .current_dir("/")
-           .stdout(Stdio::capture());
+           .stdout(Stdio::piped());
         assert_eq!(run_output(cmd), "/\n");
     }
 
@@ -580,8 +627,8 @@ mod tests {
     fn stdin_works() {
         let mut p = Command::new("/bin/sh")
                             .arg("-c").arg("read line; echo $line")
-                            .stdin(Stdio::capture())
-                            .stdout(Stdio::capture())
+                            .stdin(Stdio::piped())
+                            .stdout(Stdio::piped())
                             .spawn().unwrap();
         p.stdin.as_mut().unwrap().write("foobar".as_bytes()).unwrap();
         drop(p.stdin.take());
@@ -595,7 +642,7 @@ mod tests {
     #[cfg(all(unix, not(target_os="android")))]
     #[test]
     fn uid_works() {
-        use os::unix::*;
+        use os::unix::prelude::*;
         use libc;
         let mut p = Command::new("/bin/sh")
                             .arg("-c").arg("true")
@@ -608,7 +655,7 @@ mod tests {
     #[cfg(all(unix, not(target_os="android")))]
     #[test]
     fn uid_to_root_fails() {
-        use os::unix::*;
+        use os::unix::prelude::*;
         use libc;
 
         // if we're already root, this isn't a valid test. Most of the bots run
@@ -630,7 +677,7 @@ mod tests {
     #[test]
     fn test_process_output_fail_to_start() {
         match Command::new("/no-binary-by-this-name-should-exist").output() {
-            Err(e) => assert_eq!(e.kind(), ErrorKind::FileNotFound),
+            Err(e) => assert_eq!(e.kind(), ErrorKind::NotFound),
             Ok(..) => panic!()
         }
     }
@@ -640,7 +687,7 @@ mod tests {
     fn test_process_output_output() {
         let Output {status, stdout, stderr}
              = Command::new("echo").arg("hello").output().unwrap();
-        let output_str = str::from_utf8(stdout.as_slice()).unwrap();
+        let output_str = str::from_utf8(&stdout).unwrap();
 
         assert!(status.success());
         assert_eq!(output_str.trim().to_string(), "hello");
@@ -679,10 +726,10 @@ mod tests {
     #[cfg(not(target_os="android"))]
     #[test]
     fn test_wait_with_output_once() {
-        let prog = Command::new("echo").arg("hello").stdout(Stdio::capture())
+        let prog = Command::new("echo").arg("hello").stdout(Stdio::piped())
             .spawn().unwrap();
         let Output {status, stdout, stderr} = prog.wait_with_output().unwrap();
-        let output_str = str::from_utf8(stdout.as_slice()).unwrap();
+        let output_str = str::from_utf8(&stdout).unwrap();
 
         assert!(status.success());
         assert_eq!(output_str.trim().to_string(), "hello");
@@ -710,13 +757,15 @@ mod tests {
         cmd
     }
 
+    #[cfg(not(target_arch = "aarch64"))]
     #[test]
     fn test_keep_current_working_dir() {
         use os;
         let prog = pwd_cmd().spawn().unwrap();
 
         let output = String::from_utf8(prog.wait_with_output().unwrap().stdout).unwrap();
-        let parent_dir = os::getcwd().unwrap();
+        let parent_dir = ::env::current_dir().unwrap().to_str().unwrap().to_string();
+        let parent_dir = old_path::Path::new(parent_dir);
         let child_dir = old_path::Path::new(output.trim());
 
         let parent_stat = parent_dir.stat().unwrap();
@@ -731,8 +780,9 @@ mod tests {
         use os;
         // test changing to the parent of os::getcwd() because we know
         // the path exists (and os::getcwd() is not expected to be root)
-        let parent_dir = os::getcwd().unwrap().dir_path();
-        let result = pwd_cmd().current_dir(&parent_dir).output().unwrap();
+        let parent_dir = ::env::current_dir().unwrap().to_str().unwrap().to_string();
+        let parent_dir = old_path::Path::new(parent_dir).dir_path();
+        let result = pwd_cmd().current_dir(parent_dir.as_str().unwrap()).output().unwrap();
 
         let output = String::from_utf8(result.stdout).unwrap();
         let child_dir = old_path::Path::new(output.trim());
@@ -765,17 +815,16 @@ mod tests {
     #[cfg(not(target_os="android"))]
     #[test]
     fn test_inherit_env() {
-        use os;
+        use std::env;
         if running_on_valgrind() { return; }
 
         let result = env_cmd().output().unwrap();
         let output = String::from_utf8(result.stdout).unwrap();
 
-        let r = os::env();
-        for &(ref k, ref v) in &r {
+        for (ref k, ref v) in env::vars() {
             // don't check windows magical empty-named variables
             assert!(k.is_empty() ||
-                    output.contains(format!("{}={}", *k, *v).as_slice()),
+                    output.contains(&format!("{}={}", *k, *v)),
                     "output doesn't contain `{}={}`\n{}",
                     k, v, output);
         }
@@ -783,22 +832,21 @@ mod tests {
     #[cfg(target_os="android")]
     #[test]
     fn test_inherit_env() {
-        use os;
+        use std::env;
         if running_on_valgrind() { return; }
 
         let mut result = env_cmd().output().unwrap();
         let output = String::from_utf8(result.stdout).unwrap();
 
-        let r = os::env();
-        for &(ref k, ref v) in &r {
+        for (ref k, ref v) in env::vars() {
             // don't check android RANDOM variables
             if *k != "RANDOM".to_string() {
-                assert!(output.contains(format!("{}={}",
-                                                *k,
-                                                *v).as_slice()) ||
-                        output.contains(format!("{}=\'{}\'",
-                                                *k,
-                                                *v).as_slice()));
+                assert!(output.contains(&format!("{}={}",
+                                                 *k,
+                                                 *v)) ||
+                        output.contains(&format!("{}=\'{}\'",
+                                                 *k,
+                                                 *v)));
             }
         }
     }
@@ -817,7 +865,7 @@ mod tests {
             cmd.env("PATH", &p);
         }
         let result = cmd.output().unwrap();
-        let output = String::from_utf8_lossy(result.stdout.as_slice()).to_string();
+        let output = String::from_utf8_lossy(&result.stdout).to_string();
 
         assert!(output.contains("RUN_TEST_NEW_ENV=123"),
                 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
@@ -826,7 +874,7 @@ mod tests {
     #[test]
     fn test_add_to_env() {
         let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap();
-        let output = String::from_utf8_lossy(result.stdout.as_slice()).to_string();
+        let output = String::from_utf8_lossy(&result.stdout).to_string();
 
         assert!(output.contains("RUN_TEST_NEW_ENV=123"),
                 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
index 5c891441198039940cab0e08776a06379d9bf860..fad57323d34baf6e443addf71ea9688067214bbf 100644 (file)
 //! # Examples
 //!
 //! ```rust
+//! # #![feature(rand)]
 //! use std::rand;
 //! use std::rand::Rng;
 //!
 //! let mut rng = rand::thread_rng();
 //! if rng.gen() { // random bool
-//!     println!("int: {}, uint: {}", rng.gen::<int>(), rng.gen::<uint>())
+//!     println!("isize: {}, usize: {}", rng.gen::<isize>(), rng.gen::<usize>())
 //! }
 //! ```
 //!
 //! ```rust
+//! # #![feature(rand)]
 //! use std::rand;
 //!
 //! let tuple = rand::random::<(f64, char)>();
@@ -92,6 +94,7 @@
 //! multiply this fraction by 4.
 //!
 //! ```
+//! # #![feature(rand)]
 //! use std::rand;
 //! use std::rand::distributions::{IndependentSample, Range};
 //!
 //! [Monty Hall Problem]: http://en.wikipedia.org/wiki/Monty_Hall_problem
 //!
 //! ```
+//! # #![feature(rand)]
 //! use std::rand;
 //! use std::rand::Rng;
 //! use std::rand::distributions::{IndependentSample, Range};
 //! }
 //!
 //! // Run a single simulation of the Monty Hall problem.
-//! fn simulate<R: Rng>(random_door: &Range<uint>, rng: &mut R) -> SimulationResult {
+//! fn simulate<R: Rng>(random_door: &Range<usize>, rng: &mut R) -> SimulationResult {
 //!     let car = random_door.ind_sample(rng);
 //!
 //!     // This is our initial choice
 //!
 //! // Returns the door the game host opens given our choice and knowledge of
 //! // where the car is. The game host will never open the door with the car.
-//! fn game_host_open<R: Rng>(car: uint, choice: uint, rng: &mut R) -> uint {
+//! fn game_host_open<R: Rng>(car: usize, choice: usize, rng: &mut R) -> usize {
 //!     let choices = free_doors(&[car, choice]);
 //!     rand::sample(rng, choices.into_iter(), 1)[0]
 //! }
 //!
 //! // Returns the door we switch to, given our current choice and
 //! // the open door. There will only be one valid door.
-//! fn switch_door(choice: uint, open: uint) -> uint {
+//! fn switch_door(choice: usize, open: usize) -> usize {
 //!     free_doors(&[choice, open])[0]
 //! }
 //!
-//! fn free_doors(blocked: &[uint]) -> Vec<uint> {
+//! fn free_doors(blocked: &[usize]) -> Vec<usize> {
 //!     (0..3).filter(|x| !blocked.contains(x)).collect()
 //! }
 //!
 use cell::RefCell;
 use clone::Clone;
 use old_io::IoResult;
-use iter::{Iterator, IteratorExt};
+use iter::Iterator;
 use mem;
 use rc::Rc;
 use result::Result::{Ok, Err};
@@ -321,7 +325,7 @@ impl reseeding::Reseeder<StdRng> for ThreadRngReseeder {
         }
     }
 }
-static THREAD_RNG_RESEED_THRESHOLD: usize = 32_768;
+const THREAD_RNG_RESEED_THRESHOLD: usize = 32_768;
 type ThreadRngInner = reseeding::ReseedingRng<StdRng, ThreadRngReseeder>;
 
 /// The thread-local RNG.
@@ -332,7 +336,7 @@ pub struct ThreadRng {
 
 /// Retrieve the lazily-initialized thread-local random number
 /// generator, seeded by the system. Intended to be used in method
-/// chaining style, e.g. `thread_rng().gen::<int>()`.
+/// chaining style, e.g. `thread_rng().gen::<isize>()`.
 ///
 /// The RNG provided will reseed itself from the operating system
 /// after generating a certain amount of randomness.
@@ -384,10 +388,11 @@ impl Rng for ThreadRng {
 /// # Examples
 ///
 /// ```
+/// # #![feature(rand)]
 /// use std::rand;
 ///
-/// let x = rand::random();
-/// println!("{}", 2u8 * x);
+/// let x: u8 = rand::random();
+/// println!("{}", 2 * x as u16);
 ///
 /// let y = rand::random::<f64>();
 /// println!("{}", y);
@@ -400,6 +405,7 @@ impl Rng for ThreadRng {
 /// Caching the thread local random number generator:
 ///
 /// ```
+/// # #![feature(rand)]
 /// use std::rand;
 /// use std::rand::Rng;
 ///
@@ -424,9 +430,10 @@ pub fn random<T: Rand>() -> T {
 
 /// Randomly sample up to `amount` elements from an iterator.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand)]
 /// use std::rand::{thread_rng, sample};
 ///
 /// let mut rng = thread_rng();
@@ -468,7 +475,7 @@ mod test {
         let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
                        80, 81, 82, 83, 84, 85, 86, 87];
         for &n in &lengths {
-            let mut v = repeat(0u8).take(n).collect::<Vec<_>>();
+            let mut v = repeat(0).take(n).collect::<Vec<_>>();
             r.fill_bytes(&mut v);
 
             // use this to get nicer error messages.
@@ -500,14 +507,14 @@ mod test {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_gen_range_panic_int() {
         let mut r = thread_rng();
         r.gen_range(5, -2);
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_gen_range_panic_uint() {
         let mut r = thread_rng();
         r.gen_range(5, 2);
@@ -549,14 +556,14 @@ mod test {
         let mut r = thread_rng();
         assert_eq!(r.choose(&[1, 1, 1]).cloned(), Some(1));
 
-        let v: &[int] = &[];
+        let v: &[isize] = &[];
         assert_eq!(r.choose(v), None);
     }
 
     #[test]
     fn test_shuffle() {
         let mut r = thread_rng();
-        let empty: &mut [int] = &mut [];
+        let empty: &mut [isize] = &mut [];
         r.shuffle(empty);
         let mut one = [1];
         r.shuffle(&mut one);
@@ -576,7 +583,7 @@ mod test {
     #[test]
     fn test_thread_rng() {
         let mut r = thread_rng();
-        r.gen::<int>();
+        r.gen::<isize>();
         let mut v = [1, 1, 1];
         r.shuffle(&mut v);
         let b: &[_] = &[1, 1, 1];
@@ -587,12 +594,12 @@ mod test {
     #[test]
     fn test_random() {
         // not sure how to test this aside from just getting some values
-        let _n : uint = random();
+        let _n : usize = random();
         let _f : f32 = random();
         let _o : Option<Option<i8>> = random();
         let _many : ((),
-                     (uint,
-                      int,
+                     (usize,
+                      isize,
                       Option<(u32, (bool,))>),
                      (u8, i8, u16, i16, u32, i32, u64, i64),
                      (f32, (f64, (f64,)))) = random();
@@ -604,7 +611,7 @@ mod test {
         let max_val = 100;
 
         let mut r = thread_rng();
-        let vals = (min_val..max_val).collect::<Vec<int>>();
+        let vals = (min_val..max_val).collect::<Vec<isize>>();
         let small_sample = sample(&mut r, vals.iter(), 5);
         let large_sample = sample(&mut r, vals.iter(), vals.len() + 5);
 
@@ -618,7 +625,7 @@ mod test {
 
     #[test]
     fn test_std_rng_seeded() {
-        let s = thread_rng().gen_iter::<uint>().take(256).collect::<Vec<uint>>();
+        let s = thread_rng().gen_iter::<usize>().take(256).collect::<Vec<usize>>();
         let mut ra: StdRng = SeedableRng::from_seed(&*s);
         let mut rb: StdRng = SeedableRng::from_seed(&*s);
         assert!(order::equals(ra.gen_ascii_chars().take(100),
@@ -627,7 +634,7 @@ mod test {
 
     #[test]
     fn test_std_rng_reseed() {
-        let s = thread_rng().gen_iter::<uint>().take(256).collect::<Vec<uint>>();
+        let s = thread_rng().gen_iter::<usize>().take(256).collect::<Vec<usize>>();
         let mut r: StdRng = SeedableRng::from_seed(&*s);
         let string1 = r.gen_ascii_chars().take(100).collect::<String>();
 
@@ -638,28 +645,27 @@ mod test {
     }
 }
 
-#[cfg(test)]
-static RAND_BENCH_N: u64 = 100;
-
 #[cfg(test)]
 mod bench {
     extern crate test;
     use prelude::v1::*;
 
     use self::test::Bencher;
-    use super::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N};
+    use super::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng};
     use super::{OsRng, weak_rng};
     use mem::size_of;
 
+    const RAND_BENCH_N: u64 = 100;
+
     #[bench]
     fn rand_xorshift(b: &mut Bencher) {
         let mut rng: XorShiftRng = OsRng::new().unwrap().gen();
         b.iter(|| {
             for _ in 0..RAND_BENCH_N {
-                rng.gen::<uint>();
+                rng.gen::<usize>();
             }
         });
-        b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
+        b.bytes = size_of::<usize>() as u64 * RAND_BENCH_N;
     }
 
     #[bench]
@@ -667,10 +673,10 @@ mod bench {
         let mut rng: IsaacRng = OsRng::new().unwrap().gen();
         b.iter(|| {
             for _ in 0..RAND_BENCH_N {
-                rng.gen::<uint>();
+                rng.gen::<usize>();
             }
         });
-        b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
+        b.bytes = size_of::<usize>() as u64 * RAND_BENCH_N;
     }
 
     #[bench]
@@ -678,10 +684,10 @@ mod bench {
         let mut rng: Isaac64Rng = OsRng::new().unwrap().gen();
         b.iter(|| {
             for _ in 0..RAND_BENCH_N {
-                rng.gen::<uint>();
+                rng.gen::<usize>();
             }
         });
-        b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
+        b.bytes = size_of::<usize>() as u64 * RAND_BENCH_N;
     }
 
     #[bench]
@@ -689,16 +695,16 @@ mod bench {
         let mut rng = StdRng::new().unwrap();
         b.iter(|| {
             for _ in 0..RAND_BENCH_N {
-                rng.gen::<uint>();
+                rng.gen::<usize>();
             }
         });
-        b.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
+        b.bytes = size_of::<usize>() as u64 * RAND_BENCH_N;
     }
 
     #[bench]
     fn rand_shuffle_100(b: &mut Bencher) {
         let mut rng = weak_rng();
-        let x : &mut[uint] = &mut [1; 100];
+        let x : &mut[usize] = &mut [1; 100];
         b.iter(|| {
             rng.shuffle(x);
         })
index 0e2766f3889441331b0ec73c3ecad0ddfb25c8ca..38c57eec684dbda7ff4f4d8eea948249ed532451 100644 (file)
@@ -15,18 +15,16 @@ pub use self::imp::OsRng;
 
 #[cfg(all(unix, not(target_os = "ios")))]
 mod imp {
-    extern crate libc;
-
+    use prelude::v1::*;
     use self::OsRngInner::*;
 
+    use libc;
+    use mem;
     use old_io::{IoResult, File};
     use old_path::Path;
     use rand::Rng;
     use rand::reader::ReaderRng;
-    use result::Result::Ok;
-    use slice::SliceExt;
-    use mem;
-    use os::errno;
+    use sys::os::errno;
 
     #[cfg(all(target_os = "linux",
               any(target_arch = "x86_64",
@@ -80,13 +78,13 @@ mod imp {
     }
 
     fn getrandom_next_u32() -> u32 {
-        let mut buf: [u8; 4] = [0u8; 4];
+        let mut buf: [u8; 4] = [0; 4];
         getrandom_fill_bytes(&mut buf);
         unsafe { mem::transmute::<[u8; 4], u32>(buf) }
     }
 
     fn getrandom_next_u64() -> u64 {
-        let mut buf: [u8; 8] = [0u8; 8];
+        let mut buf: [u8; 8] = [0; 8];
         getrandom_fill_bytes(&mut buf);
         unsafe { mem::transmute::<[u8; 8], u64>(buf) }
     }
@@ -185,16 +183,13 @@ mod imp {
 
 #[cfg(target_os = "ios")]
 mod imp {
-    extern crate libc;
+    use prelude::v1::*;
 
-    use old_io::{IoResult};
-    use marker::Sync;
+    use io;
+    use old_io::IoResult;
     use mem;
-    use os;
     use rand::Rng;
-    use result::Result::{Ok};
-    use self::libc::{c_int, size_t};
-    use slice::SliceExt;
+    use libc::{c_int, size_t};
 
     /// A random number generator that retrieves randomness straight from
     /// the operating system. Platform sources:
@@ -214,10 +209,8 @@ mod imp {
     #[repr(C)]
     struct SecRandom;
 
-    unsafe impl Sync for *const SecRandom {}
-
     #[allow(non_upper_case_globals)]
-    static kSecRandomDefault: *const SecRandom = 0 as *const SecRandom;
+    const kSecRandomDefault: *const SecRandom = 0 as *const SecRandom;
 
     #[link(name = "Security", kind = "framework")]
     extern "C" {
@@ -234,12 +227,12 @@ mod imp {
 
     impl Rng for OsRng {
         fn next_u32(&mut self) -> u32 {
-            let mut v = [0u8; 4];
+            let mut v = [0; 4];
             self.fill_bytes(&mut v);
             unsafe { mem::transmute(v) }
         }
         fn next_u64(&mut self) -> u64 {
-            let mut v = [0u8; 8];
+            let mut v = [0; 8];
             self.fill_bytes(&mut v);
             unsafe { mem::transmute(v) }
         }
@@ -248,7 +241,7 @@ mod imp {
                 SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t, v.as_mut_ptr())
             };
             if ret == -1 {
-                panic!("couldn't generate random bytes: {}", os::last_os_error());
+                panic!("couldn't generate random bytes: {}", io::Error::last_os_error());
             }
         }
     }
@@ -256,17 +249,14 @@ mod imp {
 
 #[cfg(windows)]
 mod imp {
-    extern crate libc;
+    use prelude::v1::*;
 
-    use old_io::{IoResult, IoError};
+    use io;
     use mem;
-    use ops::Drop;
-    use os;
+    use old_io::{IoResult, IoError};
     use rand::Rng;
-    use result::Result::{Ok, Err};
-    use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
-    use self::libc::types::os::arch::extra::{LONG_PTR};
-    use slice::SliceExt;
+    use libc::types::os::arch::extra::{LONG_PTR};
+    use libc::{DWORD, BYTE, LPCSTR, BOOL};
 
     type HCRYPTPROV = LONG_PTR;
 
@@ -284,9 +274,9 @@ mod imp {
         hcryptprov: HCRYPTPROV
     }
 
-    static PROV_RSA_FULL: DWORD = 1;
-    static CRYPT_SILENT: DWORD = 64;
-    static CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;
+    const PROV_RSA_FULL: DWORD = 1;
+    const CRYPT_SILENT: DWORD = 64;
+    const CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;
 
     #[allow(non_snake_case)]
     extern "system" {
@@ -321,12 +311,12 @@ mod imp {
 
     impl Rng for OsRng {
         fn next_u32(&mut self) -> u32 {
-            let mut v = [0u8; 4];
+            let mut v = [0; 4];
             self.fill_bytes(&mut v);
             unsafe { mem::transmute(v) }
         }
         fn next_u64(&mut self) -> u64 {
-            let mut v = [0u8; 8];
+            let mut v = [0; 8];
             self.fill_bytes(&mut v);
             unsafe { mem::transmute(v) }
         }
@@ -336,7 +326,8 @@ mod imp {
                                v.as_mut_ptr())
             };
             if ret == 0 {
-                panic!("couldn't generate random bytes: {}", os::last_os_error());
+                panic!("couldn't generate random bytes: {}",
+                       io::Error::last_os_error());
             }
         }
     }
@@ -347,7 +338,8 @@ mod imp {
                 CryptReleaseContext(self.hcryptprov, 0)
             };
             if ret == 0 {
-                panic!("couldn't release context: {}", os::last_os_error());
+                panic!("couldn't release context: {}",
+                       io::Error::last_os_error());
             }
         }
     }
@@ -369,7 +361,7 @@ mod test {
         r.next_u32();
         r.next_u64();
 
-        let mut v = [0u8; 1000];
+        let mut v = [0; 1000];
         r.fill_bytes(&mut v);
     }
 
@@ -389,7 +381,7 @@ mod test {
                 // as possible (XXX: is this a good test?)
                 let mut r = OsRng::new().unwrap();
                 thread::yield_now();
-                let mut v = [0u8; 1000];
+                let mut v = [0; 1000];
 
                 for _ in 0..100 {
                     r.next_u32();
index b71e8b4fd61e8dadebd3d9fa754e559b23ee4532..ece6867ddcaa1e33f3d8639868cb992eecfc1be6 100644 (file)
@@ -13,7 +13,6 @@
 use old_io::Reader;
 use rand::Rng;
 use result::Result::{Ok, Err};
-use slice::SliceExt;
 
 /// An RNG that reads random bytes straight from a `Reader`. This will
 /// work best with an infinite reader, but this is not required.
@@ -22,14 +21,15 @@ use slice::SliceExt;
 ///
 /// It will panic if it there is insufficient data to fulfill a request.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(rand, old_io)]
 /// use std::rand::{reader, Rng};
 /// use std::old_io::MemReader;
 ///
 /// let mut rng = reader::ReaderRng::new(MemReader::new(vec!(1,2,3,4,5,6,7,8)));
-/// println!("{:x}", rng.gen::<uint>());
+/// println!("{:x}", rng.gen::<usize>());
 /// ```
 pub struct ReaderRng<R> {
     reader: R
@@ -84,28 +84,28 @@ mod test {
     #[test]
     fn test_reader_rng_u64() {
         // transmute from the target to avoid endianness concerns.
-        let v = vec![0u8, 0, 0, 0, 0, 0, 0, 1,
+        let v = vec![0, 0, 0, 0, 0, 0, 0, 1,
                      0  , 0, 0, 0, 0, 0, 0, 2,
                      0,   0, 0, 0, 0, 0, 0, 3];
         let mut rng = ReaderRng::new(MemReader::new(v));
 
-        assert_eq!(rng.next_u64(), 1_u64.to_be());
-        assert_eq!(rng.next_u64(), 2_u64.to_be());
-        assert_eq!(rng.next_u64(), 3_u64.to_be());
+        assert_eq!(rng.next_u64(), 1.to_be());
+        assert_eq!(rng.next_u64(), 2.to_be());
+        assert_eq!(rng.next_u64(), 3.to_be());
     }
     #[test]
     fn test_reader_rng_u32() {
-        let v = vec![0u8, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3];
+        let v = vec![0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3];
         let mut rng = ReaderRng::new(MemReader::new(v));
 
-        assert_eq!(rng.next_u32(), 1_u32.to_be());
-        assert_eq!(rng.next_u32(), 2_u32.to_be());
-        assert_eq!(rng.next_u32(), 3_u32.to_be());
+        assert_eq!(rng.next_u32(), 1.to_be());
+        assert_eq!(rng.next_u32(), 2.to_be());
+        assert_eq!(rng.next_u32(), 3.to_be());
     }
     #[test]
     fn test_reader_rng_fill_bytes() {
-        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
-        let mut w = [0u8; 8];
+        let v = [1, 2, 3, 4, 5, 6, 7, 8];
+        let mut w = [0; 8];
 
         let mut rng = ReaderRng::new(MemReader::new(v.to_vec()));
         rng.fill_bytes(&mut w);
@@ -114,10 +114,10 @@ mod test {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_reader_rng_insufficient_bytes() {
         let mut rng = ReaderRng::new(MemReader::new(vec!()));
-        let mut v = [0u8; 3];
+        let mut v = [0; 3];
         rng.fill_bytes(&mut v);
     }
 }
index 61f5bd0f013606f37f2e4476acf3b155c5f7f6af..2329861f29bc06dc6b7428d8ecb9fc560720a573 100644 (file)
@@ -23,7 +23,7 @@ use core::prelude::*;
 use vec::Vec;
 
 /// One-time global initialization.
-pub unsafe fn init(argc: int, argv: *const *const u8) { imp::init(argc, argv) }
+pub unsafe fn init(argc: isize, argv: *const *const u8) { imp::init(argc, argv) }
 
 /// One-time global cleanup.
 pub unsafe fn cleanup() { imp::cleanup() }
@@ -43,6 +43,7 @@ pub fn clone() -> Option<Vec<Vec<u8>>> { imp::clone() }
           target_os = "android",
           target_os = "freebsd",
           target_os = "dragonfly",
+          target_os = "bitrig",
           target_os = "openbsd"))]
 mod imp {
     use prelude::v1::*;
@@ -53,10 +54,10 @@ mod imp {
 
     use sync::{StaticMutex, MUTEX_INIT};
 
-    static mut GLOBAL_ARGS_PTR: uint = 0;
+    static mut GLOBAL_ARGS_PTR: usize = 0;
     static LOCK: StaticMutex = MUTEX_INIT;
 
-    pub unsafe fn init(argc: int, argv: *const *const u8) {
+    pub unsafe fn init(argc: isize, argv: *const *const u8) {
         let args = load_argc_and_argv(argc, argv);
         put(args);
     }
@@ -107,7 +108,6 @@ mod imp {
     #[cfg(test)]
     mod tests {
         use prelude::v1::*;
-        use finally::Finally;
 
         use super::*;
 
@@ -126,14 +126,11 @@ mod imp {
             assert!(take() == Some(expected.clone()));
             assert!(take() == None);
 
-            (|| {
-            }).finally(|| {
-                // Restore the actual global state.
-                match saved_value {
-                    Some(ref args) => put(args.clone()),
-                    None => ()
-                }
-            })
+            // Restore the actual global state.
+            match saved_value {
+                Some(ref args) => put(args.clone()),
+                None => ()
+            }
         }
     }
 }
@@ -145,7 +142,7 @@ mod imp {
     use core::prelude::*;
     use vec::Vec;
 
-    pub unsafe fn init(_argc: int, _argv: *const *const u8) {
+    pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
     }
 
     pub fn cleanup() {
index 72486fc55d48ee91ef09c3e4a73b3908c9d395d0..beb2870807a7e1aab75edf77b704879eb78e50ca 100644 (file)
 //!
 //! Documentation can be found on the `rt::at_exit` function.
 
-use core::prelude::*;
+// FIXME: switch this to use atexit. Currently this
+// segfaults (the queue's memory is mysteriously gone), so
+// instead the cleanup is tied to the `std::rt` entry point.
 
+use boxed;
 use boxed::Box;
 use vec::Vec;
-use mem;
 use thunk::Thunk;
 use sys_common::mutex::{Mutex, MUTEX_INIT};
 
@@ -29,47 +31,56 @@ type Queue = Vec<Thunk<'static>>;
 static LOCK: Mutex = MUTEX_INIT;
 static mut QUEUE: *mut Queue = 0 as *mut Queue;
 
-unsafe fn init() {
+// The maximum number of times the cleanup routines will be run. While running
+// the at_exit closures new ones may be registered, and this count is the number
+// of times the new closures will be allowed to register successfully. After
+// this number of iterations all new registrations will return `false`.
+const ITERS: usize = 10;
+
+unsafe fn init() -> bool {
     if QUEUE.is_null() {
         let state: Box<Queue> = box Vec::new();
-        QUEUE = mem::transmute(state);
-    } else {
+        QUEUE = boxed::into_raw(state);
+    } else if QUEUE as usize == 1 {
         // can't re-init after a cleanup
-        rtassert!(QUEUE as uint != 1);
+        return false
     }
 
-    // FIXME: switch this to use atexit as below. Currently this
-    // segfaults (the queue's memory is mysteriously gone), so
-    // instead the cleanup is tied to the `std::rt` entry point.
-    //
-    // ::libc::atexit(cleanup);
+    return true
 }
 
 pub fn cleanup() {
-    unsafe {
-        LOCK.lock();
-        let queue = QUEUE;
-        QUEUE = 1 as *mut _;
-        LOCK.unlock();
+    for i in 0..ITERS {
+        unsafe {
+            LOCK.lock();
+            let queue = QUEUE;
+            QUEUE = if i == ITERS - 1 {1} else {0} as *mut _;
+            LOCK.unlock();
 
-        // make sure we're not recursively cleaning up
-        rtassert!(queue as uint != 1);
+            // make sure we're not recursively cleaning up
+            rtassert!(queue as usize != 1);
 
-        // If we never called init, not need to cleanup!
-        if queue as uint != 0 {
-            let queue: Box<Queue> = mem::transmute(queue);
-            for to_run in *queue {
-                to_run.invoke(());
+            // If we never called init, not need to cleanup!
+            if queue as usize != 0 {
+                let queue: Box<Queue> = Box::from_raw(queue);
+                for to_run in *queue {
+                    to_run();
+                }
             }
         }
     }
 }
 
-pub fn push(f: Thunk<'static>) {
+pub fn push(f: Thunk<'static>) -> bool {
+    let mut ret = true;
     unsafe {
         LOCK.lock();
-        init();
-        (*QUEUE).push(f);
+        if init() {
+            (*QUEUE).push(f);
+        } else {
+            ret = false;
+        }
         LOCK.unlock();
     }
+    return ret
 }
index 43e3a43f56d3632ce38017ebf3df9511aed42709..4b754bd5f589f22ac3d957986a6fcc536769d9bf 100644 (file)
@@ -25,7 +25,7 @@ use libc;
 
 #[cfg(any(not(target_arch = "arm"), target_os = "ios"))]
 #[repr(C)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum _Unwind_Action {
     _UA_SEARCH_PHASE = 1,
     _UA_CLEANUP_PHASE = 2,
@@ -64,25 +64,25 @@ pub type _Unwind_Exception_Class = u64;
 pub type _Unwind_Word = libc::uintptr_t;
 
 #[cfg(target_arch = "x86")]
-pub const unwinder_private_data_size: uint = 5;
+pub const unwinder_private_data_size: usize = 5;
 
 #[cfg(target_arch = "x86_64")]
-pub const unwinder_private_data_size: uint = 6;
+pub const unwinder_private_data_size: usize = 6;
 
 #[cfg(all(target_arch = "arm", not(target_os = "ios")))]
-pub const unwinder_private_data_size: uint = 20;
+pub const unwinder_private_data_size: usize = 20;
 
 #[cfg(all(target_arch = "arm", target_os = "ios"))]
-pub const unwinder_private_data_size: uint = 5;
+pub const unwinder_private_data_size: usize = 5;
 
 #[cfg(target_arch = "aarch64")]
-pub const unwinder_private_data_size: uint = 2;
+pub const unwinder_private_data_size: usize = 2;
 
 #[cfg(any(target_arch = "mips", target_arch = "mipsel"))]
-pub const unwinder_private_data_size: uint = 2;
+pub const unwinder_private_data_size: usize = 2;
 
 #[cfg(target_arch = "powerpc")]
-pub const unwinder_private_data_size: uint = 2;
+pub const unwinder_private_data_size: usize = 2;
 
 #[repr(C)]
 pub struct _Unwind_Exception {
@@ -109,6 +109,10 @@ extern {}
 #[link(name = "gcc_pic")]
 extern {}
 
+#[cfg(target_os = "bitrig")]
+#[link(name = "c++abi")]
+extern {}
+
 extern "C" {
     // iOS on armv7 uses SjLj exceptions and requires to link
     // against corresponding routine (..._SjLj_...)
index 42cca73e5e24128e2b40b92b64615277aa01da82..0d26206f26bcfc67630547b035b5ff7c66189f2c 100644 (file)
 //! time being.
 
 #![unstable(feature = "std_misc")]
-
-// FIXME: this should not be here.
 #![allow(missing_docs)]
 
-#![allow(dead_code)]
-
-use marker::Send;
-use ops::FnOnce;
+use prelude::v1::*;
 use sys;
-use thunk::Thunk;
+use usize;
 
 // Reexport some of our utilities which are expected by other crates.
-pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
+pub use self::util::{min_stack, running_on_valgrind};
 pub use self::unwind::{begin_unwind, begin_unwind_fmt};
 
 // Reexport some functionality from liballoc.
@@ -52,16 +47,16 @@ mod libunwind;
 
 /// The default error code of the rust runtime if the main thread panics instead
 /// of exiting cleanly.
-pub const DEFAULT_ERROR_CODE: int = 101;
+pub const DEFAULT_ERROR_CODE: isize = 101;
 
 #[cfg(any(windows, android))]
-const OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
+const OS_DEFAULT_STACK_ESTIMATE: usize = 1 << 20;
 #[cfg(all(unix, not(android)))]
-const OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
+const OS_DEFAULT_STACK_ESTIMATE: usize = 2 * (1 << 20);
 
 #[cfg(not(test))]
 #[lang = "start"]
-fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
+fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
     use prelude::v1::*;
 
     use mem;
@@ -72,13 +67,26 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
     use thread::Thread;
 
     let something_around_the_top_of_the_stack = 1;
-    let addr = &something_around_the_top_of_the_stack as *const int;
-    let my_stack_top = addr as uint;
+    let addr = &something_around_the_top_of_the_stack as *const _ as *const isize;
+    let my_stack_top = addr as usize;
 
     // FIXME #11359 we just assume that this thread has a stack of a
     // certain size, and estimate that there's at most 20KB of stack
     // frames above our current position.
-    let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
+    const TWENTY_KB: usize = 20000;
+
+    // saturating-add to sidestep overflow
+    let top_plus_spill = if usize::MAX - TWENTY_KB < my_stack_top {
+        usize::MAX
+    } else {
+        my_stack_top + TWENTY_KB
+    };
+    // saturating-sub to sidestep underflow
+    let my_stack_bottom = if top_plus_spill < OS_DEFAULT_STACK_ESTIMATE {
+        0
+    } else {
+        top_plus_spill - OS_DEFAULT_STACK_ESTIMATE
+    };
 
     let failed = unsafe {
         // First, make sure we don't trigger any __morestack overflow checks,
@@ -94,9 +102,7 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
         // but we just do this to name the main thread and to give it correct
         // info about the stack bounds.
         let thread: Thread = NewThread::new(Some("<main>".to_string()));
-        thread_info::set((my_stack_bottom, my_stack_top),
-                         sys::thread::guard::main(),
-                         thread);
+        thread_info::set(sys::thread::guard::main(), thread);
 
         // By default, some platforms will send a *signal* when a EPIPE error
         // would otherwise be delivered. This runtime doesn't install a SIGPIPE
@@ -110,7 +116,7 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
             use libc;
             use libc::funcs::posix01::signal::signal;
             unsafe {
-                assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != -1);
+                assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != !0);
             }
         }
         ignore_sigpipe();
@@ -135,21 +141,18 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
     }
 }
 
-/// Enqueues a procedure to run when the runtime is cleaned up
-///
-/// The procedure passed to this function will be executed as part of the
-/// runtime cleanup phase. For normal rust programs, this means that it will run
-/// after all other threads have exited.
+/// Enqueues a procedure to run when the main thread exits.
 ///
-/// The procedure is *not* executed with a local `Thread` available to it, so
-/// primitives like logging, I/O, channels, spawning, etc, are *not* available.
-/// This is meant for "bare bones" usage to clean up runtime details, this is
-/// not meant as a general-purpose "let's clean everything up" function.
+/// Currently these closures are only run once the main *Rust* thread exits.
+/// Once the `at_exit` handlers begin running, more may be enqueued, but not
+/// infinitely so. Eventually a handler registration will be forced to fail.
 ///
-/// It is forbidden for procedures to register more `at_exit` handlers when they
-/// are running, and doing so will lead to a process abort.
-pub fn at_exit<F:FnOnce()+Send+'static>(f: F) {
-    at_exit_imp::push(Thunk::new(f));
+/// Returns `Ok` if the handler was successfully registered, meaning that the
+/// closure will be run once the main thread exits. Returns `Err` to indicate
+/// that the closure could not be registered, meaning that it is not scheduled
+/// to be rune.
+pub fn at_exit<F: FnOnce() + Send + 'static>(f: F) -> Result<(), ()> {
+    if at_exit_imp::push(Box::new(f)) {Ok(())} else {Err(())}
 }
 
 /// One-time runtime cleanup.
@@ -164,8 +167,5 @@ pub fn at_exit<F:FnOnce()+Send+'static>(f: F) {
 pub unsafe fn cleanup() {
     args::cleanup();
     sys::stack_overflow::cleanup();
-    // FIXME: (#20012): the resources being cleaned up by at_exit
-    // currently are not prepared for cleanup to happen asynchronously
-    // with detached threads using the resources; for now, we leak.
-    // at_exit_imp::cleanup();
+    at_exit_imp::cleanup();
 }
index 1f5eb3af695be8e09040c92463db3ce950031e97..f71811b1eadf6f0c90567f684a872e9bb749d191 100644 (file)
@@ -60,6 +60,7 @@
 use prelude::v1::*;
 
 use any::Any;
+use boxed;
 use cell::Cell;
 use cmp;
 use panicking;
@@ -68,7 +69,7 @@ use intrinsics;
 use libc::c_void;
 use mem;
 use sync::atomic::{self, Ordering};
-use sync::{Once, ONCE_INIT};
+use sys_common::mutex::{Mutex, MUTEX_INIT};
 
 use rt::libunwind as uw;
 
@@ -77,12 +78,12 @@ struct Exception {
     cause: Option<Box<Any + Send + 'static>>,
 }
 
-pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: uint);
+pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: usize);
 
 // Variables used for invoking callbacks when a thread starts to unwind.
 //
 // For more information, see below.
-const MAX_CALLBACKS: uint = 16;
+const MAX_CALLBACKS: usize = 16;
 static CALLBACKS: [atomic::AtomicUsize; MAX_CALLBACKS] =
         [atomic::ATOMIC_USIZE_INIT, atomic::ATOMIC_USIZE_INIT,
          atomic::ATOMIC_USIZE_INIT, atomic::ATOMIC_USIZE_INIT,
@@ -165,7 +166,7 @@ fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
     rtdebug!("begin_unwind()");
 
     unsafe {
-        let exception = box Exception {
+        let exception: Box<_> = box Exception {
             uwe: uw::_Unwind_Exception {
                 exception_class: rust_exception_class(),
                 exception_cleanup: exception_cleanup,
@@ -173,15 +174,16 @@ fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
             },
             cause: Some(cause),
         };
-        let error = uw::_Unwind_RaiseException(mem::transmute(exception));
-        rtabort!("Could not unwind stack, error = {}", error as int)
+        let exception_param = boxed::into_raw(exception) as *mut uw::_Unwind_Exception;
+        let error = uw::_Unwind_RaiseException(exception_param);
+        rtabort!("Could not unwind stack, error = {}", error as isize)
     }
 
     extern fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
                                 exception: *mut uw::_Unwind_Exception) {
         rtdebug!("exception_cleanup()");
         unsafe {
-            let _: Box<Exception> = mem::transmute(exception);
+            let _: Box<Exception> = Box::from_raw(exception as *mut Exception);
         }
     }
 }
@@ -396,7 +398,7 @@ pub mod eabi {
     pub struct DISPATCHER_CONTEXT;
 
     #[repr(C)]
-    #[derive(Copy)]
+    #[derive(Copy, Clone)]
     pub enum EXCEPTION_DISPOSITION {
         ExceptionContinueExecution,
         ExceptionContinueSearch,
@@ -482,7 +484,7 @@ pub mod eabi {
 /// Entry point of panic from the libcore crate.
 #[lang = "panic_fmt"]
 pub extern fn rust_begin_unwind(msg: fmt::Arguments,
-                                file: &'static str, line: uint) -> ! {
+                                file: &'static str, line: usize) -> ! {
     begin_unwind_fmt(msg, &(file, line))
 }
 
@@ -494,7 +496,7 @@ pub extern fn rust_begin_unwind(msg: fmt::Arguments,
 /// the actual formatting into this shared place.
 #[inline(never)] #[cold]
 #[stable(since = "1.0.0", feature = "rust1")]
-pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
+pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, usize)) -> ! {
     use fmt::Write;
 
     // We do two allocations here, unfortunately. But (a) they're
@@ -504,13 +506,13 @@ pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, uint)) -
 
     let mut s = String::new();
     let _ = write!(&mut s, "{}", msg);
-    begin_unwind_inner(box s, file_line)
+    begin_unwind_inner(Box::new(s), file_line)
 }
 
 /// This is the entry point of unwinding for panic!() and assert!().
 #[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
 #[stable(since = "1.0.0", feature = "rust1")]
-pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, uint)) -> ! {
+pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, usize)) -> ! {
     // Note that this should be the only allocation performed in this code path.
     // Currently this means that panic!() on OOM will invoke this code path,
     // but then again we're not really ready for panic on OOM anyway. If
@@ -519,7 +521,7 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, uint)) ->
     // panicking.
 
     // see below for why we do the `Any` coercion here.
-    begin_unwind_inner(box msg, file_line)
+    begin_unwind_inner(Box::new(msg), file_line)
 }
 
 /// The core of the unwinding.
@@ -532,11 +534,22 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, uint)) ->
 /// Doing this split took the LLVM IR line counts of `fn main() { panic!()
 /// }` from ~1900/3700 (-O/no opts) to 180/590.
 #[inline(never)] #[cold] // this is the slow path, please never inline this
-fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) -> ! {
-    // Make sure the default panic handler is registered before we look at the
-    // callbacks.
-    static INIT: Once = ONCE_INIT;
-    INIT.call_once(|| unsafe { register(panicking::on_panic); });
+fn begin_unwind_inner(msg: Box<Any + Send>,
+                      file_line: &(&'static str, usize)) -> ! {
+    // Make sure the default failure handler is registered before we look at the
+    // callbacks. We also use a raw sys-based mutex here instead of a
+    // `std::sync` one as accessing TLS can cause weird recursive problems (and
+    // we don't need poison checking).
+    unsafe {
+        static LOCK: Mutex = MUTEX_INIT;
+        static mut INIT: bool = false;
+        LOCK.lock();
+        if !INIT {
+            register(panicking::on_panic);
+            INIT = true;
+        }
+        LOCK.unlock();
+    }
 
     // First, invoke call the user-defined callbacks triggered on thread panic.
     //
index a304f1f844d748f8f263fc73db78d984ec38bbe9..5a482fbb50fec1d85f37cb50d13bedabd07f0ac9 100644 (file)
 //
 // ignore-lexer-test FIXME #15677
 
-use prelude::v1::*;
+use io::prelude::*;
 
-use cmp;
 use env;
 use fmt;
 use intrinsics;
-use libc::{self, uintptr_t};
-use os;
-use slice;
-use str;
+use libc::uintptr_t;
 use sync::atomic::{self, Ordering};
+use sys::stdio::Stderr;
 
 /// Dynamically inquire about whether we're running under V.
 /// You should usually not use this unless your test definitely
@@ -46,7 +43,7 @@ pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
     (cfg!(target_os="macos")) && running_on_valgrind()
 }
 
-pub fn min_stack() -> uint {
+pub fn min_stack() -> usize {
     static MIN: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
     match MIN.load(Ordering::SeqCst) {
         0 => {}
@@ -60,27 +57,6 @@ pub fn min_stack() -> uint {
     return amt;
 }
 
-/// Get's the number of scheduler threads requested by the environment
-/// either `RUST_THREADS` or `num_cpus`.
-pub fn default_sched_threads() -> uint {
-    match env::var("RUST_THREADS") {
-        Ok(nstr) => {
-            let opt_n: Option<uint> = nstr.parse().ok();
-            match opt_n {
-                Some(n) if n > 0 => n,
-                _ => panic!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
-            }
-        }
-        Err(..) => {
-            if limit_thread_creation_due_to_osx_and_valgrind() {
-                1
-            } else {
-                os::num_cpus()
-            }
-        }
-    }
-}
-
 // Indicates whether we should perform expensive sanity checks, including rtassert!
 //
 // FIXME: Once the runtime matures remove the `true` below to turn off rtassert,
@@ -88,76 +64,17 @@ pub fn default_sched_threads() -> uint {
 pub const ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) ||
                                   cfg!(rtassert);
 
-pub struct Stdio(libc::c_int);
-
-#[allow(non_upper_case_globals)]
-pub const Stdout: Stdio = Stdio(libc::STDOUT_FILENO);
-#[allow(non_upper_case_globals)]
-pub const Stderr: Stdio = Stdio(libc::STDERR_FILENO);
-
-impl Stdio {
-    pub fn write_bytes(&mut self, data: &[u8]) {
-        #[cfg(unix)]
-        type WriteLen = libc::size_t;
-        #[cfg(windows)]
-        type WriteLen = libc::c_uint;
-        unsafe {
-            let Stdio(fd) = *self;
-            libc::write(fd,
-                        data.as_ptr() as *const libc::c_void,
-                        data.len() as WriteLen);
-        }
-    }
-}
-
-impl fmt::Write for Stdio {
-    fn write_str(&mut self, data: &str) -> fmt::Result {
-        self.write_bytes(data.as_bytes());
-        Ok(()) // yes, we're lying
-    }
-}
-
 pub fn dumb_print(args: fmt::Arguments) {
-    let _ = Stderr.write_fmt(args);
+    let _ = write!(&mut Stderr::new(), "{}", args);
 }
 
 pub fn abort(args: fmt::Arguments) -> ! {
-    use fmt::Write;
-
-    struct BufWriter<'a> {
-        buf: &'a mut [u8],
-        pos: uint,
-    }
-    impl<'a> fmt::Write for BufWriter<'a> {
-        fn write_str(&mut self, bytes: &str) -> fmt::Result {
-            let left = &mut self.buf[self.pos..];
-            let to_write = &bytes.as_bytes()[..cmp::min(bytes.len(), left.len())];
-            slice::bytes::copy_memory(left, to_write);
-            self.pos += to_write.len();
-            Ok(())
-        }
-    }
-
-    // Convert the arguments into a stack-allocated string
-    let mut msg = [0u8; 512];
-    let mut w = BufWriter { buf: &mut msg, pos: 0 };
-    let _ = write!(&mut w, "{}", args);
-    let msg = str::from_utf8(&w.buf[..w.pos]).unwrap_or("aborted");
-    let msg = if msg.is_empty() {"aborted"} else {msg};
-    rterrln!("fatal runtime error: {}", msg);
+    rterrln!("fatal runtime error: {}", args);
     unsafe { intrinsics::abort(); }
 }
 
 pub unsafe fn report_overflow() {
     use thread;
-
-    // See the message below for why this is not emitted to the
-    // ^ Where did the message below go?
-    // task's logger. This has the additional conundrum of the
-    // logger may not be initialized just yet, meaning that an FFI
-    // call would happen to initialized it (calling out to libuv),
-    // and the FFI call needs 2MB of stack when we just ran out.
-
     rterrln!("\nthread '{}' has overflowed its stack",
              thread::current().name().unwrap_or("<unknown>"));
 }
index 1392bc815c4f9d68d31a93aa47ae87e3a72af478..96c4bcec853dc28d8d687eae95b3b1e64f9f5a22 100644 (file)
@@ -39,7 +39,9 @@ extern {}
 #[link(name = "pthread")]
 extern {}
 
-#[cfg(any(target_os = "dragonfly", target_os = "openbsd"))]
+#[cfg(any(target_os = "dragonfly",
+          target_os = "bitrig",
+          target_os = "openbsd"))]
 #[link(name = "pthread")]
 extern {}
 
index b036177af153a50da6ff9f4951ae7ea69d4cdffa..ebf4d3377499e99188b372b54ec5ff091ff6bc2a 100644 (file)
@@ -13,7 +13,7 @@ use sync::{Mutex, Condvar};
 /// A barrier enables multiple tasks to synchronize the beginning
 /// of some computation.
 ///
-/// ```rust
+/// ```
 /// use std::sync::{Arc, Barrier};
 /// use std::thread;
 ///
@@ -33,13 +33,13 @@ use sync::{Mutex, Condvar};
 pub struct Barrier {
     lock: Mutex<BarrierState>,
     cvar: Condvar,
-    num_threads: uint,
+    num_threads: usize,
 }
 
 // The inner state of a double barrier
 struct BarrierState {
-    count: uint,
-    generation_id: uint,
+    count: usize,
+    generation_id: usize,
 }
 
 /// A result returned from wait.
@@ -54,7 +54,7 @@ impl Barrier {
     /// A barrier will block `n`-1 threads which call `wait` and then wake up
     /// all threads at once when the `n`th thread calls `wait`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new(n: uint) -> Barrier {
+    pub fn new(n: usize) -> Barrier {
         Barrier {
             lock: Mutex::new(BarrierState {
                 count: 0,
@@ -115,7 +115,7 @@ mod tests {
 
     #[test]
     fn test_barrier() {
-        const N: uint = 10;
+        const N: usize = 10;
 
         let barrier = Arc::new(Barrier::new(N));
         let (tx, rx) = channel();
index 52561d482c39dcc4b5acf9a05de030865870b91d..a7d8b287a64c031567a8605f50c69fb8ef6dc9a8 100644 (file)
@@ -34,7 +34,7 @@ use sync::{mutex, MutexGuard, PoisonError};
 /// in a runtime panic. If this is not desired, then the unsafe primitives in
 /// `sys` do not have this restriction but may result in undefined behavior.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// use std::sync::{Arc, Mutex, Condvar};
@@ -61,17 +61,15 @@ use sync::{mutex, MutexGuard, PoisonError};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Condvar { inner: Box<StaticCondvar> }
 
-unsafe impl Send for Condvar {}
-unsafe impl Sync for Condvar {}
-
 /// Statically allocated condition variables.
 ///
 /// This structure is identical to `Condvar` except that it is suitable for use
 /// in static initializers for other structures.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
+/// # #![feature(std_misc)]
 /// use std::sync::{StaticCondvar, CONDVAR_INIT};
 ///
 /// static CVAR: StaticCondvar = CONDVAR_INIT;
@@ -83,9 +81,6 @@ pub struct StaticCondvar {
     mutex: AtomicUsize,
 }
 
-unsafe impl Send for StaticCondvar {}
-unsafe impl Sync for StaticCondvar {}
-
 /// Constant initializer for a statically allocated condition variable.
 #[unstable(feature = "std_misc",
            reason = "may be merged with Condvar in the future")]
@@ -145,33 +140,43 @@ impl Condvar {
     /// Wait on this condition variable for a notification, timing out after a
     /// specified duration.
     ///
-    /// The semantics of this function are equivalent to `wait()` except that
-    /// the thread will be blocked for roughly no longer than `dur`. This method
-    /// should not be used for precise timing due to anomalies such as
-    /// preemption or platform differences that may not cause the maximum amount
-    /// of time waited to be precisely `dur`.
+    /// The semantics of this function are equivalent to `wait()`
+    /// except that the thread will be blocked for roughly no longer
+    /// than `ms` milliseconds. This method should not be used for
+    /// precise timing due to anomalies such as preemption or platform
+    /// differences that may not cause the maximum amount of time
+    /// waited to be precisely `ms`.
     ///
-    /// If the wait timed out, then `false` will be returned. Otherwise if a
-    /// notification was received then `true` will be returned.
+    /// The returned boolean is `false` only if the timeout is known
+    /// to have elapsed.
     ///
     /// Like `wait`, the lock specified will be re-acquired when this function
     /// returns, regardless of whether the timeout elapsed or not.
-    #[unstable(feature = "std_misc")]
-    pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>, dur: Duration)
-                           -> LockResult<(MutexGuard<'a, T>, bool)> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn wait_timeout_ms<'a, T>(&self, guard: MutexGuard<'a, T>, ms: u32)
+                                  -> LockResult<(MutexGuard<'a, T>, bool)> {
         unsafe {
             let me: &'static Condvar = &*(self as *const _);
-            me.inner.wait_timeout(guard, dur)
+            me.inner.wait_timeout_ms(guard, ms)
         }
     }
 
+    /// Deprecated: use `wait_timeout_ms` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0", reason = "use wait_timeout_ms instead")]
+    pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>, dur: Duration)
+                               -> LockResult<(MutexGuard<'a, T>, bool)> {
+        self.wait_timeout_ms(guard, dur.num_milliseconds() as u32)
+    }
+
     /// Wait on this condition variable for a notification, timing out after a
     /// specified duration.
     ///
     /// The semantics of this function are equivalent to `wait_timeout` except
     /// that the implementation will repeatedly wait while the duration has not
     /// passed and the provided function returns `false`.
-    #[unstable(feature = "std_misc")]
+    #[unstable(feature = "wait_timeout_with",
+               reason = "unsure if this API is broadly needed or what form it should take")]
     pub fn wait_timeout_with<'a, T, F>(&self,
                                        guard: MutexGuard<'a, T>,
                                        dur: Duration,
@@ -240,12 +245,12 @@ impl StaticCondvar {
     /// See `Condvar::wait_timeout`.
     #[unstable(feature = "std_misc",
                reason = "may be merged with Condvar in the future")]
-    pub fn wait_timeout<'a, T>(&'static self, guard: MutexGuard<'a, T>, dur: Duration)
-                               -> LockResult<(MutexGuard<'a, T>, bool)> {
+    pub fn wait_timeout_ms<'a, T>(&'static self, guard: MutexGuard<'a, T>, ms: u32)
+                                  -> LockResult<(MutexGuard<'a, T>, bool)> {
         let (poisoned, success) = unsafe {
             let lock = mutex::guard_lock(&guard);
             self.verify(lock);
-            let success = self.inner.wait_timeout(lock, dur);
+            let success = self.inner.wait_timeout(lock, Duration::milliseconds(ms as i64));
             (mutex::guard_poison(&guard).get(), success)
         };
         if poisoned {
@@ -280,7 +285,8 @@ impl StaticCondvar {
             let now = SteadyTime::now();
             let consumed = &now - &start;
             let guard = guard_result.unwrap_or_else(|e| e.into_inner());
-            let (new_guard_result, no_timeout) = match self.wait_timeout(guard, dur - consumed) {
+            let res = self.wait_timeout_ms(guard, (dur - consumed).num_milliseconds() as u32);
+            let (new_guard_result, no_timeout) = match res {
                 Ok((new_guard, no_timeout)) => (Ok(new_guard), no_timeout),
                 Err(err) => {
                     let (new_guard, no_timeout) = err.into_inner();
@@ -327,7 +333,7 @@ impl StaticCondvar {
     }
 
     fn verify(&self, mutex: &sys_mutex::Mutex) {
-        let addr = mutex as *const _ as uint;
+        let addr = mutex as *const _ as usize;
         match self.mutex.compare_and_swap(0, addr, Ordering::SeqCst) {
             // If we got out 0, then we have successfully bound the mutex to
             // this cvar.
@@ -355,6 +361,7 @@ mod tests {
     use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
     use thread;
     use time::Duration;
+    use u32;
 
     #[test]
     fn smoke() {
@@ -388,7 +395,7 @@ mod tests {
 
     #[test]
     fn notify_all() {
-        const N: uint = 10;
+        const N: usize = 10;
 
         let data = Arc::new((Mutex::new(0), Condvar::new()));
         let (tx, rx) = channel();
@@ -423,19 +430,19 @@ mod tests {
     }
 
     #[test]
-    fn wait_timeout() {
+    fn wait_timeout_ms() {
         static C: StaticCondvar = CONDVAR_INIT;
         static M: StaticMutex = MUTEX_INIT;
 
         let g = M.lock().unwrap();
-        let (g, _no_timeout) = C.wait_timeout(g, Duration::nanoseconds(1000)).unwrap();
+        let (g, _no_timeout) = C.wait_timeout_ms(g, 1).unwrap();
         // spurious wakeups mean this isn't necessarily true
         // assert!(!no_timeout);
         let _t = thread::spawn(move || {
             let _g = M.lock().unwrap();
             C.notify_one();
         });
-        let (g, no_timeout) = C.wait_timeout(g, Duration::days(1)).unwrap();
+        let (g, no_timeout) = C.wait_timeout_ms(g, u32::MAX).unwrap();
         assert!(no_timeout);
         drop(g);
         unsafe { C.destroy(); M.destroy(); }
@@ -485,7 +492,7 @@ mod tests {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn two_mutexes() {
         static M1: StaticMutex = MUTEX_INIT;
         static M2: StaticMutex = MUTEX_INIT;
index d60e27388086444a4323c8f53525a8046b28ecec..2cdde1aca9e682c7696d67ffad62c8f45adaa043 100644 (file)
@@ -14,6 +14,7 @@
 //! # Examples
 //!
 //! ```
+//! # #![feature(std_misc)]
 //! use std::sync::Future;
 //!
 //! // a fake, for now
 use core::prelude::*;
 use core::mem::replace;
 
+use boxed::Box;
 use self::FutureState::*;
 use sync::mpsc::{Receiver, channel};
-use thunk::{Thunk};
+use thunk::Thunk;
 use thread;
 
 /// A type encapsulating the result of a computation which may not be complete
@@ -83,7 +85,7 @@ impl<A> Future<A> {
                 match replace(&mut self.state, Evaluating) {
                     Forced(_) | Evaluating => panic!("Logic error."),
                     Pending(f) => {
-                        self.state = Forced(f.invoke(()));
+                        self.state = Forced(f());
                         self.get_ref()
                     }
                 }
@@ -113,7 +115,7 @@ impl<A> Future<A> {
          * function. It is not spawned into another task.
          */
 
-        Future {state: Pending(Thunk::new(f))}
+        Future {state: Pending(Box::new(f))}
     }
 }
 
@@ -204,7 +206,7 @@ mod test {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_future_panic() {
         let mut f = Future::spawn(move|| panic!());
         let _x: String = f.get();
index f3b721438d807a2872f2fa706e441ebc2df3a3f2..a5259a00390f55369a7e737781fe0f6c00f52e34 100644 (file)
@@ -31,7 +31,6 @@ pub use self::barrier::{Barrier, BarrierWaitResult};
 pub use self::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
 
 pub use self::future::Future;
-pub use self::task_pool::TaskPool;
 
 pub mod mpsc;
 
@@ -43,4 +42,3 @@ mod once;
 mod poison;
 mod rwlock;
 mod semaphore;
-mod task_pool;
index 69b1e242b154d472857c032aab0ff00cdec3366c..2e4155ea35128d070c7854e304a40b58a30a87ac 100644 (file)
@@ -61,17 +61,17 @@ impl SignalToken {
         wake
     }
 
-    /// Convert to an unsafe uint value. Useful for storing in a pipe's state
+    /// Convert to an unsafe usize value. Useful for storing in a pipe's state
     /// flag.
     #[inline]
-    pub unsafe fn cast_to_uint(self) -> uint {
+    pub unsafe fn cast_to_usize(self) -> usize {
         mem::transmute(self.inner)
     }
 
-    /// Convert from an unsafe uint value. Useful for retrieving a pipe's state
+    /// Convert from an unsafe usize value. Useful for retrieving a pipe's state
     /// flag.
     #[inline]
-    pub unsafe fn cast_from_uint(signal_ptr: uint) -> SignalToken {
+    pub unsafe fn cast_from_usize(signal_ptr: usize) -> SignalToken {
         SignalToken { inner: mem::transmute(signal_ptr) }
     }
 
index 21993e51669d359789f04767c4911391c36350cb..c80182ec07d3223df0b61929e50acf163a9b06a6 100644 (file)
@@ -94,7 +94,7 @@
 //!
 //! // The call to recv() will return an error because the channel has already
 //! // hung up (or been deallocated)
-//! let (tx, rx) = channel::<int>();
+//! let (tx, rx) = channel::<i32>();
 //! drop(tx);
 //! assert!(rx.recv().is_err());
 //! ```
 //! use std::thread;
 //! use std::sync::mpsc::sync_channel;
 //!
-//! let (tx, rx) = sync_channel::<int>(0);
+//! let (tx, rx) = sync_channel::<i32>(0);
 //! thread::spawn(move|| {
 //!     // This will wait for the parent task to start receiving
 //!     tx.send(53).unwrap();
 //! ```
 //!
 //! Reading from a channel with a timeout requires to use a Timer together
-//! with the channel. You can use the select! macro to select either and
+//! with the channel. You can use the `select!` macro to select either and
 //! handle the timeout case. This first example will break out of the loop
 //! after 10 seconds no matter what:
 //!
 //! ```no_run
+//! # #![feature(std_misc, old_io)]
 //! use std::sync::mpsc::channel;
 //! use std::old_io::timer::Timer;
 //! use std::time::Duration;
 //!
-//! let (tx, rx) = channel::<int>();
+//! let (tx, rx) = channel::<i32>();
 //! let mut timer = Timer::new().unwrap();
 //! let timeout = timer.oneshot(Duration::seconds(10));
 //!
 //! has been inactive for 5 seconds:
 //!
 //! ```no_run
+//! # #![feature(std_misc, old_io)]
 //! use std::sync::mpsc::channel;
 //! use std::old_io::timer::Timer;
 //! use std::time::Duration;
 //!
-//! let (tx, rx) = channel::<int>();
+//! let (tx, rx) = channel::<i32>();
 //! let mut timer = Timer::new().unwrap();
 //!
 //! loop {
 use prelude::v1::*;
 
 use sync::Arc;
+use error;
 use fmt;
 use mem;
 use cell::UnsafeCell;
@@ -345,13 +348,13 @@ pub struct Receiver<T> {
 
 // The receiver port can be sent from place to place, so long as it
 // is not used to receive non-sendable things.
-unsafe impl<T: Send + 'static> Send for Receiver<T> { }
+unsafe impl<T: Send> Send for Receiver<T> { }
 
 /// An iterator over messages on a receiver, this iterator will block
 /// whenever `next` is called, waiting for a new message, and `None` will be
 /// returned when the corresponding channel has hung up.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct Iter<'a, T:'a> {
+pub struct Iter<'a, T: 'a> {
     rx: &'a Receiver<T>
 }
 
@@ -364,7 +367,7 @@ pub struct Sender<T> {
 
 // The send port can be sent from place to place, so long as it
 // is not used to send non-sendable things.
-unsafe impl<T: Send + 'static> Send for Sender<T> { }
+unsafe impl<T: Send> Send for Sender<T> { }
 
 /// The sending-half of Rust's synchronous channel type. This half can only be
 /// owned by one task, but it can be cloned to send to other tasks.
@@ -373,7 +376,7 @@ pub struct SyncSender<T> {
     inner: Arc<UnsafeCell<sync::Packet<T>>>,
 }
 
-unsafe impl<T: Send + 'static> Send for SyncSender<T> {}
+unsafe impl<T: Send> Send for SyncSender<T> {}
 
 impl<T> !Sync for SyncSender<T> {}
 
@@ -384,7 +387,7 @@ impl<T> !Sync for SyncSender<T> {}
 /// contains the data being sent as a payload so it can be recovered.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(PartialEq, Eq, Clone, Copy)]
-pub struct SendError<T>(pub T);
+pub struct SendError<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
 
 /// An error returned from the `recv` function on a `Receiver`.
 ///
@@ -463,7 +466,7 @@ impl<T> UnsafeFlavor<T> for Receiver<T> {
 /// All data sent on the sender will become available on the receiver, and no
 /// send will block the calling task (this channel has an "infinite buffer").
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// use std::sync::mpsc::channel;
@@ -485,7 +488,7 @@ impl<T> UnsafeFlavor<T> for Receiver<T> {
 /// println!("{:?}", rx.recv().unwrap());
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn channel<T: Send + 'static>() -> (Sender<T>, Receiver<T>) {
+pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
     let a = Arc::new(UnsafeCell::new(oneshot::Packet::new()));
     (Sender::new(Flavor::Oneshot(a.clone())), Receiver::new(Flavor::Oneshot(a)))
 }
@@ -505,7 +508,7 @@ pub fn channel<T: Send + 'static>() -> (Sender<T>, Receiver<T>) {
 /// As with asynchronous channels, all senders will panic in `send` if the
 /// `Receiver` has been destroyed.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
 /// use std::sync::mpsc::sync_channel;
@@ -525,7 +528,7 @@ pub fn channel<T: Send + 'static>() -> (Sender<T>, Receiver<T>) {
 /// assert_eq!(rx.recv().unwrap(), 2);
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn sync_channel<T: Send + 'static>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
+pub fn sync_channel<T>(bound: usize) -> (SyncSender<T>, Receiver<T>) {
     let a = Arc::new(UnsafeCell::new(sync::Packet::new(bound)));
     (SyncSender::new(a.clone()), Receiver::new(Flavor::Sync(a)))
 }
@@ -534,7 +537,7 @@ pub fn sync_channel<T: Send + 'static>(bound: uint) -> (SyncSender<T>, Receiver<
 // Sender
 ////////////////////////////////////////////////////////////////////////////////
 
-impl<T: Send + 'static> Sender<T> {
+impl<T> Sender<T> {
     fn new(inner: Flavor<T>) -> Sender<T> {
         Sender {
             inner: UnsafeCell::new(inner),
@@ -554,7 +557,7 @@ impl<T: Send + 'static> Sender<T> {
     ///
     /// This method will never block the current thread.
     ///
-    /// # Example
+    /// # Examples
     ///
     /// ```
     /// use std::sync::mpsc::channel;
@@ -591,7 +594,7 @@ impl<T: Send + 'static> Sender<T> {
                                 // asleep (we're looking at it), so the receiver
                                 // can't go away.
                                 (*a.get()).send(t).ok().unwrap();
-                        token.signal();
+                                token.signal();
                                 (a, Ok(()))
                             }
                         }
@@ -616,7 +619,7 @@ impl<T: Send + 'static> Sender<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send + 'static> Clone for Sender<T> {
+impl<T> Clone for Sender<T> {
     fn clone(&self) -> Sender<T> {
         let (packet, sleeper, guard) = match *unsafe { self.inner() } {
             Flavor::Oneshot(ref p) => {
@@ -662,7 +665,7 @@ impl<T: Send + 'static> Clone for Sender<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send + 'static> Drop for Sender<T> {
+impl<T> Drop for Sender<T> {
     fn drop(&mut self) {
         match *unsafe { self.inner_mut() } {
             Flavor::Oneshot(ref mut p) => unsafe { (*p.get()).drop_chan(); },
@@ -677,7 +680,7 @@ impl<T: Send + 'static> Drop for Sender<T> {
 // SyncSender
 ////////////////////////////////////////////////////////////////////////////////
 
-impl<T: Send + 'static> SyncSender<T> {
+impl<T> SyncSender<T> {
     fn new(inner: Arc<UnsafeCell<sync::Packet<T>>>) -> SyncSender<T> {
         SyncSender { inner: inner }
     }
@@ -717,7 +720,7 @@ impl<T: Send + 'static> SyncSender<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send + 'static> Clone for SyncSender<T> {
+impl<T> Clone for SyncSender<T> {
     fn clone(&self) -> SyncSender<T> {
         unsafe { (*self.inner.get()).clone_chan(); }
         return SyncSender::new(self.inner.clone());
@@ -726,7 +729,7 @@ impl<T: Send + 'static> Clone for SyncSender<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send + 'static> Drop for SyncSender<T> {
+impl<T> Drop for SyncSender<T> {
     fn drop(&mut self) {
         unsafe { (*self.inner.get()).drop_chan(); }
     }
@@ -736,7 +739,7 @@ impl<T: Send + 'static> Drop for SyncSender<T> {
 // Receiver
 ////////////////////////////////////////////////////////////////////////////////
 
-impl<T: Send + 'static> Receiver<T> {
+impl<T> Receiver<T> {
     fn new(inner: Flavor<T>) -> Receiver<T> {
         Receiver { inner: UnsafeCell::new(inner) }
     }
@@ -855,7 +858,7 @@ impl<T: Send + 'static> Receiver<T> {
     }
 }
 
-impl<T: Send + 'static> select::Packet for Receiver<T> {
+impl<T> select::Packet for Receiver<T> {
     fn can_recv(&self) -> bool {
         loop {
             let new_port = match *unsafe { self.inner() } {
@@ -942,7 +945,7 @@ impl<T: Send + 'static> select::Packet for Receiver<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: Send + 'static> Iterator for Iter<'a, T> {
+impl<'a, T> Iterator for Iter<'a, T> {
     type Item = T;
 
     fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
@@ -950,7 +953,7 @@ impl<'a, T: Send + 'static> Iterator for Iter<'a, T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send + 'static> Drop for Receiver<T> {
+impl<T> Drop for Receiver<T> {
     fn drop(&mut self) {
         match *unsafe { self.inner_mut() } {
             Flavor::Oneshot(ref mut p) => unsafe { (*p.get()).drop_port(); },
@@ -975,6 +978,18 @@ impl<T> fmt::Display for SendError<T> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Send> error::Error for SendError<T> {
+
+    fn description(&self) -> &str {
+        "sending on a closed channel"
+    }
+
+    fn cause(&self) -> Option<&error::Error> {
+        None
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> fmt::Debug for TrySendError<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -999,6 +1014,25 @@ impl<T> fmt::Display for TrySendError<T> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Send> error::Error for TrySendError<T> {
+
+    fn description(&self) -> &str {
+        match *self {
+            TrySendError::Full(..) => {
+                "sending on a full channel"
+            }
+            TrySendError::Disconnected(..) => {
+                "sending on a closed channel"
+            }
+        }
+    }
+
+    fn cause(&self) -> Option<&error::Error> {
+        None
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for RecvError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -1006,6 +1040,18 @@ impl fmt::Display for RecvError {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl error::Error for RecvError {
+
+    fn description(&self) -> &str {
+        "receiving on a closed channel"
+    }
+
+    fn cause(&self) -> Option<&error::Error> {
+        None
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for TryRecvError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -1020,6 +1066,25 @@ impl fmt::Display for TryRecvError {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl error::Error for TryRecvError {
+
+    fn description(&self) -> &str {
+        match *self {
+            TryRecvError::Empty => {
+                "receiving on an empty channel"
+            }
+            TryRecvError::Disconnected => {
+                "receiving on a closed channel"
+            }
+        }
+    }
+
+    fn cause(&self) -> Option<&error::Error> {
+        None
+    }
+}
+
 #[cfg(test)]
 mod test {
     use prelude::v1::*;
@@ -1028,7 +1093,7 @@ mod test {
     use super::*;
     use thread;
 
-    pub fn stress_factor() -> uint {
+    pub fn stress_factor() -> usize {
         match env::var("RUST_TEST_STRESS") {
             Ok(val) => val.parse().unwrap(),
             Err(..) => 1,
@@ -1037,20 +1102,20 @@ mod test {
 
     #[test]
     fn smoke() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         tx.send(1).unwrap();
         assert_eq!(rx.recv().unwrap(), 1);
     }
 
     #[test]
     fn drop_full() {
-        let (tx, _rx) = channel();
+        let (tx, _rx) = channel::<Box<isize>>();
         tx.send(box 1).unwrap();
     }
 
     #[test]
     fn drop_full_shared() {
-        let (tx, _rx) = channel();
+        let (tx, _rx) = channel::<Box<isize>>();
         drop(tx.clone());
         drop(tx.clone());
         tx.send(box 1).unwrap();
@@ -1058,7 +1123,7 @@ mod test {
 
     #[test]
     fn smoke_shared() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         tx.send(1).unwrap();
         assert_eq!(rx.recv().unwrap(), 1);
         let tx = tx.clone();
@@ -1068,7 +1133,7 @@ mod test {
 
     #[test]
     fn smoke_threads() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         let _t = thread::spawn(move|| {
             tx.send(1).unwrap();
         });
@@ -1077,21 +1142,21 @@ mod test {
 
     #[test]
     fn smoke_port_gone() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         drop(rx);
         assert!(tx.send(1).is_err());
     }
 
     #[test]
     fn smoke_shared_port_gone() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         drop(rx);
         assert!(tx.send(1).is_err())
     }
 
     #[test]
     fn smoke_shared_port_gone2() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         drop(rx);
         let tx2 = tx.clone();
         drop(tx);
@@ -1100,7 +1165,7 @@ mod test {
 
     #[test]
     fn port_gone_concurrent() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         let _t = thread::spawn(move|| {
             rx.recv().unwrap();
         });
@@ -1109,7 +1174,7 @@ mod test {
 
     #[test]
     fn port_gone_concurrent_shared() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         let tx2 = tx.clone();
         let _t = thread::spawn(move|| {
             rx.recv().unwrap();
@@ -1119,7 +1184,7 @@ mod test {
 
     #[test]
     fn smoke_chan_gone() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         drop(tx);
         assert!(rx.recv().is_err());
     }
@@ -1135,7 +1200,7 @@ mod test {
 
     #[test]
     fn chan_gone_concurrent() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         let _t = thread::spawn(move|| {
             tx.send(1).unwrap();
             tx.send(1).unwrap();
@@ -1145,7 +1210,7 @@ mod test {
 
     #[test]
     fn stress() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         let t = thread::spawn(move|| {
             for _ in 0..10000 { tx.send(1).unwrap(); }
         });
@@ -1157,9 +1222,9 @@ mod test {
 
     #[test]
     fn stress_shared() {
-        static AMT: uint = 10000;
-        static NTHREADS: uint = 8;
-        let (tx, rx) = channel::<int>();
+        const AMT: u32 = 10000;
+        const NTHREADS: u32 = 8;
+        let (tx, rx) = channel::<i32>();
 
         let t = thread::spawn(move|| {
             for _ in 0..AMT * NTHREADS {
@@ -1184,7 +1249,7 @@ mod test {
     #[test]
     fn send_from_outside_runtime() {
         let (tx1, rx1) = channel::<()>();
-        let (tx2, rx2) = channel::<int>();
+        let (tx2, rx2) = channel::<i32>();
         let t1 = thread::spawn(move|| {
             tx1.send(()).unwrap();
             for _ in 0..40 {
@@ -1203,7 +1268,7 @@ mod test {
 
     #[test]
     fn recv_from_outside_runtime() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         let t = thread::spawn(move|| {
             for _ in 0..40 {
                 assert_eq!(rx.recv().unwrap(), 1);
@@ -1217,8 +1282,8 @@ mod test {
 
     #[test]
     fn no_runtime() {
-        let (tx1, rx1) = channel::<int>();
-        let (tx2, rx2) = channel::<int>();
+        let (tx1, rx1) = channel::<i32>();
+        let (tx2, rx2) = channel::<i32>();
         let t1 = thread::spawn(move|| {
             assert_eq!(rx1.recv().unwrap(), 1);
             tx2.send(2).unwrap();
@@ -1234,21 +1299,21 @@ mod test {
     #[test]
     fn oneshot_single_thread_close_port_first() {
         // Simple test of closing without sending
-        let (_tx, rx) = channel::<int>();
+        let (_tx, rx) = channel::<i32>();
         drop(rx);
     }
 
     #[test]
     fn oneshot_single_thread_close_chan_first() {
         // Simple test of closing without sending
-        let (tx, _rx) = channel::<int>();
+        let (tx, _rx) = channel::<i32>();
         drop(tx);
     }
 
     #[test]
     fn oneshot_single_thread_send_port_close() {
         // Testing that the sender cleans up the payload if receiver is closed
-        let (tx, rx) = channel::<Box<int>>();
+        let (tx, rx) = channel::<Box<i32>>();
         drop(rx);
         assert!(tx.send(box 0).is_err());
     }
@@ -1257,7 +1322,7 @@ mod test {
     fn oneshot_single_thread_recv_chan_close() {
         // Receiving on a closed chan will panic
         let res = thread::spawn(move|| {
-            let (tx, rx) = channel::<int>();
+            let (tx, rx) = channel::<i32>();
             drop(tx);
             rx.recv().unwrap();
         }).join();
@@ -1267,42 +1332,42 @@ mod test {
 
     #[test]
     fn oneshot_single_thread_send_then_recv() {
-        let (tx, rx) = channel::<Box<int>>();
+        let (tx, rx) = channel::<Box<i32>>();
         tx.send(box 10).unwrap();
         assert!(rx.recv().unwrap() == box 10);
     }
 
     #[test]
     fn oneshot_single_thread_try_send_open() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         assert!(tx.send(10).is_ok());
         assert!(rx.recv().unwrap() == 10);
     }
 
     #[test]
     fn oneshot_single_thread_try_send_closed() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         drop(rx);
         assert!(tx.send(10).is_err());
     }
 
     #[test]
     fn oneshot_single_thread_try_recv_open() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         tx.send(10).unwrap();
         assert!(rx.recv() == Ok(10));
     }
 
     #[test]
     fn oneshot_single_thread_try_recv_closed() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         drop(tx);
         assert!(rx.recv().is_err());
     }
 
     #[test]
     fn oneshot_single_thread_peek_data() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
         tx.send(10).unwrap();
         assert_eq!(rx.try_recv(), Ok(10));
@@ -1310,7 +1375,7 @@ mod test {
 
     #[test]
     fn oneshot_single_thread_peek_close() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         drop(tx);
         assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
         assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
@@ -1318,13 +1383,13 @@ mod test {
 
     #[test]
     fn oneshot_single_thread_peek_open() {
-        let (_tx, rx) = channel::<int>();
+        let (_tx, rx) = channel::<i32>();
         assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
     }
 
     #[test]
     fn oneshot_multi_task_recv_then_send() {
-        let (tx, rx) = channel::<Box<int>>();
+        let (tx, rx) = channel::<Box<i32>>();
         let _t = thread::spawn(move|| {
             assert!(rx.recv().unwrap() == box 10);
         });
@@ -1334,7 +1399,7 @@ mod test {
 
     #[test]
     fn oneshot_multi_task_recv_then_close() {
-        let (tx, rx) = channel::<Box<int>>();
+        let (tx, rx) = channel::<Box<i32>>();
         let _t = thread::spawn(move|| {
             drop(tx);
         });
@@ -1347,7 +1412,7 @@ mod test {
     #[test]
     fn oneshot_multi_thread_close_stress() {
         for _ in 0..stress_factor() {
-            let (tx, rx) = channel::<int>();
+            let (tx, rx) = channel::<i32>();
             let _t = thread::spawn(move|| {
                 drop(rx);
             });
@@ -1358,7 +1423,7 @@ mod test {
     #[test]
     fn oneshot_multi_thread_send_close_stress() {
         for _ in 0..stress_factor() {
-            let (tx, rx) = channel::<int>();
+            let (tx, rx) = channel::<i32>();
             let _t = thread::spawn(move|| {
                 drop(rx);
             });
@@ -1371,7 +1436,7 @@ mod test {
     #[test]
     fn oneshot_multi_thread_recv_close_stress() {
         for _ in 0..stress_factor() {
-            let (tx, rx) = channel::<int>();
+            let (tx, rx) = channel::<i32>();
             thread::spawn(move|| {
                 let res = thread::spawn(move|| {
                     rx.recv().unwrap();
@@ -1389,7 +1454,7 @@ mod test {
     #[test]
     fn oneshot_multi_thread_send_recv_stress() {
         for _ in 0..stress_factor() {
-            let (tx, rx) = channel();
+            let (tx, rx) = channel::<Box<isize>>();
             let _t = thread::spawn(move|| {
                 tx.send(box 10).unwrap();
             });
@@ -1405,7 +1470,7 @@ mod test {
             send(tx, 0);
             recv(rx, 0);
 
-            fn send(tx: Sender<Box<int>>, i: int) {
+            fn send(tx: Sender<Box<i32>>, i: i32) {
                 if i == 10 { return }
 
                 thread::spawn(move|| {
@@ -1414,7 +1479,7 @@ mod test {
                 });
             }
 
-            fn recv(rx: Receiver<Box<int>>, i: int) {
+            fn recv(rx: Receiver<Box<i32>>, i: i32) {
                 if i == 10 { return }
 
                 thread::spawn(move|| {
@@ -1451,8 +1516,8 @@ mod test {
 
     #[test]
     fn test_nested_recv_iter() {
-        let (tx, rx) = channel::<int>();
-        let (total_tx, total_rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
+        let (total_tx, total_rx) = channel::<i32>();
 
         let _t = thread::spawn(move|| {
             let mut acc = 0;
@@ -1471,7 +1536,7 @@ mod test {
 
     #[test]
     fn test_recv_iter_break() {
-        let (tx, rx) = channel::<int>();
+        let (tx, rx) = channel::<i32>();
         let (count_tx, count_rx) = channel();
 
         let _t = thread::spawn(move|| {
@@ -1496,7 +1561,7 @@ mod test {
 
     #[test]
     fn try_recv_states() {
-        let (tx1, rx1) = channel::<int>();
+        let (tx1, rx1) = channel::<i32>();
         let (tx2, rx2) = channel::<()>();
         let (tx3, rx3) = channel::<()>();
         let _t = thread::spawn(move|| {
@@ -1550,7 +1615,7 @@ mod sync_tests {
     use thread;
     use super::*;
 
-    pub fn stress_factor() -> uint {
+    pub fn stress_factor() -> usize {
         match env::var("RUST_TEST_STRESS") {
             Ok(val) => val.parse().unwrap(),
             Err(..) => 1,
@@ -1559,20 +1624,20 @@ mod sync_tests {
 
     #[test]
     fn smoke() {
-        let (tx, rx) = sync_channel::<int>(1);
+        let (tx, rx) = sync_channel::<i32>(1);
         tx.send(1).unwrap();
         assert_eq!(rx.recv().unwrap(), 1);
     }
 
     #[test]
     fn drop_full() {
-        let (tx, _rx) = sync_channel(1);
+        let (tx, _rx) = sync_channel::<Box<isize>>(1);
         tx.send(box 1).unwrap();
     }
 
     #[test]
     fn smoke_shared() {
-        let (tx, rx) = sync_channel::<int>(1);
+        let (tx, rx) = sync_channel::<i32>(1);
         tx.send(1).unwrap();
         assert_eq!(rx.recv().unwrap(), 1);
         let tx = tx.clone();
@@ -1582,7 +1647,7 @@ mod sync_tests {
 
     #[test]
     fn smoke_threads() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         let _t = thread::spawn(move|| {
             tx.send(1).unwrap();
         });
@@ -1591,14 +1656,14 @@ mod sync_tests {
 
     #[test]
     fn smoke_port_gone() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         drop(rx);
         assert!(tx.send(1).is_err());
     }
 
     #[test]
     fn smoke_shared_port_gone2() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         drop(rx);
         let tx2 = tx.clone();
         drop(tx);
@@ -1607,7 +1672,7 @@ mod sync_tests {
 
     #[test]
     fn port_gone_concurrent() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         let _t = thread::spawn(move|| {
             rx.recv().unwrap();
         });
@@ -1616,7 +1681,7 @@ mod sync_tests {
 
     #[test]
     fn port_gone_concurrent_shared() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         let tx2 = tx.clone();
         let _t = thread::spawn(move|| {
             rx.recv().unwrap();
@@ -1626,7 +1691,7 @@ mod sync_tests {
 
     #[test]
     fn smoke_chan_gone() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         drop(tx);
         assert!(rx.recv().is_err());
     }
@@ -1642,7 +1707,7 @@ mod sync_tests {
 
     #[test]
     fn chan_gone_concurrent() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         thread::spawn(move|| {
             tx.send(1).unwrap();
             tx.send(1).unwrap();
@@ -1652,7 +1717,7 @@ mod sync_tests {
 
     #[test]
     fn stress() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         thread::spawn(move|| {
             for _ in 0..10000 { tx.send(1).unwrap(); }
         });
@@ -1663,9 +1728,9 @@ mod sync_tests {
 
     #[test]
     fn stress_shared() {
-        static AMT: uint = 1000;
-        static NTHREADS: uint = 8;
-        let (tx, rx) = sync_channel::<int>(0);
+        const AMT: u32 = 1000;
+        const NTHREADS: u32 = 8;
+        let (tx, rx) = sync_channel::<i32>(0);
         let (dtx, drx) = sync_channel::<()>(0);
 
         thread::spawn(move|| {
@@ -1692,21 +1757,21 @@ mod sync_tests {
     #[test]
     fn oneshot_single_thread_close_port_first() {
         // Simple test of closing without sending
-        let (_tx, rx) = sync_channel::<int>(0);
+        let (_tx, rx) = sync_channel::<i32>(0);
         drop(rx);
     }
 
     #[test]
     fn oneshot_single_thread_close_chan_first() {
         // Simple test of closing without sending
-        let (tx, _rx) = sync_channel::<int>(0);
+        let (tx, _rx) = sync_channel::<i32>(0);
         drop(tx);
     }
 
     #[test]
     fn oneshot_single_thread_send_port_close() {
         // Testing that the sender cleans up the payload if receiver is closed
-        let (tx, rx) = sync_channel::<Box<int>>(0);
+        let (tx, rx) = sync_channel::<Box<i32>>(0);
         drop(rx);
         assert!(tx.send(box 0).is_err());
     }
@@ -1715,7 +1780,7 @@ mod sync_tests {
     fn oneshot_single_thread_recv_chan_close() {
         // Receiving on a closed chan will panic
         let res = thread::spawn(move|| {
-            let (tx, rx) = sync_channel::<int>(0);
+            let (tx, rx) = sync_channel::<i32>(0);
             drop(tx);
             rx.recv().unwrap();
         }).join();
@@ -1725,48 +1790,48 @@ mod sync_tests {
 
     #[test]
     fn oneshot_single_thread_send_then_recv() {
-        let (tx, rx) = sync_channel::<Box<int>>(1);
+        let (tx, rx) = sync_channel::<Box<i32>>(1);
         tx.send(box 10).unwrap();
         assert!(rx.recv().unwrap() == box 10);
     }
 
     #[test]
     fn oneshot_single_thread_try_send_open() {
-        let (tx, rx) = sync_channel::<int>(1);
+        let (tx, rx) = sync_channel::<i32>(1);
         assert_eq!(tx.try_send(10), Ok(()));
         assert!(rx.recv().unwrap() == 10);
     }
 
     #[test]
     fn oneshot_single_thread_try_send_closed() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         drop(rx);
         assert_eq!(tx.try_send(10), Err(TrySendError::Disconnected(10)));
     }
 
     #[test]
     fn oneshot_single_thread_try_send_closed2() {
-        let (tx, _rx) = sync_channel::<int>(0);
+        let (tx, _rx) = sync_channel::<i32>(0);
         assert_eq!(tx.try_send(10), Err(TrySendError::Full(10)));
     }
 
     #[test]
     fn oneshot_single_thread_try_recv_open() {
-        let (tx, rx) = sync_channel::<int>(1);
+        let (tx, rx) = sync_channel::<i32>(1);
         tx.send(10).unwrap();
         assert!(rx.recv() == Ok(10));
     }
 
     #[test]
     fn oneshot_single_thread_try_recv_closed() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         drop(tx);
         assert!(rx.recv().is_err());
     }
 
     #[test]
     fn oneshot_single_thread_peek_data() {
-        let (tx, rx) = sync_channel::<int>(1);
+        let (tx, rx) = sync_channel::<i32>(1);
         assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
         tx.send(10).unwrap();
         assert_eq!(rx.try_recv(), Ok(10));
@@ -1774,7 +1839,7 @@ mod sync_tests {
 
     #[test]
     fn oneshot_single_thread_peek_close() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         drop(tx);
         assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
         assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
@@ -1782,13 +1847,13 @@ mod sync_tests {
 
     #[test]
     fn oneshot_single_thread_peek_open() {
-        let (_tx, rx) = sync_channel::<int>(0);
+        let (_tx, rx) = sync_channel::<i32>(0);
         assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
     }
 
     #[test]
     fn oneshot_multi_task_recv_then_send() {
-        let (tx, rx) = sync_channel::<Box<int>>(0);
+        let (tx, rx) = sync_channel::<Box<i32>>(0);
         let _t = thread::spawn(move|| {
             assert!(rx.recv().unwrap() == box 10);
         });
@@ -1798,7 +1863,7 @@ mod sync_tests {
 
     #[test]
     fn oneshot_multi_task_recv_then_close() {
-        let (tx, rx) = sync_channel::<Box<int>>(0);
+        let (tx, rx) = sync_channel::<Box<i32>>(0);
         let _t = thread::spawn(move|| {
             drop(tx);
         });
@@ -1811,7 +1876,7 @@ mod sync_tests {
     #[test]
     fn oneshot_multi_thread_close_stress() {
         for _ in 0..stress_factor() {
-            let (tx, rx) = sync_channel::<int>(0);
+            let (tx, rx) = sync_channel::<i32>(0);
             let _t = thread::spawn(move|| {
                 drop(rx);
             });
@@ -1822,7 +1887,7 @@ mod sync_tests {
     #[test]
     fn oneshot_multi_thread_send_close_stress() {
         for _ in 0..stress_factor() {
-            let (tx, rx) = sync_channel::<int>(0);
+            let (tx, rx) = sync_channel::<i32>(0);
             let _t = thread::spawn(move|| {
                 drop(rx);
             });
@@ -1835,7 +1900,7 @@ mod sync_tests {
     #[test]
     fn oneshot_multi_thread_recv_close_stress() {
         for _ in 0..stress_factor() {
-            let (tx, rx) = sync_channel::<int>(0);
+            let (tx, rx) = sync_channel::<i32>(0);
             let _t = thread::spawn(move|| {
                 let res = thread::spawn(move|| {
                     rx.recv().unwrap();
@@ -1853,7 +1918,7 @@ mod sync_tests {
     #[test]
     fn oneshot_multi_thread_send_recv_stress() {
         for _ in 0..stress_factor() {
-            let (tx, rx) = sync_channel::<Box<int>>(0);
+            let (tx, rx) = sync_channel::<Box<i32>>(0);
             let _t = thread::spawn(move|| {
                 tx.send(box 10).unwrap();
             });
@@ -1864,12 +1929,12 @@ mod sync_tests {
     #[test]
     fn stream_send_recv_stress() {
         for _ in 0..stress_factor() {
-            let (tx, rx) = sync_channel::<Box<int>>(0);
+            let (tx, rx) = sync_channel::<Box<i32>>(0);
 
             send(tx, 0);
             recv(rx, 0);
 
-            fn send(tx: SyncSender<Box<int>>, i: int) {
+            fn send(tx: SyncSender<Box<i32>>, i: i32) {
                 if i == 10 { return }
 
                 thread::spawn(move|| {
@@ -1878,7 +1943,7 @@ mod sync_tests {
                 });
             }
 
-            fn recv(rx: Receiver<Box<int>>, i: int) {
+            fn recv(rx: Receiver<Box<i32>>, i: i32) {
                 if i == 10 { return }
 
                 thread::spawn(move|| {
@@ -1915,8 +1980,8 @@ mod sync_tests {
 
     #[test]
     fn test_nested_recv_iter() {
-        let (tx, rx) = sync_channel::<int>(0);
-        let (total_tx, total_rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
+        let (total_tx, total_rx) = sync_channel::<i32>(0);
 
         let _t = thread::spawn(move|| {
             let mut acc = 0;
@@ -1935,7 +2000,7 @@ mod sync_tests {
 
     #[test]
     fn test_recv_iter_break() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         let (count_tx, count_rx) = sync_channel(0);
 
         let _t = thread::spawn(move|| {
@@ -1960,7 +2025,7 @@ mod sync_tests {
 
     #[test]
     fn try_recv_states() {
-        let (tx1, rx1) = sync_channel::<int>(1);
+        let (tx1, rx1) = sync_channel::<i32>(1);
         let (tx2, rx2) = sync_channel::<()>(1);
         let (tx3, rx3) = sync_channel::<()>(1);
         let _t = thread::spawn(move|| {
@@ -2007,21 +2072,21 @@ mod sync_tests {
 
     #[test]
     fn send1() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         let _t = thread::spawn(move|| { rx.recv().unwrap(); });
         assert_eq!(tx.send(1), Ok(()));
     }
 
     #[test]
     fn send2() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         let _t = thread::spawn(move|| { drop(rx); });
         assert!(tx.send(1).is_err());
     }
 
     #[test]
     fn send3() {
-        let (tx, rx) = sync_channel::<int>(1);
+        let (tx, rx) = sync_channel::<i32>(1);
         assert_eq!(tx.send(1), Ok(()));
         let _t =thread::spawn(move|| { drop(rx); });
         assert!(tx.send(1).is_err());
@@ -2029,7 +2094,7 @@ mod sync_tests {
 
     #[test]
     fn send4() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         let tx2 = tx.clone();
         let (done, donerx) = channel();
         let done2 = done.clone();
@@ -2048,20 +2113,20 @@ mod sync_tests {
 
     #[test]
     fn try_send1() {
-        let (tx, _rx) = sync_channel::<int>(0);
+        let (tx, _rx) = sync_channel::<i32>(0);
         assert_eq!(tx.try_send(1), Err(TrySendError::Full(1)));
     }
 
     #[test]
     fn try_send2() {
-        let (tx, _rx) = sync_channel::<int>(1);
+        let (tx, _rx) = sync_channel::<i32>(1);
         assert_eq!(tx.try_send(1), Ok(()));
         assert_eq!(tx.try_send(1), Err(TrySendError::Full(1)));
     }
 
     #[test]
     fn try_send3() {
-        let (tx, rx) = sync_channel::<int>(1);
+        let (tx, rx) = sync_channel::<i32>(1);
         assert_eq!(tx.try_send(1), Ok(()));
         drop(rx);
         assert_eq!(tx.try_send(1), Err(TrySendError::Disconnected(1)));
index a2accb128c310c2298ca6c277bee6792ad57b57d..9b6c8f4dd9775bbabc18c00a3c68a85815fa8235 100644 (file)
@@ -44,8 +44,8 @@ pub use self::PopResult::*;
 
 use core::prelude::*;
 
+use alloc::boxed;
 use alloc::boxed::Box;
-use core::mem;
 use core::ptr;
 use core::cell::UnsafeCell;
 
@@ -77,19 +77,19 @@ pub struct Queue<T> {
     tail: UnsafeCell<*mut Node<T>>,
 }
 
-unsafe impl<T:Send> Send for Queue<T> { }
-unsafe impl<T: Send + 'static> Sync for Queue<T> { }
+unsafe impl<T: Send> Send for Queue<T> { }
+unsafe impl<T: Send> Sync for Queue<T> { }
 
 impl<T> Node<T> {
     unsafe fn new(v: Option<T>) -> *mut Node<T> {
-        mem::transmute(box Node {
+        boxed::into_raw(box Node {
             next: AtomicPtr::new(ptr::null_mut()),
             value: v,
         })
     }
 }
 
-impl<T: Send + 'static> Queue<T> {
+impl<T> Queue<T> {
     /// Creates a new queue that is safe to share among multiple producers and
     /// one consumer.
     pub fn new() -> Queue<T> {
@@ -129,7 +129,7 @@ impl<T: Send + 'static> Queue<T> {
                 assert!((*tail).value.is_none());
                 assert!((*next).value.is_some());
                 let ret = (*next).value.take().unwrap();
-                let _: Box<Node<T>> = mem::transmute(tail);
+                let _: Box<Node<T>> = Box::from_raw(tail);
                 return Data(ret);
             }
 
@@ -140,13 +140,13 @@ impl<T: Send + 'static> Queue<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send + 'static> Drop for Queue<T> {
+impl<T> Drop for Queue<T> {
     fn drop(&mut self) {
         unsafe {
             let mut cur = *self.tail.get();
             while !cur.is_null() {
                 let next = (*cur).next.load(Ordering::Relaxed);
-                let _: Box<Node<T>> = mem::transmute(cur);
+                let _: Box<Node<T>> = Box::from_raw(cur);
                 cur = next;
             }
         }
@@ -164,7 +164,7 @@ mod tests {
 
     #[test]
     fn test_full() {
-        let q = Queue::new();
+        let q: Queue<Box<_>> = Queue::new();
         q.push(box 1);
         q.push(box 2);
     }
index 55b2caf7c6d4cccea53aa2331ea3defaf0113524..c6e8d87a22e71412c234f05de9694b2283779f73 100644 (file)
@@ -22,7 +22,7 @@
 ///
 /// # Implementation
 ///
-/// Oneshots are implemented around one atomic uint variable. This variable
+/// Oneshots are implemented around one atomic usize variable. This variable
 /// indicates both the state of the port/chan but also contains any tasks
 /// blocked on the port. All atomic operations happen on this one word.
 ///
@@ -45,9 +45,9 @@ use core::mem;
 use sync::atomic::{AtomicUsize, Ordering};
 
 // Various states you can find a port in.
-const EMPTY: uint = 0;          // initial state: no data, no blocked receiver
-const DATA: uint = 1;           // data ready for receiver to take
-const DISCONNECTED: uint = 2;   // channel is disconnected OR upgraded
+const EMPTY: usize = 0;          // initial state: no data, no blocked receiver
+const DATA: usize = 1;           // data ready for receiver to take
+const DISCONNECTED: usize = 2;   // channel is disconnected OR upgraded
 // Any other value represents a pointer to a SignalToken value. The
 // protocol ensures that when the state moves *to* a pointer,
 // ownership of the token is given to the packet, and when the state
@@ -88,7 +88,7 @@ enum MyUpgrade<T> {
     GoUp(Receiver<T>),
 }
 
-impl<T: Send + 'static> Packet<T> {
+impl<T> Packet<T> {
     pub fn new() -> Packet<T> {
         Packet {
             data: None,
@@ -123,7 +123,7 @@ impl<T: Send + 'static> Packet<T> {
             // There is a thread waiting on the other end. We leave the 'DATA'
             // state inside so it'll pick it up on the other end.
             ptr => unsafe {
-                SignalToken::cast_from_uint(ptr).signal();
+                SignalToken::cast_from_usize(ptr).signal();
                 Ok(())
             }
         }
@@ -143,7 +143,7 @@ impl<T: Send + 'static> Packet<T> {
         // like we're not empty, then immediately go through to `try_recv`.
         if self.state.load(Ordering::SeqCst) == EMPTY {
             let (wait_token, signal_token) = blocking::tokens();
-            let ptr = unsafe { signal_token.cast_to_uint() };
+            let ptr = unsafe { signal_token.cast_to_usize() };
 
             // race with senders to enter the blocking state
             if self.state.compare_and_swap(EMPTY, ptr, Ordering::SeqCst) == EMPTY {
@@ -151,7 +151,7 @@ impl<T: Send + 'static> Packet<T> {
                 debug_assert!(self.state.load(Ordering::SeqCst) != EMPTY);
             } else {
                 // drop the signal token, since we never blocked
-                drop(unsafe { SignalToken::cast_from_uint(ptr) });
+                drop(unsafe { SignalToken::cast_from_usize(ptr) });
             }
         }
 
@@ -220,7 +220,7 @@ impl<T: Send + 'static> Packet<T> {
             DISCONNECTED => { self.upgrade = prev; UpDisconnected }
 
             // If someone's waiting, we gotta wake them up
-            ptr => UpWoke(unsafe { SignalToken::cast_from_uint(ptr) })
+            ptr => UpWoke(unsafe { SignalToken::cast_from_usize(ptr) })
         }
     }
 
@@ -230,7 +230,7 @@ impl<T: Send + 'static> Packet<T> {
 
             // If someone's waiting, we gotta wake them up
             ptr => unsafe {
-                SignalToken::cast_from_uint(ptr).signal();
+                SignalToken::cast_from_usize(ptr).signal();
             }
         }
     }
@@ -283,15 +283,15 @@ impl<T: Send + 'static> Packet<T> {
     // Attempts to start selection on this port. This can either succeed, fail
     // because there is data, or fail because there is an upgrade pending.
     pub fn start_selection(&mut self, token: SignalToken) -> SelectionResult<T> {
-        let ptr = unsafe { token.cast_to_uint() };
+        let ptr = unsafe { token.cast_to_usize() };
         match self.state.compare_and_swap(EMPTY, ptr, Ordering::SeqCst) {
             EMPTY => SelSuccess,
             DATA => {
-                drop(unsafe { SignalToken::cast_from_uint(ptr) });
+                drop(unsafe { SignalToken::cast_from_usize(ptr) });
                 SelCanceled
             }
             DISCONNECTED if self.data.is_some() => {
-                drop(unsafe { SignalToken::cast_from_uint(ptr) });
+                drop(unsafe { SignalToken::cast_from_usize(ptr) });
                 SelCanceled
             }
             DISCONNECTED => {
@@ -300,7 +300,7 @@ impl<T: Send + 'static> Packet<T> {
                     // propagate upwards whether the upgrade can receive
                     // data
                     GoUp(upgrade) => {
-                        SelUpgraded(unsafe { SignalToken::cast_from_uint(ptr) }, upgrade)
+                        SelUpgraded(unsafe { SignalToken::cast_from_usize(ptr) }, upgrade)
                     }
 
                     // If the other end disconnected without sending an
@@ -308,7 +308,7 @@ impl<T: Send + 'static> Packet<T> {
                     // disconnected).
                     up => {
                         self.upgrade = up;
-                        drop(unsafe { SignalToken::cast_from_uint(ptr) });
+                        drop(unsafe { SignalToken::cast_from_usize(ptr) });
                         SelCanceled
                     }
                 }
@@ -360,7 +360,7 @@ impl<T: Send + 'static> Packet<T> {
 
             // We woke ourselves up from select.
             ptr => unsafe {
-                drop(SignalToken::cast_from_uint(ptr));
+                drop(SignalToken::cast_from_usize(ptr));
                 Ok(false)
             }
         }
@@ -368,7 +368,7 @@ impl<T: Send + 'static> Packet<T> {
 }
 
 #[unsafe_destructor]
-impl<T: Send + 'static> Drop for Packet<T> {
+impl<T> Drop for Packet<T> {
     fn drop(&mut self) {
         assert_eq!(self.state.load(Ordering::SeqCst), DISCONNECTED);
     }
index 8fcedd2ab5796cbd0d955ec65c73257c01186a80..b509b3472ee413276ecf52c78c64da05e97f4e2b 100644 (file)
 //! received values of receivers in a much more natural syntax then usage of the
 //! `Select` structure directly.
 //!
-//! # Example
+//! # Examples
 //!
 //! ```rust
+//! # #![feature(std_misc)]
 //! use std::sync::mpsc::channel;
 //!
 //! let (tx1, rx1) = channel();
@@ -71,7 +72,7 @@ use sync::mpsc::blocking::{self, SignalToken};
 pub struct Select {
     head: *mut Handle<'static, ()>,
     tail: *mut Handle<'static, ()>,
-    next_id: Cell<uint>,
+    next_id: Cell<usize>,
 }
 
 impl !marker::Send for Select {}
@@ -79,10 +80,10 @@ impl !marker::Send for Select {}
 /// A handle to a receiver which is currently a member of a `Select` set of
 /// receivers.  This handle is used to keep the receiver in the set as well as
 /// interact with the underlying receiver.
-pub struct Handle<'rx, T:'rx> {
+pub struct Handle<'rx, T:Send+'rx> {
     /// The ID of this handle, used to compare against the return value of
     /// `Select::wait()`
-    id: uint,
+    id: usize,
     selector: &'rx Select,
     next: *mut Handle<'static, ()>,
     prev: *mut Handle<'static, ()>,
@@ -119,6 +120,7 @@ impl Select {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(std_misc)]
     /// use std::sync::mpsc::Select;
     ///
     /// let select = Select::new();
@@ -134,7 +136,7 @@ impl Select {
     /// Creates a new handle into this receiver set for a new receiver. Note
     /// that this does *not* add the receiver to the receiver set, for that you
     /// must call the `add` method on the handle itself.
-    pub fn handle<'a, T: Send + 'static>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> {
+    pub fn handle<'a, T: Send>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> {
         let id = self.next_id.get();
         self.next_id.set(id + 1);
         Handle {
@@ -154,12 +156,12 @@ impl Select {
     /// the matching `id` will have some sort of event available on it. The
     /// event could either be that data is available or the corresponding
     /// channel has been closed.
-    pub fn wait(&self) -> uint {
+    pub fn wait(&self) -> usize {
         self.wait2(true)
     }
 
     /// Helper method for skipping the preflight checks during testing
-    fn wait2(&self, do_preflight_checks: bool) -> uint {
+    fn wait2(&self, do_preflight_checks: bool) -> usize {
         // Note that this is currently an inefficient implementation. We in
         // theory have knowledge about all receivers in the set ahead of time,
         // so this method shouldn't really have to iterate over all of them yet
@@ -251,10 +253,10 @@ impl Select {
     fn iter(&self) -> Packets { Packets { cur: self.head } }
 }
 
-impl<'rx, T: Send + 'static> Handle<'rx, T> {
+impl<'rx, T: Send> Handle<'rx, T> {
     /// Retrieve the id of this handle.
     #[inline]
-    pub fn id(&self) -> uint { self.id }
+    pub fn id(&self) -> usize { self.id }
 
     /// Block to receive a value on the underlying receiver, returning `Some` on
     /// success or `None` if the channel disconnects. This function has the same
@@ -322,7 +324,7 @@ impl Drop for Select {
 }
 
 #[unsafe_destructor]
-impl<'rx, T: Send + 'static> Drop for Handle<'rx, T> {
+impl<'rx, T: Send> Drop for Handle<'rx, T> {
     fn drop(&mut self) {
         unsafe { self.remove() }
     }
@@ -369,8 +371,8 @@ mod test {
 
     #[test]
     fn smoke() {
-        let (tx1, rx1) = channel::<int>();
-        let (tx2, rx2) = channel::<int>();
+        let (tx1, rx1) = channel::<i32>();
+        let (tx2, rx2) = channel::<i32>();
         tx1.send(1).unwrap();
         select! {
             foo = rx1.recv() => { assert_eq!(foo.unwrap(), 1); },
@@ -394,11 +396,11 @@ mod test {
 
     #[test]
     fn smoke2() {
-        let (_tx1, rx1) = channel::<int>();
-        let (_tx2, rx2) = channel::<int>();
-        let (_tx3, rx3) = channel::<int>();
-        let (_tx4, rx4) = channel::<int>();
-        let (tx5, rx5) = channel::<int>();
+        let (_tx1, rx1) = channel::<i32>();
+        let (_tx2, rx2) = channel::<i32>();
+        let (_tx3, rx3) = channel::<i32>();
+        let (_tx4, rx4) = channel::<i32>();
+        let (tx5, rx5) = channel::<i32>();
         tx5.send(4).unwrap();
         select! {
             _foo = rx1.recv() => { panic!("1") },
@@ -411,8 +413,8 @@ mod test {
 
     #[test]
     fn closed() {
-        let (_tx1, rx1) = channel::<int>();
-        let (tx2, rx2) = channel::<int>();
+        let (_tx1, rx1) = channel::<i32>();
+        let (tx2, rx2) = channel::<i32>();
         drop(tx2);
 
         select! {
@@ -423,9 +425,9 @@ mod test {
 
     #[test]
     fn unblocks() {
-        let (tx1, rx1) = channel::<int>();
-        let (_tx2, rx2) = channel::<int>();
-        let (tx3, rx3) = channel::<int>();
+        let (tx1, rx1) = channel::<i32>();
+        let (_tx2, rx2) = channel::<i32>();
+        let (tx3, rx3) = channel::<i32>();
 
         let _t = thread::spawn(move|| {
             for _ in 0..20 { thread::yield_now(); }
@@ -447,8 +449,8 @@ mod test {
 
     #[test]
     fn both_ready() {
-        let (tx1, rx1) = channel::<int>();
-        let (tx2, rx2) = channel::<int>();
+        let (tx1, rx1) = channel::<i32>();
+        let (tx2, rx2) = channel::<i32>();
         let (tx3, rx3) = channel::<()>();
 
         let _t = thread::spawn(move|| {
@@ -473,9 +475,9 @@ mod test {
 
     #[test]
     fn stress() {
-        static AMT: int = 10000;
-        let (tx1, rx1) = channel::<int>();
-        let (tx2, rx2) = channel::<int>();
+        const AMT: i32 = 10000;
+        let (tx1, rx1) = channel::<i32>();
+        let (tx2, rx2) = channel::<i32>();
         let (tx3, rx3) = channel::<()>();
 
         let _t = thread::spawn(move|| {
@@ -500,8 +502,8 @@ mod test {
 
     #[test]
     fn cloning() {
-        let (tx1, rx1) = channel::<int>();
-        let (_tx2, rx2) = channel::<int>();
+        let (tx1, rx1) = channel::<i32>();
+        let (_tx2, rx2) = channel::<i32>();
         let (tx3, rx3) = channel::<()>();
 
         let _t = thread::spawn(move|| {
@@ -522,8 +524,8 @@ mod test {
 
     #[test]
     fn cloning2() {
-        let (tx1, rx1) = channel::<int>();
-        let (_tx2, rx2) = channel::<int>();
+        let (tx1, rx1) = channel::<i32>();
+        let (_tx2, rx2) = channel::<i32>();
         let (tx3, rx3) = channel::<()>();
 
         let _t = thread::spawn(move|| {
@@ -716,7 +718,7 @@ mod test {
 
     #[test]
     fn sync1() {
-        let (tx, rx) = sync_channel::<int>(1);
+        let (tx, rx) = sync_channel::<i32>(1);
         tx.send(1).unwrap();
         select! {
             n = rx.recv() => { assert_eq!(n.unwrap(), 1); }
@@ -725,7 +727,7 @@ mod test {
 
     #[test]
     fn sync2() {
-        let (tx, rx) = sync_channel::<int>(0);
+        let (tx, rx) = sync_channel::<i32>(0);
         let _t = thread::spawn(move|| {
             for _ in 0..100 { thread::yield_now() }
             tx.send(1).unwrap();
@@ -737,8 +739,8 @@ mod test {
 
     #[test]
     fn sync3() {
-        let (tx1, rx1) = sync_channel::<int>(0);
-        let (tx2, rx2): (Sender<int>, Receiver<int>) = channel();
+        let (tx1, rx1) = sync_channel::<i32>(0);
+        let (tx2, rx2): (Sender<i32>, Receiver<i32>) = channel();
         let _t = thread::spawn(move|| { tx1.send(1).unwrap(); });
         let _t = thread::spawn(move|| { tx2.send(2).unwrap(); });
         select! {
index bc9c73585c21fe86ff9ec4e5630191f6330289e9..5c1610bdc317566fe49ae6fd0533f21756b2309e 100644 (file)
@@ -64,7 +64,7 @@ pub enum Failure {
     Disconnected,
 }
 
-impl<T: Send + 'static> Packet<T> {
+impl<T> Packet<T> {
     // Creation of a packet *must* be followed by a call to postinit_lock
     // and later by inherit_blocker
     pub fn new() -> Packet<T> {
@@ -101,7 +101,7 @@ impl<T: Send + 'static> Packet<T> {
         token.map(|token| {
             assert_eq!(self.cnt.load(Ordering::SeqCst), 0);
             assert_eq!(self.to_wake.load(Ordering::SeqCst), 0);
-            self.to_wake.store(unsafe { token.cast_to_uint() }, Ordering::SeqCst);
+            self.to_wake.store(unsafe { token.cast_to_usize() }, Ordering::SeqCst);
             self.cnt.store(-1, Ordering::SeqCst);
 
             // This store is a little sketchy. What's happening here is that
@@ -241,7 +241,7 @@ impl<T: Send + 'static> Packet<T> {
     // Returns true if blocking should proceed.
     fn decrement(&mut self, token: SignalToken) -> StartResult {
         assert_eq!(self.to_wake.load(Ordering::SeqCst), 0);
-        let ptr = unsafe { token.cast_to_uint() };
+        let ptr = unsafe { token.cast_to_usize() };
         self.to_wake.store(ptr, Ordering::SeqCst);
 
         let steals = self.steals;
@@ -258,7 +258,7 @@ impl<T: Send + 'static> Packet<T> {
         }
 
         self.to_wake.store(0, Ordering::SeqCst);
-        drop(unsafe { SignalToken::cast_from_uint(ptr) });
+        drop(unsafe { SignalToken::cast_from_usize(ptr) });
         Abort
     }
 
@@ -380,7 +380,7 @@ impl<T: Send + 'static> Packet<T> {
         let ptr = self.to_wake.load(Ordering::SeqCst);
         self.to_wake.store(0, Ordering::SeqCst);
         assert!(ptr != 0);
-        unsafe { SignalToken::cast_from_uint(ptr) }
+        unsafe { SignalToken::cast_from_usize(ptr) }
     }
 
     ////////////////////////////////////////////////////////////////////////////
@@ -398,7 +398,7 @@ impl<T: Send + 'static> Packet<T> {
     }
 
     // increment the count on the channel (used for selection)
-    fn bump(&mut self, amt: int) -> int {
+    fn bump(&mut self, amt: isize) -> isize {
         match self.cnt.fetch_add(amt, Ordering::SeqCst) {
             DISCONNECTED => {
                 self.cnt.store(DISCONNECTED, Ordering::SeqCst);
@@ -474,7 +474,7 @@ impl<T: Send + 'static> Packet<T> {
 }
 
 #[unsafe_destructor]
-impl<T: Send + 'static> Drop for Packet<T> {
+impl<T> Drop for Packet<T> {
     fn drop(&mut self) {
         // Note that this load is not only an assert for correctness about
         // disconnection, but also a proper fence before the read of
index e1a897065092af2ca1485b6354a70c355561b78e..c75ac13080866ce2a0f3376a91cf830af7691ac0 100644 (file)
@@ -37,8 +37,8 @@
 
 use core::prelude::*;
 
+use alloc::boxed;
 use alloc::boxed::Box;
-use core::mem;
 use core::ptr;
 use core::cell::UnsafeCell;
 
@@ -69,19 +69,19 @@ pub struct Queue<T> {
 
     // Cache maintenance fields. Additions and subtractions are stored
     // separately in order to allow them to use nonatomic addition/subtraction.
-    cache_bound: uint,
+    cache_bound: usize,
     cache_additions: AtomicUsize,
     cache_subtractions: AtomicUsize,
 }
 
-unsafe impl<T: Send + 'static> Send for Queue<T> { }
+unsafe impl<T: Send> Send for Queue<T> { }
 
-unsafe impl<T: Send + 'static> Sync for Queue<T> { }
+unsafe impl<T: Send> Sync for Queue<T> { }
 
-impl<T: Send + 'static> Node<T> {
+impl<T> Node<T> {
     fn new() -> *mut Node<T> {
         unsafe {
-            mem::transmute(box Node {
+            boxed::into_raw(box Node {
                 value: None,
                 next: AtomicPtr::new(ptr::null_mut::<Node<T>>()),
             })
@@ -89,7 +89,7 @@ impl<T: Send + 'static> Node<T> {
     }
 }
 
-impl<T: Send + 'static> Queue<T> {
+impl<T> Queue<T> {
     /// Creates a new queue.
     ///
     /// This is unsafe as the type system doesn't enforce a single
@@ -107,7 +107,7 @@ impl<T: Send + 'static> Queue<T> {
     ///               cache (if desired). If the value is 0, then the cache has
     ///               no bound. Otherwise, the cache will never grow larger than
     ///               `bound` (although the queue itself could be much larger.
-    pub unsafe fn new(bound: uint) -> Queue<T> {
+    pub unsafe fn new(bound: usize) -> Queue<T> {
         let n1 = Node::new();
         let n2 = Node::new();
         (*n1).next.store(n2, Ordering::Relaxed);
@@ -200,7 +200,7 @@ impl<T: Send + 'static> Queue<T> {
                           .next.store(next, Ordering::Relaxed);
                     // We have successfully erased all references to 'tail', so
                     // now we can safely drop it.
-                    let _: Box<Node<T>> = mem::transmute(tail);
+                    let _: Box<Node<T>> = Box::from_raw(tail);
                 }
             }
             return ret;
@@ -227,13 +227,13 @@ impl<T: Send + 'static> Queue<T> {
 }
 
 #[unsafe_destructor]
-impl<T: Send + 'static> Drop for Queue<T> {
+impl<T> Drop for Queue<T> {
     fn drop(&mut self) {
         unsafe {
             let mut cur = *self.first.get();
             while !cur.is_null() {
                 let next = (*cur).next.load(Ordering::Relaxed);
-                let _n: Box<Node<T>> = mem::transmute(cur);
+                let _n: Box<Node<T>> = Box::from_raw(cur);
                 cur = next;
             }
         }
@@ -289,7 +289,7 @@ mod test {
     #[test]
     fn drop_full() {
         unsafe {
-            let q = Queue::new(0);
+            let q: Queue<Box<_>> = Queue::new(0);
             q.push(box 1);
             q.push(box 2);
         }
@@ -319,7 +319,7 @@ mod test {
             stress_bound(1);
         }
 
-        unsafe fn stress_bound(bound: uint) {
+        unsafe fn stress_bound(bound: usize) {
             let q = Arc::new(Queue::new(bound));
 
             let (tx, rx) = channel();
index a194c99669263e356e1ad1bf46f160a6c212f8cf..f0363fae84f73f16ecdbf78f13e8006677eab7f3 100644 (file)
@@ -43,7 +43,7 @@ pub struct Packet<T> {
     queue: spsc::Queue<Message<T>>, // internal queue for all message
 
     cnt: AtomicIsize, // How many items are on this channel
-    steals: int, // How many times has a port received without blocking?
+    steals: isize, // How many times has a port received without blocking?
     to_wake: AtomicUsize, // SignalToken for the blocked thread to wake up
 
     port_dropped: AtomicBool, // flag if the channel has been destroyed.
@@ -74,7 +74,7 @@ enum Message<T> {
     GoUp(Receiver<T>),
 }
 
-impl<T: Send + 'static> Packet<T> {
+impl<T> Packet<T> {
     pub fn new() -> Packet<T> {
         Packet {
             queue: unsafe { spsc::Queue::new(128) },
@@ -146,7 +146,7 @@ impl<T: Send + 'static> Packet<T> {
         let ptr = self.to_wake.load(Ordering::SeqCst);
         self.to_wake.store(0, Ordering::SeqCst);
         assert!(ptr != 0);
-        unsafe { SignalToken::cast_from_uint(ptr) }
+        unsafe { SignalToken::cast_from_usize(ptr) }
     }
 
     // Decrements the count on the channel for a sleeper, returning the sleeper
@@ -154,7 +154,7 @@ impl<T: Send + 'static> Packet<T> {
     // steals into account.
     fn decrement(&mut self, token: SignalToken) -> Result<(), SignalToken> {
         assert_eq!(self.to_wake.load(Ordering::SeqCst), 0);
-        let ptr = unsafe { token.cast_to_uint() };
+        let ptr = unsafe { token.cast_to_usize() };
         self.to_wake.store(ptr, Ordering::SeqCst);
 
         let steals = self.steals;
@@ -171,7 +171,7 @@ impl<T: Send + 'static> Packet<T> {
         }
 
         self.to_wake.store(0, Ordering::SeqCst);
-        Err(unsafe { SignalToken::cast_from_uint(ptr) })
+        Err(unsafe { SignalToken::cast_from_usize(ptr) })
     }
 
     pub fn recv(&mut self) -> Result<T, Failure<T>> {
@@ -350,7 +350,7 @@ impl<T: Send + 'static> Packet<T> {
     }
 
     // increment the count on the channel (used for selection)
-    fn bump(&mut self, amt: int) -> int {
+    fn bump(&mut self, amt: isize) -> isize {
         match self.cnt.fetch_add(amt, Ordering::SeqCst) {
             DISCONNECTED => {
                 self.cnt.store(DISCONNECTED, Ordering::SeqCst);
@@ -472,7 +472,7 @@ impl<T: Send + 'static> Packet<T> {
 }
 
 #[unsafe_destructor]
-impl<T: Send + 'static> Drop for Packet<T> {
+impl<T> Drop for Packet<T> {
     fn drop(&mut self) {
         // Note that this load is not only an assert for correctness about
         // disconnection, but also a proper fence before the read of
index ae96a2491dc267ee06066c369ee6cfb838e3c204..6221ca59b54f7094e0d47b102bd8ece1e57e30af 100644 (file)
@@ -55,16 +55,16 @@ pub struct Packet<T> {
     lock: Mutex<State<T>>,
 }
 
-unsafe impl<T: Send + 'static> Send for Packet<T> { }
+unsafe impl<T: Send> Send for Packet<T> { }
 
-unsafe impl<T: Send + 'static> Sync for Packet<T> { }
+unsafe impl<T: Send> Sync for Packet<T> { }
 
 struct State<T> {
     disconnected: bool, // Is the channel disconnected yet?
     queue: Queue,       // queue of senders waiting to send data
     blocker: Blocker,   // currently blocked task on this channel
     buf: Buffer<T>,     // storage for buffered messages
-    cap: uint,          // capacity of this channel
+    cap: usize,         // capacity of this channel
 
     /// A curious flag used to indicate whether a sender failed or succeeded in
     /// blocking. This is used to transmit information back to the task that it
@@ -75,7 +75,7 @@ struct State<T> {
     canceled: Option<&'static mut bool>,
 }
 
-unsafe impl<T: Send + 'static> Send for State<T> {}
+unsafe impl<T: Send> Send for State<T> {}
 
 /// Possible flavors of threads who can be blocked on this channel.
 enum Blocker {
@@ -101,8 +101,8 @@ unsafe impl Send for Node {}
 /// A simple ring-buffer
 struct Buffer<T> {
     buf: Vec<Option<T>>,
-    start: uint,
-    size: uint,
+    start: usize,
+    size: usize,
 }
 
 #[derive(Debug)]
@@ -113,10 +113,10 @@ pub enum Failure {
 
 /// Atomically blocks the current thread, placing it into `slot`, unlocking `lock`
 /// in the meantime. This re-locks the mutex upon returning.
-fn wait<'a, 'b, T: Send + 'static>(lock: &'a Mutex<State<T>>,
-                         mut guard: MutexGuard<'b, State<T>>,
-                         f: fn(SignalToken) -> Blocker)
-                         -> MutexGuard<'a, State<T>>
+fn wait<'a, 'b, T>(lock: &'a Mutex<State<T>>,
+                   mut guard: MutexGuard<'b, State<T>>,
+                   f: fn(SignalToken) -> Blocker)
+                   -> MutexGuard<'a, State<T>>
 {
     let (wait_token, signal_token) = blocking::tokens();
     match mem::replace(&mut guard.blocker, f(signal_token)) {
@@ -136,8 +136,8 @@ fn wakeup<T>(token: SignalToken, guard: MutexGuard<State<T>>) {
     token.signal();
 }
 
-impl<T: Send + 'static> Packet<T> {
-    pub fn new(cap: uint) -> Packet<T> {
+impl<T> Packet<T> {
+    pub fn new(cap: usize) -> Packet<T> {
         Packet {
             channels: AtomicUsize::new(1),
             lock: Mutex::new(State {
@@ -412,7 +412,7 @@ impl<T: Send + 'static> Packet<T> {
 }
 
 #[unsafe_destructor]
-impl<T: Send + 'static> Drop for Packet<T> {
+impl<T> Drop for Packet<T> {
     fn drop(&mut self) {
         assert_eq!(self.channels.load(Ordering::SeqCst), 0);
         let mut guard = self.lock.lock().unwrap();
@@ -442,8 +442,8 @@ impl<T> Buffer<T> {
         result.take().unwrap()
     }
 
-    fn size(&self) -> uint { self.size }
-    fn cap(&self) -> uint { self.buf.len() }
+    fn size(&self) -> usize { self.size }
+    fn cap(&self) -> usize { self.buf.len() }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
index e77c4d2e5ebd4ec7ed498335eb1a3a3a67abe284..16e7f265412f3211a40e0118c6b40ff4d26b8757 100644 (file)
@@ -15,6 +15,7 @@ use marker;
 use ops::{Deref, DerefMut};
 use sync::poison::{self, TryLockError, TryLockResult, LockResult};
 use sys_common::mutex as sys;
+use fmt;
 
 /// A mutual exclusion primitive useful for protecting shared data
 ///
@@ -39,18 +40,18 @@ use sys_common::mutex as sys;
 /// among threads to ensure that a possibly invalid invariant is not witnessed.
 ///
 /// A poisoned mutex, however, does not prevent all access to the underlying
-/// data. The `PoisonError` type has an `into_guard` method which will return
+/// data. The `PoisonError` type has an `into_inner` method which will return
 /// the guard that would have otherwise been returned on a successful lock. This
 /// allows access to the data, despite the lock being poisoned.
 ///
 /// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::sync::{Arc, Mutex};
 /// use std::thread;
 /// use std::sync::mpsc::channel;
 ///
-/// const N: uint = 10;
+/// const N: usize = 10;
 ///
 /// // Spawn a few threads to increment a shared variable (non-atomically), and
 /// // let the main thread know once all increments are done.
@@ -83,7 +84,8 @@ use sys_common::mutex as sys;
 ///
 /// To recover from a poisoned mutex:
 ///
-/// ```rust
+/// ```
+/// # #![feature(std_misc)]
 /// use std::sync::{Arc, Mutex};
 /// use std::thread;
 ///
@@ -104,7 +106,7 @@ use sys_common::mutex as sys;
 /// // pattern matched on to return the underlying guard on both branches.
 /// let mut guard = match lock.lock() {
 ///     Ok(guard) => guard,
-///     Err(poisoned) => poisoned.into_guard(),
+///     Err(poisoned) => poisoned.into_inner(),
 /// };
 ///
 /// *guard += 1;
@@ -120,9 +122,11 @@ pub struct Mutex<T> {
     data: UnsafeCell<T>,
 }
 
-unsafe impl<T: Send + 'static> Send for Mutex<T> { }
+// these are the only places where `T: Send` matters; all other
+// functionality works fine on a single thread.
+unsafe impl<T: Send> Send for Mutex<T> { }
 
-unsafe impl<T: Send + 'static> Sync for Mutex<T> { }
+unsafe impl<T: Send> Sync for Mutex<T> { }
 
 /// The static mutex type is provided to allow for static allocation of mutexes.
 ///
@@ -132,9 +136,10 @@ unsafe impl<T: Send + 'static> Sync for Mutex<T> { }
 /// to a `Mutex`, a `destroy` method. This method is unsafe to call, and
 /// documentation can be found directly on the method.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
+/// # #![feature(std_misc)]
 /// use std::sync::{StaticMutex, MUTEX_INIT};
 ///
 /// static LOCK: StaticMutex = MUTEX_INIT;
@@ -152,8 +157,6 @@ pub struct StaticMutex {
     poison: poison::Flag,
 }
 
-unsafe impl Sync for StaticMutex {}
-
 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
 /// dropped (falls out of scope), the lock will be unlocked.
 ///
@@ -180,7 +183,7 @@ pub const MUTEX_INIT: StaticMutex = StaticMutex {
     poison: poison::FLAG_INIT,
 };
 
-impl<T: Send + 'static> Mutex<T> {
+impl<T> Mutex<T> {
     /// Creates a new mutex in an unlocked state ready for use.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(t: T) -> Mutex<T> {
@@ -243,7 +246,7 @@ impl<T: Send + 'static> Mutex<T> {
 
 #[unsafe_destructor]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send + 'static> Drop for Mutex<T> {
+impl<T> Drop for Mutex<T> {
     fn drop(&mut self) {
         // This is actually safe b/c we know that there is no further usage of
         // this mutex (it's up to the user to arrange for a mutex to get
@@ -252,6 +255,19 @@ impl<T: Send + 'static> Drop for Mutex<T> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: fmt::Debug + 'static> fmt::Debug for Mutex<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self.try_lock() {
+            Ok(guard) => write!(f, "Mutex {{ data: {:?} }}", *guard),
+            Err(TryLockError::Poisoned(err)) => {
+                write!(f, "Mutex {{ data: Poisoned({:?}) }}", **err.get_ref())
+            },
+            Err(TryLockError::WouldBlock) => write!(f, "Mutex {{ <locked> }}")
+        }
+    }
+}
+
 struct Dummy(UnsafeCell<()>);
 unsafe impl Sync for Dummy {}
 static DUMMY: Dummy = Dummy(UnsafeCell { value: () });
@@ -352,9 +368,9 @@ mod test {
     use sync::{Arc, Mutex, StaticMutex, MUTEX_INIT, Condvar};
     use thread;
 
-    struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
+    struct Packet<T: Send>(Arc<(Mutex<T>, Condvar)>);
 
-    unsafe impl<T:'static+Send> Send for Packet<T> {}
+    unsafe impl<T: Send> Send for Packet<T> {}
     unsafe impl<T> Sync for Packet<T> {}
 
     #[test]
@@ -377,9 +393,9 @@ mod test {
     #[test]
     fn lots_and_lots() {
         static M: StaticMutex = MUTEX_INIT;
-        static mut CNT: uint = 0;
-        static J: uint = 1000;
-        static K: uint = 3;
+        static mut CNT: u32 = 0;
+        const J: u32 = 1000;
+        const K: u32 = 3;
 
         fn inc() {
             for _ in 0..J {
@@ -501,7 +517,7 @@ mod test {
         let arc2 = arc.clone();
         let _ = thread::spawn(move|| -> () {
             struct Unwinder {
-                i: Arc<Mutex<int>>,
+                i: Arc<Mutex<i32>>,
             }
             impl Drop for Unwinder {
                 fn drop(&mut self) {
index 97f985e21e8aba0bbc5068d55db1e2e6432695ea..258cf1d38a8ca887369ffb830f2aa6410386c584 100644 (file)
 //! This primitive is meant to be used to run one-time initialization. An
 //! example use case would be for initializing an FFI library.
 
+use prelude::v1::*;
+
 use isize;
-use marker::Sync;
-use mem::drop;
-use ops::FnOnce;
 use sync::atomic::{AtomicIsize, Ordering, ATOMIC_ISIZE_INIT};
 use sync::{StaticMutex, MUTEX_INIT};
 
@@ -25,9 +24,9 @@ use sync::{StaticMutex, MUTEX_INIT};
 /// functionality. This type can only be constructed with the `ONCE_INIT`
 /// value.
 ///
-/// # Example
+/// # Examples
 ///
-/// ```rust
+/// ```
 /// use std::sync::{Once, ONCE_INIT};
 ///
 /// static START: Once = ONCE_INIT;
@@ -43,8 +42,6 @@ pub struct Once {
     lock_cnt: AtomicIsize,
 }
 
-unsafe impl Sync for Once {}
-
 /// Initialization value for static `Once` values.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const ONCE_INIT: Once = Once {
index 32c8150ba4070172473cfe7d7602dca56a8c09de..347cd0b464ed95892e74b13adafdb30a3013e532 100644 (file)
 use prelude::v1::*;
 
 use cell::UnsafeCell;
-use error::{Error, FromError};
+use error::{Error};
 use fmt;
 use thread;
 
 pub struct Flag { failed: UnsafeCell<bool> }
+
+// This flag is only ever accessed with a lock previously held. Note that this
+// a totally private structure.
+unsafe impl Send for Flag {}
+unsafe impl Sync for Flag {}
+
 pub const FLAG_INIT: Flag = Flag { failed: UnsafeCell { value: false } };
 
 impl Flag {
@@ -99,11 +105,11 @@ impl<T> fmt::Debug for PoisonError<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> fmt::Display for PoisonError<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.description().fmt(f)
+        "poisoned lock: another task failed inside".fmt(f)
     }
 }
 
-impl<T> Error for PoisonError<T> {
+impl<T: Send> Error for PoisonError<T> {
     fn description(&self) -> &str {
         "poisoned lock: another task failed inside"
     }
@@ -116,12 +122,6 @@ impl<T> PoisonError<T> {
         PoisonError { guard: guard }
     }
 
-    /// Consumes this error indicating that a lock is poisoned, returning the
-    /// underlying guard to allow access regardless.
-    #[unstable(feature = "std_misc")]
-    #[deprecated(since = "1.0.0", reason = "renamed to into_inner")]
-    pub fn into_guard(self) -> T { self.guard }
-
     /// Consumes this error indicating that a lock is poisoned, returning the
     /// underlying guard to allow access regardless.
     #[unstable(feature = "std_misc")]
@@ -138,8 +138,8 @@ impl<T> PoisonError<T> {
     pub fn get_mut(&mut self) -> &mut T { &mut self.guard }
 }
 
-impl<T> FromError<PoisonError<T>> for TryLockError<T> {
-    fn from_error(err: PoisonError<T>) -> TryLockError<T> {
+impl<T> From<PoisonError<T>> for TryLockError<T> {
+    fn from(err: PoisonError<T>) -> TryLockError<T> {
         TryLockError::Poisoned(err)
     }
 }
@@ -155,13 +155,13 @@ impl<T> fmt::Debug for TryLockError<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> fmt::Display for TryLockError<T> {
+impl<T: Send> fmt::Display for TryLockError<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.description().fmt(f)
     }
 }
 
-impl<T> Error for TryLockError<T> {
+impl<T: Send> Error for TryLockError<T> {
     fn description(&self) -> &str {
         match *self {
             TryLockError::Poisoned(ref p) => p.description(),
index cd833b17867106baa763e5ab4c1defe3fddb2a01..d70350bc7d6512d40a975dd8dd1da2637c6afa4c 100644 (file)
@@ -15,6 +15,7 @@ use marker;
 use ops::{Deref, DerefMut};
 use sync::poison::{self, LockResult, TryLockError, TryLockResult};
 use sys_common::rwlock as sys;
+use fmt;
 
 /// A reader-writer lock
 ///
@@ -64,8 +65,8 @@ pub struct RwLock<T> {
     data: UnsafeCell<T>,
 }
 
-unsafe impl<T:'static+Send> Send for RwLock<T> {}
-unsafe impl<T> Sync for RwLock<T> {}
+unsafe impl<T: Send + Sync> Send for RwLock<T> {}
+unsafe impl<T: Send + Sync> Sync for RwLock<T> {}
 
 /// Structure representing a statically allocated RwLock.
 ///
@@ -73,9 +74,10 @@ unsafe impl<T> Sync for RwLock<T> {}
 /// automatic global access as well as lazy initialization. The internal
 /// resources of this RwLock, however, must be manually deallocated.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
+/// # #![feature(std_misc)]
 /// use std::sync::{StaticRwLock, RW_LOCK_INIT};
 ///
 /// static LOCK: StaticRwLock = RW_LOCK_INIT;
@@ -97,9 +99,6 @@ pub struct StaticRwLock {
     poison: poison::Flag,
 }
 
-unsafe impl Send for StaticRwLock {}
-unsafe impl Sync for StaticRwLock {}
-
 /// Constant initialization for a statically-initialized rwlock.
 #[unstable(feature = "std_misc",
            reason = "may be merged with RwLock in the future")]
@@ -131,7 +130,7 @@ pub struct RwLockWriteGuard<'a, T: 'a> {
 
 impl<'a, T> !marker::Send for RwLockWriteGuard<'a, T> {}
 
-impl<T: Send + Sync> RwLock<T> {
+impl<T> RwLock<T> {
     /// Creates a new instance of an `RwLock<T>` which is unlocked.
     ///
     /// # Examples
@@ -258,6 +257,19 @@ impl<T> Drop for RwLock<T> {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: fmt::Debug> fmt::Debug for RwLock<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self.try_read() {
+            Ok(guard) => write!(f, "RwLock {{ data: {:?} }}", *guard),
+            Err(TryLockError::Poisoned(err)) => {
+                write!(f, "RwLock {{ data: Poisoned({:?}) }}", **err.get_ref())
+            },
+            Err(TryLockError::WouldBlock) => write!(f, "RwLock {{ <locked> }}")
+        }
+    }
+}
+
 struct Dummy(UnsafeCell<()>);
 unsafe impl Sync for Dummy {}
 static DUMMY: Dummy = Dummy(UnsafeCell { value: () });
@@ -425,8 +437,8 @@ mod tests {
     #[test]
     fn frob() {
         static R: StaticRwLock = RW_LOCK_INIT;
-        static N: usize = 10;
-        static M: usize = 1000;
+        const N: usize = 10;
+        const M: usize = 1000;
 
         let (tx, rx) = channel::<()>();
         for _ in 0..N {
@@ -539,7 +551,7 @@ mod tests {
         let arc2 = arc.clone();
         let _ = thread::spawn(move|| -> () {
             struct Unwinder {
-                i: Arc<RwLock<int>>,
+                i: Arc<RwLock<isize>>,
             }
             impl Drop for Unwinder {
                 fn drop(&mut self) {
index 410e1c11bb9a992387af0b8fa0562b7eb6e65e56..be521095aa95f9fa1aeaaa46d457eb1dd2c7d584 100644 (file)
@@ -22,9 +22,10 @@ use sync::{Mutex, Condvar};
 /// until the counter is positive, and each release will increment the counter
 /// and unblock any threads if necessary.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```
+/// # #![feature(std_misc)]
 /// use std::sync::Semaphore;
 ///
 /// // Create a semaphore that represents 5 resources
@@ -43,7 +44,7 @@ use sync::{Mutex, Condvar};
 /// sem.release();
 /// ```
 pub struct Semaphore {
-    lock: Mutex<int>,
+    lock: Mutex<isize>,
     cvar: Condvar,
 }
 
@@ -59,7 +60,7 @@ impl Semaphore {
     /// The count specified can be thought of as a number of resources, and a
     /// call to `acquire` or `access` will block until at least one resource is
     /// available. It is valid to initialize a semaphore with a negative count.
-    pub fn new(count: int) -> Semaphore {
+    pub fn new(count: isize) -> Semaphore {
         Semaphore {
             lock: Mutex::new(count),
             cvar: Condvar::new(),
diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs
deleted file mode 100644 (file)
index a45048b..0000000
+++ /dev/null
@@ -1,214 +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.
-
-//! Abstraction of a thread pool for basic parallelism.
-
-#![unstable(feature = "std_misc",
-            reason = "the semantics of a failing task and whether a thread is \
-                      re-attached to a thread pool are somewhat unclear, and the \
-                      utility of this type in `std::sync` is questionable with \
-                      respect to the jobs of other primitives")]
-
-use core::prelude::*;
-
-use sync::{Arc, Mutex};
-use sync::mpsc::{channel, Sender, Receiver};
-use thread;
-use thunk::Thunk;
-
-struct Sentinel<'a> {
-    jobs: &'a Arc<Mutex<Receiver<Thunk<'static>>>>,
-    active: bool
-}
-
-impl<'a> Sentinel<'a> {
-    fn new(jobs: &'a Arc<Mutex<Receiver<Thunk<'static>>>>) -> Sentinel<'a> {
-        Sentinel {
-            jobs: jobs,
-            active: true
-        }
-    }
-
-    // Cancel and destroy this sentinel.
-    fn cancel(mut self) {
-        self.active = false;
-    }
-}
-
-#[unsafe_destructor]
-impl<'a> Drop for Sentinel<'a> {
-    fn drop(&mut self) {
-        if self.active {
-            spawn_in_pool(self.jobs.clone())
-        }
-    }
-}
-
-/// A thread pool used to execute functions in parallel.
-///
-/// Spawns `n` worker threads and replenishes the pool if any worker threads
-/// panic.
-///
-/// # Example
-///
-/// ```rust
-/// use std::sync::TaskPool;
-/// use std::iter::AdditiveIterator;
-/// use std::sync::mpsc::channel;
-///
-/// let pool = TaskPool::new(4);
-///
-/// let (tx, rx) = channel();
-/// for _ in 0..8 {
-///     let tx = tx.clone();
-///     pool.execute(move|| {
-///         tx.send(1_u32).unwrap();
-///     });
-/// }
-///
-/// assert_eq!(rx.iter().take(8).sum(), 8);
-/// ```
-pub struct TaskPool {
-    // How the threadpool communicates with subthreads.
-    //
-    // This is the only such Sender, so when it is dropped all subthreads will
-    // quit.
-    jobs: Sender<Thunk<'static>>
-}
-
-impl TaskPool {
-    /// Spawns a new thread pool with `threads` threads.
-    ///
-    /// # Panics
-    ///
-    /// This function will panic if `threads` is 0.
-    pub fn new(threads: uint) -> TaskPool {
-        assert!(threads >= 1);
-
-        let (tx, rx) = channel::<Thunk>();
-        let rx = Arc::new(Mutex::new(rx));
-
-        // Threadpool threads
-        for _ in 0..threads {
-            spawn_in_pool(rx.clone());
-        }
-
-        TaskPool { jobs: tx }
-    }
-
-    /// Executes the function `job` on a thread in the pool.
-    pub fn execute<F>(&self, job: F)
-        where F : FnOnce(), F : Send + 'static
-    {
-        self.jobs.send(Thunk::new(job)).unwrap();
-    }
-}
-
-fn spawn_in_pool(jobs: Arc<Mutex<Receiver<Thunk<'static>>>>) {
-    thread::spawn(move || {
-        // Will spawn a new thread on panic unless it is cancelled.
-        let sentinel = Sentinel::new(&jobs);
-
-        loop {
-            let message = {
-                // Only lock jobs for the time it takes
-                // to get a job, not run it.
-                let lock = jobs.lock().unwrap();
-                lock.recv()
-            };
-
-            match message {
-                Ok(job) => job.invoke(()),
-
-                // The Taskpool was dropped.
-                Err(..) => break
-            }
-        }
-
-        sentinel.cancel();
-    });
-}
-
-#[cfg(test)]
-mod test {
-    use prelude::v1::*;
-    use super::*;
-    use sync::mpsc::channel;
-
-    const TEST_TASKS: uint = 4;
-
-    #[test]
-    fn test_works() {
-        use iter::AdditiveIterator;
-
-        let pool = TaskPool::new(TEST_TASKS);
-
-        let (tx, rx) = channel();
-        for _ in 0..TEST_TASKS {
-            let tx = tx.clone();
-            pool.execute(move|| {
-                tx.send(1).unwrap();
-            });
-        }
-
-        assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_zero_tasks_panic() {
-        TaskPool::new(0);
-    }
-
-    #[test]
-    fn test_recovery_from_subtask_panic() {
-        use iter::AdditiveIterator;
-
-        let pool = TaskPool::new(TEST_TASKS);
-
-        // Panic all the existing threads.
-        for _ in 0..TEST_TASKS {
-            pool.execute(move|| -> () { panic!() });
-        }
-
-        // Ensure new threads were spawned to compensate.
-        let (tx, rx) = channel();
-        for _ in 0..TEST_TASKS {
-            let tx = tx.clone();
-            pool.execute(move|| {
-                tx.send(1).unwrap();
-            });
-        }
-
-        assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
-    }
-
-    #[test]
-    fn test_should_not_panic_on_drop_if_subtasks_panic_after_drop() {
-        use sync::{Arc, Barrier};
-
-        let pool = TaskPool::new(TEST_TASKS);
-        let waiter = Arc::new(Barrier::new(TEST_TASKS + 1));
-
-        // Panic all the existing threads in a bit.
-        for _ in 0..TEST_TASKS {
-            let waiter = waiter.clone();
-            pool.execute(move|| {
-                waiter.wait();
-                panic!();
-            });
-        }
-
-        drop(pool);
-
-        // Kick off the failure.
-        waiter.wait();
-    }
-}
index 50a9f204799e9f0dc1662ac1e86fb7e7eea0d63a..cd118b3c9eefe609394f3d71c902691aaa2ade98 100644 (file)
@@ -9,14 +9,15 @@
 // except according to those terms.
 
 use prelude::v1::*;
+use io::prelude::*;
 
-use old_io::IoResult;
+use io;
 
 #[cfg(target_pointer_width = "64")]
-pub const HEX_WIDTH: uint = 18;
+pub const HEX_WIDTH: usize = 18;
 
 #[cfg(target_pointer_width = "32")]
-pub const HEX_WIDTH: uint = 10;
+pub const HEX_WIDTH: usize = 10;
 
 // All rust symbols are in theory lists of "::"-separated identifiers. Some
 // assemblers, however, can't handle these characters in symbol names. To get
@@ -35,7 +36,7 @@ pub const HEX_WIDTH: uint = 10;
 // Note that this demangler isn't quite as fancy as it could be. We have lots
 // of other information in our symbols like hashes, version, type information,
 // etc. Additionally, this doesn't handle glue symbols at all.
-pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
+pub fn demangle(writer: &mut Write, s: &str) -> io::Result<()> {
     // First validate the symbol. If it doesn't look like anything we're
     // expecting, we just print it literally. Note that we must handle non-rust
     // symbols because we could have any function in the backtrace.
@@ -56,7 +57,7 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
             let mut i = 0;
             for c in chars.by_ref() {
                 if c.is_numeric() {
-                    i = i * 10 + c as uint - '0' as uint;
+                    i = i * 10 + c as usize - '0' as usize;
                 } else {
                     break
                 }
@@ -72,12 +73,12 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
 
     // Alright, let's do this.
     if !valid {
-        try!(writer.write_str(s));
+        try!(writer.write_all(s.as_bytes()));
     } else {
         let mut first = true;
         while inner.len() > 0 {
             if !first {
-                try!(writer.write_str("::"));
+                try!(writer.write_all(b"::"));
             } else {
                 first = false;
             }
@@ -85,7 +86,7 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
             while rest.char_at(0).is_numeric() {
                 rest = &rest[1..];
             }
-            let i: uint = inner[.. (inner.len() - rest.len())].parse().unwrap();
+            let i: usize = inner[.. (inner.len() - rest.len())].parse().unwrap();
             inner = &rest[i..];
             rest = &rest[..i];
             while rest.len() > 0 {
@@ -93,11 +94,11 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
                     macro_rules! demangle {
                         ($($pat:expr, => $demangled:expr),*) => ({
                             $(if rest.starts_with($pat) {
-                                try!(writer.write_str($demangled));
+                                try!(writer.write_all($demangled));
                                 rest = &rest[$pat.len()..];
                               } else)*
                             {
-                                try!(writer.write_str(rest));
+                                try!(writer.write_all(rest.as_bytes()));
                                 break;
                             }
 
@@ -106,29 +107,29 @@ pub fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
 
                     // see src/librustc/back/link.rs for these mappings
                     demangle! (
-                        "$SP$", => "@",
-                        "$BP$", => "*",
-                        "$RF$", => "&",
-                        "$LT$", => "<",
-                        "$GT$", => ">",
-                        "$LP$", => "(",
-                        "$RP$", => ")",
-                        "$C$", => ",",
+                        "$SP$", => b"@",
+                        "$BP$", => b"*",
+                        "$RF$", => b"&",
+                        "$LT$", => b"<",
+                        "$GT$", => b">",
+                        "$LP$", => b"(",
+                        "$RP$", => b")",
+                        "$C$", => b",",
 
                         // in theory we can demangle any Unicode code point, but
                         // for simplicity we just catch the common ones.
-                        "$u7e$", => "~",
-                        "$u20$", => " ",
-                        "$u27$", => "'",
-                        "$u5b$", => "[",
-                        "$u5d$", => "]"
+                        "$u7e$", => b"~",
+                        "$u20$", => b" ",
+                        "$u27$", => b"'",
+                        "$u5b$", => b"[",
+                        "$u5d$", => b"]"
                     )
                 } else {
                     let idx = match rest.find('$') {
                         None => rest.len(),
                         Some(i) => i,
                     };
-                    try!(writer.write_str(&rest[..idx]));
+                    try!(writer.write_all(rest[..idx].as_bytes()));
                     rest = &rest[idx..];
                 }
             }
index dc1ae85efe03395660f9e63fd82b0a398e5a969e..34a58f6c83aa73002f781376b81c0bc049f211a5 100644 (file)
@@ -22,9 +22,8 @@
 
 use prelude::v1::*;
 
+use boxed;
 use cell::UnsafeCell;
-use mem;
-use ptr;
 use rt;
 use sync::{StaticMutex, StaticCondvar};
 use sync::mpsc::{channel, Sender, Receiver};
@@ -39,7 +38,7 @@ use thread;
 ///
 /// The fields of this helper are all public, but they should not be used, this
 /// is for static initialization.
-pub struct Helper<M> {
+pub struct Helper<M:Send> {
     /// Internal lock which protects the remaining fields
     pub lock: StaticMutex,
     pub cond: StaticCondvar,
@@ -52,7 +51,7 @@ pub struct Helper<M> {
     pub chan: UnsafeCell<*mut Sender<M>>,
 
     /// OS handle used to wake up a blocked helper thread
-    pub signal: UnsafeCell<uint>,
+    pub signal: UnsafeCell<usize>,
 
     /// Flag if this helper thread has booted and been initialized yet.
     pub initialized: UnsafeCell<bool>,
@@ -70,6 +69,17 @@ struct RaceBox(helper_signal::signal);
 unsafe impl Send for RaceBox {}
 unsafe impl Sync for RaceBox {}
 
+macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
+    static $name: Helper<$m> = Helper {
+        lock: ::sync::MUTEX_INIT,
+        cond: ::sync::CONDVAR_INIT,
+        chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> },
+        signal: ::cell::UnsafeCell { value: 0 },
+        initialized: ::cell::UnsafeCell { value: false },
+        shutdown: ::cell::UnsafeCell { value: false },
+    };
+) }
+
 impl<M: Send> Helper<M> {
     /// Lazily boots a helper thread, becoming a no-op if the helper has already
     /// been spawned.
@@ -86,11 +96,11 @@ impl<M: Send> Helper<M> {
     {
         unsafe {
             let _guard = self.lock.lock().unwrap();
-            if !*self.initialized.get() {
+            if *self.chan.get() as usize == 0 {
                 let (tx, rx) = channel();
-                *self.chan.get() = mem::transmute(box tx);
+                *self.chan.get() = boxed::into_raw(box tx);
                 let (receive, send) = helper_signal::new();
-                *self.signal.get() = send as uint;
+                *self.signal.get() = send as usize;
 
                 let receive = RaceBox(receive);
 
@@ -102,8 +112,10 @@ impl<M: Send> Helper<M> {
                     self.cond.notify_one()
                 });
 
-                rt::at_exit(move|| { self.shutdown() });
+                let _ = rt::at_exit(move || { self.shutdown() });
                 *self.initialized.get() = true;
+            } else if *self.chan.get() as usize == 1 {
+                panic!("cannot continue usage after shutdown");
             }
         }
     }
@@ -118,7 +130,9 @@ impl<M: Send> Helper<M> {
             // Must send and *then* signal to ensure that the child receives the
             // message. Otherwise it could wake up and go to sleep before we
             // send the message.
-            assert!(!self.chan.get().is_null());
+            assert!(*self.chan.get() as usize != 0);
+            assert!(*self.chan.get() as usize != 1,
+                    "cannot continue usage after shutdown");
             (**self.chan.get()).send(msg).unwrap();
             helper_signal::signal(*self.signal.get() as helper_signal::signal);
         }
@@ -131,9 +145,13 @@ impl<M: Send> Helper<M> {
             // returns.
             let mut guard = self.lock.lock().unwrap();
 
+            let ptr = *self.chan.get();
+            if ptr as usize == 1 {
+                panic!("cannot continue usage after shutdown");
+            }
             // Close the channel by destroying it
-            let chan: Box<Sender<M>> = mem::transmute(*self.chan.get());
-            *self.chan.get() = ptr::null_mut();
+            let chan = Box::from_raw(*self.chan.get());
+            *self.chan.get() = 1 as *mut Sender<M>;
             drop(chan);
             helper_signal::signal(*self.signal.get() as helper_signal::signal);
 
index 5054f72ea98791d5931d66f917ccd2e87fd71604..d2e2f1044d612aef23ce8d7c5a7d0a78ee952680 100644 (file)
@@ -9,19 +9,23 @@
 // except according to those terms.
 
 #![allow(missing_docs)]
-#![allow(dead_code)]
 
 use old_io::{self, IoError, IoResult};
 use prelude::v1::*;
 use sys::{last_error, retry};
 use ffi::CString;
+#[allow(deprecated)] // Int
 use num::Int;
+
+#[allow(deprecated)]
 use old_path::BytesContainer;
+
 use collections;
 
+#[macro_use] pub mod helper_thread;
+
 pub mod backtrace;
 pub mod condvar;
-pub mod helper_thread;
 pub mod mutex;
 pub mod net;
 pub mod net2;
@@ -34,6 +38,7 @@ pub mod wtf8;
 
 // common error constructors
 
+#[allow(deprecated)]
 pub fn eof() -> IoError {
     IoError {
         kind: old_io::EndOfFile,
@@ -42,6 +47,7 @@ pub fn eof() -> IoError {
     }
 }
 
+#[allow(deprecated)]
 pub fn timeout(desc: &'static str) -> IoError {
     IoError {
         kind: old_io::TimedOut,
@@ -50,7 +56,8 @@ pub fn timeout(desc: &'static str) -> IoError {
     }
 }
 
-pub fn short_write(n: uint, desc: &'static str) -> IoError {
+#[allow(deprecated)]
+pub fn short_write(n: usize, desc: &'static str) -> IoError {
     IoError {
         kind: if n == 0 { old_io::TimedOut } else { old_io::ShortWrite(n) },
         desc: desc,
@@ -58,6 +65,7 @@ pub fn short_write(n: uint, desc: &'static str) -> IoError {
     }
 }
 
+#[allow(deprecated)]
 pub fn unimpl() -> IoError {
     IoError {
         kind: old_io::IoUnavailable,
@@ -67,6 +75,7 @@ pub fn unimpl() -> IoError {
 }
 
 // unix has nonzero values as errors
+#[allow(deprecated)]
 pub fn mkerr_libc<T: Int>(ret: T) -> IoResult<()> {
     if ret != Int::zero() {
         Err(last_error())
@@ -76,7 +85,7 @@ pub fn mkerr_libc<T: Int>(ret: T) -> IoResult<()> {
 }
 
 pub fn keep_going<F>(data: &[u8], mut f: F) -> i64 where
-    F: FnMut(*const u8, uint) -> i64,
+    F: FnMut(*const u8, usize) -> i64,
 {
     let origamt = data.len();
     let mut data = data.as_ptr();
@@ -86,8 +95,8 @@ pub fn keep_going<F>(data: &[u8], mut f: F) -> i64 where
         if ret == 0 {
             break
         } else if ret != -1 {
-            amt -= ret as uint;
-            data = unsafe { data.offset(ret as int) };
+            amt -= ret as usize;
+            data = unsafe { data.offset(ret as isize) };
         } else {
             return ret;
         }
@@ -120,12 +129,13 @@ pub trait FromInner<Inner> {
 }
 
 #[doc(hidden)]
+#[allow(deprecated)]
 pub trait ProcessConfig<K: BytesContainer, V: BytesContainer> {
     fn program(&self) -> &CString;
     fn args(&self) -> &[CString];
     fn env(&self) -> Option<&collections::HashMap<K, V>>;
     fn cwd(&self) -> Option<&CString>;
-    fn uid(&self) -> Option<uint>;
-    fn gid(&self) -> Option<uint>;
+    fn uid(&self) -> Option<usize>;
+    fn gid(&self) -> Option<usize>;
     fn detach(&self) -> bool;
 }
index e2ac5ac24f89ec01269f0eb545a58d381e296b46..fc21effb45a8da06cf01b0c57534325bbd2c1d06 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 use self::SocketStatus::*;
 use self::InAddr::*;
@@ -24,7 +26,9 @@ use str;
 use sys::{self, retry, c, sock_t, last_error, last_net_error, last_gai_error, close_sock,
           wrlen, msglen_t, os, wouldblock, set_nonblocking, timer, ms_to_timeval,
           decode_error_detailed};
-use sync::{Arc, Mutex, MutexGuard};
+use sync::{Arc, Mutex};
+#[cfg(not(target_os = "linux"))]
+use sync::MutexGuard;
 use sys_common::{self, keep_going, short_write, timeout};
 use cmp;
 use old_io;
@@ -111,9 +115,9 @@ pub fn socket(addr: SocketAddr, ty: libc::c_int) -> IoResult<sock_t> {
             Ipv4Addr(..) => libc::AF_INET,
             Ipv6Addr(..) => libc::AF_INET6,
         };
-        match libc::socket(fam, ty, 0) {
+        match libc::socket(fam, ty, 0) as i32 {
             -1 => Err(last_net_error()),
-            fd => Ok(fd),
+            fd => Ok(fd as sock_t),
         }
     }
 }
@@ -144,7 +148,7 @@ pub fn getsockopt<T: Copy>(fd: sock_t, opt: libc::c_int,
         if ret != 0 {
             Err(last_net_error())
         } else {
-            assert!(len as uint == mem::size_of::<T>());
+            assert!(len as usize == mem::size_of::<T>());
             Ok(slot)
         }
     }
@@ -166,14 +170,14 @@ pub fn sockname(fd: sock_t,
             return Err(last_net_error())
         }
     }
-    return sockaddr_to_addr(&storage, len as uint);
+    return sockaddr_to_addr(&storage, len as usize);
 }
 
 pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
-                        len: uint) -> IoResult<SocketAddr> {
+                        len: usize) -> IoResult<SocketAddr> {
     match storage.ss_family as libc::c_int {
         libc::AF_INET => {
-            assert!(len as uint >= mem::size_of::<libc::sockaddr_in>());
+            assert!(len as usize >= mem::size_of::<libc::sockaddr_in>());
             let storage: &libc::sockaddr_in = unsafe {
                 mem::transmute(storage)
             };
@@ -188,7 +192,7 @@ pub fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
             })
         }
         libc::AF_INET6 => {
-            assert!(len as uint >= mem::size_of::<libc::sockaddr_in6>());
+            assert!(len as usize >= mem::size_of::<libc::sockaddr_in6>());
             let storage: &libc::sockaddr_in6 = unsafe {
                 mem::transmute(storage)
             };
@@ -279,13 +283,13 @@ pub fn get_host_addresses(host: Option<&str>, servname: Option<&str>,
     while !rp.is_null() {
         unsafe {
             let addr = try!(sockaddr_to_addr(mem::transmute((*rp).ai_addr),
-                                             (*rp).ai_addrlen as uint));
+                                             (*rp).ai_addrlen as usize));
             addrs.push(addrinfo::Info {
                 address: addr,
-                family: (*rp).ai_family as uint,
+                family: (*rp).ai_family as usize,
                 socktype: None,
                 protocol: None,
-                flags: (*rp).ai_flags as uint
+                flags: (*rp).ai_flags as usize
             });
 
             rp = (*rp).ai_next as *mut libc::addrinfo;
@@ -308,7 +312,7 @@ extern "system" {
         flags: c_int) -> c_int;
 }
 
-const NI_MAXHOST: uint = 1025;
+const NI_MAXHOST: usize = 1025;
 
 pub fn get_address_name(addr: IpAddr) -> Result<String, IoError> {
     let addr = SocketAddr{ip: addr, port: 0};
@@ -389,7 +393,7 @@ pub fn get_address_name(addr: IpAddr) -> Result<String, IoError> {
 // [1] http://twistedmatrix.com/pipermail/twisted-commits/2012-April/034692.html
 // [2] http://stackoverflow.com/questions/19819198/does-send-msg-dontwait
 
-pub fn read<T, L, R>(fd: sock_t, deadline: u64, mut lock: L, mut read: R) -> IoResult<uint> where
+pub fn read<T, L, R>(fd: sock_t, deadline: u64, mut lock: L, mut read: R) -> IoResult<usize> where
     L: FnMut() -> T,
     R: FnMut(bool) -> libc::c_int,
 {
@@ -427,7 +431,7 @@ pub fn read<T, L, R>(fd: sock_t, deadline: u64, mut lock: L, mut read: R) -> IoR
     match ret {
         0 => Err(sys_common::eof()),
         n if n < 0 => Err(last_net_error()),
-        n => Ok(n as uint)
+        n => Ok(n as usize)
     }
 }
 
@@ -436,9 +440,9 @@ pub fn write<T, L, W>(fd: sock_t,
                       buf: &[u8],
                       write_everything: bool,
                       mut lock: L,
-                      mut write: W) -> IoResult<uint> where
+                      mut write: W) -> IoResult<usize> where
     L: FnMut() -> T,
-    W: FnMut(bool, *const u8, uint) -> i64,
+    W: FnMut(bool, *const u8, usize) -> i64,
 {
     let mut ret = -1;
     let mut written = 0;
@@ -450,7 +454,7 @@ pub fn write<T, L, W>(fd: sock_t,
             });
         } else {
             ret = retry(|| { write(false, buf.as_ptr(), buf.len()) });
-            if ret > 0 { written = ret as uint; }
+            if ret > 0 { written = ret as usize; }
         }
     }
 
@@ -479,7 +483,7 @@ pub fn write<T, L, W>(fd: sock_t,
             match retry(|| write(deadline.is_some(), ptr, len)) {
                 -1 if wouldblock() => {}
                 -1 => return Err(last_net_error()),
-                n => { written += n as uint; }
+                n => { written += n as usize; }
             }
         }
         ret = 0;
@@ -503,14 +507,14 @@ pub fn connect_timeout(fd: sock_t,
     #[cfg(windows)] use libc::WSAEWOULDBLOCK as WOULDBLOCK;
 
     // Make sure the call to connect() doesn't block
-    try!(set_nonblocking(fd, true));
+    set_nonblocking(fd, true);
 
     let ret = match unsafe { libc::connect(fd, addrp, len) } {
         // If the connection is in progress, then we need to wait for it to
         // finish (with a timeout). The current strategy for doing this is
         // to use select() with a timeout.
-        -1 if os::errno() as int == INPROGRESS as int ||
-              os::errno() as int == WOULDBLOCK as int => {
+        -1 if os::errno() as isize == INPROGRESS as isize ||
+              os::errno() as isize == WOULDBLOCK as isize => {
             let mut set: c::fd_set = unsafe { mem::zeroed() };
             c::fd_set(&mut set, fd);
             match await(fd, &mut set, timeout_ms) {
@@ -533,7 +537,7 @@ pub fn connect_timeout(fd: sock_t,
     };
 
     // be sure to turn blocking I/O back on
-    try!(set_nonblocking(fd, false));
+    set_nonblocking(fd, false);
     return ret;
 
     #[cfg(unix)]
@@ -618,15 +622,17 @@ impl Drop for Inner {
     fn drop(&mut self) { unsafe { close_sock(self.fd); } }
 }
 
+#[cfg(not(target_os = "linux"))]
 pub struct Guard<'a> {
     pub fd: sock_t,
     pub guard: MutexGuard<'a, ()>,
 }
 
+#[cfg(not(target_os = "linux"))]
 #[unsafe_destructor]
 impl<'a> Drop for Guard<'a> {
     fn drop(&mut self) {
-        assert!(set_nonblocking(self.fd, false).is_ok());
+        set_nonblocking(self.fd, false);
     }
 }
 
@@ -680,7 +686,7 @@ impl TcpStream {
                    nodelay as libc::c_int)
     }
 
-    pub fn set_keepalive(&mut self, seconds: Option<uint>) -> IoResult<()> {
+    pub fn set_keepalive(&mut self, seconds: Option<usize>) -> IoResult<()> {
         let ret = setsockopt(self.fd(), libc::SOL_SOCKET, libc::SO_KEEPALIVE,
                              seconds.is_some() as libc::c_int);
         match seconds {
@@ -690,17 +696,18 @@ impl TcpStream {
     }
 
     #[cfg(any(target_os = "macos", target_os = "ios"))]
-    fn set_tcp_keepalive(&mut self, seconds: uint) -> IoResult<()> {
+    fn set_tcp_keepalive(&mut self, seconds: usize) -> IoResult<()> {
         setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_KEEPALIVE,
                    seconds as libc::c_int)
     }
-    #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
-    fn set_tcp_keepalive(&mut self, seconds: uint) -> IoResult<()> {
+    #[cfg(any(target_os = "freebsd",
+              target_os = "dragonfly"))]
+    fn set_tcp_keepalive(&mut self, seconds: usize) -> IoResult<()> {
         setsockopt(self.fd(), libc::IPPROTO_TCP, libc::TCP_KEEPIDLE,
                    seconds as libc::c_int)
     }
     #[cfg(target_os = "openbsd")]
-    fn set_tcp_keepalive(&mut self, seconds: uint) -> IoResult<()> {
+    fn set_tcp_keepalive(&mut self, seconds: usize) -> IoResult<()> {
         setsockopt(self.fd(), libc::IPPROTO_TCP, libc::SO_KEEPALIVE,
                    seconds as libc::c_int)
     }
@@ -709,7 +716,7 @@ impl TcpStream {
                   target_os = "freebsd",
                   target_os = "dragonfly",
                   target_os = "openbsd")))]
-    fn set_tcp_keepalive(&mut self, _seconds: uint) -> IoResult<()> {
+    fn set_tcp_keepalive(&mut self, _seconds: usize) -> IoResult<()> {
         Ok(())
     }
 
@@ -722,11 +729,11 @@ impl TcpStream {
             fd: self.fd(),
             guard: self.inner.lock.lock().unwrap(),
         };
-        assert!(set_nonblocking(self.fd(), true).is_ok());
+        set_nonblocking(self.fd(), true);
         ret
     }
 
-    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         let fd = self.fd();
         let dolock = || self.lock_nonblocking();
         let doread = |nb| unsafe {
@@ -742,7 +749,7 @@ impl TcpStream {
     pub fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         let fd = self.fd();
         let dolock = || self.lock_nonblocking();
-        let dowrite = |nb: bool, buf: *const u8, len: uint| unsafe {
+        let dowrite = |nb: bool, buf: *const u8, len: usize| unsafe {
             let flags = if nb {c::MSG_DONTWAIT} else {0};
             libc::send(fd,
                        buf as *const _,
@@ -861,7 +868,7 @@ impl UdpSocket {
             fd: self.fd(),
             guard: self.inner.lock.lock().unwrap(),
         };
-        assert!(set_nonblocking(self.fd(), true).is_ok());
+        set_nonblocking(self.fd(), true);
         ret
     }
 
@@ -869,7 +876,7 @@ impl UdpSocket {
         sockname(self.fd(), libc::getsockname)
     }
 
-    pub fn recv_from(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)> {
+    pub fn recv_from(&mut self, buf: &mut [u8]) -> IoResult<(usize, SocketAddr)> {
         let fd = self.fd();
         let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
         let storagep = &mut storage as *mut _ as *mut libc::sockaddr;
@@ -886,9 +893,7 @@ impl UdpSocket {
                            storagep,
                            &mut addrlen) as libc::c_int
         }));
-        sockaddr_to_addr(&storage, addrlen as uint).and_then(|addr| {
-            Ok((n as uint, addr))
-        })
+        Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize).unwrap()))
     }
 
     pub fn send_to(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()> {
@@ -898,7 +903,7 @@ impl UdpSocket {
 
         let fd = self.fd();
         let dolock = || self.lock_nonblocking();
-        let dowrite = |nb, buf: *const u8, len: uint| unsafe {
+        let dowrite = |nb, buf: *const u8, len: usize| unsafe {
             let flags = if nb {c::MSG_DONTWAIT} else {0};
             libc::sendto(fd,
                          buf as *const libc::c_void,
@@ -909,11 +914,8 @@ impl UdpSocket {
         };
 
         let n = try!(write(fd, self.write_deadline, buf, false, dolock, dowrite));
-        if n != buf.len() {
-            Err(short_write(n, "couldn't send entire packet at once"))
-        } else {
-            Ok(())
-        }
+        assert!(n == buf.len(), "UDP packet not completely written.");
+        Ok(())
     }
 
     pub fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()> {
@@ -937,11 +939,11 @@ impl UdpSocket {
         }
     }
 
-    pub fn multicast_time_to_live(&mut self, ttl: int) -> IoResult<()> {
+    pub fn multicast_time_to_live(&mut self, ttl: isize) -> IoResult<()> {
         setsockopt(self.fd(), libc::IPPROTO_IP, libc::IP_MULTICAST_TTL,
                    ttl as libc::c_int)
     }
-    pub fn time_to_live(&mut self, ttl: int) -> IoResult<()> {
+    pub fn time_to_live(&mut self, ttl: isize) -> IoResult<()> {
         setsockopt(self.fd(), libc::IPPROTO_IP, libc::IP_TTL, ttl as libc::c_int)
     }
 
index 713f79c5d0814d29b64d0936779ce547cd3ce29c..7d42d65d360f548db50943439b54c8908ffd6854 100644 (file)
 
 use prelude::v1::*;
 
-use ffi::CString;
+use ffi::{CStr, CString};
 use io::{self, Error, ErrorKind};
 use libc::{self, c_int, c_char, c_void, socklen_t};
 use mem;
-use net::{IpAddr, SocketAddr, Shutdown};
-use num::Int;
+use net::{SocketAddr, Shutdown, IpAddr};
+use str::from_utf8;
 use sys::c;
 use sys::net::{cvt, cvt_r, cvt_gai, Socket, init, wrlen_t};
 use sys_common::{AsInner, FromInner, IntoInner};
@@ -24,9 +24,6 @@ use sys_common::{AsInner, FromInner, IntoInner};
 // sockaddr and misc bindings
 ////////////////////////////////////////////////////////////////////////////////
 
-fn hton<I: Int>(i: I) -> I { i.to_be() }
-fn ntoh<I: Int>(i: I) -> I { Int::from_be(i) }
-
 fn setsockopt<T>(sock: &Socket, opt: c_int, val: c_int,
                      payload: T) -> io::Result<()> {
     unsafe {
@@ -39,7 +36,7 @@ fn setsockopt<T>(sock: &Socket, opt: c_int, val: c_int,
 
 #[allow(dead_code)]
 fn getsockopt<T: Copy>(sock: &Socket, opt: c_int,
-                           val: c_int) -> io::Result<T> {
+                       val: c_int) -> io::Result<T> {
     unsafe {
         let mut slot: T = mem::zeroed();
         let mut len = mem::size_of::<T>() as socklen_t;
@@ -67,18 +64,18 @@ fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
     match storage.ss_family as libc::c_int {
         libc::AF_INET => {
             assert!(len as usize >= mem::size_of::<libc::sockaddr_in>());
-            Ok(FromInner::from_inner(unsafe {
+            Ok(SocketAddr::V4(FromInner::from_inner(unsafe {
                 *(storage as *const _ as *const libc::sockaddr_in)
-            }))
+            })))
         }
         libc::AF_INET6 => {
             assert!(len as usize >= mem::size_of::<libc::sockaddr_in6>());
-            Ok(FromInner::from_inner(unsafe {
+            Ok(SocketAddr::V6(FromInner::from_inner(unsafe {
                 *(storage as *const _ as *const libc::sockaddr_in6)
-            }))
+            })))
         }
         _ => {
-            Err(Error::new(ErrorKind::InvalidInput, "invalid argument", None))
+            Err(Error::new(ErrorKind::InvalidInput, "invalid argument"))
         }
     }
 }
@@ -130,6 +127,41 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
     }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// lookup_addr
+////////////////////////////////////////////////////////////////////////////////
+
+extern "system" {
+    fn getnameinfo(sa: *const libc::sockaddr, salen: socklen_t,
+                   host: *mut c_char, hostlen: libc::size_t,
+                   serv: *mut c_char, servlen: libc::size_t,
+                   flags: c_int) -> c_int;
+}
+
+const NI_MAXHOST: usize = 1025;
+
+pub fn lookup_addr(addr: &IpAddr) -> io::Result<String> {
+    init();
+
+    let saddr = SocketAddr::new(*addr, 0);
+    let (inner, len) = saddr.into_inner();
+    let mut hostbuf = [0 as c_char; NI_MAXHOST];
+
+    let data = unsafe {
+        try!(cvt_gai(getnameinfo(inner, len,
+                                 hostbuf.as_mut_ptr(), NI_MAXHOST as libc::size_t,
+                                 0 as *mut _, 0, 0)));
+
+        CStr::from_ptr(hostbuf.as_ptr())
+    };
+
+    match from_utf8(data.to_bytes()) {
+        Ok(name) => Ok(name.to_string()),
+        Err(_) => Err(io::Error::new(io::ErrorKind::Other,
+                                     "failed to lookup address information"))
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // TCP streams
 ////////////////////////////////////////////////////////////////////////////////
@@ -226,6 +258,12 @@ impl TcpStream {
     }
 }
 
+impl FromInner<Socket> for TcpStream {
+    fn from_inner(socket: Socket) -> TcpStream {
+        TcpStream { inner: socket }
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // TCP listeners
 ////////////////////////////////////////////////////////////////////////////////
@@ -279,6 +317,12 @@ impl TcpListener {
     }
 }
 
+impl FromInner<Socket> for TcpListener {
+    fn from_inner(socket: Socket) -> TcpListener {
+        TcpListener { inner: socket }
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // UDP
 ////////////////////////////////////////////////////////////////////////////////
@@ -391,3 +435,9 @@ impl UdpSocket {
         self.inner.duplicate().map(|s| UdpSocket { inner: s })
     }
 }
+
+impl FromInner<Socket> for UdpSocket {
+    fn from_inner(socket: Socket) -> UdpSocket {
+        UdpSocket { inner: socket }
+    }
+}
index fe374e1fd78a3dd55ac97c08234d60054832fe90..f7d7a5715bc68647c9566e4a5c51d28e0b04f28e 100644 (file)
@@ -25,7 +25,7 @@ impl RWLock {
     /// thread to do so.
     ///
     /// Behavior is undefined if the rwlock has been moved between this and any
-    /// previous methodo call.
+    /// previous method call.
     #[inline]
     pub unsafe fn read(&self) { self.0.read() }
 
@@ -35,7 +35,7 @@ impl RWLock {
     /// This function does not block the current thread.
     ///
     /// Behavior is undefined if the rwlock has been moved between this and any
-    /// previous methodo call.
+    /// previous method call.
     #[inline]
     pub unsafe fn try_read(&self) -> bool { self.0.try_read() }
 
@@ -43,7 +43,7 @@ impl RWLock {
     /// to do so.
     ///
     /// Behavior is undefined if the rwlock has been moved between this and any
-    /// previous methodo call.
+    /// previous method call.
     #[inline]
     pub unsafe fn write(&self) { self.0.write() }
 
@@ -53,7 +53,7 @@ impl RWLock {
     /// This function does not block the current thread.
     ///
     /// Behavior is undefined if the rwlock has been moved between this and any
-    /// previous methodo call.
+    /// previous method call.
     #[inline]
     pub unsafe fn try_write(&self) -> bool { self.0.try_write() }
 
index 8dd2f154fa8e3028fd5c0cd31cbc71060cca6b93..8dc3407db77a20f27b51818ddd6dec3c0d40c7b4 100644 (file)
@@ -46,7 +46,7 @@
 // corresponding prolog, decision was taken to disable segmented
 // stack support on iOS.
 
-pub const RED_ZONE: uint = 20 * 1024;
+pub const RED_ZONE: usize = 20 * 1024;
 
 /// This function is invoked from rust's current __morestack function. Segmented
 /// stacks are currently not enabled as segmented stacks, but rather one giant
@@ -117,41 +117,10 @@ extern fn stack_exhausted() {
 // On all other platforms both variants behave identically.
 
 #[inline(always)]
-pub unsafe fn record_os_managed_stack_bounds(stack_lo: uint, _stack_hi: uint) {
+pub unsafe fn record_os_managed_stack_bounds(stack_lo: usize, _stack_hi: usize) {
     record_sp_limit(stack_lo + RED_ZONE);
 }
 
-#[inline(always)]
-pub unsafe fn record_rust_managed_stack_bounds(stack_lo: uint, stack_hi: uint) {
-    // When the old runtime had segmented stacks, it used a calculation that was
-    // "limit + RED_ZONE + FUDGE". The red zone was for things like dynamic
-    // symbol resolution, llvm function calls, etc. In theory this red zone
-    // value is 0, but it matters far less when we have gigantic stacks because
-    // we don't need to be so exact about our stack budget. The "fudge factor"
-    // was because LLVM doesn't emit a stack check for functions < 256 bytes in
-    // size. Again though, we have giant stacks, so we round all these
-    // calculations up to the nice round number of 20k.
-    record_sp_limit(stack_lo + RED_ZONE);
-
-    return target_record_stack_bounds(stack_lo, stack_hi);
-
-    #[cfg(not(windows))] #[inline(always)]
-    unsafe fn target_record_stack_bounds(_stack_lo: uint, _stack_hi: uint) {}
-
-    #[cfg(all(windows, target_arch = "x86"))] #[inline(always)]
-    unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
-        // stack range is at TIB: %fs:0x04 (top) and %fs:0x08 (bottom)
-        asm!("mov $0, %fs:0x04" :: "r"(stack_hi) :: "volatile");
-        asm!("mov $0, %fs:0x08" :: "r"(stack_lo) :: "volatile");
-    }
-    #[cfg(all(windows, target_arch = "x86_64"))] #[inline(always)]
-    unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
-        // stack range is at TIB: %gs:0x08 (top) and %gs:0x10 (bottom)
-        asm!("mov $0, %gs:0x08" :: "r"(stack_hi) :: "volatile");
-        asm!("mov $0, %gs:0x10" :: "r"(stack_lo) :: "volatile");
-    }
-}
-
 /// Records the current limit of the stack as specified by `end`.
 ///
 /// This is stored in an OS-dependent location, likely inside of the thread
@@ -167,30 +136,31 @@ pub unsafe fn record_rust_managed_stack_bounds(stack_lo: uint, stack_hi: uint) {
 /// would be unfortunate for the functions themselves to trigger a morestack
 /// invocation (if they were an actual function call).
 #[inline(always)]
-pub unsafe fn record_sp_limit(limit: uint) {
+pub unsafe fn record_sp_limit(limit: usize) {
     return target_record_sp_limit(limit);
 
     // x86-64
     #[cfg(all(target_arch = "x86_64",
               any(target_os = "macos", target_os = "ios")))]
     #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
+    unsafe fn target_record_sp_limit(limit: usize) {
         asm!("movq $$0x60+90*8, %rsi
               movq $0, %gs:(%rsi)" :: "r"(limit) : "rsi" : "volatile")
     }
     #[cfg(all(target_arch = "x86_64", target_os = "linux"))] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
+    unsafe fn target_record_sp_limit(limit: usize) {
         asm!("movq $0, %fs:112" :: "r"(limit) :: "volatile")
     }
     #[cfg(all(target_arch = "x86_64", target_os = "windows"))] #[inline(always)]
-    unsafe fn target_record_sp_limit(_: uint) {
+    unsafe fn target_record_sp_limit(_: usize) {
     }
     #[cfg(all(target_arch = "x86_64", target_os = "freebsd"))] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
+    unsafe fn target_record_sp_limit(limit: usize) {
         asm!("movq $0, %fs:24" :: "r"(limit) :: "volatile")
     }
-    #[cfg(all(target_arch = "x86_64", target_os = "dragonfly"))] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
+    #[cfg(all(target_arch = "x86_64", target_os = "dragonfly"))]
+    #[inline(always)]
+    unsafe fn target_record_sp_limit(limit: usize) {
         asm!("movq $0, %fs:32" :: "r"(limit) :: "volatile")
     }
 
@@ -198,18 +168,18 @@ pub unsafe fn record_sp_limit(limit: uint) {
     #[cfg(all(target_arch = "x86",
               any(target_os = "macos", target_os = "ios")))]
     #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
+    unsafe fn target_record_sp_limit(limit: usize) {
         asm!("movl $$0x48+90*4, %eax
               movl $0, %gs:(%eax)" :: "r"(limit) : "eax" : "volatile")
     }
     #[cfg(all(target_arch = "x86",
               any(target_os = "linux", target_os = "freebsd")))]
     #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
+    unsafe fn target_record_sp_limit(limit: usize) {
         asm!("movl $0, %gs:48" :: "r"(limit) :: "volatile")
     }
     #[cfg(all(target_arch = "x86", target_os = "windows"))] #[inline(always)]
-    unsafe fn target_record_sp_limit(_: uint) {
+    unsafe fn target_record_sp_limit(_: usize) {
     }
 
     // mips, arm - Some brave soul can port these to inline asm, but it's over
@@ -218,7 +188,7 @@ pub unsafe fn record_sp_limit(limit: uint) {
               target_arch = "mipsel",
               all(target_arch = "arm", not(target_os = "ios"))))]
     #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
+    unsafe fn target_record_sp_limit(limit: usize) {
         use libc::c_void;
         return record_sp_limit(limit as *const c_void);
         extern {
@@ -233,8 +203,9 @@ pub unsafe fn record_sp_limit(limit: uint) {
     #[cfg(any(target_arch = "aarch64",
               target_arch = "powerpc",
               all(target_arch = "arm", target_os = "ios"),
+              target_os = "bitrig",
               target_os = "openbsd"))]
-    unsafe fn target_record_sp_limit(_: uint) {
+    unsafe fn target_record_sp_limit(_: usize) {
     }
 }
 
@@ -247,48 +218,48 @@ pub unsafe fn record_sp_limit(limit: uint) {
 /// As with the setter, this function does not have a __morestack header and can
 /// therefore be called in a "we're out of stack" situation.
 #[inline(always)]
-pub unsafe fn get_sp_limit() -> uint {
+pub unsafe fn get_sp_limit() -> usize {
     return target_get_sp_limit();
 
     // x86-64
     #[cfg(all(target_arch = "x86_64",
               any(target_os = "macos", target_os = "ios")))]
     #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
+    unsafe fn target_get_sp_limit() -> usize {
         let limit;
         asm!("movq $$0x60+90*8, %rsi
               movq %gs:(%rsi), $0" : "=r"(limit) :: "rsi" : "volatile");
         return limit;
     }
     #[cfg(all(target_arch = "x86_64", target_os = "linux"))] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
+    unsafe fn target_get_sp_limit() -> usize {
         let limit;
         asm!("movq %fs:112, $0" : "=r"(limit) ::: "volatile");
         return limit;
     }
     #[cfg(all(target_arch = "x86_64", target_os = "windows"))] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
+    unsafe fn target_get_sp_limit() -> usize {
         return 1024;
     }
     #[cfg(all(target_arch = "x86_64", target_os = "freebsd"))] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
+    unsafe fn target_get_sp_limit() -> usize {
         let limit;
         asm!("movq %fs:24, $0" : "=r"(limit) ::: "volatile");
         return limit;
     }
-    #[cfg(all(target_arch = "x86_64", target_os = "dragonfly"))] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
+    #[cfg(all(target_arch = "x86_64", target_os = "dragonfly"))]
+    #[inline(always)]
+    unsafe fn target_get_sp_limit() -> usize {
         let limit;
         asm!("movq %fs:32, $0" : "=r"(limit) ::: "volatile");
         return limit;
     }
 
-
     // x86
     #[cfg(all(target_arch = "x86",
               any(target_os = "macos", target_os = "ios")))]
     #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
+    unsafe fn target_get_sp_limit() -> usize {
         let limit;
         asm!("movl $$0x48+90*4, %eax
               movl %gs:(%eax), $0" : "=r"(limit) :: "eax" : "volatile");
@@ -297,13 +268,13 @@ pub unsafe fn get_sp_limit() -> uint {
     #[cfg(all(target_arch = "x86",
               any(target_os = "linux", target_os = "freebsd")))]
     #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
+    unsafe fn target_get_sp_limit() -> usize {
         let limit;
         asm!("movl %gs:48, $0" : "=r"(limit) ::: "volatile");
         return limit;
     }
     #[cfg(all(target_arch = "x86", target_os = "windows"))] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
+    unsafe fn target_get_sp_limit() -> usize {
         return 1024;
     }
 
@@ -313,9 +284,9 @@ pub unsafe fn get_sp_limit() -> uint {
               target_arch = "mipsel",
               all(target_arch = "arm", not(target_os = "ios"))))]
     #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
+    unsafe fn target_get_sp_limit() -> usize {
         use libc::c_void;
-        return get_sp_limit() as uint;
+        return get_sp_limit() as usize;
         extern {
             fn get_sp_limit() -> *const c_void;
         }
@@ -331,9 +302,10 @@ pub unsafe fn get_sp_limit() -> uint {
     #[cfg(any(target_arch = "aarch64",
               target_arch = "powerpc",
               all(target_arch = "arm", target_os = "ios"),
+              target_os = "bitrig",
               target_os = "openbsd"))]
     #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
+    unsafe fn target_get_sp_limit() -> usize {
         1024
     }
 }
index b725b6c7e6e93f3dbb8960dbaf9b1464f0eafaba..1845b6266ed8d1aa405ad7581278205ef5a30546 100644 (file)
@@ -8,28 +8,24 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::prelude::*;
+use prelude::v1::*;
 
-use boxed::Box;
-use mem;
 use usize;
 use libc;
 use thunk::Thunk;
 use sys_common::stack;
-use sys::{thread, stack_overflow};
+use sys::stack_overflow;
 
 // This is the starting point of rust os threads. The first thing we do
 // is make sure that we don't trigger __morestack (also why this has a
 // no_stack_check annotation), and then we extract the main function
 // and invoke it.
 #[no_stack_check]
-pub fn start_thread(main: *mut libc::c_void) -> thread::rust_thread_return {
+pub fn start_thread(main: *mut libc::c_void) {
     unsafe {
         stack::record_os_managed_stack_bounds(0, usize::MAX);
-        let handler = stack_overflow::Handler::new();
-        let f: Box<Thunk> = mem::transmute(main);
-        f.invoke(());
-        drop(handler);
-        mem::transmute(0 as thread::rust_thread_return)
+        let _handler = stack_overflow::Handler::new();
+        let main: Box<Thunk> = Box::from_raw(main as *mut Thunk);
+        main();
     }
 }
index 65c706033f213034c2923f4a78b1c8ce859fe16e..22cb59433713043dbaf2a3409072e147e13901c5 100644 (file)
@@ -8,19 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(dead_code)] // stack_guard isn't used right now on all platforms
+
 use core::prelude::*;
 
 use cell::RefCell;
 use string::String;
 use thread::Thread;
-use thread_local::State;
+use thread::LocalKeyState;
 
 struct ThreadInfo {
-    // This field holds the known bounds of the stack in (lo, hi)
-    // form. Not all threads necessarily know their precise bounds,
-    // hence this is optional.
-    stack_bounds: (uint, uint),
-    stack_guard: uint,
+    stack_guard: usize,
     thread: Thread,
 }
 
@@ -28,7 +26,7 @@ thread_local! { static THREAD_INFO: RefCell<Option<ThreadInfo>> = RefCell::new(N
 
 impl ThreadInfo {
     fn with<R, F>(f: F) -> R where F: FnOnce(&mut ThreadInfo) -> R {
-        if THREAD_INFO.state() == State::Destroyed {
+        if THREAD_INFO.state() == LocalKeyState::Destroyed {
             panic!("Use of std::thread::current() is not possible after \
                     the thread's local data has been destroyed");
         }
@@ -36,7 +34,6 @@ impl ThreadInfo {
         THREAD_INFO.with(move |c| {
             if c.borrow().is_none() {
                 *c.borrow_mut() = Some(ThreadInfo {
-                    stack_bounds: (0, 0),
                     stack_guard: 0,
                     thread: NewThread::new(None),
                 })
@@ -50,14 +47,13 @@ pub fn current_thread() -> Thread {
     ThreadInfo::with(|info| info.thread.clone())
 }
 
-pub fn stack_guard() -> uint {
+pub fn stack_guard() -> usize {
     ThreadInfo::with(|info| info.stack_guard)
 }
 
-pub fn set(stack_bounds: (uint, uint), stack_guard: uint, thread: Thread) {
+pub fn set(stack_guard: usize, thread: Thread) {
     THREAD_INFO.with(|c| assert!(c.borrow().is_none()));
     THREAD_INFO.with(move |c| *c.borrow_mut() = Some(ThreadInfo{
-        stack_bounds: stack_bounds,
         stack_guard: stack_guard,
         thread: thread,
     }));
index 27b8784e3943a6a46320fbddc45c6ee8066d88da..5995d7ac10f73d7b3270c9ab22f3303d20905c37 100644 (file)
@@ -28,7 +28,7 @@
 //! more useful in practice than this OS-based version which likely requires
 //! unsafe code to interoperate with.
 //!
-//! # Example
+//! # Examples
 //!
 //! Using a dynamically allocated TLS key. Note that this key can be shared
 //! among many threads via an `Arc`.
 //! ```
 
 #![allow(non_camel_case_types)]
+#![unstable(feature = "thread_local_internals")]
+#![allow(dead_code)] // sys isn't exported yet
 
 use prelude::v1::*;
 
 use sync::atomic::{self, AtomicUsize, Ordering};
-use sync::{Mutex, Once, ONCE_INIT};
 
 use sys::thread_local as imp;
 
@@ -72,7 +73,7 @@ use sys::thread_local as imp;
 /// time. The key is also deallocated when the Rust runtime exits or `destroy`
 /// is called, whichever comes first.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```ignore
 /// use tls::os::{StaticKey, INIT};
@@ -84,17 +85,14 @@ use sys::thread_local as imp;
 ///     KEY.set(1 as *mut u8);
 /// }
 /// ```
-#[stable(feature = "rust1", since = "1.0.0")]
 pub struct StaticKey {
     /// Inner static TLS key (internals), created with by `INIT_INNER` in this
     /// module.
-    #[stable(feature = "rust1", since = "1.0.0")]
     pub inner: StaticKeyInner,
     /// Destructor for the TLS value.
     ///
     /// See `Key::new` for information about when the destructor runs and how
     /// it runs.
-    #[stable(feature = "rust1", since = "1.0.0")]
     pub dtor: Option<unsafe extern fn(*mut u8)>,
 }
 
@@ -112,7 +110,7 @@ pub struct StaticKeyInner {
 /// Implementations will likely, however, contain unsafe code as this type only
 /// operates on `*mut u8`, an unsafe pointer.
 ///
-/// # Example
+/// # Examples
 ///
 /// ```rust,ignore
 /// use tls::os::Key;
@@ -131,7 +129,6 @@ pub struct Key {
 /// Constant initialization value for static TLS keys.
 ///
 /// This value specifies no destructor by default.
-#[stable(feature = "rust1", since = "1.0.0")]
 pub const INIT: StaticKey = StaticKey {
     inner: INIT_INNER,
     dtor: None,
@@ -140,14 +137,10 @@ pub const INIT: StaticKey = StaticKey {
 /// Constant initialization value for the inner part of static TLS keys.
 ///
 /// This value allows specific configuration of the destructor for a TLS key.
-#[stable(feature = "rust1", since = "1.0.0")]
 pub const INIT_INNER: StaticKeyInner = StaticKeyInner {
     key: atomic::ATOMIC_USIZE_INIT,
 };
 
-static INIT_KEYS: Once = ONCE_INIT;
-static mut KEYS: *mut Mutex<Vec<imp::Key>> = 0 as *mut _;
-
 impl StaticKey {
     /// Gets the value associated with this TLS key
     ///
@@ -185,7 +178,7 @@ impl StaticKey {
         }
     }
 
-    unsafe fn lazy_init(&self) -> uint {
+    unsafe fn lazy_init(&self) -> usize {
         // 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
@@ -204,9 +197,9 @@ impl StaticKey {
             key2
         };
         assert!(key != 0);
-        match self.inner.key.compare_and_swap(0, key as uint, Ordering::SeqCst) {
+        match self.inner.key.compare_and_swap(0, key as usize, Ordering::SeqCst) {
             // The CAS succeeded, so we've created the actual key
-            0 => key as uint,
+            0 => key as usize,
             // If someone beat us to the punch, use their key instead
             n => { imp::destroy(key); n }
         }
@@ -268,8 +261,8 @@ mod tests {
         assert!(k2.get().is_null());
         k1.set(1 as *mut _);
         k2.set(2 as *mut _);
-        assert_eq!(k1.get() as uint, 1);
-        assert_eq!(k2.get() as uint, 2);
+        assert_eq!(k1.get() as usize, 1);
+        assert_eq!(k2.get() as usize, 2);
     }
 
     #[test]
@@ -282,8 +275,8 @@ mod tests {
             assert!(K2.get().is_null());
             K1.set(1 as *mut _);
             K2.set(2 as *mut _);
-            assert_eq!(K1.get() as uint, 1);
-            assert_eq!(K2.get() as uint, 2);
+            assert_eq!(K1.get() as usize, 1);
+            assert_eq!(K2.get() as usize, 2);
         }
     }
 }
index ca3ae1a7a34360fa158012705feba28fbba07b83..987a12293da50c0a465cb43c9d3037b76117301f 100644 (file)
 //! nor can it decode WTF-8 from arbitrary bytes.
 //! WTF-8 strings can be obtained from UTF-8, UTF-16, or code points.
 
+// this module is imported from @SimonSapin's repo and has tons of dead code on
+// unix (it's mostly used on windows), so don't worry about dead code here.
+#![allow(dead_code)]
+
 use core::prelude::*;
 
 use core::char::{encode_utf8_raw, encode_utf16_raw};
 use core::str::{char_range_at_raw, next_code_point};
-use core::raw::Slice as RawSlice;
 
 use ascii::*;
 use borrow::Cow;
 use cmp;
 use fmt;
 use hash::{Hash, Hasher};
-#[cfg(stage0)] use hash::Writer;
 use iter::{FromIterator, IntoIterator};
 use mem;
+#[allow(deprecated)] // Int
 use num::Int;
 use ops;
 use slice;
 use str;
-use string::{String, CowString};
+use string::String;
 use sys_common::AsInner;
 use unicode::str::{Utf16Item, utf16_items};
 use vec::Vec;
 
-static UTF8_REPLACEMENT_CHARACTER: &'static [u8] = b"\xEF\xBF\xBD";
+const UTF8_REPLACEMENT_CHARACTER: &'static [u8] = b"\xEF\xBF\xBD";
 
 /// A Unicode code point: from U+0000 to U+10FFFF.
 ///
@@ -156,7 +159,7 @@ impl Wtf8Buf {
 
     /// Create an new, empty WTF-8 string with pre-allocated capacity for `n` bytes.
     #[inline]
-    pub fn with_capacity(n: uint) -> Wtf8Buf {
+    pub fn with_capacity(n: usize) -> Wtf8Buf {
         Wtf8Buf { bytes: Vec::with_capacity(n) }
     }
 
@@ -177,7 +180,7 @@ impl Wtf8Buf {
     /// Since WTF-8 is a superset of UTF-8, this always succeeds.
     #[inline]
     pub fn from_str(str: &str) -> Wtf8Buf {
-        Wtf8Buf { bytes: slice::SliceExt::to_vec(str.as_bytes()) }
+        Wtf8Buf { bytes: <[_]>::to_vec(str.as_bytes()) }
     }
 
     /// Create a WTF-8 string from a potentially ill-formed UTF-16 slice of 16-bit code units.
@@ -211,10 +214,10 @@ impl Wtf8Buf {
         unsafe {
             // Attempt to not use an intermediate buffer by just pushing bytes
             // directly onto this string.
-            let slice = RawSlice {
-                data: self.bytes.as_ptr().offset(cur_len as int),
-                len: 4,
-            };
+            let slice = slice::from_raw_parts_mut(
+                self.bytes.as_mut_ptr().offset(cur_len as isize),
+                4
+            );
             let used = encode_utf8_raw(code_point.value, mem::transmute(slice))
                 .unwrap_or(0);
             self.bytes.set_len(cur_len + used);
@@ -232,15 +235,15 @@ impl Wtf8Buf {
     ///
     /// # Panics
     ///
-    /// Panics if the new capacity overflows `uint`.
+    /// Panics if the new capacity overflows `usize`.
     #[inline]
-    pub fn reserve(&mut self, additional: uint) {
+    pub fn reserve(&mut self, additional: usize) {
         self.bytes.reserve(additional)
     }
 
     /// Returns the number of bytes that this string buffer can hold without reallocating.
     #[inline]
-    pub fn capacity(&self) -> uint {
+    pub fn capacity(&self) -> usize {
         self.bytes.capacity()
     }
 
@@ -311,7 +314,7 @@ impl Wtf8Buf {
     /// Panics if `new_len` > current length,
     /// or if `new_len` is not a code point boundary.
     #[inline]
-    pub fn truncate(&mut self, new_len: uint) {
+    pub fn truncate(&mut self, new_len: usize) {
         assert!(is_code_point_boundary(self, new_len));
         self.bytes.truncate(new_len)
     }
@@ -342,8 +345,8 @@ impl Wtf8Buf {
                 Some((surrogate_pos, _)) => {
                     pos = surrogate_pos + 3;
                     slice::bytes::copy_memory(
+                        UTF8_REPLACEMENT_CHARACTER,
                         &mut self.bytes[surrogate_pos .. pos],
-                        UTF8_REPLACEMENT_CHARACTER
                     );
                 },
                 None => return unsafe { String::from_utf8_unchecked(self.bytes) }
@@ -461,7 +464,7 @@ impl Wtf8 {
 
     /// Return the length, in WTF-8 bytes.
     #[inline]
-    pub fn len(&self) -> uint {
+    pub fn len(&self) -> usize {
         self.bytes.len()
     }
 
@@ -472,7 +475,7 @@ impl Wtf8 {
     ///
     /// Panics if `position` is beyond the end of the string.
     #[inline]
-    pub fn ascii_byte_at(&self, position: uint) -> u8 {
+    pub fn ascii_byte_at(&self, position: usize) -> u8 {
         match self.bytes[position] {
             ascii_byte @ 0x00 ... 0x7F => ascii_byte,
             _ => 0xFF
@@ -486,7 +489,7 @@ impl Wtf8 {
     /// Panics if `position` is not at a code point boundary,
     /// or is beyond the end of the string.
     #[inline]
-    pub fn code_point_at(&self, position: uint) -> CodePoint {
+    pub fn code_point_at(&self, position: usize) -> CodePoint {
         let (code_point, _) = self.code_point_range_at(position);
         code_point
     }
@@ -499,7 +502,7 @@ impl Wtf8 {
     /// Panics if `position` is not at a code point boundary,
     /// or is beyond the end of the string.
     #[inline]
-    pub fn code_point_range_at(&self, position: uint) -> (CodePoint, uint) {
+    pub fn code_point_range_at(&self, position: usize) -> (CodePoint, usize) {
         let (c, n) = char_range_at_raw(&self.bytes, position);
         (CodePoint { value: c }, n)
     }
@@ -531,7 +534,7 @@ impl Wtf8 {
     /// Surrogates are replaced with `"\u{FFFD}"` (the replacement character “�”).
     ///
     /// This only copies the data if necessary (if it contains any surrogate).
-    pub fn to_string_lossy(&self) -> CowString {
+    pub fn to_string_lossy(&self) -> Cow<str> {
         let surrogate_pos = match self.next_surrogate(0) {
             None => return Cow::Borrowed(unsafe { str::from_utf8_unchecked(&self.bytes) }),
             Some((pos, _)) => pos,
@@ -568,7 +571,7 @@ impl Wtf8 {
     }
 
     #[inline]
-    fn next_surrogate(&self, mut pos: uint) -> Option<(uint, u16)> {
+    fn next_surrogate(&self, mut pos: usize) -> Option<(usize, u16)> {
         let mut iter = self.bytes[pos..].iter();
         loop {
             let b = match iter.next() {
@@ -636,7 +639,7 @@ impl ops::Index<ops::Range<usize>> for Wtf8 {
     type Output = Wtf8;
 
     #[inline]
-    fn index(&self, range: &ops::Range<usize>) -> &Wtf8 {
+    fn index(&self, range: ops::Range<usize>) -> &Wtf8 {
         // is_code_point_boundary checks that the index is in [0, .len()]
         if range.start <= range.end &&
            is_code_point_boundary(self, range.start) &&
@@ -658,7 +661,7 @@ impl ops::Index<ops::RangeFrom<usize>> for Wtf8 {
     type Output = Wtf8;
 
     #[inline]
-    fn index(&self, range: &ops::RangeFrom<usize>) -> &Wtf8 {
+    fn index(&self, range: ops::RangeFrom<usize>) -> &Wtf8 {
         // is_code_point_boundary checks that the index is in [0, .len()]
         if is_code_point_boundary(self, range.start) {
             unsafe { slice_unchecked(self, range.start, self.len()) }
@@ -678,7 +681,7 @@ impl ops::Index<ops::RangeTo<usize>> for Wtf8 {
     type Output = Wtf8;
 
     #[inline]
-    fn index(&self, range: &ops::RangeTo<usize>) -> &Wtf8 {
+    fn index(&self, range: ops::RangeTo<usize>) -> &Wtf8 {
         // is_code_point_boundary checks that the index is in [0, .len()]
         if is_code_point_boundary(self, range.end) {
             unsafe { slice_unchecked(self, 0, range.end) }
@@ -692,7 +695,7 @@ impl ops::Index<ops::RangeFull> for Wtf8 {
     type Output = Wtf8;
 
     #[inline]
-    fn index(&self, _range: &ops::RangeFull) -> &Wtf8 {
+    fn index(&self, _range: ops::RangeFull) -> &Wtf8 {
         self
     }
 }
@@ -711,26 +714,27 @@ fn decode_surrogate_pair(lead: u16, trail: u16) -> char {
 
 /// Copied from core::str::StrPrelude::is_char_boundary
 #[inline]
-pub fn is_code_point_boundary(slice: &Wtf8, index: uint) -> bool {
+pub fn is_code_point_boundary(slice: &Wtf8, index: usize) -> bool {
     if index == slice.len() { return true; }
     match slice.bytes.get(index) {
         None => false,
-        Some(&b) => b < 128u8 || b >= 192u8,
+        Some(&b) => b < 128 || b >= 192,
     }
 }
 
 /// Copied from core::str::raw::slice_unchecked
 #[inline]
-pub unsafe fn slice_unchecked(s: &Wtf8, begin: uint, end: uint) -> &Wtf8 {
-    mem::transmute(RawSlice {
-        data: s.bytes.as_ptr().offset(begin as int),
-        len: end - begin,
-    })
+pub unsafe fn slice_unchecked(s: &Wtf8, begin: usize, end: usize) -> &Wtf8 {
+    // memory layout of an &[u8] and &Wtf8 are the same
+    mem::transmute(slice::from_raw_parts(
+        s.bytes.as_ptr().offset(begin as isize),
+        end - begin
+    ))
 }
 
 /// Copied from core::str::raw::slice_error_fail
 #[inline(never)]
-pub fn slice_error_fail(s: &Wtf8, begin: uint, end: uint) -> ! {
+pub fn slice_error_fail(s: &Wtf8, begin: usize, end: usize) -> ! {
     assert!(begin <= end);
     panic!("index {} and/or {} in `{:?}` do not lie on character boundary",
           begin, end, s);
@@ -753,7 +757,7 @@ impl<'a> Iterator for Wtf8CodePoints<'a> {
     }
 
     #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
+    fn size_hint(&self) -> (usize, Option<usize>) {
         let (len, _) = self.bytes.size_hint();
         (len.saturating_add(3) / 4, Some(len))
     }
@@ -777,7 +781,7 @@ impl<'a> Iterator for EncodeWide<'a> {
             return Some(tmp);
         }
 
-        let mut buf = [0u16; 2];
+        let mut buf = [0; 2];
         self.code_points.next().map(|code_point| {
             let n = encode_utf16_raw(code_point.value, &mut buf)
                 .unwrap_or(0);
@@ -787,7 +791,7 @@ impl<'a> Iterator for EncodeWide<'a> {
     }
 
     #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
+    fn size_hint(&self) -> (usize, Option<usize>) {
         let (low, high) = self.code_points.size_hint();
         // every code point gets either one u16 or two u16,
         // so this iterator is between 1 or 2 times as
@@ -796,14 +800,6 @@ impl<'a> Iterator for EncodeWide<'a> {
     }
 }
 
-#[cfg(stage0)]
-impl<S: Writer + Hasher> Hash<S> for CodePoint {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        self.value.hash(state)
-    }
-}
-#[cfg(not(stage0))]
 impl Hash for CodePoint {
     #[inline]
     fn hash<H: Hasher>(&self, state: &mut H) {
@@ -811,15 +807,6 @@ impl Hash for CodePoint {
     }
 }
 
-#[cfg(stage0)]
-impl<S: Writer + Hasher> Hash<S> for Wtf8Buf {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        state.write(&self.bytes);
-        0xfeu8.hash(state)
-    }
-}
-#[cfg(not(stage0))]
 impl Hash for Wtf8Buf {
     #[inline]
     fn hash<H: Hasher>(&self, state: &mut H) {
@@ -828,15 +815,6 @@ impl Hash for Wtf8Buf {
     }
 }
 
-#[cfg(stage0)]
-impl<'a, S: Writer + Hasher> Hash<S> for Wtf8 {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        state.write(&self.bytes);
-        0xfeu8.hash(state)
-    }
-}
-#[cfg(not(stage0))]
 impl Hash for Wtf8 {
     #[inline]
     fn hash<H: Hasher>(&self, state: &mut H) {
@@ -871,7 +849,6 @@ mod tests {
     use borrow::Cow;
     use super::*;
     use mem::transmute;
-    use string::CowString;
 
     #[test]
     fn code_point_from_u32() {
@@ -1058,14 +1035,14 @@ mod tests {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn wtf8buf_truncate_fail_code_point_boundary() {
         let mut string = Wtf8Buf::from_str("aé");
         string.truncate(2);
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn wtf8buf_truncate_fail_longer() {
         let mut string = Wtf8Buf::from_str("aé");
         string.truncate(4);
@@ -1161,7 +1138,7 @@ mod tests {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn wtf8_slice_not_code_point_boundary() {
         &Wtf8::from_str("aé 💩")[2.. 4];
     }
@@ -1172,7 +1149,7 @@ mod tests {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn wtf8_slice_from_not_code_point_boundary() {
         &Wtf8::from_str("aé 💩")[2..];
     }
@@ -1183,7 +1160,7 @@ mod tests {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn wtf8_slice_to_not_code_point_boundary() {
         &Wtf8::from_str("aé 💩")[5..];
     }
@@ -1229,11 +1206,11 @@ mod tests {
             string.code_points().map(|c| c.to_char()).collect::<Vec<_>>()
         }
         let mut string = Wtf8Buf::from_str("é ");
-        assert_eq!(cp(&string), vec![Some('é'), Some(' ')]);
+        assert_eq!(cp(&string), [Some('é'), Some(' ')]);
         string.push(c(0xD83D));
-        assert_eq!(cp(&string), vec![Some('é'), Some(' '), None]);
+        assert_eq!(cp(&string), [Some('é'), Some(' '), None]);
         string.push(c(0xDCA9));
-        assert_eq!(cp(&string), vec![Some('é'), Some(' '), Some('💩')]);
+        assert_eq!(cp(&string), [Some('é'), Some(' '), Some('💩')]);
     }
 
     #[test]
@@ -1251,7 +1228,7 @@ mod tests {
         assert_eq!(Wtf8::from_str("aé 💩").to_string_lossy(), Cow::Borrowed("aé 💩"));
         let mut string = Wtf8Buf::from_str("aé 💩");
         string.push(CodePoint::from_u32(0xD800).unwrap());
-        let expected: CowString = Cow::Owned(String::from_str("aé 💩�"));
+        let expected: Cow<str> = Cow::Owned(String::from_str("aé 💩�"));
         assert_eq!(string.to_string_lossy(), expected);
     }
 
index 8b560339f304474c6cb67d523d69a138f7c2341f..ca805ad02422ad6cda891f3a561bda0301dfebbf 100644 (file)
 /// all unix platforms we support right now, so it at least gets the job done.
 
 use prelude::v1::*;
+use io::prelude::*;
 
 use ffi::CStr;
-use old_io::IoResult;
+use io;
 use libc;
 use mem;
 use str;
@@ -105,7 +106,7 @@ use sys_common::backtrace::*;
 /// only viable option.
 #[cfg(all(target_os = "ios", target_arch = "arm"))]
 #[inline(never)]
-pub fn write(w: &mut Writer) -> IoResult<()> {
+pub fn write(w: &mut Write) -> io::Result<()> {
     use result;
 
     extern {
@@ -117,17 +118,17 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
     // local, it still displays much nicer backtraces when a
     // couple of tasks panic simultaneously
     static LOCK: StaticMutex = MUTEX_INIT;
-    let _g = unsafe { LOCK.lock() };
+    let _g = LOCK.lock();
 
     try!(writeln!(w, "stack backtrace:"));
     // 100 lines should be enough
-    const SIZE: uint = 100;
+    const SIZE: usize = 100;
     let mut buf: [*mut libc::c_void; SIZE] = unsafe {mem::zeroed()};
-    let cnt = unsafe { backtrace(buf.as_mut_ptr(), SIZE as libc::c_int) as uint};
+    let cnt = unsafe { backtrace(buf.as_mut_ptr(), SIZE as libc::c_int) as usize};
 
     // skipping the first one as it is write itself
     let iter = (1..cnt).map(|i| {
-        print(w, i as int, buf[i])
+        print(w, i as isize, buf[i], buf[i])
     });
     result::fold(iter, (), |_, _| ())
 }
@@ -135,13 +136,11 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
 #[cfg(not(all(target_os = "ios", target_arch = "arm")))]
 #[inline(never)] // if we know this is a function call, we can skip it when
                  // tracing
-pub fn write(w: &mut Writer) -> IoResult<()> {
-    use old_io::IoError;
-
+pub fn write(w: &mut Write) -> io::Result<()> {
     struct Context<'a> {
-        idx: int,
-        writer: &'a mut (Writer+'a),
-        last_error: Option<IoError>,
+        idx: isize,
+        writer: &'a mut (Write+'a),
+        last_error: Option<io::Error>,
     }
 
     // When using libbacktrace, we use some necessary global state, so we
@@ -150,7 +149,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
     // I/O done here is blocking I/O, not green I/O, so we don't have to
     // worry about this being a native vs green mutex.
     static LOCK: StaticMutex = MUTEX_INIT;
-    let _g = unsafe { LOCK.lock() };
+    let _g = LOCK.lock();
 
     try!(writeln!(w, "stack backtrace:"));
 
@@ -171,7 +170,16 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
     extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
                        arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
         let cx: &mut Context = unsafe { mem::transmute(arg) };
-        let ip = unsafe { uw::_Unwind_GetIP(ctx) as *mut libc::c_void };
+        let mut ip_before_insn = 0;
+        let mut ip = unsafe {
+            uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void
+        };
+        if !ip.is_null() && ip_before_insn == 0 {
+            // this is a non-signaling frame, so `ip` refers to the address
+            // after the calling instruction. account for that.
+            ip = (ip as usize - 1) as *mut _;
+        }
+
         // dladdr() on osx gets whiny when we use FindEnclosingFunction, and
         // it appears to work fine without it, so we only use
         // FindEnclosingFunction on non-osx platforms. In doing so, we get a
@@ -182,7 +190,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
         // instructions after it. This means that the return instruction
         // pointer points *outside* of the calling function, and by
         // unwinding it we go back to the original function.
-        let ip = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
+        let symaddr = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
             ip
         } else {
             unsafe { uw::_Unwind_FindEnclosingFunction(ip) }
@@ -203,7 +211,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
         // Once we hit an error, stop trying to print more frames
         if cx.last_error.is_some() { return uw::_URC_FAILURE }
 
-        match print(cx.writer, cx.idx, ip) {
+        match print(cx.writer, cx.idx, ip, symaddr) {
             Ok(()) => {}
             Err(e) => { cx.last_error = Some(e); }
         }
@@ -214,7 +222,8 @@ pub fn write(w: &mut Writer) -> IoResult<()> {
 }
 
 #[cfg(any(target_os = "macos", target_os = "ios"))]
-fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
+fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
+         _symaddr: *mut libc::c_void) -> io::Result<()> {
     use intrinsics;
     #[repr(C)]
     struct Dl_info {
@@ -239,8 +248,10 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
 }
 
 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
-fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
+fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
+         symaddr: *mut libc::c_void) -> io::Result<()> {
     use env;
+    use os::unix::prelude::*;
     use ptr;
 
     ////////////////////////////////////////////////////////////////////////
@@ -252,6 +263,12 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
                       symname: *const libc::c_char,
                       symval: libc::uintptr_t,
                       symsize: libc::uintptr_t);
+    type backtrace_full_callback =
+        extern "C" fn(data: *mut libc::c_void,
+                      pc: libc::uintptr_t,
+                      filename: *const libc::c_char,
+                      lineno: libc::c_int,
+                      function: *const libc::c_char) -> libc::c_int;
     type backtrace_error_callback =
         extern "C" fn(data: *mut libc::c_void,
                       msg: *const libc::c_char,
@@ -272,12 +289,19 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
                              cb: backtrace_syminfo_callback,
                              error: backtrace_error_callback,
                              data: *mut libc::c_void) -> libc::c_int;
+        fn backtrace_pcinfo(state: *mut backtrace_state,
+                            addr: libc::uintptr_t,
+                            cb: backtrace_full_callback,
+                            error: backtrace_error_callback,
+                            data: *mut libc::c_void) -> libc::c_int;
     }
 
     ////////////////////////////////////////////////////////////////////////
     // helper callbacks
     ////////////////////////////////////////////////////////////////////////
 
+    type FileLine = (*const libc::c_char, libc::c_int);
+
     extern fn error_cb(_data: *mut libc::c_void, _msg: *const libc::c_char,
                        _errnum: libc::c_int) {
         // do nothing for now
@@ -290,6 +314,25 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
         let slot = data as *mut *const libc::c_char;
         unsafe { *slot = symname; }
     }
+    extern fn pcinfo_cb(data: *mut libc::c_void,
+                        _pc: libc::uintptr_t,
+                        filename: *const libc::c_char,
+                        lineno: libc::c_int,
+                        _function: *const libc::c_char) -> libc::c_int {
+        if !filename.is_null() {
+            let slot = data as *mut &mut [FileLine];
+            let buffer = unsafe {ptr::read(slot)};
+
+            // if the buffer is not full, add file:line to the buffer
+            // and adjust the buffer for next possible calls to pcinfo_cb.
+            if !buffer.is_empty() {
+                buffer[0] = (filename, lineno);
+                unsafe { ptr::write(slot, &mut buffer[1..]); }
+            }
+        }
+
+        0
+    }
 
     // The libbacktrace API supports creating a state, but it does not
     // support destroying a state. I personally take this to mean that a
@@ -319,6 +362,7 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
         if !STATE.is_null() { return STATE }
         let selfname = if cfg!(target_os = "freebsd") ||
                           cfg!(target_os = "dragonfly") ||
+                          cfg!(target_os = "bitrig") ||
                           cfg!(target_os = "openbsd") {
             env::current_exe().ok()
         } else {
@@ -326,7 +370,7 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
         };
         let filename = match selfname {
             Some(path) => {
-                let bytes = path.as_vec();
+                let bytes = path.as_os_str().as_bytes();
                 if bytes.len() < LAST_FILENAME.len() {
                     let i = bytes.iter();
                     for (slot, val) in LAST_FILENAME.iter_mut().zip(i) {
@@ -357,20 +401,47 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
     let mut data = ptr::null();
     let data_addr = &mut data as *mut *const libc::c_char;
     let ret = unsafe {
-        backtrace_syminfo(state, addr as libc::uintptr_t,
+        backtrace_syminfo(state, symaddr as libc::uintptr_t,
                           syminfo_cb, error_cb,
                           data_addr as *mut libc::c_void)
     };
     if ret == 0 || data.is_null() {
-        output(w, idx, addr, None)
+        try!(output(w, idx, addr, None));
     } else {
-        output(w, idx, addr, Some(unsafe { CStr::from_ptr(data).to_bytes() }))
+        try!(output(w, idx, addr, Some(unsafe { CStr::from_ptr(data).to_bytes() })));
+    }
+
+    // pcinfo may return an arbitrary number of file:line pairs,
+    // in the order of stack trace (i.e. inlined calls first).
+    // in order to avoid allocation, we stack-allocate a fixed size of entries.
+    const FILELINE_SIZE: usize = 32;
+    let mut fileline_buf = [(ptr::null(), -1); FILELINE_SIZE];
+    let ret;
+    let fileline_count;
+    {
+        let mut fileline_win: &mut [FileLine] = &mut fileline_buf;
+        let fileline_addr = &mut fileline_win as *mut &mut [FileLine];
+        ret = unsafe {
+            backtrace_pcinfo(state, addr as libc::uintptr_t,
+                             pcinfo_cb, error_cb,
+                             fileline_addr as *mut libc::c_void)
+        };
+        fileline_count = FILELINE_SIZE - fileline_win.len();
+    }
+    if ret == 0 {
+        for (i, &(file, line)) in fileline_buf[..fileline_count].iter().enumerate() {
+            if file.is_null() { continue; } // just to be sure
+            let file = unsafe { CStr::from_ptr(file).to_bytes() };
+            try!(output_fileline(w, file, line, i == FILELINE_SIZE - 1));
+        }
     }
+
+    Ok(())
 }
 
 // Finally, after all that work above, we can emit a symbol.
-fn output(w: &mut Writer, idx: int, addr: *mut libc::c_void,
-          s: Option<&[u8]>) -> IoResult<()> {
+fn output(w: &mut Write, idx: isize, addr: *mut libc::c_void,
+          s: Option<&[u8]>) -> io::Result<()> {
     try!(write!(w, "  {:2}: {:2$?} - ", idx, addr, HEX_WIDTH));
     match s.and_then(|s| str::from_utf8(s).ok()) {
         Some(string) => try!(demangle(w, string)),
@@ -379,6 +450,18 @@ fn output(w: &mut Writer, idx: int, addr: *mut libc::c_void,
     w.write_all(&['\n' as u8])
 }
 
+#[allow(dead_code)]
+fn output_fileline(w: &mut Write, file: &[u8], line: libc::c_int,
+                   more: bool) -> io::Result<()> {
+    let file = str::from_utf8(file).unwrap_or("<unknown>");
+    // prior line: "  ##: {:2$} - func"
+    try!(write!(w, "      {:3$}at {}:{}", "", file, line, HEX_WIDTH));
+    if more {
+        try!(write!(w, " <... and possibly more>"));
+    }
+    w.write_all(&['\n' as u8])
+}
+
 /// Unwind library interface used for backtraces
 ///
 /// Note that dead code is allowed as here are just bindings
@@ -419,9 +502,12 @@ mod uw {
                                  trace_argument: *mut libc::c_void)
                     -> _Unwind_Reason_Code;
 
+        // available since GCC 4.2.0, should be fine for our purpose
         #[cfg(all(not(all(target_os = "android", target_arch = "arm")),
                   not(all(target_os = "linux", target_arch = "arm"))))]
-        pub fn _Unwind_GetIP(ctx: *mut _Unwind_Context) -> libc::uintptr_t;
+        pub fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context,
+                                 ip_before_insn: *mut libc::c_int)
+                    -> libc::uintptr_t;
 
         #[cfg(all(not(target_os = "android"),
                   not(all(target_os = "linux", target_arch = "arm"))))]
@@ -477,6 +563,18 @@ mod uw {
         (val & !1) as libc::uintptr_t
     }
 
+    // This function doesn't exist on Android or ARM/Linux, so make it same
+    // to _Unwind_GetIP
+    #[cfg(any(all(target_os = "android", target_arch = "arm"),
+              all(target_os = "linux", target_arch = "arm")))]
+    pub unsafe fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context,
+                                    ip_before_insn: *mut libc::c_int)
+        -> libc::uintptr_t
+    {
+        *ip_before_insn = 0;
+        _Unwind_GetIP(ctx)
+    }
+
     // This function also doesn't exist on Android or ARM/Linux, so make it
     // a no-op
     #[cfg(any(target_os = "android",
index 345808189a0ceaf2c2a1dfeb76f00eb2e75385b3..2514d4bf4a39605b0c7b76a4ae30d51be503ae87 100644 (file)
@@ -24,6 +24,7 @@ use libc;
           target_os = "ios",
           target_os = "freebsd",
           target_os = "dragonfly",
+          target_os = "bitrig",
           target_os = "openbsd"))]
 pub const FIONBIO: libc::c_ulong = 0x8004667e;
 #[cfg(any(all(target_os = "linux",
@@ -43,6 +44,7 @@ pub const FIONBIO: libc::c_ulong = 0x667e;
           target_os = "ios",
           target_os = "freebsd",
           target_os = "dragonfly",
+          target_os = "bitrig",
           target_os = "openbsd"))]
 pub const FIOCLEX: libc::c_ulong = 0x20006601;
 #[cfg(any(all(target_os = "linux",
@@ -62,6 +64,7 @@ pub const FIOCLEX: libc::c_ulong = 0x6601;
           target_os = "ios",
           target_os = "freebsd",
           target_os = "dragonfly",
+          target_os = "bitrig",
           target_os = "openbsd"))]
 pub const MSG_DONTWAIT: libc::c_int = 0x80;
 #[cfg(any(target_os = "linux", target_os = "android"))]
@@ -75,7 +78,8 @@ pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 70;
           target_os = "freebsd",
           target_os = "dragonfly"))]
 pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 71;
-#[cfg(target_os = "openbsd")]
+#[cfg(any(target_os = "bitrig",
+          target_os = "openbsd"))]
 pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 101;
 #[cfg(target_os = "android")]
 pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 0x0048;
@@ -96,6 +100,7 @@ pub struct passwd {
 #[cfg(any(target_os = "macos",
           target_os = "freebsd",
           target_os = "dragonfly",
+          target_os = "bitrig",
           target_os = "openbsd"))]
 pub struct passwd {
     pub pw_name: *mut libc::c_char,
@@ -162,7 +167,7 @@ extern {
 
 #[cfg(any(target_os = "macos", target_os = "ios"))]
 mod select {
-    pub const FD_SETSIZE: uint = 1024;
+    pub const FD_SETSIZE: usize = 1024;
 
     #[repr(C)]
     pub struct fd_set {
@@ -170,13 +175,14 @@ mod select {
     }
 
     pub fn fd_set(set: &mut fd_set, fd: i32) {
-        set.fds_bits[(fd / 32) as uint] |= 1 << ((fd % 32) as uint);
+        set.fds_bits[(fd / 32) as usize] |= 1 << ((fd % 32) as usize);
     }
 }
 
 #[cfg(any(target_os = "android",
           target_os = "freebsd",
           target_os = "dragonfly",
+          target_os = "bitrig",
           target_os = "openbsd",
           target_os = "linux"))]
 mod select {
@@ -188,12 +194,12 @@ mod select {
     #[repr(C)]
     pub struct fd_set {
         // FIXME: shouldn't this be a c_ulong?
-        fds_bits: [libc::uintptr_t; (FD_SETSIZE / usize::BITS)]
+        fds_bits: [libc::uintptr_t; (FD_SETSIZE / usize::BITS as usize)]
     }
 
     pub fn fd_set(set: &mut fd_set, fd: i32) {
-        let fd = fd as uint;
-        set.fds_bits[fd / usize::BITS] |= 1 << (fd % usize::BITS);
+        let fd = fd as usize;
+        set.fds_bits[fd / usize::BITS as usize] |= 1 << (fd % usize::BITS as usize);
     }
 }
 
@@ -302,8 +308,7 @@ mod signal {
 #[cfg(any(target_os = "macos",
           target_os = "ios",
           target_os = "freebsd",
-          target_os = "dragonfly",
-          target_os = "openbsd"))]
+          target_os = "dragonfly"))]
 mod signal {
     use libc;
 
@@ -317,8 +322,7 @@ mod signal {
     pub const SIGCHLD: libc::c_int = 20;
 
     #[cfg(any(target_os = "macos",
-              target_os = "ios",
-              target_os = "openbsd"))]
+              target_os = "ios"))]
     pub type sigset_t = u32;
     #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
     #[repr(C)]
@@ -345,3 +349,41 @@ mod signal {
         pub sa_mask: sigset_t,
     }
 }
+
+#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
+mod signal {
+    use libc;
+
+    pub const SA_ONSTACK: libc::c_int = 0x0001;
+    pub const SA_RESTART: libc::c_int = 0x0002;
+    pub const SA_RESETHAND: libc::c_int = 0x0004;
+    pub const SA_NOCLDSTOP: libc::c_int = 0x0008;
+    pub const SA_NODEFER: libc::c_int = 0x0010;
+    pub const SA_NOCLDWAIT: libc::c_int = 0x0020;
+    pub const SA_SIGINFO: libc::c_int = 0x0040;
+    pub const SIGCHLD: libc::c_int = 20;
+
+    pub type sigset_t = libc::c_uint;
+
+    // This structure has more fields, but we're not all that interested in
+    // them.
+    #[repr(C)]
+    pub struct siginfo {
+        pub si_signo: libc::c_int,
+        pub si_code: libc::c_int,
+        pub si_errno: libc::c_int,
+        // FIXME: Bitrig has a crazy union here in the siginfo, I think this
+        // layout will still work tho.  The status might be off by the size of
+        // a clock_t by my reading, but we can fix this later.
+        pub pid: libc::pid_t,
+        pub uid: libc::uid_t,
+        pub status: libc::c_int,
+    }
+
+    #[repr(C)]
+    pub struct sigaction {
+        pub sa_handler: extern fn(libc::c_int),
+        pub sa_mask: sigset_t,
+        pub sa_flags: libc::c_int,
+    }
+}
index 3bc414731526300d15d5fa0d0716b132c7d892f6..90dfebc4c454c7735808255c52a5994e08452f34 100644 (file)
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use prelude::v1::*;
+
 use cell::UnsafeCell;
 use libc;
 use ptr;
-use std::option::Option::{Some, None};
 use sys::mutex::{self, Mutex};
 use sys::time;
 use sys::sync as ffi;
@@ -20,6 +21,9 @@ use num::{Int, NumCast};
 
 pub struct Condvar { inner: UnsafeCell<ffi::pthread_cond_t> }
 
+unsafe impl Send for Condvar {}
+unsafe impl Sync for Condvar {}
+
 pub const CONDVAR_INIT: Condvar = Condvar {
     inner: UnsafeCell { value: ffi::PTHREAD_COND_INITIALIZER },
 };
index b8b9dcfb3c68920b2602ed2e1e22072ac5d106be..fbfbb40701fd9f5887a841ba7e50dde90ed36479 100644 (file)
 //! }
 //! ```
 
-#![unstable(feature = "std_misc")]
-
-use prelude::v1::*;
-
-use ffi::{CString, NulError, OsStr, OsString};
-use fs::{self, Permissions, OpenOptions};
-use net;
-use mem;
-use process;
-use sys;
-use sys::os_str::Buf;
-use sys_common::{AsInner, AsInnerMut, IntoInner, FromInner};
-use libc::{self, gid_t, uid_t};
-
-use old_io;
+#![stable(feature = "rust1", since = "1.0.0")]
+
+/// Unix-specific extensions to general I/O primitives
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod io {
+    #[allow(deprecated)] use old_io;
+    use fs;
+    use libc;
+    use net;
+    use sys_common::{net2, AsInner, FromInner};
+    use sys;
+
+    /// Raw file descriptors.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub type RawFd = libc::c_int;
+
+    /// A trait to extract the raw unix file descriptor from an underlying
+    /// object.
+    ///
+    /// This is only available on unix platforms and must be imported in order
+    /// to call the method. Windows platforms have a corresponding `AsRawHandle`
+    /// and `AsRawSocket` set of traits.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait AsRawFd {
+        /// Extract the raw file descriptor.
+        ///
+        /// This method does **not** pass ownership of the raw file descriptor
+        /// to the caller. The descriptor is only guarantee to be valid while
+        /// the original object has not yet been destroyed.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn as_raw_fd(&self) -> RawFd;
+    }
 
-/// Raw file descriptors.
-pub type Fd = libc::c_int;
+    /// A trait to express the ability to construct an object from a raw file
+    /// descriptor.
+    #[unstable(feature = "from_raw_os",
+               reason = "recent addition to std::os::unix::io")]
+    pub trait FromRawFd {
+        /// Constructs a new instances of `Self` from the given raw file
+        /// descriptor.
+        ///
+        /// This function **consumes ownership** of the specified file
+        /// descriptor. The returned object will take responsibility for closing
+        /// it when the object goes out of scope.
+        ///
+        /// Callers should normally only pass in a valid file descriptor to this
+        /// method or otherwise methods will return errors.
+        fn from_raw_fd(fd: RawFd) -> Self;
+    }
 
-/// Extract raw file descriptor
-pub trait AsRawFd {
-    /// Extract the raw file descriptor, without taking any ownership.
-    fn as_raw_fd(&self) -> Fd;
-}
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawFd for old_io::fs::File {
+        fn as_raw_fd(&self) -> RawFd {
+            self.as_inner().fd()
+        }
+    }
 
-impl AsRawFd for old_io::fs::File {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawFd for fs::File {
+        fn as_raw_fd(&self) -> RawFd {
+            self.as_inner().fd().raw()
+        }
+    }
+    #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+    impl FromRawFd for fs::File {
+        fn from_raw_fd(fd: RawFd) -> fs::File {
+            fs::File::from_inner(sys::fs2::File::from_inner(fd))
+        }
     }
-}
 
-impl AsRawFd for fs::File {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd().raw()
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawFd for old_io::pipe::PipeStream {
+        fn as_raw_fd(&self) -> RawFd {
+            self.as_inner().fd()
+        }
     }
-}
 
-impl AsRawFd for old_io::pipe::PipeStream {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawFd for old_io::net::pipe::UnixStream {
+        fn as_raw_fd(&self) -> RawFd {
+            self.as_inner().fd()
+        }
     }
-}
 
-impl AsRawFd for old_io::net::pipe::UnixStream {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawFd for old_io::net::pipe::UnixListener {
+        fn as_raw_fd(&self) -> RawFd {
+            self.as_inner().fd()
+        }
     }
-}
 
-impl AsRawFd for old_io::net::pipe::UnixListener {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawFd for old_io::net::pipe::UnixAcceptor {
+        fn as_raw_fd(&self) -> RawFd {
+            self.as_inner().fd()
+        }
     }
-}
 
-impl AsRawFd for old_io::net::pipe::UnixAcceptor {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[allow(deprecated)]
+    impl AsRawFd for old_io::net::tcp::TcpStream {
+        fn as_raw_fd(&self) -> RawFd {
+            self.as_inner().fd()
+        }
     }
-}
 
-impl AsRawFd for old_io::net::tcp::TcpStream {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[allow(deprecated)]
+    impl AsRawFd for old_io::net::tcp::TcpListener {
+        fn as_raw_fd(&self) -> RawFd {
+            self.as_inner().fd()
+        }
     }
-}
 
-impl AsRawFd for old_io::net::tcp::TcpListener {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[allow(deprecated)]
+    impl AsRawFd for old_io::net::tcp::TcpAcceptor {
+        fn as_raw_fd(&self) -> RawFd {
+            self.as_inner().fd()
+        }
     }
-}
 
-impl AsRawFd for old_io::net::tcp::TcpAcceptor {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawFd for old_io::net::udp::UdpSocket {
+        fn as_raw_fd(&self) -> RawFd {
+            self.as_inner().fd()
+        }
     }
-}
 
-impl AsRawFd for old_io::net::udp::UdpSocket {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawFd for net::TcpStream {
+        fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
+    }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawFd for net::TcpListener {
+        fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
+    }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawFd for net::UdpSocket {
+        fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
     }
-}
 
-impl AsRawFd for net::TcpStream {
-    fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
-}
-impl AsRawFd for net::TcpListener {
-    fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
-}
-impl AsRawFd for net::UdpSocket {
-    fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
+    #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+    impl FromRawFd for net::TcpStream {
+        fn from_raw_fd(fd: RawFd) -> net::TcpStream {
+            let socket = sys::net::Socket::from_inner(fd);
+            net::TcpStream::from_inner(net2::TcpStream::from_inner(socket))
+        }
+    }
+    #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+    impl FromRawFd for net::TcpListener {
+        fn from_raw_fd(fd: RawFd) -> net::TcpListener {
+            let socket = sys::net::Socket::from_inner(fd);
+            net::TcpListener::from_inner(net2::TcpListener::from_inner(socket))
+        }
+    }
+    #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+    impl FromRawFd for net::UdpSocket {
+        fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
+            let socket = sys::net::Socket::from_inner(fd);
+            net::UdpSocket::from_inner(net2::UdpSocket::from_inner(socket))
+        }
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // OsString and OsStr
 ////////////////////////////////////////////////////////////////////////////////
 
-/// Unix-specific extensions to `OsString`.
-pub trait OsStringExt {
-    /// Create an `OsString` from a byte vector.
-    fn from_vec(vec: Vec<u8>) -> Self;
-
-    /// Yield the underlying byte vector of this `OsString`.
-    fn into_vec(self) -> Vec<u8>;
-}
-
-impl OsStringExt for OsString {
-    fn from_vec(vec: Vec<u8>) -> OsString {
-        FromInner::from_inner(Buf { inner: vec })
+/// Unix-specific extension to the primitives in the `std::ffi` module
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod ffi {
+    use ffi::{OsStr, OsString};
+    use mem;
+    use prelude::v1::*;
+    use sys::os_str::Buf;
+    use sys_common::{FromInner, IntoInner, AsInner};
+
+    /// Unix-specific extensions to `OsString`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait OsStringExt {
+        /// Create an `OsString` from a byte vector.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn from_vec(vec: Vec<u8>) -> Self;
+
+        /// Yield the underlying byte vector of this `OsString`.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn into_vec(self) -> Vec<u8>;
     }
 
-    fn into_vec(self) -> Vec<u8> {
-        self.into_inner().inner
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl OsStringExt for OsString {
+        fn from_vec(vec: Vec<u8>) -> OsString {
+            FromInner::from_inner(Buf { inner: vec })
+        }
+        fn into_vec(self) -> Vec<u8> {
+            self.into_inner().inner
+        }
     }
-}
-
-/// Unix-specific extensions to `OsStr`.
-pub trait OsStrExt {
-    fn from_bytes(slice: &[u8]) -> &OsStr;
 
-    /// Get the underlying byte view of the `OsStr` slice.
-    fn as_bytes(&self) -> &[u8];
+    /// Unix-specific extensions to `OsStr`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait OsStrExt {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn from_bytes(slice: &[u8]) -> &Self;
 
-    /// Convert the `OsStr` slice into a `CString`.
-    fn to_cstring(&self) -> Result<CString, NulError>;
-}
-
-impl OsStrExt for OsStr {
-    fn from_bytes(slice: &[u8]) -> &OsStr {
-        unsafe { mem::transmute(slice) }
-    }
-    fn as_bytes(&self) -> &[u8] {
-        &self.as_inner().inner
+        /// Get the underlying byte view of the `OsStr` slice.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn as_bytes(&self) -> &[u8];
     }
 
-    fn to_cstring(&self) -> Result<CString, NulError> {
-        CString::new(self.as_bytes())
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl OsStrExt for OsStr {
+        fn from_bytes(slice: &[u8]) -> &OsStr {
+            unsafe { mem::transmute(slice) }
+        }
+        fn as_bytes(&self) -> &[u8] {
+            &self.as_inner().inner
+        }
     }
 }
 
-// Unix-specific extensions to `Permissions`
-pub trait PermissionsExt {
-    fn set_mode(&mut self, mode: i32);
-}
+/// Unix-specific extensions to primitives in the `std::fs` module.
+#[unstable(feature = "fs_ext",
+           reason = "may want a more useful mode abstraction")]
+pub mod fs {
+    use sys_common::{FromInner, AsInner, AsInnerMut};
+    use fs::{Permissions, OpenOptions};
+
+    /// Unix-specific extensions to `Permissions`
+    pub trait PermissionsExt {
+        fn mode(&self) -> i32;
+        fn set_mode(&mut self, mode: i32);
+    }
 
-impl PermissionsExt for Permissions {
-    fn set_mode(&mut self, mode: i32) {
-        *self = FromInner::from_inner(FromInner::from_inner(mode));
+    impl PermissionsExt for Permissions {
+        fn mode(&self) -> i32 { self.as_inner().mode() }
+
+        fn set_mode(&mut self, mode: i32) {
+            *self = FromInner::from_inner(FromInner::from_inner(mode));
+        }
     }
-}
 
-// Unix-specific extensions to `OpenOptions`
-pub trait OpenOptionsExt {
-    /// Set the mode bits that a new file will be created with.
-    ///
-    /// If a new file is created as part of a `File::open_opts` call then this
-    /// specified `mode` will be used as the permission bits for the new file.
-    fn mode(&mut self, mode: i32) -> &mut Self;
-}
+    /// Unix-specific extensions to `OpenOptions`
+    pub trait OpenOptionsExt {
+        /// Set the mode bits that a new file will be created with.
+        ///
+        /// If a new file is created as part of a `File::open_opts` call then this
+        /// specified `mode` will be used as the permission bits for the new file.
+        fn mode(&mut self, mode: i32) -> &mut Self;
+    }
 
-impl OpenOptionsExt for OpenOptions {
-    fn mode(&mut self, mode: i32) -> &mut OpenOptions {
-        self.as_inner_mut().mode(mode); self
+    impl OpenOptionsExt for OpenOptions {
+        fn mode(&mut self, mode: i32) -> &mut OpenOptions {
+            self.as_inner_mut().mode(mode); self
+        }
     }
 }
 
@@ -201,41 +298,58 @@ impl OpenOptionsExt for OpenOptions {
 // Process and Command
 ////////////////////////////////////////////////////////////////////////////////
 
-/// Unix-specific extensions to the `std::process::Command` builder
-pub trait CommandExt {
-    /// Sets the child process's user id. This translates to a
-    /// `setuid` call in the child process. Failure in the `setuid`
-    /// call will cause the spawn to fail.
-    fn uid(&mut self, id: uid_t) -> &mut process::Command;
+/// Unix-specific extensions to primitives in the `std::process` module.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod process {
+    use prelude::v1::*;
+    use libc::{uid_t, gid_t};
+    use process;
+    use sys;
+    use sys_common::{AsInnerMut, AsInner};
+
+    /// Unix-specific extensions to the `std::process::Command` builder
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait CommandExt {
+        /// Sets the child process's user id. This translates to a
+        /// `setuid` call in the child process. Failure in the `setuid`
+        /// call will cause the spawn to fail.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn uid(&mut self, id: uid_t) -> &mut process::Command;
+
+        /// Similar to `uid`, but sets the group id of the child process. This has
+        /// the same semantics as the `uid` field.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn gid(&mut self, id: gid_t) -> &mut process::Command;
+    }
 
-    /// Similar to `uid`, but sets the group id of the child process. This has
-    /// the same semantics as the `uid` field.
-    fn gid(&mut self, id: gid_t) -> &mut process::Command;
-}
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl CommandExt for process::Command {
+        fn uid(&mut self, id: uid_t) -> &mut process::Command {
+            self.as_inner_mut().uid = Some(id);
+            self
+        }
 
-impl CommandExt for process::Command {
-    fn uid(&mut self, id: uid_t) -> &mut process::Command {
-        self.as_inner_mut().uid = Some(id);
-        self
+        fn gid(&mut self, id: gid_t) -> &mut process::Command {
+            self.as_inner_mut().gid = Some(id);
+            self
+        }
     }
 
-    fn gid(&mut self, id: gid_t) -> &mut process::Command {
-        self.as_inner_mut().gid = Some(id);
-        self
+    /// Unix-specific extensions to `std::process::ExitStatus`
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait ExitStatusExt {
+        /// If the process was terminated by a signal, returns that signal.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn signal(&self) -> Option<i32>;
     }
-}
-
-/// Unix-specific extensions to `std::process::ExitStatus`
-pub trait ExitStatusExt {
-    /// If the process was terminated by a signal, returns that signal.
-    fn signal(&self) -> Option<i32>;
-}
 
-impl ExitStatusExt for process::ExitStatus {
-    fn signal(&self) -> Option<i32> {
-        match *self.as_inner() {
-            sys::process2::ExitStatus::Signal(s) => Some(s),
-            _ => None
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl ExitStatusExt for process::ExitStatus {
+        fn signal(&self) -> Option<i32> {
+            match *self.as_inner() {
+                sys::process2::ExitStatus::Signal(s) => Some(s),
+                _ => None
+            }
         }
     }
 }
@@ -247,9 +361,14 @@ impl ExitStatusExt for process::ExitStatus {
 /// A prelude for conveniently writing platform-specific code.
 ///
 /// Includes all extension traits, and some important type definitions.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub mod prelude {
     #[doc(no_inline)]
-    pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt};
+    pub use super::io::{RawFd, AsRawFd};
+    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+    pub use super::ffi::{OsStrExt, OsStringExt};
     #[doc(no_inline)]
-    pub use super::{CommandExt, ExitStatusExt};
+    pub use super::fs::{PermissionsExt, OpenOptionsExt};
+    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+    pub use super::process::{CommandExt, ExitStatusExt};
 }
index 327d117823ee37e1360164a678ad4a71fabb5b6b..f7c57c3f5e53747992ef77809b574dc02ae0a1a2 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use core::prelude::*;
-use io::prelude::*;
 
 use io;
 use libc::{self, c_int, size_t, c_void};
index 5c847002d2394f35c1f4d7cb9c142f40edbe2de6..6b085c8eb7a85fc90b41b2239c4410e29118c5f4 100644 (file)
@@ -9,6 +9,9 @@
 // except according to those terms.
 
 //! Blocking posix-based file I/O
+#![allow(deprecated)]
+
+#![allow(deprecated)] // this module itself is essentially deprecated
 
 use prelude::v1::*;
 
@@ -17,6 +20,7 @@ use old_io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode
 use old_io::{IoResult, FileStat, SeekStyle};
 use old_io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append};
 use old_io;
+use old_path::{Path, GenericPath};
 use libc::{self, c_int, c_void};
 use mem;
 use ptr;
@@ -38,7 +42,7 @@ impl FileDesc {
         FileDesc { fd: fd, close_on_drop: close_on_drop }
     }
 
-    pub fn read(&self, buf: &mut [u8]) -> IoResult<uint> {
+    pub fn read(&self, buf: &mut [u8]) -> IoResult<usize> {
         let ret = retry(|| unsafe {
             libc::read(self.fd(),
                        buf.as_mut_ptr() as *mut libc::c_void,
@@ -49,7 +53,7 @@ impl FileDesc {
         } else if ret < 0 {
             Err(super::last_error())
         } else {
-            Ok(ret as uint)
+            Ok(ret as usize)
         }
     }
     pub fn write(&self, buf: &[u8]) -> IoResult<()> {
@@ -177,7 +181,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
     }
 }
 
-pub fn mkdir(p: &Path, mode: uint) -> IoResult<()> {
+pub fn mkdir(p: &Path, mode: usize) -> IoResult<()> {
     let p = try!(cstr(p));
     mkerr_libc(unsafe { libc::mkdir(p.as_ptr(), mode as libc::mode_t) })
 }
@@ -200,13 +204,13 @@ pub fn readdir(p: &Path) -> IoResult<Vec<Path>> {
     }
 
     let size = unsafe { rust_dirent_t_size() };
-    let mut buf = Vec::<u8>::with_capacity(size as uint);
+    let mut buf = Vec::<u8>::with_capacity(size as usize);
     let ptr = buf.as_mut_ptr() as *mut dirent_t;
 
     let p = try!(CString::new(p.as_vec()));
     let dir_ptr = unsafe {opendir(p.as_ptr())};
 
-    if dir_ptr as uint != 0 {
+    if dir_ptr as usize != 0 {
         let mut paths = vec!();
         let mut entry_ptr = ptr::null_mut();
         while unsafe { readdir_r(dir_ptr, ptr, &mut entry_ptr) == 0 } {
@@ -235,7 +239,7 @@ pub fn rename(old: &Path, new: &Path) -> IoResult<()> {
     })
 }
 
-pub fn chmod(p: &Path, mode: uint) -> IoResult<()> {
+pub fn chmod(p: &Path, mode: usize) -> IoResult<()> {
     let p = try!(cstr(p));
     mkerr_libc(retry(|| unsafe {
         libc::chmod(p.as_ptr(), mode as libc::mode_t)
@@ -247,7 +251,7 @@ pub fn rmdir(p: &Path) -> IoResult<()> {
     mkerr_libc(unsafe { libc::rmdir(p.as_ptr()) })
 }
 
-pub fn chown(p: &Path, uid: int, gid: int) -> IoResult<()> {
+pub fn chown(p: &Path, uid: isize, gid: isize) -> IoResult<()> {
     let p = try!(cstr(p));
     mkerr_libc(retry(|| unsafe {
         libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t)
@@ -261,7 +265,7 @@ pub fn readlink(p: &Path) -> IoResult<Path> {
     if len == -1 {
         len = 1024; // FIXME: read PATH_MAX from C ffi?
     }
-    let mut buf: Vec<u8> = Vec::with_capacity(len as uint);
+    let mut buf: Vec<u8> = Vec::with_capacity(len as usize);
     match unsafe {
         libc::readlink(p, buf.as_ptr() as *mut libc::c_char,
                        len as libc::size_t) as libc::c_int
@@ -269,7 +273,7 @@ pub fn readlink(p: &Path) -> IoResult<Path> {
         -1 => Err(super::last_error()),
         n => {
             assert!(n > 0);
-            unsafe { buf.set_len(n as uint); }
+            unsafe { buf.set_len(n as usize); }
             Ok(Path::new(buf))
         }
     }
@@ -291,6 +295,18 @@ fn mkstat(stat: &libc::stat) -> FileStat {
     // FileStat times are in milliseconds
     fn mktime(secs: u64, nsecs: u64) -> u64 { secs * 1000 + nsecs / 1000000 }
 
+    fn ctime(stat: &libc::stat) -> u64 {
+      mktime(stat.st_ctime as u64, stat.st_ctime_nsec as u64)
+    }
+
+    fn atime(stat: &libc::stat) -> u64 {
+      mktime(stat.st_atime as u64, stat.st_atime_nsec as u64)
+    }
+
+    fn mtime(stat: &libc::stat) -> u64 {
+      mktime(stat.st_mtime as u64, stat.st_mtime_nsec as u64)
+    }
+
     #[cfg(not(any(target_os = "linux", target_os = "android")))]
     fn flags(stat: &libc::stat) -> u64 { stat.st_flags as u64 }
     #[cfg(any(target_os = "linux", target_os = "android"))]
@@ -312,9 +328,9 @@ fn mkstat(stat: &libc::stat) -> FileStat {
             _ => old_io::FileType::Unknown,
         },
         perm: FilePermission::from_bits_truncate(stat.st_mode as u32),
-        created: mktime(stat.st_ctime as u64, stat.st_ctime_nsec as u64),
-        modified: mktime(stat.st_mtime as u64, stat.st_mtime_nsec as u64),
-        accessed: mktime(stat.st_atime as u64, stat.st_atime_nsec as u64),
+        created: ctime(stat),
+        modified: mtime(stat),
+        accessed: atime(stat),
         unstable: UnstableFileStat {
             device: stat.st_dev as u64,
             inode: stat.st_ino as u64,
@@ -372,12 +388,10 @@ mod tests {
     fn test_file_desc() {
         // Run this test with some pipes so we don't have to mess around with
         // opening or closing files.
-        let os::Pipe { reader, writer } = unsafe { os::pipe().unwrap() };
-        let mut reader = FileDesc::new(reader, true);
-        let mut writer = FileDesc::new(writer, true);
+        let (mut reader, mut writer) = unsafe { ::sys::os::pipe().unwrap() };
 
-        writer.write(b"test").ok().unwrap();
-        let mut buf = [0u8; 4];
+        writer.write(b"test").unwrap();
+        let mut buf = [0; 4];
         match reader.read(&mut buf) {
             Ok(4) => {
                 assert_eq!(buf[0], 't' as u8);
index 92a47c6c3850df3a34b3ac132e83f72314db86d6..c0426af051be372061b45cae94f907247ae57298 100644 (file)
@@ -12,13 +12,13 @@ use core::prelude::*;
 use io::prelude::*;
 use os::unix::prelude::*;
 
-use ffi::{CString, CStr, OsString, AsOsStr, OsStr};
-use io::{self, Error, Seek, SeekFrom};
-use libc::{self, c_int, c_void, size_t, off_t, c_char, mode_t};
+use ffi::{CString, CStr, OsString, OsStr};
+use io::{self, Error, SeekFrom};
+use libc::{self, c_int, size_t, off_t, c_char, mode_t};
 use mem;
 use path::{Path, PathBuf};
 use ptr;
-use rc::Rc;
+use sync::Arc;
 use sys::fd::FileDesc;
 use sys::{c, cvt, cvt_r};
 use sys_common::FromInner;
@@ -31,14 +31,18 @@ pub struct FileAttr {
 }
 
 pub struct ReadDir {
-    dirp: *mut libc::DIR,
-    root: Rc<PathBuf>,
+    dirp: Dir,
+    root: Arc<PathBuf>,
 }
 
+struct Dir(*mut libc::DIR);
+
+unsafe impl Send for Dir {}
+unsafe impl Sync for Dir {}
+
 pub struct DirEntry {
-    buf: Vec<u8>,
-    dirent: *mut libc::dirent_t,
-    root: Rc<PathBuf>,
+    buf: Vec<u8>, // actually *mut libc::dirent_t
+    root: Arc<PathBuf>,
 }
 
 #[derive(Clone)]
@@ -86,6 +90,7 @@ impl FilePermissions {
             self.mode |= 0o222;
         }
     }
+    pub fn mode(&self) -> i32 { self.mode as i32 }
 }
 
 impl FromInner<i32> for FilePermissions {
@@ -109,7 +114,7 @@ impl Iterator for ReadDir {
 
         let mut entry_ptr = ptr::null_mut();
         loop {
-            if unsafe { libc::readdir_r(self.dirp, ptr, &mut entry_ptr) != 0 } {
+            if unsafe { libc::readdir_r(self.dirp.0, ptr, &mut entry_ptr) != 0 } {
                 return Some(Err(Error::last_os_error()))
             }
             if entry_ptr.is_null() {
@@ -118,7 +123,6 @@ impl Iterator for ReadDir {
 
             let entry = DirEntry {
                 buf: buf,
-                dirent: entry_ptr,
                 root: self.root.clone()
             };
             if entry.name_bytes() == b"." || entry.name_bytes() == b".." {
@@ -130,9 +134,9 @@ impl Iterator for ReadDir {
     }
 }
 
-impl Drop for ReadDir {
+impl Drop for Dir {
     fn drop(&mut self) {
-        let r = unsafe { libc::closedir(self.dirp) };
+        let r = unsafe { libc::closedir(self.0) };
         debug_assert_eq!(r, 0);
     }
 }
@@ -147,9 +151,13 @@ impl DirEntry {
             fn rust_list_dir_val(ptr: *mut libc::dirent_t) -> *const c_char;
         }
         unsafe {
-            CStr::from_ptr(rust_list_dir_val(self.dirent)).to_bytes()
+            CStr::from_ptr(rust_list_dir_val(self.dirent())).to_bytes()
         }
     }
+
+    fn dirent(&self) -> *mut libc::dirent_t {
+        self.buf.as_ptr() as *mut _
+    }
 }
 
 impl OpenOptions {
@@ -268,8 +276,14 @@ impl File {
 }
 
 fn cstr(path: &Path) -> io::Result<CString> {
-    let cstring = try!(path.as_os_str().to_cstring());
-    Ok(cstring)
+    path.as_os_str().to_cstring().ok_or(
+        io::Error::new(io::ErrorKind::InvalidInput, "path contained a null"))
+}
+
+impl FromInner<c_int> for File {
+    fn from_inner(fd: c_int) -> File {
+        File(FileDesc::new(fd))
+    }
 }
 
 pub fn mkdir(p: &Path) -> io::Result<()> {
@@ -279,14 +293,14 @@ pub fn mkdir(p: &Path) -> io::Result<()> {
 }
 
 pub fn readdir(p: &Path) -> io::Result<ReadDir> {
-    let root = Rc::new(p.to_path_buf());
+    let root = Arc::new(p.to_path_buf());
     let p = try!(cstr(p));
     unsafe {
         let ptr = libc::opendir(p.as_ptr());
         if ptr.is_null() {
             Err(Error::last_os_error())
         } else {
-            Ok(ReadDir { dirp: ptr, root: root })
+            Ok(ReadDir { dirp: Dir(ptr), root: root })
         }
     }
 }
@@ -316,14 +330,6 @@ pub fn rmdir(p: &Path) -> io::Result<()> {
     Ok(())
 }
 
-pub fn chown(p: &Path, uid: isize, gid: isize) -> io::Result<()> {
-    let p = try!(cstr(p));
-    try!(cvt_r(|| unsafe {
-        libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t)
-    }));
-    Ok(())
-}
-
 pub fn readlink(p: &Path) -> io::Result<PathBuf> {
     let c_path = try!(cstr(p));
     let p = c_path.as_ptr();
@@ -338,8 +344,7 @@ pub fn readlink(p: &Path) -> io::Result<PathBuf> {
         }));
         buf.set_len(n as usize);
     }
-    let s: OsString = OsStringExt::from_vec(buf);
-    Ok(PathBuf::new(&s))
+    Ok(PathBuf::from(OsString::from_vec(buf)))
 }
 
 pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
index ed9bd0a239f11b30056db8ad240ce397a2f5c740..fe0ede80fc663cbda1451a8cfffecb65aaecb178 100644 (file)
@@ -8,20 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(deprecated)]
+
 use libc;
-use os;
+use sys::os;
 
 use sys::fs::FileDesc;
 
 pub type signal = libc::c_int;
 
 pub fn new() -> (signal, signal) {
-    let os::Pipe { reader, writer } = unsafe { os::pipe().unwrap() };
-    (reader, writer)
+    let (a, b) = unsafe { os::pipe().unwrap() };
+    (a.unwrap(), b.unwrap())
 }
 
 pub fn signal(fd: libc::c_int) {
-    FileDesc::new(fd, false).write(&[0]).ok().unwrap();
+    FileDesc::new(fd, false).write(&[0]).unwrap();
 }
 
 pub fn close(fd: libc::c_int) {
index b79ad7031fa48dc31dcc208036ae5f5bf353eaf1..e8409bb4fd42c3ae61d322ed070b19257b547d19 100644 (file)
 
 #![allow(missing_docs)]
 #![allow(non_camel_case_types)]
-#![allow(unused_imports)]
-#![allow(dead_code)]
-#![allow(unused_unsafe)]
-#![allow(unused_mut)]
 
 use prelude::v1::*;
 
@@ -21,22 +17,10 @@ use ffi::CStr;
 use io::{self, ErrorKind};
 use libc;
 use num::{Int, SignedInt};
-use num;
-use old_io::{self, IoResult, IoError};
+use old_io::{self, IoError};
 use str;
 use sys_common::mkerr_libc;
 
-macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
-    static $name: Helper<$m> = Helper {
-        lock: ::sync::MUTEX_INIT,
-        cond: ::sync::CONDVAR_INIT,
-        chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> },
-        signal: ::cell::UnsafeCell { value: 0 },
-        initialized: ::cell::UnsafeCell { value: false },
-        shutdown: ::cell::UnsafeCell { value: false },
-    };
-) }
-
 pub mod backtrace;
 pub mod c;
 pub mod condvar;
@@ -63,6 +47,7 @@ pub mod time;
 pub mod timer;
 pub mod tty;
 pub mod udp;
+pub mod stdio;
 
 pub mod addrinfo {
     pub use sys_common::net::get_host_addresses;
@@ -75,10 +60,12 @@ pub type wrlen = libc::size_t;
 pub type msglen_t = libc::size_t;
 pub unsafe fn close_sock(sock: sock_t) { let _ = libc::close(sock); }
 
+#[allow(deprecated)]
 pub fn last_error() -> IoError {
     decode_error_detailed(os::errno() as i32)
 }
 
+#[allow(deprecated)]
 pub fn last_net_error() -> IoError {
     last_error()
 }
@@ -87,6 +74,7 @@ extern "system" {
     fn gai_strerror(errcode: libc::c_int) -> *const libc::c_char;
 }
 
+#[allow(deprecated)]
 pub fn last_gai_error(s: libc::c_int) -> IoError {
 
     let mut err = decode_error(s);
@@ -98,6 +86,7 @@ pub fn last_gai_error(s: libc::c_int) -> IoError {
 }
 
 /// Convert an `errno` value into a high-level error variant and description.
+#[allow(deprecated)]
 pub fn decode_error(errno: i32) -> IoError {
     // FIXME: this should probably be a bit more descriptive...
     let (kind, desc) = match errno {
@@ -134,12 +123,14 @@ pub fn decode_error(errno: i32) -> IoError {
     IoError { kind: kind, desc: desc, detail: None }
 }
 
+#[allow(deprecated)]
 pub fn decode_error_detailed(errno: i32) -> IoError {
     let mut err = decode_error(errno);
     err.detail = Some(os::error_string(errno));
     err
 }
 
+#[allow(deprecated)]
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
     match errno as libc::c_int {
         libc::ECONNREFUSED => ErrorKind::ConnectionRefused,
@@ -148,28 +139,26 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
         libc::EPIPE => ErrorKind::BrokenPipe,
         libc::ENOTCONN => ErrorKind::NotConnected,
         libc::ECONNABORTED => ErrorKind::ConnectionAborted,
-        libc::EADDRNOTAVAIL => ErrorKind::ConnectionRefused,
-        libc::EADDRINUSE => ErrorKind::ConnectionRefused,
-        libc::ENOENT => ErrorKind::FileNotFound,
-        libc::EISDIR => ErrorKind::InvalidInput,
+        libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
+        libc::EADDRINUSE => ErrorKind::AddrInUse,
+        libc::ENOENT => ErrorKind::NotFound,
         libc::EINTR => ErrorKind::Interrupted,
         libc::EINVAL => ErrorKind::InvalidInput,
-        libc::ENOTTY => ErrorKind::MismatchedFileTypeForOperation,
         libc::ETIMEDOUT => ErrorKind::TimedOut,
-        libc::ECANCELED => ErrorKind::TimedOut,
-        libc::consts::os::posix88::EEXIST => ErrorKind::PathAlreadyExists,
+        libc::consts::os::posix88::EEXIST => ErrorKind::AlreadyExists,
 
         // These two constants can have the same value on some systems,
         // but different values on others, so we can't use a match
         // clause
         x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
-            ErrorKind::ResourceUnavailable,
+            ErrorKind::WouldBlock,
 
         _ => ErrorKind::Other,
     }
 }
 
 #[inline]
+#[allow(deprecated)]
 pub fn retry<T, F> (mut f: F) -> T where
     T: SignedInt,
     F: FnMut() -> T,
@@ -182,6 +171,7 @@ pub fn retry<T, F> (mut f: F) -> T where
     }
 }
 
+#[allow(deprecated)]
 pub fn cvt<T: SignedInt>(t: T) -> io::Result<T> {
     let one: T = Int::one();
     if t == -one {
@@ -191,6 +181,7 @@ pub fn cvt<T: SignedInt>(t: T) -> io::Result<T> {
     }
 }
 
+#[allow(deprecated)]
 pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
     where T: SignedInt, F: FnMut() -> T
 {
@@ -209,14 +200,16 @@ pub fn ms_to_timeval(ms: u64) -> libc::timeval {
     }
 }
 
+#[allow(deprecated)]
 pub fn wouldblock() -> bool {
     let err = os::errno();
     err == libc::EWOULDBLOCK as i32 || err == libc::EAGAIN as i32
 }
 
-pub fn set_nonblocking(fd: sock_t, nb: bool) -> IoResult<()> {
+#[allow(deprecated)]
+pub fn set_nonblocking(fd: sock_t, nb: bool) {
     let set = nb as libc::c_int;
-    mkerr_libc(retry(|| unsafe { c::ioctl(fd, c::FIONBIO, &set) }))
+    mkerr_libc(retry(|| unsafe { c::ioctl(fd, c::FIONBIO, &set) })).unwrap();
 }
 
 // nothing needed on unix platforms
index 9e1527aef201abdfb0215143a18bdb46ef0bc4cd..1c0ce2938040dceee727939abeff47242bda5f19 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use prelude::v1::*;
+
 use cell::UnsafeCell;
-use marker::Sync;
 use sys::sync as ffi;
-use sys_common::mutex;
 
 pub struct Mutex { inner: UnsafeCell<ffi::pthread_mutex_t> }
 
@@ -24,8 +24,10 @@ pub const MUTEX_INIT: Mutex = Mutex {
     inner: UnsafeCell { value: ffi::PTHREAD_MUTEX_INITIALIZER },
 };
 
+unsafe impl Send for Mutex {}
 unsafe impl Sync for Mutex {}
 
+#[allow(dead_code)] // sys isn't exported yet
 impl Mutex {
     #[inline]
     pub unsafe fn new() -> Mutex {
index 83b6a14b78d95fd3f1ed4d8c385ec550bbb63d11..908136a42ab00a96723bc902d863def68d5f26ef 100644 (file)
@@ -15,9 +15,9 @@ use io;
 use libc::{self, c_int, size_t};
 use str;
 use sys::c;
-use net::{SocketAddr, IpAddr};
+use net::SocketAddr;
 use sys::fd::FileDesc;
-use sys_common::AsInner;
+use sys_common::{AsInner, FromInner};
 
 pub use sys::{cvt, cvt_r};
 
@@ -35,14 +35,15 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
             .to_string()
     };
     Err(io::Error::new(io::ErrorKind::Other,
-                       "failed to lookup address information", Some(detail)))
+                       &format!("failed to lookup address information: {}",
+                                detail)[..]))
 }
 
 impl Socket {
     pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
-        let fam = match addr.ip() {
-            IpAddr::V4(..) => libc::AF_INET,
-            IpAddr::V6(..) => libc::AF_INET6,
+        let fam = match *addr {
+            SocketAddr::V4(..) => libc::AF_INET,
+            SocketAddr::V6(..) => libc::AF_INET6,
         };
         unsafe {
             let fd = try!(cvt(libc::socket(fam, ty, 0)));
@@ -72,3 +73,7 @@ impl Socket {
 impl AsInner<c_int> for Socket {
     fn as_inner(&self) -> &c_int { self.0.as_inner() }
 }
+
+impl FromInner<c_int> for Socket {
+    fn from_inner(fd: c_int) -> Socket { Socket(FileDesc::new(fd)) }
+}
index 3d1ef3a2c37f7e8267dfb65d84f79ba4e0e55bc1..d2220bdec32b78fa1f054a720742c900ac7a6e63 100644 (file)
 
 //! Implementation of `std::os` functionality for unix systems
 
+#![allow(unused_imports)] // lots of cfg code here
+
 use prelude::v1::*;
-use os::unix::*;
+use os::unix::prelude::*;
 
 use error::Error as StdError;
-use ffi::{CString, CStr, OsString, OsStr, AsOsStr};
+use ffi::{CString, CStr, OsString, OsStr};
 use fmt;
+use io;
 use iter;
 use libc::{self, c_int, c_char, c_void};
 use mem;
-use io;
-use old_io::{IoResult, IoError, fs};
+#[allow(deprecated)] use old_io::{IoError, IoResult};
 use ptr;
+use path::{self, PathBuf};
 use slice;
 use str;
 use sys::c;
@@ -32,6 +35,14 @@ use vec;
 const BUF_BYTES: usize = 2048;
 const TMPBUF_SZ: usize = 128;
 
+fn bytes2path(b: &[u8]) -> PathBuf {
+    PathBuf::from(<OsStr as OsStrExt>::from_bytes(b))
+}
+
+fn os2path(os: OsString) -> PathBuf {
+    bytes2path(os.as_bytes())
+}
+
 /// Returns the platform-specific value of errno
 pub fn errno() -> i32 {
     #[cfg(any(target_os = "macos",
@@ -42,6 +53,16 @@ pub fn errno() -> i32 {
         __error()
     }
 
+    #[cfg(target_os = "bitrig")]
+    fn errno_location() -> *const c_int {
+        extern {
+            fn __errno() -> *const c_int;
+        }
+        unsafe {
+            __errno()
+        }
+    }
+
     #[cfg(target_os = "dragonfly")]
     unsafe fn errno_location() -> *const c_int {
         extern { fn __dfly_error() -> *const c_int; }
@@ -92,30 +113,31 @@ pub fn error_string(errno: i32) -> String {
     }
 }
 
-pub fn getcwd() -> IoResult<Path> {
+pub fn getcwd() -> io::Result<PathBuf> {
     let mut buf = [0 as c_char; BUF_BYTES];
     unsafe {
         if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() {
-            Err(IoError::last_error())
+            Err(io::Error::last_os_error())
         } else {
-            Ok(Path::new(CStr::from_ptr(buf.as_ptr()).to_bytes()))
+            Ok(bytes2path(CStr::from_ptr(buf.as_ptr()).to_bytes()))
         }
     }
 }
 
-pub fn chdir(p: &Path) -> IoResult<()> {
-    let p = CString::new(p.as_vec()).unwrap();
+pub fn chdir(p: &path::Path) -> io::Result<()> {
+    let p: &OsStr = p.as_ref();
+    let p = try!(CString::new(p.as_bytes()));
     unsafe {
         match libc::chdir(p.as_ptr()) == (0 as c_int) {
             true => Ok(()),
-            false => Err(IoError::last_error()),
+            false => Err(io::Error::last_os_error()),
         }
     }
 }
 
 pub struct SplitPaths<'a> {
     iter: iter::Map<slice::Split<'a, u8, fn(&u8) -> bool>,
-                    fn(&'a [u8]) -> Path>,
+                    fn(&'a [u8]) -> PathBuf>,
 }
 
 pub fn split_paths<'a>(unparsed: &'a OsStr) -> SplitPaths<'a> {
@@ -123,13 +145,13 @@ pub fn split_paths<'a>(unparsed: &'a OsStr) -> SplitPaths<'a> {
     let unparsed = unparsed.as_bytes();
     SplitPaths {
         iter: unparsed.split(is_colon as fn(&u8) -> bool)
-                      .map(Path::new as fn(&'a [u8]) ->  Path)
+                      .map(bytes2path as fn(&'a [u8]) -> PathBuf)
     }
 }
 
 impl<'a> Iterator for SplitPaths<'a> {
-    type Item = Path;
-    fn next(&mut self) -> Option<Path> { self.iter.next() }
+    type Item = PathBuf;
+    fn next(&mut self) -> Option<PathBuf> { self.iter.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
 }
 
@@ -137,13 +159,13 @@ impl<'a> Iterator for SplitPaths<'a> {
 pub struct JoinPathsError;
 
 pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
-    where I: Iterator<Item=T>, T: AsOsStr
+    where I: Iterator<Item=T>, T: AsRef<OsStr>
 {
     let mut joined = Vec::new();
     let sep = b':';
 
     for (i, path) in paths.enumerate() {
-        let path = path.as_os_str().as_bytes();
+        let path = path.as_ref().as_bytes();
         if i > 0 { joined.push(sep) }
         if path.contains(&sep) {
             return Err(JoinPathsError)
@@ -164,7 +186,7 @@ impl StdError for JoinPathsError {
 }
 
 #[cfg(target_os = "freebsd")]
-pub fn current_exe() -> IoResult<Path> {
+pub fn current_exe() -> io::Result<PathBuf> {
     unsafe {
         use libc::funcs::bsd44::*;
         use libc::consts::os::extra::*;
@@ -176,28 +198,27 @@ pub fn current_exe() -> IoResult<Path> {
         let err = sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint,
                          ptr::null_mut(), &mut sz, ptr::null_mut(),
                          0 as libc::size_t);
-        if err != 0 { return Err(IoError::last_error()); }
-        if sz == 0 { return Err(IoError::last_error()); }
-        let mut v: Vec<u8> = Vec::with_capacity(sz as uint);
+        if err != 0 { return Err(io::Error::last_os_error()); }
+        if sz == 0 { return Err(io::Error::last_os_error()); }
+        let mut v: Vec<u8> = Vec::with_capacity(sz as usize);
         let err = sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint,
                          v.as_mut_ptr() as *mut libc::c_void, &mut sz,
                          ptr::null_mut(), 0 as libc::size_t);
-        if err != 0 { return Err(IoError::last_error()); }
-        if sz == 0 { return Err(IoError::last_error()); }
-        v.set_len(sz as uint - 1); // chop off trailing NUL
-        Ok(Path::new(v))
+        if err != 0 { return Err(io::Error::last_os_error()); }
+        if sz == 0 { return Err(io::Error::last_os_error()); }
+        v.set_len(sz as usize - 1); // chop off trailing NUL
+        Ok(PathBuf::from(OsString::from_vec(v)))
     }
 }
 
 #[cfg(target_os = "dragonfly")]
-pub fn current_exe() -> IoResult<Path> {
-    fs::readlink(&Path::new("/proc/curproc/file"))
+pub fn current_exe() -> io::Result<PathBuf> {
+    ::fs::read_link("/proc/curproc/file")
 }
 
-#[cfg(target_os = "openbsd")]
-pub fn current_exe() -> IoResult<Path> {
+#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
+pub fn current_exe() -> io::Result<PathBuf> {
     use sync::{StaticMutex, MUTEX_INIT};
-
     static LOCK: StaticMutex = MUTEX_INIT;
 
     extern {
@@ -209,30 +230,31 @@ pub fn current_exe() -> IoResult<Path> {
     unsafe {
         let v = rust_current_exe();
         if v.is_null() {
-            Err(IoError::last_error())
+            Err(io::Error::last_os_error())
         } else {
-            Ok(Path::new(CStr::from_ptr(&v).to_bytes().to_vec()))
+            let vec = CStr::from_ptr(v).to_bytes().to_vec();
+            Ok(PathBuf::from(OsString::from_vec(vec)))
         }
     }
 }
 
 #[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn current_exe() -> IoResult<Path> {
-    fs::readlink(&Path::new("/proc/self/exe"))
+pub fn current_exe() -> io::Result<PathBuf> {
+    ::fs::read_link("/proc/self/exe")
 }
 
 #[cfg(any(target_os = "macos", target_os = "ios"))]
-pub fn current_exe() -> IoResult<Path> {
+pub fn current_exe() -> io::Result<PathBuf> {
     unsafe {
         use libc::funcs::extra::_NSGetExecutablePath;
         let mut sz: u32 = 0;
         _NSGetExecutablePath(ptr::null_mut(), &mut sz);
-        if sz == 0 { return Err(IoError::last_error()); }
-        let mut v: Vec<u8> = Vec::with_capacity(sz as uint);
+        if sz == 0 { return Err(io::Error::last_os_error()); }
+        let mut v: Vec<u8> = Vec::with_capacity(sz as usize);
         let err = _NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz);
-        if err != 0 { return Err(IoError::last_error()); }
-        v.set_len(sz as uint - 1); // chop off trailing NUL
-        Ok(Path::new(v))
+        if err != 0 { return Err(io::Error::last_os_error()); }
+        v.set_len(sz as usize - 1); // chop off trailing NUL
+        Ok(PathBuf::from(OsString::from_vec(v)))
     }
 }
 
@@ -265,7 +287,7 @@ pub fn args() -> Args {
     let vec = unsafe {
         let (argc, argv) = (*_NSGetArgc() as isize,
                             *_NSGetArgv() as *const *const c_char);
-        range(0, argc as isize).map(|i| {
+        (0.. argc as isize).map(|i| {
             let bytes = CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec();
             OsStringExt::from_vec(bytes)
         }).collect::<Vec<_>>()
@@ -285,12 +307,11 @@ pub fn args() -> Args {
 // In general it looks like:
 // res = Vec::new()
 // let args = [[NSProcessInfo processInfo] arguments]
-// for i in range(0, [args count])
+// for i in (0..[args count])
 //      res.push([args objectAtIndex:i])
 // res
 #[cfg(target_os = "ios")]
 pub fn args() -> Args {
-    use iter::range;
     use mem;
 
     #[link(name = "objc")]
@@ -319,13 +340,13 @@ pub fn args() -> Args {
         let info = objc_msgSend(klass, process_info_sel);
         let args = objc_msgSend(info, arguments_sel);
 
-        let cnt: int = mem::transmute(objc_msgSend(args, count_sel));
-        for i in range(0, cnt) {
+        let cnt: usize = mem::transmute(objc_msgSend(args, count_sel));
+        for i in (0..cnt) {
             let tmp = objc_msgSend(args, object_at_sel, i);
             let utf_c_str: *const libc::c_char =
                 mem::transmute(objc_msgSend(tmp, utf8_sel));
             let bytes = CStr::from_ptr(utf_c_str).to_bytes();
-            res.push(OsString::from_str(str::from_utf8(bytes).unwrap()))
+            res.push(OsString::from(str::from_utf8(bytes).unwrap()))
         }
     }
 
@@ -336,6 +357,7 @@ pub fn args() -> Args {
           target_os = "android",
           target_os = "freebsd",
           target_os = "dragonfly",
+          target_os = "bitrig",
           target_os = "openbsd"))]
 pub fn args() -> Args {
     use rt;
@@ -376,7 +398,7 @@ pub fn env() -> Env {
         let mut environ = *environ();
         if environ as usize == 0 {
             panic!("os::env() failure getting env string from OS: {}",
-                   IoError::last_error());
+                   io::Error::last_os_error());
         }
         let mut result = Vec::new();
         while *environ != ptr::null() {
@@ -387,7 +409,7 @@ pub fn env() -> Env {
     };
 
     fn parse(input: &[u8]) -> (OsString, OsString) {
-        let mut it = input.splitn(1, |b| *b == b'=');
+        let mut it = input.splitn(2, |b| *b == b'=');
         let key = it.next().unwrap().to_vec();
         let default: &[u8] = &[];
         let val = it.next().unwrap_or(default).to_vec();
@@ -412,7 +434,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) {
         let k = k.to_cstring().unwrap();
         let v = v.to_cstring().unwrap();
         if libc::funcs::posix01::unistd::setenv(k.as_ptr(), v.as_ptr(), 1) != 0 {
-            panic!("failed setenv: {}", IoError::last_error());
+            panic!("failed setenv: {}", io::Error::last_os_error());
         }
     }
 }
@@ -421,11 +443,12 @@ pub fn unsetenv(n: &OsStr) {
     unsafe {
         let nbuf = n.to_cstring().unwrap();
         if libc::funcs::posix01::unistd::unsetenv(nbuf.as_ptr()) != 0 {
-            panic!("failed unsetenv: {}", IoError::last_error());
+            panic!("failed unsetenv: {}", io::Error::last_os_error());
         }
     }
 }
 
+#[allow(deprecated)]
 pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> {
     let mut fds = [0; 2];
     if libc::pipe(fds.as_mut_ptr()) == 0 {
@@ -441,22 +464,20 @@ pub fn page_size() -> usize {
     }
 }
 
-pub fn temp_dir() -> Path {
-    getenv("TMPDIR".as_os_str()).map(|p| Path::new(p.into_vec())).unwrap_or_else(|| {
+pub fn temp_dir() -> PathBuf {
+    getenv("TMPDIR".as_ref()).map(os2path).unwrap_or_else(|| {
         if cfg!(target_os = "android") {
-            Path::new("/data/local/tmp")
+            PathBuf::from("/data/local/tmp")
         } else {
-            Path::new("/tmp")
+            PathBuf::from("/tmp")
         }
     })
 }
 
-pub fn home_dir() -> Option<Path> {
-    return getenv("HOME".as_os_str()).or_else(|| unsafe {
+pub fn home_dir() -> Option<PathBuf> {
+    return getenv("HOME".as_ref()).or_else(|| unsafe {
         fallback()
-    }).map(|os| {
-        Path::new(os.into_vec())
-    });
+    }).map(os2path);
 
     #[cfg(any(target_os = "android",
               target_os = "ios"))]
@@ -464,7 +485,7 @@ pub fn home_dir() -> Option<Path> {
     #[cfg(not(any(target_os = "android",
                   target_os = "ios")))]
     unsafe fn fallback() -> Option<OsString> {
-        let mut amt = match libc::sysconf(c::_SC_GETPW_R_SIZE_MAX) {
+        let amt = match libc::sysconf(c::_SC_GETPW_R_SIZE_MAX) {
             n if n < 0 => 512 as usize,
             n => n as usize,
         };
@@ -485,3 +506,7 @@ pub fn home_dir() -> Option<Path> {
         }
     }
 }
+
+pub fn exit(code: i32) -> ! {
+    unsafe { libc::exit(code as c_int) }
+}
index 023d951dc4f8a8aad9152e24f5fc2d527b859425..69d876a48a4b22b3421aa8e293c074dc1497c7af 100644 (file)
 
 use core::prelude::*;
 
+use borrow::Cow;
 use fmt::{self, Debug};
 use vec::Vec;
-use slice::SliceExt as StdSliceExt;
 use str;
-use string::{String, CowString};
+use string::String;
 use mem;
 
 #[derive(Clone, Hash)]
@@ -46,10 +46,6 @@ impl Buf {
         Buf { inner: s.into_bytes() }
     }
 
-    pub fn from_str(s: &str) -> Buf {
-        Buf { inner: s.as_bytes().to_vec() }
-    }
-
     pub fn as_slice(&self) -> &Slice {
         unsafe { mem::transmute(&*self.inner) }
     }
@@ -69,14 +65,14 @@ impl Slice {
     }
 
     pub fn from_str(s: &str) -> &Slice {
-        unsafe { mem::transmute(s.as_bytes()) }
+        Slice::from_u8_slice(s.as_bytes())
     }
 
     pub fn to_str(&self) -> Option<&str> {
         str::from_utf8(&self.inner).ok()
     }
 
-    pub fn to_string_lossy(&self) -> CowString {
+    pub fn to_string_lossy(&self) -> Cow<str> {
         String::from_utf8_lossy(&self.inner)
     }
 
index 3c9cdc65975f6f9f5e1b7027774b2a7dd0fa564f..f0071295bf237316afdc4bed80434ea40e267d7f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 
 use ffi::CString;
@@ -143,13 +145,13 @@ impl UnixStream {
     fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
         let ret = Guard {
             fd: self.fd(),
-            guard: unsafe { self.inner.lock.lock().unwrap() },
+            guard: self.inner.lock.lock().unwrap(),
         };
-        assert!(set_nonblocking(self.fd(), true).is_ok());
+        set_nonblocking(self.fd(), true);
         ret
     }
 
-    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         let fd = self.fd();
         let dolock = || self.lock_nonblocking();
         let doread = |nb| unsafe {
@@ -165,7 +167,7 @@ impl UnixStream {
     pub fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         let fd = self.fd();
         let dolock = || self.lock_nonblocking();
-        let dowrite = |nb: bool, buf: *const u8, len: uint| unsafe {
+        let dowrite = |nb: bool, buf: *const u8, len: usize| unsafe {
             let flags = if nb {c::MSG_DONTWAIT} else {0};
             libc::send(fd,
                        buf as *const _,
@@ -235,9 +237,9 @@ impl UnixListener {
 
             _ => {
                 let (reader, writer) = try!(unsafe { sys::os::pipe() });
-                try!(set_nonblocking(reader.fd(), true));
-                try!(set_nonblocking(writer.fd(), true));
-                try!(set_nonblocking(self.fd(), true));
+                set_nonblocking(reader.fd(), true);
+                set_nonblocking(writer.fd(), true);
+                set_nonblocking(self.fd(), true);
                 Ok(UnixAcceptor {
                     inner: Arc::new(AcceptorInner {
                         listener: self,
index b30ac889120c229343f6d48938c50658c24d891f..8095325f83d1faf553220784814a6e2f84b102a7 100644 (file)
@@ -8,19 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(deprecated)] // this module itself is essentially deprecated
+
 use prelude::v1::*;
 use self::Req::*;
 
 use collections::HashMap;
-#[cfg(stage0)]
-use collections::hash_map::Hasher;
 use ffi::CString;
 use hash::Hash;
 use old_io::process::{ProcessExit, ExitStatus, ExitSignal};
-use old_io::{self, IoResult, IoError, EndOfFile};
+use old_io::{IoResult, EndOfFile};
 use libc::{self, pid_t, c_void, c_int};
+use io;
 use mem;
-use os;
+use sys::os;
 use old_path::BytesContainer;
 use ptr;
 use sync::mpsc::{channel, Sender, Receiver};
@@ -33,12 +34,6 @@ pub use sys_common::ProcessConfig;
 
 helper_init! { static HELPER: Helper<Req> }
 
-/// Unix-specific extensions to the Command builder
-pub struct CommandExt {
-    uid: Option<u32>,
-    gid: Option<u32>,
-}
-
 /// The unique id of the process (this should never be negative).
 pub struct Process {
     pub pid: pid_t
@@ -55,21 +50,20 @@ impl Process {
         self.pid
     }
 
-    pub unsafe fn kill(&self, signal: int) -> IoResult<()> {
+    pub unsafe fn kill(&self, signal: isize) -> IoResult<()> {
         Process::killpid(self.pid, signal)
     }
 
-    pub unsafe fn killpid(pid: pid_t, signal: int) -> IoResult<()> {
+    pub unsafe fn killpid(pid: pid_t, signal: isize) -> IoResult<()> {
         let r = libc::funcs::posix88::signal::kill(pid, signal as c_int);
         mkerr_libc(r)
     }
 
-    #[cfg(stage0)]
     pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
                               out_fd: Option<P>, err_fd: Option<P>)
                               -> IoResult<Process>
         where C: ProcessConfig<K, V>, P: AsInner<FileDesc>,
-              K: BytesContainer + Eq + Hash<Hasher>, V: BytesContainer
+              K: BytesContainer + Eq + Hash, V: BytesContainer
     {
         use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp};
 
@@ -79,6 +73,11 @@ impl Process {
             }
         }
 
+        unsafe fn set_cloexec(fd: c_int) {
+            let ret = c::ioctl(fd, c::FIOCLEX);
+            assert_eq!(ret, 0);
+        }
+
         #[cfg(all(target_os = "android", target_arch = "aarch64"))]
         unsafe fn getdtablesize() -> c_int {
             libc::sysconf(libc::consts::os::sysconf::_SC_OPEN_MAX) as c_int
@@ -88,219 +87,6 @@ impl Process {
             libc::funcs::bsd44::getdtablesize()
         }
 
-        unsafe fn set_cloexec(fd: c_int) {
-            let ret = c::ioctl(fd, c::FIOCLEX);
-            assert_eq!(ret, 0);
-        }
-
-        let dirp = cfg.cwd().map(|c| c.as_ptr()).unwrap_or(ptr::null());
-
-        // temporary until unboxed closures land
-        let cfg = unsafe {
-            mem::transmute::<&ProcessConfig<K,V>,&'static ProcessConfig<K,V>>(cfg)
-        };
-
-        with_envp(cfg.env(), move|envp: *const c_void| {
-            with_argv(cfg.program(), cfg.args(), move|argv: *const *const libc::c_char| unsafe {
-                let (input, mut output) = try!(sys::os::pipe());
-
-                // We may use this in the child, so perform allocations before the
-                // fork
-                let devnull = b"/dev/null\0";
-
-                set_cloexec(output.fd());
-
-                let pid = fork();
-                if pid < 0 {
-                    return Err(super::last_error())
-                } else if pid > 0 {
-                    #[inline]
-                    fn combine(arr: &[u8]) -> i32 {
-                        let a = arr[0] as u32;
-                        let b = arr[1] as u32;
-                        let c = arr[2] as u32;
-                        let d = arr[3] as u32;
-
-                        ((a << 24) | (b << 16) | (c << 8) | (d << 0)) as i32
-                    }
-
-                    let p = Process{ pid: pid };
-                    drop(output);
-                    let mut bytes = [0; 8];
-                    return match input.read(&mut bytes) {
-                        Ok(8) => {
-                            assert!(combine(CLOEXEC_MSG_FOOTER) == combine(&bytes[4.. 8]),
-                                "Validation on the CLOEXEC pipe failed: {:?}", bytes);
-                            let errno = combine(&bytes[0.. 4]);
-                            assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic");
-                            Err(super::decode_error(errno))
-                        }
-                        Err(ref e) if e.kind == EndOfFile => Ok(p),
-                        Err(e) => {
-                            assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic");
-                            panic!("the CLOEXEC pipe failed: {:?}", e)
-                        },
-                        Ok(..) => { // pipe I/O up to PIPE_BUF bytes should be atomic
-                            assert!(p.wait(0).is_ok(), "wait(0) should either return Ok or panic");
-                            panic!("short read on the CLOEXEC pipe")
-                        }
-                    };
-                }
-
-                // And at this point we've reached a special time in the life of the
-                // child. The child must now be considered hamstrung and unable to
-                // do anything other than syscalls really. Consider the following
-                // scenario:
-                //
-                //      1. Thread A of process 1 grabs the malloc() mutex
-                //      2. Thread B of process 1 forks(), creating thread C
-                //      3. Thread C of process 2 then attempts to malloc()
-                //      4. The memory of process 2 is the same as the memory of
-                //         process 1, so the mutex is locked.
-                //
-                // This situation looks a lot like deadlock, right? It turns out
-                // that this is what pthread_atfork() takes care of, which is
-                // presumably implemented across platforms. The first thing that
-                // threads to *before* forking is to do things like grab the malloc
-                // mutex, and then after the fork they unlock it.
-                //
-                // Despite this information, libnative's spawn has been witnessed to
-                // deadlock on both OSX and FreeBSD. I'm not entirely sure why, but
-                // all collected backtraces point at malloc/free traffic in the
-                // child spawned process.
-                //
-                // For this reason, the block of code below should contain 0
-                // invocations of either malloc of free (or their related friends).
-                //
-                // As an example of not having malloc/free traffic, we don't close
-                // this file descriptor by dropping the FileDesc (which contains an
-                // allocation). Instead we just close it manually. This will never
-                // have the drop glue anyway because this code never returns (the
-                // child will either exec() or invoke libc::exit)
-                let _ = libc::close(input.fd());
-
-                fn fail(output: &mut FileDesc) -> ! {
-                    let errno = sys::os::errno() as u32;
-                    let bytes = [
-                        (errno >> 24) as u8,
-                        (errno >> 16) as u8,
-                        (errno >>  8) as u8,
-                        (errno >>  0) as u8,
-                        CLOEXEC_MSG_FOOTER[0], CLOEXEC_MSG_FOOTER[1],
-                        CLOEXEC_MSG_FOOTER[2], CLOEXEC_MSG_FOOTER[3]
-                    ];
-                    // pipe I/O up to PIPE_BUF bytes should be atomic
-                    assert!(output.write(&bytes).is_ok());
-                    unsafe { libc::_exit(1) }
-                }
-
-                rustrt::rust_unset_sigprocmask();
-
-                // If a stdio file descriptor is set to be ignored (via a -1 file
-                // descriptor), then we don't actually close it, but rather open
-                // up /dev/null into that file descriptor. Otherwise, the first file
-                // descriptor opened up in the child would be numbered as one of the
-                // stdio file descriptors, which is likely to wreak havoc.
-                let setup = |src: Option<P>, dst: c_int| {
-                    let src = match src {
-                        None => {
-                            let flags = if dst == libc::STDIN_FILENO {
-                                libc::O_RDONLY
-                            } else {
-                                libc::O_RDWR
-                            };
-                            libc::open(devnull.as_ptr() as *const _, flags, 0)
-                        }
-                        Some(obj) => {
-                            let fd = obj.as_inner().fd();
-                            // Leak the memory and the file descriptor. We're in the
-                            // child now an all our resources are going to be
-                            // cleaned up very soon
-                            mem::forget(obj);
-                            fd
-                        }
-                    };
-                    src != -1 && retry(|| dup2(src, dst)) != -1
-                };
-
-                if !setup(in_fd, libc::STDIN_FILENO) { fail(&mut output) }
-                if !setup(out_fd, libc::STDOUT_FILENO) { fail(&mut output) }
-                if !setup(err_fd, libc::STDERR_FILENO) { fail(&mut output) }
-
-                // close all other fds
-                for fd in (3..getdtablesize()).rev() {
-                    if fd != output.fd() {
-                        let _ = close(fd as c_int);
-                    }
-                }
-
-                match cfg.gid() {
-                    Some(u) => {
-                        if libc::setgid(u as libc::gid_t) != 0 {
-                            fail(&mut output);
-                        }
-                    }
-                    None => {}
-                }
-                match cfg.uid() {
-                    Some(u) => {
-                        // When dropping privileges from root, the `setgroups` call
-                        // will remove any extraneous groups. If we don't call this,
-                        // then even though our uid has dropped, we may still have
-                        // groups that enable us to do super-user things. This will
-                        // fail if we aren't root, so don't bother checking the
-                        // return value, this is just done as an optimistic
-                        // privilege dropping function.
-                        extern {
-                            fn setgroups(ngroups: libc::c_int,
-                                         ptr: *const libc::c_void) -> libc::c_int;
-                        }
-                        let _ = setgroups(0, ptr::null());
-
-                        if libc::setuid(u as libc::uid_t) != 0 {
-                            fail(&mut output);
-                        }
-                    }
-                    None => {}
-                }
-                if cfg.detach() {
-                    // Don't check the error of setsid because it fails if we're the
-                    // process leader already. We just forked so it shouldn't return
-                    // error, but ignore it anyway.
-                    let _ = libc::setsid();
-                }
-                if !dirp.is_null() && chdir(dirp) == -1 {
-                    fail(&mut output);
-                }
-                if !envp.is_null() {
-                    *sys::os::environ() = envp as *const _;
-                }
-                let _ = execvp(*argv, argv as *mut _);
-                fail(&mut output);
-            })
-        })
-    }
-    #[cfg(not(stage0))]
-    pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
-                              out_fd: Option<P>, err_fd: Option<P>)
-                              -> IoResult<Process>
-        where C: ProcessConfig<K, V>, P: AsInner<FileDesc>,
-              K: BytesContainer + Eq + Hash, V: BytesContainer
-    {
-        use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp};
-        use libc::funcs::bsd44::getdtablesize;
-
-        mod rustrt {
-            extern {
-                pub fn rust_unset_sigprocmask();
-            }
-        }
-
-        unsafe fn set_cloexec(fd: c_int) {
-            let ret = c::ioctl(fd, c::FIOCLEX);
-            assert_eq!(ret, 0);
-        }
-
         let dirp = cfg.cwd().map(|c| c.as_ptr()).unwrap_or(ptr::null());
 
         // temporary until unboxed closures land
@@ -541,7 +327,7 @@ impl Process {
         // The actual communication between the helper thread and this thread is
         // quite simple, just a channel moving data around.
 
-        unsafe { HELPER.boot(register_sigchld, waitpid_helper) }
+        HELPER.boot(register_sigchld, waitpid_helper);
 
         match self.try_wait() {
             Some(ret) => return Ok(ret),
@@ -549,7 +335,7 @@ impl Process {
         }
 
         let (tx, rx) = channel();
-        unsafe { HELPER.send(NewChild(self.pid, tx, deadline)); }
+        HELPER.send(NewChild(self.pid, tx, deadline));
         return match rx.recv() {
             Ok(e) => Ok(e),
             Err(..) => Err(timeout("wait timed out")),
@@ -564,8 +350,8 @@ impl Process {
             unsafe {
                 let mut pipes = [0; 2];
                 assert_eq!(libc::pipe(pipes.as_mut_ptr()), 0);
-                set_nonblocking(pipes[0], true).ok().unwrap();
-                set_nonblocking(pipes[1], true).ok().unwrap();
+                set_nonblocking(pipes[0], true);
+                set_nonblocking(pipes[1], true);
                 WRITE_FD = pipes[1];
 
                 let mut old: c::sigaction = mem::zeroed();
@@ -581,7 +367,7 @@ impl Process {
         fn waitpid_helper(input: libc::c_int,
                           messages: Receiver<Req>,
                           (read_fd, old): (libc::c_int, c::sigaction)) {
-            set_nonblocking(input, true).ok().unwrap();
+            set_nonblocking(input, true);
             let mut set: c::fd_set = unsafe { mem::zeroed() };
             let mut tv: libc::timeval;
             let mut active = Vec::<(libc::pid_t, Sender<ProcessExit>, u64)>::new();
@@ -633,8 +419,15 @@ impl Process {
                             Ok(NewChild(pid, tx, deadline)) => {
                                 active.push((pid, tx, deadline));
                             }
+                            // Once we've been disconnected it means the main
+                            // thread is exiting (at_exit has run). We could
+                            // still have active waiter for other threads, so
+                            // we're just going to drop them all on the floor.
+                            // This means that they won't receive a "you're
+                            // done" message in which case they'll be considered
+                            // as timed out, but more generally errors will
+                            // start propagating.
                             Err(TryRecvError::Disconnected) => {
-                                assert!(active.len() == 0);
                                 break 'outer;
                             }
                             Err(TryRecvError::Empty) => break,
@@ -662,7 +455,7 @@ impl Process {
                 // with process timeouts, but libgreen should get there first
                 // (currently libuv doesn't handle old signal handlers).
                 if drain(read_fd) {
-                    let i: uint = unsafe { mem::transmute(old.sa_handler) };
+                    let i: usize = unsafe { mem::transmute(old.sa_handler) };
                     if i != 0 {
                         assert!(old.sa_flags & c::SA_SIGINFO == 0);
                         (old.sa_handler)(c::SIGCHLD);
@@ -704,7 +497,8 @@ impl Process {
                     n if n > 0 => { ret = true; }
                     0 => return true,
                     -1 if wouldblock() => return ret,
-                    n => panic!("bad read {:?} ({:?})", os::last_os_error(), n),
+                    n => panic!("bad read {} ({})",
+                                io::Error::last_os_error(), n),
                 }
             }
         }
@@ -766,45 +560,6 @@ fn with_argv<T,F>(prog: &CString, args: &[CString],
     cb(ptrs.as_ptr())
 }
 
-#[cfg(stage0)]
-fn with_envp<K,V,T,F>(env: Option<&HashMap<K, V>>,
-                      cb: F)
-                      -> T
-    where F : FnOnce(*const c_void) -> T,
-          K : BytesContainer + Eq + Hash<Hasher>,
-          V : BytesContainer
-{
-    // On posixy systems we can pass a char** for envp, which is a
-    // null-terminated array of "k=v\0" strings. Since we must create
-    // these strings locally, yet expose a raw pointer to them, we
-    // create a temporary vector to own the CStrings that outlives the
-    // call to cb.
-    match env {
-        Some(env) => {
-            let mut tmps = Vec::with_capacity(env.len());
-
-            for pair in env {
-                let mut kv = Vec::new();
-                kv.push_all(pair.0.container_as_bytes());
-                kv.push('=' as u8);
-                kv.push_all(pair.1.container_as_bytes());
-                kv.push(0); // terminating null
-                tmps.push(kv);
-            }
-
-            // As with `with_argv`, this is unsafe, since cb could leak the pointers.
-            let mut ptrs: Vec<*const libc::c_char> =
-                tmps.iter()
-                    .map(|tmp| tmp.as_ptr() as *const libc::c_char)
-                    .collect();
-            ptrs.push(ptr::null());
-
-            cb(ptrs.as_ptr() as *const c_void)
-        }
-        _ => cb(ptr::null())
-    }
-}
-#[cfg(not(stage0))]
 fn with_envp<K,V,T,F>(env: Option<&HashMap<K, V>>,
                       cb: F)
                       -> T
@@ -856,6 +611,7 @@ fn translate_status(status: c_int) -> ProcessExit {
               target_os = "ios",
               target_os = "freebsd",
               target_os = "dragonfly",
+              target_os = "bitrig",
               target_os = "openbsd"))]
     mod imp {
         pub fn WIFEXITED(status: i32) -> bool { (status & 0x7f) == 0 }
@@ -864,8 +620,8 @@ fn translate_status(status: c_int) -> ProcessExit {
     }
 
     if imp::WIFEXITED(status) {
-        ExitStatus(imp::WEXITSTATUS(status) as int)
+        ExitStatus(imp::WEXITSTATUS(status) as isize)
     } else {
-        ExitSignal(imp::WTERMSIG(status) as int)
+        ExitSignal(imp::WTERMSIG(status) as isize)
     }
 }
index 06fa5c4bba7253d66f4a3b45c00a6e3097168b8f..c2a8b26aef4ebb63306fa9f6b947f9c3df15e99e 100644 (file)
@@ -9,23 +9,18 @@
 // except according to those terms.
 
 use prelude::v1::*;
+use os::unix::prelude::*;
 
 use collections::HashMap;
 use env;
 use ffi::{OsString, OsStr, CString};
 use fmt;
-use hash::Hash;
 use io::{self, Error, ErrorKind};
 use libc::{self, pid_t, c_void, c_int, gid_t, uid_t};
 use mem;
-use old_io;
-use os;
-use os::unix::OsStrExt;
 use ptr;
-use sync::mpsc::{channel, Sender, Receiver};
 use sys::pipe2::AnonPipe;
-use sys::{self, retry, c, wouldblock, set_nonblocking, ms_to_timeval, cvt};
-use sys_common::AsInner;
+use sys::{self, retry, c, cvt};
 
 ////////////////////////////////////////////////////////////////////////////////
 // Command
@@ -59,7 +54,7 @@ impl Command {
         self.args.push(arg.to_cstring().unwrap())
     }
     pub fn args<'a, I: Iterator<Item = &'a OsStr>>(&mut self, args: I) {
-        self.args.extend(args.map(|s| OsStrExt::to_cstring(s).unwrap()))
+        self.args.extend(args.map(|s| s.to_cstring().unwrap()))
     }
     fn init_env_map(&mut self) {
         if self.env.is_none() {
@@ -127,10 +122,6 @@ pub struct Process {
 const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX";
 
 impl Process {
-    pub fn id(&self) -> pid_t {
-        self.pid
-    }
-
     pub unsafe fn kill(&self) -> io::Result<()> {
         try!(cvt(libc::funcs::posix88::signal::kill(self.pid, libc::SIGKILL)));
         Ok(())
@@ -141,7 +132,6 @@ impl Process {
                  -> io::Result<Process>
     {
         use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp};
-        use libc::funcs::bsd44::getdtablesize;
 
         mod rustrt {
             extern {
@@ -154,6 +144,16 @@ impl Process {
             assert_eq!(ret, 0);
         }
 
+        #[cfg(all(target_os = "android", target_arch = "aarch64"))]
+        unsafe fn getdtablesize() -> c_int {
+            libc::sysconf(libc::consts::os::sysconf::_SC_OPEN_MAX) as c_int
+        }
+
+        #[cfg(not(all(target_os = "android", target_arch = "aarch64")))]
+        unsafe fn getdtablesize() -> c_int {
+            libc::funcs::bsd44::getdtablesize()
+        }
+
         let dirp = cfg.cwd.as_ref().map(|c| c.as_ptr()).unwrap_or(ptr::null());
 
         with_envp(cfg.env.as_ref(), |envp: *const c_void| {
@@ -265,7 +265,7 @@ impl Process {
                 // file descriptor. Otherwise, the first file descriptor opened
                 // up in the child would be numbered as one of the stdio file
                 // descriptors, which is likely to wreak havoc.
-                let setup = |&: src: Option<AnonPipe>, dst: c_int| {
+                let setup = |src: Option<AnonPipe>, dst: c_int| {
                     let src = match src {
                         None => {
                             let flags = if dst == libc::STDIN_FILENO {
@@ -430,6 +430,7 @@ fn translate_status(status: c_int) -> ExitStatus {
               target_os = "ios",
               target_os = "freebsd",
               target_os = "dragonfly",
+              target_os = "bitrig",
               target_os = "openbsd"))]
     mod imp {
         pub fn WIFEXITED(status: i32) -> bool { (status & 0x7f) == 0 }
index 54523e0076dc3c47ce41897cb416b4b2f795b385..adf9da2d067cd202686cecaded415165c3ce3ff7 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use prelude::v1::*;
+
 use cell::UnsafeCell;
 use sys::sync as ffi;
 
@@ -17,13 +19,10 @@ pub const RWLOCK_INIT: RWLock = RWLock {
     inner: UnsafeCell { value: ffi::PTHREAD_RWLOCK_INITIALIZER },
 };
 
+unsafe impl Send for RWLock {}
+unsafe impl Sync for RWLock {}
+
 impl RWLock {
-    #[inline]
-    pub unsafe fn new() -> RWLock {
-        // Might be moved and address is changing it is better to avoid
-        // initialization of potentially opaque OS data before it landed
-        RWLOCK_INIT
-    }
     #[inline]
     pub unsafe fn read(&self) {
         let r = ffi::pthread_rwlock_rdlock(self.inner.get());
index 3512fa36eb3b7fc07e61b56a0103fc1c02ca4ba4..6887095c53a7d1cdc24a5a7cf7d1acfe5b9a8baf 100644 (file)
@@ -34,9 +34,9 @@ impl Drop for Handler {
 
 #[cfg(any(target_os = "linux",
           target_os = "macos",
+          target_os = "bitrig",
           target_os = "openbsd"))]
 mod imp {
-    use core::prelude::*;
     use sys_common::stack;
 
     use super::Handler;
@@ -60,7 +60,7 @@ mod imp {
 
 
     // This is initialized in init() and only read from after
-    static mut PAGE_SIZE: uint = 0;
+    static mut PAGE_SIZE: usize = 0;
 
     #[no_stack_check]
     unsafe extern fn signal_handler(signum: libc::c_int,
@@ -82,7 +82,7 @@ mod imp {
         stack::record_sp_limit(0);
 
         let guard = thread_info::stack_guard();
-        let addr = (*info).si_addr as uint;
+        let addr = (*info).si_addr as usize;
 
         if guard == 0 || addr < guard - PAGE_SIZE || addr >= guard {
             term(signum);
@@ -101,7 +101,7 @@ mod imp {
             panic!("failed to get page size");
         }
 
-        PAGE_SIZE = psize as uint;
+        PAGE_SIZE = psize as usize;
 
         let mut action: sigaction = mem::zeroed();
         action.sa_flags = SA_SIGINFO | SA_ONSTACK;
@@ -144,7 +144,7 @@ mod imp {
         munmap(handler._data, SIGSTKSZ);
     }
 
-    type sighandler_t = *mut libc::c_void;
+    pub type sighandler_t = *mut libc::c_void;
 
     #[cfg(any(all(target_os = "linux", target_arch = "x86"), // may not match
               all(target_os = "linux", target_arch = "x86_64"),
@@ -156,7 +156,7 @@ mod imp {
               target_os = "android"))] // may not match
     mod signal {
         use libc;
-        use super::sighandler_t;
+        pub use super::sighandler_t;
 
         pub static SA_ONSTACK: libc::c_int = 0x08000000;
         pub static SA_SIGINFO: libc::c_int = 0x00000004;
@@ -205,10 +205,12 @@ mod imp {
 
     }
 
-    #[cfg(any(target_os = "macos", target_os = "openbsd"))]
+    #[cfg(any(target_os = "macos",
+              target_os = "bitrig",
+              target_os = "openbsd"))]
     mod signal {
         use libc;
-        use super::sighandler_t;
+        pub use super::sighandler_t;
 
         pub const SA_ONSTACK: libc::c_int = 0x0001;
         pub const SA_SIGINFO: libc::c_int = 0x0040;
@@ -216,7 +218,7 @@ mod imp {
 
         #[cfg(target_os = "macos")]
         pub const SIGSTKSZ: libc::size_t = 131072;
-        #[cfg(target_os = "openbsd")]
+        #[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
         pub const SIGSTKSZ: libc::size_t = 40960;
 
         pub const SIG_DFL: sighandler_t = 0 as sighandler_t;
@@ -237,14 +239,14 @@ mod imp {
             pub si_addr: *mut libc::c_void
         }
 
-        #[cfg(target_os = "openbsd")]
+        #[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
         #[repr(C)]
         pub struct siginfo {
             pub si_signo: libc::c_int,
             pub si_code: libc::c_int,
             pub si_errno: libc::c_int,
-            // union
-            pub si_addr: *mut libc::c_void,
+            //union
+            pub si_addr: *mut libc::c_void
         }
 
         #[repr(C)]
@@ -277,6 +279,7 @@ mod imp {
 
 #[cfg(not(any(target_os = "linux",
               target_os = "macos",
+              target_os = "bitrig",
               target_os = "openbsd")))]
 mod imp {
     use libc;
diff --git a/src/libstd/sys/unix/stdio.rs b/src/libstd/sys/unix/stdio.rs
new file mode 100644 (file)
index 0000000..5f5101e
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright 2015 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 prelude::v1::*;
+
+use io;
+use libc;
+use sys::fd::FileDesc;
+
+pub struct Stdin(());
+pub struct Stdout(());
+pub struct Stderr(());
+
+impl Stdin {
+    pub fn new() -> Stdin { Stdin(()) }
+
+    pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
+        let fd = FileDesc::new(libc::STDIN_FILENO);
+        let ret = fd.read(data);
+        fd.into_raw();
+        return ret;
+    }
+}
+
+impl Stdout {
+    pub fn new() -> Stdout { Stdout(()) }
+
+    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+        let fd = FileDesc::new(libc::STDOUT_FILENO);
+        let ret = fd.write(data);
+        fd.into_raw();
+        return ret;
+    }
+}
+
+impl Stderr {
+    pub fn new() -> Stderr { Stderr(()) }
+
+    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+        let fd = FileDesc::new(libc::STDERR_FILENO);
+        let ret = fd.write(data);
+        fd.into_raw();
+        return ret;
+    }
+}
+
+// FIXME: right now this raw stderr handle is used in a few places because
+//        std::io::stderr_raw isn't exposed, but once that's exposed this impl
+//        should go away
+impl io::Write for Stderr {
+    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+        Stderr::write(self, data)
+    }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
index bc93513af63d4609f2593ba42ef213608c23dbe6..3c05fd602be8530d5d23251d12930d58bff4e900 100644 (file)
@@ -46,6 +46,7 @@ extern {
 
 #[cfg(any(target_os = "freebsd",
           target_os = "dragonfly",
+          target_os = "bitrig",
           target_os = "openbsd"))]
 mod os {
     use libc;
@@ -65,24 +66,24 @@ mod os {
 
     #[cfg(any(target_arch = "x86_64",
               target_arch = "aarch64"))]
-    const __PTHREAD_MUTEX_SIZE__: uint = 56;
+    const __PTHREAD_MUTEX_SIZE__: usize = 56;
     #[cfg(any(target_arch = "x86",
               target_arch = "arm"))]
-    const __PTHREAD_MUTEX_SIZE__: uint = 40;
+    const __PTHREAD_MUTEX_SIZE__: usize = 40;
 
     #[cfg(any(target_arch = "x86_64",
               target_arch = "aarch64"))]
-    const __PTHREAD_COND_SIZE__: uint = 40;
+    const __PTHREAD_COND_SIZE__: usize = 40;
     #[cfg(any(target_arch = "x86",
               target_arch = "arm"))]
-    const __PTHREAD_COND_SIZE__: uint = 24;
+    const __PTHREAD_COND_SIZE__: usize = 24;
 
     #[cfg(any(target_arch = "x86_64",
               target_arch = "aarch64"))]
-    const __PTHREAD_RWLOCK_SIZE__: uint = 192;
+    const __PTHREAD_RWLOCK_SIZE__: usize = 192;
     #[cfg(any(target_arch = "x86",
               target_arch = "arm"))]
-    const __PTHREAD_RWLOCK_SIZE__: uint = 124;
+    const __PTHREAD_RWLOCK_SIZE__: usize = 124;
 
     const _PTHREAD_MUTEX_SIG_INIT: libc::c_long = 0x32AAABA7;
     const _PTHREAD_COND_SIG_INIT: libc::c_long = 0x3CB0B1BB;
@@ -124,15 +125,15 @@ mod os {
 
     // minus 8 because we have an 'align' field
     #[cfg(target_arch = "x86_64")]
-    const __SIZEOF_PTHREAD_MUTEX_T: uint = 40 - 8;
+    const __SIZEOF_PTHREAD_MUTEX_T: usize = 40 - 8;
     #[cfg(any(target_arch = "x86",
               target_arch = "arm",
               target_arch = "mips",
               target_arch = "mipsel",
               target_arch = "powerpc"))]
-    const __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
+    const __SIZEOF_PTHREAD_MUTEX_T: usize = 24 - 8;
     #[cfg(target_arch = "aarch64")]
-    const __SIZEOF_PTHREAD_MUTEX_T: uint = 48 - 8;
+    const __SIZEOF_PTHREAD_MUTEX_T: usize = 48 - 8;
 
     #[cfg(any(target_arch = "x86_64",
               target_arch = "x86",
@@ -141,18 +142,18 @@ mod os {
               target_arch = "mips",
               target_arch = "mipsel",
               target_arch = "powerpc"))]
-    const __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
+    const __SIZEOF_PTHREAD_COND_T: usize = 48 - 8;
 
     #[cfg(any(target_arch = "x86_64",
               target_arch = "aarch64"))]
-    const __SIZEOF_PTHREAD_RWLOCK_T: uint = 56 - 8;
+    const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56 - 8;
 
     #[cfg(any(target_arch = "x86",
               target_arch = "arm",
               target_arch = "mips",
               target_arch = "mipsel",
               target_arch = "powerpc"))]
-    const __SIZEOF_PTHREAD_RWLOCK_T: uint = 32 - 8;
+    const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32 - 8;
 
     #[repr(C)]
     pub struct pthread_mutex_t {
index c8f9d318482b09c39a3a2a9f993c2f1d27e11e83..a9f2198208bc31cbd825ce36302f2c9c4fa0619f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 
 use old_io::net::ip;
@@ -62,14 +64,14 @@ impl TcpListener {
 
     pub fn fd(&self) -> sock_t { self.inner.fd() }
 
-    pub fn listen(self, backlog: int) -> IoResult<TcpAcceptor> {
+    pub fn listen(self, backlog: isize) -> IoResult<TcpAcceptor> {
         match unsafe { libc::listen(self.fd(), backlog as libc::c_int) } {
             -1 => Err(last_net_error()),
             _ => {
                 let (reader, writer) = try!(unsafe { sys::os::pipe() });
-                try!(set_nonblocking(reader.fd(), true));
-                try!(set_nonblocking(writer.fd(), true));
-                try!(set_nonblocking(self.fd(), true));
+                set_nonblocking(reader.fd(), true);
+                set_nonblocking(writer.fd(), true);
+                set_nonblocking(self.fd(), true);
                 Ok(TcpAcceptor {
                     inner: Arc::new(AcceptorInner {
                         listener: self,
@@ -137,10 +139,6 @@ impl TcpAcceptor {
         Err(sys_common::eof())
     }
 
-    pub fn socket_name(&mut self) -> IoResult<ip::SocketAddr> {
-        net::sockname(self.fd(), libc::getsockname)
-    }
-
     pub fn set_timeout(&mut self, timeout: Option<u64>) {
         self.deadline = timeout.map(|a| sys::timer::now() + a).unwrap_or(0);
     }
index c90ba7645feb4b29f14a6b6854804c6d79d617e9..eb61f21aacd5d52ee5a7c66106948e90ac835287 100644 (file)
@@ -8,71 +8,61 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(dead_code)]
+
 use core::prelude::*;
 
-use io;
-use boxed::Box;
 use cmp;
+use ffi::CString;
+use io;
+use libc::consts::os::posix01::PTHREAD_STACK_MIN;
+use libc;
 use mem;
 use ptr;
-use libc::consts::os::posix01::{PTHREAD_CREATE_JOINABLE, PTHREAD_STACK_MIN};
-use libc;
+use sys::os;
 use thunk::Thunk;
-use ffi::CString;
+use time::Duration;
 
 use sys_common::stack::RED_ZONE;
 use sys_common::thread::*;
 
 pub type rust_thread = libc::pthread_t;
-pub type rust_thread_return = *mut u8;
-pub type StartFn = extern "C" fn(*mut libc::c_void) -> rust_thread_return;
-
-#[no_stack_check]
-pub extern fn thread_start(main: *mut libc::c_void) -> rust_thread_return {
-    return start_thread(main);
-}
 
 #[cfg(all(not(target_os = "linux"),
           not(target_os = "macos"),
+          not(target_os = "bitrig"),
           not(target_os = "openbsd")))]
 pub mod guard {
-    pub unsafe fn current() -> uint {
-        0
-    }
-
-    pub unsafe fn main() -> uint {
-        0
-    }
-
-    pub unsafe fn init() {
-    }
+    pub unsafe fn current() -> usize { 0 }
+    pub unsafe fn main() -> usize { 0 }
+    pub unsafe fn init() {}
 }
 
 
 #[cfg(any(target_os = "linux",
           target_os = "macos",
+          target_os = "bitrig",
           target_os = "openbsd"))]
+#[allow(unused_imports)]
 pub mod guard {
-    use super::*;
-    #[cfg(any(target_os = "linux",
-              target_os = "android",
-              target_os = "openbsd"))]
-    use mem;
-    #[cfg(any(target_os = "linux", target_os = "android"))]
-    use ptr;
-    use libc;
-    use libc::funcs::posix88::mman::{mmap};
+    use libc::{self, pthread_t};
+    use libc::funcs::posix88::mman::mmap;
     use libc::consts::os::posix88::{PROT_NONE,
                                     MAP_PRIVATE,
                                     MAP_ANON,
                                     MAP_FAILED,
                                     MAP_FIXED};
+    use mem;
+    use ptr;
+    use super::{pthread_self, pthread_attr_destroy};
+    use sys::os;
 
     // These are initialized in init() and only read from after
-    static mut PAGE_SIZE: uint = 0;
-    static mut GUARD_PAGE: uint = 0;
+    static mut GUARD_PAGE: usize = 0;
 
-    #[cfg(any(target_os = "macos", target_os = "openbsd"))]
+    #[cfg(any(target_os = "macos",
+              target_os = "bitrig",
+              target_os = "openbsd"))]
     unsafe fn get_stack_start() -> *mut libc::c_void {
         current() as *mut libc::c_void
     }
@@ -80,28 +70,16 @@ pub mod guard {
     #[cfg(any(target_os = "linux", target_os = "android"))]
     unsafe fn get_stack_start() -> *mut libc::c_void {
         let mut attr: libc::pthread_attr_t = mem::zeroed();
-        if pthread_getattr_np(pthread_self(), &mut attr) != 0 {
-            panic!("failed to get thread attributes");
-        }
+        assert_eq!(pthread_getattr_np(pthread_self(), &mut attr), 0);
         let mut stackaddr = ptr::null_mut();
         let mut stacksize = 0;
-        if pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize) != 0 {
-            panic!("failed to get stack information");
-        }
-        if pthread_attr_destroy(&mut attr) != 0 {
-            panic!("failed to destroy thread attributes");
-        }
+        assert_eq!(pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize), 0);
+        assert_eq!(pthread_attr_destroy(&mut attr), 0);
         stackaddr
     }
 
     pub unsafe fn init() {
-        let psize = libc::sysconf(libc::consts::os::sysconf::_SC_PAGESIZE);
-        if psize == -1 {
-            panic!("failed to get page size");
-        }
-
-        PAGE_SIZE = psize as uint;
-
+        let psize = os::page_size();
         let mut stackaddr = get_stack_start();
 
         // Ensure stackaddr is page aligned! A parent process might
@@ -110,9 +88,9 @@ pub mod guard {
         // stackaddr < stackaddr + stacksize, so if stackaddr is not
         // page-aligned, calculate the fix such that stackaddr <
         // new_page_aligned_stackaddr < stackaddr + stacksize
-        let remainder = (stackaddr as usize) % (PAGE_SIZE as usize);
+        let remainder = (stackaddr as usize) % psize;
         if remainder != 0 {
-            stackaddr = ((stackaddr as usize) + (PAGE_SIZE as usize) - remainder)
+            stackaddr = ((stackaddr as usize) + psize - remainder)
                 as *mut libc::c_void;
         }
 
@@ -120,7 +98,7 @@ pub mod guard {
         // This ensures SIGBUS will be raised on
         // stack overflow.
         let result = mmap(stackaddr,
-                          PAGE_SIZE as libc::size_t,
+                          psize as libc::size_t,
                           PROT_NONE,
                           MAP_PRIVATE | MAP_ANON | MAP_FIXED,
                           -1,
@@ -130,138 +108,154 @@ pub mod guard {
             panic!("failed to allocate a guard page");
         }
 
-        let offset = if cfg!(target_os = "linux") {
-            2
-        } else {
-            1
-        };
+        let offset = if cfg!(target_os = "linux") {2} else {1};
 
-        GUARD_PAGE = stackaddr as uint + offset * PAGE_SIZE;
+        GUARD_PAGE = stackaddr as usize + offset * psize;
     }
 
-    pub unsafe fn main() -> uint {
+    pub unsafe fn main() -> usize {
         GUARD_PAGE
     }
 
     #[cfg(target_os = "macos")]
-    pub unsafe fn current() -> uint {
+    pub unsafe fn current() -> usize {
+        extern {
+            fn pthread_get_stackaddr_np(thread: pthread_t) -> *mut libc::c_void;
+            fn pthread_get_stacksize_np(thread: pthread_t) -> libc::size_t;
+        }
         (pthread_get_stackaddr_np(pthread_self()) as libc::size_t -
-         pthread_get_stacksize_np(pthread_self())) as uint
+         pthread_get_stacksize_np(pthread_self())) as usize
     }
 
-    #[cfg(target_os = "openbsd")]
-    pub unsafe fn current() -> uint {
-        let mut current_stack: stack_t = mem::zeroed();
-        if pthread_stackseg_np(pthread_self(), &mut current_stack) != 0 {
-            panic!("failed to get current stack: pthread_stackseg_np")
+    #[cfg(any(target_os = "openbsd", target_os = "bitrig"))]
+    pub unsafe fn current() -> usize {
+        #[repr(C)]
+        struct stack_t {
+            ss_sp: *mut libc::c_void,
+            ss_size: libc::size_t,
+            ss_flags: libc::c_int,
+        }
+        extern {
+            fn pthread_main_np() -> libc::c_uint;
+            fn pthread_stackseg_np(thread: pthread_t,
+                                   sinfo: *mut stack_t) -> libc::c_uint;
         }
 
+        let mut current_stack: stack_t = mem::zeroed();
+        assert_eq!(pthread_stackseg_np(pthread_self(), &mut current_stack), 0);
+
+        let extra = if cfg!(target_os = "bitrig") {3} else {1} * os::page_size();
         if pthread_main_np() == 1 {
             // main thread
-            current_stack.ss_sp as uint - current_stack.ss_size as uint + 3 * PAGE_SIZE as uint
-
+            current_stack.ss_sp as usize - current_stack.ss_size as usize + extra
         } else {
             // new thread
-            current_stack.ss_sp as uint - current_stack.ss_size as uint
+            current_stack.ss_sp as usize - current_stack.ss_size as usize
         }
     }
 
     #[cfg(any(target_os = "linux", target_os = "android"))]
-    pub unsafe fn current() -> uint {
+    pub unsafe fn current() -> usize {
         let mut attr: libc::pthread_attr_t = mem::zeroed();
-        if pthread_getattr_np(pthread_self(), &mut attr) != 0 {
-            panic!("failed to get thread attributes");
-        }
+        assert_eq!(pthread_getattr_np(pthread_self(), &mut attr), 0);
         let mut guardsize = 0;
-        if pthread_attr_getguardsize(&attr, &mut guardsize) != 0 {
-            panic!("failed to get stack guard page");
-        }
+        assert_eq!(pthread_attr_getguardsize(&attr, &mut guardsize), 0);
         if guardsize == 0 {
             panic!("there is no guard page");
         }
         let mut stackaddr = ptr::null_mut();
-        let mut stacksize = 0;
-        if pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize) != 0 {
-            panic!("failed to get stack information");
-        }
-        if pthread_attr_destroy(&mut attr) != 0 {
-            panic!("failed to destroy thread attributes");
-        }
+        let mut size = 0;
+        assert_eq!(pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0);
+        assert_eq!(pthread_attr_destroy(&mut attr), 0);
 
-        stackaddr as uint + guardsize as uint
+        stackaddr as usize + guardsize as usize
+    }
+
+    #[cfg(any(target_os = "linux", target_os = "android"))]
+    extern {
+        fn pthread_getattr_np(native: libc::pthread_t,
+                              attr: *mut libc::pthread_attr_t) -> libc::c_int;
+        fn pthread_attr_getguardsize(attr: *const libc::pthread_attr_t,
+                                     guardsize: *mut libc::size_t) -> libc::c_int;
+        fn pthread_attr_getstack(attr: *const libc::pthread_attr_t,
+                                 stackaddr: *mut *mut libc::c_void,
+                                 stacksize: *mut libc::size_t) -> libc::c_int;
     }
 }
 
-pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
+pub unsafe fn create(stack: usize, p: Thunk) -> io::Result<rust_thread> {
+    let p = box p;
     let mut native: libc::pthread_t = mem::zeroed();
     let mut attr: libc::pthread_attr_t = mem::zeroed();
     assert_eq!(pthread_attr_init(&mut attr), 0);
-    assert_eq!(pthread_attr_setdetachstate(&mut attr,
-                                           PTHREAD_CREATE_JOINABLE), 0);
 
     // Reserve room for the red zone, the runtime's stack of last resort.
-    let stack_size = cmp::max(stack, RED_ZONE + min_stack_size(&attr) as uint);
+    let stack_size = cmp::max(stack, RED_ZONE + min_stack_size(&attr) as usize);
     match pthread_attr_setstacksize(&mut attr, stack_size as libc::size_t) {
-        0 => {
-        },
-        libc::EINVAL => {
+        0 => {}
+        n => {
+            assert_eq!(n, libc::EINVAL);
             // EINVAL means |stack_size| is either too small or not a
             // multiple of the system page size.  Because it's definitely
             // >= PTHREAD_STACK_MIN, it must be an alignment issue.
             // Round up to the nearest page and try again.
-            let page_size = libc::sysconf(libc::_SC_PAGESIZE) as uint;
+            let page_size = os::page_size();
             let stack_size = (stack_size + page_size - 1) &
-                             (-(page_size as int - 1) as uint - 1);
-            assert_eq!(pthread_attr_setstacksize(&mut attr, stack_size as libc::size_t), 0);
-        },
-        errno => {
-            // This cannot really happen.
-            panic!("pthread_attr_setstacksize() error: {}", errno);
-        },
+                             (-(page_size as isize - 1) as usize - 1);
+            assert_eq!(pthread_attr_setstacksize(&mut attr,
+                                                 stack_size as libc::size_t), 0);
+        }
     };
 
-    let arg: *mut libc::c_void = mem::transmute(box p); // must box since sizeof(p)=2*uint
-    let ret = pthread_create(&mut native, &attr, thread_start, arg);
+    let ret = pthread_create(&mut native, &attr, thread_start,
+                             &*p as *const _ as *mut _);
     assert_eq!(pthread_attr_destroy(&mut attr), 0);
 
-    if ret != 0 {
-        // be sure to not leak the closure
-        let _p: Box<Box<FnOnce()+Send>> = mem::transmute(arg);
+    return if ret != 0 {
         Err(io::Error::from_os_error(ret))
     } else {
+        mem::forget(p); // ownership passed to pthread_create
         Ok(native)
+    };
+
+    #[no_stack_check]
+    extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
+        start_thread(main);
+        0 as *mut _
     }
 }
 
 #[cfg(any(target_os = "linux", target_os = "android"))]
 pub unsafe fn set_name(name: &str) {
-    // pthread_setname_np() since glibc 2.12
-    // availability autodetected via weak linkage
-    let cname = CString::new(name).unwrap();
-    type F = unsafe extern "C" fn(libc::pthread_t, *const libc::c_char) -> libc::c_int;
+    // pthread wrapper only appeared in glibc 2.12, so we use syscall directly.
     extern {
-        #[linkage = "extern_weak"]
-        static pthread_setname_np: *const ();
-    }
-    if !pthread_setname_np.is_null() {
-        unsafe {
-            mem::transmute::<*const (), F>(pthread_setname_np)(pthread_self(), cname.as_ptr());
-        }
+        fn prctl(option: libc::c_int, arg2: libc::c_ulong, arg3: libc::c_ulong,
+                 arg4: libc::c_ulong, arg5: libc::c_ulong) -> libc::c_int;
     }
+    const PR_SET_NAME: libc::c_int = 15;
+    let cname = CString::new(name).unwrap_or_else(|_| {
+        panic!("thread name may not contain interior null bytes")
+    });
+    prctl(PR_SET_NAME, cname.as_ptr() as libc::c_ulong, 0, 0, 0);
 }
 
 #[cfg(any(target_os = "freebsd",
           target_os = "dragonfly",
+          target_os = "bitrig",
           target_os = "openbsd"))]
 pub unsafe fn set_name(name: &str) {
-    // pthread_set_name_np() since almost forever on all BSDs
+    extern {
+        fn pthread_set_name_np(tid: libc::pthread_t, name: *const libc::c_char);
+    }
     let cname = CString::new(name).unwrap();
     pthread_set_name_np(pthread_self(), cname.as_ptr());
 }
 
 #[cfg(any(target_os = "macos", target_os = "ios"))]
 pub unsafe fn set_name(name: &str) {
-    // pthread_setname_np() since OS X 10.6 and iOS 3.2
+    extern {
+        fn pthread_setname_np(name: *const libc::c_char) -> libc::c_int;
+    }
     let cname = CString::new(name).unwrap();
     pthread_setname_np(cname.as_ptr());
 }
@@ -274,90 +268,97 @@ pub unsafe fn detach(native: rust_thread) {
     assert_eq!(pthread_detach(native), 0);
 }
 
-pub unsafe fn yield_now() { assert_eq!(sched_yield(), 0); }
+pub unsafe fn yield_now() {
+    assert_eq!(sched_yield(), 0);
+}
+
+pub fn sleep(dur: Duration) {
+    unsafe {
+        if dur < Duration::zero() {
+            return yield_now()
+        }
+        let seconds = dur.num_seconds();
+        let ns = dur - Duration::seconds(seconds);
+        let mut ts = libc::timespec {
+            tv_sec: seconds as libc::time_t,
+            tv_nsec: ns.num_nanoseconds().unwrap() as libc::c_long,
+        };
+        // If we're awoken with a signal then the return value will be -1 and
+        // nanosleep will fill in `ts` with the remaining time.
+        while dosleep(&mut ts) == -1 {
+            assert_eq!(os::errno(), libc::EINTR);
+        }
+    }
+
+    #[cfg(target_os = "linux")]
+    unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
+        extern {
+            fn clock_nanosleep(clock_id: libc::c_int, flags: libc::c_int,
+                               request: *const libc::timespec,
+                               remain: *mut libc::timespec) -> libc::c_int;
+        }
+        clock_nanosleep(libc::CLOCK_MONOTONIC, 0, ts, ts)
+    }
+    #[cfg(not(target_os = "linux"))]
+    unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
+        libc::nanosleep(ts, ts)
+    }
+}
+
 // glibc >= 2.15 has a __pthread_get_minstack() function that returns
 // PTHREAD_STACK_MIN plus however many bytes are needed for thread-local
 // storage.  We need that information to avoid blowing up when a small stack
 // is created in an application with big thread-local storage requirements.
 // See #6233 for rationale and details.
 //
-// Link weakly to the symbol for compatibility with older versions of glibc.
-// Assumes that we've been dynamically linked to libpthread but that is
-// currently always the case.  Note that you need to check that the symbol
-// is non-null before calling it!
+// Use dlsym to get the symbol value at runtime, both for
+// compatibility with older versions of glibc, and to avoid creating
+// dependencies on GLIBC_PRIVATE symbols.  Assumes that we've been
+// dynamically linked to libpthread but that is currently always the
+// case.  We previously used weak linkage (under the same assumption),
+// but that caused Debian to detect an unnecessarily strict versioned
+// dependency on libc6 (#23628).
 #[cfg(target_os = "linux")]
 fn min_stack_size(attr: *const libc::pthread_attr_t) -> libc::size_t {
+    use dynamic_lib::DynamicLibrary;
+    use sync::{Once, ONCE_INIT};
+
     type F = unsafe extern "C" fn(*const libc::pthread_attr_t) -> libc::size_t;
-    extern {
-        #[linkage = "extern_weak"]
-        static __pthread_get_minstack: *const ();
-    }
-    if __pthread_get_minstack.is_null() {
-        PTHREAD_STACK_MIN
-    } else {
-        unsafe { mem::transmute::<*const (), F>(__pthread_get_minstack)(attr) }
+    static INIT: Once = ONCE_INIT;
+    static mut __pthread_get_minstack: Option<F> = None;
+
+    INIT.call_once(|| {
+        let lib = DynamicLibrary::open(None).unwrap();
+        unsafe {
+            if let Ok(f) = lib.symbol("__pthread_get_minstack") {
+                __pthread_get_minstack = Some(mem::transmute::<*const (), F>(f));
+            }
+        }
+    });
+
+    match unsafe { __pthread_get_minstack } {
+        None => PTHREAD_STACK_MIN,
+        Some(f) => unsafe { f(attr) },
     }
 }
 
-// __pthread_get_minstack() is marked as weak but extern_weak linkage is
-// not supported on OS X, hence this kludge...
+// No point in looking up __pthread_get_minstack() on non-glibc
+// platforms.
 #[cfg(not(target_os = "linux"))]
 fn min_stack_size(_: *const libc::pthread_attr_t) -> libc::size_t {
     PTHREAD_STACK_MIN
 }
 
-#[cfg(any(target_os = "linux", target_os = "android"))]
-extern {
-    pub fn pthread_self() -> libc::pthread_t;
-    pub fn pthread_getattr_np(native: libc::pthread_t,
-                              attr: *mut libc::pthread_attr_t) -> libc::c_int;
-    pub fn pthread_attr_getguardsize(attr: *const libc::pthread_attr_t,
-                                     guardsize: *mut libc::size_t) -> libc::c_int;
-    pub fn pthread_attr_getstack(attr: *const libc::pthread_attr_t,
-                                 stackaddr: *mut *mut libc::c_void,
-                                 stacksize: *mut libc::size_t) -> libc::c_int;
-}
-
-#[cfg(any(target_os = "freebsd",
-          target_os = "dragonfly",
-          target_os = "openbsd"))]
-extern {
-    pub fn pthread_self() -> libc::pthread_t;
-    fn pthread_set_name_np(tid: libc::pthread_t, name: *const libc::c_char);
-}
-
-#[cfg(any(target_os = "macos", target_os = "ios"))]
-extern {
-    pub fn pthread_self() -> libc::pthread_t;
-    pub fn pthread_get_stackaddr_np(thread: libc::pthread_t) -> *mut libc::c_void;
-    pub fn pthread_get_stacksize_np(thread: libc::pthread_t) -> libc::size_t;
-    fn pthread_setname_np(name: *const libc::c_char) -> libc::c_int;
-}
-
-#[cfg(target_os = "openbsd")]
-extern {
-        pub fn pthread_stackseg_np(thread: libc::pthread_t,
-                                   sinfo: *mut stack_t) -> libc::c_uint;
-        pub fn pthread_main_np() -> libc::c_uint;
-}
-
-#[cfg(target_os = "openbsd")]
-#[repr(C)]
-pub struct stack_t {
-    pub ss_sp: *mut libc::c_void,
-    pub ss_size: libc::size_t,
-    pub ss_flags: libc::c_int,
-}
-
 extern {
+    fn pthread_self() -> libc::pthread_t;
     fn pthread_create(native: *mut libc::pthread_t,
                       attr: *const libc::pthread_attr_t,
-                      f: StartFn,
+                      f: extern fn(*mut libc::c_void) -> *mut libc::c_void,
                       value: *mut libc::c_void) -> libc::c_int;
     fn pthread_join(native: libc::pthread_t,
                     value: *mut *mut libc::c_void) -> libc::c_int;
     fn pthread_attr_init(attr: *mut libc::pthread_attr_t) -> libc::c_int;
-    pub fn pthread_attr_destroy(attr: *mut libc::pthread_attr_t) -> libc::c_int;
+    fn pthread_attr_destroy(attr: *mut libc::pthread_attr_t) -> libc::c_int;
     fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
                                  stack_size: libc::size_t) -> libc::c_int;
     fn pthread_attr_setdetachstate(attr: *mut libc::pthread_attr_t,
index 62d9a33c83d7af78d0280a0118e950844b59c99b..9b7079ee10833de308a6cb70ba250e59f5a8d959 100644 (file)
@@ -43,6 +43,7 @@ type pthread_key_t = ::libc::c_ulong;
 
 #[cfg(any(target_os = "freebsd",
           target_os = "dragonfly",
+          target_os = "bitrig",
           target_os = "openbsd"))]
 type pthread_key_t = ::libc::c_int;
 
@@ -50,6 +51,7 @@ type pthread_key_t = ::libc::c_int;
               target_os = "ios",
               target_os = "freebsd",
               target_os = "dragonfly",
+              target_os = "bitrig",
               target_os = "openbsd")))]
 type pthread_key_t = ::libc::c_uint;
 
index bddf7b075df96ab365f534484bde9e6cff17e373..d2f51678d497fa737c463c0089b4729fe63b1a73 100644 (file)
@@ -58,11 +58,9 @@ mod inner {
         type Output = Duration;
 
         fn sub(self, other: &SteadyTime) -> Duration {
-            unsafe {
-                let info = info();
-                let diff = self.t as i64 - other.t as i64;
-                Duration::nanoseconds(diff * info.numer as i64 / info.denom as i64)
-            }
+            let info = info();
+            let diff = self.t as i64 - other.t as i64;
+            Duration::nanoseconds(diff * info.numer as i64 / info.denom as i64)
         }
     }
 }
@@ -80,8 +78,11 @@ mod inner {
     }
 
     // Apparently android provides this in some other library?
+    // Bitrig's RT extensions are in the C library, not a separate librt
     // OpenBSD provide it via libc
-    #[cfg(not(any(target_os = "android", target_os = "openbsd")))]
+    #[cfg(not(any(target_os = "android",
+                  target_os = "bitrig",
+                  target_os = "openbsd")))]
     #[link(name = "rt")]
     extern {}
 
index 4cd98f4442b0fcb8bab3506f4c7ff0388adced53..9309147b15c44f6bd14ae38417bf04ef010fcda2 100644 (file)
 //!
 //! Note that all time units in this file are in *milliseconds*.
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 use self::Req::*;
 
 use old_io::IoResult;
 use libc;
 use mem;
-use os;
+use sys::os;
+use io;
 use ptr;
 use sync::atomic::{self, Ordering};
 use sync::mpsc::{channel, Sender, Receiver, TryRecvError};
@@ -67,7 +70,7 @@ pub trait Callback {
 }
 
 pub struct Timer {
-    id: uint,
+    id: usize,
     inner: Option<Box<Inner>>,
 }
 
@@ -76,7 +79,7 @@ pub struct Inner {
     interval: u64,
     repeat: bool,
     target: u64,
-    id: uint,
+    id: usize,
 }
 
 pub enum Req {
@@ -85,7 +88,7 @@ pub enum Req {
 
     // Remove a timer based on its id and then send it back on the channel
     // provided
-    RemoveTimer(uint, Sender<Box<Inner>>),
+    RemoveTimer(usize, Sender<Box<Inner>>),
 }
 
 // returns the current time (in milliseconds)
@@ -100,7 +103,7 @@ pub fn now() -> u64 {
 fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
     let mut set: c::fd_set = unsafe { mem::zeroed() };
 
-    let mut fd = FileDesc::new(input, true);
+    let fd = FileDesc::new(input, true);
     let mut timeout: libc::timeval = unsafe { mem::zeroed() };
 
     // active timers are those which are able to be selected upon (and it's a
@@ -119,7 +122,7 @@ fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
 
     // signals the first requests in the queue, possible re-enqueueing it.
     fn signal(active: &mut Vec<Box<Inner>>,
-              dead: &mut Vec<(uint, Box<Inner>)>) {
+              dead: &mut Vec<(usize, Box<Inner>)>) {
         if active.is_empty() { return }
 
         let mut timer = active.remove(0);
@@ -168,8 +171,15 @@ fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
             1 => {
                 loop {
                     match messages.try_recv() {
+                        // Once we've been disconnected it means the main thread
+                        // is exiting (at_exit has run). We could still have
+                        // active timers for other threads, so we're just going
+                        // to drop them all on the floor. This is all we can
+                        // really do, however, to prevent resource leakage. The
+                        // remaining timers will likely start panicking quickly
+                        // as they attempt to re-use this thread but are
+                        // disallowed to do so.
                         Err(TryRecvError::Disconnected) => {
-                            assert!(active.len() == 0);
                             break 'outer;
                         }
 
@@ -195,19 +205,19 @@ fn helper(input: libc::c_int, messages: Receiver<Req>, _: ()) {
 
                 // drain the file descriptor
                 let mut buf = [0];
-                assert_eq!(fd.read(&mut buf).ok().unwrap(), 1);
+                assert_eq!(fd.read(&mut buf).unwrap(), 1);
             }
 
             -1 if os::errno() == libc::EINTR as i32 => {}
             n => panic!("helper thread failed in select() with error: {} ({})",
-                       n, os::last_os_error())
+                       n, io::Error::last_os_error())
         }
     }
 }
 
 impl Timer {
     pub fn new() -> IoResult<Timer> {
-        // See notes above regarding using int return value
+        // See notes above regarding using isize return value
         // instead of ()
         HELPER.boot(|| {}, helper);
 
@@ -235,7 +245,7 @@ impl Timer {
             tv_nsec: ((ms % 1000) * 1000000) as libc::c_long,
         };
         while unsafe { libc::nanosleep(&to_sleep, &mut to_sleep) } != 0 {
-            if os::errno() as int != libc::EINTR as int {
+            if os::errno() as isize != libc::EINTR as isize {
                 panic!("failed to sleep, but not because of EINTR?");
             }
         }
index 3a79047445cdd8d10a5a70b6c9df8d36e60649f7..2f6fd713bfba50c01d7049e83e84ab5a48d873fd 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 
 use sys::fs::FileDesc;
-use libc::{self, c_int, c_ulong, funcs};
+use libc::{self, c_int, c_ulong};
 use old_io::{self, IoResult, IoError};
 use sys::c;
 use sys_common;
@@ -21,7 +23,10 @@ pub struct TTY {
 }
 
 #[cfg(any(target_os = "macos",
+          target_os = "ios",
+          target_os = "dragonfly",
           target_os = "freebsd",
+          target_os = "bitrig",
           target_os = "openbsd"))]
 const TIOCGWINSZ: c_ulong = 0x40087468;
 
@@ -41,7 +46,7 @@ impl TTY {
         }
     }
 
-    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         self.fd.read(buf)
     }
     pub fn write(&mut self, buf: &[u8]) -> IoResult<()> {
@@ -51,12 +56,7 @@ impl TTY {
         Err(sys_common::unimpl())
     }
 
-    #[cfg(any(target_os = "linux",
-              target_os = "android",
-              target_os = "macos",
-              target_os = "freebsd",
-              target_os = "openbsd"))]
-    pub fn get_winsize(&mut self) -> IoResult<(int, int)> {
+    pub fn get_winsize(&mut self) -> IoResult<(isize, isize)> {
         unsafe {
             #[repr(C)]
             struct winsize {
@@ -74,16 +74,8 @@ impl TTY {
                     detail: None,
                 })
             } else {
-                Ok((size.ws_col as int, size.ws_row as int))
+                Ok((size.ws_col as isize, size.ws_row as isize))
             }
         }
     }
-
-    #[cfg(any(target_os = "ios",
-              target_os = "dragonfly"))]
-    pub fn get_winsize(&mut self) -> IoResult<(int, int)> {
-        Err(sys_common::unimpl())
-    }
-
-    pub fn isatty(&self) -> bool { false }
 }
index 51cf30324233c772cfaa66185365640db174b275..385834a6226e05ec82d77b760fa897484b2d56d9 100644 (file)
 
 #![allow(dead_code)]
 
+use prelude::v1::*;
+use io::prelude::*;
+
 use dynamic_lib::DynamicLibrary;
 use ffi::CStr;
 use intrinsics;
-use old_io::{IoResult, Writer};
+use io;
 use libc;
 use mem;
-use ops::Drop;
-use option::Option::{Some};
-use old_path::Path;
+use path::Path;
 use ptr;
-use result::Result::{Ok, Err};
-use slice::SliceExt;
-use str::{self, StrExt};
+use str;
 use sync::{StaticMutex, MUTEX_INIT};
 
 use sys_common::backtrace::*;
@@ -63,7 +62,7 @@ type StackWalk64Fn =
                        *mut libc::c_void, *mut libc::c_void,
                        *mut libc::c_void, *mut libc::c_void) -> libc::BOOL;
 
-const MAX_SYM_NAME: uint = 2000;
+const MAX_SYM_NAME: usize = 2000;
 const IMAGE_FILE_MACHINE_I386: libc::DWORD = 0x014c;
 const IMAGE_FILE_MACHINE_IA64: libc::DWORD = 0x0200;
 const IMAGE_FILE_MACHINE_AMD64: libc::DWORD = 0x8664;
@@ -105,7 +104,7 @@ struct ADDRESS64 {
     Mode: ADDRESS_MODE,
 }
 
-struct STACKFRAME64 {
+pub struct STACKFRAME64 {
     AddrPC: ADDRESS64,
     AddrReturn: ADDRESS64,
     AddrFrame: ADDRESS64,
@@ -138,7 +137,7 @@ struct KDHELP64 {
 mod arch {
     use libc;
 
-    const MAXIMUM_SUPPORTED_EXTENSION: uint = 512;
+    const MAXIMUM_SUPPORTED_EXTENSION: usize = 512;
 
     #[repr(C)]
     pub struct CONTEXT {
@@ -294,7 +293,7 @@ impl Drop for Cleanup {
     fn drop(&mut self) { (self.SymCleanup)(self.handle); }
 }
 
-pub fn write(w: &mut Writer) -> IoResult<()> {
+pub fn write(w: &mut Write) -> io::Result<()> {
     // According to windows documentation, all dbghelp functions are
     // single-threaded.
     static LOCK: StaticMutex = MUTEX_INIT;
index 2d1a5e10bd63f73a6e815452f8ea9abb41e35cf6..4804f6504419c599992c3549c12f9fcb652f7c65 100644 (file)
@@ -48,6 +48,11 @@ pub const WSAESHUTDOWN: libc::c_int = 10058;
 pub const ERROR_NO_MORE_FILES: libc::DWORD = 18;
 pub const TOKEN_READ: libc::DWORD = 0x20008;
 
+// Note that these are not actually HANDLEs, just values to pass to GetStdHandle
+pub const STD_INPUT_HANDLE: libc::DWORD = -10i32 as libc::DWORD;
+pub const STD_OUTPUT_HANDLE: libc::DWORD = -11i32 as libc::DWORD;
+pub const STD_ERROR_HANDLE: libc::DWORD = -12i32 as libc::DWORD;
+
 #[repr(C)]
 #[cfg(target_arch = "x86")]
 pub struct WSADATA {
@@ -84,7 +89,6 @@ pub type LPWSANETWORKEVENTS = *mut WSANETWORKEVENTS;
 pub type WSAEVENT = libc::HANDLE;
 
 #[repr(C)]
-#[derive(Copy)]
 pub struct WSAPROTOCOL_INFO {
     pub dwServiceFlags1: libc::DWORD,
     pub dwServiceFlags2: libc::DWORD,
@@ -295,7 +299,7 @@ pub mod compat {
 
     /// Macro for creating a compatibility fallback for a Windows function
     ///
-    /// # Example
+    /// # Examples
     /// ```
     /// compat_fn!(adll32::SomeFunctionW(_arg: LPCWSTR) {
     ///     // Fallback implementation
@@ -427,6 +431,8 @@ extern "system" {
                             DesiredAccess: libc::DWORD,
                             TokenHandle: *mut libc::HANDLE) -> libc::BOOL;
     pub fn GetCurrentProcess() -> libc::HANDLE;
+    pub fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
+    pub fn ExitProcess(uExitCode: libc::c_uint) -> !;
 }
 
 #[link(name = "userenv")]
index db8038006fd6a81451a3783951609bddb7f8719f..67552255fdbeb50e0c5a294059606ccfbd31722a 100644 (file)
@@ -8,15 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use prelude::v1::*;
+
 use cell::UnsafeCell;
 use libc::{self, DWORD};
-use os;
+use sys::os;
 use sys::mutex::{self, Mutex};
 use sys::sync as ffi;
 use time::Duration;
 
 pub struct Condvar { inner: UnsafeCell<ffi::CONDITION_VARIABLE> }
 
+unsafe impl Send for Condvar {}
+unsafe impl Sync for Condvar {}
+
 pub const CONDVAR_INIT: Condvar = Condvar {
     inner: UnsafeCell { value: ffi::CONDITION_VARIABLE_INIT }
 };
@@ -41,7 +46,7 @@ impl Condvar {
                                                0);
         if r == 0 {
             const ERROR_TIMEOUT: DWORD = 0x5B4;
-            debug_assert_eq!(os::errno() as uint, ERROR_TIMEOUT as uint);
+            debug_assert_eq!(os::errno() as usize, ERROR_TIMEOUT as usize);
             false
         } else {
             true
index ac1006e653f09dc7c76c1e423e8c536f54d93a81..2dd61861bd6dc8c78299ffb2b7c9065f3aef29c9 100644 (file)
 //! descriptors, and sockets, but its functionality will grow over
 //! time.
 
-#![unstable(feature = "std_misc")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
-pub use sys_common::wtf8::{Wtf8Buf, EncodeWide};
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod io {
+    use fs;
+    use libc;
+    use net;
+    use sys_common::{net2, AsInner, FromInner};
+    use sys;
 
-use ffi::{OsStr, OsString};
-use fs::{self, OpenOptions};
-use libc;
-use net;
-use sys::os_str::Buf;
-use sys_common::{AsInner, FromInner, AsInnerMut};
+    #[allow(deprecated)]
+    use old_io;
 
-use old_io;
+    /// Raw HANDLEs.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub type RawHandle = libc::HANDLE;
 
-/// Raw HANDLEs.
-pub type Handle = libc::HANDLE;
+    /// Raw SOCKETs.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub type RawSocket = libc::SOCKET;
 
-/// Raw SOCKETs.
-pub type Socket = libc::SOCKET;
+    /// Extract raw handles.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait AsRawHandle {
+        /// Extract the raw handle, without taking any ownership.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn as_raw_handle(&self) -> RawHandle;
+    }
 
-/// Extract raw handles.
-pub trait AsRawHandle {
-    /// Extract the raw handle, without taking any ownership.
-    fn as_raw_handle(&self) -> Handle;
-}
+    /// Construct I/O objects from raw handles.
+    #[unstable(feature = "from_raw_os",
+               reason = "recent addition to the std::os::windows::io module")]
+    pub trait FromRawHandle {
+        /// Construct a new I/O object from the specified raw handle.
+        ///
+        /// This function will **consume ownership** of the handle given,
+        /// passing responsibility for closing the handle to the returned
+        /// object.
+        fn from_raw_handle(handle: RawHandle) -> Self;
+    }
 
-impl AsRawHandle for old_io::fs::File {
-    fn as_raw_handle(&self) -> Handle {
-        self.as_inner().handle()
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawHandle for old_io::fs::File {
+        fn as_raw_handle(&self) -> RawHandle {
+            self.as_inner().handle()
+        }
     }
-}
 
-impl AsRawHandle for fs::File {
-    fn as_raw_handle(&self) -> Handle {
-        self.as_inner().handle().raw()
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawHandle for fs::File {
+        fn as_raw_handle(&self) -> RawHandle {
+            self.as_inner().handle().raw()
+        }
     }
-}
 
-impl AsRawHandle for old_io::pipe::PipeStream {
-    fn as_raw_handle(&self) -> Handle {
-        self.as_inner().handle()
+    #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+    impl FromRawHandle for fs::File {
+        fn from_raw_handle(handle: RawHandle) -> fs::File {
+            fs::File::from_inner(sys::fs2::File::from_inner(handle))
+        }
     }
-}
 
-impl AsRawHandle for old_io::net::pipe::UnixStream {
-    fn as_raw_handle(&self) -> Handle {
-        self.as_inner().handle()
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawHandle for old_io::pipe::PipeStream {
+        fn as_raw_handle(&self) -> RawHandle {
+            self.as_inner().handle()
+        }
     }
-}
 
-impl AsRawHandle for old_io::net::pipe::UnixListener {
-    fn as_raw_handle(&self) -> Handle {
-        self.as_inner().handle()
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawHandle for old_io::net::pipe::UnixStream {
+        fn as_raw_handle(&self) -> RawHandle {
+            self.as_inner().handle()
+        }
     }
-}
 
-impl AsRawHandle for old_io::net::pipe::UnixAcceptor {
-    fn as_raw_handle(&self) -> Handle {
-        self.as_inner().handle()
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawHandle for old_io::net::pipe::UnixListener {
+        fn as_raw_handle(&self) -> RawHandle {
+            self.as_inner().handle()
+        }
     }
-}
 
-/// Extract raw sockets.
-pub trait AsRawSocket {
-    fn as_raw_socket(&self) -> Socket;
-}
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawHandle for old_io::net::pipe::UnixAcceptor {
+        fn as_raw_handle(&self) -> RawHandle {
+            self.as_inner().handle()
+        }
+    }
 
-impl AsRawSocket for old_io::net::tcp::TcpStream {
-    fn as_raw_socket(&self) -> Socket {
-        self.as_inner().fd()
+    /// Extract raw sockets.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait AsRawSocket {
+        /// Extract the underlying raw socket from this object.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn as_raw_socket(&self) -> RawSocket;
     }
-}
 
-impl AsRawSocket for old_io::net::tcp::TcpListener {
-    fn as_raw_socket(&self) -> Socket {
-        self.as_inner().socket()
+    /// Create I/O objects from raw sockets.
+    #[unstable(feature = "from_raw_os", reason = "recent addition to module")]
+    pub trait FromRawSocket {
+        /// Creates a new I/O object from the given raw socket.
+        ///
+        /// This function will **consume ownership** of the socket provided and
+        /// it will be closed when the returned object goes out of scope.
+        fn from_raw_socket(sock: RawSocket) -> Self;
     }
-}
 
-impl AsRawSocket for old_io::net::tcp::TcpAcceptor {
-    fn as_raw_socket(&self) -> Socket {
-        self.as_inner().socket()
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawSocket for old_io::net::tcp::TcpStream {
+        fn as_raw_socket(&self) -> RawSocket {
+            self.as_inner().fd()
+        }
     }
-}
 
-impl AsRawSocket for old_io::net::udp::UdpSocket {
-    fn as_raw_socket(&self) -> Socket {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawSocket for old_io::net::tcp::TcpListener {
+        fn as_raw_socket(&self) -> RawSocket {
+            self.as_inner().socket()
+        }
     }
-}
 
-impl AsRawSocket for net::TcpStream {
-    fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
-}
-impl AsRawSocket for net::TcpListener {
-    fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
-}
-impl AsRawSocket for net::UdpSocket {
-    fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
-}
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawSocket for old_io::net::tcp::TcpAcceptor {
+        fn as_raw_socket(&self) -> RawSocket {
+            self.as_inner().socket()
+        }
+    }
 
-// Windows-specific extensions to `OsString`.
-pub trait OsStringExt {
-    /// Create an `OsString` from a potentially ill-formed UTF-16 slice of 16-bit code units.
-    ///
-    /// This is lossless: calling `.encode_wide()` on the resulting string
-    /// will always return the original code units.
-    fn from_wide(wide: &[u16]) -> Self;
-}
+    #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawSocket for old_io::net::udp::UdpSocket {
+        fn as_raw_socket(&self) -> RawSocket {
+            self.as_inner().fd()
+        }
+    }
 
-impl OsStringExt for OsString {
-    fn from_wide(wide: &[u16]) -> OsString {
-        FromInner::from_inner(Buf { inner: Wtf8Buf::from_wide(wide) })
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawSocket for net::TcpStream {
+        fn as_raw_socket(&self) -> RawSocket {
+            *self.as_inner().socket().as_inner()
+        }
+    }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawSocket for net::TcpListener {
+        fn as_raw_socket(&self) -> RawSocket {
+            *self.as_inner().socket().as_inner()
+        }
+    }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl AsRawSocket for net::UdpSocket {
+        fn as_raw_socket(&self) -> RawSocket {
+            *self.as_inner().socket().as_inner()
+        }
     }
-}
 
-// Windows-specific extensions to `OsStr`.
-pub trait OsStrExt {
-    fn encode_wide(&self) -> EncodeWide;
+    #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+    impl FromRawSocket for net::TcpStream {
+        fn from_raw_socket(sock: RawSocket) -> net::TcpStream {
+            let sock = sys::net::Socket::from_inner(sock);
+            net::TcpStream::from_inner(net2::TcpStream::from_inner(sock))
+        }
+    }
+    #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+    impl FromRawSocket for net::TcpListener {
+        fn from_raw_socket(sock: RawSocket) -> net::TcpListener {
+            let sock = sys::net::Socket::from_inner(sock);
+            net::TcpListener::from_inner(net2::TcpListener::from_inner(sock))
+        }
+    }
+    #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+    impl FromRawSocket for net::UdpSocket {
+        fn from_raw_socket(sock: RawSocket) -> net::UdpSocket {
+            let sock = sys::net::Socket::from_inner(sock);
+            net::UdpSocket::from_inner(net2::UdpSocket::from_inner(sock))
+        }
+    }
 }
 
-impl OsStrExt for OsStr {
-    fn encode_wide(&self) -> EncodeWide {
-        self.as_inner().inner.encode_wide()
+/// Windows-specific extensions to the primitives in the `std::ffi` module.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod ffi {
+    use ffi::{OsString, OsStr};
+    use sys::os_str::Buf;
+    use sys_common::wtf8::Wtf8Buf;
+    use sys_common::{FromInner, AsInner};
+
+    pub use sys_common::wtf8::EncodeWide;
+
+    /// Windows-specific extensions to `OsString`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait OsStringExt {
+        /// Create an `OsString` from a potentially ill-formed UTF-16 slice of
+        /// 16-bit code units.
+        ///
+        /// This is lossless: calling `.encode_wide()` on the resulting string
+        /// will always return the original code units.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn from_wide(wide: &[u16]) -> Self;
     }
-}
 
-// Windows-specific extensions to `OpenOptions`
-pub trait OpenOptionsExt {
-    /// Override the `dwDesiredAccess` argument to the call to `CreateFile` with
-    /// the specified value.
-    fn desired_access(&mut self, access: i32) -> &mut Self;
-
-    /// Override the `dwCreationDisposition` argument to the call to
-    /// `CreateFile` with the specified value.
-    ///
-    /// This will override any values of the standard `create` flags, for
-    /// example.
-    fn creation_disposition(&mut self, val: i32) -> &mut Self;
-
-    /// Override the `dwFlagsAndAttributes` argument to the call to
-    /// `CreateFile` with the specified value.
-    ///
-    /// This will override any values of the standard flags on the `OpenOptions`
-    /// structure.
-    fn flags_and_attributes(&mut self, val: i32) -> &mut Self;
-
-    /// Override the `dwShareMode` argument to the call to `CreateFile` with the
-    /// specified value.
-    ///
-    /// This will override any values of the standard flags on the `OpenOptions`
-    /// structure.
-    fn share_mode(&mut self, val: i32) -> &mut Self;
-}
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl OsStringExt for OsString {
+        fn from_wide(wide: &[u16]) -> OsString {
+            FromInner::from_inner(Buf { inner: Wtf8Buf::from_wide(wide) })
+        }
+    }
 
-impl OpenOptionsExt for OpenOptions {
-    fn desired_access(&mut self, access: i32) -> &mut OpenOptions {
-        self.as_inner_mut().desired_access(access); self
+    /// Windows-specific extensions to `OsStr`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait OsStrExt {
+        /// Re-encode an `OsStr` as a wide character sequence,
+        /// i.e. potentially ill-formed UTF-16.
+        ///
+        /// This is lossless. Note that the encoding does not include a final
+        /// null.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn encode_wide(&self) -> EncodeWide;
     }
-    fn creation_disposition(&mut self, access: i32) -> &mut OpenOptions {
-        self.as_inner_mut().creation_disposition(access); self
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl OsStrExt for OsStr {
+        fn encode_wide(&self) -> EncodeWide {
+            self.as_inner().inner.encode_wide()
+        }
     }
-    fn flags_and_attributes(&mut self, access: i32) -> &mut OpenOptions {
-        self.as_inner_mut().flags_and_attributes(access); self
+}
+
+/// Windows-specific extensions for the primitives in `std::fs`
+#[unstable(feature = "fs_ext", reason = "may require more thought/methods")]
+pub mod fs {
+    use fs::OpenOptions;
+    use sys_common::AsInnerMut;
+
+    /// Windows-specific extensions to `OpenOptions`
+    pub trait OpenOptionsExt {
+        /// Override the `dwDesiredAccess` argument to the call to `CreateFile`
+        /// with the specified value.
+        fn desired_access(&mut self, access: i32) -> &mut Self;
+
+        /// Override the `dwCreationDisposition` argument to the call to
+        /// `CreateFile` with the specified value.
+        ///
+        /// This will override any values of the standard `create` flags, for
+        /// example.
+        fn creation_disposition(&mut self, val: i32) -> &mut Self;
+
+        /// Override the `dwFlagsAndAttributes` argument to the call to
+        /// `CreateFile` with the specified value.
+        ///
+        /// This will override any values of the standard flags on the
+        /// `OpenOptions` structure.
+        fn flags_and_attributes(&mut self, val: i32) -> &mut Self;
+
+        /// Override the `dwShareMode` argument to the call to `CreateFile` with
+        /// the specified value.
+        ///
+        /// This will override any values of the standard flags on the
+        /// `OpenOptions` structure.
+        fn share_mode(&mut self, val: i32) -> &mut Self;
     }
-    fn share_mode(&mut self, access: i32) -> &mut OpenOptions {
-        self.as_inner_mut().share_mode(access); self
+
+    impl OpenOptionsExt for OpenOptions {
+        fn desired_access(&mut self, access: i32) -> &mut OpenOptions {
+            self.as_inner_mut().desired_access(access); self
+        }
+        fn creation_disposition(&mut self, access: i32) -> &mut OpenOptions {
+            self.as_inner_mut().creation_disposition(access); self
+        }
+        fn flags_and_attributes(&mut self, access: i32) -> &mut OpenOptions {
+            self.as_inner_mut().flags_and_attributes(access); self
+        }
+        fn share_mode(&mut self, access: i32) -> &mut OpenOptions {
+            self.as_inner_mut().share_mode(access); self
+        }
     }
 }
 
 /// A prelude for conveniently writing platform-specific code.
 ///
 /// Includes all extension traits, and some important type definitions.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub mod prelude {
     #[doc(no_inline)]
-    pub use super::{Socket, Handle, AsRawSocket, AsRawHandle};
-    #[doc(no_inline)]
-    pub use super::{OsStrExt, OsStringExt};
+    pub use super::io::{RawSocket, RawHandle, AsRawSocket, AsRawHandle};
+    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+    pub use super::ffi::{OsStrExt, OsStringExt};
     #[doc(no_inline)]
-    pub use super::OpenOptionsExt;
+    pub use super::fs::OpenOptionsExt;
 }
index 304d7e015327960747c3fc6dbb0e413d4b5845fd..0bbb1a9e92752c09c39f81adbcb6b53335b23baf 100644 (file)
@@ -10,6 +10,8 @@
 
 //! Blocking Windows-based file I/O
 
+#![allow(deprecated)] // this module itself is essentially deprecated
+
 use libc::{self, c_int};
 
 use mem;
@@ -18,8 +20,9 @@ use old_io;
 
 use prelude::v1::*;
 use sys;
-use sys_common::{mkerr_libc};
+use sys_common::{self, mkerr_libc};
 
+use old_path::{Path, GenericPath};
 use old_io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode};
 use old_io::{IoResult, IoError, FileStat, SeekStyle};
 use old_io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append};
@@ -39,7 +42,7 @@ impl FileDesc {
         FileDesc { fd: fd, close_on_drop: close_on_drop }
     }
 
-    pub fn read(&self, buf: &mut [u8]) -> IoResult<uint> {
+    pub fn read(&self, buf: &mut [u8]) -> IoResult<usize> {
         let mut read = 0;
         let ret = unsafe {
             libc::ReadFile(self.handle(), buf.as_ptr() as libc::LPVOID,
@@ -47,7 +50,7 @@ impl FileDesc {
                            ptr::null_mut())
         };
         if ret != 0 {
-            Ok(read as uint)
+            Ok(read as usize)
         } else {
             Err(super::last_error())
         }
@@ -64,8 +67,8 @@ impl FileDesc {
                                 ptr::null_mut())
             };
             if ret != 0 {
-                remaining -= amt as uint;
-                cur = unsafe { cur.offset(amt as int) };
+                remaining -= amt as usize;
+                cur = unsafe { cur.offset(amt as isize) };
             } else {
                 return Err(super::last_error())
             }
@@ -133,7 +136,7 @@ impl FileDesc {
         }
     }
 
-    /// Extract the actual filedescriptor without closing it.
+    #[allow(dead_code)]
     pub fn unwrap(self) -> fd_t {
         let fd = self.fd;
         unsafe { mem::forget(self) };
@@ -231,7 +234,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
     }
 }
 
-pub fn mkdir(p: &Path, _mode: uint) -> IoResult<()> {
+pub fn mkdir(p: &Path, _mode: usize) -> IoResult<()> {
     let p = try!(to_utf16(p));
     super::mkerr_winbool(unsafe {
         // FIXME: turn mode into something useful? #2623
@@ -305,11 +308,11 @@ pub fn unlink(p: &Path) -> IoResult<()> {
                 };
                 if stat.perm.intersects(old_io::USER_WRITE) { return Err(e) }
 
-                match chmod(p, (stat.perm | old_io::USER_WRITE).bits() as uint) {
+                match chmod(p, (stat.perm | old_io::USER_WRITE).bits() as usize) {
                     Ok(()) => do_unlink(&p_utf16),
                     Err(..) => {
                         // Try to put it back as we found it
-                        let _ = chmod(p, stat.perm.bits() as uint);
+                        let _ = chmod(p, stat.perm.bits() as usize);
                         Err(e)
                     }
                 }
@@ -328,7 +331,7 @@ pub fn rename(old: &Path, new: &Path) -> IoResult<()> {
     })
 }
 
-pub fn chmod(p: &Path, mode: uint) -> IoResult<()> {
+pub fn chmod(p: &Path, mode: usize) -> IoResult<()> {
     let p = try!(to_utf16(p));
     mkerr_libc(unsafe {
         libc::wchmod(p.as_ptr(), mode as libc::c_int)
@@ -340,7 +343,7 @@ pub fn rmdir(p: &Path) -> IoResult<()> {
     super::mkerr_winbool(unsafe { libc::RemoveDirectoryW(p.as_ptr()) })
 }
 
-pub fn chown(_p: &Path, _uid: int, _gid: int) -> IoResult<()> {
+pub fn chown(_p: &Path, _uid: isize, _gid: isize) -> IoResult<()> {
     // libuv has this as a no-op, so seems like this should as well?
     Ok(())
 }
@@ -368,7 +371,9 @@ pub fn readlink(p: &Path) -> IoResult<Path> {
                                   buf as *const u16,
                                   sz - 1,
                                   libc::VOLUME_NAME_DOS)
-    }, super::os2path);
+    }, |data| {
+        Path::new(String::from_utf16(data).unwrap())
+    });
     assert!(unsafe { libc::CloseHandle(handle) } != 0);
     return ret;
 }
@@ -432,7 +437,7 @@ pub fn stat(p: &Path) -> IoResult<FileStat> {
 // FIXME: move this to platform-specific modules (for now)?
 pub fn lstat(_p: &Path) -> IoResult<FileStat> {
     // FIXME: implementation is missing
-    Err(super::unimpl())
+    Err(sys_common::unimpl())
 }
 
 pub fn utime(p: &Path, atime: u64, mtime: u64) -> IoResult<()> {
index 8abcd90efe8578a6cab8523babf818b1a12e8b44..d03e45649ed05e3a8a3daec584b453eb32fbc4da 100644 (file)
@@ -19,20 +19,30 @@ use libc::{self, HANDLE};
 use mem;
 use path::{Path, PathBuf};
 use ptr;
-use sys::handle::Handle as RawHandle;
+use sync::Arc;
+use sys::handle::Handle;
 use sys::{c, cvt};
+use sys_common::FromInner;
 use vec::Vec;
 
-pub struct File { handle: RawHandle }
+pub struct File { handle: Handle }
 pub struct FileAttr { data: c::WIN32_FILE_ATTRIBUTE_DATA }
 
 pub struct ReadDir {
-    handle: libc::HANDLE,
-    root: PathBuf,
+    handle: FindNextFileHandle,
+    root: Arc<PathBuf>,
     first: Option<libc::WIN32_FIND_DATAW>,
 }
 
-pub struct DirEntry { path: PathBuf }
+struct FindNextFileHandle(libc::HANDLE);
+
+unsafe impl Send for FindNextFileHandle {}
+unsafe impl Sync for FindNextFileHandle {}
+
+pub struct DirEntry {
+    root: Arc<PathBuf>,
+    data: libc::WIN32_FIND_DATAW,
+}
 
 #[derive(Clone, Default)]
 pub struct OpenOptions {
@@ -61,7 +71,7 @@ impl Iterator for ReadDir {
         unsafe {
             let mut wfd = mem::zeroed();
             loop {
-                if libc::FindNextFileW(self.handle, &mut wfd) == 0 {
+                if libc::FindNextFileW(self.handle.0, &mut wfd) == 0 {
                     if libc::GetLastError() ==
                         c::ERROR_NO_MORE_FILES as libc::DWORD {
                         return None
@@ -77,15 +87,15 @@ impl Iterator for ReadDir {
     }
 }
 
-impl Drop for ReadDir {
+impl Drop for FindNextFileHandle {
     fn drop(&mut self) {
-        let r = unsafe { libc::FindClose(self.handle) };
+        let r = unsafe { libc::FindClose(self.0) };
         debug_assert!(r != 0);
     }
 }
 
 impl DirEntry {
-    fn new(root: &Path, wfd: &libc::WIN32_FIND_DATAW) -> Option<DirEntry> {
+    fn new(root: &Arc<PathBuf>, wfd: &libc::WIN32_FIND_DATAW) -> Option<DirEntry> {
         match &wfd.cFileName[0..3] {
             // check for '.' and '..'
             [46, 0, ..] |
@@ -93,13 +103,15 @@ impl DirEntry {
             _ => {}
         }
 
-        let filename = super::truncate_utf16_at_nul(&wfd.cFileName);
-        let filename: OsString = OsStringExt::from_wide(filename);
-        Some(DirEntry { path: root.join(&filename) })
+        Some(DirEntry {
+            root: root.clone(),
+            data: *wfd,
+        })
     }
 
     pub fn path(&self) -> PathBuf {
-        self.path.clone()
+        let filename = super::truncate_utf16_at_nul(&self.data.cFileName);
+        self.root.join(&<OsString as OsStringExt>::from_wide(filename))
     }
 }
 
@@ -181,7 +193,7 @@ impl File {
         if handle == libc::INVALID_HANDLE_VALUE {
             Err(Error::last_os_error())
         } else {
-            Ok(File { handle: RawHandle::new(handle) })
+            Ok(File { handle: Handle::new(handle) })
         }
     }
 
@@ -249,7 +261,13 @@ impl File {
         Ok(newpos as u64)
     }
 
-    pub fn handle(&self) -> &RawHandle { &self.handle }
+    pub fn handle(&self) -> &Handle { &self.handle }
+}
+
+impl FromInner<libc::HANDLE> for File {
+    fn from_inner(handle: libc::HANDLE) -> File {
+        File { handle: Handle::new(handle) }
+    }
 }
 
 pub fn to_utf16(s: &Path) -> Vec<u16> {
@@ -312,7 +330,11 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
         let mut wfd = mem::zeroed();
         let find_handle = libc::FindFirstFileW(path.as_ptr(), &mut wfd);
         if find_handle != libc::INVALID_HANDLE_VALUE {
-            Ok(ReadDir { handle: find_handle, root: root, first: Some(wfd) })
+            Ok(ReadDir {
+                handle: FindNextFileHandle(find_handle),
+                root: Arc::new(root),
+                first: Some(wfd),
+            })
         } else {
             Err(Error::last_os_error())
         }
@@ -357,7 +379,7 @@ pub fn readlink(p: &Path) -> io::Result<PathBuf> {
                                   sz - 1,
                                   libc::VOLUME_NAME_DOS)
     }, |s| OsStringExt::from_wide(s)));
-    Ok(PathBuf::new(&ret))
+    Ok(PathBuf::from(&ret))
 }
 
 pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
index 99de659be41edf7986b81236f3cea90305bb9fc3..0089dcad455df2f731608871524b6edf803f329a 100644 (file)
 
 use prelude::v1::*;
 
-use libc::{self, HANDLE};
-use io;
 use io::ErrorKind;
+use io;
+use libc::{self, HANDLE};
+use mem;
 use ptr;
 use sys::cvt;
 
@@ -28,6 +29,12 @@ impl Handle {
 
     pub fn raw(&self) -> HANDLE { self.0 }
 
+    pub fn into_raw(self) -> HANDLE {
+        let ret = self.0;
+        unsafe { mem::forget(self) }
+        return ret;
+    }
+
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
         read(self.0, buf)
     }
index a756fb29f81aeb5f32c4d446efb633cf6220b2b9..e9d5fca531fdb8b7ecd5fd3f8360b2d5059879c4 100644 (file)
 
 use prelude::v1::*;
 
-use ffi::OsStr;
+use ffi::{OsStr, OsString};
 use io::{self, ErrorKind};
 use libc;
 use mem;
-use old_io::{self, IoResult, IoError};
+#[allow(deprecated)]
 use num::Int;
-use os::windows::OsStrExt;
+use old_io::{self, IoResult, IoError};
+use os::windows::ffi::{OsStrExt, OsStringExt};
+use path::PathBuf;
 use sync::{Once, ONCE_INIT};
 
-macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
-    static $name: Helper<$m> = Helper {
-        lock: ::sync::MUTEX_INIT,
-        cond: ::sync::CONDVAR_INIT,
-        chan: ::cell::UnsafeCell { value: 0 as *mut ::sync::mpsc::Sender<$m> },
-        signal: ::cell::UnsafeCell { value: 0 },
-        initialized: ::cell::UnsafeCell { value: false },
-        shutdown: ::cell::UnsafeCell { value: false },
-    };
-) }
-
 pub mod backtrace;
 pub mod c;
 pub mod condvar;
@@ -60,6 +51,7 @@ pub mod time;
 pub mod timer;
 pub mod tty;
 pub mod udp;
+pub mod stdio;
 
 pub mod addrinfo {
     pub use sys_common::net::get_host_addresses;
@@ -73,6 +65,7 @@ pub type msglen_t = libc::c_int;
 pub unsafe fn close_sock(sock: sock_t) { let _ = libc::closesocket(sock); }
 
 // windows has zero values as errors
+#[allow(deprecated)]
 fn mkerr_winbool(ret: libc::c_int) -> IoResult<()> {
     if ret == 0 {
         Err(last_error())
@@ -81,6 +74,7 @@ fn mkerr_winbool(ret: libc::c_int) -> IoResult<()> {
     }
 }
 
+#[allow(deprecated)]
 pub fn last_error() -> IoError {
     let errno = os::errno() as i32;
     let mut err = decode_error(errno);
@@ -88,6 +82,7 @@ pub fn last_error() -> IoError {
     err
 }
 
+#[allow(deprecated)]
 pub fn last_net_error() -> IoError {
     let errno = unsafe { c::WSAGetLastError() as i32 };
     let mut err = decode_error(errno);
@@ -95,11 +90,13 @@ pub fn last_net_error() -> IoError {
     err
 }
 
+#[allow(deprecated)]
 pub fn last_gai_error(_errno: i32) -> IoError {
     last_net_error()
 }
 
 /// Convert an `errno` value into a high-level error variant and description.
+#[allow(deprecated)]
 pub fn decode_error(errno: i32) -> IoError {
     let (kind, desc) = match errno {
         libc::EOF => (old_io::EndOfFile, "end of file"),
@@ -143,6 +140,7 @@ pub fn decode_error(errno: i32) -> IoError {
     IoError { kind: kind, desc: desc, detail: None }
 }
 
+#[allow(deprecated)]
 pub fn decode_error_detailed(errno: i32) -> IoError {
     let mut err = decode_error(errno);
     err.detail = Some(os::error_string(errno));
@@ -152,25 +150,21 @@ pub fn decode_error_detailed(errno: i32) -> IoError {
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
     match errno as libc::c_int {
         libc::ERROR_ACCESS_DENIED => ErrorKind::PermissionDenied,
-        libc::ERROR_ALREADY_EXISTS => ErrorKind::PathAlreadyExists,
+        libc::ERROR_ALREADY_EXISTS => ErrorKind::AlreadyExists,
         libc::ERROR_BROKEN_PIPE => ErrorKind::BrokenPipe,
-        libc::ERROR_FILE_NOT_FOUND => ErrorKind::FileNotFound,
-        libc::ERROR_INVALID_FUNCTION => ErrorKind::InvalidInput,
-        libc::ERROR_INVALID_HANDLE => ErrorKind::MismatchedFileTypeForOperation,
-        libc::ERROR_INVALID_NAME => ErrorKind::InvalidInput,
-        libc::ERROR_NOTHING_TO_TERMINATE => ErrorKind::InvalidInput,
+        libc::ERROR_FILE_NOT_FOUND => ErrorKind::NotFound,
         libc::ERROR_NO_DATA => ErrorKind::BrokenPipe,
         libc::ERROR_OPERATION_ABORTED => ErrorKind::TimedOut,
 
         libc::WSAEACCES => ErrorKind::PermissionDenied,
-        libc::WSAEADDRINUSE => ErrorKind::ConnectionRefused,
-        libc::WSAEADDRNOTAVAIL => ErrorKind::ConnectionRefused,
+        libc::WSAEADDRINUSE => ErrorKind::AddrInUse,
+        libc::WSAEADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
         libc::WSAECONNABORTED => ErrorKind::ConnectionAborted,
         libc::WSAECONNREFUSED => ErrorKind::ConnectionRefused,
         libc::WSAECONNRESET => ErrorKind::ConnectionReset,
         libc::WSAEINVAL => ErrorKind::InvalidInput,
         libc::WSAENOTCONN => ErrorKind::NotConnected,
-        libc::WSAEWOULDBLOCK => ErrorKind::ResourceUnavailable,
+        libc::WSAEWOULDBLOCK => ErrorKind::WouldBlock,
 
         _ => ErrorKind::Other,
     }
@@ -187,17 +181,19 @@ pub fn ms_to_timeval(ms: u64) -> libc::timeval {
     }
 }
 
+#[allow(deprecated)]
 pub fn wouldblock() -> bool {
     let err = os::errno();
     err == libc::WSAEWOULDBLOCK as i32
 }
 
-pub fn set_nonblocking(fd: sock_t, nb: bool) -> IoResult<()> {
+#[allow(deprecated)]
+pub fn set_nonblocking(fd: sock_t, nb: bool) {
     let mut set = nb as libc::c_ulong;
-    if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) != 0 } {
-        Err(last_error())
-    } else {
-        Ok(())
+    if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) } != 0 {
+        // The above function should not return an error unless we passed it
+        // invalid parameters. Panic on errors.
+        panic!("set_nonblocking called with invalid parameters: {}", last_error());
     }
 }
 
@@ -214,15 +210,8 @@ pub fn init_net() {
     }
 }
 
-pub fn unimpl() -> IoError {
-    IoError {
-        kind: old_io::IoUnavailable,
-        desc: "operation is not implemented",
-        detail: None,
-    }
-}
-
-fn to_utf16(s: Option<&str>) -> IoResult<Vec<u16>> {
+#[allow(deprecated)]
+pub fn to_utf16(s: Option<&str>) -> IoResult<Vec<u16>> {
     match s {
         Some(s) => Ok(to_utf16_os(OsStr::from_str(s))),
         None => Err(IoError {
@@ -300,6 +289,7 @@ fn fill_utf16_buf_base<F1, F2, T>(mut f1: F1, f2: F2) -> Result<T, ()>
     }
 }
 
+#[allow(deprecated)]
 fn fill_utf16_buf<F1, F2, T>(f1: F1, f2: F2) -> IoResult<T>
     where F1: FnMut(*mut u16, libc::DWORD) -> libc::DWORD,
           F2: FnOnce(&[u16]) -> T
@@ -314,9 +304,8 @@ fn fill_utf16_buf_new<F1, F2, T>(f1: F1, f2: F2) -> io::Result<T>
     fill_utf16_buf_base(f1, f2).map_err(|()| io::Error::last_os_error())
 }
 
-fn os2path(s: &[u16]) -> Path {
-    // FIXME: this should not be a panicking conversion (aka path reform)
-    Path::new(String::from_utf16(s).unwrap())
+fn os2path(s: &[u16]) -> PathBuf {
+    PathBuf::from(OsString::from_wide(s))
 }
 
 pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
@@ -327,6 +316,7 @@ pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
     }
 }
 
+#[allow(deprecated)]
 fn cvt<I: Int>(i: I) -> io::Result<I> {
     if i == Int::zero() {
         Err(io::Error::last_os_error())
index 75495efc7cbb60f9d2a7f12ffa78980f2540ab39..0847f3b52bfabe171e370bed4e1b6a43cb75bfa5 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use marker::Sync;
+use prelude::v1::*;
+
 use cell::UnsafeCell;
 use sys::sync as ffi;
 
@@ -18,6 +19,7 @@ pub const MUTEX_INIT: Mutex = Mutex {
     inner: UnsafeCell { value: ffi::SRWLOCK_INIT }
 };
 
+unsafe impl Send for Mutex {}
 unsafe impl Sync for Mutex {}
 
 #[inline]
@@ -27,14 +29,15 @@ pub unsafe fn raw(m: &Mutex) -> ffi::PSRWLOCK {
 
 // So you might be asking why we're using SRWLock instead of CriticalSection?
 //
-// 1. SRWLock is several times faster than CriticalSection according to benchmarks performed on both
-// Windows 8 and Windows 7.
+// 1. SRWLock is several times faster than CriticalSection according to
+//    benchmarks performed on both Windows 8 and Windows 7.
 //
-// 2. CriticalSection allows recursive locking while SRWLock deadlocks. The Unix implementation
-// deadlocks so consistency is preferred. See #19962 for more details.
+// 2. CriticalSection allows recursive locking while SRWLock deadlocks. The Unix
+//    implementation deadlocks so consistency is preferred. See #19962 for more
+//    details.
 //
-// 3. While CriticalSection is fair and SRWLock is not, the current Rust policy is there there are
-// no guarantees of fairness.
+// 3. While CriticalSection is fair and SRWLock is not, the current Rust policy
+//    is there there are no guarantees of fairness.
 
 impl Mutex {
     #[inline]
index 3451232f40ab89acb88de0fa53ce591dc2739cbd..12a8ef99d764adc3a9d70b6eea9c66bb71787ca0 100644 (file)
@@ -14,17 +14,20 @@ use io;
 use libc::consts::os::extra::INVALID_SOCKET;
 use libc::{self, c_int, c_void};
 use mem;
-use net::{SocketAddr, IpAddr};
+use net::SocketAddr;
+#[allow(deprecated)]
 use num::{SignedInt, Int};
 use rt;
 use sync::{Once, ONCE_INIT};
 use sys::c;
-use sys_common::AsInner;
+use sys_common::{AsInner, FromInner};
 
 pub type wrlen_t = i32;
 
 pub struct Socket(libc::SOCKET);
 
+/// Checks whether the Windows socket interface has been started already, and
+/// if not, starts it.
 pub fn init() {
     static START: Once = ONCE_INIT;
 
@@ -34,14 +37,21 @@ pub fn init() {
                                 &mut data);
         assert_eq!(ret, 0);
 
-        rt::at_exit(|| { c::WSACleanup(); })
+        let _ = rt::at_exit(|| { c::WSACleanup(); });
     });
 }
 
+/// Returns the last error from the Windows socket interface.
 fn last_error() -> io::Error {
     io::Error::from_os_error(unsafe { c::WSAGetLastError() })
 }
 
+/// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
+/// and if so, returns the last error from the Windows socket interface. . This
+/// function must be called before another call to the socket API is made.
+///
+/// FIXME: generics needed?
+#[allow(deprecated)]
 pub fn cvt<T: SignedInt>(t: T) -> io::Result<T> {
     let one: T = Int::one();
     if t == -one {
@@ -51,20 +61,24 @@ pub fn cvt<T: SignedInt>(t: T) -> io::Result<T> {
     }
 }
 
+/// Provides the functionality of `cvt` for the return values of `getaddrinfo`
+/// and similar, meaning that they return an error if the return value is 0.
 pub fn cvt_gai(err: c_int) -> io::Result<()> {
     if err == 0 { return Ok(()) }
     cvt(err).map(|_| ())
 }
 
+/// Provides the functionality of `cvt` for a closure.
+#[allow(deprecated)]
 pub fn cvt_r<T: SignedInt, F>(mut f: F) -> io::Result<T> where F: FnMut() -> T {
     cvt(f())
 }
 
 impl Socket {
     pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
-        let fam = match addr.ip() {
-            IpAddr::V4(..) => libc::AF_INET,
-            IpAddr::V6(..) => libc::AF_INET6,
+        let fam = match *addr {
+            SocketAddr::V4(..) => libc::AF_INET,
+            SocketAddr::V6(..) => libc::AF_INET6,
         };
         match unsafe { libc::socket(fam, ty, 0) } {
             INVALID_SOCKET => Err(last_error()),
@@ -112,10 +126,14 @@ impl Socket {
 
 impl Drop for Socket {
     fn drop(&mut self) {
-        unsafe { let _ = libc::closesocket(self.0); }
+        let _ = unsafe { libc::closesocket(self.0) };
     }
 }
 
 impl AsInner<libc::SOCKET> for Socket {
     fn as_inner(&self) -> &libc::SOCKET { &self.0 }
 }
+
+impl FromInner<libc::SOCKET> for Socket {
+    fn from_inner(sock: libc::SOCKET) -> Socket { Socket(sock) }
+}
index 6520d30487c76d978e6d5441370214c0332402c3..d5843a2f9987b153b67543303530eb44dc9af436 100644 (file)
 #![allow(bad_style)]
 
 use prelude::v1::*;
-use os::windows::*;
+use os::windows::prelude::*;
 
 use error::Error as StdError;
-use ffi::{OsString, OsStr, AsOsStr};
+use ffi::{OsString, OsStr};
 use fmt;
-use ops::Range;
+use io;
 use libc::types::os::arch::extra::LPWCH;
 use libc::{self, c_int, c_void};
 use mem;
+#[allow(deprecated)]
 use old_io::{IoError, IoResult};
+use ops::Range;
+use os::windows::ffi::EncodeWide;
+use path::{self, PathBuf};
 use ptr;
 use slice;
 use sys::c;
 use sys::fs::FileDesc;
-use sys::handle::Handle as RawHandle;
+use sys::handle::Handle;
 
 use libc::funcs::extra::kernel32::{
     GetEnvironmentStringsW,
@@ -57,8 +61,8 @@ pub fn error_string(errnum: i32) -> String {
                           -> DWORD;
     }
 
-    static FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
-    static FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
+    const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
+    const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
 
     // This value is calculated from the macro
     // MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
@@ -105,7 +109,7 @@ impl Iterator for Env {
             if *self.cur == 0 { return None }
             let p = &*self.cur;
             let mut len = 0;
-            while *(p as *const _).offset(len) != 0 {
+            while *(p as *const u16).offset(len) != 0 {
                 len += 1;
             }
             let p = p as *const u16;
@@ -132,7 +136,7 @@ pub fn env() -> Env {
         let ch = GetEnvironmentStringsW();
         if ch as usize == 0 {
             panic!("failure getting env string from OS: {}",
-                   IoError::last_error());
+                   io::Error::last_os_error());
         }
         Env { base: ch, cur: ch }
     }
@@ -151,8 +155,8 @@ pub fn split_paths(unparsed: &OsStr) -> SplitPaths {
 }
 
 impl<'a> Iterator for SplitPaths<'a> {
-    type Item = Path;
-    fn next(&mut self) -> Option<Path> {
+    type Item = PathBuf;
+    fn next(&mut self) -> Option<PathBuf> {
         // On Windows, the PATH environment variable is semicolon separated.
         // Double quotes are used as a way of introducing literal semicolons
         // (since c:\some;dir is a valid Windows path). Double quotes are not
@@ -186,7 +190,7 @@ impl<'a> Iterator for SplitPaths<'a> {
         if !must_yield && in_progress.is_empty() {
             None
         } else {
-            Some(super::os2path(&in_progress[..]))
+            Some(super::os2path(&in_progress))
         }
     }
 }
@@ -195,13 +199,13 @@ impl<'a> Iterator for SplitPaths<'a> {
 pub struct JoinPathsError;
 
 pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
-    where I: Iterator<Item=T>, T: AsOsStr
+    where I: Iterator<Item=T>, T: AsRef<OsStr>
 {
     let mut joined = Vec::new();
     let sep = b';' as u16;
 
     for (i, path) in paths.enumerate() {
-        let path = path.as_os_str();
+        let path = path.as_ref();
         if i > 0 { joined.push(sep) }
         let v = path.encode_wide().collect::<Vec<u16>>();
         if v.contains(&(b'"' as u16)) {
@@ -228,33 +232,34 @@ impl StdError for JoinPathsError {
     fn description(&self) -> &str { "failed to join paths" }
 }
 
-pub fn current_exe() -> IoResult<Path> {
-    super::fill_utf16_buf(|buf, sz| unsafe {
+pub fn current_exe() -> io::Result<PathBuf> {
+    super::fill_utf16_buf_new(|buf, sz| unsafe {
         libc::GetModuleFileNameW(ptr::null_mut(), buf, sz)
     }, super::os2path)
 }
 
-pub fn getcwd() -> IoResult<Path> {
-    super::fill_utf16_buf(|buf, sz| unsafe {
+pub fn getcwd() -> io::Result<PathBuf> {
+    super::fill_utf16_buf_new(|buf, sz| unsafe {
         libc::GetCurrentDirectoryW(sz, buf)
     }, super::os2path)
 }
 
-pub fn chdir(p: &Path) -> IoResult<()> {
-    let mut p = p.as_os_str().encode_wide().collect::<Vec<_>>();
+pub fn chdir(p: &path::Path) -> io::Result<()> {
+    let p: &OsStr = p.as_ref();
+    let mut p = p.encode_wide().collect::<Vec<_>>();
     p.push(0);
 
     unsafe {
         match libc::SetCurrentDirectoryW(p.as_ptr()) != (0 as libc::BOOL) {
             true => Ok(()),
-            false => Err(IoError::last_error()),
+            false => Err(io::Error::last_os_error()),
         }
     }
 }
 
 pub fn getenv(k: &OsStr) -> Option<OsString> {
     let k = super::to_utf16_os(k);
-    super::fill_utf16_buf(|buf, sz| unsafe {
+    super::fill_utf16_buf_new(|buf, sz| unsafe {
         libc::GetEnvironmentVariableW(k.as_ptr(), buf, sz)
     }, |buf| {
         OsStringExt::from_wide(buf)
@@ -267,7 +272,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) {
 
     unsafe {
         if libc::SetEnvironmentVariableW(k.as_ptr(), v.as_ptr()) == 0 {
-            panic!("failed to set env: {}", IoError::last_error());
+            panic!("failed to set env: {}", io::Error::last_os_error());
         }
     }
 }
@@ -276,7 +281,7 @@ pub fn unsetenv(n: &OsStr) {
     let v = super::to_utf16_os(n);
     unsafe {
         if libc::SetEnvironmentVariableW(v.as_ptr(), ptr::null()) == 0 {
-            panic!("failed to unset env: {}", IoError::last_error());
+            panic!("failed to unset env: {}", io::Error::last_os_error());
         }
     }
 }
@@ -331,6 +336,7 @@ pub fn page_size() -> usize {
     }
 }
 
+#[allow(deprecated)]
 pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> {
     // Windows pipes work subtly differently than unix pipes, and their
     // inheritance has to be handled in a different way that I do not
@@ -349,26 +355,23 @@ pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> {
     }
 }
 
-pub fn temp_dir() -> Path {
-    super::fill_utf16_buf(|buf, sz| unsafe {
+pub fn temp_dir() -> PathBuf {
+    super::fill_utf16_buf_new(|buf, sz| unsafe {
         c::GetTempPathW(sz, buf)
     }, super::os2path).unwrap()
 }
 
-pub fn home_dir() -> Option<Path> {
-    getenv("HOME".as_os_str()).or_else(|| {
-        getenv("USERPROFILE".as_os_str())
-    }).map(|os| {
-        // FIXME: OsString => Path
-        Path::new(os.to_str().unwrap())
-    }).or_else(|| unsafe {
+pub fn home_dir() -> Option<PathBuf> {
+    getenv("HOME".as_ref()).or_else(|| {
+        getenv("USERPROFILE".as_ref())
+    }).map(PathBuf::from).or_else(|| unsafe {
         let me = c::GetCurrentProcess();
         let mut token = ptr::null_mut();
         if c::OpenProcessToken(me, c::TOKEN_READ, &mut token) == 0 {
             return None
         }
-        let _handle = RawHandle::new(token);
-        super::fill_utf16_buf(|buf, mut sz| {
+        let _handle = Handle::new(token);
+        super::fill_utf16_buf_new(|buf, mut sz| {
             match c::GetUserProfileDirectoryW(token, buf, &mut sz) {
                 0 if libc::GetLastError() != 0 => 0,
                 0 => sz,
@@ -377,3 +380,7 @@ pub fn home_dir() -> Option<Path> {
         }, super::os2path).ok()
     })
 }
+
+pub fn exit(code: i32) -> ! {
+    unsafe { c::ExitProcess(code as libc::c_uint) }
+}
index af94b56bf1f71aaf39433a4072093ca4ee64475e..91905ae7489d528b100b874e19183cedaeca9e4c 100644 (file)
 /// The underlying OsString/OsStr implementation on Windows is a
 /// wrapper around the "WTF-8" encoding; see the `wtf8` module for more.
 
+use borrow::Cow;
 use fmt::{self, Debug};
 use sys_common::wtf8::{Wtf8, Wtf8Buf};
-use string::{String, CowString};
+use string::String;
 use result::Result;
 use option::Option;
 use mem;
@@ -44,10 +45,6 @@ impl Buf {
         Buf { inner: Wtf8Buf::from_string(s) }
     }
 
-    pub fn from_str(s: &str) -> Buf {
-        Buf { inner: Wtf8Buf::from_str(s) }
-    }
-
     pub fn as_slice(&self) -> &Slice {
         unsafe { mem::transmute(self.inner.as_slice()) }
     }
@@ -70,7 +67,7 @@ impl Slice {
         self.inner.as_str()
     }
 
-    pub fn to_string_lossy(&self) -> CowString {
+    pub fn to_string_lossy(&self) -> Cow<str> {
         self.inner.to_string_lossy()
     }
 
index 1f228b7d32e35042131cefcbce51e8fab742409a..064c003bd15a909b90392f5ce531e5330a6085d7 100644 (file)
@@ -84,6 +84,8 @@
 //! the test suite passing (the suite is in libstd), and that's good enough for
 //! me!
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 
 use libc;
@@ -113,7 +115,7 @@ impl Event {
                                initial_state as libc::BOOL,
                                ptr::null())
         };
-        if event as uint == 0 {
+        if event as usize == 0 {
             Err(super::last_error())
         } else {
             Ok(Event(event))
@@ -179,7 +181,7 @@ unsafe fn pipe(name: *const u16, init: bool) -> libc::HANDLE {
 }
 
 pub fn await(handle: libc::HANDLE, deadline: u64,
-             events: &[libc::HANDLE]) -> IoResult<uint> {
+             events: &[libc::HANDLE]) -> IoResult<usize> {
     use libc::consts::os::extra::{WAIT_FAILED, WAIT_TIMEOUT, WAIT_OBJECT_0};
 
     // If we've got a timeout, use WaitForSingleObject in tandem with CancelIo
@@ -202,7 +204,7 @@ pub fn await(handle: libc::HANDLE, deadline: u64,
             let _ = c::CancelIo(handle);
             Err(sys_common::timeout("operation timed out"))
         },
-        n => Ok((n - WAIT_OBJECT_0) as uint)
+        n => Ok((n - WAIT_OBJECT_0) as usize)
     }
 }
 
@@ -312,7 +314,7 @@ impl UnixStream {
             // `WaitNamedPipe` function, and this is indicated with an error
             // code of ERROR_PIPE_BUSY.
             let code = unsafe { libc::GetLastError() };
-            if code as int != libc::ERROR_PIPE_BUSY as int {
+            if code as isize != libc::ERROR_PIPE_BUSY as isize {
                 return Err(super::last_error())
             }
 
@@ -360,7 +362,7 @@ impl UnixStream {
         }
     }
 
-    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         if self.read.is_none() {
             self.read = Some(try!(Event::new(true, false)));
         }
@@ -388,7 +390,7 @@ impl UnixStream {
                            &mut bytes_read,
                            &mut overlapped)
         };
-        if ret != 0 { return Ok(bytes_read as uint) }
+        if ret != 0 { return Ok(bytes_read as usize) }
 
         // If our errno doesn't say that the I/O is pending, then we hit some
         // legitimate error and return immediately.
@@ -416,7 +418,7 @@ impl UnixStream {
             };
             // If we succeeded, or we failed for some reason other than
             // CancelIoEx, return immediately
-            if ret != 0 { return Ok(bytes_read as uint) }
+            if ret != 0 { return Ok(bytes_read as usize) }
             if os::errno() != libc::ERROR_OPERATION_ABORTED as i32 {
                 return Err(super::last_error())
             }
@@ -485,7 +487,7 @@ impl UnixStream {
                         return Err(super::last_error())
                     }
                     if !wait_succeeded.is_ok() {
-                        let amt = offset + bytes_written as uint;
+                        let amt = offset + bytes_written as usize;
                         return if amt > 0 {
                             Err(IoError {
                                 kind: old_io::ShortWrite(amt),
@@ -502,7 +504,7 @@ impl UnixStream {
                     continue // retry
                 }
             }
-            offset += bytes_written as uint;
+            offset += bytes_written as usize;
         }
         Ok(())
     }
@@ -755,10 +757,10 @@ impl UnixAcceptor {
 
 impl Clone for UnixAcceptor {
     fn clone(&self) -> UnixAcceptor {
-        let name = to_utf16(&self.listener.name).ok().unwrap();
+        let name = to_utf16(&self.listener.name).unwrap();
         UnixAcceptor {
             inner: self.inner.clone(),
-            event: Event::new(true, false).ok().unwrap(),
+            event: Event::new(true, false).unwrap(),
             deadline: 0,
             listener: UnixListener {
                 name: self.listener.name.clone(),
index 60d24e6174fd757a5cd949443ebc803ae1a6b61e..b10042090ddc8d634a89d875cb10334ea07cf52e 100644 (file)
@@ -8,9 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(deprecated)] // this module itself is essentially deprecated
+
 use prelude::v1::*;
 
-#[cfg(stage0)] use collections::hash_map::Hasher;
 use collections;
 use env;
 use ffi::CString;
@@ -18,17 +19,16 @@ use hash::Hash;
 use libc::{pid_t, c_void};
 use libc;
 use mem;
-use old_io::fs::PathExtensions;
+#[allow(deprecated)] use old_io::fs::PathExtensions;
 use old_io::process::{ProcessExit, ExitStatus};
 use old_io::{IoResult, IoError};
 use old_io;
-use os;
-use old_path::BytesContainer;
+use fs::PathExt;
+use old_path::{BytesContainer, GenericPath};
 use ptr;
 use str;
 use sync::{StaticMutex, MUTEX_INIT};
 use sys::fs::FileDesc;
-
 use sys::timer;
 use sys_common::{AsInner, timeout};
 
@@ -63,11 +63,11 @@ impl Process {
         self.pid
     }
 
-    pub unsafe fn kill(&self, signal: int) -> IoResult<()> {
+    pub unsafe fn kill(&self, signal: isize) -> IoResult<()> {
         Process::killpid(self.pid, signal)
     }
 
-    pub unsafe fn killpid(pid: pid_t, signal: int) -> IoResult<()> {
+    pub unsafe fn killpid(pid: pid_t, signal: isize) -> IoResult<()> {
         let handle = libc::OpenProcess(libc::PROCESS_TERMINATE |
                                        libc::PROCESS_QUERY_INFORMATION,
                                        libc::FALSE, pid as libc::DWORD);
@@ -106,170 +106,6 @@ impl Process {
     }
 
     #[allow(deprecated)]
-    #[cfg(stage0)]
-    pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
-                              out_fd: Option<P>, err_fd: Option<P>)
-                              -> IoResult<Process>
-        where C: ProcessConfig<K, V>, P: AsInner<FileDesc>,
-              K: BytesContainer + Eq + Hash<Hasher>, V: BytesContainer
-    {
-        use libc::types::os::arch::extra::{DWORD, HANDLE, STARTUPINFO};
-        use libc::consts::os::extra::{
-            TRUE, FALSE,
-            STARTF_USESTDHANDLES,
-            INVALID_HANDLE_VALUE,
-            DUPLICATE_SAME_ACCESS
-        };
-        use libc::funcs::extra::kernel32::{
-            GetCurrentProcess,
-            DuplicateHandle,
-            CloseHandle,
-            CreateProcessW
-        };
-        use libc::funcs::extra::msvcrt::get_osfhandle;
-
-        use mem;
-        use iter::IteratorExt;
-        use str::StrExt;
-
-        if cfg.gid().is_some() || cfg.uid().is_some() {
-            return Err(IoError {
-                kind: old_io::IoUnavailable,
-                desc: "unsupported gid/uid requested on windows",
-                detail: None,
-            })
-        }
-
-        // To have the spawning semantics of unix/windows stay the same, we need to
-        // read the *child's* PATH if one is provided. See #15149 for more details.
-        let program = cfg.env().and_then(|env| {
-            for (key, v) in env {
-                if b"PATH" != key.container_as_bytes() { continue }
-
-                // Split the value and test each path to see if the
-                // program exists.
-                for path in os::split_paths(v.container_as_bytes()) {
-                    let path = path.join(cfg.program().as_bytes())
-                                   .with_extension(env::consts::EXE_EXTENSION);
-                    if path.exists() {
-                        return Some(CString::from_slice(path.as_vec()))
-                    }
-                }
-                break
-            }
-            None
-        });
-
-        unsafe {
-            let mut si = zeroed_startupinfo();
-            si.cb = mem::size_of::<STARTUPINFO>() as DWORD;
-            si.dwFlags = STARTF_USESTDHANDLES;
-
-            let cur_proc = GetCurrentProcess();
-
-            // Similarly to unix, we don't actually leave holes for the stdio file
-            // descriptors, but rather open up /dev/null equivalents. These
-            // equivalents are drawn from libuv's windows process spawning.
-            let set_fd = |fd: &Option<P>, slot: &mut HANDLE,
-                          is_stdin: bool| {
-                match *fd {
-                    None => {
-                        let access = if is_stdin {
-                            libc::FILE_GENERIC_READ
-                        } else {
-                            libc::FILE_GENERIC_WRITE | libc::FILE_READ_ATTRIBUTES
-                        };
-                        let size = mem::size_of::<libc::SECURITY_ATTRIBUTES>();
-                        let mut sa = libc::SECURITY_ATTRIBUTES {
-                            nLength: size as libc::DWORD,
-                            lpSecurityDescriptor: ptr::null_mut(),
-                            bInheritHandle: 1,
-                        };
-                        let mut filename: Vec<u16> = "NUL".utf16_units().collect();
-                        filename.push(0);
-                        *slot = libc::CreateFileW(filename.as_ptr(),
-                                                  access,
-                                                  libc::FILE_SHARE_READ |
-                                                      libc::FILE_SHARE_WRITE,
-                                                  &mut sa,
-                                                  libc::OPEN_EXISTING,
-                                                  0,
-                                                  ptr::null_mut());
-                        if *slot == INVALID_HANDLE_VALUE {
-                            return Err(super::last_error())
-                        }
-                    }
-                    Some(ref fd) => {
-                        let orig = get_osfhandle(fd.as_inner().fd()) as HANDLE;
-                        if orig == INVALID_HANDLE_VALUE {
-                            return Err(super::last_error())
-                        }
-                        if DuplicateHandle(cur_proc, orig, cur_proc, slot,
-                                           0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE {
-                            return Err(super::last_error())
-                        }
-                    }
-                }
-                Ok(())
-            };
-
-            try!(set_fd(&in_fd, &mut si.hStdInput, true));
-            try!(set_fd(&out_fd, &mut si.hStdOutput, false));
-            try!(set_fd(&err_fd, &mut si.hStdError, false));
-
-            let cmd_str = make_command_line(program.as_ref().unwrap_or(cfg.program()),
-                                            cfg.args());
-            let mut pi = zeroed_process_information();
-            let mut create_err = None;
-
-            // stolen from the libuv code.
-            let mut flags = libc::CREATE_UNICODE_ENVIRONMENT;
-            if cfg.detach() {
-                flags |= libc::DETACHED_PROCESS | libc::CREATE_NEW_PROCESS_GROUP;
-            }
-
-            with_envp(cfg.env(), |envp| {
-                with_dirp(cfg.cwd(), |dirp| {
-                    let mut cmd_str: Vec<u16> = cmd_str.utf16_units().collect();
-                    cmd_str.push(0);
-                    let _lock = CREATE_PROCESS_LOCK.lock().unwrap();
-                    let created = CreateProcessW(ptr::null(),
-                                                 cmd_str.as_mut_ptr(),
-                                                 ptr::null_mut(),
-                                                 ptr::null_mut(),
-                                                 TRUE,
-                                                 flags, envp, dirp,
-                                                 &mut si, &mut pi);
-                    if created == FALSE {
-                        create_err = Some(super::last_error());
-                    }
-                })
-            });
-
-            assert!(CloseHandle(si.hStdInput) != 0);
-            assert!(CloseHandle(si.hStdOutput) != 0);
-            assert!(CloseHandle(si.hStdError) != 0);
-
-            match create_err {
-                Some(err) => return Err(err),
-                None => {}
-            }
-
-            // We close the thread handle because we don't care about keeping the
-            // thread id valid, and we aren't keeping the thread handle around to be
-            // able to close it later. We don't close the process handle however
-            // because std::we want the process id to stay valid at least until the
-            // calling code closes the process handle.
-            assert!(CloseHandle(pi.hThread) != 0);
-
-            Ok(Process {
-                pid: pi.dwProcessId as pid_t,
-                handle: pi.hProcess as *mut ()
-            })
-        }
-    }
-    #[allow(deprecated)]
-    #[cfg(not(stage0))]
     pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
                               out_fd: Option<P>, err_fd: Option<P>)
                               -> IoResult<Process>
@@ -292,8 +128,6 @@ impl Process {
         use libc::funcs::extra::msvcrt::get_osfhandle;
 
         use mem;
-        use iter::IteratorExt;
-        use str::StrExt;
 
         if cfg.gid().is_some() || cfg.uid().is_some() {
             return Err(IoError {
@@ -308,14 +142,19 @@ impl Process {
         let program = cfg.env().and_then(|env| {
             for (key, v) in env {
                 if b"PATH" != key.container_as_bytes() { continue }
+                let v = match ::str::from_utf8(v.container_as_bytes()) {
+                    Ok(s) => s,
+                    Err(..) => continue,
+                };
 
                 // Split the value and test each path to see if the
                 // program exists.
-                for path in os::split_paths(v.container_as_bytes()) {
-                    let path = path.join(cfg.program().as_bytes())
+                for path in ::env::split_paths(v) {
+                    let program = str::from_utf8(cfg.program().as_bytes()).unwrap();
+                    let path = path.join(program)
                                    .with_extension(env::consts::EXE_EXTENSION);
                     if path.exists() {
-                        return Some(CString::from_slice(path.as_vec()))
+                        return Some(CString::new(path.to_str().unwrap()).unwrap())
                     }
                 }
                 break
@@ -475,7 +314,7 @@ impl Process {
                 }
                 if status != STILL_ACTIVE {
                     assert!(CloseHandle(process) != 0);
-                    return Ok(ExitStatus(status as int));
+                    return Ok(ExitStatus(status as isize));
                 }
                 let interval = if deadline == 0 {
                     INFINITE
@@ -560,7 +399,7 @@ fn make_command_line(prog: &CString, args: &[CString]) -> String {
         }
     }
 
-    fn append_char_at(cmd: &mut String, arg: &[char], i: uint) {
+    fn append_char_at(cmd: &mut String, arg: &[char], i: usize) {
         match arg[i] {
             '"' => {
                 // Escape quotes.
@@ -581,7 +420,7 @@ fn make_command_line(prog: &CString, args: &[CString]) -> String {
         }
     }
 
-    fn backslash_run_ends_in_quote(s: &[char], mut i: uint) -> bool {
+    fn backslash_run_ends_in_quote(s: &[char], mut i: usize) -> bool {
         while i < s.len() && s[i] == '\\' {
             i += 1;
         }
@@ -589,35 +428,6 @@ fn make_command_line(prog: &CString, args: &[CString]) -> String {
     }
 }
 
-#[cfg(stage0)]
-fn with_envp<K, V, T, F>(env: Option<&collections::HashMap<K, V>>, cb: F) -> T
-    where K: BytesContainer + Eq + Hash<Hasher>,
-          V: BytesContainer,
-          F: FnOnce(*mut c_void) -> T,
-{
-    // On Windows we pass an "environment block" which is not a char**, but
-    // rather a concatenation of null-terminated k=v\0 sequences, with a final
-    // \0 to terminate.
-    match env {
-        Some(env) => {
-            let mut blk = Vec::new();
-
-            for pair in env {
-                let kv = format!("{}={}",
-                                 pair.0.container_as_str().unwrap(),
-                                 pair.1.container_as_str().unwrap());
-                blk.extend(kv.utf16_units());
-                blk.push(0);
-            }
-
-            blk.push(0);
-
-            cb(blk.as_mut_ptr() as *mut c_void)
-        }
-        _ => cb(ptr::null_mut())
-    }
-}
-#[cfg(not(stage0))]
 fn with_envp<K, V, T, F>(env: Option<&collections::HashMap<K, V>>, cb: F) -> T
     where K: BytesContainer + Eq + Hash,
           V: BytesContainer,
@@ -677,9 +487,9 @@ mod tests {
     #[test]
     fn test_make_command_line() {
         fn test_wrapper(prog: &str, args: &[&str]) -> String {
-            make_command_line(&CString::from_slice(prog.as_bytes()),
+            make_command_line(&CString::new(prog).unwrap(),
                               &args.iter()
-                                   .map(|a| CString::from_slice(a.as_bytes()))
+                                   .map(|a| CString::new(*a).unwrap())
                                    .collect::<Vec<CString>>())
         }
 
index 19e38196d199fc360f20c199dd5047ed9cf5d939..7e832b6384dee46ce09686ccd483c7c4008928b3 100644 (file)
@@ -16,16 +16,15 @@ use collections;
 use env;
 use ffi::{OsString, OsStr};
 use fmt;
+use fs;
 use io::{self, Error};
 use libc::{self, c_void};
-use old_io::fs;
-use old_path;
-use os::windows::OsStrExt;
+use os::windows::ffi::OsStrExt;
 use ptr;
 use sync::{StaticMutex, MUTEX_INIT};
+use sys::handle::Handle;
 use sys::pipe2::AnonPipe;
 use sys::{self, cvt};
-use sys::handle::Handle;
 use sys_common::{AsInner, FromInner};
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -128,8 +127,7 @@ impl Process {
 
         use env::split_paths;
         use mem;
-        use iter::IteratorExt;
-        use str::StrExt;
+        use iter::Iterator;
 
         // To have the spawning semantics of unix/windows stay the same, we need to
         // read the *child's* PATH if one is provided. See #15149 for more details.
@@ -142,9 +140,8 @@ impl Process {
                 for path in split_paths(&v) {
                     let path = path.join(cfg.program.to_str().unwrap())
                                    .with_extension(env::consts::EXE_EXTENSION);
-                    // FIXME: update with new fs module once it lands
-                    if fs::stat(&old_path::Path::new(&path)).is_ok() {
-                        return Some(OsString::from_str(path.as_str().unwrap()))
+                    if fs::metadata(&path).is_ok() {
+                        return Some(path.into_os_string())
                     }
                 }
                 break
@@ -162,7 +159,7 @@ impl Process {
             // Similarly to unix, we don't actually leave holes for the stdio file
             // descriptors, but rather open up /dev/null equivalents. These
             // equivalents are drawn from libuv's windows process spawning.
-            let set_fd = |&: fd: &Option<AnonPipe>, slot: &mut HANDLE,
+            let set_fd = |fd: &Option<AnonPipe>, slot: &mut HANDLE,
                           is_stdin: bool| {
                 match *fd {
                     None => {
@@ -448,10 +445,9 @@ mod tests {
         fn test_wrapper(prog: &str, args: &[&str]) -> String {
             String::from_utf16(
                 &make_command_line(OsStr::from_str(prog),
-                                   args.iter()
-                                       .map(|a| OsString::from_str(a))
-                                       .collect::<Vec<OsString>>()
-                                       .as_slice())).unwrap()
+                                   &args.iter()
+                                        .map(|a| OsString::from(a))
+                                        .collect::<Vec<OsString>>())).unwrap()
         }
 
         assert_eq!(
index 76fe352ed7717cf6ca623bb693a1fcf48663d5c1..009605535a0237026d18ec29e0d783feb626a362 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use prelude::v1::*;
+
 use cell::UnsafeCell;
 use sys::sync as ffi;
 
@@ -17,6 +19,9 @@ pub const RWLOCK_INIT: RWLock = RWLock {
     inner: UnsafeCell { value: ffi::SRWLOCK_INIT }
 };
 
+unsafe impl Send for RWLock {}
+unsafe impl Sync for RWLock {}
+
 impl RWLock {
     #[inline]
     pub unsafe fn read(&self) {
index b0410701ee1012817ece41b7fb16eda28c47cd08..79b7de4f341ac07280d7d69a5c28faa44266f75d 100644 (file)
@@ -31,7 +31,7 @@ impl Drop for Handler {
 }
 
 // This is initialized in init() and only read from after
-static mut PAGE_SIZE: uint = 0;
+static mut PAGE_SIZE: usize = 0;
 
 #[no_stack_check]
 extern "system" fn vectored_handler(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG {
@@ -56,7 +56,7 @@ extern "system" fn vectored_handler(ExceptionInfo: *mut EXCEPTION_POINTERS) -> L
 pub unsafe fn init() {
     let mut info = mem::zeroed();
     libc::GetSystemInfo(&mut info);
-    PAGE_SIZE = info.dwPageSize as uint;
+    PAGE_SIZE = info.dwPageSize as usize;
 
     if AddVectoredExceptionHandler(0, vectored_handler) == ptr::null_mut() {
         panic!("failed to install exception handler");
@@ -96,7 +96,7 @@ pub type PVECTORED_EXCEPTION_HANDLER = extern "system"
 pub type ULONG = libc::c_ulong;
 
 const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
-const EXCEPTION_MAXIMUM_PARAMETERS: uint = 15;
+const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;
 const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
 
 extern "system" {
diff --git a/src/libstd/sys/windows/stdio.rs b/src/libstd/sys/windows/stdio.rs
new file mode 100644 (file)
index 0000000..91f6f32
--- /dev/null
@@ -0,0 +1,164 @@
+// Copyright 2015 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 prelude::v1::*;
+use io::prelude::*;
+
+use io::{self, Cursor};
+use iter::repeat;
+use libc;
+use ptr;
+use str;
+use sync::Mutex;
+use sys::c;
+use sys::cvt;
+use sys::handle::Handle;
+
+struct NoClose(Option<Handle>);
+
+enum Output {
+    Console(NoClose),
+    Pipe(NoClose),
+}
+
+pub struct Stdin {
+    handle: Output,
+    utf8: Mutex<io::Cursor<Vec<u8>>>,
+}
+pub struct Stdout(Output);
+pub struct Stderr(Output);
+
+fn get(handle: libc::DWORD) -> io::Result<Output> {
+    let handle = unsafe { c::GetStdHandle(handle) };
+    if handle == libc::INVALID_HANDLE_VALUE {
+        Err(io::Error::last_os_error())
+    } else if handle.is_null() {
+        Err(io::Error::new(io::ErrorKind::Other,
+                           "no stdio handle available for this process"))
+    } else {
+        let ret = NoClose::new(handle);
+        let mut out = 0;
+        match unsafe { c::GetConsoleMode(handle, &mut out) } {
+            0 => Ok(Output::Pipe(ret)),
+            _ => Ok(Output::Console(ret)),
+        }
+    }
+}
+
+fn write(out: &Output, data: &[u8]) -> io::Result<usize> {
+    let handle = match *out {
+        Output::Console(ref c) => c.get().raw(),
+        Output::Pipe(ref p) => return p.get().write(data),
+    };
+    let utf16 = match str::from_utf8(data).ok() {
+        Some(utf8) => utf8.utf16_units().collect::<Vec<u16>>(),
+        None => return Err(invalid_encoding()),
+    };
+    let mut written = 0;
+    try!(cvt(unsafe {
+        c::WriteConsoleW(handle,
+                         utf16.as_ptr() as libc::LPCVOID,
+                         utf16.len() as u32,
+                         &mut written,
+                         ptr::null_mut())
+    }));
+
+    // FIXME if this only partially writes the utf16 buffer then we need to
+    //       figure out how many bytes of `data` were actually written
+    assert_eq!(written as usize, utf16.len());
+    Ok(data.len())
+}
+
+impl Stdin {
+    pub fn new() -> Stdin {
+        Stdin {
+            handle: get(c::STD_INPUT_HANDLE).unwrap(),
+            utf8: Mutex::new(Cursor::new(Vec::new())),
+        }
+    }
+
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        let handle = match self.handle {
+            Output::Console(ref c) => c.get().raw(),
+            Output::Pipe(ref p) => return p.get().read(buf),
+        };
+        let mut utf8 = self.utf8.lock().unwrap();
+        // Read more if the buffer is empty
+        if utf8.position() as usize == utf8.get_ref().len() {
+            let mut utf16: Vec<u16> = repeat(0u16).take(0x1000).collect();
+            let mut num = 0;
+            try!(cvt(unsafe {
+                c::ReadConsoleW(handle,
+                                utf16.as_mut_ptr() as libc::LPVOID,
+                                utf16.len() as u32,
+                                &mut num,
+                                ptr::null_mut())
+            }));
+            utf16.truncate(num as usize);
+            // FIXME: what to do about this data that has already been read?
+            let data = match String::from_utf16(&utf16) {
+                Ok(utf8) => utf8.into_bytes(),
+                Err(..) => return Err(invalid_encoding()),
+            };
+            *utf8 = Cursor::new(data);
+        }
+
+        // MemReader shouldn't error here since we just filled it
+        utf8.read(buf)
+    }
+}
+
+impl Stdout {
+    pub fn new() -> Stdout {
+        Stdout(get(c::STD_OUTPUT_HANDLE).unwrap())
+    }
+
+    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+        write(&self.0, data)
+    }
+}
+
+impl Stderr {
+    pub fn new() -> Stderr {
+        Stderr(get(c::STD_ERROR_HANDLE).unwrap())
+    }
+
+    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+        write(&self.0, data)
+    }
+}
+
+// FIXME: right now this raw stderr handle is used in a few places because
+//        std::io::stderr_raw isn't exposed, but once that's exposed this impl
+//        should go away
+impl io::Write for Stderr {
+    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+        Stderr::write(self, data)
+    }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+
+impl NoClose {
+    fn new(handle: libc::HANDLE) -> NoClose {
+        NoClose(Some(Handle::new(handle)))
+    }
+
+    fn get(&self) -> &Handle { self.0.as_ref().unwrap() }
+}
+
+impl Drop for NoClose {
+    fn drop(&mut self) {
+        self.0.take().unwrap().into_raw();
+    }
+}
+
+fn invalid_encoding() -> io::Error {
+    io::Error::new(io::ErrorKind::InvalidInput, "text was not valid unicode")
+}
index 4804ca510cb0ba0e9be1b8fffdbd75285e78a703..41e97dc8475027741473f7f5458ff89661bdfea2 100644 (file)
@@ -8,12 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(deprecated)]
+
+use prelude::v1::*;
+
 use old_io::net::ip;
 use old_io::IoResult;
 use libc;
+use libc::consts::os::extra::INVALID_SOCKET;
 use mem;
 use ptr;
-use prelude::v1::*;
 use super::{last_error, last_net_error, sock_t};
 use sync::Arc;
 use sync::atomic::{AtomicBool, Ordering};
@@ -74,7 +78,7 @@ impl TcpListener {
 
     pub fn socket(&self) -> sock_t { self.sock }
 
-    pub fn listen(self, backlog: int) -> IoResult<TcpAcceptor> {
+    pub fn listen(self, backlog: isize) -> IoResult<TcpAcceptor> {
         match unsafe { libc::listen(self.socket(), backlog as libc::c_int) } {
             -1 => Err(last_net_error()),
 
@@ -180,8 +184,8 @@ impl TcpAcceptor {
             match unsafe {
                 libc::accept(self.socket(), ptr::null_mut(), ptr::null_mut())
             } {
-                -1 if wouldblock() => {}
-                -1 => return Err(last_net_error()),
+                INVALID_SOCKET if wouldblock() => {}
+                INVALID_SOCKET => return Err(last_net_error()),
 
                 // Accepted sockets inherit the same properties as the caller,
                 // so we need to deregister our event and switch the socket back
@@ -192,7 +196,7 @@ impl TcpAcceptor {
                         c::WSAEventSelect(socket, events[1], 0)
                     };
                     if ret != 0 { return Err(last_net_error()) }
-                    try!(set_nonblocking(socket, false));
+                    set_nonblocking(socket, false);
                     return Ok(stream)
                 }
             }
index f3a27877e5c58512fc8c6dce9dc08749141f12d5..98e4a737c7b178a8fcf0a02d7746752e5351ac23 100644 (file)
@@ -12,40 +12,26 @@ use prelude::v1::*;
 
 use cmp;
 use io;
-use mem;
-use ptr;
-use libc;
+use libc::{self, c_void};
 use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES, SIZE_T, BOOL,
                                    LPVOID, DWORD, LPDWORD, HANDLE};
-use thunk::Thunk;
+use mem;
+use ptr;
 use sys_common::stack::RED_ZONE;
 use sys_common::thread::*;
+use thunk::Thunk;
+use time::Duration;
 
 pub type rust_thread = HANDLE;
-pub type rust_thread_return = DWORD;
-
-pub type StartFn = extern "system" fn(*mut libc::c_void) -> rust_thread_return;
-
-#[no_stack_check]
-pub extern "system" fn thread_start(main: *mut libc::c_void) -> rust_thread_return {
-    return start_thread(main);
-}
 
 pub mod guard {
-    pub unsafe fn main() -> uint {
-        0
-    }
-
-    pub unsafe fn current() -> uint {
-        0
-    }
-
-    pub unsafe fn init() {
-    }
+    pub unsafe fn main() -> usize { 0 }
+    pub unsafe fn current() -> usize { 0 }
+    pub unsafe fn init() {}
 }
 
-pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
-    let arg: *mut libc::c_void = mem::transmute(box p);
+pub unsafe fn create(stack: usize, p: Thunk) -> io::Result<rust_thread> {
+    let p = box p;
     // FIXME On UNIX, we guard against stack sizes that are too small but
     // that's because pthreads enforces that stacks are at least
     // PTHREAD_STACK_MIN bytes big.  Windows has no such lower limit, it's
@@ -57,14 +43,20 @@ pub unsafe fn create(stack: uint, p: Thunk) -> io::Result<rust_thread> {
     // 20 kB red zone, that makes for a 64 kB minimum stack.
     let stack_size = (cmp::max(stack, RED_ZONE) + 0xfffe) & (-0xfffe - 1);
     let ret = CreateThread(ptr::null_mut(), stack_size as libc::size_t,
-                           thread_start, arg, 0, ptr::null_mut());
+                           thread_start, &*p as *const _ as *mut _,
+                           0, ptr::null_mut());
 
-    if ret as uint == 0 {
-        // be sure to not leak the closure
-        let _p: Box<Thunk> = mem::transmute(arg);
+    return if ret as usize == 0 {
         Err(io::Error::last_os_error())
     } else {
+        mem::forget(p); // ownership passed to CreateThread
         Ok(ret)
+    };
+
+    #[no_stack_check]
+    extern "system" fn thread_start(main: *mut libc::c_void) -> DWORD {
+        start_thread(main);
+        0
     }
 }
 
@@ -91,14 +83,29 @@ pub unsafe fn yield_now() {
     SwitchToThread();
 }
 
+pub fn sleep(dur: Duration) {
+    unsafe {
+        if dur < Duration::zero() {
+            return yield_now()
+        }
+        let ms = dur.num_milliseconds();
+        // if we have a fractional number of milliseconds then add an extra
+        // millisecond to sleep for
+        let extra = dur - Duration::milliseconds(ms);
+        let ms = ms + if extra.is_zero() {0} else {1};
+        Sleep(ms as DWORD);
+    }
+}
+
 #[allow(non_snake_case)]
 extern "system" {
     fn CreateThread(lpThreadAttributes: LPSECURITY_ATTRIBUTES,
                     dwStackSize: SIZE_T,
-                    lpStartAddress: StartFn,
+                    lpStartAddress: extern "system" fn(*mut c_void) -> DWORD,
                     lpParameter: LPVOID,
                     dwCreationFlags: DWORD,
                     lpThreadId: LPDWORD) -> HANDLE;
     fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
     fn SwitchToThread() -> BOOL;
+    fn Sleep(dwMilliseconds: DWORD);
 }
index 0c24ab1fa09b4e964f1f424f5c4d117e8e4e93bc..cbabab8acb78060b1959de4c29fcd307489ccd70 100644 (file)
@@ -12,7 +12,7 @@ use prelude::v1::*;
 
 use libc::types::os::arch::extra::{DWORD, LPVOID, BOOL};
 
-use mem;
+use boxed;
 use ptr;
 use rt;
 use sys_common::mutex::{MUTEX_INIT, Mutex};
@@ -133,21 +133,28 @@ unsafe fn init_dtors() {
     if !DTORS.is_null() { return }
 
     let dtors = box Vec::<(Key, Dtor)>::new();
-    DTORS = mem::transmute(dtors);
 
-    rt::at_exit(move|| {
+    let res = rt::at_exit(move|| {
         DTOR_LOCK.lock();
         let dtors = DTORS;
-        DTORS = ptr::null_mut();
-        mem::transmute::<_, Box<Vec<(Key, Dtor)>>>(dtors);
-        assert!(DTORS.is_null()); // can't re-init after destructing
+        DTORS = 1 as *mut _;
+        Box::from_raw(dtors);
+        assert!(DTORS as usize == 1); // can't re-init after destructing
         DTOR_LOCK.unlock();
     });
+    if res.is_ok() {
+        DTORS = boxed::into_raw(dtors);
+    } else {
+        DTORS = 1 as *mut _;
+    }
 }
 
 unsafe fn register_dtor(key: Key, dtor: Dtor) {
     DTOR_LOCK.lock();
     init_dtors();
+    assert!(DTORS as usize != 0);
+    assert!(DTORS as usize != 1,
+            "cannot create new TLS keys after the main thread has exited");
     (*DTORS).push((key, dtor));
     DTOR_LOCK.unlock();
 }
@@ -155,6 +162,9 @@ unsafe fn register_dtor(key: Key, dtor: Dtor) {
 unsafe fn unregister_dtor(key: Key) -> bool {
     DTOR_LOCK.lock();
     init_dtors();
+    assert!(DTORS as usize != 0);
+    assert!(DTORS as usize != 1,
+            "cannot unregister destructors after the main thread has exited");
     let ret = {
         let dtors = &mut *DTORS;
         let before = dtors.len();
@@ -241,7 +251,7 @@ unsafe fn run_dtors() {
         any_run = false;
         let dtors = {
             DTOR_LOCK.lock();
-            let ret = if DTORS.is_null() {
+            let ret = if DTORS as usize <= 1 {
                 Vec::new()
             } else {
                 (*DTORS).iter().map(|s| *s).collect()
index 20ceff0aa6931c41105646a50b01c0fade32f4df..209460df10b7ceb118f53669dafc0257e2a6ae88 100644 (file)
@@ -12,6 +12,8 @@ use ops::Sub;
 use time::Duration;
 use sync::{Once, ONCE_INIT};
 
+const NANOS_PER_SEC: i64 = 1_000_000_000;
+
 pub struct SteadyTime {
     t: libc::LARGE_INTEGER,
 }
@@ -24,7 +26,7 @@ impl SteadyTime {
     }
 
     pub fn ns(&self) -> u64 {
-        self.t as u64 * 1_000_000_000 / frequency() as u64
+        mul_div_i64(self.t as i64, NANOS_PER_SEC, frequency() as i64) as u64
     }
 }
 
@@ -45,6 +47,27 @@ impl<'a> Sub for &'a SteadyTime {
 
     fn sub(self, other: &SteadyTime) -> Duration {
         let diff = self.t as i64 - other.t as i64;
-        Duration::microseconds(diff * 1_000_000 / frequency() as i64)
+        Duration::nanoseconds(mul_div_i64(diff, NANOS_PER_SEC, frequency() as i64))
     }
 }
+
+// Computes (value*numer)/denom without overflow, as long as both
+// (numer*denom) and the overall result fit into i64 (which is the case
+// for our time conversions).
+fn mul_div_i64(value: i64, numer: i64, denom: i64) -> i64 {
+    let q = value / denom;
+    let r = value % denom;
+    // Decompose value as (value/denom*denom + value%denom),
+    // substitute into (value*numer)/denom and simplify.
+    // r < denom, so (denom*numer) is the upper bound of (r*numer)
+    q * numer + r * numer / denom
+}
+
+#[test]
+fn test_muldiv() {
+    assert_eq!(mul_div_i64( 1_000_000_000_001, 1_000_000_000, 1_000_000),  1_000_000_000_001_000);
+    assert_eq!(mul_div_i64(-1_000_000_000_001, 1_000_000_000, 1_000_000), -1_000_000_000_001_000);
+    assert_eq!(mul_div_i64(-1_000_000_000_001,-1_000_000_000, 1_000_000),  1_000_000_000_001_000);
+    assert_eq!(mul_div_i64( 1_000_000_000_001, 1_000_000_000,-1_000_000), -1_000_000_000_001_000);
+    assert_eq!(mul_div_i64( 1_000_000_000_001,-1_000_000_000,-1_000_000),  1_000_000_000_001_000);
+}
index d156dd801f974905fa2d2adc64d461bbdd1f7525..8856cc26b2e9060b8eaa3dbff863e5e70a6bba5f 100644 (file)
 //! Other than that, the implementation is pretty straightforward in terms of
 //! the other two implementations of timers with nothing *that* new showing up.
 
-use self::Req::*;
+#![allow(deprecated)]
+
 use prelude::v1::*;
+use self::Req::*;
 
 use libc;
 use ptr;
 
 use old_io::IoResult;
-use sync::mpsc::{channel, Sender, Receiver, TryRecvError};
 use sys_common::helper_thread::Helper;
+use sync::mpsc::{channel, TryRecvError, Sender, Receiver};
 
 helper_init! { static HELPER: Helper<Req> }
 
@@ -78,9 +80,10 @@ fn helper(input: libc::HANDLE, messages: Receiver<Req>, _: ()) {
                             None => {}
                         }
                     }
+                    // See the comment in unix::timer for why we don't have any
+                    // asserts here and why we're likely just leaving timers on
+                    // the floor as we exit.
                     Err(TryRecvError::Disconnected) => {
-                        assert_eq!(objs.len(), 1);
-                        assert_eq!(chans.len(), 0);
                         break 'outer;
                     }
                     Err(..) => break
@@ -88,13 +91,13 @@ fn helper(input: libc::HANDLE, messages: Receiver<Req>, _: ()) {
             }
         } else {
             let remove = {
-                match &mut chans[idx as uint - 1] {
+                match &mut chans[idx as usize - 1] {
                     &mut (ref mut c, oneshot) => { c.call(); oneshot }
                 }
             };
             if remove {
-                drop(objs.remove(idx as uint));
-                drop(chans.remove(idx as uint - 1));
+                drop(objs.remove(idx as usize));
+                drop(chans.remove(idx as usize - 1));
             }
         }
     }
index 8a8b53090570cadcd188b6f840b41ffbe81771ed..791c7532bd007148b282967fb797a45828b29c34 100644 (file)
 //! wrapper that performs encoding/decoding, this implementation should switch
 //! to working in raw UTF-16, with such a wrapper around it.
 
+#![allow(deprecated)]
+
 use prelude::v1::*;
 
-use old_io::{self, IoError, IoResult, MemReader};
+use old_io::{self, IoError, IoResult, MemReader, Reader};
 use iter::repeat;
 use libc::types::os::arch::extra::LPCVOID;
 use libc::{c_int, HANDLE, LPDWORD, DWORD, LPVOID};
@@ -38,9 +40,9 @@ use str::from_utf8;
 use super::c::{ENABLE_ECHO_INPUT, ENABLE_EXTENDED_FLAGS};
 use super::c::{ENABLE_INSERT_MODE, ENABLE_LINE_INPUT};
 use super::c::{ENABLE_PROCESSED_INPUT, ENABLE_QUICK_EDIT_MODE};
-use super::c::{CONSOLE_SCREEN_BUFFER_INFO};
+use super::c::CONSOLE_SCREEN_BUFFER_INFO;
 use super::c::{ReadConsoleW, WriteConsoleW, GetConsoleMode, SetConsoleMode};
-use super::c::{GetConsoleScreenBufferInfo};
+use super::c::GetConsoleScreenBufferInfo;
 
 fn invalid_encoding() -> IoError {
     IoError {
@@ -52,7 +54,7 @@ fn invalid_encoding() -> IoError {
 
 pub fn is_tty(fd: c_int) -> bool {
     let mut out: DWORD = 0;
-    // If this function doesn't panic then fd is a TTY
+    // If this function doesn't return an error, then fd is a TTY
     match unsafe { GetConsoleMode(get_osfhandle(fd) as HANDLE,
                                   &mut out as LPDWORD) } {
         0 => false,
@@ -90,7 +92,7 @@ impl TTY {
         }
     }
 
-    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+    pub fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
         // Read more if the buffer is empty
         if self.utf8.eof() {
             let mut utf16: Vec<u16> = repeat(0u16).take(0x1000).collect();
@@ -103,7 +105,7 @@ impl TTY {
                 0 => return Err(super::last_error()),
                 _ => (),
             };
-            utf16.truncate(num as uint);
+            utf16.truncate(num as usize);
             let utf8 = match String::from_utf16(&utf16) {
                 Ok(utf8) => utf8.into_bytes(),
                 Err(..) => return Err(invalid_encoding()),
@@ -147,12 +149,12 @@ impl TTY {
         }
     }
 
-    pub fn get_winsize(&mut self) -> IoResult<(int, int)> {
+    pub fn get_winsize(&mut self) -> IoResult<(isize, isize)> {
         let mut info: CONSOLE_SCREEN_BUFFER_INFO = unsafe { mem::zeroed() };
         match unsafe { GetConsoleScreenBufferInfo(self.handle, &mut info as *mut _) } {
             0 => Err(super::last_error()),
-            _ => Ok(((info.srWindow.Right + 1 - info.srWindow.Left) as int,
-                     (info.srWindow.Bottom + 1 - info.srWindow.Top) as int)),
+            _ => Ok(((info.srWindow.Right + 1 - info.srWindow.Left) as isize,
+                     (info.srWindow.Bottom + 1 - info.srWindow.Top) as isize)),
         }
     }
 }
diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs
deleted file mode 100644 (file)
index 3653e7e..0000000
+++ /dev/null
@@ -1,972 +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.
-
-//! Native threads
-//!
-//! ## The threading model
-//!
-//! An executing Rust program consists of a collection of native OS threads,
-//! each with their own stack and local state.
-//!
-//! Communication between threads can be done through
-//! [channels](../../std/sync/mpsc/index.html), Rust's message-passing
-//! types, along with [other forms of thread
-//! synchronization](../../std/sync/index.html) and shared-memory data
-//! structures. In particular, types that are guaranteed to be
-//! threadsafe are easily shared between threads using the
-//! atomically-reference-counted container,
-//! [`Arc`](../../std/sync/struct.Arc.html).
-//!
-//! Fatal logic errors in Rust cause *thread panic*, during which
-//! a thread will unwind the stack, running destructors and freeing
-//! owned resources. Thread panic is unrecoverable from within
-//! the panicking thread (i.e. there is no 'try/catch' in Rust), but
-//! panic may optionally be detected from a different thread. If
-//! the main thread panics the application will exit with a non-zero
-//! exit code.
-//!
-//! When the main thread of a Rust program terminates, the entire program shuts
-//! down, even if other threads are still running. However, this module provides
-//! convenient facilities for automatically waiting for the termination of a
-//! child thread (i.e., join), described below.
-//!
-//! ## The `Thread` type
-//!
-//! Already-running threads are represented via the `Thread` type, which you can
-//! get in one of two ways:
-//!
-//! * By spawning a new thread, e.g. using the `thread::spawn` constructor;
-//! * By requesting the current thread, using the `thread::current` function.
-//!
-//! Threads can be named, and provide some built-in support for low-level
-//! synchronization described below.
-//!
-//! The `thread::current()` function is available even for threads not spawned
-//! by the APIs of this module.
-//!
-//! ## Spawning a thread
-//!
-//! A new thread can be spawned using the `thread::spawn` function:
-//!
-//! ```rust
-//! use std::thread;
-//!
-//! thread::spawn(move || {
-//!     println!("Hello, World!");
-//!     // some computation here
-//! });
-//! ```
-//!
-//! In this example, the spawned thread is "detached" from the current
-//! thread, meaning that it can outlive the thread that spawned
-//! it. (Note, however, that when the main thread terminates all
-//! detached threads are terminated as well.)
-//!
-//! ## Scoped threads
-//!
-//! Often a parent thread uses a child thread to perform some particular task,
-//! and at some point must wait for the child to complete before continuing.
-//! For this scenario, use the `scoped` constructor:
-//!
-//! ```rust
-//! use std::thread;
-//!
-//! let guard = thread::scoped(move || {
-//!     println!("Hello, World!");
-//!     // some computation here
-//! });
-//! // do some other work in the meantime
-//! let output = guard.join();
-//! ```
-//!
-//! The `scoped` function doesn't return a `Thread` directly; instead,
-//! it returns a *join guard*. The join guard is an RAII-style guard
-//! that will automatically join the child thread (block until it
-//! terminates) when it is dropped. You can join the child thread in
-//! advance by calling the `join` method on the guard, which will also
-//! return the result produced by the thread.  A handle to the thread
-//! itself is available via the `thread` method on the join guard.
-//!
-//! (Note: eventually, the `scoped` constructor will allow the parent and child
-//! threads to data that lives on the parent thread's stack, but some language
-//! changes are needed before this is possible.)
-//!
-//! ## Configuring threads
-//!
-//! A new thread can be configured before it is spawned via the `Builder` type,
-//! which currently allows you to set the name, stack size, and writers for
-//! `println!` and `panic!` for the child thread:
-//!
-//! ```rust
-//! use std::thread;
-//!
-//! thread::Builder::new().name("child1".to_string()).spawn(move || {
-//!     println!("Hello, world!")
-//! });
-//! ```
-//!
-//! ## Blocking support: park and unpark
-//!
-//! Every thread is equipped with some basic low-level blocking support, via the
-//! `park` and `unpark` functions.
-//!
-//! Conceptually, each `Thread` handle has an associated token, which is
-//! initially not present:
-//!
-//! * The `thread::park()` function blocks the current thread unless or until
-//!   the token is available for its thread handle, at which point It atomically
-//!   consumes the token. It may also return *spuriously*, without consuming the
-//!   token. `thread::park_timeout()` does the same, but allows specifying a
-//!   maximum time to block the thread for.
-//!
-//! * The `unpark()` method on a `Thread` atomically makes the token available
-//!   if it wasn't already.
-//!
-//! In other words, each `Thread` acts a bit like a semaphore with initial count
-//! 0, except that the semaphore is *saturating* (the count cannot go above 1),
-//! and can return spuriously.
-//!
-//! The API is typically used by acquiring a handle to the current thread,
-//! placing that handle in a shared data structure so that other threads can
-//! find it, and then `park`ing. When some desired condition is met, another
-//! thread calls `unpark` on the handle.
-//!
-//! The motivation for this design is twofold:
-//!
-//! * It avoids the need to allocate mutexes and condvars when building new
-//!   synchronization primitives; the threads already provide basic blocking/signaling.
-//!
-//! * It can be implemented highly efficiently on many platforms.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use prelude::v1::*;
-
-use any::Any;
-use cell::UnsafeCell;
-use fmt;
-use io;
-use marker::PhantomData;
-use old_io::stdio;
-use rt::{self, unwind};
-use sync::{Mutex, Condvar, Arc};
-use thunk::Thunk;
-use time::Duration;
-
-use sys::thread as imp;
-use sys_common::{stack, thread_info};
-
-/// Thread configuration. Provides detailed control over the properties
-/// and behavior of new threads.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Builder {
-    // A name for the thread-to-be, for identification in panic messages
-    name: Option<String>,
-    // The size of the stack for the spawned thread
-    stack_size: Option<uint>,
-    // Thread-local stdout
-    stdout: Option<Box<Writer + Send + 'static>>,
-    // Thread-local stderr
-    stderr: Option<Box<Writer + Send + 'static>>,
-}
-
-impl Builder {
-    /// Generate the base configuration for spawning a thread, from which
-    /// configuration methods can be chained.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> Builder {
-        Builder {
-            name: None,
-            stack_size: None,
-            stdout: None,
-            stderr: None,
-        }
-    }
-
-    /// Name the thread-to-be. Currently the name is used for identification
-    /// only in panic messages.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn name(mut self, name: String) -> Builder {
-        self.name = Some(name);
-        self
-    }
-
-    /// Set the size of the stack for the new thread.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn stack_size(mut self, size: uint) -> Builder {
-        self.stack_size = Some(size);
-        self
-    }
-
-    /// Redirect thread-local stdout.
-    #[unstable(feature = "std_misc",
-               reason = "Will likely go away after proc removal")]
-    pub fn stdout(mut self, stdout: Box<Writer + Send + 'static>) -> Builder {
-        self.stdout = Some(stdout);
-        self
-    }
-
-    /// Redirect thread-local stderr.
-    #[unstable(feature = "std_misc",
-               reason = "Will likely go away after proc removal")]
-    pub fn stderr(mut self, stderr: Box<Writer + Send + 'static>) -> Builder {
-        self.stderr = Some(stderr);
-        self
-    }
-
-    /// Spawn a new thread, and return a join handle for it.
-    ///
-    /// The child thread may outlive the parent (unless the parent thread
-    /// is the main thread; the whole process is terminated when the main
-    /// thread finishes.) The join handle can be used to block on
-    /// termination of the child thread, including recovering its panics.
-    ///
-    /// # Errors
-    ///
-    /// Unlike the `spawn` free function, this method yields an
-    /// `io::Result` to capture any failure to create the thread at
-    /// the OS level.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn spawn<F>(self, f: F) -> io::Result<JoinHandle> where
-        F: FnOnce(), F: Send + 'static
-    {
-        self.spawn_inner(Thunk::new(f)).map(|i| JoinHandle(i))
-    }
-
-    /// Spawn a new child thread that must be joined within a given
-    /// scope, and return a `JoinGuard`.
-    ///
-    /// The join guard can be used to explicitly join the child thread (via
-    /// `join`), returning `Result<T>`, or it will implicitly join the child
-    /// upon being dropped. Because the child thread may refer to data on the
-    /// current thread's stack (hence the "scoped" name), it cannot be detached;
-    /// it *must* be joined before the relevant stack frame is popped. See the
-    /// module documentation for additional details.
-    ///
-    /// # Errors
-    ///
-    /// Unlike the `scoped` free function, this method yields an
-    /// `io::Result` to capture any failure to create the thread at
-    /// the OS level.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn scoped<'a, T, F>(self, f: F) -> io::Result<JoinGuard<'a, T>> where
-        T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
-    {
-        self.spawn_inner(Thunk::new(f)).map(|inner| {
-            JoinGuard { inner: inner, _marker: PhantomData }
-        })
-    }
-
-    fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> {
-        let Builder { name, stack_size, stdout, stderr } = self;
-
-        let stack_size = stack_size.unwrap_or(rt::min_stack());
-
-        let my_thread = Thread::new(name);
-        let their_thread = my_thread.clone();
-
-        let my_packet = Packet(Arc::new(UnsafeCell::new(None)));
-        let their_packet = Packet(my_packet.0.clone());
-
-        // Spawning a new OS thread guarantees that __morestack will never get
-        // triggered, but we must manually set up the actual stack bounds once
-        // this function starts executing. This raises the lower limit by a bit
-        // because by the time that this function is executing we've already
-        // consumed at least a little bit of stack (we don't know the exact byte
-        // address at which our stack started).
-        let main = move || {
-            let something_around_the_top_of_the_stack = 1;
-            let addr = &something_around_the_top_of_the_stack as *const int;
-            let my_stack_top = addr as uint;
-            let my_stack_bottom = my_stack_top - stack_size + 1024;
-            unsafe {
-                stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
-            }
-            match their_thread.name() {
-                Some(name) => unsafe { imp::set_name(name.as_slice()); },
-                None => {}
-            }
-            thread_info::set(
-                (my_stack_bottom, my_stack_top),
-                unsafe { imp::guard::current() },
-                their_thread
-            );
-
-            let mut output = None;
-            let f: Thunk<(), T> = if stdout.is_some() || stderr.is_some() {
-                Thunk::new(move || {
-                    let _ = stdout.map(stdio::set_stdout);
-                    let _ = stderr.map(stdio::set_stderr);
-                    f.invoke(())
-                })
-            } else {
-                f
-            };
-
-            let try_result = {
-                let ptr = &mut output;
-
-                // There are two primary reasons that general try/catch is
-                // unsafe. The first is that we do not support nested
-                // try/catch. The fact that this is happening in a newly-spawned
-                // thread suffices. The second is that unwinding while unwinding
-                // is not defined.  We take care of that by having an
-                // 'unwinding' flag in the thread itself. For these reasons,
-                // this unsafety should be ok.
-                unsafe {
-                    unwind::try(move || *ptr = Some(f.invoke(())))
-                }
-            };
-            unsafe {
-                *their_packet.0.get() = Some(match (output, try_result) {
-                    (Some(data), Ok(_)) => Ok(data),
-                    (None, Err(cause)) => Err(cause),
-                    _ => unreachable!()
-                });
-            }
-        };
-
-        Ok(JoinInner {
-            native: try!(unsafe { imp::create(stack_size, Thunk::new(main)) }),
-            thread: my_thread,
-            packet: my_packet,
-            joined: false,
-        })
-    }
-}
-
-/// Spawn a new, returning a join handle for it.
-///
-/// The child thread may outlive the parent (unless the parent thread
-/// is the main thread; the whole process is terminated when the main
-/// thread finishes.) The join handle can be used to block on
-/// termination of the child thread, including recovering its panics.
-///
-/// # Panics
-///
-/// Panicks if the OS fails to create a thread; use `Builder::spawn`
-/// to recover from such errors.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn spawn<F>(f: F) -> JoinHandle where F: FnOnce(), F: Send + 'static {
-    Builder::new().spawn(f).unwrap()
-}
-
-/// Spawn a new *scoped* thread, returning a `JoinGuard` for it.
-///
-/// The join guard can be used to explicitly join the child thread (via
-/// `join`), returning `Result<T>`, or it will implicitly join the child
-/// upon being dropped. Because the child thread may refer to data on the
-/// current thread's stack (hence the "scoped" name), it cannot be detached;
-/// it *must* be joined before the relevant stack frame is popped. See the
-/// module documentation for additional details.
-///
-/// # Panics
-///
-/// Panicks if the OS fails to create a thread; use `Builder::scoped`
-/// to recover from such errors.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where
-    T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
-{
-    Builder::new().scoped(f).unwrap()
-}
-
-/// Gets a handle to the thread that invokes it.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn current() -> Thread {
-    thread_info::current_thread()
-}
-
-/// Cooperatively give up a timeslice to the OS scheduler.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn yield_now() {
-    unsafe { imp::yield_now() }
-}
-
-/// Determines whether the current thread is unwinding because of panic.
-#[inline]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn panicking() -> bool {
-    unwind::panicking()
-}
-
-/// Block unless or until the current thread's token is made available (may wake spuriously).
-///
-/// See the module doc for more detail.
-//
-// The implementation currently uses the trivial strategy of a Mutex+Condvar
-// with wakeup flag, which does not actually allow spurious wakeups. In the
-// future, this will be implemented in a more efficient way, perhaps along the lines of
-//   http://cr.openjdk.java.net/~stefank/6989984.1/raw_files/new/src/os/linux/vm/os_linux.cpp
-// or futuxes, and in either case may allow spurious wakeups.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub fn park() {
-    let thread = current();
-    let mut guard = thread.inner.lock.lock().unwrap();
-    while !*guard {
-        guard = thread.inner.cvar.wait(guard).unwrap();
-    }
-    *guard = false;
-}
-
-/// Block unless or until the current thread's token is made available or
-/// the specified duration has been reached (may wake spuriously).
-///
-/// The semantics of this function are equivalent to `park()` except that the
-/// thread will be blocked for roughly no longer than dur. This method
-/// should not be used for precise timing due to anomalies such as
-/// preemption or platform differences that may not cause the maximum
-/// amount of time waited to be precisely dur
-///
-/// See the module doc for more detail.
-#[unstable(feature = "std_misc", reason = "recently introduced, depends on Duration")]
-pub fn park_timeout(dur: Duration) {
-    let thread = current();
-    let mut guard = thread.inner.lock.lock().unwrap();
-    if !*guard {
-        let (g, _) = thread.inner.cvar.wait_timeout(guard, dur).unwrap();
-        guard = g;
-    }
-    *guard = false;
-}
-
-/// The internal representation of a `Thread` handle
-struct Inner {
-    name: Option<String>,
-    lock: Mutex<bool>,          // true when there is a buffered unpark
-    cvar: Condvar,
-}
-
-unsafe impl Sync for Inner {}
-
-#[derive(Clone)]
-#[stable(feature = "rust1", since = "1.0.0")]
-/// A handle to a thread.
-pub struct Thread {
-    inner: Arc<Inner>,
-}
-
-impl Thread {
-    // Used only internally to construct a thread object without spawning
-    fn new(name: Option<String>) -> Thread {
-        Thread {
-            inner: Arc::new(Inner {
-                name: name,
-                lock: Mutex::new(false),
-                cvar: Condvar::new(),
-            })
-        }
-    }
-
-    /// Deprecated: use module-level free fucntion.
-    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
-    #[unstable(feature = "std_misc",
-               reason = "may change with specifics of new Send semantics")]
-    pub fn spawn<F>(f: F) -> Thread where F: FnOnce(), F: Send + 'static {
-        Builder::new().spawn(f).unwrap().thread().clone()
-    }
-
-    /// Deprecated: use module-level free fucntion.
-    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
-    #[unstable(feature = "std_misc",
-               reason = "may change with specifics of new Send semantics")]
-    pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where
-        T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
-    {
-        Builder::new().scoped(f).unwrap()
-    }
-
-    /// Deprecated: use module-level free fucntion.
-    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn current() -> Thread {
-        thread_info::current_thread()
-    }
-
-    /// Deprecated: use module-level free fucntion.
-    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
-    #[unstable(feature = "std_misc", reason = "name may change")]
-    pub fn yield_now() {
-        unsafe { imp::yield_now() }
-    }
-
-    /// Deprecated: use module-level free fucntion.
-    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
-    #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn panicking() -> bool {
-        unwind::panicking()
-    }
-
-    /// Deprecated: use module-level free fucntion.
-    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
-    #[unstable(feature = "std_misc", reason = "recently introduced")]
-    pub fn park() {
-        let thread = current();
-        let mut guard = thread.inner.lock.lock().unwrap();
-        while !*guard {
-            guard = thread.inner.cvar.wait(guard).unwrap();
-        }
-        *guard = false;
-    }
-
-    /// Deprecated: use module-level free fucntion.
-    #[deprecated(since = "1.0.0", reason = "use module-level free fucntion")]
-    #[unstable(feature = "std_misc", reason = "recently introduced")]
-    pub fn park_timeout(dur: Duration) {
-        let thread = current();
-        let mut guard = thread.inner.lock.lock().unwrap();
-        if !*guard {
-            let (g, _) = thread.inner.cvar.wait_timeout(guard, dur).unwrap();
-            guard = g;
-        }
-        *guard = false;
-    }
-
-    /// Atomically makes the handle's token available if it is not already.
-    ///
-    /// See the module doc for more detail.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn unpark(&self) {
-        let mut guard = self.inner.lock.lock().unwrap();
-        if !*guard {
-            *guard = true;
-            self.inner.cvar.notify_one();
-        }
-    }
-
-    /// Get the thread's name.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn name(&self) -> Option<&str> {
-        self.inner.name.as_ref().map(|s| &**s)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for Thread {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Debug::fmt(&self.name(), f)
-    }
-}
-
-// a hack to get around privacy restrictions
-impl thread_info::NewThread for Thread {
-    fn new(name: Option<String>) -> Thread { Thread::new(name) }
-}
-
-/// Indicates the manner in which a thread exited.
-///
-/// A thread that completes without panicking is considered to exit successfully.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub type Result<T> = ::result::Result<T, Box<Any + Send + 'static>>;
-
-struct Packet<T>(Arc<UnsafeCell<Option<Result<T>>>>);
-
-unsafe impl<T:Send> Send for Packet<T> {}
-unsafe impl<T> Sync for Packet<T> {}
-
-/// Inner representation for JoinHandle and JoinGuard
-struct JoinInner<T> {
-    native: imp::rust_thread,
-    thread: Thread,
-    packet: Packet<T>,
-    joined: bool,
-}
-
-impl<T> JoinInner<T> {
-    fn join(&mut self) -> Result<T> {
-        assert!(!self.joined);
-        unsafe { imp::join(self.native) };
-        self.joined = true;
-        unsafe {
-            (*self.packet.0.get()).take().unwrap()
-        }
-    }
-}
-
-/// An owned permission to join on a thread (block on its termination).
-///
-/// Unlike a `JoinGuard`, a `JoinHandle` *detaches* the child thread
-/// when it is dropped, rather than automatically joining on drop.
-///
-/// Due to platform restrictions, it is not possible to `Clone` this
-/// handle: the ability to join a child thread is a uniquely-owned
-/// permission.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct JoinHandle(JoinInner<()>);
-
-impl JoinHandle {
-    /// Extract a handle to the underlying thread
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn thread(&self) -> &Thread {
-        &self.0.thread
-    }
-
-    /// Wait for the associated thread to finish.
-    ///
-    /// If the child thread panics, `Err` is returned with the parameter given
-    /// to `panic`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn join(mut self) -> Result<()> {
-        self.0.join()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Drop for JoinHandle {
-    fn drop(&mut self) {
-        if !self.0.joined {
-            unsafe { imp::detach(self.0.native) }
-        }
-    }
-}
-
-/// An RAII-style guard that will block until thread termination when dropped.
-///
-/// The type `T` is the return type for the thread's main function.
-///
-/// Joining on drop is necessary to ensure memory safety when stack
-/// data is shared between a parent and child thread.
-///
-/// Due to platform restrictions, it is not possible to `Clone` this
-/// handle: the ability to join a child thread is a uniquely-owned
-/// permission.
-#[must_use]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct JoinGuard<'a, T: 'a> {
-    inner: JoinInner<T>,
-    _marker: PhantomData<&'a T>,
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<'a, T: Send + 'a> Sync for JoinGuard<'a, T> {}
-
-impl<'a, T: Send + 'a> JoinGuard<'a, T> {
-    /// Extract a handle to the thread this guard will join on.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn thread(&self) -> &Thread {
-        &self.inner.thread
-    }
-
-    /// Wait for the associated thread to finish, returning the result of the thread's
-    /// calculation.
-    ///
-    /// # Panics
-    ///
-    /// Panics on the child thread are propagated by panicking the parent.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn join(mut self) -> T {
-        match self.inner.join() {
-            Ok(res) => res,
-            Err(_) => panic!("child thread {:?} panicked", self.thread()),
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Send> JoinGuard<'static, T> {
-    /// Detaches the child thread, allowing it to outlive its parent.
-    #[deprecated(since = "1.0.0", reason = "use spawn instead")]
-    #[unstable(feature = "std_misc")]
-    pub fn detach(mut self) {
-        unsafe { imp::detach(self.inner.native) };
-        self.inner.joined = true; // avoid joining in the destructor
-    }
-}
-
-#[unsafe_destructor]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: Send + 'a> Drop for JoinGuard<'a, T> {
-    fn drop(&mut self) {
-        if !self.inner.joined {
-            if self.inner.join().is_err() {
-                panic!("child thread {:?} panicked", self.thread());
-            }
-        }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use prelude::v1::*;
-
-    use any::Any;
-    use sync::mpsc::{channel, Sender};
-    use boxed::BoxAny;
-    use result;
-    use std::old_io::{ChanReader, ChanWriter};
-    use super::{Thread, Builder};
-    use thread;
-    use thunk::Thunk;
-    use time::Duration;
-
-    // !!! These tests are dangerous. If something is buggy, they will hang, !!!
-    // !!! instead of exiting cleanly. This might wedge the buildbots.       !!!
-
-    #[test]
-    fn test_unnamed_thread() {
-        thread::spawn(move|| {
-            assert!(thread::current().name().is_none());
-        }).join().ok().unwrap();
-    }
-
-    #[test]
-    fn test_named_thread() {
-        Builder::new().name("ada lovelace".to_string()).scoped(move|| {
-            assert!(thread::current().name().unwrap() == "ada lovelace".to_string());
-        }).unwrap().join();
-    }
-
-    #[test]
-    fn test_run_basic() {
-        let (tx, rx) = channel();
-        thread::spawn(move|| {
-            tx.send(()).unwrap();
-        });
-        rx.recv().unwrap();
-    }
-
-    #[test]
-    fn test_join_success() {
-        assert!(thread::scoped(move|| -> String {
-            "Success!".to_string()
-        }).join() == "Success!");
-    }
-
-    #[test]
-    fn test_join_panic() {
-        match thread::spawn(move|| {
-            panic!()
-        }).join() {
-            result::Result::Err(_) => (),
-            result::Result::Ok(()) => panic!()
-        }
-    }
-
-    #[test]
-    fn test_scoped_success() {
-        let res = thread::scoped(move|| -> String {
-            "Success!".to_string()
-        }).join();
-        assert!(res == "Success!");
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_scoped_panic() {
-        thread::scoped(|| panic!()).join();
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_scoped_implicit_panic() {
-        thread::scoped(|| panic!());
-    }
-
-    #[test]
-    fn test_spawn_sched() {
-        use clone::Clone;
-
-        let (tx, rx) = channel();
-
-        fn f(i: int, tx: Sender<()>) {
-            let tx = tx.clone();
-            thread::spawn(move|| {
-                if i == 0 {
-                    tx.send(()).unwrap();
-                } else {
-                    f(i - 1, tx);
-                }
-            });
-
-        }
-        f(10, tx);
-        rx.recv().unwrap();
-    }
-
-    #[test]
-    fn test_spawn_sched_childs_on_default_sched() {
-        let (tx, rx) = channel();
-
-        thread::spawn(move|| {
-            thread::spawn(move|| {
-                tx.send(()).unwrap();
-            });
-        });
-
-        rx.recv().unwrap();
-    }
-
-    fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk<'static>) {
-        let (tx, rx) = channel::<uint>();
-
-        let x = box 1;
-        let x_in_parent = (&*x) as *const int as uint;
-
-        spawnfn(Thunk::new(move|| {
-            let x_in_child = (&*x) as *const int as uint;
-            tx.send(x_in_child).unwrap();
-        }));
-
-        let x_in_child = rx.recv().unwrap();
-        assert_eq!(x_in_parent, x_in_child);
-    }
-
-    #[test]
-    fn test_avoid_copying_the_body_spawn() {
-        avoid_copying_the_body(|v| {
-            thread::spawn(move || v.invoke(()));
-        });
-    }
-
-    #[test]
-    fn test_avoid_copying_the_body_thread_spawn() {
-        avoid_copying_the_body(|f| {
-            thread::spawn(move|| {
-                f.invoke(());
-            });
-        })
-    }
-
-    #[test]
-    fn test_avoid_copying_the_body_join() {
-        avoid_copying_the_body(|f| {
-            let _ = thread::spawn(move|| {
-                f.invoke(())
-            }).join();
-        })
-    }
-
-    #[test]
-    fn test_child_doesnt_ref_parent() {
-        // If the child refcounts the parent task, this will stack overflow when
-        // climbing the task tree to dereference each ancestor. (See #1789)
-        // (well, it would if the constant were 8000+ - I lowered it to be more
-        // valgrind-friendly. try this at home, instead..!)
-        static GENERATIONS: uint = 16;
-        fn child_no(x: uint) -> Thunk<'static> {
-            return Thunk::new(move|| {
-                if x < GENERATIONS {
-                    thread::spawn(move|| child_no(x+1).invoke(()));
-                }
-            });
-        }
-        thread::spawn(|| child_no(0).invoke(()));
-    }
-
-    #[test]
-    fn test_simple_newsched_spawn() {
-        thread::spawn(move || {});
-    }
-
-    #[test]
-    fn test_try_panic_message_static_str() {
-        match thread::spawn(move|| {
-            panic!("static string");
-        }).join() {
-            Err(e) => {
-                type T = &'static str;
-                assert!(e.is::<T>());
-                assert_eq!(*e.downcast::<T>().ok().unwrap(), "static string");
-            }
-            Ok(()) => panic!()
-        }
-    }
-
-    #[test]
-    fn test_try_panic_message_owned_str() {
-        match thread::spawn(move|| {
-            panic!("owned string".to_string());
-        }).join() {
-            Err(e) => {
-                type T = String;
-                assert!(e.is::<T>());
-                assert_eq!(*e.downcast::<T>().ok().unwrap(), "owned string".to_string());
-            }
-            Ok(()) => panic!()
-        }
-    }
-
-    #[test]
-    fn test_try_panic_message_any() {
-        match thread::spawn(move|| {
-            panic!(box 413u16 as Box<Any + Send>);
-        }).join() {
-            Err(e) => {
-                type T = Box<Any + Send>;
-                assert!(e.is::<T>());
-                let any = e.downcast::<T>().ok().unwrap();
-                assert!(any.is::<u16>());
-                assert_eq!(*any.downcast::<u16>().ok().unwrap(), 413u16);
-            }
-            Ok(()) => panic!()
-        }
-    }
-
-    #[test]
-    fn test_try_panic_message_unit_struct() {
-        struct Juju;
-
-        match thread::spawn(move|| {
-            panic!(Juju)
-        }).join() {
-            Err(ref e) if e.is::<Juju>() => {}
-            Err(_) | Ok(()) => panic!()
-        }
-    }
-
-    #[test]
-    fn test_stdout() {
-        let (tx, rx) = channel();
-        let mut reader = ChanReader::new(rx);
-        let stdout = ChanWriter::new(tx);
-
-        Builder::new().stdout(box stdout as Box<Writer + Send>).scoped(move|| {
-            print!("Hello, world!");
-        }).unwrap().join();
-
-        let output = reader.read_to_string().unwrap();
-        assert_eq!(output, "Hello, world!".to_string());
-    }
-
-    #[test]
-    fn test_park_timeout_unpark_before() {
-        for _ in 0..10 {
-            thread::current().unpark();
-            thread::park_timeout(Duration::seconds(10_000_000));
-        }
-    }
-
-    #[test]
-    fn test_park_timeout_unpark_not_called() {
-        for _ in 0..10 {
-            thread::park_timeout(Duration::milliseconds(10));
-        }
-    }
-
-    #[test]
-    fn test_park_timeout_unpark_called_other_thread() {
-        use std::old_io;
-
-        for _ in 0..10 {
-            let th = thread::current();
-
-            let _guard = thread::spawn(move || {
-                old_io::timer::sleep(Duration::milliseconds(50));
-                th.unpark();
-            });
-
-            thread::park_timeout(Duration::seconds(10_000_000));
-        }
-    }
-
-    // NOTE: the corresponding test for stderr is in run-pass/task-stderr, due
-    // to the test harness apparently interfering with stderr configuration.
-}
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
new file mode 100644 (file)
index 0000000..acd6970
--- /dev/null
@@ -0,0 +1,728 @@
+// Copyright 2014-2015 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.
+
+//! Thread local storage
+
+#![unstable(feature = "thread_local_internals")]
+
+use prelude::v1::*;
+
+use cell::UnsafeCell;
+
+// Sure wish we had macro hygiene, no?
+#[doc(hidden)]
+#[unstable(feature = "thread_local_internals")]
+pub mod __impl {
+    pub use super::imp::Key as KeyInner;
+    pub use super::imp::destroy_value;
+    pub use sys_common::thread_local::INIT_INNER as OS_INIT_INNER;
+    pub use sys_common::thread_local::StaticKey as OsStaticKey;
+}
+
+/// A thread local storage key which owns its contents.
+///
+/// This key uses the fastest possible implementation available to it for the
+/// target platform. It is instantiated with the `thread_local!` macro and the
+/// primary method is the `with` method.
+///
+/// The `with` method yields a reference to the contained value which cannot be
+/// sent across tasks or escape the given closure.
+///
+/// # Initialization and Destruction
+///
+/// Initialization is dynamically performed on the first call to `with()`
+/// within a thread, and values support destructors which will be run when a
+/// thread exits.
+///
+/// # Examples
+///
+/// ```
+/// use std::cell::RefCell;
+/// use std::thread;
+///
+/// thread_local!(static FOO: RefCell<u32> = RefCell::new(1));
+///
+/// FOO.with(|f| {
+///     assert_eq!(*f.borrow(), 1);
+///     *f.borrow_mut() = 2;
+/// });
+///
+/// // each thread starts out with the initial value of 1
+/// thread::spawn(move|| {
+///     FOO.with(|f| {
+///         assert_eq!(*f.borrow(), 1);
+///         *f.borrow_mut() = 3;
+///     });
+/// });
+///
+/// // we retain our original value of 2 despite the child thread
+/// FOO.with(|f| {
+///     assert_eq!(*f.borrow(), 2);
+/// });
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct LocalKey<T> {
+    // The key itself may be tagged with #[thread_local], and this `Key` is
+    // stored as a `static`, and it's not valid for a static to reference the
+    // address of another thread_local static. For this reason we kinda wonkily
+    // work around this by generating a shim function which will give us the
+    // address of the inner TLS key at runtime.
+    //
+    // This is trivially devirtualizable by LLVM because we never store anything
+    // to this field and rustc can declare the `static` as constant as well.
+    #[doc(hidden)]
+    #[unstable(feature = "thread_local_internals")]
+    pub inner: fn() -> &'static __impl::KeyInner<UnsafeCell<Option<T>>>,
+
+    // initialization routine to invoke to create a value
+    #[doc(hidden)]
+    #[unstable(feature = "thread_local_internals")]
+    pub init: fn() -> T,
+}
+
+/// Declare a new thread local storage key of type `std::thread::LocalKey`.
+#[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow_internal_unstable]
+macro_rules! thread_local {
+    (static $name:ident: $t:ty = $init:expr) => (
+        static $name: ::std::thread::LocalKey<$t> = {
+            use std::cell::UnsafeCell as __UnsafeCell;
+            use std::thread::__local::__impl::KeyInner as __KeyInner;
+            use std::option::Option as __Option;
+            use std::option::Option::None as __None;
+
+            __thread_local_inner!(static __KEY: __UnsafeCell<__Option<$t>> = {
+                __UnsafeCell { value: __None }
+            });
+            fn __init() -> $t { $init }
+            fn __getit() -> &'static __KeyInner<__UnsafeCell<__Option<$t>>> {
+                &__KEY
+            }
+            ::std::thread::LocalKey { inner: __getit, init: __init }
+        };
+    );
+    (pub static $name:ident: $t:ty = $init:expr) => (
+        pub static $name: ::std::thread::LocalKey<$t> = {
+            use std::cell::UnsafeCell as __UnsafeCell;
+            use std::thread::__local::__impl::KeyInner as __KeyInner;
+            use std::option::Option as __Option;
+            use std::option::Option::None as __None;
+
+            __thread_local_inner!(static __KEY: __UnsafeCell<__Option<$t>> = {
+                __UnsafeCell { value: __None }
+            });
+            fn __init() -> $t { $init }
+            fn __getit() -> &'static __KeyInner<__UnsafeCell<__Option<$t>>> {
+                &__KEY
+            }
+            ::std::thread::LocalKey { inner: __getit, init: __init }
+        };
+    );
+}
+
+// Macro pain #4586:
+//
+// When cross compiling, rustc will load plugins and macros from the *host*
+// platform before search for macros from the target platform. This is primarily
+// done to detect, for example, plugins. Ideally the macro below would be
+// defined once per module below, but unfortunately this means we have the
+// following situation:
+//
+// 1. We compile libstd for x86_64-unknown-linux-gnu, this thread_local!() macro
+//    will inject #[thread_local] statics.
+// 2. We then try to compile a program for arm-linux-androideabi
+// 3. The compiler has a host of linux and a target of android, so it loads
+//    macros from the *linux* libstd.
+// 4. The macro generates a #[thread_local] field, but the android libstd does
+//    not use #[thread_local]
+// 5. Compile error about structs with wrong fields.
+//
+// To get around this, we're forced to inject the #[cfg] logic into the macro
+// itself. Woohoo.
+
+#[macro_export]
+#[doc(hidden)]
+#[allow_internal_unstable]
+macro_rules! __thread_local_inner {
+    (static $name:ident: $t:ty = $init:expr) => (
+        #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
+                       not(target_arch = "aarch64")),
+                   thread_local)]
+        static $name: ::std::thread::__local::__impl::KeyInner<$t> =
+            __thread_local_inner!($init, $t);
+    );
+    (pub static $name:ident: $t:ty = $init:expr) => (
+        #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
+                       not(target_arch = "aarch64")),
+                   thread_local)]
+        pub static $name: ::std::thread::__local::__impl::KeyInner<$t> =
+            __thread_local_inner!($init, $t);
+    );
+    ($init:expr, $t:ty) => ({
+        #[cfg(all(any(target_os = "macos", target_os = "linux"), not(target_arch = "aarch64")))]
+        const _INIT: ::std::thread::__local::__impl::KeyInner<$t> = {
+            ::std::thread::__local::__impl::KeyInner {
+                inner: ::std::cell::UnsafeCell { value: $init },
+                dtor_registered: ::std::cell::UnsafeCell { value: false },
+                dtor_running: ::std::cell::UnsafeCell { value: false },
+            }
+        };
+
+        #[allow(trivial_casts)]
+        #[cfg(any(not(any(target_os = "macos", target_os = "linux")), target_arch = "aarch64"))]
+        const _INIT: ::std::thread::__local::__impl::KeyInner<$t> = {
+            ::std::thread::__local::__impl::KeyInner {
+                inner: ::std::cell::UnsafeCell { value: $init },
+                os: ::std::thread::__local::__impl::OsStaticKey {
+                    inner: ::std::thread::__local::__impl::OS_INIT_INNER,
+                    dtor: ::std::option::Option::Some(
+                        ::std::thread::__local::__impl::destroy_value::<$t>
+                    ),
+                },
+            }
+        };
+
+        _INIT
+    });
+}
+
+/// Indicator of the state of a thread local storage key.
+#[unstable(feature = "std_misc",
+           reason = "state querying was recently added")]
+#[derive(Eq, PartialEq, Copy, Clone)]
+pub enum LocalKeyState {
+    /// All keys are in this state whenever a thread starts. Keys will
+    /// transition to the `Valid` state once the first call to `with` happens
+    /// and the initialization expression succeeds.
+    ///
+    /// Keys in the `Uninitialized` state will yield a reference to the closure
+    /// passed to `with` so long as the initialization routine does not panic.
+    Uninitialized,
+
+    /// Once a key has been accessed successfully, it will enter the `Valid`
+    /// state. Keys in the `Valid` state will remain so until the thread exits,
+    /// at which point the destructor will be run and the key will enter the
+    /// `Destroyed` state.
+    ///
+    /// Keys in the `Valid` state will be guaranteed to yield a reference to the
+    /// closure passed to `with`.
+    Valid,
+
+    /// When a thread exits, the destructors for keys will be run (if
+    /// necessary). While a destructor is running, and possibly after a
+    /// destructor has run, a key is in the `Destroyed` state.
+    ///
+    /// Keys in the `Destroyed` states will trigger a panic when accessed via
+    /// `with`.
+    Destroyed,
+}
+
+impl<T: 'static> LocalKey<T> {
+    /// Acquire a reference to the value in this TLS key.
+    ///
+    /// This will lazily initialize the value if this thread has not referenced
+    /// this key yet.
+    ///
+    /// # Panics
+    ///
+    /// This function will `panic!()` if the key currently has its
+    /// destructor running, and it **may** panic if the destructor has
+    /// previously been run for this thread.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn with<F, R>(&'static self, f: F) -> R
+                      where F: FnOnce(&T) -> R {
+        let slot = (self.inner)();
+        unsafe {
+            let slot = slot.get().expect("cannot access a TLS value during or \
+                                          after it is destroyed");
+            f(match *slot.get() {
+                Some(ref inner) => inner,
+                None => self.init(slot),
+            })
+        }
+    }
+
+    unsafe fn init(&self, slot: &UnsafeCell<Option<T>>) -> &T {
+        // Execute the initialization up front, *then* move it into our slot,
+        // just in case initialization fails.
+        let value = (self.init)();
+        let ptr = slot.get();
+        *ptr = Some(value);
+        (*ptr).as_ref().unwrap()
+    }
+
+    /// Query the current state of this key.
+    ///
+    /// A key is initially in the `Uninitialized` state whenever a thread
+    /// starts. It will remain in this state up until the first call to `with`
+    /// within a thread has run the initialization expression successfully.
+    ///
+    /// Once the initialization expression succeeds, the key transitions to the
+    /// `Valid` state which will guarantee that future calls to `with` will
+    /// succeed within the thread.
+    ///
+    /// When a thread exits, each key will be destroyed in turn, and as keys are
+    /// destroyed they will enter the `Destroyed` state just before the
+    /// destructor starts to run. Keys may remain in the `Destroyed` state after
+    /// destruction has completed. Keys without destructors (e.g. with types
+    /// that are `Copy`), may never enter the `Destroyed` state.
+    ///
+    /// Keys in the `Uninitialized` can be accessed so long as the
+    /// initialization does not panic. Keys in the `Valid` state are guaranteed
+    /// to be able to be accessed. Keys in the `Destroyed` state will panic on
+    /// any call to `with`.
+    #[unstable(feature = "std_misc",
+               reason = "state querying was recently added")]
+    pub fn state(&'static self) -> LocalKeyState {
+        unsafe {
+            match (self.inner)().get() {
+                Some(cell) => {
+                    match *cell.get() {
+                        Some(..) => LocalKeyState::Valid,
+                        None => LocalKeyState::Uninitialized,
+                    }
+                }
+                None => LocalKeyState::Destroyed,
+            }
+        }
+    }
+}
+
+#[cfg(all(any(target_os = "macos", target_os = "linux"), not(target_arch = "aarch64")))]
+mod imp {
+    use prelude::v1::*;
+
+    use cell::UnsafeCell;
+    use intrinsics;
+    use ptr;
+
+    #[doc(hidden)]
+    #[unstable(feature = "thread_local_internals")]
+    pub struct Key<T> {
+        // Place the inner bits in an `UnsafeCell` to currently get around the
+        // "only Sync statics" restriction. This allows any type to be placed in
+        // the cell.
+        //
+        // Note that all access requires `T: 'static` so it can't be a type with
+        // any borrowed pointers still.
+        #[unstable(feature = "thread_local_internals")]
+        pub inner: UnsafeCell<T>,
+
+        // Metadata to keep track of the state of the destructor. Remember that
+        // these variables are thread-local, not global.
+        #[unstable(feature = "thread_local_internals")]
+        pub dtor_registered: UnsafeCell<bool>, // should be Cell
+        #[unstable(feature = "thread_local_internals")]
+        pub dtor_running: UnsafeCell<bool>, // should be Cell
+    }
+
+    unsafe impl<T> ::marker::Sync for Key<T> { }
+
+    #[doc(hidden)]
+    impl<T> Key<T> {
+        pub unsafe fn get(&'static self) -> Option<&'static T> {
+            if intrinsics::needs_drop::<T>() && *self.dtor_running.get() {
+                return None
+            }
+            self.register_dtor();
+            Some(&*self.inner.get())
+        }
+
+        unsafe fn register_dtor(&self) {
+            if !intrinsics::needs_drop::<T>() || *self.dtor_registered.get() {
+                return
+            }
+
+            register_dtor(self as *const _ as *mut u8,
+                          destroy_value::<T>);
+            *self.dtor_registered.get() = true;
+        }
+    }
+
+    // Since what appears to be glibc 2.18 this symbol has been shipped which
+    // GCC and clang both use to invoke destructors in thread_local globals, so
+    // let's do the same!
+    //
+    // Note, however, that we run on lots older linuxes, as well as cross
+    // compiling from a newer linux to an older linux, so we also have a
+    // fallback implementation to use as well.
+    //
+    // Due to rust-lang/rust#18804, make sure this is not generic!
+    #[cfg(target_os = "linux")]
+    unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
+        use boxed;
+        use mem;
+        use libc;
+        use sys_common::thread_local as os;
+
+        extern {
+            static __dso_handle: *mut u8;
+            #[linkage = "extern_weak"]
+            static __cxa_thread_atexit_impl: *const ();
+        }
+        if !__cxa_thread_atexit_impl.is_null() {
+            type F = unsafe extern fn(dtor: unsafe extern fn(*mut u8),
+                                      arg: *mut u8,
+                                      dso_handle: *mut u8) -> libc::c_int;
+            mem::transmute::<*const (), F>(__cxa_thread_atexit_impl)
+            (dtor, t, __dso_handle);
+            return
+        }
+
+        // The fallback implementation uses a vanilla OS-based TLS key to track
+        // the list of destructors that need to be run for this thread. The key
+        // then has its own destructor which runs all the other destructors.
+        //
+        // The destructor for DTORS is a little special in that it has a `while`
+        // loop to continuously drain the list of registered destructors. It
+        // *should* be the case that this loop always terminates because we
+        // provide the guarantee that a TLS key cannot be set after it is
+        // flagged for destruction.
+        static DTORS: os::StaticKey = os::StaticKey {
+            inner: os::INIT_INNER,
+            dtor: Some(run_dtors as unsafe extern "C" fn(*mut u8)),
+        };
+        type List = Vec<(*mut u8, unsafe extern fn(*mut u8))>;
+        if DTORS.get().is_null() {
+            let v: Box<List> = box Vec::new();
+            DTORS.set(boxed::into_raw(v) as *mut u8);
+        }
+        let list: &mut List = &mut *(DTORS.get() as *mut List);
+        list.push((t, dtor));
+
+        unsafe extern fn run_dtors(mut ptr: *mut u8) {
+            while !ptr.is_null() {
+                let list: Box<List> = Box::from_raw(ptr as *mut List);
+                for &(ptr, dtor) in &*list {
+                    dtor(ptr);
+                }
+                ptr = DTORS.get();
+                DTORS.set(ptr::null_mut());
+            }
+        }
+    }
+
+    // OSX's analog of the above linux function is this _tlv_atexit function.
+    // The disassembly of thread_local globals in C++ (at least produced by
+    // clang) will have this show up in the output.
+    #[cfg(target_os = "macos")]
+    unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
+        extern {
+            fn _tlv_atexit(dtor: unsafe extern fn(*mut u8),
+                           arg: *mut u8);
+        }
+        _tlv_atexit(dtor, t);
+    }
+
+    #[doc(hidden)]
+    #[unstable(feature = "thread_local_internals")]
+    pub unsafe extern fn destroy_value<T>(ptr: *mut u8) {
+        let ptr = ptr as *mut Key<T>;
+        // Right before we run the user destructor be sure to flag the
+        // destructor as running for this thread so calls to `get` will return
+        // `None`.
+        *(*ptr).dtor_running.get() = true;
+        ptr::read((*ptr).inner.get());
+    }
+}
+
+#[cfg(any(not(any(target_os = "macos", target_os = "linux")), target_arch = "aarch64"))]
+mod imp {
+    use prelude::v1::*;
+
+    use alloc::boxed;
+    use cell::UnsafeCell;
+    use mem;
+    use ptr;
+    use sys_common::thread_local::StaticKey as OsStaticKey;
+
+    #[doc(hidden)]
+    #[unstable(feature = "thread_local_internals")]
+    pub struct Key<T> {
+        // Statically allocated initialization expression, using an `UnsafeCell`
+        // for the same reasons as above.
+        #[unstable(feature = "thread_local_internals")]
+        pub inner: UnsafeCell<T>,
+
+        // OS-TLS key that we'll use to key off.
+        #[unstable(feature = "thread_local_internals")]
+        pub os: OsStaticKey,
+    }
+
+    unsafe impl<T> ::marker::Sync for Key<T> { }
+
+    struct Value<T: 'static> {
+        key: &'static Key<T>,
+        value: T,
+    }
+
+    #[doc(hidden)]
+    impl<T> Key<T> {
+        pub unsafe fn get(&'static self) -> Option<&'static T> {
+            self.ptr().map(|p| &*p)
+        }
+
+        unsafe fn ptr(&'static self) -> Option<*mut T> {
+            let ptr = self.os.get() as *mut Value<T>;
+            if !ptr.is_null() {
+                if ptr as usize == 1 {
+                    return None
+                }
+                return Some(&mut (*ptr).value as *mut T);
+            }
+
+            // If the lookup returned null, we haven't initialized our own local
+            // copy, so do that now.
+            //
+            // Also note that this transmute_copy should be ok because the value
+            // `inner` is already validated to be a valid `static` value, so we
+            // should be able to freely copy the bits.
+            let ptr: Box<Value<T>> = box Value {
+                key: self,
+                value: mem::transmute_copy(&self.inner),
+            };
+            let ptr: *mut Value<T> = boxed::into_raw(ptr);
+            self.os.set(ptr as *mut u8);
+            Some(&mut (*ptr).value as *mut T)
+        }
+    }
+
+    #[doc(hidden)]
+    #[unstable(feature = "thread_local_internals")]
+    pub unsafe extern fn destroy_value<T: 'static>(ptr: *mut u8) {
+        // The OS TLS ensures that this key contains a NULL value when this
+        // destructor starts to run. We set it back to a sentinel value of 1 to
+        // ensure that any future calls to `get` for this thread will return
+        // `None`.
+        //
+        // Note that to prevent an infinite loop we reset it back to null right
+        // before we return from the destructor ourselves.
+        let ptr: Box<Value<T>> = Box::from_raw(ptr as *mut Value<T>);
+        let key = ptr.key;
+        key.os.set(1 as *mut u8);
+        drop(ptr);
+        key.os.set(ptr::null_mut());
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use prelude::v1::*;
+
+    use sync::mpsc::{channel, Sender};
+    use cell::UnsafeCell;
+    use super::LocalKeyState;
+    use thread;
+
+    struct Foo(Sender<()>);
+
+    impl Drop for Foo {
+        fn drop(&mut self) {
+            let Foo(ref s) = *self;
+            s.send(()).unwrap();
+        }
+    }
+
+    #[test]
+    fn smoke_no_dtor() {
+        thread_local!(static FOO: UnsafeCell<i32> = UnsafeCell { value: 1 });
+
+        FOO.with(|f| unsafe {
+            assert_eq!(*f.get(), 1);
+            *f.get() = 2;
+        });
+        let (tx, rx) = channel();
+        let _t = thread::spawn(move|| {
+            FOO.with(|f| unsafe {
+                assert_eq!(*f.get(), 1);
+            });
+            tx.send(()).unwrap();
+        });
+        rx.recv().unwrap();
+
+        FOO.with(|f| unsafe {
+            assert_eq!(*f.get(), 2);
+        });
+    }
+
+    #[test]
+    fn states() {
+        struct Foo;
+        impl Drop for Foo {
+            fn drop(&mut self) {
+                assert!(FOO.state() == LocalKeyState::Destroyed);
+            }
+        }
+        fn foo() -> Foo {
+            assert!(FOO.state() == LocalKeyState::Uninitialized);
+            Foo
+        }
+        thread_local!(static FOO: Foo = foo());
+
+        thread::spawn(|| {
+            assert!(FOO.state() == LocalKeyState::Uninitialized);
+            FOO.with(|_| {
+                assert!(FOO.state() == LocalKeyState::Valid);
+            });
+            assert!(FOO.state() == LocalKeyState::Valid);
+        }).join().ok().unwrap();
+    }
+
+    #[test]
+    fn smoke_dtor() {
+        thread_local!(static FOO: UnsafeCell<Option<Foo>> = UnsafeCell {
+            value: None
+        });
+
+        let (tx, rx) = channel();
+        let _t = thread::spawn(move|| unsafe {
+            let mut tx = Some(tx);
+            FOO.with(|f| {
+                *f.get() = Some(Foo(tx.take().unwrap()));
+            });
+        });
+        rx.recv().unwrap();
+    }
+
+    #[test]
+    fn circular() {
+        struct S1;
+        struct S2;
+        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell {
+            value: None
+        });
+        thread_local!(static K2: UnsafeCell<Option<S2>> = UnsafeCell {
+            value: None
+        });
+        static mut HITS: u32 = 0;
+
+        impl Drop for S1 {
+            fn drop(&mut self) {
+                unsafe {
+                    HITS += 1;
+                    if K2.state() == LocalKeyState::Destroyed {
+                        assert_eq!(HITS, 3);
+                    } else {
+                        if HITS == 1 {
+                            K2.with(|s| *s.get() = Some(S2));
+                        } else {
+                            assert_eq!(HITS, 3);
+                        }
+                    }
+                }
+            }
+        }
+        impl Drop for S2 {
+            fn drop(&mut self) {
+                unsafe {
+                    HITS += 1;
+                    assert!(K1.state() != LocalKeyState::Destroyed);
+                    assert_eq!(HITS, 2);
+                    K1.with(|s| *s.get() = Some(S1));
+                }
+            }
+        }
+
+        thread::spawn(move|| {
+            drop(S1);
+        }).join().ok().unwrap();
+    }
+
+    #[test]
+    fn self_referential() {
+        struct S1;
+        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell {
+            value: None
+        });
+
+        impl Drop for S1 {
+            fn drop(&mut self) {
+                assert!(K1.state() == LocalKeyState::Destroyed);
+            }
+        }
+
+        thread::spawn(move|| unsafe {
+            K1.with(|s| *s.get() = Some(S1));
+        }).join().ok().unwrap();
+    }
+
+    #[test]
+    fn dtors_in_dtors_in_dtors() {
+        struct S1(Sender<()>);
+        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell {
+            value: None
+        });
+        thread_local!(static K2: UnsafeCell<Option<Foo>> = UnsafeCell {
+            value: None
+        });
+
+        impl Drop for S1 {
+            fn drop(&mut self) {
+                let S1(ref tx) = *self;
+                unsafe {
+                    if K2.state() != LocalKeyState::Destroyed {
+                        K2.with(|s| *s.get() = Some(Foo(tx.clone())));
+                    }
+                }
+            }
+        }
+
+        let (tx, rx) = channel();
+        let _t = thread::spawn(move|| unsafe {
+            let mut tx = Some(tx);
+            K1.with(|s| *s.get() = Some(S1(tx.take().unwrap())));
+        });
+        rx.recv().unwrap();
+    }
+}
+
+#[cfg(test)]
+mod dynamic_tests {
+    use prelude::v1::*;
+
+    use cell::RefCell;
+    use collections::HashMap;
+
+    #[test]
+    fn smoke() {
+        fn square(i: i32) -> i32 { i * i }
+        thread_local!(static FOO: i32 = square(3));
+
+        FOO.with(|f| {
+            assert_eq!(*f, 9);
+        });
+    }
+
+    #[test]
+    fn hashmap() {
+        fn map() -> RefCell<HashMap<i32, i32>> {
+            let mut m = HashMap::new();
+            m.insert(1, 2);
+            RefCell::new(m)
+        }
+        thread_local!(static FOO: RefCell<HashMap<i32, i32>> = map());
+
+        FOO.with(|map| {
+            assert_eq!(map.borrow()[&1], 2);
+        });
+    }
+
+    #[test]
+    fn refcell_vec() {
+        thread_local!(static FOO: RefCell<Vec<u32>> = RefCell::new(vec![1, 2, 3]));
+
+        FOO.with(|vec| {
+            assert_eq!(vec.borrow().len(), 3);
+            vec.borrow_mut().push(4);
+            assert_eq!(vec.borrow()[3], 4);
+        });
+    }
+}
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
new file mode 100644 (file)
index 0000000..5fe6e80
--- /dev/null
@@ -0,0 +1,992 @@
+// 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.
+
+//! Native threads
+//!
+//! ## The threading model
+//!
+//! An executing Rust program consists of a collection of native OS threads,
+//! each with their own stack and local state.
+//!
+//! Communication between threads can be done through
+//! [channels](../../std/sync/mpsc/index.html), Rust's message-passing
+//! types, along with [other forms of thread
+//! synchronization](../../std/sync/index.html) and shared-memory data
+//! structures. In particular, types that are guaranteed to be
+//! threadsafe are easily shared between threads using the
+//! atomically-reference-counted container,
+//! [`Arc`](../../std/sync/struct.Arc.html).
+//!
+//! Fatal logic errors in Rust cause *thread panic*, during which
+//! a thread will unwind the stack, running destructors and freeing
+//! owned resources. Thread panic is unrecoverable from within
+//! the panicking thread (i.e. there is no 'try/catch' in Rust), but
+//! the panic may optionally be detected from a different thread. If
+//! the main thread panics, the application will exit with a non-zero
+//! exit code.
+//!
+//! When the main thread of a Rust program terminates, the entire program shuts
+//! down, even if other threads are still running. However, this module provides
+//! convenient facilities for automatically waiting for the termination of a
+//! child thread (i.e., join).
+//!
+//! ## The `Thread` type
+//!
+//! Threads are represented via the `Thread` type, which you can
+//! get in one of two ways:
+//!
+//! * By spawning a new thread, e.g. using the `thread::spawn` function.
+//! * By requesting the current thread, using the `thread::current` function.
+//!
+//! Threads can be named, and provide some built-in support for low-level
+//! synchronization (described below).
+//!
+//! The `thread::current()` function is available even for threads not spawned
+//! by the APIs of this module.
+//!
+//! ## Spawning a thread
+//!
+//! A new thread can be spawned using the `thread::spawn` function:
+//!
+//! ```rust
+//! use std::thread;
+//!
+//! thread::spawn(move || {
+//!     // some work here
+//! });
+//! ```
+//!
+//! In this example, the spawned thread is "detached" from the current
+//! thread. This means that it can outlive its parent (the thread that spawned
+//! it), unless this parent is the main thread.
+//!
+//! ## Scoped threads
+//!
+//! Often a parent thread uses a child thread to perform some particular task,
+//! and at some point must wait for the child to complete before continuing.
+//! For this scenario, use the `thread::scoped` function:
+//!
+//! ```rust
+//! use std::thread;
+//!
+//! let guard = thread::scoped(move || {
+//!     // some work here
+//! });
+//!
+//! // do some other work in the meantime
+//! let output = guard.join();
+//! ```
+//!
+//! The `scoped` function doesn't return a `Thread` directly; instead,
+//! it returns a *join guard*. The join guard is an RAII-style guard
+//! that will automatically join the child thread (block until it
+//! terminates) when it is dropped. You can join the child thread in
+//! advance by calling the `join` method on the guard, which will also
+//! return the result produced by the thread.  A handle to the thread
+//! itself is available via the `thread` method of the join guard.
+//!
+//! ## Configuring threads
+//!
+//! A new thread can be configured before it is spawned via the `Builder` type,
+//! which currently allows you to set the name, stack size, and writers for
+//! `println!` and `panic!` for the child thread:
+//!
+//! ```rust
+//! use std::thread;
+//!
+//! thread::Builder::new().name("child1".to_string()).spawn(move || {
+//!     println!("Hello, world!");
+//! });
+//! ```
+//!
+//! ## Blocking support: park and unpark
+//!
+//! Every thread is equipped with some basic low-level blocking support, via the
+//! `park` and `unpark` functions.
+//!
+//! Conceptually, each `Thread` handle has an associated token, which is
+//! initially not present:
+//!
+//! * The `thread::park()` function blocks the current thread unless or until
+//!   the token is available for its thread handle, at which point it atomically
+//!   consumes the token. It may also return *spuriously*, without consuming the
+//!   token. `thread::park_timeout()` does the same, but allows specifying a
+//!   maximum time to block the thread for.
+//!
+//! * The `unpark()` method on a `Thread` atomically makes the token available
+//!   if it wasn't already.
+//!
+//! In other words, each `Thread` acts a bit like a semaphore with initial count
+//! 0, except that the semaphore is *saturating* (the count cannot go above 1),
+//! and can return spuriously.
+//!
+//! The API is typically used by acquiring a handle to the current thread,
+//! placing that handle in a shared data structure so that other threads can
+//! find it, and then `park`ing. When some desired condition is met, another
+//! thread calls `unpark` on the handle.
+//!
+//! The motivation for this design is twofold:
+//!
+//! * It avoids the need to allocate mutexes and condvars when building new
+//!   synchronization primitives; the threads already provide basic blocking/signaling.
+//!
+//! * It can be implemented very efficiently on many platforms.
+//!
+//! ## Thread-local storage
+//!
+//! This module also provides an implementation of thread local storage for Rust
+//! programs. Thread local storage is a method of storing data into a global
+//! variable which each thread in the program will have its own copy of.
+//! Threads do not share this data, so accesses do not need to be synchronized.
+//!
+//! At a high level, this module provides two variants of storage:
+//!
+//! * Owned thread-local storage. This is a type of thread local key which
+//!   owns the value that it contains, and will destroy the value when the
+//!   thread exits. This variant is created with the `thread_local!` macro and
+//!   can contain any value which is `'static` (no borrowed pointers).
+//!
+//! * Scoped thread-local storage. This type of key is used to store a reference
+//!   to a value into local storage temporarily for the scope of a function
+//!   call. There are no restrictions on what types of values can be placed
+//!   into this key.
+//!
+//! Both forms of thread local storage provide an accessor function, `with`,
+//! which will yield a shared reference to the value to the specified
+//! closure. Thread-local keys only allow shared access to values as there is no
+//! way to guarantee uniqueness if a mutable borrow was allowed. Most values
+//! will want to make use of some form of **interior mutability** through the
+//! `Cell` or `RefCell` types.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::__local::{LocalKey, LocalKeyState};
+
+#[unstable(feature = "scoped_tls",
+            reason = "scoped TLS has yet to have wide enough use to fully consider \
+                      stabilizing its interface")]
+pub use self::__scoped::ScopedKey;
+
+use prelude::v1::*;
+
+use any::Any;
+use cell::UnsafeCell;
+use fmt;
+use io;
+use marker::PhantomData;
+use rt::{self, unwind};
+use sync::{Mutex, Condvar, Arc};
+use sys::thread as imp;
+use sys_common::{stack, thread_info};
+use thunk::Thunk;
+use time::Duration;
+
+////////////////////////////////////////////////////////////////////////////////
+// Thread-local storage
+////////////////////////////////////////////////////////////////////////////////
+
+#[macro_use]
+#[doc(hidden)]
+#[path = "local.rs"] pub mod __local;
+
+#[macro_use]
+#[doc(hidden)]
+#[path = "scoped.rs"] pub mod __scoped;
+
+////////////////////////////////////////////////////////////////////////////////
+// Builder
+////////////////////////////////////////////////////////////////////////////////
+
+/// Thread configuration. Provides detailed control over the properties
+/// and behavior of new threads.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Builder {
+    // A name for the thread-to-be, for identification in panic messages
+    name: Option<String>,
+    // The size of the stack for the spawned thread
+    stack_size: Option<usize>,
+}
+
+impl Builder {
+    /// Generate the base configuration for spawning a thread, from which
+    /// configuration methods can be chained.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new() -> Builder {
+        Builder {
+            name: None,
+            stack_size: None,
+        }
+    }
+
+    /// Name the thread-to-be. Currently the name is used for identification
+    /// only in panic messages.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn name(mut self, name: String) -> Builder {
+        self.name = Some(name);
+        self
+    }
+
+    /// Set the size of the stack for the new thread.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn stack_size(mut self, size: usize) -> Builder {
+        self.stack_size = Some(size);
+        self
+    }
+
+    /// Spawn a new thread, and return a join handle for it.
+    ///
+    /// The child thread may outlive the parent (unless the parent thread
+    /// is the main thread; the whole process is terminated when the main
+    /// thread finishes.) The join handle can be used to block on
+    /// termination of the child thread, including recovering its panics.
+    ///
+    /// # Errors
+    ///
+    /// Unlike the `spawn` free function, this method yields an
+    /// `io::Result` to capture any failure to create the thread at
+    /// the OS level.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn spawn<F>(self, f: F) -> io::Result<JoinHandle> where
+        F: FnOnce(), F: Send + 'static
+    {
+        self.spawn_inner(Box::new(f)).map(|i| JoinHandle(i))
+    }
+
+    /// Spawn a new child thread that must be joined within a given
+    /// scope, and return a `JoinGuard`.
+    ///
+    /// The join guard can be used to explicitly join the child thread (via
+    /// `join`), returning `Result<T>`, or it will implicitly join the child
+    /// upon being dropped. Because the child thread may refer to data on the
+    /// current thread's stack (hence the "scoped" name), it cannot be detached;
+    /// it *must* be joined before the relevant stack frame is popped. See the
+    /// module documentation for additional details.
+    ///
+    /// # Errors
+    ///
+    /// Unlike the `scoped` free function, this method yields an
+    /// `io::Result` to capture any failure to create the thread at
+    /// the OS level.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn scoped<'a, T, F>(self, f: F) -> io::Result<JoinGuard<'a, T>> where
+        T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
+    {
+        self.spawn_inner(Box::new(f)).map(|inner| {
+            JoinGuard { inner: inner, _marker: PhantomData }
+        })
+    }
+
+    fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> io::Result<JoinInner<T>> {
+        let Builder { name, stack_size } = self;
+
+        let stack_size = stack_size.unwrap_or(rt::min_stack());
+
+        let my_thread = Thread::new(name);
+        let their_thread = my_thread.clone();
+
+        let my_packet = Packet(Arc::new(UnsafeCell::new(None)));
+        let their_packet = Packet(my_packet.0.clone());
+
+        // Spawning a new OS thread guarantees that __morestack will never get
+        // triggered, but we must manually set up the actual stack bounds once
+        // this function starts executing. This raises the lower limit by a bit
+        // because by the time that this function is executing we've already
+        // consumed at least a little bit of stack (we don't know the exact byte
+        // address at which our stack started).
+        let main = move || {
+            let something_around_the_top_of_the_stack = 1;
+            let addr = &something_around_the_top_of_the_stack as *const i32;
+            let my_stack_top = addr as usize;
+            let my_stack_bottom = my_stack_top - stack_size + 1024;
+            unsafe {
+                if let Some(name) = their_thread.name() {
+                    imp::set_name(name);
+                }
+                stack::record_os_managed_stack_bounds(my_stack_bottom,
+                                                      my_stack_top);
+                thread_info::set(imp::guard::current(), their_thread);
+            }
+
+            let mut output: Option<T> = None;
+            let try_result = {
+                let ptr = &mut output;
+
+                // There are two primary reasons that general try/catch is
+                // unsafe. The first is that we do not support nested
+                // try/catch. The fact that this is happening in a newly-spawned
+                // thread suffices. The second is that unwinding while unwinding
+                // is not defined.  We take care of that by having an
+                // 'unwinding' flag in the thread itself. For these reasons,
+                // this unsafety should be ok.
+                unsafe {
+                    unwind::try(move || {
+                        let f: Thunk<(), T> = f;
+                        let v: T = f();
+                        *ptr = Some(v)
+                    })
+                }
+            };
+            unsafe {
+                *their_packet.0.get() = Some(match (output, try_result) {
+                    (Some(data), Ok(_)) => Ok(data),
+                    (None, Err(cause)) => Err(cause),
+                    _ => unreachable!()
+                });
+            }
+        };
+
+        Ok(JoinInner {
+            native: try!(unsafe { imp::create(stack_size, Box::new(main)) }),
+            thread: my_thread,
+            packet: my_packet,
+            joined: false,
+        })
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Free functions
+////////////////////////////////////////////////////////////////////////////////
+
+/// Spawn a new thread, returning a `JoinHandle` for it.
+///
+/// The join handle will implicitly *detach* the child thread upon being
+/// dropped. In this case, the child thread may outlive the parent (unless
+/// the parent thread is the main thread; the whole process is terminated when
+/// the main thread finishes.) Additionally, the join handle provides a `join`
+/// method that can be used to join the child thread. If the child thread
+/// panics, `join` will return an `Err` containing the argument given to
+/// `panic`.
+///
+/// # Panics
+///
+/// Panicks if the OS fails to create a thread; use `Builder::spawn`
+/// to recover from such errors.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn spawn<F>(f: F) -> JoinHandle where F: FnOnce(), F: Send + 'static {
+    Builder::new().spawn(f).unwrap()
+}
+
+/// Spawn a new *scoped* thread, returning a `JoinGuard` for it.
+///
+/// The join guard can be used to explicitly join the child thread (via
+/// `join`), returning `Result<T>`, or it will implicitly join the child
+/// upon being dropped. Because the child thread may refer to data on the
+/// current thread's stack (hence the "scoped" name), it cannot be detached;
+/// it *must* be joined before the relevant stack frame is popped. See the
+/// module documentation for additional details.
+///
+/// # Panics
+///
+/// Panicks if the OS fails to create a thread; use `Builder::scoped`
+/// to recover from such errors.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where
+    T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
+{
+    Builder::new().scoped(f).unwrap()
+}
+
+/// Gets a handle to the thread that invokes it.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn current() -> Thread {
+    thread_info::current_thread()
+}
+
+/// Cooperatively give up a timeslice to the OS scheduler.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn yield_now() {
+    unsafe { imp::yield_now() }
+}
+
+/// Determines whether the current thread is unwinding because of panic.
+#[inline]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn panicking() -> bool {
+    unwind::panicking()
+}
+
+/// Invoke a closure, capturing the cause of panic if one occurs.
+///
+/// This function will return `Ok(())` if the closure does not panic, and will
+/// return `Err(cause)` if the closure panics. The `cause` returned is the
+/// object with which panic was originally invoked.
+///
+/// It is currently undefined behavior to unwind from Rust code into foreign
+/// code, so this function is particularly useful when Rust is called from
+/// another language (normally C). This can run arbitrary Rust code, capturing a
+/// panic and allowing a graceful handling of the error.
+///
+/// It is **not** recommended to use this function for a general try/catch
+/// mechanism. The `Result` type is more appropriate to use for functions that
+/// can fail on a regular basis.
+///
+/// The closure provided is required to adhere to the `'static` bound to ensure
+/// that it cannot reference data in the parent stack frame, mitigating problems
+/// with exception safety. Furthermore, a `Send` bound is also required,
+/// providing the same safety guarantees as `thread::spawn` (ensuring the
+/// closure is properly isolated from the parent).
+///
+/// # Examples
+///
+/// ```
+/// # #![feature(catch_panic)]
+/// use std::thread;
+///
+/// let result = thread::catch_panic(|| {
+///     println!("hello!");
+/// });
+/// assert!(result.is_ok());
+///
+/// let result = thread::catch_panic(|| {
+///     panic!("oh no!");
+/// });
+/// assert!(result.is_err());
+/// ```
+#[unstable(feature = "catch_panic", reason = "recent API addition")]
+pub fn catch_panic<F, R>(f: F) -> Result<R>
+    where F: FnOnce() -> R + Send + 'static
+{
+    let mut result = None;
+    unsafe {
+        let result = &mut result;
+        try!(::rt::unwind::try(move || *result = Some(f())))
+    }
+    Ok(result.unwrap())
+}
+
+/// Put the current thread to sleep for the specified amount of time.
+///
+/// The thread may sleep longer than the duration specified due to scheduling
+/// specifics or platform-dependent functionality. Note that on unix platforms
+/// this function will not return early due to a signal being received or a
+/// spurious wakeup.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn sleep_ms(ms: u32) {
+    imp::sleep(Duration::milliseconds(ms as i64))
+}
+
+/// Deprecated: use `sleep_ms` instead.
+#[unstable(feature = "thread_sleep",
+           reason = "recently added, needs an RFC, and `Duration` itself is \
+                     unstable")]
+#[deprecated(since = "1.0.0", reason = "use sleep_ms instead")]
+pub fn sleep(dur: Duration) {
+    imp::sleep(dur)
+}
+
+/// Block unless or until the current thread's token is made available (may wake spuriously).
+///
+/// See the module doc for more detail.
+//
+// The implementation currently uses the trivial strategy of a Mutex+Condvar
+// with wakeup flag, which does not actually allow spurious wakeups. In the
+// future, this will be implemented in a more efficient way, perhaps along the lines of
+//   http://cr.openjdk.java.net/~stefank/6989984.1/raw_files/new/src/os/linux/vm/os_linux.cpp
+// or futuxes, and in either case may allow spurious wakeups.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn park() {
+    let thread = current();
+    let mut guard = thread.inner.lock.lock().unwrap();
+    while !*guard {
+        guard = thread.inner.cvar.wait(guard).unwrap();
+    }
+    *guard = false;
+}
+
+/// Block unless or until the current thread's token is made available or
+/// the specified duration has been reached (may wake spuriously).
+///
+/// The semantics of this function are equivalent to `park()` except that the
+/// thread will be blocked for roughly no longer than *duration*. This method
+/// should not be used for precise timing due to anomalies such as
+/// preemption or platform differences that may not cause the maximum
+/// amount of time waited to be precisely *duration* long.
+///
+/// See the module doc for more detail.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub fn park_timeout_ms(ms: u32) {
+    let thread = current();
+    let mut guard = thread.inner.lock.lock().unwrap();
+    if !*guard {
+        let (g, _) = thread.inner.cvar.wait_timeout_ms(guard, ms).unwrap();
+        guard = g;
+    }
+    *guard = false;
+}
+
+/// Deprecated: use `park_timeout_ms`
+#[unstable(feature = "std_misc", reason = "recently introduced, depends on Duration")]
+#[deprecated(since = "1.0.0", reason = "use park_timeout_ms instead")]
+pub fn park_timeout(duration: Duration) {
+    park_timeout_ms(duration.num_milliseconds() as u32)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Thread
+////////////////////////////////////////////////////////////////////////////////
+
+/// The internal representation of a `Thread` handle
+struct Inner {
+    name: Option<String>,
+    lock: Mutex<bool>,          // true when there is a buffered unpark
+    cvar: Condvar,
+}
+
+unsafe impl Sync for Inner {}
+
+#[derive(Clone)]
+#[stable(feature = "rust1", since = "1.0.0")]
+/// A handle to a thread.
+pub struct Thread {
+    inner: Arc<Inner>,
+}
+
+impl Thread {
+    // Used only internally to construct a thread object without spawning
+    fn new(name: Option<String>) -> Thread {
+        Thread {
+            inner: Arc::new(Inner {
+                name: name,
+                lock: Mutex::new(false),
+                cvar: Condvar::new(),
+            })
+        }
+    }
+
+    /// Atomically makes the handle's token available if it is not already.
+    ///
+    /// See the module doc for more detail.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn unpark(&self) {
+        let mut guard = self.inner.lock.lock().unwrap();
+        if !*guard {
+            *guard = true;
+            self.inner.cvar.notify_one();
+        }
+    }
+
+    /// Get the thread's name.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn name(&self) -> Option<&str> {
+        self.inner.name.as_ref().map(|s| &**s)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Debug for Thread {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&self.name(), f)
+    }
+}
+
+// a hack to get around privacy restrictions
+impl thread_info::NewThread for Thread {
+    fn new(name: Option<String>) -> Thread { Thread::new(name) }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// JoinHandle and JoinGuard
+////////////////////////////////////////////////////////////////////////////////
+
+/// Indicates the manner in which a thread exited.
+///
+/// A thread that completes without panicking is considered to exit successfully.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub type Result<T> = ::result::Result<T, Box<Any + Send + 'static>>;
+
+struct Packet<T>(Arc<UnsafeCell<Option<Result<T>>>>);
+
+unsafe impl<T:Send> Send for Packet<T> {}
+unsafe impl<T> Sync for Packet<T> {}
+
+/// Inner representation for JoinHandle and JoinGuard
+struct JoinInner<T> {
+    native: imp::rust_thread,
+    thread: Thread,
+    packet: Packet<T>,
+    joined: bool,
+}
+
+impl<T> JoinInner<T> {
+    fn join(&mut self) -> Result<T> {
+        assert!(!self.joined);
+        unsafe { imp::join(self.native) };
+        self.joined = true;
+        unsafe {
+            (*self.packet.0.get()).take().unwrap()
+        }
+    }
+}
+
+/// An owned permission to join on a thread (block on its termination).
+///
+/// Unlike a `JoinGuard`, a `JoinHandle` *detaches* the child thread
+/// when it is dropped, rather than automatically joining on drop.
+///
+/// Due to platform restrictions, it is not possible to `Clone` this
+/// handle: the ability to join a child thread is a uniquely-owned
+/// permission.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct JoinHandle(JoinInner<()>);
+
+impl JoinHandle {
+    /// Extract a handle to the underlying thread
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn thread(&self) -> &Thread {
+        &self.0.thread
+    }
+
+    /// Wait for the associated thread to finish.
+    ///
+    /// If the child thread panics, `Err` is returned with the parameter given
+    /// to `panic`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn join(mut self) -> Result<()> {
+        self.0.join()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Drop for JoinHandle {
+    fn drop(&mut self) {
+        if !self.0.joined {
+            unsafe { imp::detach(self.0.native) }
+        }
+    }
+}
+
+/// An RAII-style guard that will block until thread termination when dropped.
+///
+/// The type `T` is the return type for the thread's main function.
+///
+/// Joining on drop is necessary to ensure memory safety when stack
+/// data is shared between a parent and child thread.
+///
+/// Due to platform restrictions, it is not possible to `Clone` this
+/// handle: the ability to join a child thread is a uniquely-owned
+/// permission.
+#[must_use = "thread will be immediately joined if `JoinGuard` is not used"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct JoinGuard<'a, T: Send + 'a> {
+    inner: JoinInner<T>,
+    _marker: PhantomData<&'a T>,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl<'a, T: Send + 'a> Sync for JoinGuard<'a, T> {}
+
+impl<'a, T: Send + 'a> JoinGuard<'a, T> {
+    /// Extract a handle to the thread this guard will join on.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn thread(&self) -> &Thread {
+        &self.inner.thread
+    }
+
+    /// Wait for the associated thread to finish, returning the result of the
+    /// thread's calculation.
+    ///
+    /// # Panics
+    ///
+    /// Panics on the child thread are propagated by panicking the parent.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn join(mut self) -> T {
+        match self.inner.join() {
+            Ok(res) => res,
+            Err(_) => panic!("child thread {:?} panicked", self.thread()),
+        }
+    }
+}
+
+#[unsafe_destructor]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: Send + 'a> Drop for JoinGuard<'a, T> {
+    fn drop(&mut self) {
+        if !self.inner.joined {
+            if self.inner.join().is_err() {
+                panic!("child thread {:?} panicked", self.thread());
+            }
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Tests
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(test)]
+mod test {
+    use prelude::v1::*;
+
+    use any::Any;
+    use sync::mpsc::{channel, Sender};
+    use result;
+    use std::old_io::{ChanReader, ChanWriter};
+    use super::{Builder};
+    use thread;
+    use thunk::Thunk;
+    use time::Duration;
+    use u32;
+
+    // !!! These tests are dangerous. If something is buggy, they will hang, !!!
+    // !!! instead of exiting cleanly. This might wedge the buildbots.       !!!
+
+    #[test]
+    fn test_unnamed_thread() {
+        thread::spawn(move|| {
+            assert!(thread::current().name().is_none());
+        }).join().ok().unwrap();
+    }
+
+    #[test]
+    fn test_named_thread() {
+        Builder::new().name("ada lovelace".to_string()).scoped(move|| {
+            assert!(thread::current().name().unwrap() == "ada lovelace".to_string());
+        }).unwrap().join();
+    }
+
+    #[test]
+    fn test_run_basic() {
+        let (tx, rx) = channel();
+        thread::spawn(move|| {
+            tx.send(()).unwrap();
+        });
+        rx.recv().unwrap();
+    }
+
+    #[test]
+    fn test_join_success() {
+        assert!(thread::scoped(move|| -> String {
+            "Success!".to_string()
+        }).join() == "Success!");
+    }
+
+    #[test]
+    fn test_join_panic() {
+        match thread::spawn(move|| {
+            panic!()
+        }).join() {
+            result::Result::Err(_) => (),
+            result::Result::Ok(()) => panic!()
+        }
+    }
+
+    #[test]
+    fn test_scoped_success() {
+        let res = thread::scoped(move|| -> String {
+            "Success!".to_string()
+        }).join();
+        assert!(res == "Success!");
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_scoped_panic() {
+        thread::scoped(|| panic!()).join();
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_scoped_implicit_panic() {
+        let _ = thread::scoped(|| panic!());
+    }
+
+    #[test]
+    fn test_spawn_sched() {
+        use clone::Clone;
+
+        let (tx, rx) = channel();
+
+        fn f(i: i32, tx: Sender<()>) {
+            let tx = tx.clone();
+            thread::spawn(move|| {
+                if i == 0 {
+                    tx.send(()).unwrap();
+                } else {
+                    f(i - 1, tx);
+                }
+            });
+
+        }
+        f(10, tx);
+        rx.recv().unwrap();
+    }
+
+    #[test]
+    fn test_spawn_sched_childs_on_default_sched() {
+        let (tx, rx) = channel();
+
+        thread::spawn(move|| {
+            thread::spawn(move|| {
+                tx.send(()).unwrap();
+            });
+        });
+
+        rx.recv().unwrap();
+    }
+
+    fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk<'static>) {
+        let (tx, rx) = channel();
+
+        let x: Box<_> = box 1;
+        let x_in_parent = (&*x) as *const i32 as usize;
+
+        spawnfn(Box::new(move|| {
+            let x_in_child = (&*x) as *const i32 as usize;
+            tx.send(x_in_child).unwrap();
+        }));
+
+        let x_in_child = rx.recv().unwrap();
+        assert_eq!(x_in_parent, x_in_child);
+    }
+
+    #[test]
+    fn test_avoid_copying_the_body_spawn() {
+        avoid_copying_the_body(|v| {
+            thread::spawn(move || v());
+        });
+    }
+
+    #[test]
+    fn test_avoid_copying_the_body_thread_spawn() {
+        avoid_copying_the_body(|f| {
+            thread::spawn(move|| {
+                f();
+            });
+        })
+    }
+
+    #[test]
+    fn test_avoid_copying_the_body_join() {
+        avoid_copying_the_body(|f| {
+            let _ = thread::spawn(move|| {
+                f()
+            }).join();
+        })
+    }
+
+    #[test]
+    fn test_child_doesnt_ref_parent() {
+        // If the child refcounts the parent task, this will stack overflow when
+        // climbing the task tree to dereference each ancestor. (See #1789)
+        // (well, it would if the constant were 8000+ - I lowered it to be more
+        // valgrind-friendly. try this at home, instead..!)
+        const GENERATIONS: u32 = 16;
+        fn child_no(x: u32) -> Thunk<'static> {
+            return Box::new(move|| {
+                if x < GENERATIONS {
+                    thread::spawn(move|| child_no(x+1)());
+                }
+            });
+        }
+        thread::spawn(|| child_no(0)());
+    }
+
+    #[test]
+    fn test_simple_newsched_spawn() {
+        thread::spawn(move || {});
+    }
+
+    #[test]
+    fn test_try_panic_message_static_str() {
+        match thread::spawn(move|| {
+            panic!("static string");
+        }).join() {
+            Err(e) => {
+                type T = &'static str;
+                assert!(e.is::<T>());
+                assert_eq!(*e.downcast::<T>().unwrap(), "static string");
+            }
+            Ok(()) => panic!()
+        }
+    }
+
+    #[test]
+    fn test_try_panic_message_owned_str() {
+        match thread::spawn(move|| {
+            panic!("owned string".to_string());
+        }).join() {
+            Err(e) => {
+                type T = String;
+                assert!(e.is::<T>());
+                assert_eq!(*e.downcast::<T>().unwrap(), "owned string".to_string());
+            }
+            Ok(()) => panic!()
+        }
+    }
+
+    #[test]
+    fn test_try_panic_message_any() {
+        match thread::spawn(move|| {
+            panic!(box 413u16 as Box<Any + Send>);
+        }).join() {
+            Err(e) => {
+                type T = Box<Any + Send>;
+                assert!(e.is::<T>());
+                let any = e.downcast::<T>().unwrap();
+                assert!(any.is::<u16>());
+                assert_eq!(*any.downcast::<u16>().unwrap(), 413);
+            }
+            Ok(()) => panic!()
+        }
+    }
+
+    #[test]
+    fn test_try_panic_message_unit_struct() {
+        struct Juju;
+
+        match thread::spawn(move|| {
+            panic!(Juju)
+        }).join() {
+            Err(ref e) if e.is::<Juju>() => {}
+            Err(_) | Ok(()) => panic!()
+        }
+    }
+
+    #[test]
+    fn test_park_timeout_unpark_before() {
+        for _ in 0..10 {
+            thread::current().unpark();
+            thread::park_timeout_ms(u32::MAX);
+        }
+    }
+
+    #[test]
+    fn test_park_timeout_unpark_not_called() {
+        for _ in 0..10 {
+            thread::park_timeout_ms(10);
+        }
+    }
+
+    #[test]
+    fn test_park_timeout_unpark_called_other_thread() {
+        use std::old_io;
+
+        for _ in 0..10 {
+            let th = thread::current();
+
+            let _guard = thread::spawn(move || {
+                old_io::timer::sleep(Duration::milliseconds(50));
+                th.unpark();
+            });
+
+            thread::park_timeout_ms(u32::MAX);
+        }
+    }
+
+    #[test]
+    fn sleep_ms_smoke() {
+        thread::sleep_ms(2);
+    }
+
+    // NOTE: the corresponding test for stderr is in run-pass/task-stderr, due
+    // to the test harness apparently interfering with stderr configuration.
+}
diff --git a/src/libstd/thread/scoped.rs b/src/libstd/thread/scoped.rs
new file mode 100644 (file)
index 0000000..b384879
--- /dev/null
@@ -0,0 +1,320 @@
+// Copyright 2014-2015 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.
+
+//! Scoped thread-local storage
+//!
+//! This module provides the ability to generate *scoped* thread-local
+//! variables. In this sense, scoped indicates that thread local storage
+//! actually stores a reference to a value, and this reference is only placed
+//! in storage for a scoped amount of time.
+//!
+//! There are no restrictions on what types can be placed into a scoped
+//! variable, but all scoped variables are initialized to the equivalent of
+//! null. Scoped thread local storage is useful when a value is present for a known
+//! period of time and it is not required to relinquish ownership of the
+//! contents.
+//!
+//! # Examples
+//!
+//! ```
+//! # #![feature(scoped_tls)]
+//! scoped_thread_local!(static FOO: u32);
+//!
+//! // Initially each scoped slot is empty.
+//! assert!(!FOO.is_set());
+//!
+//! // When inserting a value, the value is only in place for the duration
+//! // of the closure specified.
+//! FOO.set(&1, || {
+//!     FOO.with(|slot| {
+//!         assert_eq!(*slot, 1);
+//!     });
+//! });
+//! ```
+
+#![unstable(feature = "thread_local_internals")]
+
+use prelude::v1::*;
+
+// macro hygiene sure would be nice, wouldn't it?
+#[doc(hidden)]
+pub mod __impl {
+    pub use super::imp::KeyInner;
+    pub use sys_common::thread_local::INIT as OS_INIT;
+}
+
+/// Type representing a thread local storage key corresponding to a reference
+/// to the type parameter `T`.
+///
+/// Keys are statically allocated and can contain a reference to an instance of
+/// type `T` scoped to a particular lifetime. Keys provides two methods, `set`
+/// and `with`, both of which currently use closures to control the scope of
+/// their contents.
+#[unstable(feature = "scoped_tls",
+           reason = "scoped TLS has yet to have wide enough use to fully consider \
+                     stabilizing its interface")]
+pub struct ScopedKey<T> { #[doc(hidden)] pub inner: __impl::KeyInner<T> }
+
+/// Declare a new scoped thread local storage key.
+///
+/// This macro declares a `static` item on which methods are used to get and
+/// set the value stored within.
+#[macro_export]
+#[allow_internal_unstable]
+macro_rules! scoped_thread_local {
+    (static $name:ident: $t:ty) => (
+        __scoped_thread_local_inner!(static $name: $t);
+    );
+    (pub static $name:ident: $t:ty) => (
+        __scoped_thread_local_inner!(pub static $name: $t);
+    );
+}
+
+#[macro_export]
+#[doc(hidden)]
+#[allow_internal_unstable]
+macro_rules! __scoped_thread_local_inner {
+    (static $name:ident: $t:ty) => (
+        #[cfg_attr(not(any(windows,
+                           target_os = "android",
+                           target_os = "ios",
+                           target_os = "openbsd",
+                           target_arch = "aarch64")),
+                   thread_local)]
+        static $name: ::std::thread::ScopedKey<$t> =
+            __scoped_thread_local_inner!($t);
+    );
+    (pub static $name:ident: $t:ty) => (
+        #[cfg_attr(not(any(windows,
+                           target_os = "android",
+                           target_os = "ios",
+                           target_os = "openbsd",
+                           target_arch = "aarch64")),
+                   thread_local)]
+        pub static $name: ::std::thread::ScopedKey<$t> =
+            __scoped_thread_local_inner!($t);
+    );
+    ($t:ty) => ({
+        use std::thread::ScopedKey as __Key;
+
+        #[cfg(not(any(windows,
+                      target_os = "android",
+                      target_os = "ios",
+                      target_os = "openbsd",
+                      target_arch = "aarch64")))]
+        const _INIT: __Key<$t> = __Key {
+            inner: ::std::thread::__scoped::__impl::KeyInner {
+                inner: ::std::cell::UnsafeCell { value: 0 as *mut _ },
+            }
+        };
+
+        #[cfg(any(windows,
+                  target_os = "android",
+                  target_os = "ios",
+                  target_os = "openbsd",
+                  target_arch = "aarch64"))]
+        const _INIT: __Key<$t> = __Key {
+            inner: ::std::thread::__scoped::__impl::KeyInner {
+                inner: ::std::thread::__scoped::__impl::OS_INIT,
+                marker: ::std::marker::PhantomData::<::std::cell::Cell<$t>>,
+            }
+        };
+
+        _INIT
+    })
+}
+
+#[unstable(feature = "scoped_tls",
+           reason = "scoped TLS has yet to have wide enough use to fully consider \
+                     stabilizing its interface")]
+impl<T> ScopedKey<T> {
+    /// Insert a value into this scoped thread local storage slot for a
+    /// duration of a closure.
+    ///
+    /// While `cb` is running, the value `t` will be returned by `get` unless
+    /// this function is called recursively inside of `cb`.
+    ///
+    /// Upon return, this function will restore the previous value, if any
+    /// was available.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(scoped_tls)]
+    /// scoped_thread_local!(static FOO: u32);
+    ///
+    /// FOO.set(&100, || {
+    ///     let val = FOO.with(|v| *v);
+    ///     assert_eq!(val, 100);
+    ///
+    ///     // set can be called recursively
+    ///     FOO.set(&101, || {
+    ///         // ...
+    ///     });
+    ///
+    ///     // Recursive calls restore the previous value.
+    ///     let val = FOO.with(|v| *v);
+    ///     assert_eq!(val, 100);
+    /// });
+    /// ```
+    pub fn set<R, F>(&'static self, t: &T, cb: F) -> R where
+        F: FnOnce() -> R,
+    {
+        struct Reset<'a, T: 'a> {
+            key: &'a __impl::KeyInner<T>,
+            val: *mut T,
+        }
+        #[unsafe_destructor]
+        impl<'a, T> Drop for Reset<'a, T> {
+            fn drop(&mut self) {
+                unsafe { self.key.set(self.val) }
+            }
+        }
+
+        let prev = unsafe {
+            let prev = self.inner.get();
+            self.inner.set(t as *const T as *mut T);
+            prev
+        };
+
+        let _reset = Reset { key: &self.inner, val: prev };
+        cb()
+    }
+
+    /// Get a value out of this scoped variable.
+    ///
+    /// This function takes a closure which receives the value of this
+    /// variable.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic if `set` has not previously been called.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// # #![feature(scoped_tls)]
+    /// scoped_thread_local!(static FOO: u32);
+    ///
+    /// FOO.with(|slot| {
+    ///     // work with `slot`
+    /// });
+    /// ```
+    pub fn with<R, F>(&'static self, cb: F) -> R where
+        F: FnOnce(&T) -> R
+    {
+        unsafe {
+            let ptr = self.inner.get();
+            assert!(!ptr.is_null(), "cannot access a scoped thread local \
+                                     variable without calling `set` first");
+            cb(&*ptr)
+        }
+    }
+
+    /// Test whether this TLS key has been `set` for the current thread.
+    pub fn is_set(&'static self) -> bool {
+        unsafe { !self.inner.get().is_null() }
+    }
+}
+
+#[cfg(not(any(windows,
+              target_os = "android",
+              target_os = "ios",
+              target_os = "openbsd",
+              target_arch = "aarch64")))]
+mod imp {
+    use std::cell::UnsafeCell;
+
+    #[doc(hidden)]
+    pub struct KeyInner<T> { pub inner: UnsafeCell<*mut T> }
+
+    unsafe impl<T> ::marker::Sync for KeyInner<T> { }
+
+    #[doc(hidden)]
+    impl<T> KeyInner<T> {
+        #[doc(hidden)]
+        pub unsafe fn set(&self, ptr: *mut T) { *self.inner.get() = ptr; }
+        #[doc(hidden)]
+        pub unsafe fn get(&self) -> *mut T { *self.inner.get() }
+    }
+}
+
+#[cfg(any(windows,
+          target_os = "android",
+          target_os = "ios",
+          target_os = "openbsd",
+          target_arch = "aarch64"))]
+mod imp {
+    use marker;
+    use std::cell::Cell;
+    use sys_common::thread_local::StaticKey as OsStaticKey;
+
+    #[doc(hidden)]
+    pub struct KeyInner<T> {
+        pub inner: OsStaticKey,
+        pub marker: marker::PhantomData<Cell<T>>,
+    }
+
+    unsafe impl<T> ::marker::Sync for KeyInner<T> { }
+
+    #[doc(hidden)]
+    impl<T> KeyInner<T> {
+        #[doc(hidden)]
+        pub unsafe fn set(&self, ptr: *mut T) { self.inner.set(ptr as *mut _) }
+        #[doc(hidden)]
+        pub unsafe fn get(&self) -> *mut T { self.inner.get() as *mut _ }
+    }
+}
+
+
+#[cfg(test)]
+mod tests {
+    use cell::Cell;
+    use prelude::v1::*;
+
+    scoped_thread_local!(static FOO: u32);
+
+    #[test]
+    fn smoke() {
+        scoped_thread_local!(static BAR: u32);
+
+        assert!(!BAR.is_set());
+        BAR.set(&1, || {
+            assert!(BAR.is_set());
+            BAR.with(|slot| {
+                assert_eq!(*slot, 1);
+            });
+        });
+        assert!(!BAR.is_set());
+    }
+
+    #[test]
+    fn cell_allowed() {
+        scoped_thread_local!(static BAR: Cell<u32>);
+
+        BAR.set(&Cell::new(1), || {
+            BAR.with(|slot| {
+                assert_eq!(slot.get(), 1);
+            });
+        });
+    }
+
+    #[test]
+    fn scope_item_allowed() {
+        assert!(!FOO.is_set());
+        FOO.set(&1, || {
+            assert!(FOO.is_set());
+            FOO.with(|slot| {
+                assert_eq!(*slot, 1);
+            });
+        });
+        assert!(!FOO.is_set());
+    }
+}
diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs
deleted file mode 100644 (file)
index 2ed296e..0000000
+++ /dev/null
@@ -1,756 +0,0 @@
-// Copyright 2014-2015 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.
-
-//! Thread local storage
-//!
-//! This module provides an implementation of thread local storage for Rust
-//! programs. Thread local storage is a method of storing data into a global
-//! variable which each thread in the program will have its own copy of.
-//! Threads do not share this data, so accesses do not need to be synchronized.
-//!
-//! At a high level, this module provides two variants of storage:
-//!
-//! * Owning thread local storage. This is a type of thread local key which
-//!   owns the value that it contains, and will destroy the value when the
-//!   thread exits. This variant is created with the `thread_local!` macro and
-//!   can contain any value which is `'static` (no borrowed pointers.
-//!
-//! * Scoped thread local storage. This type of key is used to store a reference
-//!   to a value into local storage temporarily for the scope of a function
-//!   call. There are no restrictions on what types of values can be placed
-//!   into this key.
-//!
-//! Both forms of thread local storage provide an accessor function, `with`,
-//! which will yield a shared reference to the value to the specified
-//! closure. Thread local keys only allow shared access to values as there is no
-//! way to guarantee uniqueness if a mutable borrow was allowed. Most values
-//! will want to make use of some form of **interior mutability** through the
-//! `Cell` or `RefCell` types.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use prelude::v1::*;
-
-use cell::UnsafeCell;
-
-#[macro_use]
-pub mod scoped;
-
-// Sure wish we had macro hygiene, no?
-#[doc(hidden)]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub mod __impl {
-    pub use super::imp::Key as KeyInner;
-    pub use super::imp::destroy_value;
-    pub use sys_common::thread_local::INIT_INNER as OS_INIT_INNER;
-    pub use sys_common::thread_local::StaticKey as OsStaticKey;
-}
-
-/// A thread local storage key which owns its contents.
-///
-/// This key uses the fastest possible implementation available to it for the
-/// target platform. It is instantiated with the `thread_local!` macro and the
-/// primary method is the `with` method.
-///
-/// The `with` method yields a reference to the contained value which cannot be
-/// sent across tasks or escape the given closure.
-///
-/// # Initialization and Destruction
-///
-/// Initialization is dynamically performed on the first call to `with()`
-/// within a thread, and values support destructors which will be run when a
-/// thread exits.
-///
-/// # Example
-///
-/// ```
-/// use std::cell::RefCell;
-/// use std::thread;
-///
-/// thread_local!(static FOO: RefCell<uint> = RefCell::new(1));
-///
-/// FOO.with(|f| {
-///     assert_eq!(*f.borrow(), 1);
-///     *f.borrow_mut() = 2;
-/// });
-///
-/// // each thread starts out with the initial value of 1
-/// thread::spawn(move|| {
-///     FOO.with(|f| {
-///         assert_eq!(*f.borrow(), 1);
-///         *f.borrow_mut() = 3;
-///     });
-/// });
-///
-/// // we retain our original value of 2 despite the child thread
-/// FOO.with(|f| {
-///     assert_eq!(*f.borrow(), 2);
-/// });
-/// ```
-#[stable(feature = "rust1", since = "1.0.0")]
-pub struct Key<T> {
-    // The key itself may be tagged with #[thread_local], and this `Key` is
-    // stored as a `static`, and it's not valid for a static to reference the
-    // address of another thread_local static. For this reason we kinda wonkily
-    // work around this by generating a shim function which will give us the
-    // address of the inner TLS key at runtime.
-    //
-    // This is trivially devirtualizable by LLVM because we never store anything
-    // to this field and rustc can declare the `static` as constant as well.
-    #[doc(hidden)]
-    pub inner: fn() -> &'static __impl::KeyInner<UnsafeCell<Option<T>>>,
-
-    // initialization routine to invoke to create a value
-    #[doc(hidden)]
-    pub init: fn() -> T,
-}
-
-/// Declare a new thread local storage key of type `std::thread_local::Key`.
-#[macro_export]
-#[stable(feature = "rust1", since = "1.0.0")]
-macro_rules! thread_local {
-    (static $name:ident: $t:ty = $init:expr) => (
-        static $name: ::std::thread_local::Key<$t> = {
-            use std::cell::UnsafeCell as __UnsafeCell;
-            use std::thread_local::__impl::KeyInner as __KeyInner;
-            use std::option::Option as __Option;
-            use std::option::Option::None as __None;
-
-            __thread_local_inner!(static __KEY: __UnsafeCell<__Option<$t>> = {
-                __UnsafeCell { value: __None }
-            });
-            fn __init() -> $t { $init }
-            fn __getit() -> &'static __KeyInner<__UnsafeCell<__Option<$t>>> {
-                &__KEY
-            }
-            ::std::thread_local::Key { inner: __getit, init: __init }
-        };
-    );
-    (pub static $name:ident: $t:ty = $init:expr) => (
-        pub static $name: ::std::thread_local::Key<$t> = {
-            use std::cell::UnsafeCell as __UnsafeCell;
-            use std::thread_local::__impl::KeyInner as __KeyInner;
-            use std::option::Option as __Option;
-            use std::option::Option::None as __None;
-
-            __thread_local_inner!(static __KEY: __UnsafeCell<__Option<$t>> = {
-                __UnsafeCell { value: __None }
-            });
-            fn __init() -> $t { $init }
-            fn __getit() -> &'static __KeyInner<__UnsafeCell<__Option<$t>>> {
-                &__KEY
-            }
-            ::std::thread_local::Key { inner: __getit, init: __init }
-        };
-    );
-}
-
-// Macro pain #4586:
-//
-// When cross compiling, rustc will load plugins and macros from the *host*
-// platform before search for macros from the target platform. This is primarily
-// done to detect, for example, plugins. Ideally the macro below would be
-// defined once per module below, but unfortunately this means we have the
-// following situation:
-//
-// 1. We compile libstd for x86_64-unknown-linux-gnu, this thread_local!() macro
-//    will inject #[thread_local] statics.
-// 2. We then try to compile a program for arm-linux-androideabi
-// 3. The compiler has a host of linux and a target of android, so it loads
-//    macros from the *linux* libstd.
-// 4. The macro generates a #[thread_local] field, but the android libstd does
-//    not use #[thread_local]
-// 5. Compile error about structs with wrong fields.
-//
-// To get around this, we're forced to inject the #[cfg] logic into the macro
-// itself. Woohoo.
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! __thread_local_inner {
-    (static $name:ident: $t:ty = $init:expr) => (
-        #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
-                       not(target_arch = "aarch64")),
-                   thread_local)]
-        static $name: ::std::thread_local::__impl::KeyInner<$t> =
-            __thread_local_inner!($init, $t);
-    );
-    (pub static $name:ident: $t:ty = $init:expr) => (
-        #[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
-                       not(target_arch = "aarch64")),
-                   thread_local)]
-        pub static $name: ::std::thread_local::__impl::KeyInner<$t> =
-            __thread_local_inner!($init, $t);
-    );
-    ($init:expr, $t:ty) => ({
-        #[cfg(all(any(target_os = "macos", target_os = "linux"), not(target_arch = "aarch64")))]
-        const _INIT: ::std::thread_local::__impl::KeyInner<$t> = {
-            ::std::thread_local::__impl::KeyInner {
-                inner: ::std::cell::UnsafeCell { value: $init },
-                dtor_registered: ::std::cell::UnsafeCell { value: false },
-                dtor_running: ::std::cell::UnsafeCell { value: false },
-            }
-        };
-
-        #[cfg(any(not(any(target_os = "macos", target_os = "linux")), target_arch = "aarch64"))]
-        const _INIT: ::std::thread_local::__impl::KeyInner<$t> = {
-            unsafe extern fn __destroy(ptr: *mut u8) {
-                ::std::thread_local::__impl::destroy_value::<$t>(ptr);
-            }
-
-            ::std::thread_local::__impl::KeyInner {
-                inner: ::std::cell::UnsafeCell { value: $init },
-                os: ::std::thread_local::__impl::OsStaticKey {
-                    inner: ::std::thread_local::__impl::OS_INIT_INNER,
-                    dtor: ::std::option::Option::Some(__destroy as unsafe extern fn(*mut u8)),
-                },
-            }
-        };
-
-        _INIT
-    });
-}
-
-/// Indicator of the state of a thread local storage key.
-#[unstable(feature = "std_misc",
-           reason = "state querying was recently added")]
-#[derive(Eq, PartialEq, Copy)]
-pub enum State {
-    /// All keys are in this state whenever a thread starts. Keys will
-    /// transition to the `Valid` state once the first call to `with` happens
-    /// and the initialization expression succeeds.
-    ///
-    /// Keys in the `Uninitialized` state will yield a reference to the closure
-    /// passed to `with` so long as the initialization routine does not panic.
-    Uninitialized,
-
-    /// Once a key has been accessed successfully, it will enter the `Valid`
-    /// state. Keys in the `Valid` state will remain so until the thread exits,
-    /// at which point the destructor will be run and the key will enter the
-    /// `Destroyed` state.
-    ///
-    /// Keys in the `Valid` state will be guaranteed to yield a reference to the
-    /// closure passed to `with`.
-    Valid,
-
-    /// When a thread exits, the destructors for keys will be run (if
-    /// necessary). While a destructor is running, and possibly after a
-    /// destructor has run, a key is in the `Destroyed` state.
-    ///
-    /// Keys in the `Destroyed` states will trigger a panic when accessed via
-    /// `with`.
-    Destroyed,
-}
-
-impl<T: 'static> Key<T> {
-    /// Acquire a reference to the value in this TLS key.
-    ///
-    /// This will lazily initialize the value if this thread has not referenced
-    /// this key yet.
-    ///
-    /// # Panics
-    ///
-    /// This function will `panic!()` if the key currently has its
-    /// destructor running, and it **may** panic if the destructor has
-    /// previously been run for this thread.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn with<F, R>(&'static self, f: F) -> R
-                      where F: FnOnce(&T) -> R {
-        let slot = (self.inner)();
-        unsafe {
-            let slot = slot.get().expect("cannot access a TLS value during or \
-                                          after it is destroyed");
-            f(match *slot.get() {
-                Some(ref inner) => inner,
-                None => self.init(slot),
-            })
-        }
-    }
-
-    unsafe fn init(&self, slot: &UnsafeCell<Option<T>>) -> &T {
-        // Execute the initialization up front, *then* move it into our slot,
-        // just in case initialization fails.
-        let value = (self.init)();
-        let ptr = slot.get();
-        *ptr = Some(value);
-        (*ptr).as_ref().unwrap()
-    }
-
-    /// Query the current state of this key.
-    ///
-    /// A key is initially in the `Uninitialized` state whenever a thread
-    /// starts. It will remain in this state up until the first call to `with`
-    /// within a thread has run the initialization expression successfully.
-    ///
-    /// Once the initialization expression succeeds, the key transitions to the
-    /// `Valid` state which will guarantee that future calls to `with` will
-    /// succeed within the thread.
-    ///
-    /// When a thread exits, each key will be destroyed in turn, and as keys are
-    /// destroyed they will enter the `Destroyed` state just before the
-    /// destructor starts to run. Keys may remain in the `Destroyed` state after
-    /// destruction has completed. Keys without destructors (e.g. with types
-    /// that are `Copy`), may never enter the `Destroyed` state.
-    ///
-    /// Keys in the `Uninitialized` can be accessed so long as the
-    /// initialization does not panic. Keys in the `Valid` state are guaranteed
-    /// to be able to be accessed. Keys in the `Destroyed` state will panic on
-    /// any call to `with`.
-    #[unstable(feature = "std_misc",
-               reason = "state querying was recently added")]
-    pub fn state(&'static self) -> State {
-        unsafe {
-            match (self.inner)().get() {
-                Some(cell) => {
-                    match *cell.get() {
-                        Some(..) => State::Valid,
-                        None => State::Uninitialized,
-                    }
-                }
-                None => State::Destroyed,
-            }
-        }
-    }
-
-    /// Deprecated
-    #[unstable(feature = "std_misc")]
-    #[deprecated(since = "1.0.0",
-                 reason = "function renamed to state() and returns more info")]
-    pub fn destroyed(&'static self) -> bool { self.state() == State::Destroyed }
-}
-
-#[cfg(all(any(target_os = "macos", target_os = "linux"), not(target_arch = "aarch64")))]
-mod imp {
-    use prelude::v1::*;
-
-    use cell::UnsafeCell;
-    use intrinsics;
-    use ptr;
-
-    #[doc(hidden)]
-    #[stable(since = "1.0.0", feature = "rust1")]
-    pub struct Key<T> {
-        // Place the inner bits in an `UnsafeCell` to currently get around the
-        // "only Sync statics" restriction. This allows any type to be placed in
-        // the cell.
-        //
-        // Note that all access requires `T: 'static` so it can't be a type with
-        // any borrowed pointers still.
-        #[stable(since = "1.0.0", feature = "rust1")]
-        pub inner: UnsafeCell<T>,
-
-        // Metadata to keep track of the state of the destructor. Remember that
-        // these variables are thread-local, not global.
-        #[stable(since = "1.0.0", feature = "rust1")]
-        pub dtor_registered: UnsafeCell<bool>, // should be Cell
-        #[stable(since = "1.0.0", feature = "rust1")]
-        pub dtor_running: UnsafeCell<bool>, // should be Cell
-    }
-
-    unsafe impl<T> ::marker::Sync for Key<T> { }
-
-    #[doc(hidden)]
-    impl<T> Key<T> {
-        pub unsafe fn get(&'static self) -> Option<&'static T> {
-            if intrinsics::needs_drop::<T>() && *self.dtor_running.get() {
-                return None
-            }
-            self.register_dtor();
-            Some(&*self.inner.get())
-        }
-
-        unsafe fn register_dtor(&self) {
-            if !intrinsics::needs_drop::<T>() || *self.dtor_registered.get() {
-                return
-            }
-
-            register_dtor(self as *const _ as *mut u8,
-                          destroy_value::<T>);
-            *self.dtor_registered.get() = true;
-        }
-    }
-
-    // Since what appears to be glibc 2.18 this symbol has been shipped which
-    // GCC and clang both use to invoke destructors in thread_local globals, so
-    // let's do the same!
-    //
-    // Note, however, that we run on lots older linuxes, as well as cross
-    // compiling from a newer linux to an older linux, so we also have a
-    // fallback implementation to use as well.
-    //
-    // Due to rust-lang/rust#18804, make sure this is not generic!
-    #[cfg(target_os = "linux")]
-    unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
-        use mem;
-        use libc;
-        use sys_common::thread_local as os;
-
-        extern {
-            static __dso_handle: *mut u8;
-            #[linkage = "extern_weak"]
-            static __cxa_thread_atexit_impl: *const ();
-        }
-        if !__cxa_thread_atexit_impl.is_null() {
-            type F = unsafe extern fn(dtor: unsafe extern fn(*mut u8),
-                                      arg: *mut u8,
-                                      dso_handle: *mut u8) -> libc::c_int;
-            mem::transmute::<*const (), F>(__cxa_thread_atexit_impl)
-            (dtor, t, __dso_handle);
-            return
-        }
-
-        // The fallback implementation uses a vanilla OS-based TLS key to track
-        // the list of destructors that need to be run for this thread. The key
-        // then has its own destructor which runs all the other destructors.
-        //
-        // The destructor for DTORS is a little special in that it has a `while`
-        // loop to continuously drain the list of registered destructors. It
-        // *should* be the case that this loop always terminates because we
-        // provide the guarantee that a TLS key cannot be set after it is
-        // flagged for destruction.
-        static DTORS: os::StaticKey = os::StaticKey {
-            inner: os::INIT_INNER,
-            dtor: Some(run_dtors as unsafe extern "C" fn(*mut u8)),
-        };
-        type List = Vec<(*mut u8, unsafe extern fn(*mut u8))>;
-        if DTORS.get().is_null() {
-            let v: Box<List> = box Vec::new();
-            DTORS.set(mem::transmute(v));
-        }
-        let list: &mut List = &mut *(DTORS.get() as *mut List);
-        list.push((t, dtor));
-
-        unsafe extern fn run_dtors(mut ptr: *mut u8) {
-            while !ptr.is_null() {
-                let list: Box<List> = mem::transmute(ptr);
-                for &(ptr, dtor) in &*list {
-                    dtor(ptr);
-                }
-                ptr = DTORS.get();
-                DTORS.set(ptr::null_mut());
-            }
-        }
-    }
-
-    // OSX's analog of the above linux function is this _tlv_atexit function.
-    // The disassembly of thread_local globals in C++ (at least produced by
-    // clang) will have this show up in the output.
-    #[cfg(target_os = "macos")]
-    unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
-        extern {
-            fn _tlv_atexit(dtor: unsafe extern fn(*mut u8),
-                           arg: *mut u8);
-        }
-        _tlv_atexit(dtor, t);
-    }
-
-    #[doc(hidden)]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub unsafe extern fn destroy_value<T>(ptr: *mut u8) {
-        let ptr = ptr as *mut Key<T>;
-        // Right before we run the user destructor be sure to flag the
-        // destructor as running for this thread so calls to `get` will return
-        // `None`.
-        *(*ptr).dtor_running.get() = true;
-        ptr::read((*ptr).inner.get());
-    }
-}
-
-#[cfg(any(not(any(target_os = "macos", target_os = "linux")), target_arch = "aarch64"))]
-mod imp {
-    use prelude::v1::*;
-
-    use cell::UnsafeCell;
-    use mem;
-    use ptr;
-    use sys_common::thread_local::StaticKey as OsStaticKey;
-
-    #[doc(hidden)]
-    #[stable(since = "1.0.0", feature = "rust1")]
-    pub struct Key<T> {
-        // Statically allocated initialization expression, using an `UnsafeCell`
-        // for the same reasons as above.
-        #[stable(since = "1.0.0", feature = "rust1")]
-        pub inner: UnsafeCell<T>,
-
-        // OS-TLS key that we'll use to key off.
-        #[stable(since = "1.0.0", feature = "rust1")]
-        pub os: OsStaticKey,
-    }
-
-    unsafe impl<T> ::marker::Sync for Key<T> { }
-
-    struct Value<T: 'static> {
-        key: &'static Key<T>,
-        value: T,
-    }
-
-    #[doc(hidden)]
-    impl<T> Key<T> {
-        pub unsafe fn get(&'static self) -> Option<&'static T> {
-            self.ptr().map(|p| &*p)
-        }
-
-        unsafe fn ptr(&'static self) -> Option<*mut T> {
-            let ptr = self.os.get() as *mut Value<T>;
-            if !ptr.is_null() {
-                if ptr as uint == 1 {
-                    return None
-                }
-                return Some(&mut (*ptr).value as *mut T);
-            }
-
-            // If the lookup returned null, we haven't initialized our own local
-            // copy, so do that now.
-            //
-            // Also note that this transmute_copy should be ok because the value
-            // `inner` is already validated to be a valid `static` value, so we
-            // should be able to freely copy the bits.
-            let ptr: Box<Value<T>> = box Value {
-                key: self,
-                value: mem::transmute_copy(&self.inner),
-            };
-            let ptr: *mut Value<T> = mem::transmute(ptr);
-            self.os.set(ptr as *mut u8);
-            Some(&mut (*ptr).value as *mut T)
-        }
-    }
-
-    #[doc(hidden)]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub unsafe extern fn destroy_value<T: 'static>(ptr: *mut u8) {
-        // The OS TLS ensures that this key contains a NULL value when this
-        // destructor starts to run. We set it back to a sentinel value of 1 to
-        // ensure that any future calls to `get` for this thread will return
-        // `None`.
-        //
-        // Note that to prevent an infinite loop we reset it back to null right
-        // before we return from the destructor ourselves.
-        let ptr: Box<Value<T>> = mem::transmute(ptr);
-        let key = ptr.key;
-        key.os.set(1 as *mut u8);
-        drop(ptr);
-        key.os.set(ptr::null_mut());
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::v1::*;
-
-    use sync::mpsc::{channel, Sender};
-    use cell::UnsafeCell;
-    use super::State;
-    use thread;
-
-    struct Foo(Sender<()>);
-
-    impl Drop for Foo {
-        fn drop(&mut self) {
-            let Foo(ref s) = *self;
-            s.send(()).unwrap();
-        }
-    }
-
-    #[test]
-    fn smoke_no_dtor() {
-        thread_local!(static FOO: UnsafeCell<int> = UnsafeCell { value: 1 });
-
-        FOO.with(|f| unsafe {
-            assert_eq!(*f.get(), 1);
-            *f.get() = 2;
-        });
-        let (tx, rx) = channel();
-        let _t = thread::spawn(move|| {
-            FOO.with(|f| unsafe {
-                assert_eq!(*f.get(), 1);
-            });
-            tx.send(()).unwrap();
-        });
-        rx.recv().unwrap();
-
-        FOO.with(|f| unsafe {
-            assert_eq!(*f.get(), 2);
-        });
-    }
-
-    #[test]
-    fn states() {
-        struct Foo;
-        impl Drop for Foo {
-            fn drop(&mut self) {
-                assert!(FOO.state() == State::Destroyed);
-            }
-        }
-        fn foo() -> Foo {
-            assert!(FOO.state() == State::Uninitialized);
-            Foo
-        }
-        thread_local!(static FOO: Foo = foo());
-
-        thread::spawn(|| {
-            assert!(FOO.state() == State::Uninitialized);
-            FOO.with(|_| {
-                assert!(FOO.state() == State::Valid);
-            });
-            assert!(FOO.state() == State::Valid);
-        }).join().ok().unwrap();
-    }
-
-    #[test]
-    fn smoke_dtor() {
-        thread_local!(static FOO: UnsafeCell<Option<Foo>> = UnsafeCell {
-            value: None
-        });
-
-        let (tx, rx) = channel();
-        let _t = thread::spawn(move|| unsafe {
-            let mut tx = Some(tx);
-            FOO.with(|f| {
-                *f.get() = Some(Foo(tx.take().unwrap()));
-            });
-        });
-        rx.recv().unwrap();
-    }
-
-    #[test]
-    fn circular() {
-        struct S1;
-        struct S2;
-        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell {
-            value: None
-        });
-        thread_local!(static K2: UnsafeCell<Option<S2>> = UnsafeCell {
-            value: None
-        });
-        static mut HITS: uint = 0;
-
-        impl Drop for S1 {
-            fn drop(&mut self) {
-                unsafe {
-                    HITS += 1;
-                    if K2.state() == State::Destroyed {
-                        assert_eq!(HITS, 3);
-                    } else {
-                        if HITS == 1 {
-                            K2.with(|s| *s.get() = Some(S2));
-                        } else {
-                            assert_eq!(HITS, 3);
-                        }
-                    }
-                }
-            }
-        }
-        impl Drop for S2 {
-            fn drop(&mut self) {
-                unsafe {
-                    HITS += 1;
-                    assert!(K1.state() != State::Destroyed);
-                    assert_eq!(HITS, 2);
-                    K1.with(|s| *s.get() = Some(S1));
-                }
-            }
-        }
-
-        thread::spawn(move|| {
-            drop(S1);
-        }).join().ok().unwrap();
-    }
-
-    #[test]
-    fn self_referential() {
-        struct S1;
-        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell {
-            value: None
-        });
-
-        impl Drop for S1 {
-            fn drop(&mut self) {
-                assert!(K1.state() == State::Destroyed);
-            }
-        }
-
-        thread::spawn(move|| unsafe {
-            K1.with(|s| *s.get() = Some(S1));
-        }).join().ok().unwrap();
-    }
-
-    #[test]
-    fn dtors_in_dtors_in_dtors() {
-        struct S1(Sender<()>);
-        thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell {
-            value: None
-        });
-        thread_local!(static K2: UnsafeCell<Option<Foo>> = UnsafeCell {
-            value: None
-        });
-
-        impl Drop for S1 {
-            fn drop(&mut self) {
-                let S1(ref tx) = *self;
-                unsafe {
-                    if K2.state() != State::Destroyed {
-                        K2.with(|s| *s.get() = Some(Foo(tx.clone())));
-                    }
-                }
-            }
-        }
-
-        let (tx, rx) = channel();
-        let _t = thread::spawn(move|| unsafe {
-            let mut tx = Some(tx);
-            K1.with(|s| *s.get() = Some(S1(tx.take().unwrap())));
-        });
-        rx.recv().unwrap();
-    }
-}
-
-#[cfg(test)]
-mod dynamic_tests {
-    use prelude::v1::*;
-
-    use cell::RefCell;
-    use collections::HashMap;
-
-    #[test]
-    fn smoke() {
-        fn square(i: int) -> int { i * i }
-        thread_local!(static FOO: int = square(3));
-
-        FOO.with(|f| {
-            assert_eq!(*f, 9);
-        });
-    }
-
-    #[test]
-    fn hashmap() {
-        fn map() -> RefCell<HashMap<int, int>> {
-            let mut m = HashMap::new();
-            m.insert(1, 2);
-            RefCell::new(m)
-        }
-        thread_local!(static FOO: RefCell<HashMap<int, int>> = map());
-
-        FOO.with(|map| {
-            assert_eq!(map.borrow()[1], 2);
-        });
-    }
-
-    #[test]
-    fn refcell_vec() {
-        thread_local!(static FOO: RefCell<Vec<uint>> = RefCell::new(vec![1, 2, 3]));
-
-        FOO.with(|vec| {
-            assert_eq!(vec.borrow().len(), 3);
-            vec.borrow_mut().push(4);
-            assert_eq!(vec.borrow()[3], 4);
-        });
-    }
-}
diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs
deleted file mode 100644 (file)
index 01220e7..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright 2014-2015 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.
-
-//! Scoped thread-local storage
-//!
-//! This module provides the ability to generate *scoped* thread-local
-//! variables. In this sense, scoped indicates that thread local storage
-//! actually stores a reference to a value, and this reference is only placed
-//! in storage for a scoped amount of time.
-//!
-//! There are no restrictions on what types can be placed into a scoped
-//! variable, but all scoped variables are initialized to the equivalent of
-//! null. Scoped thread local storage is useful when a value is present for a known
-//! period of time and it is not required to relinquish ownership of the
-//! contents.
-//!
-//! # Example
-//!
-//! ```
-//! scoped_thread_local!(static FOO: uint);
-//!
-//! // Initially each scoped slot is empty.
-//! assert!(!FOO.is_set());
-//!
-//! // When inserting a value, the value is only in place for the duration
-//! // of the closure specified.
-//! FOO.set(&1, || {
-//!     FOO.with(|slot| {
-//!         assert_eq!(*slot, 1);
-//!     });
-//! });
-//! ```
-
-#![unstable(feature = "std_misc",
-            reason = "scoped TLS has yet to have wide enough use to fully consider \
-                      stabilizing its interface")]
-
-use prelude::v1::*;
-
-// macro hygiene sure would be nice, wouldn't it?
-#[doc(hidden)]
-pub mod __impl {
-    pub use super::imp::KeyInner;
-    pub use sys_common::thread_local::INIT as OS_INIT;
-}
-
-/// Type representing a thread local storage key corresponding to a reference
-/// to the type parameter `T`.
-///
-/// Keys are statically allocated and can contain a reference to an instance of
-/// type `T` scoped to a particular lifetime. Keys provides two methods, `set`
-/// and `with`, both of which currently use closures to control the scope of
-/// their contents.
-pub struct Key<T> { #[doc(hidden)] pub inner: __impl::KeyInner<T> }
-
-/// Declare a new scoped thread local storage key.
-///
-/// This macro declares a `static` item on which methods are used to get and
-/// set the value stored within.
-#[macro_export]
-macro_rules! scoped_thread_local {
-    (static $name:ident: $t:ty) => (
-        __scoped_thread_local_inner!(static $name: $t);
-    );
-    (pub static $name:ident: $t:ty) => (
-        __scoped_thread_local_inner!(pub static $name: $t);
-    );
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! __scoped_thread_local_inner {
-    (static $name:ident: $t:ty) => (
-        #[cfg_attr(not(any(windows,
-                           target_os = "android",
-                           target_os = "ios",
-                           target_os = "openbsd",
-                           target_arch = "aarch64")),
-                   thread_local)]
-        static $name: ::std::thread_local::scoped::Key<$t> =
-            __scoped_thread_local_inner!($t);
-    );
-    (pub static $name:ident: $t:ty) => (
-        #[cfg_attr(not(any(windows,
-                           target_os = "android",
-                           target_os = "ios",
-                           target_os = "openbsd",
-                           target_arch = "aarch64")),
-                   thread_local)]
-        pub static $name: ::std::thread_local::scoped::Key<$t> =
-            __scoped_thread_local_inner!($t);
-    );
-    ($t:ty) => ({
-        use std::thread_local::scoped::Key as __Key;
-
-        #[cfg(not(any(windows,
-                      target_os = "android",
-                      target_os = "ios",
-                      target_os = "openbsd",
-                      target_arch = "aarch64")))]
-        const _INIT: __Key<$t> = __Key {
-            inner: ::std::thread_local::scoped::__impl::KeyInner {
-                inner: ::std::cell::UnsafeCell { value: 0 as *mut _ },
-            }
-        };
-
-        #[cfg(any(windows,
-                  target_os = "android",
-                  target_os = "ios",
-                  target_os = "openbsd",
-                  target_arch = "aarch64"))]
-        const _INIT: __Key<$t> = __Key {
-            inner: ::std::thread_local::scoped::__impl::KeyInner {
-                inner: ::std::thread_local::scoped::__impl::OS_INIT,
-                marker: ::std::marker::InvariantType,
-            }
-        };
-
-        _INIT
-    })
-}
-
-impl<T> Key<T> {
-    /// Insert a value into this scoped thread local storage slot for a
-    /// duration of a closure.
-    ///
-    /// While `cb` is running, the value `t` will be returned by `get` unless
-    /// this function is called recursively inside of `cb`.
-    ///
-    /// Upon return, this function will restore the previous value, if any
-    /// was available.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// scoped_thread_local!(static FOO: uint);
-    ///
-    /// FOO.set(&100, || {
-    ///     let val = FOO.with(|v| *v);
-    ///     assert_eq!(val, 100);
-    ///
-    ///     // set can be called recursively
-    ///     FOO.set(&101, || {
-    ///         // ...
-    ///     });
-    ///
-    ///     // Recursive calls restore the previous value.
-    ///     let val = FOO.with(|v| *v);
-    ///     assert_eq!(val, 100);
-    /// });
-    /// ```
-    pub fn set<R, F>(&'static self, t: &T, cb: F) -> R where
-        F: FnOnce() -> R,
-    {
-        struct Reset<'a, T: 'a> {
-            key: &'a __impl::KeyInner<T>,
-            val: *mut T,
-        }
-        #[unsafe_destructor]
-        impl<'a, T> Drop for Reset<'a, T> {
-            fn drop(&mut self) {
-                unsafe { self.key.set(self.val) }
-            }
-        }
-
-        let prev = unsafe {
-            let prev = self.inner.get();
-            self.inner.set(t as *const T as *mut T);
-            prev
-        };
-
-        let _reset = Reset { key: &self.inner, val: prev };
-        cb()
-    }
-
-    /// Get a value out of this scoped variable.
-    ///
-    /// This function takes a closure which receives the value of this
-    /// variable.
-    ///
-    /// # Panics
-    ///
-    /// This function will panic if `set` has not previously been called.
-    ///
-    /// # Example
-    ///
-    /// ```no_run
-    /// scoped_thread_local!(static FOO: uint);
-    ///
-    /// FOO.with(|slot| {
-    ///     // work with `slot`
-    /// });
-    /// ```
-    pub fn with<R, F>(&'static self, cb: F) -> R where
-        F: FnOnce(&T) -> R
-    {
-        unsafe {
-            let ptr = self.inner.get();
-            assert!(!ptr.is_null(), "cannot access a scoped thread local \
-                                     variable without calling `set` first");
-            cb(&*ptr)
-        }
-    }
-
-    /// Test whether this TLS key has been `set` for the current thread.
-    pub fn is_set(&'static self) -> bool {
-        unsafe { !self.inner.get().is_null() }
-    }
-}
-
-#[cfg(not(any(windows,
-              target_os = "android",
-              target_os = "ios",
-              target_os = "openbsd",
-              target_arch = "aarch64")))]
-mod imp {
-    use std::cell::UnsafeCell;
-
-    #[doc(hidden)]
-    pub struct KeyInner<T> { pub inner: UnsafeCell<*mut T> }
-
-    unsafe impl<T> ::marker::Sync for KeyInner<T> { }
-
-    #[doc(hidden)]
-    impl<T> KeyInner<T> {
-        #[doc(hidden)]
-        pub unsafe fn set(&self, ptr: *mut T) { *self.inner.get() = ptr; }
-        #[doc(hidden)]
-        pub unsafe fn get(&self) -> *mut T { *self.inner.get() }
-    }
-}
-
-#[cfg(any(windows,
-          target_os = "android",
-          target_os = "ios",
-          target_os = "openbsd",
-          target_arch = "aarch64"))]
-mod imp {
-    use marker;
-    use sys_common::thread_local::StaticKey as OsStaticKey;
-
-    #[doc(hidden)]
-    pub struct KeyInner<T> {
-        pub inner: OsStaticKey,
-        pub marker: marker::InvariantType<T>,
-    }
-
-    unsafe impl<T> ::marker::Sync for KeyInner<T> { }
-
-    #[doc(hidden)]
-    impl<T> KeyInner<T> {
-        #[doc(hidden)]
-        pub unsafe fn set(&self, ptr: *mut T) { self.inner.set(ptr as *mut _) }
-        #[doc(hidden)]
-        pub unsafe fn get(&self) -> *mut T { self.inner.get() as *mut _ }
-    }
-}
-
-
-#[cfg(test)]
-mod tests {
-    use cell::Cell;
-    use prelude::v1::*;
-
-    scoped_thread_local!(static FOO: uint);
-
-    #[test]
-    fn smoke() {
-        scoped_thread_local!(static BAR: uint);
-
-        assert!(!BAR.is_set());
-        BAR.set(&1, || {
-            assert!(BAR.is_set());
-            BAR.with(|slot| {
-                assert_eq!(*slot, 1);
-            });
-        });
-        assert!(!BAR.is_set());
-    }
-
-    #[test]
-    fn cell_allowed() {
-        scoped_thread_local!(static BAR: Cell<uint>);
-
-        BAR.set(&Cell::new(1), || {
-            BAR.with(|slot| {
-                assert_eq!(slot.get(), 1);
-            });
-        });
-    }
-
-    #[test]
-    fn scope_item_allowed() {
-        assert!(!FOO.is_set());
-        FOO.set(&1, || {
-            assert!(FOO.is_set());
-            FOO.with(|slot| {
-                assert_eq!(*slot, 1);
-            });
-        });
-        assert!(!FOO.is_set());
-    }
-}
index fe39954f0d446fd5ae3b45d8971b097a8ecae6a6..6091794ed428660162d848512845e186a1b075a9 100644 (file)
 #![allow(missing_docs)]
 #![unstable(feature = "std_misc")]
 
-use alloc::boxed::Box;
+use alloc::boxed::{Box, FnBox};
 use core::marker::Send;
-use core::ops::FnOnce;
 
-pub struct Thunk<'a, A=(),R=()> {
-    #[cfg(stage0)]
-    invoke: Box<Invoke<A,R>+Send>,
-    #[cfg(not(stage0))]
-    invoke: Box<Invoke<A,R>+Send + 'a>,
-}
+pub type Thunk<'a, A=(), R=()> =
+    Box<FnBox<A,Output=R> + Send + 'a>;
 
-impl<'a, R> Thunk<'a,(),R> {
-    pub fn new<F>(func: F) -> Thunk<'a,(),R>
-        where F : FnOnce() -> R, F : Send + 'a
-    {
-        Thunk::with_arg(move|()| func())
-    }
-}
-
-impl<'a,A,R> Thunk<'a,A,R> {
-    pub fn with_arg<F>(func: F) -> Thunk<'a,A,R>
-        where F : FnOnce(A) -> R, F : Send + 'a
-    {
-        Thunk {
-            invoke: box func
-        }
-    }
-
-    pub fn invoke(self, arg: A) -> R {
-        self.invoke.invoke(arg)
-    }
-}
-
-pub trait Invoke<A=(),R=()> {
-    fn invoke(self: Box<Self>, arg: A) -> R;
-}
-
-impl<A,R,F> Invoke<A,R> for F
-    where F : FnOnce(A) -> R
-{
-    fn invoke(self: Box<F>, arg: A) -> R {
-        let f = *self;
-        f(arg)
-    }
-}
index 42ef3459a0ed7cf931f191e300a7940ca87b21e9..9b79b483b28cfbc77b27c21ee4ac2f9395ca1ebf 100644 (file)
@@ -16,6 +16,7 @@ use {fmt, i64};
 use ops::{Add, Sub, Mul, Div, Neg, FnOnce};
 use option::Option;
 use option::Option::{Some, None};
+#[allow(deprecated)] // Int
 use num::Int;
 use result::Result::Ok;
 
@@ -68,7 +69,7 @@ pub const MAX: Duration = Duration {
 
 impl Duration {
     /// Makes a new `Duration` with given number of weeks.
-    /// Equivalent to `Duration::seconds(weeks * 7 * 24 * 60 * 60), with overflow checks.
+    /// Equivalent to `Duration::seconds(weeks * 7 * 24 * 60 * 60)` with overflow checks.
     /// Panics when the duration is out of bounds.
     #[inline]
     #[unstable(feature = "std_misc")]
index 988b13cd160462b42fa62200dcc8fac8663d7005..41b70889c9f276f96735a7d473b56960bb8f64dd 100644 (file)
@@ -53,7 +53,7 @@
 //! assert!(b == c);
 //!
 //! let d : (u32, f32) = Default::default();
-//! assert_eq!(d, (0u32, 0.0f32));
+//! assert_eq!(d, (0, 0.0f32));
 //! ```
 
 #![doc(primitive = "tuple")]
index de3fa1135b161382d5cb13eb363c026cd72c6aae..27e331893e5d7fcd642113988baf2123092ef15a 100644 (file)
@@ -15,7 +15,7 @@ pub use self::AbiArchitecture::*;
 
 use std::fmt;
 
-#[derive(Copy, PartialEq, Eq, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum Os {
     OsWindows,
     OsMacos,
@@ -24,6 +24,7 @@ pub enum Os {
     OsFreebsd,
     OsiOS,
     OsDragonfly,
+    OsBitrig,
     OsOpenbsd,
 }
 
@@ -48,7 +49,7 @@ pub enum Abi {
 }
 
 #[allow(non_camel_case_types)]
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum Architecture {
     X86,
     X86_64,
@@ -57,7 +58,7 @@ pub enum Architecture {
     Mipsel
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct AbiData {
     abi: Abi,
 
@@ -65,7 +66,7 @@ pub struct AbiData {
     name: &'static str,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum AbiArchitecture {
     /// Not a real ABI (e.g., intrinsic)
     RustArch,
@@ -76,11 +77,11 @@ pub enum AbiArchitecture {
 }
 
 #[allow(non_upper_case_globals)]
-static AbiDatas: &'static [AbiData] = &[
+const AbiDatas: &'static [AbiData] = &[
     // Platform-specific ABIs
     AbiData {abi: Cdecl, name: "cdecl" },
     AbiData {abi: Stdcall, name: "stdcall" },
-    AbiData {abi: Fastcall, name:"fastcall" },
+    AbiData {abi: Fastcall, name: "fastcall" },
     AbiData {abi: Aapcs, name: "aapcs" },
     AbiData {abi: Win64, name: "win64" },
 
@@ -136,6 +137,7 @@ impl fmt::Display for Os {
             OsAndroid => "android".fmt(f),
             OsFreebsd => "freebsd".fmt(f),
             OsDragonfly => "dragonfly".fmt(f),
+            OsBitrig => "bitrig".fmt(f),
             OsOpenbsd => "openbsd".fmt(f),
         }
     }
index 140e21b5d04b756cb0a1abcf4e838f74a56e3231..40390765dde84b54b5addb290961af2fce61cb32 100644 (file)
@@ -22,7 +22,7 @@ pub use self::Expr_::*;
 pub use self::FloatTy::*;
 pub use self::FunctionRetTy::*;
 pub use self::ForeignItem_::*;
-pub use self::ImplItem::*;
+pub use self::ImplItem_::*;
 pub use self::InlinedItem::*;
 pub use self::IntTy::*;
 pub use self::Item_::*;
@@ -33,7 +33,6 @@ pub use self::LocalSource::*;
 pub use self::Mac_::*;
 pub use self::MacStmtStyle::*;
 pub use self::MetaItem_::*;
-pub use self::Method_::*;
 pub use self::Mutability::*;
 pub use self::Pat_::*;
 pub use self::PathListItem_::*;
@@ -44,7 +43,7 @@ pub use self::Stmt_::*;
 pub use self::StrStyle::*;
 pub use self::StructFieldKind::*;
 pub use self::TokenTree::*;
-pub use self::TraitItem::*;
+pub use self::TraitItem_::*;
 pub use self::Ty_::*;
 pub use self::TyParamBound::*;
 pub use self::UintTy::*;
@@ -58,12 +57,16 @@ pub use self::PathParameters::*;
 use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
 use abi::Abi;
 use ast_util;
+use ext::base;
+use ext::tt::macro_parser;
 use owned_slice::OwnedSlice;
 use parse::token::{InternedString, str_to_ident};
 use parse::token;
+use parse::lexer;
 use ptr::P;
 
 use std::fmt;
+#[allow(deprecated)]
 use std::num::Int;
 use std::rc::Rc;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
@@ -148,7 +151,7 @@ impl PartialEq for Ident {
 
 /// A SyntaxContext represents a chain of macro-expandings
 /// and renamings. Each macro expansion corresponds to
-/// a fresh usize
+/// a fresh u32
 
 // I'm representing this syntax context as an index into
 // a table, in order to work around a compiler bug
@@ -213,6 +216,7 @@ pub struct Lifetime {
     pub name: Name
 }
 
+/// A lifetime definition, eg `'a: 'b+'c+'d`
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct LifetimeDef {
     pub lifetime: Lifetime,
@@ -249,7 +253,9 @@ pub struct PathSegment {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum PathParameters {
+    /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
     AngleBracketedParameters(AngleBracketedParameterData),
+    /// The `(A,B)` and `C` in `Foo(A,B) -> C`
     ParenthesizedParameters(ParenthesizedParameterData),
 }
 
@@ -382,7 +388,7 @@ pub const CRATE_NODE_ID: NodeId = 0;
 /// When parsing and doing expansions, we initially give all AST nodes this AST
 /// node value. Then later, in the renumber pass, we renumber them to have
 /// small, positive ids.
-pub const DUMMY_NODE_ID: NodeId = -1;
+pub const DUMMY_NODE_ID: NodeId = !0;
 
 /// The AST represents all type param bounds as types.
 /// typeck::collect::compute_bounds matches these against
@@ -434,27 +440,37 @@ impl Generics {
     }
 }
 
+/// A `where` clause in a definition
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct WhereClause {
     pub id: NodeId,
     pub predicates: Vec<WherePredicate>,
 }
 
+/// A single predicate in a `where` clause
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum WherePredicate {
+    /// A type binding, eg `for<'c> Foo: Send+Clone+'c`
     BoundPredicate(WhereBoundPredicate),
+    /// A lifetime predicate, e.g. `'a: 'b+'c`
     RegionPredicate(WhereRegionPredicate),
+    /// An equality predicate (unsupported)
     EqPredicate(WhereEqPredicate)
 }
 
+/// A type bound, eg `for<'c> Foo: Send+Clone+'c`
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct WhereBoundPredicate {
     pub span: Span,
+    /// Any lifetimes from a `for` binding
     pub bound_lifetimes: Vec<LifetimeDef>,
+    /// The type being bounded
     pub bounded_ty: P<Ty>,
+    /// Trait and lifetime bounds (`Clone+Send+'static`)
     pub bounds: OwnedSlice<TyParamBound>,
 }
 
+/// A lifetime predicate, e.g. `'a: 'b+'c`
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct WhereRegionPredicate {
     pub span: Span,
@@ -462,6 +478,7 @@ pub struct WhereRegionPredicate {
     pub bounds: Vec<Lifetime>,
 }
 
+/// An equality predicate (unsupported), e.g. `T=int`
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct WhereEqPredicate {
     pub id: NodeId,
@@ -519,9 +536,13 @@ impl PartialEq for MetaItem_ {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Block {
+    /// Statements in a block
     pub stmts: Vec<P<Stmt>>,
+    /// An expression at the end of the block
+    /// without a semicolon, if any
     pub expr: Option<P<Expr>>,
     pub id: NodeId,
+    /// Distinguishes between `unsafe { ... }` and `{ ... }`
     pub rules: BlockCheckMode,
     pub span: Span,
 }
@@ -533,9 +554,16 @@ pub struct Pat {
     pub span: Span,
 }
 
+/// A single field in a struct pattern
+///
+/// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
+/// are treated the same as` x: x, y: ref y, z: ref mut z`,
+/// except is_shorthand is true
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct FieldPat {
+    /// The identifier for the field
     pub ident: Ident,
+    /// The pattern the field is destructured to
     pub pat: P<Pat>,
     pub is_shorthand: bool,
 }
@@ -563,6 +591,7 @@ pub enum Pat_ {
     /// A PatIdent may either be a new bound variable,
     /// or a nullary enum (in which case the third field
     /// is None).
+    ///
     /// In the nullary enum case, the parser can't determine
     /// which it is. The resolver determines this, and
     /// records this pattern's NodeId in an auxiliary
@@ -572,15 +601,23 @@ pub enum Pat_ {
     /// "None" means a * pattern where we don't bind the fields to names.
     PatEnum(Path, Option<Vec<P<Pat>>>),
 
+    /// Destructuring of a struct, e.g. `Foo {x, y, ..}`
+    /// The `bool` is `true` in the presence of a `..`
     PatStruct(Path, Vec<Spanned<FieldPat>>, bool),
+    /// A tuple pattern `(a, b)`
     PatTup(Vec<P<Pat>>),
+    /// A `box` pattern
     PatBox(P<Pat>),
-    PatRegion(P<Pat>, Mutability), // reference pattern
+    /// A reference pattern, e.g. `&mut (a, b)`
+    PatRegion(P<Pat>, Mutability),
+    /// A literal
     PatLit(P<Expr>),
+    /// A range pattern, e.g. `1...2`
     PatRange(P<Expr>, P<Expr>),
     /// [a, b, ..i, y, z] is represented as:
     ///     PatVec(box [a, b], Some(i), box [y, z])
     PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
+    /// A macro pattern; pre-expansion
     PatMac(Mac),
 }
 
@@ -592,23 +629,41 @@ pub enum Mutability {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
 pub enum BinOp_ {
+    /// The `+` operator (addition)
     BiAdd,
+    /// The `-` operator (subtraction)
     BiSub,
+    /// The `*` operator (multiplication)
     BiMul,
+    /// The `/` operator (division)
     BiDiv,
+    /// The `%` operator (modulus)
     BiRem,
+    /// The `&&` operator (logical and)
     BiAnd,
+    /// The `||` operator (logical or)
     BiOr,
+    /// The `^` operator (bitwise xor)
     BiBitXor,
+    /// The `&` operator (bitwise and)
     BiBitAnd,
+    /// The `|` operator (bitwise or)
     BiBitOr,
+    /// The `<<` operator (shift left)
     BiShl,
+    /// The `>>` operator (shift right)
     BiShr,
+    /// The `==` operator (equality)
     BiEq,
+    /// The `<` operator (less than)
     BiLt,
+    /// The `<=` operator (less than or equal to)
     BiLe,
+    /// The `!=` operator (not equal to)
     BiNe,
+    /// The `>=` operator (greater than or equal to)
     BiGe,
+    /// The `>` operator (greater than)
     BiGt,
 }
 
@@ -616,12 +671,17 @@ pub type BinOp = Spanned<BinOp_>;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
 pub enum UnOp {
+    /// The `box` operator
     UnUniq,
+    /// The `*` operator for dereferencing
     UnDeref,
+    /// The `!` operator for logical inversion
     UnNot,
+    /// The `-` operator for negation
     UnNeg
 }
 
+/// A statement
 pub type Stmt = Spanned<Stmt_>;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
@@ -666,6 +726,7 @@ pub enum LocalSource {
 pub struct Local {
     pub pat: P<Pat>,
     pub ty: Option<P<Ty>>,
+    /// Initializer expression to set the value, if any
     pub init: Option<P<Expr>>,
     pub id: NodeId,
     pub span: Span,
@@ -712,6 +773,7 @@ pub enum UnsafeSource {
     UserProvided,
 }
 
+/// An expression
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Expr {
     pub id: NodeId,
@@ -723,71 +785,149 @@ pub struct Expr {
 pub enum Expr_ {
     /// First expr is the place; second expr is the value.
     ExprBox(Option<P<Expr>>, P<Expr>),
+    /// An array (`[a, b, c, d]`)
     ExprVec(Vec<P<Expr>>),
+    /// A function call
+    ///
+    /// The first field resolves to the function itself,
+    /// and the second field is the list of arguments
     ExprCall(P<Expr>, Vec<P<Expr>>),
+    /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
+    ///
+    /// The `SpannedIdent` is the identifier for the method name.
+    /// The vector of `Ty`s are the ascripted type parameters for the method
+    /// (within the angle brackets).
+    ///
+    /// The first element of the vector of `Expr`s is the expression that evaluates
+    /// to the object on which the method is being called on (the receiver),
+    /// and the remaining elements are the rest of the arguments.
+    ///
+    /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
+    /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
     ExprMethodCall(SpannedIdent, Vec<P<Ty>>, Vec<P<Expr>>),
+    /// A tuple (`(a, b, c ,d)`)
     ExprTup(Vec<P<Expr>>),
+    /// A binary operation (For example: `a + b`, `a * b`)
     ExprBinary(BinOp, P<Expr>, P<Expr>),
+    /// A unary operation (For example: `!x`, `*x`)
     ExprUnary(UnOp, P<Expr>),
+    /// A literal (For example: `1u8`, `"foo"`)
     ExprLit(P<Lit>),
+    /// A cast (`foo as f64`)
     ExprCast(P<Expr>, P<Ty>),
+    /// An `if` block, with an optional else block
+    ///
+    /// `if expr { block } else { expr }`
     ExprIf(P<Expr>, P<Block>, Option<P<Expr>>),
+    /// An `if let` expression with an optional else block
+    ///
+    /// `if let pat = expr { block } else { expr }`
+    ///
+    /// This is desugared to a `match` expression.
     ExprIfLet(P<Pat>, P<Expr>, P<Block>, Option<P<Expr>>),
     // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
+    /// A while loop, with an optional label
+    ///
+    /// `'label: while expr { block }`
     ExprWhile(P<Expr>, P<Block>, Option<Ident>),
     // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
+    /// A while-let loop, with an optional label
+    ///
+    /// `'label: while let pat = expr { block }`
+    ///
+    /// This is desugared to a combination of `loop` and `match` expressions.
     ExprWhileLet(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
     // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
+    /// A for loop, with an optional label
+    ///
+    /// `'label: for pat in expr { block }`
+    ///
+    /// This is desugared to a combination of `loop` and `match` expressions.
     ExprForLoop(P<Pat>, P<Expr>, P<Block>, Option<Ident>),
-    // Conditionless loop (can be exited with break, cont, or ret)
+    /// Conditionless loop (can be exited with break, continue, or return)
+    ///
+    /// `'label: loop { block }`
     // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     ExprLoop(P<Block>, Option<Ident>),
+    /// A `match` block, with a source that indicates whether or not it is
+    /// the result of a desugaring, and if so, which kind.
     ExprMatch(P<Expr>, Vec<Arm>, MatchSource),
+    /// A closure (for example, `move |a, b, c| {a + b + c}`)
     ExprClosure(CaptureClause, P<FnDecl>, P<Block>),
+    /// A block (`{ ... }`)
     ExprBlock(P<Block>),
 
+    /// An assignment (`a = foo()`)
     ExprAssign(P<Expr>, P<Expr>),
+    /// An assignment with an operator
+    ///
+    /// For example, `a += 1`.
     ExprAssignOp(BinOp, P<Expr>, P<Expr>),
+    /// Access of a named struct field (`obj.foo`)
     ExprField(P<Expr>, SpannedIdent),
+    /// Access of an unnamed field of a struct or tuple-struct
+    ///
+    /// For example, `foo.0`.
     ExprTupField(P<Expr>, Spanned<usize>),
+    /// An indexing operation (`foo[2]`)
     ExprIndex(P<Expr>, P<Expr>),
+    /// A range (`1..2`, `1..`, or `..2`)
     ExprRange(Option<P<Expr>>, Option<P<Expr>>),
 
-    /// Variable reference, possibly containing `::` and/or
-    /// type parameters, e.g. foo::bar::<baz>
-    ExprPath(Path),
-    /// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType`
-    ExprQPath(P<QPath>),
+    /// Variable reference, possibly containing `::` and/or type
+    /// parameters, e.g. foo::bar::<baz>.
+    ///
+    /// Optionally "qualified",
+    /// e.g. `<Vec<T> as SomeTrait>::SomeType`.
+    ExprPath(Option<QSelf>, Path),
 
+    /// A referencing operation (`&a` or `&mut a`)
     ExprAddrOf(Mutability, P<Expr>),
+    /// A `break`, with an optional label to break
     ExprBreak(Option<Ident>),
+    /// A `continue`, with an optional label
     ExprAgain(Option<Ident>),
+    /// A `return`, with an optional value to be returned
     ExprRet(Option<P<Expr>>),
 
+    /// Output of the `asm!()` macro
     ExprInlineAsm(InlineAsm),
 
+    /// A macro invocation; pre-expansion
     ExprMac(Mac),
 
     /// A struct literal expression.
-    ExprStruct(Path, Vec<Field>, Option<P<Expr>> /* base */),
+    ///
+    /// For example, `Foo {x: 1, y: 2}`, or
+    /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
+    ExprStruct(Path, Vec<Field>, Option<P<Expr>>),
 
     /// A vector literal constructed from one repeated element.
-    ExprRepeat(P<Expr> /* element */, P<Expr> /* count */),
+    ///
+    /// For example, `[1u8; 5]`. The first expression is the element
+    /// to be repeated; the second is the number of times to repeat it.
+    ExprRepeat(P<Expr>, P<Expr>),
 
     /// No-op: used solely so we can pretty-print faithfully
     ExprParen(P<Expr>)
 }
 
-/// A "qualified path":
+/// The explicit Self type in a "qualified path". The actual
+/// path, including the trait and the associated item, is stored
+/// separately. `position` represents the index of the associated
+/// item qualified with this Self type.
+///
+///     <Vec<T> as a::b::Trait>::AssociatedItem
+///      ^~~~~     ~~~~~~~~~~~~~~^
+///      ty        position = 3
 ///
-///     <Vec<T> as SomeTrait>::SomeAssociatedItem
-///      ^~~~~     ^~~~~~~~~   ^~~~~~~~~~~~~~~~~~
-///      self_type  trait_name  item_path
+///     <Vec<T>>::AssociatedItem
+///      ^~~~~    ^
+///      ty       position = 0
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct QPath {
-    pub self_type: P<Ty>,
-    pub trait_ref: P<TraitRef>,
-    pub item_path: PathSegment,
+pub struct QSelf {
+    pub ty: P<Ty>,
+    pub position: usize
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
@@ -873,7 +1013,6 @@ pub enum KleeneOp {
 /// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
 /// Nothing special happens to misnamed or misplaced `SubstNt`s.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-#[doc="For macro invocations; parsing is delegated to the macro"]
 pub enum TokenTree {
     /// A single token
     TtToken(Span, token::Token),
@@ -955,6 +1094,18 @@ impl TokenTree {
             TtSequence(span, _)  => span,
         }
     }
+
+    /// Use this token tree as a matcher to parse given tts.
+    pub fn parse(cx: &base::ExtCtxt, mtch: &[TokenTree], tts: &[TokenTree])
+                 -> macro_parser::NamedParseResult {
+        // `None` is because we're not interpolating
+        let arg_rdr = lexer::new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic,
+                                                         None,
+                                                         None,
+                                                         tts.iter().cloned().collect(),
+                                                         true);
+        macro_parser::parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtch)
+    }
 }
 
 pub type Mac = Spanned<Mac_>;
@@ -962,6 +1113,7 @@ pub type Mac = Spanned<Mac_>;
 /// Represents a macro invocation. The Path indicates which macro
 /// is being invoked, and the vector of token-trees contains the source
 /// of the macro invocation.
+///
 /// There's only one flavor, now, so this could presumably be simplified.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Mac_ {
@@ -972,10 +1124,15 @@ pub enum Mac_ {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
 pub enum StrStyle {
+    /// A regular string, like `"foo"`
     CookedStr,
+    /// A raw string, like `r##"foo"##`
+    ///
+    /// The uint is the number of `#` symbols used
     RawStr(usize)
 }
 
+/// A literal
 pub type Lit = Spanned<Lit_>;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
@@ -985,6 +1142,7 @@ pub enum Sign {
 }
 
 impl Sign {
+    #[allow(deprecated)] // Int
     pub fn new<T:Int>(n: T) -> Sign {
         if n < Int::zero() {
             Minus
@@ -1013,13 +1171,21 @@ impl LitIntType {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Lit_ {
+    /// A string literal (`"foo"`)
     LitStr(InternedString, StrStyle),
+    /// A byte string (`b"foo"`)
     LitBinary(Rc<Vec<u8>>),
+    /// A byte char (`b'f'`)
     LitByte(u8),
+    /// A character literal (`'a'`)
     LitChar(char),
+    /// An integer literal (`1u8`)
     LitInt(u64, LitIntType),
+    /// A float literal (`1f64` or `1E10f64`)
     LitFloat(InternedString, FloatTy),
+    /// A float literal without a suffix (`1.0 or 1.0E10`)
     LitFloatUnsuffixed(InternedString),
+    /// A boolean literal
     LitBool(bool),
 }
 
@@ -1038,20 +1204,15 @@ pub struct TypeField {
     pub span: Span,
 }
 
-/// Represents a required method in a trait declaration,
-/// one without a default implementation
+/// Represents a method's signature in a trait declaration,
+/// or in an implementation.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct TypeMethod {
-    pub ident: Ident,
-    pub attrs: Vec<Attribute>,
+pub struct MethodSig {
     pub unsafety: Unsafety,
     pub abi: Abi,
     pub decl: P<FnDecl>,
     pub generics: Generics,
     pub explicit_self: ExplicitSelf,
-    pub id: NodeId,
-    pub span: Span,
-    pub vis: Visibility,
 }
 
 /// Represents a method declaration in a trait declaration, possibly including
@@ -1059,57 +1220,46 @@ pub struct TypeMethod {
 /// doesn't have an implementation, just a signature) or provided (meaning it
 /// has a default implementation).
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TraitItem {
-    RequiredMethod(TypeMethod),
-    ProvidedMethod(P<Method>),
-    TypeTraitItem(P<AssociatedType>),
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum ImplItem {
-    MethodImplItem(P<Method>),
-    TypeImplItem(P<Typedef>),
+pub struct TraitItem {
+    pub id: NodeId,
+    pub ident: Ident,
+    pub attrs: Vec<Attribute>,
+    pub node: TraitItem_,
+    pub span: Span,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct AssociatedType {
-    pub attrs: Vec<Attribute>,
-    pub ty_param: TyParam,
+pub enum TraitItem_ {
+    MethodTraitItem(MethodSig, Option<P<Block>>),
+    TypeTraitItem(TyParamBounds, Option<P<Ty>>),
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Typedef {
+pub struct ImplItem {
     pub id: NodeId,
-    pub span: Span,
     pub ident: Ident,
     pub vis: Visibility,
     pub attrs: Vec<Attribute>,
-    pub typ: P<Ty>,
+    pub node: ImplItem_,
+    pub span: Span,
+}
+
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum ImplItem_ {
+    MethodImplItem(MethodSig, P<Block>),
+    TypeImplItem(P<Ty>),
+    MacImplItem(Mac),
 }
 
-#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
 pub enum IntTy {
-    TyIs(bool /* is this deprecated `int`? */),
+    TyIs,
     TyI8,
     TyI16,
     TyI32,
     TyI64,
 }
 
-impl PartialEq for IntTy {
-    fn eq(&self, other: &IntTy) -> bool {
-        match (*self, *other) {
-            // true/false need to compare the same, so this can't be derived
-            (TyIs(_), TyIs(_)) |
-            (TyI8, TyI8) |
-            (TyI16, TyI16) |
-            (TyI32, TyI32) |
-            (TyI64, TyI64) => true,
-            _ => false
-        }
-    }
-}
-
 impl fmt::Debug for IntTy {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(self, f)
@@ -1125,41 +1275,25 @@ impl fmt::Display for IntTy {
 impl IntTy {
     pub fn suffix_len(&self) -> usize {
         match *self {
-            TyIs(true) /* i */ => 1,
-            TyIs(false) /* is */ | TyI8 => 2,
+            TyIs | TyI8 => 2,
             TyI16 | TyI32 | TyI64  => 3,
         }
     }
 }
 
-#[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
 pub enum UintTy {
-    TyUs(bool /* is this deprecated uint? */),
+    TyUs,
     TyU8,
     TyU16,
     TyU32,
     TyU64,
 }
 
-impl PartialEq for UintTy {
-    fn eq(&self, other: &UintTy) -> bool {
-        match (*self, *other) {
-            // true/false need to compare the same, so this can't be derived
-            (TyUs(_), TyUs(_)) |
-            (TyU8, TyU8) |
-            (TyU16, TyU16) |
-            (TyU32, TyU32) |
-            (TyU64, TyU64) => true,
-            _ => false
-        }
-    }
-}
-
 impl UintTy {
     pub fn suffix_len(&self) -> usize {
         match *self {
-            TyUs(true) /* u */ => 1,
-            TyUs(false) /* us */ | TyU8 => 2,
+            TyUs | TyU8 => 2,
             TyU16 | TyU32 | TyU64  => 3,
         }
     }
@@ -1244,7 +1378,7 @@ pub struct BareFnTy {
 /// The different kinds of types recognized by the compiler
 pub enum Ty_ {
     TyVec(P<Ty>),
-    /// A fixed length array (`[T, ..n]`)
+    /// A fixed length array (`[Tn]`)
     TyFixedLengthVec(P<Ty>, P<Expr>),
     /// A raw pointer (`*const T` or `*mut T`)
     TyPtr(MutTy),
@@ -1254,16 +1388,15 @@ pub enum Ty_ {
     TyBareFn(P<BareFnTy>),
     /// A tuple (`(A, B, C, D,...)`)
     TyTup(Vec<P<Ty>> ),
-    /// A path (`module::module::...::Type`) or primitive
+    /// A path (`module::module::...::Type`), optionally
+    /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
     ///
     /// Type parameters are stored in the Path itself
-    TyPath(Path, NodeId),
+    TyPath(Option<QSelf>, Path),
     /// Something like `A+B`. Note that `B` must always be a path.
     TyObjectSum(P<Ty>, TyParamBounds),
     /// A type like `for<'a> Foo<&'a Bar>`
     TyPolyTraitRef(TyParamBounds),
-    /// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType`
-    TyQPath(P<QPath>),
     /// No-op; kept solely so that we can pretty-print faithfully
     TyParen(P<Ty>),
     /// Unused for now
@@ -1320,7 +1453,7 @@ impl Arg {
     }
 }
 
-/// represents the header (not the body) of a function declaration
+/// Represents the header (not the body) of a function declaration
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct FnDecl {
     pub inputs: Vec<Arg>,
@@ -1345,9 +1478,9 @@ impl fmt::Display for Unsafety {
 
 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
 pub enum ImplPolarity {
-    /// impl Trait for Type
+    /// `impl Trait for Type`
     Positive,
-    /// impl !Trait for Type
+    /// `impl !Trait for Type`
     Negative,
 }
 
@@ -1363,10 +1496,12 @@ impl fmt::Debug for ImplPolarity {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum FunctionRetTy {
-    /// Functions with return type that always
+    /// Functions with return type `!`that always
     /// raise an error or exit (i.e. never return to the caller)
     NoReturn(Span),
-    /// Return type is not specified. Functions default to () and
+    /// Return type is not specified.
+    ///
+    /// Functions default to `()` and
     /// closures default to inference. Span points to where return
     /// type would be inserted.
     DefaultReturn(Span),
@@ -1399,29 +1534,6 @@ pub enum ExplicitSelf_ {
 
 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
 
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct Method {
-    pub attrs: Vec<Attribute>,
-    pub id: NodeId,
-    pub span: Span,
-    pub node: Method_,
-}
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum Method_ {
-    /// Represents a method declaration
-    MethDecl(Ident,
-             Generics,
-             Abi,
-             ExplicitSelf,
-             Unsafety,
-             P<FnDecl>,
-             P<Block>,
-             Visibility),
-    /// Represents a macro in method position
-    MethMac(Mac),
-}
-
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Mod {
     /// A span from the first token past `{` to the last token until `}`.
@@ -1445,7 +1557,9 @@ pub struct VariantArg {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum VariantKind {
+    /// Tuple variant, e.g. `Foo(A, B)`
     TupleVariantKind(Vec<VariantArg>),
+    /// Struct variant, e.g. `Foo {x: A, y: B}`
     StructVariantKind(P<StructDef>),
 }
 
@@ -1460,6 +1574,7 @@ pub struct Variant_ {
     pub attrs: Vec<Attribute>,
     pub kind: VariantKind,
     pub id: NodeId,
+    /// Explicit discriminant, eg `Foo = 1`
     pub disr_expr: Option<P<Expr>>,
     pub vis: Visibility,
 }
@@ -1526,6 +1641,7 @@ pub struct Attribute_ {
 }
 
 /// TraitRef's appear in impls.
+///
 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
 /// If this impl is an ItemImpl, the impl_id is redundant (it could be the
@@ -1610,6 +1726,9 @@ pub struct StructDef {
   FIXME (#3300): Should allow items to be anonymous. Right now
   we just use dummy names for anon items.
  */
+/// An item
+///
+/// The name might be a dummy name in case of anonymous items
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct Item {
     pub ident: Ident,
@@ -1622,31 +1741,46 @@ pub struct Item {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Item_ {
-    // Optional location (containing arbitrary characters) from which
-    // to fetch the crate sources.
-    // For example, extern crate whatever = "github.com/rust-lang/rust".
-    ItemExternCrate(Option<(InternedString, StrStyle)>),
+    /// An`extern crate` item, with optional original crate name,
+    ///
+    /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
+    ItemExternCrate(Option<Name>),
+    /// A `use` or `pub use` item
     ItemUse(P<ViewPath>),
 
+    /// A `static` item
     ItemStatic(P<Ty>, Mutability, P<Expr>),
+    /// A `const` item
     ItemConst(P<Ty>, P<Expr>),
+    /// A function declaration
     ItemFn(P<FnDecl>, Unsafety, Abi, Generics, P<Block>),
+    /// A module
     ItemMod(Mod),
+    /// An external module
     ItemForeignMod(ForeignMod),
+    /// A type alias, e.g. `type Foo = Bar<u8>`
     ItemTy(P<Ty>, Generics),
+    /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
     ItemEnum(EnumDef, Generics),
+    /// A struct definition, e.g. `struct Foo<A> {x: A}`
     ItemStruct(P<StructDef>, Generics),
     /// Represents a Trait Declaration
     ItemTrait(Unsafety,
               Generics,
               TyParamBounds,
-              Vec<TraitItem>),
+              Vec<P<TraitItem>>),
+
+    // Default trait implementations
+    ///
+    // `impl Trait for .. {}`
+    ItemDefaultImpl(Unsafety, TraitRef),
+    /// An implementation, eg `impl<A> Trait for Foo { .. }`
     ItemImpl(Unsafety,
              ImplPolarity,
              Generics,
              Option<TraitRef>, // (optional) trait this impl implements
              P<Ty>, // self
-             Vec<ImplItem>),
+             Vec<P<ImplItem>>),
     /// A macro invocation (which includes macro definition)
     ItemMac(Mac),
 }
@@ -1666,7 +1800,8 @@ impl Item_ {
             ItemStruct(..) => "struct",
             ItemTrait(..) => "trait",
             ItemMac(..) |
-            ItemImpl(..) => "item"
+            ItemImpl(..) |
+            ItemDefaultImpl(..) => "item"
         }
     }
 }
@@ -1681,10 +1816,14 @@ pub struct ForeignItem {
     pub vis: Visibility,
 }
 
+/// An item within an `extern` block
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum ForeignItem_ {
+    /// A foreign function
     ForeignItemFn(P<FnDecl>, Generics),
-    ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
+    /// A foreign static item (`static ext: u8`), with optional mutability
+    /// (the boolean is true when mutable)
+    ForeignItemStatic(P<Ty>, bool),
 }
 
 impl ForeignItem_ {
@@ -1702,8 +1841,8 @@ impl ForeignItem_ {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum InlinedItem {
     IIItem(P<Item>),
-    IITraitItem(DefId /* impl id */, TraitItem),
-    IIImplItem(DefId /* impl id */, ImplItem),
+    IITraitItem(DefId /* impl id */, P<TraitItem>),
+    IIImplItem(DefId /* impl id */, P<ImplItem>),
     IIForeign(P<ForeignItem>),
 }
 
@@ -1719,6 +1858,7 @@ pub struct MacroDef {
     pub imported_from: Option<Ident>,
     pub export: bool,
     pub use_locally: bool,
+    pub allow_internal_unstable: bool,
     pub body: Vec<TokenTree>,
 }
 
index 1a537c7a5b8f89fdd7f5b3623c3750c6c714eed4..475970ac30a75c972aaaa029adf92edcd1166dd5 100644 (file)
@@ -26,9 +26,8 @@ pub use self::Code::*;
 use abi;
 use ast::{Block, FnDecl, NodeId};
 use ast;
-use ast_map::{Node};
+use ast_map::Node;
 use ast_map;
-use ast_util::PostExpansionMethod;
 use codemap::Span;
 use visit;
 
@@ -41,7 +40,7 @@ use visit;
 ///   - The default implementation for a trait method.
 ///
 /// To construct one, use the `Code::from_node` function.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct FnLikeNode<'a> { node: ast_map::Node<'a> }
 
 /// MaybeFnLike wraps a method that indicates if an object
@@ -65,7 +64,7 @@ impl MaybeFnLike for ast::Item {
 
 impl MaybeFnLike for ast::TraitItem {
     fn is_fn_like(&self) -> bool {
-        match *self { ast::ProvidedMethod(_) => true, _ => false, }
+        match self.node { ast::MethodTraitItem(_, Some(_)) => true, _ => false, }
     }
 }
 
@@ -81,7 +80,7 @@ impl MaybeFnLike for ast::Expr {
 /// Carries either an FnLikeNode or a Block, as these are the two
 /// constructs that correspond to "code" (as in, something from which
 /// we can construct a control-flow graph).
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum Code<'a> {
     FnLikeCode(FnLikeNode<'a>),
     BlockCode(&'a Block),
@@ -156,25 +155,25 @@ impl<'a> FnLikeNode<'a> {
 
     pub fn body(self) -> &'a Block {
         self.handle(|i: ItemFnParts<'a>|  &*i.body,
-                    |m: &'a ast::Method|  m.pe_body(),
+                    |_, _, _: &'a ast::MethodSig, body: &'a ast::Block, _|  body,
                     |c: ClosureParts<'a>| c.body)
     }
 
     pub fn decl(self) -> &'a FnDecl {
         self.handle(|i: ItemFnParts<'a>|  &*i.decl,
-                    |m: &'a ast::Method|  m.pe_fn_decl(),
+                    |_, _, sig: &'a ast::MethodSig, _, _|  &sig.decl,
                     |c: ClosureParts<'a>| c.decl)
     }
 
     pub fn span(self) -> Span {
         self.handle(|i: ItemFnParts|     i.span,
-                    |m: &'a ast::Method| m.span,
+                    |_, _, _: &'a ast::MethodSig, _, span| span,
                     |c: ClosureParts|    c.span)
     }
 
     pub fn id(self) -> NodeId {
         self.handle(|i: ItemFnParts|     i.id,
-                    |m: &'a ast::Method| m.id,
+                    |id, _, _: &'a ast::MethodSig, _, _| id,
                     |c: ClosureParts|    c.id)
     }
 
@@ -185,15 +184,15 @@ impl<'a> FnLikeNode<'a> {
         let closure = |_: ClosureParts| {
             visit::FkFnBlock
         };
-        let method = |m: &'a ast::Method| {
-            visit::FkMethod(m.pe_ident(), m.pe_generics(), m)
+        let method = |_, ident, sig: &'a ast::MethodSig, _, _| {
+            visit::FkMethod(ident, sig)
         };
         self.handle(item, method, closure)
     }
 
     fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where
         I: FnOnce(ItemFnParts<'a>) -> A,
-        M: FnOnce(&'a ast::Method) -> A,
+        M: FnOnce(NodeId, ast::Ident, &'a ast::MethodSig, &'a ast::Block, Span) -> A,
         C: FnOnce(ClosureParts<'a>) -> A,
     {
         match self.node {
@@ -205,14 +204,19 @@ impl<'a> FnLikeNode<'a> {
                     }),
                 _ => panic!("item FnLikeNode that is not fn-like"),
             },
-            ast_map::NodeTraitItem(t) => match *t {
-                ast::ProvidedMethod(ref m) => method(&**m),
+            ast_map::NodeTraitItem(ti) => match ti.node {
+                ast::MethodTraitItem(ref sig, Some(ref body)) => {
+                    method(ti.id, ti.ident, sig, body, ti.span)
+                }
                 _ => panic!("trait method FnLikeNode that is not fn-like"),
             },
             ast_map::NodeImplItem(ii) => {
-                match *ii {
-                    ast::MethodImplItem(ref m) => method(&**m),
-                    ast::TypeImplItem(_) => {
+                match ii.node {
+                    ast::MethodImplItem(ref sig, ref body) => {
+                        method(ii.id, ii.ident, sig, body, ii.span)
+                    }
+                    ast::TypeImplItem(_) |
+                    ast::MacImplItem(_) => {
                         panic!("impl method FnLikeNode that is not fn-like")
                     }
                 }
index ba08f61b5575ccef6c7817b9ddc712605b296a1e..2a9a609ecd1e9dcbc89278eb04806f1c88dd77c0 100644 (file)
@@ -19,13 +19,12 @@ use codemap::{DUMMY_SP, Span, Spanned};
 use fold::Folder;
 use parse::token;
 use print::pprust;
-use ptr::P;
 use visit::{self, Visitor};
 
 use arena::TypedArena;
 use std::cell::RefCell;
 use std::fmt;
-use std::old_io::IoResult;
+use std::io;
 use std::iter::{self, repeat};
 use std::mem;
 use std::slice;
@@ -54,18 +53,29 @@ impl fmt::Display for PathElem {
 }
 
 #[derive(Clone)]
-struct LinkedPathNode<'a> {
+pub struct LinkedPathNode<'a> {
     node: PathElem,
     next: LinkedPath<'a>,
 }
 
-type LinkedPath<'a> = Option<&'a LinkedPathNode<'a>>;
+#[derive(Copy, Clone)]
+pub struct LinkedPath<'a>(Option<&'a LinkedPathNode<'a>>);
+
+impl<'a> LinkedPath<'a> {
+    pub fn empty() -> LinkedPath<'a> {
+        LinkedPath(None)
+    }
+
+    pub fn from(node: &'a LinkedPathNode) -> LinkedPath<'a> {
+        LinkedPath(Some(node))
+    }
+}
 
 impl<'a> Iterator for LinkedPath<'a> {
     type Item = PathElem;
 
     fn next(&mut self) -> Option<PathElem> {
-        match *self {
+        match self.0 {
             Some(node) => {
                 *self = node.next;
                 Some(node.node)
@@ -91,7 +101,7 @@ pub fn path_to_string<PI: Iterator<Item=PathElem>>(path: PI) -> String {
     })
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 pub enum Node<'ast> {
     NodeItem(&'ast Item),
     NodeForeignItem(&'ast ForeignItem),
@@ -375,35 +385,8 @@ impl<'ast> Map<'ast> {
                 }
             }
             NodeForeignItem(i) => PathName(i.ident.name),
-            NodeImplItem(ii) => {
-                match *ii {
-                    MethodImplItem(ref m) => {
-                        match m.node {
-                            MethDecl(ident, _, _, _, _, _, _, _) => {
-                                PathName(ident.name)
-                            }
-                            MethMac(_) => {
-                                panic!("no path elem for {:?}", node)
-                            }
-                        }
-                    }
-                    TypeImplItem(ref t) => PathName(t.ident.name),
-                }
-            },
-            NodeTraitItem(tm) => match *tm {
-                RequiredMethod(ref m) => PathName(m.ident.name),
-                ProvidedMethod(ref m) => {
-                    match m.node {
-                        MethDecl(ident, _, _, _, _, _, _, _) => {
-                            PathName(ident.name)
-                        }
-                        MethMac(_) => panic!("no path elem for {:?}", node),
-                    }
-                }
-                TypeTraitItem(ref m) => {
-                    PathName(m.ty_param.ident.name)
-                }
-            },
+            NodeImplItem(ii) => PathName(ii.ident.name),
+            NodeTraitItem(ti) => PathName(ti.ident.name),
             NodeVariant(v) => PathName(v.node.name.name),
             _ => panic!("no path elem for {:?}", node)
         }
@@ -412,7 +395,7 @@ impl<'ast> Map<'ast> {
     pub fn with_path<T, F>(&self, id: NodeId, f: F) -> T where
         F: FnOnce(PathElems) -> T,
     {
-        self.with_path_next(id, None, f)
+        self.with_path_next(id, LinkedPath::empty(), f)
     }
 
     pub fn path_to_string(&self, id: NodeId) -> String {
@@ -450,42 +433,30 @@ impl<'ast> Map<'ast> {
                 _ => f([].iter().cloned().chain(next))
             }
         } else {
-            self.with_path_next(parent, Some(&LinkedPathNode {
+            self.with_path_next(parent, LinkedPath::from(&LinkedPathNode {
                 node: self.get_path_elem(id),
                 next: next
             }), f)
         }
     }
 
-    /// Given a node ID and a closure, apply the closure to the array
-    /// of attributes associated with the AST corresponding to the Node ID
-    pub fn with_attrs<T, F>(&self, id: NodeId, f: F) -> T where
-        F: FnOnce(Option<&[Attribute]>) -> T,
-    {
-        let attrs = match self.get(id) {
-            NodeItem(i) => Some(&i.attrs[..]),
-            NodeForeignItem(fi) => Some(&fi.attrs[..]),
-            NodeTraitItem(ref tm) => match **tm {
-                RequiredMethod(ref type_m) => Some(&type_m.attrs[..]),
-                ProvidedMethod(ref m) => Some(&m.attrs[..]),
-                TypeTraitItem(ref typ) => Some(&typ.attrs[..]),
-            },
-            NodeImplItem(ref ii) => {
-                match **ii {
-                    MethodImplItem(ref m) => Some(&m.attrs[..]),
-                    TypeImplItem(ref t) => Some(&t.attrs[..]),
-                }
-            }
-            NodeVariant(ref v) => Some(&v.node.attrs[..]),
+    /// Given a node ID, get a list of of attributes associated with the AST
+    /// corresponding to the Node ID
+    pub fn attrs(&self, id: NodeId) -> &'ast [Attribute] {
+        let attrs = match self.find(id) {
+            Some(NodeItem(i)) => Some(&i.attrs[..]),
+            Some(NodeForeignItem(fi)) => Some(&fi.attrs[..]),
+            Some(NodeTraitItem(ref ti)) => Some(&ti.attrs[..]),
+            Some(NodeImplItem(ref ii)) => Some(&ii.attrs[..]),
+            Some(NodeVariant(ref v)) => Some(&v.node.attrs[..]),
             // unit/tuple structs take the attributes straight from
             // the struct definition.
-            // FIXME(eddyb) make this work again (requires access to the map).
-            NodeStructCtor(_) => {
-                return self.with_attrs(self.get_parent(id), f);
+            Some(NodeStructCtor(_)) => {
+                return self.attrs(self.get_parent(id));
             }
             _ => None
         };
-        f(attrs)
+        attrs.unwrap_or(&[])
     }
 
     /// Returns an iterator that yields the node id's with paths that
@@ -509,19 +480,8 @@ impl<'ast> Map<'ast> {
         let sp = match self.find(id) {
             Some(NodeItem(item)) => item.span,
             Some(NodeForeignItem(foreign_item)) => foreign_item.span,
-            Some(NodeTraitItem(trait_method)) => {
-                match *trait_method {
-                    RequiredMethod(ref type_method) => type_method.span,
-                    ProvidedMethod(ref method) => method.span,
-                    TypeTraitItem(ref typedef) => typedef.ty_param.span,
-                }
-            }
-            Some(NodeImplItem(ref impl_item)) => {
-                match **impl_item {
-                    MethodImplItem(ref method) => method.span,
-                    TypeImplItem(ref typedef) => typedef.span,
-                }
-            }
+            Some(NodeTraitItem(trait_method)) => trait_method.span,
+            Some(NodeImplItem(ref impl_item)) => impl_item.span,
             Some(NodeVariant(variant)) => variant.span,
             Some(NodeExpr(expr)) => expr.span,
             Some(NodeStmt(stmt)) => stmt.span,
@@ -654,31 +614,8 @@ impl<T:Named> Named for Spanned<T> { fn name(&self) -> Name { self.node.name() }
 impl Named for Item { fn name(&self) -> Name { self.ident.name } }
 impl Named for ForeignItem { fn name(&self) -> Name { self.ident.name } }
 impl Named for Variant_ { fn name(&self) -> Name { self.name.name } }
-impl Named for TraitItem {
-    fn name(&self) -> Name {
-        match *self {
-            RequiredMethod(ref tm) => tm.ident.name,
-            ProvidedMethod(ref m) => m.name(),
-            TypeTraitItem(ref at) => at.ty_param.ident.name,
-        }
-    }
-}
-impl Named for ImplItem {
-    fn name(&self) -> Name {
-        match *self {
-            MethodImplItem(ref m) => m.name(),
-            TypeImplItem(ref td) => td.ident.name,
-        }
-    }
-}
-impl Named for Method {
-    fn name(&self) -> Name {
-        match self.node {
-            MethDecl(i, _, _, _, _, _, _, _) => i.name,
-            MethMac(_) => panic!("encountered unexpanded method macro."),
-        }
-    }
-}
+impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } }
+impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } }
 
 pub trait FoldOps {
     fn new_id(&self, id: NodeId) -> NodeId {
@@ -743,15 +680,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
         self.parent = i.id;
         match i.node {
             ItemImpl(_, _, _, _, _, ref impl_items) => {
-                for impl_item in impl_items {
-                    match *impl_item {
-                        MethodImplItem(ref m) => {
-                            self.insert(m.id, NodeImplItem(impl_item));
-                        }
-                        TypeImplItem(ref t) => {
-                            self.insert(t.id, NodeImplItem(impl_item));
-                        }
-                    }
+                for ii in impl_items {
+                    self.insert(ii.id, NodeImplItem(ii));
                 }
             }
             ItemEnum(ref enum_definition, _) => {
@@ -780,18 +710,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
                     }
                 }
 
-                for tm in trait_items {
-                    match *tm {
-                        RequiredMethod(ref m) => {
-                            self.insert(m.id, NodeTraitItem(tm));
-                        }
-                        ProvidedMethod(ref m) => {
-                            self.insert(m.id, NodeTraitItem(tm));
-                        }
-                        TypeTraitItem(ref typ) => {
-                            self.insert(typ.ty_param.id, NodeTraitItem(tm));
-                        }
-                    }
+                for ti in trait_items {
+                    self.insert(ti.id, NodeTraitItem(ti));
                 }
             }
             _ => {}
@@ -800,6 +720,20 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
         self.parent = parent;
     }
 
+    fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
+        let parent = self.parent;
+        self.parent = ti.id;
+        visit::walk_trait_item(self, ti);
+        self.parent = parent;
+    }
+
+    fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
+        let parent = self.parent;
+        self.parent = ii.id;
+        visit::walk_impl_item(self, ii);
+        self.parent = parent;
+    }
+
     fn visit_pat(&mut self, pat: &'ast Pat) {
         self.insert(pat.id, match pat.node {
             // Note: this is at least *potentially* a pattern...
@@ -819,29 +753,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
         visit::walk_stmt(self, stmt);
     }
 
-    fn visit_ty_method(&mut self, m: &'ast TypeMethod) {
-        let parent = self.parent;
-        self.parent = m.id;
-        self.visit_fn_decl(&*m.decl);
-        visit::walk_ty_method(self, m);
-        self.parent = parent;
-    }
-
     fn visit_fn(&mut self, fk: visit::FnKind<'ast>, fd: &'ast FnDecl,
-                b: &'ast Block, s: Span, id: NodeId) {
-        match fk {
-            visit::FkMethod(..) => {
-                let parent = self.parent;
-                self.parent = id;
-                self.visit_fn_decl(fd);
-                visit::walk_fn(self, fk, fd, b, s);
-                self.parent = parent;
-            }
-            _ => {
-                self.visit_fn_decl(fd);
-                visit::walk_fn(self, fk, fd, b, s);
-            }
-        }
+                b: &'ast Block, s: Span, _: NodeId) {
+        self.visit_fn_decl(fd);
+        visit::walk_fn(self, fk, fd, b, s);
     }
 
     fn visit_ty(&mut self, ty: &'ast Ty) {
@@ -923,33 +838,14 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
     let mut fld = IdAndSpanUpdater { fold_ops: fold_ops };
     let ii = match ii {
         IIItem(i) => IIItem(fld.fold_item(i).expect_one("expected one item")),
-        IITraitItem(d, ti) => match ti {
-            ProvidedMethod(m) => {
-                IITraitItem(fld.fold_ops.new_def_id(d),
-                            ProvidedMethod(fld.fold_method(m)
-                                              .expect_one("expected one method")))
-            }
-            RequiredMethod(ty_m) => {
-                IITraitItem(fld.fold_ops.new_def_id(d),
-                            RequiredMethod(fld.fold_type_method(ty_m)))
-            }
-            TypeTraitItem(at) => {
-                IITraitItem(
-                    fld.fold_ops.new_def_id(d),
-                    TypeTraitItem(P(fld.fold_associated_type((*at).clone()))))
-            }
-        },
-        IIImplItem(d, m) => match m {
-            MethodImplItem(m) => {
-                IIImplItem(fld.fold_ops.new_def_id(d),
-                           MethodImplItem(fld.fold_method(m)
-                                             .expect_one("expected one method")))
-            }
-            TypeImplItem(t) => {
-                IIImplItem(fld.fold_ops.new_def_id(d),
-                           TypeImplItem(P(fld.fold_typedef((*t).clone()))))
-            }
-        },
+        IITraitItem(d, ti) => {
+            IITraitItem(fld.fold_ops.new_def_id(d),
+                        fld.fold_trait_item(ti).expect_one("expected one trait item"))
+        }
+        IIImplItem(d, ii) => {
+            IIImplItem(fld.fold_ops.new_def_id(d),
+                       fld.fold_impl_item(ii).expect_one("expected one impl item"))
+        }
         IIForeign(i) => IIForeign(fld.fold_foreign_item(i))
     };
 
@@ -971,25 +867,14 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
     // add it to the table now. Likewise with foreign items.
     match ii_parent.ii {
         IIItem(_) => {}
-        IITraitItem(_, ref trait_item) => {
-            let trait_item_id = match *trait_item {
-                ProvidedMethod(ref m) => m.id,
-                RequiredMethod(ref m) => m.id,
-                TypeTraitItem(ref ty) => ty.ty_param.id,
-            };
-
-            collector.insert(trait_item_id, NodeTraitItem(trait_item));
+        IITraitItem(_, ref ti) => {
+            collector.insert(ti.id, NodeTraitItem(ti));
         }
-        IIImplItem(_, ref impl_item) => {
-            let impl_item_id = match *impl_item {
-                MethodImplItem(ref m) => m.id,
-                TypeImplItem(ref ti) => ti.id,
-            };
-
-            collector.insert(impl_item_id, NodeImplItem(impl_item));
+        IIImplItem(_, ref ii) => {
+            collector.insert(ii.id, NodeImplItem(ii));
         }
         IIForeign(ref i) => {
-            collector.insert(i.id, NodeForeignItem(&**i));
+            collector.insert(i.id, NodeForeignItem(i));
         }
     }
     *map.map.borrow_mut() = collector.map;
@@ -997,16 +882,16 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
 }
 
 pub trait NodePrinter {
-    fn print_node(&mut self, node: &Node) -> IoResult<()>;
+    fn print_node(&mut self, node: &Node) -> io::Result<()>;
 }
 
 impl<'a> NodePrinter for pprust::State<'a> {
-    fn print_node(&mut self, node: &Node) -> IoResult<()> {
+    fn print_node(&mut self, node: &Node) -> io::Result<()> {
         match *node {
             NodeItem(a)        => self.print_item(&*a),
             NodeForeignItem(a) => self.print_foreign_item(&*a),
-            NodeTraitItem(a)   => self.print_trait_method(&*a),
-            NodeImplItem(a)    => self.print_impl_item(&*a),
+            NodeTraitItem(a)   => self.print_trait_item(a),
+            NodeImplItem(a)    => self.print_impl_item(a),
             NodeVariant(a)     => self.print_variant(&*a),
             NodeExpr(a)        => self.print_expr(&*a),
             NodeStmt(a)        => self.print_stmt(&*a),
@@ -1044,6 +929,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
                 ItemStruct(..) => "struct",
                 ItemTrait(..) => "trait",
                 ItemImpl(..) => "impl",
+                ItemDefaultImpl(..) => "default impl",
                 ItemMac(..) => "macro"
             };
             format!("{} {}{}", item_str, path_str, id_str)
@@ -1052,44 +938,38 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
             let path_str = map.path_to_str_with_ident(id, item.ident);
             format!("foreign item {}{}", path_str, id_str)
         }
-        Some(NodeImplItem(ref ii)) => {
-            match **ii {
-                MethodImplItem(ref m) => {
-                    match m.node {
-                        MethDecl(ident, _, _, _, _, _, _, _) =>
-                            format!("method {} in {}{}",
-                                    token::get_ident(ident),
-                                    map.path_to_string(id), id_str),
-                        MethMac(ref mac) =>
-                            format!("method macro {}{}",
-                                    pprust::mac_to_string(mac), id_str)
-                    }
-                }
-                TypeImplItem(ref t) => {
-                    format!("typedef {} in {}{}",
-                            token::get_ident(t.ident),
-                            map.path_to_string(id),
-                            id_str)
-                }
-            }
-        }
-        Some(NodeTraitItem(ref tm)) => {
-            match **tm {
-                RequiredMethod(_) | ProvidedMethod(_) => {
-                    let m = ast_util::trait_item_to_ty_method(&**tm);
+        Some(NodeImplItem(ii)) => {
+            match ii.node {
+                MethodImplItem(..) => {
                     format!("method {} in {}{}",
-                            token::get_ident(m.ident),
-                            map.path_to_string(id),
-                            id_str)
+                            token::get_ident(ii.ident),
+                            map.path_to_string(id), id_str)
                 }
-                TypeTraitItem(ref t) => {
-                    format!("type item {} in {}{}",
-                            token::get_ident(t.ty_param.ident),
+                TypeImplItem(_) => {
+                    format!("assoc type {} in {}{}",
+                            token::get_ident(ii.ident),
                             map.path_to_string(id),
                             id_str)
                 }
+                MacImplItem(ref mac) => {
+                    format!("method macro {}{}",
+                            pprust::mac_to_string(mac), id_str)
+                }
             }
         }
+        Some(NodeTraitItem(ti)) => {
+            let kind = match ti.node {
+                MethodTraitItem(..) => "trait method",
+                TypeTraitItem(..) => "assoc type",
+//                 ConstTraitItem(..) => "assoc constant"
+            };
+
+            format!("{} {} in {}{}",
+                    kind,
+                    token::get_ident(ti.ident),
+                    map.path_to_string(id),
+                    id_str)
+        }
         Some(NodeVariant(ref variant)) => {
             format!("variant {} in {}{}",
                     token::get_ident(variant.node.name),
index f660296fcd7b6c72892ac064bf3c0963376256a0..c4c2249d029596b2af15a845bb8823d18bdd4d29 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use abi::Abi;
 use ast::*;
 use ast;
 use ast_util;
@@ -87,33 +86,17 @@ pub fn is_shift_binop(b: BinOp_) -> bool {
 
 pub fn is_comparison_binop(b: BinOp_) -> bool {
     match b {
-        BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => true,
-        _ => false
+        BiEq | BiLt | BiLe | BiNe | BiGt | BiGe =>
+            true,
+        BiAnd | BiOr | BiAdd | BiSub | BiMul | BiDiv | BiRem |
+        BiBitXor | BiBitAnd | BiBitOr | BiShl | BiShr =>
+            false,
     }
 }
 
 /// Returns `true` if the binary operator takes its arguments by value
 pub fn is_by_value_binop(b: BinOp_) -> bool {
-    match b {
-        BiAdd | BiSub | BiMul | BiDiv | BiRem | BiBitXor | BiBitAnd | BiBitOr | BiShl | BiShr => {
-            true
-        }
-        _ => false
-    }
-}
-
-/// Returns `true` if the binary operator is symmetric in the sense that LHS
-/// and RHS must have the same type. So the type of LHS can serve as an hint
-/// for the type of RHS and vice versa.
-pub fn is_symmetric_binop(b: BinOp_) -> bool {
-    match b {
-        BiAdd | BiSub | BiMul | BiDiv | BiRem |
-        BiBitXor | BiBitAnd | BiBitOr |
-        BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => {
-            true
-        }
-        _ => false
-    }
+    !is_comparison_binop(b)
 }
 
 /// Returns `true` if the unary operator takes its argument by value
@@ -134,14 +117,14 @@ pub fn unop_to_string(op: UnOp) -> &'static str {
 }
 
 pub fn is_path(e: P<Expr>) -> bool {
-    return match e.node { ExprPath(_) => true, _ => false };
+    match e.node { ExprPath(..) => true, _ => false }
 }
 
 /// Get a string representation of a signed int type, with its value.
 /// We want to avoid "45int" and "-3int" in favor of "45" and "-3"
 pub fn int_ty_to_string(t: IntTy, val: Option<i64>) -> String {
     let s = match t {
-        TyIs(_) => "isize",
+        TyIs => "isize",
         TyI8 => "i8",
         TyI16 => "i16",
         TyI32 => "i32",
@@ -159,10 +142,10 @@ pub fn int_ty_to_string(t: IntTy, val: Option<i64>) -> String {
 
 pub fn int_ty_max(t: IntTy) -> u64 {
     match t {
-        TyI8 => 0x80u64,
-        TyI16 => 0x8000u64,
-        TyIs(_) | TyI32 => 0x80000000u64, // actually ni about TyIs
-        TyI64 => 0x8000000000000000u64
+        TyI8 => 0x80,
+        TyI16 => 0x8000,
+        TyIs | TyI32 => 0x80000000, // actually ni about TyIs
+        TyI64 => 0x8000000000000000
     }
 }
 
@@ -170,7 +153,7 @@ pub fn int_ty_max(t: IntTy) -> u64 {
 /// We want to avoid "42u" in favor of "42us". "42uint" is right out.
 pub fn uint_ty_to_string(t: UintTy, val: Option<u64>) -> String {
     let s = match t {
-        TyUs(_) => "usize",
+        TyUs => "usize",
         TyU8 => "u8",
         TyU16 => "u16",
         TyU32 => "u32",
@@ -185,10 +168,10 @@ pub fn uint_ty_to_string(t: UintTy, val: Option<u64>) -> String {
 
 pub fn uint_ty_max(t: UintTy) -> u64 {
     match t {
-        TyU8 => 0xffu64,
-        TyU16 => 0xffffu64,
-        TyUs(_) | TyU32 => 0xffffffffu64, // actually ni about TyUs
-        TyU64 => 0xffffffffffffffffu64
+        TyU8 => 0xff,
+        TyU16 => 0xffff,
+        TyUs | TyU32 => 0xffffffff, // actually ni about TyUs
+        TyU64 => 0xffffffffffffffff
     }
 }
 
@@ -252,8 +235,12 @@ pub fn name_to_dummy_lifetime(name: Name) -> Lifetime {
 /// hint of where they came from, (previously they would all just be
 /// listed as `__extensions__::method_name::hash`, with no indication
 /// of the type).
-pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
-    let mut pretty = pprust::ty_to_string(ty);
+pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: Option<&Ty>) -> Ident {
+    let mut pretty = match ty {
+        Some(t) => pprust::ty_to_string(t),
+        None => String::from_str("..")
+    };
+
     match *trait_ref {
         Some(ref trait_ref) => {
             pretty.push('.');
@@ -264,62 +251,6 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
     token::gensym_ident(&pretty[..])
 }
 
-pub fn trait_method_to_ty_method(method: &Method) -> TypeMethod {
-    match method.node {
-        MethDecl(ident,
-                 ref generics,
-                 abi,
-                 ref explicit_self,
-                 unsafety,
-                 ref decl,
-                 _,
-                 vis) => {
-            TypeMethod {
-                ident: ident,
-                attrs: method.attrs.clone(),
-                unsafety: unsafety,
-                decl: (*decl).clone(),
-                generics: generics.clone(),
-                explicit_self: (*explicit_self).clone(),
-                id: method.id,
-                span: method.span,
-                vis: vis,
-                abi: abi,
-            }
-        },
-        MethMac(_) => panic!("expected non-macro method declaration")
-    }
-}
-
-/// extract a TypeMethod from a TraitItem. if the TraitItem is
-/// a default, pull out the useful fields to make a TypeMethod
-//
-// NB: to be used only after expansion is complete, and macros are gone.
-pub fn trait_item_to_ty_method(method: &TraitItem) -> TypeMethod {
-    match *method {
-        RequiredMethod(ref m) => (*m).clone(),
-        ProvidedMethod(ref m) => trait_method_to_ty_method(&**m),
-        TypeTraitItem(_) => {
-            panic!("trait_method_to_ty_method(): expected method but found \
-                   typedef")
-        }
-    }
-}
-
-pub fn split_trait_methods(trait_methods: &[TraitItem])
-                           -> (Vec<TypeMethod>, Vec<P<Method>> ) {
-    let mut reqd = Vec::new();
-    let mut provd = Vec::new();
-    for trt_method in trait_methods {
-        match *trt_method {
-            RequiredMethod(ref tm) => reqd.push((*tm).clone()),
-            ProvidedMethod(ref m) => provd.push((*m).clone()),
-            TypeTraitItem(_) => {}
-        }
-    };
-    (reqd, provd)
-}
-
 pub fn struct_field_visibility(field: ast::StructField) -> Visibility {
     match field.node.kind {
         ast::NamedField(_, v) | ast::UnnamedField(v) => v
@@ -360,7 +291,7 @@ pub fn empty_generics() -> Generics {
 // ______________________________________________________________________
 // Enumerating the IDs which appear in an AST
 
-#[derive(RustcEncodable, RustcDecodable, Debug, Copy)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct IdRange {
     pub min: NodeId,
     pub max: NodeId,
@@ -484,9 +415,6 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
 
     fn visit_ty(&mut self, typ: &Ty) {
         self.operation.visit_id(typ.id);
-        if let TyPath(_, id) = typ.node {
-            self.operation.visit_id(id);
-        }
         visit::walk_ty(self, typ)
     }
 
@@ -512,10 +440,12 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
         self.operation.visit_id(node_id);
 
         match function_kind {
-            visit::FkItemFn(_, generics, _, _) |
-            visit::FkMethod(_, generics, _) => {
+            visit::FkItemFn(_, generics, _, _) => {
                 self.visit_generics_helper(generics)
             }
+            visit::FkMethod(_, sig) => {
+                self.visit_generics_helper(&sig.generics)
+            }
             visit::FkFnBlock => {}
         }
 
@@ -551,22 +481,28 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
         visit::walk_struct_def(self, struct_def);
     }
 
-    fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
-        match *tm {
-            ast::RequiredMethod(ref m) => self.operation.visit_id(m.id),
-            ast::ProvidedMethod(ref m) => self.operation.visit_id(m.id),
-            ast::TypeTraitItem(ref typ) => self.operation.visit_id(typ.ty_param.id),
-        }
-        visit::walk_trait_item(self, tm);
+    fn visit_trait_item(&mut self, ti: &ast::TraitItem) {
+        self.operation.visit_id(ti.id);
+        visit::walk_trait_item(self, ti);
     }
 
-    fn visit_lifetime_ref(&mut self, lifetime: &'v Lifetime) {
+    fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
+        self.operation.visit_id(ii.id);
+        visit::walk_impl_item(self, ii);
+    }
+
+    fn visit_lifetime_ref(&mut self, lifetime: &Lifetime) {
         self.operation.visit_id(lifetime.id);
     }
 
-    fn visit_lifetime_def(&mut self, def: &'v LifetimeDef) {
+    fn visit_lifetime_def(&mut self, def: &LifetimeDef) {
         self.visit_lifetime_ref(&def.lifetime);
     }
+
+    fn visit_trait_ref(&mut self, trait_ref: &TraitRef) {
+        self.operation.visit_id(trait_ref.ref_id);
+        visit::walk_trait_ref(self, trait_ref);
+    }
 }
 
 pub fn visit_ids_for_inlined_item<O: IdVisitingOperation>(item: &InlinedItem,
@@ -695,52 +631,6 @@ pub fn lit_is_str(lit: &Lit) -> bool {
     }
 }
 
-/// Macro invocations are guaranteed not to occur after expansion is complete.
-/// Extracting fields of a method requires a dynamic check to make sure that it's
-/// not a macro invocation. This check is guaranteed to succeed, assuming
-/// that the invocations are indeed gone.
-pub trait PostExpansionMethod {
-    fn pe_ident(&self) -> ast::Ident;
-    fn pe_generics<'a>(&'a self) -> &'a ast::Generics;
-    fn pe_abi(&self) -> Abi;
-    fn pe_explicit_self<'a>(&'a self) -> &'a ast::ExplicitSelf;
-    fn pe_unsafety(&self) -> ast::Unsafety;
-    fn pe_fn_decl<'a>(&'a self) -> &'a ast::FnDecl;
-    fn pe_body<'a>(&'a self) -> &'a ast::Block;
-    fn pe_vis(&self) -> ast::Visibility;
-}
-
-macro_rules! mf_method{
-    ($meth_name:ident, $field_ty:ty, $field_pat:pat, $result:expr) => {
-        fn $meth_name<'a>(&'a self) -> $field_ty {
-            match self.node {
-                $field_pat => $result,
-                MethMac(_) => {
-                    panic!("expected an AST without macro invocations");
-                }
-            }
-        }
-    }
-}
-
-
-impl PostExpansionMethod for Method {
-    mf_method! { pe_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_,_),ident }
-    mf_method! {
-        pe_generics,&'a ast::Generics,
-        MethDecl(_,ref generics,_,_,_,_,_,_),generics
-    }
-    mf_method! { pe_abi,Abi,MethDecl(_,_,abi,_,_,_,_,_),abi }
-    mf_method! {
-        pe_explicit_self,&'a ast::ExplicitSelf,
-        MethDecl(_,_,_,ref explicit_self,_,_,_,_),explicit_self
-    }
-    mf_method! { pe_unsafety,ast::Unsafety,MethDecl(_,_,_,_,unsafety,_,_,_),unsafety }
-    mf_method! { pe_fn_decl,&'a ast::FnDecl,MethDecl(_,_,_,_,_,ref decl,_,_),&**decl }
-    mf_method! { pe_body,&'a ast::Block,MethDecl(_,_,_,_,_,_,ref body,_),&**body }
-    mf_method! { pe_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,_,vis),vis }
-}
-
 #[cfg(test)]
 mod test {
     use ast::*;
@@ -754,13 +644,13 @@ mod test {
     #[test] fn idents_name_eq_test() {
         assert!(segments_name_eq(
             &[Ident{name:Name(3),ctxt:4}, Ident{name:Name(78),ctxt:82}]
-                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()[],
+                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>(),
             &[Ident{name:Name(3),ctxt:104}, Ident{name:Name(78),ctxt:182}]
-                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()[]));
+                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()));
         assert!(!segments_name_eq(
             &[Ident{name:Name(3),ctxt:4}, Ident{name:Name(78),ctxt:82}]
-                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()[],
+                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>(),
             &[Ident{name:Name(3),ctxt:104}, Ident{name:Name(77),ctxt:182}]
-                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()[]));
+                .iter().map(ident_to_segment).collect::<Vec<PathSegment>>()));
     }
 }
index 62e676891a0e6c349fc6581cacf302c8de2484e5..06e447bb12af4b076c8dad9c8c9cb0d0031478d0 100644 (file)
@@ -10,7 +10,6 @@
 
 // Functions dealing with attributes and meta items
 
-pub use self::InlineAttr::*;
 pub use self::StabilityLevel::*;
 pub use self::ReprAttr::*;
 pub use self::IntType::*;
@@ -283,31 +282,35 @@ pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
     first_attr_value_str_by_name(attrs, "crate_name")
 }
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum InlineAttr {
-    InlineNone,
-    InlineHint,
-    InlineAlways,
-    InlineNever,
+    None,
+    Hint,
+    Always,
+    Never,
 }
 
 /// Determine what `#[inline]` attribute is present in `attrs`, if any.
-pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr {
+pub fn find_inline_attr(diagnostic: Option<&SpanHandler>, attrs: &[Attribute]) -> InlineAttr {
     // FIXME (#2809)---validate the usage of #[inline] and #[inline]
-    attrs.iter().fold(InlineNone, |ia,attr| {
+    attrs.iter().fold(InlineAttr::None, |ia,attr| {
         match attr.node.value.node {
             MetaWord(ref n) if *n == "inline" => {
                 mark_used(attr);
-                InlineHint
+                InlineAttr::Hint
             }
             MetaList(ref n, ref items) if *n == "inline" => {
                 mark_used(attr);
-                if contains_name(&items[..], "always") {
-                    InlineAlways
+                if items.len() != 1 {
+                    diagnostic.map(|d|{ d.span_err(attr.span, "expected one argument"); });
+                    InlineAttr::None
+                } else if contains_name(&items[..], "always") {
+                    InlineAttr::Always
                 } else if contains_name(&items[..], "never") {
-                    InlineNever
+                    InlineAttr::Never
                 } else {
-                    InlineHint
+                    diagnostic.map(|d|{ d.span_err((*items[0]).span, "invalid argument"); });
+                    InlineAttr::None
                 }
             }
             _ => ia
@@ -317,9 +320,9 @@ pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr {
 
 /// True if `#[inline]` or `#[inline(always)]` is present in `attrs`.
 pub fn requests_inline(attrs: &[Attribute]) -> bool {
-    match find_inline_attr(attrs) {
-        InlineHint | InlineAlways => true,
-        InlineNone | InlineNever => false,
+    match find_inline_attr(None, attrs) {
+        InlineAttr::Hint | InlineAttr::Always => true,
+        InlineAttr::None | InlineAttr::Never => false,
     }
 }
 
@@ -562,15 +565,13 @@ fn int_type_of_word(s: &str) -> Option<IntType> {
         "u32" => Some(UnsignedInt(ast::TyU32)),
         "i64" => Some(SignedInt(ast::TyI64)),
         "u64" => Some(UnsignedInt(ast::TyU64)),
-        "int" => Some(SignedInt(ast::TyIs(true))),
-        "uint" => Some(UnsignedInt(ast::TyUs(true))),
-        "isize" => Some(SignedInt(ast::TyIs(false))),
-        "usize" => Some(UnsignedInt(ast::TyUs(false))),
+        "isize" => Some(SignedInt(ast::TyIs)),
+        "usize" => Some(UnsignedInt(ast::TyUs)),
         _ => None
     }
 }
 
-#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable, Copy)]
+#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
 pub enum ReprAttr {
     ReprAny,
     ReprInt(Span, IntType),
@@ -589,7 +590,7 @@ impl ReprAttr {
     }
 }
 
-#[derive(Eq, Hash, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy)]
+#[derive(Eq, Hash, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
 pub enum IntType {
     SignedInt(ast::IntTy),
     UnsignedInt(ast::UintTy)
@@ -609,7 +610,7 @@ impl IntType {
             SignedInt(ast::TyI16) | UnsignedInt(ast::TyU16) |
             SignedInt(ast::TyI32) | UnsignedInt(ast::TyU32) |
             SignedInt(ast::TyI64) | UnsignedInt(ast::TyU64) => true,
-            SignedInt(ast::TyIs(_)) | UnsignedInt(ast::TyUs(_)) => false
+            SignedInt(ast::TyIs) | UnsignedInt(ast::TyUs) => false
         }
     }
 }
index 099f646294235d175dcdf47b59ac0daa419f7024..b563a5e7d6e841f017c94eb0cc9e134985fd77d4 100644 (file)
@@ -29,6 +29,11 @@ use std::rc::Rc;
 use libc::c_uint;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
+
+// _____________________________________________________________________________
+// Pos, BytePos, CharPos
+//
+
 pub trait Pos {
     fn from_usize(n: usize) -> Self;
     fn to_usize(&self) -> usize;
@@ -42,7 +47,7 @@ pub struct BytePos(pub u32);
 /// 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.
-#[derive(Copy, PartialEq, Hash, PartialOrd, Debug)]
+#[derive(Copy, Clone, PartialEq, Hash, PartialOrd, Debug)]
 pub struct CharPos(pub usize);
 
 // FIXME: Lots of boilerplate in these impls, but so far my attempts to fix
@@ -69,6 +74,18 @@ impl Sub for BytePos {
     }
 }
 
+impl Encodable for BytePos {
+    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        s.emit_u32(self.0)
+    }
+}
+
+impl Decodable for BytePos {
+    fn decode<D: Decoder>(d: &mut D) -> Result<BytePos, D::Error> {
+        Ok(BytePos(try!{ d.read_u32() }))
+    }
+}
+
 impl Pos for CharPos {
     fn from_usize(n: usize) -> CharPos { CharPos(n) }
     fn to_usize(&self) -> usize { let CharPos(n) = *self; n }
@@ -90,6 +107,10 @@ impl Sub for CharPos {
     }
 }
 
+// _____________________________________________________________________________
+// Span, Spanned
+//
+
 /// Spans represent a region of code, used for error reporting. Positions in spans
 /// are *absolute* positions from the beginning of the codemap, not positions
 /// relative to FileMaps. Methods on the CodeMap can be used to relate spans back
@@ -126,15 +147,20 @@ impl PartialEq for Span {
 impl Eq for Span {}
 
 impl Encodable for Span {
-    /* Note #1972 -- spans are encoded but not decoded */
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_nil()
+        // Encode spans as a single u64 in order to cut down on tagging overhead
+        // added by the RBML metadata encoding. The should be solved differently
+        // altogether some time (FIXME #21482)
+        s.emit_u64( (self.lo.0 as u64) | ((self.hi.0 as u64) << 32) )
     }
 }
 
 impl Decodable for Span {
-    fn decode<D: Decoder>(_d: &mut D) -> Result<Span, D::Error> {
-        Ok(DUMMY_SP)
+    fn decode<D: Decoder>(d: &mut D) -> Result<Span, D::Error> {
+        let lo_hi: u64 = try! { d.read_u64() };
+        let lo = BytePos(lo_hi as u32);
+        let hi = BytePos((lo_hi >> 32) as u32);
+        Ok(mk_sp(lo, hi))
     }
 }
 
@@ -168,6 +194,10 @@ pub fn original_sp(cm: &CodeMap, sp: Span, enclosing_sp: Span) -> Span {
     }
 }
 
+// _____________________________________________________________________________
+// Loc, LocWithOpt, FileMapAndLine, FileMapAndBytePos
+//
+
 /// A source code location used for error reporting
 pub struct Loc {
     /// Information about the original source
@@ -192,6 +222,11 @@ pub struct LocWithOpt {
 pub struct FileMapAndLine { pub fm: Rc<FileMap>, pub line: usize }
 pub struct FileMapAndBytePos { pub fm: Rc<FileMap>, pub pos: BytePos }
 
+
+// _____________________________________________________________________________
+// MacroFormat, NameAndSpan, ExpnInfo, ExpnId
+//
+
 /// The syntax with which a macro was invoked.
 #[derive(Clone, Copy, Hash, Debug)]
 pub enum MacroFormat {
@@ -208,6 +243,10 @@ pub struct NameAndSpan {
     pub name: String,
     /// The format with which the macro was invoked.
     pub format: MacroFormat,
+    /// Whether the macro is allowed to use #[unstable]/feature-gated
+    /// features internally without forcing the whole crate to opt-in
+    /// to them.
+    pub allow_internal_unstable: bool,
     /// The span of the macro definition itself. The macro may not
     /// have a sensible definition span (e.g. something defined
     /// completely inside libsyntax) in which case this is None.
@@ -239,13 +278,13 @@ pub struct ExpnInfo {
 #[derive(PartialEq, Eq, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Copy)]
 pub struct ExpnId(u32);
 
-pub const NO_EXPANSION: ExpnId = ExpnId(-1);
+pub const NO_EXPANSION: ExpnId = ExpnId(!0);
 // For code appearing from the command line
-pub const COMMAND_LINE_EXPN: ExpnId = ExpnId(-2);
+pub const COMMAND_LINE_EXPN: ExpnId = ExpnId(!1);
 
 impl ExpnId {
     pub fn from_llvm_cookie(cookie: c_uint) -> ExpnId {
-        ExpnId(cookie as u32)
+        ExpnId(cookie)
     }
 
     pub fn to_llvm_cookie(self) -> i32 {
@@ -254,6 +293,10 @@ impl ExpnId {
     }
 }
 
+// _____________________________________________________________________________
+// FileMap, MultiByteChar, FileName, FileLines
+//
+
 pub type FileName = String;
 
 pub struct FileLines {
@@ -262,7 +305,7 @@ pub struct FileLines {
 }
 
 /// Identifies an offset of a multi-byte character in a FileMap
-#[derive(Copy)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Eq, PartialEq)]
 pub struct MultiByteChar {
     /// The absolute offset of the character in the CodeMap
     pub pos: BytePos,
@@ -277,13 +320,133 @@ pub struct FileMap {
     /// e.g. `<anon>`
     pub name: FileName,
     /// The complete source code
-    pub src: String,
+    pub src: Option<Rc<String>>,
     /// The start position of this source in the CodeMap
     pub start_pos: BytePos,
+    /// The end position of this source in the CodeMap
+    pub end_pos: BytePos,
     /// Locations of lines beginnings in the source code
-    pub lines: RefCell<Vec<BytePos> >,
+    pub lines: RefCell<Vec<BytePos>>,
     /// Locations of multi-byte characters in the source code
-    pub multibyte_chars: RefCell<Vec<MultiByteChar> >,
+    pub multibyte_chars: RefCell<Vec<MultiByteChar>>,
+}
+
+impl Encodable for FileMap {
+    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        s.emit_struct("FileMap", 5, |s| {
+            try! { s.emit_struct_field("name", 0, |s| self.name.encode(s)) };
+            try! { s.emit_struct_field("start_pos", 1, |s| self.start_pos.encode(s)) };
+            try! { s.emit_struct_field("end_pos", 2, |s| self.end_pos.encode(s)) };
+            try! { s.emit_struct_field("lines", 3, |s| {
+                    let lines = self.lines.borrow();
+                    // store the length
+                    try! { s.emit_u32(lines.len() as u32) };
+
+                    if lines.len() > 0 {
+                        // In order to preserve some space, we exploit the fact that
+                        // the lines list is sorted and individual lines are
+                        // probably not that long. Because of that we can store lines
+                        // as a difference list, using as little space as possible
+                        // for the differences.
+                        let max_line_length = if lines.len() == 1 {
+                            0
+                        } else {
+                            lines.windows(2)
+                                 .map(|w| w[1] - w[0])
+                                 .map(|bp| bp.to_usize())
+                                 .max()
+                                 .unwrap()
+                        };
+
+                        let bytes_per_diff: u8 = match max_line_length {
+                            0 ... 0xFF => 1,
+                            0x100 ... 0xFFFF => 2,
+                            _ => 4
+                        };
+
+                        // Encode the number of bytes used per diff.
+                        try! { bytes_per_diff.encode(s) };
+
+                        // Encode the first element.
+                        try! { lines[0].encode(s) };
+
+                        let diff_iter = (&lines[..]).windows(2)
+                                                    .map(|w| (w[1] - w[0]));
+
+                        match bytes_per_diff {
+                            1 => for diff in diff_iter { try! { (diff.0 as u8).encode(s) } },
+                            2 => for diff in diff_iter { try! { (diff.0 as u16).encode(s) } },
+                            4 => for diff in diff_iter { try! { diff.0.encode(s) } },
+                            _ => unreachable!()
+                        }
+                    }
+
+                    Ok(())
+                })
+            };
+            s.emit_struct_field("multibyte_chars", 4, |s| {
+                (*self.multibyte_chars.borrow()).encode(s)
+            })
+        })
+    }
+}
+
+impl Decodable for FileMap {
+    fn decode<D: Decoder>(d: &mut D) -> Result<FileMap, D::Error> {
+
+        d.read_struct("FileMap", 5, |d| {
+            let name: String = try! {
+                d.read_struct_field("name", 0, |d| Decodable::decode(d))
+            };
+            let start_pos: BytePos = try! {
+                d.read_struct_field("start_pos", 1, |d| Decodable::decode(d))
+            };
+            let end_pos: BytePos = try! {
+                d.read_struct_field("end_pos", 2, |d| Decodable::decode(d))
+            };
+            let lines: Vec<BytePos> = try! {
+                d.read_struct_field("lines", 3, |d| {
+                    let num_lines: u32 = try! { Decodable::decode(d) };
+                    let mut lines = Vec::with_capacity(num_lines as usize);
+
+                    if num_lines > 0 {
+                        // Read the number of bytes used per diff.
+                        let bytes_per_diff: u8 = try! { Decodable::decode(d) };
+
+                        // Read the first element.
+                        let mut line_start: BytePos = try! { Decodable::decode(d) };
+                        lines.push(line_start);
+
+                        for _ in 1..num_lines {
+                            let diff = match bytes_per_diff {
+                                1 => try! { d.read_u8() } as u32,
+                                2 => try! { d.read_u16() } as u32,
+                                4 => try! { d.read_u32() },
+                                _ => unreachable!()
+                            };
+
+                            line_start = line_start + BytePos(diff);
+
+                            lines.push(line_start);
+                        }
+                    }
+
+                    Ok(lines)
+                })
+            };
+            let multibyte_chars: Vec<MultiByteChar> = try! {
+                d.read_struct_field("multibyte_chars", 4, |d| Decodable::decode(d))
+            };
+            Ok(FileMap {
+                name: name,
+                start_pos: start_pos,
+                end_pos: end_pos,
+                src: None,
+                lines: RefCell::new(lines),
+                multibyte_chars: RefCell::new(multibyte_chars)
+            })
+        })
+    }
 }
 
 impl FileMap {
@@ -307,16 +470,21 @@ impl FileMap {
     /// get a line from the list of pre-computed line-beginnings
     ///
     pub fn get_line(&self, line_number: usize) -> Option<String> {
-        let lines = self.lines.borrow();
-        lines.get(line_number).map(|&line| {
-            let begin: BytePos = line - self.start_pos;
-            let begin = begin.to_usize();
-            let slice = &self.src[begin..];
-            match slice.find('\n') {
-                Some(e) => &slice[..e],
-                None => slice
-            }.to_string()
-        })
+        match self.src {
+            Some(ref src) => {
+                let lines = self.lines.borrow();
+                lines.get(line_number).map(|&line| {
+                    let begin: BytePos = line - self.start_pos;
+                    let begin = begin.to_usize();
+                    let slice = &src[begin..];
+                    match slice.find('\n') {
+                        Some(e) => &slice[..e],
+                        None => slice
+                    }.to_string()
+                })
+            }
+            None => None
+        }
     }
 
     pub fn record_multibyte_char(&self, pos: BytePos, bytes: usize) {
@@ -332,8 +500,17 @@ impl FileMap {
         !(self.name.starts_with("<") &&
           self.name.ends_with(">"))
     }
+
+    pub fn is_imported(&self) -> bool {
+        self.src.is_none()
+    }
 }
 
+
+// _____________________________________________________________________________
+// CodeMap
+//
+
 pub struct CodeMap {
     pub files: RefCell<Vec<Rc<FileMap>>>,
     expansions: RefCell<Vec<ExpnInfo>>
@@ -351,7 +528,7 @@ impl CodeMap {
         let mut files = self.files.borrow_mut();
         let start_pos = match files.last() {
             None => 0,
-            Some(last) => last.start_pos.to_usize() + last.src.len(),
+            Some(last) => last.end_pos.to_usize(),
         };
 
         // Remove utf-8 BOM if any.
@@ -372,10 +549,13 @@ impl CodeMap {
             src.push('\n');
         }
 
+        let end_pos = start_pos + src.len();
+
         let filemap = Rc::new(FileMap {
             name: filename,
-            src: src.to_string(),
+            src: Some(Rc::new(src)),
             start_pos: Pos::from_usize(start_pos),
+            end_pos: Pos::from_usize(end_pos),
             lines: RefCell::new(Vec::new()),
             multibyte_chars: RefCell::new(Vec::new()),
         });
@@ -385,6 +565,45 @@ impl CodeMap {
         filemap
     }
 
+    /// Allocates a new FileMap representing a source file from an external
+    /// crate. The source code of such an "imported filemap" is not available,
+    /// but we still know enough to generate accurate debuginfo location
+    /// information for things inlined from other crates.
+    pub fn new_imported_filemap(&self,
+                                filename: FileName,
+                                source_len: usize,
+                                file_local_lines: Vec<BytePos>,
+                                file_local_multibyte_chars: Vec<MultiByteChar>)
+                                -> Rc<FileMap> {
+        let mut files = self.files.borrow_mut();
+        let start_pos = match files.last() {
+            None => 0,
+            Some(last) => last.end_pos.to_usize(),
+        };
+
+        let end_pos = Pos::from_usize(start_pos + source_len);
+        let start_pos = Pos::from_usize(start_pos);
+
+        let lines = file_local_lines.map_in_place(|pos| pos + start_pos);
+        let multibyte_chars = file_local_multibyte_chars.map_in_place(|mbc| MultiByteChar {
+            pos: mbc.pos + start_pos,
+            bytes: mbc.bytes
+        });
+
+        let filemap = Rc::new(FileMap {
+            name: filename,
+            src: None,
+            start_pos: start_pos,
+            end_pos: end_pos,
+            lines: RefCell::new(lines),
+            multibyte_chars: RefCell::new(multibyte_chars),
+        });
+
+        files.push(filemap.clone());
+
+        filemap
+    }
+
     pub fn mk_substr_filename(&self, sp: Span) -> String {
         let pos = self.lookup_char_pos(sp.lo);
         (format!("<{}:{}:{}>",
@@ -431,7 +650,7 @@ impl CodeMap {
         let lo = self.lookup_char_pos(sp.lo);
         let hi = self.lookup_char_pos(sp.hi);
         let mut lines = Vec::new();
-        for i in lo.line - 1..hi.line as usize {
+        for i in lo.line - 1..hi.line {
             lines.push(i);
         };
         FileLines {file: lo.file, lines: lines}
@@ -442,30 +661,42 @@ impl CodeMap {
             return Err(SpanSnippetError::IllFormedSpan(sp));
         }
 
-        let begin = self.lookup_byte_offset(sp.lo);
-        let end = self.lookup_byte_offset(sp.hi);
+        let local_begin = self.lookup_byte_offset(sp.lo);
+        let local_end = self.lookup_byte_offset(sp.hi);
 
-        if begin.fm.start_pos != end.fm.start_pos {
+        if local_begin.fm.start_pos != local_end.fm.start_pos {
             return Err(SpanSnippetError::DistinctSources(DistinctSources {
-                begin: (begin.fm.name.clone(),
-                        begin.fm.start_pos),
-                end: (end.fm.name.clone(),
-                      end.fm.start_pos)
+                begin: (local_begin.fm.name.clone(),
+                        local_begin.fm.start_pos),
+                end: (local_end.fm.name.clone(),
+                      local_end.fm.start_pos)
             }));
         } else {
-            let start = begin.pos.to_usize();
-            let limit = end.pos.to_usize();
-            if start > limit || limit > begin.fm.src.len() {
-                return Err(SpanSnippetError::MalformedForCodemap(
-                    MalformedCodemapPositions {
-                        name: begin.fm.name.clone(),
-                        source_len: begin.fm.src.len(),
-                        begin_pos: begin.pos,
-                        end_pos: end.pos,
-                    }));
-            }
+            match local_begin.fm.src {
+                Some(ref src) => {
+                    let start_index = local_begin.pos.to_usize();
+                    let end_index = local_end.pos.to_usize();
+                    let source_len = (local_begin.fm.end_pos -
+                                      local_begin.fm.start_pos).to_usize();
+
+                    if start_index > end_index || end_index > source_len {
+                        return Err(SpanSnippetError::MalformedForCodemap(
+                            MalformedCodemapPositions {
+                                name: local_begin.fm.name.clone(),
+                                source_len: source_len,
+                                begin_pos: local_begin.pos,
+                                end_pos: local_end.pos,
+                            }));
+                    }
 
-            return Ok((&begin.fm.src[start..limit]).to_string())
+                    return Ok((&src[start_index..end_index]).to_string())
+                }
+                None => {
+                    return Err(SpanSnippetError::SourceNotAvailable {
+                        filename: local_begin.fm.name.clone()
+                    });
+                }
+            }
         }
     }
 
@@ -478,6 +709,7 @@ impl CodeMap {
         panic!("asking for {} which we don't know about", filename);
     }
 
+    /// For a global BytePos compute the local offset within the containing FileMap
     pub fn lookup_byte_offset(&self, bpos: BytePos) -> FileMapAndBytePos {
         let idx = self.lookup_filemap_idx(bpos);
         let fm = (*self.files.borrow())[idx].clone();
@@ -601,49 +833,56 @@ impl CodeMap {
         }
     }
 
-    /// Check if a span is "internal" to a macro. This means that it is entirely generated by a
-    /// macro expansion and contains no code that was passed in as an argument.
-    pub fn span_is_internal(&self, span: Span) -> bool {
-        // first, check if the given expression was generated by a macro or not
-        // we need to go back the expn_info tree to check only the arguments
-        // of the initial macro call, not the nested ones.
-        let mut is_internal = false;
-        let mut expnid = span.expn_id;
-        while self.with_expn_info(expnid, |expninfo| {
-            match expninfo {
-                Some(ref info) => {
-                    // save the parent expn_id for next loop iteration
-                    expnid = info.call_site.expn_id;
-                    if info.callee.name == "format_args" {
-                        // This is a hack because the format_args builtin calls unstable APIs.
-                        // I spent like 6 hours trying to solve this more generally but am stupid.
-                        is_internal = true;
-                        false
-                    } else if info.callee.span.is_none() {
-                        // it's a compiler built-in, we *really* don't want to mess with it
-                        // so we skip it, unless it was called by a regular macro, in which case
-                        // we will handle the caller macro next turn
-                        is_internal = true;
-                        true // continue looping
+    /// Check if a span is "internal" to a macro in which #[unstable]
+    /// items can be used (that is, a macro marked with
+    /// `#[allow_internal_unstable]`).
+    pub fn span_allows_unstable(&self, span: Span) -> bool {
+        debug!("span_allows_unstable(span = {:?})", span);
+        let mut allows_unstable = false;
+        let mut expn_id = span.expn_id;
+        loop {
+            let quit = self.with_expn_info(expn_id, |expninfo| {
+                debug!("span_allows_unstable: expninfo = {:?}", expninfo);
+                expninfo.map_or(/* hit the top level */ true, |info| {
+
+                    let span_comes_from_this_expansion =
+                        info.callee.span.map_or(span == info.call_site, |mac_span| {
+                            mac_span.lo <= span.lo && span.hi <= mac_span.hi
+                        });
+
+                    debug!("span_allows_unstable: from this expansion? {}, allows unstable? {}",
+                           span_comes_from_this_expansion,
+                           info.callee.allow_internal_unstable);
+                    if span_comes_from_this_expansion {
+                        allows_unstable = info.callee.allow_internal_unstable;
+                        // we've found the right place, stop looking
+                        true
                     } else {
-                        // was this expression from the current macro arguments ?
-                        is_internal = !( span.lo > info.call_site.lo &&
-                                         span.hi < info.call_site.hi );
-                        true // continue looping
+                        // not the right place, keep looking
+                        expn_id = info.call_site.expn_id;
+                        false
                     }
-                },
-                _ => false // stop looping
+                })
+            });
+            if quit {
+                break
             }
-        }) { /* empty while loop body */ }
-        return is_internal;
+        }
+        debug!("span_allows_unstable? {}", allows_unstable);
+        allows_unstable
     }
 }
 
+// _____________________________________________________________________________
+// SpanSnippetError, DistinctSources, MalformedCodemapPositions
+//
+
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub enum SpanSnippetError {
     IllFormedSpan(Span),
     DistinctSources(DistinctSources),
     MalformedForCodemap(MalformedCodemapPositions),
+    SourceNotAvailable { filename: String }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug)]
@@ -660,6 +899,11 @@ pub struct MalformedCodemapPositions {
     end_pos: BytePos
 }
 
+
+// _____________________________________________________________________________
+// Tests
+//
+
 #[cfg(test)]
 mod test {
     use super::*;
@@ -677,7 +921,7 @@ mod test {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn t2 () {
         let cm = CodeMap::new();
         let fm = cm.new_filemap("blork.rs".to_string(),
index dfe3477bddc3bba2eaafb7a92479e2c1e013a6d9..489a7721d7ba770a117add88db41d25b25353fe8 100644 (file)
@@ -118,13 +118,13 @@ fn fold_item_underscore<F>(cx: &mut Context<F>, item: ast::Item_) -> ast::Item_
     let item = match item {
         ast::ItemImpl(u, o, a, b, c, impl_items) => {
             let impl_items = impl_items.into_iter()
-                                       .filter(|ii| impl_item_in_cfg(cx, ii))
+                                       .filter(|ii| (cx.in_cfg)(&ii.attrs))
                                        .collect();
             ast::ItemImpl(u, o, a, b, c, impl_items)
         }
         ast::ItemTrait(u, a, b, methods) => {
             let methods = methods.into_iter()
-                                 .filter(|m| trait_method_in_cfg(cx, m))
+                                 .filter(|ti| (cx.in_cfg)(&ti.attrs))
                                  .collect();
             ast::ItemTrait(u, a, b, methods)
         }
@@ -246,25 +246,6 @@ fn foreign_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ForeignItem) -> bool
     return (cx.in_cfg)(&item.attrs);
 }
 
-fn trait_method_in_cfg<F>(cx: &mut Context<F>, meth: &ast::TraitItem) -> bool where
-    F: FnMut(&[ast::Attribute]) -> bool
-{
-    match *meth {
-        ast::RequiredMethod(ref meth) => (cx.in_cfg)(&meth.attrs),
-        ast::ProvidedMethod(ref meth) => (cx.in_cfg)(&meth.attrs),
-        ast::TypeTraitItem(ref typ) => (cx.in_cfg)(&typ.attrs),
-    }
-}
-
-fn impl_item_in_cfg<F>(cx: &mut Context<F>, impl_item: &ast::ImplItem) -> bool where
-    F: FnMut(&[ast::Attribute]) -> bool
-{
-    match *impl_item {
-        ast::MethodImplItem(ref meth) => (cx.in_cfg)(&meth.attrs),
-        ast::TypeImplItem(ref typ) => (cx.in_cfg)(&typ.attrs),
-    }
-}
-
 // Determine if an item should be translated in the current crate
 // configuration based on the item's attributes
 fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attribute]) -> bool {
index 27219774cf148c52f68f8e009fc8d7130691fdd8..f35cc8c8d2399f9d695364c5cb4b121d3ace8399 100644 (file)
@@ -19,13 +19,14 @@ use diagnostics;
 
 use std::cell::{RefCell, Cell};
 use std::fmt;
-use std::old_io;
-use std::string::String;
+use std::io::prelude::*;
+use std::io;
 use term::WriterWrapper;
 use term;
+use libc;
 
 /// maximum number of lines we will print for each error; arbitrary.
-static MAX_LINES: usize = 6;
+const MAX_LINES: usize = 6;
 
 #[derive(Clone, Copy)]
 pub enum RenderSpan {
@@ -70,12 +71,12 @@ pub trait Emitter {
 /// This structure is used to signify that a task has panicked with a fatal error
 /// from the diagnostics. You can use this with the `Any` trait to figure out
 /// how a rustc task died (if so desired).
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct FatalError;
 
 /// Signifies that the compiler died with an explicit call to `.bug`
 /// or `.span_bug` rather than a failed assertion, etc.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct ExplicitBug;
 
 /// A span-handler is like a handler but also
@@ -223,7 +224,7 @@ pub fn mk_span_handler(handler: Handler, cm: codemap::CodeMap) -> SpanHandler {
 pub fn default_handler(color_config: ColorConfig,
                        registry: Option<diagnostics::registry::Registry>,
                        can_emit_warnings: bool) -> Handler {
-    mk_handler(can_emit_warnings, box EmitterWriter::stderr(color_config, registry))
+    mk_handler(can_emit_warnings, Box::new(EmitterWriter::stderr(color_config, registry)))
 }
 
 pub fn mk_handler(can_emit_warnings: bool, e: Box<Emitter + Send>) -> Handler {
@@ -271,7 +272,7 @@ impl Level {
 
 fn print_maybe_styled(w: &mut EmitterWriter,
                       msg: &str,
-                      color: term::attr::Attr) -> old_io::IoResult<()> {
+                      color: term::attr::Attr) -> io::Result<()> {
     match w.dst {
         Terminal(ref mut t) => {
             try!(t.attr(color));
@@ -289,23 +290,21 @@ fn print_maybe_styled(w: &mut EmitterWriter,
             // to be miscolored. We assume this is rare enough that we don't
             // have to worry about it.
             if msg.ends_with("\n") {
-                try!(t.write_str(&msg[..msg.len()-1]));
+                try!(t.write_all(msg[..msg.len()-1].as_bytes()));
                 try!(t.reset());
-                try!(t.write_str("\n"));
+                try!(t.write_all(b"\n"));
             } else {
-                try!(t.write_str(msg));
+                try!(t.write_all(msg.as_bytes()));
                 try!(t.reset());
             }
             Ok(())
         }
-        Raw(ref mut w) => {
-            w.write_str(msg)
-        }
+        Raw(ref mut w) => w.write_all(msg.as_bytes()),
     }
 }
 
 fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,
-                    msg: &str, code: Option<&str>) -> old_io::IoResult<()> {
+                    msg: &str, code: Option<&str>) -> io::Result<()> {
     if !topic.is_empty() {
         try!(write!(&mut dst.dst, "{} ", topic));
     }
@@ -324,7 +323,7 @@ fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,
         }
         None => ()
     }
-    try!(dst.dst.write_char('\n'));
+    try!(write!(&mut dst.dst, "\n"));
     Ok(())
 }
 
@@ -335,42 +334,67 @@ pub struct EmitterWriter {
 
 enum Destination {
     Terminal(Box<term::Terminal<WriterWrapper> + Send>),
-    Raw(Box<Writer + Send>),
+    Raw(Box<Write + Send>),
 }
 
 impl EmitterWriter {
     pub fn stderr(color_config: ColorConfig,
                   registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
-        let stderr = old_io::stderr();
+        let stderr = io::stderr();
 
         let use_color = match color_config {
             Always => true,
             Never  => false,
-            Auto   => stderr.get_ref().isatty()
+            Auto   => stderr_isatty(),
         };
 
         if use_color {
             let dst = match term::stderr() {
                 Some(t) => Terminal(t),
-                None    => Raw(box stderr),
+                None    => Raw(Box::new(stderr)),
             };
             EmitterWriter { dst: dst, registry: registry }
         } else {
-            EmitterWriter { dst: Raw(box stderr), registry: registry }
+            EmitterWriter { dst: Raw(Box::new(stderr)), registry: registry }
         }
     }
 
-    pub fn new(dst: Box<Writer + Send>,
+    pub fn new(dst: Box<Write + Send>,
                registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
         EmitterWriter { dst: Raw(dst), registry: registry }
     }
 }
 
-impl Writer for Destination {
-    fn write_all(&mut self, bytes: &[u8]) -> old_io::IoResult<()> {
+#[cfg(unix)]
+fn stderr_isatty() -> bool {
+    unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
+}
+#[cfg(windows)]
+fn stderr_isatty() -> bool {
+    const STD_ERROR_HANDLE: libc::DWORD = -12i32 as libc::DWORD;
+    extern "system" {
+        fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
+        fn GetConsoleMode(hConsoleHandle: libc::HANDLE,
+                          lpMode: libc::LPDWORD) -> libc::BOOL;
+    }
+    unsafe {
+        let handle = GetStdHandle(STD_ERROR_HANDLE);
+        let mut out = 0;
+        GetConsoleMode(handle, &mut out) != 0
+    }
+}
+
+impl Write for Destination {
+    fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
+        match *self {
+            Terminal(ref mut t) => t.write(bytes),
+            Raw(ref mut w) => w.write(bytes),
+        }
+    }
+    fn flush(&mut self) -> io::Result<()> {
         match *self {
-            Terminal(ref mut t) => t.write_all(bytes),
-            Raw(ref mut w) => w.write_all(bytes),
+            Terminal(ref mut t) => t.flush(),
+            Raw(ref mut w) => w.flush(),
         }
     }
 }
@@ -403,7 +427,7 @@ impl Emitter for EmitterWriter {
 }
 
 fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
-        msg: &str, code: Option<&str>, lvl: Level, custom: bool) -> old_io::IoResult<()> {
+        msg: &str, code: Option<&str>, lvl: Level, custom: bool) -> io::Result<()> {
     let sp = rsp.span();
 
     // We cannot check equality directly with COMMAND_LINE_SP
@@ -451,7 +475,7 @@ fn highlight_lines(err: &mut EmitterWriter,
                    cm: &codemap::CodeMap,
                    sp: Span,
                    lvl: Level,
-                   lines: codemap::FileLines) -> old_io::IoResult<()> {
+                   lines: codemap::FileLines) -> io::Result<()> {
     let fm = &*lines.file;
 
     let mut elided = false;
@@ -560,7 +584,7 @@ fn custom_highlight_lines(w: &mut EmitterWriter,
                           sp: Span,
                           lvl: Level,
                           lines: codemap::FileLines)
-                          -> old_io::IoResult<()> {
+                          -> io::Result<()> {
     let fm = &*lines.file;
 
     let lines = &lines.lines[..];
@@ -617,8 +641,8 @@ fn custom_highlight_lines(w: &mut EmitterWriter,
 fn print_macro_backtrace(w: &mut EmitterWriter,
                          cm: &codemap::CodeMap,
                          sp: Span)
-                         -> old_io::IoResult<()> {
-    let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| -> old_io::IoResult<_> {
+                         -> io::Result<()> {
+    let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| -> io::Result<_> {
         match expn_info {
             Some(ei) => {
                 let ss = ei.callee.span.map_or(String::new(),
index 54689a1f77ad2dddcb9e6fa96bdff67b0de08e53..055ade46a3f01ab482ce08674ca5cb0eb9462f1b 100644 (file)
@@ -52,6 +52,13 @@ macro_rules! span_help {
     })
 }
 
+#[macro_export]
+macro_rules! fileline_help {
+    ($session:expr, $span:expr, $($message:tt)*) => ({
+        ($session).fileline_help($span, &format!($($message)*))
+    })
+}
+
 #[macro_export]
 macro_rules! register_diagnostics {
     ($($code:tt),*) => (
index b3afc3fc4dd13399d7ff542496a0850279f22e22..59fe3658437bdefbc356473fb04e564772f0f78e 100644 (file)
@@ -14,10 +14,11 @@ use std::collections::BTreeMap;
 use ast;
 use ast::{Ident, Name, TokenTree};
 use codemap::Span;
-use ext::base::{ExtCtxt, MacExpr, MacResult, MacItems};
+use ext::base::{ExtCtxt, MacEager, MacResult};
 use ext::build::AstBuilder;
 use parse::token;
 use ptr::P;
+use util::small_vector::SmallVector;
 
 thread_local! {
     static REGISTERED_DIAGNOSTICS: RefCell<BTreeMap<Name, Option<Name>>> = {
@@ -73,7 +74,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
             ));
         }
     });
-    MacExpr::new(quote_expr!(ecx, ()))
+    MacEager::expr(quote_expr!(ecx, ()))
 }
 
 pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
@@ -101,7 +102,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
     let sym = Ident::new(token::gensym(&(
         "__register_diagnostic_".to_string() + &token::get_ident(*code)
     )));
-    MacItems::new(vec![quote_item!(ecx, mod $sym {}).unwrap()].into_iter())
+    MacEager::items(SmallVector::many(vec![quote_item!(ecx, mod $sym {}).unwrap()]))
 }
 
 pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
@@ -126,7 +127,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
             (descriptions.len(), ecx.expr_vec(span, descriptions))
         });
 
-    MacItems::new(vec![quote_item!(ecx,
+    MacEager::items(SmallVector::many(vec![quote_item!(ecx,
         pub static $name: [(&'static str, &'static str); $count] = $expr;
-    ).unwrap()].into_iter())
+    ).unwrap()]))
 }
index d8cba139fb5979b9258c5d8e6498a24e00be8f42..d256698b88598cd5cd764379514d23aaf3056785 100644 (file)
@@ -45,7 +45,7 @@ impl State {
     }
 }
 
-static OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];
+const OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];
 
 pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                        -> Box<base::MacResult+'cx> {
@@ -113,7 +113,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         Some(('=', _)) => None,
                         Some(('+', operand)) => {
                             Some(token::intern_and_get_ident(&format!(
-                                        "={}", operand)[]))
+                                        "={}", operand)))
                         }
                         _ => {
                             cx.span_err(span, "output operand constraint lacks '=' or '+'");
@@ -214,10 +214,11 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             name: "asm".to_string(),
             format: codemap::MacroBang,
             span: None,
+            allow_internal_unstable: false,
         },
     });
 
-    MacExpr::new(P(ast::Expr {
+    MacEager::expr(P(ast::Expr {
         id: ast::DUMMY_NODE_ID,
         node: ast::ExprInlineAsm(ast::InlineAsm {
             asm: token::intern_and_get_ident(&asm),
index d4ccabbd63b4a2edfb5f411a13b06b317e27440c..71fba789ff83509fcdaa2d82d95b128ce05b7793 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -28,6 +28,7 @@ use fold::Folder;
 
 use std::collections::HashMap;
 use std::rc::Rc;
+use std::default::Default;
 
 pub trait ItemDecorator {
     fn expand(&self,
@@ -76,51 +77,31 @@ impl<F> ItemModifier for F
 #[derive(Debug,Clone)]
 pub enum Annotatable {
     Item(P<ast::Item>),
-    TraitItem(ast::TraitItem),
-    ImplItem(ast::ImplItem),
+    TraitItem(P<ast::TraitItem>),
+    ImplItem(P<ast::ImplItem>),
 }
 
 impl Annotatable {
     pub fn attrs(&self) -> &[ast::Attribute] {
         match *self {
-            Annotatable::Item(ref i) => &i.attrs[],
-            Annotatable::TraitItem(ref i) => match *i {
-                ast::TraitItem::RequiredMethod(ref tm) => &tm.attrs[],
-                ast::TraitItem::ProvidedMethod(ref m) => &m.attrs[],
-                ast::TraitItem::TypeTraitItem(ref at) => &at.attrs[],
-            },
-            Annotatable::ImplItem(ref i) => match *i {
-                ast::ImplItem::MethodImplItem(ref m) => &m.attrs[],
-                ast::ImplItem::TypeImplItem(ref t) => &t.attrs[],
-            }
+            Annotatable::Item(ref i) => &i.attrs,
+            Annotatable::TraitItem(ref ti) => &ti.attrs,
+            Annotatable::ImplItem(ref ii) => &ii.attrs,
         }
     }
 
     pub fn fold_attrs(self, attrs: Vec<ast::Attribute>) -> Annotatable {
         match self {
-            Annotatable::Item(i) => Annotatable::Item(P(ast::Item {
+            Annotatable::Item(i) => Annotatable::Item(i.map(|i| ast::Item {
                 attrs: attrs,
-                ..(*i).clone()
+                ..i
+            })),
+            Annotatable::TraitItem(i) => Annotatable::TraitItem(i.map(|ti| {
+                ast::TraitItem { attrs: attrs, ..ti }
+            })),
+            Annotatable::ImplItem(i) => Annotatable::ImplItem(i.map(|ii| {
+                ast::ImplItem { attrs: attrs, ..ii }
             })),
-            Annotatable::TraitItem(i) => match i {
-                ast::TraitItem::RequiredMethod(tm) => Annotatable::TraitItem(
-                    ast::TraitItem::RequiredMethod(
-                        ast::TypeMethod { attrs: attrs, ..tm })),
-                ast::TraitItem::ProvidedMethod(m) => Annotatable::TraitItem(
-                    ast::TraitItem::ProvidedMethod(P(
-                        ast::Method { attrs: attrs, ..(*m).clone() }))),
-                ast::TraitItem::TypeTraitItem(at) => Annotatable::TraitItem(
-                    ast::TraitItem::TypeTraitItem(P(
-                        ast::AssociatedType { attrs: attrs, ..(*at).clone() }))),
-            },
-            Annotatable::ImplItem(i) => match i {
-                ast::ImplItem::MethodImplItem(m) => Annotatable::ImplItem(
-                    ast::ImplItem::MethodImplItem(P(
-                        ast::Method { attrs: attrs, ..(*m).clone() }))),
-                ast::ImplItem::TypeImplItem(t) => Annotatable::ImplItem(
-                    ast::ImplItem::TypeImplItem(P(
-                        ast::Typedef { attrs: attrs, ..(*t).clone() }))),
-            }
         }
     }
 
@@ -131,14 +112,14 @@ impl Annotatable {
         }
     }
 
-    pub fn expect_trait_item(self) -> ast::TraitItem {
+    pub fn expect_trait_item(self) -> P<ast::TraitItem> {
         match self {
             Annotatable::TraitItem(i) => i,
             _ => panic!("expected Item")
         }
     }
 
-    pub fn expect_impl_item(self) -> ast::ImplItem {
+    pub fn expect_impl_item(self) -> P<ast::ImplItem> {
         match self {
             Annotatable::ImplItem(i) => i,
             _ => panic!("expected Item")
@@ -226,9 +207,17 @@ impl<F> IdentMacroExpander for F
     }
 }
 
+// Use a macro because forwarding to a simple function has type system issues
+macro_rules! make_stmt_default {
+    ($me:expr) => {
+        $me.make_expr().map(|e| {
+            P(codemap::respan(e.span, ast::StmtExpr(e, ast::DUMMY_NODE_ID)))
+        })
+    }
+}
+
 /// The result of a macro expansion. The return values of the various
-/// methods are spliced into the AST at the callsite of the macro (or
-/// just into the compiler's internal macro table, for `make_def`).
+/// methods are spliced into the AST at the callsite of the macro.
 pub trait MacResult {
     /// Create an expression.
     fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
@@ -239,8 +228,8 @@ pub trait MacResult {
         None
     }
 
-    /// Create zero or more methods.
-    fn make_methods(self: Box<Self>) -> Option<SmallVector<P<ast::Method>>> {
+    /// Create zero or more impl items.
+    fn make_impl_items(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
         None
     }
 
@@ -254,69 +243,82 @@ pub trait MacResult {
     /// By default this attempts to create an expression statement,
     /// returning None if that fails.
     fn make_stmt(self: Box<Self>) -> Option<P<ast::Stmt>> {
-        self.make_expr()
-            .map(|e| P(codemap::respan(e.span, ast::StmtExpr(e, ast::DUMMY_NODE_ID))))
+        make_stmt_default!(self)
     }
 }
 
-/// A convenience type for macros that return a single expression.
-pub struct MacExpr {
-    e: P<ast::Expr>
-}
-impl MacExpr {
-    pub fn new(e: P<ast::Expr>) -> Box<MacResult+'static> {
-        box MacExpr { e: e } as Box<MacResult+'static>
-    }
-}
-impl MacResult for MacExpr {
-    fn make_expr(self: Box<MacExpr>) -> Option<P<ast::Expr>> {
-        Some(self.e)
-    }
-    fn make_pat(self: Box<MacExpr>) -> Option<P<ast::Pat>> {
-        match self.e.node {
-            ast::ExprLit(_) => Some(P(ast::Pat {
-                id: ast::DUMMY_NODE_ID,
-                span: self.e.span,
-                node: ast::PatLit(self.e)
-            })),
-            _ => None
+macro_rules! make_MacEager {
+    ( $( $fld:ident: $t:ty, )* ) => {
+        /// `MacResult` implementation for the common case where you've already
+        /// built each form of AST that you might return.
+        #[derive(Default)]
+        pub struct MacEager {
+            $(
+                pub $fld: Option<$t>,
+            )*
+        }
+
+        impl MacEager {
+            $(
+                pub fn $fld(v: $t) -> Box<MacResult> {
+                    box MacEager {
+                        $fld: Some(v),
+                        ..Default::default()
+                    }
+                }
+            )*
         }
     }
 }
-/// A convenience type for macros that return a single pattern.
-pub struct MacPat {
-    p: P<ast::Pat>
+
+make_MacEager! {
+    expr: P<ast::Expr>,
+    pat: P<ast::Pat>,
+    items: SmallVector<P<ast::Item>>,
+    impl_items: SmallVector<P<ast::ImplItem>>,
+    stmt: P<ast::Stmt>,
 }
-impl MacPat {
-    pub fn new(p: P<ast::Pat>) -> Box<MacResult+'static> {
-        box MacPat { p: p } as Box<MacResult+'static>
+
+impl MacResult for MacEager {
+    fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
+        self.expr
     }
-}
-impl MacResult for MacPat {
-    fn make_pat(self: Box<MacPat>) -> Option<P<ast::Pat>> {
-        Some(self.p)
+
+    fn make_items(self: Box<Self>) -> Option<SmallVector<P<ast::Item>>> {
+        self.items
     }
-}
-/// A type for macros that return multiple items.
-pub struct MacItems {
-    items: SmallVector<P<ast::Item>>
-}
 
-impl MacItems {
-    pub fn new<I: Iterator<Item=P<ast::Item>>>(it: I) -> Box<MacResult+'static> {
-        box MacItems { items: it.collect() } as Box<MacResult+'static>
+    fn make_impl_items(self: Box<Self>) -> Option<SmallVector<P<ast::ImplItem>>> {
+        self.impl_items
     }
-}
 
-impl MacResult for MacItems {
-    fn make_items(self: Box<MacItems>) -> Option<SmallVector<P<ast::Item>>> {
-        Some(self.items)
+    fn make_stmt(self: Box<Self>) -> Option<P<ast::Stmt>> {
+        match self.stmt {
+            None => make_stmt_default!(self),
+            s => s,
+        }
+    }
+
+    fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
+        if let Some(p) = self.pat {
+            return Some(p);
+        }
+        if let Some(e) = self.expr {
+            if let ast::ExprLit(_) = e.node {
+                return Some(P(ast::Pat {
+                    id: ast::DUMMY_NODE_ID,
+                    span: e.span,
+                    node: ast::PatLit(e),
+                }));
+            }
+        }
+        None
     }
 }
 
 /// Fill-in macro expansion result, to allow compilation to continue
 /// after hitting errors.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct DummyResult {
     expr_only: bool,
     span: Span
@@ -328,7 +330,7 @@ impl DummyResult {
     /// Use this as a return value after hitting any errors and
     /// calling `span_err`.
     pub fn any(sp: Span) -> Box<MacResult+'static> {
-        box DummyResult { expr_only: false, span: sp } as Box<MacResult+'static>
+        box DummyResult { expr_only: false, span: sp }
     }
 
     /// Create a default MacResult that can only be an expression.
@@ -337,7 +339,7 @@ impl DummyResult {
     /// if an error is encountered internally, the user will receive
     /// an error that they also used it in the wrong place.
     pub fn expr(sp: Span) -> Box<MacResult+'static> {
-        box DummyResult { expr_only: true, span: sp } as Box<MacResult+'static>
+        box DummyResult { expr_only: true, span: sp }
     }
 
     /// A plain dummy expression.
@@ -375,7 +377,7 @@ impl MacResult for DummyResult {
             Some(SmallVector::zero())
         }
     }
-    fn make_methods(self: Box<DummyResult>) -> Option<SmallVector<P<ast::Method>>> {
+    fn make_impl_items(self: Box<DummyResult>) -> Option<SmallVector<P<ast::ImplItem>>> {
         if self.expr_only {
             None
         } else {
@@ -408,12 +410,15 @@ pub enum SyntaxExtension {
     /// A normal, function-like syntax extension.
     ///
     /// `bytes!` is a `NormalTT`.
-    NormalTT(Box<TTMacroExpander + 'static>, Option<Span>),
+    ///
+    /// The `bool` dictates whether the contents of the macro can
+    /// directly use `#[unstable]` things (true == yes).
+    NormalTT(Box<TTMacroExpander + 'static>, Option<Span>, bool),
 
     /// A function-like syntax extension that has an extra ident before
     /// the block.
     ///
-    IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>),
+    IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>, bool),
 
     /// Represents `macro_rules!` itself.
     MacroRulesTT,
@@ -443,14 +448,14 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>)
                                         -> SyntaxEnv {
     // utility function to simplify creating NormalTT syntax extensions
     fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
-        NormalTT(box f, None)
+        NormalTT(Box::new(f), None, false)
     }
 
     let mut syntax_expanders = SyntaxEnv::new();
     syntax_expanders.insert(intern("macro_rules"), MacroRulesTT);
     syntax_expanders.insert(intern("format_args"),
-                            builtin_normal_expander(
-                                ext::format::expand_format_args));
+                            // format_args uses `unstable` things internally.
+                            NormalTT(Box::new(ext::format::expand_format_args), None, true));
     syntax_expanders.insert(intern("env"),
                             builtin_normal_expander(
                                     ext::env::expand_env));
@@ -466,10 +471,8 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>)
     syntax_expanders.insert(intern("log_syntax"),
                             builtin_normal_expander(
                                     ext::log_syntax::expand_syntax_ext));
-    syntax_expanders.insert(intern("derive"),
-                            Decorator(box ext::deriving::expand_meta_derive));
-    syntax_expanders.insert(intern("deriving"),
-                            Decorator(box ext::deriving::expand_deprecated_deriving));
+
+    ext::deriving::register_all(&mut syntax_expanders);
 
     if ecfg.enable_quotes() {
         // Quasi-quoting expanders
@@ -482,9 +485,6 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>)
         syntax_expanders.insert(intern("quote_ty"),
                            builtin_normal_expander(
                                 ext::quote::expand_quote_ty));
-        syntax_expanders.insert(intern("quote_method"),
-                           builtin_normal_expander(
-                                ext::quote::expand_quote_method));
         syntax_expanders.insert(intern("quote_item"),
                            builtin_normal_expander(
                                 ext::quote::expand_quote_item));
@@ -497,6 +497,12 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>)
         syntax_expanders.insert(intern("quote_stmt"),
                            builtin_normal_expander(
                                 ext::quote::expand_quote_stmt));
+        syntax_expanders.insert(intern("quote_matcher"),
+                           builtin_normal_expander(
+                                ext::quote::expand_quote_matcher));
+        syntax_expanders.insert(intern("quote_attr"),
+                           builtin_normal_expander(
+                                ext::quote::expand_quote_attr));
     }
 
     syntax_expanders.insert(intern("line"),
@@ -639,7 +645,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
     pub fn mod_path(&self) -> Vec<ast::Ident> {
         let mut v = Vec::new();
-        v.push(token::str_to_ident(&self.ecfg.crate_name[]));
+        v.push(token::str_to_ident(&self.ecfg.crate_name));
         v.extend(self.mod_path.iter().cloned());
         return v;
     }
@@ -648,7 +654,7 @@ impl<'a> ExtCtxt<'a> {
         if self.recursion_count > self.ecfg.recursion_limit {
             self.span_fatal(ei.call_site,
                             &format!("recursion limit reached while expanding the macro `{}`",
-                                    ei.callee.name)[]);
+                                    ei.callee.name));
         }
 
         let mut call_site = ei.call_site;
@@ -725,6 +731,10 @@ impl<'a> ExtCtxt<'a> {
         self.print_backtrace();
         self.parse_sess.span_diagnostic.span_help(sp, msg);
     }
+    pub fn fileline_help(&self, sp: Span, msg: &str) {
+        self.print_backtrace();
+        self.parse_sess.span_diagnostic.fileline_help(sp, msg);
+    }
     pub fn bug(&self, msg: &str) -> ! {
         self.print_backtrace();
         self.parse_sess.span_diagnostic.handler().bug(msg);
@@ -773,7 +783,7 @@ pub fn check_zero_tts(cx: &ExtCtxt,
                       tts: &[ast::TokenTree],
                       name: &str) {
     if tts.len() != 0 {
-        cx.span_err(sp, &format!("{} takes no arguments", name)[]);
+        cx.span_err(sp, &format!("{} takes no arguments", name));
     }
 }
 
@@ -786,12 +796,12 @@ pub fn get_single_str_from_tts(cx: &mut ExtCtxt,
                                -> Option<String> {
     let mut p = cx.new_parser_from_tts(tts);
     if p.token == token::Eof {
-        cx.span_err(sp, &format!("{} takes 1 argument", name)[]);
+        cx.span_err(sp, &format!("{} takes 1 argument", name));
         return None
     }
     let ret = cx.expander().fold_expr(p.parse_expr());
     if p.token != token::Eof {
-        cx.span_err(sp, &format!("{} takes 1 argument", name)[]);
+        cx.span_err(sp, &format!("{} takes 1 argument", name));
     }
     expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| {
         s.to_string()
index 5bfd4a9f6111c6a48f4564f2d578eac979c1c83d..5d0853761eec8321741d3dcc461559324a66e806 100644 (file)
@@ -41,16 +41,16 @@ pub trait AstBuilder {
         -> ast::Path;
 
     fn qpath(&self, self_type: P<ast::Ty>,
-             trait_ref: P<ast::TraitRef>,
-             ident: ast::Ident )
-        -> P<ast::QPath>;
+             trait_path: ast::Path,
+             ident: ast::Ident)
+             -> (ast::QSelf, ast::Path);
     fn qpath_all(&self, self_type: P<ast::Ty>,
-                trait_ref: P<ast::TraitRef>,
+                trait_path: ast::Path,
                 ident: ast::Ident,
                 lifetimes: Vec<ast::Lifetime>,
                 types: Vec<P<ast::Ty>>,
-                bindings: Vec<P<ast::TypeBinding>> )
-        -> P<ast::QPath>;
+                bindings: Vec<P<ast::TypeBinding>>)
+                -> (ast::QSelf, ast::Path);
 
     // types
     fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy;
@@ -114,7 +114,7 @@ pub trait AstBuilder {
     // expressions
     fn expr(&self, span: Span, node: ast::Expr_) -> P<ast::Expr>;
     fn expr_path(&self, path: ast::Path) -> P<ast::Expr>;
-    fn expr_qpath(&self, span: Span, qpath: P<ast::QPath>) -> P<ast::Expr>;
+    fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P<ast::Expr>;
     fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr>;
 
     fn expr_self(&self, span: Span) -> P<ast::Expr>;
@@ -148,6 +148,7 @@ pub trait AstBuilder {
     fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr>;
     fn expr_int(&self, sp: Span, i: isize) -> P<ast::Expr>;
     fn expr_u8(&self, sp: Span, u: u8) -> P<ast::Expr>;
+    fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr>;
     fn expr_bool(&self, sp: Span, value: bool) -> P<ast::Expr>;
 
     fn expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>;
@@ -345,40 +346,40 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     /// Constructs a qualified path.
     ///
-    /// Constructs a path like `<self_type as trait_ref>::ident`.
+    /// Constructs a path like `<self_type as trait_path>::ident`.
     fn qpath(&self,
              self_type: P<ast::Ty>,
-             trait_ref: P<ast::TraitRef>,
+             trait_path: ast::Path,
              ident: ast::Ident)
-             -> P<ast::QPath> {
-        self.qpath_all(self_type, trait_ref, ident, Vec::new(), Vec::new(), Vec::new())
+             -> (ast::QSelf, ast::Path) {
+        self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![])
     }
 
     /// Constructs a qualified path.
     ///
-    /// Constructs a path like `<self_type as trait_ref>::ident<a, T, A=Bar>`.
+    /// Constructs a path like `<self_type as trait_path>::ident<'a, T, A=Bar>`.
     fn qpath_all(&self,
                  self_type: P<ast::Ty>,
-                 trait_ref: P<ast::TraitRef>,
+                 trait_path: ast::Path,
                  ident: ast::Ident,
                  lifetimes: Vec<ast::Lifetime>,
                  types: Vec<P<ast::Ty>>,
-                 bindings: Vec<P<ast::TypeBinding>> )
-                 -> P<ast::QPath> {
-        let segment = ast::PathSegment {
+                 bindings: Vec<P<ast::TypeBinding>>)
+                 -> (ast::QSelf, ast::Path) {
+        let mut path = trait_path;
+        path.segments.push(ast::PathSegment {
             identifier: ident,
             parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
                 lifetimes: lifetimes,
                 types: OwnedSlice::from_vec(types),
                 bindings: OwnedSlice::from_vec(bindings),
             })
-        };
+        });
 
-        P(ast::QPath {
-            self_type: self_type,
-            trait_ref: trait_ref,
-            item_path: segment,
-        })
+        (ast::QSelf {
+            ty: self_type,
+            position: path.segments.len() - 1
+        }, path)
     }
 
     fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
@@ -397,7 +398,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     fn ty_path(&self, path: ast::Path) -> P<ast::Ty> {
-        self.ty(path.span, ast::TyPath(path, ast::DUMMY_NODE_ID))
+        self.ty(path.span, ast::TyPath(None, path))
     }
 
     fn ty_sum(&self, path: ast::Path, bounds: OwnedSlice<ast::TyParamBound>) -> P<ast::Ty> {
@@ -602,12 +603,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     fn expr_path(&self, path: ast::Path) -> P<ast::Expr> {
-        self.expr(path.span, ast::ExprPath(path))
+        self.expr(path.span, ast::ExprPath(None, path))
     }
 
     /// Constructs a QPath expression.
-    fn expr_qpath(&self, span: Span, qpath: P<ast::QPath>) -> P<ast::Expr> {
-        self.expr(span, ast::ExprQPath(qpath))
+    fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P<ast::Expr> {
+        self.expr(span, ast::ExprPath(Some(qself), path))
     }
 
     fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr> {
@@ -695,12 +696,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         self.expr(sp, ast::ExprLit(P(respan(sp, lit))))
     }
     fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr> {
-        self.expr_lit(span, ast::LitInt(i as u64, ast::UnsignedIntLit(ast::TyUs(false))))
+        self.expr_lit(span, ast::LitInt(i as u64, ast::UnsignedIntLit(ast::TyUs)))
     }
     fn expr_int(&self, sp: Span, i: isize) -> P<ast::Expr> {
-        self.expr_lit(sp, ast::LitInt(i as u64, ast::SignedIntLit(ast::TyIs(false),
+        self.expr_lit(sp, ast::LitInt(i as u64, ast::SignedIntLit(ast::TyIs,
                                                                   ast::Sign::new(i))))
     }
+    fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr> {
+        self.expr_lit(sp, ast::LitInt(u as u64, ast::UnsignedIntLit(ast::TyU32)))
+    }
     fn expr_u8(&self, sp: Span, u: u8) -> P<ast::Expr> {
         self.expr_lit(sp, ast::LitInt(u as u64, ast::UnsignedIntLit(ast::TyU8)))
     }
@@ -762,7 +766,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     fn expr_fail(&self, span: Span, msg: InternedString) -> P<ast::Expr> {
         let loc = self.codemap().lookup_char_pos(span.lo);
         let expr_file = self.expr_str(span,
-                                      token::intern_and_get_ident(&loc.file.name[]));
+                                      token::intern_and_get_ident(&loc.file.name));
         let expr_line = self.expr_usize(span, loc.line);
         let expr_file_line_tuple = self.expr_tuple(span, vec!(expr_file, expr_line));
         let expr_file_line_ptr = self.expr_addr_of(span, expr_file_line_tuple);
index 7216602071b5c694a65cc88ee2759d0372bc7721..6a2209bf0aee2f7adbd9a96666a8635fcbf63a53 100644 (file)
@@ -35,5 +35,5 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
     }
 
     let matches_cfg = attr::cfg_matches(&cx.parse_sess.span_diagnostic, &cx.cfg, &*cfg);
-    MacExpr::new(cx.expr_bool(sp, matches_cfg))
+    MacEager::expr(cx.expr_bool(sp, matches_cfg))
 }
index 38098e50dee83750ef905ce8309433f51f5c021e..754c73a9d7838485869216b364c0ca64ca8e35f9 100644 (file)
@@ -40,14 +40,14 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
                     ast::LitInt(i, ast::UnsignedIntLit(_)) |
                     ast::LitInt(i, ast::SignedIntLit(_, ast::Plus)) |
                     ast::LitInt(i, ast::UnsuffixedIntLit(ast::Plus)) => {
-                        accumulator.push_str(&format!("{}", i)[]);
+                        accumulator.push_str(&format!("{}", i));
                     }
                     ast::LitInt(i, ast::SignedIntLit(_, ast::Minus)) |
                     ast::LitInt(i, ast::UnsuffixedIntLit(ast::Minus)) => {
-                        accumulator.push_str(&format!("-{}", i)[]);
+                        accumulator.push_str(&format!("-{}", i));
                     }
                     ast::LitBool(b) => {
-                        accumulator.push_str(&format!("{}", b)[]);
+                        accumulator.push_str(&format!("{}", b));
                     }
                     ast::LitByte(..) |
                     ast::LitBinary(..) => {
@@ -60,7 +60,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
             }
         }
     }
-    base::MacExpr::new(cx.expr_str(
+    base::MacEager::expr(cx.expr_str(
             sp,
             token::intern_and_get_ident(&accumulator[..])))
 }
index 9410a51e7a5f660a368534d275fa651d7d5e13e1..5d07c36c929468394d6c8915a0d11a34fbcf2127 100644 (file)
@@ -14,7 +14,7 @@ use ext::base::*;
 use ext::base;
 use feature_gate;
 use parse::token;
-use parse::token::{str_to_ident};
+use parse::token::str_to_ident;
 use ptr::P;
 
 pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
@@ -53,7 +53,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
 
     let e = P(ast::Expr {
         id: ast::DUMMY_NODE_ID,
-        node: ast::ExprPath(
+        node: ast::ExprPath(None,
             ast::Path {
                  span: sp,
                  global: false,
@@ -67,5 +67,5 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]
         ),
         span: sp,
     });
-    MacExpr::new(e)
+    MacEager::expr(e)
 }
index 93098484ae01343de6df460a61db1d43048e0916..e408c99935d1cdada38d0ddd43c07bef07061daa 100644 (file)
@@ -8,47 +8,34 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast::{MetaItem, MetaWord, Item};
+use ast::{MetaItem, Item};
 use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use ptr::P;
 
-pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt,
-                                span: Span,
-                                mitem: &MetaItem,
-                                item: &Item,
-                                push: F) where
+pub fn expand_deriving_unsafe_bound<F>(cx: &mut ExtCtxt,
+                                       span: Span,
+                                       _: &MetaItem,
+                                       _: &Item,
+                                       _: F) where
     F: FnOnce(P<Item>),
 {
-    let name = match mitem.node {
-        MetaWord(ref tname) => {
-            match &tname[..] {
-                "Copy" => "Copy",
-                "Send" | "Sync" => {
-                    return cx.span_err(span,
-                                       &format!("{} is an unsafe trait and it \
-                                                 should be implemented explicitly",
-                                                *tname))
-                }
-                ref tname => {
-                    cx.span_bug(span,
-                                &format!("expected built-in trait name but \
-                                          found {}", *tname))
-                }
-            }
-        },
-        _ => {
-            return cx.span_err(span, "unexpected value in deriving, expected \
-                                      a trait")
-        }
-    };
+    cx.span_err(span, "this unsafe trait should be implemented explicitly");
+}
 
+pub fn expand_deriving_copy<F>(cx: &mut ExtCtxt,
+                               span: Span,
+                               mitem: &MetaItem,
+                               item: &Item,
+                               push: F) where
+    F: FnOnce(P<Item>),
+{
     let path = Path::new(vec![
         if cx.use_std { "std" } else { "core" },
         "marker",
-        name
+        "Copy",
     ]);
 
     let trait_def = TraitDef {
index 518fbcc80ee95fc8c4b248b55da91c9bc8be585e..f89f3ab55f3f90ec064847743f893c2143e4ebf5 100644 (file)
@@ -40,9 +40,9 @@ pub fn expand_deriving_clone<F>(cx: &mut ExtCtxt,
                 args: Vec::new(),
                 ret_ty: Self_,
                 attributes: attrs,
-                combine_substructure: combine_substructure(box |c, s, sub| {
+                combine_substructure: combine_substructure(Box::new(|c, s, sub| {
                     cs_clone("Clone", c, s, sub)
-                }),
+                })),
             }
         ),
         associated_types: Vec::new(),
@@ -81,11 +81,11 @@ fn cs_clone(
         EnumNonMatchingCollapsed (..) => {
             cx.span_bug(trait_span,
                         &format!("non-matching enum variants in \
-                                 `derive({})`", name)[])
+                                 `derive({})`", name))
         }
         StaticEnum(..) | StaticStruct(..) => {
             cx.span_bug(trait_span,
-                        &format!("static method in `derive({})`", name)[])
+                        &format!("static method in `derive({})`", name))
         }
     }
 
@@ -102,7 +102,7 @@ fn cs_clone(
                 None => {
                     cx.span_bug(trait_span,
                                 &format!("unnamed field in normal struct in \
-                                         `derive({})`", name)[])
+                                         `derive({})`", name))
                 }
             };
             cx.field_imm(field.span, ident, subcall(field))
index 91212a86958962d08c71761b30545ea7432e15f5..c02af437b1c7b987fdca37f696231b14740941bc 100644 (file)
@@ -40,7 +40,7 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
                 cx.expr_binary(span, ast::BiAnd, subexpr, eq)
             },
             cx.expr_bool(span, true),
-            box |cx, span, _, _| cx.expr_bool(span, false),
+            Box::new(|cx, span, _, _| cx.expr_bool(span, false)),
             cx, span, substr)
     }
     fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
@@ -57,7 +57,7 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
                 cx.expr_binary(span, ast::BiOr, subexpr, eq)
             },
             cx.expr_bool(span, false),
-            box |cx, span, _, _| cx.expr_bool(span, true),
+            Box::new(|cx, span, _, _| cx.expr_bool(span, true)),
             cx, span, substr)
     }
 
@@ -70,11 +70,11 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: vec!(borrowed_self()),
-                ret_ty: Literal(path!(bool)),
+                ret_ty: Literal(path_local!(bool)),
                 attributes: attrs,
-                combine_substructure: combine_substructure(box |a, b, c| {
+                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                     $f(a, b, c)
-                })
+                }))
             }
         } }
     }
index b109850a6bd23dac42f217f7e4b742bb527dcc7c..8ecd172b2f0d836899bcd067d1047283a9bd1d30 100644 (file)
@@ -36,11 +36,11 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: vec!(borrowed_self()),
-                ret_ty: Literal(path!(bool)),
+                ret_ty: Literal(path_local!(bool)),
                 attributes: attrs,
-                combine_substructure: combine_substructure(box |cx, span, substr| {
+                combine_substructure: combine_substructure(Box::new(|cx, span, substr| {
                     cs_op($op, $equal, cx, span, substr)
-                })
+                }))
             }
         } }
     }
@@ -61,9 +61,9 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
         args: vec![borrowed_self()],
         ret_ty: ret_ty,
         attributes: attrs,
-        combine_substructure: combine_substructure(box |cx, span, substr| {
+        combine_substructure: combine_substructure(Box::new(|cx, span, substr| {
             cs_partial_cmp(cx, span, substr)
-        })
+        }))
     };
 
     let trait_def = TraitDef {
@@ -84,7 +84,7 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
     trait_def.expand(cx, mitem, item, push)
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum OrderingOp {
     PartialCmpOp, LtOp, LeOp, GtOp, GeOp,
 }
@@ -175,13 +175,13 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
             cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
         },
         equals_expr.clone(),
-        box |cx, span, (self_args, tag_tuple), _non_self_args| {
+        Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
             if self_args.len() != 2 {
                 cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
             } else {
                 some_ordering_collapsed(cx, span, PartialCmpOp, tag_tuple)
             }
-        },
+        }),
         cx, span, substr)
 }
 
@@ -223,7 +223,7 @@ fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt,
             cx.expr_binary(span, ast::BiOr, cmp, and)
         },
         cx.expr_bool(span, equal),
-        box |cx, span, (self_args, tag_tuple), _non_self_args| {
+        Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
             if self_args.len() != 2 {
                 cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
             } else {
@@ -233,6 +233,6 @@ fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt,
                 };
                 some_ordering_collapsed(cx, span, op, tag_tuple)
             }
-        },
+        }),
         cx, span, substr)
 }
index 31a754a1254bb486c88936b9674afe9c3d31f7c3..83164d242e8fbd730fdcc9784bc4a4bb104403f0 100644 (file)
@@ -32,7 +32,8 @@ pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt,
             let block = cx.block(span, stmts, None);
             cx.expr_block(block)
         },
-                       box |cx, sp, _, _| cx.span_bug(sp, "non matching enums in derive(Eq)?"),
+                       Box::new(|cx, sp, _, _| {
+                           cx.span_bug(sp, "non matching enums in derive(Eq)?") }),
                        cx,
                        span,
                        substr)
@@ -57,9 +58,9 @@ pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt,
                 args: vec!(),
                 ret_ty: nil_ty(),
                 attributes: attrs,
-                combine_substructure: combine_substructure(box |a, b, c| {
+                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                     cs_total_eq_assert(a, b, c)
-                })
+                }))
             }
         ),
         associated_types: Vec::new(),
index 2f6f99bc1ee46211bf4959321e2b09ff43d064db..1de955856e712c208d5375574ccf3e7de76096c4 100644 (file)
@@ -41,9 +41,9 @@ pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt,
                 args: vec!(borrowed_self()),
                 ret_ty: Literal(path_std!(cx, core::cmp::Ordering)),
                 attributes: attrs,
-                combine_substructure: combine_substructure(box |a, b, c| {
+                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                     cs_cmp(a, b, c)
-                }),
+                })),
             }
         ),
         associated_types: Vec::new(),
@@ -131,12 +131,12 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
             cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
         },
         cx.expr_path(equals_path.clone()),
-        box |cx, span, (self_args, tag_tuple), _non_self_args| {
+        Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
             if self_args.len() != 2 {
                 cx.span_bug(span, "not exactly 2 arguments in `derives(Ord)`")
             } else {
                 ordering_collapsed(cx, span, tag_tuple)
             }
-        },
+        }),
         cx, span, substr)
 }
index ab0f64e823f9c197427ee0c27d2725da419b7551..6ce68948e4b010615b338836b0e85b49cd853a8b 100644 (file)
@@ -82,9 +82,9 @@ fn expand_deriving_decodable_imp<F>(cx: &mut ExtCtxt,
                     true
                 )),
                 attributes: Vec::new(),
-                combine_substructure: combine_substructure(box |a, b, c| {
+                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                     decodable_substructure(a, b, c, krate)
-                }),
+                })),
             }
         ),
         associated_types: Vec::new(),
@@ -204,7 +204,7 @@ fn decode_static_fields<F>(cx: &mut ExtCtxt,
             } else {
                 let fields = fields.iter().enumerate().map(|(i, &span)| {
                     getarg(cx, span,
-                           token::intern_and_get_ident(&format!("_field{}", i)[]),
+                           token::intern_and_get_ident(&format!("_field{}", i)),
                            i)
                 }).collect();
 
index c10975a2d32eb94e370aa0271267a472b6e5048a..f9991a233547c9dbc24511005df9643b38f65802 100644 (file)
@@ -40,9 +40,9 @@ pub fn expand_deriving_default<F>(cx: &mut ExtCtxt,
                 args: Vec::new(),
                 ret_ty: Self_,
                 attributes: attrs,
-                combine_substructure: combine_substructure(box |a, b, c| {
+                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                     default_substructure(a, b, c)
-                })
+                }))
             }
         ),
         associated_types: Vec::new(),
index dd6094705995e94a4b70818984235fb81c0dad3b..06255f46779259a67bda3460369cbb3a4e3c0954 100644 (file)
@@ -64,7 +64,7 @@
 //!     fn encode(&self, s: &mut S) -> Result<(), E> {
 //!         s.emit_struct("Spanned", 2, |this| {
 //!             this.emit_struct_field("node", 0, |this| self.node.encode(this))
-//!                 .ok().unwrap();
+//!                 .unwrap();
 //!             this.emit_struct_field("span", 1, |this| self.span.encode(this))
 //!         })
 //!     }
@@ -79,9 +79,9 @@
 //!         d.read_struct("Spanned", 2, |this| {
 //!             Ok(Spanned {
 //!                 node: this.read_struct_field("node", 0, |this| Decodable::decode(this))
-//!                     .ok().unwrap(),
+//!                     .unwrap(),
 //!                 span: this.read_struct_field("span", 1, |this| Decodable::decode(this))
-//!                     .ok().unwrap(),
+//!                     .unwrap(),
 //!             })
 //!         })
 //!     }
@@ -158,9 +158,9 @@ fn expand_deriving_encodable_imp<F>(cx: &mut ExtCtxt,
                     true
                 )),
                 attributes: Vec::new(),
-                combine_substructure: combine_substructure(box |a, b, c| {
+                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                     encodable_substructure(a, b, c)
-                }),
+                })),
             }
         ),
         associated_types: Vec::new(),
@@ -181,7 +181,6 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
         Struct(ref fields) => {
             let emit_struct_field = cx.ident_of("emit_struct_field");
             let mut stmts = Vec::new();
-            let last = fields.len() - 1;
             for (i, &FieldInfo {
                     name,
                     ref self_,
@@ -191,7 +190,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                 let name = match name {
                     Some(id) => token::get_ident(id),
                     None => {
-                        token::intern_and_get_ident(&format!("_field{}", i)[])
+                        token::intern_and_get_ident(&format!("_field{}", i))
                     }
                 };
                 let enc = cx.expr_method_call(span, self_.clone(),
@@ -204,6 +203,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
                                                  lambda));
 
                 // last call doesn't need a try!
+                let last = fields.len() - 1;
                 let call = if i != last {
                     cx.expr_try(span, call)
                 } else {
@@ -240,25 +240,24 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
             let encoder = cx.expr_ident(trait_span, blkarg);
             let emit_variant_arg = cx.ident_of("emit_enum_variant_arg");
             let mut stmts = Vec::new();
-            let last = fields.len() - 1;
-            for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() {
-                let enc = cx.expr_method_call(span, self_.clone(),
-                                              encode, vec!(blkencoder.clone()));
-                let lambda = cx.lambda_expr_1(span, enc, blkarg);
-                let call = cx.expr_method_call(span, blkencoder.clone(),
-                                               emit_variant_arg,
-                                               vec!(cx.expr_usize(span, i),
-                                                 lambda));
-                let call = if i != last {
-                    cx.expr_try(span, call)
-                } else {
-                    cx.expr(span, ExprRet(Some(call)))
-                };
-                stmts.push(cx.stmt_expr(call));
-            }
-
-            // enums with no fields need to return Ok()
-            if stmts.len() == 0 {
+            if fields.len() > 0 {
+                let last = fields.len() - 1;
+                for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() {
+                    let enc = cx.expr_method_call(span, self_.clone(),
+                                                  encode, vec!(blkencoder.clone()));
+                    let lambda = cx.lambda_expr_1(span, enc, blkarg);
+                    let call = cx.expr_method_call(span, blkencoder.clone(),
+                                                   emit_variant_arg,
+                                                   vec!(cx.expr_usize(span, i),
+                                                        lambda));
+                    let call = if i != last {
+                        cx.expr_try(span, call)
+                    } else {
+                        cx.expr(span, ExprRet(Some(call)))
+                    };
+                    stmts.push(cx.stmt_expr(call));
+                }
+            } else {
                 let ret_ok = cx.expr(trait_span,
                                      ExprRet(Some(cx.expr_ok(trait_span,
                                                              cx.expr_tuple(trait_span, vec![])))));
index b912ed34ae0ad19c780be51cbd640736a7020053..397775fdbfec384870677af77fd4d06d7b40e98e 100644 (file)
@@ -332,6 +332,46 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
     RefCell::new(f)
 }
 
+/// This method helps to extract all the type parameters referenced from a
+/// type. For a type parameter `<T>`, it looks for either a `TyPath` that
+/// is not global and starts with `T`, or a `TyQPath`.
+fn find_type_parameters(ty: &ast::Ty, ty_param_names: &[ast::Name]) -> Vec<P<ast::Ty>> {
+    use visit;
+
+    struct Visitor<'a> {
+        ty_param_names: &'a [ast::Name],
+        types: Vec<P<ast::Ty>>,
+    }
+
+    impl<'a> visit::Visitor<'a> for Visitor<'a> {
+        fn visit_ty(&mut self, ty: &'a ast::Ty) {
+            match ty.node {
+                ast::TyPath(_, ref path) if !path.global => {
+                    match path.segments.first() {
+                        Some(segment) => {
+                            if self.ty_param_names.contains(&segment.identifier.name) {
+                                self.types.push(P(ty.clone()));
+                            }
+                        }
+                        None => {}
+                    }
+                }
+                _ => {}
+            }
+
+            visit::walk_ty(self, ty)
+        }
+    }
+
+    let mut visitor = Visitor {
+        ty_param_names: ty_param_names,
+        types: Vec::new(),
+    };
+
+    visit::Visitor::visit_ty(&mut visitor, ty);
+
+    visitor.types
+}
 
 impl<'a> TraitDef<'a> {
     pub fn expand<F>(&self,
@@ -363,7 +403,7 @@ impl<'a> TraitDef<'a> {
         // generated implementations are linted
         let mut attrs = newitem.attrs.clone();
         attrs.extend(item.attrs.iter().filter(|a| {
-            match &a.name()[] {
+            match &a.name()[..] {
                 "allow" | "warn" | "deny" | "forbid" => true,
                 _ => false,
             }
@@ -374,34 +414,58 @@ impl<'a> TraitDef<'a> {
         }))
     }
 
-    /// Given that we are deriving a trait `Tr` for a type `T<'a, ...,
-    /// 'z, A, ..., Z>`, creates an impl like:
+    /// Given that we are deriving a trait `DerivedTrait` for a type like:
     ///
     /// ```ignore
-    /// impl<'a, ..., 'z, A:Tr B1 B2, ..., Z: Tr B1 B2> Tr for T<A, ..., Z> { ... }
+    /// struct Struct<'a, ..., 'z, A, B: DeclaredTrait, C, ..., Z> where C: WhereTrait {
+    ///     a: A,
+    ///     b: B::Item,
+    ///     b1: <B as DeclaredTrait>::Item,
+    ///     c1: <C as WhereTrait>::Item,
+    ///     c2: Option<<C as WhereTrait>::Item>,
+    ///     ...
+    /// }
     /// ```
     ///
-    /// where B1, B2, ... are the bounds given by `bounds_paths`.'
+    /// create an impl like:
+    ///
+    /// ```ignore
+    /// impl<'a, ..., 'z, A, B: DeclaredTrait, C, ...  Z> where
+    ///     C:                       WhereTrait,
+    ///     A: DerivedTrait + B1 + ... + BN,
+    ///     B: DerivedTrait + B1 + ... + BN,
+    ///     C: DerivedTrait + B1 + ... + BN,
+    ///     B::Item:                 DerivedTrait + B1 + ... + BN,
+    ///     <C as WhereTrait>::Item: DerivedTrait + B1 + ... + BN,
+    ///     ...
+    /// {
+    ///     ...
+    /// }
+    /// ```
+    ///
+    /// where B1, ..., BN are the bounds given by `bounds_paths`.'. Z is a phantom type, and
+    /// therefore does not get bound by the derived trait.
     fn create_derived_impl(&self,
                            cx: &mut ExtCtxt,
                            type_ident: Ident,
                            generics: &Generics,
-                           methods: Vec<P<ast::Method>>) -> P<ast::Item> {
+                           field_tys: Vec<P<ast::Ty>>,
+                           methods: Vec<P<ast::ImplItem>>) -> P<ast::Item> {
         let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
 
-        // Transform associated types from `deriving::ty::Ty` into `ast::Typedef`
+        // Transform associated types from `deriving::ty::Ty` into `ast::ImplItem`
         let associated_types = self.associated_types.iter().map(|&(ident, ref type_def)| {
-            P(ast::Typedef {
+            P(ast::ImplItem {
                 id: ast::DUMMY_NODE_ID,
                 span: self.span,
                 ident: ident,
                 vis: ast::Inherited,
                 attrs: Vec::new(),
-                typ: type_def.to_ty(cx,
+                node: ast::TypeImplItem(type_def.to_ty(cx,
                     self.span,
                     type_ident,
                     generics
-                ),
+                )),
             })
         });
 
@@ -466,6 +530,35 @@ impl<'a> TraitDef<'a> {
             }
         }));
 
+        if !ty_params.is_empty() {
+            let ty_param_names: Vec<ast::Name> = ty_params.iter()
+                .map(|ty_param| ty_param.ident.name)
+                .collect();
+
+            for field_ty in field_tys.into_iter() {
+                let tys = find_type_parameters(&*field_ty, &ty_param_names);
+
+                for ty in tys.into_iter() {
+                    let mut bounds: Vec<_> = self.additional_bounds.iter().map(|p| {
+                        cx.typarambound(p.to_path(cx, self.span, type_ident, generics))
+                    }).collect();
+
+                    // require the current trait
+                    bounds.push(cx.typarambound(trait_path.clone()));
+
+                    let predicate = ast::WhereBoundPredicate {
+                        span: self.span,
+                        bound_lifetimes: vec![],
+                        bounded_ty: ty,
+                        bounds: OwnedSlice::from_vec(bounds),
+                    };
+
+                    let predicate = ast::WherePredicate::BoundPredicate(predicate);
+                    where_clause.predicates.push(predicate);
+                }
+            }
+        }
+
         let trait_generics = Generics {
             lifetimes: lifetimes,
             ty_params: OwnedSlice::from_vec(ty_params),
@@ -498,7 +591,7 @@ impl<'a> TraitDef<'a> {
         // Just mark it now since we know that it'll end up used downstream
         attr::mark_used(&attr);
         let opt_trait_ref = Some(trait_ref);
-        let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type);
+        let ident = ast_util::impl_pretty_name(&opt_trait_ref, Some(&*self_type));
         let mut a = vec![attr];
         a.extend(self.attributes.iter().cloned());
         cx.item(
@@ -510,14 +603,7 @@ impl<'a> TraitDef<'a> {
                           trait_generics,
                           opt_trait_ref,
                           self_type,
-                          methods.into_iter()
-                                 .map(|method| {
-                                     ast::MethodImplItem(method)
-                                 }).chain(
-                                     associated_types.map(|type_| {
-                                         ast::TypeImplItem(type_)
-                                     })
-                                 ).collect()))
+                          methods.into_iter().chain(associated_types).collect()))
     }
 
     fn expand_struct_def(&self,
@@ -525,6 +611,10 @@ impl<'a> TraitDef<'a> {
                          struct_def: &StructDef,
                          type_ident: Ident,
                          generics: &Generics) -> P<ast::Item> {
+        let field_tys: Vec<P<ast::Ty>> = struct_def.fields.iter()
+            .map(|field| field.node.ty.clone())
+            .collect();
+
         let methods = self.methods.iter().map(|method_def| {
             let (explicit_self, self_args, nonself_args, tys) =
                 method_def.split_self_nonself_args(
@@ -557,7 +647,7 @@ impl<'a> TraitDef<'a> {
                                      body)
         }).collect();
 
-        self.create_derived_impl(cx, type_ident, generics, methods)
+        self.create_derived_impl(cx, type_ident, generics, field_tys, methods)
     }
 
     fn expand_enum_def(&self,
@@ -565,6 +655,21 @@ impl<'a> TraitDef<'a> {
                        enum_def: &EnumDef,
                        type_ident: Ident,
                        generics: &Generics) -> P<ast::Item> {
+        let mut field_tys = Vec::new();
+
+        for variant in enum_def.variants.iter() {
+            match variant.node.kind {
+                ast::VariantKind::TupleVariantKind(ref args) => {
+                    field_tys.extend(args.iter()
+                        .map(|arg| arg.ty.clone()));
+                }
+                ast::VariantKind::StructVariantKind(ref args) => {
+                    field_tys.extend(args.fields.iter()
+                        .map(|field| field.node.ty.clone()));
+                }
+            }
+        }
+
         let methods = self.methods.iter().map(|method_def| {
             let (explicit_self, self_args, nonself_args, tys) =
                 method_def.split_self_nonself_args(cx, self,
@@ -597,7 +702,7 @@ impl<'a> TraitDef<'a> {
                                      body)
         }).collect();
 
-        self.create_derived_impl(cx, type_ident, generics, methods)
+        self.create_derived_impl(cx, type_ident, generics, field_tys, methods)
     }
 }
 
@@ -671,7 +776,7 @@ impl<'a> MethodDef<'a> {
 
         for (i, ty) in self.args.iter().enumerate() {
             let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
-            let ident = cx.ident_of(&format!("__arg_{}", i)[]);
+            let ident = cx.ident_of(&format!("__arg_{}", i));
             arg_tys.push((ident, ast_ty));
 
             let arg_expr = cx.expr_ident(trait_.span, ident);
@@ -702,7 +807,7 @@ impl<'a> MethodDef<'a> {
                      abi: Abi,
                      explicit_self: ast::ExplicitSelf,
                      arg_types: Vec<(Ident, P<ast::Ty>)> ,
-                     body: P<Expr>) -> P<ast::Method> {
+                     body: P<Expr>) -> P<ast::ImplItem> {
         // create the generics that aren't for Self
         let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
 
@@ -725,18 +830,19 @@ impl<'a> MethodDef<'a> {
         let body_block = cx.block_expr(body);
 
         // Create the method.
-        P(ast::Method {
-            attrs: self.attributes.clone(),
+        P(ast::ImplItem {
             id: ast::DUMMY_NODE_ID,
+            attrs: self.attributes.clone(),
             span: trait_.span,
-            node: ast::MethDecl(method_ident,
-                                fn_generics,
-                                abi,
-                                explicit_self,
-                                ast::Unsafety::Normal,
-                                fn_decl,
-                                body_block,
-                                ast::Inherited)
+            vis: ast::Inherited,
+            ident: method_ident,
+            node: ast::MethodImplItem(ast::MethodSig {
+                generics: fn_generics,
+                abi: abi,
+                explicit_self: explicit_self,
+                unsafety: ast::Unsafety::Normal,
+                decl: fn_decl
+            }, body_block)
         })
     }
 
@@ -778,7 +884,7 @@ impl<'a> MethodDef<'a> {
                                              struct_path,
                                              struct_def,
                                              &format!("__self_{}",
-                                                     i)[],
+                                                     i),
                                              ast::MutImmutable);
             patterns.push(pat);
             raw_fields.push(ident_expr);
@@ -971,7 +1077,7 @@ impl<'a> MethodDef<'a> {
                 let mut subpats = Vec::with_capacity(self_arg_names.len());
                 let mut self_pats_idents = Vec::with_capacity(self_arg_names.len() - 1);
                 let first_self_pat_idents = {
-                    let (p, idents) = mk_self_pat(cx, &self_arg_names[0][]);
+                    let (p, idents) = mk_self_pat(cx, &self_arg_names[0]);
                     subpats.push(p);
                     idents
                 };
@@ -1057,7 +1163,7 @@ impl<'a> MethodDef<'a> {
             let arms: Vec<ast::Arm> = variants.iter().enumerate()
                 .map(|(index, variant)| {
                     let pat = variant_to_pat(cx, sp, type_ident, &**variant);
-                    let lit = ast::LitInt(index as u64, ast::UnsignedIntLit(ast::TyUs(false)));
+                    let lit = ast::LitInt(index as u64, ast::UnsignedIntLit(ast::TyUs));
                     cx.arm(sp, vec![pat], cx.expr_lit(sp, lit))
                 }).collect();
 
@@ -1216,7 +1322,8 @@ impl<'a> TraitDef<'a> {
             callee: codemap::NameAndSpan {
                 name: format!("derive({})", trait_name),
                 format: codemap::MacroAttribute,
-                span: Some(self.span)
+                span: Some(self.span),
+                allow_internal_unstable: false,
             }
         });
         to_set
@@ -1289,7 +1396,7 @@ impl<'a> TraitDef<'a> {
                     cx.span_bug(sp, "a struct with named and unnamed fields in `derive`");
                 }
             };
-            let ident = cx.ident_of(&format!("{}_{}", prefix, i)[]);
+            let ident = cx.ident_of(&format!("{}_{}", prefix, i));
             paths.push(codemap::Spanned{span: sp, node: ident});
             let val = cx.expr(
                 sp, ast::ExprParen(cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp,ident)))));
@@ -1335,7 +1442,7 @@ impl<'a> TraitDef<'a> {
                 let mut ident_expr = Vec::new();
                 for (i, va) in variant_args.iter().enumerate() {
                     let sp = self.set_expn_info(cx, va.ty.span);
-                    let ident = cx.ident_of(&format!("{}_{}", prefix, i)[]);
+                    let ident = cx.ident_of(&format!("{}_{}", prefix, i));
                     let path1 = codemap::Spanned{span: sp, node: ident};
                     paths.push(path1);
                     let expr_path = cx.expr_path(cx.path_ident(sp, ident));
@@ -1378,7 +1485,7 @@ pub fn cs_fold<F>(use_foldl: bool,
                       field.span,
                       old,
                       field.self_.clone(),
-                      &field.other[])
+                      &field.other)
                 })
             } else {
                 all_fields.iter().rev().fold(base, |old, field| {
@@ -1386,7 +1493,7 @@ pub fn cs_fold<F>(use_foldl: bool,
                       field.span,
                       old,
                       field.self_.clone(),
-                      &field.other[])
+                      &field.other)
                 })
             }
         },
index 2149c7a7f77a7da72d86848fd952f24a415865ca..da80c7a0e6d15553f240e727654559bb33b71342 100644 (file)
@@ -45,9 +45,9 @@ pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
                 args: vec!(Ptr(box Literal(arg), Borrowed(None, MutMutable))),
                 ret_ty: nil_ty(),
                 attributes: vec![],
-                combine_substructure: combine_substructure(box |a, b, c| {
+                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                     hash_substructure(a, b, c)
-                })
+                }))
             }
         ),
         associated_types: Vec::new(),
index f8bc331bfcfe7697a13bc4a0df84e03229f57075..d8c50b5a0942ae37eeedfbad14a71ada51aa65af 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 //! FIXME (#2810): hygiene. Search for "__" strings (in other files too). We also assume "extra" is
 //! the standard library, and "std" is the core library.
 
-use ast::{Item, MetaItem, MetaList, MetaNameValue, MetaWord};
-use ext::base::ExtCtxt;
+use ast::{Item, MetaItem, MetaWord};
+use attr::AttrMetaMethods;
+use ext::base::{ExtCtxt, SyntaxEnv, Decorator, ItemDecorator, Modifier};
+use ext::build::AstBuilder;
+use feature_gate;
 use codemap::Span;
+use parse::token::{intern, intern_and_get_ident};
 use ptr::P;
 
 macro_rules! pathvec {
@@ -30,6 +34,12 @@ macro_rules! path {
     )
 }
 
+macro_rules! path_local {
+    ($x:ident) => (
+        ::ext::deriving::generic::ty::Path::new_local(stringify!($x))
+    )
+}
+
 macro_rules! pathvec_std {
     ($cx:expr, $first:ident :: $($rest:ident)::+) => (
         if $cx.use_std {
@@ -68,101 +78,123 @@ pub mod totalord;
 
 pub mod generic;
 
-pub fn expand_deprecated_deriving(cx: &mut ExtCtxt,
-                                  span: Span,
-                                  _: &MetaItem,
-                                  _: &Item,
-                                  _: &mut FnMut(P<Item>)) {
-    cx.span_err(span, "`deriving` has been renamed to `derive`");
-}
-
-pub fn expand_meta_derive(cx: &mut ExtCtxt,
-                          _span: Span,
-                          mitem: &MetaItem,
-                          item: &Item,
-                          push: &mut FnMut(P<Item>)) {
-    match mitem.node {
-        MetaNameValue(_, ref l) => {
-            cx.span_err(l.span, "unexpected value in `derive`");
+fn expand_derive(cx: &mut ExtCtxt,
+                 _: Span,
+                 mitem: &MetaItem,
+                 item: P<Item>) -> P<Item> {
+    item.map(|mut item| {
+        if mitem.value_str().is_some() {
+            cx.span_err(mitem.span, "unexpected value in `derive`");
         }
-        MetaWord(_) => {
+
+        let traits = mitem.meta_item_list().unwrap_or(&[]);
+        if traits.is_empty() {
             cx.span_warn(mitem.span, "empty trait list in `derive`");
         }
-        MetaList(_, ref titems) if titems.len() == 0 => {
-            cx.span_warn(mitem.span, "empty trait list in `derive`");
+
+        for titem in traits.iter().rev() {
+            let tname = match titem.node {
+                MetaWord(ref tname) => tname,
+                _ => {
+                    cx.span_err(titem.span, "malformed `derive` entry");
+                    continue;
+                }
+            };
+
+            if !(is_builtin_trait(tname) || cx.ecfg.enable_custom_derive()) {
+                feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
+                                               "custom_derive",
+                                               titem.span,
+                                               feature_gate::EXPLAIN_CUSTOM_DERIVE);
+                continue;
+            }
+
+            // #[derive(Foo, Bar)] expands to #[derive_Foo] #[derive_Bar]
+            item.attrs.push(cx.attribute(titem.span, cx.meta_word(titem.span,
+                intern_and_get_ident(&format!("derive_{}", tname)))));
         }
-        MetaList(_, ref titems) => {
-            for titem in titems.iter().rev() {
-                match titem.node {
-                    MetaNameValue(ref tname, _) |
-                    MetaList(ref tname, _) |
-                    MetaWord(ref tname) => {
-                        macro_rules! expand {
-                            ($func:path) => ($func(cx, titem.span, &**titem, item,
-                                                   |i| push(i)))
-                        }
-
-                        match &tname[..] {
-                            "Clone" => expand!(clone::expand_deriving_clone),
-
-                            "Hash" => expand!(hash::expand_deriving_hash),
-
-                            "RustcEncodable" => {
-                                expand!(encodable::expand_deriving_rustc_encodable)
-                            }
-                            "RustcDecodable" => {
-                                expand!(decodable::expand_deriving_rustc_decodable)
-                            }
-                            "Encodable" => {
-                                cx.span_warn(titem.span,
-                                             "derive(Encodable) is deprecated \
-                                              in favor of derive(RustcEncodable)");
-
-                                expand!(encodable::expand_deriving_encodable)
-                            }
-                            "Decodable" => {
-                                cx.span_warn(titem.span,
-                                             "derive(Decodable) is deprecated \
-                                              in favor of derive(RustcDecodable)");
-
-                                expand!(decodable::expand_deriving_decodable)
-                            }
-
-                            "PartialEq" => expand!(eq::expand_deriving_eq),
-                            "Eq" => expand!(totaleq::expand_deriving_totaleq),
-                            "PartialOrd" => expand!(ord::expand_deriving_ord),
-                            "Ord" => expand!(totalord::expand_deriving_totalord),
-
-                            "Rand" => expand!(rand::expand_deriving_rand),
-
-                            "Show" => {
-                                cx.span_warn(titem.span,
-                                             "derive(Show) is deprecated \
-                                              in favor of derive(Debug)");
-
-                                expand!(show::expand_deriving_show)
-                            },
-
-                            "Debug" => expand!(show::expand_deriving_show),
-
-                            "Default" => expand!(default::expand_deriving_default),
-
-                            "FromPrimitive" => expand!(primitive::expand_deriving_from_primitive),
-
-                            "Send" => expand!(bounds::expand_deriving_bound),
-                            "Sync" => expand!(bounds::expand_deriving_bound),
-                            "Copy" => expand!(bounds::expand_deriving_bound),
-
-                            ref tname => {
-                                cx.span_err(titem.span,
-                                            &format!("unknown `derive` \
-                                                     trait: `{}`",
-                                                    *tname)[]);
-                            }
-                        };
+
+        item
+    })
+}
+
+macro_rules! derive_traits {
+    ($( $name:expr => $func:path, )*) => {
+        pub fn register_all(env: &mut SyntaxEnv) {
+            // Define the #[derive_*] extensions.
+            $({
+                struct DeriveExtension;
+
+                impl ItemDecorator for DeriveExtension {
+                    fn expand(&self,
+                              ecx: &mut ExtCtxt,
+                              sp: Span,
+                              mitem: &MetaItem,
+                              item: &Item,
+                              push: &mut FnMut(P<Item>)) {
+                        warn_if_deprecated(ecx, sp, $name);
+                        $func(ecx, sp, mitem, item, |i| push(i));
                     }
                 }
+
+                env.insert(intern(concat!("derive_", $name)),
+                           Decorator(Box::new(DeriveExtension)));
+            })*
+
+            env.insert(intern("derive"),
+                       Modifier(Box::new(expand_derive)));
+        }
+
+        fn is_builtin_trait(name: &str) -> bool {
+            match name {
+                $( $name )|* => true,
+                _ => false,
             }
         }
     }
 }
+
+derive_traits! {
+    "Clone" => clone::expand_deriving_clone,
+
+    "Hash" => hash::expand_deriving_hash,
+
+    "RustcEncodable" => encodable::expand_deriving_rustc_encodable,
+
+    "RustcDecodable" => decodable::expand_deriving_rustc_decodable,
+
+    "PartialEq" => eq::expand_deriving_eq,
+    "Eq" => totaleq::expand_deriving_totaleq,
+    "PartialOrd" => ord::expand_deriving_ord,
+    "Ord" => totalord::expand_deriving_totalord,
+
+    "Rand" => rand::expand_deriving_rand,
+
+    "Debug" => show::expand_deriving_show,
+
+    "Default" => default::expand_deriving_default,
+
+    "FromPrimitive" => primitive::expand_deriving_from_primitive,
+
+    "Send" => bounds::expand_deriving_unsafe_bound,
+    "Sync" => bounds::expand_deriving_unsafe_bound,
+    "Copy" => bounds::expand_deriving_copy,
+
+    // deprecated
+    "Show" => show::expand_deriving_show,
+    "Encodable" => encodable::expand_deriving_encodable,
+    "Decodable" => decodable::expand_deriving_decodable,
+}
+
+#[inline] // because `name` is a compile-time constant
+fn warn_if_deprecated(ecx: &mut ExtCtxt, sp: Span, name: &str) {
+    if let Some(replacement) = match name {
+        "Show" => Some("Debug"),
+        "Encodable" => Some("RustcEncodable"),
+        "Decodable" => Some("RustcDecodable"),
+        _ => None,
+    } {
+        ecx.span_warn(sp, &format!("derive({}) is deprecated in favor of derive({})",
+                                   name, replacement));
+    }
+}
index 22c87d978c9e5aa2771d3971e71b2c155693527a..b2d0a9f6b51ad329a30b044332f2d32cbcc37880 100644 (file)
@@ -38,31 +38,31 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
                 name: "from_i64",
                 generics: LifetimeBounds::empty(),
                 explicit_self: None,
-                args: vec!(Literal(path!(i64))),
+                args: vec!(Literal(path_local!(i64))),
                 ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                            None,
                                            vec!(box Self_),
                                            true)),
                 // #[inline] liable to cause code-bloat
                 attributes: attrs.clone(),
-                combine_substructure: combine_substructure(box |c, s, sub| {
+                combine_substructure: combine_substructure(Box::new(|c, s, sub| {
                     cs_from("i64", c, s, sub)
-                }),
+                })),
             },
             MethodDef {
                 name: "from_u64",
                 generics: LifetimeBounds::empty(),
                 explicit_self: None,
-                args: vec!(Literal(path!(u64))),
+                args: vec!(Literal(path_local!(u64))),
                 ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                            None,
                                            vec!(box Self_),
                                            true)),
                 // #[inline] liable to cause code-bloat
                 attributes: attrs,
-                combine_substructure: combine_substructure(box |c, s, sub| {
+                combine_substructure: combine_substructure(Box::new(|c, s, sub| {
                     cs_from("u64", c, s, sub)
-                }),
+                })),
             }
         ),
         associated_types: Vec::new(),
index 029b65351081967166e2793c802ce152d16c8bab..631e5f979d9ee7a38a1cf426dbc141828fa0f6a3 100644 (file)
@@ -12,7 +12,7 @@ use ast;
 use ast::{MetaItem, Item, Expr};
 use codemap::Span;
 use ext::base::ExtCtxt;
-use ext::build::{AstBuilder};
+use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use ext::deriving::generic::ty::*;
 use ptr::P;
@@ -55,9 +55,9 @@ pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt,
                 ),
                 ret_ty: Self_,
                 attributes: Vec::new(),
-                combine_substructure: combine_substructure(box |a, b, c| {
+                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                     rand_substructure(a, b, c)
-                })
+                }))
             }
         ),
         associated_types: Vec::new(),
index 281f23f9e61e8b232d2c083348bdaa90b873b790..ae9a402006095b3d08f42c13fa72ff1b03d6c860 100644 (file)
@@ -11,7 +11,6 @@
 use ast;
 use ast::{MetaItem, Item, Expr,};
 use codemap::Span;
-use ext::format;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
@@ -19,8 +18,6 @@ use ext::deriving::generic::ty::*;
 use parse::token;
 use ptr::P;
 
-use std::collections::HashMap;
-
 pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
                                span: Span,
                                mitem: &MetaItem,
@@ -46,9 +43,9 @@ pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
                 args: vec!(fmtr),
                 ret_ty: Literal(path_std!(cx, core::fmt::Result)),
                 attributes: Vec::new(),
-                combine_substructure: combine_substructure(box |a, b, c| {
+                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                     show_substructure(a, b, c)
-                })
+                }))
             }
         ],
         associated_types: Vec::new(),
@@ -56,14 +53,12 @@ pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
     trait_def.expand(cx, mitem, item, push)
 }
 
-/// We construct a format string and then defer to std::fmt, since that
-/// knows what's up with formatting and so on.
+/// We use the debug builders to do the heavy lifting here
 fn show_substructure(cx: &mut ExtCtxt, span: Span,
                      substr: &Substructure) -> P<Expr> {
-    // build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {},
-    // <field>: {}, ... }` based on the "shape".
-    //
-    // Easy start: they all start with the name.
+    // build fmt.debug_struct(<name>).field(<fieldname>, &<fieldval>)....build()
+    // or fmt.debug_tuple(<name>).field(&<fieldval>)....build()
+    // based on the "shape".
     let name = match *substr.fields {
         Struct(_) => substr.type_ident,
         EnumMatching(_, v, _) => v.node.name,
@@ -72,70 +67,53 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
         }
     };
 
-    let mut format_string = String::from_str(&token::get_ident(name));
-    // the internal fields we're actually formatting
-    let mut exprs = Vec::new();
+    // We want to make sure we have the expn_id set so that we can use unstable methods
+    let span = Span { expn_id: cx.backtrace(), .. span };
+    let name = cx.expr_lit(span, ast::Lit_::LitStr(token::get_ident(name),
+                                                   ast::StrStyle::CookedStr));
+    let mut expr = substr.nonself_args[0].clone();
 
-    // Getting harder... making the format string:
     match *substr.fields {
-        // unit struct/nullary variant: no work necessary!
-        Struct(ref fields) if fields.len() == 0 => {}
-        EnumMatching(_, _, ref fields) if fields.len() == 0 => {}
-
         Struct(ref fields) | EnumMatching(_, _, ref fields) => {
-            if fields[0].name.is_none() {
+            if fields.is_empty() || fields[0].name.is_none() {
                 // tuple struct/"normal" variant
-
-                format_string.push_str("(");
-
-                for (i, field) in fields.iter().enumerate() {
-                    if i != 0 { format_string.push_str(", "); }
-
-                    format_string.push_str("{:?}");
-
-                    exprs.push(field.self_.clone());
+                expr = cx.expr_method_call(span,
+                                           expr,
+                                           token::str_to_ident("debug_tuple"),
+                                           vec![name]);
+
+                for field in fields {
+                    expr = cx.expr_method_call(span,
+                                               expr,
+                                               token::str_to_ident("field"),
+                                               vec![cx.expr_addr_of(field.span,
+                                                                    field.self_.clone())]);
                 }
-
-                format_string.push_str(")");
             } else {
                 // normal struct/struct variant
-
-                format_string.push_str(" {{");
-
-                for (i, field) in fields.iter().enumerate() {
-                    if i != 0 { format_string.push_str(","); }
-
-                    let name = token::get_ident(field.name.unwrap());
-                    format_string.push_str(" ");
-                    format_string.push_str(&name);
-                    format_string.push_str(": {:?}");
-
-                    exprs.push(field.self_.clone());
+                expr = cx.expr_method_call(span,
+                                           expr,
+                                           token::str_to_ident("debug_struct"),
+                                           vec![name]);
+
+                for field in fields {
+                    let name = cx.expr_lit(field.span, ast::Lit_::LitStr(
+                            token::get_ident(field.name.clone().unwrap()),
+                            ast::StrStyle::CookedStr));
+                    expr = cx.expr_method_call(span,
+                                               expr,
+                                               token::str_to_ident("field"),
+                                               vec![name,
+                                                    cx.expr_addr_of(field.span,
+                                                                    field.self_.clone())]);
                 }
-
-                format_string.push_str(" }}");
             }
         }
         _ => unreachable!()
     }
 
-    // AST construction!
-    // we're basically calling
-    //
-    // format_arg_method!(fmt, write_fmt, "<format_string>", exprs...)
-    //
-    // but doing it directly via ext::format.
-    let formatter = substr.nonself_args[0].clone();
-
-    let meth = cx.ident_of("write_fmt");
-    let s = token::intern_and_get_ident(&format_string[..]);
-    let format_string = cx.expr_str(span, s);
-
-    // phew, not our responsibility any more!
-
-    let args = vec![
-        format::expand_preparsed_format_args(cx, span, format_string,
-                                             exprs, vec![], HashMap::new())
-    ];
-    cx.expr_method_call(span, formatter, meth, args)
+    cx.expr_method_call(span,
+                        expr,
+                        token::str_to_ident("finish"),
+                        vec![])
 }
index 9c04d1e928295d42c387eb8d3748b1e91d301c4d..f72303985e78cc24d45888e7e7081eb0b90b2543 100644 (file)
@@ -59,7 +59,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
                                           &s[..]))))
       }
     };
-    MacExpr::new(e)
+    MacEager::expr(e)
 }
 
 pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
@@ -83,7 +83,7 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         None => {
             token::intern_and_get_ident(&format!("environment variable `{}` \
                                                  not defined",
-                                                var)[])
+                                                var))
         }
         Some(second) => {
             match expr_to_string(cx, second, "expected string literal") {
@@ -108,5 +108,5 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         }
         Ok(s) => cx.expr_str(sp, token::intern_and_get_ident(&s))
     };
-    MacExpr::new(e)
+    MacEager::expr(e)
 }
index d4dda7390a52f7788dae1cc2e2d7fcf25de6ccf0..ee2cf9017bbf34e38e47d917ef30a03c709e0db3 100644 (file)
@@ -22,7 +22,7 @@ use attr::AttrMetaMethods;
 use codemap;
 use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
 use ext::base::*;
-use feature_gate::{Features};
+use feature_gate::{self, Features};
 use fold;
 use fold::*;
 use parse;
@@ -41,7 +41,7 @@ pub fn expand_type(t: P<ast::Ty>,
     debug!("expanding type {:?} with impl_ty {:?}", t, impl_ty);
     let t = match (t.node.clone(), impl_ty) {
         // Expand uses of `Self` in impls to the concrete type.
-        (ast::Ty_::TyPath(ref path, _), Some(ref impl_ty)) => {
+        (ast::Ty_::TyPath(None, ref path), Some(ref impl_ty)) => {
             let path_as_ident = path_to_ident(path);
             // Note unhygenic comparison here. I think this is correct, since
             // even though `Self` is almost just a type parameter, the treatment
@@ -389,19 +389,20 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span,
                     fld.cx.span_err(
                         pth.span,
                         &format!("macro undefined: '{}!'",
-                                &extnamestr)[]);
+                                &extnamestr));
 
                     // let compilation continue
                     None
                 }
                 Some(rc) => match *rc {
-                    NormalTT(ref expandfun, exp_span) => {
+                    NormalTT(ref expandfun, exp_span, allow_internal_unstable) => {
                         fld.cx.bt_push(ExpnInfo {
                                 call_site: span,
                                 callee: NameAndSpan {
                                     name: extnamestr.to_string(),
                                     format: MacroBang,
                                     span: exp_span,
+                                    allow_internal_unstable: allow_internal_unstable,
                                 },
                             });
                         let fm = fresh_mark();
@@ -426,7 +427,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span,
                                     pth.span,
                                     &format!("non-expression macro in expression position: {}",
                                             &extnamestr[..]
-                                            )[]);
+                                            ));
                                 return None;
                             }
                         };
@@ -436,7 +437,7 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac, span: codemap::Span,
                         fld.cx.span_err(
                             pth.span,
                             &format!("'{}' is not a tt-style macro",
-                                    &extnamestr)[]);
+                                    &extnamestr));
                         None
                     }
                 }
@@ -530,6 +531,9 @@ fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander)
                             name: mname.to_string(),
                             format: MacroAttribute,
                             span: None,
+                            // attributes can do whatever they like,
+                            // for now
+                            allow_internal_unstable: true,
                         }
                     });
                     it = mac.expand(fld.cx, attr.span, &*attr.node.value, it);
@@ -571,7 +575,7 @@ fn contains_macro_use(fld: &mut MacroExpander, attrs: &[ast::Attribute]) -> bool
             fld.cx.span_warn(attr.span, "macro_escape is a deprecated synonym for macro_use");
             is_use = true;
             if let ast::AttrInner = attr.node.style {
-                fld.cx.span_help(attr.span, "consider an outer attribute, \
+                fld.cx.fileline_help(attr.span, "consider an outer attribute, \
                                              #[macro_use] mod ...");
             }
         };
@@ -608,20 +612,19 @@ pub fn expand_item_mac(it: P<ast::Item>,
             None => {
                 fld.cx.span_err(path_span,
                                 &format!("macro undefined: '{}!'",
-                                        extnamestr)[]);
+                                        extnamestr));
                 // let compilation continue
                 return SmallVector::zero();
             }
 
             Some(rc) => match *rc {
-                NormalTT(ref expander, span) => {
+                NormalTT(ref expander, span, allow_internal_unstable) => {
                     if it.ident.name != parse::token::special_idents::invalid.name {
                         fld.cx
                             .span_err(path_span,
-                                      &format!("macro {}! expects no ident argument, \
-                                        given '{}'",
-                                      extnamestr,
-                                      token::get_ident(it.ident))[]);
+                                      &format!("macro {}! expects no ident argument, given '{}'",
+                                               extnamestr,
+                                               token::get_ident(it.ident)));
                         return SmallVector::zero();
                     }
                     fld.cx.bt_push(ExpnInfo {
@@ -629,18 +632,19 @@ pub fn expand_item_mac(it: P<ast::Item>,
                         callee: NameAndSpan {
                             name: extnamestr.to_string(),
                             format: MacroBang,
-                            span: span
+                            span: span,
+                            allow_internal_unstable: allow_internal_unstable,
                         }
                     });
                     // mark before expansion:
                     let marked_before = mark_tts(&tts[..], fm);
                     expander.expand(fld.cx, it.span, &marked_before[..])
                 }
-                IdentTT(ref expander, span) => {
+                IdentTT(ref expander, span, allow_internal_unstable) => {
                     if it.ident.name == parse::token::special_idents::invalid.name {
                         fld.cx.span_err(path_span,
                                         &format!("macro {}! expects an ident argument",
-                                                &extnamestr)[]);
+                                                &extnamestr));
                         return SmallVector::zero();
                     }
                     fld.cx.bt_push(ExpnInfo {
@@ -648,7 +652,8 @@ pub fn expand_item_mac(it: P<ast::Item>,
                         callee: NameAndSpan {
                             name: extnamestr.to_string(),
                             format: MacroBang,
-                            span: span
+                            span: span,
+                            allow_internal_unstable: allow_internal_unstable,
                         }
                     });
                     // mark before expansion:
@@ -659,19 +664,38 @@ pub fn expand_item_mac(it: P<ast::Item>,
                     if it.ident.name == parse::token::special_idents::invalid.name {
                         fld.cx.span_err(path_span,
                                         &format!("macro_rules! expects an ident argument")
-                                        []);
+                                        );
                         return SmallVector::zero();
                     }
+
                     fld.cx.bt_push(ExpnInfo {
                         call_site: it.span,
                         callee: NameAndSpan {
                             name: extnamestr.to_string(),
                             format: MacroBang,
                             span: None,
+                            // `macro_rules!` doesn't directly allow
+                            // unstable (this is orthogonal to whether
+                            // the macro it creates allows it)
+                            allow_internal_unstable: false,
                         }
                     });
                     // DON'T mark before expansion.
 
+                    let allow_internal_unstable = attr::contains_name(&it.attrs,
+                                                                      "allow_internal_unstable");
+
+                    // ensure any #[allow_internal_unstable]s are
+                    // detected (including nested macro definitions
+                    // etc.)
+                    if allow_internal_unstable && !fld.cx.ecfg.enable_allow_internal_unstable() {
+                        feature_gate::emit_feature_err(
+                            &fld.cx.parse_sess.span_diagnostic,
+                            "allow_internal_unstable",
+                            it.span,
+                            feature_gate::EXPLAIN_ALLOW_INTERNAL_UNSTABLE)
+                    }
+
                     let def = ast::MacroDef {
                         ident: it.ident,
                         attrs: it.attrs.clone(),
@@ -680,6 +704,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
                         imported_from: None,
                         export: attr::contains_name(&it.attrs, "macro_export"),
                         use_locally: true,
+                        allow_internal_unstable: allow_internal_unstable,
                         body: tts,
                     };
                     fld.cx.insert_macro(def);
@@ -691,7 +716,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
                 _ => {
                     fld.cx.span_err(it.span,
                                     &format!("{}! is not legal in item position",
-                                            &extnamestr)[]);
+                                            &extnamestr));
                     return SmallVector::zero();
                 }
             }
@@ -710,7 +735,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
         None => {
             fld.cx.span_err(path_span,
                             &format!("non-item macro in item position: {}",
-                                    &extnamestr)[]);
+                                    &extnamestr));
             return SmallVector::zero();
         }
     };
@@ -954,19 +979,20 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
             None => {
                 fld.cx.span_err(pth.span,
                                 &format!("macro undefined: '{}!'",
-                                        extnamestr)[]);
+                                        extnamestr));
                 // let compilation continue
                 return DummyResult::raw_pat(span);
             }
 
             Some(rc) => match *rc {
-                NormalTT(ref expander, tt_span) => {
+                NormalTT(ref expander, tt_span, allow_internal_unstable) => {
                     fld.cx.bt_push(ExpnInfo {
                         call_site: span,
                         callee: NameAndSpan {
                             name: extnamestr.to_string(),
                             format: MacroBang,
-                            span: tt_span
+                            span: tt_span,
+                            allow_internal_unstable: allow_internal_unstable,
                         }
                     });
 
@@ -983,7 +1009,7 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
                                 &format!(
                                     "non-pattern macro in pattern position: {}",
                                     &extnamestr
-                                    )[]
+                                    )
                             );
                             return DummyResult::raw_pat(span);
                         }
@@ -995,7 +1021,7 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
                 _ => {
                     fld.cx.span_err(span,
                                     &format!("{}! is not legal in pattern position",
-                                            &extnamestr)[]);
+                                            &extnamestr));
                     return DummyResult::raw_pat(span);
                 }
             }
@@ -1095,7 +1121,10 @@ fn expand_annotatable(a: Annotatable,
                         callee: NameAndSpan {
                             name: mname.to_string(),
                             format: MacroAttribute,
-                            span: None
+                            span: Some(attr.span),
+                            // attributes can do whatever they like,
+                            // for now.
+                            allow_internal_unstable: true,
                         }
                     });
 
@@ -1145,29 +1174,26 @@ fn expand_annotatable(a: Annotatable,
                 noop_fold_item(it, fld).into_iter().map(|i| Annotatable::Item(i)).collect()
             }
         },
-        Annotatable::TraitItem(it) => match it {
-            ast::TraitItem::ProvidedMethod(m) => {
-                expand_method(m, fld).into_iter().map(|m|
-                    Annotatable::TraitItem(ast::TraitItem::ProvidedMethod(m))).collect()
-            }
-            ast::TraitItem::RequiredMethod(m) => {
-                SmallVector::one(Annotatable::TraitItem(
-                    ast::TraitItem::RequiredMethod(fld.fold_type_method(m))))
-            }
-            ast::TraitItem::TypeTraitItem(t) => {
-                SmallVector::one(Annotatable::TraitItem(
-                    ast::TraitItem::TypeTraitItem(P(fld.fold_associated_type((*t).clone())))))
-            }
-        },
-        Annotatable::ImplItem(it) => match it {
-            ast::ImplItem::MethodImplItem(m) => {
-                expand_method(m, fld).into_iter().map(|m|
-                    Annotatable::ImplItem(ast::ImplItem::MethodImplItem(m))).collect()
-            }
-            ast::ImplItem::TypeImplItem(t) => {
-                SmallVector::one(Annotatable::ImplItem(
-                    ast::ImplItem::TypeImplItem(P(fld.fold_typedef((*t).clone())))))
-            }
+
+        Annotatable::TraitItem(it) => match it.node {
+            ast::MethodTraitItem(_, Some(_)) => SmallVector::one(it.map(|ti| ast::TraitItem {
+                id: ti.id,
+                ident: ti.ident,
+                attrs: ti.attrs,
+                node: match ti.node  {
+                    ast::MethodTraitItem(sig, Some(body)) => {
+                        let (sig, body) = expand_and_rename_method(sig, body, fld);
+                        ast::MethodTraitItem(sig, Some(body))
+                    }
+                    _ => unreachable!()
+                },
+                span: fld.new_span(ti.span)
+            })),
+            _ => fold::noop_fold_trait_item(it, fld)
+        }.into_iter().map(Annotatable::TraitItem).collect(),
+
+        Annotatable::ImplItem(ii) => {
+            expand_impl_item(ii, fld).into_iter().map(Annotatable::ImplItem).collect()
         }
     };
 
@@ -1175,21 +1201,6 @@ fn expand_annotatable(a: Annotatable,
     new_items
 }
 
-fn expand_trait_item(i: ast::TraitItem,
-                     fld: &mut MacroExpander)
-                     -> SmallVector<ast::TraitItem> {
-    expand_annotatable(Annotatable::TraitItem(i), fld)
-        .into_iter().map(|i| i.expect_trait_item()).collect()
-
-}
-
-fn expand_impl_item(i: ast::ImplItem,
-                    fld: &mut MacroExpander)
-                    -> SmallVector<ast::ImplItem> {
-    expand_annotatable(Annotatable::ImplItem(i), fld)
-        .into_iter().map(|i| i.expect_impl_item()).collect()
-}
-
 // partition the attributes into ItemModifiers and others
 fn modifiers(attrs: &Vec<ast::Attribute>,
              fld: &MacroExpander)
@@ -1245,6 +1256,9 @@ fn expand_item_multi_modifier(mut it: Annotatable,
                             name: mname.to_string(),
                             format: MacroAttribute,
                             span: None,
+                            // attributes can do whatever they like,
+                            // for now
+                            allow_internal_unstable: true,
                         }
                     });
                     it = mac.expand(fld.cx, attr.span, &*attr.node.value, it);
@@ -1260,54 +1274,48 @@ fn expand_item_multi_modifier(mut it: Annotatable,
     expand_item_multi_modifier(it, fld)
 }
 
-// expand a method
-fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<ast::Method>> {
-    m.and_then(|m| match m.node {
-        ast::MethDecl(ident,
-                      generics,
-                      abi,
-                      explicit_self,
-                      fn_style,
-                      decl,
-                      body,
-                      vis) => {
-            let id = fld.new_id(m.id);
-            let (rewritten_fn_decl, rewritten_body)
-                = expand_and_rename_fn_decl_and_block(decl, body, fld);
-            SmallVector::one(P(ast::Method {
-                    attrs: fold::fold_attrs(m.attrs, fld),
-                    id: id,
-                    span: fld.new_span(m.span),
-                    node: ast::MethDecl(fld.fold_ident(ident),
-                                        noop_fold_generics(generics, fld),
-                                        abi,
-                                        fld.fold_explicit_self(explicit_self),
-                                        fn_style,
-                                        rewritten_fn_decl,
-                                        rewritten_body,
-                                        vis)
-                }))
-        },
-        ast::MethMac(mac) => {
-            let maybe_new_methods =
-                expand_mac_invoc(mac, m.span,
-                                 |r| r.make_methods(),
-                                 |meths, mark| meths.move_map(|m| mark_method(m, mark)),
+fn expand_impl_item(ii: P<ast::ImplItem>, fld: &mut MacroExpander)
+                 -> SmallVector<P<ast::ImplItem>> {
+    match ii.node {
+        ast::MethodImplItem(..) => SmallVector::one(ii.map(|ii| ast::ImplItem {
+            id: ii.id,
+            ident: ii.ident,
+            attrs: ii.attrs,
+            vis: ii.vis,
+            node: match ii.node  {
+                ast::MethodImplItem(sig, body) => {
+                    let (sig, body) = expand_and_rename_method(sig, body, fld);
+                    ast::MethodImplItem(sig, body)
+                }
+                _ => unreachable!()
+            },
+            span: fld.new_span(ii.span)
+        })),
+        ast::MacImplItem(_) => {
+            let (span, mac) = ii.and_then(|ii| match ii.node {
+                ast::MacImplItem(mac) => (ii.span, mac),
+                _ => unreachable!()
+            });
+            let maybe_new_items =
+                expand_mac_invoc(mac, span,
+                                 |r| r.make_impl_items(),
+                                 |meths, mark| meths.move_map(|m| mark_impl_item(m, mark)),
                                  fld);
 
-            match maybe_new_methods {
-                Some(methods) => {
+            match maybe_new_items {
+                Some(impl_items) => {
                     // expand again if necessary
-                    let new_methods = methods.into_iter()
-                                             .flat_map(|m| fld.fold_method(m).into_iter())
-                                             .collect();
+                    let new_items = impl_items.into_iter().flat_map(|ii| {
+                        expand_impl_item(ii, fld).into_iter()
+                    }).collect();
                     fld.cx.bt_pop();
-                    new_methods
+                    new_items
                 }
                 None => SmallVector::zero()
             }
         }
-    })
+        _ => fold::noop_fold_impl_item(ii, fld)
+    }
 }
 
 /// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
@@ -1315,7 +1323,7 @@ fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<as
 /// the block, returning both the new FnDecl and the new Block.
 fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Block>,
                                        fld: &mut MacroExpander)
-    -> (P<ast::FnDecl>, P<ast::Block>) {
+                                       -> (P<ast::FnDecl>, P<ast::Block>) {
     let expanded_decl = fld.fold_fn_decl(fn_decl);
     let idents = fn_decl_arg_bindings(&*expanded_decl);
     let renames =
@@ -1329,6 +1337,20 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: P<ast::FnDecl>, block: P<ast::Bl
     (rewritten_fn_decl,rewritten_body)
 }
 
+fn expand_and_rename_method(sig: ast::MethodSig, body: P<ast::Block>,
+                            fld: &mut MacroExpander)
+                            -> (ast::MethodSig, P<ast::Block>) {
+    let (rewritten_fn_decl, rewritten_body)
+        = expand_and_rename_fn_decl_and_block(sig.decl, body, fld);
+    (ast::MethodSig {
+        generics: fld.fold_generics(sig.generics),
+        abi: sig.abi,
+        explicit_self: fld.fold_explicit_self(sig.explicit_self),
+        unsafety: sig.unsafety,
+        decl: rewritten_fn_decl
+    }, rewritten_body)
+}
+
 /// A tree-folder that performs macro expansion
 pub struct MacroExpander<'a, 'b:'a> {
     pub cx: &'a mut ExtCtxt<'b>,
@@ -1378,16 +1400,14 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
         expand_arm(arm, self)
     }
 
-    fn fold_trait_item(&mut self, i: ast::TraitItem) -> SmallVector<ast::TraitItem> {
-        expand_trait_item(i, self)
-    }
-
-    fn fold_impl_item(&mut self, i: ast::ImplItem) -> SmallVector<ast::ImplItem> {
-        expand_impl_item(i, self)
+    fn fold_trait_item(&mut self, i: P<ast::TraitItem>) -> SmallVector<P<ast::TraitItem>> {
+        expand_annotatable(Annotatable::TraitItem(i), self)
+            .into_iter().map(|i| i.expect_trait_item()).collect()
     }
 
-    fn fold_method(&mut self, method: P<ast::Method>) -> SmallVector<P<ast::Method>> {
-        expand_method(method, self)
+    fn fold_impl_item(&mut self, i: P<ast::ImplItem>) -> SmallVector<P<ast::ImplItem>> {
+        expand_annotatable(Annotatable::ImplItem(i), self)
+            .into_iter().map(|i| i.expect_impl_item()).collect()
     }
 
     fn fold_ty(&mut self, t: P<ast::Ty>) -> P<ast::Ty> {
@@ -1415,6 +1435,19 @@ pub struct ExpansionConfig<'feat> {
     pub recursion_limit: usize,
 }
 
+macro_rules! feature_tests {
+    ($( fn $getter:ident = $field:ident, )*) => {
+        $(
+            pub fn $getter(&self) -> bool {
+                match self.features {
+                    Some(&Features { $field: true, .. }) => true,
+                    _ => false,
+                }
+            }
+        )*
+    }
+}
+
 impl<'feat> ExpansionConfig<'feat> {
     pub fn default(crate_name: String) -> ExpansionConfig<'static> {
         ExpansionConfig {
@@ -1424,39 +1457,14 @@ impl<'feat> ExpansionConfig<'feat> {
         }
     }
 
-    pub fn enable_quotes(&self) -> bool {
-        match self.features {
-            Some(&Features { allow_quote: true, .. }) => true,
-            _ => false,
-        }
-    }
-
-    pub fn enable_asm(&self) -> bool {
-        match self.features {
-            Some(&Features { allow_asm: true, .. }) => true,
-            _ => false,
-        }
-    }
-
-    pub fn enable_log_syntax(&self) -> bool {
-        match self.features {
-            Some(&Features { allow_log_syntax: true, .. }) => true,
-            _ => false,
-        }
-    }
-
-    pub fn enable_concat_idents(&self) -> bool {
-        match self.features {
-            Some(&Features { allow_concat_idents: true, .. }) => true,
-            _ => false,
-        }
-    }
-
-    pub fn enable_trace_macros(&self) -> bool {
-        match self.features {
-            Some(&Features { allow_trace_macros: true, .. }) => true,
-            _ => false,
-        }
+    feature_tests! {
+        fn enable_quotes = allow_quote,
+        fn enable_asm = allow_asm,
+        fn enable_log_syntax = allow_log_syntax,
+        fn enable_concat_idents = allow_concat_idents,
+        fn enable_trace_macros = allow_trace_macros,
+        fn enable_allow_internal_unstable = allow_internal_unstable,
+        fn enable_custom_derive = allow_custom_derive,
     }
 }
 
@@ -1545,9 +1553,9 @@ fn mark_item(expr: P<ast::Item>, m: Mrk) -> P<ast::Item> {
 }
 
 // apply a given mark to the given item. Used following the expansion of a macro.
-fn mark_method(expr: P<ast::Method>, m: Mrk) -> P<ast::Method> {
-    Marker{mark:m}.fold_method(expr)
-        .expect_one("marking an item didn't return exactly one method")
+fn mark_impl_item(ii: P<ast::ImplItem>, m: Mrk) -> P<ast::ImplItem> {
+    Marker{mark:m}.fold_impl_item(ii)
+        .expect_one("marking an impl item didn't return exactly one impl item")
 }
 
 /// Check that there are no macro invocations left in the AST:
@@ -1595,13 +1603,10 @@ mod test {
 
     impl<'v> Visitor<'v> for PathExprFinderContext {
         fn visit_expr(&mut self, expr: &ast::Expr) {
-            match expr.node {
-                ast::ExprPath(ref p) => {
-                    self.path_accumulator.push(p.clone());
-                    // not calling visit_path, but it should be fine.
-                }
-                _ => visit::walk_expr(self, expr)
+            if let ast::ExprPath(None, ref p) = expr.node {
+                self.path_accumulator.push(p.clone());
             }
+            visit::walk_expr(self, expr);
         }
     }
 
@@ -1639,7 +1644,7 @@ mod test {
     }
 
     // make sure that macros can't escape fns
-    #[should_fail]
+    #[should_panic]
     #[test] fn macros_cant_escape_fns_test () {
         let src = "fn bogus() {macro_rules! z (() => (3+4));}\
                    fn inty() -> i32 { z!() }".to_string();
@@ -1653,7 +1658,7 @@ mod test {
     }
 
     // make sure that macros can't escape modules
-    #[should_fail]
+    #[should_panic]
     #[test] fn macros_cant_escape_mods_test () {
         let src = "mod foo {macro_rules! z (() => (3+4));}\
                    fn inty() -> i32 { z!() }".to_string();
@@ -1981,7 +1986,7 @@ foo_module!();
         // the xx binding should bind all of the xx varrefs:
         for (idx,v) in varrefs.iter().filter(|p| {
             p.segments.len() == 1
-            && "xx" == &token::get_ident(p.segments[0].identifier)[]
+            && "xx" == &*token::get_ident(p.segments[0].identifier)
         }).enumerate() {
             if mtwt::resolve(v.segments[0].identifier) != resolved_binding {
                 println!("uh oh, xx binding didn't match xx varref:");
@@ -2029,7 +2034,7 @@ foo_module!();
         let renamed_crate = renamer.fold_crate(the_crate);
         let idents = crate_idents(&renamed_crate);
         let resolved : Vec<ast::Name> = idents.iter().map(|id| mtwt::resolve(*id)).collect();
-        assert_eq!(resolved,vec!(f_ident.name,Name(16),int_ident.name,Name(16),Name(16),Name(16)));
+        assert_eq!(resolved, [f_ident.name,Name(16),int_ident.name,Name(16),Name(16),Name(16)]);
     }
 
     // test the PatIdentRenamer; only PatIdents get renamed
@@ -2045,8 +2050,6 @@ foo_module!();
         let idents = crate_idents(&renamed_crate);
         let resolved : Vec<ast::Name> = idents.iter().map(|id| mtwt::resolve(*id)).collect();
         let x_name = x_ident.name;
-        assert_eq!(resolved,vec!(f_ident.name,Name(16),int_ident.name,Name(16),x_name,x_name));
+        assert_eq!(resolved, [f_ident.name,Name(16),int_ident.name,Name(16),x_name,x_name]);
     }
-
-
 }
index e17329d7d33002b96f85c9060a1962a82330b7fe..2fe77bf7a5411cbff2ed0c49a6acfeb769e32491 100644 (file)
@@ -113,7 +113,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                 _ => {
                     ecx.span_err(p.span,
                                  &format!("expected ident for named argument, found `{}`",
-                                         p.this_token_to_string())[]);
+                                         p.this_token_to_string()));
                     return None;
                 }
             };
@@ -127,7 +127,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                 Some(prev) => {
                     ecx.span_err(e.span,
                                  &format!("duplicate argument named `{}`",
-                                         name)[]);
+                                         name));
                     ecx.parse_sess.span_diagnostic.span_note(prev.span, "previously here");
                     continue
                 }
@@ -281,19 +281,19 @@ impl<'a, 'b> Context<'a, 'b> {
                                   &format!("argument redeclared with type `{}` when \
                                            it was previously `{}`",
                                           *ty,
-                                          *cur)[]);
+                                          *cur));
             }
             (&Known(ref cur), _) => {
                 self.ecx.span_err(sp,
                                   &format!("argument used to format with `{}` was \
                                            attempted to not be used for formatting",
-                                           *cur)[]);
+                                           *cur));
             }
             (_, &Known(ref ty)) => {
                 self.ecx.span_err(sp,
                                   &format!("argument previously used as a format \
                                            argument attempted to be used as `{}`",
-                                           *ty)[]);
+                                           *ty));
             }
             (_, _) => {
                 self.ecx.span_err(sp, "argument declared with multiple formats");
@@ -337,7 +337,7 @@ impl<'a, 'b> Context<'a, 'b> {
     /// Translate the accumulated string literals to a literal expression
     fn trans_literal_string(&mut self) -> P<ast::Expr> {
         let sp = self.fmtsp;
-        let s = token::intern_and_get_ident(&self.literal[]);
+        let s = token::intern_and_get_ident(&self.literal);
         self.literal.clear();
         self.ecx.expr_str(sp, s)
     }
@@ -417,7 +417,7 @@ impl<'a, 'b> Context<'a, 'b> {
                     parse::AlignUnknown => align("Unknown"),
                 };
                 let align = self.ecx.expr_path(align);
-                let flags = self.ecx.expr_usize(sp, arg.format.flags);
+                let flags = self.ecx.expr_u32(sp, arg.format.flags);
                 let prec = self.trans_count(arg.format.precision);
                 let width = self.trans_count(arg.format.width);
                 let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "FormatSpec"));
@@ -494,7 +494,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 None => continue // error already generated
             };
 
-            let name = self.ecx.ident_of(&format!("__arg{}", i)[]);
+            let name = self.ecx.ident_of(&format!("__arg{}", i));
             pats.push(self.ecx.pat_ident(e.span, name));
             locals.push(Context::format_arg(self.ecx, e.span, arg_ty,
                                             self.ecx.expr_ident(e.span, name)));
@@ -511,9 +511,9 @@ impl<'a, 'b> Context<'a, 'b> {
             };
 
             let lname = self.ecx.ident_of(&format!("__arg{}",
-                                                  *name)[]);
+                                                  *name));
             pats.push(self.ecx.pat_ident(e.span, lname));
-            names[self.name_positions[*name]] =
+            names[*self.name_positions.get(name).unwrap()] =
                 Some(Context::format_arg(self.ecx, e.span, arg_ty,
                                          self.ecx.expr_ident(e.span, lname)));
             heads.push(self.ecx.expr_addr_of(e.span, e));
@@ -600,7 +600,7 @@ impl<'a, 'b> Context<'a, 'b> {
                     _ => {
                         ecx.span_err(sp,
                                      &format!("unknown format trait `{}`",
-                                             *tyname)[]);
+                                             *tyname));
                         "Dummy"
                     }
                 }
@@ -610,7 +610,7 @@ impl<'a, 'b> Context<'a, 'b> {
                         ecx.ident_of_std("core"),
                         ecx.ident_of("fmt"),
                         ecx.ident_of("ArgumentV1"),
-                        ecx.ident_of("from_uint")], vec![arg])
+                        ecx.ident_of("from_usize")], vec![arg])
             }
         };
 
@@ -633,7 +633,7 @@ pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt, sp: Span,
 
     match parse_args(ecx, sp, tts) {
         Some((efmt, args, order, names)) => {
-            MacExpr::new(expand_preparsed_format_args(ecx, sp, efmt,
+            MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt,
                                                       args, order, names))
         }
         None => DummyResult::expr(sp)
@@ -694,7 +694,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
     }
     if !parser.errors.is_empty() {
         cx.ecx.span_err(cx.fmtsp, &format!("invalid format string: {}",
-                                          parser.errors.remove(0))[]);
+                                          parser.errors.remove(0)));
         return DummyResult::raw_expr(sp);
     }
     if !cx.literal.is_empty() {
index b6563d77b8864e7df854dd6be4dbee1af75fecae..f514f72d565487d26df304dd52a8144a9a01f3a8 100644 (file)
@@ -38,7 +38,7 @@ pub struct SCTable {
     rename_memo: RefCell<HashMap<(SyntaxContext,Ident,Name),SyntaxContext>>,
 }
 
-#[derive(PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+#[derive(PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy, Clone)]
 pub enum SyntaxContext_ {
     EmptyCtxt,
     Mark (Mrk,SyntaxContext),
@@ -66,9 +66,8 @@ pub fn apply_mark(m: Mrk, ctxt: SyntaxContext) -> SyntaxContext {
 /// Extend a syntax context with a given mark and sctable (explicit memoization)
 fn apply_mark_internal(m: Mrk, ctxt: SyntaxContext, table: &SCTable) -> SyntaxContext {
     let key = (ctxt, m);
-    * table.mark_memo.borrow_mut().entry(key).get().unwrap_or_else(
-          |vacant_entry|
-              vacant_entry.insert(idx_push(&mut *table.table.borrow_mut(), Mark(m, ctxt))))
+    * table.mark_memo.borrow_mut().entry(key)
+        .or_insert_with(|| idx_push(&mut *table.table.borrow_mut(), Mark(m, ctxt)))
 }
 
 /// Extend a syntax context with a given rename
@@ -84,9 +83,8 @@ fn apply_rename_internal(id: Ident,
                        table: &SCTable) -> SyntaxContext {
     let key = (ctxt, id, to);
 
-    * table.rename_memo.borrow_mut().entry(key).get().unwrap_or_else(
-          |vacant_entry|
-              vacant_entry.insert(idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt))))
+    * table.rename_memo.borrow_mut().entry(key)
+        .or_insert_with(|| idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt)))
 }
 
 /// Apply a list of renamings to a context
@@ -288,19 +286,19 @@ mod tests {
     fn xorpush_test () {
         let mut s = Vec::new();
         xor_push(&mut s, 14);
-        assert_eq!(s.clone(), vec!(14));
+        assert_eq!(s.clone(), [14]);
         xor_push(&mut s, 14);
-        assert_eq!(s.clone(), Vec::new());
+        assert_eq!(s.clone(), []);
         xor_push(&mut s, 14);
-        assert_eq!(s.clone(), vec!(14));
+        assert_eq!(s.clone(), [14]);
         xor_push(&mut s, 15);
-        assert_eq!(s.clone(), vec!(14, 15));
+        assert_eq!(s.clone(), [14, 15]);
         xor_push(&mut s, 16);
-        assert_eq!(s.clone(), vec!(14, 15, 16));
+        assert_eq!(s.clone(), [14, 15, 16]);
         xor_push(&mut s, 16);
-        assert_eq!(s.clone(), vec!(14, 15));
+        assert_eq!(s.clone(), [14, 15]);
         xor_push(&mut s, 15);
-        assert_eq!(s.clone(), vec!(14));
+        assert_eq!(s.clone(), [14]);
     }
 
     fn id(n: u32, s: SyntaxContext) -> Ident {
@@ -389,13 +387,13 @@ mod tests {
         assert_eq!(marksof_internal (EMPTY_CTXT,stopname,&t),Vec::new());
         // FIXME #5074: ANF'd to dodge nested calls
         { let ans = unfold_marks(vec!(4,98),EMPTY_CTXT,&mut t);
-         assert_eq! (marksof_internal (ans,stopname,&t),vec!(4,98));}
+         assert_eq! (marksof_internal (ans,stopname,&t), [4, 98]);}
         // does xoring work?
         { let ans = unfold_marks(vec!(5,5,16),EMPTY_CTXT,&mut t);
-         assert_eq! (marksof_internal (ans,stopname,&t), vec!(16));}
+         assert_eq! (marksof_internal (ans,stopname,&t), [16]);}
         // does nested xoring work?
         { let ans = unfold_marks(vec!(5,10,10,5,16),EMPTY_CTXT,&mut t);
-         assert_eq! (marksof_internal (ans, stopname,&t), vec!(16));}
+         assert_eq! (marksof_internal (ans, stopname,&t), [16]);}
         // rename where stop doesn't match:
         { let chain = vec!(M(9),
                         R(id(name1.usize() as u32,
@@ -403,7 +401,7 @@ mod tests {
                           Name(100101102)),
                         M(14));
          let ans = unfold_test_sc(chain,EMPTY_CTXT,&mut t);
-         assert_eq! (marksof_internal (ans, stopname, &t), vec!(9,14));}
+         assert_eq! (marksof_internal (ans, stopname, &t), [9, 14]);}
         // rename where stop does match
         { let name1sc = apply_mark_internal(4, EMPTY_CTXT, &mut t);
          let chain = vec!(M(9),
@@ -411,7 +409,7 @@ mod tests {
                          stopname),
                        M(14));
          let ans = unfold_test_sc(chain,EMPTY_CTXT,&mut t);
-         assert_eq! (marksof_internal (ans, stopname, &t), vec!(9)); }
+         assert_eq! (marksof_internal (ans, stopname, &t), [9]); }
     }
 
 
index 2c7bf713aad85d67728d2abaddaa95906c5e9dac..87299721fb3caf65de000a6fb616239e3cf65c32 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -171,12 +171,15 @@ pub mod rt {
         }
     }
 
+    impl_to_source! { ast::Path, path_to_string }
     impl_to_source! { ast::Ty, ty_to_string }
     impl_to_source! { ast::Block, block_to_string }
     impl_to_source! { ast::Arg, arg_to_string }
     impl_to_source! { Generics, generics_to_string }
+    impl_to_source! { ast::WhereClause, where_clause_to_string }
     impl_to_source! { P<ast::Item>, item_to_string }
-    impl_to_source! { P<ast::Method>, method_to_string }
+    impl_to_source! { P<ast::ImplItem>, impl_item_to_string }
+    impl_to_source! { P<ast::TraitItem>, trait_item_to_string }
     impl_to_source! { P<ast::Stmt>, stmt_to_string }
     impl_to_source! { P<ast::Expr>, expr_to_string }
     impl_to_source! { P<ast::Pat>, pat_to_string }
@@ -273,13 +276,13 @@ pub mod rt {
         );
     }
 
-    impl_to_source_int! { signed, int, ast::TyIs(false) }
+    impl_to_source_int! { signed, isize, ast::TyIs }
     impl_to_source_int! { signed, i8,  ast::TyI8 }
     impl_to_source_int! { signed, i16, ast::TyI16 }
     impl_to_source_int! { signed, i32, ast::TyI32 }
     impl_to_source_int! { signed, i64, ast::TyI64 }
 
-    impl_to_source_int! { unsigned, uint, ast::TyUs(false) }
+    impl_to_source_int! { unsigned, usize, ast::TyUs }
     impl_to_source_int! { unsigned, u8,   ast::TyU8 }
     impl_to_source_int! { unsigned, u16,  ast::TyU16 }
     impl_to_source_int! { unsigned, u32,  ast::TyU32 }
@@ -308,14 +311,17 @@ pub mod rt {
     }
 
     impl_to_tokens! { ast::Ident }
+    impl_to_tokens! { ast::Path }
     impl_to_tokens! { P<ast::Item> }
+    impl_to_tokens! { P<ast::ImplItem> }
+    impl_to_tokens! { P<ast::TraitItem> }
     impl_to_tokens! { P<ast::Pat> }
     impl_to_tokens! { ast::Arm }
-    impl_to_tokens! { P<ast::Method> }
     impl_to_tokens_lifetime! { &'a [P<ast::Item>] }
     impl_to_tokens! { ast::Ty }
     impl_to_tokens_lifetime! { &'a [ast::Ty] }
     impl_to_tokens! { Generics }
+    impl_to_tokens! { ast::WhereClause }
     impl_to_tokens! { P<ast::Stmt> }
     impl_to_tokens! { P<ast::Expr> }
     impl_to_tokens! { ast::Block }
@@ -325,12 +331,12 @@ pub mod rt {
     impl_to_tokens! { () }
     impl_to_tokens! { char }
     impl_to_tokens! { bool }
-    impl_to_tokens! { int }
+    impl_to_tokens! { isize }
     impl_to_tokens! { i8 }
     impl_to_tokens! { i16 }
     impl_to_tokens! { i32 }
     impl_to_tokens! { i64 }
-    impl_to_tokens! { uint }
+    impl_to_tokens! { usize }
     impl_to_tokens! { u8 }
     impl_to_tokens! { u16 }
     impl_to_tokens! { u32 }
@@ -363,8 +369,7 @@ pub mod rt {
             parse::parse_stmt_from_source_str("<quote expansion>".to_string(),
                                               s,
                                               self.cfg(),
-                                              Vec::new(),
-                                              self.parse_sess())
+                                              self.parse_sess()).expect("parse error")
         }
 
         fn parse_expr(&self, s: String) -> P<ast::Expr> {
@@ -401,25 +406,24 @@ pub fn expand_quote_tokens<'cx>(cx: &'cx mut ExtCtxt,
                                 tts: &[ast::TokenTree])
                                 -> Box<base::MacResult+'cx> {
     let (cx_expr, expr) = expand_tts(cx, sp, tts);
-    let expanded = expand_wrapper(cx, sp, cx_expr, expr);
-    base::MacExpr::new(expanded)
+    let expanded = expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"]]);
+    base::MacEager::expr(expanded)
 }
 
 pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
                               sp: Span,
                               tts: &[ast::TokenTree])
                               -> Box<base::MacResult+'cx> {
-    let expanded = expand_parse_call(cx, sp, "parse_expr", Vec::new(), tts);
-    base::MacExpr::new(expanded)
+    let expanded = expand_parse_call(cx, sp, "parse_expr", vec!(), tts);
+    base::MacEager::expr(expanded)
 }
 
 pub fn expand_quote_item<'cx>(cx: &mut ExtCtxt,
                               sp: Span,
                               tts: &[ast::TokenTree])
                               -> Box<base::MacResult+'cx> {
-    let expanded = expand_parse_call(cx, sp, "parse_item_with_outer_attributes",
-                                    vec!(), tts);
-    base::MacExpr::new(expanded)
+    let expanded = expand_parse_call(cx, sp, "parse_item", vec!(), tts);
+    base::MacEager::expr(expanded)
 }
 
 pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt,
@@ -427,7 +431,7 @@ pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt,
                              tts: &[ast::TokenTree])
                              -> Box<base::MacResult+'cx> {
     let expanded = expand_parse_call(cx, sp, "parse_pat", vec!(), tts);
-    base::MacExpr::new(expanded)
+    base::MacEager::expr(expanded)
 }
 
 pub fn expand_quote_arm(cx: &mut ExtCtxt,
@@ -435,7 +439,7 @@ pub fn expand_quote_arm(cx: &mut ExtCtxt,
                         tts: &[ast::TokenTree])
                         -> Box<base::MacResult+'static> {
     let expanded = expand_parse_call(cx, sp, "parse_arm", vec!(), tts);
-    base::MacExpr::new(expanded)
+    base::MacEager::expr(expanded)
 }
 
 pub fn expand_quote_ty(cx: &mut ExtCtxt,
@@ -443,30 +447,45 @@ pub fn expand_quote_ty(cx: &mut ExtCtxt,
                        tts: &[ast::TokenTree])
                        -> Box<base::MacResult+'static> {
     let expanded = expand_parse_call(cx, sp, "parse_ty", vec!(), tts);
-    base::MacExpr::new(expanded)
+    base::MacEager::expr(expanded)
 }
 
-pub fn expand_quote_method(cx: &mut ExtCtxt,
-                           sp: Span,
-                           tts: &[ast::TokenTree])
-                           -> Box<base::MacResult+'static> {
-    let expanded = expand_parse_call(cx, sp, "parse_method_with_outer_attributes",
-                                     vec!(), tts);
-    base::MacExpr::new(expanded)
+pub fn expand_quote_stmt(cx: &mut ExtCtxt,
+                         sp: Span,
+                         tts: &[ast::TokenTree])
+                         -> Box<base::MacResult+'static> {
+    let expanded = expand_parse_call(cx, sp, "parse_stmt", vec!(), tts);
+    base::MacEager::expr(expanded)
 }
 
-pub fn expand_quote_stmt(cx: &mut ExtCtxt,
+pub fn expand_quote_attr(cx: &mut ExtCtxt,
                          sp: Span,
                          tts: &[ast::TokenTree])
                          -> Box<base::MacResult+'static> {
-    let e_attrs = cx.expr_vec_ng(sp);
-    let expanded = expand_parse_call(cx, sp, "parse_stmt",
-                                    vec!(e_attrs), tts);
-    base::MacExpr::new(expanded)
+    let expanded = expand_parse_call(cx, sp, "parse_attribute",
+                                    vec!(cx.expr_bool(sp, true)), tts);
+
+    base::MacEager::expr(expanded)
+}
+
+pub fn expand_quote_matcher(cx: &mut ExtCtxt,
+                            sp: Span,
+                            tts: &[ast::TokenTree])
+                            -> Box<base::MacResult+'static> {
+    let (cx_expr, tts) = parse_arguments_to_quote(cx, tts);
+    let mut vector = mk_stmts_let(cx, sp);
+    vector.extend(statements_mk_tts(cx, &tts[..], true).into_iter());
+    let block = cx.expr_block(
+        cx.block_all(sp,
+                     vector,
+                     Some(cx.expr_ident(sp, id_ext("tt")))));
+
+    let expanded = expand_wrapper(cx, sp, cx_expr, block, &[&["syntax", "ext", "quote", "rt"]]);
+    base::MacEager::expr(expanded)
 }
 
 fn ids_ext(strs: Vec<String> ) -> Vec<ast::Ident> {
-    strs.iter().map(|str| str_to_ident(&(*str)[])).collect()
+    strs.iter().map(|str| str_to_ident(&(*str))).collect()
 }
 
 fn id_ext(str: &str) -> ast::Ident {
@@ -527,7 +546,7 @@ fn mk_delim(cx: &ExtCtxt, sp: Span, delim: token::DelimToken) -> P<ast::Expr> {
 }
 
 #[allow(non_upper_case_globals)]
-fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
+fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
     macro_rules! mk_lit {
         ($name: expr, $suffix: expr, $($args: expr),*) => {{
             let inner = cx.expr_call(sp, mk_token_path(cx, sp, $name), vec![$($args),*]);
@@ -606,6 +625,21 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
                                 vec!(mk_name(cx, sp, ident.ident())));
         }
 
+        token::MatchNt(name, kind, namep, kindp) => {
+            return cx.expr_call(sp,
+                                mk_token_path(cx, sp, "MatchNt"),
+                                vec!(mk_ident(cx, sp, name),
+                                     mk_ident(cx, sp, kind),
+                                     match namep {
+                                        ModName => mk_token_path(cx, sp, "ModName"),
+                                        Plain   => mk_token_path(cx, sp, "Plain"),
+                                     },
+                                     match kindp {
+                                        ModName => mk_token_path(cx, sp, "ModName"),
+                                        Plain   => mk_token_path(cx, sp, "Plain"),
+                                     }));
+        }
+
         token::Interpolated(_) => panic!("quote! with interpolated token"),
 
         _ => ()
@@ -635,14 +669,15 @@ fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
         token::FatArrow     => "FatArrow",
         token::Pound        => "Pound",
         token::Dollar       => "Dollar",
+        token::Question     => "Question",
         token::Underscore   => "Underscore",
         token::Eof          => "Eof",
-        _                   => panic!(),
+        _                   => panic!("unhandled token in quote!"),
     };
     mk_token_path(cx, sp, name)
 }
 
-fn mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
+fn statements_mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree, matcher: bool) -> Vec<P<ast::Stmt>> {
     match *tt {
         ast::TtToken(sp, SubstNt(ident, _)) => {
             // tt.extend($ident.to_tokens(ext_cx).into_iter())
@@ -663,18 +698,18 @@ fn mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
 
             vec!(cx.stmt_expr(e_push))
         }
-        ref tt @ ast::TtToken(_, MatchNt(..)) => {
+        ref tt @ ast::TtToken(_, MatchNt(..)) if !matcher => {
             let mut seq = vec![];
             for i in 0..tt.len() {
                 seq.push(tt.get_tt(i));
             }
-            mk_tts(cx, &seq[..])
+            statements_mk_tts(cx, &seq[..], matcher)
         }
         ast::TtToken(sp, ref tok) => {
             let e_sp = cx.expr_ident(sp, id_ext("_sp"));
             let e_tok = cx.expr_call(sp,
                                      mk_ast_path(cx, sp, "TtToken"),
-                                     vec!(e_sp, mk_token(cx, sp, tok)));
+                                     vec!(e_sp, expr_mk_token(cx, sp, tok)));
             let e_push =
                 cx.expr_method_call(sp,
                                     cx.expr_ident(sp, id_ext("tt")),
@@ -683,27 +718,61 @@ fn mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
             vec!(cx.stmt_expr(e_push))
         },
         ast::TtDelimited(_, ref delimed) => {
-            mk_tt(cx, &delimed.open_tt()).into_iter()
-                .chain(delimed.tts.iter().flat_map(|tt| mk_tt(cx, tt).into_iter()))
-                .chain(mk_tt(cx, &delimed.close_tt()).into_iter())
+            statements_mk_tt(cx, &delimed.open_tt(), matcher).into_iter()
+                .chain(delimed.tts.iter()
+                                  .flat_map(|tt| statements_mk_tt(cx, tt, matcher).into_iter()))
+                .chain(statements_mk_tt(cx, &delimed.close_tt(), matcher).into_iter())
                 .collect()
         },
-        ast::TtSequence(..) => panic!("TtSequence in quote!"),
-    }
-}
+        ast::TtSequence(sp, ref seq) => {
+            if !matcher {
+                panic!("TtSequence in quote!");
+            }
 
-fn mk_tts(cx: &ExtCtxt, tts: &[ast::TokenTree]) -> Vec<P<ast::Stmt>> {
-    let mut ss = Vec::new();
-    for tt in tts {
-        ss.extend(mk_tt(cx, tt).into_iter());
+            let e_sp = cx.expr_ident(sp, id_ext("_sp"));
+
+            let stmt_let_tt = cx.stmt_let(sp, true, id_ext("tt"), cx.expr_vec_ng(sp));
+            let mut tts_stmts = vec![stmt_let_tt];
+            tts_stmts.extend(statements_mk_tts(cx, &seq.tts[..], matcher).into_iter());
+            let e_tts = cx.expr_block(cx.block(sp, tts_stmts,
+                                                   Some(cx.expr_ident(sp, id_ext("tt")))));
+            let e_separator = match seq.separator {
+                Some(ref sep) => cx.expr_some(sp, expr_mk_token(cx, sp, sep)),
+                None => cx.expr_none(sp),
+            };
+            let e_op = match seq.op {
+                ast::ZeroOrMore => mk_ast_path(cx, sp, "ZeroOrMore"),
+                ast::OneOrMore => mk_ast_path(cx, sp, "OneOrMore"),
+            };
+            let fields = vec![cx.field_imm(sp, id_ext("tts"), e_tts),
+                              cx.field_imm(sp, id_ext("separator"), e_separator),
+                              cx.field_imm(sp, id_ext("op"), e_op),
+                              cx.field_imm(sp, id_ext("num_captures"),
+                                               cx.expr_usize(sp, seq.num_captures))];
+            let seq_path = vec![id_ext("syntax"), id_ext("ast"), id_ext("SequenceRepetition")];
+            let e_seq_struct = cx.expr_struct(sp, cx.path_global(sp, seq_path), fields);
+            let e_rc_new = cx.expr_call_global(sp, vec![id_ext("std"),
+                                                        id_ext("rc"),
+                                                        id_ext("Rc"),
+                                                        id_ext("new")],
+                                                   vec![e_seq_struct]);
+            let e_tok = cx.expr_call(sp,
+                                     mk_ast_path(cx, sp, "TtSequence"),
+                                     vec!(e_sp, e_rc_new));
+            let e_push =
+                cx.expr_method_call(sp,
+                                    cx.expr_ident(sp, id_ext("tt")),
+                                    id_ext("push"),
+                                    vec!(e_tok));
+            vec!(cx.stmt_expr(e_push))
+        }
     }
-    ss
 }
 
-fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-              -> (P<ast::Expr>, P<ast::Expr>) {
+fn parse_arguments_to_quote(cx: &ExtCtxt, tts: &[ast::TokenTree])
+                            -> (P<ast::Expr>, Vec<ast::TokenTree>) {
     // NB: It appears that the main parser loses its mind if we consider
-    // $foo as a TtNonterminal during the main parse, so we have to re-parse
+    // $foo as a SubstNt during the main parse, so we have to re-parse
     // under quote_depth > 0. This is silly and should go away; the _guess_ is
     // it has to do with transition away from supporting old-style macros, so
     // try removing it when enough of them are gone.
@@ -719,6 +788,10 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     let tts = p.parse_all_token_trees();
     p.abort_if_errors();
 
+    (cx_expr, tts)
+}
+
+fn mk_stmts_let(cx: &ExtCtxt, sp: Span) -> Vec<P<ast::Stmt>> {
     // We also bind a single value, sp, to ext_cx.call_site()
     //
     // This causes every span in a token-tree quote to be attributed to the
@@ -756,8 +829,23 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
 
     let stmt_let_tt = cx.stmt_let(sp, true, id_ext("tt"), cx.expr_vec_ng(sp));
 
-    let mut vector = vec!(stmt_let_sp, stmt_let_tt);
-    vector.extend(mk_tts(cx, &tts[..]).into_iter());
+    vec!(stmt_let_sp, stmt_let_tt)
+}
+
+fn statements_mk_tts(cx: &ExtCtxt, tts: &[ast::TokenTree], matcher: bool) -> Vec<P<ast::Stmt>> {
+    let mut ss = Vec::new();
+    for tt in tts {
+        ss.extend(statements_mk_tt(cx, tt, matcher).into_iter());
+    }
+    ss
+}
+
+fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
+              -> (P<ast::Expr>, P<ast::Expr>) {
+    let (cx_expr, tts) = parse_arguments_to_quote(cx, tts);
+
+    let mut vector = mk_stmts_let(cx, sp);
+    vector.extend(statements_mk_tts(cx, &tts[..], false).into_iter());
     let block = cx.expr_block(
         cx.block_all(sp,
                      vector,
@@ -769,14 +857,14 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
 fn expand_wrapper(cx: &ExtCtxt,
                   sp: Span,
                   cx_expr: P<ast::Expr>,
-                  expr: P<ast::Expr>) -> P<ast::Expr> {
+                  expr: P<ast::Expr>,
+                  imports: &[&[&str]]) -> P<ast::Expr> {
     // Explicitly borrow to avoid moving from the invoker (#16992)
     let cx_expr_borrow = cx.expr_addr_of(sp, cx.expr_deref(sp, cx_expr));
     let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr_borrow);
 
-    let stmts = [
-        &["syntax", "ext", "quote", "rt"],
-    ].iter().map(|path| {
+    let stmts = imports.iter().map(|path| {
+        // make item: `use ...;`
         let path = path.iter().map(|s| s.to_string()).collect();
         cx.stmt_item(sp, cx.item_use_glob(sp, ast::Inherited, ids_ext(path)))
     }).chain(Some(stmt_let_ext_cx).into_iter()).collect();
@@ -807,5 +895,10 @@ fn expand_parse_call(cx: &ExtCtxt,
     let expr = cx.expr_method_call(sp, new_parser_call, id_ext(parse_method),
                                    arg_exprs);
 
-    expand_wrapper(cx, sp, cx_expr, expr)
+    if parse_method == "parse_attribute" {
+        expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"],
+                                                &["syntax", "parse", "attr"]])
+    } else {
+        expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"]])
+    }
 }
index c8d48750c75093259d428d491914075dd202b827..31d8b207bb9f080134fcbc582391391b1924c726 100644 (file)
@@ -20,7 +20,9 @@ use print::pprust;
 use ptr::P;
 use util::small_vector::SmallVector;
 
-use std::old_io::File;
+use std::fs::File;
+use std::io::prelude::*;
+use std::path::{Path, PathBuf};
 use std::rc::Rc;
 
 // These macros all relate to the file system; they either return
@@ -35,7 +37,7 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     let topmost = cx.original_span_in_file();
     let loc = cx.codemap().lookup_char_pos(topmost.lo);
 
-    base::MacExpr::new(cx.expr_usize(topmost, loc.line))
+    base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
 }
 
 /* column!(): expands to the current column number */
@@ -45,7 +47,8 @@ pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
 
     let topmost = cx.original_span_in_file();
     let loc = cx.codemap().lookup_char_pos(topmost.lo);
-    base::MacExpr::new(cx.expr_usize(topmost, loc.col.to_usize()))
+
+    base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32))
 }
 
 /// file!(): expands to the current filename */
@@ -57,14 +60,14 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
 
     let topmost = cx.original_span_in_file();
     let loc = cx.codemap().lookup_char_pos(topmost.lo);
-    let filename = token::intern_and_get_ident(&loc.file.name[]);
-    base::MacExpr::new(cx.expr_str(topmost, filename))
+    let filename = token::intern_and_get_ident(&loc.file.name);
+    base::MacEager::expr(cx.expr_str(topmost, filename))
 }
 
 pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                         -> Box<base::MacResult+'static> {
     let s = pprust::tts_to_string(tts);
-    base::MacExpr::new(cx.expr_str(sp,
+    base::MacEager::expr(cx.expr_str(sp,
                                    token::intern_and_get_ident(&s[..])))
 }
 
@@ -76,7 +79,7 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                    .map(|x| token::get_ident(*x).to_string())
                    .collect::<Vec<String>>()
                    .connect("::");
-    base::MacExpr::new(cx.expr_str(
+    base::MacEager::expr(cx.expr_str(
             sp,
             token::intern_and_get_ident(&string[..])))
 }
@@ -96,7 +99,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree
                                         cx.cfg(),
                                         &res_rel_file(cx,
                                                       sp,
-                                                      &Path::new(file)),
+                                                      Path::new(&file)),
                                         true,
                                         None,
                                         sp);
@@ -112,7 +115,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree
                       -> Option<SmallVector<P<ast::Item>>> {
             let mut ret = SmallVector::zero();
             while self.p.token != token::Eof {
-                match self.p.parse_item_with_outer_attributes() {
+                match self.p.parse_item() {
                     Some(item) => ret.push(item),
                     None => self.p.span_fatal(
                         self.p.span,
@@ -135,8 +138,10 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         Some(f) => f,
         None => return DummyResult::expr(sp)
     };
-    let file = res_rel_file(cx, sp, &Path::new(file));
-    let bytes = match File::open(&file).read_to_end() {
+    let file = res_rel_file(cx, sp, Path::new(&file));
+    let mut bytes = Vec::new();
+    match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) {
+        Ok(..) => {}
         Err(e) => {
             cx.span_err(sp,
                         &format!("couldn't read {}: {}",
@@ -144,7 +149,6 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                                 e));
             return DummyResult::expr(sp);
         }
-        Ok(bytes) => bytes,
     };
     match String::from_utf8(bytes) {
         Ok(src) => {
@@ -154,7 +158,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             let interned = token::intern_and_get_ident(&src[..]);
             cx.codemap().new_filemap(filename, src);
 
-            base::MacExpr::new(cx.expr_str(sp, interned))
+            base::MacEager::expr(cx.expr_str(sp, interned))
         }
         Err(_) => {
             cx.span_err(sp,
@@ -171,30 +175,30 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         Some(f) => f,
         None => return DummyResult::expr(sp)
     };
-    let file = res_rel_file(cx, sp, &Path::new(file));
-    match File::open(&file).read_to_end() {
+    let file = res_rel_file(cx, sp, Path::new(&file));
+    let mut bytes = Vec::new();
+    match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) {
         Err(e) => {
             cx.span_err(sp,
                         &format!("couldn't read {}: {}", file.display(), e));
             return DummyResult::expr(sp);
         }
-        Ok(bytes) => {
-            let bytes = bytes.iter().cloned().collect();
-            base::MacExpr::new(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
+        Ok(..) => {
+            base::MacEager::expr(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
         }
     }
 }
 
 // resolve a file-system path to an absolute file-system path (if it
 // isn't already)
-fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> Path {
+fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> PathBuf {
     // NB: relative paths are resolved relative to the compilation unit
     if !arg.is_absolute() {
-        let mut cu = Path::new(cx.codemap().span_to_filename(sp));
+        let mut cu = PathBuf::from(&cx.codemap().span_to_filename(sp));
         cu.pop();
         cu.push(arg);
         cu
     } else {
-        arg.clone()
+        arg.to_path_buf()
     }
 }
index 664f7b3e088480e2a55ef7e6a93cba00eab2a9f1..b7d40a46f3ea26026d119f0fd9be3eccfef166e2 100644 (file)
@@ -153,7 +153,7 @@ pub fn count_names(ms: &[TokenTree]) -> usize {
                 seq.num_captures
             }
             &TtDelimited(_, ref delim) => {
-                count_names(&delim.tts[])
+                count_names(&delim.tts)
             }
             &TtToken(_, MatchNt(..)) => {
                 1
@@ -243,12 +243,15 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
     ret_val
 }
 
-pub enum ParseResult {
-    Success(HashMap<Ident, Rc<NamedMatch>>),
+pub enum ParseResult<T> {
+    Success(T),
     Failure(codemap::Span, String),
     Error(codemap::Span, String)
 }
 
+pub type NamedParseResult = ParseResult<HashMap<Ident, Rc<NamedMatch>>>;
+pub type PositionalParseResult = ParseResult<Vec<Rc<NamedMatch>>>;
+
 pub fn parse_or_else(sess: &ParseSess,
                      cfg: ast::CrateConfig,
                      rdr: TtReader,
@@ -280,7 +283,7 @@ pub fn parse(sess: &ParseSess,
              cfg: ast::CrateConfig,
              mut rdr: TtReader,
              ms: &[TokenTree])
-             -> ParseResult {
+             -> NamedParseResult {
     let mut cur_eis = Vec::new();
     cur_eis.push(initial_matcher_pos(Rc::new(ms.iter()
                                                 .cloned()
@@ -479,7 +482,7 @@ pub fn parse(sess: &ParseSess,
                 }
                 rdr.next_token();
             } else /* bb_eis.len() == 1 */ {
-                let mut rust_parser = Parser::new(sess, cfg.clone(), box rdr.clone());
+                let mut rust_parser = Parser::new(sess, cfg.clone(), Box::new(rdr.clone()));
 
                 let mut ei = bb_eis.pop().unwrap();
                 match ei.top_elts.get_tt(ei.idx) {
@@ -518,12 +521,15 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
     // check at the beginning and the parser checks after each bump
     p.check_unknown_macro_variable();
     match name {
-      "item" => match p.parse_item(Vec::new()) {
+      "item" => match p.parse_item() {
         Some(i) => token::NtItem(i),
         None => p.fatal("expected an item keyword")
       },
       "block" => token::NtBlock(p.parse_block()),
-      "stmt" => token::NtStmt(p.parse_stmt(Vec::new())),
+      "stmt" => match p.parse_stmt() {
+        Some(s) => token::NtStmt(s),
+        None => p.fatal("expected a statement")
+      },
       "pat" => token::NtPat(p.parse_pat()),
       "expr" => token::NtExpr(p.parse_expr()),
       "ty" => token::NtTy(p.parse_ty()),
index fa6d934a4575581561476a177af7bb8872cdf195..1e53db6030143bbcad443e12b866da8fa706c273 100644 (file)
@@ -15,9 +15,8 @@ use ext::base::{NormalTT, TTMacroExpander};
 use ext::tt::macro_parser::{Success, Error, Failure};
 use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
 use ext::tt::macro_parser::{parse, parse_or_else};
-use parse::lexer::{new_tt_reader, new_tt_reader_with_doc_flag};
+use parse::lexer::new_tt_reader;
 use parse::parser::Parser;
-use parse::attr::ParserAttr;
 use parse::token::{self, special_idents, gensym_ident, NtTT, Token};
 use parse::token::Token::*;
 use print;
@@ -68,29 +67,21 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
     }
     fn make_items(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Item>>> {
         let mut ret = SmallVector::zero();
-        loop {
-            let mut parser = self.parser.borrow_mut();
-            // so... do outer attributes attached to the macro invocation
-            // just disappear? This question applies to make_methods, as
-            // well.
-            match parser.parse_item_with_outer_attributes() {
-                Some(item) => ret.push(item),
-                None => break
-            }
+        while let Some(item) = self.parser.borrow_mut().parse_item() {
+            ret.push(item);
         }
         self.ensure_complete_parse(false);
         Some(ret)
     }
 
-    fn make_methods(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Method>>> {
+    fn make_impl_items(self: Box<ParserAnyMacro<'a>>)
+                       -> Option<SmallVector<P<ast::ImplItem>>> {
         let mut ret = SmallVector::zero();
         loop {
             let mut parser = self.parser.borrow_mut();
             match parser.token {
                 token::Eof => break,
-                _ => {
-                    ret.push(parser.parse_method_with_outer_attributes());
-                }
+                _ => ret.push(parser.parse_impl_item())
             }
         }
         self.ensure_complete_parse(false);
@@ -98,10 +89,9 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
     }
 
     fn make_stmt(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Stmt>> {
-        let attrs = self.parser.borrow_mut().parse_outer_attributes();
-        let ret = self.parser.borrow_mut().parse_stmt(attrs);
+        let ret = self.parser.borrow_mut().parse_stmt();
         self.ensure_complete_parse(true);
-        Some(ret)
+        ret
     }
 }
 
@@ -154,15 +144,8 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                 TtDelimited(_, ref delim) => &delim.tts[..],
                 _ => cx.span_fatal(sp, "malformed macro lhs")
             };
-            // `None` is because we're not interpolating
-            let arg_rdr = new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic,
-                                                      None,
-                                                      None,
-                                                      arg.iter()
-                                                         .cloned()
-                                                         .collect(),
-                                                      true);
-            match parse(cx.parse_sess(), cx.cfg(), arg_rdr, lhs_tt) {
+
+            match TokenTree::parse(cx, lhs_tt, arg) {
               Success(named_matches) => {
                 let rhs = match *rhses[i] {
                     // okay, what's your transcriber?
@@ -180,13 +163,13 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                                            Some(named_matches),
                                            imported_from,
                                            rhs);
-                let mut p = Parser::new(cx.parse_sess(), cx.cfg(), box trncbr);
+                let mut p = Parser::new(cx.parse_sess(), cx.cfg(), Box::new(trncbr));
                 p.check_unknown_macro_variable();
                 // Let the context choose how to interpret the result.
                 // Weird, but useful for X-macros.
                 return box ParserAnyMacro {
                     parser: RefCell::new(p),
-                } as Box<MacResult+'cx>
+                }
               }
               Failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo {
                 best_fail_spot = sp;
@@ -253,7 +236,7 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
                                      argument_gram);
 
     // Extract the arguments:
-    let lhses = match *argument_map[lhs_nm] {
+    let lhses = match **argument_map.get(&lhs_nm).unwrap() {
         MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(),
         _ => cx.span_bug(def.span, "wrong-structured lhs")
     };
@@ -262,19 +245,19 @@ pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
         check_lhs_nt_follows(cx, &**lhs, def.span);
     }
 
-    let rhses = match *argument_map[rhs_nm] {
+    let rhses = match **argument_map.get(&rhs_nm).unwrap() {
         MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(),
         _ => cx.span_bug(def.span, "wrong-structured rhs")
     };
 
-    let exp = box MacroRulesMacroExpander {
+    let exp: Box<_> = box MacroRulesMacroExpander {
         name: def.ident,
         imported_from: def.imported_from,
         lhses: lhses,
         rhses: rhses,
     };
 
-    NormalTT(exp, Some(def.span))
+    NormalTT(exp, Some(def.span), def.allow_internal_unstable)
 }
 
 fn check_lhs_nt_follows(cx: &mut ExtCtxt, lhs: &NamedMatch, sp: Span) {
@@ -334,6 +317,10 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
                 let tok = if let TtToken(_, ref tok) = *token { tok } else { unreachable!() };
                 // If T' is in the set FOLLOW(NT), continue. Else, reject.
                 match (&next_token, is_in_follow(cx, &next_token, frag_spec.as_str())) {
+                    (_, Err(msg)) => {
+                        cx.span_err(sp, &msg);
+                        continue
+                    }
                     (&Eof, _) => return Some((sp, tok.clone())),
                     (_, Ok(true)) => continue,
                     (next, Ok(false)) => {
@@ -343,10 +330,6 @@ fn check_matcher<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token)
                                                  token_to_string(next)));
                         continue
                     },
-                    (_, Err(msg)) => {
-                        cx.span_err(sp, &msg);
-                        continue
-                    }
                 }
             },
             TtSequence(sp, ref seq) => {
index 071158fcebb5cf32da776b2e98394450dbf47108..dbddd9dd44d0ebf9d296900bb7fdc4c9286f9e16 100644 (file)
@@ -25,7 +25,7 @@
 use self::Status::*;
 use self::AttributeType::*;
 
-use abi::RustIntrinsic;
+use abi::Abi;
 use ast::NodeId;
 use ast;
 use attr;
@@ -45,7 +45,7 @@ use std::ascii::AsciiExt;
 // stable (active).
 // NB: The featureck.py script parses this information directly out of the source
 // so take care when modifying it.
-static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
+const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
     ("globs", "1.0.0", Accepted),
     ("macro_rules", "1.0.0", Accepted),
     ("struct_variant", "1.0.0", Accepted),
@@ -54,12 +54,10 @@ static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
     ("non_ascii_idents", "1.0.0", Active),
     ("thread_local", "1.0.0", Active),
     ("link_args", "1.0.0", Active),
-    ("phase", "1.0.0", Removed),
     ("plugin_registrar", "1.0.0", Active),
     ("log_syntax", "1.0.0", Active),
     ("trace_macros", "1.0.0", Active),
     ("concat_idents", "1.0.0", Active),
-    ("unsafe_destructor", "1.0.0", Active),
     ("intrinsics", "1.0.0", Active),
     ("lang_items", "1.0.0", Active),
 
@@ -74,6 +72,7 @@ static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
 
     ("rustc_diagnostic_macros", "1.0.0", Active),
     ("unboxed_closures", "1.0.0", Active),
+    ("reflect", "1.0.0", Active),
     ("import_shadowing", "1.0.0", Removed),
     ("advanced_slice_patterns", "1.0.0", Active),
     ("tuple_indexing", "1.0.0", Accepted),
@@ -83,6 +82,7 @@ static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
     ("box_syntax", "1.0.0", Active),
     ("on_unimplemented", "1.0.0", Active),
     ("simd_ffi", "1.0.0", Active),
+    ("allocator", "1.0.0", Active),
 
     ("if_let", "1.0.0", Accepted),
     ("while_let", "1.0.0", Accepted),
@@ -91,6 +91,12 @@ static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
     ("start", "1.0.0", Active),
     ("main", "1.0.0", Active),
 
+    ("fundamental", "1.0.0", Active),
+
+    // Deprecate after snapshot
+    // SNAP 5520801
+    ("unsafe_destructor", "1.0.0", Active),
+
     // A temporary feature gate used to enable parser extensions needed
     // to bootstrap fix for #5723.
     ("issue_5723_bootstrap", "1.0.0", Accepted),
@@ -98,18 +104,9 @@ static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
     // A way to temporarily opt out of opt in copy. This will *never* be accepted.
     ("opt_out_copy", "1.0.0", Removed),
 
-    // A way to temporarily opt out of the new orphan rules. This will *never* be accepted.
-    ("old_orphan_check", "1.0.0", Deprecated),
-
-    // A way to temporarily opt out of the new impl rules. This will *never* be accepted.
-    ("old_impl_check", "1.0.0", Deprecated),
-
     // OIBIT specific features
     ("optin_builtin_traits", "1.0.0", Active),
 
-    // int and uint are now deprecated
-    ("int_uint", "1.0.0", Active),
-
     // macro reexport needs more discussion and stabilization
     ("macro_reexport", "1.0.0", Active),
 
@@ -137,8 +134,27 @@ static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
     // Allows the use of custom attributes; RFC 572
     ("custom_attribute", "1.0.0", Active),
 
+    // Allows the use of #[derive(Anything)] as sugar for
+    // #[derive_Anything].
+    ("custom_derive", "1.0.0", Active),
+
     // Allows the use of rustc_* attributes; RFC 572
     ("rustc_attrs", "1.0.0", Active),
+
+    // Allows the use of `static_assert`
+    ("static_assert", "1.0.0", Active),
+
+    // Allows the use of #[allow_internal_unstable]. This is an
+    // attribute on macro_rules! and can't use the attribute handling
+    // below (it has to be checked before expansion possibly makes
+    // macros disappear).
+    ("allow_internal_unstable", "1.0.0", Active),
+
+    // #23121. Array patterns have some hazards yet.
+    ("slice_patterns", "1.0.0", Active),
+
+    // Allows use of unary negate on unsigned integers, e.g. -e for e: u8
+    ("negate_unsigned", "1.0.0", Active),
 ];
 // (changing above list without updating src/doc/reference.md makes @cmr sad)
 
@@ -147,10 +163,6 @@ enum Status {
     /// currently being considered for addition/removal.
     Active,
 
-    /// Represents a feature gate that is temporarily enabling deprecated behavior.
-    /// This gate will never be accepted.
-    Deprecated,
-
     /// Represents a feature which has since been removed (it was once Active)
     Removed,
 
@@ -159,7 +171,7 @@ enum Status {
 }
 
 // Attributes that have a special meaning to rustc or rustdoc
-pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
+pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
     // Normal attributes
 
     ("warn", Normal),
@@ -173,6 +185,7 @@ pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
     ("plugin_registrar", Normal),
 
     ("cfg", Normal),
+    ("cfg_attr", Normal),
     ("main", Normal),
     ("start", Normal),
     ("test", Normal),
@@ -181,19 +194,19 @@ pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
     ("repr", Normal),
     ("path", Normal),
     ("abi", Normal),
-    ("unsafe_destructor", Normal),
     ("automatically_derived", Normal),
     ("no_mangle", Normal),
     ("no_link", Normal),
     ("derive", Normal),
-    ("should_fail", Normal),
+    ("should_panic", Normal),
     ("ignore", Normal),
     ("no_implicit_prelude", Normal),
     ("reexport_test_harness_main", Normal),
     ("link_args", Normal),
     ("macro_escape", Normal),
 
-
+    ("unsafe_destructor", Gated("unsafe_destructor",
+                                "`#[unsafe_destructor]` does nothing anymore")),
     ("staged_api", Gated("staged_api",
                          "staged_api is for use by rustc only")),
     ("plugin", Gated("plugin",
@@ -214,6 +227,8 @@ pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
     ("rustc_on_unimplemented", Gated("on_unimplemented",
                                      "the `#[rustc_on_unimplemented]` attribute \
                                       is an experimental feature")),
+    ("allocator", Gated("allocator",
+                        "the `#[allocator]` attribute is an experimental feature")),
     ("rustc_variance", Gated("rustc_attrs",
                              "the `#[rustc_variance]` attribute \
                               is an experimental feature")),
@@ -224,6 +239,13 @@ pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
                                    "the `#[rustc_move_fragments]` attribute \
                                     is an experimental feature")),
 
+    ("allow_internal_unstable", Gated("allow_internal_unstable",
+                                      EXPLAIN_ALLOW_INTERNAL_UNSTABLE)),
+
+    ("fundamental", Gated("fundamental",
+                          "the `#[fundamental]` attribute \
+                           is an experimental feature")),
+
     // FIXME: #14408 whitelist docs since rustdoc looks at them
     ("doc", Whitelisted),
 
@@ -237,13 +259,15 @@ pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
     ("link_section", Whitelisted),
     ("no_builtins", Whitelisted),
     ("no_mangle", Whitelisted),
-    ("no_split_stack", Whitelisted),
     ("no_stack_check", Whitelisted),
     ("packed", Whitelisted),
-    ("static_assert", Whitelisted),
+    ("static_assert", Gated("static_assert",
+                            "`#[static_assert]` is an experimental feature, and has a poor API")),
     ("no_debug", Whitelisted),
     ("omit_gdb_pretty_printer_section", Whitelisted),
-    ("unsafe_no_drop_flag", Whitelisted),
+    ("unsafe_no_drop_flag", Gated("unsafe_no_drop_flag",
+                                  "unsafe_no_drop_flag has unstable semantics \
+                                   and may be removed in the future")),
 
     // used in resolve
     ("prelude_import", Whitelisted),
@@ -255,10 +279,10 @@ pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
     ("stable", Whitelisted),
     ("unstable", Whitelisted),
 
-    // FIXME: #19470 this shouldn't be needed forever
-    ("old_orphan_check", Whitelisted),
-    ("old_impl_check", Whitelisted),
-    ("rustc_paren_sugar", Whitelisted), // FIXME: #18101 temporary unboxed closure hack
+    ("rustc_paren_sugar", Gated("unboxed_closures",
+                                "unboxed_closures are still evolving")),
+    ("rustc_reflect_like", Gated("reflect",
+                                 "defining reflective traits is still evolving")),
 
     // Crate level attributes
     ("crate_name", CrateLevel),
@@ -271,7 +295,7 @@ pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
     ("recursion_limit", CrateLevel),
 ];
 
-#[derive(PartialEq, Copy)]
+#[derive(PartialEq, Copy, Clone, Debug)]
 pub enum AttributeType {
     /// Normal, builtin attribute that is consumed
     /// by the compiler before the unused_attribute check
@@ -300,9 +324,11 @@ pub struct Features {
     pub allow_log_syntax: bool,
     pub allow_concat_idents: bool,
     pub allow_trace_macros: bool,
-    pub old_orphan_check: bool,
+    pub allow_internal_unstable: bool,
+    pub allow_custom_derive: bool,
     pub simd_ffi: bool,
     pub unmarked_api: bool,
+    pub negate_unsigned: bool,
     /// spans of #![feature] attrs for stable language features. for error reporting
     pub declared_stable_lang_features: Vec<Span>,
     /// #![feature] attrs for non-language (library) features
@@ -320,9 +346,11 @@ impl Features {
             allow_log_syntax: false,
             allow_concat_idents: false,
             allow_trace_macros: false,
-            old_orphan_check: false,
+            allow_internal_unstable: false,
+            allow_custom_derive: false,
             simd_ffi: false,
             unmarked_api: false,
+            negate_unsigned: false,
             declared_stable_lang_features: Vec::new(),
             declared_lib_features: Vec::new()
         }
@@ -337,24 +365,51 @@ struct Context<'a> {
 
 impl<'a> Context<'a> {
     fn gate_feature(&self, feature: &str, span: Span, explain: &str) {
-        if !self.has_feature(feature) {
+        let has_feature = self.has_feature(feature);
+        debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", feature, span, has_feature);
+        if !has_feature {
             emit_feature_err(self.span_handler, feature, span, explain);
         }
     }
-
-    fn warn_feature(&self, feature: &str, span: Span, explain: &str) {
-        if !self.has_feature(feature) {
-            emit_feature_warn(self.span_handler, feature, span, explain);
-        }
-    }
     fn has_feature(&self, feature: &str) -> bool {
         self.features.iter().any(|&n| n == feature)
     }
+
+    fn check_attribute(&self, attr: &ast::Attribute) {
+        debug!("check_attribute(attr = {:?})", attr);
+        let name = &*attr.name();
+        for &(n, ty) in KNOWN_ATTRIBUTES {
+            if n == name {
+                if let Gated(gate, desc) = ty {
+                    self.gate_feature(gate, attr.span, desc);
+                }
+                debug!("check_attribute: {:?} is known, {:?}", name, ty);
+                return;
+            }
+        }
+        if name.starts_with("rustc_") {
+            self.gate_feature("rustc_attrs", attr.span,
+                              "unless otherwise specified, attributes \
+                               with the prefix `rustc_` \
+                               are reserved for internal compiler diagnostics");
+        } else if name.starts_with("derive_") {
+            self.gate_feature("custom_derive", attr.span,
+                              "attributes of the form `#[derive_*]` are reserved
+                               for the compiler");
+        } else {
+            self.gate_feature("custom_attribute", attr.span,
+                       &format!("The attribute `{}` is currently \
+                                unknown to the the compiler and \
+                                may have meaning \
+                                added to it in the future",
+                                name));
+        }
+    }
 }
 
 pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain: &str) {
     diag.span_err(span, explain);
-    diag.span_help(span, &format!("add #![feature({})] to the \
+    diag.fileline_help(span, &format!("add #![feature({})] to the \
                                    crate attributes to enable",
                                   feature));
 }
@@ -362,7 +417,7 @@ pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain:
 pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain: &str) {
     diag.span_warn(span, explain);
     if diag.handler.can_emit_warnings {
-        diag.span_help(span, &format!("add #![feature({})] to the \
+        diag.fileline_help(span, &format!("add #![feature({})] to the \
                                        crate attributes to silence this warning",
                                       feature));
     }
@@ -379,6 +434,11 @@ pub const EXPLAIN_CONCAT_IDENTS: &'static str =
 
 pub const EXPLAIN_TRACE_MACROS: &'static str =
     "`trace_macros` is not stable enough for use and is subject to change";
+pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &'static str =
+    "allow_internal_unstable side-steps feature gating and stability checks";
+
+pub const EXPLAIN_CUSTOM_DERIVE: &'static str =
+    "`#[derive]` for custom traits is not stable enough for use and is subject to change";
 
 struct MacroVisitor<'a> {
     context: &'a Context<'a>
@@ -413,6 +473,10 @@ impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
             self.context.gate_feature("concat_idents", path.span, EXPLAIN_CONCAT_IDENTS);
         }
     }
+
+    fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
+        self.context.check_attribute(attr);
+    }
 }
 
 struct PostExpansionVisitor<'a> {
@@ -421,13 +485,19 @@ struct PostExpansionVisitor<'a> {
 
 impl<'a> PostExpansionVisitor<'a> {
     fn gate_feature(&self, feature: &str, span: Span, explain: &str) {
-        if !self.context.cm.span_is_internal(span) {
+        if !self.context.cm.span_allows_unstable(span) {
             self.context.gate_feature(feature, span, explain)
         }
     }
 }
 
 impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
+    fn visit_attribute(&mut self, attr: &ast::Attribute) {
+        if !self.context.cm.span_allows_unstable(attr.span) {
+            self.context.check_attribute(attr);
+        }
+    }
+
     fn visit_name(&mut self, sp: Span, name: ast::Name) {
         if !token::get_name(name).is_ascii() {
             self.gate_feature("non_ascii_idents", sp,
@@ -452,7 +522,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                                        across platforms, it is recommended to \
                                        use `#[link(name = \"foo\")]` instead")
                 }
-                if foreign_module.abi == RustIntrinsic {
+                if foreign_module.abi == Abi::RustIntrinsic {
                     self.gate_feature("intrinsics",
                                       i.span,
                                       "intrinsics are subject to change")
@@ -485,6 +555,13 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                 }
             }
 
+            ast::ItemDefaultImpl(..) => {
+                self.gate_feature("optin_builtin_traits",
+                                  i.span,
+                                  "default trait implementations are experimental \
+                                   and possibly buggy");
+            }
+
             ast::ItemImpl(_, polarity, _, _, _, _) => {
                 match polarity {
                     ast::ImplPolarity::Negative => {
@@ -495,30 +572,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                     },
                     _ => {}
                 }
-
-                if attr::contains_name(&i.attrs,
-                                       "unsafe_destructor") {
-                    self.gate_feature("unsafe_destructor",
-                                      i.span,
-                                      "`#[unsafe_destructor]` allows too \
-                                       many unsafe patterns and may be \
-                                       removed in the future");
-                }
-
-                if attr::contains_name(&i.attrs[..],
-                                       "old_orphan_check") {
-                    self.gate_feature(
-                        "old_orphan_check",
-                        i.span,
-                        "the new orphan check rules will eventually be strictly enforced");
-                }
-
-                if attr::contains_name(&i.attrs[..],
-                                       "old_impl_check") {
-                    self.gate_feature("old_impl_check",
-                                      i.span,
-                                      "`#[old_impl_check]` will be removed in the future");
-                }
             }
 
             _ => {}
@@ -528,12 +581,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
     }
 
     fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
-        if attr::contains_name(&i.attrs, "linkage") {
-            self.gate_feature("linkage", i.span,
-                              "the `linkage` attribute is experimental \
-                               and not portable across platforms")
-        }
-
         let links_to_llvm = match attr::first_attr_value_str_by_name(&i.attrs,
                                                                      "link_name") {
             Some(val) => val.starts_with("llvm."),
@@ -547,35 +594,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
         visit::walk_foreign_item(self, i)
     }
 
-    fn visit_ty(&mut self, t: &ast::Ty) {
-        match t.node {
-            ast::TyPath(ref p, _) => {
-                match &*p.segments {
-
-                    [ast::PathSegment { identifier, .. }] => {
-                        let name = token::get_ident(identifier);
-                        let msg = if name == "int" {
-                            Some("the `int` type is deprecated; \
-                                  use `isize` or a fixed-sized integer")
-                        } else if name == "uint" {
-                            Some("the `uint` type is deprecated; \
-                                  use `usize` or a fixed-sized integer")
-                        } else {
-                            None
-                        };
-
-                        if let Some(msg) = msg {
-                            self.context.warn_feature("int_uint", t.span, msg)
-                        }
-                    }
-                    _ => {}
-                }
-            }
-            _ => {}
-        }
-        visit::walk_ty(self, t);
-    }
-
     fn visit_expr(&mut self, e: &ast::Expr) {
         match e.node {
             ast::ExprBox(..) | ast::ExprUnary(ast::UnOp::UnUniq, _) => {
@@ -584,55 +602,11 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                                   "box expression syntax is experimental; \
                                    you can call `Box::new` instead.");
             }
-            ast::ExprLit(ref lit) => {
-                match lit.node {
-                    ast::LitInt(_, ty) => {
-                        let msg = if let ast::SignedIntLit(ast::TyIs(true), _) = ty {
-                            Some("the `i` and `is` suffixes on integers are deprecated; \
-                                  use `isize` or one of the fixed-sized suffixes")
-                        } else if let ast::UnsignedIntLit(ast::TyUs(true)) = ty {
-                            Some("the `u` and `us` suffixes on integers are deprecated; \
-                                  use `usize` or one of the fixed-sized suffixes")
-                        } else {
-                            None
-                        };
-                        if let Some(msg) = msg {
-                            self.context.warn_feature("int_uint", e.span, msg);
-                        }
-                    }
-                    _ => {}
-                }
-            }
             _ => {}
         }
         visit::walk_expr(self, e);
     }
 
-    fn visit_attribute(&mut self, attr: &ast::Attribute) {
-        let name = &*attr.name();
-        for &(n, ty) in KNOWN_ATTRIBUTES {
-            if n == name {
-                if let Gated(gate, desc) = ty {
-                    self.gate_feature(gate, attr.span, desc);
-                }
-                return;
-            }
-        }
-        if name.starts_with("rustc_") {
-            self.gate_feature("rustc_attrs", attr.span,
-                              "unless otherwise specified, attributes \
-                               with the prefix `rustc_` \
-                               are reserved for internal compiler diagnostics");
-        } else {
-            self.gate_feature("custom_attribute", attr.span,
-                       format!("The attribute `{}` is currently \
-                                unknown to the the compiler and \
-                                may have meaning \
-                                added to it in the future",
-                                name).as_slice());
-        }
-    }
-
     fn visit_pat(&mut self, pattern: &ast::Pat) {
         match pattern.node {
             ast::PatVec(_, Some(_), ref last) if !last.is_empty() => {
@@ -642,6 +616,11 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                                    but at the end of a slice (e.g. \
                                    `[0, ..xs, 0]` are experimental")
             }
+            ast::PatVec(..) => {
+                self.gate_feature("slice_patterns",
+                                  pattern.span,
+                                  "slice pattern syntax is experimental");
+            }
             ast::PatBox(..) => {
                 self.gate_feature("box_patterns",
                                   pattern.span,
@@ -659,18 +638,25 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
                 span: Span,
                 _node_id: NodeId) {
         match fn_kind {
-            visit::FkItemFn(_, _, _, abi) if abi == RustIntrinsic => {
+            visit::FkItemFn(_, _, _, abi) if abi == Abi::RustIntrinsic => {
                 self.gate_feature("intrinsics",
                                   span,
                                   "intrinsics are subject to change")
             }
+            visit::FkItemFn(_, _, _, abi) |
+            visit::FkMethod(_, &ast::MethodSig { abi, .. }) if abi == Abi::RustCall => {
+                self.gate_feature("unboxed_closures",
+                                  span,
+                                  "rust-call ABI is subject to change")
+            }
             _ => {}
         }
         visit::walk_fn(self, fn_kind, fn_decl, block, span);
     }
 }
 
-fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate,
+fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
+                        krate: &ast::Crate,
                         check: F)
                        -> Features
     where F: FnOnce(&mut Context, &ast::Crate)
@@ -710,13 +696,6 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
                         Some(&(name, _, Active)) => {
                             cx.features.push(name);
                         }
-                        Some(&(name, _, Deprecated)) => {
-                            cx.features.push(name);
-                            span_handler.span_warn(
-                                mi.span,
-                                "feature is deprecated and will only be available \
-                                 for a limited time, please rewrite code that relies on it");
-                        }
                         Some(&(_, _, Removed)) => {
                             span_handler.span_err(mi.span, "feature has been removed");
                         }
@@ -746,9 +725,11 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
         allow_log_syntax: cx.has_feature("log_syntax"),
         allow_concat_idents: cx.has_feature("concat_idents"),
         allow_trace_macros: cx.has_feature("trace_macros"),
-        old_orphan_check: cx.has_feature("old_orphan_check"),
+        allow_internal_unstable: cx.has_feature("allow_internal_unstable"),
+        allow_custom_derive: cx.has_feature("custom_derive"),
         simd_ffi: cx.has_feature("simd_ffi"),
         unmarked_api: cx.has_feature("unmarked_api"),
+        negate_unsigned: cx.has_feature("negate_unsigned"),
         declared_stable_lang_features: accepted_features,
         declared_lib_features: unknown_features
     }
@@ -761,9 +742,9 @@ pub fn check_crate_macros(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast:
 }
 
 pub fn check_crate(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate)
--> Features {
+                   -> Features
+{
     check_crate_inner(cm, span_handler, krate,
                       |ctx, krate| visit::walk_crate(&mut PostExpansionVisitor { context: ctx },
                                                      krate))
 }
-
index 1fb0642d24ff74fdb0665916b7a66516da204901..d4451cc7b71243ea87a0b847d2e6941412a7d1f1 100644 (file)
@@ -40,7 +40,7 @@ impl<T> MoveMap<T> for Vec<T> {
         for p in &mut self {
             unsafe {
                 // FIXME(#5016) this shouldn't need to zero to be safe.
-                ptr::write(p, f(ptr::read_and_zero(p)));
+                ptr::write(p, f(ptr::read_and_drop(p)));
             }
         }
         self
@@ -98,11 +98,11 @@ pub trait Folder : Sized {
         noop_fold_item_underscore(i, self)
     }
 
-    fn fold_trait_item(&mut self, i: TraitItem) -> SmallVector<TraitItem> {
+    fn fold_trait_item(&mut self, i: P<TraitItem>) -> SmallVector<P<TraitItem>> {
         noop_fold_trait_item(i, self)
     }
 
-    fn fold_impl_item(&mut self, i: ImplItem) -> SmallVector<ImplItem> {
+    fn fold_impl_item(&mut self, i: P<ImplItem>) -> SmallVector<P<ImplItem>> {
         noop_fold_impl_item(i, self)
     }
 
@@ -110,14 +110,6 @@ pub trait Folder : Sized {
         noop_fold_fn_decl(d, self)
     }
 
-    fn fold_type_method(&mut self, m: TypeMethod) -> TypeMethod {
-        noop_fold_type_method(m, self)
-    }
-
-    fn fold_method(&mut self, m: P<Method>) -> SmallVector<P<Method>> {
-        noop_fold_method(m, self)
-    }
-
     fn fold_block(&mut self, b: P<Block>) -> P<Block> {
         noop_fold_block(b, self)
     }
@@ -146,10 +138,6 @@ pub trait Folder : Sized {
         noop_fold_ty(t, self)
     }
 
-    fn fold_qpath(&mut self, t: P<QPath>) -> P<QPath> {
-        noop_fold_qpath(t, self)
-    }
-
     fn fold_ty_binding(&mut self, t: P<TypeBinding>) -> P<TypeBinding> {
         noop_fold_ty_binding(t, self)
     }
@@ -319,15 +307,6 @@ pub trait Folder : Sized {
         noop_fold_where_predicate(where_predicate, self)
     }
 
-    fn fold_typedef(&mut self, typedef: Typedef) -> Typedef {
-        noop_fold_typedef(typedef, self)
-    }
-
-    fn fold_associated_type(&mut self, associated_type: AssociatedType)
-                            -> AssociatedType {
-        noop_fold_associated_type(associated_type, self)
-    }
-
     fn new_id(&mut self, i: NodeId) -> NodeId {
         i
     }
@@ -428,17 +407,19 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
             }
             TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))),
             TyParen(ty) => TyParen(fld.fold_ty(ty)),
-            TyPath(path, id) => {
-                let id = fld.new_id(id);
-                TyPath(fld.fold_path(path), id)
+            TyPath(qself, path) => {
+                let qself = qself.map(|QSelf { ty, position }| {
+                    QSelf {
+                        ty: fld.fold_ty(ty),
+                        position: position
+                    }
+                });
+                TyPath(qself, fld.fold_path(path))
             }
             TyObjectSum(ty, bounds) => {
                 TyObjectSum(fld.fold_ty(ty),
                             fld.fold_bounds(bounds))
             }
-            TyQPath(qpath) => {
-                TyQPath(fld.fold_qpath(qpath))
-            }
             TyFixedLengthVec(ty, e) => {
                 TyFixedLengthVec(fld.fold_ty(ty), fld.fold_expr(e))
             }
@@ -453,19 +434,6 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
     })
 }
 
-pub fn noop_fold_qpath<T: Folder>(qpath: P<QPath>, fld: &mut T) -> P<QPath> {
-    qpath.map(|qpath| {
-        QPath {
-            self_type: fld.fold_ty(qpath.self_type),
-            trait_ref: qpath.trait_ref.map(|tr| fld.fold_trait_ref(tr)),
-            item_path: PathSegment {
-                identifier: fld.fold_ident(qpath.item_path.identifier),
-                parameters: fld.fold_path_parameters(qpath.item_path.parameters),
-            }
-        }
-    })
-}
-
 pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, items}: ForeignMod,
                                         fld: &mut T) -> ForeignMod {
     ForeignMod {
@@ -844,41 +812,6 @@ pub fn noop_fold_where_predicate<T: Folder>(
     }
 }
 
-pub fn noop_fold_typedef<T>(t: Typedef, folder: &mut T)
-                            -> Typedef
-                            where T: Folder {
-    let new_id = folder.new_id(t.id);
-    let new_span = folder.new_span(t.span);
-    let new_attrs = t.attrs.iter().flat_map(|attr| {
-        folder.fold_attribute((*attr).clone()).into_iter()
-    }).collect();
-    let new_ident = folder.fold_ident(t.ident);
-    let new_type = folder.fold_ty(t.typ);
-    ast::Typedef {
-        ident: new_ident,
-        typ: new_type,
-        id: new_id,
-        span: new_span,
-        vis: t.vis,
-        attrs: new_attrs,
-    }
-}
-
-pub fn noop_fold_associated_type<T>(at: AssociatedType, folder: &mut T)
-                                    -> AssociatedType
-                                    where T: Folder
-{
-    let new_attrs = at.attrs
-                      .iter()
-                      .flat_map(|attr| folder.fold_attribute((*attr).clone()).into_iter())
-                      .collect();
-    let new_param = folder.fold_ty_param(at.ty_param);
-    ast::AssociatedType {
-        attrs: new_attrs,
-        ty_param: new_param,
-    }
-}
-
 pub fn noop_fold_struct_def<T: Folder>(struct_def: P<StructDef>, fld: &mut T) -> P<StructDef> {
     struct_def.map(|StructDef { fields, ctor_id }| StructDef {
         fields: fields.move_map(|f| fld.fold_struct_field(f)),
@@ -999,6 +932,9 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
             let struct_def = folder.fold_struct_def(struct_def);
             ItemStruct(struct_def, folder.fold_generics(generics))
         }
+        ItemDefaultImpl(unsafety, ref trait_ref) => {
+            ItemDefaultImpl(unsafety, folder.fold_trait_ref((*trait_ref).clone()))
+        }
         ItemImpl(unsafety, polarity, generics, ifce, ty, impl_items) => {
             let new_impl_items = impl_items.into_iter().flat_map(|item| {
                 folder.fold_impl_item(item).into_iter()
@@ -1030,61 +966,43 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
     }
 }
 
-pub fn noop_fold_trait_item<T: Folder>(i: TraitItem, folder: &mut T) -> SmallVector<TraitItem> {
-    match i {
-        RequiredMethod(m) => {
-                SmallVector::one(RequiredMethod(
-                        folder.fold_type_method(m)))
-        }
-        ProvidedMethod(method) => {
-            folder.fold_method(method).into_iter()
-                .map(|m| ProvidedMethod(m)).collect()
-        }
-        TypeTraitItem(at) => {
-            SmallVector::one(TypeTraitItem(P(
-                        folder.fold_associated_type(
-                            (*at).clone()))))
-        }
-    }
-}
-
-pub fn noop_fold_impl_item<T: Folder>(i: ImplItem, folder: &mut T) -> SmallVector<ImplItem> {
-    match i {
-        MethodImplItem(ref x) => {
-            folder.fold_method((*x).clone()).into_iter().map(|m| MethodImplItem(m)).collect()
-        }
-        TypeImplItem(ref t) => {
-            SmallVector::one(TypeImplItem(
-                    P(folder.fold_typedef((**t).clone()))))
-        }
-    }
+pub fn noop_fold_trait_item<T: Folder>(i: P<TraitItem>, folder: &mut T)
+                                       -> SmallVector<P<TraitItem>> {
+    SmallVector::one(i.map(|TraitItem {id, ident, attrs, node, span}| TraitItem {
+        id: folder.new_id(id),
+        ident: folder.fold_ident(ident),
+        attrs: fold_attrs(attrs, folder),
+        node: match node {
+            MethodTraitItem(sig, body) => {
+                MethodTraitItem(noop_fold_method_sig(sig, folder),
+                                body.map(|x| folder.fold_block(x)))
+            }
+            TypeTraitItem(bounds, default) => {
+                TypeTraitItem(folder.fold_bounds(bounds),
+                              default.map(|x| folder.fold_ty(x)))
+            }
+        },
+        span: folder.new_span(span)
+    }))
 }
 
-pub fn noop_fold_type_method<T: Folder>(m: TypeMethod, fld: &mut T) -> TypeMethod {
-    let TypeMethod {
-        id,
-        ident,
-        attrs,
-        unsafety,
-        abi,
-        decl,
-        generics,
-        explicit_self,
-        vis,
-        span
-    } = m;
-    TypeMethod {
-        id: fld.new_id(id),
-        ident: fld.fold_ident(ident),
-        attrs: fold_attrs(attrs, fld),
-        unsafety: unsafety,
-        abi: abi,
-        decl: fld.fold_fn_decl(decl),
-        generics: fld.fold_generics(generics),
-        explicit_self: fld.fold_explicit_self(explicit_self),
+pub fn noop_fold_impl_item<T: Folder>(i: P<ImplItem>, folder: &mut T)
+                                      -> SmallVector<P<ImplItem>> {
+    SmallVector::one(i.map(|ImplItem {id, ident, attrs, node, vis, span}| ImplItem {
+        id: folder.new_id(id),
+        ident: folder.fold_ident(ident),
+        attrs: fold_attrs(attrs, folder),
         vis: vis,
-        span: fld.new_span(span)
-    }
+        node: match node  {
+            MethodImplItem(sig, body) => {
+                MethodImplItem(noop_fold_method_sig(sig, folder),
+                               folder.fold_block(body))
+            }
+            TypeImplItem(ty) => TypeImplItem(folder.fold_ty(ty)),
+            MacImplItem(mac) => MacImplItem(folder.fold_mac(mac))
+        },
+        span: folder.new_span(span)
+    }))
 }
 
 pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod {
@@ -1150,7 +1068,7 @@ pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span}
     let ident = match node {
         // The node may have changed, recompute the "pretty" impl name.
         ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => {
-            ast_util::impl_pretty_name(maybe_trait, &**ty)
+            ast_util::impl_pretty_name(maybe_trait, Some(&**ty))
         }
         _ => ident
     };
@@ -1183,34 +1101,14 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
     })
 }
 
-// Default fold over a method.
-// Invariant: produces exactly one method.
-pub fn noop_fold_method<T: Folder>(m: P<Method>, folder: &mut T) -> SmallVector<P<Method>> {
-    SmallVector::one(m.map(|Method {id, attrs, node, span}| Method {
-        id: folder.new_id(id),
-        attrs: fold_attrs(attrs, folder),
-        node: match node {
-            MethDecl(ident,
-                     generics,
-                     abi,
-                     explicit_self,
-                     unsafety,
-                     decl,
-                     body,
-                     vis) => {
-                MethDecl(folder.fold_ident(ident),
-                         folder.fold_generics(generics),
-                         abi,
-                         folder.fold_explicit_self(explicit_self),
-                         unsafety,
-                         folder.fold_fn_decl(decl),
-                         folder.fold_block(body),
-                         vis)
-            },
-            MethMac(mac) => MethMac(folder.fold_mac(mac)),
-        },
-        span: folder.new_span(span)
-    }))
+pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig {
+    MethodSig {
+        generics: folder.fold_generics(sig.generics),
+        abi: sig.abi,
+        explicit_self: folder.fold_explicit_self(sig.explicit_self),
+        unsafety: sig.unsafety,
+        decl: folder.fold_fn_decl(sig.decl)
+    }
 }
 
 pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
@@ -1361,8 +1259,15 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) ->
                 ExprRange(e1.map(|x| folder.fold_expr(x)),
                           e2.map(|x| folder.fold_expr(x)))
             }
-            ExprPath(pth) => ExprPath(folder.fold_path(pth)),
-            ExprQPath(qpath) => ExprQPath(folder.fold_qpath(qpath)),
+            ExprPath(qself, path) => {
+                let qself = qself.map(|QSelf { ty, position }| {
+                    QSelf {
+                        ty: folder.fold_ty(ty),
+                        position: position
+                    }
+                });
+                ExprPath(qself, folder.fold_path(path))
+            }
             ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))),
             ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))),
             ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))),
@@ -1437,7 +1342,7 @@ pub fn noop_fold_stmt<T: Folder>(Spanned {node, span}: Stmt, folder: &mut T)
 
 #[cfg(test)]
 mod test {
-    use std::old_io;
+    use std::io;
     use ast;
     use util::parser_testing::{string_to_crate, matches_codepattern};
     use parse::token;
@@ -1447,7 +1352,7 @@ mod test {
 
     // this version doesn't care about getting comments or docstrings in.
     fn fake_print_crate(s: &mut pprust::State,
-                        krate: &ast::Crate) -> old_io::IoResult<()> {
+                        krate: &ast::Crate) -> io::Result<()> {
         s.print_mod(&krate.module, &krate.attrs)
     }
 
index 3a7fa54edbdd772ab633557e8962b8041340846a..0980acd3433dcc427dcf3da5833b856ccdaa3f60 100644 (file)
@@ -14,6 +14,8 @@
 //!
 //! This API is completely unstable and subject to change.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "syntax"]
 #![unstable(feature = "rustc_private")]
 #![staged_api]
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(env)]
-#![feature(int_uint)]
-#![feature(old_io)]
 #![feature(libc)]
 #![feature(old_path)]
 #![feature(quote, unsafe_destructor)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(std_misc)]
 #![feature(unicode)]
+#![feature(path_ext)]
+#![feature(str_char)]
+#![feature(into_cow)]
+#![feature(slice_patterns)]
 
 extern crate arena;
 extern crate fmt_macros;
@@ -46,7 +48,7 @@ extern crate libc;
 #[macro_use] extern crate log;
 #[macro_use] #[no_link] extern crate rustc_bitflags;
 
-extern crate "serialize" as rustc_serialize; // used by deriving
+extern crate serialize as rustc_serialize; // used by deriving
 
 pub mod util {
     pub mod interner;
index f5201d4a8bc68f73ea9f46c07e6bca61330a561e..25f1f9b8480a1204d71129325688b6f1d43c72be 100644 (file)
@@ -30,7 +30,7 @@ impl<T:fmt::Debug> fmt::Debug for OwnedSlice<T> {
 
 impl<T> OwnedSlice<T> {
     pub fn empty() -> OwnedSlice<T> {
-        OwnedSlice  { data: box [] }
+        OwnedSlice  { data: Box::new([]) }
     }
 
     #[inline(never)]
index 06e8728d23672d101463d36144b5c9bee83c6be8..a5dd4f222241d0d0d5a05814a970dd4e65a8737f 100644 (file)
@@ -19,9 +19,8 @@ use ptr::P;
 /// A parser that can parse attributes.
 pub trait ParserAttr {
     fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute>;
+    fn parse_inner_attributes(&mut self) -> Vec<ast::Attribute>;
     fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute;
-    fn parse_inner_attrs_and_next(&mut self)
-                                  -> (Vec<ast::Attribute>, Vec<ast::Attribute>);
     fn parse_meta_item(&mut self) -> P<ast::MetaItem>;
     fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>>;
     fn parse_optional_meta(&mut self) -> Vec<P<ast::MetaItem>>;
@@ -77,7 +76,7 @@ impl<'a> ParserAttr for Parser<'a> {
                         self.span_err(span,
                                       "an inner attribute is not permitted in \
                                        this context");
-                        self.span_help(span,
+                        self.fileline_help(span,
                                        "place inner attribute at the top of the module or block");
                     }
                     ast::AttrInner
@@ -94,7 +93,7 @@ impl<'a> ParserAttr for Parser<'a> {
             }
             _ => {
                 let token_str = self.this_token_to_string();
-                self.fatal(&format!("expected `#`, found `{}`", token_str)[]);
+                self.fatal(&format!("expected `#`, found `{}`", token_str));
             }
         };
 
@@ -118,45 +117,40 @@ impl<'a> ParserAttr for Parser<'a> {
 
     /// Parse attributes that appear after the opening of an item. These should
     /// be preceded by an exclamation mark, but we accept and warn about one
-    /// terminated by a semicolon. In addition to a vector of inner attributes,
-    /// this function also returns a vector that may contain the first outer
-    /// attribute of the next item (since we can't know whether the attribute
-    /// is an inner attribute of the containing item or an outer attribute of
-    /// the first contained item until we see the semi).
-
-    /// matches inner_attrs* outer_attr?
-    /// you can make the 'next' field an Option, but the result is going to be
-    /// more useful as a vector.
-    fn parse_inner_attrs_and_next(&mut self)
-                                  -> (Vec<ast::Attribute> , Vec<ast::Attribute> ) {
-        let mut inner_attrs: Vec<ast::Attribute> = Vec::new();
-        let mut next_outer_attrs: Vec<ast::Attribute> = Vec::new();
+    /// terminated by a semicolon.
+
+    /// matches inner_attrs*
+    fn parse_inner_attributes(&mut self) -> Vec<ast::Attribute> {
+        let mut attrs: Vec<ast::Attribute> = vec![];
         loop {
-            let attr = match self.token {
+            match self.token {
                 token::Pound => {
-                    self.parse_attribute(true)
+                    // Don't even try to parse if it's not an inner attribute.
+                    if !self.look_ahead(1, |t| t == &token::Not) {
+                        break;
+                    }
+
+                    let attr = self.parse_attribute(true);
+                    assert!(attr.node.style == ast::AttrInner);
+                    attrs.push(attr);
                 }
                 token::DocComment(s) => {
                     // we need to get the position of this token before we bump.
                     let Span { lo, hi, .. } = self.span;
-                    self.bump();
-                    attr::mk_sugared_doc_attr(attr::mk_attr_id(),
-                                              self.id_to_interned_str(s.ident()),
-                                              lo,
-                                              hi)
-                }
-                _ => {
-                    break;
+                    let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(),
+                                                         self.id_to_interned_str(s.ident()),
+                                                         lo, hi);
+                    if attr.node.style == ast::AttrInner {
+                        attrs.push(attr);
+                        self.bump();
+                    } else {
+                        break;
+                    }
                 }
-            };
-            if attr.node.style == ast::AttrInner {
-                inner_attrs.push(attr);
-            } else {
-                next_outer_attrs.push(attr);
-                break;
+                _ => break
             }
         }
-        (inner_attrs, next_outer_attrs)
+        attrs
     }
 
     /// matches meta_item = IDENT
index 1f06db600278b4162c807fcc83d8f36bae593d2d..277f5365db3eca6883cf06531db133c44a64e4ae 100644 (file)
@@ -19,9 +19,7 @@ use parse::lexer::is_block_doc_comment;
 use parse::lexer;
 use print::pprust;
 
-use std::old_io;
-use std::str;
-use std::string::String;
+use std::io::Read;
 use std::usize;
 
 #[derive(Clone, Copy, PartialEq)]
@@ -92,7 +90,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> String {
         let mut first = true;
         for line in &lines {
             for (j, c) in line.chars().enumerate() {
-                if j > i || !"* \t".contains_char(c) {
+                if j > i || !"* \t".contains(c) {
                     can_trim = false;
                     break;
                 }
@@ -124,8 +122,8 @@ pub fn strip_doc_comment_decoration(comment: &str) -> String {
     }
 
     // one-line comments lose their prefix
-    static ONLINERS: &'static [&'static str] = &["///!", "///", "//!", "//"];
-    for prefix in ONLINERS {
+    const ONELINERS: &'static [&'static str] = &["///!", "///", "//!", "//"];
+    for prefix in ONELINERS {
         if comment.starts_with(*prefix) {
             return (&comment[prefix.len()..]).to_string();
         }
@@ -211,11 +209,11 @@ fn all_whitespace(s: &str, col: CharPos) -> Option<usize> {
     let mut col = col.to_usize();
     let mut cursor: usize = 0;
     while col > 0 && cursor < len {
-        let r: str::CharRange = s.char_range_at(cursor);
-        if !r.ch.is_whitespace() {
+        let ch = s.char_at(cursor);
+        if !ch.is_whitespace() {
             return None;
         }
-        cursor = r.next;
+        cursor += ch.len_utf8();
         col -= 1;
     }
     return Some(cursor);
@@ -264,7 +262,7 @@ fn read_block_comment(rdr: &mut StringReader,
         if is_block_doc_comment(&curr_line[..]) {
             return
         }
-        assert!(!curr_line.contains_char('\n'));
+        assert!(!curr_line.contains('\n'));
         lines.push(curr_line);
     } else {
         let mut level: isize = 1;
@@ -337,9 +335,10 @@ pub struct Literal {
 // probably not a good thing.
 pub fn gather_comments_and_literals(span_diagnostic: &diagnostic::SpanHandler,
                                     path: String,
-                                    srdr: &mut old_io::Reader)
+                                    srdr: &mut Read)
                                  -> (Vec<Comment>, Vec<Literal>) {
-    let src = srdr.read_to_end().unwrap();
+    let mut src = Vec::new();
+    srdr.read_to_end(&mut src).unwrap();
     let src = String::from_utf8(src).unwrap();
     let cm = CodeMap::new();
     let filemap = cm.new_filemap(path, src);
index fd08cbd161bfe3db302137e480539c2b3de8d6ff..78470f002072ddf6f724c21e6d1858ae68f1f92a 100644 (file)
@@ -14,15 +14,13 @@ use codemap;
 use diagnostic::SpanHandler;
 use ext::tt::transcribe::tt_next_token;
 use parse::token;
-use parse::token::{str_to_ident};
+use parse::token::str_to_ident;
 
 use std::borrow::{IntoCow, Cow};
 use std::char;
 use std::fmt;
 use std::mem::replace;
-use std::num;
 use std::rc::Rc;
-use std::str;
 
 pub use ext::tt::transcribe::{TtReader, new_tt_reader, new_tt_reader_with_doc_flag};
 
@@ -76,6 +74,10 @@ pub struct StringReader<'a> {
     // are revised to go directly to token-trees.
     /// Is \x00<name>,<ctxt>\x00 is interpreted as encoded ast::Ident?
     read_embedded_ident: bool,
+
+    // cache a direct reference to the source text, so that we don't have to
+    // retrieve it via `self.filemap.src.as_ref().unwrap()` all the time.
+    source_text: Rc<String>
 }
 
 impl<'a> Reader for StringReader<'a> {
@@ -141,7 +143,14 @@ pub fn make_reader_with_embedded_idents<'b>(span_diagnostic: &'b SpanHandler,
 impl<'a> StringReader<'a> {
     /// For comments.rs, which hackily pokes into pos and curr
     pub fn new_raw<'b>(span_diagnostic: &'b SpanHandler,
-                   filemap: Rc<codemap::FileMap>) -> StringReader<'b> {
+                       filemap: Rc<codemap::FileMap>) -> StringReader<'b> {
+        if filemap.src.is_none() {
+            span_diagnostic.handler.bug(&format!("Cannot lex filemap without source: {}",
+                                                 filemap.name)[..]);
+        }
+
+        let source_text = (*filemap.src.as_ref().unwrap()).clone();
+
         let mut sr = StringReader {
             span_diagnostic: span_diagnostic,
             pos: filemap.start_pos,
@@ -153,6 +162,7 @@ impl<'a> StringReader<'a> {
             peek_tok: token::Eof,
             peek_span: codemap::DUMMY_SP,
             read_embedded_ident: false,
+            source_text: source_text
         };
         sr.bump();
         sr
@@ -213,7 +223,7 @@ impl<'a> StringReader<'a> {
         m.push_str(": ");
         let from = self.byte_offset(from_pos).to_usize();
         let to = self.byte_offset(to_pos).to_usize();
-        m.push_str(&self.filemap.src[from..to]);
+        m.push_str(&self.source_text[from..to]);
         self.fatal_span_(from_pos, to_pos, &m[..]);
     }
 
@@ -270,9 +280,8 @@ impl<'a> StringReader<'a> {
     fn with_str_from_to<T, F>(&self, start: BytePos, end: BytePos, f: F) -> T where
         F: FnOnce(&str) -> T,
     {
-        f(&self.filemap.src[
-                self.byte_offset(start).to_usize()..
-                self.byte_offset(end).to_usize()])
+        f(&self.source_text[self.byte_offset(start).to_usize()..
+                            self.byte_offset(end).to_usize()])
     }
 
     /// Converts CRLF to LF in the given string, raising an error on bare CR.
@@ -280,7 +289,8 @@ impl<'a> StringReader<'a> {
                           s: &'b str, errmsg: &'b str) -> Cow<'b, str> {
         let mut i = 0;
         while i < s.len() {
-            let str::CharRange { ch, next } = s.char_range_at(i);
+            let ch = s.char_at(i);
+            let next = i + ch.len_utf8();
             if ch == '\r' {
                 if next < s.len() && s.char_at(next) == '\n' {
                     return translate_crlf_(self, start, s, errmsg, i).into_cow();
@@ -298,7 +308,8 @@ impl<'a> StringReader<'a> {
             let mut buf = String::with_capacity(s.len());
             let mut j = 0;
             while i < s.len() {
-                let str::CharRange { ch, next } = s.char_range_at(i);
+                let ch = s.char_at(i);
+                let next = i + ch.len_utf8();
                 if ch == '\r' {
                     if j < i { buf.push_str(&s[j..i]); }
                     j = next;
@@ -321,15 +332,14 @@ impl<'a> StringReader<'a> {
     pub fn bump(&mut self) {
         self.last_pos = self.pos;
         let current_byte_offset = self.byte_offset(self.pos).to_usize();
-        if current_byte_offset < self.filemap.src.len() {
+        if current_byte_offset < self.source_text.len() {
             assert!(self.curr.is_some());
             let last_char = self.curr.unwrap();
-            let next = self.filemap
-                          .src
-                          .char_range_at(current_byte_offset);
-            let byte_offset_diff = next.next - current_byte_offset;
+            let ch = self.source_text.char_at(current_byte_offset);
+            let next = current_byte_offset + ch.len_utf8();
+            let byte_offset_diff = next - current_byte_offset;
             self.pos = self.pos + Pos::from_usize(byte_offset_diff);
-            self.curr = Some(next.ch);
+            self.curr = Some(ch);
             self.col = self.col + CharPos(1);
             if last_char == '\n' {
                 self.filemap.next_line(self.last_pos);
@@ -346,8 +356,8 @@ impl<'a> StringReader<'a> {
 
     pub fn nextch(&self) -> Option<char> {
         let offset = self.byte_offset(self.pos).to_usize();
-        if offset < self.filemap.src.len() {
-            Some(self.filemap.src.char_at(offset))
+        if offset < self.source_text.len() {
+            Some(self.source_text.char_at(offset))
         } else {
             None
         }
@@ -359,9 +369,9 @@ impl<'a> StringReader<'a> {
 
     pub fn nextnextch(&self) -> Option<char> {
         let offset = self.byte_offset(self.pos).to_usize();
-        let s = &*self.filemap.src;
+        let s = &self.source_text[..];
         if offset >= s.len() { return None }
-        let str::CharRange { next, .. } = s.char_range_at(offset);
+        let next = offset + s.char_at(offset).len_utf8();
         if next < s.len() {
             Some(s.char_at(next))
         } else {
@@ -610,9 +620,9 @@ impl<'a> StringReader<'a> {
         let base = 10;
 
         // find the integer representing the name
-        self.scan_digits(base);
+        self.scan_digits(base, base);
         let encoded_name : u32 = self.with_str_from(start_bpos, |s| {
-            num::from_str_radix(s, 10).ok().unwrap_or_else(|| {
+            u32::from_str_radix(s, 10).unwrap_or_else(|_| {
                 panic!("expected digits representing a name, got {:?}, {}, range [{:?},{:?}]",
                       s, whence, start_bpos, self.last_pos);
             })
@@ -628,9 +638,9 @@ impl<'a> StringReader<'a> {
 
         // find the integer representing the ctxt
         let start_bpos = self.last_pos;
-        self.scan_digits(base);
+        self.scan_digits(base, base);
         let encoded_ctxt : ast::SyntaxContext = self.with_str_from(start_bpos, |s| {
-            num::from_str_radix(s, 10).ok().unwrap_or_else(|| {
+            u32::from_str_radix(s, 10).unwrap_or_else(|_| {
                 panic!("expected digits representing a ctxt, got {:?}, {}", s, whence);
             })
         });
@@ -642,16 +652,28 @@ impl<'a> StringReader<'a> {
                      ctxt: encoded_ctxt, }
     }
 
-    /// Scan through any digits (base `radix`) or underscores, and return how
-    /// many digits there were.
-    fn scan_digits(&mut self, radix: u32) -> usize {
+    /// Scan through any digits (base `scan_radix`) or underscores,
+    /// and return how many digits there were.
+    ///
+    /// `real_radix` represents the true radix of the number we're
+    /// interested in, and errors will be emitted for any digits
+    /// between `real_radix` and `scan_radix`.
+    fn scan_digits(&mut self, real_radix: u32, scan_radix: u32) -> usize {
+        assert!(real_radix <= scan_radix);
         let mut len = 0;
         loop {
             let c = self.curr;
             if c == Some('_') { debug!("skipping a _"); self.bump(); continue; }
-            match c.and_then(|cc| cc.to_digit(radix)) {
+            match c.and_then(|cc| cc.to_digit(scan_radix)) {
                 Some(_) => {
                     debug!("{:?} in scan_digits", c);
+                    // check that the hypothetical digit is actually
+                    // in range for the true radix
+                    if c.unwrap().to_digit(real_radix).is_none() {
+                        self.err_span_(self.last_pos, self.pos,
+                                       &format!("invalid digit for a base {} literal",
+                                                real_radix));
+                    }
                     len += 1;
                     self.bump();
                 }
@@ -670,11 +692,11 @@ impl<'a> StringReader<'a> {
 
         if c == '0' {
             match self.curr.unwrap_or('\0') {
-                'b' => { self.bump(); base = 2; num_digits = self.scan_digits(2); }
-                'o' => { self.bump(); base = 8; num_digits = self.scan_digits(8); }
-                'x' => { self.bump(); base = 16; num_digits = self.scan_digits(16); }
+                'b' => { self.bump(); base = 2; num_digits = self.scan_digits(2, 10); }
+                'o' => { self.bump(); base = 8; num_digits = self.scan_digits(8, 10); }
+                'x' => { self.bump(); base = 16; num_digits = self.scan_digits(16, 16); }
                 '0'...'9' | '_' | '.' => {
-                    num_digits = self.scan_digits(10) + 1;
+                    num_digits = self.scan_digits(10, 10) + 1;
                 }
                 _ => {
                     // just a 0
@@ -682,7 +704,7 @@ impl<'a> StringReader<'a> {
                 }
             }
         } else if c.is_digit(10) {
-            num_digits = self.scan_digits(10) + 1;
+            num_digits = self.scan_digits(10, 10) + 1;
         } else {
             num_digits = 0;
         }
@@ -701,7 +723,7 @@ impl<'a> StringReader<'a> {
             // with a number
             self.bump();
             if self.curr.unwrap_or('\0').is_digit(10) {
-                self.scan_digits(10);
+                self.scan_digits(10, 10);
                 self.scan_float_exponent();
             }
             let last_pos = self.last_pos;
@@ -731,6 +753,7 @@ impl<'a> StringReader<'a> {
         let start_bpos = self.last_pos;
         let mut accum_int = 0;
 
+        let mut valid = true;
         for _ in 0..n_digits {
             if self.is_eof() {
                 let last_bpos = self.last_pos;
@@ -739,6 +762,7 @@ impl<'a> StringReader<'a> {
             if self.curr_is(delim) {
                 let last_bpos = self.last_pos;
                 self.err_span_(start_bpos, last_bpos, "numeric character escape is too short");
+                valid = false;
                 break;
             }
             let c = self.curr.unwrap_or('\x00');
@@ -746,8 +770,10 @@ impl<'a> StringReader<'a> {
             accum_int += c.to_digit(16).unwrap_or_else(|| {
                 self.err_span_char(self.last_pos, self.pos,
                               "illegal character in numeric character escape", c);
+
+                valid = false;
                 0
-            }) as u32;
+            });
             self.bump();
         }
 
@@ -756,10 +782,11 @@ impl<'a> StringReader<'a> {
                            self.last_pos,
                            "this form of character escape may only be used \
                             with characters in the range [\\x00-\\x7f]");
+            valid = false;
         }
 
         match char::from_u32(accum_int) {
-            Some(_) => true,
+            Some(_) => valid,
             None => {
                 let last_bpos = self.last_pos;
                 self.err_span_(start_bpos, last_bpos, "illegal numeric character escape");
@@ -768,13 +795,6 @@ impl<'a> StringReader<'a> {
         }
     }
 
-    fn old_escape_warning(&mut self, sp: Span) {
-        self.span_diagnostic
-            .span_warn(sp, "\\U00ABCD12 and \\uABCD escapes are deprecated");
-        self.span_diagnostic
-            .span_help(sp, "use \\u{ABCD12} escapes instead");
-    }
-
     /// Scan for a single (possibly escaped) byte or char
     /// in a byte, (non-raw) byte string, char, or (non-raw) string literal.
     /// `start` is the position of `first_source_char`, which is already consumed.
@@ -794,21 +814,19 @@ impl<'a> StringReader<'a> {
                         return match e {
                             'n' | 'r' | 't' | '\\' | '\'' | '"' | '0' => true,
                             'x' => self.scan_byte_escape(delim, !ascii_only),
-                            'u' if !ascii_only => {
-                                if self.curr == Some('{') {
-                                    self.scan_unicode_escape(delim)
-                                } else {
-                                    let res = self.scan_hex_digits(4, delim, false);
-                                    let sp = codemap::mk_sp(escaped_pos, self.last_pos);
-                                    self.old_escape_warning(sp);
-                                    res
-                                }
+                            'u' if self.curr_is('{') => {
+                            let valid = self.scan_unicode_escape(delim);
+                            if valid && ascii_only {
+                                self.err_span_(
+                                    escaped_pos,
+                                    self.last_pos,
+                                    "unicode escape sequences cannot be used as a byte or in \
+                                    a byte string"
+                                );
+                                false
+                            } else {
+                               valid
                             }
-                            'U' if !ascii_only => {
-                                let res = self.scan_hex_digits(8, delim, false);
-                                let sp = codemap::mk_sp(escaped_pos, self.last_pos);
-                                self.old_escape_warning(sp);
-                                res
                             }
                             '\n' if delim == '"' => {
                                 self.consume_whitespace();
@@ -878,6 +896,7 @@ impl<'a> StringReader<'a> {
         let start_bpos = self.last_pos;
         let mut count = 0;
         let mut accum_int = 0;
+        let mut valid = true;
 
         while !self.curr_is('}') && count <= 6 {
             let c = match self.curr {
@@ -893,29 +912,30 @@ impl<'a> StringReader<'a> {
                     self.fatal_span_(self.last_pos, self.pos,
                                      "unterminated unicode escape (needed a `}`)");
                 } else {
-                    self.fatal_span_char(self.last_pos, self.pos,
+                    self.err_span_char(self.last_pos, self.pos,
                                    "illegal character in unicode escape", c);
                 }
-            }) as u32;
+                valid = false;
+                0
+            });
             self.bump();
             count += 1;
         }
 
         if count > 6 {
-            self.fatal_span_(start_bpos, self.last_pos,
+            self.err_span_(start_bpos, self.last_pos,
                           "overlong unicode escape (can have at most 6 hex digits)");
+            valid = false;
         }
 
         self.bump(); // past the ending }
 
-        let mut valid = count >= 1 && count <= 6;
-        if char::from_u32(accum_int).is_none() {
-            valid = false;
+        if valid && (char::from_u32(accum_int).is_none() || count == 0) {
+            self.err_span_(start_bpos, self.last_pos, "illegal unicode character escape");
+            valid= false;
         }
 
-        if !valid {
-            self.fatal_span_(start_bpos, self.last_pos, "illegal unicode character escape");
-        }
+
         valid
     }
 
@@ -926,7 +946,7 @@ impl<'a> StringReader<'a> {
             if self.curr_is('-') || self.curr_is('+') {
                 self.bump();
             }
-            if self.scan_digits(10) == 0 {
+            if self.scan_digits(10, 10) == 0 {
                 self.err_span_(self.last_pos, self.pos, "expected at least one digit in exponent")
             }
         }
@@ -1109,7 +1129,7 @@ impl<'a> StringReader<'a> {
                 // expansion purposes. See #12512 for the gory details of why
                 // this is necessary.
                 let ident = self.with_str_from(start, |lifetime_name| {
-                    str_to_ident(&format!("'{}", lifetime_name)[])
+                    str_to_ident(&format!("'{}", lifetime_name))
                 });
 
                 // Conjure up a "keyword checking ident" to make sure that
@@ -1339,7 +1359,7 @@ impl<'a> StringReader<'a> {
                 "unterminated byte constant".to_string());
         }
 
-        let id = if valid { self.name_from(start) } else { token::intern("??") };
+        let id = if valid { self.name_from(start) } else { token::intern("?") };
         self.bump(); // advance curr past token
         return token::Byte(id);
     }
@@ -1481,11 +1501,12 @@ mod test {
     use diagnostic;
     use parse::token;
     use parse::token::{str_to_ident};
-    use std::old_io::util;
+    use std::io;
 
     fn mk_sh() -> diagnostic::SpanHandler {
-        let emitter = diagnostic::EmitterWriter::new(box util::NullWriter, None);
-        let handler = diagnostic::mk_handler(true, box emitter);
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        let emitter = diagnostic::EmitterWriter::new(Box::new(io::sink()), None);
+        let handler = diagnostic::mk_handler(true, Box::new(emitter));
         diagnostic::mk_span_handler(handler, CodeMap::new())
     }
 
index 7ed48bdbb928dc9ace647ea772f902f3c1228e96..f59e1d8214a5a632d32651e824d04dd9ef9eebff 100644 (file)
@@ -18,11 +18,14 @@ use parse::parser::Parser;
 use ptr::P;
 
 use std::cell::{Cell, RefCell};
-use std::old_io::File;
-use std::rc::Rc;
+use std::fs::File;
+use std::io::Read;
+use std::iter;
+#[allow(deprecated)] // Int
 use std::num::Int;
+use std::path::{Path, PathBuf};
+use std::rc::Rc;
 use std::str;
-use std::iter;
 
 #[macro_use]
 pub mod parser;
@@ -39,7 +42,7 @@ pub mod obsolete;
 pub struct ParseSess {
     pub span_diagnostic: SpanHandler, // better be the same as the one in the reader!
     /// Used to determine and report recursive mod inclusions
-    included_mod_stack: RefCell<Vec<Path>>,
+    included_mod_stack: RefCell<Vec<PathBuf>>,
     pub node_id: Cell<ast::NodeId>,
 }
 
@@ -94,9 +97,7 @@ pub fn parse_crate_attrs_from_file(
     cfg: ast::CrateConfig,
     sess: &ParseSess
 ) -> Vec<ast::Attribute> {
-    let mut parser = new_parser_from_file(sess, cfg, input);
-    let (inner, _) = parser.parse_inner_attrs_and_next();
-    inner
+    new_parser_from_file(sess, cfg, input).parse_inner_attributes()
 }
 
 pub fn parse_crate_from_source_str(name: String,
@@ -120,8 +121,7 @@ pub fn parse_crate_attrs_from_source_str(name: String,
                                            cfg,
                                            name,
                                            source);
-    let (inner, _) = maybe_aborted(p.parse_inner_attrs_and_next(),p);
-    inner
+    maybe_aborted(p.parse_inner_attributes(), p)
 }
 
 pub fn parse_expr_from_source_str(name: String,
@@ -139,7 +139,7 @@ pub fn parse_item_from_source_str(name: String,
                                   sess: &ParseSess)
                                   -> Option<P<ast::Item>> {
     let mut p = new_parser_from_source_str(sess, cfg, name, source);
-    maybe_aborted(p.parse_item_with_outer_attributes(),p)
+    maybe_aborted(p.parse_item(),p)
 }
 
 pub fn parse_meta_from_source_str(name: String,
@@ -154,16 +154,15 @@ pub fn parse_meta_from_source_str(name: String,
 pub fn parse_stmt_from_source_str(name: String,
                                   source: String,
                                   cfg: ast::CrateConfig,
-                                  attrs: Vec<ast::Attribute> ,
                                   sess: &ParseSess)
-                                  -> P<ast::Stmt> {
+                                  -> Option<P<ast::Stmt>> {
     let mut p = new_parser_from_source_str(
         sess,
         cfg,
         name,
         source
     );
-    maybe_aborted(p.parse_stmt(attrs),p)
+    maybe_aborted(p.parse_stmt(), p)
 }
 
 // Note: keep in sync with `with_hygiene::parse_tts_from_source_str`
@@ -250,24 +249,24 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
             None => sess.span_diagnostic.handler().fatal(msg),
         }
     };
-    let bytes = match File::open(path).read_to_end() {
-        Ok(bytes) => bytes,
+    let mut bytes = Vec::new();
+    match File::open(path).and_then(|mut f| f.read_to_end(&mut bytes)) {
+        Ok(..) => {}
         Err(e) => {
-            err(&format!("couldn't read {:?}: {}",
-                        path.display(), e)[]);
-            unreachable!()
+            err(&format!("couldn't read {:?}: {}", path.display(), e));
+            unreachable!();
         }
     };
     match str::from_utf8(&bytes[..]).ok() {
         Some(s) => {
-            return string_to_filemap(sess, s.to_string(),
-                                     path.as_str().unwrap().to_string())
+            string_to_filemap(sess, s.to_string(),
+                              path.to_str().unwrap().to_string())
         }
         None => {
-            err(&format!("{:?} is not UTF-8 encoded", path.display())[])
+            err(&format!("{:?} is not UTF-8 encoded", path.display()));
+            unreachable!();
         }
     }
-    unreachable!()
 }
 
 /// Given a session and a string, add the string to
@@ -374,7 +373,7 @@ pub fn maybe_aborted<T>(result: T, p: Parser) -> T {
 /// well. Can take any slice prefixed by a character escape. Returns the
 /// character and the number of characters consumed.
 pub fn char_lit(lit: &str) -> (char, isize) {
-    use std::{num, char};
+    use std::char;
 
     let mut chars = lit.chars();
     let c = match (chars.next(), chars.next()) {
@@ -401,21 +400,22 @@ pub fn char_lit(lit: &str) -> (char, isize) {
     let msg2 = &msg[..];
 
     fn esc(len: usize, lit: &str) -> Option<(char, isize)> {
-        num::from_str_radix(&lit[2..len], 16).ok()
+        u32::from_str_radix(&lit[2..len], 16).ok()
         .and_then(char::from_u32)
         .map(|x| (x, len as isize))
     }
 
-    let unicode_escape = || -> Option<(char, isize)>
+    let unicode_escape = || -> Option<(char, isize)> {
         if lit.as_bytes()[2] == b'{' {
             let idx = lit.find('}').expect(msg2);
             let subslice = &lit[3..idx];
-            num::from_str_radix(subslice, 16).ok()
+            u32::from_str_radix(subslice, 16).ok()
                 .and_then(char::from_u32)
                 .map(|x| (x, subslice.chars().count() as isize + 4))
         } else {
             esc(6, lit)
-        };
+        }
+    };
 
     // Unicode escapes
     return match lit.as_bytes()[1] as char {
@@ -583,7 +583,7 @@ pub fn byte_lit(lit: &str) -> (u8, usize) {
             b'\'' => b'\'',
             b'0' => b'\0',
             _ => {
-                match ::std::num::from_str_radix::<u64>(&lit[2..4], 16).ok() {
+                match u64::from_str_radix(&lit[2..4], 16).ok() {
                     Some(c) =>
                         if c > 0xFF {
                             panic!(err(2))
@@ -701,18 +701,18 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
     if let Some(suf) = suffix {
         if suf.is_empty() { sd.span_bug(sp, "found empty literal suffix in Some")}
         ty = match suf {
-            "isize" => ast::SignedIntLit(ast::TyIs(false), ast::Plus),
+            "isize" => ast::SignedIntLit(ast::TyIs, ast::Plus),
             "i8"  => ast::SignedIntLit(ast::TyI8, ast::Plus),
             "i16" => ast::SignedIntLit(ast::TyI16, ast::Plus),
             "i32" => ast::SignedIntLit(ast::TyI32, ast::Plus),
             "i64" => ast::SignedIntLit(ast::TyI64, ast::Plus),
-            "usize" => ast::UnsignedIntLit(ast::TyUs(false)),
+            "usize" => ast::UnsignedIntLit(ast::TyUs),
             "u8"  => ast::UnsignedIntLit(ast::TyU8),
             "u16" => ast::UnsignedIntLit(ast::TyU16),
             "u32" => ast::UnsignedIntLit(ast::TyU32),
             "u64" => ast::UnsignedIntLit(ast::TyU64),
-            "i" | "is" => ast::SignedIntLit(ast::TyIs(true), ast::Plus),
-            "u" | "us" => ast::UnsignedIntLit(ast::TyUs(true)),
+            "is" => ast::SignedIntLit(ast::TyIs, ast::Plus),
+            "us" => ast::UnsignedIntLit(ast::TyUs),
             _ => {
                 // i<digits> and u<digits> look like widths, so lets
                 // give an error message along those lines
@@ -722,7 +722,7 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
                                               &suf[1..]));
                 } else {
                     sd.span_err(sp, &*format!("illegal suffix `{}` for numeric literal", suf));
-                    sd.span_help(sp, "the suffix must be one of the integral types \
+                    sd.fileline_help(sp, "the suffix must be one of the integral types \
                                       (`u32`, `isize`, etc)");
                 }
 
@@ -734,9 +734,22 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
     debug!("integer_lit: the type is {:?}, base {:?}, the new string is {:?}, the original \
            string was {:?}, the original suffix was {:?}", ty, base, s, orig, suffix);
 
-    let res: u64 = match ::std::num::from_str_radix(s, base).ok() {
+    let res = match u64::from_str_radix(s, base).ok() {
         Some(r) => r,
-        None => { sd.span_err(sp, "int literal is too large"); 0 }
+        None => {
+            // small bases are lexed as if they were base 10, e.g, the string
+            // might be `0b10201`. This will cause the conversion above to fail,
+            // but these cases have errors in the lexer: we don't want to emit
+            // two errors, and we especially don't want to emit this error since
+            // it isn't necessarily true.
+            let already_errored = base < 10 &&
+                s.chars().any(|c| c.to_digit(10).map_or(false, |d| d >= base));
+
+            if !already_errored {
+                sd.span_err(sp, "int literal is too large");
+            }
+            0
+        }
     };
 
     // adjust the sign
@@ -751,7 +764,7 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
 #[cfg(test)]
 mod test {
     use super::*;
-    use serialize::json;
+    use std::rc::Rc;
     use codemap::{Span, BytePos, Pos, Spanned, NO_EXPANSION};
     use owned_slice::OwnedSlice;
     use ast;
@@ -774,7 +787,7 @@ mod test {
         assert!(string_to_expr("a".to_string()) ==
                    P(ast::Expr{
                     id: ast::DUMMY_NODE_ID,
-                    node: ast::ExprPath(ast::Path {
+                    node: ast::ExprPath(None, ast::Path {
                         span: sp(0, 1),
                         global: false,
                         segments: vec!(
@@ -792,7 +805,7 @@ mod test {
         assert!(string_to_expr("::a::b".to_string()) ==
                    P(ast::Expr {
                     id: ast::DUMMY_NODE_ID,
-                    node: ast::ExprPath(ast::Path {
+                    node: ast::ExprPath(None, ast::Path {
                             span: sp(0, 6),
                             global: true,
                             segments: vec!(
@@ -810,7 +823,7 @@ mod test {
                    }))
     }
 
-    #[should_fail]
+    #[should_panic]
     #[test] fn bad_path_expr_1() {
         string_to_expr("::abc::def::return".to_string());
     }
@@ -827,19 +840,19 @@ mod test {
              ast::TtDelimited(_, ref macro_delimed)]
             if name_macro_rules.as_str() == "macro_rules"
             && name_zip.as_str() == "zip" => {
-                match &macro_delimed.tts[] {
+                match &macro_delimed.tts[..] {
                     [ast::TtDelimited(_, ref first_delimed),
                      ast::TtToken(_, token::FatArrow),
                      ast::TtDelimited(_, ref second_delimed)]
                     if macro_delimed.delim == token::Paren => {
-                        match &first_delimed.tts[] {
+                        match &first_delimed.tts[..] {
                             [ast::TtToken(_, token::Dollar),
                              ast::TtToken(_, token::Ident(name, token::Plain))]
                             if first_delimed.delim == token::Paren
                             && name.as_str() == "a" => {},
                             _ => panic!("value 3: {:?}", **first_delimed),
                         }
-                        match &second_delimed.tts[] {
+                        match &second_delimed.tts[..] {
                             [ast::TtToken(_, token::Dollar),
                              ast::TtToken(_, token::Ident(name, token::Plain))]
                             if second_delimed.delim == token::Paren
@@ -855,117 +868,50 @@ mod test {
     }
 
     #[test]
-    fn string_to_tts_1 () {
+    fn string_to_tts_1() {
         let tts = string_to_tts("fn a (b : i32) { b; }".to_string());
-        assert_eq!(json::encode(&tts).unwrap(),
-        "[\
-    {\
-        \"variant\":\"TtToken\",\
-        \"fields\":[\
-            null,\
-            {\
-                \"variant\":\"Ident\",\
-                \"fields\":[\
-                    \"fn\",\
-                    \"Plain\"\
-                ]\
-            }\
-        ]\
-    },\
-    {\
-        \"variant\":\"TtToken\",\
-        \"fields\":[\
-            null,\
-            {\
-                \"variant\":\"Ident\",\
-                \"fields\":[\
-                    \"a\",\
-                    \"Plain\"\
-                ]\
-            }\
-        ]\
-    },\
-    {\
-        \"variant\":\"TtDelimited\",\
-        \"fields\":[\
-            null,\
-            {\
-                \"delim\":\"Paren\",\
-                \"open_span\":null,\
-                \"tts\":[\
-                    {\
-                        \"variant\":\"TtToken\",\
-                        \"fields\":[\
-                            null,\
-                            {\
-                                \"variant\":\"Ident\",\
-                                \"fields\":[\
-                                    \"b\",\
-                                    \"Plain\"\
-                                ]\
-                            }\
-                        ]\
-                    },\
-                    {\
-                        \"variant\":\"TtToken\",\
-                        \"fields\":[\
-                            null,\
-                            \"Colon\"\
-                        ]\
-                    },\
-                    {\
-                        \"variant\":\"TtToken\",\
-                        \"fields\":[\
-                            null,\
-                            {\
-                                \"variant\":\"Ident\",\
-                                \"fields\":[\
-                                    \"i32\",\
-                                    \"Plain\"\
-                                ]\
-                            }\
-                        ]\
-                    }\
-                ],\
-                \"close_span\":null\
-            }\
-        ]\
-    },\
-    {\
-        \"variant\":\"TtDelimited\",\
-        \"fields\":[\
-            null,\
-            {\
-                \"delim\":\"Brace\",\
-                \"open_span\":null,\
-                \"tts\":[\
-                    {\
-                        \"variant\":\"TtToken\",\
-                        \"fields\":[\
-                            null,\
-                            {\
-                                \"variant\":\"Ident\",\
-                                \"fields\":[\
-                                    \"b\",\
-                                    \"Plain\"\
-                                ]\
-                            }\
-                        ]\
-                    },\
-                    {\
-                        \"variant\":\"TtToken\",\
-                        \"fields\":[\
-                            null,\
-                            \"Semi\"\
-                        ]\
-                    }\
-                ],\
-                \"close_span\":null\
-            }\
-        ]\
-    }\
-]"
-        );
+
+        let expected = vec![
+            ast::TtToken(sp(0, 2),
+                         token::Ident(str_to_ident("fn"),
+                         token::IdentStyle::Plain)),
+            ast::TtToken(sp(3, 4),
+                         token::Ident(str_to_ident("a"),
+                         token::IdentStyle::Plain)),
+            ast::TtDelimited(
+                sp(5, 14),
+                Rc::new(ast::Delimited {
+                    delim: token::DelimToken::Paren,
+                    open_span: sp(5, 6),
+                    tts: vec![
+                        ast::TtToken(sp(6, 7),
+                                     token::Ident(str_to_ident("b"),
+                                     token::IdentStyle::Plain)),
+                        ast::TtToken(sp(8, 9),
+                                     token::Colon),
+                        ast::TtToken(sp(10, 13),
+                                     token::Ident(str_to_ident("i32"),
+                                     token::IdentStyle::Plain)),
+                    ],
+                    close_span: sp(13, 14),
+                })),
+            ast::TtDelimited(
+                sp(15, 21),
+                Rc::new(ast::Delimited {
+                    delim: token::DelimToken::Brace,
+                    open_span: sp(15, 16),
+                    tts: vec![
+                        ast::TtToken(sp(17, 18),
+                                     token::Ident(str_to_ident("b"),
+                                     token::IdentStyle::Plain)),
+                        ast::TtToken(sp(18, 19),
+                                     token::Semi)
+                    ],
+                    close_span: sp(20, 21),
+                }))
+        ];
+
+        assert_eq!(tts, expected);
     }
 
     #[test] fn ret_expr() {
@@ -974,7 +920,7 @@ mod test {
                     id: ast::DUMMY_NODE_ID,
                     node:ast::ExprRet(Some(P(ast::Expr{
                         id: ast::DUMMY_NODE_ID,
-                        node:ast::ExprPath(ast::Path{
+                        node:ast::ExprPath(None, ast::Path{
                             span: sp(7, 8),
                             global: false,
                             segments: vec!(
@@ -995,7 +941,7 @@ mod test {
                    P(Spanned{
                        node: ast::StmtExpr(P(ast::Expr {
                            id: ast::DUMMY_NODE_ID,
-                           node: ast::ExprPath(ast::Path {
+                           node: ast::ExprPath(None, ast::Path {
                                span:sp(0,1),
                                global:false,
                                segments: vec!(
@@ -1041,7 +987,7 @@ mod test {
                             node: ast::ItemFn(P(ast::FnDecl {
                                 inputs: vec!(ast::Arg{
                                     ty: P(ast::Ty{id: ast::DUMMY_NODE_ID,
-                                                  node: ast::TyPath(ast::Path{
+                                                  node: ast::TyPath(None, ast::Path{
                                         span:sp(10,13),
                                         global:false,
                                         segments: vec!(
@@ -1051,7 +997,7 @@ mod test {
                                                 parameters: ast::PathParameters::none(),
                                             }
                                         ),
-                                        }, ast::DUMMY_NODE_ID),
+                                        }),
                                         span:sp(10,13)
                                     }),
                                     pat: P(ast::Pat {
@@ -1084,7 +1030,7 @@ mod test {
                                         stmts: vec!(P(Spanned{
                                             node: ast::StmtSemi(P(ast::Expr{
                                                 id: ast::DUMMY_NODE_ID,
-                                                node: ast::ExprPath(
+                                                node: ast::ExprPath(None,
                                                       ast::Path{
                                                         span:sp(17,18),
                                                         global:false,
@@ -1128,7 +1074,7 @@ mod test {
         let vitem_s = item_to_string(&*vitem);
         assert_eq!(&vitem_s[..], ex_s);
 
-        let ex_s = "extern crate \"foo\" as bar;";
+        let ex_s = "extern crate foo as bar;";
         let vitem = string_to_item(ex_s.to_string()).unwrap();
         let vitem_s = item_to_string(&*vitem);
         assert_eq!(&vitem_s[..], ex_s);
@@ -1207,7 +1153,7 @@ mod test {
 
         let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
         let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess).unwrap();
-        let docs = item.attrs.iter().filter(|a| &a.name()[] == "doc")
+        let docs = item.attrs.iter().filter(|a| &*a.name() == "doc")
                     .map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
         let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()];
         assert_eq!(&docs[..], b);
index 8480772ce6c1ad1b7c1528031800a9bafb06327f..f120dde8e1cb6fc12225f1887fc4a290d58772b1 100644 (file)
@@ -20,15 +20,10 @@ use parse::token;
 use ptr::P;
 
 /// The specific types of unsupported syntax
-#[derive(Copy, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub enum ObsoleteSyntax {
-    Sized,
-    ForSized,
-    ProcType,
-    ProcExpr,
-    ClosureType,
     ClosureKind,
-    EmptyIndex,
+    ExternCrateString,
 }
 
 pub trait ParserObsoleteMethods {
@@ -51,40 +46,14 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
     /// Reports an obsolete syntax non-fatal error.
     fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
         let (kind_str, desc, error) = match kind {
-            ObsoleteSyntax::ForSized => (
-                "for Sized?",
-                "no longer required. Traits (and their `Self` type) do not have the `Sized` bound \
-                 by default",
-                true,
-            ),
-            ObsoleteSyntax::ProcType => (
-                "the `proc` type",
-                "use unboxed closures instead",
-                true,
-            ),
-            ObsoleteSyntax::ProcExpr => (
-                "`proc` expression",
-                "use a `move ||` expression instead",
-                true,
-            ),
-            ObsoleteSyntax::ClosureType => (
-                "`|usize| -> bool` closure type",
-                "use unboxed closures instead, no type annotation needed",
-                true,
-            ),
             ObsoleteSyntax::ClosureKind => (
                 "`:`, `&mut:`, or `&:`",
                 "rely on inference instead",
                 true,
             ),
-            ObsoleteSyntax::Sized => (
-                "`Sized? T` for removing the `Sized` bound",
-                "write `T: ?Sized` instead",
-                true,
-            ),
-            ObsoleteSyntax::EmptyIndex => (
-                "[]",
-                "write `[..]` instead",
+            ObsoleteSyntax::ExternCrateString => (
+                "\"crate-name\"",
+                "use an identifier not in quotes instead",
                 false, // warning for now
             ),
         };
@@ -106,16 +75,16 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
               desc: &str,
               error: bool) {
         if error {
-            self.span_err(sp, &format!("obsolete syntax: {}", kind_str)[]);
+            self.span_err(sp, &format!("obsolete syntax: {}", kind_str));
         } else {
-            self.span_warn(sp, &format!("obsolete syntax: {}", kind_str)[]);
+            self.span_warn(sp, &format!("obsolete syntax: {}", kind_str));
         }
 
         if !self.obsolete_set.contains(&kind) {
             self.sess
                 .span_diagnostic
                 .handler()
-                .note(&format!("{}", desc)[]);
+                .note(&format!("{}", desc));
             self.obsolete_set.insert(kind);
         }
     }
index 370201e53825efef69f01d9c7313127f3a436cef..c721624323923e18a999552bcb6b825af5af48d9 100644 (file)
@@ -11,9 +11,9 @@
 pub use self::PathParsingMode::*;
 
 use abi;
-use ast::{AssociatedType, BareFnTy};
+use ast::BareFnTy;
 use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
-use ast::{ProvidedMethod, Public, Unsafety};
+use ast::{Public, Unsafety};
 use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
 use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, BiGt, Block};
 use ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause};
@@ -25,25 +25,24 @@ use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
 use ast::{ExprBreak, ExprCall, ExprCast};
 use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex};
 use ast::{ExprLit, ExprLoop, ExprMac, ExprRange};
-use ast::{ExprMethodCall, ExprParen, ExprPath, ExprQPath};
+use ast::{ExprMethodCall, ExprParen, ExprPath};
 use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
 use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
 use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
 use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
 use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
-use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
+use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, ItemDefaultImpl};
 use ast::{ItemExternCrate, ItemUse};
 use ast::{LifetimeDef, Lit, Lit_};
 use ast::{LitBool, LitChar, LitByte, LitBinary};
 use ast::{LitStr, LitInt, Local, LocalLet};
 use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces};
 use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchSource};
-use ast::{Method, MutTy, BiMul, Mutability};
-use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, NodeId, UnNot};
+use ast::{MutTy, BiMul, Mutability};
+use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot};
 use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct};
 use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle};
-use ast::{PolyTraitRef};
-use ast::{QPath, RequiredMethod};
+use ast::{PolyTraitRef, QSelf};
 use ast::{Return, BiShl, BiShr, Stmt, StmtDecl};
 use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
 use ast::{StructVariantKind, BiSub, StrStyle};
@@ -51,11 +50,10 @@ use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue};
 use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef};
 use ast::{TtDelimited, TtSequence, TtToken};
 use ast::{TupleVariantKind, Ty, Ty_, TypeBinding};
-use ast::{TyFixedLengthVec, TyBareFn};
-use ast::{TyTypeof, TyInfer, TypeMethod};
-use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath};
+use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer};
+use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr};
 use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
-use ast::{TypeImplItem, TypeTraitItem, Typedef,};
+use ast::{TypeImplItem, TypeTraitItem};
 use ast::{UnnamedField, UnsafeBlock};
 use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::{Visibility, WhereClause};
@@ -78,10 +76,9 @@ use ptr::P;
 use owned_slice::OwnedSlice;
 
 use std::collections::HashSet;
-use std::old_io::fs::PathExtensions;
-use std::iter;
+use std::io::prelude::*;
 use std::mem;
-use std::num::Float;
+use std::path::{Path, PathBuf};
 use std::rc::Rc;
 use std::slice;
 
@@ -99,7 +96,7 @@ type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
 
 /// How to parse a path. There are four different kinds of paths, all of which
 /// are parsed somewhat differently.
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum PathParsingMode {
     /// A path with no type parameters; e.g. `foo::bar::Baz`
     NoTypesAllowed,
@@ -112,17 +109,12 @@ pub enum PathParsingMode {
 }
 
 /// How to parse a bound, whether to allow bound modifiers such as `?`.
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum BoundParsingMode {
     Bare,
     Modified,
 }
 
-/// The `Err` case indicates a failure to parse any kind of item.
-/// The attributes are returned.
-type MaybeItem = Result<P<Item>, Vec<Attribute>>;
-
-
 /// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
 /// dropped into the token stream, which happens while parsing the result of
 /// macro expansion). Placement of these is not as complex as I feared it would
@@ -143,7 +135,7 @@ macro_rules! maybe_whole_expr {
                         _ => unreachable!()
                     };
                     let span = $p.span;
-                    Some($p.mk_expr(span.lo, span.hi, ExprPath(pt)))
+                    Some($p.mk_expr(span.lo, span.hi, ExprPath(None, pt)))
                 }
                 token::Interpolated(token::NtBlock(_)) => {
                     // FIXME: The following avoids an issue with lexical borrowck scopes,
@@ -209,7 +201,7 @@ macro_rules! maybe_whole {
             }
         }
     );
-    (Some $p:expr, $constructor:ident) => (
+    (Some deref $p:expr, $constructor:ident) => (
         {
             let found = match ($p).token {
                 token::Interpolated(token::$constructor(_)) => {
@@ -218,7 +210,7 @@ macro_rules! maybe_whole {
                 _ => None
             };
             if let Some(token::Interpolated(token::$constructor(x))) = found {
-                return Some(x.clone());
+                return Some((*x).clone());
             }
         }
     );
@@ -524,11 +516,7 @@ impl<'a> Parser<'a> {
 
     pub fn parse_path_list_item(&mut self) -> ast::PathListItem {
         let lo = self.span.lo;
-        let node = if self.eat_keyword_noexpect(keywords::Mod) {
-            let span = self.last_span;
-            self.span_warn(span, "deprecated syntax; use the `self` keyword now");
-            ast::PathListMod { id: ast::DUMMY_NODE_ID }
-        } else if self.eat_keyword(keywords::SelfValue) {
+        let node = if self.eat_keyword(keywords::SelfValue) {
             ast::PathListMod { id: ast::DUMMY_NODE_ID }
         } else {
             let ident = self.parse_ident();
@@ -627,23 +615,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Expect and consume a `|`. If `||` is seen, replace it with a single
-    /// `|` and continue. If a `|` is not seen, signal an error.
-    fn expect_or(&mut self) {
-        self.expected_tokens.push(TokenType::Token(token::BinOp(token::Or)));
-        match self.token {
-            token::BinOp(token::Or) => self.bump(),
-            token::OrOr => {
-                let span = self.span;
-                let lo = span.lo + BytePos(1);
-                self.replace_token(token::BinOp(token::Or), lo, span.hi)
-            }
-            _ => {
-                self.expect_one_of(&[], &[]);
-            }
-        }
-    }
-
     pub fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option<ast::Name>) {
         match suffix {
             None => {/* everything ok */}
@@ -683,28 +654,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
-    fn parse_seq_to_before_or<T, F>(&mut self,
-                                    sep: &token::Token,
-                                    mut f: F)
-                                    -> Vec<T> where
-        F: FnMut(&mut Parser) -> T,
-    {
-        let mut first = true;
-        let mut vector = Vec::new();
-        while self.token != token::BinOp(token::Or) &&
-                self.token != token::OrOr {
-            if first {
-                first = false
-            } else {
-                self.expect(sep)
-            }
-
-            vector.push(f(self))
-        }
-        vector
-    }
-
     /// Expect and consume a GT. if a >> is seen, replace it
     /// with a single > and continue. If a GT is not seen,
     /// signal an error.
@@ -750,7 +699,7 @@ impl<'a> Parser<'a> {
         // would encounter a `>` and stop. This lets the parser handle trailing
         // commas in generic parameters, because it can stop either after
         // parsing a type or after parsing a comma.
-        for i in iter::count(0, 1) {
+        for i in 0.. {
             if self.check(&token::Gt)
                 || self.token == token::BinOp(token::Shr)
                 || self.token == token::Ge
@@ -916,7 +865,7 @@ impl<'a> Parser<'a> {
         } else {
             // Avoid token copies with `replace`.
             let buffer_start = self.buffer_start as usize;
-            let next_index = (buffer_start + 1) & 3 as usize;
+            let next_index = (buffer_start + 1) & 3;
             self.buffer_start = next_index as isize;
 
             let placeholder = TokenAndSpan {
@@ -973,7 +922,7 @@ impl<'a> Parser<'a> {
     }
     pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> ! {
         self.span_err(sp, m);
-        self.span_help(sp, help);
+        self.fileline_help(sp, help);
         panic!(diagnostic::FatalError);
     }
     pub fn span_note(&self, sp: Span, m: &str) {
@@ -982,6 +931,9 @@ impl<'a> Parser<'a> {
     pub fn span_help(&self, sp: Span, m: &str) {
         self.sess.span_diagnostic.span_help(sp, m)
     }
+    pub fn fileline_help(&self, sp: Span, m: &str) {
+        self.sess.span_diagnostic.fileline_help(sp, m)
+    }
     pub fn bug(&self, m: &str) -> ! {
         self.sess.span_diagnostic.span_bug(self.span, m)
     }
@@ -1013,11 +965,6 @@ impl<'a> Parser<'a> {
             self.check_keyword(keywords::Extern)
     }
 
-    /// Is the current token one of the keywords that signals a closure type?
-    pub fn token_is_closure_keyword(&mut self) -> bool {
-        self.check_keyword(keywords::Unsafe)
-    }
-
     pub fn get_lifetime(&mut self) -> ast::Ident {
         match self.token {
             token::Lifetime(ref ident) => *ident,
@@ -1047,14 +994,9 @@ impl<'a> Parser<'a> {
         let lifetime_defs = self.parse_late_bound_lifetime_defs();
 
         // examine next token to decide to do
-        if self.eat_keyword_noexpect(keywords::Proc) {
-            self.parse_proc_type(lifetime_defs)
-        } else if self.token_is_bare_fn_keyword() || self.token_is_closure_keyword() {
-            self.parse_ty_bare_fn_or_ty_closure(lifetime_defs)
-        } else if self.check(&token::ModSep) ||
-                  self.token.is_ident() ||
-                  self.token.is_path()
-        {
+        if self.token_is_bare_fn_keyword() {
+            self.parse_ty_bare_fn(lifetime_defs)
+        } else {
             let hi = self.span.hi;
             let trait_ref = self.parse_trait_ref();
             let poly_trait_ref = ast::PolyTraitRef { bound_lifetimes: lifetime_defs,
@@ -1070,14 +1012,11 @@ impl<'a> Parser<'a> {
                 .chain(other_bounds.into_vec().into_iter())
                 .collect();
             ast::TyPolyTraitRef(all_bounds)
-        } else {
-            self.parse_ty_closure(lifetime_defs)
         }
     }
 
     pub fn parse_ty_path(&mut self) -> Ty_ {
-        let path = self.parse_path(LifetimeAndTypesWithoutColons);
-        TyPath(path, ast::DUMMY_NODE_ID)
+        TyPath(None, self.parse_path(LifetimeAndTypesWithoutColons))
     }
 
     /// parse a TyBareFn type:
@@ -1102,7 +1041,6 @@ impl<'a> Parser<'a> {
         };
 
         self.expect_keyword(keywords::Fn);
-        let lifetime_defs = self.parse_legacy_lifetime_defs(lifetime_defs);
         let (inputs, variadic) = self.parse_fn_args(false, true);
         let ret_ty = self.parse_ret_ty();
         let decl = P(FnDecl {
@@ -1118,35 +1056,6 @@ impl<'a> Parser<'a> {
         }))
     }
 
-    /// Parses a procedure type (`proc`). The initial `proc` keyword must
-    /// already have been parsed.
-    pub fn parse_proc_type(&mut self, lifetime_defs: Vec<ast::LifetimeDef>) -> Ty_ {
-        /*
-
-        proc <'lt> (S) [:Bounds] -> T
-        ^~~^ ^~~~^  ^  ^~~~~~~~^    ^
-         |     |    |      |        |
-         |     |    |      |      Return type
-         |     |    |    Bounds
-         |     |  Argument types
-         |   Legacy lifetimes
-        the `proc` keyword (already consumed)
-
-        */
-
-        let proc_span = self.last_span;
-
-        // To be helpful, parse the proc as ever
-        let _ = self.parse_legacy_lifetime_defs(lifetime_defs);
-        let _ = self.parse_fn_args(false, false);
-        let _ = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare);
-        let _ = self.parse_ret_ty();
-
-        self.obsolete(proc_span, ObsoleteSyntax::ProcType);
-
-        TyInfer
-    }
-
     /// Parses an obsolete closure kind (`&:`, `&mut:`, or `:`).
     pub fn parse_obsolete_closure_kind(&mut self) {
          let lo = self.span.lo;
@@ -1164,7 +1073,6 @@ impl<'a> Parser<'a> {
         {
             self.bump();
             self.bump();
-            return;
         } else if
             self.eat(&token::Colon)
         {
@@ -1177,71 +1085,6 @@ impl<'a> Parser<'a> {
          self.obsolete(span, ObsoleteSyntax::ClosureKind);
     }
 
-    pub fn parse_ty_bare_fn_or_ty_closure(&mut self, lifetime_defs: Vec<LifetimeDef>) -> Ty_ {
-        // Both bare fns and closures can begin with stuff like unsafe
-        // and extern. So we just scan ahead a few tokens to see if we see
-        // a `fn`.
-        //
-        // Closure:  [unsafe] <'lt> |S| [:Bounds] -> T
-        // Fn:       [unsafe] [extern "ABI"] fn <'lt> (S) -> T
-
-        if self.check_keyword(keywords::Fn) {
-            self.parse_ty_bare_fn(lifetime_defs)
-        } else if self.check_keyword(keywords::Extern) {
-            self.parse_ty_bare_fn(lifetime_defs)
-        } else if self.check_keyword(keywords::Unsafe) {
-            if self.look_ahead(1, |t| t.is_keyword(keywords::Fn) ||
-                                      t.is_keyword(keywords::Extern)) {
-                self.parse_ty_bare_fn(lifetime_defs)
-            } else {
-                self.parse_ty_closure(lifetime_defs)
-            }
-        } else {
-            self.parse_ty_closure(lifetime_defs)
-        }
-    }
-
-    /// Parse a TyClosure type
-    pub fn parse_ty_closure(&mut self, lifetime_defs: Vec<ast::LifetimeDef>) -> Ty_ {
-        /*
-
-        [unsafe] <'lt> |S| [:Bounds] -> T
-        ^~~~~~~^ ^~~~^  ^  ^~~~~~~~^    ^
-          |        |       |      |        |
-          |        |       |      |      Return type
-          |        |       |  Closure bounds
-          |        |     Argument types
-          |      Deprecated lifetime defs
-          |
-        Function Style
-
-        */
-
-        let ty_closure_span = self.last_span;
-
-        // To be helpful, parse the closure type as ever
-        let _ = self.parse_unsafety();
-
-        let _ = self.parse_legacy_lifetime_defs(lifetime_defs);
-
-        if !self.eat(&token::OrOr) {
-            self.expect_or();
-
-            let _ = self.parse_seq_to_before_or(
-                &token::Comma,
-                |p| p.parse_arg_general(false));
-            self.expect_or();
-        }
-
-        let _ = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare);
-
-        let _ = self.parse_ret_ty();
-
-        self.obsolete(ty_closure_span, ObsoleteSyntax::ClosureType);
-
-        TyInfer
-    }
-
     pub fn parse_unsafety(&mut self) -> Unsafety {
         if self.eat_keyword(keywords::Unsafe) {
             return Unsafety::Unsafe;
@@ -1250,75 +1093,21 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parses `[ 'for' '<' lifetime_defs '>' ]'
-    fn parse_legacy_lifetime_defs(&mut self,
-                                  lifetime_defs: Vec<ast::LifetimeDef>)
-                                  -> Vec<ast::LifetimeDef>
-    {
-        if self.token == token::Lt {
-            self.bump();
-            if lifetime_defs.is_empty() {
-                self.warn("deprecated syntax; use the `for` keyword now \
-                            (e.g. change `fn<'a>` to `for<'a> fn`)");
-                let lifetime_defs = self.parse_lifetime_defs();
-                self.expect_gt();
-                lifetime_defs
-            } else {
-                self.fatal("cannot use new `for` keyword and older syntax together");
-            }
-        } else {
-            lifetime_defs
-        }
-    }
-
-    /// Parses `type Foo;` in a trait declaration only. The `type` keyword has
-    /// already been parsed.
-    fn parse_associated_type(&mut self, attrs: Vec<Attribute>)
-                             -> AssociatedType
-    {
-        let ty_param = self.parse_ty_param();
-        self.expect(&token::Semi);
-        AssociatedType {
-            attrs: attrs,
-            ty_param: ty_param,
-        }
-    }
-
-    /// Parses `type Foo = TYPE;` in an implementation declaration only. The
-    /// `type` keyword has already been parsed.
-    fn parse_typedef(&mut self, attrs: Vec<Attribute>, vis: Visibility)
-                     -> Typedef {
-        let lo = self.span.lo;
-        let ident = self.parse_ident();
-        self.expect(&token::Eq);
-        let typ = self.parse_ty_sum();
-        let hi = self.span.hi;
-        self.expect(&token::Semi);
-        Typedef {
-            id: ast::DUMMY_NODE_ID,
-            span: mk_sp(lo, hi),
-            ident: ident,
-            vis: vis,
-            attrs: attrs,
-            typ: typ,
-        }
-    }
-
     /// Parse the items in a trait declaration
-    pub fn parse_trait_items(&mut self) -> Vec<TraitItem> {
+    pub fn parse_trait_items(&mut self) -> Vec<P<TraitItem>> {
         self.parse_unspanned_seq(
             &token::OpenDelim(token::Brace),
             &token::CloseDelim(token::Brace),
             seq_sep_none(),
             |p| {
-            let attrs = p.parse_outer_attributes();
+            let lo = p.span.lo;
+            let mut attrs = p.parse_outer_attributes();
 
-            if p.eat_keyword(keywords::Type) {
-                TypeTraitItem(P(p.parse_associated_type(attrs)))
+            let (name, node) = if p.eat_keyword(keywords::Type) {
+                let TyParam {ident, bounds, default, ..} = p.parse_ty_param();
+                p.expect(&token::Semi);
+                (ident, TypeTraitItem(bounds, default))
             } else {
-                let lo = p.span.lo;
-
-                let vis = p.parse_visibility();
                 let style = p.parse_unsafety();
                 let abi = if p.eat_keyword(keywords::Extern) {
                     p.parse_opt_abi().unwrap_or(abi::C)
@@ -1337,45 +1126,27 @@ impl<'a> Parser<'a> {
                     p.parse_arg_general(false)
                 });
 
-                p.parse_where_clause(&mut generics);
+                generics.where_clause = p.parse_where_clause();
+                let sig = ast::MethodSig {
+                    unsafety: style,
+                    decl: d,
+                    generics: generics,
+                    abi: abi,
+                    explicit_self: explicit_self,
+                };
 
-                let hi = p.last_span.hi;
-                match p.token {
+                let body = match p.token {
                   token::Semi => {
                     p.bump();
                     debug!("parse_trait_methods(): parsing required method");
-                    RequiredMethod(TypeMethod {
-                        ident: ident,
-                        attrs: attrs,
-                        unsafety: style,
-                        decl: d,
-                        generics: generics,
-                        abi: abi,
-                        explicit_self: explicit_self,
-                        id: ast::DUMMY_NODE_ID,
-                        span: mk_sp(lo, hi),
-                        vis: vis,
-                    })
+                    None
                   }
                   token::OpenDelim(token::Brace) => {
                     debug!("parse_trait_methods(): parsing provided method");
                     let (inner_attrs, body) =
                         p.parse_inner_attrs_and_block();
-                    let mut attrs = attrs;
                     attrs.push_all(&inner_attrs[..]);
-                    ProvidedMethod(P(ast::Method {
-                        attrs: attrs,
-                        id: ast::DUMMY_NODE_ID,
-                        span: mk_sp(lo, hi),
-                        node: ast::MethDecl(ident,
-                                            generics,
-                                            abi,
-                                            explicit_self,
-                                            style,
-                                            d,
-                                            body,
-                                            vis)
-                    }))
+                    Some(body)
                   }
 
                   _ => {
@@ -1383,8 +1154,17 @@ impl<'a> Parser<'a> {
                       p.fatal(&format!("expected `;` or `{{`, found `{}`",
                                        token_str)[..])
                   }
-                }
-            }
+                };
+                (ident, ast::MethodTraitItem(sig, body))
+            };
+
+            P(TraitItem {
+                id: ast::DUMMY_NODE_ID,
+                ident: name,
+                attrs: attrs,
+                node: node,
+                span: mk_sp(lo, p.last_span.hi),
+            })
         })
     }
 
@@ -1401,19 +1181,7 @@ impl<'a> Parser<'a> {
             if self.eat(&token::Not) {
                 NoReturn(self.span)
             } else {
-                let t = self.parse_ty();
-
-                // We used to allow `fn foo() -> &T + U`, but don't
-                // anymore. If we see it, report a useful error.  This
-                // only makes sense because `parse_ret_ty` is only
-                // used in fn *declarations*, not fn types or where
-                // clauses (i.e., not when parsing something like
-                // `FnMut() -> T + Send`, where the `+` is legal).
-                if self.token == token::BinOp(token::Plus) {
-                    self.warn("deprecated syntax: `()` are required, see RFC 438 for details");
-                }
-
-                Return(t)
+                Return(self.parse_ty())
             }
         } else {
             let pos = self.span.lo;
@@ -1501,18 +1269,9 @@ impl<'a> Parser<'a> {
             self.parse_borrowed_pointee()
         } else if self.check_keyword(keywords::For) {
             self.parse_for_in_type()
-        } else if self.token_is_bare_fn_keyword() ||
-                  self.token_is_closure_keyword() {
-            // BARE FUNCTION OR CLOSURE
-            self.parse_ty_bare_fn_or_ty_closure(Vec::new())
-        } else if self.check(&token::BinOp(token::Or)) ||
-                  self.token == token::OrOr ||
-                  (self.token == token::Lt &&
-                   self.look_ahead(1, |t| {
-                       *t == token::Gt || t.is_lifetime()
-                   })) {
-            // CLOSURE
-            self.parse_ty_closure(Vec::new())
+        } else if self.token_is_bare_fn_keyword() {
+            // BARE FUNCTION
+            self.parse_ty_bare_fn(Vec::new())
         } else if self.eat_keyword_noexpect(keywords::Typeof) {
             // TYPEOF
             // In order to not be ambiguous, the type must be surrounded by parens.
@@ -1520,24 +1279,39 @@ impl<'a> Parser<'a> {
             let e = self.parse_expr();
             self.expect(&token::CloseDelim(token::Paren));
             TyTypeof(e)
-        } else if self.eat_keyword_noexpect(keywords::Proc) {
-            self.parse_proc_type(Vec::new())
         } else if self.eat_lt() {
             // QUALIFIED PATH `<TYPE as TRAIT_REF>::item`
             let self_type = self.parse_ty_sum();
-            self.expect_keyword(keywords::As);
-            let trait_ref = self.parse_trait_ref();
+
+            let mut path = if self.eat_keyword(keywords::As) {
+                self.parse_path(LifetimeAndTypesWithoutColons)
+            } else {
+                ast::Path {
+                    span: self.span,
+                    global: false,
+                    segments: vec![]
+                }
+            };
+
+            let qself = QSelf {
+                ty: self_type,
+                position: path.segments.len()
+            };
+
             self.expect(&token::Gt);
             self.expect(&token::ModSep);
-            let item_name = self.parse_ident();
-            TyQPath(P(QPath {
-                self_type: self_type,
-                trait_ref: P(trait_ref),
-                item_path: ast::PathSegment {
-                    identifier: item_name,
-                    parameters: ast::PathParameters::none()
-                }
-            }))
+
+            path.segments.push(ast::PathSegment {
+                identifier: self.parse_ident(),
+                parameters: ast::PathParameters::none()
+            });
+
+            if path.segments.len() == 1 {
+                path.span.lo = self.last_span.lo;
+            }
+            path.span.hi = self.last_span.hi;
+
+            TyPath(Some(qself), path)
         } else if self.check(&token::ModSep) ||
                   self.token.is_ident() ||
                   self.token.is_path() {
@@ -2164,10 +1938,7 @@ impl<'a> Parser<'a> {
                 }
             },
             token::OpenDelim(token::Brace) => {
-                self.bump();
-                let blk = self.parse_block_tail(lo, DefaultBlock);
-                return self.mk_expr(blk.span.lo, blk.span.hi,
-                                    ExprBlock(blk));
+                return self.parse_block_expr(lo, DefaultBlock);
             },
             token::BinOp(token::Or) |  token::OrOr => {
                 return self.parse_lambda_expr(CaptureByRef);
@@ -2178,7 +1949,7 @@ impl<'a> Parser<'a> {
                          }, token::Plain) => {
                 self.bump();
                 let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
-                ex = ExprPath(path);
+                ex = ExprPath(None, path);
                 hi = self.last_span.hi;
             }
             token::OpenDelim(token::Bracket) => {
@@ -2220,10 +1991,22 @@ impl<'a> Parser<'a> {
                 if self.eat_lt() {
                     // QUALIFIED PATH `<TYPE as TRAIT_REF>::item::<'a, T>`
                     let self_type = self.parse_ty_sum();
-                    self.expect_keyword(keywords::As);
-                    let trait_ref = self.parse_trait_ref();
+                    let mut path = if self.eat_keyword(keywords::As) {
+                        self.parse_path(LifetimeAndTypesWithoutColons)
+                    } else {
+                        ast::Path {
+                            span: self.span,
+                            global: false,
+                            segments: vec![]
+                        }
+                    };
+                    let qself = QSelf {
+                        ty: self_type,
+                        position: path.segments.len()
+                    };
                     self.expect(&token::Gt);
                     self.expect(&token::ModSep);
+
                     let item_name = self.parse_ident();
                     let parameters = if self.eat(&token::ModSep) {
                         self.expect_lt();
@@ -2238,25 +2021,22 @@ impl<'a> Parser<'a> {
                     } else {
                         ast::PathParameters::none()
                     };
+                    path.segments.push(ast::PathSegment {
+                        identifier: item_name,
+                        parameters: parameters
+                    });
+
+                    if path.segments.len() == 1 {
+                        path.span.lo = self.last_span.lo;
+                    }
+                    path.span.hi = self.last_span.hi;
+
                     let hi = self.span.hi;
-                    return self.mk_expr(lo, hi, ExprQPath(P(QPath {
-                        self_type: self_type,
-                        trait_ref: P(trait_ref),
-                        item_path: ast::PathSegment {
-                            identifier: item_name,
-                            parameters: parameters
-                        }
-                    })));
+                    return self.mk_expr(lo, hi, ExprPath(Some(qself), path));
                 }
                 if self.eat_keyword(keywords::Move) {
                     return self.parse_lambda_expr(CaptureByValue);
                 }
-                if self.eat_keyword_noexpect(keywords::Proc) {
-                    let span = self.last_span;
-                    let _ = self.parse_proc_decl();
-                    let _ = self.parse_expr();
-                    return self.obsolete_expr(span, ObsoleteSyntax::ProcExpr);
-                }
                 if self.eat_keyword(keywords::If) {
                     return self.parse_if_expr();
                 }
@@ -2386,7 +2166,7 @@ impl<'a> Parser<'a> {
                     }
 
                     hi = pth.span.hi;
-                    ex = ExprPath(pth);
+                    ex = ExprPath(None, pth);
                 } else {
                     // other literal expression
                     let lit = self.parse_lit();
@@ -2496,12 +2276,12 @@ impl<'a> Parser<'a> {
                     let fstr = n.as_str();
                     self.span_err(last_span,
                                   &format!("unexpected token: `{}`", n.as_str()));
-                    if fstr.chars().all(|x| "0123456789.".contains_char(x)) {
+                    if fstr.chars().all(|x| "0123456789.".contains(x)) {
                         let float = match fstr.parse::<f64>().ok() {
                             Some(f) => f,
                             None => continue,
                         };
-                        self.span_help(last_span,
+                        self.fileline_help(last_span,
                             &format!("try parenthesizing the first index; e.g., `(foo.{}){}`",
                                     float.trunc() as usize,
                                     &float.fract().to_string()[1..]));
@@ -2532,45 +2312,13 @@ impl<'a> Parser<'a> {
               // expr[...]
               // Could be either an index expression or a slicing expression.
               token::OpenDelim(token::Bracket) => {
-                let bracket_pos = self.span.lo;
                 self.bump();
 
-                if self.eat(&token::CloseDelim(token::Bracket)) {
-                    // No expression, expand to a RangeFull
-                    // FIXME(#20516) It would be better to use a lang item or
-                    // something for RangeFull.
-                    hi = self.last_span.hi;
-
-                    let idents = vec![token::str_to_ident("std"),
-                                      token::str_to_ident("ops"),
-                                      token::str_to_ident("RangeFull")];
-                    let segments = idents.into_iter().map(|ident| {
-                        ast::PathSegment {
-                            identifier: ident,
-                            parameters: ast::PathParameters::none(),
-                        }
-                    }).collect();
-                    let span = mk_sp(lo, hi);
-                    let path = ast::Path {
-                        span: span,
-                        global: true,
-                        segments: segments,
-                    };
-
-                    let range = ExprStruct(path, vec![], None);
-                    let ix = self.mk_expr(bracket_pos, hi, range);
-                    let index = self.mk_index(e, ix);
-                    e = self.mk_expr(lo, hi, index);
-
-                    self.obsolete(span, ObsoleteSyntax::EmptyIndex);
-                } else {
-                    let ix = self.parse_expr();
-                    hi = self.span.hi;
-                    self.commit_expr_expecting(&*ix, token::CloseDelim(token::Bracket));
-                    let index = self.mk_index(e, ix);
-                    e = self.mk_expr(lo, hi, index)
-                }
-
+                let ix = self.parse_expr();
+                hi = self.span.hi;
+                self.commit_expr_expecting(&*ix, token::CloseDelim(token::Bracket));
+                let index = self.mk_index(e, ix);
+                e = self.mk_expr(lo, hi, index)
               }
               _ => return e
             }
@@ -2911,7 +2659,7 @@ impl<'a> Parser<'a> {
                 self.span_err(op_span,
                     "chained comparison operators require parentheses");
                 if op.node == BiLt && outer_op == BiGt {
-                    self.span_help(op_span,
+                    self.fileline_help(op_span,
                         "use `::<...>` instead of `<...>` if you meant to specify type arguments");
                 }
             }
@@ -3053,19 +2801,30 @@ impl<'a> Parser<'a> {
     {
         let lo = self.span.lo;
         let decl = self.parse_fn_block_decl();
-        let body = self.parse_expr();
-        let fakeblock = P(ast::Block {
-            id: ast::DUMMY_NODE_ID,
-            stmts: vec![],
-            span: body.span,
-            expr: Some(body),
-            rules: DefaultBlock,
-        });
+        let body = match decl.output {
+            DefaultReturn(_) => {
+                // If no explicit return type is given, parse any
+                // expr and wrap it up in a dummy block:
+                let body_expr = self.parse_expr();
+                P(ast::Block {
+                    id: ast::DUMMY_NODE_ID,
+                    stmts: vec![],
+                    span: body_expr.span,
+                    expr: Some(body_expr),
+                    rules: DefaultBlock,
+                })
+            }
+            _ => {
+                // If an explicit return type is given, require a
+                // block to appear (RFC 968).
+                self.parse_block()
+            }
+        };
 
         self.mk_expr(
             lo,
-            fakeblock.span.hi,
-            ExprClosure(capture_clause, decl, fakeblock))
+            body.span.hi,
+            ExprClosure(capture_clause, decl, body))
     }
 
     pub fn parse_else_expr(&mut self) -> P<Expr> {
@@ -3427,7 +3186,7 @@ impl<'a> Parser<'a> {
                 let end = if self.token.is_ident() || self.token.is_path() {
                     let path = self.parse_path(LifetimeAndTypesWithColons);
                     let hi = self.span.hi;
-                    self.mk_expr(lo, hi, ExprPath(path))
+                    self.mk_expr(lo, hi, ExprPath(None, path))
                 } else {
                     self.parse_literal_maybe_minus()
                 };
@@ -3493,6 +3252,9 @@ impl<'a> Parser<'a> {
                     };
                     pat = PatIdent(BindByValue(MutImmutable), pth1, sub);
                 }
+            } else if self.look_ahead(1, |t| *t == token::Lt) {
+                self.bump();
+                self.unexpected()
             } else {
                 // parse an enum pat
                 let enum_path = self.parse_path(LifetimeAndTypesWithColons);
@@ -3504,6 +3266,19 @@ impl<'a> Parser<'a> {
                         self.bump();
                         pat = PatStruct(enum_path, fields, etc);
                     }
+                    token::DotDotDot => {
+                        let hi = self.last_span.hi;
+                        let start = self.mk_expr(lo, hi, ExprPath(None, enum_path));
+                        self.eat(&token::DotDotDot);
+                        let end = if self.token.is_ident() || self.token.is_path() {
+                            let path = self.parse_path(LifetimeAndTypesWithColons);
+                            let hi = self.span.hi;
+                            self.mk_expr(lo, hi, ExprPath(None, path))
+                        } else {
+                            self.parse_literal_maybe_minus()
+                        };
+                        pat = PatRange(start, end);
+                    }
                     _ => {
                         let mut args: Vec<P<Pat>> = Vec::new();
                         match self.token {
@@ -3645,41 +3420,47 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Get an expected item after attributes error message.
-    fn expected_item_err(attrs: &[Attribute]) -> &'static str {
-        match attrs.last() {
+    /// Emit an expected item after attributes error.
+    fn expected_item_err(&self, attrs: &[Attribute]) {
+        let message = match attrs.last() {
             Some(&Attribute { node: ast::Attribute_ { is_sugared_doc: true, .. }, .. }) => {
                 "expected item after doc comment"
             }
             _ => "expected item after attributes",
-        }
+        };
+
+        self.span_err(self.last_span, message);
     }
 
     /// Parse a statement. may include decl.
-    /// Precondition: any attributes are parsed already
-    pub fn parse_stmt(&mut self, item_attrs: Vec<Attribute>) -> P<Stmt> {
-        maybe_whole!(self, NtStmt);
+    pub fn parse_stmt(&mut self) -> Option<P<Stmt>> {
+        self.parse_stmt_().map(P)
+    }
+
+    fn parse_stmt_(&mut self) -> Option<Stmt> {
+        maybe_whole!(Some deref self, NtStmt);
 
         fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
             // If we have attributes then we should have an item
             if !attrs.is_empty() {
-                let last_span = p.last_span;
-                p.span_err(last_span, Parser::expected_item_err(attrs));
+                p.expected_item_err(attrs);
             }
         }
 
         let lo = self.span.lo;
-        if self.check_keyword(keywords::Let) {
-            check_expected_item(self, &item_attrs[..]);
+        let attrs = self.parse_outer_attributes();
+
+        Some(if self.check_keyword(keywords::Let) {
+            check_expected_item(self, &attrs);
             self.expect_keyword(keywords::Let);
             let decl = self.parse_let();
-            P(spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
+            spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID))
         } else if self.token.is_ident()
             && !self.token.is_any_keyword()
             && self.look_ahead(1, |t| *t == token::Not) {
             // it's a macro invocation:
 
-            check_expected_item(self, &item_attrs[..]);
+            check_expected_item(self, &attrs);
 
             // Potential trouble: if we allow macros with paths instead of
             // idents, we'd need to look ahead past the whole path here...
@@ -3726,12 +3507,11 @@ impl<'a> Parser<'a> {
             };
 
             if id.name == token::special_idents::invalid.name {
-                P(spanned(lo,
-                          hi,
-                          StmtMac(P(spanned(lo,
+                spanned(lo, hi,
+                        StmtMac(P(spanned(lo,
                                           hi,
                                           MacInvocTT(pth, tts, EMPTY_CTXT))),
-                                  style)))
+                                  style))
             } else {
                 // if it has a special ident, it's definitely an item
                 //
@@ -3745,35 +3525,38 @@ impl<'a> Parser<'a> {
                                        followed by a semicolon");
                     }
                 }
-                P(spanned(lo, hi, StmtDecl(
+                spanned(lo, hi, StmtDecl(
                     P(spanned(lo, hi, DeclItem(
                         self.mk_item(
                             lo, hi, id /*id is good here*/,
                             ItemMac(spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT))),
                             Inherited, Vec::new(/*no attrs*/))))),
-                    ast::DUMMY_NODE_ID)))
+                    ast::DUMMY_NODE_ID))
             }
         } else {
-            let found_attrs = !item_attrs.is_empty();
-            let item_err = Parser::expected_item_err(&item_attrs[..]);
-            match self.parse_item_(item_attrs, false) {
-                Ok(i) => {
+            match self.parse_item_(attrs, false) {
+                Some(i) => {
                     let hi = i.span.hi;
                     let decl = P(spanned(lo, hi, DeclItem(i)));
-                    P(spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
+                    spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID))
                 }
-                Err(_) => {
-                    if found_attrs {
-                        let last_span = self.last_span;
-                        self.span_err(last_span, item_err);
+                None => {
+                    // Do not attempt to parse an expression if we're done here.
+                    if self.token == token::Semi {
+                        self.bump();
+                        return None;
+                    }
+
+                    if self.token == token::CloseDelim(token::Brace) {
+                        return None;
                     }
 
                     // Remainder are line-expr stmts.
                     let e = self.parse_expr_res(RESTRICTION_STMT_EXPR);
-                    P(spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID)))
+                    spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID))
                 }
             }
-        }
+        })
     }
 
     /// Is this expression a successfully-parsed statement?
@@ -3796,153 +3579,110 @@ impl<'a> Parser<'a> {
                                  "place this code inside a block");
         }
 
-        return self.parse_block_tail_(lo, DefaultBlock, Vec::new());
+        self.parse_block_tail(lo, DefaultBlock)
     }
 
     /// Parse a block. Inner attrs are allowed.
-    fn parse_inner_attrs_and_block(&mut self)
-        -> (Vec<Attribute> , P<Block>) {
-
+    fn parse_inner_attrs_and_block(&mut self) -> (Vec<Attribute>, P<Block>) {
         maybe_whole!(pair_empty self, NtBlock);
 
         let lo = self.span.lo;
         self.expect(&token::OpenDelim(token::Brace));
-        let (inner, next) = self.parse_inner_attrs_and_next();
-
-        (inner, self.parse_block_tail_(lo, DefaultBlock, next))
+        (self.parse_inner_attributes(),
+         self.parse_block_tail(lo, DefaultBlock))
     }
 
+    /// Parse the rest of a block expression or function body
     /// Precondition: already parsed the '{'.
     fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
-        self.parse_block_tail_(lo, s, Vec::new())
-    }
-
-    /// Parse the rest of a block expression or function body
-    fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
-                         first_item_attrs: Vec<Attribute>) -> P<Block> {
         let mut stmts = vec![];
         let mut expr = None;
-        let mut attributes_box = first_item_attrs;
 
-        while self.token != token::CloseDelim(token::Brace) {
-            // parsing items even when they're not allowed lets us give
-            // better error messages and recover more gracefully.
-            attributes_box.push_all(&self.parse_outer_attributes());
-            match self.token {
-                token::Semi => {
-                    if !attributes_box.is_empty() {
-                        let last_span = self.last_span;
-                        self.span_err(last_span,
-                                      Parser::expected_item_err(&attributes_box[..]));
-                        attributes_box = Vec::new();
-                    }
-                    self.bump(); // empty
-                }
-                token::CloseDelim(token::Brace) => {
-                    // fall through and out.
+        while !self.eat(&token::CloseDelim(token::Brace)) {
+            let Spanned {node, span} = if let Some(s) = self.parse_stmt_() {
+                s
+            } else {
+                // Found only `;` or `}`.
+                continue;
+            };
+            match node {
+                StmtExpr(e, _) => {
+                    self.handle_expression_like_statement(e, span, &mut stmts, &mut expr);
                 }
-                _ => {
-                    let stmt = self.parse_stmt(attributes_box);
-                    attributes_box = Vec::new();
-                    stmt.and_then(|Spanned {node, span}| match node {
-                        StmtExpr(e, stmt_id) => {
-                            self.handle_expression_like_statement(e,
-                                                                  stmt_id,
-                                                                  span,
-                                                                  &mut stmts,
-                                                                  &mut expr);
+                StmtMac(mac, MacStmtWithoutBraces) => {
+                    // statement macro without braces; might be an
+                    // expr depending on whether a semicolon follows
+                    match self.token {
+                        token::Semi => {
+                            stmts.push(P(Spanned {
+                                node: StmtMac(mac, MacStmtWithSemicolon),
+                                span: span,
+                            }));
+                            self.bump();
                         }
-                        StmtMac(mac, MacStmtWithoutBraces) => {
-                            // statement macro without braces; might be an
-                            // expr depending on whether a semicolon follows
-                            match self.token {
-                                token::Semi => {
-                                    stmts.push(P(Spanned {
-                                        node: StmtMac(mac,
-                                                      MacStmtWithSemicolon),
-                                        span: span,
-                                    }));
-                                    self.bump();
-                                }
-                                _ => {
-                                    let e = self.mk_mac_expr(span.lo,
-                                                             span.hi,
-                                                             mac.and_then(|m| m.node));
-                                    let e = self.parse_dot_or_call_expr_with(e);
-                                    let e = self.parse_more_binops(e, 0);
-                                    let e = self.parse_assign_expr_with(e);
-                                    self.handle_expression_like_statement(
-                                        e,
-                                        ast::DUMMY_NODE_ID,
-                                        span,
-                                        &mut stmts,
-                                        &mut expr);
-                                }
-                            }
+                        _ => {
+                            let e = self.mk_mac_expr(span.lo, span.hi,
+                                                     mac.and_then(|m| m.node));
+                            let e = self.parse_dot_or_call_expr_with(e);
+                            let e = self.parse_more_binops(e, 0);
+                            let e = self.parse_assign_expr_with(e);
+                            self.handle_expression_like_statement(
+                                e,
+                                span,
+                                &mut stmts,
+                                &mut expr);
                         }
-                        StmtMac(m, style) => {
-                            // statement macro; might be an expr
-                            match self.token {
-                                token::Semi => {
-                                    stmts.push(P(Spanned {
-                                        node: StmtMac(m,
-                                                      MacStmtWithSemicolon),
-                                        span: span,
-                                    }));
-                                    self.bump();
-                                }
-                                token::CloseDelim(token::Brace) => {
-                                    // if a block ends in `m!(arg)` without
-                                    // a `;`, it must be an expr
-                                    expr = Some(
-                                        self.mk_mac_expr(span.lo,
-                                                         span.hi,
+                    }
+                }
+                StmtMac(m, style) => {
+                    // statement macro; might be an expr
+                    match self.token {
+                        token::Semi => {
+                            stmts.push(P(Spanned {
+                                node: StmtMac(m, MacStmtWithSemicolon),
+                                span: span,
+                            }));
+                            self.bump();
+                        }
+                        token::CloseDelim(token::Brace) => {
+                            // if a block ends in `m!(arg)` without
+                            // a `;`, it must be an expr
+                            expr = Some(self.mk_mac_expr(span.lo, span.hi,
                                                          m.and_then(|x| x.node)));
-                                }
-                                _ => {
-                                    stmts.push(P(Spanned {
-                                        node: StmtMac(m, style),
-                                        span: span
-                                    }));
-                                }
-                            }
                         }
-                        _ => { // all other kinds of statements:
-                            if classify::stmt_ends_with_semi(&node) {
-                                self.commit_stmt_expecting(token::Semi);
-                            }
-
+                        _ => {
                             stmts.push(P(Spanned {
-                                node: node,
+                                node: StmtMac(m, style),
                                 span: span
                             }));
                         }
-                    })
+                    }
                 }
-            }
-        }
+                _ => { // all other kinds of statements:
+                    if classify::stmt_ends_with_semi(&node) {
+                        self.commit_stmt_expecting(token::Semi);
+                    }
 
-        if !attributes_box.is_empty() {
-            let last_span = self.last_span;
-            self.span_err(last_span,
-                          Parser::expected_item_err(&attributes_box[..]));
+                    stmts.push(P(Spanned {
+                        node: node,
+                        span: span
+                    }));
+                }
+            }
         }
 
-        let hi = self.span.hi;
-        self.bump();
         P(ast::Block {
             stmts: stmts,
             expr: expr,
             id: ast::DUMMY_NODE_ID,
             rules: s,
-            span: mk_sp(lo, hi),
+            span: mk_sp(lo, self.last_span.hi),
         })
     }
 
     fn handle_expression_like_statement(
             &mut self,
             e: P<Expr>,
-            stmt_id: NodeId,
             span: Span,
             stmts: &mut Vec<P<Stmt>>,
             last_block_expr: &mut Option<P<Expr>>) {
@@ -3962,14 +3702,14 @@ impl<'a> Parser<'a> {
                     expn_id: span.expn_id,
                 };
                 stmts.push(P(Spanned {
-                    node: StmtSemi(e, stmt_id),
+                    node: StmtSemi(e, ast::DUMMY_NODE_ID),
                     span: span_with_semi,
                 }));
             }
             token::CloseDelim(token::Brace) => *last_block_expr = Some(e),
             _ => {
                 stmts.push(P(Spanned {
-                    node: StmtExpr(e, stmt_id),
+                    node: StmtExpr(e, ast::DUMMY_NODE_ID),
                     span: span
                 }));
             }
@@ -4040,56 +3780,19 @@ impl<'a> Parser<'a> {
         return OwnedSlice::from_vec(result);
     }
 
-    fn trait_ref_from_ident(ident: Ident, span: Span) -> TraitRef {
-        let segment = ast::PathSegment {
-            identifier: ident,
-            parameters: ast::PathParameters::none()
-        };
-        let path = ast::Path {
-            span: span,
-            global: false,
-            segments: vec![segment],
-        };
-        ast::TraitRef {
-            path: path,
-            ref_id: ast::DUMMY_NODE_ID,
-        }
-    }
-
-    /// Matches typaram = (unbound `?`)? IDENT (`?` unbound)? optbounds ( EQ ty )?
+    /// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?
     fn parse_ty_param(&mut self) -> TyParam {
-        // This is a bit hacky. Currently we are only interested in a single
-        // unbound, and it may only be `Sized`. To avoid backtracking and other
-        // complications, we parse an ident, then check for `?`. If we find it,
-        // we use the ident as the unbound, otherwise, we use it as the name of
-        // type param. Even worse, we need to check for `?` before or after the
-        // bound.
-        let mut span = self.span;
-        let mut ident = self.parse_ident();
-        let mut unbound = None;
-        if self.eat(&token::Question) {
-            let tref = Parser::trait_ref_from_ident(ident, span);
-            unbound = Some(tref);
-            span = self.span;
-            ident = self.parse_ident();
-            self.obsolete(span, ObsoleteSyntax::Sized);
-        }
+        let span = self.span;
+        let ident = self.parse_ident();
 
-        let mut bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Modified);
-        if let Some(unbound) = unbound {
-            let mut bounds_as_vec = bounds.into_vec();
-            bounds_as_vec.push(TraitTyParamBound(PolyTraitRef { bound_lifetimes: vec![],
-                                                                trait_ref: unbound,
-                                                                span: span },
-                                                 TraitBoundModifier::Maybe));
-            bounds = OwnedSlice::from_vec(bounds_as_vec);
-        };
+        let bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Modified);
 
         let default = if self.check(&token::Eq) {
             self.bump();
             Some(self.parse_ty_sum())
-        }
-        else { None };
+        } else {
+            None
+        };
 
         TyParam {
             ident: ident,
@@ -4196,9 +3899,14 @@ impl<'a> Parser<'a> {
     /// ```
     /// where T : Trait<U, V> + 'b, 'a : 'b
     /// ```
-    fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
+    fn parse_where_clause(&mut self) -> ast::WhereClause {
+        let mut where_clause = WhereClause {
+            id: ast::DUMMY_NODE_ID,
+            predicates: Vec::new(),
+        };
+
         if !self.eat_keyword(keywords::Where) {
-            return
+            return where_clause;
         }
 
         let mut parsed_something = false;
@@ -4221,7 +3929,7 @@ impl<'a> Parser<'a> {
                     let hi = self.span.hi;
                     let span = mk_sp(lo, hi);
 
-                    generics.where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
+                    where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
                         ast::WhereRegionPredicate {
                             span: span,
                             lifetime: bounded_lifetime,
@@ -4256,7 +3964,7 @@ impl<'a> Parser<'a> {
                                            at least one bound in it");
                         }
 
-                        generics.where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
+                        where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
                                 ast::WhereBoundPredicate {
                                     span: span,
                                     bound_lifetimes: bound_lifetimes,
@@ -4269,7 +3977,7 @@ impl<'a> Parser<'a> {
                         // let ty = self.parse_ty();
                         let hi = self.span.hi;
                         let span = mk_sp(lo, hi);
-                        // generics.where_clause.predicates.push(
+                        // where_clause.predicates.push(
                         //     ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
                         //         id: ast::DUMMY_NODE_ID,
                         //         span: span,
@@ -4300,6 +4008,8 @@ impl<'a> Parser<'a> {
                           "a `where` clause must have at least one predicate \
                            in it");
         }
+
+        where_clause
     }
 
     fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
@@ -4594,23 +4304,6 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Parses the `(arg, arg) -> return_type` header on a procedure.
-    fn parse_proc_decl(&mut self) -> P<FnDecl> {
-        let inputs =
-            self.parse_unspanned_seq(&token::OpenDelim(token::Paren),
-                                     &token::CloseDelim(token::Paren),
-                                     seq_sep_trailing_allowed(token::Comma),
-                                     |p| p.parse_fn_block_arg());
-
-        let output = self.parse_ret_ty();
-
-        P(FnDecl {
-            inputs: inputs,
-            output: output,
-            variadic: false
-        })
-    }
-
     /// Parse the name and optional generic types of a function header.
     fn parse_fn_header(&mut self) -> (Ident, ast::Generics) {
         let id = self.parse_ident();
@@ -4635,98 +4328,101 @@ impl<'a> Parser<'a> {
     fn parse_item_fn(&mut self, unsafety: Unsafety, abi: abi::Abi) -> ItemInfo {
         let (ident, mut generics) = self.parse_fn_header();
         let decl = self.parse_fn_decl(false);
-        self.parse_where_clause(&mut generics);
+        generics.where_clause = self.parse_where_clause();
         let (inner_attrs, body) = self.parse_inner_attrs_and_block();
         (ident, ItemFn(decl, unsafety, abi, generics, body), Some(inner_attrs))
     }
 
-    /// Parse a method in a trait impl
-    pub fn parse_method_with_outer_attributes(&mut self) -> P<Method> {
-        let attrs = self.parse_outer_attributes();
-        let visa = self.parse_visibility();
-        self.parse_method(attrs, visa)
+    /// Parse an impl item.
+    pub fn parse_impl_item(&mut self) -> P<ImplItem> {
+        let lo = self.span.lo;
+        let mut attrs = self.parse_outer_attributes();
+        let vis = self.parse_visibility();
+        let (name, node) = if self.eat_keyword(keywords::Type) {
+            let name = self.parse_ident();
+            self.expect(&token::Eq);
+            let typ = self.parse_ty_sum();
+            self.expect(&token::Semi);
+            (name, TypeImplItem(typ))
+        } else {
+            let (name, inner_attrs, node) = self.parse_impl_method(vis);
+            attrs.extend(inner_attrs.into_iter());
+            (name, node)
+        };
+
+        P(ImplItem {
+            id: ast::DUMMY_NODE_ID,
+            span: mk_sp(lo, self.last_span.hi),
+            ident: name,
+            vis: vis,
+            attrs: attrs,
+            node: node
+        })
     }
 
     fn complain_if_pub_macro(&mut self, visa: Visibility, span: Span) {
         match visa {
             Public => {
                 self.span_err(span, "can't qualify macro invocation with `pub`");
-                self.span_help(span, "try adjusting the macro to put `pub` inside \
+                self.fileline_help(span, "try adjusting the macro to put `pub` inside \
                                       the invocation");
             }
             Inherited => (),
         }
     }
 
-    /// Parse a method in a trait impl, starting with `attrs` attributes.
-    pub fn parse_method(&mut self,
-                        attrs: Vec<Attribute>,
-                        visa: Visibility)
-                        -> P<Method> {
-        let lo = self.span.lo;
-
+    /// Parse a method or a macro invocation in a trait impl.
+    fn parse_impl_method(&mut self, vis: Visibility)
+                         -> (Ident, Vec<ast::Attribute>, ast::ImplItem_) {
         // code copied from parse_macro_use_or_failure... abstraction!
-        let (method_, hi, new_attrs) = {
-            if !self.token.is_any_keyword()
-                && self.look_ahead(1, |t| *t == token::Not)
-                && (self.look_ahead(2, |t| *t == token::OpenDelim(token::Paren))
-                    || self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))) {
-                // method macro.
+        if !self.token.is_any_keyword()
+            && self.look_ahead(1, |t| *t == token::Not)
+            && (self.look_ahead(2, |t| *t == token::OpenDelim(token::Paren))
+                || self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))) {
+            // method macro.
 
-                let last_span = self.last_span;
-                self.complain_if_pub_macro(visa, last_span);
-
-                let pth = self.parse_path(NoTypesAllowed);
-                self.expect(&token::Not);
-
-                // eat a matched-delimiter token tree:
-                let delim = self.expect_open_delim();
-                let tts = self.parse_seq_to_end(&token::CloseDelim(delim),
-                                                seq_sep_none(),
-                                                |p| p.parse_token_tree());
-                let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
-                let m: ast::Mac = codemap::Spanned { node: m_,
-                                                 span: mk_sp(self.span.lo,
-                                                             self.span.hi) };
-                if delim != token::Brace {
-                    self.expect(&token::Semi)
-                }
-                (ast::MethMac(m), self.span.hi, attrs)
-            } else {
-                let unsafety = self.parse_unsafety();
-                let abi = if self.eat_keyword(keywords::Extern) {
-                    self.parse_opt_abi().unwrap_or(abi::C)
-                } else {
-                    abi::Rust
-                };
-                self.expect_keyword(keywords::Fn);
-                let ident = self.parse_ident();
-                let mut generics = self.parse_generics();
-                let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
-                        p.parse_arg()
-                    });
-                self.parse_where_clause(&mut generics);
-                let (inner_attrs, body) = self.parse_inner_attrs_and_block();
-                let body_span = body.span;
-                let mut new_attrs = attrs;
-                new_attrs.push_all(&inner_attrs[..]);
-                (ast::MethDecl(ident,
-                               generics,
-                               abi,
-                               explicit_self,
-                               unsafety,
-                               decl,
-                               body,
-                               visa),
-                 body_span.hi, new_attrs)
+            let last_span = self.last_span;
+            self.complain_if_pub_macro(vis, last_span);
+
+            let pth = self.parse_path(NoTypesAllowed);
+            self.expect(&token::Not);
+
+            // eat a matched-delimiter token tree:
+            let delim = self.expect_open_delim();
+            let tts = self.parse_seq_to_end(&token::CloseDelim(delim),
+                                            seq_sep_none(),
+                                            |p| p.parse_token_tree());
+            let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
+            let m: ast::Mac = codemap::Spanned { node: m_,
+                                                span: mk_sp(self.span.lo,
+                                                            self.span.hi) };
+            if delim != token::Brace {
+                self.expect(&token::Semi)
             }
-        };
-        P(ast::Method {
-            attrs: new_attrs,
-            id: ast::DUMMY_NODE_ID,
-            span: mk_sp(lo, hi),
-            node: method_,
-        })
+            (token::special_idents::invalid, vec![], ast::MacImplItem(m))
+        } else {
+            let unsafety = self.parse_unsafety();
+            let abi = if self.eat_keyword(keywords::Extern) {
+                self.parse_opt_abi().unwrap_or(abi::C)
+            } else {
+                abi::Rust
+            };
+            self.expect_keyword(keywords::Fn);
+            let ident = self.parse_ident();
+            let mut generics = self.parse_generics();
+            let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
+                    p.parse_arg()
+                });
+            generics.where_clause = self.parse_where_clause();
+            let (inner_attrs, body) = self.parse_inner_attrs_and_block();
+            (ident, inner_attrs, MethodImplItem(ast::MethodSig {
+                generics: generics,
+                abi: abi,
+                explicit_self: explicit_self,
+                unsafety: unsafety,
+                decl: decl
+             }, body))
+        }
     }
 
     /// Parse trait Foo { ... }
@@ -4734,59 +4430,23 @@ impl<'a> Parser<'a> {
 
         let ident = self.parse_ident();
         let mut tps = self.parse_generics();
-        // This is not very accurate, but since unbound only exists to catch
-        // obsolete syntax, the span is unlikely to ever be used.
-        let unbound_span = self.span;
-        let unbound = self.parse_for_sized();
 
         // Parse supertrait bounds.
-        let mut bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare);
-
-        if let Some(unbound) = unbound {
-            let mut bounds_as_vec = bounds.into_vec();
-            bounds_as_vec.push(TraitTyParamBound(PolyTraitRef { bound_lifetimes: vec![],
-                                                                trait_ref: unbound,
-                                                                span:  unbound_span },
-                                                 TraitBoundModifier::Maybe));
-            bounds = OwnedSlice::from_vec(bounds_as_vec);
-        };
+        let bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare);
 
-        self.parse_where_clause(&mut tps);
+        tps.where_clause = self.parse_where_clause();
 
         let meths = self.parse_trait_items();
         (ident, ItemTrait(unsafety, tps, bounds, meths), None)
     }
 
-    fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) {
-        let mut impl_items = Vec::new();
-        self.expect(&token::OpenDelim(token::Brace));
-        let (inner_attrs, mut method_attrs) =
-            self.parse_inner_attrs_and_next();
-        loop {
-            method_attrs.extend(self.parse_outer_attributes().into_iter());
-            if method_attrs.is_empty() && self.eat(&token::CloseDelim(token::Brace)) {
-                break;
-            }
-
-            let vis = self.parse_visibility();
-            if self.eat_keyword(keywords::Type) {
-                impl_items.push(TypeImplItem(P(self.parse_typedef(
-                            method_attrs,
-                            vis))))
-            } else {
-                impl_items.push(MethodImplItem(self.parse_method(
-                            method_attrs,
-                            vis)));
-            }
-            method_attrs = vec![];
-        }
-        (impl_items, inner_attrs)
-    }
-
-    /// Parses two variants (with the region/type params always optional):
+    /// Parses items implementations variants
     ///    impl<T> Foo { ... }
-    ///    impl<T> ToString for ~[T] { ... }
+    ///    impl<T> ToString for &'static T { ... }
+    ///    impl Send for .. {}
     fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> ItemInfo {
+        let impl_span = self.span;
+
         // First, parse type parameters if necessary.
         let mut generics = self.parse_generics();
 
@@ -4807,21 +4467,18 @@ impl<'a> Parser<'a> {
         // Parse traits, if necessary.
         let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
             // New-style trait. Reinterpret the type as a trait.
-            let opt_trait_ref = match ty.node {
-                TyPath(ref path, node_id) => {
+            match ty.node {
+                TyPath(None, ref path) => {
                     Some(TraitRef {
                         path: (*path).clone(),
-                        ref_id: node_id,
+                        ref_id: ty.id,
                     })
                 }
                 _ => {
                     self.span_err(ty.span, "not a trait");
                     None
                 }
-            };
-
-            ty = self.parse_ty_sum();
-            opt_trait_ref
+            }
         } else {
             match polarity {
                 ast::ImplPolarity::Negative => {
@@ -4834,14 +4491,34 @@ impl<'a> Parser<'a> {
             None
         };
 
-        self.parse_where_clause(&mut generics);
-        let (impl_items, attrs) = self.parse_impl_items();
+        if self.eat(&token::DotDot) {
+            if generics.is_parameterized() {
+                self.span_err(impl_span, "default trait implementations are not \
+                                          allowed to have genercis");
+            }
 
-        let ident = ast_util::impl_pretty_name(&opt_trait, &*ty);
+            self.expect(&token::OpenDelim(token::Brace));
+            self.expect(&token::CloseDelim(token::Brace));
+            (ast_util::impl_pretty_name(&opt_trait, None),
+             ItemDefaultImpl(unsafety, opt_trait.unwrap()), None)
+        } else {
+            if opt_trait.is_some() {
+                ty = self.parse_ty_sum();
+            }
+            generics.where_clause = self.parse_where_clause();
 
-        (ident,
-         ItemImpl(unsafety, polarity, generics, opt_trait, ty, impl_items),
-         Some(attrs))
+            self.expect(&token::OpenDelim(token::Brace));
+            let attrs = self.parse_inner_attributes();
+
+            let mut impl_items = vec![];
+            while !self.eat(&token::CloseDelim(token::Brace)) {
+                impl_items.push(self.parse_impl_item());
+            }
+
+            (ast_util::impl_pretty_name(&opt_trait, Some(&*ty)),
+             ItemImpl(unsafety, polarity, generics, opt_trait, ty, impl_items),
+             Some(attrs))
+        }
     }
 
     /// Parse a::B<String,i32>
@@ -4900,7 +4577,7 @@ impl<'a> Parser<'a> {
         // struct.
 
         let (fields, ctor_id) = if self.token.is_keyword(keywords::Where) {
-            self.parse_where_clause(&mut generics);
+            generics.where_clause = self.parse_where_clause();
             if self.eat(&token::Semi) {
                 // If we see a: `struct Foo<T> where T: Copy;` style decl.
                 (Vec::new(), Some(ast::DUMMY_NODE_ID))
@@ -4981,12 +4658,12 @@ impl<'a> Parser<'a> {
                     token::get_ident(class_name.clone())));
             }
 
-            self.parse_where_clause(generics);
+            generics.where_clause = self.parse_where_clause();
             self.expect(&token::Semi);
             fields
         // This is the case where we just see struct Foo<T> where T: Copy;
         } else if self.token.is_keyword(keywords::Where) {
-            self.parse_where_clause(generics);
+            generics.where_clause = self.parse_where_clause();
             self.expect(&token::Semi);
             Vec::new()
         // This case is where we see: `struct Foo<T>;`
@@ -5042,86 +4719,16 @@ impl<'a> Parser<'a> {
         else { Inherited }
     }
 
-    fn parse_for_sized(&mut self) -> Option<ast::TraitRef> {
-        // FIXME, this should really use TraitBoundModifier, but it will get
-        // re-jigged shortly in any case, so leaving the hacky version for now.
-        if self.eat_keyword(keywords::For) {
-            let span = self.span;
-
-            let mut ate_question = false;
-            if self.eat(&token::Question) {
-                ate_question = true;
-            }
-            let ident = self.parse_ident();
-            if self.eat(&token::Question) {
-                if ate_question {
-                    self.span_err(span,
-                        "unexpected `?`");
-                }
-                ate_question = true;
-            }
-            if !ate_question {
-                self.span_err(span,
-                    "expected `?Sized` after `for` in trait item");
-                return None;
-            }
-            let _tref = Parser::trait_ref_from_ident(ident, span);
-
-            self.obsolete(span, ObsoleteSyntax::ForSized);
-
-            None
-        } else {
-            None
-        }
-    }
-
-    /// Given a termination token and a vector of already-parsed
-    /// attributes (of length 0 or 1), parse all of the items in a module
-    fn parse_mod_items(&mut self,
-                       term: token::Token,
-                       first_item_attrs: Vec<Attribute>,
-                       inner_lo: BytePos)
-                       -> Mod {
-        // Parse all of the items up to closing or an attribute.
-
-        let mut attrs = first_item_attrs;
-        attrs.push_all(&self.parse_outer_attributes());
+    /// Given a termination token, parse all of the items in a module
+    fn parse_mod_items(&mut self, term: &token::Token, inner_lo: BytePos) -> Mod {
         let mut items = vec![];
-
-        loop {
-            match self.parse_item_(attrs, true) {
-                Err(returned_attrs) => {
-                    attrs = returned_attrs;
-                    break
-                }
-                Ok(item) => {
-                    attrs = self.parse_outer_attributes();
-                    items.push(item)
-                }
-            }
+        while let Some(item) = self.parse_item() {
+            items.push(item);
         }
 
-        // don't think this other loop is even necessary....
-
-        while self.token != term {
-            let mut attrs = mem::replace(&mut attrs, vec![]);
-            attrs.push_all(&self.parse_outer_attributes());
-            debug!("parse_mod_items: parse_item_(attrs={:?})", attrs);
-            match self.parse_item_(attrs, true /* macros allowed */) {
-              Ok(item) => items.push(item),
-              Err(_) => {
-                  let token_str = self.this_token_to_string();
-                  self.fatal(&format!("expected item, found `{}`",
-                                     token_str))
-              }
-            }
-        }
-
-        if !attrs.is_empty() {
-            // We parsed attributes for the first item but didn't find it
-            let last_span = self.last_span;
-            self.span_err(last_span,
-                          Parser::expected_item_err(&attrs[..]));
+        if !self.eat(term) {
+            let token_str = self.this_token_to_string();
+            self.fatal(&format!("expected item, found `{}`", token_str))
         }
 
         ast::Mod {
@@ -5159,12 +4766,11 @@ impl<'a> Parser<'a> {
             let mod_inner_lo = self.span.lo;
             let old_owns_directory = self.owns_directory;
             self.owns_directory = true;
-            let (inner, next) = self.parse_inner_attrs_and_next();
-            let m = self.parse_mod_items(token::CloseDelim(token::Brace), next, mod_inner_lo);
-            self.expect(&token::CloseDelim(token::Brace));
+            let attrs = self.parse_inner_attributes();
+            let m = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo);
             self.owns_directory = old_owns_directory;
             self.pop_mod_path();
-            (id, ItemMod(m), Some(inner))
+            (id, ItemMod(m), Some(attrs))
         }
     }
 
@@ -5188,14 +4794,17 @@ impl<'a> Parser<'a> {
                     outer_attrs: &[ast::Attribute],
                     id_sp: Span)
                     -> (ast::Item_, Vec<ast::Attribute> ) {
-        let mut prefix = Path::new(self.sess.span_diagnostic.cm.span_to_filename(self.span));
+        let mut prefix = PathBuf::from(&self.sess.span_diagnostic.cm
+                                            .span_to_filename(self.span));
         prefix.pop();
-        let mod_path = Path::new(".").join_many(&self.mod_path_stack[]);
-        let dir_path = prefix.join(&mod_path);
+        let mut dir_path = prefix;
+        for part in &self.mod_path_stack {
+            dir_path.push(&**part);
+        }
         let mod_string = token::get_ident(id);
         let (file_path, owns_directory) = match ::attr::first_attr_value_str_by_name(
                 outer_attrs, "path") {
-            Some(d) => (dir_path.join(d), true),
+            Some(d) => (dir_path.join(&*d), true),
             None => {
                 let mod_name = mod_string.to_string();
                 let default_path_str = format!("{}.rs", mod_name);
@@ -5259,7 +4868,7 @@ impl<'a> Parser<'a> {
     }
 
     fn eval_src_mod_from_path(&mut self,
-                              path: Path,
+                              path: PathBuf,
                               owns_directory: bool,
                               name: String,
                               id_sp: Span) -> (ast::Item_, Vec<ast::Attribute> ) {
@@ -5269,10 +4878,10 @@ impl<'a> Parser<'a> {
                 let mut err = String::from_str("circular modules: ");
                 let len = included_mod_stack.len();
                 for p in &included_mod_stack[i.. len] {
-                    err.push_str(&p.display().as_cow());
+                    err.push_str(&p.to_string_lossy());
                     err.push_str(" -> ");
                 }
-                err.push_str(&path.display().as_cow());
+                err.push_str(&path.to_string_lossy());
                 self.span_fatal(id_sp, &err[..]);
             }
             None => ()
@@ -5288,11 +4897,10 @@ impl<'a> Parser<'a> {
                                      Some(name),
                                      id_sp);
         let mod_inner_lo = p0.span.lo;
-        let (mod_attrs, next) = p0.parse_inner_attrs_and_next();
-        let first_item_outer_attrs = next;
-        let m0 = p0.parse_mod_items(token::Eof, first_item_outer_attrs, mod_inner_lo);
+        let mod_attrs = p0.parse_inner_attributes();
+        let m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo);
         self.sess.included_mod_stack.borrow_mut().pop();
-        return (ast::ItemMod(m0), mod_attrs);
+        (ast::ItemMod(m0), mod_attrs)
     }
 
     /// Parse a function declaration from a foreign module
@@ -5303,7 +4911,7 @@ impl<'a> Parser<'a> {
 
         let (ident, mut generics) = self.parse_fn_header();
         let decl = self.parse_fn_decl(true);
-        self.parse_where_clause(&mut generics);
+        generics.where_clause = self.parse_where_clause();
         let hi = self.span.hi;
         self.expect(&token::Semi);
         P(ast::ForeignItem {
@@ -5339,74 +4947,25 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// At this point, this is essentially a wrapper for
-    /// parse_foreign_items.
-    fn parse_foreign_mod_items(&mut self,
-                               abi: abi::Abi,
-                               first_item_attrs: Vec<Attribute>)
-                               -> ForeignMod {
-        let foreign_items = self.parse_foreign_items(first_item_attrs);
-        assert!(self.token == token::CloseDelim(token::Brace));
-        ast::ForeignMod {
-            abi: abi,
-            items: foreign_items
-        }
-    }
-
     /// Parse extern crate links
     ///
-    /// # Example
+    /// # Examples
     ///
-    /// extern crate url;
-    /// extern crate foo = "bar"; //deprecated
-    /// extern crate "bar" as foo;
+    /// extern crate foo;
+    /// extern crate bar as foo;
     fn parse_item_extern_crate(&mut self,
-                                lo: BytePos,
-                                visibility: Visibility,
-                                attrs: Vec<Attribute>)
+                               lo: BytePos,
+                               visibility: Visibility,
+                               attrs: Vec<Attribute>)
                                 -> P<Item> {
 
-        let span = self.span;
-        let (maybe_path, ident) = match self.token {
-            token::Ident(..) => {
-                let the_ident = self.parse_ident();
-                let path = if self.eat_keyword_noexpect(keywords::As) {
-                    // skip the ident if there is one
-                    if self.token.is_ident() { self.bump(); }
-
-                    self.span_err(span, "expected `;`, found `as`");
-                    self.span_help(span,
-                                   &format!("perhaps you meant to enclose the crate name `{}` in \
-                                           a string?",
-                                          the_ident.as_str()));
-                    None
-                } else {
-                    None
-                };
-                self.expect(&token::Semi);
-                (path, the_ident)
-            },
-            token::Literal(token::Str_(..), suf) | token::Literal(token::StrRaw(..), suf) => {
-                let sp = self.span;
-                self.expect_no_suffix(sp, "extern crate name", suf);
-                // forgo the internal suffix check of `parse_str` to
-                // avoid repeats (this unwrap will always succeed due
-                // to the restriction of the `match`)
-                let (s, style, _) = self.parse_optional_str().unwrap();
-                self.expect_keyword(keywords::As);
-                let the_ident = self.parse_ident();
-                self.expect(&token::Semi);
-                (Some((s, style)), the_ident)
-            },
-            _ => {
-                let span = self.span;
-                let token_str = self.this_token_to_string();
-                self.span_fatal(span,
-                                &format!("expected extern crate name but \
-                                         found `{}`",
-                                        token_str));
-            }
+        let crate_name = self.parse_ident();
+        let (maybe_path, ident) = if self.eat_keyword(keywords::As) {
+            (Some(crate_name.name), self.parse_ident())
+        } else {
+            (None, crate_name)
         };
+        self.expect(&token::Semi);
 
         let last_span = self.last_span;
         self.mk_item(lo,
@@ -5431,31 +4990,38 @@ impl<'a> Parser<'a> {
                               lo: BytePos,
                               opt_abi: Option<abi::Abi>,
                               visibility: Visibility,
-                              attrs: Vec<Attribute>)
+                              mut attrs: Vec<Attribute>)
                               -> P<Item> {
-
         self.expect(&token::OpenDelim(token::Brace));
 
         let abi = opt_abi.unwrap_or(abi::C);
 
-        let (inner, next) = self.parse_inner_attrs_and_next();
-        let m = self.parse_foreign_mod_items(abi, next);
+        attrs.extend(self.parse_inner_attributes().into_iter());
+
+        let mut foreign_items = vec![];
+        while let Some(item) = self.parse_foreign_item() {
+            foreign_items.push(item);
+        }
         self.expect(&token::CloseDelim(token::Brace));
 
         let last_span = self.last_span;
+        let m = ast::ForeignMod {
+            abi: abi,
+            items: foreign_items
+        };
         self.mk_item(lo,
                      last_span.hi,
                      special_idents::invalid,
                      ItemForeignMod(m),
                      visibility,
-                     maybe_append(attrs, Some(inner)))
+                     attrs)
     }
 
     /// Parse type Foo = Bar;
     fn parse_item_type(&mut self) -> ItemInfo {
         let ident = self.parse_ident();
         let mut tps = self.parse_generics();
-        self.parse_where_clause(&mut tps);
+        tps.where_clause = self.parse_where_clause();
         self.expect(&token::Eq);
         let ty = self.parse_ty_sum();
         self.expect(&token::Semi);
@@ -5555,7 +5121,7 @@ impl<'a> Parser<'a> {
     fn parse_item_enum(&mut self) -> ItemInfo {
         let id = self.parse_ident();
         let mut generics = self.parse_generics();
-        self.parse_where_clause(&mut generics);
+        generics.where_clause = self.parse_where_clause();
         self.expect(&token::OpenDelim(token::Brace));
 
         let enum_definition = self.parse_enum_def(&generics);
@@ -5590,12 +5156,11 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parse one of the items allowed by the flags; on failure,
-    /// return `Err(remaining_attrs)`.
+    /// Parse one of the items allowed by the flags.
     /// NB: this function no longer parses the items inside an
     /// extern crate.
     fn parse_item_(&mut self, attrs: Vec<Attribute>,
-                   macros_allowed: bool) -> MaybeItem {
+                   macros_allowed: bool) -> Option<P<Item>> {
         let nt_item = match self.token {
             token::Interpolated(token::NtItem(ref item)) => {
                 Some((**item).clone())
@@ -5608,7 +5173,7 @@ impl<'a> Parser<'a> {
                 let mut attrs = attrs;
                 mem::swap(&mut item.attrs, &mut attrs);
                 item.attrs.extend(attrs.into_iter());
-                return Ok(P(item));
+                return Some(P(item));
             }
             None => {}
         }
@@ -5629,12 +5194,12 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     attrs);
-            return Ok(item);
+            return Some(item);
         }
 
         if self.eat_keyword(keywords::Extern) {
             if self.eat_keyword(keywords::Crate) {
-                return Ok(self.parse_item_extern_crate(lo, visibility, attrs));
+                return Some(self.parse_item_extern_crate(lo, visibility, attrs));
             }
 
             let opt_abi = self.parse_opt_abi();
@@ -5651,9 +5216,9 @@ impl<'a> Parser<'a> {
                                         item_,
                                         visibility,
                                         maybe_append(attrs, extra_attrs));
-                return Ok(item);
+                return Some(item);
             } else if self.check(&token::OpenDelim(token::Brace)) {
-                return Ok(self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs));
+                return Some(self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs));
             }
 
             let span = self.span;
@@ -5679,14 +5244,14 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Const) {
             // CONST ITEM
             if self.eat_keyword(keywords::Mut) {
                 let last_span = self.last_span;
                 self.span_err(last_span, "const globals cannot be mutable");
-                self.span_help(last_span, "did you mean to declare a static?");
+                self.fileline_help(last_span, "did you mean to declare a static?");
             }
             let (ident, item_, extra_attrs) = self.parse_item_const(None);
             let last_span = self.last_span;
@@ -5696,7 +5261,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.check_keyword(keywords::Unsafe) &&
             self.look_ahead(1, |t| t.is_keyword(keywords::Trait))
@@ -5713,7 +5278,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.check_keyword(keywords::Unsafe) &&
             self.look_ahead(1, |t| t.is_keyword(keywords::Impl))
@@ -5729,7 +5294,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.check_keyword(keywords::Fn) {
             // FUNCTION ITEM
@@ -5743,7 +5308,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.check_keyword(keywords::Unsafe)
             && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) {
@@ -5764,7 +5329,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Mod) {
             // MODULE ITEM
@@ -5777,7 +5342,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Type) {
             // TYPE ITEM
@@ -5789,7 +5354,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Enum) {
             // ENUM ITEM
@@ -5801,7 +5366,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Trait) {
             // TRAIT ITEM
@@ -5814,7 +5379,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Impl) {
             // IMPL ITEM
@@ -5826,7 +5391,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Struct) {
             // STRUCT ITEM
@@ -5838,30 +5403,34 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
     }
 
-    /// Parse a foreign item; on failure, return `Err(remaining_attrs)`.
-    fn parse_foreign_item(&mut self, attrs: Vec<Attribute>)
-                          -> Result<P<ForeignItem>, Vec<Attribute>> {
+    /// Parse a foreign item.
+    fn parse_foreign_item(&mut self) -> Option<P<ForeignItem>> {
         let lo = self.span.lo;
 
+        let attrs = self.parse_outer_attributes();
         let visibility = self.parse_visibility();
 
         if self.check_keyword(keywords::Static) {
             // FOREIGN STATIC ITEM
-            return Ok(self.parse_item_foreign_static(visibility, attrs));
+            return Some(self.parse_item_foreign_static(visibility, attrs));
         }
         if self.check_keyword(keywords::Fn) || self.check_keyword(keywords::Unsafe) {
             // FOREIGN FUNCTION ITEM
-            return Ok(self.parse_item_foreign_fn(visibility, attrs));
+            return Some(self.parse_item_foreign_fn(visibility, attrs));
         }
 
         // FIXME #5668: this will occur for a macro invocation:
-        let item = try!(self.parse_macro_use_or_failure(attrs, true, lo, visibility));
-        self.span_fatal(item.span, "macros cannot expand to foreign items");
+        match self.parse_macro_use_or_failure(attrs, true, lo, visibility) {
+            Some(item) => {
+                self.span_fatal(item.span, "macros cannot expand to foreign items");
+            }
+            None => None
+        }
     }
 
     /// This is the fall-through for parsing items.
@@ -5871,7 +5440,7 @@ impl<'a> Parser<'a> {
         macros_allowed: bool,
         lo: BytePos,
         visibility: Visibility
-    ) -> MaybeItem {
+    ) -> Option<P<Item>> {
         if macros_allowed && !self.token.is_any_keyword()
                 && self.look_ahead(1, |t| *t == token::Not)
                 && (self.look_ahead(2, |t| t.is_plain_ident())
@@ -5923,7 +5492,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     attrs);
-            return Ok(item);
+            return Some(item);
         }
 
         // FAILURE TO PARSE ITEM
@@ -5934,16 +5503,16 @@ impl<'a> Parser<'a> {
                 self.span_fatal(last_span, "unmatched visibility `pub`");
             }
         }
-        Err(attrs)
-    }
 
-    pub fn parse_item_with_outer_attributes(&mut self) -> Option<P<Item>> {
-        let attrs = self.parse_outer_attributes();
-        self.parse_item(attrs)
+        if !attrs.is_empty() {
+            self.expected_item_err(&attrs);
+        }
+        None
     }
 
-    pub fn parse_item(&mut self, attrs: Vec<Attribute>) -> Option<P<Item>> {
-        self.parse_item_(attrs, true).ok()
+    pub fn parse_item(&mut self) -> Option<P<Item>> {
+        let attrs = self.parse_outer_attributes();
+        self.parse_item_(attrs, true)
     }
 
     /// Matches view_path : MOD? non_global_path as IDENT
@@ -6049,52 +5618,13 @@ impl<'a> Parser<'a> {
         P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path)))
     }
 
-    /// Parses a sequence of foreign items. Stops when it finds program
-    /// text that can't be parsed as an item
-    fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute>)
-                           -> Vec<P<ForeignItem>> {
-        let mut attrs = first_item_attrs;
-        attrs.push_all(&self.parse_outer_attributes());
-        let mut foreign_items = Vec::new();
-        loop {
-            match self.parse_foreign_item(attrs) {
-                Ok(foreign_item) => {
-                    foreign_items.push(foreign_item);
-                }
-                Err(returned_attrs) => {
-                    if self.check(&token::CloseDelim(token::Brace)) {
-                        attrs = returned_attrs;
-                        break
-                    }
-                    self.unexpected();
-                }
-            }
-            attrs = self.parse_outer_attributes();
-        }
-
-        if !attrs.is_empty() {
-            let last_span = self.last_span;
-            self.span_err(last_span,
-                          Parser::expected_item_err(&attrs[..]));
-        }
-
-        foreign_items
-    }
-
     /// Parses a source module as a crate. This is the main
     /// entry point for the parser.
     pub fn parse_crate_mod(&mut self) -> Crate {
         let lo = self.span.lo;
-        // parse the crate's inner attrs, maybe (oops) one
-        // of the attrs of an item:
-        let (inner, next) = self.parse_inner_attrs_and_next();
-        let first_item_outer_attrs = next;
-        // parse the items inside the crate:
-        let m = self.parse_mod_items(token::Eof, first_item_outer_attrs, lo);
-
         ast::Crate {
-            module: m,
-            attrs: inner,
+            attrs: self.parse_inner_attributes(),
+            module: self.parse_mod_items(&token::Eof, lo),
             config: self.cfg.clone(),
             span: mk_sp(lo, self.span.lo),
             exported_macros: Vec::new(),
index 433c013591c2d1557b84fcbb3c7a01d69b03d506..4db85eeea46f1b68917d804a2ccb5e28894606d6 100644 (file)
@@ -25,6 +25,7 @@ use serialize::{Decodable, Decoder, Encodable, Encoder};
 use std::fmt;
 use std::mem;
 use std::ops::Deref;
+#[allow(deprecated)]
 use std::old_path::BytesContainer;
 use std::rc::Rc;
 
@@ -425,10 +426,10 @@ macro_rules! declare_special_idents_and_keywords {(
         $( ($rk_name:expr, $rk_variant:ident, $rk_str:expr); )*
     }
 ) => {
-    static STRICT_KEYWORD_START: ast::Name = first!($( ast::Name($sk_name), )*);
-    static STRICT_KEYWORD_FINAL: ast::Name = last!($( ast::Name($sk_name), )*);
-    static RESERVED_KEYWORD_START: ast::Name = first!($( ast::Name($rk_name), )*);
-    static RESERVED_KEYWORD_FINAL: ast::Name = last!($( ast::Name($rk_name), )*);
+    const STRICT_KEYWORD_START: ast::Name = first!($( ast::Name($sk_name), )*);
+    const STRICT_KEYWORD_FINAL: ast::Name = last!($( ast::Name($sk_name), )*);
+    const RESERVED_KEYWORD_START: ast::Name = first!($( ast::Name($rk_name), )*);
+    const RESERVED_KEYWORD_FINAL: ast::Name = last!($( ast::Name($rk_name), )*);
 
     pub mod special_idents {
         use ast;
@@ -561,11 +562,11 @@ declare_special_idents_and_keywords! {
         (39,                         Virtual,    "virtual");
         (40,                         While,      "while");
         (41,                         Continue,   "continue");
-        (42,                         Proc,       "proc");
-        (43,                         Box,        "box");
-        (44,                         Const,      "const");
-        (45,                         Where,      "where");
+        (42,                         Box,        "box");
+        (43,                         Const,      "const");
+        (44,                         Where,      "where");
         'reserved:
+        (45,                         Proc,       "proc");
         (46,                         Alignof,    "alignof");
         (47,                         Become,     "become");
         (48,                         Offsetof,   "offsetof");
@@ -638,6 +639,7 @@ impl Deref for InternedString {
     fn deref(&self) -> &str { &*self.string }
 }
 
+#[allow(deprecated)]
 impl BytesContainer for InternedString {
     fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
         // FIXME #12938: This is a workaround for the incorrect signature
@@ -652,47 +654,47 @@ impl BytesContainer for InternedString {
 
 impl fmt::Debug for InternedString {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Debug::fmt(&self.string[], f)
+        fmt::Debug::fmt(&self.string, f)
     }
 }
 
 impl fmt::Display for InternedString {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(&self.string[], f)
+        fmt::Display::fmt(&self.string, f)
     }
 }
 
 impl<'a> PartialEq<&'a str> for InternedString {
     #[inline(always)]
     fn eq(&self, other: & &'a str) -> bool {
-        PartialEq::eq(&self.string[], *other)
+        PartialEq::eq(&self.string[..], *other)
     }
     #[inline(always)]
     fn ne(&self, other: & &'a str) -> bool {
-        PartialEq::ne(&self.string[], *other)
+        PartialEq::ne(&self.string[..], *other)
     }
 }
 
 impl<'a> PartialEq<InternedString > for &'a str {
     #[inline(always)]
     fn eq(&self, other: &InternedString) -> bool {
-        PartialEq::eq(*self, &other.string[])
+        PartialEq::eq(*self, &other.string[..])
     }
     #[inline(always)]
     fn ne(&self, other: &InternedString) -> bool {
-        PartialEq::ne(*self, &other.string[])
+        PartialEq::ne(*self, &other.string[..])
     }
 }
 
 impl Decodable for InternedString {
     fn decode<D: Decoder>(d: &mut D) -> Result<InternedString, D::Error> {
-        Ok(get_name(get_ident_interner().intern(&try!(d.read_str())[])))
+        Ok(get_name(get_ident_interner().intern(&try!(d.read_str())[..])))
     }
 }
 
 impl Encodable for InternedString {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_str(&self.string[])
+        s.emit_str(&self.string)
     }
 }
 
index 1593bfb97fe1da755ff08f1697d05c65e85d9eb1..ebfd970f3dbfc3c3e3d0634924bc90352ff11908 100644 (file)
@@ -59,7 +59,7 @@
 //! line (which it can't) and so naturally place the content on its own line to
 //! avoid combining it with other lines and making matters even worse.
 
-use std::old_io;
+use std::io;
 use std::string;
 use std::iter::repeat;
 
@@ -139,7 +139,7 @@ pub fn buf_str(toks: &[Token],
         }
         s.push_str(&format!("{}={}",
                            szs[i],
-                           tok_str(&toks[i]))[]);
+                           tok_str(&toks[i])));
         i += 1;
         i %= n;
     }
@@ -147,21 +147,21 @@ pub fn buf_str(toks: &[Token],
     s
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum PrintStackBreak {
     Fits,
     Broken(Breaks),
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct PrintStackElem {
     offset: isize,
     pbreak: PrintStackBreak
 }
 
-static SIZE_INFINITY: isize = 0xffff;
+const SIZE_INFINITY: isize = 0xffff;
 
-pub fn mk_printer(out: Box<old_io::Writer+'static>, linewidth: usize) -> Printer {
+pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
     // Yes 3, it makes the ring buffers big enough to never
     // fall behind.
     let n: usize = 3 * linewidth;
@@ -265,8 +265,8 @@ pub fn mk_printer(out: Box<old_io::Writer+'static>, linewidth: usize) -> Printer
 /// In this implementation (following the paper, again) the SCAN process is
 /// the method called 'pretty_print', and the 'PRINT' process is the method
 /// called 'print'.
-pub struct Printer {
-    pub out: Box<old_io::Writer+'static>,
+pub struct Printer<'a> {
+    pub out: Box<io::Write+'a>,
     buf_len: usize,
     /// Width of lines we're constrained to
     margin: isize,
@@ -303,7 +303,7 @@ pub struct Printer {
     pending_indentation: isize,
 }
 
-impl Printer {
+impl<'a> Printer<'a> {
     pub fn last_token(&mut self) -> Token {
         self.token[self.right].clone()
     }
@@ -311,7 +311,7 @@ impl Printer {
     pub fn replace_last_token(&mut self, t: Token) {
         self.token[self.right] = t;
     }
-    pub fn pretty_print(&mut self, token: Token) -> old_io::IoResult<()> {
+    pub fn pretty_print(&mut self, token: Token) -> io::Result<()> {
         debug!("pp ~[{},{}]", self.left, self.right);
         match token {
           Token::Eof => {
@@ -385,7 +385,7 @@ impl Printer {
           }
         }
     }
-    pub fn check_stream(&mut self) -> old_io::IoResult<()> {
+    pub fn check_stream(&mut self) -> io::Result<()> {
         debug!("check_stream ~[{}, {}] with left_total={}, right_total={}",
                self.left, self.right, self.left_total, self.right_total);
         if self.right_total - self.left_total > self.space {
@@ -445,7 +445,7 @@ impl Printer {
         self.right %= self.buf_len;
         assert!((self.right != self.left));
     }
-    pub fn advance_left(&mut self) -> old_io::IoResult<()> {
+    pub fn advance_left(&mut self) -> io::Result<()> {
         debug!("advance_left ~[{},{}], sizeof({})={}", self.left, self.right,
                self.left, self.size[self.left]);
 
@@ -506,7 +506,7 @@ impl Printer {
             }
         }
     }
-    pub fn print_newline(&mut self, amount: isize) -> old_io::IoResult<()> {
+    pub fn print_newline(&mut self, amount: isize) -> io::Result<()> {
         debug!("NEWLINE {}", amount);
         let ret = write!(self.out, "\n");
         self.pending_indentation = 0;
@@ -529,14 +529,14 @@ impl Printer {
             }
         }
     }
-    pub fn print_str(&mut self, s: &str) -> old_io::IoResult<()> {
+    pub fn print_str(&mut self, s: &str) -> io::Result<()> {
         while self.pending_indentation > 0 {
             try!(write!(self.out, " "));
             self.pending_indentation -= 1;
         }
         write!(self.out, "{}", s)
     }
-    pub fn print(&mut self, token: Token, l: isize) -> old_io::IoResult<()> {
+    pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
         debug!("print {} {} (remaining line space={})", tok_str(&token), l,
                self.space);
         debug!("{}", buf_str(&self.token,
@@ -620,61 +620,61 @@ impl Printer {
 // Convenience functions to talk to the printer.
 //
 // "raw box"
-pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> old_io::IoResult<()> {
+pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> io::Result<()> {
     p.pretty_print(Token::Begin(BeginToken {
         offset: indent as isize,
         breaks: b
     }))
 }
 
-pub fn ibox(p: &mut Printer, indent: usize) -> old_io::IoResult<()> {
+pub fn ibox(p: &mut Printer, indent: usize) -> io::Result<()> {
     rbox(p, indent, Breaks::Inconsistent)
 }
 
-pub fn cbox(p: &mut Printer, indent: usize) -> old_io::IoResult<()> {
+pub fn cbox(p: &mut Printer, indent: usize) -> io::Result<()> {
     rbox(p, indent, Breaks::Consistent)
 }
 
-pub fn break_offset(p: &mut Printer, n: usize, off: isize) -> old_io::IoResult<()> {
+pub fn break_offset(p: &mut Printer, n: usize, off: isize) -> io::Result<()> {
     p.pretty_print(Token::Break(BreakToken {
         offset: off,
         blank_space: n as isize
     }))
 }
 
-pub fn end(p: &mut Printer) -> old_io::IoResult<()> {
+pub fn end(p: &mut Printer) -> io::Result<()> {
     p.pretty_print(Token::End)
 }
 
-pub fn eof(p: &mut Printer) -> old_io::IoResult<()> {
+pub fn eof(p: &mut Printer) -> io::Result<()> {
     p.pretty_print(Token::Eof)
 }
 
-pub fn word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> {
+pub fn word(p: &mut Printer, wrd: &str) -> io::Result<()> {
     p.pretty_print(Token::String(/* bad */ wrd.to_string(), wrd.len() as isize))
 }
 
-pub fn huge_word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> {
+pub fn huge_word(p: &mut Printer, wrd: &str) -> io::Result<()> {
     p.pretty_print(Token::String(/* bad */ wrd.to_string(), SIZE_INFINITY))
 }
 
-pub fn zero_word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> {
+pub fn zero_word(p: &mut Printer, wrd: &str) -> io::Result<()> {
     p.pretty_print(Token::String(/* bad */ wrd.to_string(), 0))
 }
 
-pub fn spaces(p: &mut Printer, n: usize) -> old_io::IoResult<()> {
+pub fn spaces(p: &mut Printer, n: usize) -> io::Result<()> {
     break_offset(p, n, 0)
 }
 
-pub fn zerobreak(p: &mut Printer) -> old_io::IoResult<()> {
+pub fn zerobreak(p: &mut Printer) -> io::Result<()> {
     spaces(p, 0)
 }
 
-pub fn space(p: &mut Printer) -> old_io::IoResult<()> {
+pub fn space(p: &mut Printer) -> io::Result<()> {
     spaces(p, 1)
 }
 
-pub fn hardbreak(p: &mut Printer) -> old_io::IoResult<()> {
+pub fn hardbreak(p: &mut Printer) -> io::Result<()> {
     spaces(p, SIZE_INFINITY as usize)
 }
 
index f26578e740120d8f33695834534ac2a6c6d15d1d..46d196d13fa72f4c9191c872835e0f89ba681dfa 100644 (file)
@@ -12,8 +12,7 @@ pub use self::AnnNode::*;
 
 use abi;
 use ast;
-use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
-use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem};
+use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
 use ast_util;
 use attr;
 use owned_slice::OwnedSlice;
@@ -30,7 +29,7 @@ use ptr::P;
 use std_inject;
 
 use std::{ascii, mem};
-use std::old_io::{self, IoResult};
+use std::io::{self, Write, Read};
 use std::iter;
 
 pub enum AnnNode<'a> {
@@ -38,28 +37,29 @@ pub enum AnnNode<'a> {
     NodeName(&'a ast::Name),
     NodeBlock(&'a ast::Block),
     NodeItem(&'a ast::Item),
+    NodeSubItem(ast::NodeId),
     NodeExpr(&'a ast::Expr),
     NodePat(&'a ast::Pat),
 }
 
 pub trait PpAnn {
-    fn pre(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
-    fn post(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
+    fn pre(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { Ok(()) }
+    fn post(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { Ok(()) }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct NoAnn;
 
 impl PpAnn for NoAnn {}
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct CurrentCommentAndLiteral {
     cur_cmnt: usize,
     cur_lit: usize,
 }
 
 pub struct State<'a> {
-    pub s: pp::Printer,
+    pub s: pp::Printer<'a>,
     cm: Option<&'a CodeMap>,
     comments: Option<Vec<comments::Comment> >,
     literals: Option<Vec<comments::Literal> >,
@@ -69,12 +69,12 @@ pub struct State<'a> {
     encode_idents_with_hygiene: bool,
 }
 
-pub fn rust_printer(writer: Box<old_io::Writer+'static>) -> State<'static> {
+pub fn rust_printer<'a>(writer: Box<Write+'a>) -> State<'a> {
     static NO_ANN: NoAnn = NoAnn;
     rust_printer_annotated(writer, &NO_ANN)
 }
 
-pub fn rust_printer_annotated<'a>(writer: Box<old_io::Writer+'static>,
+pub fn rust_printer_annotated<'a>(writer: Box<Write+'a>,
                                   ann: &'a PpAnn) -> State<'a> {
     State {
         s: pp::mk_printer(writer, default_columns),
@@ -104,10 +104,10 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
                        span_diagnostic: &diagnostic::SpanHandler,
                        krate: &ast::Crate,
                        filename: String,
-                       input: &mut old_io::Reader,
-                       out: Box<old_io::Writer+'static>,
+                       input: &mut Read,
+                       out: Box<Write+'a>,
                        ann: &'a PpAnn,
-                       is_expanded: bool) -> IoResult<()> {
+                       is_expanded: bool) -> io::Result<()> {
     let mut s = State::new_from_input(cm,
                                       span_diagnostic,
                                       filename,
@@ -143,8 +143,8 @@ impl<'a> State<'a> {
     pub fn new_from_input(cm: &'a CodeMap,
                           span_diagnostic: &diagnostic::SpanHandler,
                           filename: String,
-                          input: &mut old_io::Reader,
-                          out: Box<old_io::Writer+'static>,
+                          input: &mut Read,
+                          out: Box<Write+'a>,
                           ann: &'a PpAnn,
                           is_expanded: bool) -> State<'a> {
         let (cmnts, lits) = comments::gather_comments_and_literals(
@@ -164,7 +164,7 @@ impl<'a> State<'a> {
     }
 
     pub fn new(cm: &'a CodeMap,
-               out: Box<old_io::Writer+'static>,
+               out: Box<Write+'a>,
                ann: &'a PpAnn,
                comments: Option<Vec<comments::Comment>>,
                literals: Option<Vec<comments::Literal>>) -> State<'a> {
@@ -185,14 +185,14 @@ impl<'a> State<'a> {
 }
 
 pub fn to_string<F>(f: F) -> String where
-    F: FnOnce(&mut State) -> IoResult<()>,
+    F: FnOnce(&mut State) -> io::Result<()>,
 {
     use std::raw::TraitObject;
     let mut s = rust_printer(box Vec::new());
     f(&mut s).unwrap();
     eof(&mut s.s).unwrap();
     let wr = unsafe {
-        // FIXME(pcwalton): A nasty function to extract the string from an `old_io::Writer`
+        // FIXME(pcwalton): A nasty function to extract the string from an `Write`
         // that we "know" to be a `Vec<u8>` that works around the lack of checked
         // downcasts.
         let obj: &TraitObject = mem::transmute(&s.s.out);
@@ -356,16 +356,20 @@ pub fn item_to_string(i: &ast::Item) -> String {
     $to_string(|s| s.print_item(i))
 }
 
-pub fn generics_to_string(generics: &ast::Generics) -> String {
-    $to_string(|s| s.print_generics(generics))
+pub fn impl_item_to_string(i: &ast::ImplItem) -> String {
+    $to_string(|s| s.print_impl_item(i))
+}
+
+pub fn trait_item_to_string(i: &ast::TraitItem) -> String {
+    $to_string(|s| s.print_trait_item(i))
 }
 
-pub fn ty_method_to_string(p: &ast::TypeMethod) -> String {
-    $to_string(|s| s.print_ty_method(p))
+pub fn generics_to_string(generics: &ast::Generics) -> String {
+    $to_string(|s| s.print_generics(generics))
 }
 
-pub fn method_to_string(p: &ast::Method) -> String {
-    $to_string(|s| s.print_method(p))
+pub fn where_clause_to_string(i: &ast::WhereClause) -> String {
+    $to_string(|s| s.print_where_clause(i))
 }
 
 pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
@@ -373,7 +377,7 @@ pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
 }
 
 pub fn path_to_string(p: &ast::Path) -> String {
-    $to_string(|s| s.print_path(p, false))
+    $to_string(|s| s.print_path(p, false, 0))
 }
 
 pub fn ident_to_string(id: &ast::Ident) -> String {
@@ -384,8 +388,9 @@ pub fn fun_to_string(decl: &ast::FnDecl, unsafety: ast::Unsafety, name: ast::Ide
                   opt_explicit_self: Option<&ast::ExplicitSelf_>,
                   generics: &ast::Generics) -> String {
     $to_string(|s| {
-        try!(s.print_fn(decl, Some(unsafety), abi::Rust,
-                        name, generics, opt_explicit_self, ast::Inherited));
+        try!(s.head(""));
+        try!(s.print_fn(decl, unsafety, abi::Rust, Some(name),
+                        generics, opt_explicit_self, ast::Inherited));
         try!(s.end()); // Close the head box
         s.end() // Close the outer box
     })
@@ -440,13 +445,13 @@ thing_to_string_impls! { to_string }
 pub mod with_hygiene {
     use abi;
     use ast;
-    use std::old_io::IoResult;
+    use std::io;
     use super::indent_unit;
 
     // This function is the trick that all the rest of the routines
     // hang on.
     pub fn to_string_hyg<F>(f: F) -> String where
-        F: FnOnce(&mut super::State) -> IoResult<()>,
+        F: FnOnce(&mut super::State) -> io::Result<()>,
     {
         super::to_string(move |s| {
             s.encode_idents_with_hygiene = true;
@@ -474,44 +479,44 @@ fn needs_parentheses(expr: &ast::Expr) -> bool {
 }
 
 impl<'a> State<'a> {
-    pub fn ibox(&mut self, u: usize) -> IoResult<()> {
+    pub fn ibox(&mut self, u: usize) -> io::Result<()> {
         self.boxes.push(pp::Breaks::Inconsistent);
         pp::ibox(&mut self.s, u)
     }
 
-    pub fn end(&mut self) -> IoResult<()> {
+    pub fn end(&mut self) -> io::Result<()> {
         self.boxes.pop().unwrap();
         pp::end(&mut self.s)
     }
 
-    pub fn cbox(&mut self, u: usize) -> IoResult<()> {
+    pub fn cbox(&mut self, u: usize) -> io::Result<()> {
         self.boxes.push(pp::Breaks::Consistent);
         pp::cbox(&mut self.s, u)
     }
 
     // "raw box"
-    pub fn rbox(&mut self, u: usize, b: pp::Breaks) -> IoResult<()> {
+    pub fn rbox(&mut self, u: usize, b: pp::Breaks) -> io::Result<()> {
         self.boxes.push(b);
         pp::rbox(&mut self.s, u, b)
     }
 
-    pub fn nbsp(&mut self) -> IoResult<()> { word(&mut self.s, " ") }
+    pub fn nbsp(&mut self) -> io::Result<()> { word(&mut self.s, " ") }
 
-    pub fn word_nbsp(&mut self, w: &str) -> IoResult<()> {
+    pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> {
         try!(word(&mut self.s, w));
         self.nbsp()
     }
 
-    pub fn word_space(&mut self, w: &str) -> IoResult<()> {
+    pub fn word_space(&mut self, w: &str) -> io::Result<()> {
         try!(word(&mut self.s, w));
         space(&mut self.s)
     }
 
-    pub fn popen(&mut self) -> IoResult<()> { word(&mut self.s, "(") }
+    pub fn popen(&mut self) -> io::Result<()> { word(&mut self.s, "(") }
 
-    pub fn pclose(&mut self) -> IoResult<()> { word(&mut self.s, ")") }
+    pub fn pclose(&mut self) -> io::Result<()> { word(&mut self.s, ")") }
 
-    pub fn head(&mut self, w: &str) -> IoResult<()> {
+    pub fn head(&mut self, w: &str) -> io::Result<()> {
         // outer-box is consistent
         try!(self.cbox(indent_unit));
         // head-box is inconsistent
@@ -523,17 +528,17 @@ impl<'a> State<'a> {
         Ok(())
     }
 
-    pub fn bopen(&mut self) -> IoResult<()> {
+    pub fn bopen(&mut self) -> io::Result<()> {
         try!(word(&mut self.s, "{"));
         self.end() // close the head-box
     }
 
     pub fn bclose_(&mut self, span: codemap::Span,
-                   indented: usize) -> IoResult<()> {
+                   indented: usize) -> io::Result<()> {
         self.bclose_maybe_open(span, indented, true)
     }
     pub fn bclose_maybe_open (&mut self, span: codemap::Span,
-                              indented: usize, close_box: bool) -> IoResult<()> {
+                              indented: usize, close_box: bool) -> io::Result<()> {
         try!(self.maybe_print_comment(span.hi));
         try!(self.break_offset_if_not_bol(1, -(indented as isize)));
         try!(word(&mut self.s, "}"));
@@ -542,7 +547,7 @@ impl<'a> State<'a> {
         }
         Ok(())
     }
-    pub fn bclose(&mut self, span: codemap::Span) -> IoResult<()> {
+    pub fn bclose(&mut self, span: codemap::Span) -> io::Result<()> {
         self.bclose_(span, indent_unit)
     }
 
@@ -572,18 +577,18 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn hardbreak_if_not_bol(&mut self) -> IoResult<()> {
+    pub fn hardbreak_if_not_bol(&mut self) -> io::Result<()> {
         if !self.is_bol() {
             try!(hardbreak(&mut self.s))
         }
         Ok(())
     }
-    pub fn space_if_not_bol(&mut self) -> IoResult<()> {
+    pub fn space_if_not_bol(&mut self) -> io::Result<()> {
         if !self.is_bol() { try!(space(&mut self.s)); }
         Ok(())
     }
     pub fn break_offset_if_not_bol(&mut self, n: usize,
-                                   off: isize) -> IoResult<()> {
+                                   off: isize) -> io::Result<()> {
         if !self.is_bol() {
             break_offset(&mut self.s, n, off)
         } else {
@@ -599,7 +604,7 @@ impl<'a> State<'a> {
 
     // Synthesizes a comment that was not textually present in the original source
     // file.
-    pub fn synth_comment(&mut self, text: String) -> IoResult<()> {
+    pub fn synth_comment(&mut self, text: String) -> io::Result<()> {
         try!(word(&mut self.s, "/*"));
         try!(space(&mut self.s));
         try!(word(&mut self.s, &text[..]));
@@ -607,8 +612,8 @@ impl<'a> State<'a> {
         word(&mut self.s, "*/")
     }
 
-    pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> IoResult<()> where
-        F: FnMut(&mut State, &T) -> IoResult<()>,
+    pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()> where
+        F: FnMut(&mut State, &T) -> io::Result<()>,
     {
         try!(self.rbox(0, b));
         let mut first = true;
@@ -624,8 +629,8 @@ impl<'a> State<'a> {
                                   b: Breaks,
                                   elts: &[T],
                                   mut op: F,
-                                  mut get_span: G) -> IoResult<()> where
-        F: FnMut(&mut State, &T) -> IoResult<()>,
+                                  mut get_span: G) -> io::Result<()> where
+        F: FnMut(&mut State, &T) -> io::Result<()>,
         G: FnMut(&T) -> codemap::Span,
     {
         try!(self.rbox(0, b));
@@ -646,12 +651,12 @@ impl<'a> State<'a> {
     }
 
     pub fn commasep_exprs(&mut self, b: Breaks,
-                          exprs: &[P<ast::Expr>]) -> IoResult<()> {
+                          exprs: &[P<ast::Expr>]) -> io::Result<()> {
         self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&**e), |e| e.span)
     }
 
     pub fn print_mod(&mut self, _mod: &ast::Mod,
-                     attrs: &[ast::Attribute]) -> IoResult<()> {
+                     attrs: &[ast::Attribute]) -> io::Result<()> {
         try!(self.print_inner_attributes(attrs));
         for item in &_mod.items {
             try!(self.print_item(&**item));
@@ -660,7 +665,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
-                             attrs: &[ast::Attribute]) -> IoResult<()> {
+                             attrs: &[ast::Attribute]) -> io::Result<()> {
         try!(self.print_inner_attributes(attrs));
         for item in &nmod.items {
             try!(self.print_foreign_item(&**item));
@@ -669,7 +674,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_opt_lifetime(&mut self,
-                              lifetime: &Option<ast::Lifetime>) -> IoResult<()> {
+                              lifetime: &Option<ast::Lifetime>) -> io::Result<()> {
         if let Some(l) = *lifetime {
             try!(self.print_lifetime(&l));
             try!(self.nbsp());
@@ -677,7 +682,7 @@ impl<'a> State<'a> {
         Ok(())
     }
 
-    pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
+    pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
         try!(self.maybe_print_comment(ty.span.lo));
         try!(self.ibox(0));
         match ty.node {
@@ -729,8 +734,11 @@ impl<'a> State<'a> {
                                       &generics,
                                       None));
             }
-            ast::TyPath(ref path, _) => {
-                try!(self.print_path(path, false));
+            ast::TyPath(None, ref path) => {
+                try!(self.print_path(path, false, 0));
+            }
+            ast::TyPath(Some(ref qself), ref path) => {
+                try!(self.print_qpath(path, qself, false))
             }
             ast::TyObjectSum(ref ty, ref bounds) => {
                 try!(self.print_type(&**ty));
@@ -739,9 +747,6 @@ impl<'a> State<'a> {
             ast::TyPolyTraitRef(ref bounds) => {
                 try!(self.print_bounds("", &bounds[..]));
             }
-            ast::TyQPath(ref qpath) => {
-                try!(self.print_qpath(&**qpath, false))
-            }
             ast::TyFixedLengthVec(ref ty, ref v) => {
                 try!(word(&mut self.s, "["));
                 try!(self.print_type(&**ty));
@@ -762,14 +767,16 @@ impl<'a> State<'a> {
     }
 
     pub fn print_foreign_item(&mut self,
-                              item: &ast::ForeignItem) -> IoResult<()> {
+                              item: &ast::ForeignItem) -> io::Result<()> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(item.span.lo));
         try!(self.print_outer_attributes(&item.attrs));
         match item.node {
             ast::ForeignItemFn(ref decl, ref generics) => {
-                try!(self.print_fn(&**decl, None, abi::Rust, item.ident, generics,
-                                   None, item.vis));
+                try!(self.head(""));
+                try!(self.print_fn(&**decl, ast::Unsafety::Normal,
+                                   abi::Rust, Some(item.ident),
+                                   generics, None, item.vis));
                 try!(self.end()); // end head-ibox
                 try!(word(&mut self.s, ";"));
                 self.end() // end the outer fn box
@@ -790,26 +797,27 @@ impl<'a> State<'a> {
         }
     }
 
-    fn print_associated_type(&mut self, typedef: &ast::AssociatedType)
-                             -> IoResult<()>
-    {
-        try!(self.print_outer_attributes(&typedef.attrs));
+    fn print_associated_type(&mut self,
+                             ident: ast::Ident,
+                             bounds: Option<&ast::TyParamBounds>,
+                             ty: Option<&ast::Ty>)
+                             -> io::Result<()> {
         try!(self.word_space("type"));
-        try!(self.print_ty_param(&typedef.ty_param));
+        try!(self.print_ident(ident));
+        if let Some(bounds) = bounds {
+            try!(self.print_bounds(":", bounds));
+        }
+        if let Some(ty) = ty {
+            try!(space(&mut self.s));
+            try!(self.word_space("="));
+            try!(self.print_type(ty));
+        }
         word(&mut self.s, ";")
     }
 
-    fn print_typedef(&mut self, typedef: &ast::Typedef) -> IoResult<()> {
-        try!(self.word_space("type"));
-        try!(self.print_ident(typedef.ident));
-        try!(space(&mut self.s));
-        try!(self.word_space("="));
-        try!(self.print_type(&*typedef.typ));
-        word(&mut self.s, ";")
-    }
 
     /// Pretty-print an item
-    pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
+    pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(item.span.lo));
         try!(self.print_outer_attributes(&item.attrs));
@@ -818,8 +826,13 @@ impl<'a> State<'a> {
             ast::ItemExternCrate(ref optional_path) => {
                 try!(self.head(&visibility_qualified(item.vis,
                                                      "extern crate")));
-                if let Some((ref p, style)) = *optional_path {
-                    try!(self.print_string(p, style));
+                if let Some(p) = *optional_path {
+                    let val = token::get_name(p);
+                    if val.contains("-") {
+                        try!(self.print_string(&val, ast::CookedStr));
+                    } else {
+                        try!(self.print_name(p));
+                    }
                     try!(space(&mut self.s));
                     try!(word(&mut self.s, "as"));
                     try!(space(&mut self.s));
@@ -869,11 +882,12 @@ impl<'a> State<'a> {
                 try!(self.end()); // end the outer cbox
             }
             ast::ItemFn(ref decl, unsafety, abi, ref typarams, ref body) => {
+                try!(self.head(""));
                 try!(self.print_fn(
-                    &**decl,
-                    Some(unsafety),
+                    decl,
+                    unsafety,
                     abi,
-                    item.ident,
+                    Some(item.ident),
                     typarams,
                     None,
                     item.vis
@@ -908,7 +922,7 @@ impl<'a> State<'a> {
                 try!(space(&mut self.s));
                 try!(self.word_space("="));
                 try!(self.print_type(&**ty));
-                try!(self.print_where_clause(params));
+                try!(self.print_where_clause(&params.where_clause));
                 try!(word(&mut self.s, ";"));
                 try!(self.end()); // end the outer ibox
             }
@@ -926,6 +940,18 @@ impl<'a> State<'a> {
                 try!(self.print_struct(&**struct_def, generics, item.ident, item.span));
             }
 
+            ast::ItemDefaultImpl(unsafety, ref trait_ref) => {
+                try!(self.head(""));
+                try!(self.print_visibility(item.vis));
+                try!(self.print_unsafety(unsafety));
+                try!(self.word_nbsp("impl"));
+                try!(self.print_trait_ref(trait_ref));
+                try!(space(&mut self.s));
+                try!(self.word_space("for"));
+                try!(self.word_space(".."));
+                try!(self.bopen());
+                try!(self.bclose(item.span));
+            }
             ast::ItemImpl(unsafety,
                           polarity,
                           ref generics,
@@ -959,24 +985,17 @@ impl<'a> State<'a> {
                 }
 
                 try!(self.print_type(&**ty));
-                try!(self.print_where_clause(generics));
+                try!(self.print_where_clause(&generics.where_clause));
 
                 try!(space(&mut self.s));
                 try!(self.bopen());
                 try!(self.print_inner_attributes(&item.attrs));
                 for impl_item in impl_items {
-                    match *impl_item {
-                        ast::MethodImplItem(ref meth) => {
-                            try!(self.print_method(&**meth));
-                        }
-                        ast::TypeImplItem(ref typ) => {
-                            try!(self.print_typedef(&**typ));
-                        }
-                    }
+                    try!(self.print_impl_item(impl_item));
                 }
                 try!(self.bclose(item.span));
             }
-            ast::ItemTrait(unsafety, ref generics, ref bounds, ref methods) => {
+            ast::ItemTrait(unsafety, ref generics, ref bounds, ref trait_items) => {
                 try!(self.head(""));
                 try!(self.print_visibility(item.vis));
                 try!(self.print_unsafety(unsafety));
@@ -994,11 +1013,11 @@ impl<'a> State<'a> {
                     }
                 }
                 try!(self.print_bounds(":", &real_bounds[..]));
-                try!(self.print_where_clause(generics));
+                try!(self.print_where_clause(&generics.where_clause));
                 try!(word(&mut self.s, " "));
                 try!(self.bopen());
-                for meth in methods {
-                    try!(self.print_trait_method(meth));
+                for trait_item in trait_items {
+                    try!(self.print_trait_item(trait_item));
                 }
                 try!(self.bclose(item.span));
             }
@@ -1006,7 +1025,7 @@ impl<'a> State<'a> {
             ast::ItemMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
                                             ..}) => {
                 try!(self.print_visibility(item.vis));
-                try!(self.print_path(pth, false));
+                try!(self.print_path(pth, false, 0));
                 try!(word(&mut self.s, "! "));
                 try!(self.print_ident(item.ident));
                 try!(self.cbox(indent_unit));
@@ -1020,11 +1039,11 @@ impl<'a> State<'a> {
         self.ann.post(self, NodeItem(item))
     }
 
-    fn print_trait_ref(&mut self, t: &ast::TraitRef) -> IoResult<()> {
-        self.print_path(&t.path, false)
+    fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> {
+        self.print_path(&t.path, false, 0)
     }
 
-    fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> IoResult<()> {
+    fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::Result<()> {
         if !lifetimes.is_empty() {
             try!(word(&mut self.s, "for<"));
             let mut comma = false;
@@ -1040,7 +1059,7 @@ impl<'a> State<'a> {
         Ok(())
     }
 
-    fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> IoResult<()> {
+    fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> io::Result<()> {
         try!(self.print_formal_lifetime_list(&t.bound_lifetimes));
         self.print_trait_ref(&t.trait_ref)
     }
@@ -1048,18 +1067,18 @@ impl<'a> State<'a> {
     pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
                           generics: &ast::Generics, ident: ast::Ident,
                           span: codemap::Span,
-                          visibility: ast::Visibility) -> IoResult<()> {
+                          visibility: ast::Visibility) -> io::Result<()> {
         try!(self.head(&visibility_qualified(visibility, "enum")));
         try!(self.print_ident(ident));
         try!(self.print_generics(generics));
-        try!(self.print_where_clause(generics));
+        try!(self.print_where_clause(&generics.where_clause));
         try!(space(&mut self.s));
         self.print_variants(&enum_definition.variants, span)
     }
 
     pub fn print_variants(&mut self,
                           variants: &[P<ast::Variant>],
-                          span: codemap::Span) -> IoResult<()> {
+                          span: codemap::Span) -> io::Result<()> {
         try!(self.bopen());
         for v in variants {
             try!(self.space_if_not_bol());
@@ -1074,7 +1093,7 @@ impl<'a> State<'a> {
         self.bclose(span)
     }
 
-    pub fn print_visibility(&mut self, vis: ast::Visibility) -> IoResult<()> {
+    pub fn print_visibility(&mut self, vis: ast::Visibility) -> io::Result<()> {
         match vis {
             ast::Public => self.word_nbsp("pub"),
             ast::Inherited => Ok(())
@@ -1085,7 +1104,7 @@ impl<'a> State<'a> {
                         struct_def: &ast::StructDef,
                         generics: &ast::Generics,
                         ident: ast::Ident,
-                        span: codemap::Span) -> IoResult<()> {
+                        span: codemap::Span) -> io::Result<()> {
         try!(self.print_ident(ident));
         try!(self.print_generics(generics));
         if ast_util::struct_def_is_tuple_like(struct_def) {
@@ -1106,12 +1125,12 @@ impl<'a> State<'a> {
                 ));
                 try!(self.pclose());
             }
-            try!(self.print_where_clause(generics));
+            try!(self.print_where_clause(&generics.where_clause));
             try!(word(&mut self.s, ";"));
             try!(self.end());
             self.end() // close the outer-box
         } else {
-            try!(self.print_where_clause(generics));
+            try!(self.print_where_clause(&generics.where_clause));
             try!(self.nbsp());
             try!(self.bopen());
             try!(self.hardbreak_if_not_bol());
@@ -1143,7 +1162,7 @@ impl<'a> State<'a> {
     /// appropriate macro, transcribe back into the grammar we just parsed from,
     /// and then pretty-print the resulting AST nodes (so, e.g., we print
     /// expression arguments as expressions). It can be done! I think.
-    pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
+    pub fn print_tt(&mut self, tt: &ast::TokenTree) -> io::Result<()> {
         match *tt {
             ast::TtToken(_, ref tk) => {
                 try!(word(&mut self.s, &token_to_string(tk)));
@@ -1181,7 +1200,7 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> IoResult<()> {
+    pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> io::Result<()> {
         try!(self.ibox(0));
         let mut suppress_space = false;
         for (i, tt) in tts.iter().enumerate() {
@@ -1201,7 +1220,7 @@ impl<'a> State<'a> {
         self.end()
     }
 
-    pub fn print_variant(&mut self, v: &ast::Variant) -> IoResult<()> {
+    pub fn print_variant(&mut self, v: &ast::Variant) -> io::Result<()> {
         try!(self.print_visibility(v.node.vis));
         match v.node.kind {
             ast::TupleVariantKind(ref args) => {
@@ -1230,75 +1249,80 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> {
-        try!(self.hardbreak_if_not_bol());
-        try!(self.maybe_print_comment(m.span.lo));
-        try!(self.print_outer_attributes(&m.attrs));
-        try!(self.print_ty_fn(m.abi,
-                              m.unsafety,
-                              &*m.decl,
-                              Some(m.ident),
-                              &m.generics,
-                              Some(&m.explicit_self.node)));
-        word(&mut self.s, ";")
-    }
-
-    pub fn print_trait_method(&mut self,
-                              m: &ast::TraitItem) -> IoResult<()> {
-        match *m {
-            RequiredMethod(ref ty_m) => self.print_ty_method(ty_m),
-            ProvidedMethod(ref m) => self.print_method(&**m),
-            TypeTraitItem(ref t) => self.print_associated_type(&**t),
-        }
+    pub fn print_method_sig(&mut self,
+                            ident: ast::Ident,
+                            m: &ast::MethodSig,
+                            vis: ast::Visibility)
+                            -> io::Result<()> {
+        self.print_fn(&m.decl,
+                      m.unsafety,
+                      m.abi,
+                      Some(ident),
+                      &m.generics,
+                      Some(&m.explicit_self.node),
+                      vis)
     }
 
-    pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> IoResult<()> {
-        match *ii {
-            MethodImplItem(ref m) => self.print_method(&**m),
-            TypeImplItem(ref td) => self.print_typedef(&**td),
+    pub fn print_trait_item(&mut self, ti: &ast::TraitItem)
+                            -> io::Result<()> {
+        try!(self.ann.pre(self, NodeSubItem(ti.id)));
+        try!(self.hardbreak_if_not_bol());
+        try!(self.maybe_print_comment(ti.span.lo));
+        try!(self.print_outer_attributes(&ti.attrs));
+        match ti.node {
+            ast::MethodTraitItem(ref sig, ref body) => {
+                if body.is_some() {
+                    try!(self.head(""));
+                }
+                try!(self.print_method_sig(ti.ident, sig, ast::Inherited));
+                if let Some(ref body) = *body {
+                    try!(self.nbsp());
+                    try!(self.print_block_with_attrs(body, &ti.attrs));
+                } else {
+                    try!(word(&mut self.s, ";"));
+                }
+            }
+            ast::TypeTraitItem(ref bounds, ref default) => {
+                try!(self.print_associated_type(ti.ident, Some(bounds),
+                                                default.as_ref().map(|ty| &**ty)));
+            }
         }
+        self.ann.post(self, NodeSubItem(ti.id))
     }
 
-    pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> {
+    pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> {
+        try!(self.ann.pre(self, NodeSubItem(ii.id)));
         try!(self.hardbreak_if_not_bol());
-        try!(self.maybe_print_comment(meth.span.lo));
-        try!(self.print_outer_attributes(&meth.attrs));
-        match meth.node {
-            ast::MethDecl(ident,
-                          ref generics,
-                          abi,
-                          ref explicit_self,
-                          unsafety,
-                          ref decl,
-                          ref body,
-                          vis) => {
-                try!(self.print_fn(&**decl,
-                                   Some(unsafety),
-                                   abi,
-                                   ident,
-                                   generics,
-                                   Some(&explicit_self.node),
-                                   vis));
-                try!(word(&mut self.s, " "));
-                self.print_block_with_attrs(&**body, &meth.attrs)
-            },
-            ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
-                                            ..}) => {
+        try!(self.maybe_print_comment(ii.span.lo));
+        try!(self.print_outer_attributes(&ii.attrs));
+        match ii.node {
+            ast::MethodImplItem(ref sig, ref body) => {
+                try!(self.head(""));
+                try!(self.print_method_sig(ii.ident, sig, ii.vis));
+                try!(self.nbsp());
+                try!(self.print_block_with_attrs(body, &ii.attrs));
+            }
+            ast::TypeImplItem(ref ty) => {
+                try!(self.print_associated_type(ii.ident, None, Some(ty)));
+            }
+            ast::MacImplItem(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
+                                                ..}) => {
                 // code copied from ItemMac:
-                try!(self.print_path(pth, false));
+                try!(self.print_path(pth, false, 0));
                 try!(word(&mut self.s, "! "));
                 try!(self.cbox(indent_unit));
                 try!(self.popen());
                 try!(self.print_tts(&tts[..]));
                 try!(self.pclose());
                 try!(word(&mut self.s, ";"));
-                self.end()
+                try!(self.end())
             }
         }
+        self.ann.post(self, NodeSubItem(ii.id))
     }
 
     pub fn print_outer_attributes(&mut self,
-                                  attrs: &[ast::Attribute]) -> IoResult<()> {
+                                  attrs: &[ast::Attribute]) -> io::Result<()> {
         let mut count = 0;
         for attr in attrs {
             match attr.node.style {
@@ -1316,7 +1340,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_inner_attributes(&mut self,
-                                  attrs: &[ast::Attribute]) -> IoResult<()> {
+                                  attrs: &[ast::Attribute]) -> io::Result<()> {
         let mut count = 0;
         for attr in attrs {
             match attr.node.style {
@@ -1333,7 +1357,7 @@ impl<'a> State<'a> {
         Ok(())
     }
 
-    pub fn print_attribute(&mut self, attr: &ast::Attribute) -> IoResult<()> {
+    pub fn print_attribute(&mut self, attr: &ast::Attribute) -> io::Result<()> {
         try!(self.hardbreak_if_not_bol());
         try!(self.maybe_print_comment(attr.span.lo));
         if attr.node.is_sugared_doc {
@@ -1349,7 +1373,7 @@ impl<'a> State<'a> {
     }
 
 
-    pub fn print_stmt(&mut self, st: &ast::Stmt) -> IoResult<()> {
+    pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> {
         try!(self.maybe_print_comment(st.span.lo));
         match st.node {
             ast::StmtDecl(ref decl, _) => {
@@ -1383,22 +1407,22 @@ impl<'a> State<'a> {
         self.maybe_print_trailing_comment(st.span, None)
     }
 
-    pub fn print_block(&mut self, blk: &ast::Block) -> IoResult<()> {
+    pub fn print_block(&mut self, blk: &ast::Block) -> io::Result<()> {
         self.print_block_with_attrs(blk, &[])
     }
 
-    pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> IoResult<()> {
+    pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> io::Result<()> {
         self.print_block_unclosed_indent(blk, indent_unit)
     }
 
     pub fn print_block_unclosed_indent(&mut self, blk: &ast::Block,
-                                       indented: usize) -> IoResult<()> {
+                                       indented: usize) -> io::Result<()> {
         self.print_block_maybe_unclosed(blk, indented, &[], false)
     }
 
     pub fn print_block_with_attrs(&mut self,
                                   blk: &ast::Block,
-                                  attrs: &[ast::Attribute]) -> IoResult<()> {
+                                  attrs: &[ast::Attribute]) -> io::Result<()> {
         self.print_block_maybe_unclosed(blk, indent_unit, attrs, true)
     }
 
@@ -1406,7 +1430,7 @@ impl<'a> State<'a> {
                                       blk: &ast::Block,
                                       indented: usize,
                                       attrs: &[ast::Attribute],
-                                      close_box: bool) -> IoResult<()> {
+                                      close_box: bool) -> io::Result<()> {
         match blk.rules {
             ast::UnsafeBlock(..) => try!(self.word_space("unsafe")),
             ast::DefaultBlock => ()
@@ -1432,7 +1456,7 @@ impl<'a> State<'a> {
         self.ann.post(self, NodeBlock(blk))
     }
 
-    fn print_else(&mut self, els: Option<&ast::Expr>) -> IoResult<()> {
+    fn print_else(&mut self, els: Option<&ast::Expr>) -> io::Result<()> {
         match els {
             Some(_else) => {
                 match _else.node {
@@ -1477,7 +1501,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block,
-                    elseopt: Option<&ast::Expr>) -> IoResult<()> {
+                    elseopt: Option<&ast::Expr>) -> io::Result<()> {
         try!(self.head("if"));
         try!(self.print_expr(test));
         try!(space(&mut self.s));
@@ -1486,7 +1510,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_if_let(&mut self, pat: &ast::Pat, expr: &ast::Expr, blk: &ast::Block,
-                        elseopt: Option<&ast::Expr>) -> IoResult<()> {
+                        elseopt: Option<&ast::Expr>) -> io::Result<()> {
         try!(self.head("if let"));
         try!(self.print_pat(pat));
         try!(space(&mut self.s));
@@ -1498,11 +1522,11 @@ impl<'a> State<'a> {
     }
 
     pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken)
-                     -> IoResult<()> {
+                     -> io::Result<()> {
         match m.node {
             // I think it's reasonable to hide the ctxt here:
             ast::MacInvocTT(ref pth, ref tts, _) => {
-                try!(self.print_path(pth, false));
+                try!(self.print_path(pth, false, 0));
                 try!(word(&mut self.s, "!"));
                 match delim {
                     token::Paren => try!(self.popen()),
@@ -1520,13 +1544,13 @@ impl<'a> State<'a> {
     }
 
 
-    fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> IoResult<()> {
+    fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> io::Result<()> {
         try!(self.popen());
         try!(self.commasep_exprs(Inconsistent, args));
         self.pclose()
     }
 
-    pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> IoResult<()> {
+    pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> io::Result<()> {
         let needs_par = needs_parentheses(expr);
         if needs_par {
             try!(self.popen());
@@ -1540,7 +1564,7 @@ impl<'a> State<'a> {
 
     fn print_expr_box(&mut self,
                       place: &Option<P<ast::Expr>>,
-                      expr: &ast::Expr) -> IoResult<()> {
+                      expr: &ast::Expr) -> io::Result<()> {
         try!(word(&mut self.s, "box"));
         try!(word(&mut self.s, "("));
         try!(place.as_ref().map_or(Ok(()), |e|self.print_expr(&**e)));
@@ -1548,7 +1572,7 @@ impl<'a> State<'a> {
         self.print_expr(expr)
     }
 
-    fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> {
+    fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> io::Result<()> {
         try!(self.ibox(indent_unit));
         try!(word(&mut self.s, "["));
         try!(self.commasep_exprs(Inconsistent, &exprs[..]));
@@ -1558,7 +1582,7 @@ impl<'a> State<'a> {
 
     fn print_expr_repeat(&mut self,
                          element: &ast::Expr,
-                         count: &ast::Expr) -> IoResult<()> {
+                         count: &ast::Expr) -> io::Result<()> {
         try!(self.ibox(indent_unit));
         try!(word(&mut self.s, "["));
         try!(self.print_expr(element));
@@ -1571,8 +1595,8 @@ impl<'a> State<'a> {
     fn print_expr_struct(&mut self,
                          path: &ast::Path,
                          fields: &[ast::Field],
-                         wth: &Option<P<ast::Expr>>) -> IoResult<()> {
-        try!(self.print_path(path, true));
+                         wth: &Option<P<ast::Expr>>) -> io::Result<()> {
+        try!(self.print_path(path, true, 0));
         if !(fields.is_empty() && wth.is_none()) {
             try!(word(&mut self.s, "{"));
             try!(self.commasep_cmnt(
@@ -1604,7 +1628,7 @@ impl<'a> State<'a> {
         Ok(())
     }
 
-    fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> {
+    fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> io::Result<()> {
         try!(self.popen());
         try!(self.commasep_exprs(Inconsistent, &exprs[..]));
         if exprs.len() == 1 {
@@ -1615,7 +1639,7 @@ impl<'a> State<'a> {
 
     fn print_expr_call(&mut self,
                        func: &ast::Expr,
-                       args: &[P<ast::Expr>]) -> IoResult<()> {
+                       args: &[P<ast::Expr>]) -> io::Result<()> {
         try!(self.print_expr_maybe_paren(func));
         self.print_call_post(args)
     }
@@ -1623,7 +1647,7 @@ impl<'a> State<'a> {
     fn print_expr_method_call(&mut self,
                               ident: ast::SpannedIdent,
                               tys: &[P<ast::Ty>],
-                              args: &[P<ast::Expr>]) -> IoResult<()> {
+                              args: &[P<ast::Expr>]) -> io::Result<()> {
         let base_args = &args[1..];
         try!(self.print_expr(&*args[0]));
         try!(word(&mut self.s, "."));
@@ -1640,7 +1664,7 @@ impl<'a> State<'a> {
     fn print_expr_binary(&mut self,
                          op: ast::BinOp,
                          lhs: &ast::Expr,
-                         rhs: &ast::Expr) -> IoResult<()> {
+                         rhs: &ast::Expr) -> io::Result<()> {
         try!(self.print_expr(lhs));
         try!(space(&mut self.s));
         try!(self.word_space(ast_util::binop_to_string(op.node)));
@@ -1649,20 +1673,20 @@ impl<'a> State<'a> {
 
     fn print_expr_unary(&mut self,
                         op: ast::UnOp,
-                        expr: &ast::Expr) -> IoResult<()> {
+                        expr: &ast::Expr) -> io::Result<()> {
         try!(word(&mut self.s, ast_util::unop_to_string(op)));
         self.print_expr_maybe_paren(expr)
     }
 
     fn print_expr_addr_of(&mut self,
                           mutability: ast::Mutability,
-                          expr: &ast::Expr) -> IoResult<()> {
+                          expr: &ast::Expr) -> io::Result<()> {
         try!(word(&mut self.s, "&"));
         try!(self.print_mutability(mutability));
         self.print_expr_maybe_paren(expr)
     }
 
-    pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
+    pub fn print_expr(&mut self, expr: &ast::Expr) -> io::Result<()> {
         try!(self.maybe_print_comment(expr.span.lo));
         try!(self.ibox(indent_unit));
         try!(self.ann.pre(self, NodeExpr(expr)));
@@ -1775,7 +1799,12 @@ impl<'a> State<'a> {
                 try!(self.print_fn_block_args(&**decl));
                 try!(space(&mut self.s));
 
-                if !body.stmts.is_empty() || !body.expr.is_some() {
+                let default_return = match decl.output {
+                    ast::DefaultReturn(..) => true,
+                    _ => false
+                };
+
+                if !default_return || !body.stmts.is_empty() || body.expr.is_none() {
                     try!(self.print_block_unclosed(&**body));
                 } else {
                     // we extract the block, so as not to create another set of boxes
@@ -1840,8 +1869,12 @@ impl<'a> State<'a> {
                     try!(self.print_expr(&**e));
                 }
             }
-            ast::ExprPath(ref path) => try!(self.print_path(path, true)),
-            ast::ExprQPath(ref qpath) => try!(self.print_qpath(&**qpath, true)),
+            ast::ExprPath(None, ref path) => {
+                try!(self.print_path(path, true, 0))
+            }
+            ast::ExprPath(Some(ref qself), ref path) => {
+                try!(self.print_qpath(path, qself, true))
+            }
             ast::ExprBreak(opt_ident) => {
                 try!(word(&mut self.s, "break"));
                 try!(space(&mut self.s));
@@ -1942,7 +1975,7 @@ impl<'a> State<'a> {
         self.end()
     }
 
-    pub fn print_local_decl(&mut self, loc: &ast::Local) -> IoResult<()> {
+    pub fn print_local_decl(&mut self, loc: &ast::Local) -> io::Result<()> {
         try!(self.print_pat(&*loc.pat));
         if let Some(ref ty) = loc.ty {
             try!(self.word_space(":"));
@@ -1951,7 +1984,7 @@ impl<'a> State<'a> {
         Ok(())
     }
 
-    pub fn print_decl(&mut self, decl: &ast::Decl) -> IoResult<()> {
+    pub fn print_decl(&mut self, decl: &ast::Decl) -> io::Result<()> {
         try!(self.maybe_print_comment(decl.span.lo));
         match decl.node {
             ast::DeclLocal(ref loc) => {
@@ -1973,7 +2006,7 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> {
+    pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
         if self.encode_idents_with_hygiene {
             let encoded = ident.encode_with_hygiene();
             try!(word(&mut self.s, &encoded[..]))
@@ -1983,17 +2016,17 @@ impl<'a> State<'a> {
         self.ann.post(self, NodeIdent(&ident))
     }
 
-    pub fn print_usize(&mut self, i: usize) -> IoResult<()> {
+    pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
         word(&mut self.s, &i.to_string())
     }
 
-    pub fn print_name(&mut self, name: ast::Name) -> IoResult<()> {
+    pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
         try!(word(&mut self.s, &token::get_name(name)));
         self.ann.post(self, NodeName(&name))
     }
 
     pub fn print_for_decl(&mut self, loc: &ast::Local,
-                          coll: &ast::Expr) -> IoResult<()> {
+                          coll: &ast::Expr) -> io::Result<()> {
         try!(self.print_local_decl(loc));
         try!(space(&mut self.s));
         try!(self.word_space("in"));
@@ -2002,16 +2035,14 @@ impl<'a> State<'a> {
 
     fn print_path(&mut self,
                   path: &ast::Path,
-                  colons_before_params: bool)
-                  -> IoResult<()>
+                  colons_before_params: bool,
+                  depth: usize)
+                  -> io::Result<()>
     {
         try!(self.maybe_print_comment(path.span.lo));
-        if path.global {
-            try!(word(&mut self.s, "::"));
-        }
 
-        let mut first = true;
-        for segment in &path.segments {
+        let mut first = !path.global;
+        for segment in &path.segments[..path.segments.len()-depth] {
             if first {
                 first = false
             } else {
@@ -2027,25 +2058,30 @@ impl<'a> State<'a> {
     }
 
     fn print_qpath(&mut self,
-                   qpath: &ast::QPath,
+                   path: &ast::Path,
+                   qself: &ast::QSelf,
                    colons_before_params: bool)
-                   -> IoResult<()>
+                   -> io::Result<()>
     {
         try!(word(&mut self.s, "<"));
-        try!(self.print_type(&*qpath.self_type));
-        try!(space(&mut self.s));
-        try!(self.word_space("as"));
-        try!(self.print_trait_ref(&*qpath.trait_ref));
+        try!(self.print_type(&qself.ty));
+        if qself.position > 0 {
+            try!(space(&mut self.s));
+            try!(self.word_space("as"));
+            let depth = path.segments.len() - qself.position;
+            try!(self.print_path(&path, false, depth));
+        }
         try!(word(&mut self.s, ">"));
         try!(word(&mut self.s, "::"));
-        try!(self.print_ident(qpath.item_path.identifier));
-        self.print_path_parameters(&qpath.item_path.parameters, colons_before_params)
+        let item_segment = path.segments.last().unwrap();
+        try!(self.print_ident(item_segment.identifier));
+        self.print_path_parameters(&item_segment.parameters, colons_before_params)
     }
 
     fn print_path_parameters(&mut self,
                              parameters: &ast::PathParameters,
                              colons_before_params: bool)
-                             -> IoResult<()>
+                             -> io::Result<()>
     {
         if parameters.is_empty() {
             return Ok(());
@@ -2115,7 +2151,7 @@ impl<'a> State<'a> {
         Ok(())
     }
 
-    pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
+    pub fn print_pat(&mut self, pat: &ast::Pat) -> io::Result<()> {
         try!(self.maybe_print_comment(pat.span.lo));
         try!(self.ann.pre(self, NodePat(pat)));
         /* Pat isn't normalized, but the beauty of it
@@ -2144,7 +2180,7 @@ impl<'a> State<'a> {
                 }
             }
             ast::PatEnum(ref path, ref args_) => {
-                try!(self.print_path(path, true));
+                try!(self.print_path(path, true, 0));
                 match *args_ {
                     None => try!(word(&mut self.s, "(..)")),
                     Some(ref args) => {
@@ -2158,7 +2194,7 @@ impl<'a> State<'a> {
                 }
             }
             ast::PatStruct(ref path, ref fields, etc) => {
-                try!(self.print_path(path, true));
+                try!(self.print_path(path, true, 0));
                 try!(self.nbsp());
                 try!(self.word_space("{"));
                 try!(self.commasep_cmnt(
@@ -2234,7 +2270,7 @@ impl<'a> State<'a> {
         self.ann.post(self, NodePat(pat))
     }
 
-    fn print_arm(&mut self, arm: &ast::Arm) -> IoResult<()> {
+    fn print_arm(&mut self, arm: &ast::Arm) -> io::Result<()> {
         // I have no idea why this check is necessary, but here it
         // is :(
         if arm.attrs.is_empty() {
@@ -2283,7 +2319,7 @@ impl<'a> State<'a> {
     // Returns whether it printed anything
     fn print_explicit_self(&mut self,
                            explicit_self: &ast::ExplicitSelf_,
-                           mutbl: ast::Mutability) -> IoResult<bool> {
+                           mutbl: ast::Mutability) -> io::Result<bool> {
         try!(self.print_mutability(mutbl));
         match *explicit_self {
             ast::SelfStatic => { return Ok(false); }
@@ -2307,24 +2343,26 @@ impl<'a> State<'a> {
 
     pub fn print_fn(&mut self,
                     decl: &ast::FnDecl,
-                    unsafety: Option<ast::Unsafety>,
+                    unsafety: ast::Unsafety,
                     abi: abi::Abi,
-                    name: ast::Ident,
+                    name: Option<ast::Ident>,
                     generics: &ast::Generics,
                     opt_explicit_self: Option<&ast::ExplicitSelf_>,
-                    vis: ast::Visibility) -> IoResult<()> {
-        try!(self.head(""));
+                    vis: ast::Visibility) -> io::Result<()> {
         try!(self.print_fn_header_info(unsafety, abi, vis));
-        try!(self.nbsp());
-        try!(self.print_ident(name));
+
+        if let Some(name) = name {
+            try!(self.nbsp());
+            try!(self.print_ident(name));
+        }
         try!(self.print_generics(generics));
         try!(self.print_fn_args_and_ret(decl, opt_explicit_self));
-        self.print_where_clause(generics)
+        self.print_where_clause(&generics.where_clause)
     }
 
     pub fn print_fn_args(&mut self, decl: &ast::FnDecl,
                          opt_explicit_self: Option<&ast::ExplicitSelf_>)
-        -> IoResult<()> {
+        -> io::Result<()> {
         // It is unfortunate to duplicate the commasep logic, but we want the
         // self type and the args all in the same box.
         try!(self.rbox(0, Inconsistent));
@@ -2342,7 +2380,7 @@ impl<'a> State<'a> {
 
         // HACK(eddyb) ignore the separately printed self argument.
         let args = if first {
-            &decl.inputs[]
+            &decl.inputs[..]
         } else {
             &decl.inputs[1..]
         };
@@ -2357,7 +2395,7 @@ impl<'a> State<'a> {
 
     pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl,
                                  opt_explicit_self: Option<&ast::ExplicitSelf_>)
-        -> IoResult<()> {
+        -> io::Result<()> {
         try!(self.popen());
         try!(self.print_fn_args(decl, opt_explicit_self));
         if decl.variadic {
@@ -2371,7 +2409,7 @@ impl<'a> State<'a> {
     pub fn print_fn_block_args(
             &mut self,
             decl: &ast::FnDecl)
-            -> IoResult<()> {
+            -> io::Result<()> {
         try!(word(&mut self.s, "|"));
         try!(self.print_fn_args(decl, None));
         try!(word(&mut self.s, "|"));
@@ -2396,7 +2434,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause)
-                                -> IoResult<()> {
+                                -> io::Result<()> {
         match capture_clause {
             ast::CaptureByValue => self.word_space("move"),
             ast::CaptureByRef => Ok(()),
@@ -2406,7 +2444,7 @@ impl<'a> State<'a> {
     pub fn print_bounds(&mut self,
                         prefix: &str,
                         bounds: &[ast::TyParamBound])
-                        -> IoResult<()> {
+                        -> io::Result<()> {
         if !bounds.is_empty() {
             try!(word(&mut self.s, prefix));
             let mut first = true;
@@ -2439,14 +2477,14 @@ impl<'a> State<'a> {
 
     pub fn print_lifetime(&mut self,
                           lifetime: &ast::Lifetime)
-                          -> IoResult<()>
+                          -> io::Result<()>
     {
         self.print_name(lifetime.name)
     }
 
     pub fn print_lifetime_def(&mut self,
                               lifetime: &ast::LifetimeDef)
-                              -> IoResult<()>
+                              -> io::Result<()>
     {
         try!(self.print_lifetime(&lifetime.lifetime));
         let mut sep = ":";
@@ -2460,7 +2498,7 @@ impl<'a> State<'a> {
 
     pub fn print_generics(&mut self,
                           generics: &ast::Generics)
-                          -> IoResult<()>
+                          -> io::Result<()>
     {
         let total = generics.lifetimes.len() + generics.ty_params.len();
         if total == 0 {
@@ -2489,7 +2527,7 @@ impl<'a> State<'a> {
         Ok(())
     }
 
-    pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> {
+    pub fn print_ty_param(&mut self, param: &ast::TyParam) -> io::Result<()> {
         try!(self.print_ident(param.ident));
         try!(self.print_bounds(":", &param.bounds));
         match param.default {
@@ -2502,19 +2540,16 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_where_clause(&mut self, generics: &ast::Generics)
-                              -> IoResult<()> {
-        if generics.where_clause.predicates.len() == 0 {
+    pub fn print_where_clause(&mut self, where_clause: &ast::WhereClause)
+                              -> io::Result<()> {
+        if where_clause.predicates.len() == 0 {
             return Ok(())
         }
 
         try!(space(&mut self.s));
         try!(self.word_space("where"));
 
-        for (i, predicate) in generics.where_clause
-                                      .predicates
-                                      .iter()
-                                      .enumerate() {
+        for (i, predicate) in where_clause.predicates.iter().enumerate() {
             if i != 0 {
                 try!(self.word_space(","));
             }
@@ -2543,7 +2578,7 @@ impl<'a> State<'a> {
                     }
                 }
                 &ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref path, ref ty, ..}) => {
-                    try!(self.print_path(path, false));
+                    try!(self.print_path(path, false, 0));
                     try!(space(&mut self.s));
                     try!(self.word_space("="));
                     try!(self.print_type(&**ty));
@@ -2554,7 +2589,7 @@ impl<'a> State<'a> {
         Ok(())
     }
 
-    pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> IoResult<()> {
+    pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> {
         try!(self.ibox(indent_unit));
         match item.node {
             ast::MetaWord(ref name) => {
@@ -2577,10 +2612,10 @@ impl<'a> State<'a> {
         self.end()
     }
 
-    pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> {
+    pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> io::Result<()> {
         match vp.node {
             ast::ViewPathSimple(ident, ref path) => {
-                try!(self.print_path(path, false));
+                try!(self.print_path(path, false, 0));
 
                 // FIXME(#6993) can't compare identifiers directly here
                 if path.segments.last().unwrap().identifier.name !=
@@ -2594,7 +2629,7 @@ impl<'a> State<'a> {
             }
 
             ast::ViewPathGlob(ref path) => {
-                try!(self.print_path(path, false));
+                try!(self.print_path(path, false, 0));
                 word(&mut self.s, "::*")
             }
 
@@ -2602,7 +2637,7 @@ impl<'a> State<'a> {
                 if path.segments.is_empty() {
                     try!(word(&mut self.s, "{"));
                 } else {
-                    try!(self.print_path(path, false));
+                    try!(self.print_path(path, false, 0));
                     try!(word(&mut self.s, "::{"));
                 }
                 try!(self.commasep(Inconsistent, &idents[..], |s, w| {
@@ -2621,19 +2656,19 @@ impl<'a> State<'a> {
     }
 
     pub fn print_mutability(&mut self,
-                            mutbl: ast::Mutability) -> IoResult<()> {
+                            mutbl: ast::Mutability) -> io::Result<()> {
         match mutbl {
             ast::MutMutable => self.word_nbsp("mut"),
             ast::MutImmutable => Ok(()),
         }
     }
 
-    pub fn print_mt(&mut self, mt: &ast::MutTy) -> IoResult<()> {
+    pub fn print_mt(&mut self, mt: &ast::MutTy) -> io::Result<()> {
         try!(self.print_mutability(mt.mutbl));
         self.print_type(&*mt.ty)
     }
 
-    pub fn print_arg(&mut self, input: &ast::Arg) -> IoResult<()> {
+    pub fn print_arg(&mut self, input: &ast::Arg) -> io::Result<()> {
         try!(self.ibox(indent_unit));
         match input.ty.node {
             ast::TyInfer => try!(self.print_pat(&*input.pat)),
@@ -2656,7 +2691,7 @@ impl<'a> State<'a> {
         self.end()
     }
 
-    pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
+    pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> io::Result<()> {
         if let ast::DefaultReturn(..) = decl.output {
             return Ok(());
         }
@@ -2683,31 +2718,32 @@ impl<'a> State<'a> {
                        abi: abi::Abi,
                        unsafety: ast::Unsafety,
                        decl: &ast::FnDecl,
-                       id: Option<ast::Ident>,
+                       name: Option<ast::Ident>,
                        generics: &ast::Generics,
                        opt_explicit_self: Option<&ast::ExplicitSelf_>)
-                       -> IoResult<()> {
+                       -> io::Result<()> {
         try!(self.ibox(indent_unit));
-        try!(self.print_fn_header_info(Some(unsafety), abi, ast::Inherited));
-
-        match id {
-            Some(id) => {
-                try!(word(&mut self.s, " "));
-                try!(self.print_ident(id));
-            }
-            _ => ()
-        }
-
-        try!(self.print_generics(generics));
-        try!(zerobreak(&mut self.s));
-        try!(self.print_fn_args_and_ret(decl, opt_explicit_self));
-        try!(self.print_where_clause(generics));
+        if generics.lifetimes.len() > 0 || generics.ty_params.len() > 0 {
+            try!(word(&mut self.s, "for"));
+            try!(self.print_generics(generics));
+        }
+        let generics = ast::Generics {
+            lifetimes: Vec::new(),
+            ty_params: OwnedSlice::empty(),
+            where_clause: ast::WhereClause {
+                id: ast::DUMMY_NODE_ID,
+                predicates: Vec::new(),
+            },
+        };
+        try!(self.print_fn(decl, unsafety, abi, name,
+                           &generics, opt_explicit_self,
+                           ast::Inherited));
         self.end()
     }
 
     pub fn maybe_print_trailing_comment(&mut self, span: codemap::Span,
                                         next_pos: Option<BytePos>)
-        -> IoResult<()> {
+        -> io::Result<()> {
         let cm = match self.cm {
             Some(cm) => cm,
             _ => return Ok(())
@@ -2730,7 +2766,7 @@ impl<'a> State<'a> {
         Ok(())
     }
 
-    pub fn print_remaining_comments(&mut self) -> IoResult<()> {
+    pub fn print_remaining_comments(&mut self) -> io::Result<()> {
         // If there aren't any remaining comments, then we need to manually
         // make sure there is a line break at the end.
         if self.next_comment().is_none() {
@@ -2748,7 +2784,7 @@ impl<'a> State<'a> {
         Ok(())
     }
 
-    pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
+    pub fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> {
         try!(self.maybe_print_comment(lit.span.lo));
         match self.next_lit(lit.span.lo) {
             Some(ref ltrl) => {
@@ -2806,7 +2842,7 @@ impl<'a> State<'a> {
             ast::LitBinary(ref v) => {
                 let mut escaped: String = String::new();
                 for &ch in &**v {
-                    escaped.extend(ascii::escape_default(ch as u8)
+                    escaped.extend(ascii::escape_default(ch)
                                          .map(|c| c as char));
                 }
                 word(&mut self.s, &format!("b\"{}\"", escaped))
@@ -2829,7 +2865,7 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn maybe_print_comment(&mut self, pos: BytePos) -> IoResult<()> {
+    pub fn maybe_print_comment(&mut self, pos: BytePos) -> io::Result<()> {
         loop {
             match self.next_comment() {
                 Some(ref cmnt) => {
@@ -2845,7 +2881,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_comment(&mut self,
-                         cmnt: &comments::Comment) -> IoResult<()> {
+                         cmnt: &comments::Comment) -> io::Result<()> {
         match cmnt.style {
             comments::Mixed => {
                 assert_eq!(cmnt.lines.len(), 1);
@@ -2896,7 +2932,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_string(&mut self, st: &str,
-                        style: ast::StrStyle) -> IoResult<()> {
+                        style: ast::StrStyle) -> io::Result<()> {
         let st = match style {
             ast::CookedStr => {
                 (format!("\"{}\"", st.escape_default()))
@@ -2923,17 +2959,9 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_opt_unsafety(&mut self,
-                            opt_unsafety: Option<ast::Unsafety>) -> IoResult<()> {
-        match opt_unsafety {
-            Some(unsafety) => self.print_unsafety(unsafety),
-            None => Ok(())
-        }
-    }
-
     pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
                                                   opt_abi: Option<abi::Abi>)
-        -> IoResult<()> {
+        -> io::Result<()> {
         match opt_abi {
             Some(abi::Rust) => Ok(()),
             Some(abi) => {
@@ -2945,7 +2973,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_extern_opt_abi(&mut self,
-                                opt_abi: Option<abi::Abi>) -> IoResult<()> {
+                                opt_abi: Option<abi::Abi>) -> io::Result<()> {
         match opt_abi {
             Some(abi) => {
                 try!(self.word_nbsp("extern"));
@@ -2956,11 +2984,11 @@ impl<'a> State<'a> {
     }
 
     pub fn print_fn_header_info(&mut self,
-                                opt_unsafety: Option<ast::Unsafety>,
+                                unsafety: ast::Unsafety,
                                 abi: abi::Abi,
-                                vis: ast::Visibility) -> IoResult<()> {
+                                vis: ast::Visibility) -> io::Result<()> {
         try!(word(&mut self.s, &visibility_qualified(vis, "")));
-        try!(self.print_opt_unsafety(opt_unsafety));
+        try!(self.print_unsafety(unsafety));
 
         if abi != abi::Rust {
             try!(self.word_nbsp("extern"));
@@ -2970,7 +2998,7 @@ impl<'a> State<'a> {
         word(&mut self.s, "fn")
     }
 
-    pub fn print_unsafety(&mut self, s: ast::Unsafety) -> IoResult<()> {
+    pub fn print_unsafety(&mut self, s: ast::Unsafety) -> io::Result<()> {
         match s {
             ast::Unsafety::Normal => Ok(()),
             ast::Unsafety::Unsafe => self.word_nbsp("unsafe"),
@@ -3025,7 +3053,7 @@ mod test {
     #[test]
     fn test_signed_int_to_string() {
         let pos_int = ast::LitInt(42, ast::SignedIntLit(ast::TyI32, ast::Plus));
-        let neg_int = ast::LitInt((-42) as u64, ast::SignedIntLit(ast::TyI32, ast::Minus));
+        let neg_int = ast::LitInt((!42 + 1) as u64, ast::SignedIntLit(ast::TyI32, ast::Minus));
         assert_eq!(format!("-{}", lit_to_string(&codemap::dummy_spanned(pos_int))),
                    lit_to_string(&codemap::dummy_spanned(neg_int)));
     }
index adb5383a8fd544d0f666dbf74d92e2fb729f20d5..7e0bcd3e1dc3f8a2229823209c8d47a9cb722bdc 100644 (file)
@@ -71,8 +71,8 @@ impl<T: 'static> P<T> {
     {
         unsafe {
             let p = &mut *self.ptr;
-            // FIXME(#5016) this shouldn't need to zero to be safe.
-            ptr::write(p, f(ptr::read_and_zero(p)));
+            // FIXME(#5016) this shouldn't need to drop-fill to be safe.
+            ptr::write(p, f(ptr::read_and_drop(p)));
         }
         self
     }
@@ -111,13 +111,6 @@ impl<T: Display> Display for P<T> {
     }
 }
 
-#[cfg(stage0)]
-impl<S: Hasher, T: Hash<S>> Hash<S> for P<T> {
-    fn hash(&self, state: &mut S) {
-        (**self).hash(state);
-    }
-}
-#[cfg(not(stage0))]
 impl<T: Hash> Hash for P<T> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         (**self).hash(state);
index 4e4a571ede7b864af3b797be5784fb6fc582e7b9..021ec4738ed94416797fd687d1178be21eaaad34 100644 (file)
@@ -38,7 +38,7 @@ pub fn maybe_inject_prelude(krate: ast::Crate) -> ast::Crate {
 }
 
 pub fn use_std(krate: &ast::Crate) -> bool {
-    !attr::contains_name(&krate.attrs[], "no_std")
+    !attr::contains_name(&krate.attrs, "no_std")
 }
 
 fn no_prelude(attrs: &[ast::Attribute]) -> bool {
@@ -52,10 +52,10 @@ struct StandardLibraryInjector {
 impl fold::Folder for StandardLibraryInjector {
     fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
 
-        // The name to use in `extern crate "name" as std;`
+        // The name to use in `extern crate name as std;`
         let actual_crate_name = match self.alt_std_name {
-            Some(ref s) => token::intern_and_get_ident(&s[..]),
-            None => token::intern_and_get_ident("std"),
+            Some(ref s) => token::intern(&s),
+            None => token::intern("std"),
         };
 
         krate.module.items.insert(0, P(ast::Item {
@@ -64,7 +64,7 @@ impl fold::Folder for StandardLibraryInjector {
             attrs: vec!(
                 attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
                         InternedString::new("macro_use")))),
-            node: ast::ItemExternCrate(Some((actual_crate_name, ast::CookedStr))),
+            node: ast::ItemExternCrate(Some(actual_crate_name)),
             vis: ast::Inherited,
             span: DUMMY_SP
         }));
@@ -88,14 +88,14 @@ impl fold::Folder for PreludeInjector {
         // only add `use std::prelude::*;` if there wasn't a
         // `#![no_implicit_prelude]` at the crate level.
         // fold_mod() will insert glob path.
-        if !no_prelude(&krate.attrs[]) {
+        if !no_prelude(&krate.attrs) {
             krate.module = self.fold_mod(krate.module);
         }
         krate
     }
 
     fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
-        if !no_prelude(&item.attrs[]) {
+        if !no_prelude(&item.attrs) {
             // only recur if there wasn't `#![no_implicit_prelude]`
             // on this item, i.e. this means that the prelude is not
             // implicitly imported though the whole subtree
index 7b1fc91e45b5bb3547841faf5f7505210a03b5f0..fbee11ee657c3411740dc29305edf7296c42acd7 100644 (file)
@@ -37,7 +37,7 @@ use {ast, ast_util};
 use ptr::P;
 use util::small_vector::SmallVector;
 
-enum ShouldFail {
+enum ShouldPanic {
     No,
     Yes(Option<InternedString>),
 }
@@ -47,7 +47,7 @@ struct Test {
     path: Vec<ast::Ident> ,
     bench: bool,
     ignore: bool,
-    should_fail: ShouldFail
+    should_panic: ShouldPanic
 }
 
 struct TestCtxt<'a> {
@@ -73,14 +73,14 @@ pub fn modify_for_testing(sess: &ParseSess,
     // We generate the test harness when building in the 'test'
     // configuration, either with the '--test' or '--cfg test'
     // command line options.
-    let should_test = attr::contains_name(&krate.config[], "test");
+    let should_test = attr::contains_name(&krate.config, "test");
 
     // Check for #[reexport_test_harness_main = "some_name"] which
     // creates a `use some_name = __test::main;`. This needs to be
     // unconditional, so that the attribute is still marked as used in
     // non-test builds.
     let reexport_test_harness_main =
-        attr::first_attr_value_str_by_name(&krate.attrs[],
+        attr::first_attr_value_str_by_name(&krate.attrs,
                                            "reexport_test_harness_main");
 
     if should_test {
@@ -121,13 +121,11 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
         debug!("current path: {}",
                ast_util::path_name_i(&self.cx.path));
 
-        if is_test_fn(&self.cx, &*i) || is_bench_fn(&self.cx, &*i) {
+        let i = if is_test_fn(&self.cx, &*i) || is_bench_fn(&self.cx, &*i) {
             match i.node {
                 ast::ItemFn(_, ast::Unsafety::Unsafe, _, _, _) => {
                     let diag = self.cx.span_diagnostic;
-                    diag.span_fatal(i.span,
-                                    "unsafe functions cannot be used for \
-                                     tests");
+                    diag.span_fatal(i.span, "unsafe functions cannot be used for tests");
                 }
                 _ => {
                     debug!("this is a test function");
@@ -136,15 +134,25 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
                         path: self.cx.path.clone(),
                         bench: is_bench_fn(&self.cx, &*i),
                         ignore: is_ignored(&*i),
-                        should_fail: should_fail(&*i)
+                        should_panic: should_panic(&*i)
                     };
                     self.cx.testfns.push(test);
                     self.tests.push(i.ident);
                     // debug!("have {} test/bench functions",
                     //        cx.testfns.len());
+
+                    // Make all tests public so we can call them from outside
+                    // the module (note that the tests are re-exported and must
+                    // be made public themselves to avoid privacy errors).
+                    i.map(|mut i| {
+                        i.vis = ast::Public;
+                        i
+                    })
                 }
             }
-        }
+        } else {
+            i
+        };
 
         // We don't want to recurse into anything other than mods, since
         // mods or tests inside of functions will break things
@@ -256,7 +264,8 @@ fn generate_test_harness(sess: &ParseSess,
         callee: NameAndSpan {
             name: "test".to_string(),
             format: MacroAttribute,
-            span: None
+            span: None,
+            allow_internal_unstable: false,
         }
     });
 
@@ -288,7 +297,8 @@ fn ignored_span(cx: &TestCtxt, sp: Span) -> Span {
         callee: NameAndSpan {
             name: "test".to_string(),
             format: MacroAttribute,
-            span: None
+            span: None,
+            allow_internal_unstable: true,
         }
     };
     let expn_id = cx.sess.span_diagnostic.cm.record_expansion(info);
@@ -306,7 +316,7 @@ enum HasTestSignature {
 
 
 fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
-    let has_test_attr = attr::contains_name(&i.attrs[], "test");
+    let has_test_attr = attr::contains_name(&i.attrs, "test");
 
     fn has_test_signature(i: &ast::Item) -> HasTestSignature {
         match &i.node {
@@ -342,7 +352,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
 }
 
 fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
-    let has_bench_attr = attr::contains_name(&i.attrs[], "bench");
+    let has_bench_attr = attr::contains_name(&i.attrs, "bench");
 
     fn has_test_signature(i: &ast::Item) -> bool {
         match i.node {
@@ -376,15 +386,15 @@ fn is_ignored(i: &ast::Item) -> bool {
     i.attrs.iter().any(|attr| attr.check_name("ignore"))
 }
 
-fn should_fail(i: &ast::Item) -> ShouldFail {
-    match i.attrs.iter().find(|attr| attr.check_name("should_fail")) {
+fn should_panic(i: &ast::Item) -> ShouldPanic {
+    match i.attrs.iter().find(|attr| attr.check_name("should_panic")) {
         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)
+            ShouldPanic::Yes(msg)
         }
-        None => ShouldFail::No,
+        None => ShouldPanic::No,
     }
 }
 
@@ -562,7 +572,7 @@ fn mk_tests(cx: &TestCtxt) -> P<ast::Item> {
 }
 
 fn is_test_crate(krate: &ast::Crate) -> bool {
-    match attr::find_crate_name(&krate.attrs[]) {
+    match attr::find_crate_name(&krate.attrs) {
         Some(ref s) if "test" == &s[..] => true,
         _ => false
     }
@@ -615,13 +625,13 @@ 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 should_fail_path = |name| {
-        ecx.path(span, vec![self_id, test_id, ecx.ident_of("ShouldFail"), ecx.ident_of(name)])
+    let should_panic_path = |name| {
+        ecx.path(span, vec![self_id, test_id, ecx.ident_of("ShouldPanic"), 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 fail_expr = match test.should_panic {
+        ShouldPanic::No => ecx.expr_path(should_panic_path("No")),
+        ShouldPanic::Yes(ref msg) => {
+            let path = should_panic_path("Yes");
             let arg = match *msg {
                 Some(ref msg) => ecx.expr_some(span, ecx.expr_str(span, msg.clone())),
                 None => ecx.expr_none(span),
@@ -636,7 +646,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
         test_path("TestDesc"),
         vec![field("name", name_expr),
              field("ignore", ignore_expr),
-             field("should_fail", fail_expr)]);
+             field("should_panic", fail_expr)]);
 
 
     let mut visible_path = match cx.toplevel_reexport {
index dffeac6f3f7938df88ae352309b3a9fb068c42f3..7ae9e4646e516b32bee9972485f904b3f974d2d6 100644 (file)
@@ -18,7 +18,6 @@ use std::borrow::Borrow;
 use std::cell::RefCell;
 use std::cmp::Ordering;
 use std::collections::HashMap;
-#[cfg(stage0)] use std::collections::hash_map::Hasher;
 use std::fmt;
 use std::hash::Hash;
 use std::ops::Deref;
@@ -30,71 +29,6 @@ pub struct Interner<T> {
 }
 
 // when traits can extend traits, we should extend index<Name,T> to get []
-#[cfg(stage0)]
-impl<T: Eq + Hash<Hasher> + Clone + 'static> Interner<T> {
-    pub fn new() -> Interner<T> {
-        Interner {
-            map: RefCell::new(HashMap::new()),
-            vect: RefCell::new(Vec::new()),
-        }
-    }
-
-    pub fn prefill(init: &[T]) -> Interner<T> {
-        let rv = Interner::new();
-        for v in init {
-            rv.intern((*v).clone());
-        }
-        rv
-    }
-
-    pub fn intern(&self, val: T) -> Name {
-        let mut map = self.map.borrow_mut();
-        match (*map).get(&val) {
-            Some(&idx) => return idx,
-            None => (),
-        }
-
-        let mut vect = self.vect.borrow_mut();
-        let new_idx = Name((*vect).len() as u32);
-        (*map).insert(val.clone(), new_idx);
-        (*vect).push(val);
-        new_idx
-    }
-
-    pub fn gensym(&self, val: T) -> Name {
-        let mut vect = self.vect.borrow_mut();
-        let new_idx = Name((*vect).len() as u32);
-        // leave out of .map to avoid colliding
-        (*vect).push(val);
-        new_idx
-    }
-
-    pub fn get(&self, idx: Name) -> T {
-        let vect = self.vect.borrow();
-        (*vect)[idx.usize()].clone()
-    }
-
-    pub fn len(&self) -> usize {
-        let vect = self.vect.borrow();
-        (*vect).len()
-    }
-
-    pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
-    where T: Borrow<Q>, Q: Eq + Hash<Hasher> {
-        let map = self.map.borrow();
-        match (*map).get(val) {
-            Some(v) => Some(*v),
-            None => None,
-        }
-    }
-
-    pub fn clear(&self) {
-        *self.map.borrow_mut() = HashMap::new();
-        *self.vect.borrow_mut() = Vec::new();
-    }
-}
-// when traits can extend traits, we should extend index<Name,T> to get []
-#[cfg(not(stage0))]
 impl<T: Eq + Hash + Clone + 'static> Interner<T> {
     pub fn new() -> Interner<T> {
         Interner {
@@ -275,15 +209,6 @@ impl StrInterner {
         self.vect.borrow().len()
     }
 
-    #[cfg(stage0)]
-    pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
-    where RcStr: Borrow<Q>, Q: Eq + Hash<Hasher> {
-        match (*self.map.borrow()).get(val) {
-            Some(v) => Some(*v),
-            None => None,
-        }
-    }
-    #[cfg(not(stage0))]
     pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
     where RcStr: Borrow<Q>, Q: Eq + Hash {
         match (*self.map.borrow()).get(val) {
@@ -309,7 +234,7 @@ mod tests {
     use ast::Name;
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn i1 () {
         let i : Interner<RcStr> = Interner::new();
         i.get(Name(13));
index 89854f5d979a159218c93a60595dff55f145f34d..ec608646327be4fea2f833a6415fc2a598ebbbab 100644 (file)
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 use ast;
-use parse::{new_parse_sess};
+use parse::new_parse_sess;
 use parse::{ParseSess,string_to_filemap,filemap_to_tts};
-use parse::{new_parser_from_source_str};
+use parse::new_parser_from_source_str;
 use parse::parser::Parser;
 use parse::token;
 use ptr::P;
@@ -58,14 +58,14 @@ pub fn string_to_expr (source_str : String) -> P<ast::Expr> {
 /// Parse a string, return an item
 pub fn string_to_item (source_str : String) -> Option<P<ast::Item>> {
     with_error_checking_parse(source_str, |p| {
-        p.parse_item(Vec::new())
+        p.parse_item()
     })
 }
 
 /// Parse a string, return a stmt
 pub fn string_to_stmt(source_str : String) -> P<ast::Stmt> {
     with_error_checking_parse(source_str, |p| {
-        p.parse_stmt(Vec::new())
+        p.parse_stmt().unwrap()
     })
 }
 
index 0a39d3809045a2e56f745255e6b204bc5d43f8d0..1649934f4b10e5d4628d20e9ed26370bb9e5a7f6 100644 (file)
@@ -226,23 +226,23 @@ mod test {
     fn test_move_iter() {
         let v = SmallVector::zero();
         let v: Vec<isize> = v.into_iter().collect();
-        assert_eq!(Vec::new(), v);
+        assert_eq!(v, Vec::new());
 
         let v = SmallVector::one(1);
-        assert_eq!(vec![1], v.into_iter().collect::<Vec<_>>());
+        assert_eq!(v.into_iter().collect::<Vec<_>>(), [1]);
 
         let v = SmallVector::many(vec![1, 2, 3]);
-        assert_eq!(vec!(1, 2, 3), v.into_iter().collect::<Vec<_>>());
+        assert_eq!(v.into_iter().collect::<Vec<_>>(), [1, 2, 3]);
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_expect_one_zero() {
         let _: isize = SmallVector::zero().expect_one("");
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_expect_one_many() {
         SmallVector::many(vec!(1, 2)).expect_one("");
     }
index 21cb62b0a0c112818f30308c2ec7f3888906950d..5c345c75642b8eb39ff81a692f052c694b5e07e1 100644 (file)
@@ -32,13 +32,13 @@ use codemap::Span;
 use ptr::P;
 use owned_slice::OwnedSlice;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum FnKind<'a> {
     /// fn foo() or extern "Abi" fn foo()
     FkItemFn(Ident, &'a Generics, Unsafety, Abi),
 
     /// fn foo(&self)
-    FkMethod(Ident, &'a Generics, &'a Method),
+    FkMethod(Ident, &'a MethodSig),
 
     /// |x, y| ...
     /// proc(x, y) ...
@@ -77,8 +77,8 @@ pub trait Visitor<'v> : Sized {
     fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) {
         walk_fn(self, fk, fd, b, s)
     }
-    fn visit_ty_method(&mut self, t: &'v TypeMethod) { walk_ty_method(self, t) }
-    fn visit_trait_item(&mut self, t: &'v TraitItem) { walk_trait_item(self, t) }
+    fn visit_trait_item(&mut self, ti: &'v TraitItem) { walk_trait_item(self, ti) }
+    fn visit_impl_item(&mut self, ii: &'v ImplItem) { walk_impl_item(self, ii) }
     fn visit_trait_ref(&mut self, t: &'v TraitRef) { walk_trait_ref(self, t) }
     fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
         walk_ty_param_bound(self, bounds)
@@ -125,9 +125,6 @@ pub trait Visitor<'v> : Sized {
     fn visit_path(&mut self, path: &'v Path, _id: ast::NodeId) {
         walk_path(self, path)
     }
-    fn visit_qpath(&mut self, qpath_span: Span, qpath: &'v QPath) {
-        walk_qpath(self, qpath_span, qpath)
-    }
     fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
         walk_path_segment(self, path_span, path_segment)
     }
@@ -146,13 +143,7 @@ pub fn walk_inlined_item<'v,V>(visitor: &mut V, item: &'v InlinedItem)
         IIItem(ref i) => visitor.visit_item(&**i),
         IIForeign(ref i) => visitor.visit_foreign_item(&**i),
         IITraitItem(_, ref ti) => visitor.visit_trait_item(ti),
-        IIImplItem(_, MethodImplItem(ref m)) => {
-            walk_method_helper(visitor, &**m)
-        }
-        IIImplItem(_, TypeImplItem(ref typedef)) => {
-            visitor.visit_ident(typedef.span, typedef.ident);
-            visitor.visit_ty(&*typedef.typ);
-        }
+        IIImplItem(_, ref ii) => visitor.visit_impl_item(ii),
     }
 }
 
@@ -205,8 +196,6 @@ pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V,
     }
 }
 
-/// Like with walk_method_helper this doesn't correspond to a method
-/// in Visitor, and so it gets a _helper suffix.
 pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
                                   trait_ref: &'v PolyTraitRef,
                                   _modifier: &'v TraitBoundModifier)
@@ -216,8 +205,6 @@ pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
     visitor.visit_trait_ref(&trait_ref.trait_ref);
 }
 
-/// Like with walk_method_helper this doesn't correspond to a method
-/// in Visitor, and so it gets a _helper suffix.
 pub fn walk_trait_ref<'v,V>(visitor: &mut V,
                                    trait_ref: &'v TraitRef)
     where V: Visitor<'v>
@@ -282,6 +269,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             visitor.visit_generics(type_parameters);
             walk_enum_def(visitor, enum_definition, type_parameters)
         }
+        ItemDefaultImpl(_, ref trait_ref) => {
+            visitor.visit_trait_ref(trait_ref)
+        }
         ItemImpl(_, _,
                  ref type_parameters,
                  ref trait_reference,
@@ -294,15 +284,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             }
             visitor.visit_ty(&**typ);
             for impl_item in impl_items {
-                match *impl_item {
-                    MethodImplItem(ref method) => {
-                        walk_method_helper(visitor, &**method)
-                    }
-                    TypeImplItem(ref typedef) => {
-                        visitor.visit_ident(typedef.span, typedef.ident);
-                        visitor.visit_ty(&*typedef.typ);
-                    }
-                }
+                visitor.visit_impl_item(impl_item);
             }
         }
         ItemStruct(ref struct_definition, ref generics) => {
@@ -396,16 +378,16 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
             walk_fn_ret_ty(visitor, &function_declaration.decl.output);
             walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
         }
-        TyPath(ref path, id) => {
-            visitor.visit_path(path, id);
+        TyPath(ref maybe_qself, ref path) => {
+            if let Some(ref qself) = *maybe_qself {
+                visitor.visit_ty(&qself.ty);
+            }
+            visitor.visit_path(path, typ.id);
         }
         TyObjectSum(ref ty, ref bounds) => {
             visitor.visit_ty(&**ty);
             walk_ty_param_bounds_helper(visitor, bounds);
         }
-        TyQPath(ref qpath) => {
-            visitor.visit_qpath(typ.span, &**qpath);
-        }
         TyFixedLengthVec(ref ty, ref expression) => {
             visitor.visit_ty(&**ty);
             visitor.visit_expr(&**expression)
@@ -433,14 +415,6 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
     }
 }
 
-pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V,
-                                      qpath_span: Span,
-                                      qpath: &'v QPath) {
-    visitor.visit_ty(&*qpath.self_type);
-    visitor.visit_trait_ref(&*qpath.trait_ref);
-    visitor.visit_path_segment(qpath_span, &qpath.item_path);
-}
-
 pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
                                              path_span: Span,
                                              segment: &'v PathSegment) {
@@ -569,15 +543,11 @@ pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V,
     }
 }
 
-pub fn walk_ty_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v TyParam) {
-    visitor.visit_ident(param.span, param.ident);
-    walk_ty_param_bounds_helper(visitor, &param.bounds);
-    walk_ty_opt(visitor, &param.default);
-}
-
 pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
-    for type_parameter in &*generics.ty_params {
-        walk_ty_param(visitor, type_parameter);
+    for param in &*generics.ty_params {
+        visitor.visit_ident(param.span, param.ident);
+        walk_ty_param_bounds_helper(visitor, &param.bounds);
+        walk_ty_opt(visitor, &param.default);
     }
     walk_lifetime_decls_helper(visitor, &generics.lifetimes);
     for predicate in &generics.where_clause.predicates {
@@ -622,28 +592,6 @@ pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &
     walk_fn_ret_ty(visitor, &function_declaration.output)
 }
 
-// Note: there is no visit_method() method in the visitor, instead override
-// visit_fn() and check for FkMethod().  I named this visit_method_helper()
-// because it is not a default impl of any method, though I doubt that really
-// clarifies anything. - Niko
-pub fn walk_method_helper<'v, V: Visitor<'v>>(visitor: &mut V, method: &'v Method) {
-    match method.node {
-        MethDecl(ident, ref generics, _, _, _, ref decl, ref body, _) => {
-            visitor.visit_ident(method.span, ident);
-            visitor.visit_fn(FkMethod(ident, generics, method),
-                             &**decl,
-                             &**body,
-                             method.span,
-                             method.id);
-            for attr in &method.attrs {
-                visitor.visit_attribute(attr);
-            }
-
-        },
-        MethMac(ref mac) => visitor.visit_mac(mac)
-    }
-}
-
 pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
                                    function_kind: FnKind<'v>,
                                    function_declaration: &'v FnDecl,
@@ -655,14 +603,9 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
         FkItemFn(_, generics, _, _) => {
             visitor.visit_generics(generics);
         }
-        FkMethod(_, generics, method) => {
-            visitor.visit_generics(generics);
-            match method.node {
-                MethDecl(_, _, _, ref explicit_self, _, _, _, _) =>
-                    visitor.visit_explicit_self(explicit_self),
-                MethMac(ref mac) =>
-                    visitor.visit_mac(mac)
-            }
+        FkMethod(_, sig) => {
+            visitor.visit_generics(&sig.generics);
+            visitor.visit_explicit_self(&sig.explicit_self);
         }
         FkFnBlock(..) => {}
     }
@@ -670,25 +613,43 @@ pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
     visitor.visit_block(function_body)
 }
 
-pub fn walk_ty_method<'v, V: Visitor<'v>>(visitor: &mut V, method_type: &'v TypeMethod) {
-    visitor.visit_ident(method_type.span, method_type.ident);
-    visitor.visit_explicit_self(&method_type.explicit_self);
-    for argument_type in &method_type.decl.inputs {
-        visitor.visit_ty(&*argument_type.ty)
-    }
-    visitor.visit_generics(&method_type.generics);
-    walk_fn_ret_ty(visitor, &method_type.decl.output);
-    for attr in &method_type.attrs {
+pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
+    visitor.visit_ident(trait_item.span, trait_item.ident);
+    for attr in &trait_item.attrs {
         visitor.visit_attribute(attr);
     }
+    match trait_item.node {
+        MethodTraitItem(ref sig, None) => {
+            visitor.visit_explicit_self(&sig.explicit_self);
+            visitor.visit_generics(&sig.generics);
+            walk_fn_decl(visitor, &sig.decl);
+        }
+        MethodTraitItem(ref sig, Some(ref body)) => {
+            visitor.visit_fn(FkMethod(trait_item.ident, sig), &sig.decl,
+                             body, trait_item.span, trait_item.id);
+        }
+        TypeTraitItem(ref bounds, ref default) => {
+            walk_ty_param_bounds_helper(visitor, bounds);
+            walk_ty_opt(visitor, default);
+        }
+    }
 }
 
-pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_method: &'v TraitItem) {
-    match *trait_method {
-        RequiredMethod(ref method_type) => visitor.visit_ty_method(method_type),
-        ProvidedMethod(ref method) => walk_method_helper(visitor, &**method),
-        TypeTraitItem(ref associated_type) => {
-            walk_ty_param(visitor, &associated_type.ty_param);
+pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
+    visitor.visit_ident(impl_item.span, impl_item.ident);
+    for attr in &impl_item.attrs {
+        visitor.visit_attribute(attr);
+    }
+    match impl_item.node {
+        MethodImplItem(ref sig, ref body) => {
+            visitor.visit_fn(FkMethod(impl_item.ident, sig), &sig.decl,
+                             body, impl_item.span, impl_item.id);
+        }
+        TypeImplItem(ref ty) => {
+            visitor.visit_ty(ty);
+        }
+        MacImplItem(ref mac) => {
+            visitor.visit_mac(mac);
         }
     }
 }
@@ -866,12 +827,12 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
             walk_expr_opt(visitor, start);
             walk_expr_opt(visitor, end)
         }
-        ExprPath(ref path) => {
+        ExprPath(ref maybe_qself, ref path) => {
+            if let Some(ref qself) = *maybe_qself {
+                visitor.visit_ty(&qself.ty);
+            }
             visitor.visit_path(path, expression.id)
         }
-        ExprQPath(ref qpath) => {
-            visitor.visit_qpath(expression.span, &**qpath)
-        }
         ExprBreak(_) | ExprAgain(_) => {}
         ExprRet(ref optional_expression) => {
             walk_expr_opt(visitor, optional_expression)
index 5418533aff1d918129f9bae1f6f5059dd603fe55..74ec3406f73bc3a735f640dfdb9375a9566acd25 100644 (file)
 //! # Examples
 //!
 //! ```no_run
+//! # #![feature(rustc_private)]
 //! extern crate term;
 //!
+//! use std::io::prelude::*;
+//!
 //! fn main() {
 //!     let mut t = term::stdout().unwrap();
 //!
@@ -38,6 +41,8 @@
 //! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
 //! [ti]: https://en.wikipedia.org/wiki/Terminfo
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "term"]
 #![unstable(feature = "rustc_private",
             reason = "use the crates.io `term` library instead")]
 
 #![feature(box_syntax)]
 #![feature(collections)]
-#![feature(int_uint)]
-#![feature(old_io)]
-#![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(unicode)]
 #![feature(std_misc)]
-#![feature(env)]
+#![feature(str_char)]
+#![feature(path_ext)]
 #![cfg_attr(windows, feature(libc))]
 
 #[macro_use] extern crate log;
@@ -68,27 +70,28 @@ pub use terminfo::TerminfoTerminal;
 #[cfg(windows)]
 pub use win::WinConsole;
 
-use std::old_io::IoResult;
+use std::io::prelude::*;
+use std::io;
 
 pub mod terminfo;
 
 #[cfg(windows)]
 mod win;
 
-/// A hack to work around the fact that `Box<Writer + Send>` does not
-/// currently implement `Writer`.
+/// A hack to work around the fact that `Box<Write + Send>` does not
+/// currently implement `Write`.
 pub struct WriterWrapper {
-    wrapped: Box<Writer + Send>,
+    wrapped: Box<Write + Send>,
 }
 
-impl Writer for WriterWrapper {
+impl Write for WriterWrapper {
     #[inline]
-    fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
-        self.wrapped.write_all(buf)
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.wrapped.write(buf)
     }
 
     #[inline]
-    fn flush(&mut self) -> IoResult<()> {
+    fn flush(&mut self) -> io::Result<()> {
         self.wrapped.flush()
     }
 }
@@ -98,7 +101,7 @@ impl Writer for WriterWrapper {
 /// opened.
 pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
     TerminfoTerminal::new(WriterWrapper {
-        wrapped: box std::old_io::stdout() as Box<Writer + Send>,
+        wrapped: box std::io::stdout(),
     })
 }
 
@@ -107,14 +110,14 @@ pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
 /// opened.
 pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
     let ti = TerminfoTerminal::new(WriterWrapper {
-        wrapped: box std::old_io::stdout() as Box<Writer + Send>,
+        wrapped: box std::io::stdout(),
     });
 
     match ti {
         Some(t) => Some(t),
         None => {
             WinConsole::new(WriterWrapper {
-                wrapped: box std::old_io::stdout() as Box<Writer + Send>,
+                wrapped: box std::io::stdout(),
             })
         }
     }
@@ -125,7 +128,7 @@ pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
 /// opened.
 pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send>> {
     TerminfoTerminal::new(WriterWrapper {
-        wrapped: box std::old_io::stderr() as Box<Writer + Send>,
+        wrapped: box std::io::stderr(),
     })
 }
 
@@ -134,14 +137,14 @@ pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send>> {
 /// opened.
 pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send>> {
     let ti = TerminfoTerminal::new(WriterWrapper {
-        wrapped: box std::old_io::stderr() as Box<Writer + Send>,
+        wrapped: box std::io::stderr(),
     });
 
     match ti {
         Some(t) => Some(t),
         None => {
             WinConsole::new(WriterWrapper {
-                wrapped: box std::old_io::stderr() as Box<Writer + Send>,
+                wrapped: box std::io::stderr(),
             })
         }
     }
@@ -153,23 +156,23 @@ pub mod color {
     /// Number for a terminal color
     pub type Color = u16;
 
-    pub const BLACK:   Color = 0u16;
-    pub const RED:     Color = 1u16;
-    pub const GREEN:   Color = 2u16;
-    pub const YELLOW:  Color = 3u16;
-    pub const BLUE:    Color = 4u16;
-    pub const MAGENTA: Color = 5u16;
-    pub const CYAN:    Color = 6u16;
-    pub const WHITE:   Color = 7u16;
-
-    pub const BRIGHT_BLACK:   Color = 8u16;
-    pub const BRIGHT_RED:     Color = 9u16;
-    pub const BRIGHT_GREEN:   Color = 10u16;
-    pub const BRIGHT_YELLOW:  Color = 11u16;
-    pub const BRIGHT_BLUE:    Color = 12u16;
-    pub const BRIGHT_MAGENTA: Color = 13u16;
-    pub const BRIGHT_CYAN:    Color = 14u16;
-    pub const BRIGHT_WHITE:   Color = 15u16;
+    pub const BLACK:   Color = 0;
+    pub const RED:     Color = 1;
+    pub const GREEN:   Color = 2;
+    pub const YELLOW:  Color = 3;
+    pub const BLUE:    Color = 4;
+    pub const MAGENTA: Color = 5;
+    pub const CYAN:    Color = 6;
+    pub const WHITE:   Color = 7;
+
+    pub const BRIGHT_BLACK:   Color = 8;
+    pub const BRIGHT_RED:     Color = 9;
+    pub const BRIGHT_GREEN:   Color = 10;
+    pub const BRIGHT_YELLOW:  Color = 11;
+    pub const BRIGHT_BLUE:    Color = 12;
+    pub const BRIGHT_MAGENTA: Color = 13;
+    pub const BRIGHT_CYAN:    Color = 14;
+    pub const BRIGHT_WHITE:   Color = 15;
 }
 
 /// Terminal attributes
@@ -181,7 +184,7 @@ pub mod attr {
     /// Most attributes can only be turned on and must be turned off with term.reset().
     /// The ones that can be turned off explicitly take a boolean value.
     /// Color is also represented as an attribute for convenience.
-    #[derive(Copy)]
+    #[derive(Copy, Clone)]
     pub enum Attr {
         /// Bold (or possibly bright) mode
         Bold,
@@ -208,7 +211,7 @@ pub mod attr {
 
 /// A terminal with similar capabilities to an ANSI Terminal
 /// (foreground/background colors etc).
-pub trait Terminal<T: Writer>: Writer {
+pub trait Terminal<T: Write>: Write {
     /// Sets the foreground color to the given color.
     ///
     /// If the color is a bright color, but the terminal only supports 8 colors,
@@ -216,7 +219,7 @@ pub trait Terminal<T: Writer>: Writer {
     ///
     /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
     /// if there was an I/O error.
-    fn fg(&mut self, color: color::Color) -> IoResult<bool>;
+    fn fg(&mut self, color: color::Color) -> io::Result<bool>;
 
     /// Sets the background color to the given color.
     ///
@@ -225,19 +228,19 @@ pub trait Terminal<T: Writer>: Writer {
     ///
     /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
     /// if there was an I/O error.
-    fn bg(&mut self, color: color::Color) -> IoResult<bool>;
+    fn bg(&mut self, color: color::Color) -> io::Result<bool>;
 
     /// Sets the given terminal attribute, if supported.  Returns `Ok(true)`
     /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
     /// there was an I/O error.
-    fn attr(&mut self, attr: attr::Attr) -> IoResult<bool>;
+    fn attr(&mut self, attr: attr::Attr) -> io::Result<bool>;
 
     /// Returns whether the given terminal attribute is supported.
     fn supports_attr(&self, attr: attr::Attr) -> bool;
 
     /// Resets all terminal attributes and color to the default.
     /// Returns `Ok()`.
-    fn reset(&mut self) -> IoResult<()>;
+    fn reset(&mut self) -> io::Result<()>;
 
     /// Gets an immutable reference to the stream inside
     fn get_ref<'a>(&'a self) -> &'a T;
@@ -247,7 +250,7 @@ pub trait Terminal<T: Writer>: Writer {
 }
 
 /// A terminal which can be unwrapped.
-pub trait UnwrappableTerminal<T: Writer>: Terminal<T> {
+pub trait UnwrappableTerminal<T: Write>: Terminal<T> {
     /// Returns the contained stream, destroying the `Terminal`
     fn unwrap(self) -> T;
 }
index be1c623c8590512c1f699aed09e7bc496039bd57..4840cd1fddadfe2ecd142e67b6ea2354e96f2d56 100644 (file)
@@ -11,8 +11,9 @@
 //! Terminfo database interface.
 
 use std::collections::HashMap;
-use std::old_io::IoResult;
 use std::env;
+use std::io::prelude::*;
+use std::io;
 
 use attr;
 use color;
@@ -72,8 +73,8 @@ pub struct TerminfoTerminal<T> {
     ti: Box<TermInfo>
 }
 
-impl<T: Writer+Send+'static> Terminal<T> for TerminfoTerminal<T> {
-    fn fg(&mut self, color: color::Color) -> IoResult<bool> {
+impl<T: Write+Send+'static> Terminal<T> for TerminfoTerminal<T> {
+    fn fg(&mut self, color: color::Color) -> io::Result<bool> {
         let color = self.dim_if_necessary(color);
         if self.num_colors > color {
             let s = expand(self.ti
@@ -81,7 +82,7 @@ impl<T: Writer+Send+'static> Terminal<T> for TerminfoTerminal<T> {
                                .get("setaf")
                                .unwrap()
                                ,
-                           &[Number(color as int)], &mut Variables::new());
+                           &[Number(color as isize)], &mut Variables::new());
             if s.is_ok() {
                 try!(self.out.write_all(&s.unwrap()));
                 return Ok(true)
@@ -90,7 +91,7 @@ impl<T: Writer+Send+'static> Terminal<T> for TerminfoTerminal<T> {
         Ok(false)
     }
 
-    fn bg(&mut self, color: color::Color) -> IoResult<bool> {
+    fn bg(&mut self, color: color::Color) -> io::Result<bool> {
         let color = self.dim_if_necessary(color);
         if self.num_colors > color {
             let s = expand(self.ti
@@ -98,7 +99,7 @@ impl<T: Writer+Send+'static> Terminal<T> for TerminfoTerminal<T> {
                                .get("setab")
                                .unwrap()
                                ,
-                           &[Number(color as int)], &mut Variables::new());
+                           &[Number(color as isize)], &mut Variables::new());
             if s.is_ok() {
                 try!(self.out.write_all(&s.unwrap()));
                 return Ok(true)
@@ -107,7 +108,7 @@ impl<T: Writer+Send+'static> Terminal<T> for TerminfoTerminal<T> {
         Ok(false)
     }
 
-    fn attr(&mut self, attr: attr::Attr) -> IoResult<bool> {
+    fn attr(&mut self, attr: attr::Attr) -> io::Result<bool> {
         match attr {
             attr::ForegroundColor(c) => self.fg(c),
             attr::BackgroundColor(c) => self.bg(c),
@@ -140,7 +141,7 @@ impl<T: Writer+Send+'static> Terminal<T> for TerminfoTerminal<T> {
         }
     }
 
-    fn reset(&mut self) -> IoResult<()> {
+    fn reset(&mut self) -> io::Result<()> {
         let mut cap = self.ti.strings.get("sgr0");
         if cap.is_none() {
             // are there any terminals that have color/attrs and not sgr0?
@@ -164,11 +165,11 @@ impl<T: Writer+Send+'static> Terminal<T> for TerminfoTerminal<T> {
     fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.out }
 }
 
-impl<T: Writer+Send+'static> UnwrappableTerminal<T> for TerminfoTerminal<T> {
+impl<T: Write+Send+'static> UnwrappableTerminal<T> for TerminfoTerminal<T> {
     fn unwrap(self) -> T { self.out }
 }
 
-impl<T: Writer+Send+'static> TerminfoTerminal<T> {
+impl<T: Write+Send+'static> TerminfoTerminal<T> {
     /// Returns `None` whenever the terminal cannot be created for some
     /// reason.
     pub fn new(out: T) -> Option<Box<Terminal<T>+Send+'static>> {
@@ -180,21 +181,24 @@ impl<T: Writer+Send+'static> TerminfoTerminal<T> {
             }
         };
 
-        let entry = open(&term[..]);
-        if entry.is_err() {
-            if env::var("MSYSCON").ok().map_or(false, |s| {
-                    "mintty.exe" == s
-                }) {
-                // msys terminal
-                return Some(box TerminfoTerminal {out: out,
-                                                  ti: msys_terminfo(),
-                                                  num_colors: 8} as Box<Terminal<T>+Send>);
-            }
-            debug!("error finding terminfo entry: {:?}", entry.err().unwrap());
-            return None;
-        }
+        let mut file = match open(&term[..]) {
+            Ok(f) => f,
+            Err(err) => return match env::var("MSYSCON") {
+                Ok(ref val) if &val[..] == "mintty.exe" => {
+                    // msys terminal
+                    Some(box TerminfoTerminal{
+                        out: out,
+                        ti: msys_terminfo(),
+                        num_colors: 8,
+                    })
+                },
+                _ => {
+                    debug!("error finding terminfo entry: {:?}", err);
+                    None
+                },
+            },
+        };
 
-        let mut file = entry.unwrap();
         let ti = parse(&mut file, false);
         if ti.is_err() {
             debug!("error parsing terminfo entry: {:?}", ti.err().unwrap());
@@ -209,7 +213,7 @@ impl<T: Writer+Send+'static> TerminfoTerminal<T> {
 
         return Some(box TerminfoTerminal {out: out,
                                           ti: inf,
-                                          num_colors: nc} as Box<Terminal<T>+Send>);
+                                          num_colors: nc});
     }
 
     fn dim_if_necessary(&self, color: color::Color) -> color::Color {
@@ -220,12 +224,12 @@ impl<T: Writer+Send+'static> TerminfoTerminal<T> {
 }
 
 
-impl<T: Writer> Writer for TerminfoTerminal<T> {
-    fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
-        self.out.write_all(buf)
+impl<T: Write> Write for TerminfoTerminal<T> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.out.write(buf)
     }
 
-    fn flush(&mut self) -> IoResult<()> {
+    fn flush(&mut self) -> io::Result<()> {
         self.out.flush()
     }
 }
index 0b577f8de74c2a9b2e8178584173c29e8d134b7a..01586b8f36ed0b35467b446c35fa01d19a1234d5 100644 (file)
@@ -18,7 +18,7 @@ use std::ascii::OwnedAsciiExt;
 use std::mem::replace;
 use std::iter::repeat;
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 enum States {
     Nothing,
     Percent,
@@ -27,15 +27,15 @@ enum States {
     PushParam,
     CharConstant,
     CharClose,
-    IntConstant(int),
+    IntConstant(isize),
     FormatPattern(Flags, FormatState),
-    SeekIfElse(int),
-    SeekIfElsePercent(int),
-    SeekIfEnd(int),
-    SeekIfEndPercent(int)
+    SeekIfElse(isize),
+    SeekIfElsePercent(isize),
+    SeekIfEnd(isize),
+    SeekIfEndPercent(isize)
 }
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 enum FormatState {
     FormatStateFlags,
     FormatStateWidth,
@@ -47,7 +47,7 @@ enum FormatState {
 #[derive(Clone)]
 pub enum Param {
     Words(String),
-    Number(int)
+    Number(isize)
 }
 
 /// Container for static and dynamic variable arrays
@@ -128,7 +128,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
                             // if c is 0, use 0200 (128) for ncurses compatibility
                             Number(c) => {
                                 output.push(if c == 0 {
-                                    128u8
+                                    128
                                 } else {
                                     c as u8
                                 })
@@ -143,7 +143,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
                     '{' => state = IntConstant(0),
                     'l' => if stack.len() > 0 {
                         match stack.pop().unwrap() {
-                            Words(s) => stack.push(Number(s.len() as int)),
+                            Words(s) => stack.push(Number(s.len() as isize)),
                             _        => return Err("a non-str was used with %l".to_string())
                         }
                     } else { return Err("stack is empty".to_string()) },
@@ -268,7 +268,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
                             ' ' => flags.space = true,
                             '.' => fstate = FormatStatePrecision,
                             '0'...'9' => {
-                                flags.width = cur as uint - '0' as uint;
+                                flags.width = cur as usize - '0' as usize;
                                 fstate = FormatStateWidth;
                             }
                             _ => unreachable!()
@@ -305,12 +305,12 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
                 if cur >= 'A' && cur <= 'Z' {
                     if stack.len() > 0 {
                         let idx = (cur as u8) - b'A';
-                        vars.sta[idx as uint] = stack.pop().unwrap();
+                        vars.sta[idx as usize] = stack.pop().unwrap();
                     } else { return Err("stack is empty".to_string()) }
                 } else if cur >= 'a' && cur <= 'z' {
                     if stack.len() > 0 {
                         let idx = (cur as u8) - b'a';
-                        vars.dyn[idx as uint] = stack.pop().unwrap();
+                        vars.dyn[idx as usize] = stack.pop().unwrap();
                     } else { return Err("stack is empty".to_string()) }
                 } else {
                     return Err("bad variable name in %P".to_string());
@@ -319,16 +319,16 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
             GetVar => {
                 if cur >= 'A' && cur <= 'Z' {
                     let idx = (cur as u8) - b'A';
-                    stack.push(vars.sta[idx as uint].clone());
+                    stack.push(vars.sta[idx as usize].clone());
                 } else if cur >= 'a' && cur <= 'z' {
                     let idx = (cur as u8) - b'a';
-                    stack.push(vars.dyn[idx as uint].clone());
+                    stack.push(vars.dyn[idx as usize].clone());
                 } else {
                     return Err("bad variable name in %g".to_string());
                 }
             },
             CharConstant => {
-                stack.push(Number(c as int));
+                stack.push(Number(c as isize));
                 state = CharClose;
             },
             CharClose => {
@@ -343,10 +343,10 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
                         state = Nothing;
                     }
                     '0'...'9' => {
-                        state = IntConstant(i*10 + (cur as int - '0' as int));
+                        state = IntConstant(i*10 + (cur as isize - '0' as isize));
                         old_state = Nothing;
                     }
-                    _ => return Err("bad int constant".to_string())
+                    _ => return Err("bad isize constant".to_string())
                 }
             }
             FormatPattern(ref mut flags, ref mut fstate) => {
@@ -372,7 +372,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
                         flags.space = true;
                     }
                     (FormatStateFlags,'0'...'9') => {
-                        flags.width = cur as uint - '0' as uint;
+                        flags.width = cur as usize - '0' as usize;
                         *fstate = FormatStateWidth;
                     }
                     (FormatStateFlags,'.') => {
@@ -380,7 +380,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
                     }
                     (FormatStateWidth,'0'...'9') => {
                         let old = flags.width;
-                        flags.width = flags.width * 10 + (cur as uint - '0' as uint);
+                        flags.width = flags.width * 10 + (cur as usize - '0' as usize);
                         if flags.width < old { return Err("format width overflow".to_string()) }
                     }
                     (FormatStateWidth,'.') => {
@@ -388,7 +388,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
                     }
                     (FormatStatePrecision,'0'...'9') => {
                         let old = flags.precision;
-                        flags.precision = flags.precision * 10 + (cur as uint - '0' as uint);
+                        flags.precision = flags.precision * 10 + (cur as usize - '0' as usize);
                         if flags.precision < old {
                             return Err("format precision overflow".to_string())
                         }
@@ -444,10 +444,10 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
     Ok(output)
 }
 
-#[derive(Copy, PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 struct Flags {
-    width: uint,
-    precision: uint,
+    width: usize,
+    precision: usize,
     alternate: bool,
     left: bool,
     sign: bool,
@@ -461,7 +461,7 @@ impl Flags {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum FormatOp {
     FormatDigit,
     FormatOctal,
@@ -647,20 +647,20 @@ mod test {
 
     #[test]
     fn test_comparison_ops() {
-        let v = [('<', [1u8, 0u8, 0u8]), ('=', [0u8, 1u8, 0u8]), ('>', [0u8, 0u8, 1u8])];
+        let v = [('<', [1, 0, 0]), ('=', [0, 1, 0]), ('>', [0, 0, 1])];
         for &(op, bs) in &v {
             let s = format!("%{{1}}%{{2}}%{}%d", op);
             let res = expand(s.as_bytes(), &[], &mut Variables::new());
             assert!(res.is_ok(), res.err().unwrap());
-            assert_eq!(res.unwrap(), vec!(b'0' + bs[0]));
+            assert_eq!(res.unwrap(), [b'0' + bs[0]]);
             let s = format!("%{{1}}%{{1}}%{}%d", op);
             let res = expand(s.as_bytes(), &[], &mut Variables::new());
             assert!(res.is_ok(), res.err().unwrap());
-            assert_eq!(res.unwrap(), vec!(b'0' + bs[1]));
+            assert_eq!(res.unwrap(), [b'0' + bs[1]]);
             let s = format!("%{{2}}%{{1}}%{}%d", op);
             let res = expand(s.as_bytes(), &[], &mut Variables::new());
             assert!(res.is_ok(), res.err().unwrap());
-            assert_eq!(res.unwrap(), vec!(b'0' + bs[2]));
+            assert_eq!(res.unwrap(), [b'0' + bs[2]]);
         }
     }
 
index c147e6aa056dd2a916402ab636ee7dcfadd6e268..01d191f30147b23450942f367135dac8b16d583f 100644 (file)
@@ -13,7 +13,8 @@
 //! ncurses-compatible compiled terminfo format parsing (term(5))
 
 use std::collections::HashMap;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
 use super::super::TermInfo;
 
 // These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
@@ -158,7 +159,7 @@ pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tb
     "box1"];
 
 /// Parse a compiled terminfo entry, using long capability names if `longnames` is true
-pub fn parse(file: &mut old_io::Reader, longnames: bool)
+pub fn parse(file: &mut Read, longnames: bool)
              -> Result<Box<TermInfo>, String> {
     macro_rules! try { ($e:expr) => (
         match $e {
@@ -182,37 +183,37 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
     }
 
     // Check magic number
-    let magic = try!(file.read_le_u16());
+    let magic = try!(read_le_u16(file));
     if magic != 0x011A {
         return Err(format!("invalid magic number: expected {:x}, found {:x}",
-                           0x011A as usize, magic as usize));
+                           0x011A_usize, magic as usize));
     }
 
-    let names_bytes          = try!(file.read_le_i16()) as int;
-    let bools_bytes          = try!(file.read_le_i16()) as int;
-    let numbers_count        = try!(file.read_le_i16()) as int;
-    let string_offsets_count = try!(file.read_le_i16()) as int;
-    let string_table_bytes   = try!(file.read_le_i16()) as int;
+    let names_bytes          = try!(read_le_u16(file)) as isize;
+    let bools_bytes          = try!(read_le_u16(file)) as isize;
+    let numbers_count        = try!(read_le_u16(file)) as isize;
+    let string_offsets_count = try!(read_le_u16(file)) as isize;
+    let string_table_bytes   = try!(read_le_u16(file)) as isize;
 
     assert!(names_bytes          > 0);
 
-    if (bools_bytes as uint) > boolnames.len() {
+    if (bools_bytes as usize) > boolnames.len() {
         return Err("incompatible file: more booleans than \
                     expected".to_string());
     }
 
-    if (numbers_count as uint) > numnames.len() {
+    if (numbers_count as usize) > numnames.len() {
         return Err("incompatible file: more numbers than \
                     expected".to_string());
     }
 
-    if (string_offsets_count as uint) > stringnames.len() {
+    if (string_offsets_count as usize) > stringnames.len() {
         return Err("incompatible file: more string offsets than \
                     expected".to_string());
     }
 
     // don't read NUL
-    let bytes = try!(file.read_exact(names_bytes as uint - 1));
+    let bytes = try!(read_exact(file, names_bytes as usize - 1));
     let names_str = match String::from_utf8(bytes) {
         Ok(s)  => s,
         Err(_) => return Err("input not utf-8".to_string()),
@@ -222,28 +223,28 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
                                            .map(|s| s.to_string())
                                            .collect();
 
-    try!(file.read_byte()); // consume NUL
+    try!(read_byte(file)); // consume NUL
 
     let mut bools_map = HashMap::new();
     if bools_bytes != 0 {
         for i in 0..bools_bytes {
-            let b = try!(file.read_byte());
+            let b = try!(read_byte(file));
             if b == 1 {
-                bools_map.insert(bnames[i as uint].to_string(), true);
+                bools_map.insert(bnames[i as usize].to_string(), true);
             }
         }
     }
 
     if (bools_bytes + names_bytes) % 2 == 1 {
-        try!(file.read_byte()); // compensate for padding
+        try!(read_byte(file)); // compensate for padding
     }
 
     let mut numbers_map = HashMap::new();
     if numbers_count != 0 {
         for i in 0..numbers_count {
-            let n = try!(file.read_le_u16());
+            let n = try!(read_le_u16(file));
             if n != 0xFFFF {
-                numbers_map.insert(nnames[i as uint].to_string(), n);
+                numbers_map.insert(nnames[i as usize].to_string(), n);
             }
         }
     }
@@ -253,12 +254,12 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
     if string_offsets_count != 0 {
         let mut string_offsets = Vec::with_capacity(10);
         for _ in 0..string_offsets_count {
-            string_offsets.push(try!(file.read_le_u16()));
+            string_offsets.push(try!(read_le_u16(file)));
         }
 
-        let string_table = try!(file.read_exact(string_table_bytes as uint));
+        let string_table = try!(read_exact(file, string_table_bytes as usize));
 
-        if string_table.len() != string_table_bytes as uint {
+        if string_table.len() != string_table_bytes as usize {
             return Err("error: hit EOF before end of string \
                         table".to_string());
         }
@@ -284,13 +285,13 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
 
 
             // Find the offset of the NUL we want to go to
-            let nulpos = string_table[offset as uint .. string_table_bytes as uint]
+            let nulpos = string_table[offset as usize .. string_table_bytes as usize]
                 .iter().position(|&b| b == 0);
             match nulpos {
                 Some(len) => {
                     string_map.insert(name.to_string(),
-                                      string_table[offset as uint ..
-                                                   (offset as uint + len)].to_vec())
+                                      string_table[offset as usize ..
+                                                   (offset as usize + len)].to_vec())
                 },
                 None => {
                     return Err("invalid file: missing NUL in \
@@ -309,6 +310,25 @@ pub fn parse(file: &mut old_io::Reader, longnames: bool)
     })
 }
 
+fn read_le_u16<R: Read + ?Sized>(r: &mut R) -> io::Result<u16> {
+    let mut b = [0; 2];
+    assert_eq!(try!(r.read(&mut b)), 2);
+    Ok((b[0] as u16) | ((b[1] as u16) << 8))
+}
+
+fn read_byte<R: Read + ?Sized>(r: &mut R) -> io::Result<u8> {
+    let mut b = [0; 1];
+    assert_eq!(try!(r.read(&mut b)), 1);
+    Ok(b[0])
+}
+
+fn read_exact<R: Read + ?Sized>(r: &mut R, sz: usize) -> io::Result<Vec<u8>> {
+    let mut v = Vec::with_capacity(sz);
+    try!(r.take(sz as u64).read_to_end(&mut v));
+    assert_eq!(v.len(), sz);
+    Ok(v)
+}
+
 /// Create a dummy TermInfo struct for msys terminals
 pub fn msys_terminfo() -> Box<TermInfo> {
     let mut strings = HashMap::new();
index c40a5534efbbb4e8d3d6146c6c513a124a420c62..3083f8e89298904526351d0b0bf2df4064df68c9 100644 (file)
 //!
 //! Does not support hashed database, only filesystem!
 
-use std::old_io::File;
-use std::old_io::fs::PathExtensions;
 use std::env;
+use std::fs::File;
+use std::io::prelude::*;
+use std::path::PathBuf;
 
 /// Return path to database entry for `term`
-pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
+#[allow(deprecated)]
+pub fn get_dbpath_for_term(term: &str) -> Option<Box<PathBuf>> {
     if term.len() == 0 {
         return None;
     }
@@ -28,9 +30,9 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
     let first_char = term.char_at(0);
 
     // Find search directory
-    match env::var("TERMINFO") {
-        Ok(dir) => dirs_to_search.push(Path::new(dir)),
-        Err(..) => {
+    match env::var_os("TERMINFO") {
+        Some(dir) => dirs_to_search.push(PathBuf::from(dir)),
+        None => {
             if homedir.is_some() {
                 // ncurses compatibility;
                 dirs_to_search.push(homedir.unwrap().join(".terminfo"))
@@ -38,9 +40,9 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
             match env::var("TERMINFO_DIRS") {
                 Ok(dirs) => for i in dirs.split(':') {
                     if i == "" {
-                        dirs_to_search.push(Path::new("/usr/share/terminfo"));
+                        dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
                     } else {
-                        dirs_to_search.push(Path::new(i));
+                        dirs_to_search.push(PathBuf::from(i));
                     }
                 },
                 // Found nothing in TERMINFO_DIRS, use the default paths:
@@ -48,9 +50,9 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
                 // ~/.terminfo, ncurses will search /etc/terminfo, then
                 // /lib/terminfo, and eventually /usr/share/terminfo.
                 Err(..) => {
-                    dirs_to_search.push(Path::new("/etc/terminfo"));
-                    dirs_to_search.push(Path::new("/lib/terminfo"));
-                    dirs_to_search.push(Path::new("/usr/share/terminfo"));
+                    dirs_to_search.push(PathBuf::from("/etc/terminfo"));
+                    dirs_to_search.push(PathBuf::from("/lib/terminfo"));
+                    dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
                 }
             }
         }
@@ -60,13 +62,13 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
     for p in &dirs_to_search {
         if p.exists() {
             let f = first_char.to_string();
-            let newp = p.join_many(&[&f[..], term]);
+            let newp = p.join(&f).join(term);
             if newp.exists() {
                 return Some(box newp);
             }
             // on some installations the dir is named after the hex of the char (e.g. OS X)
-            let f = format!("{:x}", first_char as uint);
-            let newp = p.join_many(&[&f[..], term]);
+            let f = format!("{:x}", first_char as usize);
+            let newp = p.join(&f).join(term);
             if newp.exists() {
                 return Some(box newp);
             }
@@ -95,17 +97,17 @@ pub fn open(term: &str) -> Result<File, String> {
 fn test_get_dbpath_for_term() {
     // woefully inadequate test coverage
     // note: current tests won't work with non-standard terminfo hierarchies (e.g. OS X's)
-    use std::os::{setenv, unsetenv};
+    use std::env;
     // FIXME (#9639): This needs to handle non-utf8 paths
     fn x(t: &str) -> String {
         let p = get_dbpath_for_term(t).expect("no terminfo entry found");
-        p.as_str().unwrap().to_string()
+        p.to_str().unwrap().to_string()
     };
     assert!(x("screen") == "/usr/share/terminfo/s/screen");
     assert!(get_dbpath_for_term("") == None);
-    setenv("TERMINFO_DIRS", ":");
+    env::set_var("TERMINFO_DIRS", ":");
     assert!(x("screen") == "/usr/share/terminfo/s/screen");
-    unsetenv("TERMINFO_DIRS");
+    env::remove_var("TERMINFO_DIRS");
 }
 
 #[test]
index e93b956dc7c835eaee3f11af0606a8bcf7437ba2..66ef5e8661797f241f9737f5988282886191062b 100644 (file)
@@ -14,7 +14,8 @@
 
 extern crate libc;
 
-use std::old_io::IoResult;
+use std::io;
+use std::io::prelude::*;
 
 use attr;
 use color;
@@ -86,7 +87,7 @@ fn bits_to_color(bits: u16) -> color::Color {
     color | (bits & 0x8) // copy the hi-intensity bit
 }
 
-impl<T: Writer+Send+'static> WinConsole<T> {
+impl<T: Write+Send+'static> WinConsole<T> {
     fn apply(&mut self) {
         let _unused = self.buf.flush();
         let mut accum: libc::WORD = 0;
@@ -103,7 +104,7 @@ impl<T: Writer+Send+'static> WinConsole<T> {
             // terminal! Admittedly, this is fragile, since stderr could be
             // redirected to a different console. This is good enough for
             // rustc though. See #13400.
-            let out = GetStdHandle(-11);
+            let out = GetStdHandle(-11i32 as libc::DWORD);
             SetConsoleTextAttribute(out, accum);
         }
     }
@@ -115,7 +116,8 @@ impl<T: Writer+Send+'static> WinConsole<T> {
         let bg;
         unsafe {
             let mut buffer_info = ::std::mem::uninitialized();
-            if GetConsoleScreenBufferInfo(GetStdHandle(-11), &mut buffer_info) != 0 {
+            if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as libc::DWORD),
+                                          &mut buffer_info) != 0 {
                 fg = bits_to_color(buffer_info.wAttributes);
                 bg = bits_to_color(buffer_info.wAttributes >> 4);
             } else {
@@ -125,36 +127,36 @@ impl<T: Writer+Send+'static> WinConsole<T> {
         }
         Some(box WinConsole { buf: out,
                               def_foreground: fg, def_background: bg,
-                              foreground: fg, background: bg } as Box<Terminal<T>+Send>)
+                              foreground: fg, background: bg })
     }
 }
 
-impl<T: Writer> Writer for WinConsole<T> {
-    fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
-        self.buf.write_all(buf)
+impl<T: Write> Write for WinConsole<T> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.buf.write(buf)
     }
 
-    fn flush(&mut self) -> IoResult<()> {
+    fn flush(&mut self) -> io::Result<()> {
         self.buf.flush()
     }
 }
 
-impl<T: Writer+Send+'static> Terminal<T> for WinConsole<T> {
-    fn fg(&mut self, color: color::Color) -> IoResult<bool> {
+impl<T: Write+Send+'static> Terminal<T> for WinConsole<T> {
+    fn fg(&mut self, color: color::Color) -> io::Result<bool> {
         self.foreground = color;
         self.apply();
 
         Ok(true)
     }
 
-    fn bg(&mut self, color: color::Color) -> IoResult<bool> {
+    fn bg(&mut self, color: color::Color) -> io::Result<bool> {
         self.background = color;
         self.apply();
 
         Ok(true)
     }
 
-    fn attr(&mut self, attr: attr::Attr) -> IoResult<bool> {
+    fn attr(&mut self, attr: attr::Attr) -> io::Result<bool> {
         match attr {
             attr::ForegroundColor(f) => {
                 self.foreground = f;
@@ -179,7 +181,7 @@ impl<T: Writer+Send+'static> Terminal<T> for WinConsole<T> {
         }
     }
 
-    fn reset(&mut self) -> IoResult<()> {
+    fn reset(&mut self) -> io::Result<()> {
         self.foreground = self.def_foreground;
         self.background = self.def_background;
         self.apply();
@@ -192,6 +194,6 @@ impl<T: Writer+Send+'static> Terminal<T> for WinConsole<T> {
     fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.buf }
 }
 
-impl<T: Writer+Send+'static> UnwrappableTerminal<T> for WinConsole<T> {
+impl<T: Write+Send+'static> UnwrappableTerminal<T> for WinConsole<T> {
     fn unwrap(self) -> T { self.buf }
 }
index 82c1a4b1195ce06ca1f948e39c13fe01f613991f..c84703b93ed263283d619ca7dbc81d75854b602a 100644 (file)
@@ -23,6 +23,8 @@
 // running tests while providing a base that other test frameworks may
 // build off of.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "test"]
 #![unstable(feature = "test")]
 #![staged_api]
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
-#![feature(env)]
-#![feature(int_uint)]
-#![feature(old_io)]
-#![feature(old_path)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(std_misc)]
+#![feature(libc)]
+#![feature(set_stdio)]
+#![cfg_attr(test, feature(old_io))]
 
 extern crate getopts;
 extern crate serialize;
-extern crate "serialize" as rustc_serialize;
+extern crate serialize as rustc_serialize;
 extern crate term;
+extern crate libc;
 
 pub use self::TestFn::*;
 pub use self::ColorConfig::*;
@@ -60,22 +62,25 @@ use self::OutputLocation::*;
 use stats::Stats;
 use getopts::{OptGroup, optflag, optopt};
 use serialize::Encodable;
+use std::boxed::FnBox;
 use term::Terminal;
 use term::color::{Color, RED, YELLOW, GREEN, CYAN};
 
 use std::any::Any;
 use std::cmp;
 use std::collections::BTreeMap;
+use std::env;
 use std::fmt;
-use std::old_io::stdio::StdWriter;
-use std::old_io::{File, ChanReader, ChanWriter};
-use std::old_io;
+use std::fs::File;
+use std::io::prelude::*;
+use std::io;
 use std::iter::repeat;
 use std::num::{Float, Int};
-use std::env;
+use std::path::PathBuf;
 use std::sync::mpsc::{channel, Sender};
+use std::sync::{Arc, Mutex};
 use std::thread;
-use std::thunk::{Thunk, Invoke};
+use std::thunk::Thunk;
 use std::time::Duration;
 
 // to be used by rustc to compile tests in libtest
@@ -85,7 +90,7 @@ pub mod test {
              Metric, MetricMap,
              StaticTestFn, StaticTestName, DynTestName, DynTestFn,
              run_test, test_main, test_main_static, filter_tests,
-             parse_opts, StaticBenchFn, ShouldFail};
+             parse_opts, StaticBenchFn, ShouldPanic};
 }
 
 pub mod stats;
@@ -122,7 +127,7 @@ enum NamePadding {
 }
 
 impl TestDesc {
-    fn padded_name(&self, column_count: uint, align: NamePadding) -> String {
+    fn padded_name(&self, column_count: usize, align: NamePadding) -> String {
         let mut name = String::from_str(self.name.as_slice());
         let fill = column_count.saturating_sub(name.len());
         let mut pad = repeat(" ").take(fill).collect::<String>();
@@ -154,7 +159,7 @@ pub enum TestFn {
     StaticBenchFn(fn(&mut Bencher)),
     StaticMetricFn(fn(&mut MetricMap)),
     DynTestFn(Thunk<'static>),
-    DynMetricFn(Box<for<'a> Invoke<&'a mut MetricMap>+'static>),
+    DynMetricFn(Box<FnBox(&mut MetricMap)+Send>),
     DynBenchFn(Box<TDynBenchFn+'static>)
 }
 
@@ -189,7 +194,7 @@ impl fmt::Debug for TestFn {
 /// This is fed into functions marked with `#[bench]` to allow for
 /// set-up & tear-down before running a piece of code repeatedly via a
 /// call to `iter`.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Bencher {
     iterations: u64,
     dur: Duration,
@@ -197,7 +202,7 @@ pub struct Bencher {
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum ShouldFail {
+pub enum ShouldPanic {
     No,
     Yes(Option<&'static str>)
 }
@@ -208,7 +213,7 @@ pub enum ShouldFail {
 pub struct TestDesc {
     pub name: TestName,
     pub ignore: bool,
-    pub should_fail: ShouldFail,
+    pub should_panic: ShouldPanic,
 }
 
 unsafe impl Send for TestDesc {}
@@ -276,7 +281,7 @@ pub fn test_main_static(args: env::Args, tests: &[TestDescAndFn]) {
     test_main(&args, owned_tests)
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum ColorConfig {
     AutoColor,
     AlwaysColor,
@@ -288,7 +293,7 @@ pub struct TestOpts {
     pub run_ignored: bool,
     pub run_tests: bool,
     pub run_benchmarks: bool,
-    pub logfile: Option<Path>,
+    pub logfile: Option<PathBuf>,
     pub nocapture: bool,
     pub color: ColorConfig,
 }
@@ -334,7 +339,7 @@ The FILTER regex is tested against the name of all tests to run, and
 only those tests that match are run.
 
 By default, all tests are run in parallel. This can be altered with the
-RUST_TEST_TASKS environment variable when running tests (set it to 1).
+RUST_TEST_THREADS environment variable when running tests (set it to 1).
 
 All tests have their standard output and standard error captured by default.
 This can be overridden with the --nocapture flag or the RUST_TEST_NOCAPTURE=1
@@ -346,10 +351,10 @@ Test Attributes:
                      takes no arguments.
     #[bench]       - Indicates a function is a benchmark to be run. This
                      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!)
+    #[should_panic] - This function (also labeled with #[test]) will only pass if
+                     the code causes a panic (an assertion failure or panic!)
                      A message may be provided, which the failure string must
-                     contain: #[should_fail(expected = "foo")].
+                     contain: #[should_panic(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
@@ -377,7 +382,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
     let run_ignored = matches.opt_present("ignored");
 
     let logfile = matches.opt_str("logfile");
-    let logfile = logfile.map(|s| Path::new(s));
+    let logfile = logfile.map(|s| PathBuf::from(&s));
 
     let run_benchmarks = matches.opt_present("bench");
     let run_tests = ! run_benchmarks ||
@@ -414,7 +419,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
 #[derive(Clone, PartialEq)]
 pub struct BenchSamples {
     ns_iter_summ: stats::Summary<f64>,
-    mb_s: uint,
+    mb_s: usize,
 }
 
 #[derive(Clone, PartialEq)]
@@ -437,25 +442,25 @@ struct ConsoleTestState<T> {
     log_out: Option<File>,
     out: OutputLocation<T>,
     use_color: bool,
-    total: uint,
-    passed: uint,
-    failed: uint,
-    ignored: uint,
-    measured: uint,
+    total: usize,
+    passed: usize,
+    failed: usize,
+    ignored: usize,
+    measured: usize,
     metrics: MetricMap,
     failures: Vec<(TestDesc, Vec<u8> )> ,
-    max_name_len: uint, // number of columns to fill when aligning names
+    max_name_len: usize, // number of columns to fill when aligning names
 }
 
-impl<T: Writer> ConsoleTestState<T> {
+impl<T: Write> ConsoleTestState<T> {
     pub fn new(opts: &TestOpts,
-               _: Option<T>) -> old_io::IoResult<ConsoleTestState<StdWriter>> {
+               _: Option<T>) -> io::Result<ConsoleTestState<io::Stdout>> {
         let log_out = match opts.logfile {
             Some(ref path) => Some(try!(File::create(path))),
             None => None
         };
         let out = match term::stdout() {
-            None => Raw(old_io::stdio::stdout_raw()),
+            None => Raw(io::stdout()),
             Some(t) => Pretty(t)
         };
 
@@ -474,29 +479,29 @@ impl<T: Writer> ConsoleTestState<T> {
         })
     }
 
-    pub fn write_ok(&mut self) -> old_io::IoResult<()> {
+    pub fn write_ok(&mut self) -> io::Result<()> {
         self.write_pretty("ok", term::color::GREEN)
     }
 
-    pub fn write_failed(&mut self) -> old_io::IoResult<()> {
+    pub fn write_failed(&mut self) -> io::Result<()> {
         self.write_pretty("FAILED", term::color::RED)
     }
 
-    pub fn write_ignored(&mut self) -> old_io::IoResult<()> {
+    pub fn write_ignored(&mut self) -> io::Result<()> {
         self.write_pretty("ignored", term::color::YELLOW)
     }
 
-    pub fn write_metric(&mut self) -> old_io::IoResult<()> {
+    pub fn write_metric(&mut self) -> io::Result<()> {
         self.write_pretty("metric", term::color::CYAN)
     }
 
-    pub fn write_bench(&mut self) -> old_io::IoResult<()> {
+    pub fn write_bench(&mut self) -> io::Result<()> {
         self.write_pretty("bench", term::color::CYAN)
     }
 
     pub fn write_pretty(&mut self,
                         word: &str,
-                        color: term::color::Color) -> old_io::IoResult<()> {
+                        color: term::color::Color) -> io::Result<()> {
         match self.out {
             Pretty(ref mut term) => {
                 if self.use_color {
@@ -506,32 +511,41 @@ impl<T: Writer> ConsoleTestState<T> {
                 if self.use_color {
                     try!(term.reset());
                 }
-                Ok(())
+                term.flush()
+            }
+            Raw(ref mut stdout) => {
+                try!(stdout.write_all(word.as_bytes()));
+                stdout.flush()
             }
-            Raw(ref mut stdout) => stdout.write_all(word.as_bytes())
         }
     }
 
-    pub fn write_plain(&mut self, s: &str) -> old_io::IoResult<()> {
+    pub fn write_plain(&mut self, s: &str) -> io::Result<()> {
         match self.out {
-            Pretty(ref mut term) => term.write_all(s.as_bytes()),
-            Raw(ref mut stdout) => stdout.write_all(s.as_bytes())
+            Pretty(ref mut term) => {
+                try!(term.write_all(s.as_bytes()));
+                term.flush()
+            },
+            Raw(ref mut stdout) => {
+                try!(stdout.write_all(s.as_bytes()));
+                stdout.flush()
+            },
         }
     }
 
-    pub fn write_run_start(&mut self, len: uint) -> old_io::IoResult<()> {
+    pub fn write_run_start(&mut self, len: usize) -> io::Result<()> {
         self.total = len;
         let noun = if len != 1 { "tests" } else { "test" };
         self.write_plain(&format!("\nrunning {} {}\n", len, noun))
     }
 
     pub fn write_test_start(&mut self, test: &TestDesc,
-                            align: NamePadding) -> old_io::IoResult<()> {
+                            align: NamePadding) -> io::Result<()> {
         let name = test.padded_name(self.max_name_len, align);
         self.write_plain(&format!("test {} ... ", name))
     }
 
-    pub fn write_result(&mut self, result: &TestResult) -> old_io::IoResult<()> {
+    pub fn write_result(&mut self, result: &TestResult) -> io::Result<()> {
         try!(match *result {
             TrOk => self.write_ok(),
             TrFailed => self.write_failed(),
@@ -552,7 +566,7 @@ impl<T: Writer> ConsoleTestState<T> {
     }
 
     pub fn write_log(&mut self, test: &TestDesc,
-                     result: &TestResult) -> old_io::IoResult<()> {
+                     result: &TestResult) -> io::Result<()> {
         match self.log_out {
             None => Ok(()),
             Some(ref mut o) => {
@@ -568,7 +582,7 @@ impl<T: Writer> ConsoleTestState<T> {
         }
     }
 
-    pub fn write_failures(&mut self) -> old_io::IoResult<()> {
+    pub fn write_failures(&mut self) -> io::Result<()> {
         try!(self.write_plain("\nfailures:\n"));
         let mut failures = Vec::new();
         let mut fail_out = String::new();
@@ -594,7 +608,7 @@ impl<T: Writer> ConsoleTestState<T> {
         Ok(())
     }
 
-    pub fn write_run_finish(&mut self) -> old_io::IoResult<bool> {
+    pub fn write_run_finish(&mut self) -> io::Result<bool> {
         assert!(self.passed + self.failed + self.ignored + self.measured == self.total);
 
         let success = self.failed == 0;
@@ -619,21 +633,21 @@ impl<T: Writer> ConsoleTestState<T> {
 pub fn fmt_bench_samples(bs: &BenchSamples) -> String {
     if bs.mb_s != 0 {
         format!("{:>9} ns/iter (+/- {}) = {} MB/s",
-             bs.ns_iter_summ.median as uint,
-             (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as uint,
+             bs.ns_iter_summ.median as usize,
+             (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize,
              bs.mb_s)
     } else {
         format!("{:>9} ns/iter (+/- {})",
-             bs.ns_iter_summ.median as uint,
-             (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as uint)
+             bs.ns_iter_summ.median as usize,
+             (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize)
     }
 }
 
 // A simple console test runner
-pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn> ) -> old_io::IoResult<bool> {
+pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn> ) -> io::Result<bool> {
 
-    fn callback<T: Writer>(event: &TestEvent,
-                           st: &mut ConsoleTestState<T>) -> old_io::IoResult<()> {
+    fn callback<T: Write>(event: &TestEvent,
+                          st: &mut ConsoleTestState<T>) -> io::Result<()> {
         match (*event).clone() {
             TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
             TeWait(ref test, padding) => st.write_test_start(test, padding),
@@ -672,8 +686,8 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn> ) -> old_io:
         }
     }
 
-    let mut st = try!(ConsoleTestState::new(opts, None::<StdWriter>));
-    fn len_if_padded(t: &TestDescAndFn) -> uint {
+    let mut st = try!(ConsoleTestState::new(opts, None::<io::Stdout>));
+    fn len_if_padded(t: &TestDescAndFn) -> usize {
         match t.testfn.padding() {
             PadNone => 0,
             PadOnLeft | PadOnRight => t.desc.name.as_slice().len(),
@@ -682,7 +696,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn> ) -> old_io:
     match tests.iter().max_by(|t|len_if_padded(*t)) {
         Some(t) => {
             let n = t.desc.name.as_slice();
-            st.max_name_len = n.as_slice().len();
+            st.max_name_len = n.len();
         },
         None => {}
     }
@@ -695,13 +709,13 @@ fn should_sort_failures_before_printing_them() {
     let test_a = TestDesc {
         name: StaticTestName("a"),
         ignore: false,
-        should_fail: ShouldFail::No
+        should_panic: ShouldPanic::No
     };
 
     let test_b = TestDesc {
         name: StaticTestName("b"),
         ignore: false,
-        should_fail: ShouldFail::No
+        should_panic: ShouldPanic::No
     };
 
     let mut st = ConsoleTestState {
@@ -724,19 +738,38 @@ fn should_sort_failures_before_printing_them() {
         Pretty(_) => unreachable!()
     };
 
-    let apos = s.find_str("a").unwrap();
-    let bpos = s.find_str("b").unwrap();
+    let apos = s.find("a").unwrap();
+    let bpos = s.find("b").unwrap();
     assert!(apos < bpos);
 }
 
 fn use_color(opts: &TestOpts) -> bool {
     match opts.color {
-        AutoColor => get_concurrency() == 1 && old_io::stdout().get_ref().isatty(),
+        AutoColor => get_concurrency() == 1 && stdout_isatty(),
         AlwaysColor => true,
         NeverColor => false,
     }
 }
 
+#[cfg(unix)]
+fn stdout_isatty() -> bool {
+    unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 }
+}
+#[cfg(windows)]
+fn stdout_isatty() -> bool {
+    const STD_OUTPUT_HANDLE: libc::DWORD = -11i32 as libc::DWORD;
+    extern "system" {
+        fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
+        fn GetConsoleMode(hConsoleHandle: libc::HANDLE,
+                          lpMode: libc::LPDWORD) -> libc::BOOL;
+    }
+    unsafe {
+        let handle = GetStdHandle(STD_OUTPUT_HANDLE);
+        let mut out = 0;
+        GetConsoleMode(handle, &mut out) != 0
+    }
+}
+
 #[derive(Clone)]
 enum TestEvent {
     TeFiltered(Vec<TestDesc> ),
@@ -749,8 +782,8 @@ pub type MonitorMsg = (TestDesc, TestResult, Vec<u8> );
 
 fn run_tests<F>(opts: &TestOpts,
                 tests: Vec<TestDescAndFn> ,
-                mut callback: F) -> old_io::IoResult<()> where
-    F: FnMut(TestEvent) -> old_io::IoResult<()>,
+                mut callback: F) -> io::Result<()> where
+    F: FnMut(TestEvent) -> io::Result<()>,
 {
     let filtered_tests = filter_tests(opts, tests);
     let filtered_descs = filtered_tests.iter()
@@ -809,18 +842,23 @@ fn run_tests<F>(opts: &TestOpts,
     Ok(())
 }
 
-fn get_concurrency() -> uint {
-    use std::rt;
-    match env::var("RUST_TEST_TASKS") {
+#[allow(deprecated)]
+fn get_concurrency() -> usize {
+    match env::var("RUST_TEST_THREADS") {
         Ok(s) => {
-            let opt_n: Option<uint> = s.parse().ok();
+            let opt_n: Option<usize> = s.parse().ok();
             match opt_n {
                 Some(n) if n > 0 => n,
-                _ => panic!("RUST_TEST_TASKS is `{}`, should be a positive integer.", s)
+                _ => panic!("RUST_TEST_THREADS is `{}`, should be a positive integer.", s)
             }
         }
         Err(..) => {
-            rt::default_sched_threads()
+            if std::rt::util::limit_thread_creation_due_to_osx_and_valgrind() {
+                1
+            } else {
+                extern { fn rust_get_num_cpus() -> libc::uintptr_t; }
+                unsafe { rust_get_num_cpus() as usize }
+            }
         }
     }
 }
@@ -878,25 +916,31 @@ pub fn run_test(opts: &TestOpts,
                       monitor_ch: Sender<MonitorMsg>,
                       nocapture: bool,
                       testfn: Thunk<'static>) {
+        struct Sink(Arc<Mutex<Vec<u8>>>);
+        impl Write for Sink {
+            fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+                Write::write(&mut *self.0.lock().unwrap(), data)
+            }
+            fn flush(&mut self) -> io::Result<()> { Ok(()) }
+        }
+
         thread::spawn(move || {
-            let (tx, rx) = channel();
-            let mut reader = ChanReader::new(rx);
-            let stdout = ChanWriter::new(tx.clone());
-            let stderr = ChanWriter::new(tx);
-            let mut cfg = thread::Builder::new().name(match desc.name {
+            let data = Arc::new(Mutex::new(Vec::new()));
+            let data2 = data.clone();
+            let cfg = thread::Builder::new().name(match desc.name {
                 DynTestName(ref name) => name.clone().to_string(),
                 StaticTestName(name) => name.to_string(),
             });
-            if nocapture {
-                drop((stdout, stderr));
-            } else {
-                cfg = cfg.stdout(box stdout as Box<Writer + Send>);
-                cfg = cfg.stderr(box stderr as Box<Writer + Send>);
-            }
 
-            let result_guard = cfg.spawn(move || { testfn.invoke(()) }).unwrap();
-            let stdout = reader.read_to_end().unwrap().into_iter().collect();
+            let result_guard = cfg.spawn(move || {
+                if !nocapture {
+                    io::set_print(box Sink(data2.clone()));
+                    io::set_panic(box Sink(data2));
+                }
+                testfn()
+            }).unwrap();
             let test_result = calc_result(&desc, result_guard.join());
+            let stdout = data.lock().unwrap().to_vec();
             monitor_ch.send((desc.clone(), test_result, stdout)).unwrap();
         });
     }
@@ -914,7 +958,7 @@ pub fn run_test(opts: &TestOpts,
         }
         DynMetricFn(f) => {
             let mut mm = MetricMap::new();
-            f.invoke(&mut mm);
+            f.call_box((&mut mm,));
             monitor_ch.send((desc, TrMetrics(mm), Vec::new())).unwrap();
             return;
         }
@@ -926,15 +970,15 @@ pub fn run_test(opts: &TestOpts,
         }
         DynTestFn(f) => run_test_inner(desc, monitor_ch, opts.nocapture, f),
         StaticTestFn(f) => run_test_inner(desc, monitor_ch, opts.nocapture,
-                                          Thunk::new(move|| f()))
+                                          Box::new(move|| f()))
     }
 }
 
 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))
+    match (&desc.should_panic, task_result) {
+        (&ShouldPanic::No, Ok(())) |
+        (&ShouldPanic::Yes(None), Err(_)) => TrOk,
+        (&ShouldPanic::Yes(Some(msg)), Err(ref err))
             if err.downcast_ref::<String>()
                 .map(|e| &**e)
                 .or_else(|| err.downcast_ref::<&'static str>().map(|e| *e))
@@ -976,7 +1020,7 @@ impl MetricMap {
         let MetricMap(ref mm) = *self;
         let v : Vec<String> = mm.iter()
             .map(|(k,v)| format!("{}: {} (+/- {})", *k,
-                                 v.value as f64, v.noise as f64))
+                                 v.value, v.noise))
             .collect();
         v.connect(", ")
     }
@@ -1003,7 +1047,7 @@ impl Bencher {
     pub fn iter<T, F>(&mut self, mut inner: F) where F: FnMut() -> T {
         self.dur = Duration::span(|| {
             let k = self.iterations;
-            for _ in 0u64..k {
+            for _ in 0..k {
                 black_box(inner());
             }
         });
@@ -1029,7 +1073,7 @@ impl Bencher {
     // This is a more statistics-driven benchmark algorithm
     pub fn auto_bench<F>(&mut self, mut f: F) -> stats::Summary<f64> where F: FnMut(&mut Bencher) {
         // Initial bench run to get ballpark figure.
-        let mut n = 1_u64;
+        let mut n = 1;
         self.bench_n(n, |x| f(x));
 
         // Try to estimate iter count for 1ms falling back to 1m
@@ -1087,7 +1131,14 @@ impl Bencher {
                 return summ5;
             }
 
-            n *= 2;
+            // If we overflow here just return the results so far. We check a
+            // multiplier of 10 because we're about to multiply by 2 and the
+            // next iteration of the loop will also multiply by 5 (to calculate
+            // the summ5 result)
+            n = match n.checked_mul(10) {
+                Some(_) => n * 2,
+                None => return summ5,
+            };
         }
     }
 }
@@ -1112,7 +1163,7 @@ pub mod bench {
 
         BenchSamples {
             ns_iter_summ: ns_iter_summ,
-            mb_s: mb_s as uint
+            mb_s: mb_s as usize
         }
     }
 }
@@ -1122,7 +1173,7 @@ mod tests {
     use test::{TrFailed, TrIgnored, TrOk, filter_tests, parse_opts,
                TestDesc, TestDescAndFn, TestOpts, run_test,
                MetricMap,
-               StaticTestName, DynTestName, DynTestFn, ShouldFail};
+               StaticTestName, DynTestName, DynTestFn, ShouldPanic};
     use std::thunk::Thunk;
     use std::sync::mpsc::channel;
 
@@ -1133,9 +1184,9 @@ mod tests {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: true,
-                should_fail: ShouldFail::No,
+                should_panic: ShouldPanic::No,
             },
-            testfn: DynTestFn(Thunk::new(move|| f())),
+            testfn: DynTestFn(Box::new(move|| f())),
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
@@ -1150,9 +1201,9 @@ mod tests {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: true,
-                should_fail: ShouldFail::No,
+                should_panic: ShouldPanic::No,
             },
-            testfn: DynTestFn(Thunk::new(move|| f())),
+            testfn: DynTestFn(Box::new(move|| f())),
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
@@ -1161,15 +1212,15 @@ mod tests {
     }
 
     #[test]
-    fn test_should_fail() {
+    fn test_should_panic() {
         fn f() { panic!(); }
         let desc = TestDescAndFn {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_fail: ShouldFail::Yes(None)
+                should_panic: ShouldPanic::Yes(None)
             },
-            testfn: DynTestFn(Thunk::new(move|| f())),
+            testfn: DynTestFn(Box::new(move|| f())),
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
@@ -1178,15 +1229,15 @@ mod tests {
     }
 
     #[test]
-    fn test_should_fail_good_message() {
+    fn test_should_panic_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"))
+                should_panic: ShouldPanic::Yes(Some("error message"))
             },
-            testfn: DynTestFn(Thunk::new(move|| f())),
+            testfn: DynTestFn(Box::new(move|| f())),
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
@@ -1195,15 +1246,15 @@ mod tests {
     }
 
     #[test]
-    fn test_should_fail_bad_message() {
+    fn test_should_panic_bad_message() {
         fn f() { panic!("an error message"); }
         let desc = TestDescAndFn {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_fail: ShouldFail::Yes(Some("foobar"))
+                should_panic: ShouldPanic::Yes(Some("foobar"))
             },
-            testfn: DynTestFn(Thunk::new(move|| f())),
+            testfn: DynTestFn(Box::new(move|| f())),
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
@@ -1212,15 +1263,15 @@ mod tests {
     }
 
     #[test]
-    fn test_should_fail_but_succeeds() {
+    fn test_should_panic_but_succeeds() {
         fn f() { }
         let desc = TestDescAndFn {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_fail: ShouldFail::Yes(None)
+                should_panic: ShouldPanic::Yes(None)
             },
-            testfn: DynTestFn(Thunk::new(move|| f())),
+            testfn: DynTestFn(Box::new(move|| f())),
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
@@ -1254,17 +1305,17 @@ mod tests {
                 desc: TestDesc {
                     name: StaticTestName("1"),
                     ignore: true,
-                    should_fail: ShouldFail::No,
+                    should_panic: ShouldPanic::No,
                 },
-                testfn: DynTestFn(Thunk::new(move|| {})),
+                testfn: DynTestFn(Box::new(move|| {})),
             },
             TestDescAndFn {
                 desc: TestDesc {
                     name: StaticTestName("2"),
                     ignore: false,
-                    should_fail: ShouldFail::No,
+                    should_panic: ShouldPanic::No,
                 },
-                testfn: DynTestFn(Thunk::new(move|| {})),
+                testfn: DynTestFn(Box::new(move|| {})),
             });
         let filtered = filter_tests(&opts, tests);
 
@@ -1281,8 +1332,8 @@ mod tests {
 
         let names =
             vec!("sha1::test".to_string(),
-                 "int::test_to_str".to_string(),
-                 "int::test_pow".to_string(),
+                 "isize::test_to_str".to_string(),
+                 "isize::test_pow".to_string(),
                  "test::do_not_run_ignored_tests".to_string(),
                  "test::ignored_tests_result_in_ignored".to_string(),
                  "test::first_free_arg_should_be_a_filter".to_string(),
@@ -1298,9 +1349,9 @@ mod tests {
                     desc: TestDesc {
                         name: DynTestName((*name).clone()),
                         ignore: false,
-                        should_fail: ShouldFail::No,
+                        should_panic: ShouldPanic::No,
                     },
-                    testfn: DynTestFn(Thunk::new(testfn)),
+                    testfn: DynTestFn(Box::new(testfn)),
                 };
                 tests.push(test);
             }
@@ -1309,8 +1360,8 @@ mod tests {
         let filtered = filter_tests(&opts, tests);
 
         let expected =
-            vec!("int::test_pow".to_string(),
-                 "int::test_to_str".to_string(),
+            vec!("isize::test_pow".to_string(),
+                 "isize::test_to_str".to_string(),
                  "sha1::test".to_string(),
                  "test::do_not_run_ignored_tests".to_string(),
                  "test::filter_for_ignored_option".to_string(),
index 4e94be59ade0dd540f2f743138df9cae9ae52dd1..94dee5ccc36b7a65dc39bf4e7e7463d839f3650d 100644 (file)
@@ -9,11 +9,9 @@
 // except according to those terms.
 
 #![allow(missing_docs)]
+#![allow(deprecated)] // Float
 
 use std::cmp::Ordering::{self, Less, Greater, Equal};
-use std::collections::hash_map::Entry::{Occupied, Vacant};
-use std::collections::hash_map;
-use std::hash::Hash;
 use std::mem;
 use std::num::{Float, FromPrimitive};
 
@@ -210,11 +208,11 @@ impl<T: Float + FromPrimitive> Stats<T> for [T] {
 
     fn mean(&self) -> T {
         assert!(self.len() != 0);
-        self.sum() / FromPrimitive::from_uint(self.len()).unwrap()
+        self.sum() / FromPrimitive::from_usize(self.len()).unwrap()
     }
 
     fn median(&self) -> T {
-        self.percentile(FromPrimitive::from_uint(50).unwrap())
+        self.percentile(FromPrimitive::from_usize(50).unwrap())
     }
 
     fn var(&self) -> T {
@@ -230,7 +228,7 @@ impl<T: Float + FromPrimitive> Stats<T> for [T] {
             // NB: this is _supposed to be_ len-1, not len. If you
             // change it back to len, you will be calculating a
             // population variance, not a sample variance.
-            let denom = FromPrimitive::from_uint(self.len()-1).unwrap();
+            let denom = FromPrimitive::from_usize(self.len()-1).unwrap();
             v/denom
         }
     }
@@ -240,7 +238,7 @@ impl<T: Float + FromPrimitive> Stats<T> for [T] {
     }
 
     fn std_dev_pct(&self) -> T {
-        let hundred = FromPrimitive::from_uint(100).unwrap();
+        let hundred = FromPrimitive::from_usize(100).unwrap();
         (self.std_dev() / self.mean()) * hundred
     }
 
@@ -254,7 +252,7 @@ impl<T: Float + FromPrimitive> Stats<T> for [T] {
     }
 
     fn median_abs_dev_pct(&self) -> T {
-        let hundred = FromPrimitive::from_uint(100).unwrap();
+        let hundred = FromPrimitive::from_usize(100).unwrap();
         (self.median_abs_dev() / self.median()) * hundred
     }
 
@@ -267,11 +265,11 @@ impl<T: Float + FromPrimitive> Stats<T> for [T] {
     fn quartiles(&self) -> (T,T,T) {
         let mut tmp = self.to_vec();
         local_sort(&mut tmp);
-        let first = FromPrimitive::from_uint(25).unwrap();
+        let first = FromPrimitive::from_usize(25).unwrap();
         let a = percentile_of_sorted(&tmp, first);
-        let secound = FromPrimitive::from_uint(50).unwrap();
+        let secound = FromPrimitive::from_usize(50).unwrap();
         let b = percentile_of_sorted(&tmp, secound);
-        let third = FromPrimitive::from_uint(75).unwrap();
+        let third = FromPrimitive::from_usize(75).unwrap();
         let c = percentile_of_sorted(&tmp, third);
         (a,b,c)
     }
@@ -293,16 +291,16 @@ fn percentile_of_sorted<T: Float + FromPrimitive>(sorted_samples: &[T],
     }
     let zero: T = Float::zero();
     assert!(zero <= pct);
-    let hundred = FromPrimitive::from_uint(100).unwrap();
+    let hundred = FromPrimitive::from_usize(100).unwrap();
     assert!(pct <= hundred);
     if pct == hundred {
         return sorted_samples[sorted_samples.len() - 1];
     }
-    let length = FromPrimitive::from_uint(sorted_samples.len() - 1).unwrap();
+    let length = FromPrimitive::from_usize(sorted_samples.len() - 1).unwrap();
     let rank = (pct / hundred) * length;
     let lrank = rank.floor();
     let d = rank - lrank;
-    let n = lrank.to_uint().unwrap();
+    let n = lrank.to_usize().unwrap();
     let lo = sorted_samples[n];
     let hi = sorted_samples[n+1];
     lo + (hi - lo) * d
@@ -319,7 +317,7 @@ pub fn winsorize<T: Float + FromPrimitive>(samples: &mut [T], pct: T) {
     let mut tmp = samples.to_vec();
     local_sort(&mut tmp);
     let lo = percentile_of_sorted(&tmp, pct);
-    let hundred: T = FromPrimitive::from_uint(100).unwrap();
+    let hundred: T = FromPrimitive::from_usize(100).unwrap();
     let hi = percentile_of_sorted(&tmp, hundred-pct);
     for samp in samples {
         if *samp > hi {
@@ -330,28 +328,13 @@ pub fn winsorize<T: Float + FromPrimitive>(samples: &mut [T], pct: T) {
     }
 }
 
-/// Returns a HashMap with the number of occurrences of every element in the
-/// sequence that the iterator exposes.
-pub fn freq_count<T, U>(iter: T) -> hash_map::HashMap<U, uint>
-  where T: Iterator<Item=U>, U: Eq + Clone + Hash
-{
-    let mut map: hash_map::HashMap<U,uint> = hash_map::HashMap::new();
-    for elem in iter {
-        match map.entry(elem) {
-            Occupied(mut entry) => { *entry.get_mut() += 1; },
-            Vacant(entry) => { entry.insert(1); },
-        }
-    }
-    map
-}
-
 // Test vectors generated from R, using the script src/etc/stat-test-vectors.r.
 
 #[cfg(test)]
 mod tests {
     use stats::Stats;
     use stats::Summary;
-    use std::old_io;
+    use std::old_io::{self, Writer};
     use std::f64;
 
     macro_rules! assert_approx_eq {
diff --git a/src/libunicode/char.rs b/src/libunicode/char.rs
new file mode 100644 (file)
index 0000000..2aeade5
--- /dev/null
@@ -0,0 +1,451 @@
+// 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.
+//
+// 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.
+
+//! Character manipulation (`char` type, Unicode Scalar Value)
+//!
+//! This module provides the `CharExt` trait, as well as its
+//! implementation for the primitive `char` type, in order to allow
+//! basic character manipulation.
+//!
+//! A `char` actually represents a
+//! *[Unicode Scalar
+//! Value](http://www.unicode.org/glossary/#unicode_scalar_value)*, as it can
+//! contain any Unicode code point except high-surrogate and low-surrogate code
+//! points.
+//!
+//! As such, only values in the ranges \[0x0,0xD7FF\] and \[0xE000,0x10FFFF\]
+//! (inclusive) are allowed. A `char` can always be safely cast to a `u32`;
+//! however the converse is not always true due to the above range limits
+//! and, as such, should be performed via the `from_u32` function.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+#![doc(primitive = "char")]
+
+use core::char::CharExt as C;
+use core::option::Option::{self, Some};
+use core::iter::Iterator;
+use tables::{derived_property, property, general_category, conversions, charwidth};
+
+// stable reexports
+pub use core::char::{MAX, from_u32, from_digit, EscapeUnicode, EscapeDefault};
+
+// unstable reexports
+pub use normalize::{decompose_canonical, decompose_compatible, compose};
+pub use tables::normalization::canonical_combining_class;
+pub use tables::UNICODE_VERSION;
+
+/// An iterator over the lowercase mapping of a given character, returned from
+/// the [`to_lowercase` method](../primitive.char.html#method.to_lowercase) on
+/// characters.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ToLowercase(Option<char>);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Iterator for ToLowercase {
+    type Item = char;
+    fn next(&mut self) -> Option<char> { self.0.take() }
+}
+
+/// An iterator over the uppercase mapping of a given character, returned from
+/// the [`to_uppercase` method](../primitive.char.html#method.to_uppercase) on
+/// characters.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ToUppercase(Option<char>);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Iterator for ToUppercase {
+    type Item = char;
+    fn next(&mut self) -> Option<char> { self.0.take() }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[lang = "char"]
+impl char {
+    /// Checks if a `char` parses as a numeric digit in the given radix.
+    ///
+    /// Compared to `is_numeric()`, this function only recognizes the characters
+    /// `0-9`, `a-z` and `A-Z`.
+    ///
+    /// # Return value
+    ///
+    /// Returns `true` if `c` is a valid digit under `radix`, and `false`
+    /// otherwise.
+    ///
+    /// # Panics
+    ///
+    /// Panics if given a radix > 36.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let c = '1';
+    ///
+    /// assert!(c.is_digit(10));
+    ///
+    /// assert!('f'.is_digit(16));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_digit(self, radix: u32) -> bool { C::is_digit(self, radix) }
+
+    /// Converts a character to the corresponding digit.
+    ///
+    /// # Return value
+    ///
+    /// If `c` is between '0' and '9', the corresponding value between 0 and
+    /// 9. If `c` is 'a' or 'A', 10. If `c` is 'b' or 'B', 11, etc. Returns
+    /// none if the character does not refer to a digit in the given radix.
+    ///
+    /// # Panics
+    ///
+    /// Panics if given a radix outside the range [0..36].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let c = '1';
+    ///
+    /// assert_eq!(c.to_digit(10), Some(1));
+    ///
+    /// assert_eq!('f'.to_digit(16), Some(15));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn to_digit(self, radix: u32) -> Option<u32> { C::to_digit(self, radix) }
+
+    /// Returns an iterator that yields the hexadecimal Unicode escape of a
+    /// character, as `char`s.
+    ///
+    /// All characters are escaped with Rust syntax of the form `\\u{NNNN}`
+    /// where `NNNN` is the shortest hexadecimal representation of the code
+    /// point.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// for i in '❤'.escape_unicode() {
+    ///     println!("{}", i);
+    /// }
+    /// ```
+    ///
+    /// This prints:
+    ///
+    /// ```text
+    /// \
+    /// u
+    /// {
+    /// 2
+    /// 7
+    /// 6
+    /// 4
+    /// }
+    /// ```
+    ///
+    /// Collecting into a `String`:
+    ///
+    /// ```
+    /// let heart: String = '❤'.escape_unicode().collect();
+    ///
+    /// assert_eq!(heart, r"\u{2764}");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn escape_unicode(self) -> EscapeUnicode { C::escape_unicode(self) }
+
+    /// Returns an iterator that yields the 'default' ASCII and
+    /// C++11-like literal escape of a character, as `char`s.
+    ///
+    /// The default is chosen with a bias toward producing literals that are
+    /// legal in a variety of languages, including C++11 and similar C-family
+    /// languages. The exact rules are:
+    ///
+    /// * Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
+    /// * Single-quote, double-quote and backslash chars are backslash-
+    ///   escaped.
+    /// * Any other chars in the range [0x20,0x7e] are not escaped.
+    /// * Any other chars are given hex Unicode escapes; see `escape_unicode`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// for i in '"'.escape_default() {
+    ///     println!("{}", i);
+    /// }
+    /// ```
+    ///
+    /// This prints:
+    ///
+    /// ```text
+    /// \
+    /// "
+    /// ```
+    ///
+    /// Collecting into a `String`:
+    ///
+    /// ```
+    /// let quote: String = '"'.escape_default().collect();
+    ///
+    /// assert_eq!(quote, "\\\"");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn escape_default(self) -> EscapeDefault { C::escape_default(self) }
+
+    /// Returns the number of bytes this character would need if encoded in
+    /// UTF-8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let n = 'ß'.len_utf8();
+    ///
+    /// assert_eq!(n, 2);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn len_utf8(self) -> usize { C::len_utf8(self) }
+
+    /// Returns the number of 16-bit code units this character would need if
+    /// encoded in UTF-16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let n = 'ß'.len_utf16();
+    ///
+    /// assert_eq!(n, 1);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn len_utf16(self) -> usize { C::len_utf16(self) }
+
+    /// Encodes this character as UTF-8 into the provided byte buffer, and then
+    /// returns the number of bytes written.
+    ///
+    /// If the buffer is not large enough, nothing will be written into it and a
+    /// `None` will be returned. A buffer of length four is large enough to
+    /// encode any `char`.
+    ///
+    /// # Examples
+    ///
+    /// In both of these examples, 'ß' takes two bytes to encode.
+    ///
+    /// ```
+    /// # #![feature(unicode)]
+    /// let mut b = [0; 2];
+    ///
+    /// let result = 'ß'.encode_utf8(&mut b);
+    ///
+    /// assert_eq!(result, Some(2));
+    /// ```
+    ///
+    /// A buffer that's too small:
+    ///
+    /// ```
+    /// # #![feature(unicode)]
+    /// let mut b = [0; 1];
+    ///
+    /// let result = 'ß'.encode_utf8(&mut b);
+    ///
+    /// assert_eq!(result, None);
+    /// ```
+    #[unstable(feature = "unicode",
+               reason = "pending decision about Iterator/Writer/Reader")]
+    pub fn encode_utf8(self, dst: &mut [u8]) -> Option<usize> { C::encode_utf8(self, dst) }
+
+    /// Encodes this character as UTF-16 into the provided `u16` buffer, and
+    /// then returns the number of `u16`s written.
+    ///
+    /// If the buffer is not large enough, nothing will be written into it and a
+    /// `None` will be returned. A buffer of length 2 is large enough to encode
+    /// any `char`.
+    ///
+    /// # Examples
+    ///
+    /// In both of these examples, 'ß' takes one `u16` to encode.
+    ///
+    /// ```
+    /// # #![feature(unicode)]
+    /// let mut b = [0; 1];
+    ///
+    /// let result = 'ß'.encode_utf16(&mut b);
+    ///
+    /// assert_eq!(result, Some(1));
+    /// ```
+    ///
+    /// A buffer that's too small:
+    ///
+    /// ```
+    /// # #![feature(unicode)]
+    /// let mut b = [0; 0];
+    ///
+    /// let result = 'ß'.encode_utf8(&mut b);
+    ///
+    /// assert_eq!(result, None);
+    /// ```
+    #[unstable(feature = "unicode",
+               reason = "pending decision about Iterator/Writer/Reader")]
+    pub fn encode_utf16(self, dst: &mut [u16]) -> Option<usize> { C::encode_utf16(self, dst) }
+
+    /// Returns whether the specified character is considered a Unicode
+    /// alphabetic code point.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_alphabetic(self) -> bool {
+        match self {
+            'a' ... 'z' | 'A' ... 'Z' => true,
+            c if c > '\x7f' => derived_property::Alphabetic(c),
+            _ => false
+        }
+    }
+
+    /// Returns whether the specified character satisfies the 'XID_Start'
+    /// Unicode property.
+    ///
+    /// 'XID_Start' is a Unicode Derived Property specified in
+    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+    /// mostly similar to ID_Start but modified for closure under NFKx.
+    #[unstable(feature = "unicode",
+               reason = "mainly needed for compiler internals")]
+    #[inline]
+    pub fn is_xid_start(self) -> bool { derived_property::XID_Start(self) }
+
+    /// Returns whether the specified `char` satisfies the 'XID_Continue'
+    /// Unicode property.
+    ///
+    /// 'XID_Continue' is a Unicode Derived Property specified in
+    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+    /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
+    #[unstable(feature = "unicode",
+               reason = "mainly needed for compiler internals")]
+    #[inline]
+    pub fn is_xid_continue(self) -> bool { derived_property::XID_Continue(self) }
+
+    /// Indicates whether a character is in lowercase.
+    ///
+    /// This is defined according to the terms of the Unicode Derived Core
+    /// Property `Lowercase`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_lowercase(self) -> bool {
+        match self {
+            'a' ... 'z' => true,
+            c if c > '\x7f' => derived_property::Lowercase(c),
+            _ => false
+        }
+    }
+
+    /// Indicates whether a character is in uppercase.
+    ///
+    /// This is defined according to the terms of the Unicode Derived Core
+    /// Property `Uppercase`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_uppercase(self) -> bool {
+        match self {
+            'A' ... 'Z' => true,
+            c if c > '\x7f' => derived_property::Uppercase(c),
+            _ => false
+        }
+    }
+
+    /// Indicates whether a character is whitespace.
+    ///
+    /// Whitespace is defined in terms of the Unicode Property `White_Space`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_whitespace(self) -> bool {
+        match self {
+            ' ' | '\x09' ... '\x0d' => true,
+            c if c > '\x7f' => property::White_Space(c),
+            _ => false
+        }
+    }
+
+    /// Indicates whether a character is alphanumeric.
+    ///
+    /// Alphanumericness is defined in terms of the Unicode General Categories
+    /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_alphanumeric(self) -> bool {
+        self.is_alphabetic() || self.is_numeric()
+    }
+
+    /// Indicates whether a character is a control code point.
+    ///
+    /// Control code points are defined in terms of the Unicode General
+    /// Category `Cc`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_control(self) -> bool { general_category::Cc(self) }
+
+    /// Indicates whether the character is numeric (Nd, Nl, or No).
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_numeric(self) -> bool {
+        match self {
+            '0' ... '9' => true,
+            c if c > '\x7f' => general_category::N(c),
+            _ => false
+        }
+    }
+
+    /// Converts a character to its lowercase equivalent.
+    ///
+    /// The case-folding performed is the common or simple mapping. See
+    /// `to_uppercase()` for references and more information.
+    ///
+    /// # Return value
+    ///
+    /// Returns an iterator which yields the characters corresponding to the
+    /// lowercase equivalent of the character. If no conversion is possible then
+    /// the input character is returned.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn to_lowercase(self) -> ToLowercase {
+        ToLowercase(Some(conversions::to_lower(self)))
+    }
+
+    /// Converts a character to its uppercase equivalent.
+    ///
+    /// The case-folding performed is the common or simple mapping: it maps
+    /// one Unicode codepoint to its uppercase equivalent according to the
+    /// Unicode database [1]. The additional [`SpecialCasing.txt`] is not yet
+    /// considered here, but the iterator returned will soon support this form
+    /// of case folding.
+    ///
+    /// A full reference can be found here [2].
+    ///
+    /// # Return value
+    ///
+    /// Returns an iterator which yields the characters corresponding to the
+    /// uppercase equivalent of the character. If no conversion is possible then
+    /// the input character is returned.
+    ///
+    /// [1]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+    ///
+    /// [`SpecialCasing`.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt
+    ///
+    /// [2]: http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn to_uppercase(self) -> ToUppercase {
+        ToUppercase(Some(conversions::to_upper(self)))
+    }
+
+    /// Returns this character's displayed width in columns, or `None` if it is a
+    /// control character other than `'\x00'`.
+    ///
+    /// `is_cjk` determines behavior for characters in the Ambiguous category:
+    /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
+    /// In CJK contexts, `is_cjk` should be `true`, else it should be `false`.
+    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
+    /// recommends that these characters be treated as 1 column (i.e.,
+    /// `is_cjk` = `false`) if the context cannot be reliably determined.
+    #[unstable(feature = "unicode",
+               reason = "needs expert opinion. is_cjk flag stands out as ugly")]
+    pub fn width(self, is_cjk: bool) -> Option<usize> { charwidth::width(self, is_cjk) }
+}
index 791886be1ce5b6a6de76889ca83bc7d7f53a3f7e..6879fa7b3ba6834a7df0543d1aef4f6e560ff94b 100644 (file)
 //! provide for basic string-related manipulations. This crate does not
 //! (yet) aim to provide a full set of Unicode tables.
 
+// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
+#![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "unicode"]
 #![unstable(feature = "unicode")]
+#![feature(lang_items)]
 #![feature(staged_api)]
 #![staged_api]
 #![crate_type = "rlib"]
@@ -32,6 +35,7 @@
 #![feature(no_std)]
 #![no_std]
 #![feature(core)]
+#![doc(test(no_crate_inject))]
 
 extern crate core;
 
@@ -40,37 +44,8 @@ pub use tables::regex;
 
 mod normalize;
 mod tables;
-mod u_char;
 mod u_str;
-
-// re-export char so that std et al see it correctly
-/// Character manipulation (`char` type, Unicode Scalar Value)
-///
-/// This module provides the `CharExt` trait, as well as its
-/// implementation for the primitive `char` type, in order to allow
-/// basic character manipulation.
-///
-/// A `char` actually represents a
-/// *[Unicode Scalar Value](http://www.unicode.org/glossary/#unicode_scalar_value)*,
-/// as it can contain any Unicode code point except high-surrogate and
-/// low-surrogate code points.
-///
-/// As such, only values in the ranges \[0x0,0xD7FF\] and \[0xE000,0x10FFFF\]
-/// (inclusive) are allowed. A `char` can always be safely cast to a `u32`;
-/// however the converse is not always true due to the above range limits
-/// and, as such, should be performed via the `from_u32` function.
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(primitive = "char")]
-pub mod char {
-    pub use core::char::{MAX, from_u32, from_digit};
-
-    pub use normalize::{decompose_canonical, decompose_compatible, compose};
-
-    pub use tables::normalization::canonical_combining_class;
-    pub use tables::UNICODE_VERSION;
-
-    pub use u_char::CharExt;
-}
+pub mod char;
 
 pub mod str {
     pub use u_str::{UnicodeStr, Words, Graphemes, GraphemeIndices};
index 61f447a3dd3b687a836c4f17f308aabd76ab41ca..1fb6ee7bc7ce1952c59d0f0dd579b6b6e86413e3 100644 (file)
@@ -27,7 +27,7 @@ fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
 }
 
 pub mod general_category {
-    pub static C_table: &'static [(char, char)] = &[
+    pub const C_table: &'static [(char, char)] = &[
         ('\u{0}', '\u{1f}'), ('\u{7f}', '\u{9f}'), ('\u{ad}', '\u{ad}'), ('\u{378}', '\u{379}'),
         ('\u{380}', '\u{383}'), ('\u{38b}', '\u{38b}'), ('\u{38d}', '\u{38d}'), ('\u{3a2}',
         '\u{3a2}'), ('\u{530}', '\u{530}'), ('\u{557}', '\u{558}'), ('\u{560}', '\u{560}'),
@@ -115,27 +115,26 @@ pub mod general_category {
         '\u{2eff}'), ('\u{2fd6}', '\u{2fef}'), ('\u{2ffc}', '\u{2fff}'), ('\u{3040}', '\u{3040}'),
         ('\u{3097}', '\u{3098}'), ('\u{3100}', '\u{3104}'), ('\u{312e}', '\u{3130}'), ('\u{318f}',
         '\u{318f}'), ('\u{31bb}', '\u{31bf}'), ('\u{31e4}', '\u{31ef}'), ('\u{321f}', '\u{321f}'),
-        ('\u{32ff}', '\u{32ff}'), ('\u{3401}', '\u{4db4}'), ('\u{4db6}', '\u{4dbf}'), ('\u{4e01}',
-        '\u{9fcb}'), ('\u{9fcd}', '\u{9fff}'), ('\u{a48d}', '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'),
-        ('\u{a62c}', '\u{a63f}'), ('\u{a69e}', '\u{a69e}'), ('\u{a6f8}', '\u{a6ff}'), ('\u{a78f}',
-        '\u{a78f}'), ('\u{a7ae}', '\u{a7af}'), ('\u{a7b2}', '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'),
-        ('\u{a83a}', '\u{a83f}'), ('\u{a878}', '\u{a87f}'), ('\u{a8c5}', '\u{a8cd}'), ('\u{a8da}',
-        '\u{a8df}'), ('\u{a8fc}', '\u{a8ff}'), ('\u{a954}', '\u{a95e}'), ('\u{a97d}', '\u{a97f}'),
-        ('\u{a9ce}', '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'), ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}',
-        '\u{aa3f}'), ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}', '\u{aa5b}'), ('\u{aac3}', '\u{aada}'),
-        ('\u{aaf7}', '\u{ab00}'), ('\u{ab07}', '\u{ab08}'), ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}',
-        '\u{ab1f}'), ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}', '\u{ab2f}'), ('\u{ab60}', '\u{ab63}'),
-        ('\u{ab66}', '\u{abbf}'), ('\u{abee}', '\u{abef}'), ('\u{abfa}', '\u{abff}'), ('\u{ac01}',
-        '\u{d7a2}'), ('\u{d7a4}', '\u{d7af}'), ('\u{d7c7}', '\u{d7ca}'), ('\u{d7fc}', '\u{d7ff}'),
-        ('\u{e000}', '\u{f8ff}'), ('\u{fa6e}', '\u{fa6f}'), ('\u{fada}', '\u{faff}'), ('\u{fb07}',
-        '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}', '\u{fb37}'), ('\u{fb3d}', '\u{fb3d}'),
-        ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'), ('\u{fb45}', '\u{fb45}'), ('\u{fbc2}',
-        '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}', '\u{fd91}'), ('\u{fdc8}', '\u{fdef}'),
-        ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'), ('\u{fe2e}', '\u{fe2f}'), ('\u{fe53}',
-        '\u{fe53}'), ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}', '\u{fe6f}'), ('\u{fe75}', '\u{fe75}'),
-        ('\u{fefd}', '\u{ff00}'), ('\u{ffbf}', '\u{ffc1}'), ('\u{ffc8}', '\u{ffc9}'), ('\u{ffd0}',
-        '\u{ffd1}'), ('\u{ffd8}', '\u{ffd9}'), ('\u{ffdd}', '\u{ffdf}'), ('\u{ffe7}', '\u{ffe7}'),
-        ('\u{ffef}', '\u{fffb}'), ('\u{fffe}', '\u{ffff}'), ('\u{1000c}', '\u{1000c}'),
+        ('\u{32ff}', '\u{32ff}'), ('\u{4db6}', '\u{4dbf}'), ('\u{9fcd}', '\u{9fff}'), ('\u{a48d}',
+        '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'), ('\u{a62c}', '\u{a63f}'), ('\u{a69e}', '\u{a69e}'),
+        ('\u{a6f8}', '\u{a6ff}'), ('\u{a78f}', '\u{a78f}'), ('\u{a7ae}', '\u{a7af}'), ('\u{a7b2}',
+        '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'), ('\u{a83a}', '\u{a83f}'), ('\u{a878}', '\u{a87f}'),
+        ('\u{a8c5}', '\u{a8cd}'), ('\u{a8da}', '\u{a8df}'), ('\u{a8fc}', '\u{a8ff}'), ('\u{a954}',
+        '\u{a95e}'), ('\u{a97d}', '\u{a97f}'), ('\u{a9ce}', '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'),
+        ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}', '\u{aa3f}'), ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}',
+        '\u{aa5b}'), ('\u{aac3}', '\u{aada}'), ('\u{aaf7}', '\u{ab00}'), ('\u{ab07}', '\u{ab08}'),
+        ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}', '\u{ab1f}'), ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}',
+        '\u{ab2f}'), ('\u{ab60}', '\u{ab63}'), ('\u{ab66}', '\u{abbf}'), ('\u{abee}', '\u{abef}'),
+        ('\u{abfa}', '\u{abff}'), ('\u{d7a4}', '\u{d7af}'), ('\u{d7c7}', '\u{d7ca}'), ('\u{d7fc}',
+        '\u{d7ff}'), ('\u{e000}', '\u{f8ff}'), ('\u{fa6e}', '\u{fa6f}'), ('\u{fada}', '\u{faff}'),
+        ('\u{fb07}', '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}', '\u{fb37}'), ('\u{fb3d}',
+        '\u{fb3d}'), ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'), ('\u{fb45}', '\u{fb45}'),
+        ('\u{fbc2}', '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}', '\u{fd91}'), ('\u{fdc8}',
+        '\u{fdef}'), ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'), ('\u{fe2e}', '\u{fe2f}'),
+        ('\u{fe53}', '\u{fe53}'), ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}', '\u{fe6f}'), ('\u{fe75}',
+        '\u{fe75}'), ('\u{fefd}', '\u{ff00}'), ('\u{ffbf}', '\u{ffc1}'), ('\u{ffc8}', '\u{ffc9}'),
+        ('\u{ffd0}', '\u{ffd1}'), ('\u{ffd8}', '\u{ffd9}'), ('\u{ffdd}', '\u{ffdf}'), ('\u{ffe7}',
+        '\u{ffe7}'), ('\u{ffef}', '\u{fffb}'), ('\u{fffe}', '\u{ffff}'), ('\u{1000c}', '\u{1000c}'),
         ('\u{10027}', '\u{10027}'), ('\u{1003b}', '\u{1003b}'), ('\u{1003e}', '\u{1003e}'),
         ('\u{1004e}', '\u{1004f}'), ('\u{1005e}', '\u{1007f}'), ('\u{100fb}', '\u{100ff}'),
         ('\u{10103}', '\u{10106}'), ('\u{10134}', '\u{10136}'), ('\u{1018d}', '\u{1018f}'),
@@ -210,13 +209,12 @@ pub mod general_category {
         ('\u{1f643}', '\u{1f644}'), ('\u{1f6d0}', '\u{1f6df}'), ('\u{1f6ed}', '\u{1f6ef}'),
         ('\u{1f6f4}', '\u{1f6ff}'), ('\u{1f774}', '\u{1f77f}'), ('\u{1f7d5}', '\u{1f7ff}'),
         ('\u{1f80c}', '\u{1f80f}'), ('\u{1f848}', '\u{1f84f}'), ('\u{1f85a}', '\u{1f85f}'),
-        ('\u{1f888}', '\u{1f88f}'), ('\u{1f8ae}', '\u{1ffff}'), ('\u{20001}', '\u{2a6d5}'),
-        ('\u{2a6d7}', '\u{2a6ff}'), ('\u{2a701}', '\u{2b733}'), ('\u{2b735}', '\u{2b73f}'),
-        ('\u{2b741}', '\u{2b81c}'), ('\u{2b81e}', '\u{2f7ff}'), ('\u{2fa1e}', '\u{e00ff}'),
+        ('\u{1f888}', '\u{1f88f}'), ('\u{1f8ae}', '\u{1ffff}'), ('\u{2a6d7}', '\u{2a6ff}'),
+        ('\u{2b735}', '\u{2b73f}'), ('\u{2b81e}', '\u{2f7ff}'), ('\u{2fa1e}', '\u{e00ff}'),
         ('\u{e01f0}', '\u{10ffff}')
     ];
 
-    pub static Cc_table: &'static [(char, char)] = &[
+    pub const Cc_table: &'static [(char, char)] = &[
         ('\u{0}', '\u{1f}'), ('\u{7f}', '\u{9f}')
     ];
 
@@ -224,7 +222,7 @@ pub mod general_category {
         super::bsearch_range_table(c, Cc_table)
     }
 
-    pub static Cf_table: &'static [(char, char)] = &[
+    pub const Cf_table: &'static [(char, char)] = &[
         ('\u{ad}', '\u{ad}'), ('\u{600}', '\u{605}'), ('\u{61c}', '\u{61c}'), ('\u{6dd}',
         '\u{6dd}'), ('\u{70f}', '\u{70f}'), ('\u{180e}', '\u{180e}'), ('\u{200b}', '\u{200f}'),
         ('\u{202a}', '\u{202e}'), ('\u{2060}', '\u{2064}'), ('\u{2066}', '\u{206f}'), ('\u{feff}',
@@ -233,7 +231,7 @@ pub mod general_category {
         '\u{e007f}')
     ];
 
-    pub static Cn_table: &'static [(char, char)] = &[
+    pub const Cn_table: &'static [(char, char)] = &[
         ('\u{378}', '\u{379}'), ('\u{380}', '\u{383}'), ('\u{38b}', '\u{38b}'), ('\u{38d}',
         '\u{38d}'), ('\u{3a2}', '\u{3a2}'), ('\u{530}', '\u{530}'), ('\u{557}', '\u{558}'),
         ('\u{560}', '\u{560}'), ('\u{588}', '\u{588}'), ('\u{58b}', '\u{58c}'), ('\u{590}',
@@ -319,115 +317,111 @@ pub mod general_category {
         ('\u{2e9a}', '\u{2e9a}'), ('\u{2ef4}', '\u{2eff}'), ('\u{2fd6}', '\u{2fef}'), ('\u{2ffc}',
         '\u{2fff}'), ('\u{3040}', '\u{3040}'), ('\u{3097}', '\u{3098}'), ('\u{3100}', '\u{3104}'),
         ('\u{312e}', '\u{3130}'), ('\u{318f}', '\u{318f}'), ('\u{31bb}', '\u{31bf}'), ('\u{31e4}',
-        '\u{31ef}'), ('\u{321f}', '\u{321f}'), ('\u{32ff}', '\u{32ff}'), ('\u{3401}', '\u{4db4}'),
-        ('\u{4db6}', '\u{4dbf}'), ('\u{4e01}', '\u{9fcb}'), ('\u{9fcd}', '\u{9fff}'), ('\u{a48d}',
-        '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'), ('\u{a62c}', '\u{a63f}'), ('\u{a69e}', '\u{a69e}'),
-        ('\u{a6f8}', '\u{a6ff}'), ('\u{a78f}', '\u{a78f}'), ('\u{a7ae}', '\u{a7af}'), ('\u{a7b2}',
-        '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'), ('\u{a83a}', '\u{a83f}'), ('\u{a878}', '\u{a87f}'),
-        ('\u{a8c5}', '\u{a8cd}'), ('\u{a8da}', '\u{a8df}'), ('\u{a8fc}', '\u{a8ff}'), ('\u{a954}',
-        '\u{a95e}'), ('\u{a97d}', '\u{a97f}'), ('\u{a9ce}', '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'),
-        ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}', '\u{aa3f}'), ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}',
-        '\u{aa5b}'), ('\u{aac3}', '\u{aada}'), ('\u{aaf7}', '\u{ab00}'), ('\u{ab07}', '\u{ab08}'),
-        ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}', '\u{ab1f}'), ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}',
-        '\u{ab2f}'), ('\u{ab60}', '\u{ab63}'), ('\u{ab66}', '\u{abbf}'), ('\u{abee}', '\u{abef}'),
-        ('\u{abfa}', '\u{abff}'), ('\u{ac01}', '\u{d7a2}'), ('\u{d7a4}', '\u{d7af}'), ('\u{d7c7}',
-        '\u{d7ca}'), ('\u{d7fc}', '\u{d7ff}'), ('\u{e001}', '\u{f8fe}'), ('\u{fa6e}', '\u{fa6f}'),
-        ('\u{fada}', '\u{faff}'), ('\u{fb07}', '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}',
-        '\u{fb37}'), ('\u{fb3d}', '\u{fb3d}'), ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'),
-        ('\u{fb45}', '\u{fb45}'), ('\u{fbc2}', '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}',
-        '\u{fd91}'), ('\u{fdc8}', '\u{fdef}'), ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'),
-        ('\u{fe2e}', '\u{fe2f}'), ('\u{fe53}', '\u{fe53}'), ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}',
-        '\u{fe6f}'), ('\u{fe75}', '\u{fe75}'), ('\u{fefd}', '\u{fefe}'), ('\u{ff00}', '\u{ff00}'),
-        ('\u{ffbf}', '\u{ffc1}'), ('\u{ffc8}', '\u{ffc9}'), ('\u{ffd0}', '\u{ffd1}'), ('\u{ffd8}',
-        '\u{ffd9}'), ('\u{ffdd}', '\u{ffdf}'), ('\u{ffe7}', '\u{ffe7}'), ('\u{ffef}', '\u{fff8}'),
-        ('\u{fffe}', '\u{ffff}'), ('\u{1000c}', '\u{1000c}'), ('\u{10027}', '\u{10027}'),
-        ('\u{1003b}', '\u{1003b}'), ('\u{1003e}', '\u{1003e}'), ('\u{1004e}', '\u{1004f}'),
-        ('\u{1005e}', '\u{1007f}'), ('\u{100fb}', '\u{100ff}'), ('\u{10103}', '\u{10106}'),
-        ('\u{10134}', '\u{10136}'), ('\u{1018d}', '\u{1018f}'), ('\u{1019c}', '\u{1019f}'),
-        ('\u{101a1}', '\u{101cf}'), ('\u{101fe}', '\u{1027f}'), ('\u{1029d}', '\u{1029f}'),
-        ('\u{102d1}', '\u{102df}'), ('\u{102fc}', '\u{102ff}'), ('\u{10324}', '\u{1032f}'),
-        ('\u{1034b}', '\u{1034f}'), ('\u{1037b}', '\u{1037f}'), ('\u{1039e}', '\u{1039e}'),
-        ('\u{103c4}', '\u{103c7}'), ('\u{103d6}', '\u{103ff}'), ('\u{1049e}', '\u{1049f}'),
-        ('\u{104aa}', '\u{104ff}'), ('\u{10528}', '\u{1052f}'), ('\u{10564}', '\u{1056e}'),
-        ('\u{10570}', '\u{105ff}'), ('\u{10737}', '\u{1073f}'), ('\u{10756}', '\u{1075f}'),
-        ('\u{10768}', '\u{107ff}'), ('\u{10806}', '\u{10807}'), ('\u{10809}', '\u{10809}'),
-        ('\u{10836}', '\u{10836}'), ('\u{10839}', '\u{1083b}'), ('\u{1083d}', '\u{1083e}'),
-        ('\u{10856}', '\u{10856}'), ('\u{1089f}', '\u{108a6}'), ('\u{108b0}', '\u{108ff}'),
-        ('\u{1091c}', '\u{1091e}'), ('\u{1093a}', '\u{1093e}'), ('\u{10940}', '\u{1097f}'),
-        ('\u{109b8}', '\u{109bd}'), ('\u{109c0}', '\u{109ff}'), ('\u{10a04}', '\u{10a04}'),
-        ('\u{10a07}', '\u{10a0b}'), ('\u{10a14}', '\u{10a14}'), ('\u{10a18}', '\u{10a18}'),
-        ('\u{10a34}', '\u{10a37}'), ('\u{10a3b}', '\u{10a3e}'), ('\u{10a48}', '\u{10a4f}'),
-        ('\u{10a59}', '\u{10a5f}'), ('\u{10aa0}', '\u{10abf}'), ('\u{10ae7}', '\u{10aea}'),
-        ('\u{10af7}', '\u{10aff}'), ('\u{10b36}', '\u{10b38}'), ('\u{10b56}', '\u{10b57}'),
-        ('\u{10b73}', '\u{10b77}'), ('\u{10b92}', '\u{10b98}'), ('\u{10b9d}', '\u{10ba8}'),
-        ('\u{10bb0}', '\u{10bff}'), ('\u{10c49}', '\u{10e5f}'), ('\u{10e7f}', '\u{10fff}'),
-        ('\u{1104e}', '\u{11051}'), ('\u{11070}', '\u{1107e}'), ('\u{110c2}', '\u{110cf}'),
-        ('\u{110e9}', '\u{110ef}'), ('\u{110fa}', '\u{110ff}'), ('\u{11135}', '\u{11135}'),
-        ('\u{11144}', '\u{1114f}'), ('\u{11177}', '\u{1117f}'), ('\u{111c9}', '\u{111cc}'),
-        ('\u{111ce}', '\u{111cf}'), ('\u{111db}', '\u{111e0}'), ('\u{111f5}', '\u{111ff}'),
-        ('\u{11212}', '\u{11212}'), ('\u{1123e}', '\u{112af}'), ('\u{112eb}', '\u{112ef}'),
-        ('\u{112fa}', '\u{11300}'), ('\u{11304}', '\u{11304}'), ('\u{1130d}', '\u{1130e}'),
-        ('\u{11311}', '\u{11312}'), ('\u{11329}', '\u{11329}'), ('\u{11331}', '\u{11331}'),
-        ('\u{11334}', '\u{11334}'), ('\u{1133a}', '\u{1133b}'), ('\u{11345}', '\u{11346}'),
-        ('\u{11349}', '\u{1134a}'), ('\u{1134e}', '\u{11356}'), ('\u{11358}', '\u{1135c}'),
-        ('\u{11364}', '\u{11365}'), ('\u{1136d}', '\u{1136f}'), ('\u{11375}', '\u{1147f}'),
-        ('\u{114c8}', '\u{114cf}'), ('\u{114da}', '\u{1157f}'), ('\u{115b6}', '\u{115b7}'),
-        ('\u{115ca}', '\u{115ff}'), ('\u{11645}', '\u{1164f}'), ('\u{1165a}', '\u{1167f}'),
-        ('\u{116b8}', '\u{116bf}'), ('\u{116ca}', '\u{1189f}'), ('\u{118f3}', '\u{118fe}'),
-        ('\u{11900}', '\u{11abf}'), ('\u{11af9}', '\u{11fff}'), ('\u{12399}', '\u{123ff}'),
-        ('\u{1246f}', '\u{1246f}'), ('\u{12475}', '\u{12fff}'), ('\u{1342f}', '\u{167ff}'),
-        ('\u{16a39}', '\u{16a3f}'), ('\u{16a5f}', '\u{16a5f}'), ('\u{16a6a}', '\u{16a6d}'),
-        ('\u{16a70}', '\u{16acf}'), ('\u{16aee}', '\u{16aef}'), ('\u{16af6}', '\u{16aff}'),
-        ('\u{16b46}', '\u{16b4f}'), ('\u{16b5a}', '\u{16b5a}'), ('\u{16b62}', '\u{16b62}'),
-        ('\u{16b78}', '\u{16b7c}'), ('\u{16b90}', '\u{16eff}'), ('\u{16f45}', '\u{16f4f}'),
-        ('\u{16f7f}', '\u{16f8e}'), ('\u{16fa0}', '\u{1afff}'), ('\u{1b002}', '\u{1bbff}'),
-        ('\u{1bc6b}', '\u{1bc6f}'), ('\u{1bc7d}', '\u{1bc7f}'), ('\u{1bc89}', '\u{1bc8f}'),
-        ('\u{1bc9a}', '\u{1bc9b}'), ('\u{1bca4}', '\u{1cfff}'), ('\u{1d0f6}', '\u{1d0ff}'),
-        ('\u{1d127}', '\u{1d128}'), ('\u{1d1de}', '\u{1d1ff}'), ('\u{1d246}', '\u{1d2ff}'),
-        ('\u{1d357}', '\u{1d35f}'), ('\u{1d372}', '\u{1d3ff}'), ('\u{1d455}', '\u{1d455}'),
-        ('\u{1d49d}', '\u{1d49d}'), ('\u{1d4a0}', '\u{1d4a1}'), ('\u{1d4a3}', '\u{1d4a4}'),
-        ('\u{1d4a7}', '\u{1d4a8}'), ('\u{1d4ad}', '\u{1d4ad}'), ('\u{1d4ba}', '\u{1d4ba}'),
-        ('\u{1d4bc}', '\u{1d4bc}'), ('\u{1d4c4}', '\u{1d4c4}'), ('\u{1d506}', '\u{1d506}'),
-        ('\u{1d50b}', '\u{1d50c}'), ('\u{1d515}', '\u{1d515}'), ('\u{1d51d}', '\u{1d51d}'),
-        ('\u{1d53a}', '\u{1d53a}'), ('\u{1d53f}', '\u{1d53f}'), ('\u{1d545}', '\u{1d545}'),
-        ('\u{1d547}', '\u{1d549}'), ('\u{1d551}', '\u{1d551}'), ('\u{1d6a6}', '\u{1d6a7}'),
-        ('\u{1d7cc}', '\u{1d7cd}'), ('\u{1d800}', '\u{1e7ff}'), ('\u{1e8c5}', '\u{1e8c6}'),
-        ('\u{1e8d7}', '\u{1edff}'), ('\u{1ee04}', '\u{1ee04}'), ('\u{1ee20}', '\u{1ee20}'),
-        ('\u{1ee23}', '\u{1ee23}'), ('\u{1ee25}', '\u{1ee26}'), ('\u{1ee28}', '\u{1ee28}'),
-        ('\u{1ee33}', '\u{1ee33}'), ('\u{1ee38}', '\u{1ee38}'), ('\u{1ee3a}', '\u{1ee3a}'),
-        ('\u{1ee3c}', '\u{1ee41}'), ('\u{1ee43}', '\u{1ee46}'), ('\u{1ee48}', '\u{1ee48}'),
-        ('\u{1ee4a}', '\u{1ee4a}'), ('\u{1ee4c}', '\u{1ee4c}'), ('\u{1ee50}', '\u{1ee50}'),
-        ('\u{1ee53}', '\u{1ee53}'), ('\u{1ee55}', '\u{1ee56}'), ('\u{1ee58}', '\u{1ee58}'),
-        ('\u{1ee5a}', '\u{1ee5a}'), ('\u{1ee5c}', '\u{1ee5c}'), ('\u{1ee5e}', '\u{1ee5e}'),
-        ('\u{1ee60}', '\u{1ee60}'), ('\u{1ee63}', '\u{1ee63}'), ('\u{1ee65}', '\u{1ee66}'),
-        ('\u{1ee6b}', '\u{1ee6b}'), ('\u{1ee73}', '\u{1ee73}'), ('\u{1ee78}', '\u{1ee78}'),
-        ('\u{1ee7d}', '\u{1ee7d}'), ('\u{1ee7f}', '\u{1ee7f}'), ('\u{1ee8a}', '\u{1ee8a}'),
-        ('\u{1ee9c}', '\u{1eea0}'), ('\u{1eea4}', '\u{1eea4}'), ('\u{1eeaa}', '\u{1eeaa}'),
-        ('\u{1eebc}', '\u{1eeef}'), ('\u{1eef2}', '\u{1efff}'), ('\u{1f02c}', '\u{1f02f}'),
-        ('\u{1f094}', '\u{1f09f}'), ('\u{1f0af}', '\u{1f0b0}'), ('\u{1f0c0}', '\u{1f0c0}'),
-        ('\u{1f0d0}', '\u{1f0d0}'), ('\u{1f0f6}', '\u{1f0ff}'), ('\u{1f10d}', '\u{1f10f}'),
-        ('\u{1f12f}', '\u{1f12f}'), ('\u{1f16c}', '\u{1f16f}'), ('\u{1f19b}', '\u{1f1e5}'),
-        ('\u{1f203}', '\u{1f20f}'), ('\u{1f23b}', '\u{1f23f}'), ('\u{1f249}', '\u{1f24f}'),
-        ('\u{1f252}', '\u{1f2ff}'), ('\u{1f32d}', '\u{1f32f}'), ('\u{1f37e}', '\u{1f37f}'),
-        ('\u{1f3cf}', '\u{1f3d3}'), ('\u{1f3f8}', '\u{1f3ff}'), ('\u{1f4ff}', '\u{1f4ff}'),
-        ('\u{1f54b}', '\u{1f54f}'), ('\u{1f57a}', '\u{1f57a}'), ('\u{1f5a4}', '\u{1f5a4}'),
-        ('\u{1f643}', '\u{1f644}'), ('\u{1f6d0}', '\u{1f6df}'), ('\u{1f6ed}', '\u{1f6ef}'),
-        ('\u{1f6f4}', '\u{1f6ff}'), ('\u{1f774}', '\u{1f77f}'), ('\u{1f7d5}', '\u{1f7ff}'),
-        ('\u{1f80c}', '\u{1f80f}'), ('\u{1f848}', '\u{1f84f}'), ('\u{1f85a}', '\u{1f85f}'),
-        ('\u{1f888}', '\u{1f88f}'), ('\u{1f8ae}', '\u{1ffff}'), ('\u{20001}', '\u{2a6d5}'),
-        ('\u{2a6d7}', '\u{2a6ff}'), ('\u{2a701}', '\u{2b733}'), ('\u{2b735}', '\u{2b73f}'),
-        ('\u{2b741}', '\u{2b81c}'), ('\u{2b81e}', '\u{2f7ff}'), ('\u{2fa1e}', '\u{e0000}'),
-        ('\u{e0002}', '\u{e001f}'), ('\u{e0080}', '\u{e00ff}'), ('\u{e01f0}', '\u{effff}'),
-        ('\u{f0001}', '\u{ffffc}'), ('\u{ffffe}', '\u{fffff}'), ('\u{100001}', '\u{10fffc}'),
-        ('\u{10fffe}', '\u{10ffff}')
-    ];
-
-    pub static Co_table: &'static [(char, char)] = &[
-        ('\u{e000}', '\u{e000}'), ('\u{f8ff}', '\u{f8ff}'), ('\u{f0000}', '\u{f0000}'),
-        ('\u{ffffd}', '\u{ffffd}'), ('\u{100000}', '\u{100000}'), ('\u{10fffd}', '\u{10fffd}')
-    ];
-
-    pub static L_table: &'static [(char, char)] = &[
+        '\u{31ef}'), ('\u{321f}', '\u{321f}'), ('\u{32ff}', '\u{32ff}'), ('\u{4db6}', '\u{4dbf}'),
+        ('\u{9fcd}', '\u{9fff}'), ('\u{a48d}', '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'), ('\u{a62c}',
+        '\u{a63f}'), ('\u{a69e}', '\u{a69e}'), ('\u{a6f8}', '\u{a6ff}'), ('\u{a78f}', '\u{a78f}'),
+        ('\u{a7ae}', '\u{a7af}'), ('\u{a7b2}', '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'), ('\u{a83a}',
+        '\u{a83f}'), ('\u{a878}', '\u{a87f}'), ('\u{a8c5}', '\u{a8cd}'), ('\u{a8da}', '\u{a8df}'),
+        ('\u{a8fc}', '\u{a8ff}'), ('\u{a954}', '\u{a95e}'), ('\u{a97d}', '\u{a97f}'), ('\u{a9ce}',
+        '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'), ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}', '\u{aa3f}'),
+        ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}', '\u{aa5b}'), ('\u{aac3}', '\u{aada}'), ('\u{aaf7}',
+        '\u{ab00}'), ('\u{ab07}', '\u{ab08}'), ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}', '\u{ab1f}'),
+        ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}', '\u{ab2f}'), ('\u{ab60}', '\u{ab63}'), ('\u{ab66}',
+        '\u{abbf}'), ('\u{abee}', '\u{abef}'), ('\u{abfa}', '\u{abff}'), ('\u{d7a4}', '\u{d7af}'),
+        ('\u{d7c7}', '\u{d7ca}'), ('\u{d7fc}', '\u{d7ff}'), ('\u{fa6e}', '\u{fa6f}'), ('\u{fada}',
+        '\u{faff}'), ('\u{fb07}', '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}', '\u{fb37}'),
+        ('\u{fb3d}', '\u{fb3d}'), ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'), ('\u{fb45}',
+        '\u{fb45}'), ('\u{fbc2}', '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}', '\u{fd91}'),
+        ('\u{fdc8}', '\u{fdef}'), ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'), ('\u{fe2e}',
+        '\u{fe2f}'), ('\u{fe53}', '\u{fe53}'), ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}', '\u{fe6f}'),
+        ('\u{fe75}', '\u{fe75}'), ('\u{fefd}', '\u{fefe}'), ('\u{ff00}', '\u{ff00}'), ('\u{ffbf}',
+        '\u{ffc1}'), ('\u{ffc8}', '\u{ffc9}'), ('\u{ffd0}', '\u{ffd1}'), ('\u{ffd8}', '\u{ffd9}'),
+        ('\u{ffdd}', '\u{ffdf}'), ('\u{ffe7}', '\u{ffe7}'), ('\u{ffef}', '\u{fff8}'), ('\u{fffe}',
+        '\u{ffff}'), ('\u{1000c}', '\u{1000c}'), ('\u{10027}', '\u{10027}'), ('\u{1003b}',
+        '\u{1003b}'), ('\u{1003e}', '\u{1003e}'), ('\u{1004e}', '\u{1004f}'), ('\u{1005e}',
+        '\u{1007f}'), ('\u{100fb}', '\u{100ff}'), ('\u{10103}', '\u{10106}'), ('\u{10134}',
+        '\u{10136}'), ('\u{1018d}', '\u{1018f}'), ('\u{1019c}', '\u{1019f}'), ('\u{101a1}',
+        '\u{101cf}'), ('\u{101fe}', '\u{1027f}'), ('\u{1029d}', '\u{1029f}'), ('\u{102d1}',
+        '\u{102df}'), ('\u{102fc}', '\u{102ff}'), ('\u{10324}', '\u{1032f}'), ('\u{1034b}',
+        '\u{1034f}'), ('\u{1037b}', '\u{1037f}'), ('\u{1039e}', '\u{1039e}'), ('\u{103c4}',
+        '\u{103c7}'), ('\u{103d6}', '\u{103ff}'), ('\u{1049e}', '\u{1049f}'), ('\u{104aa}',
+        '\u{104ff}'), ('\u{10528}', '\u{1052f}'), ('\u{10564}', '\u{1056e}'), ('\u{10570}',
+        '\u{105ff}'), ('\u{10737}', '\u{1073f}'), ('\u{10756}', '\u{1075f}'), ('\u{10768}',
+        '\u{107ff}'), ('\u{10806}', '\u{10807}'), ('\u{10809}', '\u{10809}'), ('\u{10836}',
+        '\u{10836}'), ('\u{10839}', '\u{1083b}'), ('\u{1083d}', '\u{1083e}'), ('\u{10856}',
+        '\u{10856}'), ('\u{1089f}', '\u{108a6}'), ('\u{108b0}', '\u{108ff}'), ('\u{1091c}',
+        '\u{1091e}'), ('\u{1093a}', '\u{1093e}'), ('\u{10940}', '\u{1097f}'), ('\u{109b8}',
+        '\u{109bd}'), ('\u{109c0}', '\u{109ff}'), ('\u{10a04}', '\u{10a04}'), ('\u{10a07}',
+        '\u{10a0b}'), ('\u{10a14}', '\u{10a14}'), ('\u{10a18}', '\u{10a18}'), ('\u{10a34}',
+        '\u{10a37}'), ('\u{10a3b}', '\u{10a3e}'), ('\u{10a48}', '\u{10a4f}'), ('\u{10a59}',
+        '\u{10a5f}'), ('\u{10aa0}', '\u{10abf}'), ('\u{10ae7}', '\u{10aea}'), ('\u{10af7}',
+        '\u{10aff}'), ('\u{10b36}', '\u{10b38}'), ('\u{10b56}', '\u{10b57}'), ('\u{10b73}',
+        '\u{10b77}'), ('\u{10b92}', '\u{10b98}'), ('\u{10b9d}', '\u{10ba8}'), ('\u{10bb0}',
+        '\u{10bff}'), ('\u{10c49}', '\u{10e5f}'), ('\u{10e7f}', '\u{10fff}'), ('\u{1104e}',
+        '\u{11051}'), ('\u{11070}', '\u{1107e}'), ('\u{110c2}', '\u{110cf}'), ('\u{110e9}',
+        '\u{110ef}'), ('\u{110fa}', '\u{110ff}'), ('\u{11135}', '\u{11135}'), ('\u{11144}',
+        '\u{1114f}'), ('\u{11177}', '\u{1117f}'), ('\u{111c9}', '\u{111cc}'), ('\u{111ce}',
+        '\u{111cf}'), ('\u{111db}', '\u{111e0}'), ('\u{111f5}', '\u{111ff}'), ('\u{11212}',
+        '\u{11212}'), ('\u{1123e}', '\u{112af}'), ('\u{112eb}', '\u{112ef}'), ('\u{112fa}',
+        '\u{11300}'), ('\u{11304}', '\u{11304}'), ('\u{1130d}', '\u{1130e}'), ('\u{11311}',
+        '\u{11312}'), ('\u{11329}', '\u{11329}'), ('\u{11331}', '\u{11331}'), ('\u{11334}',
+        '\u{11334}'), ('\u{1133a}', '\u{1133b}'), ('\u{11345}', '\u{11346}'), ('\u{11349}',
+        '\u{1134a}'), ('\u{1134e}', '\u{11356}'), ('\u{11358}', '\u{1135c}'), ('\u{11364}',
+        '\u{11365}'), ('\u{1136d}', '\u{1136f}'), ('\u{11375}', '\u{1147f}'), ('\u{114c8}',
+        '\u{114cf}'), ('\u{114da}', '\u{1157f}'), ('\u{115b6}', '\u{115b7}'), ('\u{115ca}',
+        '\u{115ff}'), ('\u{11645}', '\u{1164f}'), ('\u{1165a}', '\u{1167f}'), ('\u{116b8}',
+        '\u{116bf}'), ('\u{116ca}', '\u{1189f}'), ('\u{118f3}', '\u{118fe}'), ('\u{11900}',
+        '\u{11abf}'), ('\u{11af9}', '\u{11fff}'), ('\u{12399}', '\u{123ff}'), ('\u{1246f}',
+        '\u{1246f}'), ('\u{12475}', '\u{12fff}'), ('\u{1342f}', '\u{167ff}'), ('\u{16a39}',
+        '\u{16a3f}'), ('\u{16a5f}', '\u{16a5f}'), ('\u{16a6a}', '\u{16a6d}'), ('\u{16a70}',
+        '\u{16acf}'), ('\u{16aee}', '\u{16aef}'), ('\u{16af6}', '\u{16aff}'), ('\u{16b46}',
+        '\u{16b4f}'), ('\u{16b5a}', '\u{16b5a}'), ('\u{16b62}', '\u{16b62}'), ('\u{16b78}',
+        '\u{16b7c}'), ('\u{16b90}', '\u{16eff}'), ('\u{16f45}', '\u{16f4f}'), ('\u{16f7f}',
+        '\u{16f8e}'), ('\u{16fa0}', '\u{1afff}'), ('\u{1b002}', '\u{1bbff}'), ('\u{1bc6b}',
+        '\u{1bc6f}'), ('\u{1bc7d}', '\u{1bc7f}'), ('\u{1bc89}', '\u{1bc8f}'), ('\u{1bc9a}',
+        '\u{1bc9b}'), ('\u{1bca4}', '\u{1cfff}'), ('\u{1d0f6}', '\u{1d0ff}'), ('\u{1d127}',
+        '\u{1d128}'), ('\u{1d1de}', '\u{1d1ff}'), ('\u{1d246}', '\u{1d2ff}'), ('\u{1d357}',
+        '\u{1d35f}'), ('\u{1d372}', '\u{1d3ff}'), ('\u{1d455}', '\u{1d455}'), ('\u{1d49d}',
+        '\u{1d49d}'), ('\u{1d4a0}', '\u{1d4a1}'), ('\u{1d4a3}', '\u{1d4a4}'), ('\u{1d4a7}',
+        '\u{1d4a8}'), ('\u{1d4ad}', '\u{1d4ad}'), ('\u{1d4ba}', '\u{1d4ba}'), ('\u{1d4bc}',
+        '\u{1d4bc}'), ('\u{1d4c4}', '\u{1d4c4}'), ('\u{1d506}', '\u{1d506}'), ('\u{1d50b}',
+        '\u{1d50c}'), ('\u{1d515}', '\u{1d515}'), ('\u{1d51d}', '\u{1d51d}'), ('\u{1d53a}',
+        '\u{1d53a}'), ('\u{1d53f}', '\u{1d53f}'), ('\u{1d545}', '\u{1d545}'), ('\u{1d547}',
+        '\u{1d549}'), ('\u{1d551}', '\u{1d551}'), ('\u{1d6a6}', '\u{1d6a7}'), ('\u{1d7cc}',
+        '\u{1d7cd}'), ('\u{1d800}', '\u{1e7ff}'), ('\u{1e8c5}', '\u{1e8c6}'), ('\u{1e8d7}',
+        '\u{1edff}'), ('\u{1ee04}', '\u{1ee04}'), ('\u{1ee20}', '\u{1ee20}'), ('\u{1ee23}',
+        '\u{1ee23}'), ('\u{1ee25}', '\u{1ee26}'), ('\u{1ee28}', '\u{1ee28}'), ('\u{1ee33}',
+        '\u{1ee33}'), ('\u{1ee38}', '\u{1ee38}'), ('\u{1ee3a}', '\u{1ee3a}'), ('\u{1ee3c}',
+        '\u{1ee41}'), ('\u{1ee43}', '\u{1ee46}'), ('\u{1ee48}', '\u{1ee48}'), ('\u{1ee4a}',
+        '\u{1ee4a}'), ('\u{1ee4c}', '\u{1ee4c}'), ('\u{1ee50}', '\u{1ee50}'), ('\u{1ee53}',
+        '\u{1ee53}'), ('\u{1ee55}', '\u{1ee56}'), ('\u{1ee58}', '\u{1ee58}'), ('\u{1ee5a}',
+        '\u{1ee5a}'), ('\u{1ee5c}', '\u{1ee5c}'), ('\u{1ee5e}', '\u{1ee5e}'), ('\u{1ee60}',
+        '\u{1ee60}'), ('\u{1ee63}', '\u{1ee63}'), ('\u{1ee65}', '\u{1ee66}'), ('\u{1ee6b}',
+        '\u{1ee6b}'), ('\u{1ee73}', '\u{1ee73}'), ('\u{1ee78}', '\u{1ee78}'), ('\u{1ee7d}',
+        '\u{1ee7d}'), ('\u{1ee7f}', '\u{1ee7f}'), ('\u{1ee8a}', '\u{1ee8a}'), ('\u{1ee9c}',
+        '\u{1eea0}'), ('\u{1eea4}', '\u{1eea4}'), ('\u{1eeaa}', '\u{1eeaa}'), ('\u{1eebc}',
+        '\u{1eeef}'), ('\u{1eef2}', '\u{1efff}'), ('\u{1f02c}', '\u{1f02f}'), ('\u{1f094}',
+        '\u{1f09f}'), ('\u{1f0af}', '\u{1f0b0}'), ('\u{1f0c0}', '\u{1f0c0}'), ('\u{1f0d0}',
+        '\u{1f0d0}'), ('\u{1f0f6}', '\u{1f0ff}'), ('\u{1f10d}', '\u{1f10f}'), ('\u{1f12f}',
+        '\u{1f12f}'), ('\u{1f16c}', '\u{1f16f}'), ('\u{1f19b}', '\u{1f1e5}'), ('\u{1f203}',
+        '\u{1f20f}'), ('\u{1f23b}', '\u{1f23f}'), ('\u{1f249}', '\u{1f24f}'), ('\u{1f252}',
+        '\u{1f2ff}'), ('\u{1f32d}', '\u{1f32f}'), ('\u{1f37e}', '\u{1f37f}'), ('\u{1f3cf}',
+        '\u{1f3d3}'), ('\u{1f3f8}', '\u{1f3ff}'), ('\u{1f4ff}', '\u{1f4ff}'), ('\u{1f54b}',
+        '\u{1f54f}'), ('\u{1f57a}', '\u{1f57a}'), ('\u{1f5a4}', '\u{1f5a4}'), ('\u{1f643}',
+        '\u{1f644}'), ('\u{1f6d0}', '\u{1f6df}'), ('\u{1f6ed}', '\u{1f6ef}'), ('\u{1f6f4}',
+        '\u{1f6ff}'), ('\u{1f774}', '\u{1f77f}'), ('\u{1f7d5}', '\u{1f7ff}'), ('\u{1f80c}',
+        '\u{1f80f}'), ('\u{1f848}', '\u{1f84f}'), ('\u{1f85a}', '\u{1f85f}'), ('\u{1f888}',
+        '\u{1f88f}'), ('\u{1f8ae}', '\u{1ffff}'), ('\u{2a6d7}', '\u{2a6ff}'), ('\u{2b735}',
+        '\u{2b73f}'), ('\u{2b81e}', '\u{2f7ff}'), ('\u{2fa1e}', '\u{e0000}'), ('\u{e0002}',
+        '\u{e001f}'), ('\u{e0080}', '\u{e00ff}'), ('\u{e01f0}', '\u{effff}'), ('\u{ffffe}',
+        '\u{fffff}'), ('\u{10fffe}', '\u{10ffff}')
+    ];
+
+    pub const Co_table: &'static [(char, char)] = &[
+        ('\u{e000}', '\u{f8ff}'), ('\u{f0000}', '\u{ffffd}'), ('\u{100000}', '\u{10fffd}')
+    ];
+
+    pub const L_table: &'static [(char, char)] = &[
         ('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'),
         ('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{2c1}'),
         ('\u{2c6}', '\u{2d1}'), ('\u{2e0}', '\u{2e4}'), ('\u{2ec}', '\u{2ec}'), ('\u{2ee}',
@@ -511,89 +505,87 @@ pub mod general_category {
         ('\u{2e2f}', '\u{2e2f}'), ('\u{3005}', '\u{3006}'), ('\u{3031}', '\u{3035}'), ('\u{303b}',
         '\u{303c}'), ('\u{3041}', '\u{3096}'), ('\u{309d}', '\u{309f}'), ('\u{30a1}', '\u{30fa}'),
         ('\u{30fc}', '\u{30ff}'), ('\u{3105}', '\u{312d}'), ('\u{3131}', '\u{318e}'), ('\u{31a0}',
-        '\u{31ba}'), ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{3400}'), ('\u{4db5}', '\u{4db5}'),
-        ('\u{4e00}', '\u{4e00}'), ('\u{9fcc}', '\u{9fcc}'), ('\u{a000}', '\u{a48c}'), ('\u{a4d0}',
-        '\u{a4fd}'), ('\u{a500}', '\u{a60c}'), ('\u{a610}', '\u{a61f}'), ('\u{a62a}', '\u{a62b}'),
-        ('\u{a640}', '\u{a66e}'), ('\u{a67f}', '\u{a69d}'), ('\u{a6a0}', '\u{a6e5}'), ('\u{a717}',
-        '\u{a71f}'), ('\u{a722}', '\u{a788}'), ('\u{a78b}', '\u{a78e}'), ('\u{a790}', '\u{a7ad}'),
-        ('\u{a7b0}', '\u{a7b1}'), ('\u{a7f7}', '\u{a801}'), ('\u{a803}', '\u{a805}'), ('\u{a807}',
-        '\u{a80a}'), ('\u{a80c}', '\u{a822}'), ('\u{a840}', '\u{a873}'), ('\u{a882}', '\u{a8b3}'),
-        ('\u{a8f2}', '\u{a8f7}'), ('\u{a8fb}', '\u{a8fb}'), ('\u{a90a}', '\u{a925}'), ('\u{a930}',
-        '\u{a946}'), ('\u{a960}', '\u{a97c}'), ('\u{a984}', '\u{a9b2}'), ('\u{a9cf}', '\u{a9cf}'),
-        ('\u{a9e0}', '\u{a9e4}'), ('\u{a9e6}', '\u{a9ef}'), ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}',
-        '\u{aa28}'), ('\u{aa40}', '\u{aa42}'), ('\u{aa44}', '\u{aa4b}'), ('\u{aa60}', '\u{aa76}'),
-        ('\u{aa7a}', '\u{aa7a}'), ('\u{aa7e}', '\u{aaaf}'), ('\u{aab1}', '\u{aab1}'), ('\u{aab5}',
-        '\u{aab6}'), ('\u{aab9}', '\u{aabd}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac2}', '\u{aac2}'),
-        ('\u{aadb}', '\u{aadd}'), ('\u{aae0}', '\u{aaea}'), ('\u{aaf2}', '\u{aaf4}'), ('\u{ab01}',
-        '\u{ab06}'), ('\u{ab09}', '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', '\u{ab26}'),
-        ('\u{ab28}', '\u{ab2e}'), ('\u{ab30}', '\u{ab5a}'), ('\u{ab5c}', '\u{ab5f}'), ('\u{ab64}',
-        '\u{ab65}'), ('\u{abc0}', '\u{abe2}'), ('\u{ac00}', '\u{ac00}'), ('\u{d7a3}', '\u{d7a3}'),
-        ('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'), ('\u{fa70}',
-        '\u{fad9}'), ('\u{fb00}', '\u{fb06}'), ('\u{fb13}', '\u{fb17}'), ('\u{fb1d}', '\u{fb1d}'),
-        ('\u{fb1f}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'), ('\u{fb38}', '\u{fb3c}'), ('\u{fb3e}',
-        '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}', '\u{fb44}'), ('\u{fb46}', '\u{fbb1}'),
-        ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'), ('\u{fd92}', '\u{fdc7}'), ('\u{fdf0}',
-        '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}', '\u{fefc}'), ('\u{ff21}', '\u{ff3a}'),
-        ('\u{ff41}', '\u{ff5a}'), ('\u{ff66}', '\u{ffbe}'), ('\u{ffc2}', '\u{ffc7}'), ('\u{ffca}',
-        '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}'), ('\u{10000}', '\u{1000b}'),
-        ('\u{1000d}', '\u{10026}'), ('\u{10028}', '\u{1003a}'), ('\u{1003c}', '\u{1003d}'),
-        ('\u{1003f}', '\u{1004d}'), ('\u{10050}', '\u{1005d}'), ('\u{10080}', '\u{100fa}'),
-        ('\u{10280}', '\u{1029c}'), ('\u{102a0}', '\u{102d0}'), ('\u{10300}', '\u{1031f}'),
-        ('\u{10330}', '\u{10340}'), ('\u{10342}', '\u{10349}'), ('\u{10350}', '\u{10375}'),
-        ('\u{10380}', '\u{1039d}'), ('\u{103a0}', '\u{103c3}'), ('\u{103c8}', '\u{103cf}'),
-        ('\u{10400}', '\u{1049d}'), ('\u{10500}', '\u{10527}'), ('\u{10530}', '\u{10563}'),
-        ('\u{10600}', '\u{10736}'), ('\u{10740}', '\u{10755}'), ('\u{10760}', '\u{10767}'),
-        ('\u{10800}', '\u{10805}'), ('\u{10808}', '\u{10808}'), ('\u{1080a}', '\u{10835}'),
-        ('\u{10837}', '\u{10838}'), ('\u{1083c}', '\u{1083c}'), ('\u{1083f}', '\u{10855}'),
-        ('\u{10860}', '\u{10876}'), ('\u{10880}', '\u{1089e}'), ('\u{10900}', '\u{10915}'),
-        ('\u{10920}', '\u{10939}'), ('\u{10980}', '\u{109b7}'), ('\u{109be}', '\u{109bf}'),
-        ('\u{10a00}', '\u{10a00}'), ('\u{10a10}', '\u{10a13}'), ('\u{10a15}', '\u{10a17}'),
-        ('\u{10a19}', '\u{10a33}'), ('\u{10a60}', '\u{10a7c}'), ('\u{10a80}', '\u{10a9c}'),
-        ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}', '\u{10ae4}'), ('\u{10b00}', '\u{10b35}'),
-        ('\u{10b40}', '\u{10b55}'), ('\u{10b60}', '\u{10b72}'), ('\u{10b80}', '\u{10b91}'),
-        ('\u{10c00}', '\u{10c48}'), ('\u{11003}', '\u{11037}'), ('\u{11083}', '\u{110af}'),
-        ('\u{110d0}', '\u{110e8}'), ('\u{11103}', '\u{11126}'), ('\u{11150}', '\u{11172}'),
-        ('\u{11176}', '\u{11176}'), ('\u{11183}', '\u{111b2}'), ('\u{111c1}', '\u{111c4}'),
-        ('\u{111da}', '\u{111da}'), ('\u{11200}', '\u{11211}'), ('\u{11213}', '\u{1122b}'),
-        ('\u{112b0}', '\u{112de}'), ('\u{11305}', '\u{1130c}'), ('\u{1130f}', '\u{11310}'),
-        ('\u{11313}', '\u{11328}'), ('\u{1132a}', '\u{11330}'), ('\u{11332}', '\u{11333}'),
-        ('\u{11335}', '\u{11339}'), ('\u{1133d}', '\u{1133d}'), ('\u{1135d}', '\u{11361}'),
-        ('\u{11480}', '\u{114af}'), ('\u{114c4}', '\u{114c5}'), ('\u{114c7}', '\u{114c7}'),
-        ('\u{11580}', '\u{115ae}'), ('\u{11600}', '\u{1162f}'), ('\u{11644}', '\u{11644}'),
-        ('\u{11680}', '\u{116aa}'), ('\u{118a0}', '\u{118df}'), ('\u{118ff}', '\u{118ff}'),
-        ('\u{11ac0}', '\u{11af8}'), ('\u{12000}', '\u{12398}'), ('\u{13000}', '\u{1342e}'),
-        ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16ad0}', '\u{16aed}'),
-        ('\u{16b00}', '\u{16b2f}'), ('\u{16b40}', '\u{16b43}'), ('\u{16b63}', '\u{16b77}'),
-        ('\u{16b7d}', '\u{16b8f}'), ('\u{16f00}', '\u{16f44}'), ('\u{16f50}', '\u{16f50}'),
-        ('\u{16f93}', '\u{16f9f}'), ('\u{1b000}', '\u{1b001}'), ('\u{1bc00}', '\u{1bc6a}'),
-        ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'), ('\u{1bc90}', '\u{1bc99}'),
-        ('\u{1d400}', '\u{1d454}'), ('\u{1d456}', '\u{1d49c}'), ('\u{1d49e}', '\u{1d49f}'),
-        ('\u{1d4a2}', '\u{1d4a2}'), ('\u{1d4a5}', '\u{1d4a6}'), ('\u{1d4a9}', '\u{1d4ac}'),
-        ('\u{1d4ae}', '\u{1d4b9}'), ('\u{1d4bb}', '\u{1d4bb}'), ('\u{1d4bd}', '\u{1d4c3}'),
-        ('\u{1d4c5}', '\u{1d505}'), ('\u{1d507}', '\u{1d50a}'), ('\u{1d50d}', '\u{1d514}'),
-        ('\u{1d516}', '\u{1d51c}'), ('\u{1d51e}', '\u{1d539}'), ('\u{1d53b}', '\u{1d53e}'),
-        ('\u{1d540}', '\u{1d544}'), ('\u{1d546}', '\u{1d546}'), ('\u{1d54a}', '\u{1d550}'),
-        ('\u{1d552}', '\u{1d6a5}'), ('\u{1d6a8}', '\u{1d6c0}'), ('\u{1d6c2}', '\u{1d6da}'),
-        ('\u{1d6dc}', '\u{1d6fa}'), ('\u{1d6fc}', '\u{1d714}'), ('\u{1d716}', '\u{1d734}'),
-        ('\u{1d736}', '\u{1d74e}'), ('\u{1d750}', '\u{1d76e}'), ('\u{1d770}', '\u{1d788}'),
-        ('\u{1d78a}', '\u{1d7a8}'), ('\u{1d7aa}', '\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7cb}'),
-        ('\u{1e800}', '\u{1e8c4}'), ('\u{1ee00}', '\u{1ee03}'), ('\u{1ee05}', '\u{1ee1f}'),
-        ('\u{1ee21}', '\u{1ee22}'), ('\u{1ee24}', '\u{1ee24}'), ('\u{1ee27}', '\u{1ee27}'),
-        ('\u{1ee29}', '\u{1ee32}'), ('\u{1ee34}', '\u{1ee37}'), ('\u{1ee39}', '\u{1ee39}'),
-        ('\u{1ee3b}', '\u{1ee3b}'), ('\u{1ee42}', '\u{1ee42}'), ('\u{1ee47}', '\u{1ee47}'),
-        ('\u{1ee49}', '\u{1ee49}'), ('\u{1ee4b}', '\u{1ee4b}'), ('\u{1ee4d}', '\u{1ee4f}'),
-        ('\u{1ee51}', '\u{1ee52}'), ('\u{1ee54}', '\u{1ee54}'), ('\u{1ee57}', '\u{1ee57}'),
-        ('\u{1ee59}', '\u{1ee59}'), ('\u{1ee5b}', '\u{1ee5b}'), ('\u{1ee5d}', '\u{1ee5d}'),
-        ('\u{1ee5f}', '\u{1ee5f}'), ('\u{1ee61}', '\u{1ee62}'), ('\u{1ee64}', '\u{1ee64}'),
-        ('\u{1ee67}', '\u{1ee6a}'), ('\u{1ee6c}', '\u{1ee72}'), ('\u{1ee74}', '\u{1ee77}'),
-        ('\u{1ee79}', '\u{1ee7c}'), ('\u{1ee7e}', '\u{1ee7e}'), ('\u{1ee80}', '\u{1ee89}'),
-        ('\u{1ee8b}', '\u{1ee9b}'), ('\u{1eea1}', '\u{1eea3}'), ('\u{1eea5}', '\u{1eea9}'),
-        ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}', '\u{20000}'), ('\u{2a6d6}', '\u{2a6d6}'),
-        ('\u{2a700}', '\u{2a700}'), ('\u{2b734}', '\u{2b734}'), ('\u{2b740}', '\u{2b740}'),
-        ('\u{2b81d}', '\u{2b81d}'), ('\u{2f800}', '\u{2fa1d}')
+        '\u{31ba}'), ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{4db5}'), ('\u{4e00}', '\u{9fcc}'),
+        ('\u{a000}', '\u{a48c}'), ('\u{a4d0}', '\u{a4fd}'), ('\u{a500}', '\u{a60c}'), ('\u{a610}',
+        '\u{a61f}'), ('\u{a62a}', '\u{a62b}'), ('\u{a640}', '\u{a66e}'), ('\u{a67f}', '\u{a69d}'),
+        ('\u{a6a0}', '\u{a6e5}'), ('\u{a717}', '\u{a71f}'), ('\u{a722}', '\u{a788}'), ('\u{a78b}',
+        '\u{a78e}'), ('\u{a790}', '\u{a7ad}'), ('\u{a7b0}', '\u{a7b1}'), ('\u{a7f7}', '\u{a801}'),
+        ('\u{a803}', '\u{a805}'), ('\u{a807}', '\u{a80a}'), ('\u{a80c}', '\u{a822}'), ('\u{a840}',
+        '\u{a873}'), ('\u{a882}', '\u{a8b3}'), ('\u{a8f2}', '\u{a8f7}'), ('\u{a8fb}', '\u{a8fb}'),
+        ('\u{a90a}', '\u{a925}'), ('\u{a930}', '\u{a946}'), ('\u{a960}', '\u{a97c}'), ('\u{a984}',
+        '\u{a9b2}'), ('\u{a9cf}', '\u{a9cf}'), ('\u{a9e0}', '\u{a9e4}'), ('\u{a9e6}', '\u{a9ef}'),
+        ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}', '\u{aa28}'), ('\u{aa40}', '\u{aa42}'), ('\u{aa44}',
+        '\u{aa4b}'), ('\u{aa60}', '\u{aa76}'), ('\u{aa7a}', '\u{aa7a}'), ('\u{aa7e}', '\u{aaaf}'),
+        ('\u{aab1}', '\u{aab1}'), ('\u{aab5}', '\u{aab6}'), ('\u{aab9}', '\u{aabd}'), ('\u{aac0}',
+        '\u{aac0}'), ('\u{aac2}', '\u{aac2}'), ('\u{aadb}', '\u{aadd}'), ('\u{aae0}', '\u{aaea}'),
+        ('\u{aaf2}', '\u{aaf4}'), ('\u{ab01}', '\u{ab06}'), ('\u{ab09}', '\u{ab0e}'), ('\u{ab11}',
+        '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', '\u{ab2e}'), ('\u{ab30}', '\u{ab5a}'),
+        ('\u{ab5c}', '\u{ab5f}'), ('\u{ab64}', '\u{ab65}'), ('\u{abc0}', '\u{abe2}'), ('\u{ac00}',
+        '\u{d7a3}'), ('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'),
+        ('\u{fa70}', '\u{fad9}'), ('\u{fb00}', '\u{fb06}'), ('\u{fb13}', '\u{fb17}'), ('\u{fb1d}',
+        '\u{fb1d}'), ('\u{fb1f}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'), ('\u{fb38}', '\u{fb3c}'),
+        ('\u{fb3e}', '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}', '\u{fb44}'), ('\u{fb46}',
+        '\u{fbb1}'), ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'), ('\u{fd92}', '\u{fdc7}'),
+        ('\u{fdf0}', '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}', '\u{fefc}'), ('\u{ff21}',
+        '\u{ff3a}'), ('\u{ff41}', '\u{ff5a}'), ('\u{ff66}', '\u{ffbe}'), ('\u{ffc2}', '\u{ffc7}'),
+        ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}'), ('\u{10000}',
+        '\u{1000b}'), ('\u{1000d}', '\u{10026}'), ('\u{10028}', '\u{1003a}'), ('\u{1003c}',
+        '\u{1003d}'), ('\u{1003f}', '\u{1004d}'), ('\u{10050}', '\u{1005d}'), ('\u{10080}',
+        '\u{100fa}'), ('\u{10280}', '\u{1029c}'), ('\u{102a0}', '\u{102d0}'), ('\u{10300}',
+        '\u{1031f}'), ('\u{10330}', '\u{10340}'), ('\u{10342}', '\u{10349}'), ('\u{10350}',
+        '\u{10375}'), ('\u{10380}', '\u{1039d}'), ('\u{103a0}', '\u{103c3}'), ('\u{103c8}',
+        '\u{103cf}'), ('\u{10400}', '\u{1049d}'), ('\u{10500}', '\u{10527}'), ('\u{10530}',
+        '\u{10563}'), ('\u{10600}', '\u{10736}'), ('\u{10740}', '\u{10755}'), ('\u{10760}',
+        '\u{10767}'), ('\u{10800}', '\u{10805}'), ('\u{10808}', '\u{10808}'), ('\u{1080a}',
+        '\u{10835}'), ('\u{10837}', '\u{10838}'), ('\u{1083c}', '\u{1083c}'), ('\u{1083f}',
+        '\u{10855}'), ('\u{10860}', '\u{10876}'), ('\u{10880}', '\u{1089e}'), ('\u{10900}',
+        '\u{10915}'), ('\u{10920}', '\u{10939}'), ('\u{10980}', '\u{109b7}'), ('\u{109be}',
+        '\u{109bf}'), ('\u{10a00}', '\u{10a00}'), ('\u{10a10}', '\u{10a13}'), ('\u{10a15}',
+        '\u{10a17}'), ('\u{10a19}', '\u{10a33}'), ('\u{10a60}', '\u{10a7c}'), ('\u{10a80}',
+        '\u{10a9c}'), ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}', '\u{10ae4}'), ('\u{10b00}',
+        '\u{10b35}'), ('\u{10b40}', '\u{10b55}'), ('\u{10b60}', '\u{10b72}'), ('\u{10b80}',
+        '\u{10b91}'), ('\u{10c00}', '\u{10c48}'), ('\u{11003}', '\u{11037}'), ('\u{11083}',
+        '\u{110af}'), ('\u{110d0}', '\u{110e8}'), ('\u{11103}', '\u{11126}'), ('\u{11150}',
+        '\u{11172}'), ('\u{11176}', '\u{11176}'), ('\u{11183}', '\u{111b2}'), ('\u{111c1}',
+        '\u{111c4}'), ('\u{111da}', '\u{111da}'), ('\u{11200}', '\u{11211}'), ('\u{11213}',
+        '\u{1122b}'), ('\u{112b0}', '\u{112de}'), ('\u{11305}', '\u{1130c}'), ('\u{1130f}',
+        '\u{11310}'), ('\u{11313}', '\u{11328}'), ('\u{1132a}', '\u{11330}'), ('\u{11332}',
+        '\u{11333}'), ('\u{11335}', '\u{11339}'), ('\u{1133d}', '\u{1133d}'), ('\u{1135d}',
+        '\u{11361}'), ('\u{11480}', '\u{114af}'), ('\u{114c4}', '\u{114c5}'), ('\u{114c7}',
+        '\u{114c7}'), ('\u{11580}', '\u{115ae}'), ('\u{11600}', '\u{1162f}'), ('\u{11644}',
+        '\u{11644}'), ('\u{11680}', '\u{116aa}'), ('\u{118a0}', '\u{118df}'), ('\u{118ff}',
+        '\u{118ff}'), ('\u{11ac0}', '\u{11af8}'), ('\u{12000}', '\u{12398}'), ('\u{13000}',
+        '\u{1342e}'), ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16ad0}',
+        '\u{16aed}'), ('\u{16b00}', '\u{16b2f}'), ('\u{16b40}', '\u{16b43}'), ('\u{16b63}',
+        '\u{16b77}'), ('\u{16b7d}', '\u{16b8f}'), ('\u{16f00}', '\u{16f44}'), ('\u{16f50}',
+        '\u{16f50}'), ('\u{16f93}', '\u{16f9f}'), ('\u{1b000}', '\u{1b001}'), ('\u{1bc00}',
+        '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'), ('\u{1bc90}',
+        '\u{1bc99}'), ('\u{1d400}', '\u{1d454}'), ('\u{1d456}', '\u{1d49c}'), ('\u{1d49e}',
+        '\u{1d49f}'), ('\u{1d4a2}', '\u{1d4a2}'), ('\u{1d4a5}', '\u{1d4a6}'), ('\u{1d4a9}',
+        '\u{1d4ac}'), ('\u{1d4ae}', '\u{1d4b9}'), ('\u{1d4bb}', '\u{1d4bb}'), ('\u{1d4bd}',
+        '\u{1d4c3}'), ('\u{1d4c5}', '\u{1d505}'), ('\u{1d507}', '\u{1d50a}'), ('\u{1d50d}',
+        '\u{1d514}'), ('\u{1d516}', '\u{1d51c}'), ('\u{1d51e}', '\u{1d539}'), ('\u{1d53b}',
+        '\u{1d53e}'), ('\u{1d540}', '\u{1d544}'), ('\u{1d546}', '\u{1d546}'), ('\u{1d54a}',
+        '\u{1d550}'), ('\u{1d552}', '\u{1d6a5}'), ('\u{1d6a8}', '\u{1d6c0}'), ('\u{1d6c2}',
+        '\u{1d6da}'), ('\u{1d6dc}', '\u{1d6fa}'), ('\u{1d6fc}', '\u{1d714}'), ('\u{1d716}',
+        '\u{1d734}'), ('\u{1d736}', '\u{1d74e}'), ('\u{1d750}', '\u{1d76e}'), ('\u{1d770}',
+        '\u{1d788}'), ('\u{1d78a}', '\u{1d7a8}'), ('\u{1d7aa}', '\u{1d7c2}'), ('\u{1d7c4}',
+        '\u{1d7cb}'), ('\u{1e800}', '\u{1e8c4}'), ('\u{1ee00}', '\u{1ee03}'), ('\u{1ee05}',
+        '\u{1ee1f}'), ('\u{1ee21}', '\u{1ee22}'), ('\u{1ee24}', '\u{1ee24}'), ('\u{1ee27}',
+        '\u{1ee27}'), ('\u{1ee29}', '\u{1ee32}'), ('\u{1ee34}', '\u{1ee37}'), ('\u{1ee39}',
+        '\u{1ee39}'), ('\u{1ee3b}', '\u{1ee3b}'), ('\u{1ee42}', '\u{1ee42}'), ('\u{1ee47}',
+        '\u{1ee47}'), ('\u{1ee49}', '\u{1ee49}'), ('\u{1ee4b}', '\u{1ee4b}'), ('\u{1ee4d}',
+        '\u{1ee4f}'), ('\u{1ee51}', '\u{1ee52}'), ('\u{1ee54}', '\u{1ee54}'), ('\u{1ee57}',
+        '\u{1ee57}'), ('\u{1ee59}', '\u{1ee59}'), ('\u{1ee5b}', '\u{1ee5b}'), ('\u{1ee5d}',
+        '\u{1ee5d}'), ('\u{1ee5f}', '\u{1ee5f}'), ('\u{1ee61}', '\u{1ee62}'), ('\u{1ee64}',
+        '\u{1ee64}'), ('\u{1ee67}', '\u{1ee6a}'), ('\u{1ee6c}', '\u{1ee72}'), ('\u{1ee74}',
+        '\u{1ee77}'), ('\u{1ee79}', '\u{1ee7c}'), ('\u{1ee7e}', '\u{1ee7e}'), ('\u{1ee80}',
+        '\u{1ee89}'), ('\u{1ee8b}', '\u{1ee9b}'), ('\u{1eea1}', '\u{1eea3}'), ('\u{1eea5}',
+        '\u{1eea9}'), ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}', '\u{2a6d6}'), ('\u{2a700}',
+        '\u{2b734}'), ('\u{2b740}', '\u{2b81d}'), ('\u{2f800}', '\u{2fa1d}')
     ];
 
-    pub static LC_table: &'static [(char, char)] = &[
+    pub const LC_table: &'static [(char, char)] = &[
         ('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{b5}', '\u{b5}'), ('\u{c0}', '\u{d6}'),
         ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'), ('\u{1bc}', '\u{1bf}'), ('\u{1c4}', '\u{293}'),
         ('\u{295}', '\u{2af}'), ('\u{370}', '\u{373}'), ('\u{376}', '\u{377}'), ('\u{37b}',
@@ -631,7 +623,7 @@ pub mod general_category {
         ('\u{1d7aa}', '\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7cb}')
     ];
 
-    pub static Ll_table: &'static [(char, char)] = &[
+    pub const Ll_table: &'static [(char, char)] = &[
         ('\u{61}', '\u{7a}'), ('\u{b5}', '\u{b5}'), ('\u{df}', '\u{f6}'), ('\u{f8}', '\u{ff}'),
         ('\u{101}', '\u{101}'), ('\u{103}', '\u{103}'), ('\u{105}', '\u{105}'), ('\u{107}',
         '\u{107}'), ('\u{109}', '\u{109}'), ('\u{10b}', '\u{10b}'), ('\u{10d}', '\u{10d}'),
@@ -814,7 +806,7 @@ pub mod general_category {
         '\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7c9}'), ('\u{1d7cb}', '\u{1d7cb}')
     ];
 
-    pub static Lm_table: &'static [(char, char)] = &[
+    pub const Lm_table: &'static [(char, char)] = &[
         ('\u{2b0}', '\u{2c1}'), ('\u{2c6}', '\u{2d1}'), ('\u{2e0}', '\u{2e4}'), ('\u{2ec}',
         '\u{2ec}'), ('\u{2ee}', '\u{2ee}'), ('\u{374}', '\u{374}'), ('\u{37a}', '\u{37a}'),
         ('\u{559}', '\u{559}'), ('\u{640}', '\u{640}'), ('\u{6e5}', '\u{6e6}'), ('\u{7f4}',
@@ -834,7 +826,7 @@ pub mod general_category {
         '\u{16f9f}')
     ];
 
-    pub static Lo_table: &'static [(char, char)] = &[
+    pub const Lo_table: &'static [(char, char)] = &[
         ('\u{aa}', '\u{aa}'), ('\u{ba}', '\u{ba}'), ('\u{1bb}', '\u{1bb}'), ('\u{1c0}', '\u{1c3}'),
         ('\u{294}', '\u{294}'), ('\u{5d0}', '\u{5ea}'), ('\u{5f0}', '\u{5f2}'), ('\u{620}',
         '\u{63f}'), ('\u{641}', '\u{64a}'), ('\u{66e}', '\u{66f}'), ('\u{671}', '\u{6d3}'),
@@ -896,81 +888,80 @@ pub mod general_category {
         '\u{2dd6}'), ('\u{2dd8}', '\u{2dde}'), ('\u{3006}', '\u{3006}'), ('\u{303c}', '\u{303c}'),
         ('\u{3041}', '\u{3096}'), ('\u{309f}', '\u{309f}'), ('\u{30a1}', '\u{30fa}'), ('\u{30ff}',
         '\u{30ff}'), ('\u{3105}', '\u{312d}'), ('\u{3131}', '\u{318e}'), ('\u{31a0}', '\u{31ba}'),
-        ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{3400}'), ('\u{4db5}', '\u{4db5}'), ('\u{4e00}',
-        '\u{4e00}'), ('\u{9fcc}', '\u{9fcc}'), ('\u{a000}', '\u{a014}'), ('\u{a016}', '\u{a48c}'),
-        ('\u{a4d0}', '\u{a4f7}'), ('\u{a500}', '\u{a60b}'), ('\u{a610}', '\u{a61f}'), ('\u{a62a}',
-        '\u{a62b}'), ('\u{a66e}', '\u{a66e}'), ('\u{a6a0}', '\u{a6e5}'), ('\u{a7f7}', '\u{a7f7}'),
-        ('\u{a7fb}', '\u{a801}'), ('\u{a803}', '\u{a805}'), ('\u{a807}', '\u{a80a}'), ('\u{a80c}',
-        '\u{a822}'), ('\u{a840}', '\u{a873}'), ('\u{a882}', '\u{a8b3}'), ('\u{a8f2}', '\u{a8f7}'),
-        ('\u{a8fb}', '\u{a8fb}'), ('\u{a90a}', '\u{a925}'), ('\u{a930}', '\u{a946}'), ('\u{a960}',
-        '\u{a97c}'), ('\u{a984}', '\u{a9b2}'), ('\u{a9e0}', '\u{a9e4}'), ('\u{a9e7}', '\u{a9ef}'),
-        ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}', '\u{aa28}'), ('\u{aa40}', '\u{aa42}'), ('\u{aa44}',
-        '\u{aa4b}'), ('\u{aa60}', '\u{aa6f}'), ('\u{aa71}', '\u{aa76}'), ('\u{aa7a}', '\u{aa7a}'),
-        ('\u{aa7e}', '\u{aaaf}'), ('\u{aab1}', '\u{aab1}'), ('\u{aab5}', '\u{aab6}'), ('\u{aab9}',
-        '\u{aabd}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac2}', '\u{aac2}'), ('\u{aadb}', '\u{aadc}'),
-        ('\u{aae0}', '\u{aaea}'), ('\u{aaf2}', '\u{aaf2}'), ('\u{ab01}', '\u{ab06}'), ('\u{ab09}',
-        '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', '\u{ab2e}'),
-        ('\u{abc0}', '\u{abe2}'), ('\u{ac00}', '\u{ac00}'), ('\u{d7a3}', '\u{d7a3}'), ('\u{d7b0}',
-        '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'), ('\u{fa70}', '\u{fad9}'),
-        ('\u{fb1d}', '\u{fb1d}'), ('\u{fb1f}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'), ('\u{fb38}',
-        '\u{fb3c}'), ('\u{fb3e}', '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}', '\u{fb44}'),
-        ('\u{fb46}', '\u{fbb1}'), ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'), ('\u{fd92}',
-        '\u{fdc7}'), ('\u{fdf0}', '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}', '\u{fefc}'),
-        ('\u{ff66}', '\u{ff6f}'), ('\u{ff71}', '\u{ff9d}'), ('\u{ffa0}', '\u{ffbe}'), ('\u{ffc2}',
-        '\u{ffc7}'), ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}'),
-        ('\u{10000}', '\u{1000b}'), ('\u{1000d}', '\u{10026}'), ('\u{10028}', '\u{1003a}'),
-        ('\u{1003c}', '\u{1003d}'), ('\u{1003f}', '\u{1004d}'), ('\u{10050}', '\u{1005d}'),
-        ('\u{10080}', '\u{100fa}'), ('\u{10280}', '\u{1029c}'), ('\u{102a0}', '\u{102d0}'),
-        ('\u{10300}', '\u{1031f}'), ('\u{10330}', '\u{10340}'), ('\u{10342}', '\u{10349}'),
-        ('\u{10350}', '\u{10375}'), ('\u{10380}', '\u{1039d}'), ('\u{103a0}', '\u{103c3}'),
-        ('\u{103c8}', '\u{103cf}'), ('\u{10450}', '\u{1049d}'), ('\u{10500}', '\u{10527}'),
-        ('\u{10530}', '\u{10563}'), ('\u{10600}', '\u{10736}'), ('\u{10740}', '\u{10755}'),
-        ('\u{10760}', '\u{10767}'), ('\u{10800}', '\u{10805}'), ('\u{10808}', '\u{10808}'),
-        ('\u{1080a}', '\u{10835}'), ('\u{10837}', '\u{10838}'), ('\u{1083c}', '\u{1083c}'),
-        ('\u{1083f}', '\u{10855}'), ('\u{10860}', '\u{10876}'), ('\u{10880}', '\u{1089e}'),
-        ('\u{10900}', '\u{10915}'), ('\u{10920}', '\u{10939}'), ('\u{10980}', '\u{109b7}'),
-        ('\u{109be}', '\u{109bf}'), ('\u{10a00}', '\u{10a00}'), ('\u{10a10}', '\u{10a13}'),
-        ('\u{10a15}', '\u{10a17}'), ('\u{10a19}', '\u{10a33}'), ('\u{10a60}', '\u{10a7c}'),
-        ('\u{10a80}', '\u{10a9c}'), ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}', '\u{10ae4}'),
-        ('\u{10b00}', '\u{10b35}'), ('\u{10b40}', '\u{10b55}'), ('\u{10b60}', '\u{10b72}'),
-        ('\u{10b80}', '\u{10b91}'), ('\u{10c00}', '\u{10c48}'), ('\u{11003}', '\u{11037}'),
-        ('\u{11083}', '\u{110af}'), ('\u{110d0}', '\u{110e8}'), ('\u{11103}', '\u{11126}'),
-        ('\u{11150}', '\u{11172}'), ('\u{11176}', '\u{11176}'), ('\u{11183}', '\u{111b2}'),
-        ('\u{111c1}', '\u{111c4}'), ('\u{111da}', '\u{111da}'), ('\u{11200}', '\u{11211}'),
-        ('\u{11213}', '\u{1122b}'), ('\u{112b0}', '\u{112de}'), ('\u{11305}', '\u{1130c}'),
-        ('\u{1130f}', '\u{11310}'), ('\u{11313}', '\u{11328}'), ('\u{1132a}', '\u{11330}'),
-        ('\u{11332}', '\u{11333}'), ('\u{11335}', '\u{11339}'), ('\u{1133d}', '\u{1133d}'),
-        ('\u{1135d}', '\u{11361}'), ('\u{11480}', '\u{114af}'), ('\u{114c4}', '\u{114c5}'),
-        ('\u{114c7}', '\u{114c7}'), ('\u{11580}', '\u{115ae}'), ('\u{11600}', '\u{1162f}'),
-        ('\u{11644}', '\u{11644}'), ('\u{11680}', '\u{116aa}'), ('\u{118ff}', '\u{118ff}'),
-        ('\u{11ac0}', '\u{11af8}'), ('\u{12000}', '\u{12398}'), ('\u{13000}', '\u{1342e}'),
-        ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16ad0}', '\u{16aed}'),
-        ('\u{16b00}', '\u{16b2f}'), ('\u{16b63}', '\u{16b77}'), ('\u{16b7d}', '\u{16b8f}'),
-        ('\u{16f00}', '\u{16f44}'), ('\u{16f50}', '\u{16f50}'), ('\u{1b000}', '\u{1b001}'),
-        ('\u{1bc00}', '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'),
-        ('\u{1bc90}', '\u{1bc99}'), ('\u{1e800}', '\u{1e8c4}'), ('\u{1ee00}', '\u{1ee03}'),
-        ('\u{1ee05}', '\u{1ee1f}'), ('\u{1ee21}', '\u{1ee22}'), ('\u{1ee24}', '\u{1ee24}'),
-        ('\u{1ee27}', '\u{1ee27}'), ('\u{1ee29}', '\u{1ee32}'), ('\u{1ee34}', '\u{1ee37}'),
-        ('\u{1ee39}', '\u{1ee39}'), ('\u{1ee3b}', '\u{1ee3b}'), ('\u{1ee42}', '\u{1ee42}'),
-        ('\u{1ee47}', '\u{1ee47}'), ('\u{1ee49}', '\u{1ee49}'), ('\u{1ee4b}', '\u{1ee4b}'),
-        ('\u{1ee4d}', '\u{1ee4f}'), ('\u{1ee51}', '\u{1ee52}'), ('\u{1ee54}', '\u{1ee54}'),
-        ('\u{1ee57}', '\u{1ee57}'), ('\u{1ee59}', '\u{1ee59}'), ('\u{1ee5b}', '\u{1ee5b}'),
-        ('\u{1ee5d}', '\u{1ee5d}'), ('\u{1ee5f}', '\u{1ee5f}'), ('\u{1ee61}', '\u{1ee62}'),
-        ('\u{1ee64}', '\u{1ee64}'), ('\u{1ee67}', '\u{1ee6a}'), ('\u{1ee6c}', '\u{1ee72}'),
-        ('\u{1ee74}', '\u{1ee77}'), ('\u{1ee79}', '\u{1ee7c}'), ('\u{1ee7e}', '\u{1ee7e}'),
-        ('\u{1ee80}', '\u{1ee89}'), ('\u{1ee8b}', '\u{1ee9b}'), ('\u{1eea1}', '\u{1eea3}'),
-        ('\u{1eea5}', '\u{1eea9}'), ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}', '\u{20000}'),
-        ('\u{2a6d6}', '\u{2a6d6}'), ('\u{2a700}', '\u{2a700}'), ('\u{2b734}', '\u{2b734}'),
-        ('\u{2b740}', '\u{2b740}'), ('\u{2b81d}', '\u{2b81d}'), ('\u{2f800}', '\u{2fa1d}')
+        ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{4db5}'), ('\u{4e00}', '\u{9fcc}'), ('\u{a000}',
+        '\u{a014}'), ('\u{a016}', '\u{a48c}'), ('\u{a4d0}', '\u{a4f7}'), ('\u{a500}', '\u{a60b}'),
+        ('\u{a610}', '\u{a61f}'), ('\u{a62a}', '\u{a62b}'), ('\u{a66e}', '\u{a66e}'), ('\u{a6a0}',
+        '\u{a6e5}'), ('\u{a7f7}', '\u{a7f7}'), ('\u{a7fb}', '\u{a801}'), ('\u{a803}', '\u{a805}'),
+        ('\u{a807}', '\u{a80a}'), ('\u{a80c}', '\u{a822}'), ('\u{a840}', '\u{a873}'), ('\u{a882}',
+        '\u{a8b3}'), ('\u{a8f2}', '\u{a8f7}'), ('\u{a8fb}', '\u{a8fb}'), ('\u{a90a}', '\u{a925}'),
+        ('\u{a930}', '\u{a946}'), ('\u{a960}', '\u{a97c}'), ('\u{a984}', '\u{a9b2}'), ('\u{a9e0}',
+        '\u{a9e4}'), ('\u{a9e7}', '\u{a9ef}'), ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}', '\u{aa28}'),
+        ('\u{aa40}', '\u{aa42}'), ('\u{aa44}', '\u{aa4b}'), ('\u{aa60}', '\u{aa6f}'), ('\u{aa71}',
+        '\u{aa76}'), ('\u{aa7a}', '\u{aa7a}'), ('\u{aa7e}', '\u{aaaf}'), ('\u{aab1}', '\u{aab1}'),
+        ('\u{aab5}', '\u{aab6}'), ('\u{aab9}', '\u{aabd}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac2}',
+        '\u{aac2}'), ('\u{aadb}', '\u{aadc}'), ('\u{aae0}', '\u{aaea}'), ('\u{aaf2}', '\u{aaf2}'),
+        ('\u{ab01}', '\u{ab06}'), ('\u{ab09}', '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}',
+        '\u{ab26}'), ('\u{ab28}', '\u{ab2e}'), ('\u{abc0}', '\u{abe2}'), ('\u{ac00}', '\u{d7a3}'),
+        ('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'), ('\u{fa70}',
+        '\u{fad9}'), ('\u{fb1d}', '\u{fb1d}'), ('\u{fb1f}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'),
+        ('\u{fb38}', '\u{fb3c}'), ('\u{fb3e}', '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}',
+        '\u{fb44}'), ('\u{fb46}', '\u{fbb1}'), ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'),
+        ('\u{fd92}', '\u{fdc7}'), ('\u{fdf0}', '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}',
+        '\u{fefc}'), ('\u{ff66}', '\u{ff6f}'), ('\u{ff71}', '\u{ff9d}'), ('\u{ffa0}', '\u{ffbe}'),
+        ('\u{ffc2}', '\u{ffc7}'), ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}',
+        '\u{ffdc}'), ('\u{10000}', '\u{1000b}'), ('\u{1000d}', '\u{10026}'), ('\u{10028}',
+        '\u{1003a}'), ('\u{1003c}', '\u{1003d}'), ('\u{1003f}', '\u{1004d}'), ('\u{10050}',
+        '\u{1005d}'), ('\u{10080}', '\u{100fa}'), ('\u{10280}', '\u{1029c}'), ('\u{102a0}',
+        '\u{102d0}'), ('\u{10300}', '\u{1031f}'), ('\u{10330}', '\u{10340}'), ('\u{10342}',
+        '\u{10349}'), ('\u{10350}', '\u{10375}'), ('\u{10380}', '\u{1039d}'), ('\u{103a0}',
+        '\u{103c3}'), ('\u{103c8}', '\u{103cf}'), ('\u{10450}', '\u{1049d}'), ('\u{10500}',
+        '\u{10527}'), ('\u{10530}', '\u{10563}'), ('\u{10600}', '\u{10736}'), ('\u{10740}',
+        '\u{10755}'), ('\u{10760}', '\u{10767}'), ('\u{10800}', '\u{10805}'), ('\u{10808}',
+        '\u{10808}'), ('\u{1080a}', '\u{10835}'), ('\u{10837}', '\u{10838}'), ('\u{1083c}',
+        '\u{1083c}'), ('\u{1083f}', '\u{10855}'), ('\u{10860}', '\u{10876}'), ('\u{10880}',
+        '\u{1089e}'), ('\u{10900}', '\u{10915}'), ('\u{10920}', '\u{10939}'), ('\u{10980}',
+        '\u{109b7}'), ('\u{109be}', '\u{109bf}'), ('\u{10a00}', '\u{10a00}'), ('\u{10a10}',
+        '\u{10a13}'), ('\u{10a15}', '\u{10a17}'), ('\u{10a19}', '\u{10a33}'), ('\u{10a60}',
+        '\u{10a7c}'), ('\u{10a80}', '\u{10a9c}'), ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}',
+        '\u{10ae4}'), ('\u{10b00}', '\u{10b35}'), ('\u{10b40}', '\u{10b55}'), ('\u{10b60}',
+        '\u{10b72}'), ('\u{10b80}', '\u{10b91}'), ('\u{10c00}', '\u{10c48}'), ('\u{11003}',
+        '\u{11037}'), ('\u{11083}', '\u{110af}'), ('\u{110d0}', '\u{110e8}'), ('\u{11103}',
+        '\u{11126}'), ('\u{11150}', '\u{11172}'), ('\u{11176}', '\u{11176}'), ('\u{11183}',
+        '\u{111b2}'), ('\u{111c1}', '\u{111c4}'), ('\u{111da}', '\u{111da}'), ('\u{11200}',
+        '\u{11211}'), ('\u{11213}', '\u{1122b}'), ('\u{112b0}', '\u{112de}'), ('\u{11305}',
+        '\u{1130c}'), ('\u{1130f}', '\u{11310}'), ('\u{11313}', '\u{11328}'), ('\u{1132a}',
+        '\u{11330}'), ('\u{11332}', '\u{11333}'), ('\u{11335}', '\u{11339}'), ('\u{1133d}',
+        '\u{1133d}'), ('\u{1135d}', '\u{11361}'), ('\u{11480}', '\u{114af}'), ('\u{114c4}',
+        '\u{114c5}'), ('\u{114c7}', '\u{114c7}'), ('\u{11580}', '\u{115ae}'), ('\u{11600}',
+        '\u{1162f}'), ('\u{11644}', '\u{11644}'), ('\u{11680}', '\u{116aa}'), ('\u{118ff}',
+        '\u{118ff}'), ('\u{11ac0}', '\u{11af8}'), ('\u{12000}', '\u{12398}'), ('\u{13000}',
+        '\u{1342e}'), ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16ad0}',
+        '\u{16aed}'), ('\u{16b00}', '\u{16b2f}'), ('\u{16b63}', '\u{16b77}'), ('\u{16b7d}',
+        '\u{16b8f}'), ('\u{16f00}', '\u{16f44}'), ('\u{16f50}', '\u{16f50}'), ('\u{1b000}',
+        '\u{1b001}'), ('\u{1bc00}', '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}',
+        '\u{1bc88}'), ('\u{1bc90}', '\u{1bc99}'), ('\u{1e800}', '\u{1e8c4}'), ('\u{1ee00}',
+        '\u{1ee03}'), ('\u{1ee05}', '\u{1ee1f}'), ('\u{1ee21}', '\u{1ee22}'), ('\u{1ee24}',
+        '\u{1ee24}'), ('\u{1ee27}', '\u{1ee27}'), ('\u{1ee29}', '\u{1ee32}'), ('\u{1ee34}',
+        '\u{1ee37}'), ('\u{1ee39}', '\u{1ee39}'), ('\u{1ee3b}', '\u{1ee3b}'), ('\u{1ee42}',
+        '\u{1ee42}'), ('\u{1ee47}', '\u{1ee47}'), ('\u{1ee49}', '\u{1ee49}'), ('\u{1ee4b}',
+        '\u{1ee4b}'), ('\u{1ee4d}', '\u{1ee4f}'), ('\u{1ee51}', '\u{1ee52}'), ('\u{1ee54}',
+        '\u{1ee54}'), ('\u{1ee57}', '\u{1ee57}'), ('\u{1ee59}', '\u{1ee59}'), ('\u{1ee5b}',
+        '\u{1ee5b}'), ('\u{1ee5d}', '\u{1ee5d}'), ('\u{1ee5f}', '\u{1ee5f}'), ('\u{1ee61}',
+        '\u{1ee62}'), ('\u{1ee64}', '\u{1ee64}'), ('\u{1ee67}', '\u{1ee6a}'), ('\u{1ee6c}',
+        '\u{1ee72}'), ('\u{1ee74}', '\u{1ee77}'), ('\u{1ee79}', '\u{1ee7c}'), ('\u{1ee7e}',
+        '\u{1ee7e}'), ('\u{1ee80}', '\u{1ee89}'), ('\u{1ee8b}', '\u{1ee9b}'), ('\u{1eea1}',
+        '\u{1eea3}'), ('\u{1eea5}', '\u{1eea9}'), ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}',
+        '\u{2a6d6}'), ('\u{2a700}', '\u{2b734}'), ('\u{2b740}', '\u{2b81d}'), ('\u{2f800}',
+        '\u{2fa1d}')
     ];
 
-    pub static Lt_table: &'static [(char, char)] = &[
+    pub const Lt_table: &'static [(char, char)] = &[
         ('\u{1c5}', '\u{1c5}'), ('\u{1c8}', '\u{1c8}'), ('\u{1cb}', '\u{1cb}'), ('\u{1f2}',
         '\u{1f2}'), ('\u{1f88}', '\u{1f8f}'), ('\u{1f98}', '\u{1f9f}'), ('\u{1fa8}', '\u{1faf}'),
         ('\u{1fbc}', '\u{1fbc}'), ('\u{1fcc}', '\u{1fcc}'), ('\u{1ffc}', '\u{1ffc}')
     ];
 
-    pub static Lu_table: &'static [(char, char)] = &[
+    pub const Lu_table: &'static [(char, char)] = &[
         ('\u{41}', '\u{5a}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{de}'), ('\u{100}', '\u{100}'),
         ('\u{102}', '\u{102}'), ('\u{104}', '\u{104}'), ('\u{106}', '\u{106}'), ('\u{108}',
         '\u{108}'), ('\u{10a}', '\u{10a}'), ('\u{10c}', '\u{10c}'), ('\u{10e}', '\u{10e}'),
@@ -1153,7 +1144,7 @@ pub mod general_category {
         '\u{1d7ca}')
     ];
 
-    pub static M_table: &'static [(char, char)] = &[
+    pub const M_table: &'static [(char, char)] = &[
         ('\u{300}', '\u{36f}'), ('\u{483}', '\u{489}'), ('\u{591}', '\u{5bd}'), ('\u{5bf}',
         '\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'), ('\u{5c7}', '\u{5c7}'),
         ('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'), ('\u{670}', '\u{670}'), ('\u{6d6}',
@@ -1224,7 +1215,7 @@ pub mod general_category {
         ('\u{1e8d0}', '\u{1e8d6}'), ('\u{e0100}', '\u{e01ef}')
     ];
 
-    pub static Mc_table: &'static [(char, char)] = &[
+    pub const Mc_table: &'static [(char, char)] = &[
         ('\u{903}', '\u{903}'), ('\u{93b}', '\u{93b}'), ('\u{93e}', '\u{940}'), ('\u{949}',
         '\u{94c}'), ('\u{94e}', '\u{94f}'), ('\u{982}', '\u{983}'), ('\u{9be}', '\u{9c0}'),
         ('\u{9c7}', '\u{9c8}'), ('\u{9cb}', '\u{9cc}'), ('\u{9d7}', '\u{9d7}'), ('\u{a03}',
@@ -1271,12 +1262,12 @@ pub mod general_category {
         ('\u{1d165}', '\u{1d166}'), ('\u{1d16d}', '\u{1d172}')
     ];
 
-    pub static Me_table: &'static [(char, char)] = &[
+    pub const Me_table: &'static [(char, char)] = &[
         ('\u{488}', '\u{489}'), ('\u{1abe}', '\u{1abe}'), ('\u{20dd}', '\u{20e0}'), ('\u{20e2}',
         '\u{20e4}'), ('\u{a670}', '\u{a672}')
     ];
 
-    pub static Mn_table: &'static [(char, char)] = &[
+    pub const Mn_table: &'static [(char, char)] = &[
         ('\u{300}', '\u{36f}'), ('\u{483}', '\u{487}'), ('\u{591}', '\u{5bd}'), ('\u{5bf}',
         '\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'), ('\u{5c7}', '\u{5c7}'),
         ('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'), ('\u{670}', '\u{670}'), ('\u{6d6}',
@@ -1355,7 +1346,7 @@ pub mod general_category {
         '\u{1e8d6}'), ('\u{e0100}', '\u{e01ef}')
     ];
 
-    pub static N_table: &'static [(char, char)] = &[
+    pub const N_table: &'static [(char, char)] = &[
         ('\u{30}', '\u{39}'), ('\u{660}', '\u{669}'), ('\u{6f0}', '\u{6f9}'), ('\u{7c0}',
         '\u{7c9}'), ('\u{966}', '\u{96f}'), ('\u{9e6}', '\u{9ef}'), ('\u{a66}', '\u{a6f}'),
         ('\u{ae6}', '\u{aef}'), ('\u{b66}', '\u{b6f}'), ('\u{be6}', '\u{bef}'), ('\u{c66}',
@@ -1381,7 +1372,7 @@ pub mod general_category {
         super::bsearch_range_table(c, N_table)
     }
 
-    pub static Nd_table: &'static [(char, char)] = &[
+    pub const Nd_table: &'static [(char, char)] = &[
         ('\u{30}', '\u{39}'), ('\u{660}', '\u{669}'), ('\u{6f0}', '\u{6f9}'), ('\u{7c0}',
         '\u{7c9}'), ('\u{966}', '\u{96f}'), ('\u{9e6}', '\u{9ef}'), ('\u{a66}', '\u{a6f}'),
         ('\u{ae6}', '\u{aef}'), ('\u{b66}', '\u{b6f}'), ('\u{be6}', '\u{bef}'), ('\u{c66}',
@@ -1399,14 +1390,14 @@ pub mod general_category {
         ('\u{16a60}', '\u{16a69}'), ('\u{16b50}', '\u{16b59}'), ('\u{1d7ce}', '\u{1d7ff}')
     ];
 
-    pub static Nl_table: &'static [(char, char)] = &[
+    pub const Nl_table: &'static [(char, char)] = &[
         ('\u{16ee}', '\u{16f0}'), ('\u{2160}', '\u{2182}'), ('\u{2185}', '\u{2188}'), ('\u{3007}',
         '\u{3007}'), ('\u{3021}', '\u{3029}'), ('\u{3038}', '\u{303a}'), ('\u{a6e6}', '\u{a6ef}'),
         ('\u{10140}', '\u{10174}'), ('\u{10341}', '\u{10341}'), ('\u{1034a}', '\u{1034a}'),
         ('\u{103d1}', '\u{103d5}'), ('\u{12400}', '\u{1246e}')
     ];
 
-    pub static No_table: &'static [(char, char)] = &[
+    pub const No_table: &'static [(char, char)] = &[
         ('\u{b2}', '\u{b3}'), ('\u{b9}', '\u{b9}'), ('\u{bc}', '\u{be}'), ('\u{9f4}', '\u{9f9}'),
         ('\u{b72}', '\u{b77}'), ('\u{bf0}', '\u{bf2}'), ('\u{c78}', '\u{c7e}'), ('\u{d70}',
         '\u{d75}'), ('\u{f2a}', '\u{f33}'), ('\u{1369}', '\u{137c}'), ('\u{17f0}', '\u{17f9}'),
@@ -1425,7 +1416,7 @@ pub mod general_category {
         '\u{1d371}'), ('\u{1e8c7}', '\u{1e8cf}'), ('\u{1f100}', '\u{1f10c}')
     ];
 
-    pub static P_table: &'static [(char, char)] = &[
+    pub const P_table: &'static [(char, char)] = &[
         ('\u{21}', '\u{23}'), ('\u{25}', '\u{2a}'), ('\u{2c}', '\u{2f}'), ('\u{3a}', '\u{3b}'),
         ('\u{3f}', '\u{40}'), ('\u{5b}', '\u{5d}'), ('\u{5f}', '\u{5f}'), ('\u{7b}', '\u{7b}'),
         ('\u{7d}', '\u{7d}'), ('\u{a1}', '\u{a1}'), ('\u{a7}', '\u{a7}'), ('\u{ab}', '\u{ab}'),
@@ -1474,12 +1465,12 @@ pub mod general_category {
         '\u{1bc9f}')
     ];
 
-    pub static Pc_table: &'static [(char, char)] = &[
+    pub const Pc_table: &'static [(char, char)] = &[
         ('\u{5f}', '\u{5f}'), ('\u{203f}', '\u{2040}'), ('\u{2054}', '\u{2054}'), ('\u{fe33}',
         '\u{fe34}'), ('\u{fe4d}', '\u{fe4f}'), ('\u{ff3f}', '\u{ff3f}')
     ];
 
-    pub static Pd_table: &'static [(char, char)] = &[
+    pub const Pd_table: &'static [(char, char)] = &[
         ('\u{2d}', '\u{2d}'), ('\u{58a}', '\u{58a}'), ('\u{5be}', '\u{5be}'), ('\u{1400}',
         '\u{1400}'), ('\u{1806}', '\u{1806}'), ('\u{2010}', '\u{2015}'), ('\u{2e17}', '\u{2e17}'),
         ('\u{2e1a}', '\u{2e1a}'), ('\u{2e3a}', '\u{2e3b}'), ('\u{2e40}', '\u{2e40}'), ('\u{301c}',
@@ -1487,7 +1478,7 @@ pub mod general_category {
         ('\u{fe58}', '\u{fe58}'), ('\u{fe63}', '\u{fe63}'), ('\u{ff0d}', '\u{ff0d}')
     ];
 
-    pub static Pe_table: &'static [(char, char)] = &[
+    pub const Pe_table: &'static [(char, char)] = &[
         ('\u{29}', '\u{29}'), ('\u{5d}', '\u{5d}'), ('\u{7d}', '\u{7d}'), ('\u{f3b}', '\u{f3b}'),
         ('\u{f3d}', '\u{f3d}'), ('\u{169c}', '\u{169c}'), ('\u{2046}', '\u{2046}'), ('\u{207e}',
         '\u{207e}'), ('\u{208e}', '\u{208e}'), ('\u{2309}', '\u{2309}'), ('\u{230b}', '\u{230b}'),
@@ -1511,20 +1502,20 @@ pub mod general_category {
         '\u{ff60}'), ('\u{ff63}', '\u{ff63}')
     ];
 
-    pub static Pf_table: &'static [(char, char)] = &[
+    pub const Pf_table: &'static [(char, char)] = &[
         ('\u{bb}', '\u{bb}'), ('\u{2019}', '\u{2019}'), ('\u{201d}', '\u{201d}'), ('\u{203a}',
         '\u{203a}'), ('\u{2e03}', '\u{2e03}'), ('\u{2e05}', '\u{2e05}'), ('\u{2e0a}', '\u{2e0a}'),
         ('\u{2e0d}', '\u{2e0d}'), ('\u{2e1d}', '\u{2e1d}'), ('\u{2e21}', '\u{2e21}')
     ];
 
-    pub static Pi_table: &'static [(char, char)] = &[
+    pub const Pi_table: &'static [(char, char)] = &[
         ('\u{ab}', '\u{ab}'), ('\u{2018}', '\u{2018}'), ('\u{201b}', '\u{201c}'), ('\u{201f}',
         '\u{201f}'), ('\u{2039}', '\u{2039}'), ('\u{2e02}', '\u{2e02}'), ('\u{2e04}', '\u{2e04}'),
         ('\u{2e09}', '\u{2e09}'), ('\u{2e0c}', '\u{2e0c}'), ('\u{2e1c}', '\u{2e1c}'), ('\u{2e20}',
         '\u{2e20}')
     ];
 
-    pub static Po_table: &'static [(char, char)] = &[
+    pub const Po_table: &'static [(char, char)] = &[
         ('\u{21}', '\u{23}'), ('\u{25}', '\u{27}'), ('\u{2a}', '\u{2a}'), ('\u{2c}', '\u{2c}'),
         ('\u{2e}', '\u{2f}'), ('\u{3a}', '\u{3b}'), ('\u{3f}', '\u{40}'), ('\u{5c}', '\u{5c}'),
         ('\u{a1}', '\u{a1}'), ('\u{a7}', '\u{a7}'), ('\u{b6}', '\u{b7}'), ('\u{bf}', '\u{bf}'),
@@ -1572,7 +1563,7 @@ pub mod general_category {
         '\u{1bc9f}')
     ];
 
-    pub static Ps_table: &'static [(char, char)] = &[
+    pub const Ps_table: &'static [(char, char)] = &[
         ('\u{28}', '\u{28}'), ('\u{5b}', '\u{5b}'), ('\u{7b}', '\u{7b}'), ('\u{f3a}', '\u{f3a}'),
         ('\u{f3c}', '\u{f3c}'), ('\u{169b}', '\u{169b}'), ('\u{201a}', '\u{201a}'), ('\u{201e}',
         '\u{201e}'), ('\u{2045}', '\u{2045}'), ('\u{207d}', '\u{207d}'), ('\u{208d}', '\u{208d}'),
@@ -1597,7 +1588,7 @@ pub mod general_category {
         ('\u{ff62}', '\u{ff62}')
     ];
 
-    pub static S_table: &'static [(char, char)] = &[
+    pub const S_table: &'static [(char, char)] = &[
         ('\u{24}', '\u{24}'), ('\u{2b}', '\u{2b}'), ('\u{3c}', '\u{3e}'), ('\u{5e}', '\u{5e}'),
         ('\u{60}', '\u{60}'), ('\u{7c}', '\u{7c}'), ('\u{7e}', '\u{7e}'), ('\u{a2}', '\u{a6}'),
         ('\u{a8}', '\u{a9}'), ('\u{ac}', '\u{ac}'), ('\u{ae}', '\u{b1}'), ('\u{b4}', '\u{b4}'),
@@ -1663,7 +1654,7 @@ pub mod general_category {
         '\u{1f887}'), ('\u{1f890}', '\u{1f8ad}')
     ];
 
-    pub static Sc_table: &'static [(char, char)] = &[
+    pub const Sc_table: &'static [(char, char)] = &[
         ('\u{24}', '\u{24}'), ('\u{a2}', '\u{a5}'), ('\u{58f}', '\u{58f}'), ('\u{60b}', '\u{60b}'),
         ('\u{9f2}', '\u{9f3}'), ('\u{9fb}', '\u{9fb}'), ('\u{af1}', '\u{af1}'), ('\u{bf9}',
         '\u{bf9}'), ('\u{e3f}', '\u{e3f}'), ('\u{17db}', '\u{17db}'), ('\u{20a0}', '\u{20bd}'),
@@ -1671,7 +1662,7 @@ pub mod general_category {
         '\u{ff04}'), ('\u{ffe0}', '\u{ffe1}'), ('\u{ffe5}', '\u{ffe6}')
     ];
 
-    pub static Sk_table: &'static [(char, char)] = &[
+    pub const Sk_table: &'static [(char, char)] = &[
         ('\u{5e}', '\u{5e}'), ('\u{60}', '\u{60}'), ('\u{a8}', '\u{a8}'), ('\u{af}', '\u{af}'),
         ('\u{b4}', '\u{b4}'), ('\u{b8}', '\u{b8}'), ('\u{2c2}', '\u{2c5}'), ('\u{2d2}', '\u{2df}'),
         ('\u{2e5}', '\u{2eb}'), ('\u{2ed}', '\u{2ed}'), ('\u{2ef}', '\u{2ff}'), ('\u{375}',
@@ -1682,7 +1673,7 @@ pub mod general_category {
         '\u{ff3e}'), ('\u{ff40}', '\u{ff40}'), ('\u{ffe3}', '\u{ffe3}')
     ];
 
-    pub static Sm_table: &'static [(char, char)] = &[
+    pub const Sm_table: &'static [(char, char)] = &[
         ('\u{2b}', '\u{2b}'), ('\u{3c}', '\u{3e}'), ('\u{7c}', '\u{7c}'), ('\u{7e}', '\u{7e}'),
         ('\u{ac}', '\u{ac}'), ('\u{b1}', '\u{b1}'), ('\u{d7}', '\u{d7}'), ('\u{f7}', '\u{f7}'),
         ('\u{3f6}', '\u{3f6}'), ('\u{606}', '\u{608}'), ('\u{2044}', '\u{2044}'), ('\u{2052}',
@@ -1704,7 +1695,7 @@ pub mod general_category {
         '\u{1d7c3}'), ('\u{1eef0}', '\u{1eef1}')
     ];
 
-    pub static So_table: &'static [(char, char)] = &[
+    pub const So_table: &'static [(char, char)] = &[
         ('\u{a6}', '\u{a6}'), ('\u{a9}', '\u{a9}'), ('\u{ae}', '\u{ae}'), ('\u{b0}', '\u{b0}'),
         ('\u{482}', '\u{482}'), ('\u{58d}', '\u{58e}'), ('\u{60e}', '\u{60f}'), ('\u{6de}',
         '\u{6de}'), ('\u{6e9}', '\u{6e9}'), ('\u{6fd}', '\u{6fe}'), ('\u{7f6}', '\u{7f6}'),
@@ -1757,21 +1748,21 @@ pub mod general_category {
         '\u{1f887}'), ('\u{1f890}', '\u{1f8ad}')
     ];
 
-    pub static Z_table: &'static [(char, char)] = &[
+    pub const Z_table: &'static [(char, char)] = &[
         ('\u{20}', '\u{20}'), ('\u{a0}', '\u{a0}'), ('\u{1680}', '\u{1680}'), ('\u{2000}',
         '\u{200a}'), ('\u{2028}', '\u{2029}'), ('\u{202f}', '\u{202f}'), ('\u{205f}', '\u{205f}'),
         ('\u{3000}', '\u{3000}')
     ];
 
-    pub static Zl_table: &'static [(char, char)] = &[
+    pub const Zl_table: &'static [(char, char)] = &[
         ('\u{2028}', '\u{2028}')
     ];
 
-    pub static Zp_table: &'static [(char, char)] = &[
+    pub const Zp_table: &'static [(char, char)] = &[
         ('\u{2029}', '\u{2029}')
     ];
 
-    pub static Zs_table: &'static [(char, char)] = &[
+    pub const Zs_table: &'static [(char, char)] = &[
         ('\u{20}', '\u{20}'), ('\u{a0}', '\u{a0}'), ('\u{1680}', '\u{1680}'), ('\u{2000}',
         '\u{200a}'), ('\u{202f}', '\u{202f}'), ('\u{205f}', '\u{205f}'), ('\u{3000}', '\u{3000}')
     ];
@@ -1779,7 +1770,7 @@ pub mod general_category {
 }
 
 pub mod derived_property {
-    pub static Alphabetic_table: &'static [(char, char)] = &[
+    pub const Alphabetic_table: &'static [(char, char)] = &[
         ('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'),
         ('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'),
         ('\u{1bb}', '\u{1bb}'), ('\u{1bc}', '\u{1bf}'), ('\u{1c0}', '\u{1c3}'), ('\u{1c4}',
@@ -2057,7 +2048,7 @@ pub mod derived_property {
         super::bsearch_range_table(c, Alphabetic_table)
     }
 
-    pub static Default_Ignorable_Code_Point_table: &'static [(char, char)] = &[
+    pub const Default_Ignorable_Code_Point_table: &'static [(char, char)] = &[
         ('\u{ad}', '\u{ad}'), ('\u{34f}', '\u{34f}'), ('\u{61c}', '\u{61c}'), ('\u{115f}',
         '\u{1160}'), ('\u{17b4}', '\u{17b5}'), ('\u{180b}', '\u{180d}'), ('\u{180e}', '\u{180e}'),
         ('\u{200b}', '\u{200f}'), ('\u{202a}', '\u{202e}'), ('\u{2060}', '\u{2064}'), ('\u{2065}',
@@ -2068,7 +2059,7 @@ pub mod derived_property {
         '\u{e00ff}'), ('\u{e0100}', '\u{e01ef}'), ('\u{e01f0}', '\u{e0fff}')
     ];
 
-    pub static Lowercase_table: &'static [(char, char)] = &[
+    pub const Lowercase_table: &'static [(char, char)] = &[
         ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'), ('\u{ba}', '\u{ba}'),
         ('\u{df}', '\u{f6}'), ('\u{f8}', '\u{ff}'), ('\u{101}', '\u{101}'), ('\u{103}', '\u{103}'),
         ('\u{105}', '\u{105}'), ('\u{107}', '\u{107}'), ('\u{109}', '\u{109}'), ('\u{10b}',
@@ -2261,7 +2252,7 @@ pub mod derived_property {
         super::bsearch_range_table(c, Lowercase_table)
     }
 
-    pub static Uppercase_table: &'static [(char, char)] = &[
+    pub const Uppercase_table: &'static [(char, char)] = &[
         ('\u{41}', '\u{5a}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{de}'), ('\u{100}', '\u{100}'),
         ('\u{102}', '\u{102}'), ('\u{104}', '\u{104}'), ('\u{106}', '\u{106}'), ('\u{108}',
         '\u{108}'), ('\u{10a}', '\u{10a}'), ('\u{10c}', '\u{10c}'), ('\u{10e}', '\u{10e}'),
@@ -2449,7 +2440,7 @@ pub mod derived_property {
         super::bsearch_range_table(c, Uppercase_table)
     }
 
-    pub static XID_Continue_table: &'static [(char, char)] = &[
+    pub const XID_Continue_table: &'static [(char, char)] = &[
         ('\u{30}', '\u{39}'), ('\u{41}', '\u{5a}'), ('\u{5f}', '\u{5f}'), ('\u{61}', '\u{7a}'),
         ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'), ('\u{b7}', '\u{b7}'), ('\u{ba}', '\u{ba}'),
         ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'), ('\u{1bb}', '\u{1bb}'),
@@ -2775,7 +2766,7 @@ pub mod derived_property {
         super::bsearch_range_table(c, XID_Continue_table)
     }
 
-    pub static XID_Start_table: &'static [(char, char)] = &[
+    pub const XID_Start_table: &'static [(char, char)] = &[
         ('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'),
         ('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'),
         ('\u{1bb}', '\u{1bb}'), ('\u{1bc}', '\u{1bf}'), ('\u{1c0}', '\u{1c3}'), ('\u{1c4}',
@@ -2967,7 +2958,7 @@ pub mod derived_property {
 }
 
 pub mod script {
-    pub static Arabic_table: &'static [(char, char)] = &[
+    pub const Arabic_table: &'static [(char, char)] = &[
         ('\u{600}', '\u{604}'), ('\u{606}', '\u{608}'), ('\u{609}', '\u{60a}'), ('\u{60b}',
         '\u{60b}'), ('\u{60d}', '\u{60d}'), ('\u{60e}', '\u{60f}'), ('\u{610}', '\u{61a}'),
         ('\u{61e}', '\u{61e}'), ('\u{620}', '\u{63f}'), ('\u{641}', '\u{64a}'), ('\u{656}',
@@ -2994,17 +2985,17 @@ pub mod script {
         ('\u{1eef0}', '\u{1eef1}')
     ];
 
-    pub static Armenian_table: &'static [(char, char)] = &[
+    pub const Armenian_table: &'static [(char, char)] = &[
         ('\u{531}', '\u{556}'), ('\u{559}', '\u{559}'), ('\u{55a}', '\u{55f}'), ('\u{561}',
         '\u{587}'), ('\u{58a}', '\u{58a}'), ('\u{58d}', '\u{58e}'), ('\u{58f}', '\u{58f}'),
         ('\u{fb13}', '\u{fb17}')
     ];
 
-    pub static Avestan_table: &'static [(char, char)] = &[
+    pub const Avestan_table: &'static [(char, char)] = &[
         ('\u{10b00}', '\u{10b35}'), ('\u{10b39}', '\u{10b3f}')
     ];
 
-    pub static Balinese_table: &'static [(char, char)] = &[
+    pub const Balinese_table: &'static [(char, char)] = &[
         ('\u{1b00}', '\u{1b03}'), ('\u{1b04}', '\u{1b04}'), ('\u{1b05}', '\u{1b33}'), ('\u{1b34}',
         '\u{1b34}'), ('\u{1b35}', '\u{1b35}'), ('\u{1b36}', '\u{1b3a}'), ('\u{1b3b}', '\u{1b3b}'),
         ('\u{1b3c}', '\u{1b3c}'), ('\u{1b3d}', '\u{1b41}'), ('\u{1b42}', '\u{1b42}'), ('\u{1b43}',
@@ -3012,22 +3003,22 @@ pub mod script {
         ('\u{1b61}', '\u{1b6a}'), ('\u{1b6b}', '\u{1b73}'), ('\u{1b74}', '\u{1b7c}')
     ];
 
-    pub static Bamum_table: &'static [(char, char)] = &[
+    pub const Bamum_table: &'static [(char, char)] = &[
         ('\u{a6a0}', '\u{a6e5}'), ('\u{a6e6}', '\u{a6ef}'), ('\u{a6f0}', '\u{a6f1}'), ('\u{a6f2}',
         '\u{a6f7}'), ('\u{16800}', '\u{16a38}')
     ];
 
-    pub static Bassa_Vah_table: &'static [(char, char)] = &[
+    pub const Bassa_Vah_table: &'static [(char, char)] = &[
         ('\u{16ad0}', '\u{16aed}'), ('\u{16af0}', '\u{16af4}'), ('\u{16af5}', '\u{16af5}')
     ];
 
-    pub static Batak_table: &'static [(char, char)] = &[
+    pub const Batak_table: &'static [(char, char)] = &[
         ('\u{1bc0}', '\u{1be5}'), ('\u{1be6}', '\u{1be6}'), ('\u{1be7}', '\u{1be7}'), ('\u{1be8}',
         '\u{1be9}'), ('\u{1bea}', '\u{1bec}'), ('\u{1bed}', '\u{1bed}'), ('\u{1bee}', '\u{1bee}'),
         ('\u{1bef}', '\u{1bf1}'), ('\u{1bf2}', '\u{1bf3}'), ('\u{1bfc}', '\u{1bff}')
     ];
 
-    pub static Bengali_table: &'static [(char, char)] = &[
+    pub const Bengali_table: &'static [(char, char)] = &[
         ('\u{980}', '\u{980}'), ('\u{981}', '\u{981}'), ('\u{982}', '\u{983}'), ('\u{985}',
         '\u{98c}'), ('\u{98f}', '\u{990}'), ('\u{993}', '\u{9a8}'), ('\u{9aa}', '\u{9b0}'),
         ('\u{9b2}', '\u{9b2}'), ('\u{9b6}', '\u{9b9}'), ('\u{9bc}', '\u{9bc}'), ('\u{9bd}',
@@ -3038,60 +3029,60 @@ pub mod script {
         '\u{9f9}'), ('\u{9fa}', '\u{9fa}'), ('\u{9fb}', '\u{9fb}')
     ];
 
-    pub static Bopomofo_table: &'static [(char, char)] = &[
+    pub const Bopomofo_table: &'static [(char, char)] = &[
         ('\u{2ea}', '\u{2eb}'), ('\u{3105}', '\u{312d}'), ('\u{31a0}', '\u{31ba}')
     ];
 
-    pub static Brahmi_table: &'static [(char, char)] = &[
+    pub const Brahmi_table: &'static [(char, char)] = &[
         ('\u{11000}', '\u{11000}'), ('\u{11001}', '\u{11001}'), ('\u{11002}', '\u{11002}'),
         ('\u{11003}', '\u{11037}'), ('\u{11038}', '\u{11046}'), ('\u{11047}', '\u{1104d}'),
         ('\u{11052}', '\u{11065}'), ('\u{11066}', '\u{1106f}'), ('\u{1107f}', '\u{1107f}')
     ];
 
-    pub static Braille_table: &'static [(char, char)] = &[
+    pub const Braille_table: &'static [(char, char)] = &[
         ('\u{2800}', '\u{28ff}')
     ];
 
-    pub static Buginese_table: &'static [(char, char)] = &[
+    pub const Buginese_table: &'static [(char, char)] = &[
         ('\u{1a00}', '\u{1a16}'), ('\u{1a17}', '\u{1a18}'), ('\u{1a19}', '\u{1a1a}'), ('\u{1a1b}',
         '\u{1a1b}'), ('\u{1a1e}', '\u{1a1f}')
     ];
 
-    pub static Buhid_table: &'static [(char, char)] = &[
+    pub const Buhid_table: &'static [(char, char)] = &[
         ('\u{1740}', '\u{1751}'), ('\u{1752}', '\u{1753}')
     ];
 
-    pub static Canadian_Aboriginal_table: &'static [(char, char)] = &[
+    pub const Canadian_Aboriginal_table: &'static [(char, char)] = &[
         ('\u{1400}', '\u{1400}'), ('\u{1401}', '\u{166c}'), ('\u{166d}', '\u{166e}'), ('\u{166f}',
         '\u{167f}'), ('\u{18b0}', '\u{18f5}')
     ];
 
-    pub static Carian_table: &'static [(char, char)] = &[
+    pub const Carian_table: &'static [(char, char)] = &[
         ('\u{102a0}', '\u{102d0}')
     ];
 
-    pub static Caucasian_Albanian_table: &'static [(char, char)] = &[
+    pub const Caucasian_Albanian_table: &'static [(char, char)] = &[
         ('\u{10530}', '\u{10563}'), ('\u{1056f}', '\u{1056f}')
     ];
 
-    pub static Chakma_table: &'static [(char, char)] = &[
+    pub const Chakma_table: &'static [(char, char)] = &[
         ('\u{11100}', '\u{11102}'), ('\u{11103}', '\u{11126}'), ('\u{11127}', '\u{1112b}'),
         ('\u{1112c}', '\u{1112c}'), ('\u{1112d}', '\u{11134}'), ('\u{11136}', '\u{1113f}'),
         ('\u{11140}', '\u{11143}')
     ];
 
-    pub static Cham_table: &'static [(char, char)] = &[
+    pub const Cham_table: &'static [(char, char)] = &[
         ('\u{aa00}', '\u{aa28}'), ('\u{aa29}', '\u{aa2e}'), ('\u{aa2f}', '\u{aa30}'), ('\u{aa31}',
         '\u{aa32}'), ('\u{aa33}', '\u{aa34}'), ('\u{aa35}', '\u{aa36}'), ('\u{aa40}', '\u{aa42}'),
         ('\u{aa43}', '\u{aa43}'), ('\u{aa44}', '\u{aa4b}'), ('\u{aa4c}', '\u{aa4c}'), ('\u{aa4d}',
         '\u{aa4d}'), ('\u{aa50}', '\u{aa59}'), ('\u{aa5c}', '\u{aa5f}')
     ];
 
-    pub static Cherokee_table: &'static [(char, char)] = &[
+    pub const Cherokee_table: &'static [(char, char)] = &[
         ('\u{13a0}', '\u{13f4}')
     ];
 
-    pub static Common_table: &'static [(char, char)] = &[
+    pub const Common_table: &'static [(char, char)] = &[
         ('\u{0}', '\u{1f}'), ('\u{20}', '\u{20}'), ('\u{21}', '\u{23}'), ('\u{24}', '\u{24}'),
         ('\u{25}', '\u{27}'), ('\u{28}', '\u{28}'), ('\u{29}', '\u{29}'), ('\u{2a}', '\u{2a}'),
         ('\u{2b}', '\u{2b}'), ('\u{2c}', '\u{2c}'), ('\u{2d}', '\u{2d}'), ('\u{2e}', '\u{2f}'),
@@ -3261,22 +3252,22 @@ pub mod script {
         ('\u{1f890}', '\u{1f8ad}'), ('\u{e0001}', '\u{e0001}'), ('\u{e0020}', '\u{e007f}')
     ];
 
-    pub static Coptic_table: &'static [(char, char)] = &[
+    pub const Coptic_table: &'static [(char, char)] = &[
         ('\u{3e2}', '\u{3ef}'), ('\u{2c80}', '\u{2ce4}'), ('\u{2ce5}', '\u{2cea}'), ('\u{2ceb}',
         '\u{2cee}'), ('\u{2cef}', '\u{2cf1}'), ('\u{2cf2}', '\u{2cf3}'), ('\u{2cf9}', '\u{2cfc}'),
         ('\u{2cfd}', '\u{2cfd}'), ('\u{2cfe}', '\u{2cff}')
     ];
 
-    pub static Cuneiform_table: &'static [(char, char)] = &[
+    pub const Cuneiform_table: &'static [(char, char)] = &[
         ('\u{12000}', '\u{12398}'), ('\u{12400}', '\u{1246e}'), ('\u{12470}', '\u{12474}')
     ];
 
-    pub static Cypriot_table: &'static [(char, char)] = &[
+    pub const Cypriot_table: &'static [(char, char)] = &[
         ('\u{10800}', '\u{10805}'), ('\u{10808}', '\u{10808}'), ('\u{1080a}', '\u{10835}'),
         ('\u{10837}', '\u{10838}'), ('\u{1083c}', '\u{1083c}'), ('\u{1083f}', '\u{1083f}')
     ];
 
-    pub static Cyrillic_table: &'static [(char, char)] = &[
+    pub const Cyrillic_table: &'static [(char, char)] = &[
         ('\u{400}', '\u{481}'), ('\u{482}', '\u{482}'), ('\u{483}', '\u{484}'), ('\u{487}',
         '\u{487}'), ('\u{488}', '\u{489}'), ('\u{48a}', '\u{52f}'), ('\u{1d2b}', '\u{1d2b}'),
         ('\u{1d78}', '\u{1d78}'), ('\u{2de0}', '\u{2dff}'), ('\u{a640}', '\u{a66d}'), ('\u{a66e}',
@@ -3285,11 +3276,11 @@ pub mod script {
         '\u{a69b}'), ('\u{a69c}', '\u{a69d}'), ('\u{a69f}', '\u{a69f}')
     ];
 
-    pub static Deseret_table: &'static [(char, char)] = &[
+    pub const Deseret_table: &'static [(char, char)] = &[
         ('\u{10400}', '\u{1044f}')
     ];
 
-    pub static Devanagari_table: &'static [(char, char)] = &[
+    pub const Devanagari_table: &'static [(char, char)] = &[
         ('\u{900}', '\u{902}'), ('\u{903}', '\u{903}'), ('\u{904}', '\u{939}'), ('\u{93a}',
         '\u{93a}'), ('\u{93b}', '\u{93b}'), ('\u{93c}', '\u{93c}'), ('\u{93d}', '\u{93d}'),
         ('\u{93e}', '\u{940}'), ('\u{941}', '\u{948}'), ('\u{949}', '\u{94c}'), ('\u{94d}',
@@ -3299,21 +3290,21 @@ pub mod script {
         ('\u{a8f2}', '\u{a8f7}'), ('\u{a8f8}', '\u{a8fa}'), ('\u{a8fb}', '\u{a8fb}')
     ];
 
-    pub static Duployan_table: &'static [(char, char)] = &[
+    pub const Duployan_table: &'static [(char, char)] = &[
         ('\u{1bc00}', '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'),
         ('\u{1bc90}', '\u{1bc99}'), ('\u{1bc9c}', '\u{1bc9c}'), ('\u{1bc9d}', '\u{1bc9e}'),
         ('\u{1bc9f}', '\u{1bc9f}')
     ];
 
-    pub static Egyptian_Hieroglyphs_table: &'static [(char, char)] = &[
+    pub const Egyptian_Hieroglyphs_table: &'static [(char, char)] = &[
         ('\u{13000}', '\u{1342e}')
     ];
 
-    pub static Elbasan_table: &'static [(char, char)] = &[
+    pub const Elbasan_table: &'static [(char, char)] = &[
         ('\u{10500}', '\u{10527}')
     ];
 
-    pub static Ethiopic_table: &'static [(char, char)] = &[
+    pub const Ethiopic_table: &'static [(char, char)] = &[
         ('\u{1200}', '\u{1248}'), ('\u{124a}', '\u{124d}'), ('\u{1250}', '\u{1256}'), ('\u{1258}',
         '\u{1258}'), ('\u{125a}', '\u{125d}'), ('\u{1260}', '\u{1288}'), ('\u{128a}', '\u{128d}'),
         ('\u{1290}', '\u{12b0}'), ('\u{12b2}', '\u{12b5}'), ('\u{12b8}', '\u{12be}'), ('\u{12c0}',
@@ -3326,22 +3317,22 @@ pub mod script {
         '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', '\u{ab2e}')
     ];
 
-    pub static Georgian_table: &'static [(char, char)] = &[
+    pub const Georgian_table: &'static [(char, char)] = &[
         ('\u{10a0}', '\u{10c5}'), ('\u{10c7}', '\u{10c7}'), ('\u{10cd}', '\u{10cd}'), ('\u{10d0}',
         '\u{10fa}'), ('\u{10fc}', '\u{10fc}'), ('\u{10fd}', '\u{10ff}'), ('\u{2d00}', '\u{2d25}'),
         ('\u{2d27}', '\u{2d27}'), ('\u{2d2d}', '\u{2d2d}')
     ];
 
-    pub static Glagolitic_table: &'static [(char, char)] = &[
+    pub const Glagolitic_table: &'static [(char, char)] = &[
         ('\u{2c00}', '\u{2c2e}'), ('\u{2c30}', '\u{2c5e}')
     ];
 
-    pub static Gothic_table: &'static [(char, char)] = &[
+    pub const Gothic_table: &'static [(char, char)] = &[
         ('\u{10330}', '\u{10340}'), ('\u{10341}', '\u{10341}'), ('\u{10342}', '\u{10349}'),
         ('\u{1034a}', '\u{1034a}')
     ];
 
-    pub static Grantha_table: &'static [(char, char)] = &[
+    pub const Grantha_table: &'static [(char, char)] = &[
         ('\u{11301}', '\u{11301}'), ('\u{11302}', '\u{11303}'), ('\u{11305}', '\u{1130c}'),
         ('\u{1130f}', '\u{11310}'), ('\u{11313}', '\u{11328}'), ('\u{1132a}', '\u{11330}'),
         ('\u{11332}', '\u{11333}'), ('\u{11335}', '\u{11339}'), ('\u{1133c}', '\u{1133c}'),
@@ -3351,7 +3342,7 @@ pub mod script {
         ('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}')
     ];
 
-    pub static Greek_table: &'static [(char, char)] = &[
+    pub const Greek_table: &'static [(char, char)] = &[
         ('\u{370}', '\u{373}'), ('\u{375}', '\u{375}'), ('\u{376}', '\u{377}'), ('\u{37a}',
         '\u{37a}'), ('\u{37b}', '\u{37d}'), ('\u{37f}', '\u{37f}'), ('\u{384}', '\u{384}'),
         ('\u{386}', '\u{386}'), ('\u{388}', '\u{38a}'), ('\u{38c}', '\u{38c}'), ('\u{38e}',
@@ -3371,7 +3362,7 @@ pub mod script {
         '\u{1d245}')
     ];
 
-    pub static Gujarati_table: &'static [(char, char)] = &[
+    pub const Gujarati_table: &'static [(char, char)] = &[
         ('\u{a81}', '\u{a82}'), ('\u{a83}', '\u{a83}'), ('\u{a85}', '\u{a8d}'), ('\u{a8f}',
         '\u{a91}'), ('\u{a93}', '\u{aa8}'), ('\u{aaa}', '\u{ab0}'), ('\u{ab2}', '\u{ab3}'),
         ('\u{ab5}', '\u{ab9}'), ('\u{abc}', '\u{abc}'), ('\u{abd}', '\u{abd}'), ('\u{abe}',
@@ -3381,7 +3372,7 @@ pub mod script {
         ('\u{af1}', '\u{af1}')
     ];
 
-    pub static Gurmukhi_table: &'static [(char, char)] = &[
+    pub const Gurmukhi_table: &'static [(char, char)] = &[
         ('\u{a01}', '\u{a02}'), ('\u{a03}', '\u{a03}'), ('\u{a05}', '\u{a0a}'), ('\u{a0f}',
         '\u{a10}'), ('\u{a13}', '\u{a28}'), ('\u{a2a}', '\u{a30}'), ('\u{a32}', '\u{a33}'),
         ('\u{a35}', '\u{a36}'), ('\u{a38}', '\u{a39}'), ('\u{a3c}', '\u{a3c}'), ('\u{a3e}',
@@ -3390,7 +3381,7 @@ pub mod script {
         '\u{a6f}'), ('\u{a70}', '\u{a71}'), ('\u{a72}', '\u{a74}'), ('\u{a75}', '\u{a75}')
     ];
 
-    pub static Han_table: &'static [(char, char)] = &[
+    pub const Han_table: &'static [(char, char)] = &[
         ('\u{2e80}', '\u{2e99}'), ('\u{2e9b}', '\u{2ef3}'), ('\u{2f00}', '\u{2fd5}'), ('\u{3005}',
         '\u{3005}'), ('\u{3007}', '\u{3007}'), ('\u{3021}', '\u{3029}'), ('\u{3038}', '\u{303a}'),
         ('\u{303b}', '\u{303b}'), ('\u{3400}', '\u{4db5}'), ('\u{4e00}', '\u{9fcc}'), ('\u{f900}',
@@ -3398,18 +3389,18 @@ pub mod script {
         '\u{2b734}'), ('\u{2b740}', '\u{2b81d}'), ('\u{2f800}', '\u{2fa1d}')
     ];
 
-    pub static Hangul_table: &'static [(char, char)] = &[
+    pub const Hangul_table: &'static [(char, char)] = &[
         ('\u{1100}', '\u{11ff}'), ('\u{302e}', '\u{302f}'), ('\u{3131}', '\u{318e}'), ('\u{3200}',
         '\u{321e}'), ('\u{3260}', '\u{327e}'), ('\u{a960}', '\u{a97c}'), ('\u{ac00}', '\u{d7a3}'),
         ('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{ffa0}', '\u{ffbe}'), ('\u{ffc2}',
         '\u{ffc7}'), ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}')
     ];
 
-    pub static Hanunoo_table: &'static [(char, char)] = &[
+    pub const Hanunoo_table: &'static [(char, char)] = &[
         ('\u{1720}', '\u{1731}'), ('\u{1732}', '\u{1734}')
     ];
 
-    pub static Hebrew_table: &'static [(char, char)] = &[
+    pub const Hebrew_table: &'static [(char, char)] = &[
         ('\u{591}', '\u{5bd}'), ('\u{5be}', '\u{5be}'), ('\u{5bf}', '\u{5bf}'), ('\u{5c0}',
         '\u{5c0}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c3}', '\u{5c3}'), ('\u{5c4}', '\u{5c5}'),
         ('\u{5c6}', '\u{5c6}'), ('\u{5c7}', '\u{5c7}'), ('\u{5d0}', '\u{5ea}'), ('\u{5f0}',
@@ -3419,16 +3410,16 @@ pub mod script {
         ('\u{fb46}', '\u{fb4f}')
     ];
 
-    pub static Hiragana_table: &'static [(char, char)] = &[
+    pub const Hiragana_table: &'static [(char, char)] = &[
         ('\u{3041}', '\u{3096}'), ('\u{309d}', '\u{309e}'), ('\u{309f}', '\u{309f}'), ('\u{1b001}',
         '\u{1b001}'), ('\u{1f200}', '\u{1f200}')
     ];
 
-    pub static Imperial_Aramaic_table: &'static [(char, char)] = &[
+    pub const Imperial_Aramaic_table: &'static [(char, char)] = &[
         ('\u{10840}', '\u{10855}'), ('\u{10857}', '\u{10857}'), ('\u{10858}', '\u{1085f}')
     ];
 
-    pub static Inherited_table: &'static [(char, char)] = &[
+    pub const Inherited_table: &'static [(char, char)] = &[
         ('\u{300}', '\u{36f}'), ('\u{485}', '\u{486}'), ('\u{64b}', '\u{655}'), ('\u{670}',
         '\u{670}'), ('\u{951}', '\u{952}'), ('\u{1ab0}', '\u{1abd}'), ('\u{1abe}', '\u{1abe}'),
         ('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1ce0}'), ('\u{1ce2}', '\u{1ce8}'), ('\u{1ced}',
@@ -3441,29 +3432,29 @@ pub mod script {
         '\u{1d1ad}'), ('\u{e0100}', '\u{e01ef}')
     ];
 
-    pub static Inscriptional_Pahlavi_table: &'static [(char, char)] = &[
+    pub const Inscriptional_Pahlavi_table: &'static [(char, char)] = &[
         ('\u{10b60}', '\u{10b72}'), ('\u{10b78}', '\u{10b7f}')
     ];
 
-    pub static Inscriptional_Parthian_table: &'static [(char, char)] = &[
+    pub const Inscriptional_Parthian_table: &'static [(char, char)] = &[
         ('\u{10b40}', '\u{10b55}'), ('\u{10b58}', '\u{10b5f}')
     ];
 
-    pub static Javanese_table: &'static [(char, char)] = &[
+    pub const Javanese_table: &'static [(char, char)] = &[
         ('\u{a980}', '\u{a982}'), ('\u{a983}', '\u{a983}'), ('\u{a984}', '\u{a9b2}'), ('\u{a9b3}',
         '\u{a9b3}'), ('\u{a9b4}', '\u{a9b5}'), ('\u{a9b6}', '\u{a9b9}'), ('\u{a9ba}', '\u{a9bb}'),
         ('\u{a9bc}', '\u{a9bc}'), ('\u{a9bd}', '\u{a9c0}'), ('\u{a9c1}', '\u{a9cd}'), ('\u{a9d0}',
         '\u{a9d9}'), ('\u{a9de}', '\u{a9df}')
     ];
 
-    pub static Kaithi_table: &'static [(char, char)] = &[
+    pub const Kaithi_table: &'static [(char, char)] = &[
         ('\u{11080}', '\u{11081}'), ('\u{11082}', '\u{11082}'), ('\u{11083}', '\u{110af}'),
         ('\u{110b0}', '\u{110b2}'), ('\u{110b3}', '\u{110b6}'), ('\u{110b7}', '\u{110b8}'),
         ('\u{110b9}', '\u{110ba}'), ('\u{110bb}', '\u{110bc}'), ('\u{110bd}', '\u{110bd}'),
         ('\u{110be}', '\u{110c1}')
     ];
 
-    pub static Kannada_table: &'static [(char, char)] = &[
+    pub const Kannada_table: &'static [(char, char)] = &[
         ('\u{c81}', '\u{c81}'), ('\u{c82}', '\u{c83}'), ('\u{c85}', '\u{c8c}'), ('\u{c8e}',
         '\u{c90}'), ('\u{c92}', '\u{ca8}'), ('\u{caa}', '\u{cb3}'), ('\u{cb5}', '\u{cb9}'),
         ('\u{cbc}', '\u{cbc}'), ('\u{cbd}', '\u{cbd}'), ('\u{cbe}', '\u{cbe}'), ('\u{cbf}',
@@ -3473,25 +3464,25 @@ pub mod script {
         ('\u{cf1}', '\u{cf2}')
     ];
 
-    pub static Katakana_table: &'static [(char, char)] = &[
+    pub const Katakana_table: &'static [(char, char)] = &[
         ('\u{30a1}', '\u{30fa}'), ('\u{30fd}', '\u{30fe}'), ('\u{30ff}', '\u{30ff}'), ('\u{31f0}',
         '\u{31ff}'), ('\u{32d0}', '\u{32fe}'), ('\u{3300}', '\u{3357}'), ('\u{ff66}', '\u{ff6f}'),
         ('\u{ff71}', '\u{ff9d}'), ('\u{1b000}', '\u{1b000}')
     ];
 
-    pub static Kayah_Li_table: &'static [(char, char)] = &[
+    pub const Kayah_Li_table: &'static [(char, char)] = &[
         ('\u{a900}', '\u{a909}'), ('\u{a90a}', '\u{a925}'), ('\u{a926}', '\u{a92d}'), ('\u{a92f}',
         '\u{a92f}')
     ];
 
-    pub static Kharoshthi_table: &'static [(char, char)] = &[
+    pub const Kharoshthi_table: &'static [(char, char)] = &[
         ('\u{10a00}', '\u{10a00}'), ('\u{10a01}', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'),
         ('\u{10a0c}', '\u{10a0f}'), ('\u{10a10}', '\u{10a13}'), ('\u{10a15}', '\u{10a17}'),
         ('\u{10a19}', '\u{10a33}'), ('\u{10a38}', '\u{10a3a}'), ('\u{10a3f}', '\u{10a3f}'),
         ('\u{10a40}', '\u{10a47}'), ('\u{10a50}', '\u{10a58}')
     ];
 
-    pub static Khmer_table: &'static [(char, char)] = &[
+    pub const Khmer_table: &'static [(char, char)] = &[
         ('\u{1780}', '\u{17b3}'), ('\u{17b4}', '\u{17b5}'), ('\u{17b6}', '\u{17b6}'), ('\u{17b7}',
         '\u{17bd}'), ('\u{17be}', '\u{17c5}'), ('\u{17c6}', '\u{17c6}'), ('\u{17c7}', '\u{17c8}'),
         ('\u{17c9}', '\u{17d3}'), ('\u{17d4}', '\u{17d6}'), ('\u{17d7}', '\u{17d7}'), ('\u{17d8}',
@@ -3499,18 +3490,18 @@ pub mod script {
         ('\u{17e0}', '\u{17e9}'), ('\u{17f0}', '\u{17f9}'), ('\u{19e0}', '\u{19ff}')
     ];
 
-    pub static Khojki_table: &'static [(char, char)] = &[
+    pub const Khojki_table: &'static [(char, char)] = &[
         ('\u{11200}', '\u{11211}'), ('\u{11213}', '\u{1122b}'), ('\u{1122c}', '\u{1122e}'),
         ('\u{1122f}', '\u{11231}'), ('\u{11232}', '\u{11233}'), ('\u{11234}', '\u{11234}'),
         ('\u{11235}', '\u{11235}'), ('\u{11236}', '\u{11237}'), ('\u{11238}', '\u{1123d}')
     ];
 
-    pub static Khudawadi_table: &'static [(char, char)] = &[
+    pub const Khudawadi_table: &'static [(char, char)] = &[
         ('\u{112b0}', '\u{112de}'), ('\u{112df}', '\u{112df}'), ('\u{112e0}', '\u{112e2}'),
         ('\u{112e3}', '\u{112ea}'), ('\u{112f0}', '\u{112f9}')
     ];
 
-    pub static Lao_table: &'static [(char, char)] = &[
+    pub const Lao_table: &'static [(char, char)] = &[
         ('\u{e81}', '\u{e82}'), ('\u{e84}', '\u{e84}'), ('\u{e87}', '\u{e88}'), ('\u{e8a}',
         '\u{e8a}'), ('\u{e8d}', '\u{e8d}'), ('\u{e94}', '\u{e97}'), ('\u{e99}', '\u{e9f}'),
         ('\u{ea1}', '\u{ea3}'), ('\u{ea5}', '\u{ea5}'), ('\u{ea7}', '\u{ea7}'), ('\u{eaa}',
@@ -3520,7 +3511,7 @@ pub mod script {
         ('\u{edc}', '\u{edf}')
     ];
 
-    pub static Latin_table: &'static [(char, char)] = &[
+    pub const Latin_table: &'static [(char, char)] = &[
         ('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{ba}', '\u{ba}'),
         ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'), ('\u{1bb}', '\u{1bb}'),
         ('\u{1bc}', '\u{1bf}'), ('\u{1c0}', '\u{1c3}'), ('\u{1c4}', '\u{293}'), ('\u{294}',
@@ -3537,47 +3528,47 @@ pub mod script {
         '\u{ab64}'), ('\u{fb00}', '\u{fb06}'), ('\u{ff21}', '\u{ff3a}'), ('\u{ff41}', '\u{ff5a}')
     ];
 
-    pub static Lepcha_table: &'static [(char, char)] = &[
+    pub const Lepcha_table: &'static [(char, char)] = &[
         ('\u{1c00}', '\u{1c23}'), ('\u{1c24}', '\u{1c2b}'), ('\u{1c2c}', '\u{1c33}'), ('\u{1c34}',
         '\u{1c35}'), ('\u{1c36}', '\u{1c37}'), ('\u{1c3b}', '\u{1c3f}'), ('\u{1c40}', '\u{1c49}'),
         ('\u{1c4d}', '\u{1c4f}')
     ];
 
-    pub static Limbu_table: &'static [(char, char)] = &[
+    pub const Limbu_table: &'static [(char, char)] = &[
         ('\u{1900}', '\u{191e}'), ('\u{1920}', '\u{1922}'), ('\u{1923}', '\u{1926}'), ('\u{1927}',
         '\u{1928}'), ('\u{1929}', '\u{192b}'), ('\u{1930}', '\u{1931}'), ('\u{1932}', '\u{1932}'),
         ('\u{1933}', '\u{1938}'), ('\u{1939}', '\u{193b}'), ('\u{1940}', '\u{1940}'), ('\u{1944}',
         '\u{1945}'), ('\u{1946}', '\u{194f}')
     ];
 
-    pub static Linear_A_table: &'static [(char, char)] = &[
+    pub const Linear_A_table: &'static [(char, char)] = &[
         ('\u{10600}', '\u{10736}'), ('\u{10740}', '\u{10755}'), ('\u{10760}', '\u{10767}')
     ];
 
-    pub static Linear_B_table: &'static [(char, char)] = &[
+    pub const Linear_B_table: &'static [(char, char)] = &[
         ('\u{10000}', '\u{1000b}'), ('\u{1000d}', '\u{10026}'), ('\u{10028}', '\u{1003a}'),
         ('\u{1003c}', '\u{1003d}'), ('\u{1003f}', '\u{1004d}'), ('\u{10050}', '\u{1005d}'),
         ('\u{10080}', '\u{100fa}')
     ];
 
-    pub static Lisu_table: &'static [(char, char)] = &[
+    pub const Lisu_table: &'static [(char, char)] = &[
         ('\u{a4d0}', '\u{a4f7}'), ('\u{a4f8}', '\u{a4fd}'), ('\u{a4fe}', '\u{a4ff}')
     ];
 
-    pub static Lycian_table: &'static [(char, char)] = &[
+    pub const Lycian_table: &'static [(char, char)] = &[
         ('\u{10280}', '\u{1029c}')
     ];
 
-    pub static Lydian_table: &'static [(char, char)] = &[
+    pub const Lydian_table: &'static [(char, char)] = &[
         ('\u{10920}', '\u{10939}'), ('\u{1093f}', '\u{1093f}')
     ];
 
-    pub static Mahajani_table: &'static [(char, char)] = &[
+    pub const Mahajani_table: &'static [(char, char)] = &[
         ('\u{11150}', '\u{11172}'), ('\u{11173}', '\u{11173}'), ('\u{11174}', '\u{11175}'),
         ('\u{11176}', '\u{11176}')
     ];
 
-    pub static Malayalam_table: &'static [(char, char)] = &[
+    pub const Malayalam_table: &'static [(char, char)] = &[
         ('\u{d01}', '\u{d01}'), ('\u{d02}', '\u{d03}'), ('\u{d05}', '\u{d0c}'), ('\u{d0e}',
         '\u{d10}'), ('\u{d12}', '\u{d3a}'), ('\u{d3d}', '\u{d3d}'), ('\u{d3e}', '\u{d40}'),
         ('\u{d41}', '\u{d44}'), ('\u{d46}', '\u{d48}'), ('\u{d4a}', '\u{d4c}'), ('\u{d4d}',
@@ -3586,16 +3577,16 @@ pub mod script {
         '\u{d79}'), ('\u{d7a}', '\u{d7f}')
     ];
 
-    pub static Mandaic_table: &'static [(char, char)] = &[
+    pub const Mandaic_table: &'static [(char, char)] = &[
         ('\u{840}', '\u{858}'), ('\u{859}', '\u{85b}'), ('\u{85e}', '\u{85e}')
     ];
 
-    pub static Manichaean_table: &'static [(char, char)] = &[
+    pub const Manichaean_table: &'static [(char, char)] = &[
         ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac8}', '\u{10ac8}'), ('\u{10ac9}', '\u{10ae4}'),
         ('\u{10ae5}', '\u{10ae6}'), ('\u{10aeb}', '\u{10aef}'), ('\u{10af0}', '\u{10af6}')
     ];
 
-    pub static Meetei_Mayek_table: &'static [(char, char)] = &[
+    pub const Meetei_Mayek_table: &'static [(char, char)] = &[
         ('\u{aae0}', '\u{aaea}'), ('\u{aaeb}', '\u{aaeb}'), ('\u{aaec}', '\u{aaed}'), ('\u{aaee}',
         '\u{aaef}'), ('\u{aaf0}', '\u{aaf1}'), ('\u{aaf2}', '\u{aaf2}'), ('\u{aaf3}', '\u{aaf4}'),
         ('\u{aaf5}', '\u{aaf5}'), ('\u{aaf6}', '\u{aaf6}'), ('\u{abc0}', '\u{abe2}'), ('\u{abe3}',
@@ -3604,42 +3595,42 @@ pub mod script {
         '\u{abed}'), ('\u{abf0}', '\u{abf9}')
     ];
 
-    pub static Mende_Kikakui_table: &'static [(char, char)] = &[
+    pub const Mende_Kikakui_table: &'static [(char, char)] = &[
         ('\u{1e800}', '\u{1e8c4}'), ('\u{1e8c7}', '\u{1e8cf}'), ('\u{1e8d0}', '\u{1e8d6}')
     ];
 
-    pub static Meroitic_Cursive_table: &'static [(char, char)] = &[
+    pub const Meroitic_Cursive_table: &'static [(char, char)] = &[
         ('\u{109a0}', '\u{109b7}'), ('\u{109be}', '\u{109bf}')
     ];
 
-    pub static Meroitic_Hieroglyphs_table: &'static [(char, char)] = &[
+    pub const Meroitic_Hieroglyphs_table: &'static [(char, char)] = &[
         ('\u{10980}', '\u{1099f}')
     ];
 
-    pub static Miao_table: &'static [(char, char)] = &[
+    pub const Miao_table: &'static [(char, char)] = &[
         ('\u{16f00}', '\u{16f44}'), ('\u{16f50}', '\u{16f50}'), ('\u{16f51}', '\u{16f7e}'),
         ('\u{16f8f}', '\u{16f92}'), ('\u{16f93}', '\u{16f9f}')
     ];
 
-    pub static Modi_table: &'static [(char, char)] = &[
+    pub const Modi_table: &'static [(char, char)] = &[
         ('\u{11600}', '\u{1162f}'), ('\u{11630}', '\u{11632}'), ('\u{11633}', '\u{1163a}'),
         ('\u{1163b}', '\u{1163c}'), ('\u{1163d}', '\u{1163d}'), ('\u{1163e}', '\u{1163e}'),
         ('\u{1163f}', '\u{11640}'), ('\u{11641}', '\u{11643}'), ('\u{11644}', '\u{11644}'),
         ('\u{11650}', '\u{11659}')
     ];
 
-    pub static Mongolian_table: &'static [(char, char)] = &[
+    pub const Mongolian_table: &'static [(char, char)] = &[
         ('\u{1800}', '\u{1801}'), ('\u{1804}', '\u{1804}'), ('\u{1806}', '\u{1806}'), ('\u{1807}',
         '\u{180a}'), ('\u{180b}', '\u{180d}'), ('\u{180e}', '\u{180e}'), ('\u{1810}', '\u{1819}'),
         ('\u{1820}', '\u{1842}'), ('\u{1843}', '\u{1843}'), ('\u{1844}', '\u{1877}'), ('\u{1880}',
         '\u{18a8}'), ('\u{18a9}', '\u{18a9}'), ('\u{18aa}', '\u{18aa}')
     ];
 
-    pub static Mro_table: &'static [(char, char)] = &[
+    pub const Mro_table: &'static [(char, char)] = &[
         ('\u{16a40}', '\u{16a5e}'), ('\u{16a60}', '\u{16a69}'), ('\u{16a6e}', '\u{16a6f}')
     ];
 
-    pub static Myanmar_table: &'static [(char, char)] = &[
+    pub const Myanmar_table: &'static [(char, char)] = &[
         ('\u{1000}', '\u{102a}'), ('\u{102b}', '\u{102c}'), ('\u{102d}', '\u{1030}'), ('\u{1031}',
         '\u{1031}'), ('\u{1032}', '\u{1037}'), ('\u{1038}', '\u{1038}'), ('\u{1039}', '\u{103a}'),
         ('\u{103b}', '\u{103c}'), ('\u{103d}', '\u{103e}'), ('\u{103f}', '\u{103f}'), ('\u{1040}',
@@ -3657,56 +3648,56 @@ pub mod script {
         ('\u{aa7e}', '\u{aa7f}')
     ];
 
-    pub static Nabataean_table: &'static [(char, char)] = &[
+    pub const Nabataean_table: &'static [(char, char)] = &[
         ('\u{10880}', '\u{1089e}'), ('\u{108a7}', '\u{108af}')
     ];
 
-    pub static New_Tai_Lue_table: &'static [(char, char)] = &[
+    pub const New_Tai_Lue_table: &'static [(char, char)] = &[
         ('\u{1980}', '\u{19ab}'), ('\u{19b0}', '\u{19c0}'), ('\u{19c1}', '\u{19c7}'), ('\u{19c8}',
         '\u{19c9}'), ('\u{19d0}', '\u{19d9}'), ('\u{19da}', '\u{19da}'), ('\u{19de}', '\u{19df}')
     ];
 
-    pub static Nko_table: &'static [(char, char)] = &[
+    pub const Nko_table: &'static [(char, char)] = &[
         ('\u{7c0}', '\u{7c9}'), ('\u{7ca}', '\u{7ea}'), ('\u{7eb}', '\u{7f3}'), ('\u{7f4}',
         '\u{7f5}'), ('\u{7f6}', '\u{7f6}'), ('\u{7f7}', '\u{7f9}'), ('\u{7fa}', '\u{7fa}')
     ];
 
-    pub static Ogham_table: &'static [(char, char)] = &[
+    pub const Ogham_table: &'static [(char, char)] = &[
         ('\u{1680}', '\u{1680}'), ('\u{1681}', '\u{169a}'), ('\u{169b}', '\u{169b}'), ('\u{169c}',
         '\u{169c}')
     ];
 
-    pub static Ol_Chiki_table: &'static [(char, char)] = &[
+    pub const Ol_Chiki_table: &'static [(char, char)] = &[
         ('\u{1c50}', '\u{1c59}'), ('\u{1c5a}', '\u{1c77}'), ('\u{1c78}', '\u{1c7d}'), ('\u{1c7e}',
         '\u{1c7f}')
     ];
 
-    pub static Old_Italic_table: &'static [(char, char)] = &[
+    pub const Old_Italic_table: &'static [(char, char)] = &[
         ('\u{10300}', '\u{1031f}'), ('\u{10320}', '\u{10323}')
     ];
 
-    pub static Old_North_Arabian_table: &'static [(char, char)] = &[
+    pub const Old_North_Arabian_table: &'static [(char, char)] = &[
         ('\u{10a80}', '\u{10a9c}'), ('\u{10a9d}', '\u{10a9f}')
     ];
 
-    pub static Old_Permic_table: &'static [(char, char)] = &[
+    pub const Old_Permic_table: &'static [(char, char)] = &[
         ('\u{10350}', '\u{10375}'), ('\u{10376}', '\u{1037a}')
     ];
 
-    pub static Old_Persian_table: &'static [(char, char)] = &[
+    pub const Old_Persian_table: &'static [(char, char)] = &[
         ('\u{103a0}', '\u{103c3}'), ('\u{103c8}', '\u{103cf}'), ('\u{103d0}', '\u{103d0}'),
         ('\u{103d1}', '\u{103d5}')
     ];
 
-    pub static Old_South_Arabian_table: &'static [(char, char)] = &[
+    pub const Old_South_Arabian_table: &'static [(char, char)] = &[
         ('\u{10a60}', '\u{10a7c}'), ('\u{10a7d}', '\u{10a7e}'), ('\u{10a7f}', '\u{10a7f}')
     ];
 
-    pub static Old_Turkic_table: &'static [(char, char)] = &[
+    pub const Old_Turkic_table: &'static [(char, char)] = &[
         ('\u{10c00}', '\u{10c48}')
     ];
 
-    pub static Oriya_table: &'static [(char, char)] = &[
+    pub const Oriya_table: &'static [(char, char)] = &[
         ('\u{b01}', '\u{b01}'), ('\u{b02}', '\u{b03}'), ('\u{b05}', '\u{b0c}'), ('\u{b0f}',
         '\u{b10}'), ('\u{b13}', '\u{b28}'), ('\u{b2a}', '\u{b30}'), ('\u{b32}', '\u{b33}'),
         ('\u{b35}', '\u{b39}'), ('\u{b3c}', '\u{b3c}'), ('\u{b3d}', '\u{b3d}'), ('\u{b3e}',
@@ -3717,75 +3708,75 @@ pub mod script {
         '\u{b71}'), ('\u{b72}', '\u{b77}')
     ];
 
-    pub static Osmanya_table: &'static [(char, char)] = &[
+    pub const Osmanya_table: &'static [(char, char)] = &[
         ('\u{10480}', '\u{1049d}'), ('\u{104a0}', '\u{104a9}')
     ];
 
-    pub static Pahawh_Hmong_table: &'static [(char, char)] = &[
+    pub const Pahawh_Hmong_table: &'static [(char, char)] = &[
         ('\u{16b00}', '\u{16b2f}'), ('\u{16b30}', '\u{16b36}'), ('\u{16b37}', '\u{16b3b}'),
         ('\u{16b3c}', '\u{16b3f}'), ('\u{16b40}', '\u{16b43}'), ('\u{16b44}', '\u{16b44}'),
         ('\u{16b45}', '\u{16b45}'), ('\u{16b50}', '\u{16b59}'), ('\u{16b5b}', '\u{16b61}'),
         ('\u{16b63}', '\u{16b77}'), ('\u{16b7d}', '\u{16b8f}')
     ];
 
-    pub static Palmyrene_table: &'static [(char, char)] = &[
+    pub const Palmyrene_table: &'static [(char, char)] = &[
         ('\u{10860}', '\u{10876}'), ('\u{10877}', '\u{10878}'), ('\u{10879}', '\u{1087f}')
     ];
 
-    pub static Pau_Cin_Hau_table: &'static [(char, char)] = &[
+    pub const Pau_Cin_Hau_table: &'static [(char, char)] = &[
         ('\u{11ac0}', '\u{11af8}')
     ];
 
-    pub static Phags_Pa_table: &'static [(char, char)] = &[
+    pub const Phags_Pa_table: &'static [(char, char)] = &[
         ('\u{a840}', '\u{a873}'), ('\u{a874}', '\u{a877}')
     ];
 
-    pub static Phoenician_table: &'static [(char, char)] = &[
+    pub const Phoenician_table: &'static [(char, char)] = &[
         ('\u{10900}', '\u{10915}'), ('\u{10916}', '\u{1091b}'), ('\u{1091f}', '\u{1091f}')
     ];
 
-    pub static Psalter_Pahlavi_table: &'static [(char, char)] = &[
+    pub const Psalter_Pahlavi_table: &'static [(char, char)] = &[
         ('\u{10b80}', '\u{10b91}'), ('\u{10b99}', '\u{10b9c}'), ('\u{10ba9}', '\u{10baf}')
     ];
 
-    pub static Rejang_table: &'static [(char, char)] = &[
+    pub const Rejang_table: &'static [(char, char)] = &[
         ('\u{a930}', '\u{a946}'), ('\u{a947}', '\u{a951}'), ('\u{a952}', '\u{a953}'), ('\u{a95f}',
         '\u{a95f}')
     ];
 
-    pub static Runic_table: &'static [(char, char)] = &[
+    pub const Runic_table: &'static [(char, char)] = &[
         ('\u{16a0}', '\u{16ea}'), ('\u{16ee}', '\u{16f0}'), ('\u{16f1}', '\u{16f8}')
     ];
 
-    pub static Samaritan_table: &'static [(char, char)] = &[
+    pub const Samaritan_table: &'static [(char, char)] = &[
         ('\u{800}', '\u{815}'), ('\u{816}', '\u{819}'), ('\u{81a}', '\u{81a}'), ('\u{81b}',
         '\u{823}'), ('\u{824}', '\u{824}'), ('\u{825}', '\u{827}'), ('\u{828}', '\u{828}'),
         ('\u{829}', '\u{82d}'), ('\u{830}', '\u{83e}')
     ];
 
-    pub static Saurashtra_table: &'static [(char, char)] = &[
+    pub const Saurashtra_table: &'static [(char, char)] = &[
         ('\u{a880}', '\u{a881}'), ('\u{a882}', '\u{a8b3}'), ('\u{a8b4}', '\u{a8c3}'), ('\u{a8c4}',
         '\u{a8c4}'), ('\u{a8ce}', '\u{a8cf}'), ('\u{a8d0}', '\u{a8d9}')
     ];
 
-    pub static Sharada_table: &'static [(char, char)] = &[
+    pub const Sharada_table: &'static [(char, char)] = &[
         ('\u{11180}', '\u{11181}'), ('\u{11182}', '\u{11182}'), ('\u{11183}', '\u{111b2}'),
         ('\u{111b3}', '\u{111b5}'), ('\u{111b6}', '\u{111be}'), ('\u{111bf}', '\u{111c0}'),
         ('\u{111c1}', '\u{111c4}'), ('\u{111c5}', '\u{111c8}'), ('\u{111cd}', '\u{111cd}'),
         ('\u{111d0}', '\u{111d9}'), ('\u{111da}', '\u{111da}')
     ];
 
-    pub static Shavian_table: &'static [(char, char)] = &[
+    pub const Shavian_table: &'static [(char, char)] = &[
         ('\u{10450}', '\u{1047f}')
     ];
 
-    pub static Siddham_table: &'static [(char, char)] = &[
+    pub const Siddham_table: &'static [(char, char)] = &[
         ('\u{11580}', '\u{115ae}'), ('\u{115af}', '\u{115b1}'), ('\u{115b2}', '\u{115b5}'),
         ('\u{115b8}', '\u{115bb}'), ('\u{115bc}', '\u{115bd}'), ('\u{115be}', '\u{115be}'),
         ('\u{115bf}', '\u{115c0}'), ('\u{115c1}', '\u{115c9}')
     ];
 
-    pub static Sinhala_table: &'static [(char, char)] = &[
+    pub const Sinhala_table: &'static [(char, char)] = &[
         ('\u{d82}', '\u{d83}'), ('\u{d85}', '\u{d96}'), ('\u{d9a}', '\u{db1}'), ('\u{db3}',
         '\u{dbb}'), ('\u{dbd}', '\u{dbd}'), ('\u{dc0}', '\u{dc6}'), ('\u{dca}', '\u{dca}'),
         ('\u{dcf}', '\u{dd1}'), ('\u{dd2}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), ('\u{dd8}',
@@ -3793,42 +3784,42 @@ pub mod script {
         ('\u{111e1}', '\u{111f4}')
     ];
 
-    pub static Sora_Sompeng_table: &'static [(char, char)] = &[
+    pub const Sora_Sompeng_table: &'static [(char, char)] = &[
         ('\u{110d0}', '\u{110e8}'), ('\u{110f0}', '\u{110f9}')
     ];
 
-    pub static Sundanese_table: &'static [(char, char)] = &[
+    pub const Sundanese_table: &'static [(char, char)] = &[
         ('\u{1b80}', '\u{1b81}'), ('\u{1b82}', '\u{1b82}'), ('\u{1b83}', '\u{1ba0}'), ('\u{1ba1}',
         '\u{1ba1}'), ('\u{1ba2}', '\u{1ba5}'), ('\u{1ba6}', '\u{1ba7}'), ('\u{1ba8}', '\u{1ba9}'),
         ('\u{1baa}', '\u{1baa}'), ('\u{1bab}', '\u{1bad}'), ('\u{1bae}', '\u{1baf}'), ('\u{1bb0}',
         '\u{1bb9}'), ('\u{1bba}', '\u{1bbf}'), ('\u{1cc0}', '\u{1cc7}')
     ];
 
-    pub static Syloti_Nagri_table: &'static [(char, char)] = &[
+    pub const Syloti_Nagri_table: &'static [(char, char)] = &[
         ('\u{a800}', '\u{a801}'), ('\u{a802}', '\u{a802}'), ('\u{a803}', '\u{a805}'), ('\u{a806}',
         '\u{a806}'), ('\u{a807}', '\u{a80a}'), ('\u{a80b}', '\u{a80b}'), ('\u{a80c}', '\u{a822}'),
         ('\u{a823}', '\u{a824}'), ('\u{a825}', '\u{a826}'), ('\u{a827}', '\u{a827}'), ('\u{a828}',
         '\u{a82b}')
     ];
 
-    pub static Syriac_table: &'static [(char, char)] = &[
+    pub const Syriac_table: &'static [(char, char)] = &[
         ('\u{700}', '\u{70d}'), ('\u{70f}', '\u{70f}'), ('\u{710}', '\u{710}'), ('\u{711}',
         '\u{711}'), ('\u{712}', '\u{72f}'), ('\u{730}', '\u{74a}'), ('\u{74d}', '\u{74f}')
     ];
 
-    pub static Tagalog_table: &'static [(char, char)] = &[
+    pub const Tagalog_table: &'static [(char, char)] = &[
         ('\u{1700}', '\u{170c}'), ('\u{170e}', '\u{1711}'), ('\u{1712}', '\u{1714}')
     ];
 
-    pub static Tagbanwa_table: &'static [(char, char)] = &[
+    pub const Tagbanwa_table: &'static [(char, char)] = &[
         ('\u{1760}', '\u{176c}'), ('\u{176e}', '\u{1770}'), ('\u{1772}', '\u{1773}')
     ];
 
-    pub static Tai_Le_table: &'static [(char, char)] = &[
+    pub const Tai_Le_table: &'static [(char, char)] = &[
         ('\u{1950}', '\u{196d}'), ('\u{1970}', '\u{1974}')
     ];
 
-    pub static Tai_Tham_table: &'static [(char, char)] = &[
+    pub const Tai_Tham_table: &'static [(char, char)] = &[
         ('\u{1a20}', '\u{1a54}'), ('\u{1a55}', '\u{1a55}'), ('\u{1a56}', '\u{1a56}'), ('\u{1a57}',
         '\u{1a57}'), ('\u{1a58}', '\u{1a5e}'), ('\u{1a60}', '\u{1a60}'), ('\u{1a61}', '\u{1a61}'),
         ('\u{1a62}', '\u{1a62}'), ('\u{1a63}', '\u{1a64}'), ('\u{1a65}', '\u{1a6c}'), ('\u{1a6d}',
@@ -3837,20 +3828,20 @@ pub mod script {
         '\u{1aad}')
     ];
 
-    pub static Tai_Viet_table: &'static [(char, char)] = &[
+    pub const Tai_Viet_table: &'static [(char, char)] = &[
         ('\u{aa80}', '\u{aaaf}'), ('\u{aab0}', '\u{aab0}'), ('\u{aab1}', '\u{aab1}'), ('\u{aab2}',
         '\u{aab4}'), ('\u{aab5}', '\u{aab6}'), ('\u{aab7}', '\u{aab8}'), ('\u{aab9}', '\u{aabd}'),
         ('\u{aabe}', '\u{aabf}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac1}', '\u{aac1}'), ('\u{aac2}',
         '\u{aac2}'), ('\u{aadb}', '\u{aadc}'), ('\u{aadd}', '\u{aadd}'), ('\u{aade}', '\u{aadf}')
     ];
 
-    pub static Takri_table: &'static [(char, char)] = &[
+    pub const Takri_table: &'static [(char, char)] = &[
         ('\u{11680}', '\u{116aa}'), ('\u{116ab}', '\u{116ab}'), ('\u{116ac}', '\u{116ac}'),
         ('\u{116ad}', '\u{116ad}'), ('\u{116ae}', '\u{116af}'), ('\u{116b0}', '\u{116b5}'),
         ('\u{116b6}', '\u{116b6}'), ('\u{116b7}', '\u{116b7}'), ('\u{116c0}', '\u{116c9}')
     ];
 
-    pub static Tamil_table: &'static [(char, char)] = &[
+    pub const Tamil_table: &'static [(char, char)] = &[
         ('\u{b82}', '\u{b82}'), ('\u{b83}', '\u{b83}'), ('\u{b85}', '\u{b8a}'), ('\u{b8e}',
         '\u{b90}'), ('\u{b92}', '\u{b95}'), ('\u{b99}', '\u{b9a}'), ('\u{b9c}', '\u{b9c}'),
         ('\u{b9e}', '\u{b9f}'), ('\u{ba3}', '\u{ba4}'), ('\u{ba8}', '\u{baa}'), ('\u{bae}',
@@ -3860,7 +3851,7 @@ pub mod script {
         ('\u{bf3}', '\u{bf8}'), ('\u{bf9}', '\u{bf9}'), ('\u{bfa}', '\u{bfa}')
     ];
 
-    pub static Telugu_table: &'static [(char, char)] = &[
+    pub const Telugu_table: &'static [(char, char)] = &[
         ('\u{c00}', '\u{c00}'), ('\u{c01}', '\u{c03}'), ('\u{c05}', '\u{c0c}'), ('\u{c0e}',
         '\u{c10}'), ('\u{c12}', '\u{c28}'), ('\u{c2a}', '\u{c39}'), ('\u{c3d}', '\u{c3d}'),
         ('\u{c3e}', '\u{c40}'), ('\u{c41}', '\u{c44}'), ('\u{c46}', '\u{c48}'), ('\u{c4a}',
@@ -3869,17 +3860,17 @@ pub mod script {
         '\u{c7f}')
     ];
 
-    pub static Thaana_table: &'static [(char, char)] = &[
+    pub const Thaana_table: &'static [(char, char)] = &[
         ('\u{780}', '\u{7a5}'), ('\u{7a6}', '\u{7b0}'), ('\u{7b1}', '\u{7b1}')
     ];
 
-    pub static Thai_table: &'static [(char, char)] = &[
+    pub const Thai_table: &'static [(char, char)] = &[
         ('\u{e01}', '\u{e30}'), ('\u{e31}', '\u{e31}'), ('\u{e32}', '\u{e33}'), ('\u{e34}',
         '\u{e3a}'), ('\u{e40}', '\u{e45}'), ('\u{e46}', '\u{e46}'), ('\u{e47}', '\u{e4e}'),
         ('\u{e4f}', '\u{e4f}'), ('\u{e50}', '\u{e59}'), ('\u{e5a}', '\u{e5b}')
     ];
 
-    pub static Tibetan_table: &'static [(char, char)] = &[
+    pub const Tibetan_table: &'static [(char, char)] = &[
         ('\u{f00}', '\u{f00}'), ('\u{f01}', '\u{f03}'), ('\u{f04}', '\u{f12}'), ('\u{f13}',
         '\u{f13}'), ('\u{f14}', '\u{f14}'), ('\u{f15}', '\u{f17}'), ('\u{f18}', '\u{f19}'),
         ('\u{f1a}', '\u{f1f}'), ('\u{f20}', '\u{f29}'), ('\u{f2a}', '\u{f33}'), ('\u{f34}',
@@ -3893,12 +3884,12 @@ pub mod script {
         ('\u{fd0}', '\u{fd4}'), ('\u{fd9}', '\u{fda}')
     ];
 
-    pub static Tifinagh_table: &'static [(char, char)] = &[
+    pub const Tifinagh_table: &'static [(char, char)] = &[
         ('\u{2d30}', '\u{2d67}'), ('\u{2d6f}', '\u{2d6f}'), ('\u{2d70}', '\u{2d70}'), ('\u{2d7f}',
         '\u{2d7f}')
     ];
 
-    pub static Tirhuta_table: &'static [(char, char)] = &[
+    pub const Tirhuta_table: &'static [(char, char)] = &[
         ('\u{11480}', '\u{114af}'), ('\u{114b0}', '\u{114b2}'), ('\u{114b3}', '\u{114b8}'),
         ('\u{114b9}', '\u{114b9}'), ('\u{114ba}', '\u{114ba}'), ('\u{114bb}', '\u{114be}'),
         ('\u{114bf}', '\u{114c0}'), ('\u{114c1}', '\u{114c1}'), ('\u{114c2}', '\u{114c3}'),
@@ -3906,21 +3897,21 @@ pub mod script {
         ('\u{114d0}', '\u{114d9}')
     ];
 
-    pub static Ugaritic_table: &'static [(char, char)] = &[
+    pub const Ugaritic_table: &'static [(char, char)] = &[
         ('\u{10380}', '\u{1039d}'), ('\u{1039f}', '\u{1039f}')
     ];
 
-    pub static Vai_table: &'static [(char, char)] = &[
+    pub const Vai_table: &'static [(char, char)] = &[
         ('\u{a500}', '\u{a60b}'), ('\u{a60c}', '\u{a60c}'), ('\u{a60d}', '\u{a60f}'), ('\u{a610}',
         '\u{a61f}'), ('\u{a620}', '\u{a629}'), ('\u{a62a}', '\u{a62b}')
     ];
 
-    pub static Warang_Citi_table: &'static [(char, char)] = &[
+    pub const Warang_Citi_table: &'static [(char, char)] = &[
         ('\u{118a0}', '\u{118df}'), ('\u{118e0}', '\u{118e9}'), ('\u{118ea}', '\u{118f2}'),
         ('\u{118ff}', '\u{118ff}')
     ];
 
-    pub static Yi_table: &'static [(char, char)] = &[
+    pub const Yi_table: &'static [(char, char)] = &[
         ('\u{a000}', '\u{a014}'), ('\u{a015}', '\u{a015}'), ('\u{a016}', '\u{a48c}'), ('\u{a490}',
         '\u{a4c6}')
     ];
@@ -3928,11 +3919,11 @@ pub mod script {
 }
 
 pub mod property {
-    pub static Join_Control_table: &'static [(char, char)] = &[
+    pub const Join_Control_table: &'static [(char, char)] = &[
         ('\u{200c}', '\u{200d}')
     ];
 
-    pub static Noncharacter_Code_Point_table: &'static [(char, char)] = &[
+    pub const Noncharacter_Code_Point_table: &'static [(char, char)] = &[
         ('\u{fdd0}', '\u{fdef}'), ('\u{fffe}', '\u{ffff}'), ('\u{1fffe}', '\u{1ffff}'),
         ('\u{2fffe}', '\u{2ffff}'), ('\u{3fffe}', '\u{3ffff}'), ('\u{4fffe}', '\u{4ffff}'),
         ('\u{5fffe}', '\u{5ffff}'), ('\u{6fffe}', '\u{6ffff}'), ('\u{7fffe}', '\u{7ffff}'),
@@ -3941,7 +3932,7 @@ pub mod property {
         ('\u{efffe}', '\u{effff}'), ('\u{ffffe}', '\u{fffff}')
     ];
 
-    pub static White_Space_table: &'static [(char, char)] = &[
+    pub const White_Space_table: &'static [(char, char)] = &[
         ('\u{9}', '\u{d}'), ('\u{20}', '\u{20}'), ('\u{85}', '\u{85}'), ('\u{a0}', '\u{a0}'),
         ('\u{1680}', '\u{1680}'), ('\u{2000}', '\u{200a}'), ('\u{2028}', '\u{2028}'), ('\u{2029}',
         '\u{2029}'), ('\u{202f}', '\u{202f}'), ('\u{205f}', '\u{205f}'), ('\u{3000}', '\u{3000}')
@@ -3954,111 +3945,110 @@ pub mod property {
 }
 
 pub mod regex {
-    pub static UNICODE_CLASSES: &'static [(&'static str, &'static &'static [(char, char)])] = &[
-        ("Alphabetic", &super::derived_property::Alphabetic_table), ("Arabic",
-        &super::script::Arabic_table), ("Armenian", &super::script::Armenian_table), ("Avestan",
-        &super::script::Avestan_table), ("Balinese", &super::script::Balinese_table), ("Bamum",
-        &super::script::Bamum_table), ("Bassa_Vah", &super::script::Bassa_Vah_table), ("Batak",
-        &super::script::Batak_table), ("Bengali", &super::script::Bengali_table), ("Bopomofo",
-        &super::script::Bopomofo_table), ("Brahmi", &super::script::Brahmi_table), ("Braille",
-        &super::script::Braille_table), ("Buginese", &super::script::Buginese_table), ("Buhid",
-        &super::script::Buhid_table), ("C", &super::general_category::C_table),
-        ("Canadian_Aboriginal", &super::script::Canadian_Aboriginal_table), ("Carian",
-        &super::script::Carian_table), ("Caucasian_Albanian",
-        &super::script::Caucasian_Albanian_table), ("Cc", &super::general_category::Cc_table),
-        ("Cf", &super::general_category::Cf_table), ("Chakma", &super::script::Chakma_table),
-        ("Cham", &super::script::Cham_table), ("Cherokee", &super::script::Cherokee_table), ("Cn",
-        &super::general_category::Cn_table), ("Co", &super::general_category::Co_table), ("Common",
-        &super::script::Common_table), ("Coptic", &super::script::Coptic_table), ("Cuneiform",
-        &super::script::Cuneiform_table), ("Cypriot", &super::script::Cypriot_table), ("Cyrillic",
-        &super::script::Cyrillic_table), ("Default_Ignorable_Code_Point",
-        &super::derived_property::Default_Ignorable_Code_Point_table), ("Deseret",
-        &super::script::Deseret_table), ("Devanagari", &super::script::Devanagari_table),
-        ("Duployan", &super::script::Duployan_table), ("Egyptian_Hieroglyphs",
-        &super::script::Egyptian_Hieroglyphs_table), ("Elbasan", &super::script::Elbasan_table),
-        ("Ethiopic", &super::script::Ethiopic_table), ("Georgian", &super::script::Georgian_table),
-        ("Glagolitic", &super::script::Glagolitic_table), ("Gothic", &super::script::Gothic_table),
-        ("Grantha", &super::script::Grantha_table), ("Greek", &super::script::Greek_table),
-        ("Gujarati", &super::script::Gujarati_table), ("Gurmukhi", &super::script::Gurmukhi_table),
-        ("Han", &super::script::Han_table), ("Hangul", &super::script::Hangul_table), ("Hanunoo",
-        &super::script::Hanunoo_table), ("Hebrew", &super::script::Hebrew_table), ("Hiragana",
-        &super::script::Hiragana_table), ("Imperial_Aramaic",
-        &super::script::Imperial_Aramaic_table), ("Inherited", &super::script::Inherited_table),
-        ("Inscriptional_Pahlavi", &super::script::Inscriptional_Pahlavi_table),
-        ("Inscriptional_Parthian", &super::script::Inscriptional_Parthian_table), ("Javanese",
-        &super::script::Javanese_table), ("Join_Control", &super::property::Join_Control_table),
-        ("Kaithi", &super::script::Kaithi_table), ("Kannada", &super::script::Kannada_table),
-        ("Katakana", &super::script::Katakana_table), ("Kayah_Li", &super::script::Kayah_Li_table),
-        ("Kharoshthi", &super::script::Kharoshthi_table), ("Khmer", &super::script::Khmer_table),
-        ("Khojki", &super::script::Khojki_table), ("Khudawadi", &super::script::Khudawadi_table),
-        ("L", &super::general_category::L_table), ("LC", &super::general_category::LC_table),
-        ("Lao", &super::script::Lao_table), ("Latin", &super::script::Latin_table), ("Lepcha",
-        &super::script::Lepcha_table), ("Limbu", &super::script::Limbu_table), ("Linear_A",
-        &super::script::Linear_A_table), ("Linear_B", &super::script::Linear_B_table), ("Lisu",
-        &super::script::Lisu_table), ("Ll", &super::general_category::Ll_table), ("Lm",
-        &super::general_category::Lm_table), ("Lo", &super::general_category::Lo_table),
-        ("Lowercase", &super::derived_property::Lowercase_table), ("Lt",
-        &super::general_category::Lt_table), ("Lu", &super::general_category::Lu_table), ("Lycian",
-        &super::script::Lycian_table), ("Lydian", &super::script::Lydian_table), ("M",
-        &super::general_category::M_table), ("Mahajani", &super::script::Mahajani_table),
-        ("Malayalam", &super::script::Malayalam_table), ("Mandaic", &super::script::Mandaic_table),
-        ("Manichaean", &super::script::Manichaean_table), ("Mc",
-        &super::general_category::Mc_table), ("Me", &super::general_category::Me_table),
-        ("Meetei_Mayek", &super::script::Meetei_Mayek_table), ("Mende_Kikakui",
-        &super::script::Mende_Kikakui_table), ("Meroitic_Cursive",
-        &super::script::Meroitic_Cursive_table), ("Meroitic_Hieroglyphs",
-        &super::script::Meroitic_Hieroglyphs_table), ("Miao", &super::script::Miao_table), ("Mn",
-        &super::general_category::Mn_table), ("Modi", &super::script::Modi_table), ("Mongolian",
-        &super::script::Mongolian_table), ("Mro", &super::script::Mro_table), ("Myanmar",
-        &super::script::Myanmar_table), ("N", &super::general_category::N_table), ("Nabataean",
-        &super::script::Nabataean_table), ("Nd", &super::general_category::Nd_table),
-        ("New_Tai_Lue", &super::script::New_Tai_Lue_table), ("Nko", &super::script::Nko_table),
-        ("Nl", &super::general_category::Nl_table), ("No", &super::general_category::No_table),
-        ("Noncharacter_Code_Point", &super::property::Noncharacter_Code_Point_table), ("Ogham",
-        &super::script::Ogham_table), ("Ol_Chiki", &super::script::Ol_Chiki_table), ("Old_Italic",
-        &super::script::Old_Italic_table), ("Old_North_Arabian",
-        &super::script::Old_North_Arabian_table), ("Old_Permic", &super::script::Old_Permic_table),
-        ("Old_Persian", &super::script::Old_Persian_table), ("Old_South_Arabian",
-        &super::script::Old_South_Arabian_table), ("Old_Turkic", &super::script::Old_Turkic_table),
-        ("Oriya", &super::script::Oriya_table), ("Osmanya", &super::script::Osmanya_table), ("P",
-        &super::general_category::P_table), ("Pahawh_Hmong", &super::script::Pahawh_Hmong_table),
-        ("Palmyrene", &super::script::Palmyrene_table), ("Pau_Cin_Hau",
-        &super::script::Pau_Cin_Hau_table), ("Pc", &super::general_category::Pc_table), ("Pd",
-        &super::general_category::Pd_table), ("Pe", &super::general_category::Pe_table), ("Pf",
-        &super::general_category::Pf_table), ("Phags_Pa", &super::script::Phags_Pa_table),
-        ("Phoenician", &super::script::Phoenician_table), ("Pi",
-        &super::general_category::Pi_table), ("Po", &super::general_category::Po_table), ("Ps",
-        &super::general_category::Ps_table), ("Psalter_Pahlavi",
-        &super::script::Psalter_Pahlavi_table), ("Rejang", &super::script::Rejang_table), ("Runic",
-        &super::script::Runic_table), ("S", &super::general_category::S_table), ("Samaritan",
-        &super::script::Samaritan_table), ("Saurashtra", &super::script::Saurashtra_table), ("Sc",
-        &super::general_category::Sc_table), ("Sharada", &super::script::Sharada_table), ("Shavian",
-        &super::script::Shavian_table), ("Siddham", &super::script::Siddham_table), ("Sinhala",
-        &super::script::Sinhala_table), ("Sk", &super::general_category::Sk_table), ("Sm",
-        &super::general_category::Sm_table), ("So", &super::general_category::So_table),
-        ("Sora_Sompeng", &super::script::Sora_Sompeng_table), ("Sundanese",
-        &super::script::Sundanese_table), ("Syloti_Nagri", &super::script::Syloti_Nagri_table),
-        ("Syriac", &super::script::Syriac_table), ("Tagalog", &super::script::Tagalog_table),
-        ("Tagbanwa", &super::script::Tagbanwa_table), ("Tai_Le", &super::script::Tai_Le_table),
-        ("Tai_Tham", &super::script::Tai_Tham_table), ("Tai_Viet", &super::script::Tai_Viet_table),
-        ("Takri", &super::script::Takri_table), ("Tamil", &super::script::Tamil_table), ("Telugu",
-        &super::script::Telugu_table), ("Thaana", &super::script::Thaana_table), ("Thai",
-        &super::script::Thai_table), ("Tibetan", &super::script::Tibetan_table), ("Tifinagh",
-        &super::script::Tifinagh_table), ("Tirhuta", &super::script::Tirhuta_table), ("Ugaritic",
-        &super::script::Ugaritic_table), ("Uppercase", &super::derived_property::Uppercase_table),
-        ("Vai", &super::script::Vai_table), ("Warang_Citi", &super::script::Warang_Citi_table),
-        ("White_Space", &super::property::White_Space_table), ("XID_Continue",
-        &super::derived_property::XID_Continue_table), ("XID_Start",
-        &super::derived_property::XID_Start_table), ("Yi", &super::script::Yi_table), ("Z",
-        &super::general_category::Z_table), ("Zl", &super::general_category::Zl_table), ("Zp",
-        &super::general_category::Zp_table), ("Zs", &super::general_category::Zs_table)
-    ];
-
-    pub static PERLD: &'static &'static [(char, char)] = &super::general_category::Nd_table;
-
-    pub static PERLS: &'static &'static [(char, char)] = &super::property::White_Space_table;
-
-    pub static PERLW: &'static [(char, char)] = &[
+    pub const UNICODE_CLASSES: &'static [(&'static str, &'static [(char, char)])] = &[
+        ("Alphabetic", super::derived_property::Alphabetic_table), ("Arabic",
+        super::script::Arabic_table), ("Armenian", super::script::Armenian_table), ("Avestan",
+        super::script::Avestan_table), ("Balinese", super::script::Balinese_table), ("Bamum",
+        super::script::Bamum_table), ("Bassa_Vah", super::script::Bassa_Vah_table), ("Batak",
+        super::script::Batak_table), ("Bengali", super::script::Bengali_table), ("Bopomofo",
+        super::script::Bopomofo_table), ("Brahmi", super::script::Brahmi_table), ("Braille",
+        super::script::Braille_table), ("Buginese", super::script::Buginese_table), ("Buhid",
+        super::script::Buhid_table), ("C", super::general_category::C_table),
+        ("Canadian_Aboriginal", super::script::Canadian_Aboriginal_table), ("Carian",
+        super::script::Carian_table), ("Caucasian_Albanian",
+        super::script::Caucasian_Albanian_table), ("Cc", super::general_category::Cc_table), ("Cf",
+        super::general_category::Cf_table), ("Chakma", super::script::Chakma_table), ("Cham",
+        super::script::Cham_table), ("Cherokee", super::script::Cherokee_table), ("Cn",
+        super::general_category::Cn_table), ("Co", super::general_category::Co_table), ("Common",
+        super::script::Common_table), ("Coptic", super::script::Coptic_table), ("Cuneiform",
+        super::script::Cuneiform_table), ("Cypriot", super::script::Cypriot_table), ("Cyrillic",
+        super::script::Cyrillic_table), ("Default_Ignorable_Code_Point",
+        super::derived_property::Default_Ignorable_Code_Point_table), ("Deseret",
+        super::script::Deseret_table), ("Devanagari", super::script::Devanagari_table), ("Duployan",
+        super::script::Duployan_table), ("Egyptian_Hieroglyphs",
+        super::script::Egyptian_Hieroglyphs_table), ("Elbasan", super::script::Elbasan_table),
+        ("Ethiopic", super::script::Ethiopic_table), ("Georgian", super::script::Georgian_table),
+        ("Glagolitic", super::script::Glagolitic_table), ("Gothic", super::script::Gothic_table),
+        ("Grantha", super::script::Grantha_table), ("Greek", super::script::Greek_table),
+        ("Gujarati", super::script::Gujarati_table), ("Gurmukhi", super::script::Gurmukhi_table),
+        ("Han", super::script::Han_table), ("Hangul", super::script::Hangul_table), ("Hanunoo",
+        super::script::Hanunoo_table), ("Hebrew", super::script::Hebrew_table), ("Hiragana",
+        super::script::Hiragana_table), ("Imperial_Aramaic", super::script::Imperial_Aramaic_table),
+        ("Inherited", super::script::Inherited_table), ("Inscriptional_Pahlavi",
+        super::script::Inscriptional_Pahlavi_table), ("Inscriptional_Parthian",
+        super::script::Inscriptional_Parthian_table), ("Javanese", super::script::Javanese_table),
+        ("Join_Control", super::property::Join_Control_table), ("Kaithi",
+        super::script::Kaithi_table), ("Kannada", super::script::Kannada_table), ("Katakana",
+        super::script::Katakana_table), ("Kayah_Li", super::script::Kayah_Li_table), ("Kharoshthi",
+        super::script::Kharoshthi_table), ("Khmer", super::script::Khmer_table), ("Khojki",
+        super::script::Khojki_table), ("Khudawadi", super::script::Khudawadi_table), ("L",
+        super::general_category::L_table), ("LC", super::general_category::LC_table), ("Lao",
+        super::script::Lao_table), ("Latin", super::script::Latin_table), ("Lepcha",
+        super::script::Lepcha_table), ("Limbu", super::script::Limbu_table), ("Linear_A",
+        super::script::Linear_A_table), ("Linear_B", super::script::Linear_B_table), ("Lisu",
+        super::script::Lisu_table), ("Ll", super::general_category::Ll_table), ("Lm",
+        super::general_category::Lm_table), ("Lo", super::general_category::Lo_table), ("Lowercase",
+        super::derived_property::Lowercase_table), ("Lt", super::general_category::Lt_table), ("Lu",
+        super::general_category::Lu_table), ("Lycian", super::script::Lycian_table), ("Lydian",
+        super::script::Lydian_table), ("M", super::general_category::M_table), ("Mahajani",
+        super::script::Mahajani_table), ("Malayalam", super::script::Malayalam_table), ("Mandaic",
+        super::script::Mandaic_table), ("Manichaean", super::script::Manichaean_table), ("Mc",
+        super::general_category::Mc_table), ("Me", super::general_category::Me_table),
+        ("Meetei_Mayek", super::script::Meetei_Mayek_table), ("Mende_Kikakui",
+        super::script::Mende_Kikakui_table), ("Meroitic_Cursive",
+        super::script::Meroitic_Cursive_table), ("Meroitic_Hieroglyphs",
+        super::script::Meroitic_Hieroglyphs_table), ("Miao", super::script::Miao_table), ("Mn",
+        super::general_category::Mn_table), ("Modi", super::script::Modi_table), ("Mongolian",
+        super::script::Mongolian_table), ("Mro", super::script::Mro_table), ("Myanmar",
+        super::script::Myanmar_table), ("N", super::general_category::N_table), ("Nabataean",
+        super::script::Nabataean_table), ("Nd", super::general_category::Nd_table), ("New_Tai_Lue",
+        super::script::New_Tai_Lue_table), ("Nko", super::script::Nko_table), ("Nl",
+        super::general_category::Nl_table), ("No", super::general_category::No_table),
+        ("Noncharacter_Code_Point", super::property::Noncharacter_Code_Point_table), ("Ogham",
+        super::script::Ogham_table), ("Ol_Chiki", super::script::Ol_Chiki_table), ("Old_Italic",
+        super::script::Old_Italic_table), ("Old_North_Arabian",
+        super::script::Old_North_Arabian_table), ("Old_Permic", super::script::Old_Permic_table),
+        ("Old_Persian", super::script::Old_Persian_table), ("Old_South_Arabian",
+        super::script::Old_South_Arabian_table), ("Old_Turkic", super::script::Old_Turkic_table),
+        ("Oriya", super::script::Oriya_table), ("Osmanya", super::script::Osmanya_table), ("P",
+        super::general_category::P_table), ("Pahawh_Hmong", super::script::Pahawh_Hmong_table),
+        ("Palmyrene", super::script::Palmyrene_table), ("Pau_Cin_Hau",
+        super::script::Pau_Cin_Hau_table), ("Pc", super::general_category::Pc_table), ("Pd",
+        super::general_category::Pd_table), ("Pe", super::general_category::Pe_table), ("Pf",
+        super::general_category::Pf_table), ("Phags_Pa", super::script::Phags_Pa_table),
+        ("Phoenician", super::script::Phoenician_table), ("Pi", super::general_category::Pi_table),
+        ("Po", super::general_category::Po_table), ("Ps", super::general_category::Ps_table),
+        ("Psalter_Pahlavi", super::script::Psalter_Pahlavi_table), ("Rejang",
+        super::script::Rejang_table), ("Runic", super::script::Runic_table), ("S",
+        super::general_category::S_table), ("Samaritan", super::script::Samaritan_table),
+        ("Saurashtra", super::script::Saurashtra_table), ("Sc", super::general_category::Sc_table),
+        ("Sharada", super::script::Sharada_table), ("Shavian", super::script::Shavian_table),
+        ("Siddham", super::script::Siddham_table), ("Sinhala", super::script::Sinhala_table), ("Sk",
+        super::general_category::Sk_table), ("Sm", super::general_category::Sm_table), ("So",
+        super::general_category::So_table), ("Sora_Sompeng", super::script::Sora_Sompeng_table),
+        ("Sundanese", super::script::Sundanese_table), ("Syloti_Nagri",
+        super::script::Syloti_Nagri_table), ("Syriac", super::script::Syriac_table), ("Tagalog",
+        super::script::Tagalog_table), ("Tagbanwa", super::script::Tagbanwa_table), ("Tai_Le",
+        super::script::Tai_Le_table), ("Tai_Tham", super::script::Tai_Tham_table), ("Tai_Viet",
+        super::script::Tai_Viet_table), ("Takri", super::script::Takri_table), ("Tamil",
+        super::script::Tamil_table), ("Telugu", super::script::Telugu_table), ("Thaana",
+        super::script::Thaana_table), ("Thai", super::script::Thai_table), ("Tibetan",
+        super::script::Tibetan_table), ("Tifinagh", super::script::Tifinagh_table), ("Tirhuta",
+        super::script::Tirhuta_table), ("Ugaritic", super::script::Ugaritic_table), ("Uppercase",
+        super::derived_property::Uppercase_table), ("Vai", super::script::Vai_table),
+        ("Warang_Citi", super::script::Warang_Citi_table), ("White_Space",
+        super::property::White_Space_table), ("XID_Continue",
+        super::derived_property::XID_Continue_table), ("XID_Start",
+        super::derived_property::XID_Start_table), ("Yi", super::script::Yi_table), ("Z",
+        super::general_category::Z_table), ("Zl", super::general_category::Zl_table), ("Zp",
+        super::general_category::Zp_table), ("Zs", super::general_category::Zs_table)
+    ];
+
+    pub const PERLD: &'static [(char, char)] = super::general_category::Nd_table;
+
+    pub const PERLS: &'static [(char, char)] = super::property::White_Space_table;
+
+    pub const PERLW: &'static [(char, char)] = &[
         ('\u{30}', '\u{39}'), ('\u{41}', '\u{5a}'), ('\u{5f}', '\u{5f}'), ('\u{61}', '\u{7a}'),
         ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'), ('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'),
         ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{2c1}'), ('\u{2c6}', '\u{2d1}'), ('\u{2e0}', '\u{2e4}'),
@@ -4254,7 +4244,7 @@ pub mod regex {
 
 pub mod normalization {
     // Canonical decompositions
-    pub static canonical_table: &'static [(char, &'static [char])] = &[
+    pub const canonical_table: &'static [(char, &'static [char])] = &[
         ('\u{c0}', &['\u{41}', '\u{300}']), ('\u{c1}', &['\u{41}', '\u{301}']), ('\u{c2}',
         &['\u{41}', '\u{302}']), ('\u{c3}', &['\u{41}', '\u{303}']), ('\u{c4}', &['\u{41}',
         '\u{308}']), ('\u{c5}', &['\u{41}', '\u{30a}']), ('\u{c7}', &['\u{43}', '\u{327}']),
@@ -5056,7 +5046,7 @@ pub mod normalization {
     ];
 
     // Compatibility decompositions
-    pub static compatibility_table: &'static [(char, &'static [char])] = &[
+    pub const compatibility_table: &'static [(char, &'static [char])] = &[
         ('\u{a0}', &['\u{20}']), ('\u{a8}', &['\u{20}', '\u{308}']), ('\u{aa}', &['\u{61}']),
         ('\u{af}', &['\u{20}', '\u{304}']), ('\u{b2}', &['\u{32}']), ('\u{b3}', &['\u{33}']),
         ('\u{b4}', &['\u{20}', '\u{301}']), ('\u{b5}', &['\u{3bc}']), ('\u{b8}', &['\u{20}',
@@ -6480,7 +6470,7 @@ pub mod normalization {
     ];
 
     // Canonical compositions
-    pub static composition_table: &'static [(char, &'static [(char, char)])] = &[
+    pub const composition_table: &'static [(char, &'static [(char, char)])] = &[
         ('\u{3c}', &[('\u{338}', '\u{226e}')]), ('\u{3d}', &[('\u{338}', '\u{2260}')]), ('\u{3e}',
         &[('\u{338}', '\u{226f}')]), ('\u{41}', &[('\u{300}', '\u{c0}'), ('\u{301}', '\u{c1}'),
         ('\u{302}', '\u{c2}'), ('\u{303}', '\u{c3}'), ('\u{304}', '\u{100}'), ('\u{306}',
@@ -6840,7 +6830,7 @@ pub mod normalization {
         }
     }
 
-    static combining_class_table: &'static [(char, char, u8)] = &[
+    const combining_class_table: &'static [(char, char, u8)] = &[
         ('\u{300}', '\u{314}', 230), ('\u{315}', '\u{315}', 232), ('\u{316}', '\u{319}', 220),
         ('\u{31a}', '\u{31a}', 232), ('\u{31b}', '\u{31b}', 216), ('\u{31c}', '\u{320}', 220),
         ('\u{321}', '\u{322}', 202), ('\u{323}', '\u{326}', 220), ('\u{327}', '\u{328}', 202),
@@ -6988,7 +6978,7 @@ pub mod conversions {
         }
     }
 
-    static LuLl_table: &'static [(char, char)] = &[
+    const LuLl_table: &'static [(char, char)] = &[
         ('\u{41}', '\u{61}'), ('\u{42}', '\u{62}'), ('\u{43}', '\u{63}'), ('\u{44}', '\u{64}'),
         ('\u{45}', '\u{65}'), ('\u{46}', '\u{66}'), ('\u{47}', '\u{67}'), ('\u{48}', '\u{68}'),
         ('\u{49}', '\u{69}'), ('\u{4a}', '\u{6a}'), ('\u{4b}', '\u{6b}'), ('\u{4c}', '\u{6c}'),
@@ -7284,7 +7274,7 @@ pub mod conversions {
         ('\u{118be}', '\u{118de}'), ('\u{118bf}', '\u{118df}')
     ];
 
-    static LlLu_table: &'static [(char, char)] = &[
+    const LlLu_table: &'static [(char, char)] = &[
         ('\u{61}', '\u{41}'), ('\u{62}', '\u{42}'), ('\u{63}', '\u{43}'), ('\u{64}', '\u{44}'),
         ('\u{65}', '\u{45}'), ('\u{66}', '\u{46}'), ('\u{67}', '\u{47}'), ('\u{68}', '\u{48}'),
         ('\u{69}', '\u{49}'), ('\u{6a}', '\u{4a}'), ('\u{6b}', '\u{4b}'), ('\u{6c}', '\u{4c}'),
@@ -7625,7 +7615,7 @@ pub mod charwidth {
 
     // character width table. Based on Markus Kuhn's free wcwidth() implementation,
     //     http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
-    static charwidth_table: &'static [(char, char, u8, u8)] = &[
+    const charwidth_table: &'static [(char, char, u8, u8)] = &[
         ('\u{a1}', '\u{a1}', 1, 2), ('\u{a4}', '\u{a4}', 1, 2), ('\u{a7}', '\u{a8}', 1, 2),
         ('\u{aa}', '\u{aa}', 1, 2), ('\u{ae}', '\u{ae}', 1, 2), ('\u{b0}', '\u{b4}', 1, 2),
         ('\u{b6}', '\u{ba}', 1, 2), ('\u{bc}', '\u{bf}', 1, 2), ('\u{c6}', '\u{c6}', 1, 2),
@@ -7839,7 +7829,7 @@ pub mod grapheme {
         bsearch_range_value_table(c, grapheme_cat_table)
     }
 
-    static grapheme_cat_table: &'static [(char, char, GraphemeCat)] = &[
+    const grapheme_cat_table: &'static [(char, char, GraphemeCat)] = &[
         ('\u{0}', '\u{1f}', GC_Control), ('\u{7f}', '\u{9f}', GC_Control), ('\u{ad}', '\u{ad}',
         GC_Control), ('\u{300}', '\u{36f}', GC_Extend), ('\u{483}', '\u{487}', GC_Extend),
         ('\u{488}', '\u{489}', GC_Extend), ('\u{591}', '\u{5bd}', GC_Extend), ('\u{5bf}', '\u{5bf}',
diff --git a/src/libunicode/u_char.rs b/src/libunicode/u_char.rs
deleted file mode 100644 (file)
index c0f45ca..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-// 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.
-//
-// 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.
-
-//! Unicode-intensive `char` methods along with the `core` methods.
-//!
-//! These methods implement functionality for `char` that requires knowledge of
-//! Unicode definitions, including normalization, categorization, and display information.
-
-use core::char;
-use core::char::CharExt as C;
-use core::option::Option;
-use tables::{derived_property, property, general_category, conversions, charwidth};
-
-/// Functionality for manipulating `char`.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait CharExt {
-    /// Checks if a `char` parses as a numeric digit in the given radix.
-    ///
-    /// Compared to `is_numeric()`, this function only recognizes the characters
-    /// `0-9`, `a-z` and `A-Z`.
-    ///
-    /// # Return value
-    ///
-    /// Returns `true` if `c` is a valid digit under `radix`, and `false`
-    /// otherwise.
-    ///
-    /// # Panics
-    ///
-    /// Panics if given a radix > 36.
-    #[unstable(feature = "unicode",
-               reason = "pending integer conventions")]
-    fn is_digit(self, radix: u32) -> bool;
-
-    /// Converts a character to the corresponding digit.
-    ///
-    /// # Return value
-    ///
-    /// If `c` is between '0' and '9', the corresponding value between 0 and
-    /// 9. If `c` is 'a' or 'A', 10. If `c` is 'b' or 'B', 11, etc. Returns
-    /// none if the character does not refer to a digit in the given radix.
-    ///
-    /// # Panics
-    ///
-    /// Panics if given a radix outside the range [0..36].
-    #[unstable(feature = "unicode",
-               reason = "pending integer conventions")]
-    fn to_digit(self, radix: u32) -> Option<u32>;
-
-    /// Returns an iterator that yields the hexadecimal Unicode escape
-    /// of a character, as `char`s.
-    ///
-    /// All characters are escaped with Rust syntax of the form `\\u{NNNN}`
-    /// where `NNNN` is the shortest hexadecimal representation of the code
-    /// point.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn escape_unicode(self) -> char::EscapeUnicode;
-
-    /// Returns an iterator that yields the 'default' ASCII and
-    /// C++11-like literal escape of a character, as `char`s.
-    ///
-    /// The default is chosen with a bias toward producing literals that are
-    /// legal in a variety of languages, including C++11 and similar C-family
-    /// languages. The exact rules are:
-    ///
-    /// * Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
-    /// * Single-quote, double-quote and backslash chars are backslash-
-    ///   escaped.
-    /// * Any other chars in the range [0x20,0x7e] are not escaped.
-    /// * Any other chars are given hex Unicode escapes; see `escape_unicode`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn escape_default(self) -> char::EscapeDefault;
-
-    /// Returns the amount of bytes this character would need if encoded in
-    /// UTF-8.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn len_utf8(self) -> usize;
-
-    /// Returns the amount of bytes this character would need if encoded in
-    /// UTF-16.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn len_utf16(self) -> usize;
-
-    /// Encodes this character as UTF-8 into the provided byte buffer,
-    /// and then returns the number of bytes written.
-    ///
-    /// If the buffer is not large enough, nothing will be written into it
-    /// and a `None` will be returned.
-    #[unstable(feature = "unicode",
-               reason = "pending decision about Iterator/Writer/Reader")]
-    fn encode_utf8(self, dst: &mut [u8]) -> Option<usize>;
-
-    /// Encodes this character as UTF-16 into the provided `u16` buffer,
-    /// and then returns the number of `u16`s written.
-    ///
-    /// If the buffer is not large enough, nothing will be written into it
-    /// and a `None` will be returned.
-    #[unstable(feature = "unicode",
-               reason = "pending decision about Iterator/Writer/Reader")]
-    fn encode_utf16(self, dst: &mut [u16]) -> Option<usize>;
-
-    /// Returns whether the specified character is considered a Unicode
-    /// alphabetic code point.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_alphabetic(self) -> bool;
-
-    /// Returns whether the specified character satisfies the 'XID_Start'
-    /// Unicode property.
-    ///
-    /// 'XID_Start' is a Unicode Derived Property specified in
-    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-    /// mostly similar to ID_Start but modified for closure under NFKx.
-    #[unstable(feature = "unicode",
-               reason = "mainly needed for compiler internals")]
-    fn is_xid_start(self) -> bool;
-
-    /// Returns whether the specified `char` satisfies the 'XID_Continue'
-    /// Unicode property.
-    ///
-    /// 'XID_Continue' is a Unicode Derived Property specified in
-    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-    /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
-    #[unstable(feature = "unicode",
-               reason = "mainly needed for compiler internals")]
-    fn is_xid_continue(self) -> bool;
-
-    /// Indicates whether a character is in lowercase.
-    ///
-    /// This is defined according to the terms of the Unicode Derived Core
-    /// Property `Lowercase`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_lowercase(self) -> bool;
-
-    /// Indicates whether a character is in uppercase.
-    ///
-    /// This is defined according to the terms of the Unicode Derived Core
-    /// Property `Uppercase`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_uppercase(self) -> bool;
-
-    /// Indicates whether a character is whitespace.
-    ///
-    /// Whitespace is defined in terms of the Unicode Property `White_Space`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_whitespace(self) -> bool;
-
-    /// Indicates whether a character is alphanumeric.
-    ///
-    /// Alphanumericness is defined in terms of the Unicode General Categories
-    /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_alphanumeric(self) -> bool;
-
-    /// Indicates whether a character is a control code point.
-    ///
-    /// Control code points are defined in terms of the Unicode General
-    /// Category `Cc`.
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_control(self) -> bool;
-
-    /// Indicates whether the character is numeric (Nd, Nl, or No).
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_numeric(self) -> bool;
-
-    /// Converts a character to its lowercase equivalent.
-    ///
-    /// The case-folding performed is the common or simple mapping. See
-    /// `to_uppercase()` for references and more information.
-    ///
-    /// # Return value
-    ///
-    /// Returns the lowercase equivalent of the character, or the character
-    /// itself if no conversion is possible.
-    #[unstable(feature = "unicode",
-               reason = "pending case transformation decisions")]
-    fn to_lowercase(self) -> char;
-
-    /// Converts a character to its uppercase equivalent.
-    ///
-    /// The case-folding performed is the common or simple mapping: it maps
-    /// one Unicode codepoint (one character in Rust) to its uppercase
-    /// equivalent according to the Unicode database [1]. The additional
-    /// [`SpecialCasing.txt`] is not considered here, as it expands to multiple
-    /// codepoints in some cases.
-    ///
-    /// A full reference can be found here [2].
-    ///
-    /// # Return value
-    ///
-    /// Returns the uppercase equivalent of the character, or the character
-    /// itself if no conversion was made.
-    ///
-    /// [1]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
-    ///
-    /// [`SpecialCasing`.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt
-    ///
-    /// [2]: http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
-    #[unstable(feature = "unicode",
-               reason = "pending case transformation decisions")]
-    fn to_uppercase(self) -> char;
-
-    /// Returns this character's displayed width in columns, or `None` if it is a
-    /// control character other than `'\x00'`.
-    ///
-    /// `is_cjk` determines behavior for characters in the Ambiguous category:
-    /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
-    /// In CJK contexts, `is_cjk` should be `true`, else it should be `false`.
-    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
-    /// recommends that these characters be treated as 1 column (i.e.,
-    /// `is_cjk` = `false`) if the context cannot be reliably determined.
-    #[unstable(feature = "unicode",
-               reason = "needs expert opinion. is_cjk flag stands out as ugly")]
-    fn width(self, is_cjk: bool) -> Option<usize>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl CharExt for char {
-    #[unstable(feature = "unicode",
-               reason = "pending integer conventions")]
-    fn is_digit(self, radix: u32) -> bool { C::is_digit(self, radix) }
-    #[unstable(feature = "unicode",
-               reason = "pending integer conventions")]
-    fn to_digit(self, radix: u32) -> Option<u32> { C::to_digit(self, radix) }
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn escape_unicode(self) -> char::EscapeUnicode { C::escape_unicode(self) }
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn escape_default(self) -> char::EscapeDefault { C::escape_default(self) }
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn len_utf8(self) -> usize { C::len_utf8(self) }
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn len_utf16(self) -> usize { C::len_utf16(self) }
-    #[unstable(feature = "unicode",
-               reason = "pending decision about Iterator/Writer/Reader")]
-    fn encode_utf8(self, dst: &mut [u8]) -> Option<usize> { C::encode_utf8(self, dst) }
-    #[unstable(feature = "unicode",
-               reason = "pending decision about Iterator/Writer/Reader")]
-    fn encode_utf16(self, dst: &mut [u16]) -> Option<usize> { C::encode_utf16(self, dst) }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_alphabetic(self) -> bool {
-        match self {
-            'a' ... 'z' | 'A' ... 'Z' => true,
-            c if c > '\x7f' => derived_property::Alphabetic(c),
-            _ => false
-        }
-    }
-
-    #[unstable(feature = "unicode",
-               reason = "mainly needed for compiler internals")]
-    fn is_xid_start(self) -> bool { derived_property::XID_Start(self) }
-
-    #[unstable(feature = "unicode",
-               reason = "mainly needed for compiler internals")]
-    fn is_xid_continue(self) -> bool { derived_property::XID_Continue(self) }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_lowercase(self) -> bool {
-        match self {
-            'a' ... 'z' => true,
-            c if c > '\x7f' => derived_property::Lowercase(c),
-            _ => false
-        }
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_uppercase(self) -> bool {
-        match self {
-            'A' ... 'Z' => true,
-            c if c > '\x7f' => derived_property::Uppercase(c),
-            _ => false
-        }
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_whitespace(self) -> bool {
-        match self {
-            ' ' | '\x09' ... '\x0d' => true,
-            c if c > '\x7f' => property::White_Space(c),
-            _ => false
-        }
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_alphanumeric(self) -> bool {
-        self.is_alphabetic() || self.is_numeric()
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_control(self) -> bool { general_category::Cc(self) }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn is_numeric(self) -> bool {
-        match self {
-            '0' ... '9' => true,
-            c if c > '\x7f' => general_category::N(c),
-            _ => false
-        }
-    }
-
-    #[unstable(feature = "unicode",
-               reason = "pending case transformation decisions")]
-    fn to_lowercase(self) -> char { conversions::to_lower(self) }
-
-    #[unstable(feature = "unicode",
-               reason = "pending case transformation decisions")]
-    fn to_uppercase(self) -> char { conversions::to_upper(self) }
-
-    #[unstable(feature = "unicode",
-               reason = "needs expert opinion. is_cjk flag stands out as ugly")]
-    fn width(self, is_cjk: bool) -> Option<usize> { charwidth::width(self, is_cjk) }
-}
index 9bd8c5525a056828966e0838637722518d0370f6..3f9dd8ab635c3bd64bf973f06354e0cd4eb59a3e 100644 (file)
@@ -22,11 +22,9 @@ use core::char;
 use core::cmp;
 use core::iter::{Filter, AdditiveIterator};
 use core::mem;
-use core::num::Int;
 use core::slice;
 use core::str::Split;
 
-use u_char::CharExt as UCharExt; // conflicts with core::prelude::CharExt
 use tables::grapheme::GraphemeCat;
 
 /// An iterator over the words of a string, separated by a sequence of whitespace
@@ -84,7 +82,7 @@ impl UnicodeStr for str {
 
     #[inline]
     fn trim(&self) -> &str {
-        self.trim_left().trim_right()
+        self.trim_matches(|c: char| c.is_whitespace())
     }
 
     #[inline]
@@ -243,7 +241,7 @@ impl<'a> Iterator for Graphemes<'a> {
         }
 
         self.cat = if take_curr {
-            idx = self.string.char_range_at(idx).next;
+            idx = idx + self.string.char_at(idx).len_utf8();
             None
         } else {
             Some(cat)
@@ -479,22 +477,27 @@ impl<'a> Iterator for Utf16Items<'a> {
 /// Create an iterator over the UTF-16 encoded codepoints in `v`,
 /// returning invalid surrogates as `LoneSurrogate`s.
 ///
-/// # Example
+/// # Examples
+///
+/// ```
+/// # #![feature(unicode)]
+/// extern crate unicode;
 ///
-/// ```rust
 /// use unicode::str::Utf16Item::{ScalarValue, LoneSurrogate};
 ///
-/// // 𝄞mus<invalid>ic<invalid>
-/// let v = [0xD834, 0xDD1E, 0x006d, 0x0075,
-///          0x0073, 0xDD1E, 0x0069, 0x0063,
-///          0xD834];
+/// fn main() {
+///     // 𝄞mus<invalid>ic<invalid>
+///     let v = [0xD834, 0xDD1E, 0x006d, 0x0075,
+///              0x0073, 0xDD1E, 0x0069, 0x0063,
+///              0xD834];
 ///
-/// assert_eq!(unicode::str::utf16_items(&v).collect::<Vec<_>>(),
-///            vec![ScalarValue('𝄞'),
-///                 ScalarValue('m'), ScalarValue('u'), ScalarValue('s'),
-///                 LoneSurrogate(0xDD1E),
-///                 ScalarValue('i'), ScalarValue('c'),
-///                 LoneSurrogate(0xD834)]);
+///     assert_eq!(unicode::str::utf16_items(&v).collect::<Vec<_>>(),
+///                vec![ScalarValue('𝄞'),
+///                     ScalarValue('m'), ScalarValue('u'), ScalarValue('s'),
+///                     LoneSurrogate(0xDD1E),
+///                     ScalarValue('i'), ScalarValue('c'),
+///                     LoneSurrogate(0xD834)]);
+/// }
 /// ```
 pub fn utf16_items<'a>(v: &'a [u16]) -> Utf16Items<'a> {
     Utf16Items { iter : v.iter() }
@@ -525,7 +528,7 @@ impl<I> Iterator for Utf16Encoder<I> where I: Iterator<Item=char> {
             return Some(tmp);
         }
 
-        let mut buf = [0u16; 2];
+        let mut buf = [0; 2];
         self.chars.next().map(|ch| {
             let n = CharExt::encode_utf16(ch, &mut buf).unwrap_or(0);
             if n == 2 { self.extra = buf[1]; }
index 673d62bfbf5b54270b39874f780696b4680e9984..612bff3de8f3dda3ad1f06117ce0269edb676fa1 100755 (executable)
@@ -1354,7 +1354,7 @@ case $os in
              | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
              | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
              | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -bitrig*)
        # Remember, each alternative MUST END IN *, to match a version number.
                ;;
        -qnx*)
index 3bd8aa1806c27f5aed9f710bbf1125bd6355aa25..d05575222ff0895656b1fc5c747ff6c644b6ac1e 100644 (file)
@@ -267,6 +267,11 @@ AC_CACHE_CHECK([type of operating system we're going to host on],
     llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
     llvm_cv_os_type="DragonFly"
     llvm_cv_platform_type="Unix" ;;
+  *-*-bitrig*)
+    llvm_cv_link_all_option="-Wl,--whole-archive"
+    llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
+    llvm_cv_os_type="Bitrig"
+    llvm_cv_platform_type="Unix" ;;
   *-*-hpux*)
     llvm_cv_link_all_option="-Wl,--whole-archive"
     llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
@@ -347,6 +352,8 @@ AC_CACHE_CHECK([type of operating system we're going to target],
     llvm_cv_target_os_type="NetBSD" ;;
   *-*-dragonfly*)
     llvm_cv_target_os_type="DragonFly" ;;
+  *-*-bitrig*)
+    llvm_cv_target_os_type="Bitrig" ;;
   *-*-hpux*)
     llvm_cv_target_os_type="HP-UX" ;;
   *-*-interix*)
index ba5ecbef334f1f7812dc9e5318ecbca30bf06b89..d22c569a52cb77475eb76953cb7f9a7822109539 100755 (executable)
@@ -3966,6 +3966,11 @@ else
     llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
     llvm_cv_os_type="DragonFly"
     llvm_cv_platform_type="Unix" ;;
+  *-*-bitrig*)
+    llvm_cv_link_all_option="-Wl,--whole-archive"
+    llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
+    llvm_cv_os_type="Bitrig"
+    llvm_cv_platform_type="Unix" ;;
   *-*-hpux*)
     llvm_cv_link_all_option="-Wl,--whole-archive"
     llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
@@ -4052,6 +4057,8 @@ else
     llvm_cv_target_os_type="NetBSD" ;;
   *-*-dragonfly*)
     llvm_cv_target_os_type="DragonFly" ;;
+  *-*-bitrig*)
+    llvm_cv_target_os_type="Bitrig" ;;
   *-*-hpux*)
     llvm_cv_target_os_type="HP-UX" ;;
   *-*-interix*)
index 107f9d297d0fb08359e3cb04cdc29f4b61917b3c..32e8295acdd59b5f1306f8ada25927bb04d115da 100644 (file)
@@ -5,11 +5,6 @@ LLVM 3.6 Release Notes
 .. contents::
     :local:
 
-.. warning::
-   These are in-progress notes for the upcoming LLVM 3.6 release.  You may
-   prefer the `LLVM 3.5 Release Notes <http://llvm.org/releases/3.5.0/docs
-   /ReleaseNotes.html>`_.
-
 
 Introduction
 ============
@@ -26,10 +21,6 @@ have questions or comments, the `LLVM Developer's Mailing List
 <http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev>`_ is a good place to send
 them.
 
-Note that if you are reading this file from a Subversion checkout or the main
-LLVM web page, this document applies to the *next* release, not the current
-one.  To see the release notes for a specific release, please see the `releases
-page <http://llvm.org/releases/>`_.
 
 Non-comprehensive list of changes in this release
 =================================================
@@ -507,6 +498,12 @@ Changes to the OCaml bindings
 
 * As usual, many more functions have been exposed to OCaml.
 
+Go bindings
+-----------
+
+* A set of Go bindings based on `gollvm <https://github.com/go-llvm/llvm>`_
+  was introduced in this release.
+
 External Open Source Projects Using LLVM 3.6
 ============================================
 
@@ -544,6 +541,33 @@ new LLVM-based code generators "on the fly" for the designed processors and
 loads them in to the compiler backend as runtime libraries to avoid
 per-target recompilation of larger parts of the compiler chain. 
 
+Likely
+------
+
+`Likely <http://www.liblikely.org>`_ is an embeddable just-in-time Lisp for
+image recognition and heterogenous computing. Algorithms are just-in-time
+compiled using LLVM's MCJIT infrastructure to execute on single or
+multi-threaded CPUs and potentially OpenCL SPIR or CUDA enabled GPUs.
+Likely seeks to explore new optimizations for statistical learning 
+algorithms by moving them from an offline model generation step to the 
+compile-time evaluation of a function (the learning algorithm) with constant
+arguments (the training data).
+
+LDC - the LLVM-based D compiler
+-------------------------------
+
+`D <http://dlang.org>`_ is a language with C-like syntax and static typing. It
+pragmatically combines efficiency, control, and modeling power, with safety and
+programmer productivity. D supports powerful concepts like Compile-Time Function
+Execution (CTFE) and Template Meta-Programming, provides an innovative approach
+to concurrency and offers many classical paradigms.
+
+`LDC <http://wiki.dlang.org/LDC>`_ uses the frontend from the reference compiler
+combined with LLVM as backend to produce efficient native code. LDC targets
+x86/x86_64 systems like Linux, OS X, FreeBSD and Windows and also Linux on
+PowerPC (32/64 bit). Ports to other architectures like ARM, AArch64 and MIPS64
+are underway.
+
 Additional Information
 ======================
 
index dd6ea18f090630a8a1df89e1c5a961304459a327..33bb0834ace9ec51993df273ef7349b047ef2dca 100644 (file)
@@ -1,11 +1,6 @@
 Overview
 ========
 
-.. warning::
-
-   If you are using a released version of LLVM, see `the download page
-   <http://llvm.org/releases/>`_ to find your documentation.
-
 The LLVM compiler infrastructure supports a wide range of projects, from
 industrial strength compilers to specialized JIT applications to small
 research projects.
index 45e92e4b8ca8dffc1e4aae202b38a290e5e12cde..284491a267642e483f27edf89369441ac381a075 100644 (file)
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
   ExecutionEngine
   InstCombine
   MC
+  RuntimeDyld
   ScalarOpts
   Support
   native
index f0d0b2dbcdbc972f51811bdf9e5fe45b0a0550f0..584ce65c9d175e083047b67b25014a2ef80be349 100644 (file)
@@ -66,7 +66,6 @@ struct LandingPadInfo {
   MachineBasicBlock *LandingPadBlock;    // Landing pad block.
   SmallVector<MCSymbol*, 1> BeginLabels; // Labels prior to invoke.
   SmallVector<MCSymbol*, 1> EndLabels;   // Labels after invoke.
-  SmallVector<MCSymbol*, 1> ClauseLabels; // Labels for each clause.
   MCSymbol *LandingPadLabel;             // Label at beginning of landing pad.
   const Function *Personality;           // Personality function.
   std::vector<int> TypeIds;              // List of type ids (filters negative)
@@ -331,11 +330,6 @@ public:
   ///
   void addCleanup(MachineBasicBlock *LandingPad);
 
-  /// Add a clause for a landing pad. Returns a new label for the clause. This
-  /// is used by EH schemes that have more than one landing pad. In this case,
-  /// each clause gets its own basic block.
-  MCSymbol *addClauseForLandingPad(MachineBasicBlock *LandingPad);
-
   /// getTypeIDFor - Return the type id for the specified typeinfo.  This is
   /// function wide.
   unsigned getTypeIDFor(const GlobalValue *TI);
index 4950797bb1e01d2b61f8052a7b93a8b81931a252..ee4bc08495ec93c8a594fd84daeb04f867800e0a 100644 (file)
@@ -867,9 +867,11 @@ public:
                            SDValue Offset, ISD::MemIndexedMode AM);
 
   SDValue getMaskedLoad(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr,
-                        SDValue Mask, SDValue Src0, MachineMemOperand *MMO);
+                        SDValue Mask, SDValue Src0, EVT MemVT,
+                        MachineMemOperand *MMO, ISD::LoadExtType);
   SDValue getMaskedStore(SDValue Chain, SDLoc dl, SDValue Val,
-                         SDValue Ptr, SDValue Mask, MachineMemOperand *MMO);
+                         SDValue Ptr, SDValue Mask, EVT MemVT,
+                         MachineMemOperand *MMO, bool IsTrunc);
   /// getSrcValue - Construct a node to track a Value* through the backend.
   SDValue getSrcValue(const Value *v);
 
index 8e7fd547626c72f37cd42f2f9578ea80015af290..933ec7fff48395fb1d27b8b89d3087138ba607b0 100644 (file)
@@ -1970,13 +1970,17 @@ public:
 class MaskedLoadSDNode : public MaskedLoadStoreSDNode {
 public:
   friend class SelectionDAG;
-  MaskedLoadSDNode(unsigned Order, DebugLoc dl,
-                   SDValue *Operands, unsigned numOperands, 
-                   SDVTList VTs, EVT MemVT, MachineMemOperand *MMO)
+  MaskedLoadSDNode(unsigned Order, DebugLoc dl, SDValue *Operands,
+                   unsigned numOperands, SDVTList VTs, ISD::LoadExtType ETy,
+                   EVT MemVT, MachineMemOperand *MMO)
     : MaskedLoadStoreSDNode(ISD::MLOAD, Order, dl, Operands, numOperands,
-                            VTs, MemVT, MMO) 
-  {}
+                            VTs, MemVT, MMO) {
+    SubclassData |= (unsigned short)ETy;
+  }
 
+  ISD::LoadExtType getExtensionType() const {
+    return ISD::LoadExtType(SubclassData & 3);
+  } 
   const SDValue &getSrc0() const { return getOperand(3); }
   static bool classof(const SDNode *N) {
     return N->getOpcode() == ISD::MLOAD;
@@ -1989,14 +1993,19 @@ class MaskedStoreSDNode : public MaskedLoadStoreSDNode {
 
 public:
   friend class SelectionDAG;
-  MaskedStoreSDNode(unsigned Order, DebugLoc dl,
-                   SDValue *Operands, unsigned numOperands, 
-                   SDVTList VTs, EVT MemVT, MachineMemOperand *MMO)
+  MaskedStoreSDNode(unsigned Order, DebugLoc dl, SDValue *Operands,
+                    unsigned numOperands, SDVTList VTs, bool isTrunc, EVT MemVT,
+                    MachineMemOperand *MMO)
     : MaskedLoadStoreSDNode(ISD::MSTORE, Order, dl, Operands, numOperands,
-                            VTs, MemVT, MMO) 
-  {}
+                            VTs, MemVT, MMO) {
+      SubclassData |= (unsigned short)isTrunc;
+  }
+  /// isTruncatingStore - Return true if the op does a truncation before store.
+  /// For integers this is the same as doing a TRUNCATE and storing the result.
+  /// For floats, it is the same as doing an FP_ROUND and storing the result.
+  bool isTruncatingStore() const { return SubclassData & 1; }
 
-  const SDValue &getData() const { return getOperand(3); }
+  const SDValue &getValue() const { return getOperand(3); }
 
   static bool classof(const SDNode *N) {
     return N->getOpcode() == ISD::MSTORE;
index d154135e25b2ce345ec55f1eee28e241a86b5034..27f07d4e39d1e32287687e6cb7316f0db9132394 100644 (file)
@@ -6,9 +6,6 @@
 /* Exported configuration */
 #include "llvm/Config/llvm-config.h"
 
-/* Patch version of the LLVM API */
-#cmakedefine LLVM_VERSION_PATCH ${LLVM_VERSION_PATCH}
-
 /* Bug report URL. */
 #define BUG_REPORT_URL "${BUG_REPORT_URL}"
 
index 77201e6330bbab3673d513275ef20d5c902e20df..d54003d993a968501809b4adec9b4eddc0e0a946 100644 (file)
 #cmakedefine LLVM_USE_OPROFILE 1
 
 /* Major version of the LLVM API */
-#cmakedefine LLVM_VERSION_MAJOR ${LLVM_VERSION_MAJOR}
+#define LLVM_VERSION_MAJOR ${LLVM_VERSION_MAJOR}
 
 /* Minor version of the LLVM API */
-#cmakedefine LLVM_VERSION_MINOR ${LLVM_VERSION_MINOR}
+#define LLVM_VERSION_MINOR ${LLVM_VERSION_MINOR}
+
+/* Patch version of the LLVM API */
+#define LLVM_VERSION_PATCH ${LLVM_VERSION_PATCH}
 
 /* LLVM version string */
 #define LLVM_VERSION_STRING "${PACKAGE_VERSION}"
index 2d6add71a4e03240159893db4d23bb86f31b97fb..25a9295448322abd3a9e4bdb713c8de8bab2da50 100644 (file)
@@ -92,6 +92,9 @@
 /* Minor version of the LLVM API */
 #undef LLVM_VERSION_MINOR
 
+/* Patch version of the LLVM API */
+#undef LLVM_VERSION_PATCH
+
 /* LLVM version string */
 #undef LLVM_VERSION_STRING
 
index 1b0e1b7e7b7777563cc786e39ba66ff16d51cab7..5b098b4f51d6ba719fd4b917f457d3a161bcfb2e 100644 (file)
@@ -325,6 +325,9 @@ public:
   /// index.
   Constant *getElementValue(unsigned Idx) const;
 
+  /// \brief Return the number of elements in the array, vector, or struct.
+  unsigned getNumElements() const;
+
   /// Methods for support type inquiry through isa, cast, and dyn_cast:
   ///
   static bool classof(const Value *V) {
@@ -1196,6 +1199,9 @@ public:
   /// index.
   UndefValue *getElementValue(unsigned Idx) const;
 
+  /// \brief Return the number of elements in the array, vector, or struct.
+  unsigned getNumElements() const;
+
   void destroyConstant() override;
 
   /// Methods for support type inquiry through isa, cast, and dyn_cast:
index 46f87b93b001c113c5bf91b467bfdf4d92d92381..1863a84b6e65c8d1cb61a0e38a580efed1fea510 100644 (file)
@@ -371,6 +371,10 @@ namespace llvm {
       isascii,
       /// int isdigit(int c);
       isdigit,
+      /// void *je_mallocx(size_t size, int flags);
+      je_mallocx,
+      /// void *je_sdallocx(void *ptr, size_t size, int flags)
+      je_sdallocx,
       /// long int labs(long int j);
       labs,
       /// int lchown(const char *path, uid_t owner, gid_t group);
@@ -688,6 +692,7 @@ namespace llvm {
       /// ssize_t write(int fildes, const void *buf, size_t nbyte);
       write,
 
+
       NumLibFuncs
     };
   }
index 58ac5d33409ea819848e1873d493e2e1c438b743..86e7fc21b95007d60c267927b9b7ff1d72be4e53 100644 (file)
@@ -52,7 +52,7 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
   const TargetTransformInfo &TTI;
 
   /// The cache of @llvm.assume intrinsics.
-  AssumptionCache &AC;
+  AssumptionCacheTracker *ACT;
 
   // The called function.
   Function &F;
@@ -146,8 +146,8 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
 
 public:
   CallAnalyzer(const DataLayout *DL, const TargetTransformInfo &TTI,
-               AssumptionCache &AC, Function &Callee, int Threshold)
-      : DL(DL), TTI(TTI), AC(AC), F(Callee), Threshold(Threshold), Cost(0),
+               AssumptionCacheTracker *ACT, Function &Callee, int Threshold)
+      : DL(DL), TTI(TTI), ACT(ACT), F(Callee), Threshold(Threshold), Cost(0),
         IsCallerRecursive(false), IsRecursiveCall(false),
         ExposesReturnsTwice(false), HasDynamicAlloca(false),
         ContainsNoDuplicateCall(false), HasReturn(false), HasIndirectBr(false),
@@ -783,7 +783,7 @@ bool CallAnalyzer::visitCallSite(CallSite CS) {
   // during devirtualization and so we want to give it a hefty bonus for
   // inlining, but cap that bonus in the event that inlining wouldn't pan
   // out. Pretend to inline the function, with a custom threshold.
-  CallAnalyzer CA(DL, TTI, AC, *F, InlineConstants::IndirectCallThreshold);
+  CallAnalyzer CA(DL, TTI, ACT, *F, InlineConstants::IndirectCallThreshold);
   if (CA.analyzeCall(CS)) {
     // We were able to inline the indirect call! Subtract the cost from the
     // bonus we want to apply, but don't go below zero.
@@ -1110,7 +1110,7 @@ bool CallAnalyzer::analyzeCall(CallSite CS) {
   // the ephemeral values multiple times (and they're completely determined by
   // the callee, so this is purely duplicate work).
   SmallPtrSet<const Value *, 32> EphValues;
-  CodeMetrics::collectEphemeralValues(&F, &AC, EphValues);
+  CodeMetrics::collectEphemeralValues(&F, &ACT->getAssumptionCache(F), EphValues);
 
   // The worklist of live basic blocks in the callee *after* inlining. We avoid
   // adding basic blocks of the callee which can be proven to be dead for this
@@ -1310,7 +1310,7 @@ InlineCost InlineCostAnalysis::getInlineCost(CallSite CS, Function *Callee,
         << "...\n");
 
   CallAnalyzer CA(Callee->getDataLayout(), *TTI,
-                  ACT->getAssumptionCache(*Callee), *Callee, Threshold);
+                  ACT, *Callee, Threshold);
   bool ShouldInline = CA.analyzeCall(CS);
 
   DEBUG(CA.dump());
index 08b41fee44594c5608a124dd9a5553c028be0aa9..72f127fc959bc33a2006264dc82c2dd49247022e 100644 (file)
@@ -66,7 +66,8 @@ static const AllocFnsTy AllocationFnData[] = {
   {LibFunc::realloc,             ReallocLike, 2, 1,  -1},
   {LibFunc::reallocf,            ReallocLike, 2, 1,  -1},
   {LibFunc::strdup,              StrDupLike,  1, -1, -1},
-  {LibFunc::strndup,             StrDupLike,  2, 1,  -1}
+  {LibFunc::strndup,             StrDupLike,  2, 1,  -1},
+  {LibFunc::je_mallocx,          MallocLike,  2, 0,  -1}
   // TODO: Handle "int posix_memalign(void **, size_t, size_t)"
 };
 
@@ -339,6 +340,8 @@ const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
            TLIFn == LibFunc::ZdaPvm ||              // delete[](void*, ulong)
            TLIFn == LibFunc::ZdaPvRKSt9nothrow_t)   // delete[](void*, nothrow)
     ExpectedNumParams = 2;
+  else if (TLIFn == LibFunc::je_sdallocx)
+    ExpectedNumParams = 3;
   else
     return nullptr;
 
index 409adafc78631b664636955c5b8d170842ded135..3d9546fc2b79d4e2aeb0742e7746f3477f15b3fe 100644 (file)
@@ -538,9 +538,17 @@ Metadata *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) {
   if (Metadata *MD = MDValuePtrs[Idx])
     return MD;
 
-  // Create and return a placeholder, which will later be RAUW'd.
-  AnyFwdRefs = true;
+  // Track forward refs to be resolved later.
+  if (AnyFwdRefs) {
+    MinFwdRef = std::min(MinFwdRef, Idx);
+    MaxFwdRef = std::max(MaxFwdRef, Idx);
+  } else {
+    AnyFwdRefs = true;
+    MinFwdRef = MaxFwdRef = Idx;
+  }
   ++NumFwdRefs;
+
+  // Create and return a placeholder, which will later be RAUW'd.
   Metadata *MD = MDNode::getTemporary(Context, None);
   MDValuePtrs[Idx].reset(MD);
   return MD;
@@ -556,11 +564,15 @@ void BitcodeReaderMDValueList::tryToResolveCycles() {
     return;
 
   // Resolve any cycles.
-  for (auto &MD : MDValuePtrs) {
+  for (unsigned I = MinFwdRef, E = MaxFwdRef + 1; I != E; ++I) {
+    auto &MD = MDValuePtrs[I];
     assert(!(MD && isa<MDNodeFwdDecl>(MD)) && "Unexpected forward reference");
     if (auto *N = dyn_cast_or_null<UniquableMDNode>(MD))
       N->resolveCycles();
   }
+
+  // Make sure we return early again until there's another forward ref.
+  AnyFwdRefs = false;
 }
 
 Type *BitcodeReader::getTypeByID(unsigned ID) {
index 7f7eb70bce93c12c988b99cd431ee304835ef4fd..5090be48450ebc9306fd7baa995a61d45acce99b 100644 (file)
@@ -99,6 +99,8 @@ public:
 class BitcodeReaderMDValueList {
   unsigned NumFwdRefs;
   bool AnyFwdRefs;
+  unsigned MinFwdRef;
+  unsigned MaxFwdRef;
   std::vector<TrackingMDRef> MDValuePtrs;
 
   LLVMContext &Context;
index 1bc86f6c222a914893da634fb1b421bcae943037..f112120c1abc75f99922643a6e31ea1a10d26a5d 100644 (file)
@@ -121,8 +121,7 @@ computeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
       for (unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) {
         int TypeID = TypeIds[J];
         assert(-1 - TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
-        int ValueForTypeID =
-            isFilterEHSelector(TypeID) ? FilterOffsets[-1 - TypeID] : TypeID;
+        int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
         unsigned SizeTypeID = getSLEB128Size(ValueForTypeID);
 
         int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
@@ -270,14 +269,14 @@ computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
         CallSiteEntry Site = {
           BeginLabel,
           LastLabel,
-          LandingPad,
+          LandingPad->LandingPadLabel,
           FirstActions[P.PadIndex]
         };
 
         // Try to merge with the previous call-site. SJLJ doesn't do this
         if (PreviousIsInvoke && !IsSJLJ) {
           CallSiteEntry &Prev = CallSites.back();
-          if (Site.LPad == Prev.LPad && Site.Action == Prev.Action) {
+          if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
             // Extend the range of the previous entry.
             Prev.EndLabel = Site.EndLabel;
             continue;
@@ -577,15 +576,15 @@ void EHStreamer::emitExceptionTable() {
 
       // Offset of the landing pad, counted in 16-byte bundles relative to the
       // @LPStart address.
-      if (!S.LPad) {
+      if (!S.PadLabel) {
         if (VerboseAsm)
           Asm->OutStreamer.AddComment("    has no landing pad");
         Asm->OutStreamer.EmitIntValue(0, 4/*size*/);
       } else {
         if (VerboseAsm)
           Asm->OutStreamer.AddComment(Twine("    jumps to ") +
-                                      S.LPad->LandingPadLabel->getName());
-        Asm->EmitLabelDifference(S.LPad->LandingPadLabel, EHFuncBeginSym, 4);
+                                      S.PadLabel->getName());
+        Asm->EmitLabelDifference(S.PadLabel, EHFuncBeginSym, 4);
       }
 
       // Offset of the first associated action record, relative to the start of
@@ -682,7 +681,7 @@ void EHStreamer::emitTypeInfos(unsigned TTypeEncoding) {
     unsigned TypeID = *I;
     if (VerboseAsm) {
       --Entry;
-      if (isFilterEHSelector(TypeID))
+      if (TypeID != 0)
         Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry));
     }
 
index 9b316ff00e9bb6364f182f3e2beb43f52dcdd30e..e93055ce8655a7b10347e6fb2e620f538ea06845 100644 (file)
@@ -23,8 +23,6 @@ class MachineModuleInfo;
 class MachineInstr;
 class MachineFunction;
 class AsmPrinter;
-class MCSymbol;
-class MCSymbolRefExpr;
 
 template <typename T>
 class SmallVectorImpl;
@@ -62,11 +60,11 @@ protected:
   /// Structure describing an entry in the call-site table.
   struct CallSiteEntry {
     // The 'try-range' is BeginLabel .. EndLabel.
-    MCSymbol *BeginLabel; // Null indicates the start of the function.
-    MCSymbol *EndLabel;   // Null indicates the end of the function.
+    MCSymbol *BeginLabel; // zero indicates the start of the function.
+    MCSymbol *EndLabel;   // zero indicates the end of the function.
 
-    // LPad contains the landing pad start labels.
-    const LandingPadInfo *LPad; // Null indicates that there is no landing pad.
+    // The landing pad starts at PadLabel.
+    MCSymbol *PadLabel;   // zero indicates that there is no landing pad.
     unsigned Action;
   };
 
@@ -114,13 +112,6 @@ protected:
 
   virtual void emitTypeInfos(unsigned TTypeEncoding);
 
-  // Helpers for for identifying what kind of clause an EH typeid or selector
-  // corresponds to. Negative selectors are for filter clauses, the zero
-  // selector is for cleanups, and positive selectors are for catch clauses.
-  static bool isFilterEHSelector(int Selector) { return Selector < 0; }
-  static bool isCleanupEHSelector(int Selector) { return Selector == 0; }
-  static bool isCatchEHSelector(int Selector) { return Selector > 0; }
-
 public:
   EHStreamer(AsmPrinter *A);
   virtual ~EHStreamer();
index 2138cb9514f82484333c7be5c52344698e40cb4b..0f0ad755835dc4ed9bfe7f79777294cfba198f28 100644 (file)
@@ -99,156 +99,9 @@ void Win64Exception::endFunction(const MachineFunction *) {
 
   if (shouldEmitPersonality) {
     Asm->OutStreamer.PushSection();
-
-    // Emit an UNWIND_INFO struct describing the prologue.
     Asm->OutStreamer.EmitWinEHHandlerData();
-
-    // Emit either MSVC-compatible tables or the usual Itanium-style LSDA after
-    // the UNWIND_INFO struct.
-    if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::MSVC) {
-      const Function *Per = MMI->getPersonalities()[MMI->getPersonalityIndex()];
-      if (Per->getName() == "__C_specific_handler")
-        emitCSpecificHandlerTable();
-      else
-        report_fatal_error(Twine("unexpected personality function: ") +
-                           Per->getName());
-    } else {
-      emitExceptionTable();
-    }
-
+    emitExceptionTable();
     Asm->OutStreamer.PopSection();
   }
   Asm->OutStreamer.EmitWinCFIEndProc();
 }
-
-const MCSymbolRefExpr *Win64Exception::createImageRel32(const MCSymbol *Value) {
-  return MCSymbolRefExpr::Create(Value, MCSymbolRefExpr::VK_COFF_IMGREL32,
-                                 Asm->OutContext);
-}
-
-/// Emit the language-specific data that __C_specific_handler expects.  This
-/// handler lives in the x64 Microsoft C runtime and allows catching or cleaning
-/// up after faults with __try, __except, and __finally.  The typeinfo values
-/// are not really RTTI data, but pointers to filter functions that return an
-/// integer (1, 0, or -1) indicating how to handle the exception. For __finally
-/// blocks and other cleanups, the landing pad label is zero, and the filter
-/// function is actually a cleanup handler with the same prototype.  A catch-all
-/// entry is modeled with a null filter function field and a non-zero landing
-/// pad label.
-///
-/// Possible filter function return values:
-///   EXCEPTION_EXECUTE_HANDLER (1):
-///     Jump to the landing pad label after cleanups.
-///   EXCEPTION_CONTINUE_SEARCH (0):
-///     Continue searching this table or continue unwinding.
-///   EXCEPTION_CONTINUE_EXECUTION (-1):
-///     Resume execution at the trapping PC.
-///
-/// Inferred table structure:
-///   struct Table {
-///     int NumEntries;
-///     struct Entry {
-///       imagerel32 LabelStart;
-///       imagerel32 LabelEnd;
-///       imagerel32 FilterOrFinally;  // Zero means catch-all.
-///       imagerel32 LabelLPad;        // Zero means __finally.
-///     } Entries[NumEntries];
-///   };
-void Win64Exception::emitCSpecificHandlerTable() {
-  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
-
-  // Simplifying assumptions for first implementation:
-  // - Cleanups are not implemented.
-  // - Filters are not implemented.
-
-  // The Itanium LSDA table sorts similar landing pads together to simplify the
-  // actions table, but we don't need that.
-  SmallVector<const LandingPadInfo *, 64> LandingPads;
-  LandingPads.reserve(PadInfos.size());
-  for (const auto &LP : PadInfos)
-    LandingPads.push_back(&LP);
-
-  // Compute label ranges for call sites as we would for the Itanium LSDA, but
-  // use an all zero action table because we aren't using these actions.
-  SmallVector<unsigned, 64> FirstActions;
-  FirstActions.resize(LandingPads.size());
-  SmallVector<CallSiteEntry, 64> CallSites;
-  computeCallSiteTable(CallSites, LandingPads, FirstActions);
-
-  MCSymbol *EHFuncBeginSym =
-      Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber());
-  MCSymbol *EHFuncEndSym =
-      Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber());
-
-  // Emit the number of table entries.
-  unsigned NumEntries = 0;
-  for (const CallSiteEntry &CSE : CallSites) {
-    if (!CSE.LPad)
-      continue; // Ignore gaps.
-    for (int Selector : CSE.LPad->TypeIds) {
-      // Ignore C++ filter clauses in SEH.
-      // FIXME: Implement cleanup clauses.
-      if (isCatchEHSelector(Selector))
-        ++NumEntries;
-    }
-  }
-  Asm->OutStreamer.EmitIntValue(NumEntries, 4);
-
-  // Emit the four-label records for each call site entry. The table has to be
-  // sorted in layout order, and the call sites should already be sorted.
-  for (const CallSiteEntry &CSE : CallSites) {
-    // Ignore gaps. Unlike the Itanium model, unwinding through a frame without
-    // an EH table entry will propagate the exception rather than terminating
-    // the program.
-    if (!CSE.LPad)
-      continue;
-    const LandingPadInfo *LPad = CSE.LPad;
-
-    // Compute the label range. We may reuse the function begin and end labels
-    // rather than forming new ones.
-    const MCExpr *Begin =
-        createImageRel32(CSE.BeginLabel ? CSE.BeginLabel : EHFuncBeginSym);
-    const MCExpr *End;
-    if (CSE.EndLabel) {
-      // The interval is half-open, so we have to add one to include the return
-      // address of the last invoke in the range.
-      End = MCBinaryExpr::CreateAdd(createImageRel32(CSE.EndLabel),
-                                    MCConstantExpr::Create(1, Asm->OutContext),
-                                    Asm->OutContext);
-    } else {
-      End = createImageRel32(EHFuncEndSym);
-    }
-
-    // These aren't really type info globals, they are actually pointers to
-    // filter functions ordered by selector. The zero selector is used for
-    // cleanups, so slot zero corresponds to selector 1.
-    const std::vector<const GlobalValue *> &SelectorToFilter = MMI->getTypeInfos();
-
-    // Do a parallel iteration across typeids and clause labels, skipping filter
-    // clauses.
-    assert(LPad->TypeIds.size() == LPad->ClauseLabels.size());
-    for (size_t I = 0, E = LPad->TypeIds.size(); I < E; ++I) {
-      // AddLandingPadInfo stores the clauses in reverse, but there is a FIXME
-      // to change that.
-      int Selector = LPad->TypeIds[E - I - 1];
-      MCSymbol *ClauseLabel = LPad->ClauseLabels[I];
-
-      // Ignore C++ filter clauses in SEH.
-      // FIXME: Implement cleanup clauses.
-      if (!isCatchEHSelector(Selector))
-        continue;
-
-      Asm->OutStreamer.EmitValue(Begin, 4);
-      Asm->OutStreamer.EmitValue(End, 4);
-      if (isCatchEHSelector(Selector)) {
-        assert(unsigned(Selector - 1) < SelectorToFilter.size());
-        const GlobalValue *TI = SelectorToFilter[Selector - 1];
-        if (TI) // Emit the filter function pointer.
-          Asm->OutStreamer.EmitValue(createImageRel32(Asm->getSymbol(TI)), 4);
-        else  // Otherwise, this is a "catch i8* null", or catch all.
-          Asm->OutStreamer.EmitIntValue(0, 4);
-      }
-      Asm->OutStreamer.EmitValue(createImageRel32(ClauseLabel), 4);
-    }
-  }
-}
index b2d5d1bce56311c89a7473f4300b539444e103cf..538e1328157f6452bd29b7dda5b0d67698cedbb4 100644 (file)
@@ -29,10 +29,6 @@ class Win64Exception : public EHStreamer {
   /// Per-function flag to indicate if frame moves info should be emitted.
   bool shouldEmitMoves;
 
-  void emitCSpecificHandlerTable();
-
-  const MCSymbolRefExpr *createImageRel32(const MCSymbol *Value);
-
 public:
   //===--------------------------------------------------------------------===//
   // Main entry points.
index 32d511285eb21243be54b42359396f8d76df0c54..baad411e2c5bc81848bea314de9333dda1739914 100644 (file)
@@ -452,14 +452,6 @@ void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
   LP.TypeIds.push_back(0);
 }
 
-MCSymbol *
-MachineModuleInfo::addClauseForLandingPad(MachineBasicBlock *LandingPad) {
-  MCSymbol *ClauseLabel = Context.CreateTempSymbol();
-  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
-  LP.ClauseLabels.push_back(ClauseLabel);
-  return ClauseLabel;
-}
-
 /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
 /// pads.
 void MachineModuleInfo::TidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap) {
index 28e9f847a9d746dee460e8ab0c0e70da4d0a4ba6..e53e874cb17828d0449f1e954256a1f3d43d464d 100644 (file)
@@ -449,9 +449,9 @@ void TargetPassConfig::addPassesToHandleExceptions() {
   case ExceptionHandling::DwarfCFI:
   case ExceptionHandling::ARM:
   case ExceptionHandling::ItaniumWinEH:
-  case ExceptionHandling::MSVC: // FIXME: Needs preparation.
     addPass(createDwarfEHPass(TM));
     break;
+  case ExceptionHandling::MSVC: // FIXME: Add preparation.
   case ExceptionHandling::None:
     addPass(createLowerInvokePass());
 
index 5145731f6231f3922f25bfaf5d97a5c5288dac35..afb986f1d7c63fedd6b5908d6943619cf0c8931b 100644 (file)
@@ -4842,7 +4842,7 @@ SDValue DAGCombiner::visitMSTORE(SDNode *N) {
 
   MaskedStoreSDNode *MST = dyn_cast<MaskedStoreSDNode>(N);
   SDValue Mask = MST->getMask();
-  SDValue Data  = MST->getData();
+  SDValue Data  = MST->getValue();
   SDLoc DL(N);
 
   // If the MSTORE data type requires splitting and the mask is provided by a
@@ -4885,7 +4885,8 @@ SDValue DAGCombiner::visitMSTORE(SDNode *N) {
                            MachineMemOperand::MOStore,  LoMemVT.getStoreSize(),
                            Alignment, MST->getAAInfo(), MST->getRanges());
 
-    Lo = DAG.getMaskedStore(Chain, DL, DataLo, Ptr, MaskLo, MMO);
+    Lo = DAG.getMaskedStore(Chain, DL, DataLo, Ptr, MaskLo, LoMemVT, MMO,
+                            MST->isTruncatingStore());
 
     unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
     Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr,
@@ -4897,7 +4898,8 @@ SDValue DAGCombiner::visitMSTORE(SDNode *N) {
                            SecondHalfAlignment, MST->getAAInfo(),
                            MST->getRanges());
 
-    Hi = DAG.getMaskedStore(Chain, DL, DataHi, Ptr, MaskHi, MMO);
+    Hi = DAG.getMaskedStore(Chain, DL, DataHi, Ptr, MaskHi, HiMemVT, MMO,
+                            MST->isTruncatingStore());
 
     AddToWorklist(Lo.getNode());
     AddToWorklist(Hi.getNode());
@@ -4958,7 +4960,8 @@ SDValue DAGCombiner::visitMLOAD(SDNode *N) {
                          MachineMemOperand::MOLoad,  LoMemVT.getStoreSize(),
                          Alignment, MLD->getAAInfo(), MLD->getRanges());
 
-    Lo = DAG.getMaskedLoad(LoVT, DL, Chain, Ptr, MaskLo, Src0Lo, MMO);
+    Lo = DAG.getMaskedLoad(LoVT, DL, Chain, Ptr, MaskLo, Src0Lo, LoMemVT, MMO,
+                           ISD::NON_EXTLOAD);
 
     unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
     Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr,
@@ -4969,7 +4972,8 @@ SDValue DAGCombiner::visitMLOAD(SDNode *N) {
                          MachineMemOperand::MOLoad,  HiMemVT.getStoreSize(),
                          SecondHalfAlignment, MLD->getAAInfo(), MLD->getRanges());
 
-    Hi = DAG.getMaskedLoad(HiVT, DL, Chain, Ptr, MaskHi, Src0Hi, MMO);
+    Hi = DAG.getMaskedLoad(HiVT, DL, Chain, Ptr, MaskHi, Src0Hi, HiMemVT, MMO,
+                           ISD::NON_EXTLOAD);
 
     AddToWorklist(Lo.getNode());
     AddToWorklist(Hi.getNode());
@@ -6544,19 +6548,15 @@ SDValue DAGCombiner::visitBITCAST(SDNode *N) {
 
   // If the input is a constant, let getNode fold it.
   if (isa<ConstantSDNode>(N0) || isa<ConstantFPSDNode>(N0)) {
-    SDValue Res = DAG.getNode(ISD::BITCAST, SDLoc(N), VT, N0);
-    if (Res.getNode() != N) {
-      if (!LegalOperations ||
-          TLI.isOperationLegal(Res.getNode()->getOpcode(), VT))
-        return Res;
-
-      // Folding it resulted in an illegal node, and it's too late to
-      // do that. Clean up the old node and forego the transformation.
-      // Ideally this won't happen very often, because instcombine
-      // and the earlier dagcombine runs (where illegal nodes are
-      // permitted) should have folded most of them already.
-      deleteAndRecombine(Res.getNode());
-    }
+    // If we can't allow illegal operations, we need to check that this is just
+    // a fp -> int or int -> conversion and that the resulting operation will
+    // be legal.
+    if (!LegalOperations ||
+        (isa<ConstantSDNode>(N0) && VT.isFloatingPoint() && !VT.isVector() &&
+         TLI.isOperationLegal(ISD::ConstantFP, VT)) ||
+        (isa<ConstantFPSDNode>(N0) && VT.isInteger() && !VT.isVector() &&
+         TLI.isOperationLegal(ISD::Constant, VT)))
+      return DAG.getNode(ISD::BITCAST, SDLoc(N), VT, N0);
   }
 
   // (conv (conv x, t1), t2) -> (conv x, t2)
@@ -9486,6 +9486,8 @@ SDValue DAGCombiner::ReduceLoadOpStoreWidth(SDNode *N) {
     unsigned MSB = BitWidth - Imm.countLeadingZeros() - 1;
     unsigned NewBW = NextPowerOf2(MSB - ShAmt);
     EVT NewVT = EVT::getIntegerVT(*DAG.getContext(), NewBW);
+    // The narrowing should be profitable, the load/store operation should be
+    // legal (or custom) and the store size should be equal to the NewVT width.
     while (NewBW < BitWidth &&
            !(TLI.isOperationLegalOrCustom(Opc, NewVT) &&
              TLI.isNarrowingProfitable(VT, NewVT))) {
index 82b114b80aa9894bd5d6f74a403cd731bd15ed0b..a4e44ccbd7cc1141e9a070b705ce37b31cd5f9d0 100644 (file)
@@ -458,16 +458,16 @@ SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
 SDValue DAGTypeLegalizer::PromoteIntRes_MLOAD(MaskedLoadSDNode *N) {
   EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
   SDValue ExtSrc0 = GetPromotedInteger(N->getSrc0());
-  SDValue ExtMask = PromoteTargetBoolean(N->getMask(), NVT);
-  SDLoc dl(N);
 
-  MachineMemOperand *MMO = DAG.getMachineFunction().
-    getMachineMemOperand(N->getPointerInfo(),
-                         MachineMemOperand::MOLoad,  NVT.getStoreSize(),
-                         N->getAlignment(), N->getAAInfo(), N->getRanges());
+  SDValue Mask = N->getMask();
+  EVT NewMaskVT = getSetCCResultType(NVT);
+  if (NewMaskVT != N->getMask().getValueType())
+    Mask = PromoteTargetBoolean(Mask, NewMaskVT);
+  SDLoc dl(N);
 
   SDValue Res = DAG.getMaskedLoad(NVT, dl, N->getChain(), N->getBasePtr(),
-                                  ExtMask, ExtSrc0, MMO);
+                                  Mask, ExtSrc0, N->getMemoryVT(),
+                                  N->getMemOperand(), ISD::SEXTLOAD);
   // Legalized the chain result - switch anything that used the old chain to
   // use the new one.
   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
@@ -1117,16 +1117,18 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
 SDValue DAGTypeLegalizer::PromoteIntOp_MSTORE(MaskedStoreSDNode *N, unsigned OpNo){
 
   assert(OpNo == 2 && "Only know how to promote the mask!");
-  SDValue DataOp = N->getData();
+  SDValue DataOp = N->getValue();
   EVT DataVT = DataOp.getValueType();
   SDValue Mask = N->getMask();
   EVT MaskVT = Mask.getValueType();
   SDLoc dl(N);
 
+  bool TruncateStore = false;
   if (!TLI.isTypeLegal(DataVT)) {
     if (getTypeAction(DataVT) == TargetLowering::TypePromoteInteger) {
       DataOp = GetPromotedInteger(DataOp);
       Mask = PromoteTargetBoolean(Mask, DataOp.getValueType());
+      TruncateStore = true;
     }
     else {
       assert(getTypeAction(DataVT) == TargetLowering::TypeWidenVector &&
@@ -1156,10 +1158,9 @@ SDValue DAGTypeLegalizer::PromoteIntOp_MSTORE(MaskedStoreSDNode *N, unsigned OpN
   }
   else
     Mask = PromoteTargetBoolean(N->getMask(), DataOp.getValueType());
-  SmallVector<SDValue, 4> NewOps(N->op_begin(), N->op_end());
-  NewOps[2] = Mask;
-  NewOps[3] = DataOp;
-  return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
+  return DAG.getMaskedStore(N->getChain(), dl, DataOp, N->getBasePtr(), Mask,
+                            N->getMemoryVT(), N->getMemOperand(),
+                            TruncateStore);
 }
 
 SDValue DAGTypeLegalizer::PromoteIntOp_MLOAD(MaskedLoadSDNode *N, unsigned OpNo){
index 1cd9f407bca10494c2a938023e70d81bd1fb0570..cef3fc990816ce6e16ce40dbb327e640eab29325 100644 (file)
@@ -659,6 +659,7 @@ private:
   SDValue WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N);
   SDValue WidenVecOp_EXTRACT_SUBVECTOR(SDNode *N);
   SDValue WidenVecOp_STORE(SDNode* N);
+  SDValue WidenVecOp_MSTORE(SDNode* N, unsigned OpNo);
   SDValue WidenVecOp_SETCC(SDNode* N);
 
   SDValue WidenVecOp_Convert(SDNode *N);
index 11e6b38f076223bc3bbdc874f7c57683f3980823..3a8c276e26181c2b913153eaefb0b886626242f5 100644 (file)
@@ -390,7 +390,8 @@ SDValue VectorLegalizer::Promote(SDValue Op) {
       if (Op.getOperand(j)
               .getValueType()
               .getVectorElementType()
-              .isFloatingPoint())
+              .isFloatingPoint() &&
+          NVT.isVector() && NVT.getVectorElementType().isFloatingPoint())
         Operands[j] = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Op.getOperand(j));
       else
         Operands[j] = DAG.getNode(ISD::BITCAST, dl, NVT, Op.getOperand(j));
@@ -399,8 +400,9 @@ SDValue VectorLegalizer::Promote(SDValue Op) {
   }
 
   Op = DAG.getNode(Op.getOpcode(), dl, NVT, Operands);
-  if (VT.isFloatingPoint() ||
-      (VT.isVector() && VT.getVectorElementType().isFloatingPoint()))
+  if ((VT.isFloatingPoint() && NVT.isFloatingPoint()) ||
+      (VT.isVector() && VT.getVectorElementType().isFloatingPoint() &&
+       NVT.isVector() && NVT.getVectorElementType().isFloatingPoint()))
     return DAG.getNode(ISD::FP_ROUND, dl, VT, Op, DAG.getIntPtrConstant(0));
   else
     return DAG.getNode(ISD::BITCAST, dl, VT, Op);
index 96b69eec335428c43549ae66e15cf0143dfd3122..63671f75bf309f877fdd28c29985c74a8bfc7791 100644 (file)
@@ -992,6 +992,7 @@ void DAGTypeLegalizer::SplitVecRes_MLOAD(MaskedLoadSDNode *MLD,
   SDValue Ptr = MLD->getBasePtr();
   SDValue Mask = MLD->getMask();
   unsigned Alignment = MLD->getOriginalAlignment();
+  ISD::LoadExtType ExtType = MLD->getExtensionType();
 
   // if Alignment is equal to the vector size,
   // take the half of it for the second part
@@ -1015,7 +1016,8 @@ void DAGTypeLegalizer::SplitVecRes_MLOAD(MaskedLoadSDNode *MLD,
                          MachineMemOperand::MOLoad,  LoMemVT.getStoreSize(),
                          Alignment, MLD->getAAInfo(), MLD->getRanges());
 
-  Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr, MaskLo, Src0Lo, MMO);
+  Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr, MaskLo, Src0Lo, LoMemVT, MMO,
+                         ExtType);
 
   unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
   Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
@@ -1026,7 +1028,8 @@ void DAGTypeLegalizer::SplitVecRes_MLOAD(MaskedLoadSDNode *MLD,
                          MachineMemOperand::MOLoad,  HiMemVT.getStoreSize(),
                          SecondHalfAlignment, MLD->getAAInfo(), MLD->getRanges());
 
-  Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr, MaskHi, Src0Hi, MMO);
+  Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr, MaskHi, Src0Hi, HiMemVT, MMO,
+                         ExtType);
 
 
   // Build a factor node to remember that this load is independent of the
@@ -1464,7 +1467,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_MSTORE(MaskedStoreSDNode *N,
   SDValue Ch  = N->getChain();
   SDValue Ptr = N->getBasePtr();
   SDValue Mask = N->getMask();
-  SDValue Data = N->getData();
+  SDValue Data = N->getValue();
   EVT MemoryVT = N->getMemoryVT();
   unsigned Alignment = N->getOriginalAlignment();
   SDLoc DL(N);
@@ -1489,7 +1492,8 @@ SDValue DAGTypeLegalizer::SplitVecOp_MSTORE(MaskedStoreSDNode *N,
                          MachineMemOperand::MOStore, LoMemVT.getStoreSize(),
                          Alignment, N->getAAInfo(), N->getRanges());
 
-  Lo = DAG.getMaskedStore(Ch, DL, DataLo, Ptr, MaskLo, MMO);
+  Lo = DAG.getMaskedStore(Ch, DL, DataLo, Ptr, MaskLo, LoMemVT, MMO,
+                          N->isTruncatingStore());
 
   unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
   Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr,
@@ -1500,7 +1504,8 @@ SDValue DAGTypeLegalizer::SplitVecOp_MSTORE(MaskedStoreSDNode *N,
                          MachineMemOperand::MOStore,  HiMemVT.getStoreSize(),
                          SecondHalfAlignment, N->getAAInfo(), N->getRanges());
 
-  Hi = DAG.getMaskedStore(Ch, DL, DataHi, Ptr, MaskHi, MMO);
+  Hi = DAG.getMaskedStore(Ch, DL, DataHi, Ptr, MaskHi, HiMemVT, MMO,
+                          N->isTruncatingStore());
 
 
   // Build a factor node to remember that this store is independent of the
@@ -2412,6 +2417,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_MLOAD(MaskedLoadSDNode *N) {
   SDValue Mask = N->getMask();
   EVT MaskVT = Mask.getValueType();
   SDValue Src0 = GetWidenedVector(N->getSrc0());
+  ISD::LoadExtType ExtType = N->getExtensionType();
   SDLoc dl(N);
 
   if (getTypeAction(MaskVT) == TargetLowering::TypeWidenVector)
@@ -2434,14 +2440,9 @@ SDValue DAGTypeLegalizer::WidenVecRes_MLOAD(MaskedLoadSDNode *N) {
     Mask = DAG.getNode(ISD::CONCAT_VECTORS, dl, BoolVT, Ops);
   }
 
-  // Rebuild memory operand because MemoryVT was changed
-  MachineMemOperand *MMO = DAG.getMachineFunction().
-    getMachineMemOperand(N->getPointerInfo(),
-                         MachineMemOperand::MOLoad,  WidenVT.getStoreSize(),
-                         N->getAlignment(), N->getAAInfo(), N->getRanges());
-
   SDValue Res = DAG.getMaskedLoad(WidenVT, dl, N->getChain(), N->getBasePtr(),
-                                  Mask, Src0, MMO);
+                                  Mask, Src0, N->getMemoryVT(),
+                                  N->getMemOperand(), ExtType);
   // Legalized the chain result - switch anything that used the old chain to
   // use the new one.
   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
@@ -2593,6 +2594,7 @@ bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned OpNo) {
   case ISD::EXTRACT_SUBVECTOR:  Res = WidenVecOp_EXTRACT_SUBVECTOR(N); break;
   case ISD::EXTRACT_VECTOR_ELT: Res = WidenVecOp_EXTRACT_VECTOR_ELT(N); break;
   case ISD::STORE:              Res = WidenVecOp_STORE(N); break;
+  case ISD::MSTORE:             Res = WidenVecOp_MSTORE(N, OpNo); break;
   case ISD::SETCC:              Res = WidenVecOp_SETCC(N); break;
 
   case ISD::ANY_EXTEND:
@@ -2791,6 +2793,42 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
     return DAG.getNode(ISD::TokenFactor, SDLoc(ST), MVT::Other, StChain);
 }
 
+SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(SDNode *N, unsigned OpNo) {
+  MaskedStoreSDNode *MST = cast<MaskedStoreSDNode>(N);
+  SDValue Mask = MST->getMask();
+  EVT MaskVT = Mask.getValueType();
+  SDValue StVal = MST->getValue();
+  // Widen the value
+  SDValue WideVal = GetWidenedVector(StVal);
+  SDLoc dl(N);
+
+  if (OpNo == 2 || getTypeAction(MaskVT) == TargetLowering::TypeWidenVector)
+    Mask = GetWidenedVector(Mask);
+  else {
+    // The mask should be widened as well
+    EVT BoolVT = getSetCCResultType(WideVal.getValueType());
+    // We can't use ModifyToType() because we should fill the mask with
+    // zeroes
+    unsigned WidenNumElts = BoolVT.getVectorNumElements();
+    unsigned MaskNumElts = MaskVT.getVectorNumElements();
+
+    unsigned NumConcat = WidenNumElts / MaskNumElts;
+    SmallVector<SDValue, 16> Ops(NumConcat);
+    SDValue ZeroVal = DAG.getConstant(0, MaskVT);
+    Ops[0] = Mask;
+    for (unsigned i = 1; i != NumConcat; ++i)
+      Ops[i] = ZeroVal;
+
+    Mask = DAG.getNode(ISD::CONCAT_VECTORS, dl, BoolVT, Ops);
+  }
+  assert(Mask.getValueType().getVectorNumElements() ==
+         WideVal.getValueType().getVectorNumElements() &&
+         "Mask and data vectors should have the same number of elements");
+  return DAG.getMaskedStore(MST->getChain(), dl, WideVal, MST->getBasePtr(),
+                            Mask, MST->getMemoryVT(), MST->getMemOperand(),
+                            false);
+}
+
 SDValue DAGTypeLegalizer::WidenVecOp_SETCC(SDNode *N) {
   SDValue InOp0 = GetWidenedVector(N->getOperand(0));
   SDValue InOp1 = GetWidenedVector(N->getOperand(1));
index c819516eca04b3986b51d57889daad905f6206ac..f75d5f4b2bd200a8ef1466af8193fc86c5a21a3e 100644 (file)
@@ -4924,15 +4924,15 @@ SelectionDAG::getIndexedStore(SDValue OrigStore, SDLoc dl, SDValue Base,
 
 SDValue
 SelectionDAG::getMaskedLoad(EVT VT, SDLoc dl, SDValue Chain,
-                            SDValue Ptr, SDValue Mask, SDValue Src0,
-                            MachineMemOperand *MMO) {
+                            SDValue Ptr, SDValue Mask, SDValue Src0, EVT MemVT,
+                            MachineMemOperand *MMO, ISD::LoadExtType ExtTy) {
 
   SDVTList VTs = getVTList(VT, MVT::Other);
   SDValue Ops[] = { Chain, Ptr, Mask, Src0 };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::MLOAD, VTs, Ops);
   ID.AddInteger(VT.getRawBits());
-  ID.AddInteger(encodeMemSDNodeFlags(ISD::NON_EXTLOAD, ISD::UNINDEXED,
+  ID.AddInteger(encodeMemSDNodeFlags(ExtTy, ISD::UNINDEXED,
                                      MMO->isVolatile(),
                                      MMO->isNonTemporal(),
                                      MMO->isInvariant()));
@@ -4944,14 +4944,15 @@ SelectionDAG::getMaskedLoad(EVT VT, SDLoc dl, SDValue Chain,
   }
   SDNode *N = new (NodeAllocator) MaskedLoadSDNode(dl.getIROrder(),
                                              dl.getDebugLoc(), Ops, 4, VTs,
-                                             VT, MMO);
+                                             ExtTy, MemVT, MMO);
   CSEMap.InsertNode(N, IP);
   InsertNode(N);
   return SDValue(N, 0);
 }
 
 SDValue SelectionDAG::getMaskedStore(SDValue Chain, SDLoc dl, SDValue Val,
-                               SDValue Ptr, SDValue Mask, MachineMemOperand *MMO) {
+                                     SDValue Ptr, SDValue Mask, EVT MemVT,
+                                     MachineMemOperand *MMO, bool isTrunc) {
   assert(Chain.getValueType() == MVT::Other &&
         "Invalid chain type");
   EVT VT = Val.getValueType();
@@ -4970,7 +4971,7 @@ SDValue SelectionDAG::getMaskedStore(SDValue Chain, SDLoc dl, SDValue Val,
   }
   SDNode *N = new (NodeAllocator) MaskedStoreSDNode(dl.getIROrder(),
                                                     dl.getDebugLoc(), Ops, 4,
-                                                    VTs, VT, MMO);
+                                                    VTs, isTrunc, MemVT, MMO);
   CSEMap.InsertNode(N, IP);
   InsertNode(N);
   return SDValue(N, 0);
index 86a63eea7c2a3d011e1334cb7bc7971a414c0ff6..d1929107fcb70b4dadd23eeb5669decf83db1932 100644 (file)
@@ -2071,14 +2071,10 @@ void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) {
   // Get the two live-in registers as SDValues. The physregs have already been
   // copied into virtual registers.
   SDValue Ops[2];
-  if (FuncInfo.ExceptionPointerVirtReg) {
-    Ops[0] = DAG.getZExtOrTrunc(
-        DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(),
-                           FuncInfo.ExceptionPointerVirtReg, TLI.getPointerTy()),
-        getCurSDLoc(), ValueVTs[0]);
-  } else {
-    Ops[0] = DAG.getConstant(0, TLI.getPointerTy());
-  }
+  Ops[0] = DAG.getZExtOrTrunc(
+      DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(),
+                         FuncInfo.ExceptionPointerVirtReg, TLI.getPointerTy()),
+      getCurSDLoc(), ValueVTs[0]);
   Ops[1] = DAG.getZExtOrTrunc(
       DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(),
                          FuncInfo.ExceptionSelectorVirtReg, TLI.getPointerTy()),
@@ -2090,27 +2086,6 @@ void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) {
   setValue(&LP, Res);
 }
 
-unsigned
-SelectionDAGBuilder::visitLandingPadClauseBB(GlobalValue *ClauseGV,
-                                             MachineBasicBlock *LPadBB) {
-  SDValue Chain = getControlRoot();
-
-  // Get the typeid that we will dispatch on later.
-  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
-  const TargetRegisterClass *RC = TLI.getRegClassFor(TLI.getPointerTy());
-  unsigned VReg = FuncInfo.MF->getRegInfo().createVirtualRegister(RC);
-  unsigned TypeID = DAG.getMachineFunction().getMMI().getTypeIDFor(ClauseGV);
-  SDValue Sel = DAG.getConstant(TypeID, TLI.getPointerTy());
-  Chain = DAG.getCopyToReg(Chain, getCurSDLoc(), VReg, Sel);
-
-  // Branch to the main landing pad block.
-  MachineBasicBlock *ClauseMBB = FuncInfo.MBB;
-  ClauseMBB->addSuccessor(LPadBB);
-  DAG.setRoot(DAG.getNode(ISD::BR, getCurSDLoc(), MVT::Other, Chain,
-                          DAG.getBasicBlock(LPadBB)));
-  return VReg;
-}
-
 /// handleSmallSwitchCaseRange - Emit a series of specific tests (suitable for
 /// small case ranges).
 bool SelectionDAGBuilder::handleSmallSwitchRange(CaseRec& CR,
@@ -3692,7 +3667,8 @@ void SelectionDAGBuilder::visitMaskedStore(const CallInst &I) {
     getMachineMemOperand(MachinePointerInfo(PtrOperand),
                           MachineMemOperand::MOStore,  VT.getStoreSize(),
                           Alignment, AAInfo);
-  SDValue StoreNode = DAG.getMaskedStore(getRoot(), sdl, Src0, Ptr, Mask, MMO);
+  SDValue StoreNode = DAG.getMaskedStore(getRoot(), sdl, Src0, Ptr, Mask, VT,
+                                         MMO, false);
   DAG.setRoot(StoreNode);
   setValue(&I, StoreNode);
 }
@@ -3731,7 +3707,8 @@ void SelectionDAGBuilder::visitMaskedLoad(const CallInst &I) {
                           MachineMemOperand::MOLoad,  VT.getStoreSize(),
                           Alignment, AAInfo, Ranges);
 
-  SDValue Load = DAG.getMaskedLoad(VT, sdl, InChain, Ptr, Mask, Src0, MMO);
+  SDValue Load = DAG.getMaskedLoad(VT, sdl, InChain, Ptr, Mask, Src0, VT, MMO,
+                                   ISD::NON_EXTLOAD);
   SDValue OutChain = Load.getValue(1);
   DAG.setRoot(OutChain);
   setValue(&I, Load);
index eba98b8086b77f0e96dc761eace8d3a62d5c2f29..9070091d77b8101255f03d92454d7cb7f4740183 100644 (file)
@@ -713,8 +713,6 @@ public:
   void visitJumpTable(JumpTable &JT);
   void visitJumpTableHeader(JumpTable &JT, JumpTableHeader &JTH,
                             MachineBasicBlock *SwitchBB);
-  unsigned visitLandingPadClauseBB(GlobalValue *ClauseGV,
-                                   MachineBasicBlock *LPadMBB);
 
 private:
   // These all get lowered before this pass.
index 4f031d3ff7e739c0c1f36ce0ba34d35b91ed68e4..ef5452554f72478e3f34c91046b1f5cd5c09ce51 100644 (file)
@@ -19,7 +19,6 @@
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/BranchProbabilityInfo.h"
 #include "llvm/Analysis/CFG.h"
-#include "llvm/CodeGen/Analysis.h"
 #include "llvm/CodeGen/FastISel.h"
 #include "llvm/CodeGen/FunctionLoweringInfo.h"
 #include "llvm/CodeGen/GCMetadata.h"
@@ -41,7 +40,6 @@
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
-#include "llvm/MC/MCAsmInfo.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -909,8 +907,6 @@ void SelectionDAGISel::DoInstructionSelection() {
 void SelectionDAGISel::PrepareEHLandingPad() {
   MachineBasicBlock *MBB = FuncInfo->MBB;
 
-  const TargetRegisterClass *PtrRC = TLI->getRegClassFor(TLI->getPointerTy());
-
   // Add a label to mark the beginning of the landing pad.  Deletion of the
   // landing pad can thus be detected via the MachineModuleInfo.
   MCSymbol *Label = MF->getMMI().addLandingPad(MBB);
@@ -922,66 +918,8 @@ void SelectionDAGISel::PrepareEHLandingPad() {
   BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II)
     .addSym(Label);
 
-  if (TM.getMCAsmInfo()->getExceptionHandlingType() ==
-      ExceptionHandling::MSVC) {
-    // Make virtual registers and a series of labels that fill in values for the
-    // clauses.
-    auto &RI = MF->getRegInfo();
-    FuncInfo->ExceptionSelectorVirtReg = RI.createVirtualRegister(PtrRC);
-
-    // Get all invoke BBs that will unwind into the clause BBs.
-    SmallVector<MachineBasicBlock *, 4> InvokeBBs(MBB->pred_begin(),
-                                                  MBB->pred_end());
-
-    // Emit separate machine basic blocks with separate labels for each clause
-    // before the main landing pad block.
-    const BasicBlock *LLVMBB = MBB->getBasicBlock();
-    const LandingPadInst *LPadInst = LLVMBB->getLandingPadInst();
-    MachineInstrBuilder SelectorPHI = BuildMI(
-        *MBB, MBB->begin(), SDB->getCurDebugLoc(), TII->get(TargetOpcode::PHI),
-        FuncInfo->ExceptionSelectorVirtReg);
-    for (unsigned I = 0, E = LPadInst->getNumClauses(); I != E; ++I) {
-      MachineBasicBlock *ClauseBB = MF->CreateMachineBasicBlock(LLVMBB);
-      MF->insert(MBB, ClauseBB);
-
-      // Add the edge from the invoke to the clause.
-      for (MachineBasicBlock *InvokeBB : InvokeBBs)
-        InvokeBB->addSuccessor(ClauseBB);
-
-      // Mark the clause as a landing pad or MI passes will delete it.
-      ClauseBB->setIsLandingPad();
-
-      GlobalValue *ClauseGV = ExtractTypeInfo(LPadInst->getClause(I));
-
-      // Start the BB with a label.
-      MCSymbol *ClauseLabel = MF->getMMI().addClauseForLandingPad(MBB);
-      BuildMI(*ClauseBB, ClauseBB->begin(), SDB->getCurDebugLoc(), II)
-          .addSym(ClauseLabel);
-
-      // Construct a simple BB that defines a register with the typeid constant.
-      FuncInfo->MBB = ClauseBB;
-      FuncInfo->InsertPt = ClauseBB->end();
-      unsigned VReg = SDB->visitLandingPadClauseBB(ClauseGV, MBB);
-      CurDAG->setRoot(SDB->getRoot());
-      SDB->clear();
-      CodeGenAndEmitDAG();
-
-      // Add the typeid virtual register to the phi in the main landing pad.
-      SelectorPHI.addReg(VReg).addMBB(ClauseBB);
-    }
-
-    // Remove the edge from the invoke to the lpad.
-    for (MachineBasicBlock *InvokeBB : InvokeBBs)
-      InvokeBB->removeSuccessor(MBB);
-
-    // Restore FuncInfo back to its previous state and select the main landing
-    // pad block.
-    FuncInfo->MBB = MBB;
-    FuncInfo->InsertPt = MBB->end();
-    return;
-  }
-
   // Mark exception register as live in.
+  const TargetRegisterClass *PtrRC = TLI->getRegClassFor(TLI->getPointerTy());
   if (unsigned Reg = TLI->getExceptionPointerRegister())
     FuncInfo->ExceptionPointerVirtReg = MBB->addLiveIn(Reg, PtrRC);
 
index dc2fe9bf97f3ec420fd35935d9b037380b1a6560..83c91eda042fb1ef4a8b6c6d4d3d826bb068ee05 100644 (file)
@@ -4,7 +4,6 @@ add_llvm_library(LLVMExecutionEngine
   ExecutionEngine.cpp
   ExecutionEngineBindings.cpp
   GDBRegistrationListener.cpp
-  RTDyldMemoryManager.cpp
   TargetSelect.cpp
   )
 
index 7d041cef843e044f6756de876830236468d6fb55..53d62649c5e9e205ae24a3d5d40f66315391569f 100644 (file)
@@ -22,4 +22,4 @@ subdirectories = Interpreter MCJIT RuntimeDyld IntelJITEvents OProfileJIT
 type = Library
 name = ExecutionEngine
 parent = Libraries
-required_libraries = Core MC Object Support
+required_libraries = Core MC Object Support RuntimeDyld
diff --git a/src/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp b/src/llvm/lib/ExecutionEngine/RTDyldMemoryManager.cpp
deleted file mode 100644 (file)
index 2a5e4f8..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-//===-- RTDyldMemoryManager.cpp - Memory manager for MC-JIT -----*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Implementation of the runtime dynamic memory manager base class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Config/config.h"
-#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DynamicLibrary.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <cstdlib>
-
-#ifdef __linux__
-  // These includes used by RTDyldMemoryManager::getPointerToNamedFunction()
-  // for Glibc trickery. See comments in this function for more information.
-  #ifdef HAVE_SYS_STAT_H
-    #include <sys/stat.h>
-  #endif
-  #include <fcntl.h>
-  #include <unistd.h>
-#endif
-
-namespace llvm {
-
-RTDyldMemoryManager::~RTDyldMemoryManager() {}
-
-// Determine whether we can register EH tables.
-#if (defined(__GNUC__) && !defined(__ARM_EABI__) && !defined(__ia64__) && \
-     !defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__))
-#define HAVE_EHTABLE_SUPPORT 1
-#else
-#define HAVE_EHTABLE_SUPPORT 0
-#endif
-
-#if HAVE_EHTABLE_SUPPORT
-extern "C" void __register_frame(void*);
-extern "C" void __deregister_frame(void*);
-#else
-// The building compiler does not have __(de)register_frame but
-// it may be found at runtime in a dynamically-loaded library.
-// For example, this happens when building LLVM with Visual C++
-// but using the MingW runtime.
-void __register_frame(void *p) {
-  static bool Searched = false;
-  static void *rf = 0;
-
-  if (!Searched) {
-    Searched = true;
-    rf = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(
-                                                      "__register_frame");
-  }
-  if (rf)
-    ((void (*)(void *))rf)(p);
-}
-
-void __deregister_frame(void *p) {
-  static bool Searched = false;
-  static void *df = 0;
-
-  if (!Searched) {
-    Searched = true;
-    df = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(
-                                                      "__deregister_frame");
-  }
-  if (df)
-    ((void (*)(void *))df)(p);
-}
-#endif
-
-#ifdef __APPLE__
-
-static const char *processFDE(const char *Entry, bool isDeregister) {
-  const char *P = Entry;
-  uint32_t Length = *((const uint32_t *)P);
-  P += 4;
-  uint32_t Offset = *((const uint32_t *)P);
-  if (Offset != 0) {
-    if (isDeregister)
-      __deregister_frame(const_cast<char *>(Entry));
-    else
-      __register_frame(const_cast<char *>(Entry));
-  }
-  return P + Length;
-}
-
-// This implementation handles frame registration for local targets.
-// Memory managers for remote targets should re-implement this function
-// and use the LoadAddr parameter.
-void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr,
-                                           uint64_t LoadAddr,
-                                           size_t Size) {
-  // On OS X OS X __register_frame takes a single FDE as an argument.
-  // See http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-April/061768.html
-  const char *P = (const char *)Addr;
-  const char *End = P + Size;
-  do  {
-    P = processFDE(P, false);
-  } while(P != End);
-}
-
-void RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr,
-                                           uint64_t LoadAddr,
-                                           size_t Size) {
-  const char *P = (const char *)Addr;
-  const char *End = P + Size;
-  do  {
-    P = processFDE(P, true);
-  } while(P != End);
-}
-
-#else
-
-void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr,
-                                           uint64_t LoadAddr,
-                                           size_t Size) {
-  // On Linux __register_frame takes a single argument: 
-  // a pointer to the start of the .eh_frame section.
-
-  // How can it find the end? Because crtendS.o is linked 
-  // in and it has an .eh_frame section with four zero chars.
-  __register_frame(Addr);
-}
-
-void RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr,
-                                           uint64_t LoadAddr,
-                                           size_t Size) {
-  __deregister_frame(Addr);
-}
-
-#endif
-
-static int jit_noop() {
-  return 0;
-}
-
-// ARM math functions are statically linked on Android from libgcc.a, but not
-// available at runtime for dynamic linking. On Linux these are usually placed
-// in libgcc_s.so so can be found by normal dynamic lookup.
-#if defined(__BIONIC__) && defined(__arm__)
-// List of functions which are statically linked on Android and can be generated
-// by LLVM. This is done as a nested macro which is used once to declare the
-// imported functions with ARM_MATH_DECL and once to compare them to the
-// user-requested symbol in getSymbolAddress with ARM_MATH_CHECK. The test
-// assumes that all functions start with __aeabi_ and getSymbolAddress must be
-// modified if that changes.
-#define ARM_MATH_IMPORTS(PP) \
-  PP(__aeabi_d2f) \
-  PP(__aeabi_d2iz) \
-  PP(__aeabi_d2lz) \
-  PP(__aeabi_d2uiz) \
-  PP(__aeabi_d2ulz) \
-  PP(__aeabi_dadd) \
-  PP(__aeabi_dcmpeq) \
-  PP(__aeabi_dcmpge) \
-  PP(__aeabi_dcmpgt) \
-  PP(__aeabi_dcmple) \
-  PP(__aeabi_dcmplt) \
-  PP(__aeabi_dcmpun) \
-  PP(__aeabi_ddiv) \
-  PP(__aeabi_dmul) \
-  PP(__aeabi_dsub) \
-  PP(__aeabi_f2d) \
-  PP(__aeabi_f2iz) \
-  PP(__aeabi_f2lz) \
-  PP(__aeabi_f2uiz) \
-  PP(__aeabi_f2ulz) \
-  PP(__aeabi_fadd) \
-  PP(__aeabi_fcmpeq) \
-  PP(__aeabi_fcmpge) \
-  PP(__aeabi_fcmpgt) \
-  PP(__aeabi_fcmple) \
-  PP(__aeabi_fcmplt) \
-  PP(__aeabi_fcmpun) \
-  PP(__aeabi_fdiv) \
-  PP(__aeabi_fmul) \
-  PP(__aeabi_fsub) \
-  PP(__aeabi_i2d) \
-  PP(__aeabi_i2f) \
-  PP(__aeabi_idiv) \
-  PP(__aeabi_idivmod) \
-  PP(__aeabi_l2d) \
-  PP(__aeabi_l2f) \
-  PP(__aeabi_lasr) \
-  PP(__aeabi_ldivmod) \
-  PP(__aeabi_llsl) \
-  PP(__aeabi_llsr) \
-  PP(__aeabi_lmul) \
-  PP(__aeabi_ui2d) \
-  PP(__aeabi_ui2f) \
-  PP(__aeabi_uidiv) \
-  PP(__aeabi_uidivmod) \
-  PP(__aeabi_ul2d) \
-  PP(__aeabi_ul2f) \
-  PP(__aeabi_uldivmod)
-
-// Declare statically linked math functions on ARM. The function declarations
-// here do not have the correct prototypes for each function in
-// ARM_MATH_IMPORTS, but it doesn't matter because only the symbol addresses are
-// needed. In particular the __aeabi_*divmod functions do not have calling
-// conventions which match any C prototype.
-#define ARM_MATH_DECL(name) extern "C" void name();
-ARM_MATH_IMPORTS(ARM_MATH_DECL)
-#undef ARM_MATH_DECL
-#endif
-
-#if defined(__linux__) && defined(__GLIBC__) && \
-      (defined(__i386__) || defined(__x86_64__))
-extern "C" LLVM_ATTRIBUTE_WEAK void __morestack();
-#endif
-
-uint64_t
-RTDyldMemoryManager::getSymbolAddressInProcess(const std::string &Name) {
-  // This implementation assumes that the host program is the target.
-  // Clients generating code for a remote target should implement their own
-  // memory manager.
-#if defined(__linux__) && defined(__GLIBC__)
-  //===--------------------------------------------------------------------===//
-  // Function stubs that are invoked instead of certain library calls
-  //
-  // Force the following functions to be linked in to anything that uses the
-  // JIT. This is a hack designed to work around the all-too-clever Glibc
-  // strategy of making these functions work differently when inlined vs. when
-  // not inlined, and hiding their real definitions in a separate archive file
-  // that the dynamic linker can't see. For more info, search for
-  // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274.
-  if (Name == "stat") return (uint64_t)&stat;
-  if (Name == "fstat") return (uint64_t)&fstat;
-  if (Name == "lstat") return (uint64_t)&lstat;
-  if (Name == "stat64") return (uint64_t)&stat64;
-  if (Name == "fstat64") return (uint64_t)&fstat64;
-  if (Name == "lstat64") return (uint64_t)&lstat64;
-  if (Name == "atexit") return (uint64_t)&atexit;
-  if (Name == "mknod") return (uint64_t)&mknod;
-
-#if defined(__i386__) || defined(__x86_64__)
-  // __morestack lives in libgcc, a static library.
-  if (&__morestack && Name == "__morestack")
-    return (uint64_t)&__morestack;
-#endif
-#endif // __linux__ && __GLIBC__
-  
-  // See ARM_MATH_IMPORTS definition for explanation
-#if defined(__BIONIC__) && defined(__arm__)
-  if (Name.compare(0, 8, "__aeabi_") == 0) {
-    // Check if the user has requested any of the functions listed in
-    // ARM_MATH_IMPORTS, and if so redirect to the statically linked symbol.
-#define ARM_MATH_CHECK(fn) if (Name == #fn) return (uint64_t)&fn;
-    ARM_MATH_IMPORTS(ARM_MATH_CHECK)
-#undef ARM_MATH_CHECK
-  }
-#endif
-
-  // We should not invoke parent's ctors/dtors from generated main()!
-  // On Mingw and Cygwin, the symbol __main is resolved to
-  // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors
-  // (and register wrong callee's dtors with atexit(3)).
-  // We expect ExecutionEngine::runStaticConstructorsDestructors()
-  // is called before ExecutionEngine::runFunctionAsMain() is called.
-  if (Name == "__main") return (uint64_t)&jit_noop;
-
-  // Try to demangle Name before looking it up in the process, otherwise symbol
-  // '_<Name>' (if present) will shadow '<Name>', and there will be no way to
-  // refer to the latter.
-
-  const char *NameStr = Name.c_str();
-
-  if (NameStr[0] == '_')
-    if (void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr + 1))
-      return (uint64_t)Ptr;
-
-  // If we Name did not require demangling, or we failed to find the demangled
-  // name, try again without demangling.
-  return (uint64_t)sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
-}
-
-void *RTDyldMemoryManager::getPointerToNamedFunction(const std::string &Name,
-                                                     bool AbortOnFailure) {
-  uint64_t Addr = getSymbolAddress(Name);
-
-  if (!Addr && AbortOnFailure)
-    report_fatal_error("Program used external function '" + Name +
-                       "' which could not be resolved!");
-  return (void*)Addr;
-}
-
-} // namespace llvm
index 5790eee9c8229e3d163aaac305a0450e67d64f5d..12bbcc61db7eaeadfa063c4e19dc8c1ae7b58aae 100644 (file)
@@ -1,4 +1,5 @@
 add_llvm_library(LLVMRuntimeDyld
+  RTDyldMemoryManager.cpp
   RuntimeDyld.cpp
   RuntimeDyldChecker.cpp
   RuntimeDyldELF.cpp
diff --git a/src/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp b/src/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
new file mode 100644 (file)
index 0000000..2a5e4f8
--- /dev/null
@@ -0,0 +1,294 @@
+//===-- RTDyldMemoryManager.cpp - Memory manager for MC-JIT -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of the runtime dynamic memory manager base class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/config.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cstdlib>
+
+#ifdef __linux__
+  // These includes used by RTDyldMemoryManager::getPointerToNamedFunction()
+  // for Glibc trickery. See comments in this function for more information.
+  #ifdef HAVE_SYS_STAT_H
+    #include <sys/stat.h>
+  #endif
+  #include <fcntl.h>
+  #include <unistd.h>
+#endif
+
+namespace llvm {
+
+RTDyldMemoryManager::~RTDyldMemoryManager() {}
+
+// Determine whether we can register EH tables.
+#if (defined(__GNUC__) && !defined(__ARM_EABI__) && !defined(__ia64__) && \
+     !defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__))
+#define HAVE_EHTABLE_SUPPORT 1
+#else
+#define HAVE_EHTABLE_SUPPORT 0
+#endif
+
+#if HAVE_EHTABLE_SUPPORT
+extern "C" void __register_frame(void*);
+extern "C" void __deregister_frame(void*);
+#else
+// The building compiler does not have __(de)register_frame but
+// it may be found at runtime in a dynamically-loaded library.
+// For example, this happens when building LLVM with Visual C++
+// but using the MingW runtime.
+void __register_frame(void *p) {
+  static bool Searched = false;
+  static void *rf = 0;
+
+  if (!Searched) {
+    Searched = true;
+    rf = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(
+                                                      "__register_frame");
+  }
+  if (rf)
+    ((void (*)(void *))rf)(p);
+}
+
+void __deregister_frame(void *p) {
+  static bool Searched = false;
+  static void *df = 0;
+
+  if (!Searched) {
+    Searched = true;
+    df = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(
+                                                      "__deregister_frame");
+  }
+  if (df)
+    ((void (*)(void *))df)(p);
+}
+#endif
+
+#ifdef __APPLE__
+
+static const char *processFDE(const char *Entry, bool isDeregister) {
+  const char *P = Entry;
+  uint32_t Length = *((const uint32_t *)P);
+  P += 4;
+  uint32_t Offset = *((const uint32_t *)P);
+  if (Offset != 0) {
+    if (isDeregister)
+      __deregister_frame(const_cast<char *>(Entry));
+    else
+      __register_frame(const_cast<char *>(Entry));
+  }
+  return P + Length;
+}
+
+// This implementation handles frame registration for local targets.
+// Memory managers for remote targets should re-implement this function
+// and use the LoadAddr parameter.
+void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr,
+                                           uint64_t LoadAddr,
+                                           size_t Size) {
+  // On OS X OS X __register_frame takes a single FDE as an argument.
+  // See http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-April/061768.html
+  const char *P = (const char *)Addr;
+  const char *End = P + Size;
+  do  {
+    P = processFDE(P, false);
+  } while(P != End);
+}
+
+void RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr,
+                                           uint64_t LoadAddr,
+                                           size_t Size) {
+  const char *P = (const char *)Addr;
+  const char *End = P + Size;
+  do  {
+    P = processFDE(P, true);
+  } while(P != End);
+}
+
+#else
+
+void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr,
+                                           uint64_t LoadAddr,
+                                           size_t Size) {
+  // On Linux __register_frame takes a single argument: 
+  // a pointer to the start of the .eh_frame section.
+
+  // How can it find the end? Because crtendS.o is linked 
+  // in and it has an .eh_frame section with four zero chars.
+  __register_frame(Addr);
+}
+
+void RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr,
+                                           uint64_t LoadAddr,
+                                           size_t Size) {
+  __deregister_frame(Addr);
+}
+
+#endif
+
+static int jit_noop() {
+  return 0;
+}
+
+// ARM math functions are statically linked on Android from libgcc.a, but not
+// available at runtime for dynamic linking. On Linux these are usually placed
+// in libgcc_s.so so can be found by normal dynamic lookup.
+#if defined(__BIONIC__) && defined(__arm__)
+// List of functions which are statically linked on Android and can be generated
+// by LLVM. This is done as a nested macro which is used once to declare the
+// imported functions with ARM_MATH_DECL and once to compare them to the
+// user-requested symbol in getSymbolAddress with ARM_MATH_CHECK. The test
+// assumes that all functions start with __aeabi_ and getSymbolAddress must be
+// modified if that changes.
+#define ARM_MATH_IMPORTS(PP) \
+  PP(__aeabi_d2f) \
+  PP(__aeabi_d2iz) \
+  PP(__aeabi_d2lz) \
+  PP(__aeabi_d2uiz) \
+  PP(__aeabi_d2ulz) \
+  PP(__aeabi_dadd) \
+  PP(__aeabi_dcmpeq) \
+  PP(__aeabi_dcmpge) \
+  PP(__aeabi_dcmpgt) \
+  PP(__aeabi_dcmple) \
+  PP(__aeabi_dcmplt) \
+  PP(__aeabi_dcmpun) \
+  PP(__aeabi_ddiv) \
+  PP(__aeabi_dmul) \
+  PP(__aeabi_dsub) \
+  PP(__aeabi_f2d) \
+  PP(__aeabi_f2iz) \
+  PP(__aeabi_f2lz) \
+  PP(__aeabi_f2uiz) \
+  PP(__aeabi_f2ulz) \
+  PP(__aeabi_fadd) \
+  PP(__aeabi_fcmpeq) \
+  PP(__aeabi_fcmpge) \
+  PP(__aeabi_fcmpgt) \
+  PP(__aeabi_fcmple) \
+  PP(__aeabi_fcmplt) \
+  PP(__aeabi_fcmpun) \
+  PP(__aeabi_fdiv) \
+  PP(__aeabi_fmul) \
+  PP(__aeabi_fsub) \
+  PP(__aeabi_i2d) \
+  PP(__aeabi_i2f) \
+  PP(__aeabi_idiv) \
+  PP(__aeabi_idivmod) \
+  PP(__aeabi_l2d) \
+  PP(__aeabi_l2f) \
+  PP(__aeabi_lasr) \
+  PP(__aeabi_ldivmod) \
+  PP(__aeabi_llsl) \
+  PP(__aeabi_llsr) \
+  PP(__aeabi_lmul) \
+  PP(__aeabi_ui2d) \
+  PP(__aeabi_ui2f) \
+  PP(__aeabi_uidiv) \
+  PP(__aeabi_uidivmod) \
+  PP(__aeabi_ul2d) \
+  PP(__aeabi_ul2f) \
+  PP(__aeabi_uldivmod)
+
+// Declare statically linked math functions on ARM. The function declarations
+// here do not have the correct prototypes for each function in
+// ARM_MATH_IMPORTS, but it doesn't matter because only the symbol addresses are
+// needed. In particular the __aeabi_*divmod functions do not have calling
+// conventions which match any C prototype.
+#define ARM_MATH_DECL(name) extern "C" void name();
+ARM_MATH_IMPORTS(ARM_MATH_DECL)
+#undef ARM_MATH_DECL
+#endif
+
+#if defined(__linux__) && defined(__GLIBC__) && \
+      (defined(__i386__) || defined(__x86_64__))
+extern "C" LLVM_ATTRIBUTE_WEAK void __morestack();
+#endif
+
+uint64_t
+RTDyldMemoryManager::getSymbolAddressInProcess(const std::string &Name) {
+  // This implementation assumes that the host program is the target.
+  // Clients generating code for a remote target should implement their own
+  // memory manager.
+#if defined(__linux__) && defined(__GLIBC__)
+  //===--------------------------------------------------------------------===//
+  // Function stubs that are invoked instead of certain library calls
+  //
+  // Force the following functions to be linked in to anything that uses the
+  // JIT. This is a hack designed to work around the all-too-clever Glibc
+  // strategy of making these functions work differently when inlined vs. when
+  // not inlined, and hiding their real definitions in a separate archive file
+  // that the dynamic linker can't see. For more info, search for
+  // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274.
+  if (Name == "stat") return (uint64_t)&stat;
+  if (Name == "fstat") return (uint64_t)&fstat;
+  if (Name == "lstat") return (uint64_t)&lstat;
+  if (Name == "stat64") return (uint64_t)&stat64;
+  if (Name == "fstat64") return (uint64_t)&fstat64;
+  if (Name == "lstat64") return (uint64_t)&lstat64;
+  if (Name == "atexit") return (uint64_t)&atexit;
+  if (Name == "mknod") return (uint64_t)&mknod;
+
+#if defined(__i386__) || defined(__x86_64__)
+  // __morestack lives in libgcc, a static library.
+  if (&__morestack && Name == "__morestack")
+    return (uint64_t)&__morestack;
+#endif
+#endif // __linux__ && __GLIBC__
+  
+  // See ARM_MATH_IMPORTS definition for explanation
+#if defined(__BIONIC__) && defined(__arm__)
+  if (Name.compare(0, 8, "__aeabi_") == 0) {
+    // Check if the user has requested any of the functions listed in
+    // ARM_MATH_IMPORTS, and if so redirect to the statically linked symbol.
+#define ARM_MATH_CHECK(fn) if (Name == #fn) return (uint64_t)&fn;
+    ARM_MATH_IMPORTS(ARM_MATH_CHECK)
+#undef ARM_MATH_CHECK
+  }
+#endif
+
+  // We should not invoke parent's ctors/dtors from generated main()!
+  // On Mingw and Cygwin, the symbol __main is resolved to
+  // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors
+  // (and register wrong callee's dtors with atexit(3)).
+  // We expect ExecutionEngine::runStaticConstructorsDestructors()
+  // is called before ExecutionEngine::runFunctionAsMain() is called.
+  if (Name == "__main") return (uint64_t)&jit_noop;
+
+  // Try to demangle Name before looking it up in the process, otherwise symbol
+  // '_<Name>' (if present) will shadow '<Name>', and there will be no way to
+  // refer to the latter.
+
+  const char *NameStr = Name.c_str();
+
+  if (NameStr[0] == '_')
+    if (void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr + 1))
+      return (uint64_t)Ptr;
+
+  // If we Name did not require demangling, or we failed to find the demangled
+  // name, try again without demangling.
+  return (uint64_t)sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
+}
+
+void *RTDyldMemoryManager::getPointerToNamedFunction(const std::string &Name,
+                                                     bool AbortOnFailure) {
+  uint64_t Addr = getSymbolAddress(Name);
+
+  if (!Addr && AbortOnFailure)
+    report_fatal_error("Program used external function '" + Name +
+                       "' which could not be resolved!");
+  return (void*)Addr;
+}
+
+} // namespace llvm
index 1d2602aef137f4e80dcd581f976b24db97370083..44052b22457c5dfa9887288d93b654232d2f24d7 100644 (file)
@@ -257,11 +257,11 @@ Constant *Constant::getAggregateElement(unsigned Elt) const {
   if (const ConstantVector *CV = dyn_cast<ConstantVector>(this))
     return Elt < CV->getNumOperands() ? CV->getOperand(Elt) : nullptr;
 
-  if (const ConstantAggregateZero *CAZ =dyn_cast<ConstantAggregateZero>(this))
-    return CAZ->getElementValue(Elt);
+  if (const ConstantAggregateZero *CAZ = dyn_cast<ConstantAggregateZero>(this))
+    return Elt < CAZ->getNumElements() ? CAZ->getElementValue(Elt) : nullptr;
 
   if (const UndefValue *UV = dyn_cast<UndefValue>(this))
-    return UV->getElementValue(Elt);
+    return Elt < UV->getNumElements() ? UV->getElementValue(Elt) : nullptr;
 
   if (const ConstantDataSequential *CDS =dyn_cast<ConstantDataSequential>(this))
     return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt)
@@ -764,6 +764,14 @@ Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const {
   return getStructElement(Idx);
 }
 
+unsigned ConstantAggregateZero::getNumElements() const {
+  const Type *Ty = getType();
+  if (const auto *AT = dyn_cast<ArrayType>(Ty))
+    return AT->getNumElements();
+  if (const auto *VT = dyn_cast<VectorType>(Ty))
+    return VT->getNumElements();
+  return Ty->getStructNumElements();
+}
 
 //===----------------------------------------------------------------------===//
 //                         UndefValue Implementation
@@ -797,7 +805,14 @@ UndefValue *UndefValue::getElementValue(unsigned Idx) const {
   return getStructElement(Idx);
 }
 
-
+unsigned UndefValue::getNumElements() const {
+  const Type *Ty = getType();
+  if (const auto *AT = dyn_cast<ArrayType>(Ty))
+    return AT->getNumElements();
+  if (const auto *VT = dyn_cast<VectorType>(Ty))
+    return VT->getNumElements();
+  return Ty->getStructNumElements();
+}
 
 //===----------------------------------------------------------------------===//
 //                            ConstantXXX Classes
index 290dbe29c707c903c0bdfe30e1e6dd94edd6169d..71b43942e882719d952ae753e6e331df9bacbe6f 100644 (file)
@@ -525,12 +525,15 @@ bool DISubprogram::Verify() const {
         while ((IA = DL.getInlinedAt()))
           DL = DebugLoc::getFromDILocation(IA);
         DL.getScopeAndInlinedAt(Scope, IA);
+        if (!Scope)
+          return false;
         assert(!IA);
         while (!DIDescriptor(Scope).isSubprogram()) {
           DILexicalBlockFile D(Scope);
           Scope = D.isLexicalBlockFile()
                       ? D.getScope()
                       : DebugLoc::getFromDILexicalBlock(Scope).getScope();
+          assert(Scope && "lexical block file has no scope");
         }
         if (!DISubprogram(Scope).describes(F))
           return false;
index 889705e95fc25aea1bb4411810565cc495cd476d..65060dc39d277c583ae9db4b866bb5227a6c37a2 100644 (file)
@@ -708,9 +708,10 @@ VectorType::VectorType(Type *ElType, unsigned NumEl)
 VectorType *VectorType::get(Type *elementType, unsigned NumElements) {
   Type *ElementType = const_cast<Type*>(elementType);
   assert(NumElements > 0 && "#Elements of a VectorType must be greater than 0");
-  assert(isValidElementType(ElementType) &&
-         "Elements of a VectorType must be a primitive type");
-  
+  assert(isValidElementType(ElementType) && "Element type of a VectorType must "
+                                            "be an integer, floating point, or "
+                                            "pointer type.");
+
   LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
   VectorType *&Entry = ElementType->getContext().pImpl
     ->VectorTypes[std::make_pair(ElementType, NumElements)];
index c17f99b9bd7b4743b5d13f792503f71793ab650b..ec0e0f7256a477c239e7146ddda04384c100cfec 100644 (file)
@@ -710,17 +710,22 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
     CrossSection = &Symbol.getSection() != &B->getSection();
 
     // Offset of the symbol in the section
-    int64_t a = Layout.getSymbolOffset(&B_SD);
+    int64_t OffsetOfB = Layout.getSymbolOffset(&B_SD);
 
-    // Offset of the relocation in the section
-    int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
-
-    FixedValue = b - a;
     // In the case where we have SymbA and SymB, we just need to store the delta
     // between the two symbols.  Update FixedValue to account for the delta, and
     // skip recording the relocation.
-    if (!CrossSection)
+    if (!CrossSection) {
+      int64_t OffsetOfA = Layout.getSymbolOffset(&A_SD);
+      FixedValue = (OffsetOfA - OffsetOfB) + Target.getConstant();
       return;
+    }
+
+    // Offset of the relocation in the section
+    int64_t OffsetOfRelocation =
+        Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
+
+    FixedValue = OffsetOfRelocation - OffsetOfB;
   } else {
     FixedValue = Target.getConstant();
   }
index c0abdbd9279b8e2f47b5e10149d5392c347978f7..4df8092e9bd8e3bfc7036757818fdb767bd3ec5b 100644 (file)
@@ -198,6 +198,8 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =
     "iprintf",
     "isascii",
     "isdigit",
+    "je_mallocx",
+    "je_sdallocx",
     "labs",
     "lchown",
     "ldexp",
index a1fd34ea80000d01dd0e17c249e5eb2f2305bf98..177299b8afc4dadcda0d62976626dc89f4092405 100644 (file)
@@ -1679,7 +1679,9 @@ void X86TargetLowering::resetOperationActions() {
   setTargetDAGCombine(ISD::FMA);
   setTargetDAGCombine(ISD::SUB);
   setTargetDAGCombine(ISD::LOAD);
+  setTargetDAGCombine(ISD::MLOAD);
   setTargetDAGCombine(ISD::STORE);
+  setTargetDAGCombine(ISD::MSTORE);
   setTargetDAGCombine(ISD::ZERO_EXTEND);
   setTargetDAGCombine(ISD::ANY_EXTEND);
   setTargetDAGCombine(ISD::SIGN_EXTEND);
@@ -5473,6 +5475,8 @@ static bool getTargetShuffleMask(SDNode *N, MVT VT,
 
     if (auto *C = dyn_cast<Constant>(MaskCP->getConstVal())) {
       DecodePSHUFBMask(C, Mask);
+      if (Mask.empty())
+        return false;
       break;
     }
 
@@ -24736,6 +24740,166 @@ static SDValue PerformLOADCombine(SDNode *N, SelectionDAG &DAG,
   return SDValue();
 }
 
+/// PerformMLOADCombine - Resolve extending loads
+static SDValue PerformMLOADCombine(SDNode *N, SelectionDAG &DAG,
+                                   TargetLowering::DAGCombinerInfo &DCI,
+                                   const X86Subtarget *Subtarget) {
+  MaskedLoadSDNode *Mld = cast<MaskedLoadSDNode>(N);
+  if (Mld->getExtensionType() != ISD::SEXTLOAD)
+    return SDValue();
+
+  EVT VT = Mld->getValueType(0);
+  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+  unsigned NumElems = VT.getVectorNumElements();
+  EVT LdVT = Mld->getMemoryVT();
+  SDLoc dl(Mld);
+
+  assert(LdVT != VT && "Cannot extend to the same type");
+  unsigned ToSz = VT.getVectorElementType().getSizeInBits();
+  unsigned FromSz = LdVT.getVectorElementType().getSizeInBits();
+  // From, To sizes and ElemCount must be pow of two
+  assert (isPowerOf2_32(NumElems * FromSz * ToSz) &&
+    "Unexpected size for extending masked load");
+
+  unsigned SizeRatio  = ToSz / FromSz;
+  assert(SizeRatio * NumElems * FromSz == VT.getSizeInBits());
+
+  // Create a type on which we perform the shuffle
+  EVT WideVecVT = EVT::getVectorVT(*DAG.getContext(),
+          LdVT.getScalarType(), NumElems*SizeRatio);
+  assert(WideVecVT.getSizeInBits() == VT.getSizeInBits());
+
+  // Convert Src0 value
+  SDValue WideSrc0 = DAG.getNode(ISD::BITCAST, dl, WideVecVT, Mld->getSrc0());
+  if (Mld->getSrc0().getOpcode() != ISD::UNDEF) {
+    SmallVector<int, 16> ShuffleVec(NumElems * SizeRatio, -1);
+    for (unsigned i = 0; i != NumElems; ++i)
+      ShuffleVec[i] = i * SizeRatio;
+
+    // Can't shuffle using an illegal type.
+    assert (TLI.isTypeLegal(WideVecVT) && "WideVecVT should be legal");
+    WideSrc0 = DAG.getVectorShuffle(WideVecVT, dl, WideSrc0,
+                                    DAG.getUNDEF(WideVecVT), &ShuffleVec[0]);
+  }
+  // Prepare the new mask
+  SDValue NewMask;
+  SDValue Mask = Mld->getMask();
+  if (Mask.getValueType() == VT) {
+    // Mask and original value have the same type
+    NewMask = DAG.getNode(ISD::BITCAST, dl, WideVecVT, Mask);
+    SmallVector<int, 16> ShuffleVec(NumElems * SizeRatio, -1);
+    for (unsigned i = 0; i != NumElems; ++i)
+      ShuffleVec[i] = i * SizeRatio;
+    for (unsigned i = NumElems; i != NumElems*SizeRatio; ++i)
+      ShuffleVec[i] = NumElems*SizeRatio;
+    NewMask = DAG.getVectorShuffle(WideVecVT, dl, NewMask,
+                                   DAG.getConstant(0, WideVecVT),
+                                   &ShuffleVec[0]);
+  }
+  else {
+    assert(Mask.getValueType().getVectorElementType() == MVT::i1);
+    unsigned WidenNumElts = NumElems*SizeRatio;
+    unsigned MaskNumElts = VT.getVectorNumElements();
+    EVT NewMaskVT = EVT::getVectorVT(*DAG.getContext(),  MVT::i1,
+                                     WidenNumElts);
+
+    unsigned NumConcat = WidenNumElts / MaskNumElts;
+    SmallVector<SDValue, 16> Ops(NumConcat);
+    SDValue ZeroVal = DAG.getConstant(0, Mask.getValueType());
+    Ops[0] = Mask;
+    for (unsigned i = 1; i != NumConcat; ++i)
+      Ops[i] = ZeroVal;
+
+    NewMask = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewMaskVT, Ops);
+  }
+  
+  SDValue WideLd = DAG.getMaskedLoad(WideVecVT, dl, Mld->getChain(),
+                                     Mld->getBasePtr(), NewMask, WideSrc0,
+                                     Mld->getMemoryVT(), Mld->getMemOperand(),
+                                     ISD::NON_EXTLOAD);
+  SDValue NewVec = DAG.getNode(X86ISD::VSEXT, dl, VT, WideLd);
+  return DCI.CombineTo(N, NewVec, WideLd.getValue(1), true);
+
+}
+/// PerformMSTORECombine - Resolve truncating stores
+static SDValue PerformMSTORECombine(SDNode *N, SelectionDAG &DAG,
+                                    const X86Subtarget *Subtarget) {
+  MaskedStoreSDNode *Mst = cast<MaskedStoreSDNode>(N);
+  if (!Mst->isTruncatingStore())
+    return SDValue();
+
+  EVT VT = Mst->getValue().getValueType();
+  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+  unsigned NumElems = VT.getVectorNumElements();
+  EVT StVT = Mst->getMemoryVT();
+  SDLoc dl(Mst);
+
+  assert(StVT != VT && "Cannot truncate to the same type");
+  unsigned FromSz = VT.getVectorElementType().getSizeInBits();
+  unsigned ToSz = StVT.getVectorElementType().getSizeInBits();
+
+  // From, To sizes and ElemCount must be pow of two
+  assert (isPowerOf2_32(NumElems * FromSz * ToSz) &&
+    "Unexpected size for truncating masked store");
+  // We are going to use the original vector elt for storing.
+  // Accumulated smaller vector elements must be a multiple of the store size.
+  assert (((NumElems * FromSz) % ToSz) == 0 && 
+          "Unexpected ratio for truncating masked store");
+
+  unsigned SizeRatio  = FromSz / ToSz;
+  assert(SizeRatio * NumElems * ToSz == VT.getSizeInBits());
+
+  // Create a type on which we perform the shuffle
+  EVT WideVecVT = EVT::getVectorVT(*DAG.getContext(),
+          StVT.getScalarType(), NumElems*SizeRatio);
+
+  assert(WideVecVT.getSizeInBits() == VT.getSizeInBits());
+
+  SDValue WideVec = DAG.getNode(ISD::BITCAST, dl, WideVecVT, Mst->getValue());
+  SmallVector<int, 16> ShuffleVec(NumElems * SizeRatio, -1);
+  for (unsigned i = 0; i != NumElems; ++i)
+    ShuffleVec[i] = i * SizeRatio;
+
+  // Can't shuffle using an illegal type.
+  assert (TLI.isTypeLegal(WideVecVT) && "WideVecVT should be legal");
+
+  SDValue TruncatedVal = DAG.getVectorShuffle(WideVecVT, dl, WideVec,
+                                        DAG.getUNDEF(WideVecVT),
+                                        &ShuffleVec[0]);
+
+  SDValue NewMask;
+  SDValue Mask = Mst->getMask();
+  if (Mask.getValueType() == VT) {
+    // Mask and original value have the same type
+    NewMask = DAG.getNode(ISD::BITCAST, dl, WideVecVT, Mask);
+    for (unsigned i = 0; i != NumElems; ++i)
+      ShuffleVec[i] = i * SizeRatio;
+    for (unsigned i = NumElems; i != NumElems*SizeRatio; ++i)
+      ShuffleVec[i] = NumElems*SizeRatio;
+    NewMask = DAG.getVectorShuffle(WideVecVT, dl, NewMask,
+                                   DAG.getConstant(0, WideVecVT),
+                                   &ShuffleVec[0]);
+  }
+  else {
+    assert(Mask.getValueType().getVectorElementType() == MVT::i1);
+    unsigned WidenNumElts = NumElems*SizeRatio;
+    unsigned MaskNumElts = VT.getVectorNumElements();
+    EVT NewMaskVT = EVT::getVectorVT(*DAG.getContext(),  MVT::i1,
+                                     WidenNumElts);
+
+    unsigned NumConcat = WidenNumElts / MaskNumElts;
+    SmallVector<SDValue, 16> Ops(NumConcat);
+    SDValue ZeroVal = DAG.getConstant(0, Mask.getValueType());
+    Ops[0] = Mask;
+    for (unsigned i = 1; i != NumConcat; ++i)
+      Ops[i] = ZeroVal;
+
+    NewMask = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewMaskVT, Ops);
+  }
+
+  return DAG.getMaskedStore(Mst->getChain(), dl, TruncatedVal, Mst->getBasePtr(),
+                            NewMask, StVT, Mst->getMemOperand(), false);
+}
 /// PerformSTORECombine - Do target-specific dag combines on STORE nodes.
 static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
                                    const X86Subtarget *Subtarget) {
@@ -25834,7 +25998,9 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
   case ISD::OR:             return PerformOrCombine(N, DAG, DCI, Subtarget);
   case ISD::XOR:            return PerformXorCombine(N, DAG, DCI, Subtarget);
   case ISD::LOAD:           return PerformLOADCombine(N, DAG, DCI, Subtarget);
+  case ISD::MLOAD:          return PerformMLOADCombine(N, DAG, DCI, Subtarget);
   case ISD::STORE:          return PerformSTORECombine(N, DAG, Subtarget);
+  case ISD::MSTORE:         return PerformMSTORECombine(N, DAG, Subtarget);
   case ISD::SINT_TO_FP:     return PerformSINT_TO_FPCombine(N, DAG, this);
   case ISD::FADD:           return PerformFADDCombine(N, DAG, Subtarget);
   case ISD::FSUB:           return PerformFSUBCombine(N, DAG, Subtarget);
index af1694d3453c4089e8e30591b8449017e0dc2681..6230c000cf57fb5273f19b2a8dafbcfca32b5c8e 100644 (file)
@@ -330,11 +330,17 @@ static LoadInst *combineLoadToNewType(InstCombiner &IC, LoadInst &LI, Type *NewT
     case LLVMContext::MD_noalias:
     case LLVMContext::MD_nontemporal:
     case LLVMContext::MD_mem_parallel_loop_access:
-    case LLVMContext::MD_nonnull:
       // All of these directly apply.
       NewLoad->setMetadata(ID, N);
       break;
 
+    case LLVMContext::MD_nonnull:
+      // FIXME: We should translate this into range metadata for integer types
+      // and vice versa.
+      if (NewTy->isPointerTy())
+        NewLoad->setMetadata(ID, N);
+      break;
+
     case LLVMContext::MD_range:
       // FIXME: It would be nice to propagate this in some way, but the type
       // conversions make it hard.
@@ -548,13 +554,14 @@ static bool combineStoreToValueType(InstCombiner &IC, StoreInst &SI) {
       case LLVMContext::MD_noalias:
       case LLVMContext::MD_nontemporal:
       case LLVMContext::MD_mem_parallel_loop_access:
-      case LLVMContext::MD_nonnull:
         // All of these directly apply.
         NewStore->setMetadata(ID, N);
         break;
 
       case LLVMContext::MD_invariant_load:
+      case LLVMContext::MD_nonnull:
       case LLVMContext::MD_range:
+        // These don't apply for stores.
         break;
       }
     }
index 5f73b89e855129b8ee7d80285fbe4fc953ef073f..2a3d15421de9dec58b646bbc0377a7449c541ae6 100644 (file)
@@ -71,9 +71,17 @@ private:
     return isMachO() ? "__DATA,__llvm_prf_data" : "__llvm_prf_data";
   }
 
+  /// Get the section name for the coverage mapping data.
+  StringRef getCoverageSection() const {
+    return isMachO() ? "__DATA,__llvm_covmap" : "__llvm_covmap";
+  }
+
   /// Replace instrprof_increment with an increment of the appropriate value.
   void lowerIncrement(InstrProfIncrementInst *Inc);
 
+  /// Set up the section and uses for coverage data and its references.
+  void lowerCoverageData(GlobalVariable *CoverageData);
+
   /// Get the region counters for an increment, creating them if necessary.
   ///
   /// If the counter array doesn't yet exist, the profile data variables
@@ -118,6 +126,10 @@ bool InstrProfiling::runOnModule(Module &M) {
           lowerIncrement(Inc);
           MadeChange = true;
         }
+  if (GlobalVariable *Coverage = M.getNamedGlobal("__llvm_coverage_mapping")) {
+    lowerCoverageData(Coverage);
+    MadeChange = true;
+  }
   if (!MadeChange)
     return false;
 
@@ -140,6 +152,35 @@ void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) {
   Inc->eraseFromParent();
 }
 
+void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageData) {
+  CoverageData->setSection(getCoverageSection());
+  CoverageData->setAlignment(8);
+
+  Constant *Init = CoverageData->getInitializer();
+  // We're expecting { i32, i32, i32, i32, [n x { i8*, i32, i32 }], [m x i8] }
+  // for some C. If not, the frontend's given us something broken.
+  assert(Init->getNumOperands() == 6 && "bad number of fields in coverage map");
+  assert(isa<ConstantArray>(Init->getAggregateElement(4)) &&
+         "invalid function list in coverage map");
+  ConstantArray *Records = cast<ConstantArray>(Init->getAggregateElement(4));
+  for (unsigned I = 0, E = Records->getNumOperands(); I < E; ++I) {
+    Constant *Record = Records->getOperand(I);
+    Value *V = const_cast<Value *>(Record->getOperand(0))->stripPointerCasts();
+
+    assert(isa<GlobalVariable>(V) && "Missing reference to function name");
+    GlobalVariable *Name = cast<GlobalVariable>(V);
+
+    // If we have region counters for this name, we've already handled it.
+    auto It = RegionCounters.find(Name);
+    if (It != RegionCounters.end())
+      continue;
+
+    // Move the name variable to the right section.
+    Name->setSection(getNameSection());
+    Name->setAlignment(1);
+  }
+}
+
 /// Get the name of a profiling variable for a particular function.
 static std::string getVarName(InstrProfIncrementInst *Inc, StringRef VarName) {
   auto *Arr = cast<ConstantDataArray>(Inc->getName()->getInitializer());
index 394b0d3de7bdc12719051bf8c22386a9276fcebc..969b9a8f8df1d87a78ac76ff69892de0e1860e3b 100644 (file)
@@ -480,6 +480,9 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
       // Ignore volatile loads.
       if (!LI->isSimple()) {
         LastStore = nullptr;
+        // Don't CSE across synchronization boundaries.
+        if (Inst->mayWriteToMemory())
+          ++CurrentGeneration;
         continue;
       }
 
index 8509713b33679d2b5b800ddf1d2471ddcb83c4c6..1f73cbc4ac3065238f911bda25e53b0cc0b20161 100644 (file)
@@ -403,7 +403,7 @@ bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(const Instruction& Start,
                                                       const Instruction& End,
                                                       AliasAnalysis::Location
                                                       Loc) {
-  return AA->canInstructionRangeModRef(Start, End, Loc, AliasAnalysis::Ref);
+  return AA->canInstructionRangeModRef(Start, End, Loc, AliasAnalysis::ModRef);
 }
 
 ///
@@ -414,6 +414,7 @@ bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(const Instruction& Start,
 StoreInst *MergedLoadStoreMotion::canSinkFromBlock(BasicBlock *BB1,
                                                    StoreInst *Store0) {
   DEBUG(dbgs() << "can Sink? : "; Store0->dump(); dbgs() << "\n");
+  BasicBlock *BB0 = Store0->getParent();
   for (BasicBlock::reverse_iterator RBI = BB1->rbegin(), RBE = BB1->rend();
        RBI != RBE; ++RBI) {
     Instruction *Inst = &*RBI;
@@ -422,13 +423,14 @@ StoreInst *MergedLoadStoreMotion::canSinkFromBlock(BasicBlock *BB1,
        continue;
 
     StoreInst *Store1 = cast<StoreInst>(Inst);
-    BasicBlock *BB0 = Store0->getParent();
 
     AliasAnalysis::Location Loc0 = AA->getLocation(Store0);
     AliasAnalysis::Location Loc1 = AA->getLocation(Store1);
     if (AA->isMustAlias(Loc0, Loc1) && Store0->isSameOperationAs(Store1) &&
-      !isStoreSinkBarrierInRange(*Store1, BB1->back(), Loc1) &&
-      !isStoreSinkBarrierInRange(*Store0, BB0->back(), Loc0)) {
+      !isStoreSinkBarrierInRange(*(std::next(BasicBlock::iterator(Store1))),
+                                 BB1->back(), Loc1) &&
+      !isStoreSinkBarrierInRange(*(std::next(BasicBlock::iterator(Store0))),
+                                 BB0->back(), Loc0)) {
       return Store1;
     }
   }
index f12cd61d463a05df219b0dd52bfb66f9bed8cba3..8a32215a299fffa3d7496f314dd191244a0ad1f6 100644 (file)
@@ -55,7 +55,7 @@ STATISTIC(NumRuntimeUnrolled,
 /// - Branch around the original loop if the trip count is less
 ///   than the unroll factor.
 ///
-static void ConnectProlog(Loop *L, Value *TripCount, unsigned Count,
+static void ConnectProlog(Loop *L, Value *BECount, unsigned Count,
                           BasicBlock *LastPrologBB, BasicBlock *PrologEnd,
                           BasicBlock *OrigPH, BasicBlock *NewPH,
                           ValueToValueMapTy &VMap, Pass *P) {
@@ -105,12 +105,19 @@ static void ConnectProlog(Loop *L, Value *TripCount, unsigned Count,
     }
   }
 
-  // Create a branch around the orignal loop, which is taken if the
-  // trip count is less than the unroll factor.
+  // Create a branch around the orignal loop, which is taken if there are no
+  // iterations remaining to be executed after running the prologue.
   Instruction *InsertPt = PrologEnd->getTerminator();
+
+  assert(Count != 0 && "nonsensical Count!");
+
+  // If BECount <u (Count - 1) then (BECount + 1) & (Count - 1) == (BECount + 1)
+  // (since Count is a power of 2).  This means %xtraiter is (BECount + 1) and
+  // and all of the iterations of this loop were executed by the prologue.  Note
+  // that if BECount <u (Count - 1) then (BECount + 1) cannot unsigned-overflow.
   Instruction *BrLoopExit =
-    new ICmpInst(InsertPt, ICmpInst::ICMP_ULT, TripCount,
-                 ConstantInt::get(TripCount->getType(), Count));
+    new ICmpInst(InsertPt, ICmpInst::ICMP_ULT, BECount,
+                 ConstantInt::get(BECount->getType(), Count - 1));
   BasicBlock *Exit = L->getUniqueExitBlock();
   assert(Exit && "Loop must have a single exit block only");
   // Split the exit to maintain loop canonicalization guarantees
@@ -292,23 +299,28 @@ bool llvm::UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
 
   // Only unroll loops with a computable trip count and the trip count needs
   // to be an int value (allowing a pointer type is a TODO item)
-  const SCEV *BECount = SE->getBackedgeTakenCount(L);
-  if (isa<SCEVCouldNotCompute>(BECount) || !BECount->getType()->isIntegerTy())
+  const SCEV *BECountSC = SE->getBackedgeTakenCount(L);
+  if (isa<SCEVCouldNotCompute>(BECountSC) ||
+      !BECountSC->getType()->isIntegerTy())
     return false;
 
-  // If BECount is INT_MAX, we can't compute trip-count without overflow.
-  if (BECount->isAllOnesValue())
-    return false;
+  unsigned BEWidth = cast<IntegerType>(BECountSC->getType())->getBitWidth();
 
   // Add 1 since the backedge count doesn't include the first loop iteration
   const SCEV *TripCountSC =
-    SE->getAddExpr(BECount, SE->getConstant(BECount->getType(), 1));
+    SE->getAddExpr(BECountSC, SE->getConstant(BECountSC->getType(), 1));
   if (isa<SCEVCouldNotCompute>(TripCountSC))
     return false;
 
   // We only handle cases when the unroll factor is a power of 2.
   // Count is the loop unroll factor, the number of extra copies added + 1.
-  if ((Count & (Count-1)) != 0)
+  if (!isPowerOf2_32(Count))
+    return false;
+
+  // This constraint lets us deal with an overflowing trip count easily; see the
+  // comment on ModVal below.  This check is equivalent to `Log2(Count) <
+  // BEWidth`.
+  if (static_cast<uint64_t>(Count) > (1ULL << BEWidth))
     return false;
 
   // If this loop is nested, then the loop unroller changes the code in
@@ -330,16 +342,23 @@ bool llvm::UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
   SCEVExpander Expander(*SE, "loop-unroll");
   Value *TripCount = Expander.expandCodeFor(TripCountSC, TripCountSC->getType(),
                                             PreHeaderBR);
+  Value *BECount = Expander.expandCodeFor(BECountSC, BECountSC->getType(),
+                                          PreHeaderBR);
 
   IRBuilder<> B(PreHeaderBR);
   Value *ModVal = B.CreateAnd(TripCount, Count - 1, "xtraiter");
 
-  // Check if for no extra iterations, then jump to cloned/unrolled loop.
-  // We have to check that the trip count computation didn't overflow when
-  // adding one to the backedge taken count.
-  Value *LCmp = B.CreateIsNotNull(ModVal, "lcmp.mod");
-  Value *OverflowCheck = B.CreateIsNull(TripCount, "lcmp.overflow");
-  Value *BranchVal = B.CreateOr(OverflowCheck, LCmp, "lcmp.or");
+  // If ModVal is zero, we know that either
+  //  1. there are no iteration to be run in the prologue loop
+  // OR
+  //  2. the addition computing TripCount overflowed
+  //
+  // If (2) is true, we know that TripCount really is (1 << BEWidth) and so the
+  // number of iterations that remain to be run in the original loop is a
+  // multiple Count == (1 << Log2(Count)) because Log2(Count) <= BEWidth (we
+  // explicitly check this above).
+
+  Value *BranchVal = B.CreateIsNotNull(ModVal, "lcmp.mod");
 
   // Branch to either the extra iterations or the cloned/unrolled loop
   // We will fix up the true branch label when adding loop body copies
@@ -362,10 +381,7 @@ bool llvm::UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
   std::vector<BasicBlock *> NewBlocks;
   ValueToValueMapTy VMap;
 
-  // If unroll count is 2 and we can't overflow in tripcount computation (which
-  // is BECount + 1), then we don't need a loop for prologue, and we can unroll
-  // it. We can be sure that we don't overflow only if tripcount is a constant.
-  bool UnrollPrologue = (Count == 2 && isa<ConstantInt>(TripCount));
+  bool UnrollPrologue = Count == 2;
 
   // Clone all the basic blocks in the loop. If Count is 2, we don't clone
   // the loop, otherwise we create a cloned loop to execute the extra
@@ -391,7 +407,7 @@ bool llvm::UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI,
   // Connect the prolog code to the original loop and update the
   // PHI functions.
   BasicBlock *LastLoopBB = cast<BasicBlock>(VMap[Latch]);
-  ConnectProlog(L, TripCount, Count, LastLoopBB, PEnd, PH, NewPH, VMap,
+  ConnectProlog(L, BECount, Count, LastLoopBB, PEnd, PH, NewPH, VMap,
                 LPM->getAsPass());
   NumRuntimeUnrolled++;
   return true;
index 557304ed56c5a8e5225d7c318656dc8eeb50a8f0..47b92a37cf1d3e887607f9f1f9ebdea223e45eeb 100644 (file)
@@ -1874,6 +1874,7 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(Instruction *Instr) {
         // wide store needs to start at the last vector element.
         PartPtr = Builder.CreateGEP(Ptr, Builder.getInt32(-Part * VF));
         PartPtr = Builder.CreateGEP(PartPtr, Builder.getInt32(1 - VF));
+        Mask[Part] = reverseVector(Mask[Part]);
       }
 
       Value *VecPtr = Builder.CreateBitCast(PartPtr,
@@ -1902,6 +1903,7 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(Instruction *Instr) {
       // wide load needs to start at the last vector element.
       PartPtr = Builder.CreateGEP(Ptr, Builder.getInt32(-Part * VF));
       PartPtr = Builder.CreateGEP(PartPtr, Builder.getInt32(1 - VF));
+      Mask[Part] = reverseVector(Mask[Part]);
     }
 
     Instruction* NewLI;
index 2213031ecdb99b327bd915deaf2424f37e5c271e..bd8a4b3fd3d0bc685bb1599bdedf0fbdf8ec1256 100644 (file)
@@ -75,6 +75,18 @@ static const unsigned MinVecRegSize = 128;
 
 static const unsigned RecursionMaxDepth = 12;
 
+/// \brief Predicate for the element types that the SLP vectorizer supports.
+///
+/// The most important thing to filter here are types which are invalid in LLVM
+/// vectors. We also filter target specific types which have absolutely no
+/// meaningful vectorization path such as x86_fp80 and ppc_f128. This just
+/// avoids spending time checking the cost model and realizing that they will
+/// be inevitably scalarized.
+static bool isValidElementType(Type *Ty) {
+  return VectorType::isValidElementType(Ty) && !Ty->isX86_FP80Ty() &&
+         !Ty->isPPC_FP128Ty();
+}
+
 /// \returns the parent basic block if all of the instructions in \p VL
 /// are in the same block or null otherwise.
 static BasicBlock *getSameBlock(ArrayRef<Value *> VL) {
@@ -1216,7 +1228,7 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth) {
       Type *SrcTy = VL0->getOperand(0)->getType();
       for (unsigned i = 0; i < VL.size(); ++i) {
         Type *Ty = cast<Instruction>(VL[i])->getOperand(0)->getType();
-        if (Ty != SrcTy || Ty->isAggregateType() || Ty->isVectorTy()) {
+        if (Ty != SrcTy || !isValidElementType(Ty)) {
           BS.cancelScheduling(VL);
           newTreeEntry(VL, false);
           DEBUG(dbgs() << "SLP: Gathering casts with different src types.\n");
@@ -3130,7 +3142,7 @@ unsigned SLPVectorizer::collectStores(BasicBlock *BB, BoUpSLP &R) {
 
     // Check that the pointer points to scalars.
     Type *Ty = SI->getValueOperand()->getType();
-    if (Ty->isAggregateType() || Ty->isVectorTy())
+    if (!isValidElementType(Ty))
       continue;
 
     // Find the base pointer.
@@ -3171,7 +3183,7 @@ bool SLPVectorizer::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R,
 
   for (int i = 0, e = VL.size(); i < e; ++i) {
     Type *Ty = VL[i]->getType();
-    if (Ty->isAggregateType() || Ty->isVectorTy())
+    if (!isValidElementType(Ty))
       return false;
     Instruction *Inst = dyn_cast<Instruction>(VL[i]);
     if (!Inst || Inst->getOpcode() != Opcode0)
@@ -3391,7 +3403,7 @@ public:
       return false;
 
     Type *Ty = B->getType();
-    if (Ty->isVectorTy())
+    if (!isValidElementType(Ty))
       return false;
 
     ReductionOpcode = B->getOpcode();
index 5524bb9922c5d9400753884cb772ddc7eb8f2475..a9909a721c1b2a4cc15f8a4faee09d0396596bab 100644 (file)
@@ -559,11 +559,9 @@ static void freeSymName(ld_plugin_symbol &Sym) {
 }
 
 static std::unique_ptr<Module>
-getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile,
+getModuleForFile(LLVMContext &Context, claimed_file &F,
+                 off_t Filesize, raw_fd_ostream *ApiFile,
                  StringSet<> &Internalize, StringSet<> &Maybe) {
-  ld_plugin_input_file File;
-  if (get_input_file(F.handle, &File) != LDPS_OK)
-    message(LDPL_FATAL, "Failed to get file information");
 
   if (get_symbols(F.handle, F.syms.size(), &F.syms[0]) != LDPS_OK)
     message(LDPL_FATAL, "Failed to get symbol information");
@@ -572,7 +570,7 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile,
   if (get_view(F.handle, &View) != LDPS_OK)
     message(LDPL_FATAL, "Failed to get a view of file");
 
-  MemoryBufferRef BufferRef(StringRef((const char *)View, File.filesize), "");
+  MemoryBufferRef BufferRef(StringRef((const char *)View, Filesize), "");
   ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
       object::IRObjectFile::create(BufferRef, Context);
 
@@ -580,9 +578,6 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile,
     message(LDPL_FATAL, "Could not read bitcode from file : %s",
             EC.message().c_str());
 
-  if (release_input_file(F.handle) != LDPS_OK)
-    message(LDPL_FATAL, "Failed to release file information");
-
   object::IRObjectFile &Obj = **ObjOrErr;
 
   Module &M = Obj.getModule();
@@ -798,8 +793,12 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
   StringSet<> Internalize;
   StringSet<> Maybe;
   for (claimed_file &F : Modules) {
+    ld_plugin_input_file File;
+    if (get_input_file(F.handle, &File) != LDPS_OK)
+      message(LDPL_FATAL, "Failed to get file information");
     std::unique_ptr<Module> M =
-        getModuleForFile(Context, F, ApiFile, Internalize, Maybe);
+        getModuleForFile(Context, F, File.filesize, ApiFile,
+                         Internalize, Maybe);
     if (!options::triple.empty())
       M->setTargetTriple(options::triple.c_str());
     else if (M->getTargetTriple().empty()) {
@@ -808,6 +807,8 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
 
     if (L.linkInModule(M.get()))
       message(LDPL_FATAL, "Failed to link module");
+    if (release_input_file(F.handle) != LDPS_OK)
+      message(LDPL_FATAL, "Failed to release file information");
   }
 
   for (const auto &Name : Internalize) {
index 3610d76d8fd42f273bc3147fd3365ede225792e9..51f55791ea471cc785b95794820e3892954b5f75 100644 (file)
@@ -10,6 +10,7 @@ set(LLVM_LINK_COMPONENTS
   MC
   MCJIT
   Object
+  RuntimeDyld
   SelectionDAG
   Support
   native
index 783c9b519216d61a0536f5f64de3b8cd6fc1ab69..05e093e0c0b4001c14cebea58772a86eb485176f 100644 (file)
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS
   ExecutionEngine
   Interpreter
   MC
+  RuntimeDyld
   Support
   )
 
index b10cbb4c9ea4b94b20954a5591cd630d0c937f15..e29787f8f426e3504b4b1c45c8ba90b0526d6c83 100644 (file)
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
   IPO
   MC
   MCJIT
+  RuntimeDyld
   ScalarOpts
   Support
   Target
index 1e2975d8ef2e190ec1c225d2455596c116c3e843..2e54cec98e1ea812e1b31a07edd016b7a5c1873d 100644 (file)
Binary files a/src/llvm/utils/llvm-build/llvmbuild/__init__.pyc and b/src/llvm/utils/llvm-build/llvmbuild/__init__.pyc differ
index aa38c0bc58dae1deebc7e341143ecce150593e18..ed79c29d915060382c1320b1feba715df9696f33 100644 (file)
Binary files a/src/llvm/utils/llvm-build/llvmbuild/componentinfo.pyc and b/src/llvm/utils/llvm-build/llvmbuild/componentinfo.pyc differ
index a77c231aed46adeb2a0e26c627e44042bc3a497e..09c8c6722899cbd1d2713fff2718bc81f2d4ea0d 100644 (file)
Binary files a/src/llvm/utils/llvm-build/llvmbuild/configutil.pyc and b/src/llvm/utils/llvm-build/llvmbuild/configutil.pyc differ
index 65687507b8c743a6f02f02ca1032256dd06b615d..3e356bb998aa539e1aa748ac1d7e92ef48e733e3 100644 (file)
Binary files a/src/llvm/utils/llvm-build/llvmbuild/main.pyc and b/src/llvm/utils/llvm-build/llvmbuild/main.pyc differ
index 542a8aafe8a0dea0f9a0ac6035ad9a61c5d478b3..cde42a973bedd57b70ad76a4351b64c6579535f9 100644 (file)
Binary files a/src/llvm/utils/llvm-build/llvmbuild/util.pyc and b/src/llvm/utils/llvm-build/llvmbuild/util.pyc differ
index c82da57c12847af48603e9bbc1660d0a57a4e36f..cf2b9b9f717c57ff13ff997c99a33e467cd26dd6 100644 (file)
 
 #if defined(__APPLE__)
 #define EXHAUSTED               _rust_stack_exhausted
-#elif defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#elif defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__Bitrig__)
 #define EXHAUSTED               rust_stack_exhausted@PLT
 #else
 #define EXHAUSTED               rust_stack_exhausted
 #endif
 
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__Bitrig__)
        .hidden MORESTACK
 #else
 #if defined(__APPLE__)
index b83f530b0e9bccf1a7e392263446d5a7c6070d8d..7de08af314a5adc14b986990b838166382feef44 100644 (file)
@@ -94,4 +94,3 @@ namespace msvc_typeof_impl {
 #endif
 
 #endif
-
index b756602ead4f43286408ad769742f79e4fc32934..db1a602b404f60028282d84073bb3f7a2206dc98 100644 (file)
@@ -47,8 +47,8 @@ extern char **environ;
 #endif
 #endif
 
-#if defined(__FreeBSD__) || defined(__linux__) || defined(__ANDROID__) \
-  || defined(__DragonFly__) || defined(__OpenBSD__)
+#if defined(__FreeBSD__) || defined(__linux__) || defined(__ANDROID__) || \
+    defined(__DragonFly__) || defined(__Bitrig__) || defined(__OpenBSD__)
 extern char **environ;
 #endif
 
@@ -200,7 +200,282 @@ rust_unset_sigprocmask() {
 int *__dfly_error(void) { return __error(); }
 #endif
 
-#if defined(__OpenBSD__)
+#if defined(__Bitrig__)
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <limits.h>
+
+int rust_get_path(void *p, size_t* sz)
+{
+  int mib[4];
+  char *eq = NULL;
+  char *key = NULL;
+  char *val = NULL;
+  char **menv = NULL;
+  size_t maxlen, len;
+  int nenv = 0;
+  int i;
+
+  if ((p == NULL) && (sz == NULL))
+    return -1;
+
+  /* get the argv array */
+  mib[0] = CTL_KERN;
+  mib[1] = KERN_PROC_ARGS;
+  mib[2] = getpid();
+  mib[3] = KERN_PROC_ENV;
+
+  /* get the number of bytes needed to get the env */
+  maxlen = 0;
+  if (sysctl(mib, 4, NULL, &maxlen, NULL, 0) == -1)
+    return -1;
+
+  /* allocate the buffer */
+  if ((menv = calloc(maxlen, sizeof(char))) == NULL)
+    return -1;
+
+  /* get the env array */
+  if (sysctl(mib, 4, menv, &maxlen, NULL, 0) == -1)
+  {
+    free(menv);
+    return -1;
+  }
+
+  mib[3] = KERN_PROC_NENV;
+  len = sizeof(int);
+  /* get the length of env array */
+  if (sysctl(mib, 4, &nenv, &len, NULL, 0) == -1)
+  {
+    free(menv);
+    return -1;
+  }
+
+  /* find _ key and resolve the value */
+  for (i = 0; i < nenv; i++)
+  {
+    if ((eq = strstr(menv[i], "=")) == NULL)
+      continue;
+
+    key = menv[i];
+    val = eq + 1;
+    *eq = '\0';
+
+    if (strncmp(key, "PATH", maxlen) != 0)
+      continue;
+
+    if (p == NULL)
+    {
+      /* return the length of the value + NUL */
+      *sz = strnlen(val, maxlen) + 1;
+      free(menv);
+      return 0;
+    }
+    else
+    {
+      /* copy *sz bytes to the output buffer */
+      memcpy(p, val, *sz);
+      free(menv);
+      return 0;
+    }
+  }
+
+  free(menv);
+  return -1;
+}
+
+int rust_get_path_array(void * p, size_t * sz)
+{
+  char *path, *str;
+  char **buf;
+  int i, num;
+  size_t len;
+
+  if ((p == NULL) && (sz == NULL))
+    return -1;
+
+  /* get the length of the PATH value */
+  if (rust_get_path(NULL, &len) == -1)
+    return -1;
+
+  if (len == 0)
+    return -1;
+
+  /* allocate the buffer */
+  if ((path = calloc(len, sizeof(char))) == NULL)
+    return -1;
+
+  /* get the PATH value */
+  if (rust_get_path(path, &len) == -1)
+  {
+    free(path);
+    return -1;
+  }
+
+  /* count the number of parts in the PATH */
+  num = 1;
+  for(str = path; *str != '\0'; str++)
+  {
+    if (*str == ':')
+      num++;
+  }
+
+  /* calculate the size of the buffer for the 2D array */
+  len = (num * sizeof(char*) + 1) + strlen(path) + 1;
+
+  if (p == NULL)
+  {
+    free(path);
+    *sz = len;
+    return 0;
+  }
+
+  /* make sure we have enough buffer space */
+  if (*sz < len)
+  {
+    free(path);
+    return -1;
+  }
+
+  /* zero out the buffer */
+  buf = (char**)p;
+  memset(buf, 0, *sz);
+
+  /* copy the data into the right place */
+  str = p + ((num+1) * sizeof(char*));
+  memcpy(str, path, strlen(path));
+
+  /* parse the path into it's parts */
+  for (i = 0; i < num && (buf[i] = strsep(&str, ":")) != NULL; i++) {;}
+  buf[num] = NULL;
+
+  free(path);
+  return 0;
+}
+
+int rust_get_argv_zero(void* p, size_t* sz)
+{
+  int mib[4];
+  char **argv = NULL;
+  size_t len;
+
+  if ((p == NULL) && (sz == NULL))
+    return -1;
+
+  /* get the argv array */
+  mib[0] = CTL_KERN;
+  mib[1] = KERN_PROC_ARGS;
+  mib[2] = getpid();
+  mib[3] = KERN_PROC_ARGV;
+
+  /* request KERN_PROC_ARGV size */
+  len = 0;
+  if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
+    return -1;
+
+  /* allocate buffer to receive the values */
+  if ((argv = malloc(len)) == NULL)
+    return -1;
+
+  /* get the argv array */
+  if (sysctl(mib, 4, argv, &len, NULL, 0) == -1)
+  {
+    free(argv);
+    return -1;
+  }
+
+  /* get length of argv[0] */
+  len = strnlen(argv[0], len) + 1;
+
+  if (p == NULL)
+  {
+    *sz = len;
+    free(argv);
+    return 0;
+  }
+
+  if (*sz < len)
+  {
+    free(argv);
+    return -1;
+  }
+
+  memset(p, 0, len);
+  memcpy(p, argv[0], len);
+  free(argv);
+  return 0;
+}
+
+const char * rust_current_exe()
+{
+  static char *self = NULL;
+  char *argv0;
+  char **paths;
+  size_t sz;
+  int i;
+  char buf[2*PATH_MAX], exe[2*PATH_MAX];
+
+  if (self != NULL)
+    return self;
+
+  if (rust_get_argv_zero(NULL, &sz) == -1)
+    return NULL;
+  if ((argv0 = calloc(sz, sizeof(char))) == NULL)
+    return NULL;
+  if (rust_get_argv_zero(argv0, &sz) == -1)
+  {
+    free(argv0);
+    return NULL;
+  }
+
+  /* if argv0 is a relative or absolute path, resolve it with realpath */
+  if ((*argv0 == '.') || (*argv0 == '/') || (strstr(argv0, "/") != NULL))
+  {
+    self = realpath(argv0, NULL);
+    free(argv0);
+    return self;
+  }
+
+  /* get the path array */
+  if (rust_get_path_array(NULL, &sz) == -1)
+  {
+    free(argv0);
+    return NULL;
+  }
+  if ((paths = calloc(sz, sizeof(char))) == NULL)
+  {
+    free(argv0);
+    return NULL;
+  }
+  if (rust_get_path_array(paths, &sz) == -1)
+  {
+    free(argv0);
+    free(paths);
+    return NULL;
+  }
+
+  for(i = 0; paths[i] != NULL; i++)
+  {
+    snprintf(buf, 2*PATH_MAX, "%s/%s", paths[i], argv0);
+    if (realpath(buf, exe) == NULL)
+      continue;
+
+    if (access(exe, F_OK | X_OK) == -1)
+      continue;
+
+    self = strdup(exe);
+    free(argv0);
+    free(paths);
+    return self;
+  }
+
+  free(argv0);
+  free(paths);
+  return NULL;
+}
+
+#elif defined(__OpenBSD__)
+
 #include <sys/param.h>
 #include <sys/sysctl.h>
 #include <limits.h>
@@ -248,6 +523,7 @@ const char * rust_current_exe() {
 
     return (self);
 }
+
 #endif
 
 //
index 3af0728f0179695373aa94e39db442d0ae398f80..ee72707d3194e52584d8cb7f0df5fe971a95899f 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
    ----------------------------------------------------------------
 
@@ -284,4 +283,3 @@ typedef
                                     (zznbytes), 0, 0 )
 
 #endif
-
index 145697a130536a34a61fd1cd4755a74897158c72..51ee7b02ea149bd7a25f0d784a0206c2b240c4b6 100644 (file)
@@ -3,4 +3,4 @@
        url = https://github.com/rust-lang/rust-installer
 [submodule "test/rust-installer-v2"]
        path = test/rust-installer-v2
-       url = http://github.com/rust-lang/rust-installer
+       url = https://github.com/rust-lang/rust-installer
old mode 100644 (file)
new mode 100755 (executable)
index 0dc2fcccb9dea7482985d254caafc4fad3bb542b..289bead89c0bb84b3dcaab2932b3c3b9ce3b23cb 100755 (executable)
 
 set -u
 
+if [ -x /bin/echo ]; then
+    ECHO='/bin/echo'
+else
+    ECHO='echo'
+fi
+
 msg() {
     echo "gen-install-script: ${1-}"
 }
@@ -253,14 +259,14 @@ success_message=`echo "$CFG_SUCCESS_MESSAGE" | sed "s/-/ /g"`
 script_template=`cat "$src_dir/install-template.sh"`
 
 # Using /bin/echo because under sh emulation dash *seems* to escape \n, which screws up the template
-script=`/bin/echo "$script_template"`
-script=`/bin/echo "$script" | sed "s/%%TEMPLATE_PRODUCT_NAME%%/\"$product_name\"/"`
-script=`/bin/echo "$script" | sed "s/%%TEMPLATE_REL_MANIFEST_DIR%%/$CFG_REL_MANIFEST_DIR/"`
-script=`/bin/echo "$script" | sed "s/%%TEMPLATE_SUCCESS_MESSAGE%%/\"$success_message\"/"`
-script=`/bin/echo "$script" | sed "s/%%TEMPLATE_LEGACY_MANIFEST_DIRS%%/\"$CFG_LEGACY_MANIFEST_DIRS\"/"`
-script=`/bin/echo "$script" | sed "s/%%TEMPLATE_RUST_INSTALLER_VERSION%%/\"$rust_installer_version\"/"`
-
-/bin/echo "$script" > "$CFG_OUTPUT_SCRIPT"
+script=`$ECHO "$script_template"`
+script=`$ECHO "$script" | sed "s/%%TEMPLATE_PRODUCT_NAME%%/\"$product_name\"/"`
+script=`$ECHO "$script" | sed "s/%%TEMPLATE_REL_MANIFEST_DIR%%/$CFG_REL_MANIFEST_DIR/"`
+script=`$ECHO "$script" | sed "s/%%TEMPLATE_SUCCESS_MESSAGE%%/\"$success_message\"/"`
+script=`$ECHO "$script" | sed "s/%%TEMPLATE_LEGACY_MANIFEST_DIRS%%/\"$CFG_LEGACY_MANIFEST_DIRS\"/"`
+script=`$ECHO "$script" | sed "s/%%TEMPLATE_RUST_INSTALLER_VERSION%%/\"$rust_installer_version\"/"`
+
+$ECHO "$script" > "$CFG_OUTPUT_SCRIPT"
 need_ok "couldn't write script"
 chmod u+x "$CFG_OUTPUT_SCRIPT"
 need_ok "couldn't chmod script"
index 051003ea1a668c1cf60517b2fe130aa3a4f88f3b..93e79a9c186cffd126297ecd1137b0affff45f08 100755 (executable)
 
 set -u
 
+if [ -x /bin/echo ]; then
+    ECHO='/bin/echo'
+else
+    ECHO='echo'
+fi
+
 msg() {
     echo "gen-installer: ${1-}"
 }
@@ -283,7 +289,7 @@ done
 
 # Add 'file:' installation directives.
 # The -n prevents adding a blank file: if the manifest is empty
-manifest=`/bin/echo -n "$manifest" | sed s/^/file:/`
+manifest=`$ECHO -n "$manifest" | sed s/^/file:/`
 
 # Add 'dir:' directives
 for bulk_dir in $bulk_dirs; do
index fea699b90a317e48d448c2e72f498249a760a30c..1e4a17f98bbec566423a5480ce7c38288c12fb54 100644 (file)
@@ -223,7 +223,7 @@ opt() {
             fi
         done
     else
-        if [ ! -z "$META" ]
+        if [ ! -z "${META-}" ]
         then
             op="$op=<$META>"
         fi
@@ -251,7 +251,7 @@ flag() {
             fi
         done
     else
-        if [ ! -z "$META" ]
+        if [ ! -z "${META-}" ]
         then
             op="$op=<$META>"
         fi
@@ -327,6 +327,10 @@ get_host_triple() {
             _ostype=unknown-dragonfly
             ;;
 
+        OpenBSD)
+            _ostype=unknown-openbsd
+           ;;
+
        Darwin)
             _ostype=apple-darwin
             ;;
@@ -753,7 +757,7 @@ need_cmd tr
 need_cmd sed
 need_cmd chmod
 
-CFG_ARGS="$@"
+CFG_ARGS="${@:-}"
 
 HELP=0
 if [ "${1-}" = "--help" ]
@@ -778,8 +782,9 @@ valopt destdir "" "set installation root"
 valopt prefix "/usr/local" "set installation prefix"
 
 # Avoid prepending an extra / to the prefix path if there's no destdir
-if [ -z "$CFG_DESTDIR" ]; then
-    CFG_DESTDIR_PREFIX="$CFG_PREFIX"
+# NB: CFG vars here are undefined when passing --help
+if [ -z "${CFG_DESTDIR-}" ]; then
+    CFG_DESTDIR_PREFIX="${CFG_PREFIX-}"
 else
     CFG_DESTDIR_PREFIX="$CFG_DESTDIR/$CFG_PREFIX"
 fi
@@ -831,7 +836,7 @@ src_basename="$(basename "$0")"
 # then we're doing a full uninstall, as opposed to the --uninstall flag
 # which just means 'uninstall my components'.
 if [ "$src_basename" = "uninstall.sh" ]; then
-    if [ "$*" != "" ]; then
+    if [ "${*:-}" != "" ]; then
        # Currently don't know what to do with arguments in this mode
        err "uninstall.sh does not take any arguments"
     fi
index 2843c1b04b4d38d7f448f48b6544fce62fed94c9..4cab6f6994842027027ae61a40abd0592e76c5a1 100755 (executable)
@@ -2,6 +2,12 @@
 
 set -e -u
 
+if [ -x /bin/echo ]; then
+    ECHO='/bin/echo'
+else
+    ECHO='echo'
+fi
+
 S="$(cd $(dirname $0) && pwd)"
 
 TEST_DIR="$S/test"
@@ -57,7 +63,7 @@ try() {
     if [ $? -ne 0 ]; then
        echo \$ "$_cmd"
        # Using /bin/echo to avoid escaping
-       /bin/echo "$_output"
+       $ECHO "$_output"
        echo
        echo "TEST FAILED!"
        echo
@@ -67,7 +73,7 @@ try() {
            echo \$ "$_cmd"
        fi
        if [ -n "${VERBOSE-}" -o -n "${VERBOSE_OUTPUT-}" ]; then
-           /bin/echo "$_output"
+           $ECHO "$_output"
        fi
     fi
     set -e
@@ -80,7 +86,7 @@ expect_fail() {
     if [ $? -eq 0 ]; then
        echo \$ "$_cmd"
        # Using /bin/echo to avoid escaping
-       /bin/echo "$_output"
+       $ECHO "$_output"
        echo
        echo "TEST FAILED!"
        echo
@@ -90,7 +96,7 @@ expect_fail() {
            echo \$ "$_cmd"
        fi
        if [ -n "${VERBOSE-}" -o -n "${VERBOSE_OUTPUT-}" ]; then
-           /bin/echo "$_output"
+           $ECHO "$_output"
        fi
     fi
     set -e
@@ -105,14 +111,14 @@ expect_output_ok() {
     if [ $? -ne 0 ]; then
        echo \$ "$_cmd"
        # Using /bin/echo to avoid escaping
-       /bin/echo "$_output"
+       $ECHO "$_output"
        echo
        echo "TEST FAILED!"
        echo
        exit 1
     elif ! echo "$_output" | grep -q "$_expected"; then
        echo \$ "$_cmd"
-       /bin/echo "$_output"
+       $ECHO "$_output"
        echo
        echo "missing expected output '$_expected'"
        echo
@@ -125,7 +131,7 @@ expect_output_ok() {
            echo \$ "$_cmd"
        fi
        if [ -n "${VERBOSE-}" -o -n "${VERBOSE_OUTPUT-}" ]; then
-           /bin/echo "$_output"
+           $ECHO "$_output"
        fi
     fi
     set -e
@@ -140,14 +146,14 @@ expect_output_fail() {
     if [ $? -eq 0 ]; then
        echo \$ "$_cmd"
        # Using /bin/echo to avoid escaping
-       /bin/echo "$_output"
+       $ECHO "$_output"
        echo
        echo "TEST FAILED!"
        echo
        exit 1
     elif ! echo "$_output" | grep -q "$_expected"; then
        echo \$ "$_cmd"
-       /bin/echo "$_output"
+       $ECHO "$_output"
        echo
        echo "missing expected output '$_expected'"
        echo
@@ -160,7 +166,7 @@ expect_output_fail() {
            echo \$ "$_cmd"
        fi
        if [ -n "${VERBOSE-}" -o -n "${VERBOSE_OUTPUT-}" ]; then
-           /bin/echo "$_output"
+           $ECHO "$_output"
        fi
     fi
     set -e
@@ -175,14 +181,14 @@ expect_not_output_ok() {
     if [ $? -ne 0 ]; then
        echo \$ "$_cmd"
        # Using /bin/echo to avoid escaping
-       /bin/echo "$_output"
+       $ECHO "$_output"
        echo
        echo "TEST FAILED!"
        echo
        exit 1
     elif echo "$_output" | grep -q "$_expected"; then
        echo \$ "$_cmd"
-       /bin/echo "$_output"
+       $ECHO "$_output"
        echo
        echo "unexpected output '$_expected'"
        echo
@@ -195,7 +201,7 @@ expect_not_output_ok() {
            echo \$ "$_cmd"
        fi
        if [ -n "${VERBOSE-}" -o -n "${VERBOSE_OUTPUT-}" ]; then
-           /bin/echo "$_output"
+           $ECHO "$_output"
        fi
     fi
     set -e
@@ -1327,6 +1333,16 @@ leave_log_after_failure() {
 }
 runtest leave_log_after_failure
 
+# https://github.com/rust-lang/rust-installer/issues/22
+help() {
+    try sh "$S/gen-installer.sh" \
+       --image-dir="$TEST_DIR/image1" \
+       --work-dir="$WORK_DIR" \
+       --output-dir="$OUT_DIR"
+    try "$WORK_DIR/package/install.sh" --help
+}
+runtest help
+
 # TODO: mandir/libdir/bindir, etc.
 
 echo
index 21f8a7793dc0ca680ac61cce813eb20576c64ef5..a08481f8be94e0473c8cfc6b77167bf83d7aa4c1 100644 (file)
 
 //! Basic data structures for representing a book.
 
-use std::old_io::BufferedReader;
+use std::io::prelude::*;
+use std::io::BufReader;
 use std::iter;
 use std::iter::AdditiveIterator;
+use std::path::{Path, PathBuf};
 
 pub struct BookItem {
     pub title: String,
-    pub path: Path,
-    pub path_to_root: Path,
+    pub path: PathBuf,
+    pub path_to_root: PathBuf,
     pub children: Vec<BookItem>,
 }
 
@@ -50,14 +52,14 @@ impl<'a> Iterator for BookItems<'a> {
 
                 let mut section = "".to_string();
                 for &(_, idx) in &self.stack {
-                    section.push_str(&(idx + 1).to_string()[]);
+                    section.push_str(&(idx + 1).to_string()[..]);
                     section.push('.');
                 }
-                section.push_str(&(self.cur_idx + 1).to_string()[]);
+                section.push_str(&(self.cur_idx + 1).to_string()[..]);
                 section.push('.');
 
                 self.stack.push((self.cur_items, self.cur_idx));
-                self.cur_items = &cur.children[];
+                self.cur_items = &cur.children[..];
                 self.cur_idx = 0;
                 return Some((section, cur))
             }
@@ -68,7 +70,7 @@ impl<'a> Iterator for BookItems<'a> {
 impl Book {
     pub fn iter(&self) -> BookItems {
         BookItems {
-            cur_items: &self.chapters[],
+            cur_items: &self.chapters[..],
             cur_idx: 0,
             stack: Vec::new(),
         }
@@ -76,7 +78,7 @@ impl Book {
 }
 
 /// Construct a book by parsing a summary (markdown table of contents).
-pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String>> {
+pub fn parse_summary(input: &mut Read, src: &Path) -> Result<Book, Vec<String>> {
     fn collapse(stack: &mut Vec<BookItem>,
                 top_items: &mut Vec<BookItem>,
                 to_level: usize) {
@@ -100,41 +102,41 @@ pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String
     // always include the introduction
     top_items.push(BookItem {
         title: "Introduction".to_string(),
-        path: Path::new("README.md"),
-        path_to_root: Path::new("."),
+        path: PathBuf::from("README.md"),
+        path_to_root: PathBuf::from("."),
         children: vec!(),
     });
 
-    for line_result in BufferedReader::new(input).lines() {
+    for line_result in BufReader::new(input).lines() {
         let line = match line_result {
             Ok(line) => line,
             Err(err) => {
-                errors.push(err.desc.to_string()); // FIXME: include detail
+                errors.push(err.to_string());
                 return Err(errors);
             }
         };
 
-        let star_idx = match line.find_str("*") { Some(i) => i, None => continue };
+        let star_idx = match line.find("*") { Some(i) => i, None => continue };
 
-        let start_bracket = star_idx + line[star_idx..].find_str("[").unwrap();
-        let end_bracket = start_bracket + line[start_bracket..].find_str("](").unwrap();
+        let start_bracket = star_idx + line[star_idx..].find("[").unwrap();
+        let end_bracket = start_bracket + line[start_bracket..].find("](").unwrap();
         let start_paren = end_bracket + 1;
-        let end_paren = start_paren + line[start_paren..].find_str(")").unwrap();
+        let end_paren = start_paren + line[start_paren..].find(")").unwrap();
 
         let given_path = &line[start_paren + 1 .. end_paren];
         let title = line[start_bracket + 1..end_bracket].to_string();
         let indent = &line[..star_idx];
 
-        let path_from_root = match src.join(given_path).path_relative_from(src) {
-            Some(p) => p,
+        let path_from_root = match src.join(given_path).relative_from(src) {
+            Some(p) => p.to_path_buf(),
             None => {
                 errors.push(format!("paths in SUMMARY.md must be relative, \
                                      but path '{}' for section '{}' is not.",
                                      given_path, title));
-                Path::new("")
+                PathBuf::new()
             }
         };
-        let path_to_root = Path::new(iter::repeat("../")
+        let path_to_root = PathBuf::from(&iter::repeat("../")
                                          .take(path_from_root.components().count() - 1)
                                          .collect::<String>());
         let item = BookItem {
index 224f1ef1a8b9b6feaaa5e559b6bbfea5f2c953e5..f06290b27cb2809583269f159f4b3313de5745ee 100644 (file)
 
 //! Implementation of the `build` subcommand, used to compile a book.
 
-use std::os;
 use std::env;
-use std::old_io;
-use std::old_io::{fs, File, BufferedWriter, TempDir, IoResult};
+use std::fs::{self, File};
+use std::io::prelude::*;
+use std::io::{self, BufWriter};
+use std::path::{Path, PathBuf};
+use rustc_back::tempdir::TempDir;
 
 use subcommand::Subcommand;
 use term::Term;
-use error::{Error, CliResult, CommandResult};
+use error::{err, CliResult, CommandResult};
 use book;
 use book::{Book, BookItem};
 use css;
@@ -29,33 +31,33 @@ struct Build;
 
 pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
     if name == "build" {
-        Some(box Build as Box<Subcommand>)
+        Some(Box::new(Build))
     } else {
         None
     }
 }
 
-fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()> {
+fn write_toc(book: &Book, path_to_root: &Path, out: &mut Write) -> io::Result<()> {
     fn walk_items(items: &[BookItem],
                   section: &str,
                   path_to_root: &Path,
-                  out: &mut Writer) -> IoResult<()> {
+                  out: &mut Write) -> io::Result<()> {
         for (i, item) in items.iter().enumerate() {
-            try!(walk_item(item, &format!("{}{}.", section, i + 1)[], path_to_root, out));
+            try!(walk_item(item, &format!("{}{}.", section, i + 1)[..], path_to_root, out));
         }
         Ok(())
     }
     fn walk_item(item: &BookItem,
                  section: &str,
                  path_to_root: &Path,
-                 out: &mut Writer) -> IoResult<()> {
+                 out: &mut Write) -> io::Result<()> {
         try!(writeln!(out, "<li><a href='{}'><b>{}</b> {}</a>",
-                 path_to_root.join(item.path.with_extension("html")).display(),
+                 path_to_root.join(&item.path.with_extension("html")).display(),
                  section,
                  item.title));
         if !item.children.is_empty() {
             try!(writeln!(out, "<ul class='section'>"));
-            let _ = walk_items(&item.children[], section, path_to_root, out);
+            let _ = walk_items(&item.children[..], section, path_to_root, out);
             try!(writeln!(out, "</ul>"));
         }
         try!(writeln!(out, "</li>"));
@@ -65,7 +67,7 @@ fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()>
 
     try!(writeln!(out, "<div id='toc' class='mobile-hidden'>"));
     try!(writeln!(out, "<ul class='chapter'>"));
-    try!(walk_items(&book.chapters[], "", path_to_root, out));
+    try!(walk_items(&book.chapters[..], "", path_to_root, out));
     try!(writeln!(out, "</ul>"));
     try!(writeln!(out, "</div>"));
 
@@ -75,30 +77,35 @@ fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()>
 fn render(book: &Book, tgt: &Path) -> CliResult<()> {
     let tmp = try!(TempDir::new("rust-book"));
 
-    for (section, item) in book.iter() {
-        println!("{} {}", section, item.title);
-
-        let out_path = tgt.join(item.path.dirname());
+    for (_section, item) in book.iter() {
+        let out_path = match item.path.parent() {
+            Some(p) => tgt.join(p),
+            None => tgt.to_path_buf(),
+        };
 
         let src;
         if env::args().len() < 3 {
-            src = os::getcwd().unwrap().clone();
+            src = env::current_dir().unwrap().clone();
         } else {
-            src = Path::new(env::args().nth(2).unwrap().clone());
+            src = PathBuf::from(&env::args().nth(2).unwrap());
         }
         // preprocess the markdown, rerouting markdown references to html references
-        let markdown_data = try!(File::open(&src.join(&item.path)).read_to_string());
-        let preprocessed_path = tmp.path().join(item.path.filename().unwrap());
+        let mut markdown_data = String::new();
+        try!(File::open(&src.join(&item.path)).and_then(|mut f| {
+            f.read_to_string(&mut markdown_data)
+        }));
+        let preprocessed_path = tmp.path().join(item.path.file_name().unwrap());
         {
             let urls = markdown_data.replace(".md)", ".html)");
-            try!(File::create(&preprocessed_path)
-                      .write_str(&urls[..]));
+            try!(File::create(&preprocessed_path).and_then(|mut f| {
+                f.write_all(urls.as_bytes())
+            }));
         }
 
         // write the prelude to a temporary HTML file for rustdoc inclusion
         let prelude = tmp.path().join("prelude.html");
         {
-            let mut toc = BufferedWriter::new(try!(File::create(&prelude)));
+            let mut toc = BufWriter::new(try!(File::create(&prelude)));
             try!(writeln!(&mut toc, r#"<div id="nav">
                 <button id="toggle-nav">
                   <span class="sr-only">Toggle navigation</span>
@@ -115,12 +122,12 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> {
         // write the postlude to a temporary HTML file for rustdoc inclusion
         let postlude = tmp.path().join("postlude.html");
         {
-            let mut toc = BufferedWriter::new(try!(File::create(&postlude)));
-            try!(toc.write_str(javascript::JAVASCRIPT));
+            let mut toc = BufWriter::new(try!(File::create(&postlude)));
+            try!(toc.write_all(javascript::JAVASCRIPT.as_bytes()));
             try!(writeln!(&mut toc, "</div></div>"));
         }
 
-        try!(fs::mkdir_recursive(&out_path, old_io::USER_DIR));
+        try!(fs::create_dir_all(&out_path));
 
         let rustdoc_args: &[String] = &[
             "".to_string(),
@@ -135,7 +142,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> {
         if output_result != 0 {
             let message = format!("Could not execute `rustdoc` with {:?}: {}",
                                   rustdoc_args, output_result);
-            return Err(box message as Box<Error>);
+            return Err(err(&message));
         }
     }
 
@@ -150,28 +157,30 @@ impl Subcommand for Build {
     }
     fn usage(&self) {}
     fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
-        let cwd = os::getcwd().unwrap();
+        let cwd = env::current_dir().unwrap();
         let src;
         let tgt;
 
         if env::args().len() < 3 {
             src = cwd.clone();
         } else {
-            src = Path::new(env::args().nth(2).unwrap().clone());
+            src = PathBuf::from(&env::args().nth(2).unwrap());
         }
 
         if env::args().len() < 4 {
             tgt = cwd.join("_book");
         } else {
-            tgt = Path::new(env::args().nth(3).unwrap().clone());
+            tgt = PathBuf::from(&env::args().nth(3).unwrap());
         }
 
-        try!(fs::mkdir(&tgt, old_io::USER_DIR));
+        try!(fs::create_dir(&tgt));
 
-        try!(File::create(&tgt.join("rust-book.css")).write_str(css::STYLE));
+        try!(File::create(&tgt.join("rust-book.css")).and_then(|mut f| {
+            f.write_all(css::STYLE.as_bytes())
+        }));
 
-        let summary = try!(File::open(&src.join("SUMMARY.md")));
-        match book::parse_summary(summary, &src) {
+        let mut summary = try!(File::open(&src.join("SUMMARY.md")));
+        match book::parse_summary(&mut summary, &src) {
             Ok(book) => {
                 // execute rustdoc on the whole book
                 render(&book, &tgt)
@@ -179,10 +188,10 @@ impl Subcommand for Build {
             Err(errors) => {
                 let n = errors.len();
                 for err in errors {
-                    term.err(&format!("error: {}", err)[]);
+                    term.err(&format!("error: {}", err)[..]);
                 }
 
-                Err(box format!("{} errors occurred", n) as Box<Error>)
+                Err(err(&format!("{} errors occurred", n)))
             }
         }
     }
index 43c882c7d5b8a69c1c660049f7abf6f969fe8764..e896dee27919e1c4121e2be47b7c5c334e8ffa1f 100644 (file)
 
 //! Error handling utilities. WIP.
 
+use std::error::Error;
 use std::fmt;
-use std::fmt::{Debug, Formatter};
-
-use std::old_io::IoError;
 
 pub type CliError = Box<Error + 'static>;
 pub type CliResult<T> = Result<T, CliError>;
@@ -21,63 +19,18 @@ pub type CliResult<T> = Result<T, CliError>;
 pub type CommandError = Box<Error + 'static>;
 pub type CommandResult<T> = Result<T, CommandError>;
 
-pub trait Error {
-    fn description(&self) -> &str;
-
-    fn detail(&self) -> Option<&str> { None }
-    fn cause(&self) -> Option<&Error> { None }
-}
-
-pub trait FromError<E> {
-    fn from_err(err: E) -> Self;
-}
-
-impl Debug for Box<Error + 'static> {
-    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
-        write!(f, "{}", self.description())
-    }
-}
-
-impl<E: Error + 'static> FromError<E> for Box<Error + 'static> {
-    fn from_err(err: E) -> Box<Error + 'static> {
-        box err as Box<Error>
-    }
-}
+pub fn err(s: &str) -> CliError {
+    #[derive(Debug)]
+    struct E(String);
 
-impl<'a> Error for &'a str {
-    fn description<'b>(&'b self) -> &'b str {
-        *self
+    impl Error for E {
+        fn description(&self) -> &str { &self.0 }
     }
-}
-
-impl Error for String {
-    fn description<'a>(&'a self) -> &'a str {
-        &self[..]
+    impl fmt::Display for E {
+        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+            self.0.fmt(f)
+        }
     }
-}
-
-impl<'a> Error for Box<Error + 'a> {
-    fn description(&self) -> &str { (**self).description() }
-    fn detail(&self) -> Option<&str> { (**self).detail() }
-    fn cause(&self) -> Option<&Error> { (**self).cause() }
-}
-
-impl FromError<()> for () {
-    fn from_err(_: ()) -> () { () }
-}
 
-impl FromError<IoError> for IoError {
-    fn from_err(error: IoError) -> IoError { error }
+    Box::new(E(s.to_string()))
 }
-
-impl Error for IoError {
-    fn description(&self) -> &str {
-        self.desc
-    }
-    fn detail(&self) -> Option<&str> {
-        self.detail.as_ref().map(|s| &s[..])
-    }
-}
-
-
-//fn iter_map_err<T, U, E, I: Iterator<Result<T,E>>>(iter: I,
index 7fd8214f7311af078614aaf7ebcb4eebaa8f3569..995d2f2494a490b1845344aaa86886152a733bd9 100644 (file)
@@ -19,7 +19,7 @@ struct Help;
 
 pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
     match name {
-        "help" | "--help" | "-h" | "-?" => Some(box Help as Box<Subcommand>),
+        "help" | "--help" | "-h" | "-?" => Some(Box::new(Help)),
         _ => None
     }
 }
index ace57f0ac2c0b9351e6df4860955697cedd209b4..09fcd518c1e7e3998f32851738559f36840d845d 100644 (file)
@@ -8,31 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
-#![feature(collections)]
+#![deny(warnings)]
+
 #![feature(core)]
-#![feature(old_io)]
-#![feature(os)]
-#![feature(env)]
-#![feature(old_path)]
+#![feature(exit_status)]
 #![feature(rustdoc)]
+#![feature(rustc_private)]
+#![feature(path_relative_from)]
 
 extern crate rustdoc;
+extern crate rustc_back;
 
 use std::env;
+use std::error::Error;
 use subcommand::Subcommand;
 use term::Term;
 
-macro_rules! try (
-    ($expr:expr) => ({
-        use error;
-        match $expr {
-            Ok(val) => val,
-            Err(err) => return Err(error::FromError::from_err(err))
-        }
-    })
-);
-
 mod term;
 mod error;
 mod book;
@@ -54,17 +45,14 @@ fn main() {
     if cmd.len() <= 1 {
         help::usage()
     } else {
-        match subcommand::parse_name(&cmd[1][]) {
+        match subcommand::parse_name(&cmd[1][..]) {
             Some(mut subcmd) => {
-                match subcmd.parse_args(cmd.tail()) {
+                match subcmd.parse_args(&cmd[..cmd.len()-1]) {
                     Ok(_) => {
                         match subcmd.execute(&mut term) {
                             Ok(_) => (),
                             Err(err) => {
-                                term.err(&format!("error: {}", err.description())[]);
-                                err.detail().map(|detail| {
-                                    term.err(&format!("detail: {}", detail)[]);
-                                });
+                                term.err(&format!("error: {}", err));
                             }
                         }
                     }
index 808527dcef95eeeaa2b2b96f3dbfe37abc24e4aa..2fa7b7eed7b05d77a8bd6f58ea0b29c7a4f7bc48 100644 (file)
@@ -19,7 +19,7 @@ struct Serve;
 
 pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
     if name == "serve" {
-        Some(box Serve as Box<Subcommand>)
+        Some(Box::new(Serve))
     } else {
         None
     }
index 473739c919d64ee27fc4e3e3e40a85e3b0e29426..44af43be7877344cfd878700984662adb9f60058 100644 (file)
@@ -32,11 +32,11 @@ pub trait Subcommand {
 
 /// Create a Subcommand object based on its name.
 pub fn parse_name(name: &str) -> Option<Box<Subcommand>> {
-    for parser in [
-        help::parse_cmd as fn(&str) -> Option<Box<Subcommand>>,
-        build::parse_cmd as fn(&str) -> Option<Box<Subcommand>>,
-        serve::parse_cmd as fn(&str) -> Option<Box<Subcommand>>,
-        test::parse_cmd as fn(&str) -> Option<Box<Subcommand>>].iter() {
+    let cmds: [fn(&str) -> Option<Box<Subcommand>>; 4] = [help::parse_cmd,
+                                                          build::parse_cmd,
+                                                          serve::parse_cmd,
+                                                          test::parse_cmd];
+    for parser in cmds.iter() {
         let parsed = (*parser)(name);
         if parsed.is_some() { return parsed }
     }
index 98aa3fca184dca3f4c05e04fc9d09ba91641892d..060297beb758bc37da200710b716e19036b6ac9a 100644 (file)
 //! verbosity support. For now, just a wrapper around stdout/stderr.
 
 use std::env;
-use std::old_io::stdio;
+use std::io;
+use std::io::prelude::*;
 
 pub struct Term {
-    err: Box<Writer + 'static>
+    err: Box<Write + 'static>
 }
 
 impl Term {
     pub fn new() -> Term {
         Term {
-            err: box stdio::stderr() as Box<Writer>,
+            err: Box::new(io::stderr())
         }
     }
 
     pub fn err(&mut self, msg: &str) {
         // swallow any errors
-        let _ = self.err.write_line(msg);
+        let _ = writeln!(&mut self.err, "{}", msg);
         env::set_exit_status(101);
     }
 }
index c5d4875423ae1ee62893be77b7183018ff35ccf4..72df0768e7b9b5c70972123ec3c2425db87bbafe 100644 (file)
 //! Implementation of the `test` subcommand. Just a stub for now.
 
 use subcommand::Subcommand;
-use error::CliResult;
-use error::CommandResult;
-use error::Error;
+use error::{err, CliResult, CommandResult};
 use term::Term;
 use book;
-use std::old_io::{Command, File};
-use std::os;
+
+use std::fs::File;
+use std::env;
+use std::process::Command;
 
 struct Test;
 
 pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
     if name == "test" {
-        Some(box Test as Box<Subcommand>)
+        Some(Box::new(Test))
     } else {
         None
     }
@@ -35,11 +35,11 @@ impl Subcommand for Test {
     }
     fn usage(&self) {}
     fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
-        let cwd = os::getcwd().unwrap();
+        let cwd = env::current_dir().unwrap();
         let src = cwd.clone();
 
-        let summary = File::open(&src.join("SUMMARY.md"));
-        match book::parse_summary(summary, &src) {
+        let mut summary = try!(File::open(&src.join("SUMMARY.md")));
+        match book::parse_summary(&mut summary, &src) {
             Ok(book) => {
                 for (_, item) in book.iter() {
                     let output_result = Command::new("rustdoc")
@@ -50,15 +50,15 @@ impl Subcommand for Test {
                         Ok(output) => {
                             if !output.status.success() {
                                 term.err(&format!("{}\n{}",
-                                         String::from_utf8_lossy(&output.output[]),
-                                         String::from_utf8_lossy(&output.error[]))[]);
-                                return Err(box "Some tests failed." as Box<Error>);
+                                         String::from_utf8_lossy(&output.stdout),
+                                         String::from_utf8_lossy(&output.stderr)));
+                                return Err(err("some tests failed"));
                             }
 
                         }
                         Err(e) => {
-                            let message = format!("Could not execute `rustdoc`: {}", e);
-                            return Err(box message as Box<Error>);
+                            let message = format!("could not execute `rustdoc`: {}", e);
+                            return Err(err(&message))
                         }
                     }
                 }
@@ -67,7 +67,7 @@ impl Subcommand for Test {
                 for err in errors {
                     term.err(&err[..]);
                 }
-                return Err(box "There was an error." as Box<Error>);
+                return Err(err("there was an error"))
             }
         }
         Ok(()) // lol
index ce3090390db8e73ac904ee6fc6f742a2960fb8dc..b205d87598cfe5648912e48f9fda838de5e415aa 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "llvm/Support/CBindingWrapping.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Host.h"
 #include "llvm/Target/TargetLibraryInfo.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
 
@@ -83,6 +84,11 @@ LLVMRustCreateTargetMachine(const char *triple,
         return NULL;
     }
 
+    StringRef real_cpu = cpu;
+    if (real_cpu == "native") {
+        real_cpu = sys::getHostCPUName();
+    }
+
     TargetOptions Options;
     Options.PositionIndependentExecutable = PositionIndependentExecutable;
     Options.NoFramePointerElim = NoFramePointerElim;
@@ -96,7 +102,7 @@ LLVMRustCreateTargetMachine(const char *triple,
     }
 
     TargetMachine *TM = TheTarget->createTargetMachine(Trip.getTriple(),
-                                                       cpu,
+                                                       real_cpu,
                                                        feature,
                                                        Options,
                                                        RM,
index aaf6d8df29cadca7c9a1ef005698db269410d032..9a87c03f1c407dfd01262f630486b9b9cf2b2de6 100644 (file)
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 
-#if LLVM_VERSION_MINOR >= 5
 #include "llvm/IR/CallSite.h"
-#else
-#include "llvm/Support/CallSite.h"
-#endif
 
 //===----------------------------------------------------------------------===
 //
@@ -33,7 +29,6 @@ using namespace llvm::object;
 
 static char *LastError;
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" LLVMMemoryBufferRef
 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
   ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(Path,
@@ -45,18 +40,6 @@ LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
   }
   return wrap(buf_or.get().release());
 }
-#else
-extern "C" LLVMMemoryBufferRef
-LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
-  OwningPtr<MemoryBuffer> buf;
-  error_code err = MemoryBuffer::getFile(Path, buf, -1, false);
-  if (err) {
-      LLVMRustSetLastError(err.message().c_str());
-      return NULL;
-  }
-  return wrap(buf.take());
-}
-#endif
 
 extern "C" char *LLVMRustGetLastError(void) {
   char *ret = LastError;
@@ -116,7 +99,6 @@ extern "C" void LLVMAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uin
 }
 
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr, unsigned idx, uint64_t b) {
   CallSite Call = CallSite(unwrap<Instruction>(Instr));
   AttrBuilder B;
@@ -126,9 +108,6 @@ extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr, unsigned
                                        AttributeSet::get(Call->getContext(),
                                                          idx, B)));
 }
-#else
-extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef, unsigned, uint64_t) {}
-#endif
 
 extern "C" void LLVMAddFunctionAttribute(LLVMValueRef Fn, unsigned index, uint64_t Val) {
   Function *A = unwrap<Function>(Fn);
@@ -137,16 +116,12 @@ extern "C" void LLVMAddFunctionAttribute(LLVMValueRef Fn, unsigned index, uint64
   A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
 }
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" void LLVMAddDereferenceableAttr(LLVMValueRef Fn, unsigned index, uint64_t bytes) {
   Function *A = unwrap<Function>(Fn);
   AttrBuilder B;
   B.addDereferenceableAttr(bytes);
   A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
 }
-#else
-extern "C" void LLVMAddDereferenceableAttr(LLVMValueRef, unsigned, uint64_t) {}
-#endif
 
 extern "C" void LLVMAddFunctionAttrString(LLVMValueRef Fn, unsigned index, const char *Name) {
   Function *F = unwrap<Function>(Fn);
@@ -199,10 +174,8 @@ extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
                                                AtomicOrdering order,
                                                AtomicOrdering failure_order) {
     return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
-                                               unwrap(source), order
-#if LLVM_VERSION_MINOR >= 5
-                                               , failure_order
-#endif
+                                               unwrap(source), order,
+                                               failure_order
                                                ));
 }
 extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B, AtomicOrdering order) {
@@ -247,11 +220,7 @@ DIT unwrapDI(LLVMMetadataRef ref) {
     return DIT(ref ? unwrap<MDNode>(ref) : NULL);
 }
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" const uint32_t LLVMRustDebugMetadataVersion = DEBUG_METADATA_VERSION;
-#else
-extern "C" const uint32_t LLVMRustDebugMetadataVersion = 1;
-#endif
 
 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
                                       const char *name,
@@ -383,10 +352,8 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType(
         unwrapDI<DIType>(DerivedFrom),
         unwrapDI<DIArray>(Elements),
         RunTimeLang,
-        unwrapDI<DIType>(VTableHolder)
-#if LLVM_VERSION_MINOR >= 4
-        ,UniqueId
-#endif
+        unwrapDI<DIType>(VTableHolder),
+        UniqueId
         ));
 }
 
@@ -465,8 +432,8 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
 #if LLVM_VERSION_MINOR < 6
     if (AddrOpsCount > 0) {
         SmallVector<llvm::Value *, 16> addr_ops;
-        llvm::Type *Int64Ty = Type::getInt64Ty(VMContext);
-        for (int i = 0; i < AddrOpsCount; ++i)
+        llvm::Type *Int64Ty = Type::getInt64Ty(unwrap<MDNode>(Scope)->getContext());
+        for (unsigned i = 0; i < AddrOpsCount; ++i)
             addr_ops.push_back(ConstantInt::get(Int64Ty, AddrOps[i]));
 
         return wrap(Builder->createComplexVariable(
@@ -522,7 +489,11 @@ extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(
     LLVMMetadataRef* Ptr,
     unsigned Count) {
     return wrap(Builder->getOrCreateArray(
+#if LLVM_VERSION_MINOR >= 6
         ArrayRef<Metadata*>(unwrap(Ptr), Count)));
+#else
+        ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
+#endif
 }
 
 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
@@ -627,19 +598,11 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType(
         AlignInBits,
         Flags,
         unwrapDI<DIArray>(Elements),
-        RunTimeLang
-#if LLVM_VERSION_MINOR >= 4
-        ,UniqueId
-#endif
+        RunTimeLang,
+        UniqueId
         ));
 }
 
-#if LLVM_VERSION_MINOR < 5
-extern "C" void LLVMSetUnnamedAddr(LLVMValueRef Value, LLVMBool Unnamed) {
-    unwrap<GlobalValue>(Value)->setUnnamedAddr(Unnamed);
-}
-#endif
-
 extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter(
     DIBuilderRef Builder,
     LLVMMetadataRef Scope,
@@ -730,7 +693,6 @@ extern "C" void LLVMWriteValueToString(LLVMValueRef Value, RustStringRef str) {
     os << ")";
 }
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" bool
 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
     Module *Dst = unwrap(dst);
@@ -763,28 +725,7 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
     }
     return true;
 }
-#else
-extern "C" bool
-LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
-    Module *Dst = unwrap(dst);
-    MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
-    std::string Err;
-    Module *Src = llvm::getLazyBitcodeModule(buf, Dst->getContext(), &Err);
-    if (!Src) {
-        LLVMRustSetLastError(Err.c_str());
-        delete buf;
-        return false;
-    }
-
-    if (Linker::LinkModules(Dst, Src, Linker::DestroySource, &Err)) {
-        LLVMRustSetLastError(Err.c_str());
-        return false;
-    }
-    return true;
-}
-#endif
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" void*
 LLVMRustOpenArchive(char *path) {
     ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path,
@@ -817,23 +758,6 @@ LLVMRustOpenArchive(char *path) {
 
     return ret;
 }
-#else
-extern "C" void*
-LLVMRustOpenArchive(char *path) {
-    OwningPtr<MemoryBuffer> buf;
-    error_code err = MemoryBuffer::getFile(path, buf, -1, false);
-    if (err) {
-        LLVMRustSetLastError(err.message().c_str());
-        return NULL;
-    }
-    Archive *ret = new Archive(buf.take(), err);
-    if (err) {
-        LLVMRustSetLastError(err.message().c_str());
-        return NULL;
-    }
-    return ret;
-}
-#endif
 
 extern "C" const char*
 #if LLVM_VERSION_MINOR >= 6
@@ -844,21 +768,12 @@ LLVMRustArchiveReadSection(OwningBinary<Archive> *ob, char *name, size_t *size)
 LLVMRustArchiveReadSection(Archive *ar, char *name, size_t *size) {
 #endif
 
-#if LLVM_VERSION_MINOR >= 5
     Archive::child_iterator child = ar->child_begin(),
                               end = ar->child_end();
     for (; child != end; ++child) {
         ErrorOr<StringRef> name_or_err = child->getName();
         if (name_or_err.getError()) continue;
         StringRef sect_name = name_or_err.get();
-#else
-    Archive::child_iterator child = ar->begin_children(),
-                              end = ar->end_children();
-    for (; child != end; ++child) {
-        StringRef sect_name;
-        error_code err = child->getName(sect_name);
-        if (err) continue;
-#endif
         if (sect_name.trim(" ") == name) {
             StringRef buf = child->getBuffer();
             *size = buf.size();
@@ -877,18 +792,11 @@ LLVMRustDestroyArchive(Archive *ar) {
     delete ar;
 }
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" void
 LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
     GlobalValue *V = unwrap<GlobalValue>(Value);
     V->setDLLStorageClass(GlobalValue::DLLExportStorageClass);
 }
-#else
-extern "C" void
-LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
-    LLVMSetLinkage(Value, LLVMDLLExportLinkage);
-}
-#endif
 
 extern "C" int
 LLVMVersionMinor() {
@@ -918,11 +826,7 @@ inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
 extern "C" int
 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
     StringRef ret;
-#if LLVM_VERSION_MINOR >= 5
     if (std::error_code ec = (*unwrap(SI))->getName(ret))
-#else
-    if (error_code ec = (*unwrap(SI))->getName(ret))
-#endif
       report_fatal_error(ec.message());
     *ptr = ret.data();
     return ret.size();
index 1317343712430d241e9115d1c70fd69d63a57e4c..1ea40fc46a52196764be269294605440a042f794 100644 (file)
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2015-02-13
+2015-03-04
index 4759c44259d5289d7a71a29b47a6ff1387882c2f..5d265478b64da2575ea1e08427f19a8f3ee56f3f 100644 (file)
@@ -1,3 +1,62 @@
+S 2015-03-27 5520801
+  bitrig-x86_64 55a69b0ae5481ccda54c2fcfc54025a0945c4f57
+  freebsd-x86_64 0910bbad35e213f679d0433884fd51398eb3bc8d
+  linux-i386 1ef82402ed16f5a6d2f87a9a62eaa83170e249ec
+  linux-x86_64 ef2154372e97a3cb687897d027fd51c8f2c5f349
+  macos-i386 0310b1a970f2da7e61770fd14dbbbdca3b518234
+  macos-x86_64 5f35d9c920b8083a7420ef8cf5b00d5ef3085dfa
+  winnt-i386 808b7961f85872f04ec15ad0d3e9e23ae9bc0c3b
+  winnt-x86_64 903a99a58f57a9bd9848cc68a2445dda881f1ee8
+
+S 2015-03-25 a923278
+  bitrig-x86_64 e56c400a04bca7b52ab54e0780484bb68fa449c2
+  freebsd-x86_64 cd02c86a9218da73b2a45aff293787010d33bf3e
+  linux-i386 da50141558eed6dabab97b79b2c6a7de4f2d2c5e
+  linux-x86_64 bca03458d28d07506bad4b80e5770b2117286244
+  macos-i386 522d59b23dd885a45e2c5b33e80e76240bb2d9af
+  macos-x86_64 82df09d51d73d119a2f4e4d8041879615cb22081
+  winnt-i386 5056e8def5ab4f4283b8f3aab160cc10231bb28d
+  winnt-x86_64 3f6b35ac12625b4b4b42dfd5eee5f6cbf122794e
+
+S 2015-03-17 c64d671
+  bitrig-x86_64 41de2c7a69a1ac648d3fa3b65e96a29bdc122163
+  freebsd-x86_64 14ced24e1339a4dd8baa9db69995daa52a948d54
+  linux-i386 200450ad3cc56bc715ca105b9acae35204bf7351
+  linux-x86_64 a54f50fee722ba6bc7281dec3e4d5121af7c15e3
+  macos-i386 e33fd692f3808a0265e7b02fbc40e403080cdd4f
+  macos-x86_64 9a89ed364ae71aeb9d659ad223eae5f5986fc03f
+  winnt-i386 8911a28581e490d413b56467a6184545633ca04a
+  winnt-x86_64 38ce4556b19472c23ccce28685e3a2ebefb9bfbc
+
+S 2015-03-07 270a677
+  bitrig-x86_64 4b2f11a96b1b5b3782d74bda707aca33bc179880
+  freebsd-x86_64 3c147d8e4cfdcb02c2569f5aca689a1d8920d17b
+  linux-i386 50a47ef247610fb089d2c4f24e4b641eb0ba4afb
+  linux-x86_64 ccb20709b3c984f960ddde996451be8ce2268d7c
+  macos-i386 ad263bdeadcf9bf1889426e0c1391a7cf277364e
+  macos-x86_64 01c8275828042264206b7acd8e86dc719a2f27aa
+  winnt-i386 cb73ac7a9bf408e8b5cdb92d595082a537a90794
+  winnt-x86_64 b9b47e80101f726ae4f5919373ea20b92d827f3c
+
+S 2015-02-25 880fb89
+  bitrig-x86_64 8cdc4ca0a80103100f46cbf8caa9fe497df048c5
+  freebsd-x86_64 f4cbe4227739de986444211f8ee8d74745ab8f7f
+  linux-i386 3278ebbce8cb269acc0614dac5ddac07eab6a99c
+  linux-x86_64 72287d0d88de3e5a53bae78ac0d958e1a7637d73
+  macos-i386 33b366b5287427a340a0aa6ed886d5ff4edf6a76
+  macos-x86_64 914bf9baa32081a9d5633f1d06f4d382cd71504e
+  winnt-i386 d58b415b9d8629cb6c4952f1f6611a526a38323f
+  winnt-x86_64 2cb1dcc563d2ac6deada054de15748f5dd599c7e
+
+S 2015-02-19 522d09d
+  freebsd-x86_64 7ea14ef85a25bca70a310a2cd660b356cf61abc7
+  linux-i386 26e3caa1ce1c482b9941a6bdc64b3e65d036c200
+  linux-x86_64 44f514aabb4e4049e4db9a4e1fdeb16f6cee60f2
+  macos-i386 157910592224083df56f5f31ced3e6f3dc9b1de0
+  macos-x86_64 56c28aa0e14ec6991ad6ca213568f1155561105d
+  winnt-i386 da0f7a3fbc913fbb177917f2850bb41501affb5c
+  winnt-x86_64 22bd816ccd2690fc9804b27ca525f603be8aeaa5
+
 S 2015-02-17 f1bb6c2
   freebsd-x86_64 59f3a2c6350c170804fb65838e1b504eeab89105
   linux-i386 191ed5ec4f17e32d36abeade55a1c6085e51245c
index e56df439bc2a5c96bc1d3ad33e5a3d4769283448..bd23fb88217080d03513fa505f448a2d7148e402 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 trait me {
-    fn me(&self) -> uint;
+    fn me(&self) -> usize;
 }
-impl me for uint { fn me(&self) -> uint { *self } }
+impl me for usize { fn me(&self) -> usize { *self } }
index 12ab62267a363c1a5d4ff88ef7d0afdbe66d6d6f..197fb9a6d018c488ae9e81522666859c4e32d58a 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![crate_name="anonexternmod"]
+#![feature(libc)]
 
 extern crate libc;
 
index 666d2569c42b41275f3f7596ef77af22bfec6557..9d93d9689e737c94cd369ff800b2b06d51ba6687 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub struct Foo {
-    pub x: int
+    pub x: isize
 }
 
 impl Foo {
index 44fbcf2150a4bf9050ad727622351f4806cd10d4..b3960c2707b4b81c71a928c867837e64396e6518 100644 (file)
@@ -19,8 +19,8 @@ pub trait Bar {
     fn get(x: Option<Self>) -> <Self as Bar>::T;
 }
 
-impl Bar for int {
-    type T = uint;
+impl Bar for isize {
+    type T = usize;
 
-    fn get(_: Option<int>) -> uint { 22 }
+    fn get(_: Option<isize>) -> usize { 22 }
 }
index 96af3203066c7e6c79ae55d9ef7d155d74488886..9c90510a8573e7bb5dab27678bc5c84d2a537b16 100644 (file)
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn foo(x: &uint) -> uint {
+pub fn foo(x: &usize) -> usize {
     *x
 }
index 50116b397372f6319e97e31000d3c6d1a9b7a9ad..08a13fd8bcc9ab47cedd21cb844ad22c56b85da7 100644 (file)
 
 pub mod kitties {
     pub struct cat {
-      meows : uint,
+      meows : usize,
 
-      pub how_hungry : int,
+      pub how_hungry : isize,
     }
 
-    pub fn cat(in_x : uint, in_y : int) -> cat  {
+    pub fn cat(in_x : usize, in_y : isize) -> cat  {
         cat {
             meows: in_x,
             how_hungry: in_y
index 55fb424205eb82de2a389bfdd178375391592438..7d147832f09437f40d12ec428220de0884462ab6 100644 (file)
@@ -10,9 +10,9 @@
 
 pub mod kitties {
     pub struct cat {
-      meows : uint,
+      meows : usize,
 
-      pub how_hungry : int,
+      pub how_hungry : isize,
 
     }
 
@@ -20,7 +20,7 @@ pub mod kitties {
         pub fn speak(&self) {}
     }
 
-    pub fn cat(in_x : uint, in_y : int) -> cat {
+    pub fn cat(in_x : usize, in_y : isize) -> cat {
         cat {
             meows: in_x,
             how_hungry: in_y
index 98881eb09bf9bc89848da0b64cee29cfc309cb6e..ec1bf108dcb007145909d00f1fdac1ab3c652967 100644 (file)
 
 pub mod kitties {
     pub struct cat {
-        meows : uint,
+        meows : usize,
 
-        pub how_hungry : int,
+        pub how_hungry : isize,
     }
 
     impl cat {
-        pub fn speak(&mut self) { self.meows += 1_usize; }
-        pub fn meow_count(&mut self) -> uint { self.meows }
+        pub fn speak(&mut self) { self.meows += 1; }
+        pub fn meow_count(&mut self) -> usize { self.meows }
     }
 
-    pub fn cat(in_x : uint, in_y : int) -> cat {
+    pub fn cat(in_x : usize, in_y : isize) -> cat {
         cat {
             meows: in_x,
             how_hungry: in_y
index 9d7905cdebd04eb10cb8f1ccca51fe02c1bea8ab..300cc31632e40e7375004841fd67d642746dd285 100644 (file)
@@ -10,9 +10,9 @@
 
 pub mod kitties {
     pub struct cat {
-        meows : uint,
+        meows : usize,
 
-        pub how_hungry : int,
+        pub how_hungry : isize,
         pub name : String,
     }
 
@@ -34,14 +34,14 @@ pub mod kitties {
     impl cat {
         pub fn meow(&mut self) {
             println!("Meow");
-            self.meows += 1_usize;
-            if self.meows % 5_usize == 0_usize {
+            self.meows += 1;
+            if self.meows % 5 == 0 {
                 self.how_hungry += 1;
             }
         }
     }
 
-    pub fn cat(in_x : uint, in_y : int, in_name: String) -> cat {
+    pub fn cat(in_x : usize, in_y : isize, in_name: String) -> cat {
         cat {
             meows: in_x,
             how_hungry: in_y,
index d113859a6bdc773100df08f3e9e477c38fa9c0d4..7fe608f1634c2d91574d2aa66ece0d0ded301f93 100644 (file)
 
 pub mod kitties {
     pub struct cat {
-        meows : uint,
-        pub how_hungry : int,
+        meows : usize,
+        pub how_hungry : isize,
     }
 
     impl cat {
         fn nap(&self) {}
     }
 
-    pub fn cat(in_x : uint, in_y : int) -> cat {
+    pub fn cat(in_x : usize, in_y : isize) -> cat {
         cat {
             meows: in_x,
             how_hungry: in_y
index 71552f4c97efce71317c439c77c218467c395cf2..c902a6c7dca89dbbe8fe8f79427c1c35d1ecee78 100644 (file)
@@ -12,9 +12,9 @@ pub mod kitties {
 
     pub struct cat<U> {
         info : Vec<U> ,
-        meows : uint,
+        meows : usize,
 
-        pub how_hungry : int,
+        pub how_hungry : isize,
     }
 
     impl<U> cat<U> {
@@ -22,10 +22,10 @@ pub mod kitties {
             self.meows += stuff.len();
         }
 
-        pub fn meow_count(&mut self) -> uint { self.meows }
+        pub fn meow_count(&mut self) -> usize { self.meows }
     }
 
-    pub fn cat<U>(in_x : uint, in_y : int, in_info: Vec<U> ) -> cat<U> {
+    pub fn cat<U>(in_x : usize, in_y : isize, in_info: Vec<U> ) -> cat<U> {
         cat {
             meows: in_x,
             how_hungry: in_y,
index dd272bf639b9723cb53da920f1c2502b250266ac..f54a39d61ef3ed0dd53bdfc2efb389e2f3e8ea54 100644 (file)
@@ -12,12 +12,12 @@ pub mod kitty {
     use std::fmt;
 
     pub struct cat {
-      meows : uint,
-      pub how_hungry : int,
+      meows : usize,
+      pub how_hungry : isize,
       pub name : String,
     }
 
-    impl fmt::String for cat {
+    impl fmt::Display for cat {
         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             write!(f, "{}", self.name)
         }
@@ -26,8 +26,8 @@ pub mod kitty {
     impl cat {
         fn meow(&mut self) {
             println!("Meow");
-            self.meows += 1_usize;
-            if self.meows % 5_usize == 0_usize {
+            self.meows += 1;
+            if self.meows % 5 == 0 {
                 self.how_hungry += 1;
             }
         }
@@ -50,7 +50,7 @@ pub mod kitty {
         }
     }
 
-    pub fn cat(in_x : uint, in_y : int, in_name: String) -> cat {
+    pub fn cat(in_x : usize, in_y : isize, in_name: String) -> cat {
         cat {
             meows: in_x,
             how_hungry: in_y,
index 945004ede6de84518702b6e889d6027d3f2258a6..ee8290050f91babafb87664c20cd087fa1262b58 100644 (file)
@@ -12,5 +12,5 @@ pub extern fn bar() {
 }
 
 pub const foopy: &'static str = "hi there";
-pub const uint_val: uint = 12;
-pub const uint_expr: uint = (1 << uint_val) - 1;
+pub const uint_val: usize = 12;
+pub const uint_expr: usize = (1 << uint_val) - 1;
index a3bcbd201e199ef2f130f1bfdacdabdf300d055e..76fe9fe5aa40a6a73b8c8f7dd8a90c12b75fead0 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub static BLOCK_FN_DEF: fn(uint) -> uint = {
-    fn foo(a: uint) -> uint {
+pub static BLOCK_FN_DEF: fn(usize) -> usize = {
+    fn foo(a: usize) -> usize {
         a + 10
     }
     foo
index 6ee497370e8e33da19591b74937a8327ba3493fd..d8921f4e09a8a0bd2fb79cea5f2e547a482cb537 100644 (file)
 #![crate_name="cci_impl_lib"]
 
 pub trait uint_helpers {
-    fn to<F>(&self, v: uint, f: F) where F: FnMut(uint);
+    fn to<F>(&self, v: usize, f: F) where F: FnMut(usize);
 }
 
-impl uint_helpers for uint {
+impl uint_helpers for usize {
     #[inline]
-    fn to<F>(&self, v: uint, mut f: F) where F: FnMut(uint) {
+    fn to<F>(&self, v: usize, mut f: F) where F: FnMut(usize) {
         let mut i = *self;
         while i < v {
             f(i);
-            i += 1_usize;
+            i += 1;
         }
     }
 }
index a3a3dbac2b5515ca0b5d4eb3aff5f659c7bb615f..b6e69d29f70cd48dc45a44ea0542361c69890183 100644 (file)
@@ -17,7 +17,7 @@ pub mod rusti {
 }
 
 #[inline(always)]
-pub fn atomic_xchg(dst: *mut int, src: int) -> int {
+pub fn atomic_xchg(dst: *mut isize, src: isize) -> isize {
     unsafe {
         rusti::atomic_xchg(dst, src)
     }
index 8e00b0dc7be74f444d5234084a323a4b2234160b..07d03b4c7590ff9d66d6e9d2fd8beff8245759dc 100644 (file)
 
 #[inline]
 pub fn iter<T, F>(v: &[T], mut f: F) where F: FnMut(&T) {
-    let mut i = 0_usize;
+    let mut i = 0;
     let n = v.len();
     while i < n {
         f(&v[i]);
-        i += 1_usize;
+        i += 1;
     }
 }
index 587af956c77caad3d4c4c81adf830af7a23cba7d..8c1a283a72d77b98e3909af7c7e858e104c9b262 100644 (file)
@@ -44,8 +44,8 @@ pub fn alist_get<A:Clone + 'static,
 }
 
 #[inline]
-pub fn new_int_alist<B:'static>() -> alist<int, B> {
-    fn eq_int(a: int, b: int) -> bool { a == b }
+pub fn new_int_alist<B:'static>() -> alist<isize, B> {
+    fn eq_int(a: isize, b: isize) -> bool { a == b }
     return alist {
         eq_fn: eq_int,
         data: box RefCell::new(Vec::new()),
@@ -53,9 +53,9 @@ pub fn new_int_alist<B:'static>() -> alist<int, B> {
 }
 
 #[inline]
-pub fn new_int_alist_2<B:'static>() -> alist<int, B> {
+pub fn new_int_alist_2<B:'static>() -> alist<isize, B> {
     #[inline]
-    fn eq_int(a: int, b: int) -> bool { a == b }
+    fn eq_int(a: isize, b: isize) -> bool { a == b }
     return alist {
         eq_fn: eq_int,
         data: box RefCell::new(Vec::new()),
index ce041118906ed9a2f9c174e454000d9248493648..4c6f808c6192040a0fcc3e84ab4d9ecee1b47d5f 100644 (file)
 
 
 // same as cci_iter_lib, more-or-less, but not marked inline
-pub fn iter<F>(v: Vec<uint> , mut f: F) where F: FnMut(uint) {
-    let mut i = 0_usize;
+pub fn iter<F>(v: Vec<usize> , mut f: F) where F: FnMut(usize) {
+    let mut i = 0;
     let n = v.len();
     while i < n {
         f(v[i]);
-        i += 1_usize;
+        i += 1;
     }
 }
index 4331a1da2a26b62af83e6fc372a618609b08f045..b5b4390657b4f18d648421a75cf7286dbd28dd72 100644 (file)
@@ -11,7 +11,7 @@
 // this used to just ICE on compiling
 pub fn foo() {
     if cfg!(foo) {
-        static a: int = 3;
+        static a: isize = 3;
         a
     } else { 3 };
 }
index a54dcbbbfc24538eadf991054b8794c708601e47..28eae023d684b6186682116279b3965266e74323 100644 (file)
@@ -11,4 +11,3 @@
 #![crate_name = "a"]
 
 pub fn foo<T>() { println!("hello!"); }
-
index 81f924e29daa73f29bece01f2100224249b69714..7b1190fc085802ce00142236eec74bbbb979b127 100644 (file)
@@ -12,4 +12,4 @@
 
 extern crate a;
 
-pub fn foo() { a::foo::<int>(); }
+pub fn foo() { a::foo::<isize>(); }
index b5c2a4f135fe2c0101f396b5c7a1a13a57a2dc61..c0d81cd8e1bad335e807e7346044895240f3e662 100644 (file)
@@ -10,6 +10,8 @@
 
 // Helper definition for test/run-pass/check-static-recursion-foreign.rs.
 
+#![feature(libc)]
+
 #[crate_id = "check_static_recursion_foreign_helper"]
 #[crate_type = "lib"]
 
diff --git a/src/test/auxiliary/coherence-lib.rs b/src/test/auxiliary/coherence-lib.rs
deleted file mode 100644 (file)
index daa1238..0000000
+++ /dev/null
@@ -1,25 +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.
-
-#![crate_type="lib"]
-
-pub trait Remote {
-    fn foo(&self) { }
-}
-
-pub trait Remote1<T> {
-    fn foo(&self, t: T) { }
-}
-
-pub trait Remote2<T, U> {
-    fn foo(&self, t: T, u: U) { }
-}
-
-pub struct Pair<T,U>(T,U);
diff --git a/src/test/auxiliary/coherence-orphan-lib.rs b/src/test/auxiliary/coherence-orphan-lib.rs
deleted file mode 100644 (file)
index cc42b28..0000000
+++ /dev/null
@@ -1,14 +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.
-
-pub trait TheTrait<T> : ::std::marker::PhantomFn<T> {
-    fn the_fn(&self);
-}
-
diff --git a/src/test/auxiliary/coherence_copy_like_lib.rs b/src/test/auxiliary/coherence_copy_like_lib.rs
new file mode 100644 (file)
index 0000000..a1e1b48
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2015 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.
+
+#![crate_type = "rlib"]
+#![feature(fundamental)]
+
+use std::marker::MarkerTrait;
+
+pub trait MyCopy : MarkerTrait { }
+impl MyCopy for i32 { }
+
+pub struct MyStruct<T>(T);
+
+#[fundamental]
+pub struct MyFundamentalStruct<T>(T);
diff --git a/src/test/auxiliary/coherence_lib.rs b/src/test/auxiliary/coherence_lib.rs
new file mode 100644 (file)
index 0000000..daa1238
--- /dev/null
@@ -0,0 +1,25 @@
+// 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.
+
+#![crate_type="lib"]
+
+pub trait Remote {
+    fn foo(&self) { }
+}
+
+pub trait Remote1<T> {
+    fn foo(&self, t: T) { }
+}
+
+pub trait Remote2<T, U> {
+    fn foo(&self, t: T, u: U) { }
+}
+
+pub struct Pair<T,U>(T,U);
diff --git a/src/test/auxiliary/coherence_orphan_lib.rs b/src/test/auxiliary/coherence_orphan_lib.rs
new file mode 100644 (file)
index 0000000..93d8fd3
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+pub trait TheTrait<T> : ::std::marker::PhantomFn<T> {
+    fn the_fn(&self);
+}
diff --git a/src/test/auxiliary/crate_with_invalid_spans.rs b/src/test/auxiliary/crate_with_invalid_spans.rs
new file mode 100644 (file)
index 0000000..b37533d
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2015 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.
+
+#![crate_type = "rlib"]
+// no-prefer-dynamic
+
+// compile-flags: -g
+
+#[macro_use]
+mod crate_with_invalid_spans_macros;
+
+pub fn exported_generic<T>(x: T, y: u32) -> (T, u32) {
+    // Using the add1 macro will produce an invalid span, because the `y` passed
+    // to the macro will have a span from this file, but the rest of the code
+    // generated from the macro will have spans from the macro-defining file.
+    // The AST node for the (1 + y) expression generated by the macro will then
+    // take it's `lo` span bound from the `1` literal in the macro-defining file
+    // and it's `hi` bound from `y` in this file, which should be lower than the
+    // `lo` and even lower than the lower bound of the FileMap it is supposedly
+    // contained in because the FileMap for this file was allocated earlier than
+    // the FileMap of the macro-defining file.
+    return (x, add1!(y));
+}
diff --git a/src/test/auxiliary/crate_with_invalid_spans_macros.rs b/src/test/auxiliary/crate_with_invalid_spans_macros.rs
new file mode 100644 (file)
index 0000000..112315a
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+macro_rules! add1 {
+    ($e:expr) => ({
+        let a = 1 + $e;
+        let b = $e + 1;
+        a + b - 1
+    })
+}
index e26ea7c4fa6d0b73b79e49c83722512ccd5549fa..050f2fe732935e84799dc479f30d95e7b664b2b7 100644 (file)
@@ -12,4 +12,4 @@
 #![crate_name = "crateresolve1"]
 #![crate_type = "lib"]
 
-pub fn f() -> int { 10 }
+pub fn f() -> isize { 10 }
index 715171b143a4a46686e59ad3ab168f2a52a6a272..d19b3bafba5075a49fe327811b8f93fd78b15746 100644 (file)
@@ -12,4 +12,4 @@
 #![crate_name = "crateresolve1"]
 #![crate_type = "lib"]
 
-pub fn f() -> int { 20 }
+pub fn f() -> isize { 20 }
index f733b5b908ab49aff407753905edf2a33317e185..c5096ac49a885189b29c3f793096d2d46644848a 100644 (file)
@@ -12,4 +12,4 @@
 #![crate_name = "crateresolve1"]
 #![crate_type = "lib"]
 
-pub fn f() -> int { 30 }
+pub fn f() -> isize { 30 }
index 473528c681e7fb9eda5cc1530c130c56ece3cef1..0e02a8d96a3b2bc52eca85aa3a63f4617ef91032 100644 (file)
@@ -12,4 +12,4 @@
 
 #![crate_type = "lib"]
 
-pub fn f() -> int { 10 }
+pub fn f() -> isize { 10 }
index 1e95fa6b63903fcdcb7390d61670a468f303ce7d..6a11465b27ca077b67f55619e4f981847040dfcf 100644 (file)
@@ -12,4 +12,4 @@
 
 #![crate_type = "lib"]
 
-pub fn g() -> int { 20 }
+pub fn g() -> isize { 20 }
index 68a69f6dc9073c90c397b65be42581faa0bfa000..579e93aa059c68654baeff2131ef12f7f7c8fd53 100644 (file)
@@ -11,4 +11,4 @@
 #![crate_name="crateresolve4a#0.1"]
 #![crate_type = "lib"]
 
-pub fn f() -> int { 10 }
+pub fn f() -> isize { 10 }
index 6e23fddbce7dffbe10a209840647f234ced818f0..7da96e07b3f05628ded6c9f395e218e1cb3922dc 100644 (file)
@@ -11,4 +11,4 @@
 #![crate_name="crateresolve4a#0.2"]
 #![crate_type = "lib"]
 
-pub fn g() -> int { 20 }
+pub fn g() -> isize { 20 }
index 843fd57ee40d745641e39eed9b50173e63e37d57..9e4b0d158ecb90ae5a5dc92e29b9095bd5fd28d9 100644 (file)
@@ -15,4 +15,4 @@
 
 extern crate "crateresolve4a#0.2" as crateresolve4a;
 
-pub fn f() -> int { crateresolve4a::g() }
+pub fn f() -> isize { crateresolve4a::g() }
index 28c89c79316e2a31f395c6703ed27a3cd0f0c92a..a50b8dbf957eae57679298b070be0c508be4f29e 100644 (file)
@@ -15,4 +15,4 @@
 
 extern crate "crateresolve4a#0.1" as crateresolve4a;
 
-pub fn g() -> int { crateresolve4a::f() }
+pub fn g() -> isize { crateresolve4a::f() }
index 223e4f50ae8acb03ccc8ad15df9d37d5e88d3bd3..eaec37ed417d06afe8bcfee37d338d28a170515e 100644 (file)
@@ -12,7 +12,7 @@
 
 #![crate_type = "lib"]
 
-pub struct NameVal { pub name: String, pub val: int }
+pub struct NameVal { pub name: String, pub val: isize }
 
 pub fn struct_nameval() -> NameVal {
     NameVal { name: "crateresolve5".to_string(), val: 10 }
@@ -31,4 +31,4 @@ impl PartialEq for e {
     fn ne(&self, other: &e) -> bool { !nominal_eq(*self, *other) }
 }
 
-pub fn f() -> int { 10 }
+pub fn f() -> isize { 10 }
index 38740886b37ea18edb985fb03bc1eca85787be67..14d28c709cdb56f8a08ed738b2aaf9485285ef74 100644 (file)
@@ -12,7 +12,7 @@
 
 #![crate_type = "lib"]
 
-pub struct NameVal { pub name: String, pub val: int }
+pub struct NameVal { pub name: String, pub val: isize }
 pub fn struct_nameval() -> NameVal {
     NameVal { name: "crateresolve5".to_string(), val: 10 }
 }
@@ -30,4 +30,4 @@ pub fn nominal() -> e { e_val }
 
 pub fn nominal_neq(_e1: e, _e2: e) -> bool { false }
 
-pub fn f() -> int { 20 }
+pub fn f() -> isize { 20 }
index 801ace7d80492c1a2af85e2b2f91cf51edec837d..c05d292eaea47a395c115d08b5b1e6290da89061 100644 (file)
 // These both have the same version but differ in other metadata
 pub mod a {
     extern crate cr_1 (name = "crateresolve_calories", vers = "0.1", calories="100");
-    pub fn f() -> int { cr_1::f() }
+    pub fn f() -> isize { cr_1::f() }
 }
 
 pub mod b {
     extern crate cr_2 (name = "crateresolve_calories", vers = "0.1", calories="200");
-    pub fn f() -> int { cr_2::f() }
+    pub fn f() -> isize { cr_2::f() }
 }
index 5262d662971a43c82f573d45a57cd97e5ecfe9ba..bc2a2d83bfec120db02d76c7d53bff421bdab85d 100644 (file)
@@ -13,4 +13,4 @@
 
 #![crate_type = "lib"]
 
-pub fn f() -> int { 20 }
+pub fn f() -> isize { 20 }
index 4dba722971e3cd7e4cee8964147e841ab7c112ed..c1705d687abb00bf6fbdad445cc6151b77b0c23c 100644 (file)
@@ -11,4 +11,4 @@
 #![crate_name="crateresolve_calories#0.1"]
 #![crate_type = "lib"]
 
-pub fn f() -> int { 100 }
+pub fn f() -> isize { 100 }
index c7e26c8f506d43f1ef5c466176266cefb727c474..2ae87daab4e29b63f4498b9c0ac40678a752564e 100644 (file)
@@ -11,4 +11,4 @@
 #![crate_name="crateresolve_calories#0.1"]
 #![crate_type = "lib"]
 
-pub fn f() -> int { 200 }
+pub fn f() -> isize { 200 }
diff --git a/src/test/auxiliary/cross_crate_spans.rs b/src/test/auxiliary/cross_crate_spans.rs
new file mode 100644 (file)
index 0000000..91a480a
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2013-2015 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.
+
+#![crate_type = "rlib"]
+#![omit_gdb_pretty_printer_section]
+
+// no-prefer-dynamic
+// compile-flags:-g
+
+pub fn generic_function<T: Clone>(val: T) -> (T, T) {
+    let result = (val.clone(), val.clone());
+    let a_variable: u32 = 123456789;
+    let another_variable: f64 = 123456789.5;
+    zzz();
+    result
+}
+
+#[inline(never)]
+fn zzz() {()}
diff --git a/src/test/auxiliary/custom_derive_plugin.rs b/src/test/auxiliary/custom_derive_plugin.rs
new file mode 100644 (file)
index 0000000..e268896
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright 2015 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.
+
+// force-host
+
+#![feature(plugin_registrar)]
+#![feature(box_syntax)]
+#![feature(rustc_private)]
+
+extern crate syntax;
+extern crate rustc;
+
+use syntax::ast;
+use syntax::codemap::Span;
+use syntax::ext::base::{Decorator, ExtCtxt};
+use syntax::ext::build::AstBuilder;
+use syntax::ext::deriving::generic::{cs_fold, TraitDef, MethodDef, combine_substructure};
+use syntax::ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self};
+use syntax::parse::token;
+use syntax::ptr::P;
+use rustc::plugin::Registry;
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_syntax_extension(
+        token::intern("derive_TotalSum"),
+        Decorator(box expand));
+}
+
+fn expand(cx: &mut ExtCtxt,
+          span: Span,
+          mitem: &ast::MetaItem,
+          item: &ast::Item,
+          push: &mut FnMut(P<ast::Item>)) {
+    let trait_def = TraitDef {
+        span: span,
+        attributes: vec![],
+        path: Path::new(vec!["TotalSum"]),
+        additional_bounds: vec![],
+        generics: LifetimeBounds::empty(),
+        associated_types: vec![],
+        methods: vec![
+            MethodDef {
+                name: "total_sum",
+                generics: LifetimeBounds::empty(),
+                explicit_self: borrowed_explicit_self(),
+                args: vec![],
+                ret_ty: Literal(Path::new_local("isize")),
+                attributes: vec![],
+                combine_substructure: combine_substructure(box |cx, span, substr| {
+                    let zero = cx.expr_int(span, 0);
+                    cs_fold(false,
+                            |cx, span, subexpr, field, _| {
+                                cx.expr_binary(span, ast::BiAdd, subexpr,
+                                    cx.expr_method_call(span, field,
+                                        token::str_to_ident("total_sum"), vec![]))
+                            },
+                            zero,
+                            box |cx, span, _, _| { cx.span_bug(span, "wtf??"); },
+                            cx, span, substr)
+                }),
+            },
+        ],
+    };
+
+    trait_def.expand(cx, mitem, item, |i| push(i))
+}
index 0a65174911ec7149b473c4e9216bb35e2c173a27..fe852e5d8eaee4c95df68851587fde0643bb912e 100644 (file)
@@ -13,4 +13,3 @@ pub struct Heap;
 pub struct FakeHeap;
 
 pub struct FakeVec<T, A = FakeHeap> { pub f: Option<(T,A)> }
-
index 0e3b531e4581c90455bf9bfadb160cfd20b276d6..fc2e328f68657e65c58f724a1fef960d62dd688b 100644 (file)
@@ -10,6 +10,7 @@
 
 #![crate_name="externcallback"]
 #![crate_type = "lib"]
+#![feature(libc)]
 
 extern crate libc;
 
index d7e84a474e849e433fdb9fb7d662c8d782a8dda9..91a404bbba3935c4c9e2c802a303f69641aaa7b2 100644 (file)
@@ -13,7 +13,7 @@
 
 #[inline(never)]
 #[cfg(target_arch = "x86_64")]
-pub extern "win64" fn foo(a: int, b: int, c: int, d: int) {
+pub extern "win64" fn foo(a: isize, b: isize, c: isize, d: isize) {
     assert!(a == 1);
     assert!(b == 2);
     assert!(c == 3);
@@ -25,7 +25,7 @@ pub extern "win64" fn foo(a: int, b: int, c: int, d: int) {
 
 #[inline(never)]
 #[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "aarch64"))]
-pub extern fn foo(a: int, b: int, c: int, d: int) {
+pub extern fn foo(a: isize, b: isize, c: isize, d: isize) {
     assert!(a == 1);
     assert!(b == 2);
     assert!(c == 3);
index a5d672e3c0cf90d004d64151620c056751cb1c6a..92239ce55981c808dfd0991c4a7eaa2906377223 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![crate_name="foreign_lib"]
+#![feature(libc)]
 
 pub mod rustrt {
     extern crate libc;
index 4902766534a139d620203e6cc065ef9f08fa365f..0a921c8f5b3a0b1eb8fe6110786cf19a49977ba5 100644 (file)
 // Common code used for tests that model the Fn/FnMut/FnOnce hierarchy.
 
 pub trait Go {
-    fn go(&self, arg: int);
+    fn go(&self, arg: isize);
 }
 
-pub fn go<G:Go>(this: &G, arg: int) {
+pub fn go<G:Go>(this: &G, arg: isize) {
     this.go(arg)
 }
 
 pub trait GoMut {
-    fn go_mut(&mut self, arg: int);
+    fn go_mut(&mut self, arg: isize);
 }
 
-pub fn go_mut<G:GoMut>(this: &mut G, arg: int) {
+pub fn go_mut<G:GoMut>(this: &mut G, arg: isize) {
     this.go_mut(arg)
 }
 
 pub trait GoOnce {
-    fn go_once(self, arg: int);
+    fn go_once(self, arg: isize);
 }
 
-pub fn go_once<G:GoOnce>(this: G, arg: int) {
+pub fn go_once<G:GoOnce>(this: G, arg: isize) {
     this.go_once(arg)
 }
 
 impl<G> GoMut for G
     where G : Go
 {
-    fn go_mut(&mut self, arg: int) {
+    fn go_mut(&mut self, arg: isize) {
         go(&*self, arg)
     }
 }
@@ -45,7 +45,7 @@ impl<G> GoMut for G
 impl<G> GoOnce for G
     where G : GoMut
 {
-    fn go_once(mut self, arg: int) {
+    fn go_once(mut self, arg: isize) {
         go_mut(&mut self, arg)
     }
 }
index df4e0658cb83ac4786cabf7ae600d87d78b56fd5..ad3cdedf7eafebca8c7234ccdc29ea606708d3d1 100644 (file)
@@ -11,7 +11,7 @@
 #![crate_type = "lib"]
 
 pub struct Fish {
-    pub x: int
+    pub x: isize
 }
 
 impl Fish {
index 4d4b1bcc4cbf036ee5178dacc8e3dbdcec4820f7..c3212b0fc6d22da10f0e422af95a3c793f6389ad 100644 (file)
@@ -11,7 +11,7 @@
 #![crate_type = "lib"]
 
 pub struct Fish {
-    pub x: int
+    pub x: isize
 }
 
 mod unexported {
index fd049a25a0cff8bea6700dcd39ac543d2d7e873b..6f5ddfd37a5c221e6585c1b13562e9374177bd8a 100644 (file)
 #![feature(struct_inherit)]
 
 pub virtual struct S1 {
-    pub f1: int,
+    pub f1: isize,
 }
 
 pub struct S2 : S1 {
-    pub f2: int,
+    pub f2: isize,
 }
 
 pub fn test_s2(s2: S2) {
index 77eb82f80228649965299a2e1be76ffe26a84a03..c09cc53466dc1f84c6d1d45edf3f86e7a86cd35f 100644 (file)
@@ -43,7 +43,7 @@ pub trait Stable {
     fn stable(&self);
 }
 
-impl Stable for uint {
+impl Stable for usize {
     fn unstable(&self) {}
     fn stable(&self) {}
 }
index ca5c6072cb371b98bd9ea096807f65abbb570944..0d15c13a4ef1e936322f9c64d9f947db9e2d348c 100644 (file)
@@ -15,43 +15,43 @@ pub mod test {
     pub struct A<T> { pub v: T }
 
     impl<T> A<T> {
-        pub fn foo(&self) -> int {
-            static a: int = 5;
+        pub fn foo(&self) -> isize {
+            static a: isize = 5;
             return a
         }
 
-        pub fn bar(&self) -> int {
-            static a: int = 6;
+        pub fn bar(&self) -> isize {
+            static a: isize = 6;
             return a;
         }
     }
 }
 
 impl<T> A<T> {
-    pub fn foo(&self) -> int {
-        static a: int = 1;
+    pub fn foo(&self) -> isize {
+        static a: isize = 1;
         return a
     }
 
-    pub fn bar(&self) -> int {
-        static a: int = 2;
+    pub fn bar(&self) -> isize {
+        static a: isize = 2;
         return a;
     }
 }
 
 impl<T> B<T> {
-    pub fn foo(&self) -> int {
-        static a: int = 3;
+    pub fn foo(&self) -> isize {
+        static a: isize = 3;
         return a
     }
 
-    pub fn bar(&self) -> int {
-        static a: int = 4;
+    pub fn bar(&self) -> isize {
+        static a: isize = 4;
         return a;
     }
 }
 
-pub fn foo() -> int {
+pub fn foo() -> isize {
     let a = A { v: () };
     let b = B { v: () };
     let c = test::A { v: () };
diff --git a/src/test/auxiliary/internal_unstable.rs b/src/test/auxiliary/internal_unstable.rs
new file mode 100644 (file)
index 0000000..3d59b8e
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright 2015 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(staged_api, allow_internal_unstable)]
+#![staged_api]
+#![stable(feature = "stable", since = "1.0.0")]
+
+#[unstable(feature = "function")]
+pub fn unstable() {}
+
+
+#[stable(feature = "stable", since = "1.0.0")]
+pub struct Foo {
+    #[unstable(feature = "struct_field")]
+    pub x: u8
+}
+
+#[allow_internal_unstable]
+#[macro_export]
+macro_rules! call_unstable_allow {
+    () => { $crate::unstable() }
+}
+
+#[allow_internal_unstable]
+#[macro_export]
+macro_rules! construct_unstable_allow {
+    ($e: expr) => {
+        $crate::Foo { x: $e }
+    }
+}
+
+#[allow_internal_unstable]
+#[macro_export]
+macro_rules! pass_through_allow {
+    ($e: expr) => { $e }
+}
+
+#[macro_export]
+macro_rules! call_unstable_noallow {
+    () => { $crate::unstable() }
+}
+
+#[macro_export]
+macro_rules! construct_unstable_noallow {
+    ($e: expr) => {
+        $crate::Foo { x: $e }
+    }
+}
+
+#[macro_export]
+macro_rules! pass_through_noallow {
+    ($e: expr) => { $e }
+}
index 690d5783c4bc2b6b7ca7a0ffab26696eb1a18fbd..b231efa0fece4c3a6f82bcc029349254e5743079 100644 (file)
@@ -20,4 +20,3 @@ fn no_op() { }
 pub const D : C<fn()> = C {
     k: no_op as fn()
 };
-
index 560844332a128d4718362b8a7debb61deb7436a0..21935b6b9ab07fbc514e488143ff8b197b298100 100644 (file)
@@ -15,12 +15,12 @@ mod inner {
         fn f(&self) { f(); }
     }
 
-    impl Trait for int {}
+    impl Trait for isize {}
 
     fn f() {}
 }
 
 pub fn foo() {
-    let a = &1 as &inner::Trait;
+    let a = &1is as &inner::Trait;
     a.f();
 }
index 88277af4a5118667c24ca93d910f941ce0593574..37543ea1d3c5ef7028419ac7d1aa591cdf026bbd 100644 (file)
@@ -13,7 +13,7 @@ mod inner {
         fn f(&self) { f(); }
     }
 
-    impl Trait for int {}
+    impl Trait for isize {}
 
     fn f() {}
 }
index 848574a61fe8f53a641a7bc05b2434e61c3aa30c..f12e4c9b6e7ea347361f0fa075aba59997e28bf9 100644 (file)
@@ -25,7 +25,7 @@ pub trait Outer {
     fn foo<T: Trait>(&self, t: T) { t.f(); }
 }
 
-impl Outer for int {}
+impl Outer for isize {}
 
 pub fn foo<T: Outer>(t: T) {
     t.foo(inner::Foo);
index a8a4c438e67343905d49322a963a57666cfdecf3..21ef99e3c3d95c7a562254d3c3e90cbc5894ef0a 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub struct A<'a>(pub &'a int);
+pub struct A<'a>(pub &'a isize);
diff --git a/src/test/auxiliary/issue-11680.rs b/src/test/auxiliary/issue-11680.rs
deleted file mode 100644 (file)
index 249a1ba..0000000
+++ /dev/null
@@ -1,19 +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.
-
-enum Foo {
-    Bar(int)
-}
-
-pub mod test {
-    enum Foo {
-        Bar(int)
-    }
-}
index ee2b11da8f0adfe32aa202b9898ae94a1f4cab2b..fa5722ae6a31ba51392d1f986b1dc866c6b06321 100644 (file)
@@ -12,6 +12,5 @@
 
 #![crate_type = "dylib"]
 
-extern crate "issue-12133-rlib" as a;
-extern crate "issue-12133-dylib" as b;
-
+extern crate issue_12133_rlib as a;
+extern crate issue_12133_dylib as b;
diff --git a/src/test/auxiliary/issue-12612-1.rs b/src/test/auxiliary/issue-12612-1.rs
deleted file mode 100644 (file)
index a0234c1..0000000
+++ /dev/null
@@ -1,13 +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.
-
-pub mod bar {
-    pub fn foo() {}
-}
diff --git a/src/test/auxiliary/issue-12612-2.rs b/src/test/auxiliary/issue-12612-2.rs
deleted file mode 100644 (file)
index b4ae437..0000000
+++ /dev/null
@@ -1,11 +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.
-
-pub fn baz() {}
index 5510d3e2e0df18386d82ee8c10183186d608ea70..c0539aa1b6e20c2f41f1319d78eb37e5246df36e 100644 (file)
@@ -12,6 +12,5 @@
 
 #![crate_type = "rlib"]
 
-#[macro_use] #[no_link] extern crate "issue-13560-1" as t1;
-#[macro_use] extern crate "issue-13560-2" as t2;
-
+#[macro_use] #[no_link] extern crate issue_13560_1 as t1;
+#[macro_use] extern crate issue_13560_2 as t2;
index da47115e2b3f4e53a62c743669636c3ec05d06ed..554170bc130377b51268fdbc3ee2098ad36de73e 100644 (file)
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-extern crate "issue-13620-1" as crate1;
+extern crate issue_13620_1 as crate1;
 
 pub static FOO2: crate1::Foo = crate1::FOO;
index 8294d2b4594cfb00ebce192ca8d5513de99d01c1..bb51417528aef724fb5fcf913109218820046203 100644 (file)
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-extern crate "issue-13872-1" as foo;
+extern crate issue_13872_1 as foo;
 
 pub use foo::A::B;
index 827a9f18f4892a393002759dfa16ad2279e854b6..e20618f1ec076d2aab145666b1e30ef905990e48 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-extern crate "issue-13872-2" as bar;
+extern crate issue_13872_2 as bar;
 
 use bar::B;
 
index 3e23698397b4f5da4dd31ceac6ce53141537cc01..32af6d9255e5bd959ff36375cee78111ee38a514 100644 (file)
@@ -23,7 +23,7 @@ mod src {
     pub mod hidden_core {
         use super::aliases::B;
 
-        #[derive(Copy)]
+        #[derive(Copy, Clone)]
         pub struct A;
 
         pub fn make() -> B { A }
diff --git a/src/test/auxiliary/issue-16725.rs b/src/test/auxiliary/issue-16725.rs
deleted file mode 100644 (file)
index 7f388c1..0000000
+++ /dev/null
@@ -1,14 +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.
-
-extern {
-    fn bar();
-}
-
diff --git a/src/test/auxiliary/issue-17718-const-privacy.rs b/src/test/auxiliary/issue-17718-const-privacy.rs
deleted file mode 100644 (file)
index 3657d39..0000000
+++ /dev/null
@@ -1,18 +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.
-
-pub use foo::FOO2;
-
-pub const FOO: uint = 3;
-const BAR: uint = 3;
-
-mod foo {
-    pub const FOO2: uint = 3;
-}
index cbe56b00c13d59be061059d437efa6751a80c417..67474e7902170c91e96cc2a31474cb7e4a884894 100644 (file)
 
 use std::sync::atomic;
 
-pub const C1: uint = 1;
+pub const C1: usize = 1;
 pub const C2: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
 pub const C3: fn() = foo;
-pub const C4: uint = C1 * C1 + C1 / C1;
-pub const C5: &'static uint = &C4;
+pub const C4: usize = C1 * C1 + C1 / C1;
+pub const C5: &'static usize = &C4;
 
-pub static S1: uint = 3;
+pub static S1: usize = 3;
 pub static S2: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
 
 fn foo() {}
diff --git a/src/test/auxiliary/issue-21202.rs b/src/test/auxiliary/issue-21202.rs
deleted file mode 100644 (file)
index afdbf78..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 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.
-
-pub mod A {
-    pub struct Foo;
-    impl Foo {
-        fn foo(&self) { }
-    }
-}
index fe1ef549d06acc107b6125e1a8e57ab31483f991..8c414193bd6281185efdc23fe0d02df9868aa693 100644 (file)
@@ -11,7 +11,7 @@
 #![crate_name="a"]
 #![crate_type = "lib"]
 
-type t1 = uint;
+type t1 = usize;
 
 trait foo {
     fn foo(&self);
index 89b3b56121a1614961297566eb8088c21a5808ef..e85a0a90aff0fce5d1e4abc3d348f78012e39010 100644 (file)
@@ -15,8 +15,8 @@
 
 use std::marker;
 
-struct arc_destruct<T> {
-    _data: int,
+struct arc_destruct<T: Sync> {
+    _data: isize,
     _marker: marker::PhantomData<T>
 }
 
@@ -25,7 +25,7 @@ impl<T: Sync> Drop for arc_destruct<T> {
     fn drop(&mut self) {}
 }
 
-fn arc_destruct<T: Sync>(data: int) -> arc_destruct<T> {
+fn arc_destruct<T: Sync>(data: isize) -> arc_destruct<T> {
     arc_destruct {
         _data: data,
         _marker: marker::PhantomData
@@ -41,7 +41,7 @@ fn init() -> arc_destruct<context_res> {
 }
 
 struct context_res {
-    ctx : int,
+    ctx : isize,
 }
 
 impl Drop for context_res {
index dd1ad413a3d279a873f299ec853c7e03dbf68c1a..604a3e69a21767909233a369c61149385b64a07a 100644 (file)
@@ -19,6 +19,6 @@ pub type header_map = HashMap<String, Rc<RefCell<Vec<Rc<String>>>>>;
 
 // the unused ty param is necessary so this gets monomorphized
 pub fn request<T>(req: &header_map) {
-  let data = req["METHOD".to_string()].clone();
+  let data = req[&"METHOD".to_string()].clone();
   let _x = data.borrow().clone()[0].clone();
 }
index 25eb67e0423005cc14f825f02faa287206604b48..b6199f59ebe0638c9e82c3bc27ae0c129ac2104b 100644 (file)
@@ -10,6 +10,7 @@
 
 #![crate_name="socketlib"]
 #![crate_type = "lib"]
+#![feature(libc)]
 
 pub mod socket {
     extern crate libc;
index d9d393cc7492c010b247d2759bb15bc2049f94b6..82bd2b6420437f46357c755f7b47fd7a5da42802 100644 (file)
@@ -11,5 +11,4 @@
 
 use std::collections::HashMap;
 
-pub type map = Box<HashMap<uint, uint>>;
-
+pub type map = Box<HashMap<usize, usize>>;
index 7bfd2e79641d038ccc86f2f9ec81aa32bd6832b5..8f328699ae0aadb7aaefac767b1d24aaa6baf49e 100644 (file)
@@ -21,5 +21,5 @@ pub fn leaf<V>(value: V) -> TreeItem<V> {
 }
 
 fn main() {
-    BTree::<int> { node: leaf(1) };
+    BTree::<isize> { node: leaf(1) };
 }
index 1e746bf39db6196074bca1ea181bde9d73e9ab3c..0da0b9fa47d6c1c01918ae1bb4ce77e125fada9c 100644 (file)
@@ -14,9 +14,9 @@ pub use other::FooBar;
 pub use other::foo;
 
 mod other {
-    pub struct FooBar{value: int}
+    pub struct FooBar{value: isize}
     impl FooBar{
-        pub fn new(val: int) -> FooBar {
+        pub fn new(val: isize) -> FooBar {
             FooBar{value: val}
         }
     }
index 227fab73048d76a1ec4d278568d155dc7729e014..d0566a1e0914bff0230151abd5be41fdf5953419 100644 (file)
 
 pub use private::P;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct S {
     p: P,
 }
 
 mod private {
-    #[derive(Copy)]
+    #[derive(Copy, Clone)]
     pub struct P {
         p: i32,
     }
@@ -27,4 +27,3 @@ mod private {
 }
 
 pub static A: S = S { p: private::THREE };
-
index f24721adb5d968cff71300a37ba672ba71b57292..22ccb3dfacdf1285912e6bbab1083ca38e17d73d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(core)]
+
 pub mod testtypes {
     use std::any::TypeId;
 
@@ -39,10 +41,10 @@ pub mod testtypes {
     pub type FooChar = char;
 
     // Tests ty_int (does not test all variants of IntTy)
-    pub type FooInt = int;
+    pub type FooInt = isize;
 
     // Tests ty_uint (does not test all variants of UintTy)
-    pub type FooUint = uint;
+    pub type FooUint = usize;
 
     // Tests ty_float (does not test all variants of FloatTy)
     pub type FooFloat = f64;
@@ -51,8 +53,8 @@ pub mod testtypes {
 
     // Tests ty_enum
     pub enum FooEnum {
-        VarA(uint),
-        VarB(uint, uint)
+        VarA(usize),
+        VarB(usize, usize)
     }
 
     // Tests ty_uniq (of u8)
@@ -69,14 +71,14 @@ pub mod testtypes {
 
     // Tests ty_trait
     pub trait FooTrait {
-        fn foo_method(&self) -> uint;
-        fn foo_static_method() -> uint;
+        fn foo_method(&self) -> usize;
+        fn foo_static_method() -> usize;
     }
 
     // Tests ty_struct
     pub struct FooStruct {
-        pub pub_foo_field: uint,
-        foo_field: uint
+        pub pub_foo_field: usize,
+        foo_field: usize
     }
 
     // Tests ty_tup
diff --git a/src/test/auxiliary/issue_11680.rs b/src/test/auxiliary/issue_11680.rs
new file mode 100644 (file)
index 0000000..18f7875
--- /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.
+
+enum Foo {
+    Bar(isize)
+}
+
+pub mod test {
+    enum Foo {
+        Bar(isize)
+    }
+}
diff --git a/src/test/auxiliary/issue_12612_1.rs b/src/test/auxiliary/issue_12612_1.rs
new file mode 100644 (file)
index 0000000..a0234c1
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+pub mod bar {
+    pub fn foo() {}
+}
diff --git a/src/test/auxiliary/issue_12612_2.rs b/src/test/auxiliary/issue_12612_2.rs
new file mode 100644 (file)
index 0000000..b4ae437
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+
+pub fn baz() {}
index bb57b4a98bb70674795558348a7570e29b84523a..58dee1216ee6047d03262e8cf8714c5bb779907f 100644 (file)
@@ -11,7 +11,7 @@
 // ignore-stage1
 // force-host
 
-#![feature(plugin_registrar, quote)]
+#![feature(plugin_registrar, quote, rustc_private)]
 #![crate_type = "dylib"]
 
 extern crate syntax;
@@ -19,7 +19,8 @@ extern crate rustc;
 
 use syntax::ast;
 use syntax::codemap;
-use syntax::ext::base::{ExtCtxt, MacResult, MacItems};
+use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
+use syntax::util::small_vector::SmallVector;
 use rustc::plugin::Registry;
 
 #[plugin_registrar]
@@ -28,8 +29,8 @@ pub fn plugin_registrar(reg: &mut Registry) {
 }
 
 fn expand(cx: &mut ExtCtxt, _: codemap::Span, _: &[ast::TokenTree]) -> Box<MacResult+'static> {
-    MacItems::new(vec![
+    MacEager::items(SmallVector::many(vec![
         quote_item!(cx, struct Struct1;).unwrap(),
         quote_item!(cx, struct Struct2;).unwrap()
-    ].into_iter())
+    ]))
 }
diff --git a/src/test/auxiliary/issue_16725.rs b/src/test/auxiliary/issue_16725.rs
new file mode 100644 (file)
index 0000000..b3b04b4
--- /dev/null
@@ -0,0 +1,13 @@
+// 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.
+
+extern {
+    fn bar();
+}
diff --git a/src/test/auxiliary/issue_17718_const_privacy.rs b/src/test/auxiliary/issue_17718_const_privacy.rs
new file mode 100644 (file)
index 0000000..3901d73
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+pub use foo::FOO2;
+
+pub const FOO: usize = 3;
+const BAR: usize = 3;
+
+mod foo {
+    pub const FOO2: usize = 3;
+}
index 40c8eb9b23ad7dbd57b8ede9d2fcef09daf99005..12894ad72e1a4cea4f5d4a4ce1a91d576f0f97e3 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub struct Foo (pub int);
+pub struct Foo (pub isize);
 pub enum MyEnum {
     Foo(Foo),
 }
diff --git a/src/test/auxiliary/issue_21202.rs b/src/test/auxiliary/issue_21202.rs
new file mode 100644 (file)
index 0000000..afdbf78
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 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.
+
+pub mod A {
+    pub struct Foo;
+    impl Foo {
+        fn foo(&self) { }
+    }
+}
index bd8857ceef7ea4f55f14b0fa3bb6b9f06edad684..44bea136a7c3b3468d2653199572f214fb78e191 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 
-pub unsafe fn f(xs: Vec<int> ) {
+pub unsafe fn f(xs: Vec<isize> ) {
     xs.iter().map(|_x| { unsafe fn q() { panic!(); } }).collect::<Vec<()>>();
 }
index 545e15fe1664d657ef941e983f72dd1b6c66b4d9..3d5e52d709df3ec4c1966eafc87252acd368efc0 100644 (file)
@@ -8,9 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(core)]
+
 use std::marker::MarkerTrait;
 
 pub trait Foo : MarkerTrait {
     fn bar();
 }
-
index 91faace7a3f4d6b93064c4e3ab539a3b64ef74a0..5c306be69c42935cb656df5484c5a94f7b18411f 100644 (file)
 #![crate_type = "lib"]
 
 pub trait Positioned {
-  fn SetX(&mut self, int);
-  fn X(&self) -> int;
+  fn SetX(&mut self, isize);
+  fn X(&self) -> isize;
 }
 
 pub trait Movable: Positioned {
-  fn translate(&mut self, dx: int) {
+  fn translate(&mut self, dx: isize) {
     let x = self.X() + dx;
     self.SetX(x);
   }
index 0f898ae83859f1dbf42993d3b3cb5df764ecd9e5..5c878b1e667d9f61128c7f92cd90e6a1bca13e79 100644 (file)
@@ -8,9 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(libc)]
+
 extern crate libc;
 
 extern "C" {
     pub fn rand() -> libc::c_int;
 }
-
index 9006a5d1775f764eb7f569fa7f491b09dd7b27da..04b56442d0b8fc7c3d094bd2973460eb7573e75c 100644 (file)
@@ -24,4 +24,3 @@ fn foo<T>(t: &T) {
     let b = B;
     bar(unsafe { mem::transmute(&b as &A) }, t)
 }
-
index 4f2792aebcd2408639256271ae4254015e744f07..8c2546e76cfd4675eda28c4f2988955d3da15586 100644 (file)
@@ -17,4 +17,3 @@ pub trait X {
     }
     fn dummy(&self) { }
 }
-
index 5f5a8f02fd9d16191bafec4e9b5f218c564309b8..8ff85cc359d4f7bd3499daae67e7a831eef39a6d 100644 (file)
@@ -8,17 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn foo<T>() -> &'static int {
+pub fn foo<T>() -> &'static isize {
     if false {
-        static a: int = 4;
+        static a: isize = 4;
         return &a;
     } else {
-        static a: int = 5;
+        static a: isize = 5;
         return &a;
     }
 }
 
-pub fn bar() -> &'static int {
-    foo::<int>()
+pub fn bar() -> &'static isize {
+    foo::<isize>()
 }
-
index 7e090523984dadc719db7b261a34140edd071097..82f182c04bd3899f716a96867e3a5da393c1dba3 100644 (file)
@@ -16,4 +16,3 @@
 #![crate_type="lib"]
 
 pub fn f<T:Copy>() {}
-
index b9cc20b63cc5640258ac6bc70afde33440a6d24a..72dfc75f41b969747eba45465ab47b37a773825d 100644 (file)
@@ -20,7 +20,7 @@ impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
 pub trait Sized : PhantomFn<Self> {}
 
 #[lang="panic"]
-fn panic(_: &(&'static str, &'static str, uint)) -> ! { loop {} }
+fn panic(_: &(&'static str, &'static str, usize)) -> ! { loop {} }
 
 #[lang = "stack_exhausted"]
 extern fn stack_exhausted() {}
@@ -33,4 +33,21 @@ pub trait Copy : PhantomFn<Self> {
     // Empty.
 }
 
+#[lang="rem"]
+pub trait Rem<RHS=Self> {
+    type Output = Self;
+    fn rem(self, rhs: RHS) -> Self::Output;
+}
 
+impl Rem for isize {
+    type Output = isize;
+
+    #[inline]
+    fn rem(self, other: isize) -> isize {
+        // if you use `self % other` here, as one would expect, you
+        // get back an error because of potential failure/overflow,
+        // which tries to invoke error fns that don't have the
+        // appropriate signatures anymore. So...just return 0.
+        0
+    }
+}
index 6cd94ee5602aa5ccf3db96b0b1f3ccda3dcae6ef..d96dfd848f3f0e3b8968c6086abcba5628228477 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(std_misc, old_path)]
+
 use std::dynamic_lib::DynamicLibrary;
 
 #[no_mangle]
@@ -27,11 +29,10 @@ fn bar() { }
 fn baz() { }
 
 pub fn test() {
-    let none: Option<&Path> = None; // appease the typechecker
-    let lib = DynamicLibrary::open(none).unwrap();
+    let lib = DynamicLibrary::open(None).unwrap();
     unsafe {
-        assert!(lib.symbol::<int>("foo").is_ok());
-        assert!(lib.symbol::<int>("baz").is_err());
-        assert!(lib.symbol::<int>("bar").is_err());
+        assert!(lib.symbol::<isize>("foo").is_ok());
+        assert!(lib.symbol::<isize>("baz").is_err());
+        assert!(lib.symbol::<isize>("bar").is_err());
     }
 }
index a74c8c47cd9b7c7388c10ae457e6fb2bdec08cda..ca4046d81636a2a1bc9e1749f99432ee28b9c2ce 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 #[no_mangle]
-pub static foo: int = 3;
+pub static foo: isize = 3;
 
 pub fn bar() {}
diff --git a/src/test/auxiliary/lint-unused-extern-crate.rs b/src/test/auxiliary/lint-unused-extern-crate.rs
deleted file mode 100644 (file)
index 2661b1f..0000000
+++ /dev/null
@@ -1,11 +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.
-
-pub fn foo() {}
diff --git a/src/test/auxiliary/lint_for_crate.rs b/src/test/auxiliary/lint_for_crate.rs
new file mode 100644 (file)
index 0000000..3b45b0a
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2015 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.
+
+// force-host
+
+#![feature(plugin_registrar, rustc_private)]
+#![feature(box_syntax)]
+
+extern crate syntax;
+#[macro_use] extern crate rustc;
+
+use syntax::{ast, attr};
+use rustc::lint::{Context, LintPass, LintPassObject, LintArray};
+use rustc::plugin::Registry;
+
+declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]");
+
+struct Pass;
+
+impl LintPass for Pass {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(CRATE_NOT_OKAY)
+    }
+
+    fn check_crate(&mut self, cx: &Context, krate: &ast::Crate) {
+        if !attr::contains_name(&krate.attrs, "crate_okay") {
+            cx.span_lint(CRATE_NOT_OKAY, krate.span,
+                         "crate is not marked with #![crate_okay]");
+        }
+    }
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_lint_pass(box Pass as LintPassObject);
+}
index e9d98889ff854062f3434ea105b5b91f401fca81..ca5a7b75e06cfe61ac929401d378523c517fc458 100644 (file)
@@ -11,7 +11,7 @@
 // force-host
 
 #![feature(plugin_registrar)]
-#![feature(box_syntax)]
+#![feature(box_syntax, rustc_private)]
 
 extern crate syntax;
 
old mode 100755 (executable)
new mode 100644 (file)
index 1977e2a..50a9202
 
 #[stable(feature = "test_feature", since = "1.0.0")]
 #[deprecated(since = "1.0.0")]
-pub fn foo() -> uint {
+pub fn foo() -> usize {
     20
 }
 
 #[unstable(feature = "test_feature")]
-pub fn bar() -> uint {
+pub fn bar() -> usize {
     40
 }
 
 #[unstable(feature = "test_feature")]
-pub fn baz() -> uint {
+pub fn baz() -> usize {
     30
 }
index ffb234f70c8e754ec7f4d86411101598ac100118..20799ce5b467f9debdb077e3479a3baef395c58a 100644 (file)
@@ -11,7 +11,7 @@
 // force-host
 
 #![feature(plugin_registrar)]
-#![feature(box_syntax)]
+#![feature(box_syntax, rustc_private)]
 
 extern crate syntax;
 
index fb535eb8336f9b2df90d027c61cef3fb9f731097..bb3b71bc2441b3a5761c47d4362a8d25c6574c62 100644 (file)
@@ -100,14 +100,22 @@ pub trait UnstableTrait { fn dummy(&self) { } }
 
 #[stable(feature = "test_feature", since = "1.0.0")]
 #[deprecated(since = "1.0.0")]
-pub struct DeprecatedStruct { pub i: int }
+pub struct DeprecatedStruct {
+    #[stable(feature = "test_feature", since = "1.0.0")] pub i: isize
+}
 #[unstable(feature = "test_feature")]
 #[deprecated(since = "1.0.0")]
-pub struct DeprecatedUnstableStruct { pub i: int }
+pub struct DeprecatedUnstableStruct {
+    #[stable(feature = "test_feature", since = "1.0.0")] pub i: isize
+}
 #[unstable(feature = "test_feature")]
-pub struct UnstableStruct { pub i: int }
+pub struct UnstableStruct {
+    #[stable(feature = "test_feature", since = "1.0.0")] pub i: isize
+}
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct StableStruct { pub i: int }
+pub struct StableStruct {
+    #[stable(feature = "test_feature", since = "1.0.0")] pub i: isize
+}
 
 #[stable(feature = "test_feature", since = "1.0.0")]
 #[deprecated(since = "1.0.0")]
@@ -137,14 +145,14 @@ pub enum Enum {
 
 #[stable(feature = "test_feature", since = "1.0.0")]
 #[deprecated(since = "1.0.0")]
-pub struct DeprecatedTupleStruct(pub int);
+pub struct DeprecatedTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
 #[unstable(feature = "test_feature")]
 #[deprecated(since = "1.0.0")]
-pub struct DeprecatedUnstableTupleStruct(pub int);
+pub struct DeprecatedUnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
 #[unstable(feature = "test_feature")]
-pub struct UnstableTupleStruct(pub int);
+pub struct UnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct StableTupleStruct(pub int);
+pub struct StableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize);
 
 #[macro_export]
 macro_rules! macro_test {
diff --git a/src/test/auxiliary/lint_stability_fields.rs b/src/test/auxiliary/lint_stability_fields.rs
new file mode 100644 (file)
index 0000000..66940ee
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright 2015 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(staged_api)]
+#![staged_api]
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Stable {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub inherit: u8, // it's a lie (stable doesn't inherit)
+    #[unstable(feature = "test_feature")]
+    pub override1: u8,
+    #[deprecated(since = "1.0.0")]
+    #[unstable(feature = "test_feature")]
+    pub override2: u8,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Stable2(#[stable(feature = "rust1", since = "1.0.0")] pub u8,
+                   #[unstable(feature = "test_feature")] pub u8,
+                   #[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] pub u8);
+
+#[unstable(feature = "test_feature")]
+pub struct Unstable {
+    pub inherit: u8,
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub override1: u8,
+    #[deprecated(since = "1.0.0")]
+    #[unstable(feature = "test_feature")]
+    pub override2: u8,
+}
+
+#[unstable(feature = "test_feature")]
+pub struct Unstable2(pub u8,
+                     #[stable(feature = "rust1", since = "1.0.0")] pub u8,
+                     #[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] pub u8);
+
+#[unstable(feature = "test_feature")]
+#[deprecated(feature = "rust1", since = "1.0.0")]
+pub struct Deprecated {
+    pub inherit: u8,
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub override1: u8,
+    #[unstable(feature = "test_feature")]
+    pub override2: u8,
+}
+
+#[unstable(feature = "test_feature")]
+#[deprecated(feature = "rust1", since = "1.0.0")]
+pub struct Deprecated2(pub u8,
+                       #[stable(feature = "rust1", since = "1.0.0")] pub u8,
+                       #[unstable(feature = "test_feature")] pub u8);
diff --git a/src/test/auxiliary/lint_unused_extern_crate.rs b/src/test/auxiliary/lint_unused_extern_crate.rs
new file mode 100644 (file)
index 0000000..2661b1f
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+
+pub fn foo() {}
index bf4ab975cedd8c97a66dfd89a45a30488e732cdf..db26b10fc67cbf24442d3ea5bb78871234c7a03a 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(rustc_private)]
+
 #[macro_use] extern crate log;
 
 pub fn foo<T>() {
-    fn death() -> int { panic!() }
+    fn death() -> isize { panic!() }
     debug!("{}", (||{ death() })());
 }
index d50c27a4e75bb0efae4bb6c6fbd2e98e03b8bbb3..03cd70d949428886501b663dbe60de5b64df9039 100644 (file)
@@ -10,7 +10,7 @@
 
 // force-host
 
-#![feature(plugin_registrar)]
+#![feature(plugin_registrar, rustc_private)]
 
 extern crate syntax;
 extern crate rustc;
index 922efc1aec38fa99f2a1928155a0c85c28d3f78e..4f75e2b5d75651e05095f0fa6d2b0046c297363d 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn increment(x: uint) -> uint {
+pub fn increment(x: usize) -> usize {
     x + 1
 }
 
index d545a42ae1927ec7c30fa5a312a3c7bd4baca0b8..5b7e52e9164e96744d8c34162eacf10d1b783cf7 100644 (file)
 // force-host
 
 #![feature(plugin_registrar, quote)]
-#![feature(box_syntax)]
+#![feature(box_syntax, rustc_private)]
 
 extern crate syntax;
 extern crate rustc;
 
-use syntax::ast::{TokenTree, Item, MetaItem, ImplItem, TraitItem, Method};
+use syntax::ast::{self, TokenTree, Item, MetaItem};
 use syntax::codemap::Span;
 use syntax::ext::base::*;
 use syntax::parse::token;
@@ -36,10 +36,12 @@ pub fn plugin_registrar(reg: &mut Registry) {
     reg.register_macro("identity", expand_identity);
     reg.register_syntax_extension(
         token::intern("into_foo"),
-        Modifier(box expand_into_foo));
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        Modifier(Box::new(expand_into_foo)));
     reg.register_syntax_extension(
         token::intern("into_multi_foo"),
-        MultiModifier(box expand_into_foo_multi));
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        MultiModifier(Box::new(expand_into_foo_multi)));
 }
 
 fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
@@ -47,7 +49,7 @@ fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
     if !tts.is_empty() {
         cx.span_fatal(sp, "make_a_1 takes no arguments");
     }
-    MacExpr::new(quote_expr!(cx, 1))
+    MacEager::expr(quote_expr!(cx, 1))
 }
 
 // See Issue #15750
@@ -57,7 +59,7 @@ fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree])
     let mut parser = parse::new_parser_from_tts(cx.parse_sess(),
         cx.cfg(), tts.to_vec());
     let expr = parser.parse_expr();
-    MacExpr::new(quote_expr!(&mut *cx, $expr))
+    MacEager::expr(quote_expr!(&mut *cx, $expr))
 }
 
 fn expand_into_foo(cx: &mut ExtCtxt, sp: Span, attr: &MetaItem, it: P<Item>)
@@ -80,14 +82,24 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt,
             }))
         }
         Annotatable::ImplItem(it) => {
-            Annotatable::ImplItem(ImplItem::MethodImplItem(
-                quote_method!(cx, fn foo(&self) -> i32 { 42 })
-            ))
+            quote_item!(cx, impl X { fn foo(&self) -> i32 { 42 } }).unwrap().and_then(|i| {
+                match i.node {
+                    ast::ItemImpl(_, _, _, _, _, mut items) => {
+                        Annotatable::ImplItem(items.pop().expect("impl method not found"))
+                    }
+                    _ => unreachable!("impl parsed to something other than impl")
+                }
+            })
         }
         Annotatable::TraitItem(it) => {
-            Annotatable::TraitItem(TraitItem::ProvidedMethod(
-                quote_method!(cx, fn foo(&self) -> i32 { 0 })
-            ))
+            quote_item!(cx, trait X { fn foo(&self) -> i32 { 0 } }).unwrap().and_then(|i| {
+                match i.node {
+                    ast::ItemTrait(_, _, _, mut items) => {
+                        Annotatable::TraitItem(items.pop().expect("trait method not found"))
+                    }
+                    _ => unreachable!("trait parsed to something other than trait")
+                }
+            })
         }
     }
 }
@@ -114,7 +126,7 @@ fn expand_forged_ident(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<Mac
         let mut parser = new_parser_from_tts(parse_sess, cfg, tt);
         parser.parse_expr()
     };
-    MacExpr::new(expr)
+    MacEager::expr(expr)
 }
 
 pub fn foo() {}
index 9c72cb1a6800ad7b25e62f098c2dafad4e4907cf..aaeccc6e89883865bdbdb5607523f9d6ce369f0c 100644 (file)
@@ -11,5 +11,5 @@
 #![crate_type = "dylib"]
 #[macro_export]
 macro_rules! reexported {
-    () => ( 3_usize )
+    () => ( 3 )
 }
index 643442363a4463e6ac8e2c5701dedc77bbdf4c94..348b71faf0cdbd39632ff5ab9c98a677571b6d6c 100644 (file)
@@ -17,7 +17,7 @@ static mut COUNT: u64 = 1;
 
 pub fn get_count() -> u64 { unsafe { COUNT } }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Foo;
 
 impl Foo {
index fd99da87e6b0d1f1e00f67425ba66fe22a9805a5..b67ec1b9bfc655e8014e923abbacc7f28d0df50d 100644 (file)
@@ -17,7 +17,7 @@ static mut COUNT: u64 = 1;
 
 pub fn get_count() -> u64 { unsafe { COUNT } }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Foo;
 
 impl Foo {
index 6ff6da716a9e035aa8a2fba8e80fa0548f700168..f95be3f4a1d057def76337564ffd0e2f876c653f 100644 (file)
@@ -11,7 +11,7 @@
 #![crate_type="lib"]
 
 pub struct S {
-    x: int,
+    x: isize,
 }
 
 impl Drop for S {
index 7412c17fd45b28cf3b32854f39f94866ff241bcd..b7bde4a74a553b05c13e38788fdcf94a4db24e7c 100644 (file)
@@ -12,8 +12,8 @@ pub use Foo::*;
 
 pub enum Foo {
     A,
-    B(int),
-    C { a: int },
+    B(isize),
+    C { a: isize },
 }
 
 impl Foo {
@@ -25,8 +25,8 @@ pub mod nest {
 
     pub enum Bar {
         D,
-        E(int),
-        F { a: int },
+        E(isize),
+        F { a: isize },
     }
 
     impl Bar {
index 5b21d130d1704eb8198518c7424bca700334141f..3bf39b788db6e1e2b6b8c3f9728c1485916cb5ad 100644 (file)
 
 pub enum Foo {
     A,
-    B(int),
-    C { a: int },
+    B(isize),
+    C { a: isize },
 }
 
 impl Foo {
     pub fn foo() {}
     pub fn bar(&self) {}
 }
-
index fc1bea5a9fd41128c88b9a1b2506ed398cdb9477..63639c4cdb3c921eafff3fde33a11bbc7aca58d1 100644 (file)
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 // original problem
-pub fn foo<T>() -> int {
+pub fn foo<T>() -> isize {
     {
-        static foo: int = 2;
+        static foo: isize = 2;
         foo
     }
 }
@@ -20,7 +20,7 @@ pub fn foo<T>() -> int {
 struct Foo;
 impl Foo {
     pub fn foo<T>(&self) {
-        static X: uint = 1;
+        static X: usize = 1;
     }
 }
 
@@ -35,6 +35,6 @@ impl<T: std::iter::Iterator<Item=char>> Parser<T> {
 struct Bar;
 impl Foo {
     pub fn bar<T>(&self) {
-        static X: uint = 1;
+        static X: usize = 1;
     }
 }
index acd5ef0953e6e1fe7957096af0a95b8c1bcd5874..be3414b7ad2c0ab39be4334b3634cc887dda9e89 100644 (file)
@@ -10,4 +10,4 @@
 
 #![crate_type="lib"]
 
-pub struct Au(pub int);
+pub struct Au(pub isize);
index 94b079b1dcfebd225e360c402a8e53e022b79f9f..5ae8e0d298e53b046fb7e0203c6e5f51cac3505e 100644 (file)
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub type oint = Option<int>;
+pub type oint = Option<isize>;
 pub fn foo() -> oint { Some(3) }
index d0ab944813a0ac7c025de01bc2a3d0811825abac..5a615502a95e3200a11aae532eb4c3b4a1e74ffb 100644 (file)
@@ -11,7 +11,7 @@
 // force-host
 
 #![feature(plugin_registrar)]
-#![feature(box_syntax)]
+#![feature(box_syntax, rustc_private)]
 
 extern crate syntax;
 extern crate rustc;
@@ -20,7 +20,7 @@ use std::borrow::ToOwned;
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::ext::build::AstBuilder;
-use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacExpr, NormalTT};
+use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacEager, NormalTT};
 use syntax::parse::token;
 use syntax::print::pprust;
 use syntax::ptr::P;
@@ -38,7 +38,7 @@ impl TTMacroExpander for Expander {
         let args = self.args.iter().map(|i| pprust::meta_item_to_string(&*i))
             .collect::<Vec<_>>().connect(", ");
         let interned = token::intern_and_get_ident(&args[..]);
-        MacExpr::new(ecx.expr_str(sp, interned))
+        MacEager::expr(ecx.expr_str(sp, interned))
     }
 }
 
@@ -46,5 +46,6 @@ impl TTMacroExpander for Expander {
 pub fn plugin_registrar(reg: &mut Registry) {
     let args = reg.args().clone();
     reg.register_syntax_extension(token::intern("plugin_args"),
-        NormalTT(box Expander { args: args, }, None));
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        NormalTT(Box::new(Expander { args: args, }), None, false));
 }
index c460c60b02b06053ebd246fe766aab83baaa968e..5d93c131cadb73cbae3136c4a87844177c7fc3ea 100644 (file)
@@ -11,7 +11,7 @@
 // force-host
 
 #![feature(plugin_registrar)]
-#![feature(box_syntax)]
+#![feature(box_syntax, rustc_private)]
 
 extern crate rustc;
 
@@ -20,7 +20,7 @@ use std::cell::RefCell;
 use rustc::plugin::Registry;
 
 struct Foo {
-    foo: int
+    foo: isize
 }
 
 impl Drop for Foo {
@@ -32,4 +32,3 @@ pub fn registrar(_: &mut Registry) {
     thread_local!(static FOO: RefCell<Option<Box<Any+Send>>> = RefCell::new(None));
     FOO.with(|s| *s.borrow_mut() = Some(box Foo { foo: 10 } as Box<Any+Send>));
 }
-
index cfc8c015324d9384edfcbb88cb5f8b47717b39df..75f404c96cd0e7f380cdfb6e2f7cef70ca06fae1 100644 (file)
@@ -10,7 +10,7 @@
 
 // force-host
 
-#![feature(plugin_registrar)]
+#![feature(plugin_registrar, rustc_private)]
 #![deny(plugin_as_library)] // should have no effect in a plugin crate
 
 extern crate macro_crate_test;
index 8c07dd5b785fd8268c1800bd00a0df747433e817..19cdede5518a4e620f162c7482694f6b45ab9a38 100644 (file)
@@ -12,7 +12,7 @@ pub trait A {
     fn frob(&self);
 }
 
-impl A for int { fn frob(&self) {} }
+impl A for isize { fn frob(&self) {} }
 
 pub fn frob<T:A>(t: T) {
     t.frob();
diff --git a/src/test/auxiliary/privacy-tuple-struct.rs b/src/test/auxiliary/privacy-tuple-struct.rs
deleted file mode 100644 (file)
index 2fb9d99..0000000
+++ /dev/null
@@ -1,14 +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.
-
-pub struct A(());
-pub struct B(int);
-pub struct C(pub int, int);
-pub struct D(pub int);
index 266903169c7b07f373ced546cf85f392a7dd498f..e60dbb290b079a6091c645a453b6889c0e19af6e 100644 (file)
@@ -10,6 +10,6 @@
 
 pub use foo as bar;
 
-mod foo {
+pub mod foo {
     pub fn frob() {}
 }
diff --git a/src/test/auxiliary/privacy_tuple_struct.rs b/src/test/auxiliary/privacy_tuple_struct.rs
new file mode 100644 (file)
index 0000000..141b6bd
--- /dev/null
@@ -0,0 +1,14 @@
+// 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.
+
+pub struct A(());
+pub struct B(isize);
+pub struct C(pub isize, isize);
+pub struct D(pub isize);
index 42691579491bbfb7e7abb069fd995bf62288e8f0..dc08033602c99dfa9a6f9f3aed31ce6ddf1c7412 100644 (file)
@@ -8,4 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(core)]
+
 trait Foo : ::std::marker::MarkerTrait {}
diff --git a/src/test/auxiliary/procedural_mbe_matching.rs b/src/test/auxiliary/procedural_mbe_matching.rs
new file mode 100644 (file)
index 0000000..8c7ad22
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright 2015 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.
+
+// force-host
+
+#![crate_type="dylib"]
+#![feature(plugin_registrar, quote, rustc_private)]
+
+extern crate syntax;
+extern crate rustc;
+
+use syntax::codemap::Span;
+use syntax::parse::token::{self, str_to_ident, NtExpr, NtPat};
+use syntax::ast::{TokenTree, TtToken, Pat};
+use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
+use syntax::ext::build::AstBuilder;
+use syntax::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
+use syntax::ext::tt::macro_parser::{Success, Failure, Error};
+use syntax::ptr::P;
+use rustc::plugin::Registry;
+
+fn expand_mbe_matches(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
+        -> Box<MacResult + 'static> {
+
+    let mbe_matcher = quote_matcher!(cx, $matched:expr, $($pat:pat)|+);
+
+    let mac_expr = match TokenTree::parse(cx, &mbe_matcher[..], args) {
+        Success(map) => {
+            match (&*map[&str_to_ident("matched")], &*map[&str_to_ident("pat")]) {
+                (&MatchedNonterminal(NtExpr(ref matched_expr)),
+                 &MatchedSeq(ref pats, seq_sp)) => {
+                    let pats: Vec<P<Pat>> = pats.iter().map(|pat_nt|
+                        if let &MatchedNonterminal(NtPat(ref pat)) = &**pat_nt {
+                            pat.clone()
+                        } else {
+                            unreachable!()
+                        }
+                    ).collect();
+                    let arm = cx.arm(seq_sp, pats, cx.expr_bool(seq_sp, true));
+
+                    quote_expr!(cx,
+                        match $matched_expr {
+                            $arm
+                            _ => false
+                        }
+                    )
+                }
+                _ => unreachable!()
+            }
+        }
+        Failure(_, s) | Error(_, s) => {
+            panic!("expected Success, but got Error/Failure: {}", s);
+        }
+    };
+
+    MacEager::expr(mac_expr)
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_macro("matches", expand_mbe_matches);
+}
diff --git a/src/test/auxiliary/pub_static_array.rs b/src/test/auxiliary/pub_static_array.rs
new file mode 100644 (file)
index 0000000..4419a5a
--- /dev/null
@@ -0,0 +1,11 @@
+// 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.
+
+pub static ARRAY: &'static [u8] = &[1];
index 8e1e591d94fca8dcc227ac8ae087b8269c828661..41aafd64cb3f488fd8f9f514e83054420c86f3b9 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 pub struct Foo {
-    pub name: int
+    pub name: isize
 }
index 3bad76f0e703e62919f7ea9622bf32ffbe438fd8..cc4db1a9581698afb6790a3c631ca645b8421668 100644 (file)
@@ -17,8 +17,8 @@ pub trait Bar {
     fn bar() -> Self;
 }
 
-impl Bar for int {
-    fn bar() -> int { 84 }
+impl Bar for isize {
+    fn bar() -> isize { 84 }
 }
 
 pub mod sub_foo {
@@ -26,8 +26,8 @@ pub mod sub_foo {
         fn foo() -> Self;
     }
 
-    impl Foo for int {
-        fn foo() -> int { 42 }
+    impl Foo for isize {
+        fn foo() -> isize { 42 }
     }
 
     pub struct Boz {
@@ -35,7 +35,7 @@ pub mod sub_foo {
     }
 
     impl Boz {
-        pub fn boz(i: int) -> bool {
+        pub fn boz(i: isize) -> bool {
             i > 0
         }
     }
diff --git a/src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs b/src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs
deleted file mode 100644 (file)
index 9c0716e..0000000
+++ /dev/null
@@ -1,42 +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.
-
-// Check that method bounds declared on traits/impls in a cross-crate
-// scenario work. This is the library portion of the test.
-
-pub enum MaybeOwned<'a> {
-    Owned(int),
-    Borrowed(&'a int)
-}
-
-pub struct Inv<'a> { // invariant w/r/t 'a
-    x: &'a mut &'a int
-}
-
-// I encountered a bug at some point with encoding the IntoMaybeOwned
-// trait, so I'll use that as the template for this test.
-pub trait IntoMaybeOwned<'a> {
-    fn into_maybe_owned(self) -> MaybeOwned<'a>;
-
-    // Note: without this `into_inv` method, the trait is
-    // contravariant w/r/t `'a`, since if you look strictly at the
-    // interface, it only returns `'a`. This complicates the
-    // downstream test since it wants invariance to force an error.
-    // Hence we add this method.
-    fn into_inv(self) -> Inv<'a>;
-
-    fn bigger_region<'b:'a>(self, b: Inv<'b>);
-}
-
-impl<'a> IntoMaybeOwned<'a> for Inv<'a> {
-    fn into_maybe_owned(self) -> MaybeOwned<'a> { panic!() }
-    fn into_inv(self) -> Inv<'a> { panic!() }
-    fn bigger_region<'b:'a>(self, b: Inv<'b>) { panic!() }
-}
diff --git a/src/test/auxiliary/regions_bounded_method_type_parameters_cross_crate_lib.rs b/src/test/auxiliary/regions_bounded_method_type_parameters_cross_crate_lib.rs
new file mode 100644 (file)
index 0000000..f49ac4f
--- /dev/null
@@ -0,0 +1,42 @@
+// 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 that method bounds declared on traits/impls in a cross-crate
+// scenario work. This is the library portion of the test.
+
+pub enum MaybeOwned<'a> {
+    Owned(isize),
+    Borrowed(&'a isize)
+}
+
+pub struct Inv<'a> { // invariant w/r/t 'a
+    x: &'a mut &'a isize
+}
+
+// I encountered a bug at some point with encoding the IntoMaybeOwned
+// trait, so I'll use that as the template for this test.
+pub trait IntoMaybeOwned<'a> {
+    fn into_maybe_owned(self) -> MaybeOwned<'a>;
+
+    // Note: without this `into_inv` method, the trait is
+    // contravariant w/r/t `'a`, since if you look strictly at the
+    // interface, it only returns `'a`. This complicates the
+    // downstream test since it wants invariance to force an error.
+    // Hence we add this method.
+    fn into_inv(self) -> Inv<'a>;
+
+    fn bigger_region<'b:'a>(self, b: Inv<'b>);
+}
+
+impl<'a> IntoMaybeOwned<'a> for Inv<'a> {
+    fn into_maybe_owned(self) -> MaybeOwned<'a> { panic!() }
+    fn into_inv(self) -> Inv<'a> { panic!() }
+    fn bigger_region<'b:'a>(self, b: Inv<'b>) { panic!() }
+}
index be03a36393e24053b4f27194cb79d464392433ef..86ce3df9ba6efcd0740b132c8b69c6063102d418 100644 (file)
@@ -11,7 +11,7 @@
 // no-prefer-dynamic
 
 #![crate_type = "rlib"]
-#![feature(plugin_registrar)]
+#![feature(plugin_registrar, rustc_private)]
 
 extern crate rustc;
 
index e05aa16ba5fbb730f5c30f340f85579aed376e81..855708535f1e835bc8ac77a6769d045506e2f902 100644 (file)
@@ -11,7 +11,8 @@
 // force-host
 
 #![crate_type="dylib"]
-#![feature(plugin_registrar)]
+#![feature(plugin_registrar, rustc_private)]
+#![feature(slice_patterns)]
 
 extern crate syntax;
 extern crate rustc;
@@ -19,7 +20,7 @@ extern crate rustc;
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::ast::{TokenTree, TtToken};
-use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacExpr};
+use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
 use syntax::ext::build::AstBuilder;  // trait for expr_usize
 use rustc::plugin::Registry;
 
@@ -32,7 +33,7 @@ use rustc::plugin::Registry;
 fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         -> Box<MacResult + 'static> {
 
-    static NUMERALS: &'static [(&'static str, uint)] = &[
+    static NUMERALS: &'static [(&'static str, usize)] = &[
         ("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
         ("C",  100), ("XC",  90), ("L",  50), ("XL",  40),
         ("X",   10), ("IX",   9), ("V",   5), ("IV",   4),
@@ -47,7 +48,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
     };
 
     let mut text = &*text;
-    let mut total = 0_usize;
+    let mut total = 0;
     while !text.is_empty() {
         match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
             Some(&(rn, val)) => {
@@ -61,7 +62,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         }
     }
 
-    MacExpr::new(cx.expr_usize(sp, total))
+    MacEager::expr(cx.expr_usize(sp, total))
 }
 
 #[plugin_registrar]
index 8f5d3b5768a1a1d6a56767fc0dc21447c59bb5dc..72f1f73a81b81b81fbcbaf4c09feb1670b8300d0 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 #[no_mangle]
-pub extern "C" fn foo() -> uint {
+pub extern "C" fn foo() -> usize {
     1234
 }
index 1cb7ead2cff05a85e64be99693cd9143318e68a6..d62b98714026bd5ce78a7afa5b506eecc7cbb067 100644 (file)
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 #[inline]
-pub fn cci_fn() -> uint {
+pub fn cci_fn() -> usize {
     1200
 }
 
 #[inline]
-pub static CCI_STATIC: uint = 34;
+pub static CCI_STATIC: usize = 34;
index d1d9e3b8ff3ac7b12890e765d2fc546faa6d6d71..9aa16fb2694574c9f373d61fed16ece770d409db 100644 (file)
 // compile-flags: -C codegen-units=3 --crate-type=rlib,dylib
 
 pub mod a {
-    pub fn one() -> uint {
+    pub fn one() -> usize {
         1
     }
 }
 
 pub mod b {
-    pub fn two() -> uint {
+    pub fn two() -> usize {
         2
     }
 }
@@ -25,7 +25,7 @@ pub mod b {
 pub mod c {
     use a::one;
     use b::two;
-    pub fn three() -> uint {
+    pub fn three() -> usize {
         one() + two()
     }
 }
index 27befee6f07f5cea2b7efbf4722460668c1cc7eb..2ccdb4e086447f642b43c9f8debcece691047524 100644 (file)
@@ -8,9 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_name="static-function-pointer-aux"]
 
-pub fn f(x: int) -> int { -x }
+pub fn f(x: isize) -> isize { -x }
 
-pub static F: fn(int) -> int = f;
-pub static mut MutF: fn(int) -> int = f;
+pub static F: fn(isize) -> isize = f;
+pub static mut MutF: fn(isize) -> isize = f;
index d84ded25702f4b38de4abf61bb5721b6e526068a..e61fb49add5b1e7aa5f53082113d483488178d3c 100644 (file)
 #![crate_name="static_methods_crate"]
 #![crate_type = "lib"]
 
-use std::int;
-
 pub trait read {
     fn readMaybe(s: String) -> Option<Self>;
 }
 
-impl read for int {
-    fn readMaybe(s: String) -> Option<int> {
+impl read for isize {
+    fn readMaybe(s: String) -> Option<isize> {
         s.parse().ok()
     }
 }
index 0cbd4378490d935676323ae250dc91f22f4c8d07..2193e12bceb2816fd2073e1689abdb78430444da 100644 (file)
 
 pub mod num {
     pub trait Num2 {
-        fn from_int2(n: int) -> Self;
+        fn from_int2(n: isize) -> Self;
     }
 }
 
 pub mod f64 {
     impl ::num::Num2 for f64 {
         #[inline]
-        fn from_int2(n: int) -> f64 { return n as f64;  }
+        fn from_int2(n: isize) -> f64 { return n as f64;  }
     }
 }
index 8785a8085dc359ac7e75e6938b4b8d8cc5c17f09..44e875fbe3c0519a7fa0f42532a234db3f825842 100644 (file)
 
 pub mod num {
     pub trait Num2 {
-        fn from_int2(n: int) -> Self;
+        fn from_int2(n: isize) -> Self;
     }
 }
 
 pub mod f64 {
     impl ::num::Num2 for f64 {
-        fn from_int2(n: int) -> f64 { return n as f64;  }
+        fn from_int2(n: isize) -> f64 { return n as f64;  }
     }
 }
index 5660fd5b61f9db76ca044052d26e5cb208832339..9d677e3dc46071255caabb08793bfd8a6dc524df 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub static mut a: int = 3;
+pub static mut a: isize = 3;
index 6951ed729b27bb162c50b6a83e106dad3db99c06..859f38e809f917c4c32eaea6ef7f6cdbc0c1f0be 100644 (file)
@@ -10,8 +10,8 @@
 
 #![crate_type = "lib"]
 
-static private: int = 0;
-pub static public: int = 0;
+static private: isize = 0;
+pub static public: isize = 0;
 
 pub struct A(());
 
@@ -20,11 +20,11 @@ impl A {
 }
 
 mod foo {
-    pub static a: int = 0;
+    pub static a: isize = 0;
     pub fn b() {}
     pub struct c;
     pub enum d {}
-    pub type e = int;
+    pub type e = isize;
 
     pub struct A(());
 
@@ -33,11 +33,11 @@ mod foo {
     }
 
     // these are public so the parent can reexport them.
-    pub static reexported_a: int = 0;
+    pub static reexported_a: isize = 0;
     pub fn reexported_b() {}
     pub struct reexported_c;
     pub enum reexported_d {}
-    pub type reexported_e = int;
+    pub type reexported_e = isize;
 }
 
 pub mod bar {
@@ -48,14 +48,14 @@ pub mod bar {
     pub use foo::reexported_e as i;
 }
 
-pub static a: int = 0;
+pub static a: isize = 0;
 pub fn b() {}
 pub struct c;
 pub enum d {}
-pub type e = int;
+pub type e = isize;
 
-static j: int = 0;
+static j: isize = 0;
 fn k() {}
 struct l;
 enum m {}
-type n = int;
+type n = isize;
diff --git a/src/test/auxiliary/struct-field-privacy.rs b/src/test/auxiliary/struct-field-privacy.rs
deleted file mode 100644 (file)
index e2c16ae..0000000
+++ /dev/null
@@ -1,19 +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.
-
-struct A {
-    a: int,
-    pub b: int,
-}
-
-pub struct B {
-    pub a: int,
-    b: int,
-}
index 3f386ab55d585625a6aabdb0817f48d0f1b3dabd..26941b726d4c04425405ff299a0557cf8d8cd5c7 100644 (file)
@@ -11,6 +11,6 @@
 #![crate_type="lib"]
 
 pub struct S {
-    pub x: int,
-    pub y: int,
+    pub x: isize,
+    pub y: isize,
 }
diff --git a/src/test/auxiliary/struct_field_privacy.rs b/src/test/auxiliary/struct_field_privacy.rs
new file mode 100644 (file)
index 0000000..fe1dc9d
--- /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.
+
+struct A {
+    a: isize,
+    pub b: isize,
+}
+
+pub struct B {
+    pub a: isize,
+    b: isize,
+}
index 0bdda23508038a8245d8f3bc8d6b14ef1ee1a6e5..40868fa3f706e8fca58c5a1b42ca94f8be59a0ba 100644 (file)
@@ -9,6 +9,5 @@
 // except according to those terms.
 
 enum Bar {
-    Baz { a: int }
+    Baz { a: isize }
 }
-
index 76fd619f689648adba8e8cc2c444c3e50c8f3099..201f028b6b658acc981dbb5eca0f04ac44f75854 100644 (file)
@@ -11,6 +11,7 @@
 #![crate_name="struct_variant_xc_aux"]
 #![crate_type = "lib"]
 
+#[derive(Copy, Clone)]
 pub enum Enum {
     Variant(u8),
     StructVariant { arg: u8 }
index 04f1062c16f02a572e8f97c9345b2f6b99469983..7e10d2158ede08bda3eeba69d6cc8729f5b8c8b5 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -26,12 +27,12 @@ pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
-static A_CONSTANT : int = 2;
+static A_CONSTANT : isize = 2;
 
-pub fn foo<T:U>(_: int) -> int {
+pub fn foo<T:U>(_: isize) -> isize {
     3
 }
 
-pub fn an_unused_name() -> int {
+pub fn an_unused_name() -> isize {
     4
 }
index fabd2289e9a44ea61c62f41c56fb5c41a7b2be99..c5f38805511650925110d59c68159481bf2d0028 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -26,12 +27,12 @@ pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
-static A_CONSTANT : int = 2;
+static A_CONSTANT : isize = 2;
 
-pub fn foo<T:U>(_: int) -> int {
+pub fn foo<T:U>(_: isize) -> isize {
     0
 }
 
-pub fn an_unused_name() -> int {
+pub fn an_unused_name() -> isize {
     4
 }
index 3fdb861bd40c178d430e26c4b51059b55debb0d8..3168e747eb6e694c6222848a08c389458f23ef14 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -26,14 +27,14 @@ pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
-static A_CONSTANT : int = 2;
+static A_CONSTANT : isize = 2;
 
 #[cfg(some_flag)]
-pub fn foo<T:U>(_: int) -> int {
+pub fn foo<T:U>(_: isize) -> isize {
     3
 }
 
 #[cfg(not(some_flag))]
-pub fn an_unused_name() -> int {
+pub fn an_unused_name() -> isize {
     4
 }
index 3116d24673d4847bef21ac198e648c5f098a4257..f86a43494f78e740718e55b9306b5d6758550f98 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -26,12 +27,12 @@ pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
-static A_CONSTANT : int = 2;
+static A_CONSTANT : isize = 2;
 
-pub fn foo<T:V>(_: int) -> int {
+pub fn foo<T:V>(_: isize) -> isize {
     3
 }
 
-pub fn an_unused_name() -> int {
+pub fn an_unused_name() -> isize {
     4
 }
index b49a1533628f6f526225f062d21e06987dca295b..dc412b700447beade18887dd4b577e60b3a393c4 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -26,12 +27,12 @@ pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
-static A_CONSTANT : int = 2;
+static A_CONSTANT : isize = 2;
 
-pub fn foo<T:U>(_: i32) -> int {
+pub fn foo<T:U>(_: i32) -> isize {
     3
 }
 
-pub fn an_unused_name() -> int {
+pub fn an_unused_name() -> isize {
     4
 }
index 6562a93135f39740c5210eaa7824ed37668ffdd5..0cfcbbb0554e684f7304a64001ad78234195afec 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -26,9 +27,9 @@ pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
-static A_CONSTANT : int = 2;
+static A_CONSTANT : isize = 2;
 
-pub fn foo<T:U>(_: int) -> i64 {
+pub fn foo<T:U>(_: isize) -> i64 {
     3
 }
 
index c7b392c6ee82b07b942cd7188a9fe316b8ad7579..e1e32095b5cb40d4e4c9dc5582ae5679dec65234 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -28,10 +29,10 @@ impl V for () {}
 
 static A_CONSTANT : i32 = 2;
 
-pub fn foo<T:U>(_: int) -> int {
+pub fn foo<T:U>(_: isize) -> isize {
     3
 }
 
-pub fn an_unused_name() -> int {
+pub fn an_unused_name() -> isize {
     4
 }
index 450f61020260dd49416c27ea402223efd0c20157..9fd97376b6681232843fcea84aa0b42d06ec2ce9 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -26,13 +27,13 @@ pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
-static A_CONSTANT : int = 2;
+static A_CONSTANT : isize = 2;
 
-pub fn foo<T:U>(_: int) -> int {
+pub fn foo<T:U>(_: isize) -> isize {
     // a comment does not affect the svh
     3
 }
 
-pub fn an_unused_name() -> int {
+pub fn an_unused_name() -> isize {
     4
 }
index c000737c854c6a85b1264f8a87c251ac718a9d40..e64bde096b0169b0a334ce420492f434f6a17e32 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -26,15 +27,15 @@ pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
-static A_CONSTANT : int = 2;
+static A_CONSTANT : isize = 2;
 
 // Adding some documentation does not affect the svh.
 
 /// foo always returns three.
-pub fn foo<T:U>(_: int) -> int {
+pub fn foo<T:U>(_: isize) -> isize {
     3
 }
 
-pub fn an_unused_name() -> int {
+pub fn an_unused_name() -> isize {
     4
 }
index 1e12659dc4b92f15dff148558217b6eb28ba4446..b16338f1e128c87d0bb3d6b7b44e41f1fb38b8e3 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -26,14 +27,14 @@ pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
-static A_CONSTANT : int = 2;
+static A_CONSTANT : isize = 2;
 
-pub fn foo<T:U>(_: int) -> int {
+pub fn foo<T:U>(_: isize) -> isize {
     // a macro invocation in a function body does not affect the svh,
     // as long as it yields the same code.
     three!()
 }
 
-pub fn an_unused_name() -> int {
+pub fn an_unused_name() -> isize {
     4
 }
index 04f1062c16f02a572e8f97c9345b2f6b99469983..7e10d2158ede08bda3eeba69d6cc8729f5b8c8b5 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -26,12 +27,12 @@ pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
-static A_CONSTANT : int = 2;
+static A_CONSTANT : isize = 2;
 
-pub fn foo<T:U>(_: int) -> int {
+pub fn foo<T:U>(_: isize) -> isize {
     3
 }
 
-pub fn an_unused_name() -> int {
+pub fn an_unused_name() -> isize {
     4
 }
index 1e82b74f1ef2e5cd6240b735add8776a5a0d025f..8cadd7bdf4174e1faeca675ebde218ea6563c8e0 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -26,14 +27,14 @@ pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
-static A_CONSTANT : int = 2;
+static A_CONSTANT : isize = 2;
 
 // cfg attribute does not affect the svh, as long as it yields the same code.
 #[cfg(not(an_unused_name))]
-pub fn foo<T:U>(_: int) -> int {
+pub fn foo<T:U>(_: isize) -> isize {
     3
 }
 
-pub fn an_unused_name() -> int {
+pub fn an_unused_name() -> isize {
     4
 }
index 3c3dac9cdab96209dc789d35c42546ffd90ec6ef..fcaf77909554dd8bad665175ef690055b2540a61 100644 (file)
@@ -14,6 +14,7 @@
 //! (#14132).
 
 #![crate_name = "a"]
+#![feature(core)]
 
 use std::marker::MarkerTrait;
 
@@ -26,14 +27,14 @@ pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
-static A_CONSTANT : int = 2;
+static A_CONSTANT : isize = 2;
 
-pub fn foo<T:U>(_: int) -> int {
+pub fn foo<T:U>(_: isize) -> isize {
 
     3
 
 }
 
-pub fn an_unused_name() -> int {
+pub fn an_unused_name() -> isize {
     4
 }
index 67fdac5df0330d38259a81a7087be887ce943327..6bd3ddab06c72426877cec82686ff2a69112ef3b 100644 (file)
 #![crate_name = "uta"]
 
 mod traits {
-    pub trait TraitA { fn val(&self) -> int { 2 } }
-    pub trait TraitB { fn val(&self) -> int { 3 } }
+    pub trait TraitA { fn val(&self) -> isize { 2 } }
+    pub trait TraitB { fn val(&self) -> isize { 3 } }
 }
 
 impl traits::TraitA for () {}
 impl traits::TraitB for () {}
 
-pub fn foo<T>(_: int) -> int {
+pub fn foo<T>(_: isize) -> isize {
     use traits::TraitA;
     let v = ();
     v.val()
index dfcf02c0ff500ab4327fae00f279cc174d818d8e..e863416817735b1a0de7a2a089aca9aea064ccd0 100644 (file)
 #![crate_name = "uta"]
 
 mod traits {
-    pub trait TraitA { fn val(&self) -> int { 2 } }
-    pub trait TraitB { fn val(&self) -> int { 3 } }
+    pub trait TraitA { fn val(&self) -> isize { 2 } }
+    pub trait TraitB { fn val(&self) -> isize { 3 } }
 }
 
 impl traits::TraitA for () {}
 impl traits::TraitB for () {}
 
-pub fn foo<T>(_: int) -> int {
+pub fn foo<T>(_: isize) -> isize {
     use traits::TraitB;
     let v = ();
     v.val()
index 338e04fbb074646cb9d46c06654ea662c68490a6..fadeb02440533aa00a36138359526b307ddab95b 100644 (file)
@@ -12,6 +12,6 @@
 
 #![crate_type = "dylib"]
 
-pub fn the_answer() -> int {
+pub fn the_answer() -> isize {
     2
 }
index 7a24dd76f32c8e6093da9d92424204c2b173ca5a..4980eb8b91386b681911f1d5174ab628179ed76f 100644 (file)
@@ -11,9 +11,9 @@
 // force-host
 
 #![crate_type = "dylib"]
-#![feature(plugin_registrar, quote)]
+#![feature(plugin_registrar, quote, rustc_private)]
 
-extern crate "syntax_extension_with_dll_deps_1" as other;
+extern crate syntax_extension_with_dll_deps_1 as other;
 extern crate syntax;
 extern crate rustc;
 
@@ -30,5 +30,5 @@ pub fn plugin_registrar(reg: &mut Registry) {
 fn expand_foo(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
               -> Box<MacResult+'static> {
     let answer = other::the_answer();
-    MacExpr::new(quote_expr!(cx, $answer))
+    MacEager::expr(quote_expr!(cx, $answer))
 }
diff --git a/src/test/auxiliary/trait-safety-lib.rs b/src/test/auxiliary/trait-safety-lib.rs
deleted file mode 100644 (file)
index d543769..0000000
+++ /dev/null
@@ -1,19 +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.
-
-// Simple smoke test that unsafe traits can be compiled etc.
-
-pub unsafe trait Foo {
-    fn foo(&self) -> int;
-}
-
-unsafe impl Foo for int {
-    fn foo(&self) -> int { *self }
-}
index a7c469fccaa5abbcba151be4cb6e579771fd3cae..29cb0bc176a257dd03d6d088368f0b73a6608e6a 100644 (file)
@@ -17,8 +17,7 @@ pub struct Foo<T:Trait> {
 }
 
 pub enum Bar<T:Trait> {
-    ABar(int),
+    ABar(isize),
     BBar(T),
-    CBar(uint),
+    CBar(usize),
 }
-
index 7424c21be3da0c6b05fd5f6b4091951002dc68c7..c1168a912dc6846d8085012f5873109143771318 100644 (file)
@@ -8,24 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_name="trait_default_method_xc_aux"]
-
-pub struct Something { pub x: int }
+pub struct Something { pub x: isize }
 
 pub trait A {
-    fn f(&self) -> int;
-    fn g(&self) -> int { 10 }
-    fn h(&self) -> int { 11 }
-    fn lurr(x: &Self, y: &Self) -> int { x.g() + y.h() }
+    fn f(&self) -> isize;
+    fn g(&self) -> isize { 10 }
+    fn h(&self) -> isize { 11 }
+    fn lurr(x: &Self, y: &Self) -> isize { x.g() + y.h() }
 }
 
 
-impl A for int {
-    fn f(&self) -> int { 10 }
+impl A for isize {
+    fn f(&self) -> isize { 10 }
 }
 
 impl A for Something {
-    fn f(&self) -> int { 10 }
+    fn f(&self) -> isize { 10 }
 }
 
 pub trait B<T> {
@@ -33,7 +31,7 @@ pub trait B<T> {
     fn staticthing<U>(_z: &Self, x: T, y: U) -> (T, U) { (x, y) }
 }
 
-impl<T> B<T> for int { }
+impl<T> B<T> for isize { }
 impl B<f64> for bool { }
 
 
@@ -45,8 +43,8 @@ pub trait TestEquality {
     }
 }
 
-impl TestEquality for int {
-    fn test_eq(&self, rhs: &int) -> bool {
+impl TestEquality for isize {
+    fn test_eq(&self, rhs: &isize) -> bool {
         *self == *rhs
     }
 }
index 4239865d577ae9d188766766dbf712f3e2ec0aa4..7443ef9c0f35943967dce12cc2e374950e914851 100644 (file)
 
 // aux-build:trait_default_method_xc_aux.rs
 
-extern crate "trait_default_method_xc_aux" as aux;
+extern crate trait_default_method_xc_aux as aux;
 use aux::A;
 
-pub struct a_struct { pub x: int }
+pub struct a_struct { pub x: isize }
 
 impl A for a_struct {
-    fn f(&self) -> int { 10 }
+    fn f(&self) -> isize { 10 }
 }
 
 // This function will need to get inlined, and badness may result.
index 0982efbdbf47e4d8770a7adc1aa0aa4a78ac5071..0adedfd4eeb22c9f61c96b88c94b04fdc6d0f02b 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(core)]
+
 pub trait Foo : ::std::marker::MarkerTrait {
 }
 
-impl Foo for int {
+impl Foo for isize {
 }
index 9ef53795a26b44534c1ff0dc65cff8ac9c98d4e9..af0128d9676226fe3ffc73e00244bd11574bac46 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Foo { fn f(&self) -> int; }
-pub trait Bar { fn g(&self) -> int; }
-pub trait Baz { fn h(&self) -> int; }
+pub trait Foo { fn f(&self) -> isize; }
+pub trait Bar { fn g(&self) -> isize; }
+pub trait Baz { fn h(&self) -> isize; }
 
-pub struct A { pub x: int }
+pub struct A { pub x: isize }
 
-impl Foo for A { fn f(&self) -> int { 10 } }
-impl Bar for A { fn g(&self) -> int { 20 } }
-impl Baz for A { fn h(&self) -> int { 30 } }
+impl Foo for A { fn f(&self) -> isize { 10 } }
+impl Bar for A { fn g(&self) -> isize { 20 } }
+impl Baz for A { fn h(&self) -> isize { 30 } }
index 59fdaed744e3acb14c2d85dcf083de21868275f7..6be1f8c45f48db0b39612be0f782fa0240186971 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Foo { fn f(&self) -> int; }
-pub trait Bar { fn g(&self) -> int; }
-pub trait Baz { fn h(&self) -> int; }
+pub trait Foo { fn f(&self) -> isize; }
+pub trait Bar { fn g(&self) -> isize; }
+pub trait Baz { fn h(&self) -> isize; }
 
 pub trait Quux: Foo + Bar + Baz { }
 
index 0a84595124a12d366664db795398cc048377fc8e..9eeb815c5de88a0088256dd66b1fb51d6100dd59 100644 (file)
 
 
 pub trait Foo {
-    fn f(&self) -> int;
+    fn f(&self) -> isize;
 }
 
 pub struct A {
-    pub x: int
+    pub x: isize
 }
 
 impl Foo for A {
-    fn f(&self) -> int { 10 }
+    fn f(&self) -> isize { 10 }
 }
index 36442ed6c193114ae722f1eb05db77845f0029e8..1bfada612ebf6f3f1fdc3adee35c634c42938494 100644 (file)
@@ -16,7 +16,7 @@ pub trait MyNum : Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + Parti
 
 #[derive(Clone, Debug)]
 pub struct MyInt {
-    pub val: int
+    pub val: isize
 }
 
 impl Add for MyInt {
@@ -45,4 +45,4 @@ impl PartialEq for MyInt {
 
 impl MyNum for MyInt {}
 
-fn mi(v: int) -> MyInt { MyInt { val: v } }
+fn mi(v: isize) -> MyInt { MyInt { val: v } }
diff --git a/src/test/auxiliary/trait_safety_lib.rs b/src/test/auxiliary/trait_safety_lib.rs
new file mode 100644 (file)
index 0000000..585a756
--- /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.
+
+// Simple smoke test that unsafe traits can be compiled etc.
+
+pub unsafe trait Foo {
+    fn foo(&self) -> isize;
+}
+
+unsafe impl Foo for isize {
+    fn foo(&self) -> isize { *self }
+}
diff --git a/src/test/auxiliary/typeck_default_trait_impl_cross_crate_coherence_lib.rs b/src/test/auxiliary/typeck_default_trait_impl_cross_crate_coherence_lib.rs
new file mode 100644 (file)
index 0000000..5a7a3e7
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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(optin_builtin_traits, core)]
+#![crate_type = "rlib"]
+
+use std::marker::MarkerTrait;
+
+pub trait DefaultedTrait : MarkerTrait { }
+impl DefaultedTrait for .. { }
+
+pub struct Something<T> { t: T }
index 82f613ee117ca63966af0532f5d3473b3b46b41c..388d3238d4248960c37b2a317d249fca570f5a69 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::any::TypeId;
+#![feature(core)]
+
+use std::any::{Any, TypeId};
 
 pub struct A;
 pub struct B(Option<A>);
-pub struct C(Option<int>);
+pub struct C(Option<isize>);
 pub struct D(Option<&'static str>);
-pub struct E(Result<&'static str, int>);
+pub struct E(Result<&'static str, isize>);
 
-pub type F = Option<int>;
-pub type G = uint;
+pub type F = Option<isize>;
+pub type G = usize;
 pub type H = &'static str;
 
 pub unsafe fn id_A() -> TypeId { TypeId::of::<A>() }
@@ -29,4 +31,4 @@ pub unsafe fn id_F() -> TypeId { TypeId::of::<F>() }
 pub unsafe fn id_G() -> TypeId { TypeId::of::<G>() }
 pub unsafe fn id_H() -> TypeId { TypeId::of::<H>() }
 
-pub unsafe fn foo<T: 'static>() -> TypeId { TypeId::of::<T>() }
+pub unsafe fn foo<T: Any>() -> TypeId { TypeId::of::<T>() }
index 82f613ee117ca63966af0532f5d3473b3b46b41c..3ad307fd3b507b6b3cf199b4abb946227c881beb 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::any::TypeId;
+#![feature(core)]
+
+use std::any::{Any, TypeId};
 
 pub struct A;
 pub struct B(Option<A>);
-pub struct C(Option<int>);
+pub struct C(Option<isize>);
 pub struct D(Option<&'static str>);
-pub struct E(Result<&'static str, int>);
+pub struct E(Result<&'static str, isize>);
 
-pub type F = Option<int>;
-pub type G = uint;
+pub type F = Option<isize>;
+pub type G = usize;
 pub type H = &'static str;
 
 pub unsafe fn id_A() -> TypeId { TypeId::of::<A>() }
@@ -29,4 +31,4 @@ pub unsafe fn id_F() -> TypeId { TypeId::of::<F>() }
 pub unsafe fn id_G() -> TypeId { TypeId::of::<G>() }
 pub unsafe fn id_H() -> TypeId { TypeId::of::<H>() }
 
-pub unsafe fn foo<T: 'static>() -> TypeId { TypeId::of::<T>() }
+pub unsafe fn foo<T:Any>() -> TypeId { TypeId::of::<T>() }
index a5178c03443f796bff07ebc61cdb2785bf974657..dac20dd2f7a790130667ddd55da448e73f25fe50 100644 (file)
 use std::ops::Add;
 
 #[inline]
-pub fn has_closures() -> uint {
-    let x = 1_usize;
+pub fn has_closures() -> usize {
+    let x = 1;
     let mut f = move || x;
-    let y = 1_usize;
+    let y = 1;
     let g = || y;
     f() + g()
 }
diff --git a/src/test/auxiliary/unreachable-variant.rs b/src/test/auxiliary/unreachable-variant.rs
deleted file mode 100644 (file)
index 8ca85f2..0000000
+++ /dev/null
@@ -1,15 +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.
-
-mod super_sekrit {
-    pub enum sooper_sekrit {
-        quux, baz
-    }
-}
diff --git a/src/test/auxiliary/unreachable_variant.rs b/src/test/auxiliary/unreachable_variant.rs
new file mode 100644 (file)
index 0000000..8ca85f2
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+mod super_sekrit {
+    pub enum sooper_sekrit {
+        quux, baz
+    }
+}
index fa254cb91ad53e87ee17fb4ede2e84d8c126419a..ceffae79677f4100f55d7d94ef219c9383f58a1e 100644 (file)
@@ -13,7 +13,7 @@
 // This aux-file will require the eh_personality function to be codegen'd, but
 // it hasn't been defined just yet. Make sure we don't explode.
 
-#![feature(no_std)]
+#![feature(no_std, core)]
 #![no_std]
 #![crate_type = "rlib"]
 
@@ -34,4 +34,3 @@ pub fn foo() {
 mod std {
     pub use core::{option, fmt};
 }
-
index 002b31f099f381587d20dfa5ad4bc9d9eb868c53..4549bd719c65e15618646725a20e17df4ef108fe 100644 (file)
@@ -27,4 +27,3 @@ impl<T> Equal for T where T: Eq {
 pub fn equal<T>(x: &T, y: &T) -> bool where T: Eq {
     x == y
 }
-
index 07c99ecefb861cf0c612592209ca003d5dae0738..5e7bc61943be57efb922d751d3f0cefd1c39fb7d 100644 (file)
@@ -11,7 +11,7 @@
 #![crate_type="lib"]
 
 pub struct Struct {
-    pub x: int
+    pub x: isize
 }
 
 impl Struct {
@@ -19,14 +19,14 @@ impl Struct {
         Struct { x: 1 }
     }
 
-    fn meth_struct(&self) -> int {
+    fn meth_struct(&self) -> isize {
         self.x
     }
 }
 
 pub enum Enum {
-    Variant1(int),
-    Variant2(int)
+    Variant1(isize),
+    Variant2(isize)
 }
 
 impl Enum {
@@ -34,7 +34,7 @@ impl Enum {
         Enum::Variant2(10)
     }
 
-    fn meth_enum(&self) -> int {
+    fn meth_enum(&self) -> isize {
         match *self {
             Enum::Variant1(x) |
             Enum::Variant2(x) => x
index 9e62415a20b4e8d6b615980ecc188d6d5088099a..5195839c067f7c4ee1a1d97cf38148ac4bff9235 100644 (file)
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn foo<T>() -> int {
-    static a: int = 3;
+pub fn foo<T>() -> isize {
+    static a: isize = 3;
     a
 }
 
-pub fn bar() -> int {
-    foo::<int>()
+pub fn bar() -> isize {
+    foo::<isize>()
 }
index 8065533dd738269766733fe45ec908a17c1deefc..652f11a71ec6f6d82ed403e4c76932e80202753f 100644 (file)
@@ -9,22 +9,22 @@
 // except according to those terms.
 
 #[inline(never)]
-pub static global: int = 3;
+pub static global: isize = 3;
 
 #[inline(never)]
-static global0: int = 4;
+static global0: isize = 4;
 
 #[inline(never)]
-pub static global2: &'static int = &global0;
+pub static global2: &'static isize = &global0;
 
-pub fn verify_same(a: &'static int) {
-    let a = a as *const int as uint;
-    let b = &global as *const int as uint;
+pub fn verify_same(a: &'static isize) {
+    let a = a as *const isize as usize;
+    let b = &global as *const isize as usize;
     assert_eq!(a, b);
 }
 
-pub fn verify_same2(a: &'static int) {
-    let a = a as *const int as uint;
-    let b = global2 as *const int as uint;
+pub fn verify_same2(a: &'static isize) {
+    let a = a as *const isize as usize;
+    let b = global2 as *const isize as usize;
     assert_eq!(a, b);
 }
index a0ec7272720dc09da96a8dfe7b0216967cd55909..334f7829bd1923c409c6f1dbcc411971ef4d35e5 100644 (file)
@@ -9,9 +9,8 @@
 // except according to those terms.
 
 pub struct S {
-    pub x: int,
-    pub y: int,
+    pub x: isize,
+    pub y: isize,
 }
 
 pub type S2 = S;
-
index 7ae36554079166397c4a4ca73de7748384240fed..7a69be2b06c7cf2438a8f3c61fd2013871a76845 100644 (file)
 
 // used by the rpass test
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Struct;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum Unit {
     UnitVariant,
     Argument(Struct)
 }
 
-#[derive(Copy)]
-pub struct TupleStruct(pub uint, pub &'static str);
+#[derive(Copy, Clone)]
+pub struct TupleStruct(pub usize, pub &'static str);
 
 // used by the cfail test
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct StructWithFields {
-    foo: int,
+    foo: isize,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum EnumWithVariants {
     EnumVariant,
-    EnumVariantArg(int)
+    EnumVariantArg(isize)
 }
-
index 4909d84a34f126960aadfb6e28343ceb275a34fd..0cff90d61ed995c95959ae57c74fcdb9a39d2509 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, std_misc, rand)]
 
 use std::collections::{BTreeMap, HashMap, HashSet};
 use std::env;
index 994c9605fc375ccbaec7c386c6612f9a951b62b5..aeedaa288fef810f3bec9db55f07e7e93a8a9022 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty very bad with line comments
 
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, rand, std_misc, collections)]
 
 extern crate collections;
 extern crate rand;
index 4c3b3f42acaa9470b77c294bd9525e8adcf878ab..0344d6a46eeb58ffd54af4db766b59ec7c13785f 100644 (file)
 // ignore-lexer-test FIXME #15679
 // Microbenchmarks for various functions in std and extra
 
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, rand, old_io, old_path, std_misc, collections)]
 
-use std::old_io::File;
+use std::old_io::*;
+use std::old_path::{Path, GenericPath};
 use std::iter::repeat;
 use std::mem::swap;
 use std::env;
index b8d8f0cc9e6a9511acb6c5c86681c586174316d0..c7748d59c6a0481f85b68a36510c90556ff2307d 100644 (file)
@@ -18,6 +18,8 @@
 // different scalability characteristics compared to the select
 // version.
 
+#![feature(std_misc)]
+
 use std::sync::mpsc::{channel, Sender, Receiver};
 use std::env;
 use std::thread;
@@ -27,11 +29,11 @@ fn move_out<T>(_x: T) {}
 
 enum request {
     get_count,
-    bytes(uint),
+    bytes(usize),
     stop
 }
 
-fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
+fn server(requests: &Receiver<request>, responses: &Sender<usize>) {
     let mut count = 0;
     let mut done = false;
     while !done {
@@ -53,8 +55,8 @@ fn run(args: &[String]) {
     let (to_parent, from_child) = channel();
     let (to_child, from_parent) = channel();
 
-    let size = args[1].parse::<uint>().unwrap();
-    let workers = args[2].parse::<uint>().unwrap();
+    let size = args[1].parse::<usize>().unwrap();
+    let workers = args[2].parse::<usize>().unwrap();
     let num_bytes = 100;
     let mut result = None;
     let mut p = Some((to_child, to_parent, from_parent));
index 3642eb82fdb0517f4200f1b9c1676e7348380a91..b6a6e06088a09dddf770ce5722183b35369b2f1b 100644 (file)
@@ -14,6 +14,8 @@
 //
 // I *think* it's the same, more or less.
 
+#![feature(std_misc)]
+
 use std::sync::mpsc::{channel, Sender, Receiver};
 use std::env;
 use std::thread;
@@ -21,12 +23,12 @@ use std::time::Duration;
 
 enum request {
     get_count,
-    bytes(uint),
+    bytes(usize),
     stop
 }
 
-fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
-    let mut count: uint = 0;
+fn server(requests: &Receiver<request>, responses: &Sender<usize>) {
+    let mut count: usize = 0;
     let mut done = false;
     while !done {
         match requests.recv() {
@@ -46,8 +48,8 @@ fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
 fn run(args: &[String]) {
     let (to_parent, from_child) = channel();
 
-    let size = args[1].parse::<uint>().unwrap();
-    let workers = args[2].parse::<uint>().unwrap();
+    let size = args[1].parse::<usize>().unwrap();
+    let workers = args[2].parse::<usize>().unwrap();
     let num_bytes = 100;
     let mut result = None;
     let mut to_parent = Some(to_parent);
index a980b7ed9e75d0d72446f04b633ccc8505a0bbfc..c87cdb617a477732e093a26d53fefa3b622d6245 100644 (file)
 // no-pretty-expanded FIXME #15189
 // ignore-lexer-test FIXME #15679
 
+#![feature(std_misc)]
+
 use std::env;
 use std::sync::{Arc, Future, Mutex, Condvar};
 use std::time::Duration;
 
 // A poor man's pipe.
-type pipe = Arc<(Mutex<Vec<uint>>, Condvar)>;
+type pipe = Arc<(Mutex<Vec<usize>>, Condvar)>;
 
-fn send(p: &pipe, msg: uint) {
+fn send(p: &pipe, msg: usize) {
     let &(ref lock, ref cond) = &**p;
     let mut arr = lock.lock().unwrap();
     arr.push(msg);
     cond.notify_one();
 }
-fn recv(p: &pipe) -> uint {
+fn recv(p: &pipe) -> usize {
     let &(ref lock, ref cond) = &**p;
     let mut arr = lock.lock().unwrap();
     while arr.is_empty() {
@@ -46,7 +48,7 @@ fn init() -> (pipe,pipe) {
 }
 
 
-fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
+fn thread_ring(i: usize, count: usize, num_chan: pipe, num_port: pipe) {
     let mut num_chan = Some(num_chan);
     let mut num_port = Some(num_port);
     // Send/Receive lots of messages.
@@ -72,8 +74,8 @@ fn main() {
         args.collect()
     };
 
-    let num_tasks = args[1].parse::<uint>().unwrap();
-    let msg_per_task = args[2].parse::<uint>().unwrap();
+    let num_tasks = args[1].parse::<usize>().unwrap();
+    let msg_per_task = args[2].parse::<usize>().unwrap();
 
     let (num_chan, num_port) = init();
 
index 53c52ae3019f015a11204a29d1132b145fb0b4de..83c39b3f3faf6c9e5b68d474b6b96464da7914c2 100644 (file)
 // See https://github.com/nsf/pnoise for timings and alternative implementations.
 // ignore-lexer-test FIXME #15679
 
+#![feature(rand, core)]
+
 use std::f32::consts::PI;
 use std::num::Float;
 use std::rand::{Rng, StdRng};
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Vec2 {
     x: f32,
     y: f32,
@@ -27,7 +29,7 @@ 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) }
 
 fn random_gradient<R: Rng>(r: &mut R) -> Vec2 {
-    let v = PI * 2.0 * r.gen();
+    let v = PI * 2.0 * r.gen::<f32>();
     Vec2 { x: v.cos(), y: v.sin() }
 }
 
@@ -45,11 +47,11 @@ impl Noise2DContext {
         let mut rng = StdRng::new().unwrap();
 
         let mut rgradients = [Vec2 { x: 0.0, y: 0.0 }; 256];
-        for x in &mut rgradients[] {
+        for x in &mut rgradients[..] {
             *x = random_gradient(&mut rng);
         }
 
-        let mut permutations = [0i32; 256];
+        let mut permutations = [0; 256];
         for (i, x) in permutations.iter_mut().enumerate() {
             *x = i as i32;
         }
@@ -59,9 +61,9 @@ impl Noise2DContext {
     }
 
     fn get_gradient(&self, x: i32, y: i32) -> Vec2 {
-        let idx = self.permutations[(x & 255) as uint] +
-                    self.permutations[(y & 255) as uint];
-        self.rgradients[(idx & 255) as uint]
+        let idx = self.permutations[(x & 255) as usize] +
+                    self.permutations[(y & 255) as usize];
+        self.rgradients[(idx & 255) as usize]
     }
 
     fn get_gradients(&self, x: f32, y: f32) -> ([Vec2; 4], [Vec2; 4]) {
@@ -115,7 +117,7 @@ fn main() {
 
     for y in 0..256 {
         for x in 0..256 {
-            let idx = (pixels[y*256+x] / 0.2) as uint;
+            let idx = (pixels[y*256+x] / 0.2) as usize;
             print!("{}", symbols[idx]);
         }
         print!("\n");
index 1e23da3020f277b7262145bab28a0c3216e010a5..ce050cc73235dfd76aced3df5d7b3fff0aeb4690 100644 (file)
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
+#![feature(rustc_private, core, step_by)]
+
 extern crate arena;
 
-use std::iter::range_step;
 use std::thread;
 use arena::TypedArena;
 
@@ -107,9 +108,9 @@ fn main() {
     let long_lived_arena = TypedArena::new();
     let long_lived_tree = bottom_up_tree(&long_lived_arena, 0, max_depth);
 
-    let messages = range_step(min_depth, max_depth + 1, 2).map(|depth| {
+    let messages = (min_depth..max_depth + 1).step_by(2).map(|depth| {
         use std::num::Int;
-        let iterations = 2.pow((max_depth - depth + min_depth) as usize);
+        let iterations = 2.pow((max_depth - depth + min_depth) as u32);
         thread::scoped(move || inner(depth, iterations))
     }).collect::<Vec<_>>();
 
index 73e7c8eb073d1884d23be37a9c5de2fea9417489..72f3464cdb72d165d101cc5460845ac6bfda880d 100644 (file)
@@ -54,7 +54,7 @@ fn print_complements() {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum Color {
     Red,
     Yellow,
@@ -72,9 +72,9 @@ impl fmt::Debug for Color {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct CreatureInfo {
-    name: uint,
+    name: usize,
     color: Color
 }
 
@@ -87,7 +87,7 @@ fn show_color_list(set: Vec<Color>) -> String {
     out
 }
 
-fn show_digit(nn: uint) -> &'static str {
+fn show_digit(nn: usize) -> &'static str {
     match nn {
         0 => {" zero"}
         1 => {" one"}
@@ -103,7 +103,7 @@ fn show_digit(nn: uint) -> &'static str {
     }
 }
 
-struct Number(uint);
+struct Number(usize);
 impl fmt::Debug for Number {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let mut out = vec![];
@@ -139,13 +139,13 @@ fn transform(aa: Color, bb: Color) -> Color {
 }
 
 fn creature(
-    name: uint,
+    name: usize,
     mut color: Color,
     from_rendezvous: Receiver<CreatureInfo>,
     to_rendezvous: Sender<CreatureInfo>,
     to_rendezvous_log: Sender<String>
 ) {
-    let mut creatures_met = 0i32;
+    let mut creatures_met = 0;
     let mut evil_clones_met = 0;
     let mut rendezvous = from_rendezvous.iter();
 
@@ -172,7 +172,7 @@ fn creature(
     to_rendezvous_log.send(report).unwrap();
 }
 
-fn rendezvous(nn: uint, set: Vec<Color>) {
+fn rendezvous(nn: usize, set: Vec<Color>) {
     // these ports will allow us to hear from the creatures
     let (to_rendezvous, from_creatures) = channel::<CreatureInfo>();
 
index f7de935d08fdd3b67fcfc13d264a66154d48a8bf..4489a124abe0f3cb50e8d699acca7f981b308848 100644 (file)
@@ -38,7 +38,9 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
-use std::{cmp, iter, mem};
+#![feature(step_by)]
+
+use std::{cmp, mem};
 use std::thread;
 
 fn rotate(x: &mut [i32]) {
@@ -61,12 +63,12 @@ fn next_permutation(perm: &mut [i32], count: &mut [i32]) {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct P {
     p: [i32; 16],
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Perm {
     cnt: [i32; 16],
     fact: [u32; 16],
@@ -78,7 +80,7 @@ struct Perm {
 impl Perm {
     fn new(n: u32) -> Perm {
         let mut fact = [1; 16];
-        for i in 1..n as uint + 1 {
+        for i in 1..n as usize + 1 {
             fact[i] = fact[i - 1] * i as u32;
         }
         Perm {
@@ -91,13 +93,13 @@ impl Perm {
     }
 
     fn get(&mut self, mut idx: i32) -> P {
-        let mut pp = [0u8; 16];
+        let mut pp = [0; 16];
         self.permcount = idx as u32;
         for (i, place) in self.perm.p.iter_mut().enumerate() {
             *place = i as i32 + 1;
         }
 
-        for i in (1..self.n as uint).rev() {
+        for i in (1..self.n as usize).rev() {
             let d = idx / self.fact[i] as i32;
             self.cnt[i] = d;
             idx %= self.fact[i] as i32;
@@ -105,7 +107,7 @@ impl Perm {
                 *place = (*val) as u8
             }
 
-            let d = d as uint;
+            let d = d as usize;
             for j in 0..i + 1 {
                 self.perm.p[j] = if j + d <= i {pp[j + d]} else {pp[j+d-i-1]} as i32;
             }
@@ -115,7 +117,7 @@ impl Perm {
     }
 
     fn count(&self) -> u32 { self.permcount }
-    fn max(&self) -> u32 { self.fact[self.n as uint] }
+    fn max(&self) -> u32 { self.fact[self.n as usize] }
 
     fn next(&mut self) -> P {
         next_permutation(&mut self.perm.p, &mut self.cnt);
@@ -126,11 +128,11 @@ impl Perm {
 }
 
 
-fn reverse(tperm: &mut [i32], k: uint) {
+fn reverse(tperm: &mut [i32], k: usize) {
     tperm[..k].reverse()
 }
 
-fn work(mut perm: Perm, n: uint, max: uint) -> (i32, i32) {
+fn work(mut perm: Perm, n: usize, max: usize) -> (i32, i32) {
     let mut checksum = 0;
     let mut maxflips = 0;
 
@@ -140,7 +142,7 @@ fn work(mut perm: Perm, n: uint, max: uint) -> (i32, i32) {
         let mut flips = 0;
 
         while p.p[0] != 1 {
-            let k = p.p[0] as uint;
+            let k = p.p[0] as usize;
             reverse(&mut p.p, k);
             flips += 1;
         }
@@ -161,11 +163,11 @@ fn fannkuch(n: i32) -> (i32, i32) {
     let mut futures = vec![];
     let k = perm.max() / N;
 
-    for (_, j) in (0..N).zip(iter::count(0, k)) {
+    for (_, j) in (0..N).zip((0..).step_by(k)) {
         let max = cmp::min(j+k, perm.max());
 
         futures.push(thread::scoped(move|| {
-            work(perm, j as uint, max as uint)
+            work(perm, j as usize, max as usize)
         }))
     }
 
@@ -183,7 +185,7 @@ fn main() {
     let n = std::env::args()
         .nth(1)
         .and_then(|arg| arg.parse().ok())
-        .unwrap_or(2i32);
+        .unwrap_or(2);
 
     let (checksum, maxflips) = fannkuch(n);
     println!("{}\nPfannkuchen({}) = {}", checksum, n, maxflips);
index 277c3ee73dff1aa8693eb4154292a13d85c8822a..effdd67027a44b8a32b230a494451fbc2d8738cc 100644 (file)
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
+#![feature(core, old_io, io, core)]
+
 use std::cmp::min;
-use std::old_io::{stdout, IoResult};
+use std::old_io::*;
 use std::iter::repeat;
 use std::env;
 use std::slice::bytes::copy_memory;
@@ -103,7 +105,7 @@ fn sum_and_scale(a: &'static [AminoAcid]) -> Vec<AminoAcid> {
     result
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct AminoAcid {
     c: u8,
     p: f32,
@@ -121,13 +123,12 @@ impl<'a, W: Writer> RepeatFasta<'a, W> {
 
     fn make(&mut self, n: usize) -> IoResult<()> {
         let alu_len = self.alu.len();
-        let mut buf = repeat(0u8).take(alu_len + LINE_LEN).collect::<Vec<_>>();
+        let mut buf = repeat(0).take(alu_len + LINE_LEN).collect::<Vec<_>>();
         let alu: &[u8] = self.alu.as_bytes();
 
-        copy_memory(&mut buf, alu);
+        copy_memory(alu, &mut buf);
         let buf_len = buf.len();
-        copy_memory(&mut buf[alu_len..buf_len],
-                    &alu[..LINE_LEN]);
+        copy_memory(&alu[..LINE_LEN], &mut buf[alu_len..buf_len]);
 
         let mut pos = 0;
         let mut bytes;
index 2c640c4b092556cab96df76819b992575a0fbf66..78d31faeb51690c4cd8e2bc8ce6daf38ad5963e7 100644 (file)
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
+#![feature(old_io, old_path, io, core)]
+
 use std::cmp::min;
-use std::old_io::{BufferedWriter, File};
+use std::old_io::*;
 use std::old_io;
+use std::old_path::Path;
 use std::num::Float;
 use std::env;
 
@@ -89,7 +92,7 @@ fn make_fasta<W: Writer, I: Iterator<Item=u8>>(
     -> std::old_io::IoResult<()>
 {
     try!(wr.write(header.as_bytes()));
-    let mut line = [0u8; LINE_LENGTH + 1];
+    let mut line = [0; LINE_LENGTH + 1];
     while n > 0 {
         let nb = min(LINE_LENGTH, n);
         for i in 0..nb {
index 3ea4a10ea8169f7d148f287b937d599616773f1a..c190641bfbff02e468df6396c064805ad47139e9 100644 (file)
@@ -13,7 +13,7 @@
 
 // multi tasking k-nucleotide
 
-#![feature(box_syntax)]
+#![feature(box_syntax, std_misc, old_io, collections, os)]
 
 use std::ascii::{AsciiExt, OwnedAsciiExt};
 use std::cmp::Ordering::{self, Less, Greater, Equal};
@@ -42,8 +42,8 @@ fn f64_cmp(x: f64, y: f64) -> Ordering {
 }
 
 // given a map, print a sorted version of it
-fn sort_and_fmt(mm: &HashMap<Vec<u8> , uint>, total: uint) -> String {
-   fn pct(xx: uint, yy: uint) -> f64 {
+fn sort_and_fmt(mm: &HashMap<Vec<u8> , usize>, total: usize) -> String {
+   fn pct(xx: usize, yy: usize) -> f64 {
       return (xx as f64) * 100.0 / (yy as f64);
    }
 
@@ -74,7 +74,7 @@ fn sort_and_fmt(mm: &HashMap<Vec<u8> , uint>, total: uint) -> String {
 }
 
 // given a map, search for the frequency of a pattern
-fn find(mm: &HashMap<Vec<u8> , uint>, key: String) -> uint {
+fn find(mm: &HashMap<Vec<u8> , usize>, key: String) -> usize {
    let key = key.into_ascii_lowercase();
    match mm.get(key.as_bytes()) {
       option::Option::None      => { return 0; }
@@ -83,7 +83,7 @@ fn find(mm: &HashMap<Vec<u8> , uint>, key: String) -> uint {
 }
 
 // given a map, increment the counter for a key
-fn update_freq(mm: &mut HashMap<Vec<u8> , uint>, key: &[u8]) {
+fn update_freq(mm: &mut HashMap<Vec<u8> , usize>, key: &[u8]) {
     let key = key.to_vec();
     let newval = match mm.remove(&key) {
         Some(v) => v + 1,
@@ -95,7 +95,7 @@ fn update_freq(mm: &mut HashMap<Vec<u8> , uint>, key: &[u8]) {
 // given a Vec<u8>, for each window call a function
 // i.e., for "hello" and windows of size four,
 // run it("hell") and it("ello"), then return "llo"
-fn windows_with_carry<F>(bb: &[u8], nn: uint, mut it: F) -> Vec<u8> where
+fn windows_with_carry<F>(bb: &[u8], nn: usize, mut it: F) -> Vec<u8> where
     F: FnMut(&[u8]),
 {
    let mut ii = 0;
@@ -109,12 +109,12 @@ fn windows_with_carry<F>(bb: &[u8], nn: uint, mut it: F) -> Vec<u8> where
    return bb[len - (nn - 1)..len].to_vec();
 }
 
-fn make_sequence_processor(sz: uint,
+fn make_sequence_processor(sz: usize,
                            from_parent: &Receiver<Vec<u8>>,
                            to_parent: &Sender<String>) {
-   let mut freqs: HashMap<Vec<u8>, uint> = HashMap::new();
+   let mut freqs: HashMap<Vec<u8>, usize> = HashMap::new();
    let mut carry = Vec::new();
-   let mut total: uint = 0;
+   let mut total: usize = 0;
 
    let mut line: Vec<u8>;
 
@@ -147,7 +147,7 @@ fn make_sequence_processor(sz: uint,
 
 // given a FASTA file on stdin, process sequence THREE
 fn main() {
-    use std::old_io::{stdio, MemReader, BufferedReader};
+    use std::old_io::*;
 
     let rdr = if env::var_os("RUST_BENCH").is_some() {
         let foo = include_bytes!("shootout-k-nucleotide.data");
@@ -193,7 +193,7 @@ fn main() {
 
            // start processing if this is the one
            ('>', false) => {
-               match line[1..].find_str("THREE") {
+               match line[1..].find("THREE") {
                    Some(_) => { proc_mode = true; }
                    None    => { }
                }
index fb75c67253c6d057d37e962e80d9e5fe7ad03910..db131bcfdc354e55c7e14922d89a59db92151db8 100644 (file)
 
 // ignore-android see #10393 #13206
 
-#![feature(box_syntax)]
+#![feature(box_syntax, std_misc, collections)]
 
 use std::ascii::OwnedAsciiExt;
+use std::env;
+use std::fs::File;
+use std::io::prelude::*;
+use std::io;
 use std::slice;
 use std::sync::Arc;
 use std::thread;
 
 static TABLE: [u8;4] = [ 'A' as u8, 'C' as u8, 'G' as u8, 'T' as u8 ];
-static TABLE_SIZE: uint = 2 << 16;
+static TABLE_SIZE: usize = 2 << 16;
 
 static OCCURRENCES: [&'static str;5] = [
     "GGT",
@@ -60,7 +64,7 @@ static OCCURRENCES: [&'static str;5] = [
 
 // Code implementation
 
-#[derive(Copy, PartialEq, PartialOrd, Ord, Eq)]
+#[derive(Copy, Clone, PartialEq, PartialOrd, Ord, Eq)]
 struct Code(u64);
 
 impl Code {
@@ -73,15 +77,15 @@ impl Code {
         Code((self.hash() << 2) + (pack_symbol(c) as u64))
     }
 
-    fn rotate(&self, c: u8, frame: uint) -> Code {
-        Code(self.push_char(c).hash() & ((1u64 << (2 * frame)) - 1))
+    fn rotate(&self, c: u8, frame: usize) -> Code {
+        Code(self.push_char(c).hash() & ((1 << (2 * frame)) - 1))
     }
 
     fn pack(string: &str) -> Code {
-        string.bytes().fold(Code(0u64), |a, b| a.push_char(b))
+        string.bytes().fold(Code(0), |a, b| a.push_char(b))
     }
 
-    fn unpack(&self, frame: uint) -> String {
+    fn unpack(&self, frame: usize) -> String {
         let mut key = self.hash();
         let mut result = Vec::new();
         for _ in 0..frame {
@@ -113,13 +117,13 @@ struct PrintCallback(&'static str);
 impl TableCallback for PrintCallback {
     fn f(&self, entry: &mut Entry) {
         let PrintCallback(s) = *self;
-        println!("{}\t{}", entry.count as int, s);
+        println!("{}\t{}", entry.count, s);
     }
 }
 
 struct Entry {
     code: Code,
-    count: uint,
+    count: usize,
     next: Option<Box<Entry>>,
 }
 
@@ -142,7 +146,7 @@ impl Table {
     fn search_remainder<C:TableCallback>(item: &mut Entry, key: Code, c: C) {
         match item.next {
             None => {
-                let mut entry = box Entry {
+                let mut entry: Box<_> = box Entry {
                     code: key,
                     count: 0,
                     next: None,
@@ -165,20 +169,20 @@ impl Table {
         let index = key.hash() % (TABLE_SIZE as u64);
 
         {
-            if self.items[index as uint].is_none() {
-                let mut entry = box Entry {
+            if self.items[index as usize].is_none() {
+                let mut entry: Box<_> = box Entry {
                     code: key,
                     count: 0,
                     next: None,
                 };
                 c.f(&mut *entry);
-                self.items[index as uint] = Some(entry);
+                self.items[index as usize] = Some(entry);
                 return;
             }
         }
 
         {
-            let entry = self.items[index as uint].as_mut().unwrap();
+            let entry = self.items[index as usize].as_mut().unwrap();
             if entry.code == key {
                 c.f(&mut **entry);
                 return;
@@ -233,10 +237,10 @@ fn pack_symbol(c: u8) -> u8 {
 }
 
 fn unpack_symbol(c: u8) -> u8 {
-    TABLE[c as uint]
+    TABLE[c as usize]
 }
 
-fn generate_frequencies(mut input: &[u8], frame: uint) -> Table {
+fn generate_frequencies(mut input: &[u8], frame: usize) -> Table {
     let mut frequencies = Table::new();
     if input.len() < frame { return frequencies; }
     let mut code = Code(0);
@@ -256,7 +260,7 @@ fn generate_frequencies(mut input: &[u8], frame: uint) -> Table {
     frequencies
 }
 
-fn print_frequencies(frequencies: &Table, frame: uint) {
+fn print_frequencies(frequencies: &Table, frame: usize) {
     let mut vector = Vec::new();
     for entry in frequencies.iter() {
         vector.push((entry.count, entry.code));
@@ -280,9 +284,9 @@ fn print_occurrences(frequencies: &mut Table, occurrence: &'static str) {
     frequencies.lookup(Code::pack(occurrence), PrintCallback(occurrence))
 }
 
-fn get_sequence<R: Buffer>(r: &mut R, key: &str) -> Vec<u8> {
+fn get_sequence<R: BufRead>(r: &mut R, key: &str) -> Vec<u8> {
     let mut res = Vec::new();
-    for l in r.lines().map(|l| l.ok().unwrap())
+    for l in r.lines().map(|l| l.unwrap())
         .skip_while(|l| key != &l[..key.len()]).skip(1)
     {
         res.push_all(l.trim().as_bytes());
@@ -291,13 +295,13 @@ fn get_sequence<R: Buffer>(r: &mut R, key: &str) -> Vec<u8> {
 }
 
 fn main() {
-    let input = if std::env::var_os("RUST_BENCH").is_some() {
-        let fd = std::old_io::File::open(&Path::new("shootout-k-nucleotide.data"));
-        get_sequence(&mut std::old_io::BufferedReader::new(fd), ">THREE")
+    let input = if env::var_os("RUST_BENCH").is_some() {
+        let f = File::open("shootout-k-nucleotide.data").unwrap();
+        get_sequence(&mut io::BufReader::new(f), ">THREE")
     } else {
-        let mut stdin = std::old_io::stdin();
+        let stdin = io::stdin();
         let mut stdin = stdin.lock();
-        get_sequence(&mut *stdin, ">THREE")
+        get_sequence(&mut stdin, ">THREE")
     };
     let input = Arc::new(input);
 
index bddf615322816d40e1212465d46b01e9d2503be0..d248293103bdec7940ae623dd621216fe685b3ea 100644 (file)
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#![feature(simd)]
+#![feature(simd, old_io, core, io)]
 
 // ignore-pretty very bad with line comments
 
 use std::old_io;
+use std::old_io::*;
 use std::env;
 use std::simd::f64x2;
 use std::sync::Arc;
index a94fe0ccd959848a364d890eef0a1058128ad958..150522fd02d4cb75ab41d8a0fb3c445bdb351b61 100644 (file)
@@ -40,6 +40,8 @@
 
 // no-pretty-expanded FIXME #15189
 
+#![feature(core)]
+
 use std::iter::repeat;
 use std::sync::Arc;
 use std::sync::mpsc::channel;
@@ -169,7 +171,7 @@ fn make_masks() -> Vec<Vec<Vec<u64> > > {
         .map(|(id, p)| transform(p, id != 3))
         .collect();
 
-    (0i32..50).map(|yx| {
+    (0..50).map(|yx| {
         transforms.iter().enumerate().map(|(id, t)| {
             t.iter().filter_map(|p| mask(yx / 5, yx % 5, id, p)).collect()
         }).collect()
@@ -211,7 +213,7 @@ fn filter_masks(masks: &mut Vec<Vec<Vec<u64>>>) {
 
 // Gets the identifier of a mask.
 fn get_id(m: u64) -> u8 {
-    for id in 0u8..10 {
+    for id in 0..10 {
         if m & (1 << (id + 50) as usize) != 0 {return id;}
     }
     panic!("{:016x} does not have a valid identifier", m);
index 534dfe9548c2f73a5275abc4205b6028c5623c6f..669a0e86f1e659406f8f9b232532f27ec1b32780 100644 (file)
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
+#![feature(core)]
+
 use std::num::Float;
 
 const PI: f64 = 3.141592653589793;
 const SOLAR_MASS: f64 = 4.0 * PI * PI;
 const YEAR: f64 = 365.24;
-const N_BODIES: uint = 5;
+const N_BODIES: usize = 5;
 
 static BODIES: [Planet;N_BODIES] = [
     // Sun
@@ -94,14 +96,14 @@ static BODIES: [Planet;N_BODIES] = [
     },
 ];
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Planet {
     x: f64, y: f64, z: f64,
     vx: f64, vy: f64, vz: f64,
     mass: f64,
 }
 
-fn advance(bodies: &mut [Planet;N_BODIES], dt: f64, steps: int) {
+fn advance(bodies: &mut [Planet;N_BODIES], dt: f64, steps: isize) {
     for _ in 0..steps {
         let mut b_slice: &mut [_] = bodies;
         loop {
index a542c81f2394ea2523717305de5956469606a2a9..ed20f4b6362ce26a26c9220ba102fde2f9acd674 100644 (file)
@@ -18,6 +18,8 @@
 
 */
 
+#![feature(std_misc, rustc_private)]
+
 extern crate getopts;
 
 use std::sync::mpsc::{channel, Sender};
@@ -75,7 +77,7 @@ fn stress_task(id: isize) {
     }
 }
 
-fn stress(num_tasks: int) {
+fn stress(num_tasks: isize) {
     let mut results = Vec::new();
     for i in 0..num_tasks {
         results.push(thread::spawn(move|| {
index 33d959dfe93e35f592320a4913dd69d3c7c3a313..cda90c08f23ad121df4e70b0565e7d83ebeae794 100644 (file)
 
 // ignore-android see #10393 #13206
 
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, libc, old_io, collections, io, core)]
 
 extern crate libc;
 
 use std::old_io::stdio::{stdin_raw, stdout_raw};
-use std::old_io::{IoResult, EndOfFile};
-use std::ptr::{copy_memory, Unique};
+use std::old_io::*;
+use std::ptr::{copy, Unique};
 use std::thread;
 
 struct Tables {
@@ -92,12 +92,12 @@ impl Tables {
 
     /// Retrieves the complement for `i`.
     fn cpl8(&self, i: u8) -> u8 {
-        self.table8[i as uint]
+        self.table8[i as usize]
     }
 
     /// Retrieves the complement for `i`.
     fn cpl16(&self, i: u16) -> u16 {
-        self.table16[i as uint]
+        self.table16[i as usize]
     }
 }
 
@@ -107,7 +107,7 @@ fn read_to_end<R: Reader>(r: &mut R) -> IoResult<Vec<u8>> {
     // Reader::read_to_end() with a fast growing policy to limit
     // recopies.  If MREMAP_RETAIN is implemented in the linux kernel
     // and jemalloc use it, this trick will become useless.
-    const CHUNK: uint = 64 * 1024;
+    const CHUNK: usize = 64 * 1024;
 
     let mut vec = Vec::with_capacity(CHUNK);
     loop {
@@ -132,7 +132,7 @@ fn read_to_end<R: Reader>(r: &mut R) -> IoResult<Vec<u8>> {
 }
 
 /// Finds the first position at which `b` occurs in `s`.
-fn memchr(h: &[u8], n: u8) -> Option<uint> {
+fn memchr(h: &[u8], n: u8) -> Option<usize> {
     use libc::{c_void, c_int, size_t};
     let res = unsafe {
         libc::memchr(h.as_ptr() as *const c_void, n as c_int, h.len() as size_t)
@@ -140,7 +140,7 @@ fn memchr(h: &[u8], n: u8) -> Option<uint> {
     if res.is_null() {
         None
     } else {
-        Some(res as uint - h.as_ptr() as uint)
+        Some(res as usize - h.as_ptr() as usize)
     }
 }
 
@@ -171,7 +171,7 @@ impl<'a> Iterator for MutDnaSeqs<'a> {
 }
 
 /// Length of a normal line without the terminating \n.
-const LINE_LEN: uint = 60;
+const LINE_LEN: usize = 60;
 
 /// Compute the reverse complement.
 fn reverse_complement(seq: &mut [u8], tables: &Tables) {
@@ -181,8 +181,8 @@ fn reverse_complement(seq: &mut [u8], tables: &Tables) {
     let mut i = LINE_LEN;
     while i < len {
         unsafe {
-            copy_memory(seq.as_mut_ptr().offset((i - off + 1) as int),
-                        seq.as_ptr().offset((i - off) as int), off);
+            copy(seq.as_ptr().offset((i - off) as isize),
+                 seq.as_mut_ptr().offset((i - off + 1) as isize), off);
             *seq.get_unchecked_mut(i - off) = b'\n';
         }
         i += LINE_LEN + 1;
@@ -193,8 +193,8 @@ fn reverse_complement(seq: &mut [u8], tables: &Tables) {
     unsafe {
         let mut left = seq.as_mut_ptr() as *mut u16;
         // This is slow if len % 2 != 0 but still faster than bytewise operations.
-        let mut right = seq.as_mut_ptr().offset(len as int - 2) as *mut u16;
-        let end = left.offset(div as int);
+        let mut right = seq.as_mut_ptr().offset(len as isize - 2) as *mut u16;
+        let end = left.offset(div as isize);
         while left != end {
             let tmp = tables.cpl16(*left);
             *left = tables.cpl16(*right);
index f7514a3e8848d16788fc26152f6409f82010fc88..c0268e816cf3e537b9c2b7653a4c89680fbebb66 100644 (file)
@@ -41,7 +41,7 @@
 // no-pretty-expanded FIXME #15189
 
 #![allow(non_snake_case)]
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, core, os)]
 
 use std::iter::{repeat, AdditiveIterator};
 use std::thread;
@@ -64,7 +64,7 @@ fn main() {
     println!("{:.9}", answer);
 }
 
-fn spectralnorm(n: uint) -> f64 {
+fn spectralnorm(n: usize) -> f64 {
     assert!(n % 2 == 0, "only even lengths are accepted");
     let mut u = repeat(1.0).take(n).collect::<Vec<_>>();
     let mut v = u.clone();
@@ -89,8 +89,8 @@ fn mult_Atv(v: &[f64], out: &mut [f64]) {
     parallel(out, |start, out| mult(v, out, start, |i, j| A(j, i)));
 }
 
-fn mult<F>(v: &[f64], out: &mut [f64], start: uint, a: F)
-           where F: Fn(uint, uint) -> f64 {
+fn mult<F>(v: &[f64], out: &mut [f64], start: usize, a: F)
+           where F: Fn(usize, usize) -> f64 {
     for (i, slot) in out.iter_mut().enumerate().map(|(i, s)| (i + start, s)) {
         let mut sum = f64x2(0.0, 0.0);
         for (j, chunk) in v.chunks(2).enumerate().map(|(j, s)| (2 * j, s)) {
@@ -103,7 +103,7 @@ fn mult<F>(v: &[f64], out: &mut [f64], start: uint, a: F)
     }
 }
 
-fn A(i: uint, j: uint) -> f64 {
+fn A(i: usize, j: usize) -> f64 {
     ((i + j) * (i + j + 1) / 2 + i + 1) as f64
 }
 
@@ -117,8 +117,10 @@ fn dot(v: &[f64], u: &[f64]) -> f64 {
 // sub-slice of `v`.
 fn parallel<'a,T, F>(v: &mut [T], ref f: F)
                   where T: Send + Sync + 'a,
-                        F: Fn(uint, &mut [T]) + Sync + 'a {
-    let size = v.len() / os::num_cpus() + 1;
+                        F: Fn(usize, &mut [T]) + Sync + 'a {
+    // FIXME: pick a more appropriate parallel factor
+    let parallelism = 4;
+    let size = v.len() / parallelism + 1;
     v.chunks_mut(size).enumerate().map(|(i, chunk)| {
         thread::scoped(move|| {
             f(i * size, chunk)
index a54a869412e35483529c1cd943cf6c423e7e298f..dd56b18c144f2f29df781ada49cd3641008b2730 100644 (file)
@@ -10,6 +10,8 @@
 
 // Microbenchmark for the smallintmap library
 
+#![feature(collections, std_misc)]
+
 use std::collections::VecMap;
 use std::env;
 use std::time::Duration;
index b45f241e8e5d4291a7d72df40faf1535ac2d3090..3913de3a3f99f49a5202859b11eef6e9016d76bb 100644 (file)
 
 // ignore-pretty very bad with line comments
 
-#![feature(box_syntax)]
+#![feature(box_syntax, core)]
 #![allow(non_snake_case)]
 
-use std::old_io::BufferedReader;
-use std::old_io::stdio::StdReader;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
 use std::iter::repeat;
 use std::num::Int;
 use std::env;
@@ -37,7 +36,7 @@ use std::env;
 //
 
 // internal type of sudoku grids
-type grid = Vec<Vec<u8> > ;
+type grid = Vec<Vec<u8>>;
 
 struct Sudoku {
     grid: grid
@@ -55,11 +54,13 @@ impl Sudoku {
         return Sudoku::new(g)
     }
 
-    pub fn read(mut reader: &mut BufferedReader<StdReader>) -> Sudoku {
+    pub fn read(reader: &mut BufRead) -> Sudoku {
         /* assert first line is exactly "9,9" */
-        assert!(reader.read_line().unwrap() == "9,9".to_string());
+        let mut s = String::new();
+        reader.read_line(&mut s).unwrap();
+        assert_eq!(s, "9,9\n");
 
-        let mut g = repeat(vec![0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8])
+        let mut g = repeat(vec![0, 0, 0, 0, 0, 0, 0, 0, 0])
                           .take(10).collect::<Vec<_>>();
         for line in reader.lines() {
             let line = line.unwrap();
@@ -71,7 +72,7 @@ impl Sudoku {
             if comps.len() == 3 {
                 let row = comps[0].parse::<u8>().unwrap();
                 let col = comps[1].parse::<u8>().unwrap();
-                g[row as uint][col as uint] = comps[2].parse().unwrap();
+                g[row as usize][col as usize] = comps[2].parse().unwrap();
             }
             else {
                 panic!("Invalid sudoku file");
@@ -80,11 +81,11 @@ impl Sudoku {
         return Sudoku::new(g)
     }
 
-    pub fn write(&self, writer: &mut old_io::Writer) {
+    pub fn write(&self, writer: &mut Write) {
         for row in 0u8..9u8 {
-            write!(writer, "{}", self.grid[row as uint][0]);
+            write!(writer, "{}", self.grid[row as usize][0]);
             for col in 1u8..9u8 {
-                write!(writer, " {}", self.grid[row as uint][col as uint]);
+                write!(writer, " {}", self.grid[row as usize][col as usize]);
             }
             write!(writer, "\n");
          }
@@ -93,10 +94,10 @@ impl Sudoku {
     // solve sudoku grid
     pub fn solve(&mut self) {
         let mut work: Vec<(u8, u8)> = Vec::new(); /* queue of uncolored fields */
-        for row in 0u8..9u8 {
-            for col in 0u8..9u8 {
-                let color = self.grid[row as uint][col as uint];
-                if color == 0u8 {
+        for row in 0..9 {
+            for col in 0..9 {
+                let color = self.grid[row as usize][col as usize];
+                if color == 0 {
                     work.push((row, col));
                 }
             }
@@ -107,7 +108,7 @@ impl Sudoku {
         while ptr < end {
             let (row, col) = work[ptr];
             // is there another color to try?
-            let the_color = self.grid[row as uint][col as uint] +
+            let the_color = self.grid[row as usize][col as usize] +
                                 (1 as u8);
             if self.next_color(row, col, the_color) {
                 //  yes: advance work list
@@ -121,37 +122,37 @@ impl Sudoku {
     }
 
     fn next_color(&mut self, row: u8, col: u8, start_color: u8) -> bool {
-        if start_color < 10u8 {
+        if start_color < 10 {
             // colors not yet used
-            let mut avail = box Colors::new(start_color);
+            let mut avail: Box<_> = box Colors::new(start_color);
 
             // drop colors already in use in neighbourhood
             self.drop_colors(&mut *avail, row, col);
 
             // find first remaining color that is available
             let next = avail.next();
-            self.grid[row as uint][col as uint] = next;
-            return 0u8 != next;
+            self.grid[row as usize][col as usize] = next;
+            return 0 != next;
         }
-        self.grid[row as uint][col as uint] = 0u8;
+        self.grid[row as usize][col as usize] = 0;
         return false;
     }
 
     // find colors available in neighbourhood of (row, col)
     fn drop_colors(&mut self, avail: &mut Colors, row: u8, col: u8) {
-        for idx in 0u8..9u8 {
+        for idx in 0..9 {
             /* check same column fields */
-            avail.remove(self.grid[idx as uint][col as uint]);
+            avail.remove(self.grid[idx as usize][col as usize]);
             /* check same row fields */
-            avail.remove(self.grid[row as uint][idx as uint]);
+            avail.remove(self.grid[row as usize][idx as usize]);
         }
 
         // check same block fields
-        let row0 = (row / 3u8) * 3u8;
-        let col0 = (col / 3u8) * 3u8;
-        for alt_row in row0..row0 + 3u8 {
-            for alt_col in col0..col0 + 3u8 {
-                avail.remove(self.grid[alt_row as uint][alt_col as uint]);
+        let row0 = (row / 3) * 3;
+        let col0 = (col / 3) * 3;
+        for alt_row in row0..row0 + 3 {
+            for alt_col in col0..col0 + 3 {
+                avail.remove(self.grid[alt_row as usize][alt_col as usize]);
             }
         }
     }
@@ -160,29 +161,29 @@ impl Sudoku {
 // Stores available colors as simple bitfield, bit 0 is always unset
 struct Colors(u16);
 
-static HEADS: u16 = (1u16 << 10) - 1; /* bits 9..0 */
+static HEADS: u16 = (1 << 10) - 1; /* bits 9..0 */
 
 impl Colors {
     fn new(start_color: u8) -> Colors {
         // Sets bits 9..start_color
-        let tails = !0u16 << start_color as uint;
+        let tails = !0 << start_color as usize;
         return Colors(HEADS & tails);
     }
 
     fn next(&self) -> u8 {
         let Colors(c) = *self;
         let val = c & HEADS;
-        if 0u16 == val {
-            return 0u8;
+        if 0 == val {
+            return 0;
         } else {
             return val.trailing_zeros() as u8
         }
     }
 
     fn remove(&mut self, color: u8) {
-        if color != 0u8 {
+        if color != 0 {
             let Colors(val) = *self;
-            let mask = !(1u16 << color as uint);
+            let mask = !(1 << color as usize);
             *self    = Colors(val & mask);
         }
     }
@@ -190,57 +191,57 @@ impl Colors {
 
 static DEFAULT_SUDOKU: [[u8;9];9] = [
          /* 0    1    2    3    4    5    6    7    8    */
-  /* 0 */  [0u8, 4u8, 0u8, 6u8, 0u8, 0u8, 0u8, 3u8, 2u8],
-  /* 1 */  [0u8, 0u8, 8u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8],
-  /* 2 */  [7u8, 0u8, 0u8, 8u8, 0u8, 0u8, 0u8, 0u8, 0u8],
-  /* 3 */  [0u8, 0u8, 0u8, 5u8, 0u8, 0u8, 0u8, 0u8, 0u8],
-  /* 4 */  [0u8, 5u8, 0u8, 0u8, 0u8, 3u8, 6u8, 0u8, 0u8],
-  /* 5 */  [6u8, 8u8, 0u8, 0u8, 0u8, 0u8, 0u8, 9u8, 0u8],
-  /* 6 */  [0u8, 9u8, 5u8, 0u8, 0u8, 6u8, 0u8, 7u8, 0u8],
-  /* 7 */  [0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 6u8, 0u8],
-  /* 8 */  [4u8, 0u8, 0u8, 0u8, 0u8, 7u8, 2u8, 0u8, 3u8]
+  /* 0 */  [0, 4, 0, 6, 0, 0, 0, 3, 2],
+  /* 1 */  [0, 0, 8, 0, 2, 0, 0, 0, 0],
+  /* 2 */  [7, 0, 0, 8, 0, 0, 0, 0, 0],
+  /* 3 */  [0, 0, 0, 5, 0, 0, 0, 0, 0],
+  /* 4 */  [0, 5, 0, 0, 0, 3, 6, 0, 0],
+  /* 5 */  [6, 8, 0, 0, 0, 0, 0, 9, 0],
+  /* 6 */  [0, 9, 5, 0, 0, 6, 0, 7, 0],
+  /* 7 */  [0, 0, 0, 0, 4, 0, 0, 6, 0],
+  /* 8 */  [4, 0, 0, 0, 0, 7, 2, 0, 3]
 ];
 
 #[cfg(test)]
 static DEFAULT_SOLUTION: [[u8;9];9] = [
          /* 0    1    2    3    4    5    6    7    8    */
-  /* 0 */  [1u8, 4u8, 9u8, 6u8, 7u8, 5u8, 8u8, 3u8, 2u8],
-  /* 1 */  [5u8, 3u8, 8u8, 1u8, 2u8, 9u8, 7u8, 4u8, 6u8],
-  /* 2 */  [7u8, 2u8, 6u8, 8u8, 3u8, 4u8, 1u8, 5u8, 9u8],
-  /* 3 */  [9u8, 1u8, 4u8, 5u8, 6u8, 8u8, 3u8, 2u8, 7u8],
-  /* 4 */  [2u8, 5u8, 7u8, 4u8, 9u8, 3u8, 6u8, 1u8, 8u8],
-  /* 5 */  [6u8, 8u8, 3u8, 7u8, 1u8, 2u8, 5u8, 9u8, 4u8],
-  /* 6 */  [3u8, 9u8, 5u8, 2u8, 8u8, 6u8, 4u8, 7u8, 1u8],
-  /* 7 */  [8u8, 7u8, 2u8, 3u8, 4u8, 1u8, 9u8, 6u8, 5u8],
-  /* 8 */  [4u8, 6u8, 1u8, 9u8, 5u8, 7u8, 2u8, 8u8, 3u8]
+  /* 0 */  [1, 4, 9, 6, 7, 5, 8, 3, 2],
+  /* 1 */  [5, 3, 8, 1, 2, 9, 7, 4, 6],
+  /* 2 */  [7, 2, 6, 8, 3, 4, 1, 5, 9],
+  /* 3 */  [9, 1, 4, 5, 6, 8, 3, 2, 7],
+  /* 4 */  [2, 5, 7, 4, 9, 3, 6, 1, 8],
+  /* 5 */  [6, 8, 3, 7, 1, 2, 5, 9, 4],
+  /* 6 */  [3, 9, 5, 2, 8, 6, 4, 7, 1],
+  /* 7 */  [8, 7, 2, 3, 4, 1, 9, 6, 5],
+  /* 8 */  [4, 6, 1, 9, 5, 7, 2, 8, 3]
 ];
 
 #[test]
 fn colors_new_works() {
-    assert_eq!(*Colors::new(1), 1022u16);
-    assert_eq!(*Colors::new(2), 1020u16);
-    assert_eq!(*Colors::new(3), 1016u16);
-    assert_eq!(*Colors::new(4), 1008u16);
-    assert_eq!(*Colors::new(5), 992u16);
-    assert_eq!(*Colors::new(6), 960u16);
-    assert_eq!(*Colors::new(7), 896u16);
-    assert_eq!(*Colors::new(8), 768u16);
-    assert_eq!(*Colors::new(9), 512u16);
+    assert_eq!(*Colors::new(1), 1022);
+    assert_eq!(*Colors::new(2), 1020);
+    assert_eq!(*Colors::new(3), 1016);
+    assert_eq!(*Colors::new(4), 1008);
+    assert_eq!(*Colors::new(5), 992);
+    assert_eq!(*Colors::new(6), 960);
+    assert_eq!(*Colors::new(7), 896);
+    assert_eq!(*Colors::new(8), 768);
+    assert_eq!(*Colors::new(9), 512);
 }
 
 #[test]
 fn colors_next_works() {
-    assert_eq!(Colors(0).next(), 0u8);
-    assert_eq!(Colors(2).next(), 1u8);
-    assert_eq!(Colors(4).next(), 2u8);
-    assert_eq!(Colors(8).next(), 3u8);
-    assert_eq!(Colors(16).next(), 4u8);
-    assert_eq!(Colors(32).next(), 5u8);
-    assert_eq!(Colors(64).next(), 6u8);
-    assert_eq!(Colors(128).next(), 7u8);
-    assert_eq!(Colors(256).next(), 8u8);
-    assert_eq!(Colors(512).next(), 9u8);
-    assert_eq!(Colors(1024).next(), 0u8);
+    assert_eq!(Colors(0).next(), 0);
+    assert_eq!(Colors(2).next(), 1);
+    assert_eq!(Colors(4).next(), 2);
+    assert_eq!(Colors(8).next(), 3);
+    assert_eq!(Colors(16).next(), 4);
+    assert_eq!(Colors(32).next(), 5);
+    assert_eq!(Colors(64).next(), 6);
+    assert_eq!(Colors(128).next(), 7);
+    assert_eq!(Colors(256).next(), 8);
+    assert_eq!(Colors(512).next(), 9);
+    assert_eq!(Colors(1024).next(), 0);
 }
 
 #[test]
@@ -252,7 +253,7 @@ fn colors_remove_works() {
     colors.remove(1);
 
     // THEN
-    assert_eq!(colors.next(), 2u8);
+    assert_eq!(colors.next(), 2);
 }
 
 #[test]
@@ -269,15 +270,16 @@ fn check_DEFAULT_SUDOKU_solution() {
 }
 
 fn main() {
-    let args        = env::args();
+    let args = env::args();
     let use_default = args.len() == 1;
     let mut sudoku = if use_default {
         Sudoku::from_vec(&DEFAULT_SUDOKU)
     } else {
-        let mut stdin = old_io::stdin();
-        let mut stdin = stdin.lock();
-        Sudoku::read(&mut *stdin)
+        let stdin = io::stdin();
+        let mut locked = stdin.lock();
+        Sudoku::read(&mut locked)
     };
     sudoku.solve();
-    sudoku.write(&mut old_io::stdout());
+    let out = io::stdout();
+    sudoku.write(&mut out.lock());
 }
index 6b412c47cd7f81bdf9d0713f8818dbd84aaa1471..9eba2c3639039511fec82c445dd02ec900155e5b 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unsafe_destructor, box_syntax)]
+#![feature(unsafe_destructor, box_syntax, std_misc, collections)]
 
 use std::env;
 use std::thread;
@@ -29,7 +29,7 @@ fn main() {
     run(repeat, depth);
 }
 
-fn run(repeat: int, depth: int) {
+fn run(repeat: isize, depth: isize) {
     for _ in 0..repeat {
         let dur = Duration::span(|| {
             let _ = thread::spawn(move|| {
@@ -40,9 +40,7 @@ fn run(repeat: int, depth: int) {
     }
 }
 
-// FIXME(#21721) used to be `List<()>` but that can cause
-// certain LLVM versions to abort during optimizations.
-type nillist = List<[u8; 0]>;
+type nillist = List<()>;
 
 // Filled with things that have to be unwound
 
@@ -67,7 +65,7 @@ fn r(l: Box<nillist>) -> r {
     }
 }
 
-fn recurse_or_panic(depth: int, st: Option<State>) {
+fn recurse_or_panic(depth: isize, st: Option<State>) {
     if depth == 0 {
         panic!();
     } else {
@@ -83,11 +81,11 @@ fn recurse_or_panic(depth: int, st: Option<State>) {
             }
             Some(st) => {
                 let mut v = st.vec.clone();
-                v.push_all(&[box List::Cons([], st.vec.last().unwrap().clone())]);
+                v.push_all(&[box List::Cons((), st.vec.last().unwrap().clone())]);
                 State {
-                    unique: box List::Cons([], box *st.unique),
+                    unique: box List::Cons((), box *st.unique),
                     vec: v,
-                    res: r(box List::Cons([], st.res._l.clone())),
+                    res: r(box List::Cons((), st.res._l.clone())),
                 }
             }
         };
index e36d685d7c6ea9b73f85d29b147510ec1fc69030..4798e317ac840f1eb008ee89d08c15f0840269af 100644 (file)
@@ -21,7 +21,7 @@ use std::sync::mpsc::{channel, Sender};
 use std::env;
 use std::thread;
 
-fn child_generation(gens_left: uint, tx: Sender<()>) {
+fn child_generation(gens_left: usize, tx: Sender<()>) {
     // This used to be O(n^2) in the number of generations that ever existed.
     // With this code, only as many generations are alive at a time as tasks
     // alive at a time,
index b2cbd8821e4655c54e570893c76f8a4c439daf28..a5b449285ef1feaf4d7c12b7d556be6eb5bed43c 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #[no_mangle]
-pub fn test(x: &[int]) -> int {
+pub fn test(x: &[isize]) -> isize {
     let mut y = 0;
     let mut i = 0;
     while (i < x.len()) {
index b95d6b03288ea96ce476cafe7f6d1b27b270940a..fe93c864fadab8f7364595075f169513bab03b21 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo(x: int) -> int {
+fn foo(x: isize) -> isize {
     x * x
 }
 
index 948809a63267905bea5057dfdbc61a216d7f6560..5addba1724d33520b091f840f84b9faec58c2fc6 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 #[no_mangle]
-pub fn test() -> int {
+pub fn test() -> isize {
     5
 }
index d75bc5209fd25a3896339f0cc49f40daf7fe05d5..cf05a2e2f8e5fef861c3a29ce63ed1062e37d0f6 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #[no_mangle]
-pub fn test(x: int, y: int) -> int {
+pub fn test(x: isize, y: isize) -> isize {
     match x {
         1 => y,
         2 => y*2,
index 996d22038249bfba7170b27596d6a229d446a954..025f9b524c9a986c9717ebfeb6817c3ee0dbad40 100644 (file)
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 pub struct Struct {
-    field: int
+    field: isize
 }
 
 impl Struct {
-    fn method(&self, x: int) -> int {
+    fn method(&self, x: isize) -> isize {
         self.field + x
     }
 }
@@ -23,6 +23,6 @@ pub fn test(a: &Struct,
             b: &Struct,
             c: &Struct,
             d: &Struct,
-            e: &Struct) -> int {
+            e: &Struct) -> isize {
     a.method(b.method(c.method(d.method(e.method(1)))))
 }
index 9c5894fb97ac2576214c79719d7779977d0da01c..fca3784d9e002f3e6cb5c094267727dd51cba982 100644 (file)
@@ -9,16 +9,16 @@
 // except according to those terms.
 
 pub struct Struct {
-    field: int
+    field: isize
 }
 
 impl Struct {
-    fn method(&self) -> int {
+    fn method(&self) -> isize {
         self.field
     }
 }
 
 #[no_mangle]
-pub fn test(s: &Struct) -> int {
+pub fn test(s: &Struct) -> isize {
     s.method()
 }
index ff1a611c4efef802d1d50102b6c961f8e2d475e1..ae83409b45ff00e7d9ad3462b9082267f4c35c7d 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub struct Stuff {
-  a: int,
+  a: isize,
   b: f64
 }
 
@@ -18,6 +18,6 @@ pub trait Trait {
 }
 
 #[no_mangle]
-pub fn test(t: &Trait) -> int {
+pub fn test(t: &Trait) -> isize {
     t.method().a
 }
index 036c0957e99d926d21353a9eee43071a0f394754..9bfeef1f018a702716f0cf3dd7458016415d9958 100644 (file)
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 pub trait Trait {
-    fn method(&self) -> int;
+    fn method(&self) -> isize;
 }
 
 #[no_mangle]
-pub fn test(t: &Trait) -> int {
+pub fn test(t: &Trait) -> isize {
     t.method()
 }
diff --git a/src/test/compile-fail-fulldeps/gated-macro-reexports.rs b/src/test/compile-fail-fulldeps/gated-macro-reexports.rs
new file mode 100644 (file)
index 0000000..a88445b
--- /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 macro reexports item are gated by `macro_reexport` feature gate.
+
+// aux-build:macro_reexport_1.rs
+// ignore-stage1
+
+#![crate_type = "dylib"]
+
+#[macro_reexport(reexported)]
+#[macro_use] #[no_link]
+extern crate macro_reexport_1;
+//~^ ERROR macros reexports are experimental and possibly buggy
+//~| HELP add #![feature(macro_reexport)] to the crate attributes to enable
diff --git a/src/test/compile-fail-fulldeps/gated-quote.rs b/src/test/compile-fail-fulldeps/gated-quote.rs
new file mode 100644 (file)
index 0000000..6a5cd88
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright 2015 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 `quote`-related macro are gated by `quote` feature gate.
+
+// (To sanity-check the code, uncomment this.)
+// #![feature(quote)]
+
+// FIXME the error message that is current emitted seems pretty bad.
+
+#![feature(rustc_private)]
+#![allow(dead_code, unused_imports, unused_variables)]
+
+#[macro_use]
+extern crate syntax;
+
+use syntax::ast;
+use syntax::codemap::Span;
+use syntax::parse;
+
+struct ParseSess;
+
+impl ParseSess {
+    fn cfg(&self) -> ast::CrateConfig { loop { } }
+    fn parse_sess<'a>(&'a self) -> &'a parse::ParseSess { loop { } }
+    fn call_site(&self) -> Span { loop { } }
+    fn ident_of(&self, st: &str) -> ast::Ident { loop { } }
+    fn name_of(&self, st: &str) -> ast::Name { loop { } }
+}
+
+pub fn main() {
+    let ecx = &ParseSess;
+    let x = quote_tokens!(ecx, 3);   //~ ERROR macro undefined: 'quote_tokens!'
+    let x = quote_expr!(ecx, 3);     //~ ERROR macro undefined: 'quote_expr!'
+    let x = quote_ty!(ecx, 3);       //~ ERROR macro undefined: 'quote_ty!'
+    let x = quote_method!(ecx, 3);   //~ ERROR macro undefined: 'quote_method!'
+    let x = quote_item!(ecx, 3);     //~ ERROR macro undefined: 'quote_item!'
+    let x = quote_pat!(ecx, 3);      //~ ERROR macro undefined: 'quote_pat!'
+    let x = quote_arm!(ecx, 3);      //~ ERROR macro undefined: 'quote_arm!'
+    let x = quote_stmt!(ecx, 3);     //~ ERROR macro undefined: 'quote_stmt!'
+    let x = quote_matcher!(ecx, 3);  //~ ERROR macro undefined: 'quote_matcher!'
+    let x = quote_attr!(ecx, 3);     //~ ERROR macro undefined: 'quote_attr!'
+}
diff --git a/src/test/compile-fail-fulldeps/issue-15778-fail.rs b/src/test/compile-fail-fulldeps/issue-15778-fail.rs
new file mode 100644 (file)
index 0000000..8c6889f
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2015 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.
+
+// aux-build:lint_for_crate.rs
+// ignore-stage1
+// compile-flags: -D crate-not-okay
+
+#![feature(plugin, custom_attribute)] //~ ERROR crate is not marked with #![crate_okay]
+#![plugin(lint_for_crate)]
+
+pub fn main() { }
index 9b696e05c50df27f5f7c62b341aa113d83ba565b..06fc3db58c1598db6836e14ca4286eb5ac48691e 100644 (file)
@@ -15,6 +15,6 @@ pub use use_from_trait_xc::Trait;
 
 fn main() {
     match () {
-        Trait { x: 42_usize } => () //~ ERROR use of trait `Trait` in a struct pattern
+        Trait { x: 42 } => () //~ ERROR use of trait `Trait` in a struct pattern
     }
 }
index 7111c00d1246aa32dfa7ad3edbcd787f1e4b4f0f..6c9b8f81b2faf6779cb23a297d3f778d59db929a 100644 (file)
@@ -9,14 +9,14 @@
 // except according to those terms.
 
 fn main() {
-    let _x: i32 = [1i32, 2, 3];
+    let _x: i32 = [1, 2, 3];
     //~^ ERROR mismatched types
     //~| expected `i32`
-    //~| found `[i32; 3]`
+    //~| found `[_; 3]`
     //~| expected i32
     //~| found array of 3 elements
 
-    let x: &[i32] = &[1i32, 2, 3];
+    let x: &[i32] = &[1, 2, 3];
     let _y: &i32 = x;
     //~^ ERROR mismatched types
     //~| expected `&i32`
index 01481af817b7e5caa4bc303c4b1742a1db947603..3cb608a9c5ed29e4ba11be0a4a9d2929c59677c4 100644 (file)
@@ -20,8 +20,8 @@ pub fn main() {
     let x: isize;
     let y: isize;
     unsafe {
-        asm!("mov $1, $0" : "=r"(x) : "=r"(5_usize)); //~ ERROR operand constraint contains '='
-        asm!("mov $1, $0" : "=r"(y) : "+r"(5_usize)); //~ ERROR operand constraint contains '+'
+        asm!("mov $1, $0" : "=r"(x) : "=r"(5)); //~ ERROR operand constraint contains '='
+        asm!("mov $1, $0" : "=r"(y) : "+r"(5)); //~ ERROR operand constraint contains '+'
     }
     foo(x);
     foo(y);
index 02d06c4e1bf806adc18ac37dee7f3a2a10192405..43a0ad6b5f6bf71ea08efb88f8439b31972a0d64 100644 (file)
 
 // ignore-android
 
-#![feature(asm)]
+#![feature(asm, rustc_attrs)]
 
 #![allow(dead_code, non_upper_case_globals)]
 
 #[cfg(any(target_arch = "x86",
           target_arch = "x86_64"))]
-pub fn main() {
+#[rustc_error]
+pub fn main() { //~ ERROR compilation successful
     // assignment not dead
     let mut x: isize = 0;
     unsafe {
@@ -33,7 +34,3 @@ pub fn main() {
     }
     assert_eq!(x, 13);
 }
-
-// At least one error is needed so that compilation fails
-#[static_assert]
-static b: bool = false; //~ ERROR static assertion failed
index ff56fb14f7d5753cc2b42845b0fe60482dfcf481..8c8451623d511ee2384a54982d873c064893ae7f 100644 (file)
@@ -21,7 +21,7 @@ pub fn main() {
     x = 1; //~ NOTE prior assignment occurs here
     foo(x);
     unsafe {
-        asm!("mov $1, $0" : "=r"(x) : "r"(5_usize));
+        asm!("mov $1, $0" : "=r"(x) : "r"(5));
         //~^ ERROR re-assignment of immutable variable `x`
     }
     foo(x);
index 17c19c77ab9abd6ebe988e00b0b72132ef849870..9cf43bebe65ab858393f57817450ed8c28f29b1d 100644 (file)
@@ -19,7 +19,7 @@ fn foo(x: isize) { println!("{}", x); }
 pub fn main() {
     let x: isize;
     unsafe {
-        asm!("mov $1, $0" : "r"(x) : "r"(5_usize)); //~ ERROR output operand constraint lacks '='
+        asm!("mov $1, $0" : "r"(x) : "r"(5)); //~ ERROR output operand constraint lacks '='
     }
     foo(x);
 }
index d32ea327d0a8cfceeaec66c6cecffeee40de157a..4518ce36b6da13140019cfdc9a7d5cac12fc25f4 100644 (file)
@@ -15,7 +15,7 @@ struct cat {
 }
 
 impl cat {
-    pub fn speak(&self) { self.meows += 1_usize; }
+    pub fn speak(&self) { self.meows += 1; }
 }
 
 fn cat(in_x : usize, in_y : isize) -> cat {
@@ -26,6 +26,6 @@ fn cat(in_x : usize, in_y : isize) -> cat {
 }
 
 fn main() {
-  let nyan : cat = cat(52_usize, 99);
+  let nyan : cat = cat(52, 99);
   nyan.speak = || println!("meow"); //~ ERROR attempted to take value of method
 }
index 5b24c6bd79f96e75a4666054d35232886241a4a3..fef27af59571b186748d84cc7aed01b6d41b5d48 100644 (file)
@@ -13,5 +13,5 @@ struct Foo;
 fn main() {
   let mut a = Foo;
   let ref b = Foo;
-  a += *b; //~ Error: binary assignment operation `+=` cannot be applied to type `Foo`
+  a += *b; //~ Error: binary assignment operation `+=` cannot be applied to types `Foo` and `Foo`
 }
diff --git a/src/test/compile-fail/associated-type-projection-ambig-between-bound-and-where-clause.rs b/src/test/compile-fail/associated-type-projection-ambig-between-bound-and-where-clause.rs
new file mode 100644 (file)
index 0000000..ce97019
--- /dev/null
@@ -0,0 +1,52 @@
+// 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 equality constraints in a where clause where the type being
+// equated appears in a supertrait.
+
+pub trait Vehicle {
+    type Color;
+
+    fn go(&self) {  }
+}
+
+pub trait Box {
+    type Color;
+
+    fn mail(&self) {  }
+}
+
+fn a<C:Vehicle+Box>(_: C::Color) {
+    //~^ ERROR ambiguous associated type `Color` in bounds of `C`
+}
+
+fn b<C>(_: C::Color) where C : Vehicle+Box {
+    //~^ ERROR ambiguous associated type `Color` in bounds of `C`
+}
+
+fn c<C>(_: C::Color) where C : Vehicle, C : Box {
+    //~^ ERROR ambiguous associated type `Color` in bounds of `C`
+}
+
+struct D<X>;
+impl<X> D<X> where X : Vehicle {
+    fn d(&self, _: X::Color) where X : Box { }
+    //~^ ERROR ambiguous associated type `Color` in bounds of `X`
+}
+
+trait E<X:Vehicle> {
+    fn e(&self, _: X::Color) where X : Box;
+    //~^ ERROR ambiguous associated type `Color` in bounds of `X`
+
+    fn f(&self, _: X::Color) where X : Box { }
+    //~^ ERROR ambiguous associated type `Color` in bounds of `X`
+}
+
+pub fn main() { }
index edd1b8255ccdc38e6a4b1f7459443f0f0bda90e9..04170779ed2f6b05ae583cbdd7019c1bfa8acd6a 100644 (file)
@@ -35,5 +35,6 @@ trait Add<RHS=Self> {
 fn ice<A>(a: A) {
     let r = loop {};
     r = r + a;
-    //~^ ERROR binary operation `+` cannot be applied to type `A`
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
index b7a16c68a34e1a43fdbb1548dc903a80a3e740b8..915cb077787ea41c05330ce1185ce497633afac0 100644 (file)
@@ -57,4 +57,3 @@ pub trait ToOwned {
 
 
 fn main() {}
-
index c48f9972ebc18765fca88e164449f57bb5a9ea11..0d68b960f31356d2227f227ced2ff65ff402a2f8 100644 (file)
@@ -22,5 +22,5 @@ impl Foo for isize {
 
 pub fn main() {
     let x: isize = Foo::<A=usize>::bar();
-    //~^ERROR unexpected binding of associated item in expression path
+    //~^ ERROR unexpected binding of associated item in expression path
 }
index 3999e9cbe753d1d90ab8294ada23d1d1be274f6a..becbc27138b770e700d524844357252c7c017c95 100644 (file)
@@ -22,5 +22,8 @@ trait Grab {
     //~^ ERROR ambiguous associated type
 }
 
+type X = std::ops::Deref::Target;
+//~^ ERROR ambiguous associated type
+
 fn main() {
 }
index 625f4cdb8ef3dbc3af68abee2124f51eefb1a5b2..5c36e3356a5c026c8d3175fc64d567eae3355179 100644 (file)
@@ -18,4 +18,3 @@ trait Trait : ::std::marker::MarkerTrait {
 impl Trait for isize {}  //~ ERROR missing: `Type`
 
 fn main() {}
-
index 58a8314af211cd581dd2666a0d07f53d2d641614..de315a41361a7900667705cb9eb7882a7c871548 100644 (file)
@@ -11,7 +11,7 @@
 // Tests that a function with a ! annotation always actually fails
 
 fn bad_bang(i: usize) -> ! {
-    return 7_usize; //~ ERROR `return` in a function declared as diverging [E0166]
+    return 7; //~ ERROR `return` in a function declared as diverging [E0166]
 }
 
 fn main() { bad_bang(5); }
index 03c24c2fa3d3e2f15d8eea4caf1f18afaf7fd895..f0ecf31fd10a2532f93c470f1a5ca4aff4bfabd4 100644 (file)
@@ -11,7 +11,7 @@
 // Tests that a function with a ! annotation always actually fails
 
 fn bad_bang(i: usize) -> ! { //~ ERROR computation may converge in a function marked as diverging
-    if i < 0_usize { } else { panic!(); }
+    if i < 0 { } else { panic!(); }
 }
 
 fn main() { bad_bang(5); }
index 7e3c356b87029d0fc7f3169b22ee2160f796a4aa..a9e5c957b89d4735827153a24af639f83f7c058f 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static i: String = 10i32;
+static i: String = 10;
 //~^ ERROR mismatched types
 //~| expected `collections::string::String`
-//~| found `i32`
+//~| found `_`
 //~| expected struct `collections::string::String`
-//~| found i32
+//~| found integral variable
 fn main() { println!("{}", i); }
diff --git a/src/test/compile-fail/bad-crate-id.rs b/src/test/compile-fail/bad-crate-id.rs
deleted file mode 100644 (file)
index 71e3ce9..0000000
+++ /dev/null
@@ -1,13 +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.
-
-extern crate "" as foo; //~ ERROR: crate name must not be empty
-
-fn main() {}
diff --git a/src/test/compile-fail/bad-crate-id2.rs b/src/test/compile-fail/bad-crate-id2.rs
deleted file mode 100644 (file)
index 4899252..0000000
+++ /dev/null
@@ -1,14 +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.
-
-extern crate "#a" as bar; //~ ERROR: invalid character `#` in crate name: `#a`
-
-fn main() {}
-
index a97cf5d41e809493b774a9fef6f1da5abae75c6c..2129d4fbd505578ff2242fc7685c04eaa7e0704c 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn foo<T:'static>() {
-    1_usize.bar::<T>(); //~ ERROR `core::marker::Send` is not implemented
+    1.bar::<T>(); //~ ERROR `core::marker::Send` is not implemented
 }
 
 trait bar {
index 3e02a11c378bd5a2292e8824c149cc4792479098..7a7406115d39365a5735d7f24a735eaa43c91941 100644 (file)
@@ -43,7 +43,7 @@ fn foo<'a>() {
     //~^ ERROR too many type parameters provided
 
     let _ = S::<'a,isize>::new::<f64>(1, 1.0);
-    //~^ ERROR too many lifetime parameters provided
+    //~^ ERROR wrong number of lifetime parameters
 
     let _: S2 = Trait::new::<isize,f64>(1, 1.0);
     //~^ ERROR too many type parameters provided
diff --git a/src/test/compile-fail/binop-fail-3.rs b/src/test/compile-fail/binop-fail-3.rs
deleted file mode 100644 (file)
index 097a52b..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2013 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.
-
-fn foo() -> ! { panic!("quux"); }
-fn main() {
-    foo() //~ ERROR the type of this value must be known in this context
-    ==
-    foo();
-}
index 923d611cebeeaa01ca948632f09abae2385bb4ab..f3fb5a08c854189ecbd74d5e1302c33e1dae045e 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:`||` cannot be applied to type `f32`
-
 fn main() { let x = 1.0_f32 || 2.0_f32; }
+//~^ ERROR mismatched types
+//~| ERROR mismatched types
+
index 2217cf5e4dacb3ba867db23d7e470020c01644b9..f5e53f84c16e6472dc4b39c3aca8a084cba288e7 100644 (file)
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:`&&` cannot be applied to type `i32`
-
-fn main() { let x = 1i32 && 2i32; }
+fn main() { let x = 1 && 2; }
+//~^ ERROR mismatched types
+//~| ERROR mismatched types
index a82aa12dc80c27543b775b21636fbc55e1472717..00f51973a41ad407b6a228b0ea63138a500abc60 100644 (file)
@@ -21,25 +21,25 @@ fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
 fn main() {
     // By-ref captures
     {
-        let mut x = 0_usize;
+        let mut x = 0;
         let _f = to_fn(|| x = 42); //~ ERROR cannot assign
 
-        let mut y = 0_usize;
+        let mut y = 0;
         let _g = to_fn(|| set(&mut y)); //~ ERROR cannot borrow
 
-        let mut z = 0_usize;
+        let mut z = 0;
         let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); }); //~ ERROR cannot assign
     }
 
     // By-value captures
     {
-        let mut x = 0_usize;
+        let mut x = 0;
         let _f = to_fn(move || x = 42); //~ ERROR cannot assign
 
-        let mut y = 0_usize;
+        let mut y = 0;
         let _g = to_fn(move || set(&mut y)); //~ ERROR cannot borrow
 
-        let mut z = 0_usize;
+        let mut z = 0;
         let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); }); //~ ERROR cannot assign
     }
 }
index 40e077bd1b55d5fa17df67aa2937f8e97211765a..b1abbad525356a5ff43f6a894b765ff3d5a20290 100644 (file)
@@ -16,7 +16,7 @@ struct Foo(Box<isize>, isize);
 struct Bar(isize, isize);
 
 fn main() {
-    let x = (box 1, 2);
+    let x: (Box<_>, _) = (box 1, 2);
     let r = &x.0;
     let y = x; //~ ERROR cannot move out of `x` because it is borrowed
 
index 4d1939be5b9f7350eeeb6772b458d21badf7227d..7913f9ac90300c80f9a54abf4e6dc5a62432fe79 100644 (file)
@@ -23,7 +23,7 @@ fn add(v: &usize, w: usize) -> usize {
 }
 
 fn implicit() {
-    let mut a = box 1;
+    let mut a: Box<_> = box 1;
 
     // Note the danger here:
     //
@@ -36,7 +36,7 @@ fn implicit() {
 }
 
 fn explicit() {
-    let mut a = box 1;
+    let mut a: Box<_> = box 1;
     add(
         &*a,
         rewrite(&mut a)); //~ ERROR cannot borrow
index 9eda3689334c19f4176be63c228ea93157ac9e62..e24d4e87add83613a27f3d3acc7480cd79c84fd7 100644 (file)
@@ -23,7 +23,7 @@ fn add(v: &usize, w: Box<usize>) -> usize {
 }
 
 fn implicit() {
-    let mut a = box 1;
+    let mut a: Box<_> = box 1;
 
     // Note the danger here:
     //
@@ -36,7 +36,7 @@ fn implicit() {
 }
 
 fn explicit() {
-    let mut a = box 1;
+    let mut a: Box<_> = box 1;
     add(
         &*a,
         a); //~ ERROR cannot move
index 99618c6bf5626911d8629249df01a2a9c126e052..e5091a92581b45e613d792ee8057b16941309922 100644 (file)
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Foo {
   bar1: Bar,
   bar2: Bar
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Bar {
   int1: isize,
   int2: isize,
index 849c98e122e526b2b78f7adbf25fe7f0a3eb4c09..440be93dfdca18fea34311aa6aa08a007c22eeb8 100644 (file)
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Foo {
   bar1: Bar,
   bar2: Bar
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Bar {
   int1: isize,
   int2: isize,
index 794e0fc6e3aba95ab10168acd24d51a96b0d0ffd..3662e23a4122f71da9c7e74be2b7aa23773cb9b6 100644 (file)
@@ -18,7 +18,7 @@ impl A {
 }
 
 pub fn main() {
-    let a = box A;
+    let a: Box<_> = box A;
     a.foo();
     //~^ ERROR cannot borrow immutable `Box` content `*a` as mutable
 }
index 9126058a4e6f41cacf0ecc08f0d87948b9dc1de1..d60751eddc7bc201866255cb0b129c90744be516 100644 (file)
@@ -11,7 +11,7 @@
 // Test that attempt to reborrow an `&mut` pointer in an aliasable
 // location yields an error.
 //
-// Example from src/middle/borrowck/doc.rs
+// Example from src/librustc_borrowck/borrowck/README.md
 
 fn foo(t0: & &mut isize) {
     let t1 = t0;
index 9c10f01e027557c7e9885d43574a62044cc5f27a..8bbecfd48c6dca78c5b74dd6762f232319edb426 100644 (file)
@@ -16,9 +16,10 @@ extern crate collections;
 use std::collections::HashMap;
 
 fn main() {
-    let tmp;
+    let tmp: Box<_>;
     let mut buggy_map: HashMap<usize, &usize> = HashMap::new();
-    buggy_map.insert(42, &*box 1); //~ ERROR borrowed value does not live long enough
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    buggy_map.insert(42, &*Box::new(1)); //~ ERROR borrowed value does not live long enough
 
     // but it is ok if we use a temporary
     tmp = box 2;
index 648d0d81ffbc0ef28fd99d0da26338f68e6cb177..c980e77df6f967c38a7f858e586bab4c857a44db 100644 (file)
@@ -31,100 +31,100 @@ struct D {
 }
 
 fn copy_after_move() {
-    let a = box A { x: box 0, y: 1 };
+    let a: Box<_> = box A { x: box 0, y: 1 };
     let _x = a.x;
     let _y = a.y; //~ ERROR use of moved
     //~^^ NOTE `a` moved here (through moving `a.x`)
 }
 
 fn move_after_move() {
-    let a = box B { x: box 0, y: box 1 };
+    let a: Box<_> = box B { x: box 0, y: box 1 };
     let _x = a.x;
     let _y = a.y; //~ ERROR use of moved
     //~^^ NOTE `a` moved here (through moving `a.x`)
 }
 
 fn borrow_after_move() {
-    let a = box A { x: box 0, y: 1 };
+    let a: Box<_> = box A { x: box 0, y: 1 };
     let _x = a.x;
     let _y = &a.y; //~ ERROR use of moved
     //~^^ NOTE `a` moved here (through moving `a.x`)
 }
 
 fn move_after_borrow() {
-    let a = box B { x: box 0, y: box 1 };
+    let a: Box<_> = box B { x: box 0, y: box 1 };
     let _x = &a.x;
     let _y = a.y; //~ ERROR cannot move
 }
 
 fn copy_after_mut_borrow() {
-    let mut a = box A { x: box 0, y: 1 };
+    let mut a: Box<_> = box A { x: box 0, y: 1 };
     let _x = &mut a.x;
     let _y = a.y; //~ ERROR cannot use
 }
 
 fn move_after_mut_borrow() {
-    let mut a = box B { x: box 0, y: box 1 };
+    let mut a: Box<_> = box B { x: box 0, y: box 1 };
     let _x = &mut a.x;
     let _y = a.y; //~ ERROR cannot move
 }
 
 fn borrow_after_mut_borrow() {
-    let mut a = box A { x: box 0, y: 1 };
+    let mut a: Box<_> = box A { x: box 0, y: 1 };
     let _x = &mut a.x;
     let _y = &a.y; //~ ERROR cannot borrow
 }
 
 fn mut_borrow_after_borrow() {
-    let mut a = box A { x: box 0, y: 1 };
+    let mut a: Box<_> = box A { x: box 0, y: 1 };
     let _x = &a.x;
     let _y = &mut a.y; //~ ERROR cannot borrow
 }
 
 fn copy_after_move_nested() {
-    let a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+    let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
     let _x = a.x.x;
     let _y = a.y; //~ ERROR use of collaterally moved
 }
 
 fn move_after_move_nested() {
-    let a = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
+    let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
     let _x = a.x.x;
     let _y = a.y; //~ ERROR use of collaterally moved
 }
 
 fn borrow_after_move_nested() {
-    let a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+    let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
     let _x = a.x.x;
     let _y = &a.y; //~ ERROR use of collaterally moved
 }
 
 fn move_after_borrow_nested() {
-    let a = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
+    let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
     let _x = &a.x.x;
     let _y = a.y; //~ ERROR cannot move
 }
 
 fn copy_after_mut_borrow_nested() {
-    let mut a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+    let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
     let _x = &mut a.x.x;
     let _y = a.y; //~ ERROR cannot use
 }
 
 fn move_after_mut_borrow_nested() {
-    let mut a = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
+    let mut a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
     let _x = &mut a.x.x;
     let _y = a.y; //~ ERROR cannot move
 }
 
 fn borrow_after_mut_borrow_nested() {
-    let mut a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+    let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
     let _x = &mut a.x.x;
     let _y = &a.y; //~ ERROR cannot borrow
 }
 
 fn mut_borrow_after_borrow_nested() {
-    let mut a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+    let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
     let _x = &a.x.x;
     let _y = &mut a.y; //~ ERROR cannot borrow
 }
@@ -152,4 +152,3 @@ fn main() {
     borrow_after_mut_borrow_nested();
     mut_borrow_after_borrow_nested();
 }
-
index 9ea5fbbdb1af08e72e83750025961b6652fbfe72..7626f354eb46415a13575402bf74991f11b65bc5 100644 (file)
@@ -11,7 +11,6 @@
 // Ensure that invoking a closure counts as a unique immutable borrow
 
 #![feature(unboxed_closures)]
-#![feature(box_syntax)]
 
 type Fn<'a> = Box<FnMut() + 'a>;
 
@@ -19,11 +18,12 @@ struct Test<'a> {
     f: Box<FnMut() + 'a>
 }
 
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
 fn call<F>(mut f: F) where F: FnMut(Fn) {
-    f(box || {
+    f(Box::new(|| {
     //~^ ERROR: cannot borrow `f` as mutable more than once
-        f(box || {})
-    });
+        f((Box::new(|| {})))
+    }));
 }
 
 fn test1() {
@@ -58,11 +58,12 @@ fn test6() {
 fn test7() {
     fn foo<F>(_: F) where F: FnMut(Box<FnMut(isize)>, isize) {}
     let mut f = |g: Box<FnMut(isize)>, b: isize| {};
-    f(box |a| {
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    f(Box::new(|a| {
         foo(f);
         //~^ ERROR cannot move `f` into closure because it is borrowed
         //~| ERROR cannot move out of captured outer variable in an `FnMut` closure
-    }, 3);
+    }), 3);
 }
 
 fn main() {}
index 851b11fac2b9d1949f9eb09f3e5a15a82c5afe33..aaa0766121543fc5c4b0f2a000fb424b2d2ff106 100644 (file)
@@ -52,7 +52,7 @@ fn e() {
 }
 
 fn f() {
-    let mut x = box 3;
+    let mut x: Box<_> = box 3;
     let c1 = || get(&*x);
     *x = 5; //~ ERROR cannot assign
 }
@@ -62,7 +62,7 @@ fn g() {
         f: Box<isize>
     }
 
-    let mut x = box Foo { f: box 3 };
+    let mut x: Box<_> = box Foo { f: box 3 };
     let c1 = || get(&*x.f);
     *x.f = 5; //~ ERROR cannot assign to `*x.f`
 }
@@ -72,7 +72,7 @@ fn h() {
         f: Box<isize>
     }
 
-    let mut x = box Foo { f: box 3 };
+    let mut x: Box<_> = box Foo { f: box 3 };
     let c1 = || get(&*x.f);
     let c2 = || *x.f = 5; //~ ERROR cannot borrow `x` as mutable
 }
index 8ab4e257b0626d35a76eca6239519d5e2072e8f4..29546abe0bb20bb66b40b284ea23a686840e61af 100644 (file)
@@ -50,7 +50,7 @@ fn g() {
         f: Box<isize>
     }
 
-    let mut x = box Foo { f: box 3 };
+    let mut x: Box<_> = box Foo { f: box 3 };
     let c1 = to_fn_mut(|| set(&mut *x.f));
     let c2 = to_fn_mut(|| set(&mut *x.f));
     //~^ ERROR cannot borrow `x` as mutable more than once
index dcf43c01e1775635612f4b2e7f8d46c90ef69ac8..247a4fe89a501b4e2cfd189638ffcad9fd1c13b5 100644 (file)
@@ -22,4 +22,3 @@ pub fn main() {
     };
     r()
 }
-
index 32cd364d1f2d644ad18917d46514eeaa30e795b1..bb474342a7c6f5bcb61fbab51b66e4ba8105f189 100644 (file)
@@ -25,7 +25,7 @@ impl Drop for Foo {
 }
 
 fn main() {
-  let mut ptr = box Foo { x: 0 };
+  let mut ptr: Box<_> = box Foo { x: 0 };
   let mut test = |foo: &Foo| {
     ptr = box Foo { x: ptr.x + 1 };
   };
diff --git a/src/test/compile-fail/borrowck-consume-unsize-vec.rs b/src/test/compile-fail/borrowck-consume-unsize-vec.rs
new file mode 100644 (file)
index 0000000..32490e0
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2015 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 that we report an error if an upcast box is moved twice.
+
+fn consume(_: Box<[i32]>) {
+}
+
+fn foo(b: Box<[i32;5]>) {
+    consume(b);
+    consume(b); //~ ERROR use of moved value
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/borrowck-consume-upcast-box.rs b/src/test/compile-fail/borrowck-consume-upcast-box.rs
new file mode 100644 (file)
index 0000000..5bcafa6
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2015 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 that we report an error if an upcast box is moved twice.
+
+trait Foo { fn dummy(&self); }
+
+fn consume(_: Box<Foo>) {
+}
+
+fn foo(b: Box<Foo+Send>) {
+    consume(b);
+    consume(b); //~ ERROR use of moved value
+}
+
+fn main() {
+}
index fe5142a77341fe6152c7caea3666f12620f2da1c..13fd5fce95569590f09886fb4a1d2e69b0ad6e78 100644 (file)
@@ -124,4 +124,3 @@ fn main() {
     borrow_after_field_assign_after_uninit();
     move_after_field_assign_after_uninit();
 }
-
diff --git a/src/test/compile-fail/borrowck-fn-in-const-a.rs b/src/test/compile-fail/borrowck-fn-in-const-a.rs
new file mode 100644 (file)
index 0000000..3098807
--- /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 that we check fns appearing in constant declarations.
+// Issue #22382.
+
+const MOVE: fn(&String) -> String = {
+    fn broken(x: &String) -> String {
+        return *x //~ ERROR cannot move
+    }
+    broken
+};
+
+fn main() {
+}
diff --git a/src/test/compile-fail/borrowck-fn-in-const-b.rs b/src/test/compile-fail/borrowck-fn-in-const-b.rs
new file mode 100644 (file)
index 0000000..7e29b2e
--- /dev/null
@@ -0,0 +1,24 @@
+// 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 that we check fns appearing in constant declarations.
+// Issue #22382.
+
+// How about mutating an immutable vector?
+const MUTATE: fn(&Vec<String>) = {
+    fn broken(x: &Vec<String>) {
+        x.push(format!("this is broken"));
+        //~^ ERROR cannot borrow
+    }
+    broken
+};
+
+fn main() {
+}
diff --git a/src/test/compile-fail/borrowck-fn-in-const-c.rs b/src/test/compile-fail/borrowck-fn-in-const-c.rs
new file mode 100644 (file)
index 0000000..e607397
--- /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.
+
+// Check that we check fns appearing in constant declarations.
+// Issue #22382.
+
+// Returning local references?
+struct DropString {
+    inner: String
+}
+impl Drop for DropString {
+    fn drop(&mut self) {
+        self.inner.clear();
+        self.inner.push_str("dropped");
+    }
+}
+const LOCAL_REF: fn() -> &'static str = {
+    fn broken() -> &'static str {
+        let local = DropString { inner: format!("Some local string") };
+        return &local.inner; //~ ERROR does not live long enough
+    }
+    broken
+};
+
+fn main() {
+}
index 492fd4a2c849a8ba9d9f7a9c2c1de65fbbe2b32c..31ec5aea7f3a6e9912d91bbcd13224f69d1884d0 100644 (file)
@@ -28,8 +28,7 @@ fn main() {
     for &a in &f.a {  //~ ERROR cannot move out
     }
 
-    let x = Some(box 1);
+    let x: Option<Box<_>> = Some(box 1);
     for &a in x.iter() {    //~ ERROR cannot move out
     }
 }
-
index 01a649ae2475d7f2cf0eecaf6ed31636ab0b5cad..b79fc5b2bf622eb8fa252628374a8ff0cb6e48a5 100644 (file)
@@ -18,4 +18,3 @@ fn main() {
         vector[1] = 5;   //~ ERROR cannot borrow
     }
 }
-
index cc562afa9f818ecbe89946d1c0d64378020f1a69..64033623fe2d13e86ca3349dd9d520de47346564 100644 (file)
@@ -9,26 +9,48 @@
 // except according to those terms.
 
 // This tests that we can't modify Box<&mut T> contents while they
-// are borrowed.
+// are borrowed (#14498).
+//
+// Also includes tests of the errors reported when the Box in question
+// is immutable (#14270).
 
 #![feature(box_syntax)]
 
 struct A { a: isize }
 struct B<'a> { a: Box<&'a mut isize> }
 
+fn indirect_write_to_imm_box() {
+    let mut x: isize = 1;
+    let y: Box<_> = box &mut x;
+    let p = &y;
+    ***p = 2; //~ ERROR cannot assign to data in an immutable container
+    drop(p);
+}
+
 fn borrow_in_var_from_var() {
     let mut x: isize = 1;
-    let y = box &mut x;
+    let mut y: Box<_> = box &mut x;
+    let p = &y;
+    let q = &***p;
+    **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
+    drop(p);
+    drop(q);
+}
+
+fn borrow_in_var_from_var_via_imm_box() {
+    let mut x: isize = 1;
+    let y: Box<_> = box &mut x;
     let p = &y;
     let q = &***p;
     **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
+    //~^         ERROR cannot assign to data in an immutable container
     drop(p);
     drop(q);
 }
 
 fn borrow_in_var_from_field() {
     let mut x = A { a: 1 };
-    let y = box &mut x.a;
+    let mut y: Box<_> = box &mut x.a;
     let p = &y;
     let q = &***p;
     **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
@@ -36,30 +58,67 @@ fn borrow_in_var_from_field() {
     drop(q);
 }
 
+fn borrow_in_var_from_field_via_imm_box() {
+    let mut x = A { a: 1 };
+    let y: Box<_> = box &mut x.a;
+    let p = &y;
+    let q = &***p;
+    **y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
+    //~^         ERROR cannot assign to data in an immutable container
+    drop(p);
+    drop(q);
+}
+
 fn borrow_in_field_from_var() {
+    let mut x: isize = 1;
+    let mut y = B { a: box &mut x };
+    let p = &y.a;
+    let q = &***p;
+    **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed
+    drop(p);
+    drop(q);
+}
+
+fn borrow_in_field_from_var_via_imm_box() {
     let mut x: isize = 1;
     let y = B { a: box &mut x };
     let p = &y.a;
     let q = &***p;
     **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed
+    //~^           ERROR cannot assign to data in an immutable container
     drop(p);
     drop(q);
 }
 
 fn borrow_in_field_from_field() {
+    let mut x = A { a: 1 };
+    let mut y = B { a: box &mut x.a };
+    let p = &y.a;
+    let q = &***p;
+    **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed
+    drop(p);
+    drop(q);
+}
+
+fn borrow_in_field_from_field_via_imm_box() {
     let mut x = A { a: 1 };
     let y = B { a: box &mut x.a };
     let p = &y.a;
     let q = &***p;
     **y.a = 2; //~ ERROR cannot assign to `**y.a` because it is borrowed
+    //~^           ERROR cannot assign to data in an immutable container
     drop(p);
     drop(q);
 }
 
 fn main() {
+    indirect_write_to_imm_box();
     borrow_in_var_from_var();
+    borrow_in_var_from_var_via_imm_box();
     borrow_in_var_from_field();
+    borrow_in_var_from_field_via_imm_box();
     borrow_in_field_from_var();
+    borrow_in_field_from_var_via_imm_box();
     borrow_in_field_from_field();
+    borrow_in_field_from_field_via_imm_box();
 }
-
index 0c717d2ee5ffff4a9a194c1cdcbed3187aef57b3..0e1712137d34e27c554732cd7aa48e869ef3ee16 100644 (file)
@@ -11,7 +11,7 @@
 #![feature(box_syntax)]
 
 fn main() {
-    let x = Some(box 1);
+    let x: Option<Box<_>> = Some(box 1);
     match x {
       Some(ref _y) => {
         let _a = x; //~ ERROR cannot move
index b4e5ae1c25bf799b13c00d3048d52e17c96a341c..a389a4a5593f07ca879ecbb53f9b6d200636da51 100644 (file)
@@ -11,7 +11,7 @@
 #![feature(box_syntax)]
 
 fn main() {
-    let x = Some(box 1);
+    let x: Option<Box<_>> = Some(box 1);
     match x {
       Some(ref y) => {
         let _b = *y; //~ ERROR cannot move out
index ca8efb5dc967d7f5286982ec741c73a7b20e62c3..0efe8622621785c0e762210c11463bd3b51db05c 100644 (file)
@@ -30,7 +30,7 @@ fn pre_freeze_cond() {
     // In this instance, the freeze is conditional and starts before
     // the mut borrow.
 
-    let mut v = box 3;
+    let mut v: Box<_> = box 3;
     let _w;
     if cond() {
         _w = &v;
@@ -42,7 +42,7 @@ fn pre_freeze_else() {
     // In this instance, the freeze and mut borrow are on separate sides
     // of the if.
 
-    let mut v = box 3;
+    let mut v: Box<_> = box 3;
     let _w;
     if cond() {
         _w = &v;
index 5418a531fe68a19dd7e74652ddba41f46cb19331..f841fedf75af913cd03a0e26fe7f17c3b3dfaf5b 100644 (file)
@@ -28,7 +28,7 @@ fn inc(v: &mut Box<isize>) {
 fn loop_overarching_alias_mut() {
     // In this instance, the borrow encompasses the entire loop.
 
-    let mut v = box 3;
+    let mut v: Box<_> = box 3;
     let mut x = &mut v;
     **x += 1;
     loop {
@@ -39,7 +39,7 @@ fn loop_overarching_alias_mut() {
 fn block_overarching_alias_mut() {
     // In this instance, the borrow encompasses the entire closure call.
 
-    let mut v = box 3;
+    let mut v: Box<_> = box 3;
     let mut x = &mut v;
     for _ in 0..3 {
         borrow(&*v); //~ ERROR cannot borrow
@@ -50,8 +50,8 @@ fn block_overarching_alias_mut() {
 fn loop_aliased_mut() {
     // In this instance, the borrow is carried through the loop.
 
-    let mut v = box 3;
-    let mut w = box 4;
+    let mut v: Box<_> = box 3;
+    let mut w: Box<_> = box 4;
     let mut _x = &w;
     loop {
         borrow_mut(&mut *v); //~ ERROR cannot borrow
@@ -62,8 +62,8 @@ fn loop_aliased_mut() {
 fn while_aliased_mut() {
     // In this instance, the borrow is carried through the loop.
 
-    let mut v = box 3;
-    let mut w = box 4;
+    let mut v: Box<_> = box 3;
+    let mut w: Box<_> = box 4;
     let mut _x = &w;
     while cond() {
         borrow_mut(&mut *v); //~ ERROR cannot borrow
@@ -75,8 +75,8 @@ fn while_aliased_mut() {
 fn loop_aliased_mut_break() {
     // In this instance, the borrow is carried through the loop.
 
-    let mut v = box 3;
-    let mut w = box 4;
+    let mut v: Box<_> = box 3;
+    let mut w: Box<_> = box 4;
     let mut _x = &w;
     loop {
         borrow_mut(&mut *v);
@@ -89,8 +89,8 @@ fn loop_aliased_mut_break() {
 fn while_aliased_mut_break() {
     // In this instance, the borrow is carried through the loop.
 
-    let mut v = box 3;
-    let mut w = box 4;
+    let mut v: Box<_> = box 3;
+    let mut w: Box<_> = box 4;
     let mut _x = &w;
     while cond() {
         borrow_mut(&mut *v);
@@ -101,8 +101,8 @@ fn while_aliased_mut_break() {
 }
 
 fn while_aliased_mut_cond(cond: bool, cond2: bool) {
-    let mut v = box 3;
-    let mut w = box 4;
+    let mut v: Box<_> = box 3;
+    let mut w: Box<_> = box 4;
     let mut x = &mut w;
     while cond {
         **x += 1;
index 177976c15f0f46831762f717273b6f699c3227fd..6da8f088b3279005474b3368b9d6cd4e5f745784 100644 (file)
@@ -29,7 +29,7 @@ fn inc(v: &mut Box<isize>) {
 fn pre_freeze() {
     // In this instance, the freeze starts before the mut borrow.
 
-    let mut v = box 3;
+    let mut v: Box<_> = box 3;
     let _w = &v;
     borrow_mut(&mut *v); //~ ERROR cannot borrow
 }
@@ -37,7 +37,7 @@ fn pre_freeze() {
 fn post_freeze() {
     // In this instance, the const alias starts after the borrow.
 
-    let mut v = box 3;
+    let mut v: Box<_> = box 3;
     borrow_mut(&mut *v);
     let _w = &v;
 }
index 5729f8c56179e42da911512974effd9cc474ab6b..d760f3db0c2cc9b85370bc03f11365d3d78c778b 100644 (file)
@@ -17,4 +17,3 @@ fn f() {
 fn main() {
     f();
 }
-
index 7f676f5166f7f77fb77129553870257313bc66ac..57b584a89599f0a88512b043d7ec66dc34047eff 100644 (file)
@@ -17,7 +17,7 @@ fn borrow<F>(v: &isize, f: F) where F: FnOnce(&isize) {
 }
 
 fn box_imm() {
-    let v = box 3;
+    let v: Box<_> = box 3;
     let _w = &v;
     thread::spawn(move|| {
         println!("v={}", *v);
@@ -26,7 +26,7 @@ fn box_imm() {
 }
 
 fn box_imm_explicit() {
-    let v = box 3;
+    let v: Box<_> = box 3;
     let _w = &v;
     thread::spawn(move|| {
         println!("v={}", *v);
index a52a4484b20d123440a7c602d20c1c8d9ed6eee9..32d8088549d4fb9fd113ffe82313bee07ab7c4d0 100644 (file)
@@ -15,7 +15,7 @@ fn borrow<F>(v: &isize, f: F) where F: FnOnce(&isize) {
 }
 
 fn box_imm() {
-    let mut v = box 3;
+    let mut v: Box<_> = box 3;
     borrow(&*v,
            |w| { //~ ERROR cannot borrow `v` as mutable
             v = box 4;
index b1eb06d16b19ae47b1d199caeb62b42fc79d8eb0..cce55b6c941b90e019add2efc7d328489a341a77 100644 (file)
@@ -10,7 +10,7 @@
 
 use std::ops::Add;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Point {
     x: isize,
     y: isize,
index 38593d31842eb2c5291fea494c0dd19c44f60e32..c219b7c5424e926e20ff5a12767352b56466e3f2 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test that immutable pattern bindings cannot be reassigned.
 
+#![feature(slice_patterns)]
+
 enum E {
     Foo(isize)
 }
index a1708e7f497286c81a4d6007aafb13c7ea4420c0..bad521210439ff2f68f3773bea6e627feeb15ad6 100644 (file)
@@ -14,7 +14,7 @@ fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
 fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
 
 pub fn main() {
-    let bar = box 3;
+    let bar: Box<_> = box 3;
     let _g = to_fn_mut(|| {
         let _h = to_fn_once(move || -> isize { *bar }); //~ ERROR cannot move out of
     });
index 2d82c8be519712feea5960cd3ee185ed1def58dc..e4b9fb2671124d64e3dc20d8fd98840b6c0957a8 100644 (file)
@@ -17,7 +17,7 @@ enum Foo {
 }
 
 fn blah() {
-    let f = &Foo::Foo1(box 1u32, box 2u32);
+    let f = &Foo::Foo1(box 1, box 2);
     match *f {             //~ ERROR cannot move out of
         Foo::Foo1(num1,         //~ NOTE attempting to move value to here
                   num2) => (),  //~ NOTE and here
index 3d8d599970f2c57715347b74d249b8e1134ec7fe..c02c6a7151428fbedb7e79b8e3b2ff89cde5308d 100644 (file)
@@ -14,7 +14,7 @@
 #![feature(box_syntax)]
 
 fn main() {
-    let a = box box 2;
+    let a: Box<Box<_>> = box box 2;
     let b = &a;
 
     let z = *a; //~ ERROR: cannot move out of `*a` because it is borrowed
index 43bf3f25d1ab9ff4d8380bb8750cb7f857b62679..c46bcbb32b9cf13bd796b10637762629bd7af739 100644 (file)
@@ -15,7 +15,7 @@ fn call_f<F:FnOnce() -> isize>(f: F) -> isize {
 }
 
 fn main() {
-    let t = box 3;
+    let t: Box<_> = box 3;
 
     call_f(move|| { *t + 1 });
     call_f(move|| { *t + 1 }); //~ ERROR capture of moved value
index 5bdea6a2bd9962898812feaeb71637fc7372ae76..2fb89e6364bb1e8b24a8607cd18d46f9329fe502 100644 (file)
@@ -11,7 +11,7 @@
 // Test that attempt to move `&mut` pointer while pointee is borrowed
 // yields an error.
 //
-// Example from src/middle/borrowck/doc.rs
+// Example from src/librustc_borrowck/borrowck/README.md
 
 fn foo(t0: &mut isize) {
     let p: &isize = &*t0; // Freezes `*t0`
index f9d24130e47afdbe5f9c95588ac9a5bb62d054cf..d9a2f89a9e21ea56dc46aa936bc3f6fdfa1fb9c9 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test that we do not permit moves from &[] matched by a vec pattern.
 
+#![feature(slice_patterns)]
+
 #[derive(Clone, Debug)]
 struct Foo {
     string: String
index 9db05d76284e8d23cdc1660fb9e834e3310a9f2f..042b914ce41a49d0fccca3b5272d7fa8825a6c0f 100644 (file)
@@ -15,9 +15,9 @@ use std::thread;
 fn borrow<T>(_: &T) { }
 
 fn different_vars_after_borrows() {
-    let x1 = box 1;
+    let x1: Box<_> = box 1;
     let p1 = &x1;
-    let x2 = box 2;
+    let x2: Box<_> = box 2;
     let p2 = &x2;
     thread::spawn(move|| {
         drop(x1); //~ ERROR cannot move `x1` into closure because it is borrowed
@@ -28,9 +28,9 @@ fn different_vars_after_borrows() {
 }
 
 fn different_vars_after_moves() {
-    let x1 = box 1;
+    let x1: Box<_> = box 1;
     drop(x1);
-    let x2 = box 2;
+    let x2: Box<_> = box 2;
     drop(x2);
     thread::spawn(move|| {
         drop(x1); //~ ERROR capture of moved value: `x1`
@@ -39,7 +39,7 @@ fn different_vars_after_moves() {
 }
 
 fn same_var_after_borrow() {
-    let x = box 1;
+    let x: Box<_> = box 1;
     let p = &x;
     thread::spawn(move|| {
         drop(x); //~ ERROR cannot move `x` into closure because it is borrowed
@@ -49,7 +49,7 @@ fn same_var_after_borrow() {
 }
 
 fn same_var_after_move() {
-    let x = box 1;
+    let x: Box<_> = box 1;
     drop(x);
     thread::spawn(move|| {
         drop(x); //~ ERROR capture of moved value: `x`
@@ -63,4 +63,3 @@ fn main() {
     same_var_after_borrow();
     same_var_after_move();
 }
-
index 71dc61abb64e9c7d7e3e44b20e230b3917c0445d..bdeb7ea69bdfb84d416420bc26f3474e373d6c90 100644 (file)
@@ -11,7 +11,7 @@
 // Test that attempt to mutably borrow `&mut` pointer while pointee is
 // borrowed yields an error.
 //
-// Example from src/middle/borrowck/doc.rs
+// Example from src/librustc_borrowck/borrowck/README.md
 
 fn foo<'a>(mut t0: &'a mut isize,
            mut t1: &'a mut isize) {
index 44353ab5d960ae5d33a97767bdf3385c4c65017a..e35edca639e4535f18ff2e0fc4a3f69243507624 100644 (file)
@@ -30,4 +30,3 @@ fn foo() -> isize {
 fn main() {
     foo();
 }
-
index 6985d203fb163cc554940e8646d4d56ffeebdb83..8cb7423f3cb5efc1aa4bf349ba25c0b1821f0c31 100644 (file)
@@ -19,7 +19,7 @@ enum cycle {
     empty
 }
 fn main() {
-    let mut x = box cycle::node(node_ {a: box cycle::empty});
+    let mut x: Box<_> = box cycle::node(node_ {a: box cycle::empty});
     // Create a cycle!
     match *x {
       cycle::node(ref mut y) => {
index bbb58e211988ec115c61fee884cd1735907a4747..021b3f38e0019d9d57441d93c24b89d011c6582d 100644 (file)
@@ -37,4 +37,3 @@ fn imm_owned_receiver(mut x: Box<Foo>) {
 }
 
 fn main() {}
-
index 9b5087bd7e0b741627c1ff8b66ee8fc462d84750..1bdc32b09750bd8162e6bbd1bf8af762b9b7c4c9 100644 (file)
@@ -35,4 +35,3 @@ fn mut_owned_receiver(mut x: Box<Foo>) {
 }
 
 fn main() {}
-
index 04d73cc36f04cb2fd1d23945973a45c0a0aebd1c..93c37524bf565294dd07c4fba3c4ec794c49bd7a 100644 (file)
@@ -18,26 +18,36 @@ struct SFn {
 }
 
 impl Fn<(isize,)> for SFn {
-    type Output = isize;
-
     extern "rust-call" fn call(&self, (z,): (isize,)) -> isize {
         self.x * self.y * z
     }
 }
 
+impl FnMut<(isize,)> for SFn {
+    extern "rust-call" fn call_mut(&mut self, args: (isize,)) -> isize { self.call(args) }
+}
+
+impl FnOnce<(isize,)> for SFn {
+    type Output = isize;
+    extern "rust-call" fn call_once(self, args: (isize,)) -> isize { self.call(args) }
+}
+
 struct SFnMut {
     x: isize,
     y: isize,
 }
 
 impl FnMut<(isize,)> for SFnMut {
-    type Output = isize;
-
     extern "rust-call" fn call_mut(&mut self, (z,): (isize,)) -> isize {
         self.x * self.y * z
     }
 }
 
+impl FnOnce<(isize,)> for SFnMut {
+    type Output = isize;
+    extern "rust-call" fn call_once(mut self, args: (isize,)) -> isize { self.call_mut(args) }
+}
+
 struct SFnOnce {
     x: String,
 }
@@ -77,4 +87,3 @@ fn h() {
 }
 
 fn main() {}
-
diff --git a/src/test/compile-fail/borrowck-overloaded-index-2.rs b/src/test/compile-fail/borrowck-overloaded-index-2.rs
deleted file mode 100644 (file)
index e9d8544..0000000
+++ /dev/null
@@ -1,32 +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.
-
-#![feature(box_syntax)]
-
-use std::ops::Index;
-
-struct MyVec<T> {
-    data: Vec<T>,
-}
-
-impl<T> Index<usize> for MyVec<T> {
-    type Output = T;
-
-    fn index(&self, &i: &usize) -> &T {
-        &self.data[i]
-    }
-}
-
-fn main() {
-    let v = MyVec { data: vec!(box 1, box 2, box 3) };
-    let good = &v[0]; // Shouldn't fail here
-    let bad = v[0];
-    //~^ ERROR cannot move out of indexed content
-}
index 4188cf001423e53dea4eeef13872dba94cbedbdf..bee56c9bf390bb17092d20dc86324435decad8e7 100644 (file)
@@ -19,7 +19,7 @@ struct MyVec<T> { x: T }
 
 impl<T> Index<usize> for MyVec<T> {
     type Output = T;
-    fn index(&self, _: &usize) -> &T {
+    fn index(&self, _: usize) -> &T {
         &self.x
     }
 }
@@ -44,4 +44,3 @@ fn main() {
 }
 
 fn read(_: usize) { }
-
index 99f396ef8143213af415dbca2a649d0b4e1cd167..b726c46d5d533c8681b8a4ad65bf94a9057f921a 100644 (file)
@@ -18,10 +18,10 @@ struct Foo {
     y: isize,
 }
 
-impl Index<String> for Foo {
+impl<'a> Index<&'a String> for Foo {
     type Output = isize;
 
-    fn index<'a>(&'a self, z: &String) -> &'a isize {
+    fn index(&self, z: &String) -> &isize {
         if *z == "x" {
             &self.x
         } else {
@@ -30,8 +30,8 @@ impl Index<String> for Foo {
     }
 }
 
-impl IndexMut<String> for Foo {
-    fn index_mut<'a>(&'a mut self, z: &String) -> &'a mut isize {
+impl<'a> IndexMut<&'a String> for Foo {
+    fn index_mut(&mut self, z: &String) -> &mut isize {
         if *z == "x" {
             &mut self.x
         } else {
@@ -41,13 +41,13 @@ impl IndexMut<String> for Foo {
 }
 
 fn test1(mut f: Box<Foo>, s: String) {
-    let _p = &mut f[s];
-    let _q = &f[s]; //~ ERROR cannot borrow
+    let _p = &mut f[&s];
+    let _q = &f[&s]; //~ ERROR cannot borrow
 }
 
 fn test2(mut f: Box<Foo>, s: String) {
-    let _p = &mut f[s];
-    let _q = &mut f[s]; //~ ERROR cannot borrow
+    let _p = &mut f[&s];
+    let _q = &mut f[&s]; //~ ERROR cannot borrow
 }
 
 struct Bar {
@@ -55,37 +55,37 @@ struct Bar {
 }
 
 fn test3(mut f: Box<Bar>, s: String) {
-    let _p = &mut f.foo[s];
-    let _q = &mut f.foo[s]; //~ ERROR cannot borrow
+    let _p = &mut f.foo[&s];
+    let _q = &mut f.foo[&s]; //~ ERROR cannot borrow
 }
 
 fn test4(mut f: Box<Bar>, s: String) {
-    let _p = &f.foo[s];
-    let _q = &f.foo[s];
+    let _p = &f.foo[&s];
+    let _q = &f.foo[&s];
 }
 
 fn test5(mut f: Box<Bar>, s: String) {
-    let _p = &f.foo[s];
-    let _q = &mut f.foo[s]; //~ ERROR cannot borrow
+    let _p = &f.foo[&s];
+    let _q = &mut f.foo[&s]; //~ ERROR cannot borrow
 }
 
 fn test6(mut f: Box<Bar>, g: Foo, s: String) {
-    let _p = &f.foo[s];
+    let _p = &f.foo[&s];
     f.foo = g; //~ ERROR cannot assign
 }
 
 fn test7(mut f: Box<Bar>, g: Bar, s: String) {
-    let _p = &f.foo[s];
+    let _p = &f.foo[&s];
     *f = g; //~ ERROR cannot assign
 }
 
 fn test8(mut f: Box<Bar>, g: Foo, s: String) {
-    let _p = &mut f.foo[s];
+    let _p = &mut f.foo[&s];
     f.foo = g; //~ ERROR cannot assign
 }
 
 fn test9(mut f: Box<Bar>, g: Bar, s: String) {
-    let _p = &mut f.foo[s];
+    let _p = &mut f.foo[&s];
     *f = g; //~ ERROR cannot assign
 }
 
diff --git a/src/test/compile-fail/borrowck-overloaded-index-move-from-vec.rs b/src/test/compile-fail/borrowck-overloaded-index-move-from-vec.rs
new file mode 100644 (file)
index 0000000..1b62d9c
--- /dev/null
@@ -0,0 +1,32 @@
+// 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(box_syntax)]
+
+use std::ops::Index;
+
+struct MyVec<T> {
+    data: Vec<T>,
+}
+
+impl<T> Index<usize> for MyVec<T> {
+    type Output = T;
+
+    fn index(&self, i: usize) -> &T {
+        &self.data[i]
+    }
+}
+
+fn main() {
+    let v = MyVec::<Box<_>> { data: vec!(box 1, box 2, box 3) };
+    let good = &v[0]; // Shouldn't fail here
+    let bad = v[0];
+    //~^ ERROR cannot move out of indexed content
+}
diff --git a/src/test/compile-fail/borrowck-overloaded-index-move-index.rs b/src/test/compile-fail/borrowck-overloaded-index-move-index.rs
new file mode 100644 (file)
index 0000000..d8615d1
--- /dev/null
@@ -0,0 +1,74 @@
+// 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 std::ops::{Index, IndexMut};
+
+struct Foo {
+    x: isize,
+    y: isize,
+}
+
+impl Index<String> for Foo {
+    type Output = isize;
+
+    fn index(&self, z: String) -> &isize {
+        if z == "x" {
+            &self.x
+        } else {
+            &self.y
+        }
+    }
+}
+
+impl IndexMut<String> for Foo {
+    fn index_mut(&mut self, z: String) -> &mut isize {
+        if z == "x" {
+            &mut self.x
+        } else {
+            &mut self.y
+        }
+    }
+}
+
+struct Bar {
+    x: isize,
+}
+
+impl Index<isize> for Bar {
+    type Output = isize;
+
+    fn index<'a>(&'a self, z: isize) -> &'a isize {
+        &self.x
+    }
+}
+
+fn main() {
+    let mut f = Foo {
+        x: 1,
+        y: 2,
+    };
+    let mut s = "hello".to_string();
+    let rs = &mut s;
+
+    println!("{}", f[s]);
+    //~^ ERROR cannot move out of `s` because it is borrowed
+
+    f[s] = 10;
+    //~^ ERROR cannot move out of `s` because it is borrowed
+    //~| ERROR use of moved value: `s`
+
+    let s = Bar {
+        x: 1,
+    };
+    let i = 2;
+    let _j = &i;
+    println!("{}", s[i]); // no error, i is copy
+    println!("{}", s[i]);
+}
diff --git a/src/test/compile-fail/borrowck-overloaded-index-ref-index.rs b/src/test/compile-fail/borrowck-overloaded-index-ref-index.rs
new file mode 100644 (file)
index 0000000..4c50caf
--- /dev/null
@@ -0,0 +1,68 @@
+// 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 std::ops::{Index, IndexMut};
+
+struct Foo {
+    x: isize,
+    y: isize,
+}
+
+impl<'a> Index<&'a String> for Foo {
+    type Output = isize;
+
+    fn index(&self, z: &String) -> &isize {
+        if *z == "x" {
+            &self.x
+        } else {
+            &self.y
+        }
+    }
+}
+
+impl<'a> IndexMut<&'a String> for Foo {
+    fn index_mut(&mut self, z: &String) -> &mut isize {
+        if *z == "x" {
+            &mut self.x
+        } else {
+            &mut self.y
+        }
+    }
+}
+
+struct Bar {
+    x: isize,
+}
+
+impl Index<isize> for Bar {
+    type Output = isize;
+
+    fn index<'a>(&'a self, z: isize) -> &'a isize {
+        &self.x
+    }
+}
+
+fn main() {
+    let mut f = Foo {
+        x: 1,
+        y: 2,
+    };
+    let mut s = "hello".to_string();
+    let rs = &mut s;
+    println!("{}", f[&s]);
+    //~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
+    f[&s] = 10;
+    //~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
+    let s = Bar {
+        x: 1,
+    };
+    s[2] = 20;
+    //~^ ERROR cannot assign to immutable indexed content
+}
diff --git a/src/test/compile-fail/borrowck-overloaded-index.rs b/src/test/compile-fail/borrowck-overloaded-index.rs
deleted file mode 100644 (file)
index 2d752ab..0000000
+++ /dev/null
@@ -1,68 +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.
-
-use std::ops::{Index, IndexMut};
-
-struct Foo {
-    x: isize,
-    y: isize,
-}
-
-impl Index<String> for Foo {
-    type Output = isize;
-
-    fn index<'a>(&'a self, z: &String) -> &'a isize {
-        if *z == "x" {
-            &self.x
-        } else {
-            &self.y
-        }
-    }
-}
-
-impl IndexMut<String> for Foo {
-    fn index_mut<'a>(&'a mut self, z: &String) -> &'a mut isize {
-        if *z == "x" {
-            &mut self.x
-        } else {
-            &mut self.y
-        }
-    }
-}
-
-struct Bar {
-    x: isize,
-}
-
-impl Index<isize> for Bar {
-    type Output = isize;
-
-    fn index<'a>(&'a self, z: &isize) -> &'a isize {
-        &self.x
-    }
-}
-
-fn main() {
-    let mut f = Foo {
-        x: 1,
-        y: 2,
-    };
-    let mut s = "hello".to_string();
-    let rs = &mut s;
-    println!("{}", f[s]);
-    //~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
-    f[s] = 10;
-    //~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
-    let s = Bar {
-        x: 1,
-    };
-    s[2] = 20;
-    //~^ ERROR cannot assign to immutable indexed content
-}
index 0926ba6e4325007716502d6cd606dab80c06400e..c9cdeff9c7a17afa830f39a69cba68ed838abfc7 100644 (file)
@@ -31,4 +31,3 @@ fn main() {
     stuff();
     println!("Hello, world!")
 }
-
index 216373707241efe7318e41825a6079c0c22eff6a..61bf2c11a1f72d1b96d371f762d352e61947ae1d 100644 (file)
@@ -11,7 +11,7 @@
 #![allow(dead_code)]
 fn main() {
     // Original borrow ends at end of function
-    let mut x = 1_usize;
+    let mut x = 1;
     let y = &mut x;
     let z = &x; //~ ERROR cannot borrow
 }
@@ -21,7 +21,7 @@ fn foo() {
     match true {
         true => {
             // Original borrow ends at end of match arm
-            let mut x = 1_usize;
+            let mut x = 1;
             let y = &x;
             let z = &mut x; //~ ERROR cannot borrow
         }
@@ -33,7 +33,7 @@ fn foo() {
 fn bar() {
     // Original borrow ends at end of closure
     || {
-        let mut x = 1_usize;
+        let mut x = 1;
         let y = &mut x;
         let z = &mut x; //~ ERROR cannot borrow
     };
index 0102a909188468ff92dc6625fc6e916abe974fae..552fcec8e2858e921fd6a8842b3981667986e5a0 100644 (file)
@@ -11,7 +11,7 @@
 // Test that attempt to swap `&mut` pointer while pointee is borrowed
 // yields an error.
 //
-// Example from src/middle/borrowck/doc.rs
+// Example from src/librustc_borrowck/borrowck/README.md
 
 use std::mem::swap;
 
index 8e7e2e3e77782e9aa3cb33be33ec026bf4a2db22..3eca850e493c7231687dddfe6ad84c54235dd696 100644 (file)
@@ -26,4 +26,3 @@ fn c<F:FnOnce(isize, isize) -> isize>(f: F) {
 }
 
 fn main() {}
-
index 49a1b782a3db443aeff1c72640ea17e74c722f2c..f36dc0ca43fa25beaa03a6ac3bd03bbbcbaa1f07 100644 (file)
@@ -13,7 +13,7 @@
 fn borrow(_v: &isize) {}
 
 fn local() {
-    let mut v = box 3;
+    let mut v: Box<_> = box 3;
     borrow(&*v);
 }
 
@@ -32,27 +32,27 @@ fn local_recs() {
 }
 
 fn aliased_imm() {
-    let mut v = box 3;
+    let mut v: Box<_> = box 3;
     let _w = &v;
     borrow(&*v);
 }
 
 fn aliased_mut() {
-    let mut v = box 3;
+    let mut v: Box<_> = box 3;
     let _w = &mut v;
     borrow(&*v); //~ ERROR cannot borrow `*v`
 }
 
 fn aliased_other() {
-    let mut v = box 3;
-    let mut w = box 4;
+    let mut v: Box<_> = box 3;
+    let mut w: Box<_> = box 4;
     let _x = &mut w;
     borrow(&*v);
 }
 
 fn aliased_other_reassign() {
-    let mut v = box 3;
-    let mut w = box 4;
+    let mut v: Box<_> = box 3;
+    let mut w: Box<_> = box 4;
     let mut _x = &mut w;
     _x = &mut v;
     borrow(&*v); //~ ERROR cannot borrow `*v`
index 52f89da10b97726013a74d01d5a324fa4f2047b5..c11e58651aa76a1f7979bafda0f0e12cd8100c1a 100644 (file)
@@ -10,7 +10,7 @@
 
 #![feature(box_syntax)]
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct A { a: isize, b: isize }
 
 struct B { a: isize, b: Box<isize> }
@@ -94,4 +94,3 @@ fn main() {
     field_deref_after_var_borrow();
     field_deref_after_field_borrow();
 }
-
index 2d6a4b7d2c9df023f55075450f18727d43bf27b3..98052ad31a7ef13b524fba8b559d493bd834aabd 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![feature(advanced_slice_patterns)]
+#![feature(slice_patterns)]
 
 fn a<'a>() -> &'a [isize] {
     let vec = vec!(1, 2, 3, 4);
index c1906758a5ae89586c8531770d9bbbc56abc856a..db635893c81b9f5d4c03c61e1545dba44a5fba5f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 fn a() {
     let mut v = vec!(1, 2, 3);
     let vb: &mut [isize] = &mut v;
index 242a38440034ccaca016addea210f249a000de09..97dcaeb0bf1a3d2c2eb8a9b90f821aa0c72c81f5 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 fn main() {
     let mut a = [1, 2, 3, 4];
     let t = match a {
index b471439f751ffdb3e1d5938eedb8dbac38c753c9..a69ce0cb365c765a07cf5d842edb9b5e4fda2455 100644 (file)
@@ -11,6 +11,7 @@
 #![feature(advanced_slice_patterns)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
+#![feature(slice_patterns)]
 
 fn a() {
     let mut vec = [box 1, box 2, box 3];
index df0fee437b94ab93ef87107bd71f5eca0fd06c19..82b3490d7d7e118c79a875ec91288b0cd2960ad9 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 fn a<'a>() -> &'a isize {
     let vec = vec!(1, 2, 3, 4);
     let vec: &[isize] = &vec; //~ ERROR `vec` does not live long enough
index e59bd62d178549133ae66fe02cd04cc1cb21bbba..5ddde6460b01f9504bf283aa53675e186bb65bf2 100644 (file)
@@ -10,6 +10,8 @@
 
 #![feature(unboxed_closures)]
 
+use std::io::Read;
+
 fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
 
 fn main() {
@@ -17,7 +19,7 @@ fn main() {
     to_fn_once(move|| { x = 2; });
     //~^ ERROR: cannot assign to immutable captured outer variable
 
-    let s = std::old_io::stdin();
-    to_fn_once(move|| { s.read_to_end(); });
+    let s = std::io::stdin();
+    to_fn_once(move|| { s.read_to_end(&mut Vec::new()); });
     //~^ ERROR: cannot borrow immutable captured outer variable
 }
diff --git a/src/test/compile-fail/cfg-attr-unknown-attribute-macro-expansion.rs b/src/test/compile-fail/cfg-attr-unknown-attribute-macro-expansion.rs
new file mode 100644 (file)
index 0000000..afcb896
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+macro_rules! foo {
+    () => {
+        #[cfg_attr(all(), unknown)] //~ ERROR `unknown` is currently unknown
+        fn foo() {}
+    }
+}
+
+foo!();
+
+fn main() {}
index ada45e8c1fc8b1528803fd00c5ab35f58266a4d8..46b100a4d399e35593ef3cda5b34899e5796dbcd 100644 (file)
@@ -27,5 +27,5 @@ fn cat(in_x : usize) -> cat {
 }
 
 fn main() {
-  let nyan = cat(0_usize);
+  let nyan = cat(0);
 }
index f25b2e65388ee190801e27ce09f55646d6f9be46..ab76af1cbe600d91168633f3b66f3b5db04d6ee7 100644 (file)
@@ -16,7 +16,7 @@ impl cat {
     fn sleep(&self) { loop{} }
     fn meow(&self) {
       println!("Meow");
-      meows += 1_usize; //~ ERROR unresolved name
+      meows += 1; //~ ERROR unresolved name
       sleep();     //~ ERROR unresolved name
     }
 
index d2295eba6d7a41f99fc288e116dcbf2ab72d669d..490734d463da4ceb43eb37cde1f4fd966949d4fd 100644 (file)
@@ -20,4 +20,3 @@ fn main() {
     let f = |s: &str| println!("{}{}", s, string);
     call_bare(f)    //~ ERROR mismatched types
 }
-
index fe7635f065cdc5ee969fe64c792b991de8fe45a6..27b4a04054f073f203503b5ef9a01298e864a622 100644 (file)
@@ -10,5 +10,6 @@
 
 fn main() {
     let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
-    //~^ ERROR: is not implemented for the type
+    //~^ ERROR E0277
+    //~| ERROR E0277
 }
index aac180f9ad7bf63ca00a2c5f560d5bd1bbed0723..bb4d1693af7e35902839a9d920b85b4b7f5af701 100644 (file)
 // Tests that we forbid coercion from `[T; n]` to `&[T]`
 
 fn main() {
-    let _: &[i32] = [0i32];
+    let _: &[i32] = [0];
     //~^ ERROR mismatched types
     //~| expected `&[i32]`
-    //~| found `[i32; 1]`
+    //~| found `[_; 1]`
     //~| expected &-ptr
     //~| found array of 1 elements
 }
index 1e3b7f6dbd22f94b819466d1dea00b9aced81b14..7a5340041c21bd911f3eaa8646bcd9df766eb70d 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-extern crate "coherence-lib" as lib;
+extern crate coherence_lib as lib;
 use lib::Remote1;
 
 impl<T> Remote1<T> for isize { }
index b7ca499be736623db82a570eccbda76c7718a28e..32c5b6693814ecada9787e5c319975b574acdd7f 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-extern crate "coherence-lib" as lib;
+extern crate coherence_lib as lib;
 use lib::Remote1;
 
 pub struct BigInt;
index d4decb713498df2e3e35eff101178d59b87af488..98a9c713e84c331c9d305a63ff0ffa0cb79cec4f 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::fmt::Show;
+use std::fmt::Debug;
 use std::default::Default;
 use std::marker::MarkerTrait;
 
index b1ee1762b6e71ab2d9c722de3564acc3da722821..57d25a3bf586dcab40fe8df4857095ca8db25ed7 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::fmt::Show;
+use std::fmt::Debug;
 use std::default::Default;
 
 // Test that two blanket impls conflict (at least without negative
index 1f6bb08871c76db6ff94850c8fb35d2c3be3548f..b3ef79c6cc01e98474df89b02339b3406df1f5fa 100644 (file)
@@ -13,7 +13,7 @@
 extern crate go_trait;
 
 use go_trait::{Go,GoMut};
-use std::fmt::Show;
+use std::fmt::Debug;
 use std::default::Default;
 
 struct MyThingy;
index c3563792ce3c7d2e5b9f8c17a183560838ff5f9a..7b60a5ecbd71f4ac8533599cfb20cb73c4b42a71 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::fmt::Show;
+use std::fmt::Debug;
 use std::default::Default;
 
 // Test that a blank impl for all T conflicts with an impl for some
index 980e4256d2b854d635c4ccdaff00a97a4d710025..d218b64af05270f0dec430b4b1001d410edfd0e9 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::fmt::Show;
+use std::fmt::Debug;
 use std::default::Default;
 
 // Test that a blank impl for all T conflicts with an impl for some
diff --git a/src/test/compile-fail/coherence-cow-1.rs b/src/test/compile-fail/coherence-cow-1.rs
new file mode 100644 (file)
index 0000000..530bbf5
--- /dev/null
@@ -0,0 +1,28 @@
+// 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.
+
+// aux-build:coherence_lib.rs
+
+// pretty-expanded FIXME #23616
+
+// Test that the `Pair` type reports an error if it contains type
+// parameters, even when they are covered by local types. This test
+// was originally intended to test the opposite, but the rules changed
+// with RFC 1023 and this became illegal.
+
+extern crate coherence_lib as lib;
+use lib::{Remote,Pair};
+
+pub struct Cover<T>(T);
+
+impl<T> Remote for Pair<T,Cover<T>> { }
+//~^ ERROR E0210
+
+fn main() { }
diff --git a/src/test/compile-fail/coherence-cow-2.rs b/src/test/compile-fail/coherence-cow-2.rs
new file mode 100644 (file)
index 0000000..52abcea
--- /dev/null
@@ -0,0 +1,27 @@
+// 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.
+
+// aux-build:coherence_lib.rs
+
+// Test that the `Pair` type reports an error if it contains type
+// parameters, even when they are covered by local types. This test
+// was originally intended to test the opposite, but the rules changed
+// with RFC 1023 and this became illegal.
+
+// pretty-expanded FIXME #23616
+
+extern crate coherence_lib as lib;
+use lib::{Remote,Pair};
+
+pub struct Cover<T>(T);
+
+impl<T> Remote for Pair<Cover<T>,T> { } //~ ERROR E0210
+
+fn main() { }
index 1bec97de53386a4020f4ef071327b69a8a51f28a..cd32e797ae9bf0a8d237c6b067fc5a82ffd1ce2b 100644 (file)
@@ -8,16 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-// Test that it's not ok for U to appear uncovered
+// Test that it's not ok for T to appear uncovered
 
-extern crate "coherence-lib" as lib;
+extern crate coherence_lib as lib;
 use lib::{Remote,Pair};
 
 pub struct Cover<T>(T);
 
 impl<T,U> Remote for Pair<Cover<T>,U> { }
-//~^ ERROR type parameter `U` must be used as the type parameter for some local type
+//~^ ERROR type parameter `T` must be used as the type parameter for some local type
 
 fn main() { }
diff --git a/src/test/compile-fail/coherence-default-trait-impl.rs b/src/test/compile-fail/coherence-default-trait-impl.rs
new file mode 100644 (file)
index 0000000..a5b3173
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2015 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.
+
+// ignore-tidy-linelength
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::MarkerTrait;
+
+trait MyTrait: MarkerTrait {}
+
+impl MyTrait for .. {}
+
+impl MyTrait for .. {}
+//~^ ERROR conflicting implementations for trait `MyTrait`
+
+trait MySafeTrait: MarkerTrait {}
+
+unsafe impl MySafeTrait for .. {}
+//~^ ERROR implementing the trait `MySafeTrait` is not unsafe
+
+unsafe trait MyUnsafeTrait: MarkerTrait {}
+
+impl MyUnsafeTrait for .. {}
+//~^ ERROR the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
+
+fn main() {}
diff --git a/src/test/compile-fail/coherence-impls-builtin.rs b/src/test/compile-fail/coherence-impls-builtin.rs
deleted file mode 100644 (file)
index 38730d2..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2015 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(optin_builtin_traits)]
-
-use std::marker::Send;
-
-enum TestE {
-  A
-}
-
-struct MyType;
-
-struct NotSync;
-impl !Sync for NotSync {}
-
-unsafe impl Send for TestE {}
-unsafe impl Send for MyType {}
-unsafe impl Send for (MyType, MyType) {}
-//~^ ERROR builtin traits can only be implemented on structs or enums
-
-unsafe impl Send for &'static NotSync {}
-//~^ ERROR builtin traits can only be implemented on structs or enums
-
-unsafe impl Send for [MyType] {}
-//~^ ERROR builtin traits can only be implemented on structs or enums
-
-unsafe impl Send for &'static [NotSync] {}
-//~^ ERROR builtin traits can only be implemented on structs or enums
-
-fn is_send<T: Send>() {}
-
-fn main() {
-    is_send::<(MyType, TestE)>();
-}
diff --git a/src/test/compile-fail/coherence-impls-copy.rs b/src/test/compile-fail/coherence-impls-copy.rs
new file mode 100644 (file)
index 0000000..1be606c
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright 2015 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(optin_builtin_traits)]
+
+use std::marker::Copy;
+
+enum TestE {
+  A
+}
+
+struct MyType;
+
+struct NotSync;
+impl !Sync for NotSync {}
+
+impl Copy for TestE {}
+impl Clone for TestE { fn clone(&self) -> Self { *self } }
+
+impl Copy for MyType {}
+
+impl Copy for &'static mut MyType {}
+//~^ ERROR E0206
+//~| ERROR E0277
+//~| ERROR E0277
+impl Clone for MyType { fn clone(&self) -> Self { *self } }
+
+impl Copy for (MyType, MyType) {}
+//~^ ERROR E0206
+//~| ERROR E0117
+
+impl Copy for &'static NotSync {}
+//~^ ERROR E0206
+
+impl Copy for [MyType] {}
+//~^ ERROR E0206
+//~| ERROR E0117
+//~| ERROR E0277
+//~| ERROR E0277
+
+impl Copy for &'static [NotSync] {}
+//~^ ERROR E0206
+//~| ERROR E0117
+
+fn main() {
+}
diff --git a/src/test/compile-fail/coherence-impls-send.rs b/src/test/compile-fail/coherence-impls-send.rs
new file mode 100644 (file)
index 0000000..f130a93
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2015 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(optin_builtin_traits)]
+
+use std::marker::Copy;
+
+enum TestE {
+  A
+}
+
+struct MyType;
+
+struct NotSync;
+impl !Sync for NotSync {}
+
+unsafe impl Send for TestE {}
+unsafe impl Send for MyType {}
+unsafe impl Send for (MyType, MyType) {}
+//~^ ERROR E0117
+
+unsafe impl Send for &'static NotSync {}
+//~^ ERROR E0321
+
+unsafe impl Send for [MyType] {}
+//~^ ERROR E0117
+
+unsafe impl Send for &'static [NotSync] {}
+//~^ ERROR E0117
+//~| ERROR E0119
+
+fn main() {
+}
diff --git a/src/test/compile-fail/coherence-impls-sized.rs b/src/test/compile-fail/coherence-impls-sized.rs
new file mode 100644 (file)
index 0000000..2ac4bb0
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright 2015 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(optin_builtin_traits)]
+
+use std::marker::Copy;
+
+enum TestE {
+  A
+}
+
+struct MyType;
+
+struct NotSync;
+impl !Sync for NotSync {}
+
+impl Sized for TestE {} //~ ERROR E0322
+
+impl Sized for MyType {} //~ ERROR E0322
+
+impl Sized for (MyType, MyType) {} //~ ERROR E0117
+
+impl Sized for &'static NotSync {} //~ ERROR E0322
+
+impl Sized for [MyType] {} //~ ERROR E0117
+//~^ ERROR E0277
+
+impl Sized for &'static [NotSync] {} //~ ERROR E0117
+
+fn main() {
+}
index 9f7481f12f2f7d3201c3b0bcf629b8f34615194d..e78f392b386bbb0841a281e5e302ed2467b10ce7 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-extern crate "coherence-lib" as lib;
+extern crate coherence_lib as lib;
 use lib::Remote;
 
 impl<T> Remote for T { }
index d7cd68e73c3498acc75b0557ceca6224e450e455..2243a0507f2d14cc4a32d8f70cbaf5ed2d79d55e 100644 (file)
@@ -9,23 +9,25 @@
 // except according to those terms.
 
 // ignore-tidy-linelength
-// aux-build:coherence-orphan-lib.rs
+// aux-build:coherence_orphan_lib.rs
 
 #![feature(optin_builtin_traits)]
 
-extern crate "coherence-orphan-lib" as lib;
+extern crate coherence_orphan_lib as lib;
 
 use lib::TheTrait;
 
 struct TheType;
 
-impl TheTrait<usize> for isize { } //~ ERROR E0117
+impl TheTrait<usize> for isize { }
+//~^ ERROR E0117
 
 impl TheTrait<TheType> for isize { }
 
 impl TheTrait<isize> for TheType { }
 
-impl !Send for Vec<isize> { } //~ ERROR E0117
-//~^ ERROR conflicting
+impl !Send for Vec<isize> { }
+//~^ ERROR E0117
+//~| ERROR E0119
 
 fn main() { }
diff --git a/src/test/compile-fail/coherence-overlap-issue-23516.rs b/src/test/compile-fail/coherence-overlap-issue-23516.rs
new file mode 100644 (file)
index 0000000..d7f060a
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// Tests that we consider `Box<U>: !Sugar` to be ambiguous, even
+// though we see no impl of `Sugar` for `Box`. Therefore, an overlap
+// error is reported for the following pair of impls (#23516).
+
+pub trait Sugar { fn dummy(&self) { } }
+pub trait Sweet { fn dummy(&self) { } }
+impl<T:Sugar> Sweet for T { } //~ ERROR E0119
+impl<U:Sugar> Sweet for Box<U> { }
+fn main() { }
index 9878bdec2c36ffc56100fbffe72ad6c1716389f7..ba9dc53e8680f6d683591f3a4b45e2193501e205 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-extern crate "coherence-lib" as lib;
+extern crate coherence_lib as lib;
 use lib::Remote;
 
 struct Foo;
index 2bdcc346f70d3055193c616afa1324ece4c7f08e..f55efef14fade3b47adc5d4825f500310211f1a7 100644 (file)
@@ -11,9 +11,9 @@
 // Test that the same coverage rules apply even if the local type appears in the
 // list of type parameters, not the self type.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-extern crate "coherence-lib" as lib;
+extern crate coherence_lib as lib;
 use lib::{Remote1, Pair};
 
 pub struct Local<T>(T);
index 881494f009f1576784b3f10d345ffa88e94d83bb..0642dff4b28257baa2d9caf866fd3b28b0c2877e 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-extern crate "coherence-lib" as lib;
+extern crate coherence_lib as lib;
 use lib::{Remote, Pair};
 
 struct Local<T>(T);
index 9673fb6a21392dd3e619715beaa4c51b98fa31c2..87b007fdd698239d3af23c2558975c29ad994eb2 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::fmt::Show;
+use std::fmt::Debug;
 use std::default::Default;
 
 // Test that a blank impl for all T conflicts with an impl for some
diff --git a/src/test/compile-fail/coherence-vec-local-2.rs b/src/test/compile-fail/coherence-vec-local-2.rs
new file mode 100644 (file)
index 0000000..5f0b56a
--- /dev/null
@@ -0,0 +1,25 @@
+// 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 a local, generic type appearing within a
+// *non-fundamental* remote type like `Vec` is not considered local.
+
+// aux-build:coherence_lib.rs
+
+// pretty-expanded FIXME #23616
+
+extern crate coherence_lib as lib;
+use lib::Remote;
+
+struct Local<T>(T);
+
+impl<T> Remote for Vec<Local<T>> { } //~ ERROR E0210
+
+fn main() { }
diff --git a/src/test/compile-fail/coherence-vec-local.rs b/src/test/compile-fail/coherence-vec-local.rs
new file mode 100644 (file)
index 0000000..c354caa
--- /dev/null
@@ -0,0 +1,25 @@
+// 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 a local type (with no type parameters) appearing within a
+// *non-fundamental* remote type like `Vec` is not considered local.
+
+// aux-build:coherence_lib.rs
+
+// pretty-expanded FIXME #23616
+
+extern crate coherence_lib as lib;
+use lib::Remote;
+
+struct Local;
+
+impl Remote for Vec<Local> { } //~ ERROR E0117
+
+fn main() { }
diff --git a/src/test/compile-fail/coherence_copy_like_err_fundamental_struct.rs b/src/test/compile-fail/coherence_copy_like_err_fundamental_struct.rs
new file mode 100644 (file)
index 0000000..f13175c
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2015 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 we are able to introduce a negative constraint that
+// `MyType: !MyTrait` along with other "fundamental" wrappers.
+
+// aux-build:coherence_copy_like_lib.rs
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+extern crate coherence_copy_like_lib as lib;
+
+use std::marker::MarkerTrait;
+
+struct MyType { x: i32 }
+
+trait MyTrait : MarkerTrait { }
+impl<T: lib::MyCopy> MyTrait for T { }
+
+// `MyFundamentalStruct` is declared fundamental, so we can test that
+//
+//    MyFundamentalStruct<MyTrait>: !MyTrait
+//
+// Huzzah.
+impl MyTrait for lib::MyFundamentalStruct<MyType> { }
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/coherence_copy_like_err_fundamental_struct_ref.rs b/src/test/compile-fail/coherence_copy_like_err_fundamental_struct_ref.rs
new file mode 100644 (file)
index 0000000..ae3d242
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2015 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 we are able to introduce a negative constraint that
+// `MyType: !MyTrait` along with other "fundamental" wrappers.
+
+// aux-build:coherence_copy_like_lib.rs
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+extern crate coherence_copy_like_lib as lib;
+
+use std::marker::MarkerTrait;
+
+struct MyType { x: i32 }
+
+trait MyTrait : MarkerTrait { }
+impl<T: lib::MyCopy> MyTrait for T { }
+
+// `MyFundamentalStruct` is declared fundamental, so we can test that
+//
+//    MyFundamentalStruct<&MyTrait>: !MyTrait
+//
+// Huzzah.
+impl<'a> MyTrait for lib::MyFundamentalStruct<&'a MyType> { }
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/coherence_copy_like_err_fundamental_struct_tuple.rs b/src/test/compile-fail/coherence_copy_like_err_fundamental_struct_tuple.rs
new file mode 100644 (file)
index 0000000..c4e95e7
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2015 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 we are able to introduce a negative constraint that
+// `MyType: !MyTrait` along with other "fundamental" wrappers.
+
+// aux-build:coherence_copy_like_lib.rs
+
+#![feature(rustc_attrs)]
+
+extern crate coherence_copy_like_lib as lib;
+
+use std::marker::MarkerTrait;
+
+struct MyType { x: i32 }
+
+trait MyTrait : MarkerTrait { }
+
+impl<T: lib::MyCopy> MyTrait for T { } //~ ERROR E0119
+
+// Tuples are not fundamental.
+impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { }
+
+#[rustc_error]
+fn main() { }
diff --git a/src/test/compile-fail/coherence_copy_like_err_struct.rs b/src/test/compile-fail/coherence_copy_like_err_struct.rs
new file mode 100644 (file)
index 0000000..f768a47
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2015 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.
+
+// aux-build:coherence_copy_like_lib.rs
+
+// Test that we are able to introduce a negative constraint that
+// `MyType: !MyTrait` along with other "fundamental" wrappers.
+
+extern crate coherence_copy_like_lib as lib;
+
+use std::marker::MarkerTrait;
+
+struct MyType { x: i32 }
+
+trait MyTrait : MarkerTrait { }
+impl<T: lib::MyCopy> MyTrait for T { } //~ ERROR E0119
+
+// `MyStruct` is not declared fundamental, therefore this would
+// require that
+//
+//     MyStruct<MyType>: !MyTrait
+//
+// which we cannot approve.
+impl MyTrait for lib::MyStruct<MyType> { }
+
+fn main() { }
diff --git a/src/test/compile-fail/coherence_copy_like_err_tuple.rs b/src/test/compile-fail/coherence_copy_like_err_tuple.rs
new file mode 100644 (file)
index 0000000..0c78fff
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2015 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 we are able to introduce a negative constraint that
+// `MyType: !MyTrait` along with other "fundamental" wrappers.
+
+// aux-build:coherence_copy_like_lib.rs
+
+extern crate coherence_copy_like_lib as lib;
+
+use std::marker::MarkerTrait;
+
+struct MyType { x: i32 }
+
+trait MyTrait : MarkerTrait { }
+impl<T: lib::MyCopy> MyTrait for T { } //~ ERROR E0119
+
+// Tuples are not fundamental, therefore this would require that
+//
+//     (MyType,): !MyTrait
+//
+// which we cannot approve.
+impl MyTrait for (MyType,) { }
+
+fn main() { }
diff --git a/src/test/compile-fail/coherence_local.rs b/src/test/compile-fail/coherence_local.rs
new file mode 100644 (file)
index 0000000..551577b
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2015 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 we are able to introduce a negative constraint that
+// `MyType: !MyTrait` along with other "fundamental" wrappers.
+
+// aux-build:coherence_copy_like_lib.rs
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+extern crate coherence_copy_like_lib as lib;
+
+struct MyType { x: i32 }
+
+// These are all legal because they are all fundamental types:
+
+impl lib::MyCopy for MyType { }
+impl<'a> lib::MyCopy for &'a MyType { }
+impl<'a> lib::MyCopy for &'a Box<MyType> { }
+impl lib::MyCopy for Box<MyType> { }
+impl lib::MyCopy for lib::MyFundamentalStruct<MyType> { }
+impl lib::MyCopy for lib::MyFundamentalStruct<Box<MyType>> { }
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/coherence_local_err_struct.rs b/src/test/compile-fail/coherence_local_err_struct.rs
new file mode 100644 (file)
index 0000000..01f4c1c
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2015 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 we are able to introduce a negative constraint that
+// `MyType: !MyTrait` along with other "fundamental" wrappers.
+
+// aux-build:coherence_copy_like_lib.rs
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+extern crate coherence_copy_like_lib as lib;
+
+struct MyType { x: i32 }
+
+// These are all legal because they are all fundamental types:
+
+// MyStruct is not fundamental.
+impl lib::MyCopy for lib::MyStruct<MyType> { } //~ ERROR E0117
+
+#[rustc_error]
+fn main() { }
diff --git a/src/test/compile-fail/coherence_local_err_tuple.rs b/src/test/compile-fail/coherence_local_err_tuple.rs
new file mode 100644 (file)
index 0000000..590f68c
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2015 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 we are able to introduce a negative constraint that
+// `MyType: !MyTrait` along with other "fundamental" wrappers.
+
+// aux-build:coherence_copy_like_lib.rs
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+extern crate coherence_copy_like_lib as lib;
+
+struct MyType { x: i32 }
+
+// These are all legal because they are all fundamental types:
+
+// Tuples are not fundamental, so this is not a local impl.
+impl lib::MyCopy for (MyType,) { } //~ ERROR E0117
+
+#[rustc_error]
+fn main() { }
diff --git a/src/test/compile-fail/coherence_local_ref.rs b/src/test/compile-fail/coherence_local_ref.rs
new file mode 100644 (file)
index 0000000..f6e1aab
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2015 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 we are able to introduce a negative constraint that
+// `MyType: !MyTrait` along with other "fundamental" wrappers.
+
+// aux-build:coherence_copy_like_lib.rs
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+extern crate coherence_copy_like_lib as lib;
+
+struct MyType { x: i32 }
+
+// naturally, legal
+impl lib::MyCopy for MyType { }
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/const-array-oob.rs b/src/test/compile-fail/const-array-oob.rs
new file mode 100644 (file)
index 0000000..84d3529
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 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.
+
+const FOO: [u32; 3] = [1, 2, 3];
+const BAR: u32 = FOO[5]; //~ ERROR const index-expr is out of bounds
+
+fn main() {
+    let _ = BAR;
+}
index fa63b16afa6d0835e459e555b3d325efc12d36f8..5ccfb1ddec78adb5d3403a409a001a766942856e 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const A: usize = { 1_usize; 2 };
+const A: usize = { 1; 2 };
 //~^ ERROR: blocks in constants are limited to items and tail expressions
 
 const B: usize = { { } 2 };
@@ -19,7 +19,7 @@ macro_rules! foo {
 }
 const C: usize = { foo!(); 2 };
 
-const D: usize = { let x = 4_usize; 2 };
+const D: usize = { let x = 4; 2 };
 //~^ ERROR: blocks in constants are limited to items and tail expressions
 
 pub fn main() {
diff --git a/src/test/compile-fail/const-eval-overflow-2.rs b/src/test/compile-fail/const-eval-overflow-2.rs
new file mode 100644 (file)
index 0000000..be04bc9
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2015 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.
+
+// Evaluation of constants in refutable patterns goes through
+// different compiler control-flow paths.
+
+#![allow(unused_imports)]
+
+use std::fmt;
+use std::{i8, i16, i32, i64, isize};
+use std::{u8, u16, u32, u64, usize};
+
+const NEG_128: i8 = -128;
+const NEG_NEG_128: i8 = -NEG_128;
+//~^ ERROR constant evaluation error: attempted to negate with overflow
+//~| ERROR attempted to negate with overflow
+
+fn main() {
+    match -128i8 {
+        NEG_NEG_128 => println!("A"),
+        _ => println!("B"),
+    }
+}
diff --git a/src/test/compile-fail/const-eval-overflow-3.rs b/src/test/compile-fail/const-eval-overflow-3.rs
new file mode 100644 (file)
index 0000000..c2bc5b2
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2015 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.
+
+// Evaluation of constants in array-elem count goes through different
+// compiler control-flow paths.
+//
+// This test is checking the count in an array expression.
+
+// FIXME (#23926): the error output is not consistent between a
+// self-hosted and a cross-compiled setup; therefore resorting to
+// error-pattern for now.
+
+// error-pattern: expected constant integer for repeat count, but attempted to add with overflow
+
+#![allow(unused_imports)]
+
+use std::fmt;
+use std::{i8, i16, i32, i64, isize};
+use std::{u8, u16, u32, u64, usize};
+
+const A_I8_I
+    : [u32; (i8::MAX as usize) + 1]
+    = [0; (i8::MAX + 1) as usize];
+
+fn main() {
+    foo(&A_I8_I[..]);
+}
+
+fn foo<T:fmt::Debug>(x: T) {
+    println!("{:?}", x);
+}
+
diff --git a/src/test/compile-fail/const-eval-overflow-3b.rs b/src/test/compile-fail/const-eval-overflow-3b.rs
new file mode 100644 (file)
index 0000000..719b210
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2015 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.
+
+// Evaluation of constants in array-elem count goes through different
+// compiler control-flow paths.
+//
+// This test is checking the count in an array expression.
+//
+// This is a variation of another such test, but in this case the
+// types for the left- and right-hand sides of the addition do not
+// match (as well as overflow).
+
+// FIXME (#23926): the error output is not consistent between a
+// self-hosted and a cross-compiled setup; therefore resorting to
+// error-pattern for now.
+
+// error-pattern: mismatched types
+
+#![allow(unused_imports)]
+
+use std::fmt;
+use std::{i8, i16, i32, i64, isize};
+use std::{u8, u16, u32, u64, usize};
+
+const A_I8_I
+    : [u32; (i8::MAX as usize) + 1]
+    = [0; (i8::MAX + 1u8) as usize];
+
+fn main() {
+    foo(&A_I8_I[..]);
+}
+
+fn foo<T:fmt::Debug>(x: T) {
+    println!("{:?}", x);
+}
+
diff --git a/src/test/compile-fail/const-eval-overflow-4.rs b/src/test/compile-fail/const-eval-overflow-4.rs
new file mode 100644 (file)
index 0000000..f1f125a
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2015 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.
+
+// ignore-test this should fail to compile (#23833)
+
+// Evaluation of constants in array-elem count goes through different
+// compiler control-flow paths.
+//
+// This test is checking the count in an array type.
+
+#![allow(unused_imports)]
+
+use std::fmt;
+use std::{i8, i16, i32, i64, isize};
+use std::{u8, u16, u32, u64, usize};
+
+const A_I8_T
+    : [u32; (i8::MAX as i8 + 1i8) as usize]
+    //~^ ERROR error evaluating count: attempted to add with overflow
+    = [0; (i8::MAX as usize) + 1];
+
+fn main() {
+    foo(&A_I8_T[..]);
+}
+
+fn foo<T:fmt::Debug>(x: T) {
+    println!("{:?}", x);
+}
+
diff --git a/src/test/compile-fail/const-eval-overflow-4b.rs b/src/test/compile-fail/const-eval-overflow-4b.rs
new file mode 100644 (file)
index 0000000..6322b56
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2015 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.
+
+// Evaluation of constants in array-elem count goes through different
+// compiler control-flow paths.
+//
+// This test is checking the count in an array type.
+
+#![allow(unused_imports)]
+
+use std::fmt;
+use std::{i8, i16, i32, i64, isize};
+use std::{u8, u16, u32, u64, usize};
+
+const A_I8_T
+    : [u32; (i8::MAX as i8 + 1u8) as usize]
+    //~^ ERROR mismatched types
+    //~| the trait `core::ops::Add<u8>` is not implemented for the type `i8`
+    //~| the trait `core::ops::Add<u8>` is not implemented for the type `i8`
+    = [0; (i8::MAX as usize) + 1];
+
+fn main() {
+    foo(&A_I8_T[..]);
+}
+
+fn foo<T:fmt::Debug>(x: T) {
+    println!("{:?}", x);
+}
+
diff --git a/src/test/compile-fail/const-eval-overflow.rs b/src/test/compile-fail/const-eval-overflow.rs
new file mode 100644 (file)
index 0000000..19b5f9b
--- /dev/null
@@ -0,0 +1,132 @@
+// Copyright 2015 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(negate_unsigned)]
+
+#![allow(unused_imports)]
+#![feature(negate_unsigned)]
+
+// Note: the relevant lint pass here runs before some of the constant
+// evaluation below (e.g. that performed by trans and llvm), so if you
+// change this warn to a deny, then the compiler will exit before
+// those errors are detected.
+#![warn(unsigned_negation)]
+
+use std::fmt;
+use std::{i8, i16, i32, i64, isize};
+use std::{u8, u16, u32, u64, usize};
+
+const VALS_I8: (i8, i8, i8, i8) =
+    (-i8::MIN,
+     //~^ ERROR attempted to negate with overflow
+     i8::MIN - 1,
+     //~^ ERROR attempted to sub with overflow
+     i8::MAX + 1,
+     //~^ ERROR attempted to add with overflow
+     i8::MIN * 2,
+     //~^ ERROR attempted to mul with overflow
+     );
+
+const VALS_I16: (i16, i16, i16, i16) =
+    (-i16::MIN,
+     //~^ ERROR attempted to negate with overflow
+     i16::MIN - 1,
+     //~^ ERROR attempted to sub with overflow
+     i16::MAX + 1,
+     //~^ ERROR attempted to add with overflow
+     i16::MIN * 2,
+     //~^ ERROR attempted to mul with overflow
+     );
+
+const VALS_I32: (i32, i32, i32, i32) =
+    (-i32::MIN,
+     //~^ ERROR attempted to negate with overflow
+     i32::MIN - 1,
+     //~^ ERROR attempted to sub with overflow
+     i32::MAX + 1,
+     //~^ ERROR attempted to add with overflow
+     i32::MIN * 2,
+     //~^ ERROR attempted to mul with overflow
+     );
+
+const VALS_I64: (i64, i64, i64, i64) =
+    (-i64::MIN,
+     //~^ ERROR attempted to negate with overflow
+     i64::MIN - 1,
+     //~^ ERROR attempted to sub with overflow
+     i64::MAX + 1,
+     //~^ ERROR attempted to add with overflow
+     i64::MAX * 2,
+     //~^ ERROR attempted to mul with overflow
+     );
+
+const VALS_U8: (u8, u8, u8, u8) =
+    (-u8::MIN,
+     //~^ WARNING negation of unsigned int variable may be unintentional
+     // (The above is separately linted; unsigned negation is defined to be !x+1.)
+     u8::MIN - 1,
+     //~^ ERROR attempted to sub with overflow
+     u8::MAX + 1,
+     //~^ ERROR attempted to add with overflow
+     u8::MAX * 2,
+     //~^ ERROR attempted to mul with overflow
+     );
+
+const VALS_U16: (u16, u16, u16, u16) =
+    (-u16::MIN,
+     //~^ WARNING negation of unsigned int variable may be unintentional
+     // (The above is separately linted; unsigned negation is defined to be !x+1.)
+     u16::MIN - 1,
+     //~^ ERROR attempted to sub with overflow
+     u16::MAX + 1,
+     //~^ ERROR attempted to add with overflow
+     u16::MAX * 2,
+     //~^ ERROR attempted to mul with overflow
+     );
+
+const VALS_U32: (u32, u32, u32, u32) =
+    (-u32::MIN,
+     //~^ WARNING negation of unsigned int variable may be unintentional
+     // (The above is separately linted; unsigned negation is defined to be !x+1.)
+     u32::MIN - 1,
+     //~^ ERROR attempted to sub with overflow
+     u32::MAX + 1,
+     //~^ ERROR attempted to add with overflow
+     u32::MAX * 2,
+     //~^ ERROR attempted to mul with overflow
+     );
+
+const VALS_U64: (u64, u64, u64, u64) =
+    (-u64::MIN,
+     //~^ WARNING negation of unsigned int variable may be unintentional
+     // (The above is separately linted; unsigned negation is defined to be !x+1.)
+     u64::MIN - 1,
+     //~^ ERROR attempted to sub with overflow
+     u64::MAX + 1,
+     //~^ ERROR attempted to add with overflow
+     u64::MAX * 2,
+     //~^ ERROR attempted to mul with overflow
+     );
+
+fn main() {
+    foo(VALS_I8);
+    foo(VALS_I16);
+    foo(VALS_I32);
+    foo(VALS_I64);
+
+    foo(VALS_U8);
+    foo(VALS_U16);
+    foo(VALS_U32);
+    foo(VALS_U64);
+}
+
+fn foo<T:fmt::Debug>(x: T) {
+    println!("{:?}", x);
+}
diff --git a/src/test/compile-fail/const-len-underflow-separate-spans.rs b/src/test/compile-fail/const-len-underflow-separate-spans.rs
new file mode 100644 (file)
index 0000000..cd021a0
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2012-2013 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 that an constant-evaluation underflow highlights the correct
+// spot (where the underflow occurred), while also providing the
+// overall context for what caused the evaluation.
+
+const ONE: usize = 1;
+const TWO: usize = 2;
+const LEN: usize = ONE - TWO;
+//~^ ERROR array length constant evaluation error: attempted to sub with overflow [E0250]
+
+fn main() {
+    let a: [i8; LEN] = unimplemented!();
+    //~^ NOTE for array length here
+}
diff --git a/src/test/compile-fail/const-len-underflow-subspans.rs b/src/test/compile-fail/const-len-underflow-subspans.rs
new file mode 100644 (file)
index 0000000..a31da11
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2012-2013 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 that an constant-evaluation underflow highlights the correct
+// spot (where the underflow occurred).
+
+const ONE: usize = 1;
+const TWO: usize = 2;
+
+fn main() {
+    let a: [i8; ONE - TWO] = unimplemented!();
+    //~^ ERROR array length constant evaluation error: attempted to sub with overflow [E0250]
+}
index 6bd21101a609df402b94dd01bb93a5a36892a5d7..d60fb1d5d19669651b8ab45804a84efcd1196f56 100644 (file)
 // Test that cross-borrowing (implicitly converting from `Box<T>` to `&T`) is
 // forbidden when `T` is a trait.
 
-#![feature(box_syntax)]
-
 struct Foo;
 trait Trait { fn foo(&self) {} }
 impl Trait for Foo {}
 
 pub fn main() {
-    let x: Box<Trait> = box Foo;
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let x: Box<Trait> = Box::new(Foo);
     let _y: &Trait = x; //~  ERROR mismatched types
                         //~| expected `&Trait`
                         //~| found `Box<Trait>`
                         //~| expected &-ptr
                         //~| found box
 }
-
index 193063a98cb0057865629edcdfd7d8268b46367a..4e089a4e59c427e41e66f2886997531de8e47119 100644 (file)
@@ -11,4 +11,4 @@
 #[foo] //~ ERROR The attribute `foo`
 fn main() {
 
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/cycle-projection-based-on-where-clause.rs b/src/test/compile-fail/cycle-projection-based-on-where-clause.rs
new file mode 100644 (file)
index 0000000..5ca0700
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2015 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.
+
+// Example cycle where a bound on `T` uses a shorthand for `T`. This
+// creates a cycle because we have to know the bounds on `T` to figure
+// out what trait defines `Item`, but we can't know the bounds on `T`
+// without knowing how to handle `T::Item`.
+//
+// Note that in the future cases like this could perhaps become legal,
+// if we got more fine-grained about our cycle detection or changed
+// how we handle `T::Item` resolution.
+
+use std::ops::Add;
+
+// Preamble.
+trait Trait { type Item; }
+
+struct A<T>
+    where T : Trait,
+          T : Add<T::Item>
+    //~^ ERROR unsupported cyclic reference between types/traits detected
+{
+    data: T
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/cycle-trait-default-type-trait.rs b/src/test/compile-fail/cycle-trait-default-type-trait.rs
new file mode 100644 (file)
index 0000000..e6caeb3
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2015 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 a cycle where a type parameter on a trait has a default that
+// again references the trait.
+
+trait Foo<X = Box<Foo>> {
+    //~^ ERROR unsupported cyclic reference
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/cycle-trait-supertrait-direct.rs b/src/test/compile-fail/cycle-trait-supertrait-direct.rs
new file mode 100644 (file)
index 0000000..ef3fead
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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 a supertrait cycle where a trait extends itself.
+
+trait Chromosome: Chromosome {
+    //~^ ERROR unsupported cyclic reference
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/cycle-trait-supertrait-indirect.rs b/src/test/compile-fail/cycle-trait-supertrait-indirect.rs
new file mode 100644 (file)
index 0000000..c9bfde3
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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 a supertrait cycle where the first trait we find (`A`) is not
+// a direct participant in the cycle.
+
+trait A: B {
+    //~^ ERROR unsupported cyclic reference
+}
+
+trait B: C {
+    //~^ ERROR unsupported cyclic reference
+}
+
+trait C: B { }
+    //~^ ERROR unsupported cyclic reference
+
+fn main() { }
diff --git a/src/test/compile-fail/deprecated-phase.rs b/src/test/compile-fail/deprecated-phase.rs
deleted file mode 100644 (file)
index 1401494..0000000
+++ /dev/null
@@ -1,15 +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.
-
-#[phase(blah)]
-//~^ ERROR #[phase] is deprecated
-extern crate foo;
-
-fn main() {}
diff --git a/src/test/compile-fail/derive-assoc-type-not-impl.rs b/src/test/compile-fail/derive-assoc-type-not-impl.rs
new file mode 100644 (file)
index 0000000..3799f2f
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2015 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 {
+    type X;
+    fn method(&self) {}
+}
+
+#[derive(Clone)]
+struct Bar<T: Foo> {
+    x: T::X,
+}
+
+struct NotClone;
+
+impl Foo for NotClone {
+    type X = i8;
+}
+
+fn main() {
+    Bar::<NotClone> { x: 1 }.clone(); //~ ERROR
+}
index f82e7f3e36a8ac7bbd7cce6b52606ddff2b5c19b..d0cb4f23a8c2844a27094dd0a19db8393d5b0b86 100644 (file)
@@ -13,7 +13,7 @@
 
 extern crate core;
 extern crate rand;
-extern crate "serialize" as rustc_serialize;
+extern crate serialize as rustc_serialize;
 
 #[derive(Rand)]  //~ ERROR this trait cannot be derived
 //~^ WARNING `#[derive(Rand)]` is deprecated
index c0bcbb284a15e961093cc1bb9021f5b8cc6390f0..72d06274de471af216a2a87f4c33d45f6720eb4e 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy(Bad))]
-//~^ ERROR unexpected value in deriving, expected a trait
+#[derive(Send)]
+//~^ ERROR this unsafe trait should be implemented explicitly
 struct Test;
 
 #[derive(Sync)]
-//~^ ERROR Sync is an unsafe trait and it should be implemented explicitly
+//~^ ERROR this unsafe trait should be implemented explicitly
 struct Test1;
 
 pub fn main() {}
diff --git a/src/test/compile-fail/deriving-is-deprecated.rs b/src/test/compile-fail/deriving-is-deprecated.rs
deleted file mode 100644 (file)
index 060e178..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2015 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.
-
-
-#[deriving(Clone)] //~ ERROR `deriving` has been renamed to `derive`
-struct Foo;
-
-fn main() {}
index 6b85656bdd9e63e1561ecc2287b654f6560083cd..e223499469355c30b0e92c719e200257c15bf99c 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Eqr)] //~ ERROR unknown `derive` trait: `Eqr`
+#[derive(Eqr)]
+//~^ ERROR `#[derive]` for custom traits is not stable enough for use and is subject to change
 struct Foo;
 
 pub fn main() {}
index 966e28a789cc88e7a99fba06719c2a34c33b9017..5b215f3ccd9618f1b76ea1f0b51b59622294564f 100644 (file)
@@ -22,10 +22,10 @@ impl S { }
 impl T for S { }
 
 #[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
-static s: usize = 0_usize;
+static s: usize = 0;
 
 #[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
-const c: usize = 0_usize;
+const c: usize = 0;
 
 #[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
 mod m { }
index 0836cd1695de38e62625eca6a46143a950d20949..22f615cafd71eec06ce67f396d45542e0e1eb466 100644 (file)
@@ -14,8 +14,8 @@ use std::cell::RefCell;
 
 fn main() {
     let b = {
-        let a = Box::new(RefCell::new(4i8));
-        *a.borrow() + 1i8    //~ ERROR `*a` does not live long enough
+        let a = Box::new(RefCell::new(4));
+        *a.borrow() + 1    //~ ERROR `*a` does not live long enough
     };
     println!("{}", b);
 }
diff --git a/src/test/compile-fail/discrim-ill-typed.rs b/src/test/compile-fail/discrim-ill-typed.rs
new file mode 100644 (file)
index 0000000..23106c9
--- /dev/null
@@ -0,0 +1,118 @@
+// Copyright 2015 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.
+
+// When explicit discriminant value has
+// a type that does not match the representation
+// type, rustc should fail gracefully.
+
+// See also run-pass/discrim-explicit-23030.rs where the input types
+// are correct.
+
+#![allow(dead_code, unused_variables, unused_imports)]
+
+use std::{i8,u8,i16,u16,i32,u32,i64, u64};
+
+fn f_i8() {
+    #[repr(i8)]
+    enum A {
+        Ok = i8::MAX - 1,
+        Ok2,
+        OhNo = 0_u8,
+        //~^ ERROR mismatched types
+    }
+
+    let x = A::Ok;
+}
+
+fn f_u8() {
+    #[repr(u8)]
+    enum A {
+        Ok = u8::MAX - 1,
+        Ok2,
+        OhNo = 0_i8,
+        //~^  ERROR mismatched types
+    }
+
+    let x = A::Ok;
+}
+
+fn f_i16() {
+    #[repr(i16)]
+    enum A {
+        Ok = i16::MAX - 1,
+        Ok2,
+        OhNo = 0_u16,
+        //~^ ERROR mismatched types
+    }
+
+    let x = A::Ok;
+}
+
+fn f_u16() {
+    #[repr(u16)]
+    enum A {
+        Ok = u16::MAX - 1,
+        Ok2,
+        OhNo = 0_i16,
+        //~^ ERROR mismatched types
+    }
+
+    let x = A::Ok;
+}
+
+fn f_i32() {
+    #[repr(i32)]
+    enum A {
+        Ok = i32::MAX - 1,
+        Ok2,
+        OhNo = 0_u32,
+        //~^ ERROR mismatched types
+    }
+
+    let x = A::Ok;
+}
+
+fn f_u32() {
+    #[repr(u32)]
+    enum A {
+        Ok = u32::MAX - 1,
+        Ok2,
+        OhNo = 0_i32,
+        //~^ ERROR mismatched types
+    }
+
+    let x = A::Ok;
+}
+
+fn f_i64() {
+    #[repr(i64)]
+    enum A {
+        Ok = i64::MAX - 1,
+        Ok2,
+        OhNo = 0_u64,
+        //~^ ERROR mismatched types
+    }
+
+    let x = A::Ok;
+}
+
+fn f_u64() {
+    #[repr(u64)]
+    enum A {
+        Ok = u64::MAX - 1,
+        Ok2,
+        OhNo = 0_i64,
+        //~^ ERROR mismatched types
+    }
+
+    let x = A::Ok;
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/discrim-overflow-2.rs b/src/test/compile-fail/discrim-overflow-2.rs
new file mode 100644 (file)
index 0000000..76378d5
--- /dev/null
@@ -0,0 +1,94 @@
+// Copyright 2015 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.
+
+// ignore-tidy-linelength
+
+// Issue 23030: Detect overflowing discriminant
+//
+// Check that we detect the overflow even if enum is not used.
+
+// See also run-pass/discrim-explicit-23030.rs where the suggested
+// workaround is tested.
+
+use std::{i8,u8,i16,u16,i32,u32,i64, u64};
+
+fn f_i8() {
+    #[repr(i8)]
+    enum A {
+        Ok = i8::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed on value after 127: i8; set explicitly via OhNo = -128 if that is desired outcome
+    }
+}
+
+fn f_u8() {
+    #[repr(u8)]
+    enum A {
+        Ok = u8::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed on value after 255: u8; set explicitly via OhNo = 0 if that is desired outcome
+    }
+}
+
+fn f_i16() {
+    #[repr(i16)]
+    enum A {
+        Ok = i16::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed
+    }
+}
+
+fn f_u16() {
+    #[repr(u16)]
+    enum A {
+        Ok = u16::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed
+    }
+}
+
+fn f_i32() {
+    #[repr(i32)]
+    enum A {
+        Ok = i32::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed
+    }
+}
+
+fn f_u32() {
+    #[repr(u32)]
+    enum A {
+        Ok = u32::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed
+    }
+}
+
+fn f_i64() {
+    #[repr(i64)]
+    enum A {
+        Ok = i64::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed
+    }
+}
+
+fn f_u64() {
+    #[repr(u64)]
+    enum A {
+        Ok = u64::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed
+    }
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/discrim-overflow.rs b/src/test/compile-fail/discrim-overflow.rs
new file mode 100644 (file)
index 0000000..5d7e61e
--- /dev/null
@@ -0,0 +1,108 @@
+// Copyright 2015 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.
+
+// ignore-tidy-linelength
+
+// Issue 23030: Detect overflowing discriminant
+
+// See also run-pass/discrim-explicit-23030.rs where the suggested
+// workaround is tested.
+
+use std::{i8,u8,i16,u16,i32,u32,i64, u64};
+
+fn f_i8() {
+    #[repr(i8)]
+    enum A {
+        Ok = i8::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed on value after 127: i8; set explicitly via OhNo = -128 if that is desired outcome
+    }
+
+    let x = A::Ok;
+}
+
+fn f_u8() {
+    #[repr(u8)]
+    enum A {
+        Ok = u8::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed on value after 255: u8; set explicitly via OhNo = 0 if that is desired outcome
+    }
+
+    let x = A::Ok;
+}
+
+fn f_i16() {
+    #[repr(i16)]
+    enum A {
+        Ok = i16::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed
+    }
+
+    let x = A::Ok;
+}
+
+fn f_u16() {
+    #[repr(u16)]
+    enum A {
+        Ok = u16::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed
+    }
+
+    let x = A::Ok;
+}
+
+fn f_i32() {
+    #[repr(i32)]
+    enum A {
+        Ok = i32::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed
+    }
+
+    let x = A::Ok;
+}
+
+fn f_u32() {
+    #[repr(u32)]
+    enum A {
+        Ok = u32::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed
+    }
+
+    let x = A::Ok;
+}
+
+fn f_i64() {
+    #[repr(i64)]
+    enum A {
+        Ok = i64::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed
+    }
+
+    let x = A::Ok;
+}
+
+fn f_u64() {
+    #[repr(u64)]
+    enum A {
+        Ok = u64::MAX - 1,
+        Ok2,
+        OhNo, //~ ERROR enum discriminant overflowed
+    }
+
+    let x = A::Ok;
+}
+
+fn main() { }
index dc8deb04833450805bdddf11366ba557a6c76e16..903365fb909f5d7de2741785336c79a3ed2acd40 100644 (file)
@@ -16,4 +16,3 @@ fn main() {
         println!("{}", *s);
     }
 }
-
index 3aa2fae282693fd3b42bdfe69ae64e7012c6f11a..40d992fe21f207abe22984110f44735c61fcced7 100644 (file)
@@ -20,9 +20,9 @@ use id::Id;
 
 mod s {
     #![allow(unstable)]
-    use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
+    use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 
-    static S_COUNT: AtomicUint = ATOMIC_UINT_INIT;
+    static S_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
 
     pub fn next_count() -> usize {
         S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
diff --git a/src/test/compile-fail/dropck_no_diverge_on_nonregular_1.rs b/src/test/compile-fail/dropck_no_diverge_on_nonregular_1.rs
new file mode 100644 (file)
index 0000000..f096885
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2015 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.
+
+// Issue 22443: Reject code using non-regular types that would
+// otherwise cause dropck to loop infinitely.
+
+use std::marker::PhantomData;
+
+struct Digit<T> {
+    elem: T
+}
+
+struct Node<T:'static> { m: PhantomData<&'static T> }
+
+
+enum FingerTree<T:'static> {
+    Single(T),
+    // Bug report said Digit after Box would stack overflow (versus
+    // Digit before Box; see dropck_no_diverge_on_nonregular_2).
+    Deep(
+        Box<FingerTree<Node<T>>>,
+        Digit<T>,
+        )
+}
+
+fn main() {
+    let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
+        FingerTree::Single(1);
+    //~^ ERROR overflow while adding drop-check rules for FingerTree
+}
diff --git a/src/test/compile-fail/dropck_no_diverge_on_nonregular_2.rs b/src/test/compile-fail/dropck_no_diverge_on_nonregular_2.rs
new file mode 100644 (file)
index 0000000..886bd6b
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2015 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.
+
+// Issue 22443: Reject code using non-regular types that would
+// otherwise cause dropck to loop infinitely.
+
+use std::marker::PhantomData;
+
+struct Digit<T> {
+    elem: T
+}
+
+struct Node<T:'static> { m: PhantomData<&'static T> }
+
+enum FingerTree<T:'static> {
+    Single(T),
+    // Bug report said Digit before Box would infinite loop (versus
+    // Digit after Box; see dropck_no_diverge_on_nonregular_1).
+    Deep(
+        Digit<T>,
+        Box<FingerTree<Node<T>>>,
+        )
+}
+
+fn main() {
+    let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
+        FingerTree::Single(1);
+    //~^ ERROR overflow while adding drop-check rules for FingerTree
+}
diff --git a/src/test/compile-fail/dropck_no_diverge_on_nonregular_3.rs b/src/test/compile-fail/dropck_no_diverge_on_nonregular_3.rs
new file mode 100644 (file)
index 0000000..f7eb6e1
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+// Issue 22443: Reject code using non-regular types that would
+// otherwise cause dropck to loop infinitely.
+//
+// This version is just checking that we still sanely handle a trivial
+// wrapper around the non-regular type. (It also demonstrates how the
+// error messages will report different types depending on which type
+// dropck is analyzing.)
+
+use std::marker::PhantomData;
+
+struct Digit<T> {
+    elem: T
+}
+
+struct Node<T:'static> { m: PhantomData<&'static T> }
+
+enum FingerTree<T:'static> {
+    Single(T),
+    // According to the bug report, Digit before Box would infinite loop.
+    Deep(
+        Digit<T>,
+        Box<FingerTree<Node<T>>>,
+        )
+}
+
+enum Wrapper<T:'static> {
+    Simple,
+    Other(FingerTree<T>),
+}
+
+fn main() {
+    let w = //~ ERROR overflow while adding drop-check rules for core::option
+        Some(Wrapper::Simple::<u32>);
+    //~^ ERROR overflow while adding drop-check rules for core::option::Option
+    //~| ERROR overflow while adding drop-check rules for Wrapper
+}
index 74e3c724b676daa75bec403ad02e31762476faed..9488882ca94a51421a5bf04d89d7ab0d5eb35df6 100644 (file)
@@ -27,9 +27,9 @@ use id::Id;
 
 mod s {
     #![allow(unstable)]
-    use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
+    use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 
-    static S_COUNT: AtomicUint = ATOMIC_UINT_INIT;
+    static S_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
 
     pub fn next_count() -> usize {
         S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
index 3f69c7d1a9c3ee1755f3bb3682fcf9b5be7ba572..9d92552244f28e651f83b1d03a639f68ce11cd32 100644 (file)
@@ -19,9 +19,9 @@ use id::Id;
 
 mod s {
     #![allow(unstable)]
-    use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
+    use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 
-    static S_COUNT: AtomicUint = ATOMIC_UINT_INIT;
+    static S_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
 
     pub fn next_count() -> usize {
         S_COUNT.fetch_add(1, Ordering::SeqCst) + 1
index 7dbb8fc92e345bd3021f2485628f9dcd7ab332a1..8441f3a99e1aa6b3430191b4672c1303de85d3c4 100644 (file)
@@ -10,8 +10,6 @@
 
 // Forbid assignment into a dynamically sized type.
 
-#![feature(box_syntax)]
-
 struct Fat<T: ?Sized> {
     f1: isize,
     f2: &'static str,
@@ -43,7 +41,8 @@ impl ToBar for Bar1 {
 pub fn main() {
     // Assignment.
     let f5: &mut Fat<ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} };
-    let z: Box<ToBar> = box Bar1 {f: 36};
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let z: Box<ToBar> = Box::new(Bar1 {f: 36});
     f5.ptr = *z;
     //~^ ERROR the trait `core::marker::Sized` is not implemented
 }
index 152864b601c20818da6b5f6a8eff691d58a97305..d3029bc6a99801a785754a1a9b8ac6bf92e05ec0 100644 (file)
@@ -10,8 +10,6 @@
 
 // Forbid assignment into a dynamically sized type.
 
-#![feature(box_syntax)]
-
 struct Fat<T: ?Sized> {
     f1: isize,
     f2: &'static str,
@@ -43,7 +41,8 @@ impl ToBar for Bar1 {
 pub fn main() {
     // Assignment.
     let f5: &mut Fat<ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} };
-    let z: Box<ToBar> = box Bar1 {f: 36};
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let z: Box<ToBar> = Box::new(Bar1 {f: 36});
     f5.ptr = Bar1 {f: 36};
     //~^ ERROR mismatched types
     //~| expected `ToBar`
index ddc929017718d02b6729740f3386812063fef3bd..2d87345db2245f5c71701480ad892e3cceda4f61 100644 (file)
@@ -23,10 +23,6 @@ pub fn main() {
     let f2: &Fat<[isize; 3]> = &f1;
     let f3: &Fat<[usize]> = f2;
     //~^ ERROR mismatched types
-    //~| expected `&Fat<[usize]>`
-    //~| found `&Fat<[isize; 3]>`
-    //~| expected usize
-    //~| found isize
 
     // With a trait.
     let f1 = Fat { ptr: Foo };
index 91f34320482561aca98a3a707e8405a976579c41..c52458934bd1c90b378e9f15813201a8bc1e4378 100644 (file)
 use std::ops::Index;
 use std::fmt::Debug;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct S;
 
 impl Index<usize> for S {
     type Output = str;
 
-    fn index<'a>(&'a self, _: &usize) -> &'a str {
+    fn index(&self, _: usize) -> &str {
         "hello"
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct T;
 
 impl Index<usize> for T {
     type Output = Debug + 'static;
 
-    fn index<'a>(&'a self, idx: &usize) -> &'a (Debug + 'static) {
+    fn index<'a>(&'a self, idx: usize) -> &'a (Debug + 'static) {
         static x: usize = 42;
         &x
     }
index 18ec55e10bb9a0410c1b54f6568687281275b0a6..7586bc61cd6d4e64e896c711a005a85ae8ad2a8d 100644 (file)
@@ -13,4 +13,3 @@ fn f(a: isize, a: isize) {}
 
 fn main() {
 }
-
diff --git a/src/test/compile-fail/duplicate-trait-bounds.rs b/src/test/compile-fail/duplicate-trait-bounds.rs
deleted file mode 100644 (file)
index d9aa9d9..0000000
+++ /dev/null
@@ -1,15 +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.
-
-trait Foo {}
-
-fn foo<T: Foo + Foo>() {} //~ ERROR `Foo` already appears in the list of bounds
-
-fn main() {}
index d535ce4a69a2d33316ce5ad78beb4892364b5b40..42b67337c64e58bccdbfdfc2890937a5b2532835 100644 (file)
@@ -36,4 +36,3 @@ impl<T,T> Qux<T,T> for Option<T> {}
 
 fn main() {
 }
-
index 9b7df81a5dcbd666e0e489327f6dc9d97516f519..8791481d9e75e63b42ac90350468f0b3d5dc5244 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 // compile-flags: --extern std=
-// error-pattern: is not a file
+// error-pattern: can't find crate for `std`
 
 fn main() {}
index 1d7794336a09671999d7f8f50ae9dff971bc9357..cdf7d026d5eebd4b26039d7b9508496c51b8aad4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(negate_unsigned)]
+
 #[repr(u8)] //~ NOTE discriminant type specified here
 enum Eu8 {
     Au8 = 23,
index 6e64e01d7410d2858315a2e6e3f4d462f8abe5f3..b5c6db0cea9e32767687133e5330509b1f5b3bdb 100644 (file)
@@ -18,7 +18,7 @@ fn has_uniq(x: String) {
 
 fn has_slice(x: &str) {
    wants_uniq(x); //~ ERROR mismatched types
-   wants_slice(x.as_slice());
+   wants_slice(x);
 }
 
 fn main() {
index 92b7b601e4dc36430bf5447ed5f17209916e2176..ed1327f31185e8d565dd95307800193381e584a5 100644 (file)
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 enum test {
-    div_zero = 1/0, //~ERROR expected constant: attempted to divide by zero
-    rem_zero = 1%0  //~ERROR expected constant: attempted remainder with a divisor of zero
+    div_zero = 1/0, //~ERROR constant evaluation error: attempted to divide by zero
+    rem_zero = 1%0  //~ERROR constant evaluation error: attempted remainder with a divisor of zero
 }
 
 fn main() {}
index f47f14d587992f83c2a95790130da77cf6651fdc..460c396750ff0b6fda97337e1d46c12824a46822 100644 (file)
 
 // issue #20126
 
-#[derive(Copy)] //~ ERROR the trait `Copy` may not be implemented
+#[derive(Copy, Clone)] //~ ERROR the trait `Copy` may not be implemented
 struct Foo;
 
 impl Drop for Foo {
     fn drop(&mut self) {}
 }
 
-#[derive(Copy)] //~ ERROR the trait `Copy` may not be implemented
+#[derive(Copy, Clone)] //~ ERROR the trait `Copy` may not be implemented
 struct Bar<T>(::std::marker::PhantomData<T>);
 
 #[unsafe_destructor]
index 92542ab3bcb8114fe9a316806c44c7efb8a462b5..922e58698dd754e273fcec3315230b7c21ac29e1 100644 (file)
@@ -26,4 +26,3 @@ impl<'a,'b> Foo<'a,'b> {
 }
 
 fn main() {}
-
index ade8b397e0003d0e306f145ee334f934a8850a0d..2553bdcbb273ef48cb3c5e33ff053cf2722a550d 100644 (file)
@@ -24,8 +24,7 @@ extern "rust-intrinsic" {
 
     // Unresolved bounds should still error.
     fn align_of<T: NoSuchTrait>() -> usize;
-    //~^ ERROR attempt to bound type parameter with a nonexistent trait `NoSuchTrait`
+    //~^ ERROR use of undeclared trait name `NoSuchTrait`
 }
 
 fn main() {}
-
index db3373ea02772285a8300795963091b2e992609b..d1abed9b2627c0a636bd9f1eb96ceb6ce7c3f008 100644 (file)
@@ -18,5 +18,5 @@ fn main() {
     let _x: extern "C" fn() = f; // OK
     is_fn(f);
     //~^ ERROR the trait `core::ops::Fn<()>` is not implemented for the type `extern "C" fn()
-    //~| ERROR the trait `core::ops::Fn<()>` is not implemented for the type `extern "C" fn()
+    //~| ERROR the trait `core::ops::FnOnce<()>` is not implemented for the type `extern "C" fn()
 }
index d5841e1e77e4020ed3fa6711ec006e77c0cf4fad..1daca371b3409c3eb9225936fe06408cb32cc264 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 fn main() {
     let x = [ 1, 2, 3, 4, 5 ];
     match x {
@@ -16,4 +18,3 @@ fn main() {
         [ 1, 2, xs.. ] => {}    // OK without feature gate
     }
 }
-
diff --git a/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs b/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs
new file mode 100644 (file)
index 0000000..c9251c9
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2015 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.
+
+macro_rules! bar {
+    () => {
+        // more layers don't help:
+        #[allow_internal_unstable]
+        macro_rules! baz { //~ ERROR allow_internal_unstable side-steps
+            () => {}
+        }
+    }
+}
+
+bar!();
+
+fn main() {}
diff --git a/src/test/compile-fail/feature-gate-allow-internal-unstable.rs b/src/test/compile-fail/feature-gate-allow-internal-unstable.rs
new file mode 100644 (file)
index 0000000..8a2d8dd
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 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_internal_unstable] //~ ERROR allow_internal_unstable side-steps
+macro_rules! foo {
+    () => {}
+}
+
+fn main() {}
index 39f54be4561692b21185563ff02d1ea47c138124..8f8b035f4a96b82b16ee2dd136df4005076f2637 100644 (file)
@@ -20,4 +20,3 @@ fn main() {
     let x = box (HEAP) 'c'; //~ ERROR box expression syntax is experimental
     println!("x: {}", x);
 }
-
diff --git a/src/test/compile-fail/feature-gate-int-uint.rs b/src/test/compile-fail/feature-gate-int-uint.rs
deleted file mode 100644 (file)
index 948e485..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 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, unused_variables)]
-#![feature(rustc_attrs)]
-
-mod u {
-    type X = uint; //~ WARN the `uint` type is deprecated
-    struct Foo {
-        x: uint //~ WARN the `uint` type is deprecated
-    }
-    fn bar(x: uint) { //~ WARN the `uint` type is deprecated
-        1_u; //~ WARN the `u` and `us` suffixes on integers are deprecated
-        1_us; //~ WARN the `u` and `us` suffixes on integers are deprecated
-    }
-}
-mod i {
-    type X = int; //~ WARN the `int` type is deprecated
-    struct Foo {
-        x: int //~ WARN the `int` type is deprecated
-    }
-    fn bar(x: int) { //~ WARN the `int` type is deprecated
-        1_i; //~ WARN the `i` and `is` suffixes on integers are deprecated
-        1_is; //~ WARN the `i` and `is` suffixes on integers are deprecated
-    }
-}
-
-#[rustc_error]
-fn main() { //~ ERROR compilation successful
-}
diff --git a/src/test/compile-fail/feature-gate-intrinsics-and-lang-items.rs b/src/test/compile-fail/feature-gate-intrinsics-and-lang-items.rs
deleted file mode 100644 (file)
index 986d52b..0000000
+++ /dev/null
@@ -1,23 +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.
-
-#[lang="foo"]   //~ ERROR language items are subject to change
-trait Foo {}
-
-extern "rust-intrinsic" {   //~ ERROR intrinsics are subject to change
-    fn bar();
-}
-
-extern "rust-intrinsic" fn baz() {  //~ ERROR intrinsics are subject to change
-}
-
-fn main() {
-}
-
diff --git a/src/test/compile-fail/feature-gate-intrinsics.rs b/src/test/compile-fail/feature-gate-intrinsics.rs
new file mode 100644 (file)
index 0000000..a4c09b2
--- /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.
+
+extern "rust-intrinsic" {   //~ ERROR intrinsics are subject to change
+    fn bar();
+}
+
+extern "rust-intrinsic" fn baz() {  //~ ERROR intrinsics are subject to change
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/feature-gate-lang-items.rs b/src/test/compile-fail/feature-gate-lang-items.rs
new file mode 100644 (file)
index 0000000..0435ff4
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+#[lang="foo"]   //~ ERROR language items are subject to change
+trait Foo {}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/feature-gate-rust-call.rs b/src/test/compile-fail/feature-gate-rust-call.rs
new file mode 100644 (file)
index 0000000..029a9ca
--- /dev/null
@@ -0,0 +1,21 @@
+// 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.
+
+extern "rust-call" fn foo() { } //~ ERROR rust-call ABI is subject to change
+
+trait Foo {
+    extern "rust-call" fn foo();
+}
+
+impl Foo for i32 {
+    extern "rust-call" fn foo() { } //~ ERROR rust-call ABI is subject to change
+}
+
+fn main() { }
index 9ee3fcee0235557da422bec01305fb010d843112..dcd7a0ded812fcd7176d7143fe207ecfc34fb438 100644 (file)
@@ -13,7 +13,7 @@
 
 use std::simd::f32x4;
 
-#[simd] #[derive(Copy)] #[repr(C)] struct LocalSimd(u8, u8);
+#[simd] #[derive(Copy, Clone)] #[repr(C)] struct LocalSimd(u8, u8);
 
 extern {
     fn foo() -> f32x4; //~ ERROR use of SIMD type
index 6a9acf04290e4a13d6e36bb40d1e91a5b2337661..7a0924d8adf1ba8fce115cfc36bbfb917e25f826 100644 (file)
@@ -10,4 +10,3 @@
 
 #[start]
 fn foo() {} //~ ERROR: a #[start] function is an experimental feature
-
diff --git a/src/test/compile-fail/feature-gate-static-assert.rs b/src/test/compile-fail/feature-gate-static-assert.rs
new file mode 100644 (file)
index 0000000..2574039
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2015 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.
+
+#[static_assert] //~ ERROR `#[static_assert]` is an experimental feature
+static X: bool = true;
+
+fn main() {}
index e5e5ddadafccf8014d09b675f53a1b093c896e4c..5df309321d3108a956131d8494dfc1d1a1ccd1f4 100644 (file)
 
 struct Foo;
 impl Fn<()> for Foo {
-    //~^ ERROR angle-bracket notation is not stable when used with the `Fn` family of traits
-    type Output = ();
-
-    extern "rust-call" fn call(&self, args: ()) -> () {}
+    extern "rust-call" fn call(self, args: ()) -> () {}
+    //~^ ERROR rust-call ABI is subject to change
 }
 struct Foo1;
-impl Fn() for Foo1 {
-    //~^ ERROR associated type bindings are not allowed here
-
-    extern "rust-call" fn call(&self, args: ()) -> () {}
+impl FnOnce() for Foo1 {
+    extern "rust-call" fn call_once(self, args: ()) -> () {}
+    //~^ ERROR rust-call ABI is subject to change
 }
 struct Bar;
 impl FnMut<()> for Bar {
-    //~^ ERROR angle-bracket notation is not stable when used with the `Fn` family of traits
-    type Output = ();
-
     extern "rust-call" fn call_mut(&self, args: ()) -> () {}
+    //~^ ERROR rust-call ABI is subject to change
 }
 struct Baz;
 impl FnOnce<()> for Baz {
-    //~^ ERROR angle-bracket notation is not stable when used with the `Fn` family of traits
-    type Output = ();
-
     extern "rust-call" fn call_once(&self, args: ()) -> () {}
+    //~^ ERROR rust-call ABI is subject to change
 }
 
 fn main() {}
index 1e15e67876ed44f140e63b877fae4e5158baba79..54bdaf011c875c63de26a56c6ec368cb0ecfca7d 100644 (file)
@@ -21,7 +21,7 @@
 // test. Not ideal, but oh well :(
 
 fn main() {
-    let a = &[1i32, 2, 3];
+    let a = &[1, 2, 3];
     println!("{}", {
         extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change
             fn atomic_fence();
index 6178d37a5bd6c49bde6c12afb451d56db2ffceff..27be1ada445505dbd4c54d5aad0996cf178135ea 100644 (file)
@@ -13,4 +13,5 @@ fn main() {
     fn g() { }
     let x = f == g;
     //~^ ERROR binary operation `==` cannot be applied
+    //~| ERROR mismatched types
 }
index 71e1f7091b2c99094e9459e64ba25fe261906ecc..6433255bd4d2fcb7e3dd05894e669f8a38b0b945 100644 (file)
@@ -15,8 +15,7 @@ fn needs_fn<F>(x: F) where F: Fn(isize) -> isize {}
 
 fn main() {
     let _: () = (box |_: isize| {}) as Box<FnOnce(isize)>;
-    //~^ ERROR object-safe
-    //~| ERROR mismatched types
+    //~^ ERROR mismatched types
     //~| expected `()`
     //~| found `Box<core::ops::FnOnce(isize)>`
     //~| expected ()
@@ -27,7 +26,7 @@ fn main() {
     //~| found `Box<core::ops::Fn(isize, isize)>`
     //~| expected ()
     //~| found box
-    let _: () = (box || -> isize unimplemented!()) as Box<FnMut() -> isize>;
+    let _: () = (box || -> isize { unimplemented!() }) as Box<FnMut() -> isize>;
     //~^ ERROR mismatched types
     //~| expected `()`
     //~| found `Box<core::ops::FnMut() -> isize>`
@@ -36,5 +35,5 @@ fn main() {
 
     needs_fn(1);
     //~^ ERROR `core::ops::Fn<(isize,)>`
-    //~| ERROR `core::ops::Fn<(isize,)>`
+    //~| ERROR `core::ops::FnOnce<(isize,)>`
 }
index 838e65e1d0574718d893ed2856e2daab64c0d057..8e1e88a92e452c09d0200806c4bfe2cdc7386394 100644 (file)
@@ -17,9 +17,13 @@ fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
 }
 
 fn main() {
-    apply(&3, takes_mut); //~ ERROR (values differ in mutability)
     apply(&3, takes_imm);
+    apply(&3, takes_mut);
+    //~^ ERROR (values differ in mutability)
+    //~| ERROR (values differ in mutability)
 
     apply(&mut 3, takes_mut);
-    apply(&mut 3, takes_imm); //~ ERROR (values differ in mutability)
+    apply(&mut 3, takes_imm);
+    //~^ ERROR (values differ in mutability)
+    //~| ERROR (values differ in mutability)
 }
diff --git a/src/test/compile-fail/gated-box-patterns.rs b/src/test/compile-fail/gated-box-patterns.rs
new file mode 100644 (file)
index 0000000..abaa256
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2015 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 patterns including the box syntax are gated by `box_patterns` feature gate.
+
+fn main() {
+    let x = Box::new(1);
+
+    match x {
+        box 1 => (),
+        //~^ box pattern syntax is experimental
+        //~| add #![feature(box_patterns)] to the crate attributes to enable
+        _     => ()
+    };
+}
diff --git a/src/test/compile-fail/gated-box-syntax.rs b/src/test/compile-fail/gated-box-syntax.rs
new file mode 100644 (file)
index 0000000..3e08c1f
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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 use of the box syntax is gated by `box_syntax` feature gate.
+
+fn main() {
+    let x = box 3;
+    //~^ ERROR box expression syntax is experimental; you can call `Box::new` instead.
+    //~| HELP add #![feature(box_syntax)] to the crate attributes to enable
+}
diff --git a/src/test/compile-fail/gated-link-args.rs b/src/test/compile-fail/gated-link-args.rs
new file mode 100644 (file)
index 0000000..c8845ce
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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 `#[link_args]` attribute is gated by `link_args`
+// feature gate.
+
+#[link_args = "aFdEfSeVEEE"]
+extern {}
+//~^ ERROR the `link_args` attribute is not portable across platforms
+//~| HELP add #![feature(link_args)] to the crate attributes to enable
+
+fn main() { }
diff --git a/src/test/compile-fail/gated-link-llvm-intrinsics.rs b/src/test/compile-fail/gated-link-llvm-intrinsics.rs
new file mode 100644 (file)
index 0000000..716ea9f
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+extern {
+    #[link_name = "llvm.sqrt.f32"]
+    fn sqrt(x: f32) -> f32;
+    //~^ ERROR linking to LLVM intrinsics is experimental
+    //~| HELP add #![feature(link_llvm_intrinsics)] to the crate attributes
+}
+
+fn main(){
+}
index f6e11ffd9e5239c92f732a01c6cbd0969afd6726..d716c53e1d18ce68c4db2f1a79f42b7c9802cae4 100644 (file)
@@ -8,8 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Test that `#[plugin_registrar]` attribute is gated by `plugin_registrar`
+// feature gate.
+
 // the registration function isn't typechecked yet
 #[plugin_registrar]
-pub fn registrar() {} //~ ERROR compiler plugins are experimental
-
+pub fn registrar() {}
+//~^ ERROR compiler plugins are experimental
+//~| HELP add #![feature(plugin_registrar)] to the crate attributes to enable
 fn main() {}
diff --git a/src/test/compile-fail/gated-simd-ffi.rs b/src/test/compile-fail/gated-simd-ffi.rs
new file mode 100644 (file)
index 0000000..883e1be
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2015 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 use of smid types in the ffi is gated by `smid_ffi` feature gate.
+
+#![feature(simd)]
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+#[simd]
+pub struct f32x4(f32, f32, f32, f32);
+
+#[allow(dead_code)]
+extern {
+    fn foo(x: f32x4);
+    //~^ ERROR use of SIMD type `f32x4` in FFI is highly experimental and may result in invalid code
+    //~| HELP add #![feature(simd_ffi)] to the crate attributes to enable
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/gated-thread-local.rs b/src/test/compile-fail/gated-thread-local.rs
new file mode 100644 (file)
index 0000000..f355c65
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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 `#[thread_local]` attribute is gated by `thread_local`
+// feature gate.
+//
+// (Note that the `thread_local!` macro is explicitly *not* gated; it
+// is given permission to expand into this unstable attribute even
+// when the surrounding context does not have permission to use it.)
+
+#[thread_local] //~ ERROR `#[thread_local]` is an experimental feature
+static FOO: i32 = 3;
+
+pub fn main() {
+    FOO.with(|x| {
+        println!("x: {}", x);
+    });
+}
diff --git a/src/test/compile-fail/gated-unsafe-destructor.rs b/src/test/compile-fail/gated-unsafe-destructor.rs
new file mode 100644 (file)
index 0000000..2aebbf3
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2015 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 `#[unsafe_destructor]` attribute is gated by `unsafe_destructor`
+// feature gate.
+//
+// (This test can be removed entirely when we remove the
+// `unsafe_destructor` feature itself.)
+
+struct D<'a>(&'a u32);
+
+#[unsafe_destructor]
+//~^ ERROR `#[unsafe_destructor]` does nothing anymore
+//~| HELP: add #![feature(unsafe_destructor)] to the crate attributes to enable
+// (but of couse there is no point in doing so)
+impl<'a> Drop for D<'a> {
+    fn drop(&mut self) { }
+}
+
+pub fn main() { }
index 9fea5e609d1f4807812476ea8b2e53c5da09fcdf..5fa429445a35e66fc5d68df606e872227e308adf 100644 (file)
@@ -19,5 +19,5 @@ impl<A, B, C = (A, B)> Foo<A, B, C> {
 
 fn main() {
     Foo::<isize>::new();
-    //~^ ERROR too few type parameters provided
+    //~^ ERROR wrong number of type arguments
 }
index 73c19aa012dcf67dd0d39d97f8a748f9cb1a436c..d3babb8982ddca652bdd9c16e113d89ea74f445a 100644 (file)
@@ -21,5 +21,5 @@ impl<T, A = Heap> Vec<T, A> {
 
 fn main() {
     Vec::<isize, Heap, bool>::new();
-    //~^ ERROR too many type parameters provided
+    //~^ ERROR wrong number of type arguments
 }
index f4ead18ee168d099953403fdeaa385cd97b13dca..4163d531e870e9003046e676de9a7d6ea5898c89 100644 (file)
@@ -15,4 +15,3 @@ fn foo<T>() {} //~ ERROR generic functions must be mangled
 
 #[no_mangle]
 extern fn foo<T>() {} //~ ERROR generic functions must be mangled
-
index fce8a07d7270d3444fb83e4343a77e2bc90f7886..181503db818462907d8854a0cbb9e6b4cd4752dd 100644 (file)
@@ -36,9 +36,6 @@ fn main() {
     import(); //~ ERROR: unresolved
 
     foo::<A>(); //~ ERROR: undeclared
-    //~^ ERROR: undeclared
     foo::<C>(); //~ ERROR: undeclared
-    //~^ ERROR: undeclared
     foo::<D>(); //~ ERROR: undeclared
-    //~^ ERROR: undeclared
 }
diff --git a/src/test/compile-fail/hrtb-precedence-of-plus-error-message.rs b/src/test/compile-fail/hrtb-precedence-of-plus-error-message.rs
deleted file mode 100644 (file)
index db67249..0000000
+++ /dev/null
@@ -1,36 +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.
-
-#![feature(unboxed_closures)]
-
-// Test that we suggest the correct parentheses
-
-trait Bar {
-    fn dummy(&self) { }
-}
-
-struct Foo<'a> {
-    a: &'a Bar+'a,
-        //~^ ERROR E0178
-        //~^^ HELP perhaps you meant `&'a (Bar + 'a)`?
-
-    b: &'a mut Bar+'a,
-        //~^ ERROR E0178
-        //~^^ HELP perhaps you meant `&'a mut (Bar + 'a)`?
-
-    c: Box<Bar+'a>, // OK, no paren needed in this context
-
-    d: fn() -> Bar+'a,
-        //~^ ERROR E0178
-        //~^^ HELP perhaps you forgot parentheses
-        //~^^^ WARN deprecated syntax
-}
-
-fn main() { }
index 1e04e685e41b8b3434ca2b62dfd92671eea445eb..54340cf7ac414f17d922749321a2814c7997f5e1 100644 (file)
@@ -8,8 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: too big for the current
+// FIXME (#23926): the error output is not consistent between a
+// self-hosted and a cross-compiled setup. Skipping for now.
+
+// ignore-test FIXME(#23926)
+
+#![allow(exceeding_bitshifts)]
 
 fn main() {
-   let fat : [u8; (1<<61)+(1<<31)] = [0; (1u64<<61) as usize +(1u64<<31) as usize];
+    let _fat : [u8; (1<<61)+(1<<31)] =
+        [0; (1u64<<61) as usize +(1u64<<31) as usize];
 }
diff --git a/src/test/compile-fail/if-loop.rs b/src/test/compile-fail/if-loop.rs
new file mode 100644 (file)
index 0000000..15f04df
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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(rustc_attrs)]
+#![allow(warnings)]
+
+// This used to ICE because the "if" being unreachable was not handled correctly
+fn err() {
+    if loop {} {}
+}
+
+#[rustc_error]
+fn main() {} //~ ERROR compilation successful
index c6ce4d04e10866951d30c17fadb8c4dfefb1e56b..3b4def8c5086954ff69b1ee9973c3981d4067c26 100644 (file)
@@ -11,7 +11,7 @@
 struct Foo;
 impl Foo {
     fn orange(&self){}
-    fn orange(&self){}   //~ ERROR error: duplicate definition of value `orange`
+    fn orange(&self){}   //~ ERROR error: duplicate method
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/impl-not-adjacent-to-type.rs b/src/test/compile-fail/impl-not-adjacent-to-type.rs
deleted file mode 100644 (file)
index 7a7673d..0000000
+++ /dev/null
@@ -1,24 +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.
-
-mod foo {
-    pub struct Foo {
-        x: isize,
-        y: isize,
-    }
-}
-
-impl foo::Foo {
-//~^ ERROR implementations may only be implemented in the same module
-    fn bar() {}
-}
-
-fn main() {}
-
index f38172db4447b58ae06dcd7a694877079348486f..67834a9996948f5ca756b67d4b019d0d0ec7e340 100644 (file)
 mod circ1 {
     pub use circ2::f2;
     pub fn f1() { println!("f1"); }
-    pub fn common() -> usize { return 0_usize; }
+    pub fn common() -> usize { return 0; }
 }
 
 mod circ2 {
     pub use circ1::f1;
     pub fn f2() { println!("f2"); }
-    pub fn common() -> usize { return 1_usize; }
+    pub fn common() -> usize { return 1; }
 }
 
 mod test {
index b28f2a746fdc40c5d64345bef176d52d33ef0e53..70c362303ae30cba82ac7837aa7f326f32cabf0b 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    (return)[0_usize]; //~ ERROR the type of this value must be known in this context
+    (return)[0]; //~ ERROR the type of this value must be known in this context
 }
index 901d8783d0278997a9e6dfd00e909b2f1af4a40e..3ca00fcb66ac16e1a51dbc48fa99feb96fa6a21d 100644 (file)
@@ -23,4 +23,3 @@ fn main() {
     bar::<isize>(i);  // i should not be re-coerced back to an isize
     //~^ ERROR: mismatched types
 }
-
index 2642ac6204ce4d8490f021c563994e7dd52c3b58..559e0e9a292a6dda32676241228923421dcede21 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,31 +8,37 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: reached the recursion limit during monomorphization
-// issue 2258
+//~^^^^^^^^^^ ERROR overflow
+//
+// We get an error message at the top of file (dummy span).
+// This is not helpful, but also kind of annoying to prevent,
+// so for now just live with it.
+// This test case was originally for issue #2258.
 
-trait to_opt {
+trait ToOpt {
     fn to_option(&self) -> Option<Self>;
 }
 
-impl to_opt for usize {
+impl ToOpt for usize {
     fn to_option(&self) -> Option<usize> {
         Some(*self)
     }
 }
 
-impl<T:Clone> to_opt for Option<T> {
+impl<T:Clone> ToOpt for Option<T> {
     fn to_option(&self) -> Option<Option<T>> {
         Some((*self).clone())
     }
 }
 
-fn function<T:to_opt + Clone>(counter: usize, t: T) {
-    if counter > 0_usize {
-        function(counter - 1_usize, t.to_option());
+fn function<T:ToOpt + Clone>(counter: usize, t: T) {
+    if counter > 0 {
+        function(counter - 1, t.to_option());
+        // FIXME(#4287) Error message should be here. It should be
+        // a type error to instantiate `test` at a type other than T.
     }
 }
 
 fn main() {
-    function(22_usize, 22_usize);
+    function(22, 22);
 }
index 74835f4bf22cafce53576e85bfb0c108da852fa9..14d22702db7a45d873bd41f8cb3c702d366f8813 100644 (file)
@@ -15,4 +15,3 @@ macro_rules! recursive {
 fn main() {
     recursive!()
 }
-
index 5bcba350b2ecba893f97825acf2c751d0f1b21f8..e5120840f7672a6d19ad8fae9faa4d87f29504df 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: illegal recursive type
-
-
 type x = Vec<x>;
+//~^ ERROR unsupported cyclic reference
 
 fn main() { let b: x = Vec::new(); }
index abd7efe0e8ed1faf141b88d662d7e4482294cc3c..cf2a70deee513cf3945a6389557febc52367ec1f 100644 (file)
@@ -14,7 +14,8 @@ enum Bar<T> { What }
 
 fn foo<T>() {
     static a: Bar<T> = Bar::What;
-    //~^ ERROR: cannot use an outer type parameter in this context
+    //~^ ERROR cannot use an outer type parameter in this context
+    //~| ERROR use of undeclared type name `T`
 }
 
 fn main() {
index e8998dd7a9d48c54f50c97723638ba8ebd0016e2..e2fb0fa4f2fa518f7fe9280c959b417d052e0c4b 100644 (file)
@@ -24,11 +24,11 @@ pub fn main() {
     s.as_bytes()[3_usize];
     s.as_bytes()[3];
     s.as_bytes()[3u8];  //~ERROR the trait `core::ops::Index<u8>` is not implemented
-    //~^ERROR the trait `core::ops::Index<u8>` is not implemented
+    //~^ ERROR the trait `core::ops::Index<u8>` is not implemented
     s.as_bytes()[3i8];  //~ERROR the trait `core::ops::Index<i8>` is not implemented
-    //~^ERROR the trait `core::ops::Index<i8>` is not implemented
+    //~^ ERROR the trait `core::ops::Index<i8>` is not implemented
     s.as_bytes()[3u32]; //~ERROR the trait `core::ops::Index<u32>` is not implemented
-    //~^ERROR the trait `core::ops::Index<u32>` is not implemented
+    //~^ ERROR the trait `core::ops::Index<u32>` is not implemented
     s.as_bytes()[3i32]; //~ERROR the trait `core::ops::Index<i32>` is not implemented
-    //~^ERROR the trait `core::ops::Index<i32>` is not implemented
+    //~^ ERROR the trait `core::ops::Index<i32>` is not implemented
 }
diff --git a/src/test/compile-fail/internal-unstable-noallow.rs b/src/test/compile-fail/internal-unstable-noallow.rs
new file mode 100644 (file)
index 0000000..2b48d47
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2015 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.
+
+// this has to be separate to internal-unstable.rs because these tests
+// have error messages pointing deep into the internals of the
+// cross-crate macros, and hence need to use error-pattern instead of
+// the // ~ form.
+
+// aux-build:internal_unstable.rs
+// error-pattern:use of unstable library feature 'function'
+// error-pattern:use of unstable library feature 'struct_field'
+
+#[macro_use]
+extern crate internal_unstable;
+
+fn main() {
+    call_unstable_noallow!();
+
+    construct_unstable_noallow!(0);
+}
diff --git a/src/test/compile-fail/internal-unstable-thread-local.rs b/src/test/compile-fail/internal-unstable-thread-local.rs
new file mode 100644 (file)
index 0000000..74526fb
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2015 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.
+
+// aux-build:internal_unstable.rs
+
+#![allow(dead_code)]
+
+extern crate internal_unstable;
+
+
+thread_local!(static FOO: () = ());
+thread_local!(static BAR: () = internal_unstable::unstable()); //~ ERROR use of unstable
+
+fn main() {}
diff --git a/src/test/compile-fail/internal-unstable.rs b/src/test/compile-fail/internal-unstable.rs
new file mode 100755 (executable)
index 0000000..accc898
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright 2015 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.
+
+// aux-build:internal_unstable.rs
+
+#![feature(allow_internal_unstable)]
+
+#[macro_use]
+extern crate internal_unstable;
+
+macro_rules! foo {
+    ($e: expr, $f: expr) => {{
+        $e;
+        $f;
+        internal_unstable::unstable(); //~ ERROR use of unstable
+    }}
+}
+
+#[allow_internal_unstable]
+macro_rules! bar {
+    ($e: expr) => {{
+        foo!($e,
+             internal_unstable::unstable());
+        internal_unstable::unstable();
+    }}
+}
+
+fn main() {
+    // ok, the instability is contained.
+    call_unstable_allow!();
+    construct_unstable_allow!(0);
+
+    // bad.
+    pass_through_allow!(internal_unstable::unstable()); //~ ERROR use of unstable
+
+    pass_through_noallow!(internal_unstable::unstable()); //~ ERROR use of unstable
+
+
+
+    println!("{:?}", internal_unstable::unstable()); //~ ERROR use of unstable
+
+    bar!(internal_unstable::unstable()); //~ ERROR use of unstable
+}
index a80d393155539ed1e3b10b0f6f5c3143373a31c4..b83f0f73436cffe488e9f358ed532eec95f091e0 100644 (file)
@@ -27,5 +27,3 @@ unsafe fn g() -> isize {
 }
 
 fn main() {}
-
-
diff --git a/src/test/compile-fail/invalid-inline.rs b/src/test/compile-fail/invalid-inline.rs
new file mode 100644 (file)
index 0000000..ad89087
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2015 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)]
+
+#[inline(please_no)] //~ ERROR invalid argument
+fn a() {
+}
+
+#[inline(please,no)] //~ ERROR expected one argument
+fn b() {
+}
+
+#[inline()] //~ ERROR expected one argument
+fn c() {
+}
+
+fn main() {}
index 45f6e55914a1b07ba3a8c28cd3e87dc4858ee94f..9711d760ae666ccb54409aa5fdb6dd90f43f3478 100644 (file)
@@ -8,13 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
-
 fn test<'x>(x: &'x isize) {
-    drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(box |z| {
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
         x
         //~^ ERROR cannot infer an appropriate lifetime
-    });
+    }));
 }
 
 fn main() {}
index 736f9630127121e23bd24340114c5700f4102656..08e8effc626f5bd68b7e6bda91e97b9fb3fa3aa5 100644 (file)
@@ -11,7 +11,7 @@
 #![feature(box_syntax)]
 
 fn main() {
-    let x = box 1;
+    let x: Box<_> = box 1;
     let f = move|| {
         let _a = x;
         drop(x);
index 370a6228db6ac733358a97e8ee5df73b3cde769d..3b0ea55cfa9c1550ae8927240c6b06098380dbb4 100644 (file)
@@ -29,4 +29,3 @@ pub fn main() {
     // least throw a conventional error.
     assert!({one! two});
 }
-
index a95bcc73a9c473adf98a2ac38839dfdeaf42ee73..7d8a1528aba36973a5cc86d395b82a716d36772c 100644 (file)
@@ -21,7 +21,7 @@ impl Drop for Foo {
 }
 
 fn main() {
-    let mut ptr = box Foo { x: 0 };
+    let mut ptr: Box<_> = box Foo { x: 0 };
     let mut test = |foo: &Foo| {
         println!("access {}", foo.x);
         ptr = box Foo { x: ptr.x + 1 };
@@ -30,4 +30,3 @@ fn main() {
     test(&*ptr);
     //~^ ERROR: cannot borrow `*ptr` as immutable
 }
-
index 09d7293a3d0c020202b99da5a11299e531d68e74..f78786a2889dab5df60ce1d813fef94b1f00b6b8 100644 (file)
@@ -8,15 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::old_io;
+use std::io::{self, Read};
 use std::vec;
 
 pub struct Container<'a> {
-    reader: &'a mut Reader
+    reader: &'a mut Read
 }
 
 impl<'a> Container<'a> {
-    pub fn wrap<'s>(reader: &'s mut Reader) -> Container<'s> {
+    pub fn wrap<'s>(reader: &'s mut io::Read) -> Container<'s> {
         Container { reader: reader }
     }
 
@@ -26,8 +26,8 @@ impl<'a> Container<'a> {
 }
 
 pub fn for_stdin<'a>() -> Container<'a> {
-    let mut r = old_io::stdin();
-    Container::wrap(&mut r as &mut Reader)
+    let mut r = io::stdin();
+    Container::wrap(&mut r as &mut io::Read)
 }
 
 fn main() {
index 4ff574e939df649794a2b31bdd4f49a374ed3c05..f682d618ab646131735f3cf47ff98976be17369c 100644 (file)
@@ -15,6 +15,7 @@ struct Test {
 }
 
 fn main() {
-    let closure: Box<Fn()+'static> = box || ();
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let closure: Box<Fn()+'static> = Box::new(|| ());
     let test = box Test { func: closure }; //~ ERROR mismatched types
 }
index ecc584d81b0e10d5d9afef848fad14a72fd3c190..2749438433d16fd150e063a693c7a5cb408e3a48 100644 (file)
@@ -18,4 +18,3 @@ impl private_trait_xc::Foo for Bar {}
 //~^ ERROR: trait `Foo` is private
 
 fn main() {}
-
index 0f30243b39a1942ad54ddfa30fb7c05441d07498..1bd7b0aa1c27913f4b6537354d0022d9736fb83e 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:issue-11680.rs
+// aux-build:issue_11680.rs
 
-extern crate "issue-11680" as other;
+extern crate issue_11680 as other;
 
 fn main() {
     let _b = other::Foo::Bar(1);
index d307352517feaf5e95c51d8cbb268c0e74c2fcde..998576097a0a06887275de88b1d82149f2fcae6e 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn blah() -> i32 { //~ ERROR not all control paths return a value
-    1i32
+    1
 
     ; //~ HELP consider removing this semicolon:
 }
index 2de86e527ef594460289a4307d522cd75e6918a1..40fc6b1ed6aaacebf6a682e43b67d369b5dff5ab 100644 (file)
 fn main() {
     let x = ();
     1 +
-    x //~  ERROR mismatched types
-      //~| expected `_`
-      //~| found `()`
-      //~| expected integral variable
-      //~| found ()
+    x //~^ ERROR E0277
+      //~| ERROR E0277
     ;
 
     let x: () = ();
     1 +
-    x //~  ERROR mismatched types
-      //~| expected `_`
-      //~| found `()`
-      //~| expected integral variable
-      //~| found ()
+    x //~^ ERROR E0277
+      //~| ERROR E0277
     ;
 }
index 560cbe1b8a87f2240a89f43056afc2d54dd501f2..a6dbe954ec0aca714e14c2c5b4891fe0d824ad70 100644 (file)
@@ -18,4 +18,3 @@ fn main() {
         None => panic!()
     }
 }
-
index df4dab2552e7de8922613d5f6a683a4a338778b3..7bd072c6268cdfcc7520130b545a62fc46a8a95b 100644 (file)
@@ -14,7 +14,7 @@ fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
 
 fn main() {
     let r = {
-        let x = box 42;
+        let x: Box<_> = box 42;
         let f = to_fn_once(move|| &x); //~ ERROR: `x` does not live long enough
         f()
     };
index 735f529277c360be6c7291d432c54373e65d0446..f0f4bf5ca71bb611031a86f871bdf974ce923717 100644 (file)
@@ -21,4 +21,3 @@ fn main() {
         }
     });
 }
-
index 40d446b91a5a8b659d56cb79dcbec7b202c8249d..5565a9a5761166d0a52fb7649d241990b546c492 100644 (file)
@@ -14,7 +14,7 @@ fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
 fn do_it(x: &isize) { }
 
 fn main() {
-    let x = box 22;
+    let x: Box<_> = box 22;
     let f = to_fn_once(move|| do_it(&*x));
     to_fn_once(move|| {
         f();
index 9a471a4341f5f1706bfc9a9458c264b1e9fbef44..1333bfac64ee86d1edc9f2d0b3c624ec70462a5a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 fn main() {
     let sl = vec![1,2,3];
     let v: isize = match &*sl {
index d186a83676a804abf601b48d5372eaa6eacfe09b..1580ec00f94b068b3c59c0884975ed4a8885bad2 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) {
     match (l1, l2) {
         ([], []) => println!("both empty"),
index 0550472dabb80ba5659fdcbf59d46d74aa0f3c76..f76d12d93fdf68cf9227aa2c3a5e97bb792861d9 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:issue-12612-1.rs
+// aux-build:issue_12612_1.rs
 
-extern crate "issue-12612-1" as foo;
+extern crate issue_12612_1 as foo;
 
 use foo::bar;
 
@@ -20,4 +20,3 @@ mod test {
 }
 
 fn main() {}
-
diff --git a/src/test/compile-fail/issue-12729.rs b/src/test/compile-fail/issue-12729.rs
deleted file mode 100644 (file)
index ae033bb..0000000
+++ /dev/null
@@ -1,23 +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.
-
-// ignore-tidy-linelength
-
-pub struct Foo;
-
-mod bar {
-    use Foo;
-
-    impl Foo { //~ERROR inherent implementations are only allowed on types defined in the current module
-        fn baz(&self) {}
-    }
-}
-fn main() {}
-
index 06f14158b91577f7b4219f5b2bcc767e231fc511..8886dd80be5039bed56eb68650bcf347efd7d6b9 100644 (file)
@@ -8,14 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::iter::{Range,range};
+use std::ops::Range;
 
 trait Itble<'r, T, I: Iterator<Item=T>> { fn iter(&'r self) -> I; }
 
 impl<'r> Itble<'r, usize, Range<usize>> for (usize, usize) {
     fn iter(&'r self) -> Range<usize> {
         let &(min, max) = self;
-        range(min, max)
+        min..max
     }
 }
 
@@ -24,7 +24,7 @@ fn check<'r, I: Iterator<Item=usize>, T: Itble<'r, usize, I>>(cont: &T) -> bool
 {
     let cont_iter = cont.iter();
 //~^ ERROR cannot infer an appropriate lifetime for autoref due to conflicting requirements
-    let result = cont_iter.fold(Some(0u16), |state, val| {
+    let result = cont_iter.fold(Some(0), |state, val| {
         state.map_or(None, |mask| {
             let bit = 1 << val;
             if mask & bit == 0 {Some(mask|bit)} else {None}
@@ -34,10 +34,10 @@ fn check<'r, I: Iterator<Item=usize>, T: Itble<'r, usize, I>>(cont: &T) -> bool
 }
 
 fn main() {
-    check((3_usize, 5_usize));
+    check((3, 5));
 //~^ ERROR mismatched types
 //~| expected `&_`
-//~| found `(usize, usize)`
+//~| found `(_, _)`
 //~| expected &-ptr
 //~| found tuple
 }
diff --git a/src/test/compile-fail/issue-13352.rs b/src/test/compile-fail/issue-13352.rs
new file mode 100644 (file)
index 0000000..a8c8c8b
--- /dev/null
@@ -0,0 +1,28 @@
+// 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.
+
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc, libc)]
+
+extern crate libc;
+
+use std::thunk::Thunk;
+
+fn foo(_: Thunk) {}
+
+fn main() {
+    foo(loop {
+        unsafe { libc::exit(0 as libc::c_int); }
+    });
+    2_usize + (loop {});
+    //~^ ERROR E0277
+    //~| ERROR E0277
+}
diff --git a/src/test/compile-fail/issue-13407.rs b/src/test/compile-fail/issue-13407.rs
new file mode 100644 (file)
index 0000000..f845eba
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+mod A {
+    struct C;
+}
+
+fn main() {
+    A::C = 1;
+    //~^ ERROR: illegal left-hand side expression
+    //~| ERROR: mismatched types
+}
index a0a7660428d4106815906f0d7561c58802b01df7..53d1486288984477a2afe57140c08c1459a7a5bf 100644 (file)
@@ -16,4 +16,3 @@
 static VEC: [u32; 256] = vec!();
 
 fn main() {}
-
index 16128e52d64d1d9804e481c89269cf444541e8bc..a29a83c43063214f6bb0c2ebae731c2b7327f575 100644 (file)
@@ -14,17 +14,17 @@ pub fn main() {
     // The expected arm type `Option<T>` has one type parameter, while
     // the actual arm `Result<T, E>` has two. typeck should not be
     // tricked into looking up a non-existing second type parameter.
-    let _x: usize = match Some(1_usize) {
+    let _x: usize = match Some(1) {
         Ok(u) => u,
         //~^ ERROR mismatched types
-        //~| expected `core::option::Option<usize>`
+        //~| expected `core::option::Option<_>`
         //~| found `core::result::Result<_, _>`
         //~| expected enum `core::option::Option`
         //~| found enum `core::result::Result`
 
         Err(e) => panic!(e)
         //~^ ERROR mismatched types
-        //~| expected `core::option::Option<usize>`
+        //~| expected `core::option::Option<_>`
         //~| found `core::result::Result<_, _>`
         //~| expected enum `core::option::Option`
         //~| found enum `core::result::Result`
index 86a79416c77bc6807d16123c3d209a0170165608..f907be161fa0815a4fa5af331cf97386d1d1f347 100644 (file)
@@ -10,6 +10,8 @@
 
 // compile-flags:-Z verbose
 
+#![feature(slice_patterns)]
+
 fn main() {
     let x = [1,2];
     let y = match x {
index a345ce79612cc37ed80088b1b458b7ebc2820a47..2fbfd6cc84eadccb0a1a1e83cfc1ed0ad514e56d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 fn main() {
   let x = [1,2];
   let y = match x {
index 3f5d29a82175805b40221dac4818821908952190..51b6dc0d07865eda130cbc0e8633f90907501550 100644 (file)
@@ -17,9 +17,9 @@ mod a {
 
 fn main() {
     a::Foo::new();
-    //~^ ERROR: static method `new` is inaccessible
+    //~^ ERROR: method `new` is inaccessible
     //~^^ NOTE: struct `Foo` is private
     a::Bar::new();
-    //~^ ERROR: static method `new` is inaccessible
+    //~^ ERROR: method `new` is inaccessible
     //~^^ NOTE: enum `Bar` is private
 }
diff --git a/src/test/compile-fail/issue-13853-3.rs b/src/test/compile-fail/issue-13853-3.rs
deleted file mode 100644 (file)
index 7ca158c..0000000
+++ /dev/null
@@ -1,36 +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.
-
-#![crate_type = "lib"]
-
-use std::marker::PhantomData;
-
-enum NodeContents<'a> {
-    Children(Vec<Node<'a>>),
-}
-
-impl<'a> Drop for NodeContents<'a> {
-    //~^ ERROR cannot implement a destructor on a structure with type parameters
-    fn drop( &mut self ) {
-    }
-}
-
-struct Node<'a> {
-    contents: NodeContents<'a>,
-    marker: PhantomData<&'a ()>,
-}
-
-impl<'a> Node<'a> {
-    fn noName(contents: NodeContents<'a>) -> Node<'a> {
-        Node { contents: contents, marker: PhantomData }
-    }
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/issue-13853-4.rs b/src/test/compile-fail/issue-13853-4.rs
deleted file mode 100644 (file)
index b0db9e5..0000000
+++ /dev/null
@@ -1,21 +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.
-
-struct AutoBuilder<'a> {
-    context: &'a isize
-}
-
-impl<'a> Drop for AutoBuilder<'a> {
-    //~^ ERROR cannot implement a destructor on a structure with type parameters
-    fn drop(&mut self) {
-    }
-}
-
-fn main() {}
index 0ab37a888267f44eed1c158dc69f0ff1d3a3d038..c87dcb8ae79b21119b3b01b4ccd13b1afa1d4949 100644 (file)
@@ -11,4 +11,3 @@
 fn fn1(0: Box) {} //~ ERROR: wrong number of type arguments: expected 1, found 0
 
 fn main() {}
-
index 74eea0c57a01aaf3e29e86a5b197986134119815..ce5fa1f1fe1a5e66e4fc4cb9fc54f8d4de85c873 100644 (file)
@@ -29,7 +29,7 @@ impl Foo for *const BarTy {
         baz();
         //~^ ERROR: unresolved name `baz`. Did you mean to call `self.baz`?
         a;
-        //~^ ERROR: unresolved name `a`. Did you mean to call `BarTy::a`?
+        //~^ ERROR: unresolved name `a`
     }
 }
 
@@ -42,11 +42,11 @@ impl<'a> Foo for &'a BarTy {
         y;
         //~^ ERROR: unresolved name `y`. Did you mean `self.y`?
         a;
-        //~^ ERROR: unresolved name `a`. Did you mean to call `BarTy::a`?
+        //~^ ERROR: unresolved name `a`
         bah;
         //~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
         b;
-        //~^ ERROR: unresolved name `b`. Did you mean to call `self.b`?
+        //~^ ERROR: unresolved name `b`
     }
 }
 
@@ -59,11 +59,11 @@ impl<'a> Foo for &'a mut BarTy {
         y;
         //~^ ERROR: unresolved name `y`. Did you mean `self.y`?
         a;
-        //~^ ERROR: unresolved name `a`. Did you mean to call `BarTy::a`?
+        //~^ ERROR: unresolved name `a`
         bah;
         //~^ ERROR: unresolved name `bah`. Did you mean to call `Foo::bah`?
         b;
-        //~^ ERROR: unresolved name `b`. Did you mean to call `self.b`?
+        //~^ ERROR: unresolved name `b`
     }
 }
 
index d7ff6f2fe63ce38f423aad11654552febbbba6b6..3f994102a173e0853f052c0b7ba9f3d65e0864bc 100644 (file)
@@ -22,7 +22,7 @@ fn main() {
     //~| expected u8
     //~| found array of 1 elements
 
-    let local = [0u8];
+    let local: [u8; 1] = [0];
     let _v = &local as *mut u8;
     //~^ ERROR mismatched types
     //~| expected `*mut u8`
index 8f79022405ebe40139c5784530c59061018c5bfe..3853434e128ebd0b9465747277150ddf0c9fc41b 100644 (file)
@@ -16,11 +16,10 @@ struct Debuger<T> {
     x: T
 }
 
-impl<T: fmt::Debug> ops::Fn<(),> for Debuger<T> {
+impl<T: fmt::Debug> ops::FnOnce<(),> for Debuger<T> {
     type Output = ();
-
-    fn call(&self, _args: ()) {
-//~^ ERROR `call` has an incompatible type for trait: expected "rust-call" fn, found "Rust" fn
+    fn call_once(self, _args: ()) {
+//~^ ERROR `call_once` has an incompatible type for trait: expected "rust-call" fn, found "Rust" fn
         println!("{:?}", self.x);
     }
 }
index 817e4ae165031cd2fc47096f5c8363df68817ab4..653ba165e74397c256bba6d36e690fa98f684926 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 fn main() {
     let values: Vec<u8> = vec![1,2,3,4,5,6,7,8];
 
index a924cc9f9bbd5b23e69db20b753d0291e6f40922..4954c95fcd1f2ec307c4e997102ad1966024cc2c 100644 (file)
@@ -19,4 +19,3 @@ fn main() {
         _ => false
     };
 }
-
index ba936561ae53d9ed7bda362e5447369e62414755..ba369734daa47abd55b3b4444353e9eaa793dc96 100644 (file)
@@ -18,4 +18,3 @@ fn main() {
     //~| expected &-ptr
     //~| found struct `core::raw::Slice`
 }
-
diff --git a/src/test/compile-fail/issue-16465.rs b/src/test/compile-fail/issue-16465.rs
deleted file mode 100644 (file)
index 825b40c..0000000
+++ /dev/null
@@ -1,24 +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.
-
-// Used to cause an ICE
-
-struct Foo<T>{
-    x : T
-}
-
-type FooInt = Foo<isize>;
-
-impl Drop for FooInt {
-//~^ ERROR cannot implement a destructor on a structure with type parameters
-    fn drop(&mut self){}
-}
-
-fn main() {}
index 6d2cfcab04e36aa757cf40418f7127e917453590..a4e0f69b63b39e0b55c2353ca65c1d95221c6180 100644 (file)
@@ -19,8 +19,7 @@ mod Y {
 }
 
 static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
-//~^ ERROR cannot refer to other statics by value
-//~| ERROR the trait `core::marker::Sync` is not implemented for the type
+//~^ ERROR the trait `core::marker::Sync` is not implemented for the type
 //~| ERROR function calls in statics are limited to struct and enum constructors
 
 fn main() {}
index 218e9dba065b9ff0a0dfe62cf91550b4c4388cd2..cadf602a4cfc4aa962c34d062c130b721c7c7610 100644 (file)
@@ -8,12 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:issue-16725.rs
+// aux-build:issue_16725.rs
 
-extern crate "issue-16725" as foo;
+extern crate issue_16725 as foo;
 
 fn main() {
     unsafe { foo::bar(); }
     //~^ ERROR: function `bar` is private
 }
-
index a213234b89b0ff247c73f9ac27cf1fc0dfce01d3..64334fe4392f8774962a9c301aa109bc50bb0c1e 100644 (file)
@@ -18,11 +18,10 @@ trait Collection { fn len(&self) -> usize; }
 
 struct List<'a, T: ListItem<'a>> {
 //~^ ERROR the parameter type `T` may not live long enough
-//~^^ HELP consider adding an explicit lifetime bound
-//~^^^ NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at
+//~^^ NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at
     slice: &'a [T]
 }
-
+//~^ HELP consider adding an explicit lifetime bound
 impl<'a, T: ListItem<'a>> Collection for List<'a, T> {
     fn len(&self) -> usize {
         0
diff --git a/src/test/compile-fail/issue-16922.rs b/src/test/compile-fail/issue-16922.rs
new file mode 100644 (file)
index 0000000..b525d5f
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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 std::any::Any;
+
+fn foo<T: Any>(value: &T) -> Box<Any> {
+    Box::new(value) as Box<Any>
+    //~^ ERROR: cannot infer an appropriate lifetime
+}
+
+fn main() {
+    let _ = foo(&5);
+}
index 543063b3fc968a225f2eb99ef54ef7d2b4c3041d..f40d51f1d2fd3c59c3aef358a2ca1de3b5aef372 100644 (file)
 struct Foo { a: isize, b: isize }
 
 fn main() {
-    let mut x = box Foo { a: 1, b: 2 };
+    let mut x: Box<_> = box Foo { a: 1, b: 2 };
     let (a, b) = (&mut x.a, &mut x.b);
     //~^ ERROR cannot borrow `x` (here through borrowing `x.b`) as mutable more than once at a time
     //~^^ NOTE previous borrow of `x` occurs here (through borrowing `x.a`)
 
-    let mut foo = box Foo { a: 1, b: 2 };
+    let mut foo: Box<_> = box Foo { a: 1, b: 2 };
     let (c, d) = (&mut foo.a, &foo.b);
     //~^ ERROR cannot borrow `foo` (here through borrowing `foo.b`) as immutable
     //~^^ NOTE previous borrow of `foo` occurs here (through borrowing `foo.a`)
index 65731379094a9d1002508944b0d734c07dc9556a..a481fec6bf96839cb011e0dcc6f50ab1657ecee1 100644 (file)
@@ -16,7 +16,7 @@ struct Foo {
 }
 
 fn main() {
-    let x = 1_usize;
+    let x = 1;
     let y: Foo;
 
     // `x { ... }` should not be interpreted as a struct literal here
index 321b8b260daa9c6c04d2285889b108cce1c08dba..68ddef671887852f14b200910d6a2529ccf9be92 100644 (file)
@@ -8,18 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
-
 fn main() {
     let _foo = &[1_usize, 2] as [usize];
     //~^ ERROR cast to unsized type: `&[usize; 2]` as `[usize]`
     //~^^ HELP consider using an implicit coercion to `&[usize]` instead
-    let _bar = box 1_usize as std::fmt::Show;
-    //~^ ERROR cast to unsized type: `Box<usize>` as `core::fmt::Show`
-    //~^^ HELP did you mean `Box<core::fmt::Show>`?
-    let _baz = 1_usize as std::fmt::Show;
-    //~^ ERROR cast to unsized type: `usize` as `core::fmt::Show`
+
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let _bar = Box::new(1_usize) as std::fmt::Debug;
+    //~^ ERROR cast to unsized type: `Box<usize>` as `core::fmt::Debug`
+    //~^^ HELP did you mean `Box<core::fmt::Debug>`?
+
+    let _baz = 1_usize as std::fmt::Debug;
+    //~^ ERROR cast to unsized type: `usize` as `core::fmt::Debug`
     //~^^ HELP consider using a box or reference as appropriate
+
     let _quux = [1_usize, 2] as [usize];
     //~^ ERROR cast to unsized type: `[usize; 2]` as `[usize]`
     //~^^ HELP consider using a box or reference as appropriate
index 172f37af834400ba766388c9a2c8a54b4d8b779d..9e49abc463f15491906c9a402f844437ebdb980f 100644 (file)
 // Test that moves of unsized values within closures are caught
 // and rejected.
 
-#![feature(box_syntax)]
-
 fn main() {
-    (|| box *[0_usize].as_slice())();
-    //~^ ERROR cannot move out of borrowed content
-    //~^^ ERROR cannot move a value of type [usize]
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    (|| Box::new(*(&[0][..])))();
+    //~^ ERROR the trait `core::marker::Sized` is not implemented for the type `[_]`
 }
index 2347d3f3d5c0a66f675d1fa00792aa392db9bff8..6ee869d65a8f20f2078550262a1d73f25d8b4ace 100644 (file)
@@ -17,4 +17,3 @@ const C2: &'static mut usize = &mut S;
 //~^^ ERROR: references in constants may only refer to immutable values
 
 fn main() {}
-
index a9af30a3ff03db38ad4de825081c1754b1df4bac..021edbee566ba526514ac87f515df1bb23c716fa 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:issue-17718-const-privacy.rs
+// aux-build:issue_17718_const_privacy.rs
 
-extern crate "issue-17718-const-privacy" as other;
+extern crate issue_17718_const_privacy as other;
 
 use a::B; //~ ERROR: const `B` is private
 use other::{
index b7f58791bfcc8d32a6968938c8b5222beaccc1db..4e63f667d26fa413e83cc5d3c8ba988093c856a3 100644 (file)
@@ -13,7 +13,7 @@ static mut A2: usize = 1;
 const A3: usize = 1;
 
 fn main() {
-    match 1_usize {
+    match 1 {
         A1 => {} //~ ERROR: static variables cannot be referenced in a pattern
         A2 => {} //~ ERROR: static variables cannot be referenced in a pattern
         A3 => {}
index 8035cffabda9717aa51317533ca9ac4b19944c0c..80e5f2b6e2157917e943bc88a1397a720c917abd 100644 (file)
 #[cfg(target_pointer_width = "64")]
 fn main() {
     let n = 0_usize;
-    let a = box [&n; 0xF000000000000000_usize];
+    let a: Box<_> = box [&n; 0xF000000000000000_usize];
     println!("{}", a[0xFFFFFF_usize]);
 }
 
 #[cfg(target_pointer_width = "32")]
 fn main() {
     let n = 0_usize;
-    let a = box [&n; 0xFFFFFFFF_usize];
+    let a: Box<_> = box [&n; 0xFFFFFFFF_usize];
     println!("{}", a[0xFFFFFF_usize]);
 }
index bd0474084981f1164d795c996d9865c9c05f9499..657b31fa83c7f829419e5bf2aa88d9062c217e43 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub static X: usize = 1_usize;
+pub static X: usize = 1;
 
 fn main() {
-    match 1_usize {
+    match 1 {
         self::X => { },
         //~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead
         _       => { },
index d5fb22bdebdb477d5c03cb68f3abdf80e40aaf01..60ab616d5983bf25a4dcad218fa39f5a321caf18 100644 (file)
@@ -16,7 +16,7 @@ fn _create_render(_: &()) ->
     AbstractRenderer
 //~^ ERROR: the trait `core::marker::Sized` is not implemented
 {
-    match 0_usize {
+    match 0 {
         _ => unimplemented!()
     }
 }
index 54c51405bd73f8ad7f13068a7441b541fe189463..e3e56c7f97ad5ba400b76d5c622f5c694873b6db 100644 (file)
@@ -13,5 +13,5 @@ enum Foo {
 }
 
 fn main() {
-    let f = Foo::Variant(42_usize); //~ ERROR uses it like a function
+    let f = Foo::Variant(42); //~ ERROR uses it like a function
 }
index 20323e99003332bda38454e693b148ed2cf09bcc..271c31bd375484c6ef7c763e8c67f5079433ce75 100644 (file)
 
 use std::any::Any;
 use std::any::TypeId;
+use std::marker::MarkerTrait;
 
-pub trait Pt {}
-pub trait Rt {}
+pub trait Pt : MarkerTrait {}
+pub trait Rt : MarkerTrait {}
 
 trait Private<P: Pt, R: Rt> {
     fn call(&self, p: P, r: R);
 }
-pub trait Public: Private<
+pub trait Public: Private< //~ ERROR private trait in exported type parameter bound
     <Self as Public>::P,
-//~^ ERROR illegal recursive type; insert an enum or struct in the cycle, if this is desired
     <Self as Public>::R
 > {
     type P;
index 015f1fa603a2004ae08c5fcae9cff0af5295b7bb..f8d85f939374dabce61c3f7eeaa4f705b2fc0b5a 100644 (file)
@@ -33,7 +33,4 @@ fn main() {
 
     0.contains(bits);
     //~^ ERROR overflow
-    //~| ERROR overflow
-    //~| ERROR overflow
-    //~| ERROR mismatched types
 }
index dd3844b1a0ef07bae34d0d8d7e60fc1f3aba007c..41e82d0cd8912f1085856e03ce07fb66298d6a99 100644 (file)
@@ -28,7 +28,7 @@ impl Tr for usize {
 }
 
 fn main() {
-    let s = &mut 1_usize;
+    let s = &mut 1;
 
     MyPtr(s).poke(s);
     //~^ ERROR cannot borrow `*s` as mutable more than once at a time
index 13908bda9d83bf1e2d61f8d3304cc8144db12f97..5eb3c439df2f3170d5a2cafb8bb01f5f308777c7 100644 (file)
@@ -8,24 +8,24 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
-
 use std::cell::RefCell;
 
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
 fn main() {
-    let mut y = 1_usize;
+    let mut y = 1;
     let c = RefCell::new(vec![]);
-    c.push(box || y = 0);
-    c.push(box || y = 0);
+    c.push(Box::new(|| y = 0));
+    c.push(Box::new(|| y = 0));
 //~^ ERROR cannot borrow `y` as mutable more than once at a time
 }
 
 fn ufcs() {
-    let mut y = 1_usize;
+    let mut y = 1;
     let c = RefCell::new(vec![]);
 
-    Push::push(&c, box || y = 0);
-    Push::push(&c, box || y = 0);
+    Push::push(&c, Box::new(|| y = 0));
+    Push::push(&c, Box::new(|| y = 0));
 //~^ ERROR cannot borrow `y` as mutable more than once at a time
 }
 
diff --git a/src/test/compile-fail/issue-18919.rs b/src/test/compile-fail/issue-18919.rs
new file mode 100644 (file)
index 0000000..8c2c52e
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+type FuncType<'f> = Fn(&isize) -> isize + 'f;
+
+fn ho_func(f: Option<FuncType>) {
+    //~^ ERROR: the trait `core::marker::Sized` is not implemented for the type
+}
+
+fn main() {}
index 368f3c16f5188c47debf096ae1caedd17426be68..ebda2481803a7cef57f87661218d5831fa63fdef 100644 (file)
@@ -17,7 +17,11 @@ impl Foo for Thing {
     fn foo<T>(&self, _: &T) {}
 }
 
-#[inline(never)] fn foo(b: &Bar) { b.foo(&0_usize) }
+#[inline(never)]
+fn foo(b: &Bar) {
+    b.foo(&0)
+    //~^ ERROR the trait `Foo` is not implemented for the type `Bar`
+}
 
 fn main() {
     let mut thing = Thing;
index 0850705aee6cb1529f9dd323c6ab961e49a686d5..5c11787d46780bf5cf2740ed22ab54b3f1b661ee 100644 (file)
@@ -12,5 +12,7 @@ const TUP: (usize,) = (42,);
 
 fn main() {
     let a: [isize; TUP.1];
-    //~^ ERROR expected constant expr for array length: tuple index out of bounds
+    //~^ ERROR array length constant evaluation error: tuple index out of bounds
+    //~| ERROR attempted out-of-bounds tuple index
+    //~| ERROR attempted out-of-bounds tuple index
 }
index 93a3fc87eb0107198dd7f55571b281816f568024..d896f76865910820a5a4ddb401b650b90f9f6858 100644 (file)
@@ -13,5 +13,7 @@ const STRUCT: MyStruct = MyStruct { field: 42 };
 
 fn main() {
     let a: [isize; STRUCT.nonexistent_field];
-    //~^ ERROR expected constant expr for array length: nonexistent struct field
+    //~^ ERROR array length constant evaluation error: nonexistent struct field
+    //~| ERROR attempted access of field `nonexistent_field`
+    //~| ERROR attempted access of field `nonexistent_field`
 }
index 77aba7335bdf996cc9165263e73c13d2073254cf..4435ee0cb225dcf40360de9b05c1b5d3a4c68e30 100644 (file)
@@ -21,6 +21,6 @@ impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
 trait Sized : PhantomFn<Self> {}
 
 #[start]
-fn main(_: int, _: *const *const u8) -> int {
+fn main(_: isize, _: *const *const u8) -> isize {
     0
 }
index bbc5ee6c8f36e336e453eb9c0920de56faf1e0fb..c6ff82364b3e7cd57c279b9e4772aab1d386c51f 100644 (file)
@@ -15,18 +15,11 @@ trait From<Src> {
 }
 
 trait To {
-    // This is a typo, the return type should be `<Dst as From<Self>>::Output`
-    fn to<Dst: From<Self>>(
-        self
-        //~^ error: the trait `core::marker::Sized` is not implemented
-    ) ->
+    fn to<Dst: From<Self>>(self) ->
         <Dst as From<Self>>::Dst
-        //~^ error: the trait `core::marker::Sized` is not implemented
+        //~^ ERROR use of undeclared associated type `From::Dst`
     {
-        From::from(
-            //~^ error: the trait `core::marker::Sized` is not implemented
-            self
-        )
+        From::from(self)
     }
 }
 
diff --git a/src/test/compile-fail/issue-19982.rs b/src/test/compile-fail/issue-19982.rs
new file mode 100644 (file)
index 0000000..9dbca99
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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(unboxed_closures)]
+
+struct Foo;
+
+impl Fn<(&(),)> for Foo { } //~ ERROR missing lifetime specifier
+
+fn main() {}
index 2d73b98ec1e607d201c17318d507f78a9aca760e..6c9b0004f7754874e0f143038a15f8f8dd33b018 100644 (file)
@@ -14,9 +14,9 @@
 fn main() {
     if let Some(homura) = Some("madoka") { //~  ERROR missing an else clause
                                            //~| expected `()`
-                                           //~| found `i32`
+                                           //~| found `_`
                                            //~| expected ()
-                                           //~| found i32
-        765i32
+                                           //~| found integral variable
+        765
     };
 }
diff --git a/src/test/compile-fail/issue-20225.rs b/src/test/compile-fail/issue-20225.rs
new file mode 100644 (file)
index 0000000..fe427e0
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2015 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(unboxed_closures)]
+
+struct Foo;
+
+impl<'a, T> Fn<(&'a T,)> for Foo {
+  extern "rust-call" fn call(&self, (_,): (T,)) {}
+  //~^ ERROR: has an incompatible type for trait: expected &-ptr
+}
+
+impl<'a, T> FnMut<(&'a T,)> for Foo {
+  extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
+  //~^ ERROR: has an incompatible type for trait: expected &-ptr
+}
+
+impl<'a, T> FnOnce<(&'a T,)> for Foo {
+  type Output = ();
+
+  extern "rust-call" fn call_once(self, (_,): (T,)) {}
+  //~^ ERROR: has an incompatible type for trait: expected &-ptr
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-20261.rs b/src/test/compile-fail/issue-20261.rs
new file mode 100644 (file)
index 0000000..33e00f9
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+fn main() {
+    for (ref i,) in [].iter() { //~ ERROR: type mismatch resolving
+        i.clone();
+        //~^ ERROR: the type of this value must be known in this context
+        //~| ERROR: reached the recursion limit while auto-dereferencing
+    }
+}
diff --git a/src/test/compile-fail/issue-20714.rs b/src/test/compile-fail/issue-20714.rs
new file mode 100644 (file)
index 0000000..cb322f0
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2015 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 G;
+
+fn main() {
+    let g = G(); //~ ERROR: expected function, found `G`
+}
index 929c8ec0fd684eef81bed84c67e68fe818c201cd..fe7807042e55b706c3b8e2177a02d5b135012cb1 100644 (file)
@@ -25,11 +25,11 @@ fn mut_ref() -> &'static mut T {
 }
 
 fn mut_ptr() -> *mut T {
-    unsafe { 0u8 as *mut T }
+    unsafe { 0 as *mut T }
 }
 
 fn const_ptr() -> *const T {
-    unsafe { 0u8 as *const T }
+    unsafe { 0 as *const T }
 }
 
 pub fn main() {
index 5c1de6dfc55b46a0e2ed3055093d869ab8e08540..2bce838c1cfdc926bc32f1643b67666322a16a71 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:issue-21202.rs
+// aux-build:issue_21202.rs
 
-extern crate "issue-21202" as crate1;
+extern crate issue_21202 as crate1;
 
 use crate1::A;
 
@@ -18,7 +18,7 @@ mod B {
     use crate1::A::Foo;
     fn bar(f: Foo) {
         Foo::foo(&f);
-        //~^ ERROR: function `foo` is private
+        //~^ ERROR: method `foo` is private
     }
 }
 
index 37dbcaf39bd10ba17c99dfdc6c30f9a243a3a851..ea305c96af4a1efa39f788effa5df7a31b99aad8 100644 (file)
@@ -16,7 +16,8 @@ impl<A> vec_monad<A> for Vec<A> {
     fn bind<B, F>(&self, mut f: F) where F: FnMut(A) -> Vec<B> {
         let mut r = panic!();
         for elt in self { r = r + f(*elt); }
-        //~^ ERROR binary operation `+` cannot be applied to type `collections::vec::Vec<B>`
+        //~^ ERROR E0277
+        //~| ERROR E0277
    }
 }
 fn main() {
index 505885e6c41f9bdf7f3d309b79684c1ee44cf57d..8b109b0a5c04d9b7eae68158ee5e16e0ccbbb1d3 100644 (file)
@@ -15,7 +15,7 @@
 fn fail_len(v: Vec<isize> ) -> usize {
     let mut i = 3;
     panic!();
-    for x in &v { i += 1_usize; }
+    for x in &v { i += 1; }
     //~^ ERROR: unreachable statement
     return i;
 }
diff --git a/src/test/compile-fail/issue-22426-1.rs b/src/test/compile-fail/issue-22426-1.rs
new file mode 100644 (file)
index 0000000..f026a5d
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+fn main() {
+  match 42 {
+    x < 7 => (),
+   //~^ error: unexpected token: `<`
+    _ => ()
+  }
+}
diff --git a/src/test/compile-fail/issue-22426-2.rs b/src/test/compile-fail/issue-22426-2.rs
new file mode 100644 (file)
index 0000000..ea5180e
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2015 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.
+
+fn a(B<) {}
+   //~^ error: unexpected token: `<`
diff --git a/src/test/compile-fail/issue-22426-3.rs b/src/test/compile-fail/issue-22426-3.rs
new file mode 100644 (file)
index 0000000..2e0b5d6
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2015 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<T>(T, T);
+
+impl<T> Foo<T> {
+    fn foo(&self) {
+        match *self {
+            Foo<T>(x, y) => {
+            //~^ error: unexpected token: `<`
+              println!("Goodbye, World!")
+            }
+        }
+    }
+}
diff --git a/src/test/compile-fail/issue-22912.rs b/src/test/compile-fail/issue-22912.rs
new file mode 100644 (file)
index 0000000..f4536ce
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2015 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.
+
+pub struct PublicType;
+struct PrivateType;
+
+pub trait PublicTrait {
+    type Item;
+}
+
+trait PrivateTrait {
+    type Item;
+}
+
+impl PublicTrait for PublicType {
+    type Item = PrivateType;  //~ ERROR private type in exported type signature
+}
+
+// OK
+impl PublicTrait for PrivateType {
+    type Item = PrivateType;
+}
+
+// OK
+impl PrivateTrait for PublicType {
+    type Item = PrivateType;
+}
+
+// OK
+impl PrivateTrait for PrivateType {
+    type Item = PrivateType;
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-23080-2.rs b/src/test/compile-fail/issue-23080-2.rs
new file mode 100644 (file)
index 0000000..ff5ac9d
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2015 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.
+
+// ignore-tidy-linelength
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::MarkerTrait;
+
+unsafe trait Trait: MarkerTrait {
+//~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items
+    type Output;
+}
+
+unsafe impl Trait for .. {}
+
+fn call_method<T: Trait>(x: T) {}
+
+fn main() {
+    // ICE
+    call_method(());
+}
diff --git a/src/test/compile-fail/issue-23080.rs b/src/test/compile-fail/issue-23080.rs
new file mode 100644 (file)
index 0000000..99373a6
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+// ignore-tidy-linelength
+
+#![feature(optin_builtin_traits)]
+
+unsafe trait Trait {
+//~^ error: traits with default impls (`e.g. unsafe impl Trait for ..`) must have no methods or associated items
+    fn method(&self) {
+        println!("Hello");
+    }
+}
+
+unsafe impl Trait for .. {}
+
+fn call_method<T: Trait>(x: T) {
+    x.method();
+}
+
+fn main() {
+    // ICE
+    call_method(());
+}
index f0ae0eb59f532f768622a6f249f078161b039992..48cc27e228940b74f93d71640562f64224e88f59 100644 (file)
@@ -36,7 +36,7 @@ impl Groom for cat {
     shave(4);
     //~^ ERROR: unresolved name `shave`. Did you mean to call `Groom::shave`?
     purr();
-    //~^ ERROR: unresolved name `purr`. Did you mean to call `self.purr`?
+    //~^ ERROR: unresolved name `purr`
   }
 }
 
@@ -45,13 +45,13 @@ impl cat {
 
     fn purr_louder() {
         static_method();
-        //~^ ERROR: unresolved name `static_method`. Did you mean to call `cat::static_method`
+        //~^ ERROR: unresolved name `static_method`
         purr();
-        //~^ ERROR: unresolved name `purr`. Did you mean to call `self.purr`?
+        //~^ ERROR: unresolved name `purr`
         purr();
-        //~^ ERROR: unresolved name `purr`. Did you mean to call `self.purr`?
+        //~^ ERROR: unresolved name `purr`
         purr();
-        //~^ ERROR: unresolved name `purr`. Did you mean to call `self.purr`?
+        //~^ ERROR: unresolved name `purr`
     }
 }
 
@@ -65,7 +65,7 @@ impl cat {
 
   fn purr(&self) {
     grow_older();
-    //~^ ERROR: unresolved name `grow_older`. Did you mean to call `cat::grow_older`
+    //~^ ERROR: unresolved name `grow_older`
     shave();
     //~^ ERROR: unresolved name `shave`
   }
@@ -79,7 +79,7 @@ impl cat {
     whiskers = 4;
     //~^ ERROR: unresolved name `whiskers`. Did you mean `self.whiskers`?
     purr_louder();
-    //~^ ERROR: unresolved name `purr_louder`. Did you mean to call `cat::purr_louder`
+    //~^ ERROR: unresolved name `purr_louder`
   }
 }
 
index 1e8f81a05e7f9c51ba67ceb903c68f3f09bb1e33..c744dff0c04d46231f9b5385f317e061c87aa73e 100644 (file)
@@ -15,4 +15,3 @@ struct bar { x: bar }
 
 fn main() {
 }
-
index 678618d721692a9db1d3885679bba38fbacc1939..ad5bc4e445c9839b7ebc41064ef684f460087340 100644 (file)
@@ -11,7 +11,9 @@
 fn main() {
     let foo = 100;
 
-    static y: isize = foo + 1; //~ ERROR: attempt to use a non-constant value in a constant
+    static y: isize = foo + 1;
+    //~^ ERROR attempt to use a non-constant value in a constant
+    //~| ERROR unresolved name `foo`
 
     println!("{}", y);
 }
index c49959c16a62180c7c1b7276173585687d22c694..f06aa45ac38fd1848c106847d37e1e5421e717af 100644 (file)
@@ -13,7 +13,9 @@ fn main() {
 
     #[derive(Debug)]
     enum Stuff {
-        Bar = foo //~ ERROR attempt to use a non-constant value in a constant
+        Bar = foo
+        //~^ ERROR attempt to use a non-constant value in a constant
+        //~| ERROR unresolved name `foo`
     }
 
     println!("{}", Stuff::Bar);
index 0577b1527234d03b48c62f1d69ccc56909c7c9d9..a09c8090de06de5716e718d3d33e6291f7edfaf9 100644 (file)
@@ -9,7 +9,9 @@
 // except according to those terms.
 
 fn f(x:isize) {
-    static child: isize = x + 1; //~ ERROR attempt to use a non-constant value in a constant
+    static child: isize = x + 1;
+    //~^ ERROR attempt to use a non-constant value in a constant
+    //~| ERROR unresolved name `x`
 }
 
 fn main() {}
index 9c31dc1e38ef8ff312193b105a73e9346e9d0153..9b7476244f0d26a19e0d91639fea3c306c20406f 100644 (file)
@@ -17,6 +17,7 @@ impl PTrait for P {
    fn getChildOption(&self) -> Option<Box<P>> {
        static childVal: Box<P> = self.child.get();
        //~^ ERROR attempt to use a non-constant value in a constant
+       //~| ERROR unresolved name `self`
        panic!();
    }
 }
index 6e6c19a5bf6b08428a8024e7312b50edf5b2e927..085b4e76afbf71650fece23c0481522a9d9de5da 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
-
 mod my_mod {
     pub struct MyStruct {
         priv_field: isize
@@ -26,10 +24,15 @@ fn main() {
     let my_struct = my_mod::MyStruct();
     let _woohoo = (&my_struct).priv_field;
     //~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
-    let _woohoo = (box my_struct).priv_field;
+
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let _woohoo = (Box::new(my_struct)).priv_field;
     //~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
+
     (&my_struct).happyfun();               //~ ERROR method `happyfun` is private
-    (box my_struct).happyfun();            //~ ERROR method `happyfun` is private
+
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    (Box::new(my_struct)).happyfun();          //~ ERROR method `happyfun` is private
     let nope = my_struct.priv_field;
     //~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
 }
index 001de796b4ad75df9c916bec1ed06bd77238a422..a3d90a00d038ec14a4d2e218e20b167ddc8b88df 100644 (file)
@@ -28,4 +28,3 @@ fn main() {
     };
     s.bar();
 }
-
diff --git a/src/test/compile-fail/issue-3953.rs b/src/test/compile-fail/issue-3953.rs
deleted file mode 100644 (file)
index 0f1dd2d..0000000
+++ /dev/null
@@ -1,34 +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.
-
-// ignore-tidy-linelength
-
-use std::cmp::PartialEq;
-
-trait Hahaha: PartialEq + PartialEq {
-    //~^ ERROR trait `PartialEq` already appears in the list of bounds
-}
-
-struct Lol(isize);
-
-impl Hahaha for Lol { }
-
-impl PartialEq for Lol {
-    fn eq(&self, other: &Lol) -> bool { **self != **other }
-    fn ne(&self, other: &Lol) -> bool { **self == **other }
-}
-
-fn main() {
-    if Lol(2) == Lol(4) {
-        println!("2 == 4");
-    } else {
-        println!("2 != 4");
-    }
-}
index e4f7521c33303cc340faabfacff70c593b767580..2652fb5dfc2fd6dc453f73f1d3d9094847ccbe86 100644 (file)
@@ -30,7 +30,5 @@ impl ToString_ for Point {
 
 fn main() {
     let p = Point::new(0.0, 0.0);
-    //~^ ERROR unresolved name `Point::new`
-    //~^^ ERROR failed to resolve. Use of undeclared type or module `Point`
     println!("{}", p.to_string());
 }
index b4bc7ecdc5f89693cb35bb449882fdc9693bb247..553436607d159ca79a940c3bcb6da3ebb64a4b92 100644 (file)
@@ -17,7 +17,7 @@ impl Foo {
         Foo { baz: 0 }.bar();
     }
 
-    fn bar() { //~ ERROR duplicate definition of value `bar`
+    fn bar() { //~ ERROR duplicate method
     }
 }
 
index d0da51373d926fe599ee84da402673be3913f5d9..55a793f7480a42e1db237844f544e8271d6c0a10 100644 (file)
@@ -9,12 +9,14 @@
 // except according to those terms.
 
 #![feature(unboxed_closures)]
-#![feature(box_syntax)]
 
 fn id<T>(t: T) -> T { t }
 
 fn f<'r, T>(v: &'r T) -> Box<FnMut() -> T + 'r> {
-    id(box || *v) //~ ERROR cannot infer
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    id(Box::new(|| *v))
+        //~^ ERROR `v` does not live long enough
+        //~| ERROR cannot move out of borrowed content
 }
 
 fn main() {
index 6d4777be40b640829dd9bff83ec5c5d1a285b9a0..a1804b5a2689d92978d5a406bf73a3e3c26657fa 100644 (file)
@@ -11,7 +11,7 @@
 fn bar(int_param: usize) {}
 
 fn main() {
-    let foo: [u8; 4] = [1u8; 4_usize];
+    let foo: [u8; 4] = [1; 4];
     bar(foo);
     //~^ ERROR mismatched types
     //~| expected `usize`
index 49a43ee37adca88d9ec5224a79b161945a0354f0..1ebef06008ffa4f3c6b345dee1cd6110d7d62132 100644 (file)
@@ -12,5 +12,5 @@
 
 fn main() {
     let x = |ref x: isize| -> isize { x += 1; };
-    //~^ ERROR binary assignment operation `+=` cannot be applied to type `&isize`
+    //~^ ERROR E0368
 }
diff --git a/src/test/compile-fail/issue-5543.rs b/src/test/compile-fail/issue-5543.rs
deleted file mode 100644 (file)
index 4d721ad..0000000
+++ /dev/null
@@ -1,20 +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.
-
-#![feature(box_syntax)]
-
-trait Foo { fn foo(&self) {} }
-impl Foo for u8 {}
-
-fn main() {
-    let r: Box<Foo> = box 5;
-    let _m: Box<Foo> = r as Box<Foo>;
-    //~^ ERROR `core::marker::Sized` is not implemented for the type `Foo`
-}
index 6c85a97f7f57fe6106d1d0aefedea138b5641ad6..02e5b9b092197f94b08fe0a7452081a22002fe78 100644 (file)
@@ -15,4 +15,3 @@ extern crate issue_5844_aux;
 fn main () {
     issue_5844_aux::rand(); //~ ERROR: requires unsafe
 }
-
index 30d3ab17a463e6622480b0e22fbf7478b7b225a1..ffab194149e12c79ba1525339844aaf40e2739b4 100644 (file)
@@ -8,13 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(rustc_attrs)]
+#![feature(slice_patterns)]
 #![allow(dead_code)]
 
 // Matching against NaN should result in a warning
 
 use std::f64::NAN;
 
-fn main() {
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
     let x = NAN;
     match x {
         NAN => {},
@@ -27,7 +30,3 @@ fn main() {
     };
     //~^^^ WARNING unmatchable NaN in pattern, use the is_nan method in a guard instead
 }
-
-// At least one error is needed so that compilation fails
-#[static_assert]
-static B: bool = false; //~ ERROR static assertion failed
index b6643f439529b2a76c6b62a73ea4676dce30dc17..9c019f6ec47fb91a1d17733f737fd44083f7cc58 100644 (file)
@@ -32,17 +32,17 @@ trait UnusedTrait : MarkerTrait {
 
 impl CtxtFn for usize {
     fn f8(self, i: usize) -> usize {
-        i * 4_usize
+        i * 4
     }
 
     fn f9(i: usize) -> usize {
-        i * 4_usize
+        i * 4
     }
 }
 
 impl OtherTrait for usize {
     fn f9(i: usize) -> usize {
-        i * 8_usize
+        i * 8
     }
 }
 
index 48fc393d0da8e1cabeddd386cff78b130c727158..40c3d96bc9a119fb9eaf2bc3b5a5790df8d87d89 100644 (file)
@@ -8,15 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-tidy-linelength
-
 struct Foo {
     x: isize
 }
 
-impl Fo { //~ERROR inherent implementations are not allowed for types not defined in the current module
+impl Fo { //~ ERROR use of undeclared type name `Fo`
     fn foo() {}
 }
 
 fn main() {}
-
diff --git a/src/test/compile-fail/issue-7607-2.rs b/src/test/compile-fail/issue-7607-2.rs
deleted file mode 100644 (file)
index 9541899..0000000
+++ /dev/null
@@ -1,26 +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.
-
-// ignore-tidy-linelength
-
-pub mod a {
-    pub struct Foo { a: usize }
-}
-
-pub mod b {
-    use a::Foo;
-    impl Foo { //~ERROR inherent implementations are only allowed on types defined in the current module
-        fn bar(&self) { }
-    }
-}
-
-pub fn main() { }
-
-
index 7bb4aac23d65cebe30bb5c1857b80dd29c0dfd88..400806c3a5fa6cbfe7110e1b887212ac5be62181 100644 (file)
@@ -23,16 +23,16 @@ fn main() {
         _ => ()
     }
 
-    match &Some(42i32) {
+    match &Some(42) {
         Some(x) => (),
         //~^ ERROR mismatched types
-        //~| expected `&core::option::Option<i32>`
+        //~| expected `&core::option::Option<_>`
         //~| found `core::option::Option<_>`
         //~| expected &-ptr
         //~| found enum `core::option::Option`
         None => ()
         //~^ ERROR mismatched types
-        //~| expected `&core::option::Option<i32>`
+        //~| expected `&core::option::Option<_>`
         //~| found `core::option::Option<_>`
         //~| expected &-ptr
         //~| found enum `core::option::Option`
diff --git a/src/test/compile-fail/issue-7950.rs b/src/test/compile-fail/issue-7950.rs
new file mode 100644 (file)
index 0000000..01b90f5
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+// tests the good error message, not "missing module Foo" or something else unexpected
+
+struct Foo;
+
+fn main() {
+    Foo::bar(); //~ ERROR type `Foo` does not implement any method in scope named `bar`
+}
index 954ae8ebc48dd87df4dff656dee302492a309e1c..9c2e8d278ab0b8310db1190bd21c2ee27c824730 100644 (file)
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::{int, i8, i16, i32, i64};
+use std::{isize, i8, i16, i32, i64};
 use std::thread;
 
 fn main() {
-    assert!(thread::spawn(move|| { int::MIN / -1; }).join().is_err());
+    assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
     //~^ ERROR attempted to divide with overflow in a constant expression
     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
     //~^ ERROR attempted to divide with overflow in a constant expression
@@ -32,7 +32,7 @@ fn main() {
     //~^ ERROR attempted to divide by zero in a constant expression
     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
     //~^ ERROR attempted to divide by zero in a constant expression
-    assert!(thread::spawn(move|| { int::MIN % -1; }).join().is_err());
+    assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
     //~^ ERROR attempted remainder with overflow in a constant expression
     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
     //~^ ERROR attempted remainder with overflow in a constant expression
index 6c5bac5e0cb34bce3fbc4e38c6c300b23adc661c..9abd8c9e3fcda2acfa5c6b16255dcff546913d20 100644 (file)
@@ -10,9 +10,8 @@
 
 // ignore-tidy-linelength
 
-impl B { //~ERROR inherent implementations are not allowed for types not defined in the current module
+impl B { //~ ERROR use of undeclared type name `B`
 }
 
 fn main() {
 }
-
index 8aefc5919d13313ddf71a67d5d0fa9730447bb78..226734b84d63840f491057540147030aa62922a5 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Verify that single-variant enums cant be de-referenced
+// Verify that single-variant enums can't be de-referenced
 // Regression test for issue #9814
 
 enum Foo { Bar(isize) }
index 74e372e41eb0a1100821ef7fcaa9667a66932971..1925caf6870eef80aab0daa80651683ffbbe46d8 100644 (file)
@@ -17,7 +17,7 @@ fn assert_copy<T:Copy>() { }
 
 trait Dummy : MarkerTrait { }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct MyStruct {
     x: isize,
     y: isize,
@@ -80,4 +80,3 @@ fn test<'a,T,U:Copy>(_: &'a isize) {
 
 pub fn main() {
 }
-
diff --git a/src/test/compile-fail/kindck-destructor-owned.rs b/src/test/compile-fail/kindck-destructor-owned.rs
deleted file mode 100644 (file)
index 7f37041..0000000
+++ /dev/null
@@ -1,31 +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.
-
-
-struct Bar<'a> {
-    f: &'a isize,
-}
-
-impl<'a> Drop for Bar<'a> {
-//~^ ERROR E0141
-    fn drop(&mut self) {
-    }
-}
-
-struct Baz {
-    f: &'static isize,
-}
-
-impl Drop for Baz {
-    fn drop(&mut self) {
-    }
-}
-
-fn main() { }
index b575144f637f1e73629df653cb0ae1ea8a3974c2..fd0789421e0045fb4a5c45f25076c139a8ac7e2c 100644 (file)
@@ -21,7 +21,7 @@ impl<T:Copy> Foo for T {
 fn take_param<T:Foo>(foo: &T) { }
 
 fn main() {
-    let x = box 3;
+    let x: Box<_> = box 3;
     take_param(&x);
     //~^ ERROR the trait `core::marker::Copy` is not implemented
 }
index dffc8fa2abd70d95def12e4df2eb40fdf247cea3..71494fd5f38dcef2116756b89e57a7c6edabdb7f 100644 (file)
@@ -28,6 +28,7 @@ fn f<T>(val: T) {
     let a = &t as &Gettable<T>;
     //~^ ERROR the trait `core::marker::Send` is not implemented
     //~^^ ERROR the trait `core::marker::Copy` is not implemented
+    //~^^^ ERROR the parameter type `T` may not live long enough
 }
 
 fn g<T>(val: T) {
index 0072b1228af486d49b47c8e20f3c41c8dd8b83bc..066590252a54ad769fcb599e94f616d25770b598 100644 (file)
@@ -24,14 +24,14 @@ impl<T:Copy> Foo for T {
 fn take_param<T:Foo>(foo: &T) { }
 
 fn a() {
-    let x = box 3;
-    take_param(&x); //~ ERROR `core::marker::Copy` is not implemented
+    let x: Box<_> = box 3;
+    take_param(&x); //~ ERROR E0277
 }
 
 fn b() {
-    let x = box 3;
+    let x: Box<_> = box 3;
     let y = &x;
-    let z = &x as &Foo; //~ ERROR `core::marker::Copy` is not implemented
+    let z = &x as &Foo; //~ ERROR E0038
 }
 
 fn main() { }
index e6041cddeadb58adb75ac51e95abb70d7faf5352..bf2a209c4c48ed01a16223d5f0eaa474fef7a4eb 100644 (file)
@@ -16,8 +16,7 @@ fn foo(_x: Rc<usize>) {}
 fn bar<F:FnOnce() + Send>(_: F) { }
 
 fn main() {
-    let x = Rc::new(3_usize);
+    let x = Rc::new(3);
     bar(move|| foo(x));
     //~^ ERROR `core::marker::Send` is not implemented
 }
-
index 55cce0163354050ef534b03109b61b9b5202bce6..1fa7284f6b5dcab6e7a2726173b2c2ed7f34c427 100644 (file)
@@ -37,4 +37,3 @@ fn i(_x: isize) -> &isize { //~ ERROR missing lifetime specifier
 }
 
 fn main() {}
-
index fac518c7635692822d1e0e8746d3a8613663baea..d2d0dbf3e981fe3fa32a24d7eb7d9bd32b8cbac4 100644 (file)
 
 // ignore-tidy-linelength
 
-use std::iter::{Range,range};
+use std::ops::Range;
 
 trait Itble<'r, T, I: Iterator<Item=T>> { fn iter(&'r self) -> I; }
 
 impl<'r> Itble<'r, usize, Range<usize>> for (usize, usize) {
     fn iter(&'r self) -> Range<usize> {
         let &(min, max) = self;
-        range(min, max)
+        min..max
     }
 }
 
 fn check<'r, I: Iterator<Item=usize>, T: Itble<'r, usize, I>>(cont: &T) -> bool {
 //~^ HELP: consider using an explicit lifetime parameter as shown: fn check<'r, I: Iterator<Item = usize>, T: Itble<'r, usize, I>>(cont: &'r T)
     let cont_iter = cont.iter(); //~ ERROR: cannot infer
-    let result = cont_iter.fold(Some(0u16), |state, val| {
+    let result = cont_iter.fold(Some(0), |state, val| {
         state.map_or(None, |mask| {
             let bit = 1 << val;
             if mask & bit == 0 {Some(mask|bit)} else {None}
index 35f93c13fb5e23792d071df8a27293f168a4fb5d..555cc2b9a7aad95c8c43b10932550e08154b65c8 100644 (file)
@@ -11,5 +11,4 @@
 extern {
     #[linkage = "extern_weak"] static foo: isize;
     //~^ ERROR: the `linkage` attribute is experimental and not portable
-    //~^^ ERROR: the `linkage` attribute is experimental and not portable
 }
index c75c7002e5e0f95910ea14f431ab99e2d0ec53d7..8343f718902dc02f7ec291d1b69812b7bd906d3b 100644 (file)
@@ -18,4 +18,3 @@ extern {
 fn main() {
     println!("{:?}", foo);
 }
-
index f60c39ba020852c6d035808bc50eae46ff244ddd..ba1b7f03b0f419b2fe15570b7594b77bf4a93f7d 100644 (file)
@@ -19,7 +19,7 @@ extern crate libc;
 
 pub use extern_foo as x;
 extern {
-    fn extern_foo();
+    pub fn extern_foo();
 }
 
 struct Foo; //~ ERROR: struct is never used
@@ -86,6 +86,6 @@ mod inner {
 }
 
 pub fn foo() {
-    let a = &1 as &inner::Trait;
+    let a: &inner::Trait = &1_isize;
     a.f();
 }
index f304c26efb5417fccc7b3c60124e18059390bb8e..3a9baecb9c60e7b595702c82debaf74a76475466 100644 (file)
@@ -16,8 +16,6 @@
 
 extern crate libc;
 
-use std::num::Int;
-
 struct Foo {
     x: usize,
     b: bool, //~ ERROR: struct field is never used
@@ -63,6 +61,6 @@ fn field_match_in_let(f: Bar) -> bool {
 fn main() {
     field_read(Foo { x: 1, b: false, marker: std::marker::NoCopy });
     field_match_in_patterns(XYZ::Z);
-    field_match_in_let(Bar { x: 42_usize, b: true, _guard: () });
+    field_match_in_let(Bar { x: 42, b: true, _guard: () });
     let _ = Baz { x: 0 };
 }
index 345e56e2e5800a6cb776ee1481e84cfcd1a090bb..1f70828e411ef1cfc472b6ed1884690939457c71 100644 (file)
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(negate_unsigned)]
 #![deny(exceeding_bitshifts)]
 #![allow(unused_variables)]
 #![allow(dead_code)]
-#![feature(core)]
+#![feature(core, negate_unsigned)]
 
 fn main() {
       let n = 1u8 << 7;
@@ -60,4 +61,3 @@ fn main() {
       let n = 1_isize << std::isize::BITS; //~ ERROR: bitshift exceeds the type's number of bits
       let n = 1_usize << std::usize::BITS; //~ ERROR: bitshift exceeds the type's number of bits
 }
-
index 73a58741bbbbc42ddbcf7efa384d9d578f86fed4..04db6c8c8f39c97798136e1af46f2f2136b79143 100644 (file)
 #![doc="More garbage"]
 
 type Typedef = String;
-pub type PubTypedef = String; //~ ERROR: missing documentation
+pub type PubTypedef = String; //~ ERROR: missing documentation for a type alias
 
 struct Foo {
     a: isize,
     b: isize,
 }
 
-pub struct PubFoo { //~ ERROR: missing documentation
-    pub a: isize,      //~ ERROR: missing documentation
+pub struct PubFoo { //~ ERROR: missing documentation for a struct
+    pub a: isize,      //~ ERROR: missing documentation for a struct field
     b: isize,
 }
 
@@ -36,11 +36,11 @@ pub struct PubFoo2 {
 }
 
 mod module_no_dox {}
-pub mod pub_module_no_dox {} //~ ERROR: missing documentation
+pub mod pub_module_no_dox {} //~ ERROR: missing documentation for a module
 
 /// dox
 pub fn foo() {}
-pub fn foo2() {} //~ ERROR: missing documentation
+pub fn foo2() {} //~ ERROR: missing documentation for a function
 fn foo3() {}
 #[allow(missing_docs)] pub fn foo4() {}
 
@@ -58,9 +58,9 @@ trait B {
     fn foo_with_impl(&self) {}
 }
 
-pub trait C { //~ ERROR: missing documentation
-    fn foo(&self); //~ ERROR: missing documentation
-    fn foo_with_impl(&self) {} //~ ERROR: missing documentation
+pub trait C { //~ ERROR: missing documentation for a trait
+    fn foo(&self); //~ ERROR: missing documentation for a trait method
+    fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a trait method
 }
 
 #[allow(missing_docs)]
@@ -68,13 +68,26 @@ pub trait D {
     fn dummy(&self) { }
 }
 
+/// dox
+pub trait E {
+    type AssociatedType; //~ ERROR: missing documentation for an associated type
+    type AssociatedTypeDef = Self; //~ ERROR: missing documentation for an associated type
+
+    /// dox
+    type DocumentedType;
+    /// dox
+    type DocumentedTypeDef = Self;
+    /// dox
+    fn dummy(&self) {}
+}
+
 impl Foo {
     pub fn foo() {}
     fn bar() {}
 }
 
 impl PubFoo {
-    pub fn foo() {} //~ ERROR: missing documentation
+    pub fn foo() {} //~ ERROR: missing documentation for a method
     /// dox
     pub fn foo1() {}
     fn foo2() {}
@@ -111,9 +124,9 @@ enum Baz {
     BarB
 }
 
-pub enum PubBaz { //~ ERROR: missing documentation
-    PubBazA { //~ ERROR: missing documentation
-        a: isize, //~ ERROR: missing documentation
+pub enum PubBaz { //~ ERROR: missing documentation for an enum
+    PubBazA { //~ ERROR: missing documentation for a variant
+        a: isize, //~ ERROR: missing documentation for a struct field
     },
 }
 
@@ -139,14 +152,14 @@ pub fn baz() {}
 mod internal_impl {
     /// dox
     pub fn documented() {}
-    pub fn undocumented1() {} //~ ERROR: missing documentation
-    pub fn undocumented2() {} //~ ERROR: missing documentation
+    pub fn undocumented1() {} //~ ERROR: missing documentation for a function
+    pub fn undocumented2() {} //~ ERROR: missing documentation for a function
     fn undocumented3() {}
     /// dox
     pub mod globbed {
         /// dox
         pub fn also_documented() {}
-        pub fn also_undocumented1() {} //~ ERROR: missing documentation
+        pub fn also_undocumented1() {} //~ ERROR: missing documentation for a function
         fn also_undocumented2() {}
     }
 }
index 9f58d5791cb0bcbb07e14ad3ad0a2c1c93cc87e8..f6d3d62d0bf753bb0814887238f715610a8e34b8 100644 (file)
@@ -11,6 +11,9 @@
 #![forbid(non_camel_case_types)]
 #![allow(dead_code)]
 
+struct ONE_TWO_THREE;
+//~^ ERROR type `ONE_TWO_THREE` should have a camel case name such as `OneTwoThree`
+
 struct foo { //~ ERROR type `foo` should have a camel case name such as `Foo`
     bar: isize,
 }
index ec4e3c774dbf02d9e9aae57ef8b42788513cfdba..d95ed7f10bd17dfc63cb15e897c1f4bf85dc0339 100644 (file)
 
 #![feature(foo)] //~ ERROR unused or unknown feature
 
-extern crate lint_output_format; //~ WARNING: use of unstable library feature
+extern crate lint_output_format; //~ ERROR use of unstable library feature
 use lint_output_format::{foo, bar};
 
 fn main() {
     let _x = foo(); //~ WARNING #[warn(deprecated)] on by default
-    let _y = bar(); //~ WARNING: use of unstable library feature
+    let _y = bar(); //~ ERROR use of unstable library feature
 }
diff --git a/src/test/compile-fail/lint-stability-fields.rs b/src/test/compile-fail/lint-stability-fields.rs
new file mode 100644 (file)
index 0000000..716d767
--- /dev/null
@@ -0,0 +1,346 @@
+// Copyright 2015 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.
+
+// aux-build:lint_stability_fields.rs
+#![deny(deprecated)]
+#![allow(dead_code)]
+#![feature(staged_api)]
+#![staged_api]
+
+mod cross_crate {
+    extern crate lint_stability_fields;
+
+    use self::lint_stability_fields::*;
+
+    pub fn foo() {
+        let x = Stable {
+            inherit: 1,
+            override1: 2, //~ ERROR use of unstable
+            override2: 3,
+            //~^ ERROR use of deprecated item
+            //~^^ ERROR use of unstable
+        };
+
+        let _ = x.inherit;
+        let _ = x.override1; //~ ERROR use of unstable
+        let _ = x.override2;
+        //~^ ERROR use of deprecated item
+        //~^^ ERROR use of unstable
+
+        let Stable {
+            inherit: _,
+            override1: _, //~ ERROR use of unstable
+            override2: _
+            //~^ ERROR use of deprecated item
+            //~^^ ERROR use of unstable
+        } = x;
+        // all fine
+        let Stable { .. } = x;
+
+        let x = Stable2(1, 2, 3);
+
+        let _ = x.0;
+        let _ = x.1; //~ ERROR use of unstable
+        let _ = x.2;
+        //~^ ERROR use of deprecated item
+        //~^^ ERROR use of unstable
+
+        let Stable2(_,
+                   _, //~ ERROR use of unstable
+                   _)
+            //~^ ERROR use of deprecated item
+            //~^^ ERROR use of unstable
+            = x;
+        // all fine
+        let Stable2(..) = x;
+
+
+        let x = Unstable { //~ ERROR use of unstable
+            inherit: 1, //~ ERROR use of unstable
+            override1: 2,
+            override2: 3,
+            //~^ ERROR use of deprecated item
+            //~^^ ERROR use of unstable
+        };
+
+        let _ = x.inherit; //~ ERROR use of unstable
+        let _ = x.override1;
+        let _ = x.override2;
+        //~^ ERROR use of deprecated item
+        //~^^ ERROR use of unstable
+
+        let Unstable { //~ ERROR use of unstable
+            inherit: _, //~ ERROR use of unstable
+            override1: _,
+            override2: _
+            //~^ ERROR use of deprecated item
+            //~^^ ERROR use of unstable
+        } = x;
+
+        let Unstable  //~ ERROR use of unstable
+            // the patterns are all fine:
+            { .. } = x;
+
+
+        let x = Unstable2(1, 2, 3); //~ ERROR use of unstable
+
+        let _ = x.0; //~ ERROR use of unstable
+        let _ = x.1;
+        let _ = x.2;
+        //~^ ERROR use of deprecated item
+        //~^^ ERROR use of unstable
+
+        let Unstable2  //~ ERROR use of unstable
+            (_, //~ ERROR use of unstable
+             _,
+             _)
+            //~^ ERROR use of deprecated item
+            //~^^ ERROR use of unstable
+            = x;
+        let Unstable2 //~ ERROR use of unstable
+            // the patterns are all fine:
+            (..) = x;
+
+
+        let x = Deprecated {
+            //~^ ERROR use of deprecated item
+            //~^^ ERROR use of unstable
+            inherit: 1,
+            //~^ ERROR use of deprecated item
+            //~^^ ERROR use of unstable
+            override1: 2,
+            override2: 3, //~ ERROR use of unstable
+        };
+
+        let _ = x.inherit;
+        //~^ ERROR use of deprecated item
+        //~^^ ERROR use of unstable
+        let _ = x.override1;
+        let _ = x.override2; //~ ERROR use of unstable
+
+        let Deprecated {
+            //~^ ERROR use of deprecated item
+            //~^^ ERROR use of unstable
+            inherit: _,
+            //~^ ERROR use of deprecated item
+            //~^^ ERROR use of unstable
+            override1: _,
+            override2: _ //~ ERROR use of unstable
+        } = x;
+
+        let Deprecated
+            //~^ ERROR use of deprecated item
+            //~^^ ERROR use of unstable
+            // the patterns are all fine:
+            { .. } = x;
+
+        let x = Deprecated2(1, 2, 3);
+        //~^ ERROR use of deprecated item
+        //~^^ ERROR use of unstable
+
+        let _ = x.0;
+        //~^ ERROR use of deprecated item
+        //~^^ ERROR use of unstable
+        let _ = x.1;
+        let _ = x.2; //~ ERROR use of unstable
+
+        let Deprecated2
+        //~^ ERROR use of deprecated item
+        //~^^ ERROR use of unstable
+            (_,
+             //~^ ERROR use of deprecated item
+             //~^^ ERROR use of unstable
+             _,
+             _) //~ ERROR use of unstable
+            = x;
+        let Deprecated2
+        //~^ ERROR use of deprecated item
+        //~^^ ERROR use of unstable
+            // the patterns are all fine:
+            (..) = x;
+    }
+}
+
+mod this_crate {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    struct Stable {
+        inherit: u8,
+        #[unstable(feature = "test_feature")]
+        override1: u8,
+        #[deprecated(since = "1.0.0")]
+        #[unstable(feature = "test_feature")]
+        override2: u8,
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    struct Stable2(u8,
+                   #[stable(feature = "rust1", since = "1.0.0")] u8,
+                   #[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] u8);
+
+    #[unstable(feature = "test_feature")]
+    struct Unstable {
+        inherit: u8,
+        #[stable(feature = "rust1", since = "1.0.0")]
+        override1: u8,
+        #[deprecated(since = "1.0.0")]
+        #[unstable(feature = "test_feature")]
+        override2: u8,
+    }
+
+    #[unstable(feature = "test_feature")]
+    struct Unstable2(u8,
+                     #[stable(feature = "rust1", since = "1.0.0")] u8,
+                     #[unstable(feature = "test_feature")] #[deprecated(since = "1.0.0")] u8);
+
+    #[unstable(feature = "test_feature")]
+    #[deprecated(feature = "rust1", since = "1.0.0")]
+    struct Deprecated {
+        inherit: u8,
+        #[stable(feature = "rust1", since = "1.0.0")]
+        override1: u8,
+        #[unstable(feature = "test_feature")]
+        override2: u8,
+    }
+
+    #[unstable(feature = "test_feature")]
+    #[deprecated(feature = "rust1", since = "1.0.0")]
+    struct Deprecated2(u8,
+                       #[stable(feature = "rust1", since = "1.0.0")] u8,
+                       #[unstable(feature = "test_feature")] u8);
+
+    pub fn foo() {
+        let x = Stable {
+            inherit: 1,
+            override1: 2,
+            override2: 3,
+            //~^ ERROR use of deprecated item
+        };
+
+        let _ = x.inherit;
+        let _ = x.override1;
+        let _ = x.override2;
+        //~^ ERROR use of deprecated item
+
+        let Stable {
+            inherit: _,
+            override1: _,
+            override2: _
+            //~^ ERROR use of deprecated item
+        } = x;
+        // all fine
+        let Stable { .. } = x;
+
+        let x = Stable2(1, 2, 3);
+
+        let _ = x.0;
+        let _ = x.1;
+        let _ = x.2;
+        //~^ ERROR use of deprecated item
+
+        let Stable2(_,
+                   _,
+                   _)
+            //~^ ERROR use of deprecated item
+            = x;
+        // all fine
+        let Stable2(..) = x;
+
+
+        let x = Unstable {
+            inherit: 1,
+            override1: 2,
+            override2: 3,
+            //~^ ERROR use of deprecated item
+        };
+
+        let _ = x.inherit;
+        let _ = x.override1;
+        let _ = x.override2;
+        //~^ ERROR use of deprecated item
+
+        let Unstable {
+            inherit: _,
+            override1: _,
+            override2: _
+            //~^ ERROR use of deprecated item
+        } = x;
+
+        let Unstable
+            // the patterns are all fine:
+            { .. } = x;
+
+
+        let x = Unstable2(1, 2, 3);
+
+        let _ = x.0;
+        let _ = x.1;
+        let _ = x.2;
+        //~^ ERROR use of deprecated item
+
+        let Unstable2
+            (_,
+             _,
+             _)
+            //~^ ERROR use of deprecated item
+            = x;
+        let Unstable2
+            // the patterns are all fine:
+            (..) = x;
+
+
+        let x = Deprecated {
+            //~^ ERROR use of deprecated item
+            inherit: 1,
+            //~^ ERROR use of deprecated item
+            override1: 2,
+            override2: 3,
+        };
+
+        let _ = x.inherit;
+        //~^ ERROR use of deprecated item
+        let _ = x.override1;
+        let _ = x.override2;
+
+        let Deprecated {
+            //~^ ERROR use of deprecated item
+            inherit: _,
+            //~^ ERROR use of deprecated item
+            override1: _,
+            override2: _
+        } = x;
+
+        let Deprecated
+            //~^ ERROR use of deprecated item
+            // the patterns are all fine:
+            { .. } = x;
+
+        let x = Deprecated2(1, 2, 3);
+        //~^ ERROR use of deprecated item
+
+        let _ = x.0;
+        //~^ ERROR use of deprecated item
+        let _ = x.1;
+        let _ = x.2;
+
+        let Deprecated2
+        //~^ ERROR use of deprecated item
+            (_,
+             //~^ ERROR use of deprecated item
+             _,
+             _)
+            = x;
+        let Deprecated2
+        //~^ ERROR use of deprecated item
+            // the patterns are all fine:
+            (..) = x;
+    }
+}
+
+fn main() {}
index 88f2cbdea6d7bf81332f15efb3caf5e1dc4e6d47..391b49e10686ec41e68c71e30bcad03ec60573af 100644 (file)
@@ -24,73 +24,132 @@ extern crate lint_stability;
 
 mod cross_crate {
     extern crate stability_cfg1;
-    extern crate stability_cfg2; //~ WARNING: use of unstable library feature
+    extern crate stability_cfg2; //~ ERROR use of unstable library feature
 
     use lint_stability::*;
 
     fn test() {
+        type Foo = MethodTester;
         let foo = MethodTester;
 
         deprecated(); //~ ERROR use of deprecated item
         foo.method_deprecated(); //~ ERROR use of deprecated item
+        Foo::method_deprecated(&foo); //~ ERROR use of deprecated item
+        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item
         foo.trait_deprecated(); //~ ERROR use of deprecated item
+        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
+        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
+        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item
 
         deprecated_text(); //~ ERROR use of deprecated item: text
         foo.method_deprecated_text(); //~ ERROR use of deprecated item: text
+        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
+        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
         foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
+        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
+        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
 
         deprecated_unstable(); //~ ERROR use of deprecated item
-        //~^ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
         foo.method_deprecated_unstable(); //~ ERROR use of deprecated item
-        //~^ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
+        Foo::method_deprecated_unstable(&foo); //~ ERROR use of deprecated item
+        //~^ ERROR use of unstable library feature
+        <Foo>::method_deprecated_unstable(&foo); //~ ERROR use of deprecated item
+        //~^ ERROR use of unstable library feature
         foo.trait_deprecated_unstable(); //~ ERROR use of deprecated item
-        //~^ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
+        Trait::trait_deprecated_unstable(&foo); //~ ERROR use of deprecated item
+        //~^ ERROR use of unstable library feature
+        <Foo>::trait_deprecated_unstable(&foo); //~ ERROR use of deprecated item
+        //~^ ERROR use of unstable library feature
+        <Foo as Trait>::trait_deprecated_unstable(&foo); //~ ERROR use of deprecated item
+        //~^ ERROR use of unstable library feature
 
         deprecated_unstable_text(); //~ ERROR use of deprecated item: text
-        //~^ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
         foo.method_deprecated_unstable_text(); //~ ERROR use of deprecated item: text
-        //~^ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
+        Foo::method_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
+        //~^ ERROR use of unstable library feature
+        <Foo>::method_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
+        //~^ ERROR use of unstable library feature
         foo.trait_deprecated_unstable_text(); //~ ERROR use of deprecated item: text
-        //~^ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
+        Trait::trait_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
+        //~^ ERROR use of unstable library feature
+        <Foo>::trait_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
+        //~^ ERROR use of unstable library feature
+        <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
+        //~^ ERROR use of unstable library feature
+
+        unstable(); //~ ERROR use of unstable library feature
+        foo.method_unstable(); //~ ERROR use of unstable library feature
+        Foo::method_unstable(&foo); //~ ERROR use of unstable library feature
+        <Foo>::method_unstable(&foo); //~ ERROR use of unstable library feature
+        foo.trait_unstable(); //~ ERROR use of unstable library feature
+        Trait::trait_unstable(&foo); //~ ERROR use of unstable library feature
+        <Foo>::trait_unstable(&foo); //~ ERROR use of unstable library feature
+        <Foo as Trait>::trait_unstable(&foo); //~ ERROR use of unstable library feature
 
-        unstable(); //~ WARNING use of unstable library feature
-        foo.method_unstable(); //~ WARNING use of unstable library feature
-        foo.trait_unstable(); //~ WARNING use of unstable library feature
-
-        unstable_text(); //~ WARNING use of unstable library feature 'test_feature': text
-        foo.method_unstable_text(); //~ WARNING use of unstable library feature 'test_feature': text
-        foo.trait_unstable_text(); //~ WARNING use of unstable library feature 'test_feature': text
+        unstable_text();
+        //~^ ERROR use of unstable library feature 'test_feature': text
+        foo.method_unstable_text();
+        //~^ ERROR use of unstable library feature 'test_feature': text
+        Foo::method_unstable_text(&foo);
+        //~^ ERROR use of unstable library feature 'test_feature': text
+        <Foo>::method_unstable_text(&foo);
+        //~^ ERROR use of unstable library feature 'test_feature': text
+        foo.trait_unstable_text();
+        //~^ ERROR use of unstable library feature 'test_feature': text
+        Trait::trait_unstable_text(&foo);
+        //~^ ERROR use of unstable library feature 'test_feature': text
+        <Foo>::trait_unstable_text(&foo);
+        //~^ ERROR use of unstable library feature 'test_feature': text
+        <Foo as Trait>::trait_unstable_text(&foo);
+        //~^ ERROR use of unstable library feature 'test_feature': text
 
         stable();
         foo.method_stable();
+        Foo::method_stable(&foo);
+        <Foo>::method_stable(&foo);
         foo.trait_stable();
+        Trait::trait_stable(&foo);
+        <Foo>::trait_stable(&foo);
+        <Foo as Trait>::trait_stable(&foo);
 
         stable_text();
         foo.method_stable_text();
+        Foo::method_stable_text(&foo);
+        <Foo>::method_stable_text(&foo);
         foo.trait_stable_text();
+        Trait::trait_stable_text(&foo);
+        <Foo>::trait_stable_text(&foo);
+        <Foo as Trait>::trait_stable_text(&foo);
 
         let _ = DeprecatedStruct { i: 0 }; //~ ERROR use of deprecated item
         let _ = DeprecatedUnstableStruct { i: 0 }; //~ ERROR use of deprecated item
-        //~^ WARNING use of unstable library feature
-        let _ = UnstableStruct { i: 0 }; //~ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
+        let _ = UnstableStruct { i: 0 }; //~ ERROR use of unstable library feature
         let _ = StableStruct { i: 0 };
 
         let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item
         let _ = DeprecatedUnstableUnitStruct; //~ ERROR use of deprecated item
-        //~^ WARNING use of unstable library feature
-        let _ = UnstableUnitStruct; //~ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
+        let _ = UnstableUnitStruct; //~ ERROR use of unstable library feature
         let _ = StableUnitStruct;
 
         let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item
         let _ = Enum::DeprecatedUnstableVariant; //~ ERROR use of deprecated item
-        //~^ WARNING use of unstable library feature
-        let _ = Enum::UnstableVariant; //~ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
+        let _ = Enum::UnstableVariant; //~ ERROR use of unstable library feature
         let _ = Enum::StableVariant;
 
         let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item
         let _ = DeprecatedUnstableTupleStruct (1); //~ ERROR use of deprecated item
-        //~^ WARNING use of unstable library feature
-        let _ = UnstableTupleStruct (1); //~ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
+        let _ = UnstableTupleStruct (1); //~ ERROR use of unstable library feature
         let _ = StableTupleStruct (1);
 
         // At the moment, the lint checker only checks stability in
@@ -100,65 +159,97 @@ mod cross_crate {
         // on macros themselves are not yet linted.
         macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated item: text
         macro_test_arg!(deprecated_unstable_text()); //~ ERROR use of deprecated item: text
-        //~^ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
         macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated item: text
     }
 
-    fn test_method_param<F: Trait>(foo: F) {
+    fn test_method_param<Foo: Trait>(foo: Foo) {
         foo.trait_deprecated(); //~ ERROR use of deprecated item
+        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
+        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
+        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item
         foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
+        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
+        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
         foo.trait_deprecated_unstable(); //~ ERROR use of deprecated item
-        //~^ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
+        Trait::trait_deprecated_unstable(&foo); //~ ERROR use of deprecated item
+        //~^ ERROR use of unstable library feature
+        <Foo>::trait_deprecated_unstable(&foo); //~ ERROR use of deprecated item
+        //~^ ERROR use of unstable library feature
+        <Foo as Trait>::trait_deprecated_unstable(&foo); //~ ERROR use of deprecated item
+        //~^ ERROR use of unstable library feature
         foo.trait_deprecated_unstable_text(); //~ ERROR use of deprecated item: text
-        //~^ WARNING use of unstable library feature
-        foo.trait_unstable(); //~ WARNING use of unstable library feature
-        foo.trait_unstable_text(); //~ WARNING use of unstable library feature 'test_feature': text
+        //~^ ERROR use of unstable library feature
+        Trait::trait_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
+        //~^ ERROR use of unstable library feature
+        <Foo>::trait_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
+        //~^ ERROR use of unstable library feature
+        <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ ERROR use of deprecated item: text
+        //~^ ERROR use of unstable library feature
+        foo.trait_unstable(); //~ ERROR use of unstable library feature
+        Trait::trait_unstable(&foo); //~ ERROR use of unstable library feature
+        <Foo>::trait_unstable(&foo); //~ ERROR use of unstable library feature
+        <Foo as Trait>::trait_unstable(&foo); //~ ERROR use of unstable library feature
+        foo.trait_unstable_text();
+        //~^ ERROR use of unstable library feature 'test_feature': text
+        Trait::trait_unstable_text(&foo);
+        //~^ ERROR use of unstable library feature 'test_feature': text
+        <Foo>::trait_unstable_text(&foo);
+        //~^ ERROR use of unstable library feature 'test_feature': text
+        <Foo as Trait>::trait_unstable_text(&foo);
+        //~^ ERROR use of unstable library feature 'test_feature': text
         foo.trait_stable();
+        Trait::trait_stable(&foo);
+        <Foo>::trait_stable(&foo);
+        <Foo as Trait>::trait_stable(&foo);
     }
 
     fn test_method_object(foo: &Trait) {
         foo.trait_deprecated(); //~ ERROR use of deprecated item
         foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
         foo.trait_deprecated_unstable(); //~ ERROR use of deprecated item
-        //~^ WARNING use of unstable library feature
+        //~^ ERROR use of unstable library feature
         foo.trait_deprecated_unstable_text(); //~ ERROR use of deprecated item: text
-        //~^ WARNING use of unstable library feature
-        foo.trait_unstable(); //~ WARNING use of unstable library feature
-        foo.trait_unstable_text(); //~ WARNING use of unstable library feature 'test_feature': text
+        //~^ ERROR use of unstable library feature
+        foo.trait_unstable(); //~ ERROR use of unstable library feature
+        foo.trait_unstable_text();
+        //~^ ERROR use of unstable library feature 'test_feature': text
         foo.trait_stable();
     }
 
     struct S;
 
-    impl UnstableTrait for S { } //~ WARNING use of unstable library feature
+    impl UnstableTrait for S { } //~ ERROR use of unstable library feature
 
-    trait LocalTrait : UnstableTrait { } //~ WARNING use of unstable library feature
+    trait LocalTrait : UnstableTrait { } //~ ERROR use of unstable library feature
 
     impl Trait for S {
         fn trait_stable(&self) {}
-        fn trait_unstable(&self) {} //~ WARNING use of unstable library feature
+        fn trait_unstable(&self) {} //~ ERROR use of unstable library feature
     }
 }
 
 mod inheritance {
-    extern crate inherited_stability; //~ WARNING: use of unstable library feature
-    use self::inherited_stability::*; //~ WARNING: use of unstable library feature
+    extern crate inherited_stability; //~ ERROR use of unstable library feature
+    use self::inherited_stability::*; //~ ERROR use of unstable library feature
 
     fn test_inheritance() {
-        unstable(); //~ WARNING use of unstable library feature
+        unstable(); //~ ERROR use of unstable library feature
         stable();
 
-        stable_mod::unstable(); //~ WARNING use of unstable library feature
+        stable_mod::unstable(); //~ ERROR use of unstable library feature
         stable_mod::stable();
 
         unstable_mod::deprecated(); //~ ERROR use of deprecated item
-        unstable_mod::unstable(); //~ WARNING use of unstable library feature
+        unstable_mod::unstable(); //~ ERROR use of unstable library feature
 
-        let _ = Unstable::UnstableVariant; //~ WARNING use of unstable library feature
+        let _ = Unstable::UnstableVariant; //~ ERROR use of unstable library feature
         let _ = Unstable::StableVariant;
 
         let x: usize = 0;
-        x.unstable(); //~ WARNING use of unstable library feature
+        x.unstable(); //~ ERROR use of unstable library feature
         x.stable();
     }
 }
@@ -226,11 +317,17 @@ mod this_crate {
 
     #[unstable(feature = "test_feature")]
     #[deprecated(since = "1.0.0")]
-    pub struct DeprecatedStruct { i: isize }
+    pub struct DeprecatedStruct {
+        #[stable(feature = "test_feature", since = "1.0.0")] i: isize
+    }
     #[unstable(feature = "test_feature")]
-    pub struct UnstableStruct { i: isize }
+    pub struct UnstableStruct {
+        #[stable(feature = "test_feature", since = "1.0.0")] i: isize
+    }
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub struct StableStruct { i: isize }
+    pub struct StableStruct {
+        #[stable(feature = "test_feature", since = "1.0.0")] i: isize
+    }
 
     #[unstable(feature = "test_feature")]
     #[deprecated(since = "1.0.0")]
@@ -264,31 +361,62 @@ mod this_crate {
         // errors, because other stability attributes now have meaning
         // only *across* crates, not within a single crate.
 
+        type Foo = MethodTester;
         let foo = MethodTester;
 
         deprecated(); //~ ERROR use of deprecated item
         foo.method_deprecated(); //~ ERROR use of deprecated item
+        Foo::method_deprecated(&foo); //~ ERROR use of deprecated item
+        <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated item
         foo.trait_deprecated(); //~ ERROR use of deprecated item
+        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
+        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
+        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item
 
         deprecated_text(); //~ ERROR use of deprecated item: text
         foo.method_deprecated_text(); //~ ERROR use of deprecated item: text
+        Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
+        <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated item: text
         foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
+        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
+        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
 
         unstable();
         foo.method_unstable();
+        Foo::method_unstable(&foo);
+        <Foo>::method_unstable(&foo);
         foo.trait_unstable();
+        Trait::trait_unstable(&foo);
+        <Foo>::trait_unstable(&foo);
+        <Foo as Trait>::trait_unstable(&foo);
 
         unstable_text();
         foo.method_unstable_text();
+        Foo::method_unstable_text(&foo);
+        <Foo>::method_unstable_text(&foo);
         foo.trait_unstable_text();
+        Trait::trait_unstable_text(&foo);
+        <Foo>::trait_unstable_text(&foo);
+        <Foo as Trait>::trait_unstable_text(&foo);
 
         stable();
         foo.method_stable();
+        Foo::method_stable(&foo);
+        <Foo>::method_stable(&foo);
         foo.trait_stable();
+        Trait::trait_stable(&foo);
+        <Foo>::trait_stable(&foo);
+        <Foo as Trait>::trait_stable(&foo);
 
         stable_text();
         foo.method_stable_text();
+        Foo::method_stable_text(&foo);
+        <Foo>::method_stable_text(&foo);
         foo.trait_stable_text();
+        Trait::trait_stable_text(&foo);
+        <Foo>::trait_stable_text(&foo);
+        <Foo as Trait>::trait_stable_text(&foo);
 
         let _ = DeprecatedStruct { i: 0 }; //~ ERROR use of deprecated item
         let _ = UnstableStruct { i: 0 };
@@ -307,12 +435,27 @@ mod this_crate {
         let _ = StableTupleStruct (1);
     }
 
-    fn test_method_param<F: Trait>(foo: F) {
+    fn test_method_param<Foo: Trait>(foo: Foo) {
         foo.trait_deprecated(); //~ ERROR use of deprecated item
+        Trait::trait_deprecated(&foo); //~ ERROR use of deprecated item
+        <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated item
+        <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated item
         foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
+        Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
+        <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
+        <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated item: text
         foo.trait_unstable();
+        Trait::trait_unstable(&foo);
+        <Foo>::trait_unstable(&foo);
+        <Foo as Trait>::trait_unstable(&foo);
         foo.trait_unstable_text();
+        Trait::trait_unstable_text(&foo);
+        <Foo>::trait_unstable_text(&foo);
+        <Foo as Trait>::trait_unstable_text(&foo);
         foo.trait_stable();
+        Trait::trait_stable(&foo);
+        <Foo>::trait_stable(&foo);
+        <Foo as Trait>::trait_stable(&foo);
     }
 
     fn test_method_object(foo: &Trait) {
index 88a93134b47c0f427b63e0bd39c5f2675c849521..44a36f215f3d4c6e8c2100e0954635da8674e1de 100644 (file)
@@ -22,4 +22,3 @@ use lint_stability::*;
 fn main() {
     macro_test_arg_nested!(deprecated_text);
 }
-
index c00bd2adaa2876c2c03837b880692f196a4d9a3f..798dc112b0af995b6b10a8b8d772b03e707e3190 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(negate_unsigned)]
 #![allow(dead_code)]
+#![feature(negate_unsigned)]
 
 // compile-flags: -D unused-comparisons
 fn main() { }
@@ -50,12 +52,12 @@ fn qux() {
 }
 
 fn quy() {
-    let i = -23_usize; //~ WARNING negation of unsigned int literal may be unintentional
+    let i = -23_us; //~ WARNING negation of unsigned int literal may be unintentional
                   //~^ WARNING unused variable
 }
 
 fn quz() {
-    let i = 23_usize;
+    let i = 23_us;
     let j = -i;   //~ WARNING negation of unsigned int variable may be unintentional
                   //~^ WARNING unused variable
 }
diff --git a/src/test/compile-fail/lint-unnecessary-casts.rs b/src/test/compile-fail/lint-unnecessary-casts.rs
deleted file mode 100644 (file)
index b3cf825..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2013 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.
-
-#![forbid(unused_typecasts)]
-
-fn foo_i32(_: i32) {}
-
-fn foo_u64(a: u64) {
-    let b: i32 = a as i32;
-    foo_i32(b as i32); //~ ERROR: unnecessary type cast
-}
-
-fn main() {
-    let x: u64 = 1;
-    let y: u64 = x as u64; //~ ERROR: unnecessary type cast
-    foo_u64(y as u64); //~ ERROR: unnecessary type cast
-}
diff --git a/src/test/compile-fail/lint-unsafe-block.rs b/src/test/compile-fail/lint-unsafe-block.rs
deleted file mode 100644 (file)
index 56d2b2c..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2013 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(unused_unsafe)]
-#![allow(dead_code)]
-#![deny(unsafe_blocks)]
-unsafe fn allowed() {}
-
-#[allow(unsafe_blocks)] fn also_allowed() { unsafe {} }
-
-macro_rules! unsafe_in_macro {
-    () => {
-        unsafe {} //~ ERROR: usage of an `unsafe` block
-    }
-}
-
-fn main() {
-    unsafe {} //~ ERROR: usage of an `unsafe` block
-
-    unsafe_in_macro!()
-}
diff --git a/src/test/compile-fail/lint-unsafe-code.rs b/src/test/compile-fail/lint-unsafe-code.rs
new file mode 100644 (file)
index 0000000..8440cf3
--- /dev/null
@@ -0,0 +1,102 @@
+// Copyright 2013-2015 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(unused_unsafe)]
+#![allow(dead_code)]
+#![deny(unsafe_code)]
+
+use std::marker::PhantomFn;
+
+struct Bar;
+struct Bar2;
+struct Bar3;
+
+#[allow(unsafe_code)]
+mod allowed_unsafe {
+    use std::marker::PhantomFn;
+    fn allowed() { unsafe {} }
+    unsafe fn also_allowed() {}
+    unsafe trait AllowedUnsafe : PhantomFn<Self> {}
+    unsafe impl AllowedUnsafe for super::Bar {}
+}
+
+macro_rules! unsafe_in_macro {
+    () => {
+        unsafe {} //~ ERROR: usage of an `unsafe` block
+    }
+}
+
+unsafe fn baz() {} //~ ERROR: declaration of an `unsafe` function
+unsafe trait Foo : PhantomFn<Self> {} //~ ERROR: declaration of an `unsafe` trait
+unsafe impl Foo for Bar {} //~ ERROR: implementation of an `unsafe` trait
+
+trait Baz {
+    unsafe fn baz(&self); //~ ERROR: declaration of an `unsafe` method
+    unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method
+    unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+impl Baz for Bar {
+    unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method
+    unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+
+#[allow(unsafe_code)]
+trait A {
+    unsafe fn allowed_unsafe(&self);
+    unsafe fn allowed_unsafe_provided(&self) {}
+}
+
+#[allow(unsafe_code)]
+impl Baz for Bar2 {
+    unsafe fn baz(&self) {}
+    unsafe fn provided_override(&self) {}
+}
+
+impl Baz for Bar3 {
+    #[allow(unsafe_code)]
+    unsafe fn baz(&self) {}
+    unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+#[allow(unsafe_code)]
+unsafe trait B {
+    fn dummy(&self) {}
+}
+
+trait C {
+    #[allow(unsafe_code)]
+    unsafe fn baz(&self);
+    unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+impl C for Bar {
+    #[allow(unsafe_code)]
+    unsafe fn baz(&self) {}
+    unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+impl C for Bar2 {
+    unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method
+}
+
+trait D {
+    #[allow(unsafe_code)]
+    unsafe fn unsafe_provided(&self) {}
+}
+
+impl D for Bar {}
+
+fn main() {
+    unsafe {} //~ ERROR: usage of an `unsafe` block
+
+    unsafe_in_macro!()
+}
index ada0cd2bc98f82cf035e817aa62697cebecdb9af..854c51d0769e71bfb6f31bcd8a8d21cc2fdd17eb 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:lint-unused-extern-crate.rs
+// aux-build:lint_unused_extern_crate.rs
 
 #![deny(unused_extern_crates)]
 #![allow(unused_variables)]
 
 extern crate libc; //~ ERROR: unused extern crate
 
-extern crate "collections" as collecs; // no error, it is used
+extern crate collections as collecs; // no error, it is used
 
 extern crate rand; // no error, the use marks it as used
                    // even if imported objects aren't used
 
-extern crate "lint-unused-extern-crate" as other; // no error, the use * marks it as used
+extern crate lint_unused_extern_crate as other; // no error, the use * marks it as used
 
 #[allow(unused_imports)]
 use rand::isaac::IsaacRng;
index a4f46cbd1874fade8cc21cc143f90a7f5cb0fe2d..517be0eb8acd9e6c869ec244338fb05bb67d33e9 100644 (file)
@@ -40,4 +40,3 @@ fn main() {
 
     let _ = Something { X: 0 };
 }
-
index 69bceec8c3225ee70366326b172d6b09edbb226a..7c94e33b47b38c4296012d4aa7d63a6bacbf5b2a 100644 (file)
@@ -13,6 +13,6 @@ use std::vec::Vec;
 fn main() {
     let a: Vec<isize> = Vec::new();
     a.iter().all(|_| -> bool {
-        //~^ ERROR mismatched types
+        //~^ ERROR not all control paths return a value
     });
 }
index 57252dd58d7144a3d46eb407e494208916eb6d5d..a4eb1630afe19c00f993df2f6aa67a1ea1270e85 100644 (file)
@@ -10,7 +10,7 @@
 //
 // regression test for #8005
 
-macro_rules! test { () => { fn foo() -> i32 { 1i32; } } }
+macro_rules! test { () => { fn foo() -> i32 { 1; } } }
                                            //~^ ERROR not all control paths return a value
                                            //~^^ HELP consider removing this semicolon
 
index ac4b8a5f3090b09102e7452c2af3277ebe1b339c..0fee48a8c6c662ddeda75093ea52daf124096aae 100644 (file)
@@ -10,7 +10,7 @@
 
 #![deny(unused_variables)]
 #![deny(unused_assignments)]
-#![allow(dead_code, non_camel_case_types)]
+#![allow(dead_code, non_camel_case_types, trivial_numeric_casts)]
 
 fn f1(x: isize) {
     //~^ ERROR unused variable: `x`
index 985eb1cd7babcb556487c770e122cb82f1dc83e2..6fcab380030331417ffe56711e8eb3630ce9a15f 100644 (file)
@@ -11,7 +11,7 @@
 #![feature(box_syntax)]
 
 fn main() {
-    let x = box 5;
+    let x: Box<_> = box 5;
     let y = x;
     println!("{}", *x); //~ ERROR use of moved value: `*x`
     y.clone();
diff --git a/src/test/compile-fail/loop-labeled-break-value.rs b/src/test/compile-fail/loop-labeled-break-value.rs
new file mode 100644 (file)
index 0000000..e1ae3ae
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2015 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.
+
+fn main() {
+    loop {
+        let _: i32 = loop { break }; //~ ERROR mismatched types
+    }
+    loop {
+        let _: i32 = 'inner: loop { break 'inner }; //~ ERROR mismatched types
+    }
+    loop {
+        let _: i32 = 'inner: loop { loop { break 'inner } }; //~ ERROR mismatched types
+    }
+}
index e76eaea365ea6e0e8707341f54a86e93b421ec1c..abf0ed420e7a26c59cf03009f84cdcaae0e8364d 100644 (file)
@@ -29,4 +29,3 @@ fn main() {
     //~^^ ERROR unresolved name `a::bar`
     b::bar();
 }
-
index 13dbab12b774270a7242aba28419b6c85a961044..e8d9f444cefc6d687dee1f6ba169d3d08c7533f4 100644 (file)
@@ -16,5 +16,5 @@
 extern crate macro_non_reexport_2;
 
 fn main() {
-    assert_eq!(reexported!(), 3_usize);  //~ ERROR macro undefined
+    assert_eq!(reexported!(), 3);  //~ ERROR macro undefined
 }
index cff01f36f3ad72132a4694725a2435fe45b8f82e..0469a9d1cc859fd57c89674df4b50007a4d403b2 100644 (file)
@@ -28,4 +28,3 @@ fn main() {
     a::bar(); //~ ERROR unresolved name `a::bar`
     b::bar();
 }
-
index dc8f4fadc76c0a3185d14d80f3e2aaade7d38c34..26de51a7cf8c321e4273f19b75527acb1b4f27f7 100644 (file)
@@ -18,5 +18,5 @@
 extern crate macro_reexport_1;
 
 fn main() {
-    assert_eq!(reexported!(), 3_usize);  //~ ERROR macro undefined
+    assert_eq!(reexported!(), 3);  //~ ERROR macro undefined
 }
diff --git a/src/test/compile-fail/malformed-derive-entry.rs b/src/test/compile-fail/malformed-derive-entry.rs
new file mode 100644 (file)
index 0000000..62dbc21
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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.
+
+#[derive(Copy(Bad))]
+//~^ ERROR malformed `derive` entry
+struct Test1;
+
+#[derive(Copy="bad")]
+//~^ ERROR malformed `derive` entry
+struct Test2;
+
+#[derive()]
+//~^ WARNING empty trait list
+struct Test3;
+
+#[derive]
+//~^ WARNING empty trait list
+struct Test4;
index 254a797ef1cd0a54462062b634db348fcf9d0e2b..214a5e5e3eb115c4878422d3d978bd5b803059ea 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(plugin)]
 #![plugin] //~ ERROR malformed plugin attribute
 
 fn main() {}
index 884087b7bc534204f97f9c0513fc1102077962f6..1b112608beeb2003fc00091222574b4a2c55f305 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(plugin)]
 #![plugin="bleh"] //~ ERROR malformed plugin attribute
 
 fn main() {}
index 4885bb901df681fd68abd6daeb35db9aea4b5642..0c948831de217a6ce30c9af993fe7b7dc6c19820 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(plugin)]
 #![plugin(foo="bleh")] //~ ERROR malformed plugin attribute
 
 fn main() {}
index bd2a3eba0b5b8ff6ef0e50c65723db80ea7db0cf..fc4fa838a5693078afab08222be45fd89b727501 100644 (file)
@@ -8,10 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-l :static
+// compile-flags:-l static=
 // error-pattern: empty library name given via `-l`
 
 fn main() {
 }
-
-
index 4614440ddafd58f15673a190e599e32a045e182a..e9cbdb099480c4aca9d80700cd6962819805bdc6 100644 (file)
@@ -8,9 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-l foo:bar
+// compile-flags:-l bar=foo
 // error-pattern: unknown library kind `bar`, expected one of dylib, framework, or static
 
 fn main() {
 }
-
diff --git a/src/test/compile-fail/manual-link-bad-search-path.rs b/src/test/compile-fail/manual-link-bad-search-path.rs
new file mode 100644 (file)
index 0000000..2bf61cb
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2015 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:-L native=
+// error-pattern: empty search path given via `-L`
+
+fn main() {
+}
index 96cc35049ee40e309fb4ea4e7a083b0dc1680142..97176a533d2bd0d5e48d2aaa945d082ce106af1a 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-macos
 // ignore-ios
-// compile-flags:-l foo:framework
+// compile-flags:-l framework=foo
 // error-pattern: native frameworks are only available on OSX targets
 
 fn main() {
index 6e8719eeaceda58e6ffce825b5805468cdc8f542..e298a0f62cd81882ab9e47920f4ac74347b58e82 100644 (file)
@@ -26,6 +26,7 @@ impl<K, V> Map<K, V> for HashMap<K, V> {}
 fn main() {
     let x: Box<HashMap<isize, isize>> = box HashMap::new();
     let x: Box<Map<isize, isize>> = x;
-    let y: Box<Map<usize, isize>> = box x;
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let y: Box<Map<usize, isize>> = Box::new(x);
     //~^ ERROR the trait `Map<usize, isize>` is not implemented
 }
diff --git a/src/test/compile-fail/match-ref-ice.rs b/src/test/compile-fail/match-ref-ice.rs
new file mode 100644 (file)
index 0000000..042ec95
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2015 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(slice_patterns)]
+
+// The arity of `ref x` is always 1. If the pattern is compared to some non-structural type whose
+// arity is always 0, an ICE occurs.
+//
+// Related issue: #23009
+
+fn main() {
+    let homura = [1, 2, 3];
+
+    match homura {
+        [1, ref madoka, 3] => (),
+        [1, 2, 3] => (), //~ ERROR unreachable pattern
+        [_, _, _] => (),
+    }
+}
diff --git a/src/test/compile-fail/match-ref-mut-invariance.rs b/src/test/compile-fail/match-ref-mut-invariance.rs
new file mode 100644 (file)
index 0000000..c2b54a9
--- /dev/null
@@ -0,0 +1,24 @@
+// 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 that when making a ref mut binding with type `&mut T`, the
+// type `T` must match precisely the type `U` of the value being
+// matched, and in particular cannot be some supertype of `U`. Issue
+// #23116. This test focuses on a `match`.
+
+#![allow(dead_code)]
+struct S<'b>(&'b i32);
+impl<'b> S<'b> {
+    fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
+        match self.0 { ref mut x => x } //~ ERROR mismatched types
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/match-ref-mut-let-invariance.rs b/src/test/compile-fail/match-ref-mut-let-invariance.rs
new file mode 100644 (file)
index 0000000..ea16c61
--- /dev/null
@@ -0,0 +1,25 @@
+// 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 that when making a ref mut binding with type `&mut T`, the
+// type `T` must match precisely the type `U` of the value being
+// matched, and in particular cannot be some supertype of `U`. Issue
+// #23116. This test focuses on a `let`.
+
+#![allow(dead_code)]
+struct S<'b>(&'b i32);
+impl<'b> S<'b> {
+    fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
+        let ref mut x = self.0;
+        x //~ ERROR mismatched types
+    }
+}
+
+fn main() {}
index e778dd18e68d3e64ac24d34bacad4d4741371ab7..60d0c24bb3d3679002d03d3d4d5ffe9b590f56c7 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 fn a() {
     let v = [1, 2, 3];
     match v {
index a4abdf3ddfe94f14f7189ceeb11741be4b25874b..0bbba8861217da39ff341bfa6387414d07f8dd15 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 fn main() {
     match () {
         [()] => { }
index edbdc77f0306d3be89fa6295e93a20f5498bc825..ef75213d34b85109fa53a7e76d873d9b063f007d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 fn main() {
     match "foo".to_string() {
         ['f', 'o', ..] => {} //~ ERROR mismatched types
index 2c63438cbf3af4ef6dceb833fc4f9105251441d5..48b70b4bda08efc31983e0bffaee437639cb5ae3 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
 
 fn main() {
     let x: Vec<(isize, isize)> = Vec::new();
index 981c4c6f40d574d780c2b9e5740535a004ce7857..c1d4551fd9ec44784fc594ab5a763320508b0eb0 100644 (file)
@@ -19,4 +19,3 @@ trait me2 {
 }
 impl me2 for usize { fn me(&self) -> usize { *self } }
 fn main() { 1_usize.me(); } //~ ERROR E0034
-
index f4740492651ae03e4cd15a1412f8d8a8887bfccd..c9ef2df8e1326f01f26bb275f40bde1ce2f4d29d 100644 (file)
@@ -29,7 +29,7 @@ impl S {
 
     // Cause an error. It shouldn't have any macro backtrace frames.
     fn bar(&self) { }
-    fn bar(&self) { } //~ ERROR duplicate definition
+    fn bar(&self) { } //~ ERROR duplicate method
 }
 
 fn main() { }
index 6616dcc8e1b032c4b9a9e931b36b224e7e95b0f3..b13d4250ee958574256c4493c0e3416099a35fb1 100644 (file)
@@ -40,4 +40,3 @@ fn main() {
               .filter_map; //~ ERROR attempted to take value of method `filter_map` on type
               //~^ HELP maybe a `()` to call it is missing
 }
-
index 7b6868af805e52cea3e31325ae456cee3ce3209a..57a96bb9a26ea4febfddf3fd54dc250e5b414194 100644 (file)
@@ -23,9 +23,9 @@ fn main() {
                  //~| found `Foo`
                  //~| expected &-ptr
                  //~| found struct `Foo`
-    Foo::bar(&42i32); //~  ERROR mismatched types
+    Foo::bar(&42); //~  ERROR mismatched types
                       //~| expected `&Foo`
-                      //~| found `&i32`
+                      //~| found `&_`
                       //~| expected struct `Foo`
-                      //~| found i32
+                      //~| found integral variable
 }
index e807d2b9448d32438624feb1695713add482d12a..1d0c4254eda2eef298b911b57b5634be91499bd2 100644 (file)
@@ -19,6 +19,4 @@ fn main() {
     //~^ ERROR does not implement any method
     //~^^ HELP #1: `core::slice::SliceExt`
     //~^^^ HELP #2: `core::str::StrExt`
-    //~^^^^ HELP #3: `collections::slice::SliceExt`
-    //~^^^^^ HELP #4: `collections::str::StrExt`
 }
diff --git a/src/test/compile-fail/move-in-guard-1.rs b/src/test/compile-fail/move-in-guard-1.rs
new file mode 100644 (file)
index 0000000..068bfa3
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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(box_syntax)]
+
+pub fn main() {
+    let x: Box<_> = box 1;
+
+    let v = (1, 2);
+
+    match v {
+        (1, _) if take(x) => (),
+        (_, 2) if take(x) => (), //~ ERROR use of moved value: `x`
+        _ => (),
+    }
+}
+
+fn take<T>(_: T) -> bool { false }
diff --git a/src/test/compile-fail/move-in-guard-2.rs b/src/test/compile-fail/move-in-guard-2.rs
new file mode 100644 (file)
index 0000000..984963b
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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(box_syntax)]
+
+pub fn main() {
+    let x: Box<_> = box 1;
+
+    let v = (1, 2);
+
+    match v {
+        (1, _) |
+        (_, 2) if take(x) => (), //~ ERROR use of moved value: `x`
+        _ => (),
+    }
+}
+
+fn take<T>(_: T) -> bool { false }
index 7e3a85569d413f5ea39a489fa54df1c095de9434..b7393666719630029aa400475ed9bb880ac0acae 100644 (file)
@@ -13,7 +13,7 @@
 struct Foo(Box<isize>);
 
 fn main() {
-    let x = (box 1,);
+    let x: (Box<_>,) = (box 1,);
     let y = x.0;
     let z = x.0; //~ ERROR use of moved value: `x.0`
 
index f410541f0b7e93a15eefae799cf4e74a71771e62..5af326b4298499ed42bfdd5bb505e75657b104d9 100644 (file)
@@ -12,7 +12,6 @@
 // bound must be noncopyable. For details see
 // http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/
 
-#![feature(box_syntax)]
 #![feature(unboxed_closures)]
 
 struct R<'a> {
@@ -41,7 +40,8 @@ fn innocent_looking_victim() {
 }
 
 fn conspirator<F>(mut f: F) where F: FnMut(&mut R, bool) {
-    let mut r = R {c: box f};
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let mut r = R {c: Box::new(f)};
     f(&mut r, false) //~ ERROR use of moved value
 }
 
index 2cf6e67a90958baa9742be4d6004340c5bf4f774..73982fa2811a0871d2713fdddb82921a73de1395 100644 (file)
@@ -13,7 +13,6 @@
 fn f(_: &mut isize) {}
 
 fn main() {
-    let mut x = box 3;
+    let mut x: Box<_> = box 3;
     f(x)    //~ ERROR mismatched types
 }
-
index 6de69a9adb0c9a3b56d32b3397176a8d2eb201d1..9eb24c81960cacc29e81d41f3101a56ef298b8b6 100644 (file)
@@ -9,21 +9,21 @@
 // except according to those terms.
 
 fn main() {
-    let foo = &mut 1i32;
+    let foo = &mut 1;
 
     // (separate lines to ensure the spans are accurate)
 
      let &_ //~  ERROR mismatched types
-            //~| expected `&mut i32`
+            //~| expected `&mut _`
             //~| found `&_`
             //~| values differ in mutability
         = foo;
     let &mut _ = foo;
 
-    let bar = &1i32;
+    let bar = &1;
     let &_ = bar;
     let &mut _ //~  ERROR mismatched types
-               //~| expected `&i32`
+               //~| expected `&_`
                //~| found `&mut _`
                //~| values differ in mutability
          = bar;
index b6744d4b33a1021d7b133dbdd4a9e618cc6cc7ae..46af3a862c28f623c9801e974f7675e46275b134 100644 (file)
@@ -29,6 +29,6 @@ fn cat(in_x : usize, in_y : isize) -> cat {
 }
 
 fn main() {
-  let nyan : cat = cat(52_usize, 99);
+  let nyan : cat = cat(52, 99);
   nyan.eat();
 }
index 94b1047f85ed3720f95b32bace33af613f42ed3d..c163dc2b4d228d770398740842ca6ba649e2e7c0 100644 (file)
@@ -21,6 +21,6 @@ fn cat(in_x : usize, in_y : isize) -> cat {
 }
 
 fn main() {
-  let nyan : cat = cat(52_usize, 99);
+  let nyan : cat = cat(52, 99);
   nyan.how_hungry = 0; //~ ERROR cannot assign
 }
index 2fb097f111db47f98727566112fc8e35047c49f0..526750257d2785c81f52b11599084aebf589cd16 100644 (file)
 mod foo {
     mod baz {
         struct Test;
-        impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
-        impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
-        impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-        impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
-        impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
+        impl Add for Test {} //~ ERROR: use of undeclared trait
+        impl Clone for Test {} //~ ERROR: use of undeclared trait
+        impl Iterator for Test {} //~ ERROR: use of undeclared trait
+        impl ToString for Test {} //~ ERROR: use of undeclared trait
+        impl Writer for Test {} //~ ERROR: use of undeclared trait
 
         fn foo() {
             drop(2) //~ ERROR: unresolved name
@@ -30,11 +30,11 @@ mod foo {
     }
 
     struct Test;
-    impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
-    impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
-    impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-    impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
-    impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
+    impl Add for Test {} //~ ERROR: use of undeclared trait
+    impl Clone for Test {} //~ ERROR: use of undeclared trait
+    impl Iterator for Test {} //~ ERROR: use of undeclared trait
+    impl ToString for Test {} //~ ERROR: use of undeclared trait
+    impl Writer for Test {} //~ ERROR: use of undeclared trait
 
     fn foo() {
         drop(2) //~ ERROR: unresolved name
@@ -45,11 +45,11 @@ fn qux() {
     #[no_implicit_prelude]
     mod qux_inner {
         struct Test;
-        impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
-        impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
-        impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-        impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
-        impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
+        impl Add for Test {} //~ ERROR: use of undeclared trait
+        impl Clone for Test {} //~ ERROR: use of undeclared trait
+        impl Iterator for Test {} //~ ERROR: use of undeclared trait
+        impl ToString for Test {} //~ ERROR: use of undeclared trait
+        impl Writer for Test {} //~ ERROR: use of undeclared trait
 
         fn foo() {
             drop(2) //~ ERROR: unresolved name
index c0f7bea25b57ad88fddc5f218e6c75bd06fa1cdb..c4bcd33b93bd0beb67f68e1bf121553ec12432c6 100644 (file)
 // fail with the same error message).
 
 struct Test;
-impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
-impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
-impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
-impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
+impl Add for Test {} //~ ERROR: use of undeclared trait
+impl Clone for Test {} //~ ERROR: use of undeclared trait
+impl Iterator for Test {} //~ ERROR: use of undeclared trait
+impl ToString for Test {} //~ ERROR: use of undeclared trait
+impl Writer for Test {} //~ ERROR: use of undeclared trait
 
 fn main() {
     drop(2) //~ ERROR: unresolved name
index 0212adff305d0d53e2df9a4253ce1e2ad3154971..a7cabae16be1b8f39be0f84ae8f66a090bbfbdad 100644 (file)
@@ -8,9 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Note: This test is checking that we forbid a coding pattern that
+// Issue #5873 explicitly wants to allow.
+
 enum State { ST_NULL, ST_WHITESPACE }
 
 fn main() {
     [State::ST_NULL; (State::ST_WHITESPACE as usize)];
-    //~^ ERROR expected constant integer for repeat count, found non-constant expression
+    //~^ ERROR expected constant integer for repeat count, but non-constant path
 }
index 14d2c8d0326a1546920049d9556ad53cf874bbe9..59e910ec6afdabbca9766d8f5bdaf1368bd94d87 100644 (file)
@@ -13,6 +13,7 @@
 fn main() {
     fn bar(n: isize) {
         let _x: [isize; n];
-        //~^ ERROR expected constant expr for array length: non-constant path in constant expr
+        //~^ ERROR no type for local variable
+        //~| ERROR array length constant evaluation error: non-constant path in constant expr
     }
 }
index 26528543b435a253fa7f00f0ce4c478733c7a7eb..3ce206ff7fb2c0c13b1a5a7b1079aa2e65e9a16d 100644 (file)
@@ -12,6 +12,7 @@
 
 fn main() {
     fn bar(n: usize) {
-        let _x = [0; n]; //~ ERROR expected constant integer for repeat count, found variable
+        let _x = [0; n];
+        //~^ ERROR expected constant integer for repeat count, found variable
     }
 }
index 8f2cb61f95514cf44cef029fca3b0364ae6ffe2f..ad2b8c400e57608c0e2613223c846e1d3ae590f8 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 enum t { a(u), b }
 enum u { c, d }
 
index 1dec049aed5e66ce262aa78ecf0917492e08db42..b9749c2696e32adf505b7df91a53df19dba6bafd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 enum t { a, b, }
 
 fn main() {
index 0eb91e0419a1da232d991ef9da75f0f093a431ed..146265bf0e1508bfaa7755642f04d3c43a5a12d6 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![feature(advanced_slice_patterns)]
+#![feature(slice_patterns)]
 
 struct Foo {
     first: bool,
@@ -27,7 +28,7 @@ fn struct_with_a_nested_enum_and_vector() {
         Foo { first: true, second: None } => (),
         Foo { first: true, second: Some(_) } => (),
         Foo { first: false, second: None } => (),
-        Foo { first: false, second: Some([1_usize, 2_usize, 3_usize, 4_usize]) } => ()
+        Foo { first: false, second: Some([1, 2, 3, 4]) } => ()
     }
 }
 
diff --git a/src/test/compile-fail/nonbool_static_assert.rs b/src/test/compile-fail/nonbool_static_assert.rs
new file mode 100644 (file)
index 0000000..7a7912b
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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(static_assert)]
+#![allow(dead_code)]
+
+#[static_assert]
+static E: i32 = 1; //~ ERROR can only have static_assert on a static with type `bool`
+
+fn main() {}
index 0077d10e6ca826e4a8312615a66b3837817c0fae..4fba45e2a66c589f61ff74396997e632b30088ae 100644 (file)
@@ -81,8 +81,8 @@ fn load3<'a,'b>(ss: &'a SomeTrait) -> &'b SomeTrait {
     // which fails to type check.
 
     ss
-        //~^ ERROR cannot infer
-        //~| ERROR mismatched types
+        //~^ ERROR lifetime of the source pointer does not outlive lifetime bound
+        //~| ERROR cannot infer
 }
 
 fn main() {
index 70752cbfda19f11396ec29a6c288a365e1da3336..7fae530984f898e36b8781d30e7eb577fee63bd4 100644 (file)
@@ -25,7 +25,7 @@ fn load(ss: &mut SomeStruct) -> Box<SomeTrait> {
     // `Box<SomeTrait>` defaults to a `'static` bound, so this return
     // is illegal.
 
-    ss.r //~ ERROR mismatched types
+    ss.r //~ ERROR lifetime of the source pointer does not outlive lifetime bound
 }
 
 fn store(ss: &mut SomeStruct, b: Box<SomeTrait>) {
@@ -38,7 +38,7 @@ fn store(ss: &mut SomeStruct, b: Box<SomeTrait>) {
 fn store1<'b>(ss: &mut SomeStruct, b: Box<SomeTrait+'b>) {
     // Here we override the lifetimes explicitly, and so naturally we get an error.
 
-    ss.r = b; //~ ERROR mismatched types
+    ss.r = b; //~ ERROR lifetime of the source pointer does not outlive lifetime bound
 }
 
 fn main() {
diff --git a/src/test/compile-fail/object-safety-by-value-self-use.rs b/src/test/compile-fail/object-safety-by-value-self-use.rs
new file mode 100644 (file)
index 0000000..36356cb
--- /dev/null
@@ -0,0 +1,28 @@
+// 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 that while a trait with by-value self is object-safe, we
+// can't actually invoke it from an object (yet...?).
+
+#![feature(rustc_attrs)]
+
+trait Bar {
+    fn bar(self);
+}
+
+trait Baz {
+    fn baz(self: Self);
+}
+
+fn use_bar(t: Box<Bar>) {
+    t.bar() //~ ERROR cannot move a value of type Bar
+}
+
+fn main() { }
index 5ebcc8516ca0516610c34ab2d470b2674c8c7136..5a8772d61425fcb9176c7c69abe6368a900c34c1 100644 (file)
@@ -8,8 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Check that we correctly prevent users from making trait objects
-// from traits with a `fn(self)` method.
+// Check that a trait with by-value self is considered object-safe.
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+#![allow(trivial_casts)]
 
 trait Bar {
     fn bar(self);
@@ -19,29 +22,35 @@ trait Baz {
     fn baz(self: Self);
 }
 
+trait Quux {
+    // Legal because of the where clause:
+    fn baz(self: Self) where Self : Sized;
+}
+
 fn make_bar<T:Bar>(t: &T) -> &Bar {
-    t
-        //~^ ERROR `Bar` is not object-safe
-        //~| NOTE method `bar` has a receiver type of `Self`
+    t // legal
 }
 
 fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
-    t as &Bar
-        //~^ ERROR `Bar` is not object-safe
-        //~| NOTE method `bar` has a receiver type of `Self`
+    t as &Bar // legal
 }
 
 fn make_baz<T:Baz>(t: &T) -> &Baz {
-    t
-        //~^ ERROR `Baz` is not object-safe
-        //~| NOTE method `baz` has a receiver type of `Self`
+    t // legal
 }
 
 fn make_baz_explicit<T:Baz>(t: &T) -> &Baz {
-    t as &Baz
-        //~^ ERROR `Baz` is not object-safe
-        //~| NOTE method `baz` has a receiver type of `Self`
+    t as &Baz // legal
+}
+
+fn make_quux<T:Quux>(t: &T) -> &Quux {
+    t
+}
+
+fn make_quux_explicit<T:Quux>(t: &T) -> &Quux {
+    t as &Quux
 }
 
-fn main() {
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
 }
index 0ca706404c1f309028b36775d7d3d16daa237841..fd20accfa1e6b562bd319e86b3a987a86baefcaf 100644 (file)
@@ -9,12 +9,18 @@
 // except according to those terms.
 
 // Check that we correctly prevent users from making trait objects
-// from traits with generic methods.
+// from traits with generic methods, unless `where Self : Sized` is
+// present.
 
 trait Bar {
     fn bar<T>(&self, t: T);
 }
 
+trait Quux {
+    fn bar<T>(&self, t: T)
+        where Self : Sized;
+}
+
 fn make_bar<T:Bar>(t: &T) -> &Bar {
     t
         //~^ ERROR `Bar` is not object-safe
@@ -27,5 +33,13 @@ fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
         //~| NOTE method `bar` has generic type parameters
 }
 
+fn make_quux<T:Quux>(t: &T) -> &Quux {
+    t
+}
+
+fn make_quux_explicit<T:Quux>(t: &T) -> &Quux {
+    t as &Quux
+}
+
 fn main() {
 }
index df0f44c1391580898084e7484bf3d06e75686225..b546774ccbd8cae8deb49bb638bf3e8fa886fac1 100644 (file)
@@ -9,7 +9,8 @@
 // except according to those terms.
 
 // Check that we correctly prevent users from making trait objects
-// form traits that make use of `Self` in an argument or return position.
+// form traits that make use of `Self` in an argument or return
+// position, unless `where Self : Sized` is present..
 
 trait Bar {
     fn bar(&self, x: &Self);
@@ -19,6 +20,10 @@ trait Baz {
     fn bar(&self) -> Self;
 }
 
+trait Quux {
+    fn get(&self, s: &Self) -> Self where Self : Sized;
+}
+
 fn make_bar<T:Bar>(t: &T) -> &Bar {
     t
         //~^ ERROR `Bar` is not object-safe
@@ -43,5 +48,13 @@ fn make_baz_explicit<T:Baz>(t: &T) -> &Baz {
         //~| NOTE method `bar` references the `Self` type in its arguments or return type
 }
 
+fn make_quux<T:Quux>(t: &T) -> &Quux {
+    t
+}
+
+fn make_quux_explicit<T:Quux>(t: &T) -> &Quux {
+    t as &Quux
+}
+
 fn main() {
 }
index 56f71c844ac2935aa9dc942bec03b4896399251d..be321b6290354197c03dfcd2c5b0447e271b0cc2 100644 (file)
@@ -16,6 +16,7 @@ struct IWantToCopyThis {
 
 impl Copy for IWantToCopyThis {}
 //~^ ERROR the trait `Copy` may not be implemented for this type
+//~| ERROR E0277
 
 enum CantCopyThisEither {
     A,
@@ -28,6 +29,6 @@ enum IWantToCopyThisToo {
 
 impl Copy for IWantToCopyThisToo {}
 //~^ ERROR the trait `Copy` may not be implemented for this type
+//~| ERROR E0277
 
 fn main() {}
-
index 4b261d89888dcd3b02060865863568edab2cad6a..59508d6ac95f9645d2c3a67af396e0eaf29d1e98 100644 (file)
@@ -12,4 +12,4 @@
 
 enum blah { a(isize, isize, usize), b(isize, isize), }
 
-fn main() { match blah::a(1, 1, 2_usize) { blah::a(_, x, y) | blah::b(x, y) => { } } }
+fn main() { match blah::a(1, 1, 2) { blah::a(_, x, y) | blah::b(x, y) => { } } }
index 61752e62abdefe90e80100478f48b9f6c5246bba..77ac97bc8b89951427bf7aaa9d69d0e45675f55a 100644 (file)
@@ -18,13 +18,18 @@ struct S {
 }
 
 impl FnMut<(isize,)> for S {
-    type Output = isize;
-
     extern "rust-call" fn call_mut(&mut self, (z,): (isize,)) -> isize {
         self.x * self.y * z
     }
 }
 
+impl FnOnce<(isize,)> for S {
+    type Output = isize;
+    extern "rust-call" fn call_once(mut self, (z,): (isize,)) -> isize {
+        self.call_mut((z,))
+    }
+}
+
 fn main() {
     let mut s = S {
         x: 3,
index 41ecf7146138dbb8d7ba1503a4d02ce0fe608977..ea47d676412098c04e54399afc0a05d7187a7be7 100644 (file)
@@ -18,12 +18,16 @@ struct S {
 }
 
 impl FnMut<isize> for S {
-    type Output = isize;
     extern "rust-call" fn call_mut(&mut self, z: isize) -> isize {
         self.x + self.y + z
     }
 }
 
+impl FnOnce<isize> for S {
+    type Output = isize;
+    extern "rust-call" fn call_once(mut self, z: isize) -> isize { self.call_mut(z) }
+}
+
 fn main() {
     let mut s = S {
         x: 1,
@@ -31,4 +35,3 @@ fn main() {
     };
     drop(s(3))  //~ ERROR cannot use call notation
 }
-
index 80544099329cffde6c2e918939be02111ee965c6..da2a97b0ca8abb4bb999f2693b367033b3d685ca 100644 (file)
@@ -23,4 +23,3 @@ fn main() {
         _ => ()
     }
 }
-
index 58288fa484221f596e250652a8ea60157a0129c4..0b7886842b49e002cf60699b42561cde22118ff1 100644 (file)
@@ -14,4 +14,3 @@ fn main() {
         Some(_) => {}
     }
 }
-
diff --git a/src/test/compile-fail/phantom-oibit.rs b/src/test/compile-fail/phantom-oibit.rs
new file mode 100644 (file)
index 0000000..c912d08
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2015 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.
+
+// Ensure that OIBIT checks `T` when it encounters a `PhantomData<T>` field, instead of checking
+// the `PhantomData<T>` type itself (which almost always implements a "default" trait
+// (`impl Trait for ..`))
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::{MarkerTrait, PhantomData};
+
+unsafe trait Zen: MarkerTrait {}
+
+unsafe impl Zen for .. {}
+
+unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {}
+
+struct Guard<'a, T: 'a> {
+    _marker: PhantomData<&'a T>,
+}
+
+struct Nested<T>(T);
+
+fn is_zen<T: Zen>(_: T) {}
+
+fn not_sync<T>(x: Guard<T>) {
+    is_zen(x)  //~ error: the trait `core::marker::Sync` is not implemented for the type `T`
+}
+
+fn nested_not_sync<T>(x: Nested<Guard<T>>) {
+    is_zen(x)  //~ error: the trait `core::marker::Sync` is not implemented for the type `T`
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/plugin-extern-crate-attr-deprecated.rs b/src/test/compile-fail/plugin-extern-crate-attr-deprecated.rs
deleted file mode 100644 (file)
index ccda5cb..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2015 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.
-
-#[plugin]  //~ ERROR #[plugin] on `extern crate` is deprecated
-//~^ HELP use a crate attribute instead, i.e. #![plugin(std)]
-extern crate std;
-
-fn main() {}
diff --git a/src/test/compile-fail/priv_in_pub_sig_priv_mod.rs b/src/test/compile-fail/priv_in_pub_sig_priv_mod.rs
new file mode 100644 (file)
index 0000000..f589daf
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2015 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 we properly check for private types in public signatures, even
+// inside a private module (#22261).
+
+mod a {
+    struct Priv;
+
+    pub fn expose_a() -> Priv { //~Error: private type in exported type signature
+        panic!();
+    }
+
+    mod b {
+        pub fn expose_b() -> super::Priv { //~Error: private type in exported type signature
+            panic!();
+        }
+    }
+}
+
+pub fn main() {}
index 1ae79adbad76ae953da4cf7aa0045da158c03de5..67dccb4c93e1ac0e6bb4fb6ed89610f2fe7a6923 100644 (file)
@@ -27,10 +27,6 @@ mod bar {
 
     // can't publicly re-export private items
     pub use self::baz::{foo, bar};
-    //~^ ERROR: function `bar` is private
-
-    pub use self::private::ppriv;
-    //~^ ERROR: function `ppriv` is private
 
     pub struct A;
     impl A {
@@ -61,10 +57,8 @@ mod bar {
             fn bar2(&self) {}
         }
 
-        // both of these are re-exported by `bar`, but only one should be
-        // validly re-exported
         pub fn foo() {}
-        fn bar() {}
+        pub fn bar() {}
     }
 
     extern {
@@ -92,10 +86,6 @@ mod bar {
         pub fn gpub() {}
         fn gpriv() {}
     }
-
-    mod private {
-        fn ppriv() {}
-    }
 }
 
 pub fn gpub() {}
@@ -142,13 +132,13 @@ mod foo {
 
         ::bar::baz::foo(); //~ ERROR: function `foo` is inaccessible
                            //~^ NOTE: module `baz` is private
-        ::bar::baz::bar(); //~ ERROR: function `bar` is private
+        ::bar::baz::bar(); //~ ERROR: function `bar` is inaccessible
     }
 
     fn test2() {
         use bar::baz::{foo, bar};
         //~^ ERROR: function `foo` is inaccessible
-        //~^^ ERROR: function `bar` is private
+        //~^^ ERROR: function `bar` is inaccessible
         foo();
         bar();
     }
index df570fd46479296c9c92a71c0a0656df847de92c..4ca37fc2ad209f6fd1eaab56f01bf0e80b156759 100644 (file)
@@ -8,10 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:privacy-tuple-struct.rs
-// ignore-fast
+// aux-build:privacy_tuple_struct.rs
 
-extern crate "privacy-tuple-struct" as other;
+extern crate privacy_tuple_struct as other;
 
 mod a {
     pub struct A(());
@@ -102,30 +101,30 @@ fn xcrate() {
     let c = other::C(2, 3); //~ ERROR: cannot invoke tuple struct constructor
     let d = other::D(4);
 
-    let other::A(()) = a; //~ ERROR: field #1 of struct `privacy-tuple-struct::A` is private
+    let other::A(()) = a; //~ ERROR: field #1 of struct `privacy_tuple_struct::A` is private
     let other::A(_) = a;
     match a { other::A(()) => {} }
-    //~^ ERROR: field #1 of struct `privacy-tuple-struct::A` is private
+    //~^ ERROR: field #1 of struct `privacy_tuple_struct::A` is private
     match a { other::A(_) => {} }
 
     let other::B(_) = b;
-    let other::B(_b) = b; //~ ERROR: field #1 of struct `privacy-tuple-struct::B` is private
+    let other::B(_b) = b; //~ ERROR: field #1 of struct `privacy_tuple_struct::B` is private
     match b { other::B(_) => {} }
     match b { other::B(_b) => {} }
-    //~^ ERROR: field #1 of struct `privacy-tuple-struct::B` is private
+    //~^ ERROR: field #1 of struct `privacy_tuple_struct::B` is private
     match b { other::B(1) => {} other::B(_) => {} }
-    //~^ ERROR: field #1 of struct `privacy-tuple-struct::B` is private
+    //~^ ERROR: field #1 of struct `privacy_tuple_struct::B` is private
 
     let other::C(_, _) = c;
     let other::C(_a, _) = c;
-    let other::C(_, _b) = c; //~ ERROR: field #2 of struct `privacy-tuple-struct::C` is private
-    let other::C(_a, _b) = c; //~ ERROR: field #2 of struct `privacy-tuple-struct::C` is private
+    let other::C(_, _b) = c; //~ ERROR: field #2 of struct `privacy_tuple_struct::C` is private
+    let other::C(_a, _b) = c; //~ ERROR: field #2 of struct `privacy_tuple_struct::C` is private
     match c { other::C(_, _) => {} }
     match c { other::C(_a, _) => {} }
     match c { other::C(_, _b) => {} }
-    //~^ ERROR: field #2 of struct `privacy-tuple-struct::C` is private
+    //~^ ERROR: field #2 of struct `privacy_tuple_struct::C` is private
     match c { other::C(_a, _b) => {} }
-    //~^ ERROR: field #2 of struct `privacy-tuple-struct::C` is private
+    //~^ ERROR: field #2 of struct `privacy_tuple_struct::C` is private
 
     let other::D(_) = d;
     let other::D(_d) = d;
index ccbdd52a98328dc769f1b9268852d2e50a313c4a..16510c2c8c99cb01f07743f86cbd0c1508a5ca3f 100644 (file)
@@ -30,6 +30,6 @@ mod kitties {
 }
 
 fn main() {
-  let nyan : kitties::cat = kitties::cat(52_usize, 99);
+  let nyan : kitties::cat = kitties::cat(52, 99);
   nyan.nap();
 }
index 243d835d46e6213d7f8bf9143872d899b5404223..fb4491a63757b4e27b93f6d24db04fd3dfc113db 100644 (file)
@@ -13,7 +13,7 @@ extern crate cci_class;
 use cci_class::kitties::cat;
 
 fn main() {
-  let nyan : cat = cat(52_usize, 99);
-  assert!((nyan.meows == 52_usize));
+  let nyan : cat = cat(52, 99);
+  assert!((nyan.meows == 52));
   //~^ ERROR field `meows` of struct `cci_class::kitties::cat` is private
 }
index aa890550f1c4868aa6ac3a4734bb98dc02fe19c6..198fa5b9aca0bf4009c238cc2ed2651278b86a15 100644 (file)
@@ -20,7 +20,7 @@ mod bleh {
         )
     }
 
-    #[derive(Copy)]
+    #[derive(Copy, Clone)]
     pub struct S;
 
     impl S {
index a8b6e399418f7ef430f333d95aaa993894594ecb..3ae61722bcff3e9c7206b875f3d403b0361add99 100644 (file)
@@ -15,12 +15,13 @@ pub fn main() {
     let _ = 0u32..10i32;
     //~^ ERROR start and end of range have incompatible types
 
-    // Float => does not implement iterator.
-    for i in 0f32..42f32 {}
-    //~^ ERROR the trait `core::num::Int` is not implemented for the type `f32`
+    // Bool => does not implement iterator.
+    for i in false..true {}
+    //~^ ERROR the trait
+    //~^^ ERROR the trait
 
     // Unsized type.
-    let arr: &[_] = &[1u32, 2, 3];
+    let arr: &[_] = &[1, 2, 3];
     let range = *arr..;
     //~^ ERROR the trait `core::marker::Sized` is not implemented
 }
index ffc21a5ce612326c9ef5e895a6526628679a841c..55f3b995336534c5e7cf8e9424ceb167bf2387b5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 
 //~^^^^^^^^^^ ERROR overflow
 //
-// We also get a second error message at the top of file (dummy
-// span). This is not helpful, but also kind of annoying to prevent,
-// so for now just live with it, since we also get a second message
-// that is more helpful.
+// We get an error message at the top of file (dummy span).
+// This is not helpful, but also kind of annoying to prevent,
+// so for now just live with it.
 
 enum Nil {NilValue}
 struct Cons<T> {head:isize, tail:T}
@@ -28,9 +27,8 @@ impl<T:Dot> Dot for Cons<T> {
 }
 fn test<T:Dot> (n:isize, i:isize, first:T, second:T) ->isize {
   match n {    0 => {first.dot(second)}
-      //~^ ERROR: reached the recursion limit during monomorphization
-      // Error message should be here. It should be a type error
-      // to instantiate `test` at a type other than T. (See #4287)
+      // FIXME(#4287) Error message should be here. It should be
+      // a type error to instantiate `test` at a type other than T.
     _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})}
   }
 }
index 6cd984c071a0c1d444d61e2b02634965bfc77231..368269999a296c0008f457a5f7c37f12b63d9e63 100644 (file)
@@ -42,9 +42,5 @@ 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 required by `is_send`
-    //~^^^^ ERROR overflow evaluating
-    //~^^^^^ NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
-    //~^^^^^^ NOTE required by `is_send`
+    //~| NOTE consider adding a `#![recursion_limit="20"]` attribute to your crate
 }
diff --git a/src/test/compile-fail/reflect-assoc.rs b/src/test/compile-fail/reflect-assoc.rs
new file mode 100644 (file)
index 0000000..9cf0d25
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2015 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 types that appear in assoc bindings in an object
+// type are subject to the reflect check.
+
+use std::marker::Reflect;
+use std::io::Write;
+
+trait Get {
+    type Output;
+    fn get(self) -> Self::Output;
+}
+
+struct Struct<T>(T);
+
+fn is_reflect<T:Reflect>() { }
+
+fn a<T>() {
+    is_reflect::<Box<Get<Output=T>>>(); //~ ERROR not implemented
+}
+
+fn ok_a<T: Reflect>() {
+    is_reflect::<Box<Get<Output=T>>>(); // OK
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/reflect-object-param.rs b/src/test/compile-fail/reflect-object-param.rs
new file mode 100644 (file)
index 0000000..9f07466
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2015 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 types that appear in input types in an object type are
+// subject to the reflect check.
+
+use std::marker::Reflect;
+use std::io::Write;
+
+trait Get<T> {
+    fn get(self) -> T;
+}
+
+struct Struct<T>(T);
+
+fn is_reflect<T:Reflect>() { }
+
+fn a<T>() {
+    is_reflect::<T>(); //~ ERROR not implemented
+}
+
+fn ok_a<T: Reflect>() {
+    is_reflect::<T>(); // OK
+}
+
+fn b<T>() {
+    is_reflect::<Box<Get<T>>>(); //~ ERROR not implemented
+}
+
+fn ok_b<T: Reflect>() {
+    is_reflect::<Box<Get<T>>>(); // OK
+}
+
+fn c<T>() {
+    is_reflect::<Box<Get<Struct<T>>>>(); //~ ERROR not implemented
+}
+
+fn main() {
+    is_reflect::<Box<Get<Struct<()>>>>(); // OK
+}
diff --git a/src/test/compile-fail/reflect.rs b/src/test/compile-fail/reflect.rs
new file mode 100644 (file)
index 0000000..701aa5b
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2015 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 there is no way to get a generic type `T` to be
+// considered as `Reflect` (or accessible via something that is
+// considered `Reflect`) without a reflect bound, but that any
+// concrete type works fine. Note that object types are tested
+// separately.
+
+use std::marker::Reflect;
+use std::io::Write;
+
+struct Struct<T>(T);
+
+fn is_reflect<T:Reflect>() { }
+
+fn c<T>() {
+    is_reflect::<Struct<T>>(); //~ ERROR not implemented
+}
+
+fn ok_c<T: Reflect>() {
+    is_reflect::<Struct<T>>(); // OK
+}
+
+fn d<T>() {
+    is_reflect::<(i32, T)>(); //~ ERROR not implemented
+}
+
+fn main() {
+    is_reflect::<&i32>(); // OK
+    is_reflect::<Box<Write>>(); // OK
+}
index 9f35c636b4526e18a95dd3b3c22ffd1e52dd9cf1..b73c283fa515e3527f1a745893876a2d2f5d49be 100644 (file)
@@ -13,4 +13,3 @@ fn call_rec<F>(mut f: F) -> usize where F: FnMut(usize) -> usize {
 }
 
 fn main() {}
-
index 2095fb903b844d7526f33321cb171bac111e5a8f..1e615be9d6acc57a452f69059a0cda171c0697dc 100644 (file)
@@ -26,4 +26,3 @@ fn borrowed_receiver_same_lifetime<'a>(x: &'a Foo) -> &'a () {
 
 #[rustc_error]
 fn main() {} //~ ERROR compilation successful
-
index f9bf4e257b3638188003768a744bad8ead6526b8..e011b8f56972be4d1818665aeaf7021ed3dfdafc 100644 (file)
@@ -21,4 +21,3 @@ fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a Foo) -> &'b () {
 }
 
 fn main() {}
-
index 097053276c7fb99a52811aa893e2e2dcf12105c2..84dd97643a107ab88370cd4eaf1dee394d3873ca 100644 (file)
@@ -26,4 +26,3 @@ fn borrowed_receiver_related_lifetimes<'a,'b>(x: &'a (Foo+'b)) -> &'a () {
 
 #[rustc_error]
 fn main() {} //~ ERROR compilation successful
-
index fe0ff8dc3fe5d2d9e38d96d23479e9915b50fd87..0a68e7f1076caffab8c67f7fec2c567d046f88cd 100644 (file)
@@ -23,4 +23,3 @@ fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (Foo+'b)) -> &'b () {
 }
 
 fn main() {}
-
index f07f753d82529965f2b306eda2f2513c8c050f2d..26aad0e33b1b4ff3da1b3c7e339df1a83fd72983 100644 (file)
@@ -22,4 +22,3 @@ fn owned_receiver(x: Box<Foo>) -> &'static () {
 }
 
 fn main() {}
-
index 2da414befd8979312cc7b1c3e18466197d5f9f7a..1bb2bb5a15450f3aa774ded692b1ac6f0e610626 100644 (file)
 // Test that attempts to implicitly coerce a value into an
 // object respect the lifetime bound on the object type.
 
-#![feature(box_syntax)]
-
 trait Foo : ::std::marker::MarkerTrait {}
 impl<'a> Foo for &'a [u8] {}
 
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
 fn a(v: &[u8]) -> Box<Foo + 'static> {
-    let x: Box<Foo + 'static> = box v; //~ ERROR does not fulfill the required lifetime
+    let x: Box<Foo + 'static> = Box::new(v);
+    //~^ ERROR cannot infer an appropriate lifetime due to conflicting
     x
 }
 
 fn b(v: &[u8]) -> Box<Foo + 'static> {
-    box v //~ ERROR does not fulfill the required lifetime
+    Box::new(v)
+        //~^ ERROR cannot infer an appropriate lifetime due to conflicting
 }
 
 fn c(v: &[u8]) -> Box<Foo> {
     // same as previous case due to RFC 599
 
-    box v //~ ERROR does not fulfill the required lifetime
+    Box::new(v)
+        //~^ ERROR cannot infer an appropriate lifetime due to conflicting
 }
 
 fn d<'a,'b>(v: &'a [u8]) -> Box<Foo+'b> {
-    box v //~ ERROR does not fulfill the required lifetime
+    Box::new(v)
+        //~^ ERROR cannot infer an appropriate lifetime due to conflicting
 }
 
 fn e<'a:'b,'b>(v: &'a [u8]) -> Box<Foo+'b> {
-    box v // OK, thanks to 'a:'b
+    Box::new(v) // OK, thanks to 'a:'b
 }
 
 fn main() { }
index 9418156ffcd086ee6560431c84ac400f9b42de33..5db9a01c01286760b8e5c6c6fd9c68365e8f02d5 100644 (file)
@@ -20,4 +20,3 @@ fn main() {
         f = move |a: isize, b: isize| { a + b + *c_ref };
     }
 }
-
index 45e468b3ab06676c446ac7d1de41d822573c7270..04ee0526403fbe9dfedf2c8ca39205e2e2a8f9fb 100644 (file)
@@ -15,18 +15,18 @@ struct dog {
 impl dog {
     pub fn chase_cat(&mut self) {
         let p: &'static mut usize = &mut self.cats_chased; //~ ERROR cannot infer
-        *p += 1_usize;
+        *p += 1;
     }
 
     pub fn chase_cat_2(&mut self) {
         let p: &mut usize = &mut self.cats_chased;
-        *p += 1_usize;
+        *p += 1;
     }
 }
 
 fn dog() -> dog {
     dog {
-        cats_chased: 0_usize
+        cats_chased: 0
     }
 }
 
index 8cc2dd6afc645bc4203de7a03dd814c20bc0ee77..28491f1155c367b204ae52d128c2d4ca1698c3cf 100644 (file)
@@ -18,7 +18,7 @@ impl dog {
     pub fn chase_cat(&mut self) {
         let _f = || {
             let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
-            *p = 3_usize;
+            *p = 3;
         };
     }
 }
index 1705cfec6e2beba63ac0b9a55ea012cd9fe783c7..82d05c5d716aabe1238e3f95d3f0faf085ecddd2 100644 (file)
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:regions-bounded-method-type-parameters-cross-crate-lib.rs
+// aux-build:regions_bounded_method_type_parameters_cross_crate_lib.rs
 
 // Check explicit region bounds on methods in the cross crate case.
 
-extern crate "regions-bounded-method-type-parameters-cross-crate-lib" as lib;
+extern crate regions_bounded_method_type_parameters_cross_crate_lib as lib;
 
 use lib::Inv;
 use lib::MaybeOwned;
index 979c1e997d03c8b694c2bcb78605f5fcade1e610..f80b0ffa5aadf09eb20cc9447601b900dc949f3c 100644 (file)
@@ -10,6 +10,8 @@
 
 #![feature(box_syntax)]
 
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
 use std::marker::MarkerTrait;
 
 trait X : MarkerTrait {}
@@ -24,48 +26,48 @@ trait Iter {
 fn bad1<T: Iter>(v: T) -> Box<X+'static>
 {
     let item = v.into_item();
-    box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+    Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
 }
 
 fn bad2<T: Iter>(v: T) -> Box<X+'static>
     where Box<T::Item> : X
 {
-    let item = box v.into_item();
-    box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+    let item: Box<_> = box v.into_item();
+    Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
 }
 
 fn bad3<'a, T: Iter>(v: T) -> Box<X+'a>
 {
     let item = v.into_item();
-    box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+    Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
 }
 
 fn bad4<'a, T: Iter>(v: T) -> Box<X+'a>
     where Box<T::Item> : X
 {
-    let item = box v.into_item();
-    box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+    let item: Box<_> = box v.into_item();
+    Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
 }
 
 fn ok1<'a, T: Iter>(v: T) -> Box<X+'a>
     where T::Item : 'a
 {
     let item = v.into_item();
-    box item // OK, T::Item : 'a is declared
+    Box::new(item) // OK, T::Item : 'a is declared
 }
 
 fn ok2<'a, T: Iter>(v: &T, w: &'a T::Item) -> Box<X+'a>
     where T::Item : Clone
 {
     let item = Clone::clone(w);
-    box item // OK, T::Item : 'a is implied
+    Box::new(item) // OK, T::Item : 'a is implied
 }
 
 fn ok3<'a, T: Iter>(v: &'a T) -> Box<X+'a>
     where T::Item : Clone + 'a
 {
     let item = Clone::clone(v.as_item());
-    box item // OK, T::Item : 'a was declared
+    Box::new(item) // OK, T::Item : 'a was declared
 }
 
 fn meh1<'a, T: Iter>(v: &'a T) -> Box<X+'a>
@@ -78,8 +80,7 @@ fn meh1<'a, T: Iter>(v: &'a T) -> Box<X+'a>
     // T::Item`. But we're not that smart at present.
 
     let item = Clone::clone(v.as_item());
-    box item //~ ERROR associated type `<T as Iter>::Item` may not live
+    Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live
 }
 
 fn main() {}
-
index 7bbce7dad530db4fc9a21ab9a947009c486d8b8a..4c831a2b65953d15aae100091a9ca609251646dd 100644 (file)
@@ -25,4 +25,3 @@ fn f<'a, T:'static, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
 }
 
 fn main() {}
-
index e22d0c7d0a4f51bc9b14f95c53c90d077c3609b2..b723efff3c902e182d6140d1045c7bcf3018bbb3 100644 (file)
@@ -24,4 +24,3 @@ fn h<'a, T, U>(v: Box<A<U>+'static>) -> Box<X+'static> {
 }
 
 fn main() {}
-
index 147a575d38caca1ce10c1e18d4925efa308b7236..9b311588bb1ea7275312ead2b05331dc1efaca0b 100644 (file)
@@ -23,4 +23,3 @@ fn i<'a, T, U>(v: Box<A<U>+'a>) -> Box<X+'static> {
 }
 
 fn main() {}
-
index bdc52eca2cb2ded04fe7faa06459efa25b60f4dc..253132e5f07d02ed93ea98fcb613cb440934a750 100644 (file)
@@ -24,7 +24,7 @@ impl<'a, T> X for B<'a, T> {}
 
 fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
     box B(&*v) as Box<X> //~ ERROR the parameter type `T` may not live long enough
+        //~^ ERROR the parameter type `T` may not live long enough
 }
 
 fn main() {}
-
index fc18095fc8336585a582c9e0d51edf0fa3ab340d..924044647d84a08473c547d8da2366d2bb8b34b6 100644 (file)
@@ -19,6 +19,7 @@ trait SomeTrait { fn get(&self) -> isize; }
 fn make_object1<A:SomeTrait>(v: A) -> Box<SomeTrait+'static> {
     box v as Box<SomeTrait+'static>
         //~^ ERROR the parameter type `A` may not live long enough
+        //~^^ ERROR the parameter type `A` may not live long enough
 }
 
 fn make_object2<'a,A:SomeTrait+'a>(v: A) -> Box<SomeTrait+'a> {
@@ -28,6 +29,7 @@ fn make_object2<'a,A:SomeTrait+'a>(v: A) -> Box<SomeTrait+'a> {
 fn make_object3<'a,'b,A:SomeTrait+'a>(v: A) -> Box<SomeTrait+'b> {
     box v as Box<SomeTrait+'b>
         //~^ ERROR the parameter type `A` may not live long enough
+        //~^^ ERROR the parameter type `A` may not live long enough
 }
 
 fn main() { }
index 0f8bc6d684f12ab05df4fe4ea7f79f9b42e100db..10b883d4dc830b8568e8eb3391d5ffe0a0f3e0fc 100644 (file)
@@ -27,7 +27,7 @@ fn make_object_good2<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'b> {
 
 fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'c> {
     // A outlives 'a AND 'b...but not 'c.
-    box v as Box<SomeTrait+'a> //~ ERROR mismatched types
+    box v as Box<SomeTrait+'a> //~ ERROR lifetime of the source pointer does not outlive
 }
 
 fn main() {
index 655ac6f66c97db2ac173069431fcb36ce6203896..7324d4a4a0ed624e314b3ed46eb80c90ac9576b3 100644 (file)
@@ -8,33 +8,32 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
 
 trait X { fn foo(&self) {} }
 
 fn p1<T>(v: T) -> Box<X+'static>
     where T : X
 {
-    box v //~ ERROR parameter type `T` may not live long enough
+    Box::new(v) //~ ERROR parameter type `T` may not live long enough
 }
 
 fn p2<T>(v: Box<T>) -> Box<X+'static>
     where Box<T> : X
 {
-    box v //~ ERROR parameter type `T` may not live long enough
+    Box::new(v) //~ ERROR parameter type `T` may not live long enough
 }
 
 fn p3<'a,T>(v: T) -> Box<X+'a>
     where T : X
 {
-    box v //~ ERROR parameter type `T` may not live long enough
+    Box::new(v) //~ ERROR parameter type `T` may not live long enough
 }
 
 fn p4<'a,T>(v: Box<T>) -> Box<X+'a>
     where Box<T> : X
 {
-    box v //~ ERROR parameter type `T` may not live long enough
+    Box::new(v) //~ ERROR parameter type `T` may not live long enough
 }
 
 fn main() {}
-
index 4c361427bf37c6e0507bccfc84527363118ed9d1..ad2dc28afef02f3be21e4ca19cf918fa33fba6c9 100644 (file)
@@ -14,8 +14,8 @@ enum ast<'a> {
 }
 
 fn build() {
-    let x = ast::num(3_usize);
-    let y = ast::num(4_usize);
+    let x = ast::num(3);
+    let y = ast::num(4);
     let z = ast::add(&x, &y);
     compute(&z);
 }
index 58386c319f8abaaf107f3b7b5d339cd282a3725b..f114a8bc7ce668bfe6a35ac4e3141cf41709bed1 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
 
 fn ignore<T>(t: T) {}
 
@@ -16,17 +16,17 @@ fn nested<'x>(x: &'x isize) {
     let y = 3;
     let mut ay = &y;
 
-    ignore::<Box<for<'z> FnMut(&'z isize)>>(box |z| {
+    ignore::<Box<for<'z> FnMut(&'z isize)>>(Box::new(|z| {
         ay = x; //~ ERROR cannot infer
         ay = &y;
         ay = z;
-    });
+    }));
 
-    ignore::< Box<for<'z> FnMut(&'z isize) -> &'z isize>>(box |z| {
+    ignore::< Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
         if false { return x; }  //~ ERROR cannot infer an appropriate lifetime for automatic
         if false { return ay; }
         return z;
-    });
+    }));
 }
 
 fn main() {}
index 3401dd1becdd8b141dd5e8940e1af672ac7e68f2..8e83177090bb5223133a40c4b203fad65c2d1184 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 fn assert_static<T: 'static>(_t: T) {}
 
 fn main() {
index da839d72172619e19ecf7be11edc97235752b54e..ae9ceb600d45c1bb5be47b430b21453dd0746229 100644 (file)
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 fn main() {
-    let a0 = 0u8;
-    let f = 1u8;
+    let a0 = 0;
+    let f = 1;
     let mut a1 = &a0;
     match (&a1,) {
         (&ref b0,) => {
index 7ea4d1c7507afc5ae434ac63d07a753f10d489ba..3c137133c9867ca077ec86420b3d0c6e3716cce6 100644 (file)
@@ -8,17 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
 
 fn borrowed_proc<'a>(x: &'a isize) -> Box<FnMut()->(isize) + 'a> {
     // This is legal, because the region bound on `proc`
     // states that it captures `x`.
-    box move|| { *x }
+    Box::new(move|| { *x })
 }
 
 fn static_proc(x: &isize) -> Box<FnMut()->(isize) + 'static> {
     // This is illegal, because the region bound on `proc` is 'static.
-    box move|| { *x } //~ ERROR cannot infer
+    Box::new(move|| { *x }) //~ ERROR captured variable `x` does not outlive the enclosing closure
 }
 
 fn main() { }
index aa20efa5a12b157822f468aa47f73f795654d87c..1e2224eafaeb057567115767d28744583d64cb76 100644 (file)
@@ -15,7 +15,7 @@
 fn main() {
     // Unboxed closure case
     {
-        let mut x = 0_usize;
+        let mut x = 0;
         let mut f = || &mut x; //~ ERROR cannot infer
         let x = f();
         let y = f();
index 97b51fdb3250800ce687bac0731d5f1088e76424..a30d8471a31788e6136a8498f009b8539722a075 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
 #![feature(unboxed_closures)]
 
 struct closure_box<'a> {
@@ -20,9 +19,10 @@ fn box_it<'r>(x: Box<FnMut() + 'r>) -> closure_box<'r> {
 }
 
 fn main() {
-    let cl_box = {
+    let mut cl_box = {
         let mut i = 3;
-        box_it(box || i += 1) //~ ERROR cannot infer
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        box_it(Box::new(|| i += 1)) //~ ERROR `i` does not live long enough
     };
     cl_box.cl.call_mut(());
 }
index b45a37d26e58a2d0c41f7df1fd60dcd9924110f3..01439ce5e68775f83454622d295e33ac0aa92ac2 100644 (file)
@@ -34,7 +34,7 @@ fn get_v(gc: Box<get_ctxt>) -> usize {
 }
 
 fn main() {
-    let ctxt = ctxt { v: 22_usize };
+    let ctxt = ctxt { v: 22 };
     let hc = has_ctxt { c: &ctxt };
-    assert_eq!(get_v(box hc as Box<get_ctxt>), 22_usize);
+    assert_eq!(get_v(box hc as Box<get_ctxt>), 22);
 }
diff --git a/src/test/compile-fail/regions-trait-object-subtyping.rs b/src/test/compile-fail/regions-trait-object-subtyping.rs
new file mode 100644 (file)
index 0000000..f372269
--- /dev/null
@@ -0,0 +1,35 @@
+// 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 Dummy { fn dummy(&self); }
+
+fn foo1<'a:'b,'b>(x: &'a mut (Dummy+'a)) -> &'b mut (Dummy+'b) {
+    // Here, we are able to coerce
+    x
+}
+
+fn foo2<'a:'b,'b>(x: &'b mut (Dummy+'a)) -> &'b mut (Dummy+'b) {
+    // Here, we are able to coerce
+    x
+}
+
+fn foo3<'a,'b>(x: &'a mut Dummy) -> &'b mut Dummy {
+    // Without knowing 'a:'b, we can't coerce
+    x //~ ERROR lifetime of the source pointer does not outlive
+     //~^ ERROR cannot infer
+}
+
+struct Wrapper<T>(T);
+fn foo4<'a:'b,'b>(x: Wrapper<&'a mut Dummy>) -> Wrapper<&'b mut Dummy> {
+    // We can't coerce because it is packed in `Wrapper`
+    x //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/reject-specialized-drops-8142.rs b/src/test/compile-fail/reject-specialized-drops-8142.rs
new file mode 100644 (file)
index 0000000..30264c9
--- /dev/null
@@ -0,0 +1,79 @@
+// Copyright 2015 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.
+
+// Issue 8142: Test that Drop impls cannot be specialized beyond the
+// predicates attached to the struct/enum definition itself.
+
+#![feature(unsafe_destructor)]
+
+trait Bound { fn foo(&self) { } }
+struct K<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 }
+struct L<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 }
+struct M<'m> { x: &'m i8 }
+struct N<'n> { x: &'n i8 }
+struct O<To> { x: *const To }
+struct P<Tp> { x: *const Tp }
+struct Q<Tq> { x: *const Tq }
+struct R<Tr> { x: *const Tr }
+struct S<Ts:Bound> { x: *const Ts }
+struct T<'t,Ts:'t> { x: &'t Ts }
+struct U;
+struct V<Tva, Tvb> { x: *const Tva, y: *const Tvb }
+struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 }
+
+#[unsafe_destructor]
+impl<'al,'adds_bnd:'al> Drop for K<'al,'adds_bnd> {                        // REJECT
+    //~^ ERROR The requirement `'adds_bnd : 'al` is added only by the Drop impl.
+    fn drop(&mut self) { } }
+
+#[unsafe_destructor]
+impl<'al,'adds_bnd>     Drop for L<'al,'adds_bnd> where 'adds_bnd:'al {    // REJECT
+    //~^ ERROR The requirement `'adds_bnd : 'al` is added only by the Drop impl.
+    fn drop(&mut self) { } }
+
+#[unsafe_destructor]
+impl<'ml>               Drop for M<'ml>         { fn drop(&mut self) { } } // ACCEPT
+
+#[unsafe_destructor]
+impl                    Drop for N<'static>     { fn drop(&mut self) { } } // REJECT
+//~^ ERROR Implementations of Drop cannot be specialized
+
+#[unsafe_destructor]
+impl<Cok_nobound> Drop for O<Cok_nobound> { fn drop(&mut self) { } } // ACCEPT
+
+#[unsafe_destructor]
+impl              Drop for P<i8>          { fn drop(&mut self) { } } // REJECT
+//~^ ERROR Implementations of Drop cannot be specialized
+
+#[unsafe_destructor]
+impl<Adds_bnd:Bound> Drop for Q<Adds_bnd> { fn drop(&mut self) { } } // REJECT
+//~^ ERROR The requirement `Adds_bnd : Bound` is added only by the Drop impl.
+
+#[unsafe_destructor]
+impl<'rbnd,Adds_rbnd:'rbnd> Drop for R<Adds_rbnd> { fn drop(&mut self) { } } // REJECT
+//~^ ERROR The requirement `Adds_rbnd : 'rbnd` is added only by the Drop impl.
+
+#[unsafe_destructor]
+impl<Bs:Bound>    Drop for S<Bs>          { fn drop(&mut self) { } } // ACCEPT
+
+#[unsafe_destructor]
+impl<'t,Bt:'t>    Drop for T<'t,Bt>       { fn drop(&mut self) { } } // ACCEPT
+
+impl              Drop for U              { fn drop(&mut self) { } } // ACCEPT
+
+#[unsafe_destructor]
+impl<One>         Drop for V<One,One>     { fn drop(&mut self) { } } // REJECT
+//~^ERROR Implementations of Drop cannot be specialized
+
+#[unsafe_destructor]
+impl<'lw>         Drop for W<'lw,'lw>     { fn drop(&mut self) { } } // REJECT
+//~^ERROR Implementations of Drop cannot be specialized
+
+pub fn main() { }
index 9b3e2668042eaa0545513a8a5b5d4525e7c2a2e3..121581412202cdc882e168f51372689d7803408e 100644 (file)
@@ -19,7 +19,7 @@ fn main() {
 //~| found `()`
 //~| expected usize
 //~| found ()
-//~| ERROR expected constant integer for repeat count, found non-constant expression
+//~| ERROR expected positive integer for repeat count, found tuple
     let c = [0; true];
     //~^ ERROR mismatched types
     //~| expected `usize`
diff --git a/src/test/compile-fail/reserved-attr-on-macro.rs b/src/test/compile-fail/reserved-attr-on-macro.rs
new file mode 100644 (file)
index 0000000..db8f82a
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2015 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.
+
+#[rustc_attribute_should_be_reserved] //~ ERROR attributes with the prefix `rustc_` are reserved
+macro_rules! foo {
+    () => (());
+}
+
+fn main() {
+    foo!();
+}
index 8673d95de1b17e8770b4689e79cdf32c9b614b0a..af3ee7f353731c13141ce7b07fdcad5cf5d69d84 100644 (file)
@@ -12,4 +12,3 @@ extern crate std;
 //~^ ERROR an external crate named `std` has already been imported
 
 fn main(){}
-
index f27b11d5411c9589b417d9acf0bc93a92b92e812..0c601a81178b3ad28fcc71a301491f016ead71b6 100644 (file)
@@ -12,4 +12,3 @@ use std::slice as std; //~ ERROR import `std` conflicts with imported crate
 
 fn main() {
 }
-
index beb4b74f3264bff84693b3d6739aa6dbcdb37bfb..10afe82f2ef0fc65a347623e92b95ba81b4601b7 100644 (file)
@@ -14,4 +14,3 @@ use std::mem::transmute;
 
 fn main() {
 }
-
index 9d40196d4ac6b368d2d4ab15f3be605950670c98..e685353592f52cd8684777fbcc56529dc19a4555 100644 (file)
@@ -12,4 +12,3 @@ fn std() {}    //~ ERROR the name `std` conflicts with an external crate
 
 fn main() {
 }
-
index 96800918351c139becbaac93aac5efdb58d746e0..1edf815ecaeca402f5b6be30fef47213f07d8dec 100644 (file)
@@ -15,4 +15,3 @@ fn transmute() {}
 
 fn main() {
 }
-
index 0d0dc0a05d12ad1f006745501e5b043deb476d8d..fd4dce51fc8dbe17e9b6ee4db8002c92928a4f29 100644 (file)
 
 
 trait NewTrait : SomeNonExistentTrait {}
-//~^ ERROR attempt to derive a nonexistent trait `SomeNonExistentTrait`
+//~^ ERROR use of undeclared trait name `SomeNonExistentTrait`
 
 impl SomeNonExistentTrait for isize {}
-//~^ ERROR attempt to implement a nonexistent trait `SomeNonExistentTrait`
+//~^ ERROR use of undeclared trait name `SomeNonExistentTrait`
 
 fn f<T:SomeNonExistentTrait>() {}
-//~^ ERROR attempt to bound type parameter with a nonexistent trait `SomeNonExistentTrait`
-
+//~^ ERROR use of undeclared trait name `SomeNonExistentTrait`
diff --git a/src/test/compile-fail/retslot-cast.rs b/src/test/compile-fail/retslot-cast.rs
new file mode 100644 (file)
index 0000000..4ef07ec
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2015 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(rustc_attrs)]
+#![allow(warnings)]
+
+pub fn fail(x: Option<& (Iterator+Send)>) -> Option<&Iterator> {
+    // This call used to trigger an LLVM assertion because the return
+    // slot had type "Option<&Iterator>"* instead of
+    // "Option<&(Iterator+Send)>"* -- but this now yields a
+    // compilation error and I'm not sure how to create a comparable
+    // test. To ensure that this PARTICULAR failure doesn't occur
+    // again, though, I've left this test here, so if this ever starts
+    // to compile again, we can adjust the test appropriately (clearly
+    // it should never ICE...). -nmatsakis
+    inner(x) //~ ERROR mismatched types
+}
+
+pub fn inner(x: Option<& (Iterator+Send)>) -> Option<&(Iterator+Send)> {
+    x
+}
+
+#[rustc_error]
+fn main() {}
old mode 100755 (executable)
new mode 100644 (file)
index abbcd7e..fe03ca8
@@ -13,9 +13,10 @@ use std::thread;
 fn main() {
     let bad = {
         let x = 1;
-        let y = &x;
+        let y = &x; //~ ERROR `x` does not live long enough
 
-        thread::scoped(|| { //~ ERROR cannot infer an appropriate lifetime
+        thread::scoped(|| {
+            //~^ ERROR `y` does not live long enough
             let _z = y;
         })
     };
diff --git a/src/test/compile-fail/send-is-not-static-std-sync-2.rs b/src/test/compile-fail/send-is-not-static-std-sync-2.rs
new file mode 100644 (file)
index 0000000..d9d3706
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2015 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.
+
+// basic tests to see that certain "obvious" errors are caught by
+// these types no longer requiring `'static` (RFC 458)
+
+#![allow(dead_code)]
+
+use std::sync::{Mutex, RwLock, mpsc};
+
+fn mutex() {
+    let lock = {
+        let x = 1;
+        Mutex::new(&x) //~ ERROR does not live long enough
+    };
+
+    let _dangling = *lock.lock().unwrap();
+}
+
+fn rwlock() {
+    let lock = {
+        let x = 1;
+        RwLock::new(&x) //~ ERROR does not live long enough
+    };
+    let _dangling = *lock.read().unwrap();
+}
+
+fn channel() {
+    let (_tx, rx) = {
+        let x = 1;
+        let (tx, rx) = mpsc::channel();
+        let _ = tx.send(&x); //~ ERROR does not live long enough
+        (tx, rx)
+    };
+
+    let _dangling = rx.recv();
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/send-is-not-static-std-sync.rs b/src/test/compile-fail/send-is-not-static-std-sync.rs
new file mode 100644 (file)
index 0000000..8ec2fe8
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright 2015 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.
+
+// basic tests to see that certain "obvious" errors are caught by
+// these types no longer requiring `'static` (RFC 458)
+
+#![allow(dead_code)]
+
+use std::sync::{Mutex, RwLock, mpsc};
+
+fn mutex() {
+    let x = 1;
+    let y = Box::new(1);
+    let lock = Mutex::new(&x);
+    *lock.lock().unwrap() = &*y;
+    drop(y); //~ ERROR cannot move out
+    {
+        let z = 2;
+        *lock.lock().unwrap() = &z; //~ ERROR does not live long enough
+    }
+}
+
+fn rwlock() {
+    let x = 1;
+    let y = Box::new(1);
+    let lock = RwLock::new(&x);
+    *lock.write().unwrap() = &*y;
+    drop(y); //~ ERROR cannot move out
+    {
+        let z = 2;
+        *lock.write().unwrap() = &z; //~ ERROR does not live long enough
+    }
+}
+
+fn channel() {
+    let x = 1;
+    let y = Box::new(1);
+    let (tx, rx) = mpsc::channel();
+
+    tx.send(&x).unwrap();
+    tx.send(&*y);
+    drop(y); //~ ERROR cannot move out
+    {
+        let z = 2;
+        tx.send(&z).unwrap(); //~ ERROR does not live long enough
+    }
+}
+
+fn main() {}
index c29534128ae452f1e036fe041aa7119d832e45e8..e847d3324169ce7a5d17cdbecdf837afd224fe8d 100644 (file)
@@ -15,4 +15,3 @@ fn f((a, a): (isize, isize)) {} //~ ERROR identifier `a` is bound more than once
 fn main() {
     let (a, a) = (1, 1);    //~ ERROR identifier `a` is bound more than once
 }
-
index 901ae1d5e2ab1584e6d3053ee7d36942be4c019d..24b66213b39bd410cdffb9d011bd6b38caa63ab4 100644 (file)
@@ -17,19 +17,19 @@ struct Panolpy {
 
 fn foo(p: &Panolpy) {
     22 >> p.char;
-    //~^ ERROR right-hand-side of a shift operation must have integral type
+    //~^ ERROR E0277
+    //~| ERROR E0277
 
     22 >> p.str;
-    //~^ ERROR right-hand-side of a shift operation must have integral type
+    //~^ ERROR E0277
+    //~| ERROR E0277
 
     22 >> p;
-    //~^ ERROR right-hand-side of a shift operation must have integral type
+    //~^ ERROR E0277
+    //~| ERROR E0277
 
-    // We could be more accepting in the case of a type not yet inferred, but not
-    // known to be an integer, but meh.
     let x;
-    22 >> x;
-    //~^ ERROR the type of this value must be known in this context
+    22 >> x; // ambiguity error winds up being suppressed
 
     22 >> 1;
     // Integer literal types are OK
index f028c9af46235647a0fbe65c47fdbf8dd169fe63..feffe5c0b06c8e09fc10dcd75c68c9cec4ff21f6 100644 (file)
@@ -10,6 +10,7 @@
 
 // ignore-tidy-linelength
 
+#![feature(core)]
 
 use std::simd::f32x4;
 
diff --git a/src/test/compile-fail/single-derive-attr.rs b/src/test/compile-fail/single-derive-attr.rs
new file mode 100644 (file)
index 0000000..0b1b314
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2015 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.
+
+#[derive_Clone]
+//~^ ERROR attributes of the form `#[derive_*]` are reserved
+struct Test;
+
+pub fn main() {}
diff --git a/src/test/compile-fail/single-primitive-inherent-impl.rs b/src/test/compile-fail/single-primitive-inherent-impl.rs
new file mode 100644 (file)
index 0000000..b2cfcfa
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2015 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.
+
+// ignore-tidy-linelength
+
+#![crate_type = "lib"]
+#![feature(lang_items)]
+#![feature(no_std)]
+#![no_std]
+
+// OK
+#[lang = "char"]
+impl char {}
+
+impl char {
+//~^ error: only a single inherent implementation marked with `#[lang = "char"]` is allowed for the `char` primitive
+}
diff --git a/src/test/compile-fail/slice-1.rs b/src/test/compile-fail/slice-1.rs
deleted file mode 100644 (file)
index 3b992e3..0000000
+++ /dev/null
@@ -1,20 +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.
-
-// Test slicing &expr[] is deprecated and gives a helpful error message.
-
-struct Foo;
-
-fn main() {
-    let x = Foo;
-    &x[];
-    //~^ WARN obsolete syntax
-    //~| ERROR cannot index
-}
diff --git a/src/test/compile-fail/static-array-across-crate.rs b/src/test/compile-fail/static-array-across-crate.rs
new file mode 100644 (file)
index 0000000..04a731e
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+// aux-build:pub_static_array.rs
+
+extern crate pub_static_array as array;
+
+use array::ARRAY;
+
+static X: &'static u8 = &ARRAY[0];
+//~^ ERROR: cannot refer to the interior of another static, use a constant
+
+pub fn main() {}
index 349e5f4cb5105c433ab38fb9e4fd52c2bf7c933e..d0cfbfbbcccc21adaea08611ed774546c0eba768 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(static_assert)]
 #![allow(dead_code)]
 
 #[static_assert]
index d5e70205e9536f5ffa22f71232c8f5d0fc8b256c..35f840dab0c0cb6a0d7aa7446def00b272269145 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(static_assert)]
 #![allow(dead_code)]
 
 #[static_assert]
index 200aa9891935a3cee037a9c55cdb39a5392385a5..eca22bfdda07a8a1579af54dd3cb380d5d450c6d 100644 (file)
@@ -13,7 +13,7 @@
 fn f<T:'static>(_: T) {}
 
 fn main() {
-    let x = box 3;
+    let x: Box<_> = box 3;
     f(x);
     let x = &3; //~ ERROR borrowed value does not live long enough
     f(x);
index 667e944f92c5627c5888f430fff88d75b61f37fa..a1b6b9a744c72c56da60b731c7d86318f7ea5044 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:struct-field-privacy.rs
+// aux-build:struct_field_privacy.rs
 
-extern crate "struct-field-privacy" as xc;
+extern crate struct_field_privacy as xc;
 
 struct A {
     a: isize,
@@ -37,11 +37,11 @@ fn test(a: A, b: inner::A, c: inner::B, d: xc::A, e: xc::B) {
     c.a;
     c.b; //~ ERROR: field `b` of struct `inner::B` is private
 
-    d.a; //~ ERROR: field `a` of struct `struct-field-privacy::A` is private
+    d.a; //~ ERROR: field `a` of struct `struct_field_privacy::A` is private
     d.b;
 
     e.a;
-    e.b; //~ ERROR: field `b` of struct `struct-field-privacy::B` is private
+    e.b; //~ ERROR: field `b` of struct `struct_field_privacy::B` is private
 }
 
 fn main() {}
index c58273361ad0bebc691fd34903f9f9e9ad61f056..b8be7d0cdc20a59aa6f03d8e2d2beaba82c4a41f 100644 (file)
@@ -18,4 +18,3 @@ fn f(b: struct_variant_privacy::Bar) { //~ ERROR enum `Bar` is private
 }
 
 fn main() {}
-
index c276228b18ee3552cadd01ab33491abcb2828759..02c4f3d5d5268fd5fcc46ee291c0372d336ce88f 100644 (file)
@@ -26,40 +26,39 @@ fn main() {
     let pt = PointF {
         //~^ ERROR structure constructor specifies a structure of type
         //~| expected f32
-        //~| found i32
-        x: 1i32,
-        y: 2i32,
+        //~| found integral variable
+        x: 1,
+        y: 2,
     };
 
     let pt2 = Point::<f32> {
         //~^ ERROR structure constructor specifies a structure of type
         //~| expected f32
-        //~| found i32
-        x: 3i32,
-        y: 4i32,
+        //~| found integral variable
+        x: 3,
+        y: 4,
     };
 
     let pair = PairF {
         //~^ ERROR structure constructor specifies a structure of type
         //~| expected f32
-        //~| found i32
-        x: 5i32,
-        y: 6i32,
+        //~| found integral variable
+        x: 5,
+        y: 6,
     };
 
     let pair2 = PairF::<i32> {
         //~^ ERROR structure constructor specifies a structure of type
         //~| expected f32
-        //~| found i32
-        x: 7i32,
-        y: 8i32,
+        //~| found integral variable
+        x: 7,
+        y: 8,
     };
 
     let pt3 = PointF::<i32> {
         //~^ ERROR wrong number of type arguments
         //~| ERROR structure constructor specifies a structure of type
-        x: 9i32,
-        y: 10i32,
+        x: 9,
+        y: 10,
     };
 }
-
diff --git a/src/test/compile-fail/suggest-private-fields.rs b/src/test/compile-fail/suggest-private-fields.rs
new file mode 100644 (file)
index 0000000..f987257
--- /dev/null
@@ -0,0 +1,36 @@
+// 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.
+
+// aux-build:struct_field_privacy.rs
+
+extern crate struct_field_privacy as xc;
+
+use xc::B;
+
+struct A {
+    pub a: u32,
+    b: u32,
+}
+
+fn main () {
+    // external crate struct
+    let k = B {
+        aa: 20, //~ ERROR structure `struct_field_privacy::B` has no field named `aa`
+        //~^ HELP did you mean `a`?
+        bb: 20, //~ ERROR structure `struct_field_privacy::B` has no field named `bb`
+    };
+    // local crate struct
+    let l = A {
+        aa: 20, //~ ERROR structure `A` has no field named `aa`
+        //~^ HELP did you mean `a`?
+        bb: 20, //~ ERROR structure `A` has no field named `bb`
+        //~^ HELP did you mean `b`?
+    };
+}
diff --git a/src/test/compile-fail/syntaxt-default-trait-impls.rs b/src/test/compile-fail/syntaxt-default-trait-impls.rs
new file mode 100644 (file)
index 0000000..a33cd0e
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2015 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(optin_builtin_traits)]
+
+trait MyDefaultImpl {}
+
+impl<T> MyDefaultImpl for .. {}
+//~^ ERROR default trait implementations are not allowed to have genercis
+
+fn main() {}
index 9c1d318d5889990efb92f1d33bf6abcd0be641be..5c1270aa0e43d8f25adb1d42969871318dfc4c97 100644 (file)
@@ -12,6 +12,6 @@
 
 fn f() -> isize { return g(); }
 
-fn g() -> usize { return 0_usize; }
+fn g() -> usize { return 0; }
 
 fn main() { let y = f(); }
index fff144140947a11307157513cc8d4900e26444a0..1fd711ca4fb2c4eb898df30eaacf112ae0307693 100644 (file)
@@ -14,4 +14,3 @@ fn main() {
     TraitNotAStruct{ value: 0 };
     //~^ ERROR: use of trait `TraitNotAStruct` as a struct constructor [E0159]
 }
-
index 284c4fac953f2302b81fcc9b9efa6a0ba7d9ead5..217540415a7dd185c3b7f2c42f417729cfe29416 100644 (file)
@@ -32,4 +32,3 @@ struct ZipIterator<T, U> {
 }
 
 fn main() {}
-
index 448b186f6a5c6de1cff16451a9ff6db965d8cb7e..e126a3040e99277741f5910c278787d49216d29b 100644 (file)
@@ -15,7 +15,7 @@ trait Foo {
 // This should emit the less confusing error, not the more confusing one.
 
 fn foo(_x: Foo + Send) {
-    //~^ERROR the trait `core::marker::Sized` is not implemented
+    //~^ ERROR the trait `core::marker::Sized` is not implemented
 }
 
 fn main() { }
index df44e847c50fd5ffca5d96fbad2edc875444fd8c..d39b7e15edc34e9d2f7e2b20839c9258ee62882f 100644 (file)
@@ -25,4 +25,3 @@ fn main() {
     let baz: Foo<usize> = panic!();
     //~^ ERROR not implemented
 }
-
index 18871d0d386d77ec178838299a0861bbb8e7e338..d93c9bafaef27c36c205a5e933f106810aac50f1 100644 (file)
@@ -23,4 +23,3 @@ static X: Foo<usize> = Foo {
 
 fn main() {
 }
-
index ded75aa1d85e4e52b4dfdcc0ec9668ec1dd16af3..5f95a7ca6e20455ba2959975c8228334fbee5ebd 100644 (file)
@@ -22,4 +22,3 @@ fn kaboom(y: Bar<f32>) {}
 
 fn main() {
 }
-
index 8a9732de7fbd79e62d9ee048ae6130b3467779c2..840787022e65cc736d40a70d35087032bdc81e7e 100644 (file)
@@ -23,4 +23,3 @@ fn main() {
     //~^ ERROR not implemented
     let _ = bar;
 }
-
index 8dfdb2f205d6f27d7e423e7ea2cb471485d812f7..ce0a7d3bb36cf1bca80b0de8ba253f9450c2335d 100644 (file)
@@ -66,4 +66,3 @@ impl PolyTrait<Foo<usize>> for Struct {
 
 fn main() {
 }
-
index 1ddfc5b7ccd487d9369e73b06df65189f4fc6292..b25af522b2476e35759af8a255ade6225020a8c0 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
-
 struct Struct {
     person: &'static str
 }
@@ -25,7 +23,8 @@ impl Trait<&'static str> for Struct {
 }
 
 fn main() {
-    let s: Box<Trait<isize>> = box Struct { person: "Fred" };
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let s: Box<Trait<isize>> = Box::new(Struct { person: "Fred" });
     //~^ ERROR the trait `Trait<isize>` is not implemented for the type `Struct`
     s.f(1);
 }
index 7b426a4c0331545da4961f70a408d13627fdb7cd..9ba017e150e6112a1f1c3f4db1f2d6da1d7188e3 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
-
 struct Struct {
     person: &'static str
 }
@@ -27,6 +25,6 @@ impl Trait<&'static str> for Struct {
 fn main() {
     let person = "Fred".to_string();
     let person: &str = &person;  //~ ERROR `person` does not live long enough
-    let s: Box<Trait<&'static str>> = box Struct { person: person };
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let s: Box<Trait<&'static str>> = Box::new(Struct { person: person });
 }
-
diff --git a/src/test/compile-fail/trait-impl-2.rs b/src/test/compile-fail/trait-impl-2.rs
deleted file mode 100644 (file)
index 303e3d9..0000000
+++ /dev/null
@@ -1,24 +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.
-
-// Test calling methods on an impl for a bare trait. This test checks trait impls
-// must be in the same module as the trait.
-
-mod Foo {
-    trait T {}
-}
-
-mod Bar {
-    impl<'a> ::Foo::T+'a { //~ERROR: inherent implementations may only be implemented in the same
-        fn foo(&self) {}
-    }
-}
-
-fn main() {}
index 28d20483c7e7bcc498d4580c91eb1542e4374d4e..969b6398fdb10d787ed9ef456c64273afc92ade3 100644 (file)
@@ -14,7 +14,7 @@ mod a {
 trait A {
 }
 
-impl A for a { //~ERROR found module name used as a type
+impl A for a { //~ ERROR use of undeclared type name `a`
 }
 
 fn main() {
index e621d77a65c8d37a11700abea70b0c91b9a600a1..3aec23a55b8118e9f4766c28ed7c5d2c9e02e5d5 100644 (file)
@@ -8,9 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-tidy-linelength
-
-impl<T> Option<T> { //~ERROR inherent implementations are not allowed for types not defined in the current module
+impl<T> Option<T> {
+//~^ ERROR cannot associate methods with a type outside the crate the type is defined in
     pub fn foo(&self) { }
 }
 
index 032deb2e017ac59bf01c2ee0caf050c8ddadba20..6050b549b656f5bf5f228686136a98ab014ed14b 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:trait-safety-lib.rs
+// aux-build:trait_safety_lib.rs
 
 // Check that unsafe traits require unsafe impls and that inherent
 // impls cannot be unsafe.
 
-extern crate "trait-safety-lib" as lib;
+extern crate trait_safety_lib as lib;
 
 struct Bar;
 impl lib::Foo for Bar { //~ ERROR requires an `unsafe impl` declaration
index d8b3176787c040b1f75efdc2b741c05686522092..b09b10ffa0aad9dc22572e47f9348b44d7d7e7ac 100644 (file)
@@ -18,4 +18,5 @@ fn main() {
     10.dup::<i32>(); //~ ERROR does not take type parameters
     10.blah::<i32, i32>(); //~ ERROR incorrect number of type parameters
     (box 10 as Box<bar>).dup(); //~ ERROR cannot convert to a trait object
+    //~^ ERROR the trait `bar` is not implemented for the type `bar`
 }
diff --git a/src/test/compile-fail/traits-assoc-type-in-supertrait-bad.rs b/src/test/compile-fail/traits-assoc-type-in-supertrait-bad.rs
new file mode 100644 (file)
index 0000000..971869b
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2015 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 case where an associated type is referenced from within the
+// supertrait definition, and the impl makes the wrong
+// associations. Issue #20220.
+
+use std::vec::IntoIter;
+
+pub trait Foo: Iterator<Item=<Self as Foo>::Key> {
+    type Key;
+}
+
+impl Foo for IntoIter<i32> { //~ ERROR type mismatch
+    type Key = u32;
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/traits-issue-23003-overflow.rs b/src/test/compile-fail/traits-issue-23003-overflow.rs
new file mode 100644 (file)
index 0000000..ea41775
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright 2015 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 variant of traits-issue-23003 in which an infinite series of
+// types are required. This currently creates an overflow. This test
+// is included to ensure that some controlled failure, at least,
+// results -- but it might be that we should adjust the rules somewhat
+// to make this legal. -nmatsakis
+
+use std::marker::PhantomData;
+
+trait Async {
+    type Cancel;
+}
+
+struct Receipt<A:Async> {
+    marker: PhantomData<A>,
+}
+
+struct Complete<B> {
+    core: Option<B>,
+}
+
+impl<B> Async for Complete<B> {
+    type Cancel = Receipt<Complete<Option<B>>>;
+}
+
+fn foo(r: Receipt<Complete<()>>) { }
+//~^ ERROR overflow
+
+fn main() { }
index 0a5aa1b7bd34695cebb9a8451c45d0d5e25eb52f..8fe1f4d2371c42120120c57cf985d960692c75a6 100644 (file)
@@ -33,7 +33,7 @@ where T : Convert<U>
 }
 
 fn a() {
-    test(22_i32, std::default::Default::default()); //~ ERROR type annotations required
+    test(22, std::default::Default::default()); //~ ERROR type annotations required
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/traits-repeated-supertrait-ambig.rs b/src/test/compile-fail/traits-repeated-supertrait-ambig.rs
new file mode 100644 (file)
index 0000000..d61ac6f
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright 2015 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 a case of a trait which extends the same supertrait twice, but
+// with difference type parameters. Test then that when we don't give
+// enough information to pick between these, no selection is made. In
+// this particular case, the two choices are i64/u64 -- so when we use
+// an integer literal, we wind up falling this literal back to i32.
+// See also `run-pass/trait-repeated-supertrait.rs`.
+
+trait CompareTo<T> {
+    fn same_as(&self, t: T) -> bool;
+}
+
+trait CompareToInts : CompareTo<i64> + CompareTo<u64> {
+}
+
+impl CompareTo<i64> for i64 {
+    fn same_as(&self, t: i64) -> bool { *self == t }
+}
+
+impl CompareTo<u64> for i64 {
+    fn same_as(&self, t: u64) -> bool { *self == (t as i64) }
+}
+
+impl CompareToInts for i64 { }
+
+fn with_obj(c: &CompareToInts) -> bool {
+    c.same_as(22) //~ ERROR `CompareTo<i32>` is not implemented
+}
+
+fn with_trait<C:CompareToInts>(c: &C) -> bool {
+    c.same_as(22) //~ ERROR `CompareTo<i32>` is not implemented
+}
+
+fn with_ufcs1<C:CompareToInts>(c: &C) -> bool {
+    CompareToInts::same_as(c, 22) //~ ERROR `CompareTo<i32>` is not implemented
+}
+
+fn with_ufcs2<C:CompareToInts>(c: &C) -> bool {
+    CompareTo::same_as(c, 22) //~ ERROR `CompareTo<i32>` is not implemented
+}
+
+fn main() {
+    assert_eq!(22_i64.same_as(22), true); //~ ERROR `CompareTo<i32>` is not implemented
+}
index 5c61212a7f5a56324b4c7388acc6dcdd03e09315..918589b8fd3ac0f665d45b57e716d26f8234ff61 100644 (file)
@@ -25,5 +25,3 @@ unsafe fn g<T>(x: &T) {
 }
 
 fn main() {}
-
-
diff --git a/src/test/compile-fail/trivial_casts.rs b/src/test/compile-fail/trivial_casts.rs
new file mode 100644 (file)
index 0000000..3119b86
--- /dev/null
@@ -0,0 +1,94 @@
+// Copyright 2015 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 the trivial_casts and trivial_numeric_casts lints. For each error we also
+// check that the cast can be done using just coercion.
+
+#![deny(trivial_casts, trivial_numeric_casts)]
+
+trait Foo {
+    fn foo(&self) {}
+}
+
+pub struct Bar;
+
+impl Foo for Bar {}
+
+pub fn main() {
+    // Numeric
+    let _ = 42_i32 as i32; //~ ERROR trivial numeric cast: `i32` as `i32`
+    let _: i32 = 42_i32;
+
+    let _ = 42_u8 as u8; //~ ERROR trivial numeric cast: `u8` as `u8`
+    let _: u8 = 42_u8;
+
+    // & to * pointers
+    let x: &u32 = &42;
+    let _ = x as *const u32; //~ERROR trivial cast: `&u32` as `*const u32`
+    let _: *const u32 = x;
+
+    let x: &mut u32 = &mut 42;
+    let _ = x as *mut u32; //~ERROR trivial cast: `&mut u32` as `*mut u32`
+    let _: *mut u32 = x;
+
+    // unsize array
+    let x: &[u32; 3] = &[42, 43, 44];
+    let _ = x as &[u32]; //~ERROR trivial cast: `&[u32; 3]` as `&[u32]`
+    let _ = x as *const [u32]; //~ERROR trivial cast: `&[u32; 3]` as `*const [u32]`
+    let _: &[u32] = x;
+    let _: *const [u32] = x;
+
+    let x: &mut [u32; 3] = &mut [42, 43, 44];
+    let _ = x as &mut [u32]; //~ERROR trivial cast: `&mut [u32; 3]` as `&mut [u32]`
+    let _ = x as *mut [u32]; //~ERROR trivial cast: `&mut [u32; 3]` as `*mut [u32]`
+    let _: &mut [u32] = x;
+    let _: *mut [u32] = x;
+
+    let x: Box<[u32; 3]> = Box::new([42, 43, 44]);
+    let _ = x as Box<[u32]>; //~ERROR trivial cast: `Box<[u32; 3]>` as `Box<[u32]>`
+    let x: Box<[u32; 3]> = Box::new([42, 43, 44]);
+    let _: Box<[u32]> = x;
+
+    // unsize trait
+    let x: &Bar = &Bar;
+    let _ = x as &Foo; //~ERROR trivial cast: `&Bar` as `&Foo`
+    let _ = x as *const Foo; //~ERROR trivial cast: `&Bar` as `*const Foo`
+    let _: &Foo = x;
+    let _: *const Foo = x;
+
+    let x: &mut Bar = &mut Bar;
+    let _ = x as &mut Foo; //~ERROR trivial cast: `&mut Bar` as `&mut Foo`
+    let _ = x as *mut Foo; //~ERROR trivial cast: `&mut Bar` as `*mut Foo`
+    let _: &mut Foo = x;
+    let _: *mut Foo = x;
+
+    let x: Box<Bar> = Box::new(Bar);
+    let _ = x as Box<Foo>; //~ERROR trivial cast: `Box<Bar>` as `Box<Foo>`
+    let x: Box<Bar> = Box::new(Bar);
+    let _: Box<Foo> = x;
+
+    // functions
+    fn baz(_x: i32) {}
+    let _ = &baz as &Fn(i32); //~ERROR trivial cast: `&fn(i32) {main::baz}` as `&core::ops::Fn(i32)`
+    let _: &Fn(i32) = &baz;
+    let x = |_x: i32| {};
+    let _ = &x as &Fn(i32); //~ERROR trivial cast
+    let _: &Fn(i32) = &x;
+}
+
+// subtyping
+pub fn test_subtyping<'a, 'b: 'a>(a: &'a Bar, b: &'b Bar) {
+    let _ = a as &'a Bar; //~ERROR trivial cast
+    let _: &'a Bar = a;
+    let _ = b as &'a Bar; //~ERROR trivial cast
+    let _: &'a Bar = b;
+    let _ = b as &'b Bar; //~ERROR trivial cast
+    let _: &'b Bar = b;
+}
index 54b8d551f202e5fee102e8f95591805b10bcc945..c2c41fbbb2aaf16857a721a4a2dd90ec859dfafe 100644 (file)
 struct Point(i32, i32);
 
 fn main() {
-    let origin = Point(0i32, 0i32);
+    let origin = Point(0, 0);
     origin.0;
     origin.1;
     origin.2;
     //~^ ERROR attempted out-of-bounds tuple index `2` on type `Point`
-    let tuple = (0i32, 0i32);
+    let tuple = (0, 0);
     tuple.0;
     tuple.1;
     tuple.2;
-    //~^ ERROR attempted out-of-bounds tuple index `2` on type `(i32, i32)`
+    //~^ ERROR attempted out-of-bounds tuple index `2` on type `(_, _)`
 }
index 3bf0896d990af6fdea1ab8521cf65648695cc6ef..627300a037720b92ba9a45e7981b1f9a985638ee 100644 (file)
 
 // Checking that the compiler reports multiple type errors at once
 
-fn main() { let a: bool = 1i32; let b: i32 = true; }
+fn main() { let a: bool = 1; let b: i32 = true; }
 //~^ ERROR mismatched types
 //~| expected `bool`
-//~| found `i32`
+//~| found `_`
 //~| expected bool
-//~| found i32
+//~| found integral variable
 //~| ERROR mismatched types
 //~| expected `i32`
 //~| found `bool`
index 8ff514e04e360fbcef36cf6b39a4d61089b44214..8cc531625d17956c0d01223736884c2601774dc1 100644 (file)
@@ -20,7 +20,7 @@ impl MyAdd for i32 {
 }
 
 fn main() {
-    let x = 5;
+    let x: i32 = 5;
     let y = x as MyAdd<i32>;
     //~^ ERROR as `MyAdd<i32>`
 }
index de9623de7cd3a551c56e74a21d878e6a4baa8c55..88d8788d63a3de54bdcdc0f8dc3b1313558f709a 100644 (file)
@@ -23,7 +23,7 @@ trait BrokenAdd: Int {
 impl<T: Int> BrokenAdd for T {}
 
 pub fn main() {
-    let foo: u8 = 0u8;
+    let foo: u8 = 0;
     let x: u8 = foo.broken_add("hello darkness my old friend".to_string());
     println!("{}", x);
 }
index 3a4cc9e874e7d2d0f91da799ebfb9f2d4cc570dd..71e9113603a6061a50e20fa57dd62ae06cc7022f 100644 (file)
@@ -29,4 +29,3 @@ trait B<T>: Tr<T> {
 
 fn main() {
 }
-
index c113e1b7815212a6f39bd9433095aee0d77c91c8..3ad1e9ab538dbac58c286d07977659f9bf429d63 100644 (file)
@@ -15,4 +15,3 @@ trait Tr : Sized {
 }
 
 fn main() {}
-
diff --git a/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs b/src/test/compile-fail/typeck-builtin-bound-type-parameters.rs
new file mode 100644 (file)
index 0000000..fb6c43a
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2015 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.
+
+fn foo1<T:Copy<U>, U>(x: T) {}
+//~^ ERROR: wrong number of type arguments: expected 0, found 1
+
+trait Trait: Copy<Send> {}
+//~^ ERROR: wrong number of type arguments: expected 0, found 1
+
+struct MyStruct1<T: Copy<T>>;
+//~^ ERROR wrong number of type arguments: expected 0, found 1
+
+struct MyStruct2<'a, T: Copy<'a>>;
+//~^ ERROR: wrong number of lifetime parameters: expected 0, found 1
+
+fn foo2<'a, T:Copy<'a, U>, U>(x: T) {}
+//~^ ERROR: wrong number of type arguments: expected 0, found 1
+//~^^ ERROR: wrong number of lifetime parameters: expected 0, found 1
+
+fn main() {
+}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-assoc-type.rs b/src/test/compile-fail/typeck-default-trait-impl-assoc-type.rs
new file mode 100644 (file)
index 0000000..8a9d537
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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 we do not consider associated types to be sendable without
+// some applicable trait bound (and we don't ICE).
+
+trait Trait {
+    type AssocType;
+    fn dummy(&self) { }
+}
+fn bar<T:Trait+Send>() {
+    is_send::<T::AssocType>(); //~ ERROR not implemented
+}
+
+fn is_send<T:Send>() {
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs b/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs
new file mode 100644 (file)
index 0000000..0f3453d
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2015 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(optin_builtin_traits)]
+
+use std::marker::MarkerTrait;
+
+trait MyTrait: MarkerTrait {}
+
+impl MyTrait for .. {}
+
+struct MyS;
+
+struct MyS2;
+
+impl !MyTrait for MyS2 {}
+
+fn is_mytrait<T: MyTrait>() {}
+
+fn main() {
+    is_mytrait::<MyS>();
+
+    is_mytrait::<(MyS2, MyS)>();
+    //~^ ERROR the trait `MyTrait` is not implemented for the type `MyS2`
+}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs b/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs
new file mode 100644 (file)
index 0000000..524f467
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2015 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(optin_builtin_traits)]
+
+use std::marker::MarkerTrait;
+
+trait MyTrait: MarkerTrait {}
+
+impl MyTrait for .. {}
+impl<T> !MyTrait for *mut T {}
+
+struct MyS;
+
+struct MyS2;
+
+impl !MyTrait for MyS2 {}
+
+struct MyS3;
+
+fn is_mytrait<T: MyTrait>() {}
+
+fn main() {
+    is_mytrait::<MyS>();
+
+    is_mytrait::<MyS2>();
+    //~^ ERROR the trait `MyTrait` is not implemented for the type `MyS2`
+}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-cross-crate-coherence.rs b/src/test/compile-fail/typeck-default-trait-impl-cross-crate-coherence.rs
new file mode 100644 (file)
index 0000000..b1febae
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2015 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.
+
+// aux-build:typeck_default_trait_impl_cross_crate_coherence_lib.rs
+
+// Test that we do not consider associated types to be sendable without
+// some applicable trait bound (and we don't ICE).
+
+#![feature(optin_builtin_traits)]
+
+extern crate typeck_default_trait_impl_cross_crate_coherence_lib as lib;
+
+use lib::DefaultedTrait;
+
+struct A;
+impl DefaultedTrait for (A,) { } //~ ERROR E0117
+
+struct B;
+impl !DefaultedTrait for (B,) { } //~ ERROR E0117
+
+struct C;
+struct D<T>(T);
+impl DefaultedTrait for Box<C> { } //~ ERROR E0321
+impl DefaultedTrait for lib::Something<C> { } //~ ERROR E0117
+impl DefaultedTrait for D<C> { } // OK
+
+fn main() { }
diff --git a/src/test/compile-fail/typeck-default-trait-impl-negation-send.rs b/src/test/compile-fail/typeck-default-trait-impl-negation-send.rs
new file mode 100644 (file)
index 0000000..db4d1fe
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2015 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(optin_builtin_traits)]
+
+struct MySendable {
+   t: *mut u8
+}
+
+unsafe impl Send for MySendable {}
+
+struct MyNotSendable {
+   t: *mut u8
+}
+
+impl !Send for MyNotSendable {}
+
+fn is_send<T: Send>() {}
+
+fn main() {
+    is_send::<MySendable>();
+    is_send::<MyNotSendable>();
+    //~^ ERROR the trait `core::marker::Send` is not implemented for the type `MyNotSendable`
+}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-negation-sync.rs b/src/test/compile-fail/typeck-default-trait-impl-negation-sync.rs
new file mode 100644 (file)
index 0000000..d613589
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright 2015 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.
+
+// ignore-tidy-linelength
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::Managed;
+use std::cell::UnsafeCell;
+
+struct MySync {
+   t: *mut u8
+}
+
+unsafe impl Sync for MySync {}
+
+struct MyNotSync {
+   t: *mut u8
+}
+
+impl !Sync for MyNotSync {}
+
+struct MyTypeWUnsafe {
+   t: UnsafeCell<u8>
+}
+
+struct MyTypeManaged {
+   t: Managed
+}
+
+fn is_sync<T: Sync>() {}
+
+fn main() {
+    is_sync::<MySync>();
+    is_sync::<MyNotSync>();
+    //~^ ERROR the trait `core::marker::Sync` is not implemented for the type `MyNotSync`
+
+    is_sync::<MyTypeWUnsafe>();
+    //~^ ERROR the trait `core::marker::Sync` is not implemented for the type `core::cell::UnsafeCell<u8>`
+
+    is_sync::<MyTypeManaged>();
+    //~^ ERROR the trait `core::marker::Sync` is not implemented for the type `core::marker::Managed`
+}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-negation.rs b/src/test/compile-fail/typeck-default-trait-impl-negation.rs
new file mode 100644 (file)
index 0000000..a1ca0e3
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright 2015 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(optin_builtin_traits)]
+
+use std::marker::MarkerTrait;
+
+trait MyTrait: MarkerTrait {}
+
+impl MyTrait for .. {}
+
+unsafe trait MyUnsafeTrait: MarkerTrait {}
+
+unsafe impl MyUnsafeTrait for .. {}
+
+struct ThisImplsTrait;
+
+impl !MyUnsafeTrait for ThisImplsTrait {}
+
+
+struct ThisImplsUnsafeTrait;
+
+impl !MyTrait for ThisImplsUnsafeTrait {}
+
+fn is_my_trait<T: MyTrait>() {}
+fn is_my_unsafe_trait<T: MyUnsafeTrait>() {}
+
+fn main() {
+    is_my_trait::<ThisImplsTrait>();
+    is_my_trait::<ThisImplsUnsafeTrait>();
+    //~^ ERROR the trait `MyTrait` is not implemented for the type `ThisImplsUnsafeTrait`
+
+    is_my_unsafe_trait::<ThisImplsTrait>();
+    //~^ ERROR the trait `MyUnsafeTrait` is not implemented for the type `ThisImplsTrait`
+
+    is_my_unsafe_trait::<ThisImplsUnsafeTrait>();
+}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs b/src/test/compile-fail/typeck-default-trait-impl-outside-crate.rs
new file mode 100644 (file)
index 0000000..a345bd1
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2015 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.
+
+// ignore-tidy-linelength
+
+#![feature(optin_builtin_traits)]
+
+impl Copy for .. {}
+//~^ ERROR E0318
+
+fn main() {}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-precedence.rs b/src/test/compile-fail/typeck-default-trait-impl-precedence.rs
new file mode 100644 (file)
index 0000000..4006eb2
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2015 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 declaring that `&T` is `Defaulted` if `T:Signed` implies
+// that other `&T` is NOT `Defaulted` if `T:Signed` does not hold. In
+// other words, the `..` impl only applies if there are no existing
+// impls whose types unify.
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::MarkerTrait;
+
+trait Defaulted : MarkerTrait { }
+impl Defaulted for .. { }
+impl<'a,T:Signed> Defaulted for &'a T { }
+impl<'a,T:Signed> Defaulted for &'a mut T { }
+fn is_defaulted<T:Defaulted>() { }
+
+trait Signed : MarkerTrait { }
+impl Signed for i32 { }
+
+fn main() {
+    is_defaulted::<&'static i32>();
+    is_defaulted::<&'static u32>();
+    //~^ ERROR the trait `Signed` is not implemented for the type `u32`
+}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-send-param.rs b/src/test/compile-fail/typeck-default-trait-impl-send-param.rs
new file mode 100644 (file)
index 0000000..185e9dc
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2015 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 we do not consider parameter types to be sendable without
+// an explicit trait bound.
+
+fn foo<T>() {
+    is_send::<T>() //~ ERROR not implemented
+}
+
+fn is_send<T:Send>() {
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/typeck-default-trait-impl-superregion.rs b/src/test/compile-fail/typeck-default-trait-impl-superregion.rs
new file mode 100644 (file)
index 0000000..4a6a77a
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2015 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 when a `..` impl applies, we also check that any
+// supertrait conditions are met.
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::MarkerTrait;
+
+trait MyTrait : 'static {}
+
+impl MyTrait for .. {}
+
+fn foo<T:MyTrait>() { }
+
+fn bar<'a>() {
+    foo::<&'a ()>(); //~ ERROR does not fulfill the required lifetime
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-supertrait.rs b/src/test/compile-fail/typeck-default-trait-impl-supertrait.rs
new file mode 100644 (file)
index 0000000..7f24058
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2015 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 when a `..` impl applies, we also check that any
+// supertrait conditions are met.
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::MarkerTrait;
+
+trait NotImplemented: MarkerTrait { }
+
+trait MyTrait : NotImplemented {}
+
+impl MyTrait for .. {}
+
+fn foo<T:MyTrait>() { bar::<T>() }
+
+fn bar<T:NotImplemented>() { }
+
+fn main() {
+    foo::<i32>(); //~ ERROR the trait `NotImplemented` is not implemented for the type `i32`
+    bar::<i64>(); //~ ERROR the trait `NotImplemented` is not implemented for the type `i64`
+}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs b/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs
new file mode 100644 (file)
index 0000000..c970aaa
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2015 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.
+
+// ignore-tidy-linelength
+
+// Test that when a `..` impl applies, we also check that any
+// supertrait conditions are met.
+
+#![feature(optin_builtin_traits)]
+
+use std::marker::MarkerTrait;
+
+trait NotImplemented: MarkerTrait { }
+
+trait MyTrait: MarkerTrait
+    where Option<Self> : NotImplemented
+{}
+
+impl NotImplemented for i32 {}
+
+impl MyTrait for .. {}
+
+fn foo<T:MyTrait>() {
+    bar::<Option<T>>()
+    //~^ ERROR the trait `NotImplemented` is not implemented for the type `core::option::Option<T>`
+    //
+    // This should probably typecheck. This is #20671.
+}
+
+fn bar<T:NotImplemented>() { }
+
+fn test() {
+    bar::<Option<i32>>();
+    //~^ ERROR the trait `NotImplemented` is not implemented for the type `core::option::Option<i32>`
+}
+
+fn main() {
+    foo::<i32>();
+    //~^ ERROR the trait `NotImplemented` is not implemented for the type `core::option::Option<i32>`
+}
index 557fb2f4f8833ff18f775a5c654841ebf9760fcf..57a394dc7f1ec746847641673a6ac0ef8fcf126c 100644 (file)
@@ -17,6 +17,6 @@ trait TestTrait {
 }
 
 impl !TestTrait for TestType {}
-//~^ ERROR  negative impls are currently allowed just for `Send` and `Sync`
+//~^ ERROR negative impls are only allowed for traits with default impls (e.g., `Send` and `Sync`)
 
 fn main() {}
index 5bfad94867e2544c4291236bb0d11c17dcda23a9..d4f3cdfd8b7e248eefedc4d3896d13a0101ff235 100644 (file)
@@ -21,7 +21,7 @@ fn test2() -> (_, _) { (5, 5) }
 static TEST3: _ = "test";
 //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
 
-static TEST4: _ = 145u16;
+static TEST4: _ = 145;
 //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
 
 static TEST5: (_, _) = (1, 2);
@@ -74,7 +74,7 @@ pub fn main() {
     static FN_TEST3: _ = "test";
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
 
-    static FN_TEST4: _ = 145u16;
+    static FN_TEST4: _ = 145;
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
 
     static FN_TEST5: (_, _) = (1, 2);
index cbcf31b5b7edbc46355ea238d31cfad03671517b..5d2b5fa52db41b29910a9952974f2c2258f12358 100644 (file)
@@ -63,4 +63,3 @@ fn main() {
     };
     println!("{} {}", bar.foo(2), bar.bar(2));
 }
-
index f4e18265fd9901b528653a777f77ea31f6a55226..b3fe178dc455e83b0d8c40f7092b57cbee1090fd 100644 (file)
@@ -12,5 +12,5 @@ use std::borrow::IntoCow;
 
 fn main() {
     <String as IntoCow>::into_cow("foo".to_string());
-    //~^ ERROR wrong number of type arguments: expected 1, found 0
+    //~^ ERROR too few type parameters provided: expected 1 parameter(s)
 }
index 868c1eae4a9e1fd80c868847aba8e576885c8f29..8e60064beca170487a7b0834d63e90d86f62d4e6 100644 (file)
@@ -18,4 +18,3 @@ fn main() {
     <i32 as Add<i32>>::add(1, 2u32);
     //~^ ERROR mismatched types
 }
-
index 800126450c9726887796a01a8c5343225e3982ab..564b1b4669f7d0235ea2ed45c1a124b6577485cc 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
 #![feature(unboxed_closures)]
 
 // Tests that we can't move out of an unboxed closure environment
@@ -19,31 +18,33 @@ fn to_fn<A,F:Fn<A>>(f: F) -> F { f }
 fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
 fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
 
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
 fn main() {
     // By-ref cases
     {
-        let x = box 0_usize;
+        let x = Box::new(0);
         let f = to_fn(|| drop(x)); //~ ERROR cannot move
     }
     {
-        let x = box 0_usize;
+        let x = Box::new(0);
         let f = to_fn_mut(|| drop(x)); //~ ERROR cannot move
     }
     {
-        let x = box 0_usize;
+        let x = Box::new(0);
         let f = to_fn_once(|| drop(x)); // OK -- FnOnce
     }
     // By-value cases
     {
-        let x = box 0_usize;
+        let x = Box::new(0);
         let f = to_fn(move || drop(x)); //~ ERROR cannot move
     }
     {
-        let x = box 0_usize;
+        let x = Box::new(0);
         let f = to_fn_mut(move || drop(x)); //~ ERROR cannot move
     }
     {
-        let x = box 0_usize;
+        let x = Box::new(0);
         let f = to_fn_once(move || drop(x)); // this one is ok
     }
 }
index b40a91181adde2b63c9ededa0260da8c553ec8a9..5be2738b47eff1c1296ea1829755ded3fab1d51a 100644 (file)
@@ -17,7 +17,7 @@
 fn set(x: &mut usize) { *x = 0; }
 
 fn main() {
-    let x = 0_usize;
+    let x = 0;
     move || x = 1; //~ ERROR cannot assign
     move || set(&mut x); //~ ERROR cannot borrow
     move || x = 1; //~ ERROR cannot assign
index 59c8495371852c809d39db541b7d4a5f5ede996e..eee1b6ce30b5e7467aa53ef15c5700b248f71b08 100644 (file)
@@ -14,7 +14,7 @@
 // reference cannot escape the region of that variable.
 fn main() {
     let _f = {
-        let x = 0_usize;
-        || x //~ ERROR cannot infer an appropriate lifetime due to conflicting requirements
+        let x = 0;
+        || x //~ ERROR `x` does not live long enough
     };
 }
index 12f62d805e15a8235d47b5df91fbf50768fadd11..b195a932acaa63d21e6a304fb1d5202d39d10896 100644 (file)
 
 #![feature(unboxed_closures)]
 
-fn f<F:Nonexist(isize) -> isize>(x: F) {} //~ ERROR nonexistent trait `Nonexist`
+fn f<F:Nonexist(isize) -> isize>(x: F) {} //~ ERROR undeclared trait name `Nonexist`
 
 type Typedef = isize;
 
 fn g<F:Typedef(isize) -> isize>(x: F) {} //~ ERROR `Typedef` is not a trait
 
 fn main() {}
-
index 1f0d5aae36db5abaefa64597eff7537312522474..55156e28cd703e3e33b75ebf58028076a9e01fdd 100644 (file)
@@ -20,4 +20,3 @@ fn bar2<T>(x: &T) where T: Fn<()> {
 }
 
 fn main() { }
-
index a3991a87b78f8a1caa47891adc7c43c2c5d3f4ee..1e36c47c0973b443b5104abcf31245495554a81f 100644 (file)
@@ -22,4 +22,3 @@ fn bar() {
 }
 
 fn main() { }
-
index ad85cdcaa03a15246be7261f407f6ab69ce5b4d9..f50d91a4ddd9faf571eed087af1e867f1d394942 100644 (file)
@@ -20,4 +20,3 @@ fn foo(b: Box<Bar()>) {
 }
 
 fn main() { }
-
index 5810ffcf21ab69e569974f9aa8fee6f92a6f810e..e6e18d996b9e2e7adce47d19f41e49daa46c2204 100644 (file)
@@ -17,4 +17,3 @@ fn f<F:Trait(isize) -> isize>(x: F) {}
 //~| ERROR no associated type `Output`
 
 fn main() {}
-
index 1191cfa2600b8a231f1d5d3c5dc4e148e492fcf5..372f3277931e1ff7eab1deaa6cce0605a78f6b29 100644 (file)
@@ -14,7 +14,7 @@
 // cause borrow conflicts.
 
 fn main() {
-    let mut x = 0_usize;
+    let mut x = 0;
     let f = || x += 1;
     let _y = x; //~ ERROR cannot use `x` because it was mutably borrowed
 }
index bbafd5109edff0b25cbdf00b3ecfae7dd42b280d..93498ac7f83514c1768d1babc95dcd640c3435e2 100644 (file)
@@ -19,13 +19,17 @@ use std::ops::{Fn,FnMut,FnOnce};
 struct S;
 
 impl FnMut<(isize,)> for S {
-    type Output = isize;
-
     extern "rust-call" fn call_mut(&mut self, (x,): (isize,)) -> isize {
         x * x
     }
 }
 
+impl FnOnce<(isize,)> for S {
+    type Output = isize;
+
+    extern "rust-call" fn call_once(mut self, args: (isize,)) -> isize { self.call_mut(args) }
+}
+
 fn call_it<F:Fn(isize)->isize>(f: &F, x: isize) -> isize {
     f.call((x,))
 }
@@ -33,6 +37,4 @@ fn call_it<F:Fn(isize)->isize>(f: &F, x: isize) -> isize {
 fn main() {
     let x = call_it(&S, 22);
     //~^ ERROR not implemented
-    //~| ERROR not implemented
 }
-
index f993b8fa8c4d1ec92ade3857b6c6c7227a23170e..226b516e09db26730b5b64e9aec3234f33fd2315 100644 (file)
@@ -15,4 +15,3 @@ fn main() {
     let () = zero.call_mut(());
     //~^ ERROR we have not yet inferred what kind of closure it is
 }
-
index afbc141b5d246aa8390d13001e41c26ede2e424e..7c5ea031596563b71a8868e7dfed7f4b5ea7c10d 100644 (file)
@@ -29,4 +29,3 @@ fn main() {
 
     tick2(); //~ ERROR cannot borrow
 }
-
index 650bb17bb7758f9ce60d81d2dcc7ec38ff7cab7b..35052ec0bd507b2334336590723c349eb6680fd5 100644 (file)
@@ -20,21 +20,21 @@ fn to_fn<A,F:Fn<A>>(f: F) -> F { f }
 fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
 
 fn a() {
-    let n = 0u8;
+    let n = 0;
     let mut f = to_fn_mut(|| { //~ ERROR closure cannot assign
         n += 1;
     });
 }
 
 fn b() {
-    let mut n = 0u8;
+    let mut n = 0;
     let mut f = to_fn_mut(|| {
         n += 1; // OK
     });
 }
 
 fn c() {
-    let n = 0u8;
+    let n = 0;
     let mut f = to_fn_mut(move || {
         // If we just did a straight-forward desugaring, this would
         // compile, but we do something a bit more subtle, and hence
@@ -44,21 +44,21 @@ fn c() {
 }
 
 fn d() {
-    let mut n = 0u8;
+    let mut n = 0;
     let mut f = to_fn_mut(move || {
         n += 1; // OK
     });
 }
 
 fn e() {
-    let n = 0u8;
+    let n = 0;
     let mut f = to_fn(move || {
         n += 1; //~ ERROR cannot assign
     });
 }
 
 fn f() {
-    let mut n = 0u8;
+    let mut n = 0;
     let mut f = to_fn(move || {
         n += 1; //~ ERROR cannot assign
     });
index 2345a86595e2da0223b60d29f68147c5964c3bdc..432c7fa5d1b2025c9d8d2605e7bb31052ac80fd2 100644 (file)
@@ -16,7 +16,7 @@ fn call<F>(f: F) where F : Fn() {
 }
 
 fn main() {
-    let mut counter = 0_u32;
+    let mut counter = 0;
     call(|| {
         counter += 1;
         //~^ ERROR cannot assign to data in a captured outer variable in an `Fn` closure
index 713b64b1349fcc5893ac455a2755aa9449a203ef..2dcd7a97d8977eec83fc37a53c8dd016bc3b31fa 100644 (file)
@@ -28,14 +28,19 @@ impl<F,A,R> YCombinator<F,A,R> {
 }
 
 impl<A,R,F : FnMut(&mut FnMut(A) -> R, A) -> R> FnMut<(A,)> for YCombinator<F,A,R> {
-    type Output = R;
-
     extern "rust-call" fn call_mut(&mut self, (arg,): (A,)) -> R {
         (self.func)(self, arg)
             //~^ ERROR cannot borrow `*self` as mutable more than once at a time
     }
 }
 
+impl<A,R,F : FnMut(&mut FnMut(A) -> R, A) -> R> FnOnce<(A,)> for YCombinator<F,A,R> {
+    type Output = R;
+    extern "rust-call" fn call_once(mut self, args: (A,)) -> R {
+        self.call_mut(args)
+    }
+}
+
 fn main() {
     let mut counter = 0;
     let factorial = |recur: &mut FnMut(u32) -> u32, arg: u32| -> u32 {
index f430e9fc7590228fba05867ea5a3e855a85f8188..1a52e22419eb46c6c59a61b2f505ec0c235d00c2 100644 (file)
@@ -16,4 +16,3 @@ fn main() {
     let mut_ = to_fn_mut(|x| x);
     mut_.call((0, )); //~ ERROR does not implement any method in scope named `call`
 }
-
index 23f7ee2b0101d78cca2d2db9fcaa4702ac8e33bd..dc7c70ba649d8b0524766893a060679a1714c511 100644 (file)
@@ -27,11 +27,15 @@ fn a() {
 }
 
 fn b() {
-    let y = call_it_mut(&mut square, 22); //~ ERROR not implemented
+    let y = call_it_mut(&mut square, 22);
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
 
 fn c() {
-    let z = call_it_once(square, 22); //~ ERROR not implemented
+    let z = call_it_once(square, 22);
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
 
 fn main() { }
index c2a2e5162ace070a12c18aa6383f7cc9078ab323..28e8b8db2a46bde8037790eee0ca456b2f9dd90b 100644 (file)
@@ -25,4 +25,3 @@ pub fn main() {
     //~| ERROR type mismatch
     println!("{}", z);
 }
-
index 96619bef36fd5fb400deeec4c343351183b7e74a..cdcb435b65a6acfcc8cdc3700d420022234385bb 100644 (file)
@@ -27,12 +27,15 @@ fn a() {
 }
 
 fn b() {
-    let y = call_it_mut(&mut square, 22); //~ ERROR not implemented
+    let y = call_it_mut(&mut square, 22);
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
 
 fn c() {
-    let z = call_it_once(square, 22); //~ ERROR not implemented
+    let z = call_it_once(square, 22);
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
 
 fn main() { }
-
index ebcbdbbc006df83585ba4d02dad8817285a1109d..150bf36dcc286db2befd582b8dd6fa055495e1b8 100644 (file)
@@ -28,11 +28,15 @@ fn a() {
 }
 
 fn b() {
-    let y = call_it_mut(&mut square, 22); //~ ERROR not implemented
+    let y = call_it_mut(&mut square, 22);
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
 
 fn c() {
-    let z = call_it_once(square, 22); //~ ERROR not implemented
+    let z = call_it_once(square, 22);
+    //~^ ERROR not implemented
+    //~| ERROR not implemented
 }
 
 fn main() { }
index 88535ee04fb5b847fd23c21f4433d4d0331cdcf7..2ec10d08bb41d5ff92087c2eae36c4a410fd15a9 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
-
 #[derive(Debug)]
 struct r {
   b: bool,
@@ -20,7 +18,8 @@ impl Drop for r {
 }
 
 fn main() {
-    let i = box r { b: true };
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let i = Box::new(r { b: true });
     let _j = i.clone(); //~ ERROR not implement
     println!("{:?}", i);
 }
index 046337c33f0131dc4c2b4f5f5c58e26ec269a63a..86fe4da3429d084f23d164d47fe024fc4811ae79 100644 (file)
@@ -8,15 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
-
 use std::rc::Rc;
 
 fn f<T:Send>(__isize: T) {
 }
 
 fn main() {
-    let i = box Rc::new(100);
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let i = Box::new(Rc::new(100));
     f(i);
     //~^ ERROR `core::marker::Send` is not implemented
 }
index 91a41ad6a4986d81e8d91f0dad2bd50642c5642a..938abbf2c2018952a44739b07b3a7c027c866598 100644 (file)
@@ -10,8 +10,6 @@
 
 #![feature(unsafe_destructor)]
 
-#![feature(box_syntax)]
-
 use std::cell::Cell;
 
 #[derive(Debug)]
@@ -36,8 +34,9 @@ fn clone<T: Clone>(t: &T) -> T { t.clone() }
 fn main() {
     let i1 = &Cell::new(0);
     let i2 = &Cell::new(1);
-    let r1 = vec!(box r { i: i1 });
-    let r2 = vec!(box r { i: i2 });
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let r1 = vec!(Box::new(r { i: i1 }));
+    let r2 = vec!(Box::new(r { i: i2 }));
     f(clone(&r1), clone(&r2));
     //~^ ERROR the trait `core::clone::Clone` is not implemented for the type
     //~^^ ERROR the trait `core::clone::Clone` is not implemented for the type
index 964db6e9a4546bfb8b8ad18cfd80dc5af26110eb..113393490cb6de18fb5c3c60dcdcaeca9a530a01 100644 (file)
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 fn main() {
-    pub use std::uint; //~ ERROR: visibility has no effect
+    pub use std::usize; //~ ERROR: visibility has no effect
     pub struct A; //~ ERROR: visibility has no effect
     pub enum B {} //~ ERROR: visibility has no effect
     pub trait C { //~ ERROR: visibility has no effect
-        pub fn foo(&self) {} //~ ERROR: visibility has no effect
+        fn foo(&self) {}
     }
     impl A {
         pub fn foo(&self) {} //~ ERROR: visibility has no effect
index eb5ffeaf888866712075f36d91c00ecafd816718..bc93b86a391191229ae64e45f89aaf94eb469799 100644 (file)
@@ -15,4 +15,4 @@
 
 enum foo { a(Box<foo>, isize), b(usize), }
 
-fn main() { match foo::b(1_usize) { foo::b(_) | foo::a(box _, 1) => { } foo::a(_, 1) => { } } }
+fn main() { match foo::b(1) { foo::b(_) | foo::a(box _, 1) => { } foo::a(_, 1) => { } } }
index ef991d8533737d646f9606ba53e4b89264e1db51..5983c83f8b401b59646632d17de96c19d0d6d3c4 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:unreachable-variant.rs
+// aux-build:unreachable_variant.rs
 
-extern crate "unreachable-variant" as other;
+extern crate unreachable_variant as other;
 
 fn main() {
     let _x = other::super_sekrit::sooper_sekrit::baz; //~ ERROR is private
diff --git a/src/test/compile-fail/unsafe-destructor-check-crash.rs b/src/test/compile-fail/unsafe-destructor-check-crash.rs
deleted file mode 100644 (file)
index af67558..0000000
+++ /dev/null
@@ -1,23 +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.
-
-
-
-// Regression test for issue #15557
-
-#![allow(dead_code)]
-struct AReg1<'a>(&'a u32);
-
-impl<'a> Drop for AReg1<'a> {
-//~^ ERROR: cannot implement a destructor on a structure with type parameters
-  fn drop(&mut self) {}
-}
-
-fn main() {}
index 97908118e3518fa82ba54d64a8f2c076b7ce8fa9..4ea7051775e132edf7e53eae6d1081adcfda8a40 100644 (file)
@@ -10,7 +10,7 @@
 
 
 fn f(p: *const u8) {
-    *p = 0u8; //~ ERROR dereference of unsafe pointer requires unsafe function or block
+    *p = 0; //~ ERROR dereference of unsafe pointer requires unsafe function or block
     return;
 }
 
diff --git a/src/test/compile-fail/unsafe-subtyping.rs b/src/test/compile-fail/unsafe-subtyping.rs
new file mode 100644 (file)
index 0000000..f486763
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2013-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 that safe fns are not a subtype of unsafe fns.
+
+fn foo(x: Option<fn(i32)>) -> Option<unsafe fn(i32)> {
+    x //~ ERROR mismatched types
+}
+
+fn bar(x: fn(i32)) -> unsafe fn(i32) {
+    x // OK, coercion!
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/unsafe-trait-impl.rs b/src/test/compile-fail/unsafe-trait-impl.rs
new file mode 100644 (file)
index 0000000..71da2f7
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2013-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 that safe fns are not a subtype of unsafe fns.
+
+trait Foo {
+    unsafe fn len(&self) -> u32;
+}
+
+impl Foo for u32 {
+    fn len(&self) -> u32 { *self }
+    //~^ ERROR incompatible type for trait: expected unsafe fn, found normal fn
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/unsafe_no_drop_flag-gate.rs b/src/test/compile-fail/unsafe_no_drop_flag-gate.rs
new file mode 100644 (file)
index 0000000..542698f
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2015 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.
+
+pub struct T;
+
+#[unsafe_no_drop_flag]
+//~^ ERROR unsafe_no_drop_flag has unstable semantics and may be removed
+pub struct S {
+    pub x: T,
+}
+
+impl Drop for S {
+    fn drop(&mut self) {}
+}
+
+pub fn main() {}
diff --git a/src/test/compile-fail/unsendable-class.rs b/src/test/compile-fail/unsendable-class.rs
deleted file mode 100644 (file)
index f51eee3..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.
-
-use std::sync::mpsc::channel;
-
-// Test that a class with an unsendable field can't be
-// sent
-
-use std::rc::Rc;
-
-struct foo {
-  i: isize,
-  j: Rc<String>,
-}
-
-fn foo(i:isize, j: Rc<String>) -> foo {
-    foo {
-        i: i,
-        j: j
-    }
-}
-
-fn main() {
-  let cat = "kitty".to_string();
-  let (tx, _) = channel();
-  //~^ ERROR `core::marker::Send` is not implemented
-  tx.send(foo(42, Rc::new(cat)));
-}
diff --git a/src/test/compile-fail/unsized4.rs b/src/test/compile-fail/unsized4.rs
deleted file mode 100644 (file)
index f8b8ad2..0000000
+++ /dev/null
@@ -1,19 +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.
-
-// Test that bounds are sized-compatible.
-
-trait T : Sized {}
-fn f<Y: ?Sized + T>() {
-//~^ERROR incompatible bounds on `Y`, bound `T` does not allow unsized type
-}
-
-pub fn main() {
-}
diff --git a/src/test/compile-fail/unused-macro-with-bad-frag-spec.rs b/src/test/compile-fail/unused-macro-with-bad-frag-spec.rs
new file mode 100644 (file)
index 0000000..b868b79
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+// Issue #21370
+
+macro_rules! test {
+    ($wrong:t_ty) => () //~ ERROR invalid fragment specifier `t_ty`
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/unused-macro-with-follow-violation.rs b/src/test/compile-fail/unused-macro-with-follow-violation.rs
new file mode 100644 (file)
index 0000000..e9d09bb
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2015 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.
+
+macro_rules! test {
+    ($e:expr +) => () //~ ERROR not allowed for `expr` fragments
+}
+
+fn main() { }
index d8a82d8fbf0467863cf201616693610afce9c8db..26d22b072eb48ce3eda25139d5348ebe21141180 100644 (file)
@@ -18,7 +18,7 @@ struct Number {
     n: i64
 }
 
-impl fmt::String for Number {
+impl fmt::Display for Number {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{}", self.n)
     }
@@ -34,8 +34,8 @@ impl List {
 }
 
 fn main() {
-    let n = box Number { n: 42 };
-    let mut l = box List { list: Vec::new() };
+    let n: Box<_> = box Number { n: 42 };
+    let mut l: Box<_> = box List { list: Vec::new() };
     l.push(n);
     let x = n.to_string();
     //~^ ERROR: use of moved value: `n`
index 2a97155dd2efb878eebba9b619663ceaf824553c..49d8622976bb2dfd43159d1ee1ce01c9d764591b 100644 (file)
@@ -11,7 +11,7 @@
 use Trait::foo;
 //~^ ERROR `foo` is not directly importable
 use Foo::new;
-//~^ ERROR `new` is not directly importable
+//~^ ERROR unresolved import `Foo::new`. Not a module `Foo`
 
 pub trait Trait {
     fn foo();
index 808deea226bfc170909570c51d7f825ba83e28e5..6b7b9c8914955ca52233e9779884e0f80a8beae5 100644 (file)
@@ -10,6 +10,6 @@
 
 // error-pattern:can't find crate for `extra`
 
-extern crate "fake-crate" as extra;
+extern crate fake_crate as extra;
 
 fn main() { }
index b1120e54434eb1861c96d8459b449e7d49ddf708..59964d0df956c83233d3de29ee0e9e784b7fa3ff 100644 (file)
@@ -12,10 +12,7 @@ struct A { pub i: isize }
 pub enum C { pub Variant }      //~ ERROR: unnecessary `pub`
 
 pub trait E {
-    pub fn foo(&self) {}         //~ ERROR: unnecessary visibility
-}
-trait F {
-    pub fn foo(&self) {}     //~ ERROR: unnecessary visibility
+    fn foo(&self);
 }
 
 impl E for A {
diff --git a/src/test/compile-fail/useless-priv2.rs b/src/test/compile-fail/useless-priv2.rs
deleted file mode 100644 (file)
index a404d09..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 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.
-
-pub trait E {
-    pub fn foo(&self);               //~ ERROR: unnecessary visibility
-}
-trait F {
-    pub fn foo(&self);               //~ ERROR: unnecessary visibility
-}
-
-fn main() {}
index 86271f670ce6f7d2078c912ae2fa62e81ca05b56..2a62ac2ac303ad758a5ef1f20c40ad585709db08 100644 (file)
@@ -30,9 +30,9 @@ fn main() {
         //~| expected non-variadic fn
         //~| found variadic function
 
-        let y: unsafe extern "C" fn(f: isize, x: u8, ...) = bar;
+        let y: extern "C" fn(f: isize, x: u8, ...) = bar;
         //~^ ERROR: mismatched types
-        //~| expected `unsafe extern "C" fn(isize, u8, ...)`
+        //~| expected `extern "C" fn(isize, u8, ...)`
         //~| found `extern "C" fn(isize, u8) {bar}`
         //~| expected variadic fn
         //~| found non-variadic function
diff --git a/src/test/compile-fail/variance-deprecated-markers.rs b/src/test/compile-fail/variance-deprecated-markers.rs
deleted file mode 100644 (file)
index 8f9d24c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2015 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 deprecated markers still have their old effect.
-
-#![feature(rustc_attrs)]
-
-use std::marker;
-
-#[rustc_variance]
-struct A<T>(marker::CovariantType<T>); //~ ERROR types=[[+];[];[]]
-
-#[rustc_variance]
-struct B<T>(marker::ContravariantType<T>); //~ ERROR types=[[-];[];[]]
-
-#[rustc_variance]
-struct C<T>(marker::InvariantType<T>); //~ ERROR types=[[o];[];[]]
-
-#[rustc_variance]
-struct D<'a>(marker::CovariantLifetime<'a>); //~ ERROR regions=[[+];[];[]]
-
-#[rustc_variance]
-struct E<'a>(marker::ContravariantLifetime<'a>); //~ ERROR regions=[[-];[];[]]
-
-#[rustc_variance]
-struct F<'a>(marker::InvariantLifetime<'a>); //~ ERROR regions=[[o];[];[]]
-
-fn main() { }
index 0254f56bd1a944b86b1e8db2f55722105416c7d9..60690012485e28b4a22d137089d77a7da8fe12c4 100644 (file)
@@ -33,22 +33,21 @@ struct AffineU32(u32);
 
 fn main() {
     {
-        let a = AffineU32(1_u32);
+        let a = AffineU32(1);
         let x = foo(&a);
         drop(a); //~ ERROR cannot move out of `a`
         drop(x);
     }
     {
-        let a = AffineU32(1_u32);
+        let a = AffineU32(1);
         let x = bar(&a);
         drop(a); //~ ERROR cannot move out of `a`
         drop(x);
     }
     {
-        let a = AffineU32(1_u32);
+        let a = AffineU32(1);
         let x = baz(&a);
         drop(a); //~ ERROR cannot move out of `a`
         drop(x);
     }
 }
-
diff --git a/src/test/compile-fail/variance-region-bounds.rs b/src/test/compile-fail/variance-region-bounds.rs
new file mode 100644 (file)
index 0000000..96ae201
--- /dev/null
@@ -0,0 +1,25 @@
+// 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 that `T:'a` is contravariant in T.
+
+#![feature(rustc_attrs)]
+
+#[rustc_variance]
+trait Foo: 'static { //~ ERROR types=[[];[-];[]]
+}
+
+#[rustc_variance]
+trait Bar<T> { //~ ERROR types=[[+];[-];[]]
+    fn do_it(&self)
+        where T: 'static;
+}
+
+fn main() { }
index d4dab5f0ed05d4647e461d8bc1a5ae27dfb328d7..ec020f18818938c7a7ddcb48e84f9c42065b1ab0 100644 (file)
@@ -27,4 +27,3 @@ fn f() -> &'static mut isize {
 }
 
 fn main() {}
-
index 6aaf51278afd8ac1d1c77294b8789f617b90d83f..44a3f716e3eea4a3602cc43a5d8928d8faa9a71e 100644 (file)
@@ -30,9 +30,9 @@ use id::Id;
 
 mod s {
     #![allow(unstable)]
-    use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
+    use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 
-    static S_COUNT: AtomicUint = ATOMIC_UINT_INIT;
+    static S_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
 
     /// generates globally unique count (global across the current
     /// process, that is)
index a191b3e56c41754fd3274c0be3ecca3cb7c63e54..0025449a3dbb7f93b2ae5bfb94675b1825ac9ddb 100644 (file)
@@ -27,5 +27,5 @@ fn main() {
     v.push(&x); //~ ERROR `x` does not live long enough
     v.push(&y); //~ ERROR `y` does not live long enough
 
-    assert_eq!(v.as_slice(), [&3, &4]);
+    assert_eq!(v, [&3, &4]);
 }
index c5109ce473e9efebbcd5e191792769ca976758ce..cac52306d6ae0e1a4d08dfd13763c4552f6099a7 100644 (file)
@@ -10,6 +10,8 @@
 
 // Issue #14893. Tests that casts from vectors don't behave strangely in the
 // presence of the `_` type shorthand notation.
+// Update: after a change to the way casts are done, we have more type information
+// around and so the errors here are no longer exactly the same.
 
 struct X {
     y: [u8; 2],
@@ -18,14 +20,15 @@ struct X {
 fn main() {
     let x1 = X { y: [0, 0] };
 
-    let p1: *const u8 = &x1.y as *const _;  //~ ERROR mismatched types
+    // No longer a type mismatch - the `_` can be fully resolved by type inference.
+    let p1: *const u8 = &x1.y as *const _;
     let t1: *const [u8; 2] = &x1.y as *const _;
     let h1: *const [u8; 2] = &x1.y as *const [u8; 2];
 
     let mut x1 = X { y: [0, 0] };
 
+    // This is still an error since we don't allow casts from &mut [T; n] to *mut T.
     let p1: *mut u8 = &mut x1.y as *mut _;  //~ ERROR mismatched types
     let t1: *mut [u8; 2] = &mut x1.y as *mut _;
     let h1: *mut [u8; 2] = &mut x1.y as *mut [u8; 2];
 }
-
index cc6ff2d8ebcc204b2e9965fc00cb22911a82f6e7..654272f5bc6eba34b09220e9eff6adbd080ebcad 100644 (file)
@@ -23,7 +23,7 @@ impl TraitB for isize {
 }
 
 fn call_it<B:TraitB>(b: B)  -> isize {
-    let y = 4_usize;
+    let y = 4;
     b.gimme_an_a(y) //~ ERROR the trait `TraitA` is not implemented
 }
 
index 0f3754e09e41e39ff7a703f64876604d4e821d78..10503084b9d9fc1d39e1ddefd84608d43bf42490 100644 (file)
@@ -25,4 +25,3 @@ fn main(){
     let end = Mine{other_val:1, ..start.make_string_bar()};
     println!("{}", start.test); //~ ERROR use of moved value: `start.test`
 }
-
index 42df43934a89cd19499ccbea68bf528b32f3f4a8..708d56442fe82b8fa15327814eff464547a34544 100644 (file)
@@ -17,4 +17,4 @@
 #![no_std]
 
 extern crate core;
-extern crate "weak-lang-items" as other;
+extern crate weak_lang_items;
index 4a4a5f3193d3af085083f5444af4cf0092dca131..269df212489cb5f8f0abf3864249e05ed7b399a8 100644 (file)
@@ -17,4 +17,3 @@ fn main() {
     drop(equal(&Struct, &Struct))
     //~^ ERROR the trait `core::cmp::Eq` is not implemented
 }
-
index 26117e7a13b6f2f1666499e755c988011375de16..63132d91327ca5f4bf74cbc87566239c2c1375e3 100644 (file)
@@ -139,13 +139,13 @@ fn assoc_enum<T: TraitWithAssocType>(arg: Enum<T>) {
 }
 
 fn main() {
-    assoc_struct(Struct { b: -1i32, b1: 0i64 });
-    assoc_local(1i32);
-    assoc_arg::<i32>(2i64);
-    assoc_return_value(3i32);
-    assoc_tuple((4i32, 5i64));
-    assoc_enum(Enum::Variant1(6i32, 7i64));
-    assoc_enum(Enum::Variant2(8i64, 9i32));
+    assoc_struct(Struct { b: -1, b1: 0 });
+    assoc_local(1);
+    assoc_arg::<i32>(2);
+    assoc_return_value(3);
+    assoc_tuple((4, 5));
+    assoc_enum(Enum::Variant1(6, 7));
+    assoc_enum(Enum::Variant2(8, 9));
 }
 
 fn zzz() { () }
index 30a70fe0b374703633a9a4bd9c2cd25701b27a92..1aabd549ca59506d8330cd52d1a2be91a47df7ba 100644 (file)
 
 // compile-flags:-g
 // gdb-command:run
-// gdb-command:whatis 'basic-types-globals-metadata::B'
+// gdb-command:whatis 'basic_types_globals_metadata::B'
 // gdb-check:type = bool
-// gdb-command:whatis 'basic-types-globals-metadata::I'
+// gdb-command:whatis 'basic_types_globals_metadata::I'
 // gdb-check:type = isize
-// gdb-command:whatis 'basic-types-globals-metadata::C'
+// gdb-command:whatis 'basic_types_globals_metadata::C'
 // gdb-check:type = char
-// gdb-command:whatis 'basic-types-globals-metadata::I8'
+// gdb-command:whatis 'basic_types_globals_metadata::I8'
 // gdb-check:type = i8
-// gdb-command:whatis 'basic-types-globals-metadata::I16'
+// gdb-command:whatis 'basic_types_globals_metadata::I16'
 // gdb-check:type = i16
-// gdb-command:whatis 'basic-types-globals-metadata::I32'
+// gdb-command:whatis 'basic_types_globals_metadata::I32'
 // gdb-check:type = i32
-// gdb-command:whatis 'basic-types-globals-metadata::I64'
+// gdb-command:whatis 'basic_types_globals_metadata::I64'
 // gdb-check:type = i64
-// gdb-command:whatis 'basic-types-globals-metadata::U'
+// gdb-command:whatis 'basic_types_globals_metadata::U'
 // gdb-check:type = usize
-// gdb-command:whatis 'basic-types-globals-metadata::U8'
+// gdb-command:whatis 'basic_types_globals_metadata::U8'
 // gdb-check:type = u8
-// gdb-command:whatis 'basic-types-globals-metadata::U16'
+// gdb-command:whatis 'basic_types_globals_metadata::U16'
 // gdb-check:type = u16
-// gdb-command:whatis 'basic-types-globals-metadata::U32'
+// gdb-command:whatis 'basic_types_globals_metadata::U32'
 // gdb-check:type = u32
-// gdb-command:whatis 'basic-types-globals-metadata::U64'
+// gdb-command:whatis 'basic_types_globals_metadata::U64'
 // gdb-check:type = u64
-// gdb-command:whatis 'basic-types-globals-metadata::F32'
+// gdb-command:whatis 'basic_types_globals_metadata::F32'
 // gdb-check:type = f32
-// gdb-command:whatis 'basic-types-globals-metadata::F64'
+// gdb-command:whatis 'basic_types_globals_metadata::F64'
 // gdb-check:type = f64
 // gdb-command:continue
 
 
 // N.B. These are `mut` only so they don't constant fold away.
 static mut B: bool = false;
-static mut I: int = -1;
+static mut I: isize = -1;
 static mut C: char = 'a';
 static mut I8: i8 = 68;
 static mut I16: i16 = -16;
 static mut I32: i32 = -32;
 static mut I64: i64 = -64;
-static mut U: uint = 1;
+static mut U: usize = 1;
 static mut U8: u8 = 100;
 static mut U16: u16 = 16;
 static mut U32: u32 = 32;
index cb89879481bcdc4b5e844581d3aa15ce5148cce8..f0c187fd223781fa1e80f6d4ee4b731f9589c930 100644 (file)
 
 // compile-flags:-g
 // gdb-command:run
-// gdb-command:print 'basic-types-globals::B'
+// gdb-command:print 'basic_types_globals::B'
 // gdb-check:$1 = false
-// gdb-command:print 'basic-types-globals::I'
+// gdb-command:print 'basic_types_globals::I'
 // gdb-check:$2 = -1
-// gdb-command:print 'basic-types-globals::C'
+// gdb-command:print 'basic_types_globals::C'
 // gdb-check:$3 = 97
-// gdb-command:print/d 'basic-types-globals::I8'
+// gdb-command:print/d 'basic_types_globals::I8'
 // gdb-check:$4 = 68
-// gdb-command:print 'basic-types-globals::I16'
+// gdb-command:print 'basic_types_globals::I16'
 // gdb-check:$5 = -16
-// gdb-command:print 'basic-types-globals::I32'
+// gdb-command:print 'basic_types_globals::I32'
 // gdb-check:$6 = -32
-// gdb-command:print 'basic-types-globals::I64'
+// gdb-command:print 'basic_types_globals::I64'
 // gdb-check:$7 = -64
-// gdb-command:print 'basic-types-globals::U'
+// gdb-command:print 'basic_types_globals::U'
 // gdb-check:$8 = 1
-// gdb-command:print/d 'basic-types-globals::U8'
+// gdb-command:print/d 'basic_types_globals::U8'
 // gdb-check:$9 = 100
-// gdb-command:print 'basic-types-globals::U16'
+// gdb-command:print 'basic_types_globals::U16'
 // gdb-check:$10 = 16
-// gdb-command:print 'basic-types-globals::U32'
+// gdb-command:print 'basic_types_globals::U32'
 // gdb-check:$11 = 32
-// gdb-command:print 'basic-types-globals::U64'
+// gdb-command:print 'basic_types_globals::U64'
 // gdb-check:$12 = 64
-// gdb-command:print 'basic-types-globals::F32'
+// gdb-command:print 'basic_types_globals::F32'
 // gdb-check:$13 = 2.5
-// gdb-command:print 'basic-types-globals::F64'
+// gdb-command:print 'basic_types_globals::F64'
 // gdb-check:$14 = 3.5
 // gdb-command:continue
 
 
 // N.B. These are `mut` only so they don't constant fold away.
 static mut B: bool = false;
-static mut I: int = -1;
+static mut I: isize = -1;
 static mut C: char = 'a';
 static mut I8: i8 = 68;
 static mut I16: i16 = -16;
 static mut I32: i32 = -32;
 static mut I64: i64 = -64;
-static mut U: uint = 1;
+static mut U: usize = 1;
 static mut U8: u8 = 100;
 static mut U16: u16 = 16;
 static mut U32: u32 = 32;
index 7f82878e080ce1c6fe4d0faff181596d4f2e0eab..4094c2e9b133928ff14a770d8433adab863c0570 100644 (file)
 // gdb-command:run
 
 // Check initializers
-// gdb-command:print 'basic-types-mut-globals::B'
+// gdb-command:print 'basic_types_mut_globals::B'
 // gdb-check:$1 = false
-// gdb-command:print 'basic-types-mut-globals::I'
+// gdb-command:print 'basic_types_mut_globals::I'
 // gdb-check:$2 = -1
-// gdb-command:print 'basic-types-mut-globals::C'
+// gdb-command:print 'basic_types_mut_globals::C'
 // gdb-check:$3 = 97
-// gdb-command:print/d 'basic-types-mut-globals::I8'
+// gdb-command:print/d 'basic_types_mut_globals::I8'
 // gdb-check:$4 = 68
-// gdb-command:print 'basic-types-mut-globals::I16'
+// gdb-command:print 'basic_types_mut_globals::I16'
 // gdb-check:$5 = -16
-// gdb-command:print 'basic-types-mut-globals::I32'
+// gdb-command:print 'basic_types_mut_globals::I32'
 // gdb-check:$6 = -32
-// gdb-command:print 'basic-types-mut-globals::I64'
+// gdb-command:print 'basic_types_mut_globals::I64'
 // gdb-check:$7 = -64
-// gdb-command:print 'basic-types-mut-globals::U'
+// gdb-command:print 'basic_types_mut_globals::U'
 // gdb-check:$8 = 1
-// gdb-command:print/d 'basic-types-mut-globals::U8'
+// gdb-command:print/d 'basic_types_mut_globals::U8'
 // gdb-check:$9 = 100
-// gdb-command:print 'basic-types-mut-globals::U16'
+// gdb-command:print 'basic_types_mut_globals::U16'
 // gdb-check:$10 = 16
-// gdb-command:print 'basic-types-mut-globals::U32'
+// gdb-command:print 'basic_types_mut_globals::U32'
 // gdb-check:$11 = 32
-// gdb-command:print 'basic-types-mut-globals::U64'
+// gdb-command:print 'basic_types_mut_globals::U64'
 // gdb-check:$12 = 64
-// gdb-command:print 'basic-types-mut-globals::F32'
+// gdb-command:print 'basic_types_mut_globals::F32'
 // gdb-check:$13 = 2.5
-// gdb-command:print 'basic-types-mut-globals::F64'
+// gdb-command:print 'basic_types_mut_globals::F64'
 // gdb-check:$14 = 3.5
 // gdb-command:continue
 
 // Check new values
-// gdb-command:print 'basic-types-mut-globals'::B
+// gdb-command:print 'basic_types_mut_globals'::B
 // gdb-check:$15 = true
-// gdb-command:print 'basic-types-mut-globals'::I
+// gdb-command:print 'basic_types_mut_globals'::I
 // gdb-check:$16 = 2
-// gdb-command:print 'basic-types-mut-globals'::C
+// gdb-command:print 'basic_types_mut_globals'::C
 // gdb-check:$17 = 102
-// gdb-command:print/d 'basic-types-mut-globals'::I8
+// gdb-command:print/d 'basic_types_mut_globals'::I8
 // gdb-check:$18 = 78
-// gdb-command:print 'basic-types-mut-globals'::I16
+// gdb-command:print 'basic_types_mut_globals'::I16
 // gdb-check:$19 = -26
-// gdb-command:print 'basic-types-mut-globals'::I32
+// gdb-command:print 'basic_types_mut_globals'::I32
 // gdb-check:$20 = -12
-// gdb-command:print 'basic-types-mut-globals'::I64
+// gdb-command:print 'basic_types_mut_globals'::I64
 // gdb-check:$21 = -54
-// gdb-command:print 'basic-types-mut-globals'::U
+// gdb-command:print 'basic_types_mut_globals'::U
 // gdb-check:$22 = 5
-// gdb-command:print/d 'basic-types-mut-globals'::U8
+// gdb-command:print/d 'basic_types_mut_globals'::U8
 // gdb-check:$23 = 20
-// gdb-command:print 'basic-types-mut-globals'::U16
+// gdb-command:print 'basic_types_mut_globals'::U16
 // gdb-check:$24 = 32
-// gdb-command:print 'basic-types-mut-globals'::U32
+// gdb-command:print 'basic_types_mut_globals'::U32
 // gdb-check:$25 = 16
-// gdb-command:print 'basic-types-mut-globals'::U64
+// gdb-command:print 'basic_types_mut_globals'::U64
 // gdb-check:$26 = 128
-// gdb-command:print 'basic-types-mut-globals'::F32
+// gdb-command:print 'basic_types_mut_globals'::F32
 // gdb-check:$27 = 5.75
-// gdb-command:print 'basic-types-mut-globals'::F64
+// gdb-command:print 'basic_types_mut_globals'::F64
 // gdb-check:$28 = 9.25
 
 #![allow(unused_variables)]
 #![omit_gdb_pretty_printer_section]
 
 static mut B: bool = false;
-static mut I: int = -1;
+static mut I: isize = -1;
 static mut C: char = 'a';
 static mut I8: i8 = 68;
 static mut I16: i16 = -16;
 static mut I32: i32 = -32;
 static mut I64: i64 = -64;
-static mut U: uint = 1;
+static mut U: usize = 1;
 static mut U8: u8 = 100;
 static mut U16: u16 = 16;
 static mut U32: u32 = 32;
index 95483c16783cc8a97679662d4d98c6ac8d7fd831..c9144b18b2fe811827d1de86ad5f47aaf4b2a75f 100644 (file)
@@ -60,7 +60,7 @@
 // lldb-check:[...]$1 = -1
 
 // NOTE: LLDB does not support 32bit chars
-// d ebugger:print (uint)(c)
+// d ebugger:print (usize)(c)
 // c heck:$3 = 97
 
 // lldb-command:print i8
 
 fn main() {
     let b: bool = false;
-    let i: int = -1;
+    let i: isize = -1;
     let c: char = 'a';
     let i8: i8 = 68;
     let i16: i16 = -16;
     let i32: i32 = -32;
     let i64: i64 = -64;
-    let u: uint = 1;
+    let u: usize = 1;
     let u8: u8 = 100;
     let u16: u16 = 16;
     let u32: u32 = 32;
index 52e81b7e046a561723be6f5800eb29b9d2a2ee98..b0f06bb8a758c3ecabfd8502fd1d461c49a07aee 100644 (file)
@@ -114,8 +114,8 @@ fn main() {
     let bool_val: bool = true;
     let bool_ref: &bool = &bool_val;
 
-    let int_val: int = -1;
-    let int_ref: &int = &int_val;
+    let int_val: isize = -1;
+    let int_ref: &isize = &int_val;
 
     let char_val: char = 'a';
     let char_ref: &char = &char_val;
@@ -132,8 +132,8 @@ fn main() {
     let i64_val: i64 = -64;
     let i64_ref: &i64 = &i64_val;
 
-    let uint_val: uint = 1;
-    let uint_ref: &uint = &uint_val;
+    let uint_val: usize = 1;
+    let uint_ref: &usize = &uint_val;
 
     let u8_val: u8 = 100;
     let u8_ref: &u8 = &u8_val;
index 2cfc6855e5bc6c9e4b4e08d8a38c4250ad261026..70c24fc2ab07bf6a47acdfea1b0f2252ec29d8b5 100644 (file)
 #![omit_gdb_pretty_printer_section]
 
 struct SomeStruct {
-    x: int,
+    x: isize,
     y: f64
 }
 
 fn main() {
     let stack_val: SomeStruct = SomeStruct { x: 10, y: 23.5 };
     let stack_val_ref: &SomeStruct = &stack_val;
-    let stack_val_interior_ref_1: &int = &stack_val.x;
+    let stack_val_interior_ref_1: &isize = &stack_val.x;
     let stack_val_interior_ref_2: &f64 = &stack_val.y;
     let ref_to_unnamed: &SomeStruct = &SomeStruct { x: 11, y: 24.5 };
 
-    let unique_val = box SomeStruct { x: 13, y: 26.5 };
+    let unique_val: Box<_> = box SomeStruct { x: 13, y: 26.5 };
     let unique_val_ref: &SomeStruct = &*unique_val;
-    let unique_val_interior_ref_1: &int = &unique_val.x;
+    let unique_val_interior_ref_1: &isize = &unique_val.x;
     let unique_val_interior_ref_2: &f64 = &unique_val.y;
 
     zzz(); // #break
index 14a3d008f420db9e090e8a1b5bd07c6d5d7a9139..d8ce3af478911a27c4a655936a57b19fbb44efca 100644 (file)
@@ -118,8 +118,8 @@ fn main() {
     let bool_box: Box<bool> = box true;
     let bool_ref: &bool = &*bool_box;
 
-    let int_box: Box<int> = box -1;
-    let int_ref: &int = &*int_box;
+    let int_box: Box<isize> = box -1;
+    let int_ref: &isize = &*int_box;
 
     let char_box: Box<char> = box 'a';
     let char_ref: &char = &*char_box;
@@ -136,8 +136,8 @@ fn main() {
     let i64_box: Box<i64> = box -64;
     let i64_ref: &i64 = &*i64_box;
 
-    let uint_box: Box<uint> = box 1;
-    let uint_ref: &uint = &*uint_box;
+    let uint_box: Box<usize> = box 1;
+    let uint_ref: &usize = &*uint_box;
 
     let u8_box: Box<u8> = box 100;
     let u8_ref: &u8 = &*u8_box;
index 972d6ab12e13fea6c3049e0041a2eaf66f39e9b3..9c6e197e65e23ebd495db0996f15fe8ed50c762e 100644 (file)
@@ -57,9 +57,9 @@ impl Drop for StructWithDestructor {
 
 fn main() {
 
-    let unique = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 };
+    let unique: Box<_> = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 };
 
-    let unique_dtor = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 };
+    let unique_dtor: Box<_> = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 };
     zzz(); // #break
 }
 
index 3efda1e2f6aa84f0deb2862595b8074132dfc16d..bc1116b064177d3f65cc498209693fbac84c357e 100644 (file)
@@ -74,7 +74,7 @@
 
 #[derive(Clone)]
 struct Struct {
-    a: int,
+    a: isize,
     b: f64
 }
 
@@ -92,11 +92,11 @@ fn fun_fun(StructStruct { a: x, b: Struct { a: y, b: z } }: StructStruct) {
     zzz(); // #break
 }
 
-fn tup(a: (int, uint, f64, f64)) {
+fn tup(a: (isize, usize, f64, f64)) {
     zzz(); // #break
 }
 
-struct Newtype(f64, f64, int, uint);
+struct Newtype(f64, f64, isize, usize);
 
 fn new_type(a: Newtype) {
     zzz(); // #break
index 2b2a9bf83f1428854a775a0e1178913890393a89..5bd872f9faf738e1029740bcab03ee2570c1899f 100644 (file)
@@ -51,16 +51,16 @@ trait Trait {
     fn method(self) -> Self;
 }
 
-impl Trait for int {
-    fn method(self) -> int {
+impl Trait for isize {
+    fn method(self) -> isize {
         zzz(); // #break
         self
     }
 }
 
 struct Struct {
-    x: uint,
-    y: uint,
+    x: usize,
+    y: usize,
 }
 
 impl Trait for Struct {
@@ -70,15 +70,15 @@ impl Trait for Struct {
     }
 }
 
-impl Trait for (f64, int, int, f64) {
-    fn method(self) -> (f64, int, int, f64) {
+impl Trait for (f64, isize, isize, f64) {
+    fn method(self) -> (f64, isize, isize, f64) {
         zzz(); // #break
         self
     }
 }
 
 fn main() {
-    let _ = (1111 as int).method();
+    let _ = (1111 as isize).method();
     let _ = Struct { x: 2222, y: 3333 }.method();
     let _ = (4444.5, 5555, 6666, 7777.5).method();
 }
index 2305d7bc5c245039cc603c631ca2ddf6107d1807..3024ca0fe69834142d101a102f98f220876f6228 100644 (file)
@@ -8,31 +8,32 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-aarch64
 // min-lldb-version: 310
 
 // compile-flags:-g
 
 // === GDB TESTS ===================================================================================
 
-// gdb-command:print 'c-style-enum::SINGLE_VARIANT'
+// gdb-command:print 'c_style_enum::SINGLE_VARIANT'
 // gdb-check:$1 = TheOnlyVariant
 
-// gdb-command:print 'c-style-enum::AUTO_ONE'
+// gdb-command:print 'c_style_enum::AUTO_ONE'
 // gdb-check:$2 = One
 
-// gdb-command:print 'c-style-enum::AUTO_TWO'
+// gdb-command:print 'c_style_enum::AUTO_TWO'
 // gdb-check:$3 = One
 
-// gdb-command:print 'c-style-enum::AUTO_THREE'
+// gdb-command:print 'c_style_enum::AUTO_THREE'
 // gdb-check:$4 = One
 
-// gdb-command:print 'c-style-enum::MANUAL_ONE'
+// gdb-command:print 'c_style_enum::MANUAL_ONE'
 // gdb-check:$5 = OneHundred
 
-// gdb-command:print 'c-style-enum::MANUAL_TWO'
+// gdb-command:print 'c_style_enum::MANUAL_TWO'
 // gdb-check:$6 = OneHundred
 
-// gdb-command:print 'c-style-enum::MANUAL_THREE'
+// gdb-command:print 'c_style_enum::MANUAL_THREE'
 // gdb-check:$7 = OneHundred
 
 // gdb-command:run
 // gdb-command:print single_variant
 // gdb-check:$14 = TheOnlyVariant
 
-// gdb-command:print 'c-style-enum::AUTO_TWO'
+// gdb-command:print 'c_style_enum::AUTO_TWO'
 // gdb-check:$15 = Two
 
-// gdb-command:print 'c-style-enum::AUTO_THREE'
+// gdb-command:print 'c_style_enum::AUTO_THREE'
 // gdb-check:$16 = Three
 
-// gdb-command:print 'c-style-enum::MANUAL_TWO'
+// gdb-command:print 'c_style_enum::MANUAL_TWO'
 // gdb-check:$17 = OneThousand
 
-// gdb-command:print 'c-style-enum::MANUAL_THREE'
+// gdb-command:print 'c_style_enum::MANUAL_THREE'
 // gdb-check:$18 = OneMillion
 
 
@@ -104,21 +105,21 @@ use self::AutoDiscriminant::{One, Two, Three};
 use self::ManualDiscriminant::{OneHundred, OneThousand, OneMillion};
 use self::SingleVariant::TheOnlyVariant;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum AutoDiscriminant {
     One,
     Two,
     Three
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum ManualDiscriminant {
     OneHundred = 100,
     OneThousand = 1000,
     OneMillion = 1000000
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum SingleVariant {
     TheOnlyVariant
 }
index b92f5de21b5753d0b815d0db6022ae61c04a0f7d..448e157a251b211494910338d7a26a639e0c5ff1 100644 (file)
@@ -60,7 +60,7 @@ fn some_generic_fun<T1, T2>(a: T1, b: T2) -> (T2, T1) {
 
 fn main() {
     some_generic_fun(0.5f64, 10);
-    some_generic_fun(&29, box 110);
+    some_generic_fun(&29, Box::new(110));
 }
 
 fn zzz() { () }
diff --git a/src/test/debuginfo/constant-debug-locs.rs b/src/test/debuginfo/constant-debug-locs.rs
new file mode 100644 (file)
index 0000000..f150e84
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright 2013-2015 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.
+
+// ignore-android: FIXME(#10381)
+// min-lldb-version: 310
+
+// compile-flags:-g
+
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
+#![feature(std_misc, core)]
+
+// This test makes sure that the compiler doesn't crash when trying to assign
+// debug locations to const-expressions.
+
+use std::sync::MUTEX_INIT;
+use std::cell::UnsafeCell;
+
+const CONSTANT: u64 = 3 + 4;
+
+struct Struct {
+    a: isize,
+    b: usize,
+}
+const STRUCT: Struct = Struct { a: 1, b: 2 };
+
+struct TupleStruct(u32);
+const TUPLE_STRUCT: TupleStruct = TupleStruct(4);
+
+enum Enum {
+    Variant1(char),
+    Variant2 { a: u8 },
+    Variant3
+}
+
+const VARIANT1: Enum = Enum::Variant1('v');
+const VARIANT2: Enum = Enum::Variant2 { a: 2 };
+const VARIANT3: Enum = Enum::Variant3;
+
+const STRING: &'static str = "String";
+
+const VEC: [u32; 8] = [0; 8];
+
+const NESTED: (Struct, TupleStruct) = (STRUCT, TUPLE_STRUCT);
+
+const UNSAFE_CELL: UnsafeCell<bool> = UnsafeCell { value: false };
+
+fn main() {
+    let mut _constant = CONSTANT;
+    let mut _struct = STRUCT;
+    let mut _tuple_struct = TUPLE_STRUCT;
+    let mut _variant1 = VARIANT1;
+    let mut _variant2 = VARIANT2;
+    let mut _variant3 = VARIANT3;
+    let mut _string = STRING;
+    let mut _vec = VEC;
+    let mut _nested = NESTED;
+    let mut _extern = MUTEX_INIT;
+    let mut _unsafe_cell = UNSAFE_CELL;
+}
diff --git a/src/test/debuginfo/cross-crate-spans.rs b/src/test/debuginfo/cross-crate-spans.rs
new file mode 100644 (file)
index 0000000..3aef943
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright 2013-2015 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.
+
+#![omit_gdb_pretty_printer_section]
+
+// ignore-android: FIXME(#10381)
+// min-lldb-version: 310
+
+// aux-build:cross_crate_spans.rs
+extern crate cross_crate_spans;
+
+// compile-flags:-g
+
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:break cross_crate_spans.rs:21
+// gdb-command:run
+
+// gdb-command:print result
+// gdb-check:$1 = {17, 17}
+// gdb-command:print a_variable
+// gdb-check:$2 = 123456789
+// gdb-command:print another_variable
+// gdb-check:$3 = 123456789.5
+// gdb-command:continue
+
+// gdb-command:print result
+// gdb-check:$4 = {1212, 1212}
+// gdb-command:print a_variable
+// gdb-check:$5 = 123456789
+// gdb-command:print another_variable
+// gdb-check:$6 = 123456789.5
+// gdb-command:continue
+
+
+
+// === LLDB TESTS ==================================================================================
+
+// lldb-command:b cross_crate_spans.rs:21
+// lldb-command:run
+
+// lldb-command:print result
+// lldb-check:[...]$0 = (17, 17)
+// lldb-command:print a_variable
+// lldb-check:[...]$1 = 123456789
+// lldb-command:print another_variable
+// lldb-check:[...]$2 = 123456789.5
+// lldb-command:continue
+
+// lldb-command:print result
+// lldb-check:[...]$3 = (1212, 1212)
+// lldb-command:print a_variable
+// lldb-check:[...]$4 = 123456789
+// lldb-command:print another_variable
+// lldb-check:[...]$5 = 123456789.5
+// lldb-command:continue
+
+
+// This test makes sure that we can break in functions inlined from other crates.
+
+fn main() {
+
+    let _ = cross_crate_spans::generic_function(17u32);
+    let _ = cross_crate_spans::generic_function(1212i16);
+
+}
index 51cced204398f45ef99d996e31dd94cb55ffe014..d7ec5673258e1eb7bd65b2c37554de620c9aebbf 100644 (file)
@@ -325,18 +325,18 @@ enum Univariant {
     Unit(i32)
 }
 
-struct TupleStruct (f64, int);
+struct TupleStruct (f64, isize);
 
 
-fn simple_tuple((a, b): (int, bool)) {
+fn simple_tuple((a, b): (isize, bool)) {
     zzz(); // #break
 }
 
-fn nested_tuple((a, (b, c)): (int, (u16, u16))) {
+fn nested_tuple((a, (b, c)): (isize, (u16, u16))) {
     zzz(); // #break
 }
 
-fn destructure_only_first_level((a, b): (int, (u32, u32))) {
+fn destructure_only_first_level((a, b): (isize, (u32, u32))) {
     zzz(); // #break
 }
 
@@ -348,7 +348,7 @@ fn struct_pattern(Struct { a: k, b: l }: Struct) {
     zzz(); // #break
 }
 
-fn ignored_tuple_element((m, _, n): (int, u16, i32)) {
+fn ignored_tuple_element((m, _, n): (isize, u16, i32)) {
     zzz(); // #break
 }
 
@@ -370,27 +370,27 @@ fn complex_nesting(((u,   v  ), ((w,   (x,   Struct { a: y, b: z})), Struct { a:
     zzz(); // #break
 }
 
-fn managed_box(&aa: &(int, int)) {
+fn managed_box(&aa: &(isize, isize)) {
     zzz(); // #break
 }
 
-fn borrowed_pointer(&bb: &(int, int)) {
+fn borrowed_pointer(&bb: &(isize, isize)) {
     zzz(); // #break
 }
 
-fn contained_borrowed_pointer((&cc, _): (&int, int)) {
+fn contained_borrowed_pointer((&cc, _): (&isize, isize)) {
     zzz(); // #break
 }
 
-fn unique_pointer(box dd: Box<(int, int, int)>) {
+fn unique_pointer(box dd: Box<(isize, isize, isize)>) {
     zzz(); // #break
 }
 
-fn ref_binding(ref ee: (int, int, int)) {
+fn ref_binding(ref ee: (isize, isize, isize)) {
     zzz(); // #break
 }
 
-fn ref_binding_in_tuple((ref ff, gg): (int, (int, int))) {
+fn ref_binding_in_tuple((ref ff, gg): (isize, (isize, isize))) {
     zzz(); // #break
 }
 
@@ -414,7 +414,7 @@ fn tuple_struct_with_ref_binding(TupleStruct(mm, ref nn): TupleStruct) {
     zzz(); // #break
 }
 
-fn multiple_arguments((oo, pp): (int, int), qq : int) {
+fn multiple_arguments((oo, pp): (isize, isize), qq : isize) {
     zzz(); // #break
 }
 
@@ -442,7 +442,7 @@ fn main() {
     tuple_struct_with_ref_binding(TupleStruct(55.0, 56));
     multiple_arguments((57, 58), 59);
 
-    fn nested_function(rr: int, (ss, tt): (int, int)) {
+    fn nested_function(rr: isize, (ss, tt): (isize, isize)) {
         zzz(); // #break
     }
 
index cf0ca0b67a7b4db57364314f531531bb268a087e..4b1c57e0afb4a5532f4512aa82677285d84658fd 100644 (file)
@@ -258,18 +258,18 @@ enum Univariant {
     Unit(i32)
 }
 
-struct TupleStruct (f64, int);
+struct TupleStruct (f64, isize);
 
 
 fn main() {
     // simple tuple
-    let (a, b) : (int, bool) = (1, false);
+    let (a, b) : (isize, bool) = (1, false);
 
     // nested tuple
-    let (c, (d, e)) : (int, (u16, u16)) = (2, (3, 4));
+    let (c, (d, e)) : (isize, (u16, u16)) = (2, (3, 4));
 
     // bind tuple-typed value to one name (destructure only first level)
-    let (f, g) : (int, (u32, u32)) = (5, (6, 7));
+    let (f, g) : (isize, (u32, u32)) = (5, (6, 7));
 
     // struct as tuple element
     let (h, i, j) : (i16, Struct, i16) = (8, Struct { a: 9, b: 10 }, 11);
diff --git a/src/test/debuginfo/extern-c-fn.rs b/src/test/debuginfo/extern-c-fn.rs
new file mode 100644 (file)
index 0000000..9e73417
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright 2013-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.
+
+// min-lldb-version: 310
+
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+// gdb-command:run
+
+// gdb-command:print s
+// gdb-check:$1 = [...]"abcd"
+// gdb-command:print len
+// gdb-check:$2 = 20
+// gdb-command:print local0
+// gdb-check:$3 = 19
+// gdb-command:print local1
+// gdb-check:$4 = true
+// gdb-command:print local2
+// gdb-check:$5 = 20.5
+
+// gdb-command:continue
+
+// === LLDB TESTS ==================================================================================
+// lldb-command:run
+
+// lldb-command:print len
+// lldb-check:[...]$0 = 20
+// lldb-command:print local0
+// lldb-check:[...]$1 = 19
+// lldb-command:print local1
+// lldb-check:[...]$2 = true
+// lldb-command:print local2
+// lldb-check:[...]$3 = 20.5
+
+// lldb-command:continue
+
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
+
+
+#[no_mangle]
+pub unsafe extern "C" fn fn_with_c_abi(s: *const u8, len: i32) -> i32 {
+    let local0 = len - 1;
+    let local1 = len > 2;
+    let local2 = (len as f64) + 0.5;
+
+    zzz(); // #break
+
+    return 0;
+}
+
+fn main() {
+    unsafe {
+        fn_with_c_abi(b"abcd\0".as_ptr(), 20);
+    }
+}
+
+#[inline(never)]
+fn zzz() {()}
index 9eadf3cc19b928175253d196ccd6bd57a8fb77f7..d611e4a65a61385a395e361591ef69e29ffb713f 100644 (file)
@@ -17,6 +17,8 @@
 
 // compile-flags:-g
 
+#![feature(old_io)]
+
 // === GDB TESTS ===================================================================================
 
 // gdb-command:run
 #![allow(unused_variables)]
 #![omit_gdb_pretty_printer_section]
 
-fn immediate_args(a: int, b: bool, c: f64) {
+fn immediate_args(a: isize, b: bool, c: f64) {
     ::std::old_io::print("") // #break
 }
 
@@ -330,6 +332,3 @@ fn main() {
     while_expr(40, 41, 42);
     loop_expr(43, 44, 45);
 }
-
-
-
index 2ab3668abb9dd5ec256024fd1350ac368fdc8cad..21c2cc09a9fd4f91019895676599b6d0bb7c4569 100644 (file)
@@ -58,7 +58,7 @@ fn main() {
     }
 }
 
-fn fun(x: int, y: bool) -> (int, bool) {
+fn fun(x: isize, y: bool) -> (isize, bool) {
     zzz(); // #break
 
     (x, y)
index 8d456f334323c5681157df3a29df3124687d3eff..0608e49b28cf43b84a0463885a577291dafc7d6b 100644 (file)
@@ -20,6 +20,8 @@
 
 // compile-flags:-g
 
+#![feature(old_io)]
+
 // === GDB TESTS ===================================================================================
 
 // gdb-command:rbreak immediate_args
 #![omit_gdb_pretty_printer_section]
 
 #[no_stack_check]
-fn immediate_args(a: int, b: bool, c: f64) {
+fn immediate_args(a: isize, b: bool, c: f64) {
     ::std::old_io::print("");
 }
 
index 14433fbcd23b3500de51f516d881aaea705ea328..e1a77b34e7f057bfdf9066eb2dcec75f23ee5767 100644 (file)
 // lldb-command:continue
 
 #![allow(unused_variables)]
+#![feature(old_io)]
 #![omit_gdb_pretty_printer_section]
 
-fn immediate_args(a: int, b: bool, c: f64) {
+fn immediate_args(a: isize, b: bool, c: f64) {
     ()
 }
 
diff --git a/src/test/debuginfo/gdb-pretty-std.rs b/src/test/debuginfo/gdb-pretty-std.rs
new file mode 100644 (file)
index 0000000..dbf80a9
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright 2013-2015 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.
+
+// ignore-windows failing on win32 bot
+// ignore-freebsd: gdb package too new
+// ignore-tidy-linelength
+// ignore-lldb
+// ignore-android: FIXME(#10381)
+// compile-flags:-g
+// min-gdb-version 7.7
+
+// gdb-command: run
+
+// gdb-command: print slice
+// gdb-check:$1 = &[i32](len: 4) = {0, 1, 2, 3}
+
+// gdb-command: print vec
+// gdb-check:$2 = Vec<u64>(len: 4, cap: [...]) = {4, 5, 6, 7}
+
+// gdb-command: print str_slice
+// gdb-check:$3 = "IAMA string slice!"
+
+// gdb-command: print string
+// gdb-check:$4 = "IAMA string!"
+
+// gdb-command: print some
+// gdb-check:$5 = Some = {8}
+
+// gdb-command: print none
+// gdb-check:$6 = None
+
+fn main() {
+
+    // &[]
+    let slice: &[i32] = &[0, 1, 2, 3];
+
+    // Vec
+    let vec = vec![4u64, 5, 6, 7];
+
+    // &str
+    let str_slice = "IAMA string slice!";
+
+    // String
+    let string = "IAMA string!".to_string();
+
+    // Option
+    let some = Some(8i16);
+    let none: Option<i64> = None;
+
+    zzz(); // #break
+}
+
+fn zzz() { () }
index aa902a9b2d4ade48db06cde5dbc70a7372a5373d..aa6051d79224585469ae51fd5207f59852fef156 100644 (file)
@@ -37,7 +37,7 @@
 // gdb-check:$5 = CStyleEnumVar3
 
 struct RegularStruct {
-    the_first_field: int,
+    the_first_field: isize,
     the_second_field: f64,
     the_third_field: bool,
 }
index d47dee14f55a3f331a1da3ddb56e0528393ef32c..81af9c213a34357cd2b28829ea88febfaa2a7e8b 100644 (file)
@@ -81,7 +81,7 @@ use self::MixedEnum::{MixedEnumCStyleVar, MixedEnumTupleVar, MixedEnumStructVar}
 use self::NestedEnum::{NestedVariant1, NestedVariant2};
 
 struct RegularStruct {
-    the_first_field: int,
+    the_first_field: isize,
     the_second_field: f64,
     the_third_field: bool,
     the_fourth_field: &'static str,
@@ -140,7 +140,7 @@ fn main() {
     let mixed_enum_struct_var = MixedEnumStructVar { field1: 108.5, field2: 109 };
 
     let some = Some(110_usize);
-    let none: Option<int> = None;
+    let none: Option<isize> = None;
     let some_fat = Some("abc");
     let none_fat: Option<&'static str> = None;
 
@@ -177,7 +177,7 @@ fn main() {
         }
     };
 
-    let none_check1: Option<(uint, Vec<uint>)> = None;
+    let none_check1: Option<(usize, Vec<usize>)> = None;
     let none_check2: Option<String> = None;
 
     zzz(); // #break
index 76b7a3e729d2e0035932e11f17e677e57d081818..1748083b2ba1f6c59e877838bbd0f5d81b589149 100644 (file)
@@ -73,7 +73,7 @@
 
 #[derive(Clone)]
 struct Struct {
-    a: int,
+    a: isize,
     b: f64
 }
 
index 8c4eeb27c0f6d5b69c2aefd6e1b10d54233168ed..fc9ef8e3a98ed01ae87b7621a896a80a6662d7c3 100644 (file)
 #![feature(box_syntax)]
 #![omit_gdb_pretty_printer_section]
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Struct<T> {
     x: T
 }
 
 impl<T1> Struct<T1> {
 
-    fn self_by_ref<T2>(&self, arg1: int, arg2: T2) -> int {
+    fn self_by_ref<T2>(&self, arg1: isize, arg2: T2) -> isize {
         zzz(); // #break
         arg1
     }
 
-    fn self_by_val<T2>(self, arg1: int, arg2: T2) -> int {
+    fn self_by_val<T2>(self, arg1: isize, arg2: T2) -> isize {
         zzz(); // #break
         arg1
     }
 
-    fn self_owned<T2>(self: Box<Struct<T1>>, arg1: int, arg2: T2) -> int {
+    fn self_owned<T2>(self: Box<Struct<T1>>, arg1: isize, arg2: T2) -> isize {
         zzz(); // #break
         arg1
     }
@@ -142,11 +142,10 @@ fn main() {
     let _ = stack.self_by_ref(-1, 2_u16);
     let _ = stack.self_by_val(-3, -4_i16);
 
-    let owned = box Struct { x: 1234.5f64 };
+    let owned: Box<_> = box Struct { x: 1234.5f64 };
     let _ = owned.self_by_ref(-5, -6_i32);
     let _ = owned.self_by_val(-7, -8_i64);
     let _ = owned.self_owned(-9, -10.5_f32);
 }
 
 fn zzz() {()}
-
index eb1083f624faaca834221eb4fbf7b76f8cb1b171..f24b221ccec2c4caae433dfc8e54570bbcd29ff8 100644 (file)
 #![omit_gdb_pretty_printer_section]
 
 struct Struct {
-    x: int
+    x: isize
 }
 
 impl Struct {
 
-    fn static_method<T1, T2>(arg1: T1, arg2: T2) -> int {
+    fn static_method<T1, T2>(arg1: T1, arg2: T2) -> isize {
         zzz(); // #break
         return 0;
     }
 }
 
 enum Enum {
-    Variant1 { x: int },
+    Variant1 { x: isize },
     Variant2,
-    Variant3(f64, int, char),
+    Variant3(f64, isize, char),
 }
 
 impl Enum {
 
-    fn static_method<T1, T2, T3>(arg1: T1, arg2: T2, arg3: T3) -> int {
+    fn static_method<T1, T2, T3>(arg1: T1, arg2: T2, arg3: T3) -> isize {
         zzz(); // #break
         return 1;
     }
index 455861b1ea1eba65626afb29cd4449506677aaea..caed4bd181d64ab2d649052d75e74375cea89cae 100644 (file)
@@ -53,7 +53,7 @@ enum Univariant<T> {
 
 fn main() {
 
-    // In order to avoid endianess trouble all of the following test values consist of a single
+    // In order to avoid endianness trouble all of the following test values consist of a single
     // repeated byte. This way each interpretation of the union should look the same, no matter if
     // this is a big or little endian machine.
 
index 15982f309c6bbf9c96e93f93edeac81e4516ad6a..a459badfa8a3c2f1ebbeda73ad5226ffbe2a5ac6 100644 (file)
@@ -38,7 +38,7 @@
 // lldb-check:[...]$2 = AGenericStruct<f64, i32> { key: 4.5, value: 5 }
 
 // lldb-command:print float_int_float
-// lldb-check:[...]$3 = AGenericStruct<f64, generic-struct::AGenericStruct<i32, f64>> { key: 6.5, value: AGenericStruct<i32, f64> { key: 7, value: 8.5 } }
+// lldb-check:[...]$3 = AGenericStruct<f64, generic_struct::AGenericStruct<i32, f64>> { key: 6.5, value: AGenericStruct<i32, f64> { key: 7, value: 8.5 } }
 
 
 #![omit_gdb_pretty_printer_section]
index 4382861fd20991af0d3e2f248fc4978e5528449c..45da87a56740e32c71ebfddac157dd38b4eb1c50 100644 (file)
 #![omit_gdb_pretty_printer_section]
 
 struct Struct {
-    x: int
+    x: isize
 }
 
 trait Trait<T1> {
-    fn generic_static_default_method<T2>(arg1: int, arg2: &(T1, T2)) -> int {
+    fn generic_static_default_method<T2>(arg1: isize, arg2: &(T1, T2)) -> isize {
         zzz(); // #break
         arg1
     }
@@ -43,8 +43,9 @@ impl<T> Trait<T> for Struct {}
 fn main() {
 
     // Is this really how to use these?
-    Trait::generic_static_default_method::<int, Struct, float>(1000, &(1, 2.5));
-    Trait::generic_static_default_method::<float, Struct, (int, int, int)>(2000, &(3.5, (4, 5, 6)));
+    Trait::generic_static_default_method::<isize, Struct, float>(1000, &(1, 2.5));
+    Trait::generic_static_default_method::<float, Struct, (isize, isize, isize)>(2000,
+            &(3.5, (4, 5, 6)));
 
 }
 
index da62e335557a20093d0f50ecc4514da6f84916ff..b0f0852c69e46675cda27e18e54e43f72d65aa13 100644 (file)
@@ -71,7 +71,7 @@ enum Univariant<T64> {
 
 fn main() {
 
-    // In order to avoid endianess trouble all of the following test values consist of a single
+    // In order to avoid endianness trouble all of the following test values consist of a single
     // repeated byte. This way each interpretation of the union should look the same, no matter if
     // this is a big or little endian machine.
 
index 424ba50e3c97836da80f1dbaae9e0a2386de9bdc..b259efc9caf804cac305122f01517fad8434c125 100644 (file)
 
 // ignore-windows failing on 64-bit bots FIXME #17638
 // ignore-lldb
+// ignore-aarch64
 
 // compile-flags:-g
 
 // gdb-command:run
 // gdb-command:next
-// gdb-check:[...]33[...]s
+// gdb-check:[...]34[...]s
 // gdb-command:continue
 
 #![omit_gdb_pretty_printer_section]
@@ -28,7 +29,7 @@
 // contained in the output, after calling `next` just once, we can be sure that we did not stop in
 // unwrap(). (The testing framework doesn't allow for checking that some text is *not* contained in
 // the output, which is why we have to make the test in this kind of roundabout way)
-fn bar() -> int {
+fn bar() -> isize {
     let s = Some(5).unwrap(); // #break
     s
 }
index a079ddbd0f507e7c1ab1d09340c8644c7a0239e8..38b149ef243e9fbfe6b2ef0146abccffcdfbd926 100644 (file)
@@ -11,6 +11,9 @@
 // min-lldb-version: 310
 
 // aux-build:issue13213aux.rs
+
+#![feature(old_io)]
+
 extern crate issue13213aux;
 
 // compile-flags:-g
diff --git a/src/test/debuginfo/issue22656.rs b/src/test/debuginfo/issue22656.rs
new file mode 100644 (file)
index 0000000..af51879
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright 2013-2015 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.
+
+
+// This test makes sure that the LLDB pretty printer does not throw an exception
+// when trying to handle a Vec<> or anything else that contains zero-sized
+// fields.
+
+// min-lldb-version: 310
+// ignore-gdb
+// ignore-tidy-linelength
+
+// compile-flags:-g
+
+// === LLDB TESTS ==================================================================================
+// lldb-command:run
+
+// lldb-command:print v
+// lldb-check:[...]$0 = vec![1, 2, 3]
+// lldb-command:print zs
+// lldb-check:[...]$1 = StructWithZeroSizedField { x: ZeroSizedStruct, y: 123, z: ZeroSizedStruct, w: 456 }
+// lldb-command:continue
+
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
+
+struct ZeroSizedStruct;
+
+struct StructWithZeroSizedField {
+    x: ZeroSizedStruct,
+    y: u32,
+    z: ZeroSizedStruct,
+    w: u64
+}
+
+fn main() {
+    let v = vec![1,2,3];
+
+    let zs = StructWithZeroSizedField {
+        x: ZeroSizedStruct,
+        y: 123,
+        z: ZeroSizedStruct,
+        w: 456
+    };
+
+    zzz(); // #break
+}
+
+fn zzz() { () }
index c2cddd25768598f67910ee7883feba7a70c6b1f3..228799848c64667371627443841557f7095def69 100644 (file)
 #![omit_gdb_pretty_printer_section]
 
 struct Struct {
-    x: int,
-    y: int
+    x: isize,
+    y: isize
 }
 
 fn main() {
index e097ec2adb1a702134c6115b51ef558adbe813a3..59935e55b3337d4c86dc24707078fef9e55eb0e5 100644 (file)
@@ -20,4 +20,3 @@ fn main() {
     let _ = ||();
     let _ = (1_usize..3).map(|_| 5);
 }
-
index 6a909ced818ef53cb4be353c8d827eb11782d126..c0b65fbb22b53bc6dba2666e3d189b1efc2687da 100644 (file)
@@ -78,7 +78,7 @@ fn main() {
     zzz(); // #break
     sentinel();
 
-    let closure = |x: int| {
+    let closure = |x: isize| {
         zzz(); // #break
         sentinel();
 
index c0a5a31c9ce38e1237ff0b57c3e1bc329ae6d466..5bae2aa7ae2cc14dde3bd697347e713a5ce227e0 100644 (file)
@@ -79,7 +79,7 @@ fn main() {
     zzz(); // #break
     sentinel();
 
-    let unique_closure = |x:int| {
+    let unique_closure = |x:isize| {
         zzz(); // #break
         sentinel();
 
index c1ec837a4b8188383ee8d17189fcb77750abbbc8..1d406af10a21564a5193dfe6edbedcbacd64b46d 100644 (file)
@@ -16,7 +16,7 @@
 
 // gdb-command:run
 
-// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-command:print 'lexical_scopes_in_block_expression::MUT_INT'
 // gdb-check:$1 = 0
 
 // STRUCT EXPRESSION
@@ -28,7 +28,7 @@
 
 // gdb-command:print val
 // gdb-check:$4 = 11
-// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-command:print 'lexical_scopes_in_block_expression::MUT_INT'
 // gdb-check:$5 = 1
 // gdb-command:print ten
 // gdb-check:$6 = 10
@@ -49,7 +49,7 @@
 
 // gdb-command:print val
 // gdb-check:$11 = 12
-// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-command:print 'lexical_scopes_in_block_expression::MUT_INT'
 // gdb-check:$12 = 2
 // gdb-command:print ten
 // gdb-check:$13 = 10
@@ -70,7 +70,7 @@
 
 // gdb-command:print val
 // gdb-check:$18 = 13
-// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-command:print 'lexical_scopes_in_block_expression::MUT_INT'
 // gdb-check:$19 = 3
 // gdb-command:print ten
 // gdb-check:$20 = 10
@@ -91,7 +91,7 @@
 
 // gdb-command:print val
 // gdb-check:$25 = 14
-// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-command:print 'lexical_scopes_in_block_expression::MUT_INT'
 // gdb-check:$26 = 4
 // gdb-command:print ten
 // gdb-check:$27 = 10
 
 // gdb-command:print val
 // gdb-check:$32 = 15
-// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-command:print 'lexical_scopes_in_block_expression::MUT_INT'
 // gdb-check:$33 = 5
 // gdb-command:print ten
 // gdb-check:$34 = 10
 
 // gdb-command:print val
 // gdb-check:$39 = 16
-// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-command:print 'lexical_scopes_in_block_expression::MUT_INT'
 // gdb-check:$40 = 6
 // gdb-command:print ten
 // gdb-check:$41 = 10
 
 // gdb-command:print val
 // gdb-check:$46 = 17
-// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-command:print 'lexical_scopes_in_block_expression::MUT_INT'
 // gdb-check:$47 = 7
 // gdb-command:print ten
 // gdb-check:$48 = 10
 
 // gdb-command:print val
 // gdb-check:$53 = 18
-// gdb-command:print 'lexical-scopes-in-block-expression::MUT_INT'
+// gdb-command:print 'lexical_scopes_in_block_expression::MUT_INT'
 // gdb-check:$54 = 8
 // gdb-command:print ten
 // gdb-check:$55 = 10
 #![allow(unused_assignments)]
 #![omit_gdb_pretty_printer_section]
 
-static mut MUT_INT: int = 0;
+static mut MUT_INT: isize = 0;
 
 struct Point {
-    x: int,
-    y: int
+    x: isize,
+    y: isize
 }
 
-fn a_function(x: int) -> int {
+fn a_function(x: isize) -> isize {
     x + 1
 }
 
@@ -502,7 +502,7 @@ fn main() {
         zzz(); // #break
         sentinel();
 
-        val as uint
+        val as usize
     }];
 
     zzz(); // #break
index e51842992ccd36cd3fc15268709a9426586c2956..ea7d150164dfb6efc082e85a17e49dc6c6a5821e 100644 (file)
@@ -44,7 +44,7 @@ fn main() {
 
 fn zzz() {()}
 
-fn some_function(a: int, b: int) {
+fn some_function(a: isize, b: isize) {
     let some_variable = Struct { a: 11, b: 22 };
     let some_other_variable = 23;
 
@@ -53,5 +53,4 @@ fn some_function(a: int, b: int) {
     }
 }
 
-fn some_other_function(a: int, b: int) -> bool { true }
-
+fn some_other_function(a: isize, b: isize) -> bool { true }
index 7ad668791d3b899b1ff6f4756c7f2c5fdfdbb5f4..6468a36f8c61c703c39fe5b0a421d6a5f4770355 100644 (file)
 #![feature(box_syntax)]
 #![omit_gdb_pretty_printer_section]
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum Enum {
     Variant1 { x: u16, y: u16 },
     Variant2 (u32)
@@ -123,17 +123,17 @@ enum Enum {
 
 impl Enum {
 
-    fn self_by_ref(&self, arg1: int, arg2: int) -> int {
+    fn self_by_ref(&self, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
 
-    fn self_by_val(self, arg1: int, arg2: int) -> int {
+    fn self_by_val(self, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
 
-    fn self_owned(self: Box<Enum>, arg1: int, arg2: int) -> int {
+    fn self_owned(self: Box<Enum>, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
@@ -144,11 +144,10 @@ fn main() {
     let _ = stack.self_by_ref(-1, -2);
     let _ = stack.self_by_val(-3, -4);
 
-    let owned = box Enum::Variant1{ x: 1799, y: 1799 };
+    let owned: Box<_> = box Enum::Variant1{ x: 1799, y: 1799 };
     let _ = owned.self_by_ref(-5, -6);
     let _ = owned.self_by_val(-7, -8);
     let _ = owned.self_owned(-9, -10);
 }
 
 fn zzz() {()}
-
index 6b56a7998c919880a2ba618b9bcd9859a735c361..975668baa12852163c2008a7cf88e1f8f229f6f4 100644 (file)
 #![feature(box_syntax)]
 #![omit_gdb_pretty_printer_section]
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Struct<T> {
     x: T
 }
 
 impl<T> Struct<T> {
 
-    fn self_by_ref(&self, arg1: int, arg2: int) -> int {
+    fn self_by_ref(&self, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
 
-    fn self_by_val(self, arg1: int, arg2: int) -> int {
+    fn self_by_val(self, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
 
-    fn self_owned(self: Box<Struct<T>>, arg1: int, arg2: int) -> int {
+    fn self_owned(self: Box<Struct<T>>, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
@@ -143,11 +143,10 @@ fn main() {
     let _ = stack.self_by_ref(-1, -2);
     let _ = stack.self_by_val(-3, -4);
 
-    let owned = box Struct { x: 1234.5f64 };
+    let owned: Box<_> = box Struct { x: 1234.5f64 };
     let _ = owned.self_by_ref(-5, -6);
     let _ = owned.self_by_val(-7, -8);
     let _ = owned.self_owned(-9, -10);
 }
 
 fn zzz() {()}
-
index e32288a8e7d0362df7765afe467ea62dd3370bd1..28885d0ad9b79828bd10b5638242babaef775081 100644 (file)
 #![feature(box_syntax)]
 #![omit_gdb_pretty_printer_section]
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Struct {
-    x: int
+    x: isize
 }
 
 impl Struct {
 
-    fn self_by_ref(&self, arg1: int, arg2: int) -> int {
+    fn self_by_ref(&self, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         self.x + arg1 + arg2
     }
 
-    fn self_by_val(self, arg1: int, arg2: int) -> int {
+    fn self_by_val(self, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         self.x + arg1 + arg2
     }
 
-    fn self_owned(self: Box<Struct>, arg1: int, arg2: int) -> int {
+    fn self_owned(self: Box<Struct>, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         self.x + arg1 + arg2
     }
@@ -143,11 +143,10 @@ fn main() {
     let _ = stack.self_by_ref(-1, -2);
     let _ = stack.self_by_val(-3, -4);
 
-    let owned = box Struct { x: 200 };
+    let owned: Box<_> = box Struct { x: 200 };
     let _ = owned.self_by_ref(-5, -6);
     let _ = owned.self_by_val(-7, -8);
     let _ = owned.self_owned(-9, -10);
 }
 
 fn zzz() {()}
-
index 6e9a695720a141b68d0288b26c8c9d4074cfc96b..b69a3856736c4521d8677d5331fc1230462487a3 100644 (file)
 #![feature(box_syntax)]
 #![omit_gdb_pretty_printer_section]
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Struct {
-    x: int
+    x: isize
 }
 
 trait Trait {
-    fn self_by_ref(&self, arg1: int, arg2: int) -> int;
-    fn self_by_val(self, arg1: int, arg2: int) -> int;
-    fn self_owned(self: Box<Self>, arg1: int, arg2: int) -> int;
+    fn self_by_ref(&self, arg1: isize, arg2: isize) -> isize;
+    fn self_by_val(self, arg1: isize, arg2: isize) -> isize;
+    fn self_owned(self: Box<Self>, arg1: isize, arg2: isize) -> isize;
 }
 
 impl Trait for Struct {
 
-    fn self_by_ref(&self, arg1: int, arg2: int) -> int {
+    fn self_by_ref(&self, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         self.x + arg1 + arg2
     }
 
-    fn self_by_val(self, arg1: int, arg2: int) -> int {
+    fn self_by_val(self, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         self.x + arg1 + arg2
     }
 
-    fn self_owned(self: Box<Struct>, arg1: int, arg2: int) -> int {
+    fn self_owned(self: Box<Struct>, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         self.x + arg1 + arg2
     }
@@ -149,11 +149,10 @@ fn main() {
     let _ = stack.self_by_ref(-1, -2);
     let _ = stack.self_by_val(-3, -4);
 
-    let owned = box Struct { x: 200 };
+    let owned: Box<_> = box Struct { x: 200 };
     let _ = owned.self_by_ref(-5, -6);
     let _ = owned.self_by_val(-7, -8);
     let _ = owned.self_owned(-9, -10);
 }
 
 fn zzz() {()}
-
index cee04e92c2d24e4de671dbb7a5225a1b17a491c2..97d4496cce12b3d34a78aa520e50bd9434746fac 100644 (file)
 #![feature(box_syntax)]
 #![omit_gdb_pretty_printer_section]
 
-#[derive(Copy)]
-struct TupleStruct(int, f64);
+#[derive(Copy, Clone)]
+struct TupleStruct(isize, f64);
 
 impl TupleStruct {
 
-    fn self_by_ref(&self, arg1: int, arg2: int) -> int {
+    fn self_by_ref(&self, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
 
-    fn self_by_val(self, arg1: int, arg2: int) -> int {
+    fn self_by_val(self, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
 
-    fn self_owned(self: Box<TupleStruct>, arg1: int, arg2: int) -> int {
+    fn self_owned(self: Box<TupleStruct>, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
@@ -141,11 +141,10 @@ fn main() {
     let _ = stack.self_by_ref(-1, -2);
     let _ = stack.self_by_val(-3, -4);
 
-    let owned = box TupleStruct(200, -200.5);
+    let owned: Box<_> = box TupleStruct(200, -200.5);
     let _ = owned.self_by_ref(-5, -6);
     let _ = owned.self_by_val(-7, -8);
     let _ = owned.self_owned(-9, -10);
 }
 
 fn zzz() {()}
-
index 5b2045d59dc771d0c53ed5184194eaf156765070..f39e8ee222932e1cf1a9557ca3f3d41cfeee5c37 100644 (file)
@@ -40,4 +40,3 @@ fn main() {
     function_without_debuginfo();
     function_with_debuginfo();
 }
-
index 3b1979337d525fa5d9e1bba910b3fa7a621c19ff..4772ee10ff7243c550374a5a09de06211af8f082 100644 (file)
@@ -105,7 +105,7 @@ struct LongCycle4<T> {
 
 struct LongCycleWithAnonymousTypes {
     next: Opt<Box<Box<Box<Box<Box<LongCycleWithAnonymousTypes>>>>>>,
-    value: uint,
+    value: usize,
 }
 
 // This test case makes sure that recursive structs are properly described. The Node structs are
@@ -128,10 +128,10 @@ fn main() {
         next: Val {
             val: box UniqueNode {
                 next: Empty,
-                value: 1_u16,
+                value: 1,
             }
         },
-        value: 0_u16,
+        value: 0,
     };
 
     let unique_unique: Box<UniqueNode<u32>> = box UniqueNode {
@@ -219,4 +219,3 @@ fn main() {
 }
 
 fn zzz() {()}
-
index cb2b04f4d8695df3f9a116ab144278d3646c8b3c..f16f236a0cb0612750600331e838bb786e0d03d1 100644 (file)
 #![feature(box_syntax)]
 #![omit_gdb_pretty_printer_section]
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Struct {
-    x: int
+    x: isize
 }
 
 trait Trait : Sized {
-    fn self_by_ref(&self, arg1: int, arg2: int) -> int {
+    fn self_by_ref(&self, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
 
-    fn self_by_val(self, arg1: int, arg2: int) -> int {
+    fn self_by_val(self, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
 
-    fn self_owned(self: Box<Self>, arg1: int, arg2: int) -> int {
+    fn self_owned(self: Box<Self>, arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
@@ -143,11 +143,10 @@ fn main() {
     let _ = stack.self_by_ref(-1, -2);
     let _ = stack.self_by_val(-3, -4);
 
-    let owned = box Struct { x: 200 };
+    let owned: Box<_> = box Struct { x: 200 };
     let _ = owned.self_by_ref(-5, -6);
     let _ = owned.self_by_val(-7, -8);
     let _ = owned.self_owned(-9, -10);
 }
 
 fn zzz() {()}
-
index b96ec3b7b889cc18f815403a47798b3d6fd3b092..56de877016deebdb3d42b22de9abe7b872c199be 100644 (file)
 #![feature(box_syntax)]
 #![omit_gdb_pretty_printer_section]
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Struct {
-    x: int
+    x: isize
 }
 
 trait Trait : Sized {
 
-    fn self_by_ref<T>(&self, arg1: int, arg2: T) -> int {
+    fn self_by_ref<T>(&self, arg1: isize, arg2: T) -> isize {
         zzz(); // #break
         arg1
     }
 
-    fn self_by_val<T>(self, arg1: int, arg2: T) -> int {
+    fn self_by_val<T>(self, arg1: isize, arg2: T) -> isize {
         zzz(); // #break
         arg1
     }
 
-    fn self_owned<T>(self: Box<Self>, arg1: int, arg2: T) -> int {
+    fn self_owned<T>(self: Box<Self>, arg1: isize, arg2: T) -> isize {
         zzz(); // #break
         arg1
     }
@@ -144,11 +144,10 @@ fn main() {
     let _ = stack.self_by_ref(-1, 2_u16);
     let _ = stack.self_by_val(-3, -4_i16);
 
-    let owned = box Struct { x: 879 };
+    let owned: Box<_> = box Struct { x: 879 };
     let _ = owned.self_by_ref(-5, -6_i32);
     let _ = owned.self_by_val(-7, -8_i64);
     let _ = owned.self_owned(-9, -10.5_f32);
 }
 
 fn zzz() {()}
-
index 161392c94c8f01e61435478bc307a83c399a6eea..16ae83ee8dc2b0e630b91f1f93d643bfb2d9b025 100644 (file)
 
 #![allow(unused_variables)]
 #![omit_gdb_pretty_printer_section]
+#![feature(core)]
 
 use std::simd::{i8x16, i16x8,i32x4,i64x2,u8x16,u16x8,u32x4,u64x2,f32x4,f64x2};
 
 fn main() {
 
-    let vi8x16 = i8x16(0i8, 1i8, 2i8, 3i8, 4i8, 5i8, 6i8, 7i8,
-                      8i8, 9i8, 10i8, 11i8, 12i8, 13i8, 14i8, 15i8);
+    let vi8x16 = i8x16(0, 1, 2, 3, 4, 5, 6, 7,
+                      8, 9, 10, 11, 12, 13, 14, 15);
 
-    let vi16x8 = i16x8(16i16, 17i16, 18i16, 19i16, 20i16, 21i16, 22i16, 23i16);
-    let vi32x4 = i32x4(24i32, 25i32, 26i32, 27i32);
-    let vi64x2 = i64x2(28i64, 29i64);
+    let vi16x8 = i16x8(16, 17, 18, 19, 20, 21, 22, 23);
+    let vi32x4 = i32x4(24, 25, 26, 27);
+    let vi64x2 = i64x2(28, 29);
 
-    let vu8x16 = u8x16(30u8, 31u8, 32u8, 33u8, 34u8, 35u8, 36u8, 37u8,
-                      38u8, 39u8, 40u8, 41u8, 42u8, 43u8, 44u8, 45u8);
-    let vu16x8 = u16x8(46u16, 47u16, 48u16, 49u16, 50u16, 51u16, 52u16, 53u16);
-    let vu32x4 = u32x4(54u32, 55u32, 56u32, 57u32);
-    let vu64x2 = u64x2(58u64, 59u64);
+    let vu8x16 = u8x16(30, 31, 32, 33, 34, 35, 36, 37,
+                      38, 39, 40, 41, 42, 43, 44, 45);
+    let vu16x8 = u16x8(46, 47, 48, 49, 50, 51, 52, 53);
+    let vu32x4 = u32x4(54, 55, 56, 57);
+    let vu64x2 = u64x2(58, 59);
 
     let vf32x4 = f32x4(60.5f32, 61.5f32, 62.5f32, 63.5f32);
     let vf64x2 = f64x2(64.5f64, 65.5f64);
index eee3cf55052a346a7e8b455bb21447e6503954e8..36007c1093297e14ba015b3eb5f3047cb8659ca0 100644 (file)
 
 // === GDB TESTS ===================================================================================
 
-// gdb-command:print 'simple-struct::NO_PADDING_16'
+// gdb-command:print 'simple_struct::NO_PADDING_16'
 // gdb-check:$1 = {x = 1000, y = -1001}
 
-// gdb-command:print 'simple-struct::NO_PADDING_32'
+// gdb-command:print 'simple_struct::NO_PADDING_32'
 // gdb-check:$2 = {x = 1, y = 2, z = 3}
 
-// gdb-command:print 'simple-struct::NO_PADDING_64'
+// gdb-command:print 'simple_struct::NO_PADDING_64'
 // gdb-check:$3 = {x = 4, y = 5, z = 6}
 
-// gdb-command:print 'simple-struct::NO_PADDING_163264'
+// gdb-command:print 'simple_struct::NO_PADDING_163264'
 // gdb-check:$4 = {a = 7, b = 8, c = 9, d = 10}
 
-// gdb-command:print 'simple-struct::INTERNAL_PADDING'
+// gdb-command:print 'simple_struct::INTERNAL_PADDING'
 // gdb-check:$5 = {x = 11, y = 12}
 
-// gdb-command:print 'simple-struct::PADDING_AT_END'
+// gdb-command:print 'simple_struct::PADDING_AT_END'
 // gdb-check:$6 = {x = 13, y = 14}
 
 // gdb-command:run
 // gdb-command:print padding_at_end
 // gdb-check:$12 = {x = -10014, y = 10015}
 
-// gdb-command:print 'simple-struct::NO_PADDING_16'
+// gdb-command:print 'simple_struct::NO_PADDING_16'
 // gdb-check:$13 = {x = 100, y = -101}
 
-// gdb-command:print 'simple-struct::NO_PADDING_32'
+// gdb-command:print 'simple_struct::NO_PADDING_32'
 // gdb-check:$14 = {x = -15, y = -16, z = 17}
 
-// gdb-command:print 'simple-struct::NO_PADDING_64'
+// gdb-command:print 'simple_struct::NO_PADDING_64'
 // gdb-check:$15 = {x = -18, y = 19, z = 20}
 
-// gdb-command:print 'simple-struct::NO_PADDING_163264'
+// gdb-command:print 'simple_struct::NO_PADDING_163264'
 // gdb-check:$16 = {a = -21, b = 22, c = 23, d = 24}
 
-// gdb-command:print 'simple-struct::INTERNAL_PADDING'
+// gdb-command:print 'simple_struct::INTERNAL_PADDING'
 // gdb-check:$17 = {x = 25, y = -26}
 
-// gdb-command:print 'simple-struct::PADDING_AT_END'
+// gdb-command:print 'simple_struct::PADDING_AT_END'
 // gdb-check:$18 = {x = -27, y = 28}
 
 // gdb-command:continue
index 75db47af2463fefca9a652929ab33f0fe61f06be..3c3a85a34c7cf29c2ab58692f2807764f48af297 100644 (file)
 
 // === GDB TESTS ===================================================================================
 
-// gdb-command:print/d 'simple-tuple::NO_PADDING_8'
+// gdb-command:print/d 'simple_tuple::NO_PADDING_8'
 // gdb-check:$1 = {-50, 50}
-// gdb-command:print 'simple-tuple::NO_PADDING_16'
+// gdb-command:print 'simple_tuple::NO_PADDING_16'
 // gdb-check:$2 = {-1, 2, 3}
-// gdb-command:print 'simple-tuple::NO_PADDING_32'
+// gdb-command:print 'simple_tuple::NO_PADDING_32'
 // gdb-check:$3 = {4, 5, 6}
-// gdb-command:print 'simple-tuple::NO_PADDING_64'
+// gdb-command:print 'simple_tuple::NO_PADDING_64'
 // gdb-check:$4 = {7, 8, 9}
 
-// gdb-command:print 'simple-tuple::INTERNAL_PADDING_1'
+// gdb-command:print 'simple_tuple::INTERNAL_PADDING_1'
 // gdb-check:$5 = {10, 11}
-// gdb-command:print 'simple-tuple::INTERNAL_PADDING_2'
+// gdb-command:print 'simple_tuple::INTERNAL_PADDING_2'
 // gdb-check:$6 = {12, 13, 14, 15}
 
-// gdb-command:print 'simple-tuple::PADDING_AT_END'
+// gdb-command:print 'simple_tuple::PADDING_AT_END'
 // gdb-check:$7 = {16, 17}
 
 // gdb-command:run
 // gdb-command:print paddingAtEnd
 // gdb-check:$14 = {15, 16}
 
-// gdb-command:print/d 'simple-tuple::NO_PADDING_8'
+// gdb-command:print/d 'simple_tuple::NO_PADDING_8'
 // gdb-check:$15 = {-127, 127}
-// gdb-command:print 'simple-tuple::NO_PADDING_16'
+// gdb-command:print 'simple_tuple::NO_PADDING_16'
 // gdb-check:$16 = {-10, 10, 9}
-// gdb-command:print 'simple-tuple::NO_PADDING_32'
+// gdb-command:print 'simple_tuple::NO_PADDING_32'
 // gdb-check:$17 = {14, 15, 16}
-// gdb-command:print 'simple-tuple::NO_PADDING_64'
+// gdb-command:print 'simple_tuple::NO_PADDING_64'
 // gdb-check:$18 = {17, 18, 19}
 
-// gdb-command:print 'simple-tuple::INTERNAL_PADDING_1'
+// gdb-command:print 'simple_tuple::INTERNAL_PADDING_1'
 // gdb-check:$19 = {110, 111}
-// gdb-command:print 'simple-tuple::INTERNAL_PADDING_2'
+// gdb-command:print 'simple_tuple::INTERNAL_PADDING_2'
 // gdb-check:$20 = {112, 113, 114, 115}
 
-// gdb-command:print 'simple-tuple::PADDING_AT_END'
+// gdb-command:print 'simple_tuple::PADDING_AT_END'
 // gdb-check:$21 = {116, 117}
 
 
index 48db69289c073678a438bf6f6b8be4f69fe85397..59fe96f99580e9d1d44fc4cefef3356cb077a9d6 100644 (file)
 #![omit_gdb_pretty_printer_section]
 
 struct Struct {
-    x: int
+    x: isize
 }
 
 impl Struct {
 
-    fn static_method(arg1: int, arg2: int) -> int {
+    fn static_method(arg1: isize, arg2: isize) -> isize {
         zzz(); // #break
         arg1 + arg2
     }
 }
 
 enum Enum {
-    Variant1 { x: int },
+    Variant1 { x: isize },
     Variant2,
-    Variant3(f64, int, char),
+    Variant3(f64, isize, char),
 }
 
 impl Enum {
 
-    fn static_method(arg1: int, arg2: f64, arg3: uint) -> int {
+    fn static_method(arg1: isize, arg2: f64, arg3: usize) -> isize {
         zzz(); // #break
         arg1
     }
index b2971329cc8fb50bfbbb45e2ad661446d89c9b3f..b7956c221224e5d000867b821b84a2dd0c01f9e9 100644 (file)
@@ -66,7 +66,7 @@ enum Univariant {
 
 fn main() {
 
-    // In order to avoid endianess trouble all of the following test values consist of a single
+    // In order to avoid endianness trouble all of the following test values consist of a single
     // repeated byte. This way each interpretation of the union should look the same, no matter if
     // this is a big or little endian machine.
 
index d522e9f89105689892a21ddd2f1f0b2e2d2da951..43cb48d16bf4b8cb6e8e11f554b9ed43aa42263c 100644 (file)
@@ -68,7 +68,7 @@ enum Univariant {
 
 fn main() {
 
-    // In order to avoid endianess trouble all of the following test values consist of a single
+    // In order to avoid endianness trouble all of the following test values consist of a single
     // repeated byte. This way each interpretation of the union should look the same, no matter if
     // this is a big or little endian machine.
 
index 2ecafb02ae52d4e8ac4f1d1355e98d962f1162de..d066af53e35348c9dcff0fa2749ae970d9129781 100644 (file)
 #![omit_gdb_pretty_printer_section]
 
 struct Struct {
-    x: int
+    x: isize
 }
 
 trait Trait {
-    fn generic_static_default_method<T>(arg1: int, arg2: T) -> int {
+    fn generic_static_default_method<T>(arg1: isize, arg2: T) -> isize {
         zzz(); // #break
         arg1
     }
@@ -64,7 +64,7 @@ fn main() {
 
     // Is this really how to use these?
     Trait::generic_static_default_method::<Struct, float>(1000, 0.5);
-    Trait::generic_static_default_method::<Struct, &(int, int, int)>(2000, &(1, 2, 3));
+    Trait::generic_static_default_method::<Struct, &(isize, isize, isize)>(2000, &(1, 2, 3));
 
 }
 
index f74c9953f7d6cfc83c98908833d9c49f7d7396e6..3054f646b91009d28bf646be5df2a1efe2f73a19 100644 (file)
 #![omit_gdb_pretty_printer_section]
 
 trait Trait {
-    fn method(&self) -> int { 0 }
+    fn method(&self) -> isize { 0 }
 }
 
 struct Struct {
-    a: int,
+    a: isize,
     b: f64
 }
 
index 7c9760c3a5353c1205aa32ac5bc2b19e36c62886..6ed231726b163b2c382d24aabb5d90a6d8257d00 100644 (file)
@@ -68,7 +68,7 @@ enum Univariant {
 
 fn main() {
 
-    // In order to avoid endianess trouble all of the following test values consist of a single
+    // In order to avoid endianness trouble all of the following test values consist of a single
     // repeated byte. This way each interpretation of the union should look the same, no matter if
     // this is a big or little endian machine.
 
index bf26fc23d3c16a1607af005ebe04e6cb26aad378..e7ee9e2ccf8188ca431ba29c029955cc6fb81351 100644 (file)
 // gdb-check:type = struct Struct1
 
 // gdb-command:whatis generic_struct1
-// gdb-check:type = struct GenericStruct<type-names::Mod1::Struct2, type-names::Mod1::Mod2::Struct3>
+// gdb-check:type = struct GenericStruct<type_names::Mod1::Struct2, type_names::Mod1::Mod2::Struct3>
 
 // gdb-command:whatis generic_struct2
-// gdb-check:type = struct GenericStruct<type-names::Struct1, extern "fastcall" fn(isize) -> usize>
+// gdb-check:type = struct GenericStruct<type_names::Struct1, extern "fastcall" fn(isize) -> usize>
 
 // gdb-command:whatis mod_struct
 // gdb-check:type = struct Struct2
 // gdb-check:type = union Enum2
 
 // gdb-command:whatis generic_enum_1
-// gdb-check:type = union Enum3<type-names::Mod1::Struct2>
+// gdb-check:type = union Enum3<type_names::Mod1::Struct2>
 
 // gdb-command:whatis generic_enum_2
-// gdb-check:type = union Enum3<type-names::Struct1>
+// gdb-check:type = union Enum3<type_names::Struct1>
 
 
 // TUPLES
 // gdb-command:whatis tuple1
-// gdb-check:type = struct (u32, type-names::Struct1, type-names::Mod1::Mod2::Enum3<type-names::Mod1::Struct2>)
+// gdb-check:type = struct (u32, type_names::Struct1, type_names::Mod1::Mod2::Enum3<type_names::Mod1::Struct2>)
 
 // gdb-command:whatis tuple2
-// gdb-check:type = struct ((type-names::Struct1, type-names::Mod1::Mod2::Struct3), type-names::Mod1::Enum2, char)
+// gdb-check:type = struct ((type_names::Struct1, type_names::Mod1::Mod2::Struct3), type_names::Mod1::Enum2, char)
 
 
 // BOX
 // gdb-check:type = struct (Box<f32>, i32)
 
 // gdb-command:whatis box2
-// gdb-check:type = struct (Box<type-names::Mod1::Mod2::Enum3<f32>>, i32)
+// gdb-check:type = struct (Box<type_names::Mod1::Mod2::Enum3<f32>>, i32)
 
 
 // REFERENCES
 // gdb-command:whatis ref1
-// gdb-check:type = struct (&type-names::Struct1, i32)
+// gdb-check:type = struct (&type_names::Struct1, i32)
 
 // gdb-command:whatis ref2
-// gdb-check:type = struct (&type-names::GenericStruct<char, type-names::Struct1>, i32)
+// gdb-check:type = struct (&type_names::GenericStruct<char, type_names::Struct1>, i32)
 
 // gdb-command:whatis mut_ref1
-// gdb-check:type = struct (&mut type-names::Struct1, i32)
+// gdb-check:type = struct (&mut type_names::Struct1, i32)
 
 // gdb-command:whatis mut_ref2
-// gdb-check:type = struct (&mut type-names::GenericStruct<type-names::Mod1::Enum2, f64>, i32)
+// gdb-check:type = struct (&mut type_names::GenericStruct<type_names::Mod1::Enum2, f64>, i32)
 
 
 // RAW POINTERS
 // gdb-command:whatis mut_ptr1
-// gdb-check:type = struct (*mut type-names::Struct1, isize)
+// gdb-check:type = struct (*mut type_names::Struct1, isize)
 
 // gdb-command:whatis mut_ptr2
 // gdb-check:type = struct (*mut isize, isize)
 
 // gdb-command:whatis mut_ptr3
-// gdb-check:type = struct (*mut type-names::Mod1::Mod2::Enum3<type-names::Struct1>, isize)
+// gdb-check:type = struct (*mut type_names::Mod1::Mod2::Enum3<type_names::Struct1>, isize)
 
 // gdb-command:whatis const_ptr1
-// gdb-check:type = struct (*const type-names::Struct1, isize)
+// gdb-check:type = struct (*const type_names::Struct1, isize)
 
 // gdb-command:whatis const_ptr2
 // gdb-check:type = struct (*const isize, isize)
 
 // gdb-command:whatis const_ptr3
-// gdb-check:type = struct (*const type-names::Mod1::Mod2::Enum3<type-names::Struct1>, isize)
+// gdb-check:type = struct (*const type_names::Mod1::Mod2::Enum3<type_names::Struct1>, isize)
 
 
 // VECTORS
 // gdb-command:whatis fixed_size_vec1
-// gdb-check:type = struct ([type-names::Struct1; 3], i16)
+// gdb-check:type = struct ([type_names::Struct1; 3], i16)
 
 // gdb-command:whatis fixed_size_vec2
 // gdb-check:type = struct ([usize; 3], i16)
 // gdb-check:type = struct &[usize]
 
 // gdb-command:whatis slice2
-// gdb-check:type = struct &[type-names::Mod1::Enum2]
+// gdb-check:type = struct &[type_names::Mod1::Enum2]
 
 
 // TRAITS
 // gdb-check:type = struct &mut Trait1
 
 // gdb-command:whatis generic_box_trait
-// gdb-check:type = struct Box<Trait2<i32, type-names::Mod1::Struct2>>
+// gdb-check:type = struct Box<Trait2<i32, type_names::Mod1::Struct2>>
 
 // gdb-command:whatis generic_ref_trait
-// gdb-check:type = struct &Trait2<type-names::Struct1, type-names::Struct1>
+// gdb-check:type = struct &Trait2<type_names::Struct1, type_names::Struct1>
 
 // gdb-command:whatis generic_mut_ref_trait
-// gdb-check:type = struct &mut Trait2<type-names::Mod1::Mod2::Struct3, type-names::GenericStruct<usize, isize>>
+// gdb-check:type = struct &mut Trait2<type_names::Mod1::Mod2::Struct3, type_names::GenericStruct<usize, isize>>
 
 
 // BARE FUNCTIONS
 // gdb-command:whatis rust_fn
-// gdb-check:type = struct (fn(core::option::Option<isize>, core::option::Option<&type-names::Mod1::Struct2>), usize)
+// gdb-check:type = struct (fn(core::option::Option<isize>, core::option::Option<&type_names::Mod1::Struct2>), usize)
 
 // gdb-command:whatis extern_c_fn
 // gdb-check:type = struct (extern "C" fn(isize), usize)
 // gdb-check:type = struct (fn(f64) -> usize, usize)
 
 // gdb-command:whatis extern_c_fn_with_return_value
-// gdb-check:type = struct (extern "C" fn() -> type-names::Struct1, usize)
+// gdb-check:type = struct (extern "C" fn() -> type_names::Struct1, usize)
 
 // gdb-command:whatis unsafe_fn_with_return_value
-// gdb-check:type = struct (unsafe fn(type-names::GenericStruct<u16, u8>) -> type-names::Mod1::Struct2, usize)
+// gdb-check:type = struct (unsafe fn(type_names::GenericStruct<u16, u8>) -> type_names::Mod1::Struct2, usize)
 
 // gdb-command:whatis extern_stdcall_fn_with_return_value
 // gdb-check:type = struct (extern "stdcall" fn(Box<isize>) -> usize, usize)
 // gdb-check:type = struct (fn(isize) -> isize, usize)
 
 // gdb-command:whatis generic_function_struct3
-// gdb-check:type = struct (fn(type-names::Mod1::Mod2::Struct3) -> type-names::Mod1::Mod2::Struct3, usize)
+// gdb-check:type = struct (fn(type_names::Mod1::Mod2::Struct3) -> type_names::Mod1::Mod2::Struct3, usize)
 
 // gdb-command:whatis variadic_function
 // gdb-check:type = struct (unsafe extern "C" fn(*const u8, ...) -> isize, usize)
@@ -291,15 +291,15 @@ fn main() {
     let slice2 = &*vec2;
 
     // Trait Objects
-    let box_trait = (box 0) as Box<Trait1>;
-    let ref_trait = &0 as &Trait1;
-    let mut mut_int1 = 0;
+    let box_trait = (box 0_isize) as Box<Trait1>;
+    let ref_trait = &0_isize as &Trait1;
+    let mut mut_int1 = 0_isize;
     let mut_ref_trait = (&mut mut_int1) as &mut Trait1;
 
-    let generic_box_trait = (box 0) as Box<Trait2<i32, Mod1::Struct2>>;
-    let generic_ref_trait  = (&0) as &Trait2<Struct1, Struct1>;
+    let generic_box_trait = (box 0_isize) as Box<Trait2<i32, Mod1::Struct2>>;
+    let generic_ref_trait  = (&0_isize) as &Trait2<Struct1, Struct1>;
 
-    let mut generic_mut_ref_trait_impl = 0;
+    let mut generic_mut_ref_trait_impl = 0_isize;
     let generic_mut_ref_trait = (&mut generic_mut_ref_trait_impl) as
         &mut Trait2<Mod1::Mod2::Struct3, GenericStruct<usize, isize>>;
 
index 69b5797007bdb8b689708aa6315a5d9a536fc8be..e450ead009bb25bac4502559a8ade395a24d8274 100644 (file)
@@ -59,7 +59,7 @@ enum Univariant {
 
 fn main() {
 
-    // In order to avoid endianess trouble all of the following test values consist of a single
+    // In order to avoid endianness trouble all of the following test values consist of a single
     // repeated byte. This way each interpretation of the union should look the same, no matter if
     // this is a big or little endian machine.
 
@@ -67,15 +67,15 @@ fn main() {
     // 0b01111100011111000111110001111100 = 2088533116
     // 0b0111110001111100 = 31868
     // 0b01111100 = 124
-    let the_a = box ABC::TheA { x: 0, y: 8970181431921507452 };
+    let the_a: Box<_> = box ABC::TheA { x: 0, y: 8970181431921507452 };
 
     // 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
     // 0b00010001000100010001000100010001 = 286331153
     // 0b0001000100010001 = 4369
     // 0b00010001 = 17
-    let the_b = box ABC::TheB (0, 286331153, 286331153);
+    let the_b: Box<_> = box ABC::TheB (0, 286331153, 286331153);
 
-    let univariant = box Univariant::TheOnlyCase(123234);
+    let univariant: Box<_> = box Univariant::TheOnlyCase(123234);
 
     zzz(); // #break
 }
index 309848d6cedc9b400e00b9ba55b43cfc543a27c8..63536b1383475be0889ea6b93bb21a572f6ccb74 100644 (file)
@@ -26,6 +26,22 @@ fn after_return() {
         (a, ref b) => {}
     }
     for a in &[111i32] {}
+    let test = if some_predicate() { 1 } else { 2 };
+    while some_predicate() {
+        let abc = !some_predicate();
+    }
+    loop {
+        let abc = !some_predicate();
+        break;
+    }
+    // nested block
+    {
+        let abc = !some_predicate();
+
+        {
+            let def = !some_predicate();
+        }
+    }
 }
 
 fn after_panic() {
@@ -36,6 +52,22 @@ fn after_panic() {
         (a, ref b) => {}
     }
     for a in &[111i32] {}
+    let test = if some_predicate() { 1 } else { 2 };
+    while some_predicate() {
+        let abc = !some_predicate();
+    }
+    loop {
+        let abc = !some_predicate();
+        break;
+    }
+    // nested block
+    {
+        let abc = !some_predicate();
+
+        {
+            let def = !some_predicate();
+        }
+    }
 }
 
 fn after_diverging_function() {
@@ -46,6 +78,22 @@ fn after_diverging_function() {
         (a, ref b) => {}
     }
     for a in &[111i32] {}
+    let test = if some_predicate() { 1 } else { 2 };
+    while some_predicate() {
+        let abc = !some_predicate();
+    }
+    loop {
+        let abc = !some_predicate();
+        break;
+    }
+    // nested block
+    {
+        let abc = !some_predicate();
+
+        {
+            let def = !some_predicate();
+        }
+    }
 }
 
 fn after_break() {
@@ -57,18 +105,50 @@ fn after_break() {
             (a, ref b) => {}
         }
         for a in &[111i32] {}
+        let test = if some_predicate() { 1 } else { 2 };
+        while some_predicate() {
+            let abc = !some_predicate();
+        }
+        loop {
+            let abc = !some_predicate();
+            break;
+        }
+        // nested block
+        {
+            let abc = !some_predicate();
+
+            {
+                let def = !some_predicate();
+            }
+        }
     }
 }
 
 fn after_continue() {
     for _ in 0..10i32 {
-        break;
+        continue;
         let x = "0";
         let (ref y,z) = (1i32, 2u32);
         match (20i32, 'c') {
             (a, ref b) => {}
         }
         for a in &[111i32] {}
+        let test = if some_predicate() { 1 } else { 2 };
+        while some_predicate() {
+            let abc = !some_predicate();
+        }
+        loop {
+            let abc = !some_predicate();
+            break;
+        }
+        // nested block
+        {
+            let abc = !some_predicate();
+
+            {
+                let def = !some_predicate();
+            }
+        }
     }
 }
 
@@ -83,3 +163,6 @@ fn main() {
 fn diverge() -> ! {
     panic!();
 }
+
+fn some_predicate() -> bool { true || false }
+
index 9c9d82249ee317d70764a9f17fdd8067f6a9806e..d576aff8b1c08319b3bdbb1d1712f38439155c4f 100644 (file)
@@ -82,9 +82,9 @@
 #![omit_gdb_pretty_printer_section]
 
 struct Struct {
-    a: int,
+    a: isize,
     b: f64,
-    c: uint
+    c: usize
 }
 
 fn main() {
@@ -98,7 +98,7 @@ fn main() {
     };
 
     let struct_ref = &a_struct;
-    let owned = box 6;
+    let owned: Box<_> = box 6;
 
     let mut closure = || {
         let closure_local = 8;
index 3c442c95e0f59aa0329cc2029ad13207ee0c7c54..2b27f938b308f7a1b937d8e224d4870e11af88c2 100644 (file)
@@ -44,9 +44,9 @@
 #![omit_gdb_pretty_printer_section]
 
 struct Struct {
-    a: int,
+    a: isize,
     b: f64,
-    c: uint
+    c: usize
 }
 
 fn main() {
@@ -58,7 +58,7 @@ fn main() {
         c: 4
     };
 
-    let owned = box 5;
+    let owned: Box<_> = box 5;
 
     let closure = move || {
         zzz(); // #break
@@ -80,7 +80,7 @@ fn main() {
     immedate_env();
 }
 
-fn do_something(_: &int, _:&int, _:&int) {
+fn do_something(_: &isize, _:&isize, _:&isize) {
 
 }
 
index e3bd1eade7538d9d3c08b429c1962e2e3e90ac99..54ef42b48f1b1d8c070c9b6c367075480534f117 100644 (file)
@@ -74,9 +74,9 @@
 #![omit_gdb_pretty_printer_section]
 
 struct Struct {
-    a: int,
+    a: isize,
     b: f64,
-    c: uint
+    c: usize
 }
 
 fn main() {
@@ -90,7 +90,7 @@ fn main() {
     };
 
     let struct_ref = &a_struct;
-    let owned = box 6;
+    let owned: Box<_> = box 6;
 
     {
         let mut first_closure = || {
index 3ceb3946f3c0d3289af1ef99549b1e9ea231bbdb..3759082db2caabb0ca7b55325c80ccf0d0533a87 100644 (file)
@@ -49,9 +49,9 @@
 // gdb-command:print padded_struct.data_ptr[1]
 // gdb-check:$13 = {x = 13, y = 14, z = 15}
 
-// gdb-command:print 'vec-slices::MUT_VECT_SLICE'.length
+// gdb-command:print 'vec_slices::MUT_VECT_SLICE'.length
 // gdb-check:$14 = 2
-// gdb-command:print *((int64_t[2]*)('vec-slices::MUT_VECT_SLICE'.data_ptr))
+// gdb-command:print *((int64_t[2]*)('vec_slices::MUT_VECT_SLICE'.data_ptr))
 // gdb-check:$15 = {64, 65}
 
 
index 1ba25a827a5b1398957fe66abdfac7b906faf27e..bcfcc4347039b05e884b27b5f09f5069b7ae0f76 100644 (file)
@@ -14,4 +14,3 @@ fn main() {
     let z = "\xe2"; //~ ERROR may only be used
     let a = b"\x00e2";  // ok because byte literal
 }
-
index d10337e768c71a06090136348d55510084fe5e0b..f1f18115825caf6b7d8130870f8c423acb5a0ffb 100644 (file)
@@ -9,10 +9,6 @@
 // except according to those terms.
 
 
-extern crate
-    "foo"suffix //~ ERROR extern crate name with a suffix is illegal
-     as foo;
-
 extern
     "C"suffix //~ ERROR ABI spec with a suffix is illegal
     fn foo() {}
index 436078fa762e57d1d99baa8e45618f8f4e8447f7..08935a24a1b61bd89af3670cc952c94bddfc6e8d 100644 (file)
@@ -21,5 +21,3 @@ pub fn main() {
     b'é';  //~ ERROR byte constant must be ASCII
     b'a  //~ ERROR unterminated byte constant
 }
-
-
index ec67cdd77e19fa755f81d250e5fac4e2ae88acab..ee3d86a6638d8bb34a931dfa2f77b03c18ef32b6 100644 (file)
@@ -19,5 +19,3 @@ pub fn main() {
     b"é";  //~ ERROR byte constant must be ASCII
     b"a  //~ ERROR unterminated double quote byte string
 }
-
-
index ac5ec1236ff9d083294b9503ac261c84022f0436..3e548981f1ed4676f86801259a8573090f35044a 100644 (file)
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 #[path = "circular_modules_hello.rs"]
-mod circular_modules_hello; //~ERROR: circular modules
+mod circular_modules_hello; //~ ERROR: circular modules
 
 pub fn hi_str() -> String {
-  "Hi!".to_string()
+    "Hi!".to_string()
 }
 
 fn main() {
index d709ffdc3fc125c3d29b23dd303937286dfeffa9..7de51c1ea75cab90166e8fed825be1560fa38f65 100644 (file)
@@ -15,5 +15,5 @@ class cat : nonexistent {
 }
 
 fn main() {
-  let nyan = cat(0us);
+  let nyan = cat(0);
 }
diff --git a/src/test/parse-fail/closure-return-syntax.rs b/src/test/parse-fail/closure-return-syntax.rs
new file mode 100644 (file)
index 0000000..da62455
--- /dev/null
@@ -0,0 +1,16 @@
+// 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 we cannot parse a closure with an explicit return type
+// unless it uses braces.
+
+fn main() {
+    let x = || -> i32 22; //~ ERROR expected `{`, found `22`
+}
index 621b480fe77d37b5fb2f35357c831a6ae43f26b3..a00ded61758c28d8c4673ac6c6512604a3203ce9 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-# //~ ERROR 11:1: 11:2 error: expected one of `!` or `[`, found `<eof>`
+# //~ ERROR 11:1: 11:2 error: expected `[`, found `<eof>`
index 70c7d42feb53f063c3094c815a97ec25034b9b94..a2e780d49b8eaac9e5f89cd0debfe19937bacf4b 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-impl Foo; //~ ERROR expected one of `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `;`
+impl Foo; //~ ERROR expected one of `(`, `+`, `..`, `::`, `<`, `for`, `where`, or `{`, found `;`
diff --git a/src/test/parse-fail/extern-crate-as-no-string-help.rs b/src/test/parse-fail/extern-crate-as-no-string-help.rs
deleted file mode 100644 (file)
index 5cc52f6..0000000
+++ /dev/null
@@ -1,15 +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.
-
-// Tests that the proper help is displayed in the error message
-
-extern crate foo as bar;
-//~^ ERROR expected `;`, found `as`
-//~^^ HELP perhaps you meant to enclose the crate name `foo` in a string?
index 24b978b0a21ffeb8597d8a8fd13eec017da226e3..1ff4368dac5e2fac4824caf06e11d4b2657266be 100644 (file)
@@ -11,4 +11,4 @@
 // Verifies that the expected token errors for `extern crate` are
 // raised
 
-extern crate foo {} //~ERROR expected `;`, found `{`
+extern crate foo {} //~ERROR expected one of `;` or `as`, found `{`
index b077081c5b0c819f52ab9ebf9902ca4db3f70d40..2a3dd7fba0cff265e1224933d51c3a12ab5bd864 100644 (file)
@@ -15,4 +15,3 @@ fn a() -> A { panic!() }
 fn main() {
     let A { .., } = a(); //~ ERROR: expected `}`
 }
-
index a8704f7545f06a25311c942ab2573e8d0f83fa58..6bdcf5c5edced68d52077d9f5a3c5138e091a283 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:expected one of `!` or `[`, found `vec`
+// error-pattern:expected `[`, found `vec`
 mod blade_runner {
     #vec[doc(
         brief = "Blade Runner is probably the best movie ever",
index 5177ebbc1882f6144802348bb3947374250bbf40..b7feeecbfd91eeb1d08e638d9f0ebe1b7131d474 100644 (file)
@@ -15,4 +15,3 @@ FOO: usize = 3;
 
 fn main() {
 }
-
index 8ce99f517c48af568cd611a0b2ec3c3747a3a83a..00fb2808faa95124227431a325a22660525b0f8b 100644 (file)
@@ -10,5 +10,5 @@
 
 // error-pattern:no valid digits found for number
 fn main() {
-    log(error, 0b42);
+    log(error, 0b);
 }
index a6c4570c60f7f93d7862d086f1bfabb4cbc9a5c1..a50a757160dde4a2d4cf9724e4d61c909f427bfe 100644 (file)
@@ -17,4 +17,3 @@ impl Foo {
 } //~ ERROR expected one of `extern`, `fn`, `pub`, `type`, or `unsafe`, found `}`
 
 fn main() {}
-
index e2b6deb0ad93a4a04c7c416f86aac0b18a3e1147..6496ffebbc849db8e73068b36942851516345dea 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 trait MyTrait<T>: Iterator {
-    Item = T; //~ ERROR expected one of `extern`, `fn`, `pub`, `type`, or `unsafe`, found `Item`
+    Item = T; //~ ERROR expected one of `extern`, `fn`, `type`, or `unsafe`, found `Item`
 }
diff --git a/src/test/parse-fail/issue-22647.rs b/src/test/parse-fail/issue-22647.rs
new file mode 100644 (file)
index 0000000..5de8627
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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.
+
+fn main() {
+    let caller<F> = |f: F|  //~ ERROR unexpected token: `<`
+    where F: Fn() -> i32
+    {
+        let x = f();
+        println!("Y {}",x);
+        return x;
+    };
+
+    caller(bar_handler);
+}
+
+fn bar_handler() -> i32 {
+    5
+}
diff --git a/src/test/parse-fail/issue-22712.rs b/src/test/parse-fail/issue-22712.rs
new file mode 100644 (file)
index 0000000..abc9e59
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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<B> {
+    buffer: B
+}
+
+fn bar() {
+    let Foo<Vec<u8>>  //~ ERROR unexpected token: `<`
+}
+
+fn main() {}
index d37837b9714f04756bea35f96cda541420f64b64..48cdeeb0d7027629f309d28e563895dd531fc459 100644 (file)
@@ -9,4 +9,3 @@
 // except according to those terms.
 
 static foo: isize = 2; } //~ ERROR incorrect close delimiter:
-
diff --git a/src/test/parse-fail/issue-23620-invalid-escapes.rs b/src/test/parse-fail/issue-23620-invalid-escapes.rs
new file mode 100644 (file)
index 0000000..7930ea7
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright 2015 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.
+
+fn main() {
+    let _ = b"\u{a66e}";
+    //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
+
+    let _ = b'\u{a66e}';
+    //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
+
+    let _ = b'\u';
+    //~^ ERROR unknown byte escape: u
+
+    let _ = b'\x5';
+    //~^ ERROR numeric character escape is too short
+
+    let _ = b'\xxy';
+    //~^ ERROR illegal character in numeric character escape: x
+    //~^^ ERROR illegal character in numeric character escape: y
+
+    let _ = '\x5';
+    //~^ ERROR numeric character escape is too short
+
+    let _ = '\xxy';
+    //~^ ERROR illegal character in numeric character escape: x
+    //~^^ ERROR illegal character in numeric character escape: y
+
+    let _ = b"\u{a4a4} \xf \u";
+    //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
+    //~^^ ERROR illegal character in numeric character escape:
+    //~^^^ ERROR unknown byte escape: u
+
+    let _ = "\u{ffffff} \xf \u";
+    //~^ ERROR illegal unicode character escape
+    //~^^ ERROR illegal character in numeric character escape:
+    //~^^^ ERROR form of character escape may only be used with characters in the range [\x00-\x7f]
+    //~^^^^ ERROR unknown character escape: u
+}
index afff5984b46141d61f0c9b3de054473b83bd0657..9c35d77baf015398f60141bdc76be0adc9a4e506 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 fn main() {
-    let __isize = 0xff_ffff_ffff_ffff_ffff__isize;
+    let __isize = 0xff_ffff_ffff_ffff_ffff;
     //~^ ERROR int literal is too large
 }
index 597366a1b35dfc8b8ad13d393f1132b56d727828..09de97d71b83e25b76a634c799818d51cc24b27f 100644 (file)
@@ -8,15 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Copyright 2013 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.
+// ignore-windows
+// ignore-freebsd
+// ignore-openbsd
 
 #[path = "../compile-fail"]
 mod foo; //~ ERROR: a directory
index f69b041597edfcf153eca1888cdce13cf1d1ef31..ba04a5ac9af09f71f315d99dc8744ba24892b327 100644 (file)
@@ -12,4 +12,3 @@ fn main() {
     struct::foo();  //~ ERROR expected identifier
     mut::baz(); //~ ERROR expected identifier
 }
-
diff --git a/src/test/parse-fail/lex-bad-binary-literal.rs b/src/test/parse-fail/lex-bad-binary-literal.rs
new file mode 100644 (file)
index 0000000..e92000c
--- /dev/null
@@ -0,0 +1,21 @@
+// 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.
+
+fn main() {
+    0b121; //~ ERROR invalid digit for a base 2 literal
+    0b10_10301; //~ ERROR invalid digit for a base 2 literal
+    0b30; //~ ERROR invalid digit for a base 2 literal
+    0b41; //~ ERROR invalid digit for a base 2 literal
+    0b5; //~ ERROR invalid digit for a base 2 literal
+    0b6; //~ ERROR invalid digit for a base 2 literal
+    0b7; //~ ERROR invalid digit for a base 2 literal
+    0b8; //~ ERROR invalid digit for a base 2 literal
+    0b9; //~ ERROR invalid digit for a base 2 literal
+}
index fbe03e355eed6e5cba7b267c5e044072aff74b11..4aa01bcde69897b3423fc5b32ff32c269575039b 100644 (file)
@@ -8,36 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static c: char =
-    '\u539_' //~ ERROR: illegal character in numeric character escape
-    //~^ WARNING: \uABCD escapes are deprecated
-;
-
-static c2: char =
-    '\Uffffffff' //~ ERROR: illegal numeric character escape
-    //~^ WARNING: \uABCD escapes are deprecated
-;
-
 static c3: char =
     '\x1' //~ ERROR: numeric character escape is too short
 ;
 
-static c4: char =
-    '\u23q' //~  ERROR: illegal character in numeric character escape
-    //~^ WARNING: \uABCD escapes are deprecated
-;
-//~^^^ ERROR: numeric character escape is too short
-
 static s: &'static str =
     "\x1" //~ ERROR: numeric character escape is too short
 ;
 
-static s2: &'static str =
-    "\u23q" //~ ERROR: illegal character in numeric character escape
-    //~^ ERROR: numeric character escape is too short
-    //~^^ WARNING: \uABCD escapes are deprecated
-;
-
 static c: char =
     '\●' //~ ERROR: unknown character escape
 ;
index 9a490be6a0169963e5d4b8c7ace243f4911b8fa9..62b87e3f480adcf2eea6a3ad8d2f759a0407b86d 100644 (file)
@@ -22,7 +22,7 @@ fn main() {
     1e+; //~ ERROR: expected at least one digit in exponent
     0x539.0; //~ ERROR: hexadecimal float literal is not supported
     99999999999999999999999999999999; //~ ERROR: int literal is too large
-    99999999999999999999999999999999u32; //~ ERROR: int literal is too large
+    99999999999999999999999999999999; //~ ERROR: int literal is too large
     0x; //~ ERROR: no valid digits
     0xu32; //~ ERROR: no valid digits
     0ou32; //~ ERROR: no valid digits
diff --git a/src/test/parse-fail/lex-bad-octal-literal.rs b/src/test/parse-fail/lex-bad-octal-literal.rs
new file mode 100644 (file)
index 0000000..bf9880c
--- /dev/null
@@ -0,0 +1,14 @@
+// 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.
+
+fn main() {
+    0o18; //~ ERROR invalid digit for a base 8 literal
+    0o1234_9_5670;  //~ ERROR invalid digit for a base 8 literal
+}
index 77ea0c9c4f3024812dbc670cf513b3814e34102d..52f867fe913b8af0a3de2bcc19a46ecfcf443b66 100644 (file)
@@ -10,4 +10,3 @@
 
 #[doc = $not_there] //~ error: unexpected token: `$`
 fn main() { }
-
index 0e85551e2161caee9f4882ef0731057bcb95fc67..23b27b49a86f654392ecfb9958c0317c707d0975 100644 (file)
@@ -13,4 +13,3 @@ fn main() {
     assert!(3 == 4) //~ ERROR expected one of `.`, `;`, `}`, or an operator, found `assert`
     println!("hello");
 }
-
index f182eb8fa5ba6bb7f77f84e7eb80f39245500773..a8b2fa4e115be10543f9b86b77a8409115a6e048 100644 (file)
@@ -13,7 +13,7 @@ struct S {
 }
 
 impl Cmp, ToString for S {
-//~^ ERROR: expected one of `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `,`
+//~^ ERROR: expected one of `(`, `+`, `..`, `::`, `<`, `for`, `where`, or `{`, found `,`
   fn eq(&&other: S) { false }
   fn to_string(&self) -> String { "hi".to_string() }
 }
index ffc2b11e0c13caba1ff7f9e639349528f706ff23..96b86f1f5635f96cc2243076085258cf455ffea3 100644 (file)
@@ -9,5 +9,8 @@
 // except according to those terms.
 
 pub fn main() {
-    let s = "\u{lol}"; //~ ERROR illegal character in unicode escape
+    let s = "\u{lol}";
+     //~^ ERROR illegal character in unicode escape: l
+     //~^^ ERROR illegal character in unicode escape: o
+     //~^^^ ERROR illegal character in unicode escape: l
 }
diff --git a/src/test/parse-fail/obsolete-closure-kind.rs b/src/test/parse-fail/obsolete-closure-kind.rs
new file mode 100644 (file)
index 0000000..89134e8
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2015 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 we generate obsolete syntax errors around usages of closure kinds: `|:|`, `|&:|` and
+// `|&mut:|`.
+
+fn main() {
+    let a = |:| {};  //~ ERROR obsolete syntax: `:`, `&mut:`, or `&:`
+    let a = |&:| {};  //~ ERROR obsolete syntax: `:`, `&mut:`, or `&:`
+    let a = |&mut:| {};  //~ ERROR obsolete syntax: `:`, `&mut:`, or `&:`
+}
diff --git a/src/test/parse-fail/obsolete-for-sized.rs b/src/test/parse-fail/obsolete-for-sized.rs
deleted file mode 100644 (file)
index 1b86d08..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2015 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 we generate obsolete syntax errors around usages of `for Sized?`
-
-trait Foo for Sized? {} //~ ERROR obsolete syntax: for Sized?
-
-trait Bar for ?Sized {} //~ ERROR obsolete syntax: for Sized?
-
-fn main() { }
index 5208cdb6ad23191f5577b9cad0203f7a078d974f..4767c66c2a0580c8379c4af5a421c8beff7ee02c 100644 (file)
@@ -10,8 +10,8 @@
 
 // Test that we generate obsolete syntax errors around usages of `proc`.
 
-fn foo(p: proc()) { } //~ ERROR obsolete syntax: the `proc` type
+fn foo(p: proc()) { } //~ ERROR `proc` is a reserved keyword
 
-fn bar() { proc() 1; } //~ ERROR obsolete syntax: `proc` expression
+fn bar() { proc() 1; }
 
 fn main() { }
index 83ea9db39b798b1f80009c7bc6a016fe5851477a..ccf9e2d86882b9d0648c32f1797a6d28fc8eb498 100644 (file)
@@ -12,5 +12,3 @@
 pub fn main() {
     br##"a"#;  //~ unterminated raw string
 }
-
-
index 7a3d1b2318a3186c776a3d5fc504209468b5189a..d6073a10307fdbd43603d4d4e40b5110f451459e 100644 (file)
@@ -13,5 +13,3 @@ pub fn main() {
     br"é";  //~ raw byte string must be ASCII
     br##~"a"~##;  //~ only `#` is allowed in raw string delimitation
 }
-
-
index 8b36e87db3e53741c5b3b14a48f9baf0486b2525..7a7113cd594b5629fed3cf550f3a80dfca258e77 100644 (file)
@@ -26,7 +26,7 @@ impl<'a> get_ctxt for has_ctxt<'a> {
 }
 
 fn make_gc() -> @get_ctxt  {
-    let ctxt = ctxt { v: 22us };
+    let ctxt = ctxt { v: 22 };
     let hc = has_ctxt { c: &ctxt };
     return @hc as @get_ctxt;
     //~^ ERROR source contains reference
index 4bb5d5e6aa1767c871dff52cfeab0f3182f4f750..a6d4da526fb0eacf9bb695f8b473e70bd413e370 100644 (file)
@@ -25,4 +25,3 @@ fn main() {
         println!("yo");
     }
 }
-
index b2bc8a4901f4cc46aeabb6c1fb0baf33f71a739c..00ece3fcca341d52ac15d7a3cfe7e368d8e79e80 100644 (file)
@@ -25,4 +25,3 @@ fn main() {
         println!("yo");
     }
 }
-
index e6948b7c7c99580145f650518df52725ecfb6aa1..cdcf98a42f94b0582e7cb2211b8c7f096eb16948 100644 (file)
@@ -21,4 +21,3 @@ fn main() {
         } => {}
     }
 }
-
index 05fa3a8dd5fc2288f00ece8407b2d9d8d572f282..c23b5dbb9cc867a8bffe911b63af1fce02cca23a 100644 (file)
@@ -25,4 +25,3 @@ fn main() {
         println!("yo");
     }
 }
-
index e8f9ed4d2cfc8d760da40f213ef332a7043c8552..8febbf8309ea78cb046705b4c04ad9d3c7d5b0be 100644 (file)
@@ -8,11 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::fmt::Show;
+use std::fmt::Debug;
 
 fn main() {
-    let x: Box<Show+> = box 3 as Box<Show+>;
+    let x: Box<Debug+> = box 3 as Box<Debug+>;
     //~^ ERROR at least one type parameter bound must be specified
     //~^^ ERROR at least one type parameter bound must be specified
 }
-
index a034352c4a69457e8f6cf49c31f13ac20819f90a..51447b225763b258258fcfc33efa992fcabc5a76 100644 (file)
@@ -13,7 +13,9 @@ trait Foo {
 
 struct Bar;
 
-impl Foo + Owned for Bar { //~ ERROR not a trait
+impl Foo + Owned for Bar {
+//~^ ERROR not a trait
+//~^^ ERROR expected one of `..`, `where`, or `{`, found `Bar`
 }
 
 fn main() { }
diff --git a/src/test/parse-fail/trait-pub-assoc-ty.rs b/src/test/parse-fail/trait-pub-assoc-ty.rs
new file mode 100644 (file)
index 0000000..02d7623
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2015 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 {
+    pub type Foo; //~ ERROR expected one of `extern`, `fn`, `type`, or `unsafe`, found `pub`
+}
+
+fn main() {}
diff --git a/src/test/parse-fail/trait-pub-method.rs b/src/test/parse-fail/trait-pub-method.rs
new file mode 100644 (file)
index 0000000..e76802d
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2015 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 {
+    pub fn foo(); //~ ERROR expected one of `extern`, `fn`, `type`, or `unsafe`, found `pub`
+}
+
+fn main() {}
index 54ddb3e19fa48cd70981998f5de280dbcdb8df6b..191bd78212458f50ce2d5ab4d77bcbe784a33557 100644 (file)
@@ -21,4 +21,3 @@ fn main() {
     f.x::<isize>;
     //~^ ERROR field expressions may not have type parameters
 }
-
index d86f55d53685ab6ed01d9721633c38a1756bfdc1..de6291c7cc38beb683bb7107b5463aa7224aaa0c 100644 (file)
@@ -26,4 +26,3 @@ fn bar() {
 }
 
 fn main() { }
-
index a8b551b5376c9647a2ba5a64f43efafb0f5cf852..52d0d1a5fba1538017cccde64624b051f48eb118 100644 (file)
@@ -12,4 +12,3 @@ use foo::self;
 //~^ ERROR expected identifier, found keyword `self`
 
 fn main() {}
-
index b96c7c2de6b3c356618c4be86cb855900db4a5f8..ebdbdc4b2b54f1c83a579cf69330326429356d93 100644 (file)
@@ -20,4 +20,3 @@ fn equal2<T>(_: &T, _: &T) -> bool where T: {
 
 fn main() {
 }
-
index 20a3ac226bdc5f1459d3c70ddaab553a43e1ca0e..c72add8d3d68a41f323ab68702b360e8d25a5cc4 100644 (file)
@@ -11,4 +11,3 @@
 #![feature(asm)]
 
 pub fn main() { unsafe { asm!("" : : : "hello", "world") }; }
-
index 1774edd3f76e2bc88bf0e71796d79bded267cdd6..4d135801dab7430a4dc2e91b1791dcb004a28856 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // pp-exact
-fn f() -> [int; 3] {
+fn f() -> [isize; 3] {
     let picard = 0;
 
     let data = 1;
index 5a55cb4e561309b2781f8b28c7767f5c42e3d3d1..a5d82277d2f94aaa66de840350b9d03503b57efd 100644 (file)
@@ -105,10 +105,11 @@ fn f() {
 fn main() {
     // Taken from http://www.unicode.org/Public/UNIDATA/PropList.txt
     let chars =
-        ['\x0A', '\x0B', '\x0C', '\x0D', '\x20', '\u0085', '\u00A0', '\u1680',
-         '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006',
-         '\u2007', '\u2008', '\u2009', '\u200A', '\u2028', '\u2029', '\u202F',
-         '\u205F', '\u3000'];
+        ['\x0A', '\x0B', '\x0C', '\x0D', '\x20', '\u{85}', '\u{A0}',
+         '\u{1680}', '\u{2000}', '\u{2001}', '\u{2002}', '\u{2003}',
+         '\u{2004}', '\u{2005}', '\u{2006}', '\u{2007}', '\u{2008}',
+         '\u{2009}', '\u{200A}', '\u{2028}', '\u{2029}', '\u{202F}',
+         '\u{205F}', '\u{3000}'];
     for c in &chars {
         let ws = c.is_whitespace();
         println!("{} {}" , c , ws);
index c82bdcd8dcb9388efc2fa79409a8be1557686fbe..eb6d2a4a0a17392851e3808808b65721053ac897 100644 (file)
@@ -99,10 +99,11 @@ fn f() {
 fn main() {
     // Taken from http://www.unicode.org/Public/UNIDATA/PropList.txt
     let chars =
-        ['\x0A', '\x0B', '\x0C', '\x0D', '\x20', '\u0085', '\u00A0', '\u1680',
-         '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', '\u2006',
-         '\u2007', '\u2008', '\u2009', '\u200A', '\u2028', '\u2029', '\u202F',
-         '\u205F', '\u3000'];
+        ['\x0A', '\x0B', '\x0C', '\x0D', '\x20', '\u{85}', '\u{A0}',
+         '\u{1680}', '\u{2000}', '\u{2001}', '\u{2002}', '\u{2003}',
+         '\u{2004}', '\u{2005}', '\u{2006}', '\u{2007}', '\u{2008}',
+         '\u{2009}', '\u{200A}', '\u{2028}', '\u{2029}', '\u{202F}',
+         '\u{205F}', '\u{3000}'];
     for c in &chars {
         let ws = c.is_whitespace();
         println!("{} {}", c , ws);
index c9cb72d8af7193875fc37752a37c76a21cac2a60..3d5e6e78deaf15e4a601312396fd787217664a7e 100644 (file)
@@ -17,10 +17,10 @@ use std::cell::Cell;
 
 fn test1() { let val = &0; { } *val; }
 
-fn test2() -> int { let val = &0; { } *val }
+fn test2() -> isize { let val = &0; { } *val }
 
-#[derive(Copy)]
-struct S { eax: int }
+#[derive(Copy, Clone)]
+struct S { eax: isize }
 
 fn test3() {
     let regs = &Cell::new(S {eax: 0});
@@ -30,17 +30,17 @@ fn test3() {
 
 fn test4() -> bool { let regs = &true; if true { } *regs || false }
 
-fn test5() -> (int, int) { { } (0, 1) }
+fn test5() -> (isize, isize) { { } (0, 1) }
 
 fn test6() -> bool { { } (true || false) && true }
 
-fn test7() -> uint {
+fn test7() -> usize {
     let regs = &0;
     match true { true => { } _ => { } }
-    (*regs < 2) as uint
+    (*regs < 2) as usize
 }
 
-fn test8() -> int {
+fn test8() -> isize {
     let val = &0;
     match true {
         true => { }
@@ -58,10 +58,10 @@ fn test9() {
     match true { true => { } _ => { } } regs.set(regs.get() + 1);
 }
 
-fn test10() -> int {
+fn test10() -> isize {
     let regs = vec!(0);
     match true { true => { } _ => { } }
     regs[0]
 }
 
-fn test11() -> Vec<int> { if true { } vec!(1, 2) }
+fn test11() -> Vec<isize> { if true { } vec!(1, 2) }
index 094e3ce91568623094d272c85a5c10366498be88..63568dbcd5b184cf757542494b6e641efe55892b 100644 (file)
@@ -17,11 +17,10 @@ fn call_it(f: Box<FnMut(String) -> String>) { }
 
 fn call_this<F>(f: F) where F: Fn(&str) + Send { }
 
-fn call_that<F>(f: F) where F: for<'a>Fn(&'a int, &'a int) -> int { }
+fn call_that<F>(f: F) where F: for<'a>Fn(&'a isize, &'a isize) -> isize { }
 
-fn call_extern(f: fn() -> int) { }
+fn call_extern(f: fn() -> isize) { }
 
-fn call_abid_extern(f: extern "C" fn() -> int) { }
+fn call_abid_extern(f: extern "C" fn() -> isize) { }
 
 pub fn main() { }
-
diff --git a/src/test/pretty/default-trait-impl.rs b/src/test/pretty/default-trait-impl.rs
new file mode 100644 (file)
index 0000000..509bee9
--- /dev/null
@@ -0,0 +1,21 @@
+// 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(optin_builtin_traits, core)]
+
+// pp-exact
+
+use std::marker::MarkerTrait;
+
+trait MyTrait: MarkerTrait { }
+
+impl MyTrait for .. { }
+
+pub fn main() { }
index 0c4cd103b82ef73547ebf7c1e32da23d101d18ef..610d9a7782d2a1f445e52a0c865c01c912456f8e 100644 (file)
@@ -14,7 +14,7 @@
 // preserved.  They are needed to disambiguate `{return n+1}; - 0` from
 // `({return n+1}-0)`.
 
-fn id<F>(f: F) -> int where F: Fn() -> int { f() }
+fn id<F>(f: F) -> isize where F: Fn() -> isize { f() }
 
-fn wsucc(_n: int) -> int { id(|| { 1 }) - 0 }
+fn wsucc(_n: isize) -> isize { id(|| { 1 }) - 0 }
 fn main() { }
index e0066053f3c5baf5b9d2f0ad2c347055a7b5db10..a85f85a395c61cf2813ddecdbbaa27beb6d0d37f 100644 (file)
@@ -10,6 +10,6 @@
 
 // pp-exact
 
-fn f<F>(f: F) where F: Fn(int) { f(10) }
+fn f<F>(f: F) where F: Fn(isize) { f(10) }
 
 fn main() { f(|i| { assert!(i == 10) }) }
index f5205de5c1fcd3ee32661b60d821915bbd10efb7..b30f2264355e650e3a8283f8edccbb1795b54ccc 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 trait X { fn dummy(&self) { } }
-impl X for uint { }
+impl X for usize { }
 
 trait Y { fn dummy(&self) { } }
-impl Y for uint { }
+impl Y for usize { }
index 58f6ae960b1895b2835da025c825d8bae1045872..3104941fb465a893d36e924c36c1d440e1957c81 100644 (file)
@@ -11,7 +11,7 @@
 // Issue #759
 // Whitespace under block opening should not expand forever
 
-fn a() -> uint {
+fn a() -> usize {
 
-    1usize
+    1
 }
index 0f2a667e11cb212cff5bbe66c3e2c9a4feb5a4c6..43c41deaaea01ce87d757ac232858812708c784c 100644 (file)
@@ -10,7 +10,7 @@
 
 // pp-exact
 
-fn f(v: &[int]) -> int {
+fn f(v: &[isize]) -> isize {
     let mut n = 0;
     for e in v {
         n = *e; // This comment once triggered pretty printer bug
index 83ee2bd08f4adbcad507ae75e4260aa0a359c6c8..c2ed10ce6a18746d07edd9bf7d11f44537459f6d 100644 (file)
@@ -3,7 +3,7 @@
 #[prelude_import]
 use std::prelude::v1::*;
 #[macro_use]
-extern crate "std" as std;
+extern crate std as std;
 // 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.
@@ -26,12 +26,12 @@ pub fn bar() {
     const FOO: usize = ((5 as usize) - (4 as usize) as usize);
     let _: [(); (FOO as usize)] = ([(() as ())] as [(); 1]);
 
-    let _: [(); (1usize as usize)] = ([(() as ())] as [(); 1]);
+    let _: [(); (1 as usize)] = ([(() as ())] as [(); 1]);
 
     let _ =
         (((&((([(1 as i32), (2 as i32), (3 as i32)] as [i32; 3])) as [i32; 3])
               as &[i32; 3]) as *const _ as *const [i32; 3]) as
-            *const [i32; (3usize as usize)] as *const [i32; 3]);
+            *const [i32; (3 as usize)] as *const [i32; 3]);
 
 
 
index 3aa2f4826b24cdaadd5ac816f3cad62793c3a13e..90757c92c4c998fec6a3fb5f50909ccc84750c22 100644 (file)
@@ -20,9 +20,9 @@ pub fn bar() {
     const FOO: usize = 5 - 4;
     let _: [(); FOO] = [()];
 
-    let _ : [(); 1usize] = [()];
+    let _ : [(); 1] = [()];
 
-    let _ = &([1,2,3]) as *const _ as *const [i32; 3usize];
+    let _ = &([1,2,3]) as *const _ as *const [i32; 3];
 
     format!("test");
 }
diff --git a/src/test/pretty/issue-929.rs b/src/test/pretty/issue-929.rs
deleted file mode 100644 (file)
index 75a6b91..0000000
+++ /dev/null
@@ -1,13 +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.
-
-fn f() { if (1 == panic!()) { } else { } }
-
-fn main() { }
index 9e1f2aa8bfe01e7729e5e71c30f76908082b918b..06d57b261e6864c3e4e78ea7b2a9077574f14c59 100644 (file)
 trait Tr {
     fn dummy(&self) { }
 }
-impl Tr for int { }
+impl Tr for isize { }
 
 fn foo<'a>(x: Box<Tr+ Sync + 'a>) -> Box<Tr+ Sync + 'a> { x }
 
 fn main() {
     let x: Box<Tr+ Sync>;
 
-    Box::new(1) as Box<Tr+ Sync>;
+    Box::new(1isize) as Box<Tr+ Sync>;
 }
-
index 965b1760f1ff16f7c4b1cd21464d14419b7a04db..bce78e4f4c1f8cff3ce5d94c870e981bbb278ce8 100644 (file)
@@ -13,6 +13,6 @@
 #![feature(asm)]
 
 #[cfg(foo = r#"just parse this"#)]
-extern crate r##"blah"## as blah;
+extern crate blah as blah;
 
 fn main() { unsafe { asm!(r###"blah"###); } }
index 1cdf2e6de4607b8b52b19f562de1f1a4a5072eb1..dd7fbf32dd31e583725d9c7c5da75ee04b02c71d 100644 (file)
@@ -11,8 +11,8 @@
 // ignore-test
 // pp-exact
 struct Thing {
-    x: int,
-    y: int,
+    x: isize,
+    y: isize,
 }
 
 fn main() {
index acd534ccbfa2c8125cd51d5ca06b11976b106013..82d430b2701360bdffea047023e5ac4ad7f96bcf 100644 (file)
 
 // pp-exact
 struct Foo;
-struct Bar(int, int);
+struct Bar(isize, isize);
 
 fn main() {
     struct Foo2;
-    struct Bar2(int, int, int);
+    struct Bar2(isize, isize, isize);
     let _a = Bar(5, 5);
     let _b = Foo;
 }
index b96dbbf3cc964159bb4dfef44461921ad571bb09..95dfc751ff5a0cb6890eae320a0dbde3fa68d26d 100644 (file)
@@ -14,7 +14,7 @@ unsafe trait UnsafeTrait {
     fn foo(&self);
 }
 
-unsafe impl UnsafeTrait for int {
+unsafe impl UnsafeTrait for isize {
     fn foo(&self) { }
 }
 
index 1592e010aaff770537a7f36ee76eb80867ccb86a..2a9066accd5ad027c2c288161de9907bf0165e75 100644 (file)
 
 fn f() { }
 
-fn block_semi() -> int { { f() }; -1 }
+fn block_semi() -> isize { { f() }; -1 }
 
-fn block_nosemi() -> int { ({ 0 }) - 1 }
+fn block_nosemi() -> isize { ({ 0 }) - 1 }
 
-fn if_semi() -> int { if true { f() } else { f() }; -1 }
+fn if_semi() -> isize { if true { f() } else { f() }; -1 }
 
-fn if_nosemi() -> int { (if true { 0 } else { 0 }) - 1 }
+fn if_nosemi() -> isize { (if true { 0 } else { 0 }) - 1 }
 
-fn alt_semi() -> int { match true { true => { f() } _ => { } }; -1 }
+fn alt_semi() -> isize { match true { true => { f() } _ => { } }; -1 }
 
-fn alt_no_semi() -> int { (match true { true => { 0 } _ => { 1 } }) - 1 }
+fn alt_no_semi() -> isize { (match true { true => { 0 } _ => { 1 } }) - 1 }
 
 fn stmt() { { f() }; -1; }
index 0f3b914334e12b09cb9b4fabfe668124419fadf0..cca7707509f0c7f335d3581aa99345e5403df8d7 100644 (file)
@@ -10,7 +10,6 @@
 
 // pp-exact
 
-fn f<'a, 'b, T>(t: T) -> int where T: 'a, 'a:'b, T: Eq { 0 }
+fn f<'a, 'b, T>(t: T) -> isize where T: 'a, 'a:'b, T: Eq { 0 }
 
 fn main() { }
-
index eab7475bc866899d9ca4f0d28ba157a2e7363485..47831f1af737bb47f465d936ec1b94d805bdb6c2 100644 (file)
@@ -14,6 +14,6 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn f(_a: int, _b: int, _c: Box<int>) { panic!("moop"); }
+fn f(_a: isize, _b: isize, _c: Box<isize>) { panic!("moop"); }
 
 fn main() { f(1, panic!("meep"), box 42); }
index fd6d69efb4f6e018664bdbe38fc43ff311e30c82..0b35062b186e9227bebbbb35c022fa4454f9df5a 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:assertion failed: `(left == right) && (right == left)` (left: `14`, right: `15`)
+// error-pattern:assertion failed: `(left == right)` (left: `14`, right: `15`)
 
 fn main() {
     assert_eq!(14,15);
diff --git a/src/test/run-fail/binop-fail-3.rs b/src/test/run-fail/binop-fail-3.rs
new file mode 100644 (file)
index 0000000..8cabd3b
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2013 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.
+
+// error-pattern:quux
+fn foo() -> ! { panic!("quux"); }
+fn main() {
+    foo() == foo(); // these types wind up being defaulted to ()
+}
index be4ad0781f272f9ee40110772d5b1b79000ca3e9..4d502cb2106b116eaa6eb28e8cedfcfcd72449be 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:index out of bounds: the len is 3 but the index is
+// error-pattern:assertion failed: index < self.len()
 
-use std::uint;
+use std::usize;
 use std::mem::size_of;
 
 fn main() {
     let xs = [1, 2, 3];
-    xs[uint::MAX / size_of::<int>() + 1];
+    xs[usize::MAX / size_of::<isize>() + 1];
 }
index 6dd329b729500802a0efa0a67f73ae02bbe8c1fe..07fac8e39c4a12045da034efe9ad835525b0b099 100644 (file)
@@ -11,7 +11,7 @@
 // ignore-test
 // error-pattern:index out of bounds
 
-use std::uint;
+use std::usize;
 
 fn main() {
     let x = vec!(1_usize,2_usize,3_usize);
@@ -21,7 +21,7 @@ fn main() {
     // length (in bytes), because the scaling of the index will cause it to
     // wrap around to a small number.
 
-    let idx = uint::MAX & !(uint::MAX >> 1_usize);
+    let idx = usize::MAX & !(usize::MAX >> 1_usize);
     println!("ov2 idx = 0x%x", idx);
 
     // This should panic.
index ec7fde171013324c3fb2c09fe13fb3de2359862f..b7aff8d1be1e2373e69d8e0d782d02f22091dc3d 100644 (file)
@@ -25,8 +25,8 @@ fn main() {
 
     let idx = u64::MAX & !(u64::MAX >> 1_usize);
     println!("ov3 idx = 0x%8.8x%8.8x",
-           (idx >> 32) as uint,
-           idx as uint);
+           (idx >> 32) as usize,
+           idx as usize);
 
     // This should panic.
     println!("ov3 0x%x",  x[idx]);
index e48d749d9451ec1996845548a862f9be11fe1dab..5e3da8476af3fe8f5c74f982c4e8b8f28e620755 100644 (file)
@@ -22,13 +22,13 @@ fn main() {
 
     let x = vec!(1_usize,2_usize,3_usize);
 
-    let base = x.as_ptr() as uint;
-    let idx = base / mem::size_of::<uint>();
+    let base = x.as_ptr() as usize;
+    let idx = base / mem::size_of::<usize>();
     println!("ov1 base = 0x{:x}", base);
     println!("ov1 idx = 0x{:x}", idx);
-    println!("ov1 sizeof::<uint>() = 0x{:x}", mem::size_of::<uint>());
-    println!("ov1 idx * sizeof::<uint>() = 0x{:x}",
-           idx * mem::size_of::<uint>());
+    println!("ov1 sizeof::<usize>() = 0x{:x}", mem::size_of::<usize>());
+    println!("ov1 idx * sizeof::<usize>() = 0x{:x}",
+           idx * mem::size_of::<usize>());
 
     // This should panic.
     println!("ov1 0x{:x}", x[idx]);
index 4ad81197286bb992734e8d8f24ae04fa74ad50c7..fc64d7c1ba356768fecfbb81462d409dbe188a48 100644 (file)
 
 use std::marker::PhantomData;
 
-fn test00_start(ch: chan_t<int>, message: int) { send(ch, message); }
+fn test00_start(ch: chan_t<isize>, message: isize) { send(ch, message); }
 
-type task_id = int;
-type port_id = int;
+type task_id = isize;
+type port_id = isize;
 
 struct chan_t<T> {
     task: task_id,
index f2253b7342eb8d4d8b42c1041f999f28e805c001..16aa4d48d911ff9f59c3ab065df1796ce8407902 100644 (file)
@@ -11,5 +11,5 @@
 // error-pattern:test
 
 fn main() {
-    let __isize: int = panic!("test");
+    let __isize: isize = panic!("test");
 }
index 987bee55c606d617d30a0070f197628f7e0a66e4..e9f493c16f1716d2a4d26d0d873ada4c895e731e 100644 (file)
@@ -12,6 +12,6 @@
 
 fn f() -> ! { panic!() }
 
-fn g() -> int { let x = if true { f() } else { 10 }; return x; }
+fn g() -> isize { let x = if true { f() } else { 10 }; return x; }
 
 fn main() { g(); }
index 069c1d5ed35574fdd6c54c06318d5b0bfa661b91..0269eb0af9c34347f4c819263eede16318f130c1 100644 (file)
@@ -12,6 +12,6 @@
 
 fn f() -> ! { panic!() }
 
-fn g() -> int { let x = match true { true => { f() } false => { 10 } }; return x; }
+fn g() -> isize { let x = match true { true => { f() } false => { 10 } }; return x; }
 
 fn main() { g(); }
index 225ce5a741b7cb4f4e6e484ee5f512cd537f9b61..f4a3adba76eddae0a6365ea147b702e23cfccd8f 100644 (file)
@@ -12,6 +12,7 @@
 // error-pattern:explicit failure
 // Testing that runtime failure doesn't cause callbacks to abort abnormally.
 // Instead the failure will be delivered after the callbacks return.
+#![feature(std_misc, libc)]
 
 extern crate libc;
 use std::task;
@@ -26,14 +27,14 @@ mod rustrt {
 }
 
 extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
-    if data == 1_usize {
+    if data == 1 {
         data
     } else {
-        count(data - 1_usize) + count(data - 1_usize)
+        count(data - 1) + count(data - 1)
     }
 }
 
-fn count(n: uint) -> uint {
+fn count(n: usize) -> usize {
     unsafe {
         task::deschedule();
         rustrt::rust_dbg_call(cb, n)
@@ -41,9 +42,9 @@ fn count(n: uint) -> uint {
 }
 
 fn main() {
-    for _ in 0..10_usize {
+    for _ in 0..10 {
         task::spawn(move|| {
-            let result = count(5_usize);
+            let result = count(5);
             println!("result = %?", result);
             panic!();
         });
index c86f8a38f63c409f32eeb4885a17da54050f398e..2c7c0875227d9baeddb83028f6bf45cf2c6290d8 100644 (file)
 // error-pattern:capacity overflow
 
 use std::collections::hash_map::HashMap;
-use std::uint;
+use std::usize;
 use std::mem::size_of;
 
 fn main() {
-    let threshold = uint::MAX / size_of::<(u64, u64, u64)>();
+    let threshold = usize::MAX / size_of::<(u64, u64, u64)>();
     let mut h = HashMap::<u64, u64>::with_capacity(threshold + 100);
     h.insert(0, 0);
 }
index 19a57db5ec79d0d01463bdf1e34b11928382de38..8c4caccdb65978e079afece2869d1ee363020876 100644 (file)
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 // error-pattern:Number is odd
-fn even(x: uint) -> bool {
-    if x < 2_usize {
+fn even(x: usize) -> bool {
+    if x < 2 {
         return false;
-    } else if x == 2_usize { return true; } else { return even(x - 2_usize); }
+    } else if x == 2 { return true; } else { return even(x - 2); }
 }
 
-fn foo(x: uint) {
+fn foo(x: usize) {
     if even(x) {
         println!("{}", x);
     } else {
@@ -23,4 +23,4 @@ fn foo(x: uint) {
     }
 }
 
-fn main() { foo(3_usize); }
+fn main() { foo(3); }
index 49449be52af8f5a13981b8aabd13e24bc1850f04..7213d3ef7c5f054a69baee479895bc5c2416d88b 100644 (file)
@@ -12,7 +12,7 @@
 // error-pattern: task '<main>' has overflowed its stack
 
 struct R {
-    b: int,
+    b: isize,
 }
 
 impl Drop for R {
diff --git a/src/test/run-fail/issue-23354-2.rs b/src/test/run-fail/issue-23354-2.rs
new file mode 100644 (file)
index 0000000..b120d32
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+// error-pattern:panic evaluated
+
+#[allow(unused_variables)]
+fn main() {
+    // This used to trigger an LLVM assertion during compilation
+    let x = [panic!("panic evaluated"); 2];
+}
diff --git a/src/test/run-fail/issue-23354.rs b/src/test/run-fail/issue-23354.rs
new file mode 100644 (file)
index 0000000..f6b937c
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 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.
+
+// error-pattern:panic evaluated
+
+#[allow(unused_variables)]
+fn main() {
+    let x = [panic!("panic evaluated"); 0];
+}
index 2b20540501ec043554dc9eea5d6ab98851eaca42..ce91af95d96b042bbde270876f02c22182a5b478 100644 (file)
@@ -14,7 +14,7 @@ use std::sync::Arc;
 
 enum e<T> { ee(Arc<T>) }
 
-fn foo() -> e<int> {panic!();}
+fn foo() -> e<isize> {panic!();}
 
 fn main() {
    let _f = foo();
index e51e8d93eb0ca0771485b3eb7fffd33463f03c32..272d85d7b508bbf2e0fa3c6985a6f4a311493ac6 100644 (file)
@@ -12,7 +12,7 @@
 
 #![allow(unused_variables)]
 
-struct Point { x: int, y: int }
+struct Point { x: isize, y: isize }
 
 fn main() {
     let origin = Point {x: 0, y: 0};
index 2b1672ad4e53763e73e76fae51c8fc2e1e54ad9c..c1f90bb8f2b3c81d22fa78b4daa89bcfc20f6e20 100644 (file)
@@ -17,6 +17,6 @@ fn foo(s: String) { }
 
 fn main() {
     let i =
-        match Some::<int>(3) { None::<int> => { panic!() } Some::<int>(_) => { panic!() } };
+        match Some::<isize>(3) { None::<isize> => { panic!() } Some::<isize>(_) => { panic!() } };
     foo(i);
 }
index da08f53fcde56d24573b5afdc8a6922ddf108acf..90b729a6dd271ee1ea5d4890db711e0a7a9122f5 100644 (file)
@@ -10,5 +10,5 @@
 
 // error-pattern:quux
 fn f() -> ! { panic!("quux") }
-fn g() -> int { match f() { true => { 1 } false => { 0 } } }
+fn g() -> isize { match f() { true => { 1 } false => { 0 } } }
 fn main() { g(); }
index 5c1a9e1a5e7125bee72556f53f1ac9cd4932508c..54e24de31653106614e92b960b08d277e70f05e9 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // error-pattern:squirrelcupcake
-fn cmp() -> int {
+fn cmp() -> isize {
     match (Some('a'), None::<char>) {
         (Some(_), _) => { panic!("squirrelcupcake"); }
         (_, Some(_)) => { panic!(); }
diff --git a/src/test/run-fail/overflowing-add.rs b/src/test/run-fail/overflowing-add.rs
new file mode 100644 (file)
index 0000000..cd13b81
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn value() -> u8 { 200 }
+
+fn main() {
+    let _x = value() + value() + value();
+}
diff --git a/src/test/run-fail/overflowing-lsh-1.rs b/src/test/run-fail/overflowing-lsh-1.rs
new file mode 100644 (file)
index 0000000..5415915
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'shift operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn id<T>(x: T) -> T { x }
+
+fn main() {
+    let _x = 1_i32 << id(32);
+}
diff --git a/src/test/run-fail/overflowing-lsh-2.rs b/src/test/run-fail/overflowing-lsh-2.rs
new file mode 100644 (file)
index 0000000..fd3e801
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'shift operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn id<T>(x: T) -> T { x }
+
+fn main() {
+    let _x = 1 << id(-1);
+}
diff --git a/src/test/run-fail/overflowing-lsh-3.rs b/src/test/run-fail/overflowing-lsh-3.rs
new file mode 100644 (file)
index 0000000..58914ba
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'shift operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn id<T>(x: T) -> T { x }
+
+fn main() {
+    let _x = 1_u64 << id(64);
+}
diff --git a/src/test/run-fail/overflowing-lsh-4.rs b/src/test/run-fail/overflowing-lsh-4.rs
new file mode 100644 (file)
index 0000000..ed25876
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'shift operation overflowed'
+// compile-flags: -C debug-assertions
+
+// This function is checking that our automatic truncation does not
+// sidestep the overflow checking.
+
+// (Work around constant-evaluation)
+fn id<T>(x: T) -> T { x }
+
+fn main() {
+    // this signals overflow when checking is on
+    let x = 1_i8 << id(17);
+
+    // ... but when checking is off, the fallback will truncate the
+    // input to its lower three bits (= 1). Note that this is *not*
+    // the behavior of the x86 processor for 8- and 16-bit types,
+    // but it is necessary to avoid undefined behavior from LLVM.
+    //
+    // We check that here, by ensuring the result has only been
+    // shifted by one place; if overflow checking is turned off, then
+    // this assertion will pass (and the compiletest driver will
+    // report that the test did not produce the error expected above).
+    assert_eq!(x, 2_i8);
+}
diff --git a/src/test/run-fail/overflowing-mul.rs b/src/test/run-fail/overflowing-mul.rs
new file mode 100644 (file)
index 0000000..5d2f539
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn value() -> u8 { 200 }
+
+fn main() {
+    let x = value() * 4;
+}
diff --git a/src/test/run-fail/overflowing-rsh-1.rs b/src/test/run-fail/overflowing-rsh-1.rs
new file mode 100644 (file)
index 0000000..c36a16f
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'shift operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn id<T>(x: T) -> T { x }
+
+fn main() {
+    let _x = -1_i32 >> id(32);
+}
diff --git a/src/test/run-fail/overflowing-rsh-2.rs b/src/test/run-fail/overflowing-rsh-2.rs
new file mode 100644 (file)
index 0000000..f619ebe
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'shift operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn id<T>(x: T) -> T { x }
+
+fn main() {
+    let _x = -1_i32 >> id(-1);
+}
diff --git a/src/test/run-fail/overflowing-rsh-3.rs b/src/test/run-fail/overflowing-rsh-3.rs
new file mode 100644 (file)
index 0000000..c261e19
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'shift operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn id<T>(x: T) -> T { x }
+
+fn main() {
+    let _x = -1_i64 >> id(64);
+}
diff --git a/src/test/run-fail/overflowing-rsh-4.rs b/src/test/run-fail/overflowing-rsh-4.rs
new file mode 100644 (file)
index 0000000..6e79a13
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'shift operation overflowed'
+// compile-flags: -C debug-assertions
+
+// This function is checking that our (type-based) automatic
+// truncation does not sidestep the overflow checking.
+
+// (Work around constant-evaluation)
+fn id<T>(x: T) -> T { x }
+
+fn main() {
+    // this signals overflow when checking is on
+    let x = 2_i8 >> id(17);
+
+    // ... but when checking is off, the fallback will truncate the
+    // input to its lower three bits (= 1). Note that this is *not*
+    // the behavior of the x86 processor for 8- and 16-bit types,
+    // but it is necessary to avoid undefined behavior from LLVM.
+    //
+    // We check that here, by ensuring the result is not zero; if
+    // overflow checking is turned off, then this assertion will pass
+    // (and the compiletest driver will report that the test did not
+    // produce the error expected above).
+    assert_eq!(x, 1_i8);
+}
diff --git a/src/test/run-fail/overflowing-sub.rs b/src/test/run-fail/overflowing-sub.rs
new file mode 100644 (file)
index 0000000..b089dcc
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn value() -> u8 { 42 }
+
+fn main() {
+    let _x = value() - (value() + 1);
+}
index 4d4f931751067929c8c2afe8a9a2e52c44de1dac..0e029b6ecbc85a71068fcd89862c016ad6b00328 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 // error-pattern:woe
-fn f(a: int) { println!("{}", a); }
+fn f(a: isize) { println!("{}", a); }
 
 fn main() { f(panic!("woe")); }
index 89e47bf46ab020c375f1d16a72acb219d9379513..4d0f7c29cb9df4ead4e9e10ff50fb7c2e2d7e386 100644 (file)
@@ -10,9 +10,6 @@
 
 // error-pattern:panicked at 'Box<Any>'
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
 fn main() {
-    panic!(box 612_i64);
+    panic!(Box::new(612_i64));
 }
index df14efd6c3a97a1ea46e0260c2f7f221f2d2348f..dbded1075442c10240261e204b4ffd238d6e6c1c 100644 (file)
@@ -13,5 +13,5 @@
 use std::result::Result::Err;
 
 fn main() {
-    println!("{}", Err::<int,String>("kitty".to_string()).unwrap());
+    println!("{}", Err::<isize,String>("kitty".to_string()).unwrap());
 }
index fd7c3f8cc0e4b346713e2854ff1d97d8ea09402d..249e2e1ac2d64938594f638ccbc8186a405e1bfd 100644 (file)
 
 // error-pattern:whatever
 
+#![feature(exit_status, rustc_private)]
+
 #[macro_use] extern crate log;
-use std::os;
+use std::env;
 
 fn main() {
     error!("whatever");
     // Setting the exit status only works when the scheduler terminates
     // normally. In this case we're going to panic, so instead of
     // returning 50 the process will return the typical rt failure code.
-    os::set_exit_status(50);
+    env::set_exit_status(50);
     panic!();
 }
index 775d38c8b3044ca917d8729799552664e21e90d2..fddff3c5a9f4fea67ab205b483e7f34a8b17720c 100644 (file)
 
 // error-pattern:whatever
 
+#![feature(exit_status, rustc_private)]
+
 #[macro_use] extern crate log;
-use std::os;
+use std::env;
 use std::thread;
 
 struct r {
-  x:int,
+  x:isize,
 }
 
 // Setting the exit status after the runtime has already
@@ -23,11 +25,11 @@ struct r {
 // runtime's exit code
 impl Drop for r {
     fn drop(&mut self) {
-        os::set_exit_status(50);
+        env::set_exit_status(50);
     }
 }
 
-fn r(x:int) -> r {
+fn r(x:isize) -> r {
     r {
         x: x
     }
@@ -35,7 +37,7 @@ fn r(x:int) -> r {
 
 fn main() {
     error!("whatever");
-    let _t = thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
       let _i = r(5);
     });
     panic!();
index 39ece8a464a6fe8c77600ca6f9eacab0cb27196b..c33a8d2d03227027c976a20bb5d8782b9d4e1e4d 100644 (file)
 
 // error-pattern:whatever
 
+#![feature(rustc_private, exit_status)]
+
 #[macro_use] extern crate log;
-use std::os;
+use std::env;
 
 fn main() {
     error!("whatever");
     // 101 is the code the runtime uses on task panic and the value
     // compiletest expects run-fail tests to return.
-    os::set_exit_status(101);
+    env::set_exit_status(101);
 }
index 5a5bb53a33a209f12f25f928a01fb662e034e7ff..e18c5d9631a702358a6964b918fe8b2db3bb3267 100644 (file)
@@ -14,7 +14,7 @@
 // ignore-pretty: does not work well with `--test`
 
 #[test]
-#[should_fail(expected = "foobar")]
+#[should_panic(expected = "foobar")]
 fn test_foo() {
     panic!("blah")
 }
index 8c9cd2d63cb4758f4c29f40e3e2435294872a126..94ed641c79c9372cabcf34a107356b5e2bc780cc 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// This checks that RUST_TEST_TASKS not being 1, 2, ... is detected
+// This checks that RUST_TEST_THREADS not being 1, 2, ... is detected
 // properly.
 
 // error-pattern:should be a positive integer
 // compile-flags: --test
-// exec-env:RUST_TEST_TASKS=foo
+// exec-env:RUST_TEST_THREADS=foo
 // ignore-pretty: does not work well with `--test`
 
 #[test]
index 9f643c09795dfd1c63ca7a45c50ee1959f2c7eae..83b2bb91f0073a59ba3418da547d8df276e47677 100644 (file)
@@ -10,7 +10,4 @@
 
 // error-pattern: panic
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
-fn main() { box panic!(); }
+fn main() { Box::new(panic!()); }
index 1c72686b60287ace08d2905f00c68075da791f68..6df279b047f64889133acf8045f95bee33e8a639 100644 (file)
 // error-pattern:fail
 
 
-fn build() -> Vec<int> {
+fn build() -> Vec<isize> {
     panic!();
 }
 
-struct Blk { node: Vec<int> }
+struct Blk { node: Vec<isize> }
 
 fn main() {
     let _blk = Blk {
index 943b4cd76715c35e3490e8624af652137a685a00..d5d60d18924d542e28a62c6ccbaf764174bf2190 100644 (file)
 // error-pattern:fail
 
 
-fn build1() -> Vec<int> {
+fn build1() -> Vec<isize> {
     vec!(0,0,0,0,0,0,0)
 }
 
-fn build2() -> Vec<int> {
+fn build2() -> Vec<isize> {
     panic!();
 }
 
-struct Blk { node: Vec<int> , span: Vec<int> }
+struct Blk { node: Vec<isize> , span: Vec<isize> }
 
 fn main() {
     let _blk = Blk {
index e1176b1bcdbc931f7ce1806cfad95c9cbb8a53b7..f4ba789d6bf7be1c92b6bb1b7e2114c4936aae4f 100644 (file)
 
 // error-pattern:fail
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
 fn failfn() {
     panic!();
 }
 
 fn main() {
-    box 0;
+    Box::new(0);
     failfn();
 }
index c378e852f897e2dbe7524acedfa590f9033c4ea4..da52cd56a1a080d39044defa6051864cf4e8cc3d 100644 (file)
@@ -12,8 +12,8 @@
 
 
 fn main() {
-    let v: Vec<int> = vec!(10);
-    let x: uint = 0;
+    let v: Vec<isize> = vec!(10);
+    let x: usize = 0;
     assert_eq!(v[x], 10);
     // Bounds-check panic.
 
index 6a7d0a1d73e8fe7170d65a7b2c4446d52432190b..cfe499f8a4aeb9a28c85bc0fd61de0167581be88 100644 (file)
@@ -11,4 +11,4 @@
 #![allow(while_true)]
 
 // error-pattern:quux
-fn main() { let _x: int = { while true { panic!("quux"); } ; 8 } ; }
+fn main() { let _x: isize = { while true { panic!("quux"); } ; 8 } ; }
index 961342591aa51efbb0bf060687b1c0b569ffc988..c14006cc2e052b7a0bd77f6ae17dc0fa668b23cb 100644 (file)
@@ -9,4 +9,3 @@ all: foo
 # This is just to make sure the above command actually succeeds
 foo:
        $(RUSTC) foo.rs -A warnings
-
index 19ce5d0a7ca40a60a787f82b8a6fd0fed6b1e783..a9e18f5a8f1e6b0dade592613e8579396a091dcd 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #[derive()]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Foo;
 
 pub fn main() { }
index 64b7f58caeaf3e7e7be37dda3b90f25c82d65406..3eecaf9314226c884551faa7241a621a3f9db70f 100644 (file)
@@ -13,7 +13,3 @@ bar:
 
 foo: bar
        $(RUSTC) foo.rs -A warnings
-
-
-
-
index fb23a214016a7ec41df3389036b118300d6d2410..a36cc474c2bf052054aa6614b805302073987703 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(test_feature)]
+
 extern crate bar;
 
 pub fn main() { bar::baz() }
diff --git a/src/test/run-make/bare-outfile/Makefile b/src/test/run-make/bare-outfile/Makefile
new file mode 100644 (file)
index 0000000..97d09c8
--- /dev/null
@@ -0,0 +1,4 @@
+-include ../tools.mk
+
+all:
+       $(rustc) -o foo foo.rs
diff --git a/src/test/run-make/bare-outfile/foo.rs b/src/test/run-make/bare-outfile/foo.rs
new file mode 100644 (file)
index 0000000..63e7479
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2015 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.
+
+fn main() {
+}
index 89352a16d8ba2fe3792b017c9f66bebae9cd9020..02af5244b8aabe93cf4e7f208e8d51957b2f506a 100644 (file)
@@ -8,8 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(old_io, old_path)]
+
 use std::env;
-use std::old_io::{File, Command};
+use std::fs::File;
+use std::process::Command;
+use std::io::Write;
+use std::path::Path;
 
 // creates broken.rs, which has the Ident \x00name_0,ctxt_0\x00
 // embedded within it, and then attempts to compile broken.rs with the
@@ -22,21 +27,18 @@ fn main() {
 
     let main_file = tmpdir.join("broken.rs");
     let _ = File::create(&main_file).unwrap()
-        .write_str("pub fn main() {
+        .write_all(b"pub fn main() {
                    let \x00name_0,ctxt_0\x00 = 3;
                    println!(\"{}\", \x00name_0,ctxt_0\x00);
-        }");
+        }").unwrap();
 
     // rustc is passed to us with --out-dir and -L etc., so we
     // can't exec it directly
     let result = Command::new("sh")
         .arg("-c")
-        .arg(&format!("{} {}",
-                      rustc,
-                      main_file.as_str()
-                      .unwrap()))
+        .arg(&format!("{} {}", rustc, main_file.display()))
         .output().unwrap();
-    let err = String::from_utf8_lossy(&result.error);
+    let err = String::from_utf8_lossy(&result.stderr);
 
     // positive test so that this test will be updated when the
     // compiler changes.
index 8a801d589fb819e798fab29da4af3eb81048eedc..b5c54558a4f0ac9165b8d7436171a619be766388 100644 (file)
@@ -10,4 +10,3 @@
 
 #![crate_type = "lib"]
 extern crate b;
-
index 0f02f1005728ef6a418956ba2450cff44c57fbae..a397d6bc749fe4de75f64cf3c0c9d3b2367847f5 100644 (file)
@@ -11,4 +11,3 @@
 #![crate_name = "foo"]
 
 fn main() {}
-
diff --git a/src/test/run-make/debug-assertions/Makefile b/src/test/run-make/debug-assertions/Makefile
new file mode 100644 (file)
index 0000000..7129756
--- /dev/null
@@ -0,0 +1,21 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) debug.rs -C debug-assertions=no
+       $(call RUN,debug) good
+       $(RUSTC) debug.rs -C opt-level=0
+       $(call RUN,debug) bad
+       $(RUSTC) debug.rs -C opt-level=1
+       $(call RUN,debug) good
+       $(RUSTC) debug.rs -C opt-level=2
+       $(call RUN,debug) good
+       $(RUSTC) debug.rs -C opt-level=3
+       $(call RUN,debug) good
+       $(RUSTC) debug.rs -O
+       $(call RUN,debug) good
+       $(RUSTC) debug.rs
+       $(call RUN,debug) bad
+       $(RUSTC) debug.rs -C debug-assertions=yes -O
+       $(call RUN,debug) bad
+       $(RUSTC) debug.rs -C debug-assertions=yes -C opt-level=1
+       $(call RUN,debug) bad
diff --git a/src/test/run-make/debug-assertions/debug.rs b/src/test/run-make/debug-assertions/debug.rs
new file mode 100644 (file)
index 0000000..a0ccc75
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2015 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.
+
+#![deny(warnings)]
+
+use std::env;
+use std::thread;
+
+fn main() {
+    let should_fail = env::args().nth(1) == Some("bad".to_string());
+
+    assert_eq!(thread::spawn(debug_assert_eq).join().is_err(), should_fail);
+    assert_eq!(thread::spawn(debug_assert).join().is_err(), should_fail);
+    assert_eq!(thread::spawn(overflow).join().is_err(), should_fail);
+}
+
+fn debug_assert_eq() {
+    let mut hit1 = false;
+    let mut hit2 = false;
+    debug_assert_eq!({ hit1 = true; 1 }, { hit2 = true; 2 });
+    assert!(!hit1);
+    assert!(!hit2);
+}
+
+fn debug_assert() {
+    let mut hit = false;
+    debug_assert!({ hit = true; false });
+    assert!(!hit);
+}
+
+fn overflow() {
+    fn add(a: u8, b: u8) -> u8 { a + b }
+
+    add(200u8, 200u8);
+}
index 049b76c1b648a7514625fa2e8adead8fd8004150..81930e969a9f6a1adf43e1842cb9e7322969a8c6 100644 (file)
@@ -23,4 +23,3 @@ all:
        @echo after
        $(RUSTC) --cfg after  d.rs --extern a=$(TMPDIR)/liba-1.rlib
        $(call RUN,d)
-
index 2152aa79c3370a337ef242c64a9f04c09d45d8f3..e6c760257380c6639446ab5e533b74c2a17b7a3e 100644 (file)
@@ -7,4 +7,3 @@
 // <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.
-
index 0f759efb02539bc874d624f4511cd767b819f89e..b93bdbaa16f2abe5414dadb0bc2399b5acf2d5b9 100644 (file)
@@ -8,17 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(std_misc, old_path, os)]
+
 use std::dynamic_lib::DynamicLibrary;
 use std::os;
+use std::path::Path;
 
 pub fn main() {
     unsafe {
         let path = Path::new("libdylib.so");
         let a = DynamicLibrary::open(Some(&path)).unwrap();
-        assert!(a.symbol::<int>("fun1").is_ok());
-        assert!(a.symbol::<int>("fun2").is_err());
-        assert!(a.symbol::<int>("fun3").is_err());
-        assert!(a.symbol::<int>("fun4").is_ok());
-        assert!(a.symbol::<int>("fun5").is_ok());
+        assert!(a.symbol::<isize>("fun1").is_ok());
+        assert!(a.symbol::<isize>("fun2").is_err());
+        assert!(a.symbol::<isize>("fun3").is_err());
+        assert!(a.symbol::<isize>("fun4").is_ok());
+        assert!(a.symbol::<isize>("fun5").is_ok());
     }
 }
index 838ef338846a8dbb05ddf90cb1cf1bb43df039e7..c0f55893a3abe4370e0a779081591bd56a3cdc71 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #[repr(packed)]
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 struct Foo {
     a: i8,
     b: i16,
index 92b353c892ae7fe58f4a8c24e7e401e4a5833192..451841e736899aba7746a755900ba610b6f12c67 100644 (file)
@@ -13,4 +13,3 @@ extern crate libc;
 fn main() {
     libc::foo();
 }
-
index bee4a120d5909fd2b0f375c81518071f9c986d03..51c6b14e1deedb01fed39975d73f22ed15b113cf 100644 (file)
@@ -22,12 +22,12 @@ digraph block {
     N3 -> N4;
     N4 -> N5;
     N5 -> N6;
-    N6 -> N8;
-    N8 -> N9;
+    N6 -> N9;
     N9 -> N10;
     N10 -> N11;
     N11 -> N12;
-    N12 -> N13;
+    N12 -> N8;
+    N8 -> N13;
     N13 -> N14;
     N14 -> N15;
     N15 -> N7;
index 39f71d309fdf9363d55bba93be259e0c8a51878a..f36b8d0abc7e3a293e7acf00790403c4066abcbd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 pub fn pat_vec_7() {
     match [7, 77, 777, 7777] {
         [x, y, ..] => x + y
index 76e66513515622c71406b246e371b26feab9e3bc..fb7d2ad97bd5f553277f80ae09dfcba4cbd3f1bd 100644 (file)
@@ -32,16 +32,16 @@ digraph block {
     N6 -> N7;
     N7 -> N8;
     N8 -> N9;
-    N9 -> N11;
-    N11 -> N12;
-    N12 -> N13;
+    N9 -> N12;
+    N12 -> N11;
+    N11 -> N13;
     N13 -> N14;
     N14 -> N15;
     N15 -> N10;
-    N11 -> N16;
-    N16 -> N17;
+    N9 -> N17;
     N17 -> N18;
-    N18 -> N19;
+    N18 -> N16;
+    N16 -> N19;
     N19 -> N20;
     N20 -> N21;
     N21 -> N22;
index b4ec986ef25fd8f50141116a5d4aad171cc7a0be..21e84fb858bcfef907b6023f58fdf3c89e75f66e 100644 (file)
@@ -1,17 +1,17 @@
 digraph block {
     N0[label="entry"];
     N1[label="exit"];
-    N2[label="expr 2usize"];
-    N3[label="expr 0usize"];
-    N4[label="expr 20usize"];
-    N5[label="expr [2usize, 0usize, 20usize]"];
+    N2[label="expr 2"];
+    N3[label="expr 0"];
+    N4[label="expr 20"];
+    N5[label="expr [2, 0, 20]"];
     N6[label="local v"];
-    N7[label="stmt let v = [2usize, 0usize, 20usize];"];
+    N7[label="stmt let v = [2, 0, 20];"];
     N8[label="expr v"];
-    N9[label="expr 20usize"];
-    N10[label="expr v[20usize]"];
-    N11[label="stmt v[20usize];"];
-    N12[label="block { let v = [2usize, 0usize, 20usize]; v[20usize]; }"];
+    N9[label="expr 20"];
+    N10[label="expr v[20]"];
+    N11[label="stmt v[20];"];
+    N12[label="block { let v = [2, 0, 20]; v[20]; }"];
     N0 -> N2;
     N2 -> N3;
     N3 -> N4;
index d65de18b5470ad11e15c4ec283d0a65d5e7426f1..d7349932355b10c92a06c3a1d93af996a6b7e7cb 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 pub fn expr_index_20() {
-    let v = [2_usize, 0_usize, 20_usize];
-    v[20_usize];
+    let v = [2, 0, 20];
+    v[20];
 }
index 7654917b4623201a0f371c41327caf4868f7aa24..cf7683479f08e648341db30acada9f0988dcd6e7 100644 (file)
@@ -12,4 +12,3 @@ all: $(call STATICLIB,foo) $(call STATICLIB,bar)
        $(RUSTC) foo.rs
        $(RUSTC) bar.rs
        $(RUSTC) main.rs -Z print-link-args
-
index 5311af2959b2c609106282ba09738e9b28df1551..88fc98615f0b342cb29b537627cfa2947bc59a13 100644 (file)
@@ -20,4 +20,3 @@ extern {
 pub fn doit() {
     unsafe { bar(); }
 }
-
index 02c03445ef4e6d804773e8c3fa300dd40353f15e..f5be5a055c3e0c99c10bfa965d570accd4ab6093 100644 (file)
@@ -11,7 +11,7 @@
 #![feature(asm)]
 #![crate_type="lib"]
 
-pub fn exit(n: uint) {
+pub fn exit(n: usize) {
     unsafe {
         // Pretend this asm is an exit() syscall.
         asm!("" :: "r"(n) :: "volatile");
index 835e068c15cfd2b468e3d851a069de3f692f7d67..81ed446595ab0c6474c7c9802621bcb41f0e6f2c 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(asm)]
+#![feature(asm, core)]
 #![crate_type="lib"]
 
 use std::intrinsics;
 
-pub fn exit(n: uint) -> ! {
+pub fn exit(n: usize) -> ! {
     unsafe {
         // Pretend this asm is an exit() syscall.
         asm!("" :: "r"(n) :: "volatile");
index 446c6e5c81b69830b7b8158aa728588b4cbd430d..c19d3d5c30f1473a41d571e54edea4a4404805ce 100644 (file)
@@ -11,4 +11,3 @@ all:
        $(RUSTC) bar.rs --crate-type=staticlib -C lto -L. -o $(TMPDIR)/libbar.a
        $(CC) foo.c -lbar -o $(call RUN_BINFILE,foo) $(EXTRACFLAGS)
        $(call RUN,foo)
-
index c96210896fd652c94296e47b38ff632c5db31271..0d42e0be58d0702edccef3084d2cd87cc685aa97 100644 (file)
@@ -8,8 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(rustc_private, path, convert)]
+
 extern crate rustc;
 extern crate rustc_driver;
+extern crate rustc_lint;
 extern crate syntax;
 
 use rustc::session::{build_session, Session};
@@ -17,6 +20,8 @@ use rustc::session::config::{basic_options, build_configuration, Input, OutputTy
 use rustc_driver::driver::{compile_input, CompileController};
 use syntax::diagnostics::registry::Registry;
 
+use std::path::PathBuf;
+
 fn main() {
     let src = r#"
     fn main() {}
@@ -28,9 +33,9 @@ fn main() {
         panic!("expected rustc path");
     }
 
-    let tmpdir = Path::new(&args[1]);
+    let tmpdir = PathBuf::from(&args[1]);
 
-    let mut sysroot = Path::new(&args[3]);
+    let mut sysroot = PathBuf::from(&args[3]);
     sysroot.pop();
     sysroot.pop();
 
@@ -39,17 +44,18 @@ fn main() {
     compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
 }
 
-fn basic_sess(sysroot: Path) -> Session {
+fn basic_sess(sysroot: PathBuf) -> Session {
     let mut opts = basic_options();
     opts.output_types = vec![OutputTypeExe];
     opts.maybe_sysroot = Some(sysroot);
 
     let descriptions = Registry::new(&rustc::diagnostics::DIAGNOSTICS);
     let sess = build_session(opts, None, descriptions);
+    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
     sess
 }
 
-fn compile(code: String, output: Path, sysroot: Path) {
+fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
     let sess = basic_sess(sysroot);
     let cfg = build_configuration(&sess);
     let control = CompileController::basic();
index 3a2ced80ef41ed86657c865aa349a0efc6642394..6c39b33be086e279f5580e39998707473fc2dfa5 100644 (file)
@@ -23,8 +23,8 @@ extern "C" fn outer_foreign<T>() {
 }
 
 fn main() {
-    outer::<int>();
-    outer::<uint>();
-    outer_foreign::<int>();
-    outer_foreign::<uint>();
+    outer::<isize>();
+    outer::<usize>();
+    outer_foreign::<isize>();
+    outer_foreign::<usize>();
 }
index 4d975d2f71718e60741a975eef24ba3539262bbb..cc3b257a5c5bf6b9efa35011a6962f4638f6ff61 100644 (file)
@@ -4,4 +4,3 @@ all:
        $(RUSTC) foo.rs
        $(call RUN,foo)
        rm $(TMPDIR)/$(call DYLIB_GLOB,foo)
-
index b8ebe6db6fd8f4d06a69fa29862460ec8365ea59..116c7ae991cf67ae778218719addc8542f7c838f 100644 (file)
@@ -14,4 +14,3 @@ all: $(TMPDIR)/libcorrect.a $(TMPDIR)/libwrong.a
        $(call RUN,should_succeed)
        $(RUSTC) main.rs -o $(TMPDIR)/should_fail -L $(WRONG_DIR) -L $(CORRECT_DIR)
        $(call FAIL,should_fail)
-
index cd286af602a70c36856faf30947b3ec046c0372d..c1787eb03f5925a67ececa5b076df9828345c957 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(libc, exit_status)]
+
 extern crate libc;
 
 #[link(name="foo")]
@@ -21,6 +23,6 @@ fn main() {
     };
 
     if result != 1 {
-        std::os::set_exit_status(255);
+        std::env::set_exit_status(255);
     }
 }
index 6bcde96335cff07c99a7d09ae824112095e389c7..1871a5bbdc7f6dd0befd848c07e5a19b071bacbd 100644 (file)
@@ -5,4 +5,3 @@ all:
        $(AR) rcs $(TMPDIR)/libfoo.a $(TMPDIR)/foo.o
        $(RUSTC) bar.rs -lfoo -L $(TMPDIR)
        $(call RUN,bar) || exit 1
-
index a38b2cfb9628772d560e5b4703d021578b196551..c9395f557fd4f7ec9007bbf8cf6fa6ba66043a56 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(rustc_private)]
+
 extern crate lib;
 #[macro_use] extern crate log;
 
index d0536956152504a1a95c58eea9080d532ea28c64..dccf0d99b0f8207c9316fdf51c547920b89c1c77 100644 (file)
@@ -4,4 +4,3 @@ all: $(TMPDIR)/libbar.a
        $(RUSTC) foo.rs -lstatic=bar
        $(RUSTC) main.rs
        $(call RUN,main)
-
index da5fc78f3284e4b8ab5d991b0cfab86c0c820d8c..edf8e9df465dc23e825d18a1bee7bade996eb494 100644 (file)
@@ -16,7 +16,7 @@ A3=$(TMPDIR)/a3
 # A hack to match distinct lines of output from a single run.
 LOG=$(TMPDIR)/log.txt
 
-all: 
+all:
        mkdir -p $(A1) $(A2) $(A3)
        $(RUSTC) --crate-type=rlib crateA1.rs
        mv $(TMPDIR)/$(call RLIB_GLOB,crateA) $(A1)
index ed04eed8cf77e602f57358e674da214027fcc84e..baabdc9ad7bbe792339f9e6ab1acbe56542c76b8 100644 (file)
@@ -11,6 +11,6 @@
 #![crate_name = "foo"]
 #![crate_type = "rlib"]
 
-static FOO: uint = 3;
+static FOO: usize = 3;
 
-pub fn foo() -> &'static uint { &FOO }
+pub fn foo() -> &'static usize { &FOO }
index 3f8b97f2566520a3c28d0e41b67e0e2d82151095..275658047d3cec690de04572d4da06eb3b09ef8c 100644 (file)
@@ -1,6 +1,6 @@
 -include ../tools.mk
 
-all: 
+all:
        $(RUSTC) --crate-type=rlib crateA.rs
        $(RUSTC) --crate-type=rlib crateB.rs
        $(call REMOVE_RLIBS,crateA)
index 7696c27ad71fcf53f3eac8aeaf677722fdcf268d..c44335e2bbc2abbe07dc370dcf18ee81fd6bf79f 100644 (file)
@@ -11,4 +11,4 @@
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 
-pub static foo: int = 4;
+pub static foo: isize = 4;
index d60cc05cc9f9cbeca66d87eb58550a75ac635c56..78af525f386fac6244ffc5b15e58771f5ef89ba5 100644 (file)
@@ -13,4 +13,4 @@ extern crate both;
 
 use std::mem;
 
-pub fn addr() -> uint { unsafe { mem::transmute(&both::foo) } }
+pub fn addr() -> usize { unsafe { mem::transmute(&both::foo) } }
index 8006987e9f349152d125f7aa4e651ce3ec74f659..c3d88016fdaa3a95130e0118903634e0b8b2492a 100644 (file)
@@ -14,6 +14,6 @@ extern crate both;
 use std::mem;
 
 fn main() {
-    assert_eq!(unsafe { mem::transmute::<&int, uint>(&both::foo) },
+    assert_eq!(unsafe { mem::transmute::<&isize, usize>(&both::foo) },
                dylib::addr());
 }
index 4cfa65330bd1901a91109e26e681e78858997675..c5066ccd6566f1dd2282637738a34b93970047ea 100644 (file)
@@ -12,4 +12,3 @@ extern crate bar1;
 extern crate bar2;
 
 fn main() {}
-
index 0bec6148189a908ea43df5f599c278c5f76236db..29f52f97a88878f0b8c8ab821ff683ac32b3578b 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, no_std)]
+#![feature(lang_items, no_std, libc)]
 #![no_std]
 #![crate_type = "dylib"]
 
index 9e8afdc5696ed6dd604cd78a4acc655ad207517d..ae424c6569dbe3f976c61522148dbd0c92738957 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, no_std)]
+#![feature(lang_items, no_std, libc)]
 #![no_std]
 #![crate_type = "dylib"]
 
index 8eb82b48eacf7baf30a9ea77bc7855835ab9de45..e6c8b8eb179e6341990348735af236ebd952c8b6 100644 (file)
@@ -10,4 +10,3 @@
 
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
-
diff --git a/src/test/run-make/output-with-hyphens/Makefile b/src/test/run-make/output-with-hyphens/Makefile
new file mode 100644 (file)
index 0000000..783d826
--- /dev/null
@@ -0,0 +1,6 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) foo-bar.rs
+       [ -f $(TMPDIR)/$(call BIN,foo-bar) ]
+       [ -f $(TMPDIR)/libfoo_bar.rlib ]
diff --git a/src/test/run-make/output-with-hyphens/foo-bar.rs b/src/test/run-make/output-with-hyphens/foo-bar.rs
new file mode 100644 (file)
index 0000000..2f93b2d
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2015 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.
+
+#![crate_type = "lib"]
+#![crate_type = "bin"]
+
+fn main() {}
index b6137c3eba91bd9e701258ef210feb1bc67fbdf6..04bf17dc28aecaf630680fc82ff145c46fd91ad7 100644 (file)
@@ -15,8 +15,8 @@
 extern crate serialize;
 
 #[derive(Encodable)] pub struct A;
-#[derive(Encodable)] pub struct B(int);
-#[derive(Encodable)] pub struct C { x: int }
+#[derive(Encodable)] pub struct B(isize);
+#[derive(Encodable)] pub struct C { x: isize }
 #[derive(Encodable)] pub enum D {}
 #[derive(Encodable)] pub enum E { y }
-#[derive(Encodable)] pub enum F { z(int) }
+#[derive(Encodable)] pub enum F { z(isize) }
index acf3f90cb0e1f0dac2a798202f07f37ea1b41046..4879fbfe6d34346172d9c0d75a1111829a9cfeaf 100644 (file)
@@ -12,5 +12,5 @@
 
 
 
-fn foo_method(&self) -> &'static str { return "i am very similiar to foo."; }
+fn foo_method(&self) -> &'static str { return "i am very similar to foo."; }
 /* nest::S::foo_method */
index 4942540126b11fee3e4fae0c72c3a38042cf5703..8ea86a94f935e97d30742469f60e772b37229482 100644 (file)
@@ -22,7 +22,7 @@ pub mod nest {
     struct S;
     impl S {
         fn foo_method(&self) -> &'static str {
-            return "i am very similiar to foo.";
+            return "i am very similar to foo.";
         }
     }
 }
diff --git a/src/test/run-make/rustdoc-default-impl/Makefile b/src/test/run-make/rustdoc-default-impl/Makefile
new file mode 100644 (file)
index 0000000..338cf9d
--- /dev/null
@@ -0,0 +1,5 @@
+-include ../tools.mk
+
+all: foo.rs bar.rs
+       $(RUSTC) foo.rs --crate-type lib
+       $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc bar.rs -L $(TMPDIR)
diff --git a/src/test/run-make/rustdoc-default-impl/bar.rs b/src/test/run-make/rustdoc-default-impl/bar.rs
new file mode 100644 (file)
index 0000000..60a2f72
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 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.
+
+extern crate foo;
+
+pub use foo::bar;
+
+pub fn wut<T: bar::Bar>() {
+}
diff --git a/src/test/run-make/rustdoc-default-impl/foo.rs b/src/test/run-make/rustdoc-default-impl/foo.rs
new file mode 100644 (file)
index 0000000..8f11629
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2015 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(optin_builtin_traits)]
+#![feature(core)]
+
+pub mod bar {
+    use std::marker;
+
+    pub trait Bar: marker::MarkerTrait + 'static {}
+
+    impl Bar for .. {}
+
+    pub trait Foo {
+        fn foo(&self) {}
+    }
+
+    impl Foo {
+        pub fn test<T: Bar>(&self) {}
+    }
+
+    pub struct TypeId;
+
+    impl TypeId {
+        pub fn of<T: Bar + ?Sized>() -> TypeId {
+            panic!()
+        }
+    }
+}
diff --git a/src/test/run-make/rustdoc-extern-default-method/Makefile b/src/test/run-make/rustdoc-extern-default-method/Makefile
new file mode 100644 (file)
index 0000000..ffc4a08
--- /dev/null
@@ -0,0 +1,6 @@
+-include ../tools.mk
+
+all: lib.rs ext.rs
+       $(HOST_RPATH_ENV) $(RUSTC) ext.rs
+       $(HOST_RPATH_ENV) $(RUSTDOC) -L $(TMPDIR) -w html -o $(TMPDIR)/doc lib.rs
+       $(HTMLDOCCK) $(TMPDIR)/doc lib.rs
diff --git a/src/test/run-make/rustdoc-extern-default-method/ext.rs b/src/test/run-make/rustdoc-extern-default-method/ext.rs
new file mode 100644 (file)
index 0000000..8615627
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2015 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.
+
+#![crate_type="lib"]
+
+pub trait Trait {
+    fn provided(&self) {}
+}
+
+pub struct Struct;
+
+impl Trait for Struct {
+    fn provided(&self) {}
+}
diff --git a/src/test/run-make/rustdoc-extern-default-method/lib.rs b/src/test/run-make/rustdoc-extern-default-method/lib.rs
new file mode 100644 (file)
index 0000000..df92764
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2015 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.
+
+extern crate ext;
+
+// @count lib/struct.Struct.html '//*[@id="method.provided"]' 1
+pub use ext::Struct;
index c87684f59ea01057d9f46888e7d0e561ed598b67..55cbd2da6ae2ebdf0b9b2be12cbc54da9121ffee 100644 (file)
@@ -5,4 +5,3 @@ all: foo.rs bar.rs
        $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
        $(HOST_RPATH_ENV) $(RUSTDOC) -L $(TMPDIR) -w html -o $(TMPDIR)/doc bar.rs
        $(HTMLDOCCK) $(TMPDIR)/doc bar.rs
-
index 672090c13a23376ef59adf3665d903d6c8b13893..26a05f8490fd191d207d60a90d03fc0e7e3efd3d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(unboxed_closures)]
+
 extern crate foo;
 
 // @has bar/trait.Foo.html //pre "pub trait Foo"
index fc5f03e8bd36a4abb029c6328fff6c61c64800c6..96a7a8378b792e04d01a0e5837043f455417af05 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![crate_type="lib"]
+#![feature(unboxed_closures)]
 
 pub trait Foo {
     extern "rust-call" fn foo(&self, _: ()) -> i32;
index 1316ee256e147d8e5eedbd72572910dc58b88e00..c1b1683efdb7fad32880ae69c03656b5510e2be7 100644 (file)
@@ -3,4 +3,3 @@
 all: foo.rs
        $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
        $(HTMLDOCCK) $(TMPDIR)/doc foo.rs
-
index b7fc6d6c0ad5b6f22c4c908dccd7f6c2426944b8..ba971836e5a9d64c2ca7df1580e39c9addb7c251 100644 (file)
@@ -9,4 +9,3 @@ all:
 else
 all:
 endif
-
index 29a909f139ead13238b3c4153b6fe0c4916c04bf..7505d20566dbb45ef209d92c1d86b050393a6d80 100644 (file)
@@ -22,4 +22,3 @@ mod m {
         pub use super::*;
     }
 }
-
index f6b73021bebdfb0ffc70941642062208c65a8a9b..494eb03d728034d0facb9689d0173dd1ec4ff70a 100644 (file)
@@ -29,8 +29,8 @@ pub mod bar {
     pub trait Doge { fn dummy(&self) { } }
 
     // @has foo/bar/struct.Foo.html
-    pub struct Foo { x: int, y: uint }
+    pub struct Foo { x: isize, y: usize }
 
     // @has foo/bar/fn.prawns.html
-    pub fn prawns((a, b): (int, uint), Foo { x, y }: Foo) { }
+    pub fn prawns((a, b): (isize, usize), Foo { x, y }: Foo) { }
 }
diff --git a/src/test/run-make/rustdoc-src-links/Makefile b/src/test/run-make/rustdoc-src-links/Makefile
new file mode 100644 (file)
index 0000000..419603e
--- /dev/null
@@ -0,0 +1,5 @@
+-include ../tools.mk
+all:
+       $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
+       $(HTMLDOCCK) $(TMPDIR)/doc foo.rs
+       $(HTMLDOCCK) $(TMPDIR)/doc qux/mod.rs
diff --git a/src/test/run-make/rustdoc-src-links/foo.rs b/src/test/run-make/rustdoc-src-links/foo.rs
new file mode 100644 (file)
index 0000000..9a964f1
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright 2015 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.
+
+#![crate_name = "foo"]
+
+//! Dox
+// @has src/foo/foo.rs.html
+// @has foo/index.html '//a/@href' '../src/foo/foo.rs.html'
+
+pub mod qux;
+
+// @has foo/bar/index.html '//a/@href' '../../src/foo/foo.rs.html'
+pub mod bar {
+
+    /// Dox
+    // @has foo/bar/baz/index.html '//a/@href' '../../../src/foo/foo.rs.html'
+    pub mod baz {
+        /// Dox
+        // @has foo/bar/baz/fn.baz.html '//a/@href' '../../../src/foo/foo.rs.html'
+        pub fn baz() { }
+    }
+
+    /// Dox
+    // @has foo/bar/trait.Foobar.html '//a/@href' '../../src/foo/foo.rs.html'
+    pub trait Foobar { fn dummy(&self) { } }
+
+    // @has foo/bar/struct.Foo.html '//a/@href' '../../src/foo/foo.rs.html'
+    pub struct Foo { x: i32, y: u32 }
+
+    // @has foo/bar/fn.prawns.html '//a/@href' '../../src/foo/foo.rs.html'
+    pub fn prawns((a, b): (i32, u32), Foo { x, y }: Foo) { }
+}
+
+/// Dox
+// @has foo/fn.modfn.html '//a/@href' '../src/foo/foo.rs.html'
+pub fn modfn() { }
diff --git a/src/test/run-make/rustdoc-src-links/qux/mod.rs b/src/test/run-make/rustdoc-src-links/qux/mod.rs
new file mode 100644 (file)
index 0000000..9b1563d
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2015 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.
+
+//! Dox
+// @has src/foo/qux/mod.rs.html
+// @has foo/qux/index.html '//a/@href' '../../src/foo/qux/mod.rs.html'
+
+// @has foo/qux/bar/index.html '//a/@href' '../../../src/foo/qux/mod.rs.html'
+pub mod bar {
+
+    /// Dox
+    // @has foo/qux/bar/baz/index.html '//a/@href' '../../../../src/foo/qux/mod.rs.html'
+    pub mod baz {
+        /// Dox
+        // @has foo/qux/bar/baz/fn.baz.html '//a/@href' '../../../../src/foo/qux/mod.rs.html'
+        pub fn baz() { }
+    }
+
+    /// Dox
+    // @has foo/qux/bar/trait.Foobar.html '//a/@href' '../../../src/foo/qux/mod.rs.html'
+    pub trait Foobar { fn dummy(&self) { } }
+
+    // @has foo/qux/bar/struct.Foo.html '//a/@href' '../../../src/foo/qux/mod.rs.html'
+    pub struct Foo { x: i32, y: u32 }
+
+    // @has foo/qux/bar/fn.prawns.html '//a/@href' '../../../src/foo/qux/mod.rs.html'
+    pub fn prawns((a, b): (i32, u32), Foo { x, y }: Foo) { }
+}
+
+/// Dox
+// @has foo/qux/fn.modfn.html '//a/@href' '../../src/foo/qux/mod.rs.html'
+pub fn modfn() { }
index 1316ee256e147d8e5eedbd72572910dc58b88e00..c1b1683efdb7fad32880ae69c03656b5510e2be7 100644 (file)
@@ -3,4 +3,3 @@
 all: foo.rs
        $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
        $(HTMLDOCCK) $(TMPDIR)/doc foo.rs
-
index 1316ee256e147d8e5eedbd72572910dc58b88e00..c1b1683efdb7fad32880ae69c03656b5510e2be7 100644 (file)
@@ -3,4 +3,3 @@
 all: foo.rs
        $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
        $(HTMLDOCCK) $(TMPDIR)/doc foo.rs
-
index 38381da3670c18be3fa9e126ccb3c08e0237f031..9d1ab00359dd955e28a36f7eb93f73c255b5aebf 100644 (file)
 
 #![ crate_name = "test" ]
 #![allow(unstable)]
-#![feature(box_syntax)]
+#![feature(box_syntax, old_io, rustc_private, core)]
 
 extern crate graphviz;
 // A simple rust project
 
-extern crate "flate" as myflate;
+extern crate flate as myflate;
 
 use std::collections::{HashMap,HashSet};
 use std::cell::RefCell;
@@ -39,23 +39,23 @@ static bob: Option<&'static [isize]> = None;
 // buglink test - see issue #1337.
 
 fn test_alias<I: Iterator>(i: Option<<I as Iterator>::Item>) {
-    let s = sub_struct{ field2: 45u32, };
+    let s = sub_struct{ field2: 45, };
 
     // import tests
     fn foo(x: &Float) {}
     let _: Option<u8> = from_i32(45);
 
-    let x = 42_usize;
+    let x = 42;
 
     myflate::deflate_bytes(&[]);
 
-    let x = (3, 4_usize);
+    let x = (3, 4);
     let y = x.1;
 }
 
-struct TupStruct(int, int, Box<str>);
+struct TupStruct(isize, isize, Box<str>);
 
-fn test_tup_struct(x: TupStruct) -> int {
+fn test_tup_struct(x: TupStruct) -> isize {
     x.1
 }
 
@@ -179,7 +179,7 @@ enum SomeEnum<'a> {
     MyTypes(MyType, MyType)
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum SomeOtherEnum {
     SomeConst1,
     SomeConst2,
@@ -245,9 +245,10 @@ fn hello<X: SomeTrait>((z, a) : (u32, String), ex: X) {
     let x = 32.0f32;
     let _ = (x + ((x * x) + 1.0).sqrt()).ln();
 
-    let s: Box<SomeTrait> = box some_fields {field1: 43};
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let s: Box<SomeTrait> = Box::new(some_fields {field1: 43});
     let s2: Box<some_fields> =  box some_fields {field1: 43};
-    let s3 = box nofields;
+    let s3: Box<_> = box nofields;
 
     s.Method(43);
     s3.Method(43);
@@ -282,7 +283,7 @@ pub struct blah {
 }
 
 fn main() { // foo
-    let s = box some_fields {field1: 43};
+    let s: Box<_> = box some_fields {field1: 43};
     hello((43, "a".to_string()), *s);
     sub::sub2::hello();
     sub2::sub3::hello();
index a7cd85db4a2d116cec2883a41b954428bf50e5fd..62bc3294286902d7b4de458fcbe2ccdaa7281fc4 100644 (file)
@@ -11,6 +11,6 @@
 #![crate_type = "rlib"]
 
 #[inline]
-pub fn cci_fn() -> uint {
+pub fn cci_fn() -> usize {
     1234
 }
index b0642b64cdaac8983e7287d3f9b6ecd465d5d495..e00cab20f6b34a16a290c40402f07f2be41b9d88 100644 (file)
@@ -9,21 +9,21 @@
 // except according to those terms.
 
 extern crate cci_lib;
-use cci_lib::{cci_fn};
+use cci_lib::cci_fn;
 
-fn call1() -> uint {
+fn call1() -> usize {
     cci_fn()
 }
 
 mod a {
     use cci_lib::cci_fn;
-    pub fn call2() -> uint {
+    pub fn call2() -> usize {
         cci_fn()
     }
 }
 
 mod b {
-    pub fn call3() -> uint {
+    pub fn call3() -> usize {
         0
     }
 }
index fe6a7b5a18f27c0115f4ebaa7d5c69fd21a0af97..bfa2162e27dd211eb05a9b779c83ae5b10889df6 100644 (file)
@@ -8,18 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn magic_fn() -> uint {
+fn magic_fn() -> usize {
     1234
 }
 
 mod a {
-    pub fn magic_fn() -> uint {
+    pub fn magic_fn() -> usize {
         2345
     }
 }
 
 mod b {
-    pub fn magic_fn() -> uint {
+    pub fn magic_fn() -> usize {
         3456
     }
 }
old mode 100755 (executable)
new mode 100644 (file)
index e1f36ecda53e83c5daaf73456b44b6c886688baa..8ba705bfb61115837f74dada2f483ab335896c5e 100644 (file)
@@ -12,9 +12,9 @@ pub static X: &'static str = "foobarbaz";
 pub static Y: &'static [u8] = include_bytes!("lib.rs");
 
 trait Foo { fn dummy(&self) { } }
-impl Foo for uint {}
+impl Foo for usize {}
 
 pub fn dummy() {
     // force the vtable to be created
-    let _x = &1_usize as &Foo;
+    let _x = &1us as &Foo;
 }
diff --git a/src/test/run-make/target-cpu-native/Makefile b/src/test/run-make/target-cpu-native/Makefile
new file mode 100644 (file)
index 0000000..0c9d93e
--- /dev/null
@@ -0,0 +1,5 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) foo.rs -C target-cpu=native
+       $(call RUN,foo)
diff --git a/src/test/run-make/target-cpu-native/foo.rs b/src/test/run-make/target-cpu-native/foo.rs
new file mode 100644 (file)
index 0000000..f7a9f96
--- /dev/null
@@ -0,0 +1,12 @@
+// 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.
+
+fn main() {
+}
index acda8705b19e30e22ad6b2cb662f9e74bb59d34c..b13c41be5597174a012a4fbeaecfc965cff22626 100644 (file)
@@ -22,7 +22,7 @@ trait Copy : PhantomFn<Self> { }
 trait Sized : PhantomFn<Self>  { }
 
 #[lang="start"]
-fn start(_main: *const u8, _argc: int, _argv: *const *const u8) -> int { 0 }
+fn start(_main: *const u8, _argc: isize, _argv: *const *const u8) -> isize { 0 }
 
 extern {
     fn _foo() -> [u8; 16];
index 23c422bc7a7fecc2221cc88d6e9a1de0dda7237c..7b604bedfd00bfe6e459b286ed4a5a626553c751 100644 (file)
@@ -83,4 +83,3 @@ REMOVE_RLIBS      = rm $(TMPDIR)/$(call RLIB_GLOB,$(1))
 
 $(TMPDIR)/lib%.o: %.c
        $(CC) -c -o $@ $<
-
index ce3e69918ffee927e8c77037456fcc472e6b420c..aa2ce785771211f3875fa326644030f1b0c0842e 100644 (file)
@@ -8,9 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::{char, env};
-use std::old_io::{File, Command};
+#![feature(rand)]
+
+use std::fs::File;
+use std::io::prelude::*;
+use std::path::Path;
+use std::process::Command;
 use std::rand::{thread_rng, Rng};
+use std::{char, env};
 
 // creates unicode_input_multiple_files_{main,chars}.rs, where the
 // former imports the latter. `_chars` just contains an identifier
@@ -40,7 +45,7 @@ fn main() {
     let main_file = tmpdir.join("unicode_input_multiple_files_main.rs");
     {
         let _ = File::create(&main_file).unwrap()
-            .write_str("mod unicode_input_multiple_files_chars;");
+            .write_all(b"mod unicode_input_multiple_files_chars;").unwrap();
     }
 
     for _ in 0..100 {
@@ -48,7 +53,7 @@ fn main() {
             let randoms = tmpdir.join("unicode_input_multiple_files_chars.rs");
             let mut w = File::create(&randoms).unwrap();
             for _ in 0..30 {
-                let _ = w.write_char(random_char());
+                write!(&mut w, "{}", random_char()).unwrap();
             }
         }
 
@@ -58,10 +63,9 @@ fn main() {
                              .arg("-c")
                              .arg(&format!("{} {}",
                                            rustc,
-                                           main_file.as_str()
-                                                    .unwrap()))
+                                           main_file.display()))
                              .output().unwrap();
-        let err = String::from_utf8_lossy(&result.error);
+        let err = String::from_utf8_lossy(&result.stderr);
 
         // positive test so that this test will be updated when the
         // compiler changes.
index ef6c799336bd4e5171878fe7ccf1b9339c32fded..a70a160076520aca44acdf60aa98baea8d2542dc 100644 (file)
@@ -8,8 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::old_io::{File, Command};
+#![feature(rand, core)]
+
+use std::fs::File;
+use std::io::prelude::*;
 use std::iter::repeat;
+use std::path::Path;
+use std::process::Command;
 use std::rand::{thread_rng, Rng};
 use std::{char, env};
 
@@ -54,11 +59,11 @@ fn main() {
                              .arg("-c")
                              .arg(&format!("{} {}",
                                            rustc,
-                                           main_file.as_str()
+                                           main_file.to_str()
                                                     .unwrap()))
                              .output().unwrap();
 
-        let err = String::from_utf8_lossy(&result.error);
+        let err = String::from_utf8_lossy(&result.stderr);
 
         // the span should end the line (e.g no extra ~'s)
         let expected_span = format!("^{}\n", repeat("~").take(n - 1)
@@ -73,17 +78,16 @@ fn main() {
     }
 
     // Extra characters. Every line is preceded by `filename:lineno <actual code>`
-    let offset = main_file.as_str().unwrap().len() + 3;
+    let offset = main_file.to_str().unwrap().len() + 3;
 
     let result = Command::new("sh")
                          .arg("-c")
                          .arg(format!("{} {}",
                                       rustc,
-                                      main_file.as_str()
-                                               .unwrap()).as_slice())
+                                      main_file.display()))
                          .output().unwrap();
 
-    let err = String::from_utf8_lossy(result.error.as_slice());
+    let err = String::from_utf8_lossy(&result.stderr);
 
     // Test both the length of the snake and the leading spaces up to it
 
@@ -91,10 +95,10 @@ fn main() {
     let expected_span = format!("\n{}^{}\n",
                                 repeat(" ").take(offset + 7).collect::<String>(),
                                 repeat("~").take(8).collect::<String>());
-    assert!(err.contains(expected_span.as_slice()));
+    assert!(err.contains(&expected_span));
     // Second snake is 8 ~s long, with 36 preceding spaces
     let expected_span = format!("\n{}^{}\n",
                                 repeat(" ").take(offset + 36).collect::<String>(),
                                 repeat("~").take(8).collect::<String>());
-    assert!(err.contains(expected_span.as_slice()));
+    assert!(err.contains(&expected_span));
 }
index 6dffb53e4a319754c20e37b14992f6f887284cac..217dee4b881c7a92ac13ea61cc97c9c26b6d8908 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(core)]
+
 use std::intrinsics::{volatile_load, volatile_store};
 
 pub fn main() {
     unsafe {
-        let mut i : int = 1;
+        let mut i : isize = 1;
         volatile_store(&mut i, 2);
         assert_eq!(volatile_load(&i), 2);
     }
index 5d6e629ffc1d1627dccc0be3042322042e096d0f..8b69c68279dca0a1f36a95e88562041036395ea0 100644 (file)
@@ -10,3 +10,6 @@ all:
        cp foo.rs $(TMPDIR)/+foo+bar
        $(RUSTC) $(TMPDIR)/+foo+bar 2>&1 \
                | grep "invalid character.*in crate name:"
+       cp foo.rs $(TMPDIR)/-foo.rs
+       $(RUSTC) $(TMPDIR)/-foo.rs 2>&1 \
+               | grep 'crate names cannot start with a `-`'
index 9e164522d77a60db51fd8c6e693eecb7587b36a2..4bacde0aadf3fc67fed7a79fbef5e90361342828 100644 (file)
@@ -12,7 +12,7 @@
 
 // ignore-android
 
-#![feature(rustc_private)]
+#![feature(rustc_private, path)]
 #![feature(core)]
 
 extern crate getopts;
@@ -25,6 +25,7 @@ use rustc::session::config::{self, Input};
 use rustc_driver::{driver, CompilerCalls, Compilation};
 use syntax::diagnostics;
 
+use std::path::PathBuf;
 
 struct TestCalls {
     count: u32
@@ -43,14 +44,15 @@ impl<'a> CompilerCalls<'a> for TestCalls {
                      _: &getopts::Matches,
                      _: &Session,
                      _: &Input,
-                     _: &Option<Path>,
-                     _: &Option<Path>)
+                     _: &Option<PathBuf>,
+                     _: &Option<PathBuf>)
                      -> Compilation {
         self.count *= 3;
         Compilation::Stop
     }
 
-    fn some_input(&mut self, input: Input, input_path: Option<Path>) -> (Input, Option<Path>) {
+    fn some_input(&mut self, input: Input, input_path: Option<PathBuf>)
+                  -> (Input, Option<PathBuf>) {
         self.count *= 5;
         (input, input_path)
     }
@@ -58,10 +60,10 @@ impl<'a> CompilerCalls<'a> for TestCalls {
     fn no_input(&mut self,
                 _: &getopts::Matches,
                 _: &config::Options,
-                _: &Option<Path>,
-                _: &Option<Path>,
+                _: &Option<PathBuf>,
+                _: &Option<PathBuf>,
                 _: &diagnostics::registry::Registry)
-                -> Option<(Input, Option<Path>)> {
+                -> Option<(Input, Option<PathBuf>)> {
         panic!("This shouldn't happen");
     }
 
@@ -75,7 +77,6 @@ fn main() {
     let mut tc = TestCalls { count: 1 };
     // we should never get use this filename, but lets make sure they are valid args.
     let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()];
-    rustc_driver::run_compiler(args.as_slice(), &mut tc);
+    rustc_driver::run_compiler(&args, &mut tc);
     assert!(tc.count == 30);
 }
-
diff --git a/src/test/run-pass-fulldeps/create-dir-all-bare.rs b/src/test/run-pass-fulldeps/create-dir-all-bare.rs
new file mode 100644 (file)
index 0000000..e4fb7c1
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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.
+
+// ignore-android
+
+#![feature(rustc_private)]
+
+extern crate rustc_back;
+
+use std::env;
+use std::fs;
+use rustc_back::tempdir::TempDir;
+
+fn main() {
+    let td = TempDir::new("create-dir-all-bare").unwrap();
+    env::set_current_dir(td.path()).unwrap();
+    fs::create_dir_all("create-dir-all-bare").unwrap();
+}
diff --git a/src/test/run-pass-fulldeps/derive-totalsum.rs b/src/test/run-pass-fulldeps/derive-totalsum.rs
new file mode 100644 (file)
index 0000000..848b242
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright 2015 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.
+
+// aux-build:custom_derive_plugin.rs
+// ignore-stage1
+
+#![feature(plugin, custom_derive)]
+#![plugin(custom_derive_plugin)]
+
+trait TotalSum {
+    fn total_sum(&self) -> isize;
+}
+
+impl TotalSum for isize {
+    fn total_sum(&self) -> isize {
+        *self
+    }
+}
+
+struct Seven;
+
+impl TotalSum for Seven {
+    fn total_sum(&self) -> isize {
+        7
+    }
+}
+
+#[derive(TotalSum)]
+struct Foo {
+    seven: Seven,
+    bar: Bar,
+    baz: isize,
+}
+
+#[derive(TotalSum)]
+struct Bar {
+    quux: isize,
+    bleh: isize,
+}
+
+
+pub fn main() {
+    let v = Foo {
+        seven: Seven,
+        bar: Bar {
+            quux: 9,
+            bleh: 3,
+        },
+        baz: 80,
+    };
+    assert_eq!(v.total_sum(), 99);
+}
index cd79a95dace7afcef69ac94f66e180f2218617d6..1541e809b6178d24a77c953d764e784c1dfcf023 100644 (file)
@@ -16,7 +16,7 @@
 // Regression test for issue #13560, the test itself is all in the dependent
 // libraries. The fail which previously failed to compile is the one numbered 3.
 
-extern crate "issue-13560-2" as t2;
-extern crate "issue-13560-3" as t3;
+extern crate issue_13560_2 as t2;
+extern crate issue_13560_3 as t3;
 
 fn main() {}
diff --git a/src/test/run-pass-fulldeps/issue-15778-pass.rs b/src/test/run-pass-fulldeps/issue-15778-pass.rs
new file mode 100644 (file)
index 0000000..a767779
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// aux-build:lint_for_crate.rs
+// ignore-stage1
+// compile-flags: -D crate-not-okay
+
+#![feature(plugin, custom_attribute)]
+#![plugin(lint_for_crate)]
+#![crate_okay]
+
+pub fn main() { }
index 6306627df0f8d05c27d82c5e87ec321c90e57bdc..172d3e31d45e8c73a4e3e80b5042357f61c26135 100644 (file)
 
 // aux-build:issue-16822.rs
 
-extern crate "issue-16822" as lib;
+extern crate issue_16822 as lib;
 
 use std::cell::RefCell;
 
 struct App {
-    i: int
+    i: isize
 }
 
 impl lib::Update for App {
index 9e3ad8ee283e8c6db318219d9ed1502b2eeca816..40947b2e25652fd3e494fe91309a0110bfdfb1c6 100644 (file)
@@ -11,7 +11,7 @@
 // ignore-pretty
 // ignore-android
 
-#![feature(quote)]
+#![feature(quote, rustc_private)]
 
 extern crate syntax;
 
index 91b24b3b2abac4dc39736842bd4a287d9aa840c3..8367fc110e137c734ddaa5ada7d75fe59614d719 100644 (file)
@@ -10,7 +10,7 @@
 
 // aux-build:issue-18502.rs
 
-extern crate "issue-18502" as fmt;
+extern crate issue_18502 as fmt;
 
 fn main() {
     ::fmt::baz();
index aeb6a89a98ea6e2c50030096399f7546c5b1ffec..e1ef32b64d7152c4f8baecfd545cb393ae46a94f 100644 (file)
@@ -11,7 +11,7 @@
 // ignore-android
 // ignore-pretty: does not work well with `--test`
 
-#![feature(quote)]
+#![feature(quote, rustc_private)]
 
 extern crate syntax;
 
@@ -20,11 +20,11 @@ use syntax::ext::base::ExtCtxt;
 fn syntax_extension(cx: &ExtCtxt) {
     let _toks_1 = vec![quote_tokens!(cx, /** comment */ fn foo() {})];
     let name = quote_tokens!(cx, bar);
-    let _toks_2 = vec![quote_item!(cx, static $name:int = 2;)];
+    let _toks_2 = vec![quote_item!(cx, static $name:isize = 2;)];
     let _toks_4 = quote_tokens!(cx, $name:static $name:sizeof);
     let _toks_3 = vec![quote_item!(cx,
         /// comment
-        fn foo() { let $name:int = 3; }
+        fn foo() { let $name:isize = 3; }
     )];
 }
 
index 58ccd79b7121dbe9afe8201db76283556de8a170..7a2846c31b66331815ce76613619a2a83386a51a 100644 (file)
@@ -11,7 +11,7 @@
 // aux-build:macro_crate_test.rs
 // ignore-stage1
 
-#![feature(plugin)]
+#![feature(plugin, custom_attribute)]
 #![plugin(macro_crate_test)]
 
 #[macro_use] #[no_link]
diff --git a/src/test/run-pass-fulldeps/mbe_matching_test_macro.rs b/src/test/run-pass-fulldeps/mbe_matching_test_macro.rs
new file mode 100644 (file)
index 0000000..5383b11
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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.
+
+// aux-build:procedural_mbe_matching.rs
+// ignore-stage1
+
+#![feature(plugin)]
+#![plugin(procedural_mbe_matching)]
+
+#[no_link]
+extern crate procedural_mbe_matching;
+
+pub fn main() {
+    let abc = 123u32;
+    assert_eq!(matches!(Some(123), None | Some(0)), false);
+    assert_eq!(matches!(Some(123), None | Some(123)), true);
+    assert_eq!(matches!(true, true), true);
+}
index 252d297d12d3053d44f3be816057c9d146d0e928..7e11b9d9f278956289aca857a8ba66e4e0a7adbb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -60,11 +60,11 @@ fn main() {
     check_pp(ext_cx, abc,  pprust::print_expr, "23".to_string());
 
 
-    let ty = quote_ty!(cx, int);
-    check_pp(ext_cx, ty, pprust::print_type, "int".to_string());
+    let ty = quote_ty!(cx, isize);
+    check_pp(ext_cx, ty, pprust::print_type, "isize".to_string());
 
-    let item = quote_item!(cx, static x : int = 10;).get();
-    check_pp(ext_cx, item, pprust::print_item, "static x: int = 10;".to_string());
+    let item = quote_item!(cx, static x : isize = 10;).get();
+    check_pp(ext_cx, item, pprust::print_item, "static x: isize = 10;".to_string());
 
     let stmt = quote_stmt!(cx, let x = 20;);
     check_pp(ext_cx, *stmt, pprust::print_stmt, "let x = 20;".to_string());
@@ -74,6 +74,9 @@ fn main() {
 
     let arm = quote_arm!(cx, (ref x, ref y) => (x, y));
     check_pp(ext_cx, arm, pprust::print_stmt, "(ref x, ref y) = (x, y)".to_string());
+
+    let attr = quote_attr!(cx, #![cfg(foo = "bar")]);
+    check_pp(ext_cx, attr, pprust::print_attribute, "#![cfg(foo = "bar")]".to_string());
 }
 
 fn check_pp<T>(cx: fake_ext_ctxt,
index e76c379177b9962dec61dfa1028c2ebe95d4180f..f6ae71f8b6f31533b40225112bcd3864f27fedfa 100644 (file)
@@ -11,7 +11,7 @@
 // ignore-android
 // ignore-pretty: does not work well with `--test`
 
-#![feature(quote)]
+#![feature(quote, rustc_private)]
 
 extern crate syntax;
 
@@ -23,9 +23,9 @@ fn syntax_extension(cx: &ExtCtxt) {
     let p_toks : Vec<syntax::ast::TokenTree> = quote_tokens!(cx, (x, 1 .. 4, *));
 
     let a: P<syntax::ast::Expr> = quote_expr!(cx, 1 + 2);
-    let _b: Option<P<syntax::ast::Item>> = quote_item!(cx, static foo : int = $e_toks; );
+    let _b: Option<P<syntax::ast::Item>> = quote_item!(cx, static foo : isize = $e_toks; );
     let _c: P<syntax::ast::Pat> = quote_pat!(cx, (x, 1 .. 4, *) );
-    let _d: P<syntax::ast::Stmt> = quote_stmt!(cx, let x = $a; );
+    let _d: Option<P<syntax::ast::Stmt>> = quote_stmt!(cx, let x = $a; );
     let _d: syntax::ast::Arm = quote_arm!(cx, (ref x, ref y) = (x, y) );
     let _e: P<syntax::ast::Expr> = quote_expr!(cx, match foo { $p_toks => 10 } );
 
@@ -36,10 +36,12 @@ fn syntax_extension(cx: &ExtCtxt) {
     let i: Option<P<syntax::ast::Item>> = quote_item!(cx, #[derive(Eq)] struct Foo; );
     assert!(i.is_some());
 
-    let _j: P<syntax::ast::Method> = quote_method!(cx, fn foo(&self) {});
-    let _k: P<syntax::ast::Method> = quote_method!(cx, #[doc = "hello"] fn foo(&self) {});
+    let _l: P<syntax::ast::Ty> = quote_ty!(cx, &isize);
 
-    let _l: P<syntax::ast::Ty> = quote_ty!(cx, &int);
+    let _m: Vec<syntax::ast::TokenTree> = quote_matcher!(cx, $($foo:tt,)* bar);
+    let _n: syntax::ast::Attribute = quote_attr!(cx, #![cfg(foo, bar = "baz")]);
+
+    let _o: Option<P<syntax::ast::Item>> = quote_item!(cx, fn foo<T: ?Sized>() {});
 }
 
 fn main() {
index 848ea738ed7d54c7a3d78e8f591e9c25c16ad714..928368fabdf3684dde673bca6478dce74e612d05 100644 (file)
@@ -11,7 +11,7 @@
 // ignore-android
 // ignore-pretty: does not work well with `--test`
 
-#![feature(quote)]
+#![feature(quote, rustc_private)]
 #![deny(unused_variable)]
 
 extern crate syntax;
diff --git a/src/test/run-pass-fulldeps/rename-directory.rs b/src/test/run-pass-fulldeps/rename-directory.rs
new file mode 100644 (file)
index 0000000..a1e016b
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2013-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.
+
+// This test can't be a unit test in std,
+// because it needs TempDir, which is in extra
+
+// ignore-android
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_private, path_ext)]
+
+extern crate rustc_back;
+
+use std::ffi::CString;
+use std::fs::{self, File, PathExt};
+use rustc_back::tempdir::TempDir;
+
+fn rename_directory() {
+    let tmpdir = TempDir::new("rename_directory").ok().expect("rename_directory failed");
+    let tmpdir = tmpdir.path();
+    let old_path = tmpdir.join("foo/bar/baz");
+    fs::create_dir_all(&old_path).unwrap();
+    let test_file = &old_path.join("temp.txt");
+
+    File::create(test_file).unwrap();
+
+    let new_path = tmpdir.join("quux/blat");
+    fs::create_dir_all(&new_path).unwrap();
+    fs::rename(&old_path, &new_path.join("newdir"));
+    assert!(new_path.join("newdir").is_dir());
+    assert!(new_path.join("newdir/temp.txt").exists());
+}
+
+pub fn main() { rename_directory() }
index b7570eb09261286a84f9830a5fe7066bf1464639..23096828c4b95be06ab2da1b25bff3b4aaa89624 100644 (file)
@@ -12,7 +12,7 @@
 // aux-build:syntax_extension_with_dll_deps_2.rs
 // ignore-stage1
 
-#![feature(plugin)]
+#![feature(plugin, rustc_private)]
 #![plugin(syntax_extension_with_dll_deps_2)]
 
 fn main() {
index aecec44f6fd3df0e4cd6cbdec45dbbd5dcff17b9..0bbb9ed128592d3e3a9cea3ca427bf809b799129 100644 (file)
@@ -36,4 +36,3 @@ pub fn main() {
         assert!(DROP_RAN);
     }
 }
-
index c16f1f4c842ac1d1afacc0205d28635c7b224d9a..301c4b917816a8e1c8dec09a0a4a914a7eb5d623 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(old_io, io)]
+
 fn main() {
     let _ = std::old_io::stdin();
+    let _ = std::io::stdin();
 }
index c49a684de945df046b3015e2cd5b0a35488b865e..d051b7b491b946d775b677ca982c4e7fba40dc1a 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
-
 static mut DROP_RAN: bool = false;
 
 struct Foo;
@@ -28,7 +26,8 @@ struct Fat<T: ?Sized> {
 
 pub fn main() {
     {
-        let _x: Box<Fat<Trait>> = box Fat { f: Foo };
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        let _x: Box<Fat<Trait>> = Box::<Fat<Foo>>::new(Fat { f: Foo });
     }
     unsafe {
         assert!(DROP_RAN);
index 2c7b89d680a3d92275c096f97dd55f35eb6de962..59b593b1ab3f604d0d0ca08fd36fabd6de7ce21b 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
-
-static mut DROP_RAN: int = 0;
+static mut DROP_RAN: isize = 0;
 
 struct Foo;
 impl Drop for Foo {
@@ -25,7 +23,8 @@ struct Fat<T: ?Sized> {
 
 pub fn main() {
     {
-        let _x: Box<Fat<[Foo]>> = box Fat { f: [Foo, Foo, Foo] };
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        let _x: Box<Fat<[Foo]>> = Box::<Fat<[Foo; 3]>>::new(Fat { f: [Foo, Foo, Foo] });
     }
     unsafe {
         assert!(DROP_RAN == 3);
index b1bebf0b3e60648b3a051be51a4c535589a53dcb..77b9efb0012f067e199362325da3575ceeeefbaf 100644 (file)
 
 // Regression test for issue #374
 
+// pretty-expanded FIXME #23616
+
 enum sty { ty_nil, }
 
-struct RawT {struct_: sty, cname: Option<String>, hash: uint}
+struct RawT {struct_: sty, cname: Option<String>, hash: usize}
 
 fn mk_raw_ty(st: sty, cname: Option<String>) -> RawT {
-    return RawT {struct_: st, cname: cname, hash: 0_usize};
+    return RawT {struct_: st, cname: cname, hash: 0};
 }
 
 pub fn main() { mk_raw_ty(sty::ty_nil, None::<String>); }
index c356d1d527e5e4e3bd453696f24988273a2b5a71..23a1e7998012c9394892667edffb5e6b9c4a38d6 100644 (file)
@@ -9,10 +9,12 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 enum option<T> { some(T), none, }
 
 struct R<T> {v: Vec<option<T>> }
 
 fn f<T>() -> Vec<T> { return Vec::new(); }
 
-pub fn main() { let mut r: R<int> = R {v: Vec::new()}; r.v = f(); }
+pub fn main() { let mut r: R<isize> = R {v: Vec::new()}; r.v = f(); }
index 0ef666031114eacaae619625919022eb65fdaf95..b40774e2be82fcff268e35176eb9426b36907fa0 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // aux-build:anon-extern-mod-cross-crate-1.rs
+// pretty-expanded FIXME #23616
+
 extern crate anonexternmod;
 
 use anonexternmod::rust_get_test_int;
index 78e1cdabb47486c683a9e43704e473a1f9fde484..e96b0cc1442c64ee33556d1bf1baeca09c3f4cbd 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 extern crate libc;
 
 #[link(name = "rust_test_helpers")]
index 98975c7f021c3ffaefdfc31d1b364dd20136090b..5889bfce3c4783e72f0e9c09a00e77f8bc1caa5b 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct Foo {
-    x: int
+    x: isize
 }
 
 impl Foo {
index dfce311529028c49d02e0ff9a62afe770e50e9ea..7101cfb55796714a85405eccdf67b5c90aeffebd 100644 (file)
@@ -9,18 +9,20 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 struct X {
-    x: int
+    x: isize
 }
 
-fn f1(a: &mut X, b: &mut int, c: int) -> int {
+fn f1(a: &mut X, b: &mut isize, c: isize) -> isize {
     let r = a.x + *b + c;
     a.x = 0;
     *b = 10;
     return r;
 }
 
-fn f2<F>(a: int, f: F) -> int where F: FnOnce(int) { f(1); return a; }
+fn f2<F>(a: isize, f: F) -> isize where F: FnOnce(isize) { f(1); return a; }
 
 pub fn main() {
     let mut a = X {x: 1};
index 24c63e5affc0dc36bcffd4398162900ac6d56792..a4365efbbbd0ebd3ea9409f8524379cebbe49f30 100644 (file)
@@ -11,7 +11,7 @@
 
 
 pub fn main() {
-    let a: int = 10;
+    let a: isize = 10;
     println!("{}", a);
     assert_eq!(a * (a - 1), 90);
 }
index 1e043d77fa811cea1c02646b926560293e920e99..fd281ea1173cfb9530f354cd70f72143eef3e43d 100644 (file)
@@ -11,7 +11,7 @@
 
 
 pub fn main() {
-    let i32_a: int = 10;
+    let i32_a: isize = 10;
     assert_eq!(i32_a, 10);
     assert_eq!(i32_a - 10, 0);
     assert_eq!(i32_a / 10, 1);
@@ -22,8 +22,8 @@ pub fn main() {
     assert_eq!(i32_a * i32_a * i32_a, 1000);
     assert_eq!(i32_a * i32_a * i32_a * i32_a, 10000);
     assert_eq!(i32_a * i32_a / i32_a * i32_a, 100);
-    assert_eq!(i32_a * (i32_a - 1) << (2 + i32_a as uint), 368640);
-    let i32_b: int = 0x10101010;
+    assert_eq!(i32_a * (i32_a - 1) << (2 + i32_a as usize), 368640);
+    let i32_b: isize = 0x10101010;
     assert_eq!(i32_b + 1 - 1, i32_b);
     assert_eq!(i32_b << 1, i32_b << 1);
     assert_eq!(i32_b >> 1, i32_b >> 1);
index 70df6e46e59d7c4c115214193bdaf126cb12cd55..0f4523c6818849e5c40fb2dcf186e00fa872de30 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let i32_c: int = 0x10101010;
+    let i32_c: isize = 0x10101010;
     assert!(i32_c + i32_c * 2 / 3 * 2 + (i32_c - 7 % 3) ==
                  i32_c + i32_c * 2 / 3 * 2 + (i32_c - 7 % 3));
 }
index 43288d9044ec5c7b0a5513544441048ed3873bf7..8a0fc8adc189574d323684769e197ac2647b9dab 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(type_limits)]
 
 // Unsigned integer operations
index 7bc1354c3cefe9ee817e8e401dc47c2e6cffd94a..3348a6754ee82886e24126e47e6ae2803c6c77d5 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f() -> int { { return 3; } }
+// pretty-expanded FIXME #23616
+
+fn f() -> isize { { return 3; } }
 
 pub fn main() { assert!((f() == 3)); }
index 0760f13200c8fcd813d6822da432249fc61c9735..8e38128975bb954e5601a5a15d8d3a914d468092 100644 (file)
@@ -8,11 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
-    assert_eq!(3 as uint * 3, 9);
-    assert_eq!(3 as (uint) * 3, 9);
-    assert_eq!(3 as (uint) / 3, 1);
-    assert_eq!(3 as uint + 3, 6);
-    assert_eq!(3 as (uint) + 3, 6);
+    assert_eq!(3 as usize * 3, 9);
+    assert_eq!(3 as (usize) * 3, 9);
+    assert_eq!(3 as (usize) / 3, 1);
+    assert_eq!(3 as usize + 3, 6);
+    assert_eq!(3 as (usize) + 3, 6);
 }
-
index 9df96b35ce1b40bbfb2f923d9a4b8b3dbcdc6a47..716c3d47a0365a2fb8410be081464a8fe3413dbf 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(asm)]
 
 pub fn main() {
index 3ac8e4d0ee9ca846ad4b4388aa734fec1148de39..32924bcf74451d718f6ddfe7f76e6dc0dc816529 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(asm)]
 
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
@@ -34,8 +36,8 @@ pub fn main() {
         assert_eq!(2147483648, next_power_of_2(2147483647));
     }
 
-    let mut y: int = 5;
-    let x: int;
+    let mut y: isize = 5;
+    let x: isize;
     unsafe {
         // Treat the output as initialization.
         asm!(
index 0f6fec133d1ce1985aaaac5159eb9eecd7c7979f..3cb7f6400daf468297b3336b9cd1387bf300e474 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(asm)]
 
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn main() {
-    let x: int;
+    let x: isize;
     unsafe {
         // Treat the output as initialization.
         asm!("mov $1, $0" : "=r"(x) : "r"(5_usize));
index e55a2d39cbf889af375405d39a020049a64eddfa..9662e1ff33d11238c4a3f6fde6ab312889a278c3 100644 (file)
@@ -8,15 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
 #[derive(PartialEq, Debug)]
-struct Point { x : int }
+struct Point { x : isize }
 
 pub fn main() {
     assert_eq!(14,14);
     assert_eq!("abc".to_string(),"abc".to_string());
-    assert_eq!(box Point{x:34},box Point{x:34});
+    assert_eq!(Box::new(Point{x:34}),Box::new(Point{x:34}));
     assert_eq!(&Point{x:34},&Point{x:34});
 }
index 0f5d27015fb747a7709a6b3b908eeccf5a11eecb..110f4720ceb6841a1854d639c5eedd413cd8f7b2 100644 (file)
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 // Issue 483 - Assignment expressions result in nil
+// pretty-expanded FIXME #23616
+
 fn test_assign() {
-    let mut x: int;
+    let mut x: isize;
     let y: () = x = 10;
     assert_eq!(x, 10);
     assert_eq!(y, ());
@@ -23,7 +25,7 @@ fn test_assign() {
 }
 
 fn test_assign_op() {
-    let mut x: int = 0;
+    let mut x: isize = 0;
     let y: () = x += 10;
     assert_eq!(x, 10);
     assert_eq!(y, ());
index 57c50511604ca3f095418cac0f56ca53e264191a..473f744a3ff61a56bc310256abbe27814ae1f07c 100644 (file)
@@ -12,6 +12,8 @@
 // making method calls, but only if there aren't any matches without
 // it.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 trait iterable<A> {
@@ -30,7 +32,7 @@ impl<A> iterable<A> for Vec<A> {
     }
 }
 
-fn length<A, T: iterable<A>>(x: T) -> uint {
+fn length<A, T: iterable<A>>(x: T) -> usize {
     let mut len = 0;
     x.iterate(|_y| {
         len += 1;
@@ -40,17 +42,17 @@ fn length<A, T: iterable<A>>(x: T) -> uint {
 }
 
 pub fn main() {
-    let x: Vec<int> = vec!(0,1,2,3);
+    let x: Vec<isize> = vec!(0,1,2,3);
     // Call a method
-    x.iterate(|y| { assert!(x[*y as uint] == *y); true });
+    x.iterate(|y| { assert!(x[*y as usize] == *y); true });
     // Call a parameterized function
     assert_eq!(length(x.clone()), x.len());
     // Call a parameterized function, with type arguments that require
     // a borrow
-    assert_eq!(length::<int, &[int]>(&*x), x.len());
+    assert_eq!(length::<isize, &[isize]>(&*x), x.len());
 
     // Now try it with a type that *needs* to be borrowed
     let z = [0,1,2,3];
     // Call a parameterized function
-    assert_eq!(length::<int, &[int]>(&z), z.len());
+    assert_eq!(length::<isize, &[isize]>(&z), z.len());
 }
index f5521f7da853bd025b017cac1cf7a3a4d8c463fd..d4ed2ee2d6e55835b78bd611c669e11481afb052 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::marker::MarkerTrait;
 
 trait Foo : MarkerTrait {
@@ -15,11 +19,11 @@ trait Foo : MarkerTrait {
 }
 
 impl Foo for i32 {
-    type T = int;
+    type T = isize;
 }
 
 fn main() {
     let x: <i32 as Foo>::T = 22;
-    let y: int = 44;
+    let y: isize = 44;
     assert_eq!(x * 2, y);
 }
index b47b0109bdf39220700753aed82820fb24a025e0..39fc224148e8ed7d8f3403c1e0d044ba4018ca35 100644 (file)
@@ -11,6 +11,8 @@
 // Test a case where the associated type binding (to `bool`, in this
 // case) is derived from the trait definition. Issue #21636.
 
+// pretty-expanded FIXME #23616
+
 use std::vec;
 
 pub trait BitIter {
index 2f9a0b328b5d492146d76adb077dd3e8585d97db..82ebac7e5dc7e0e8d78199431be713f14ce0a2b0 100644 (file)
 
 // Test equality constraints on associated types in a where clause.
 
+// pretty-expanded FIXME #23616
+
 pub trait Foo {
     type A;
     fn boo(&self) -> <Self as Foo>::A;
 }
 
 #[derive(PartialEq)]
-struct Bar;
+pub struct Bar;
 
-impl Foo for int {
-    type A = uint;
-    fn boo(&self) -> uint { 42 }
+impl Foo for isize {
+    type A = usize;
+    fn boo(&self) -> usize { 42 }
 }
 
 impl Foo for char {
@@ -32,7 +34,7 @@ fn foo_bar<I: Foo<A=Bar>>(x: I) -> Bar {
     x.boo()
 }
 
-fn foo_uint<I: Foo<A=uint>>(x: I) -> uint {
+fn foo_uint<I: Foo<A=usize>>(x: I) -> usize {
     x.boo()
 }
 
index 9f97d69ce3f9b6b1b6a5b519ad977eb4f584b6ee..2301821f66358fe58a488d5e6c9284b8034533ad 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test equality constrai32s on associated types in a where clause.
 
+// pretty-expanded FIXME #23616
+
 pub trait ToI32 {
     fn to_i32(&self) -> i32;
 }
index 948192f4fc0754180bbe8215a3d2098041af29c0..b2be87be4cb35397bf57e14443af8120f70537c4 100644 (file)
@@ -13,7 +13,7 @@
 // Test that we are able to reference cross-crate traits that employ
 // associated types.
 
-extern crate "associated-types-cc-lib" as bar;
+extern crate associated_types_cc_lib as bar;
 
 use bar::Bar;
 
index aa65b0ed10bafe93e5521d26a074cbf801a9f25d..1a8da6755588be0e41cb3f3f5e4551293dbce350 100644 (file)
@@ -14,6 +14,8 @@
 // `Target=[A]`, then the impl marked with `(*)` is seen to conflict
 // with all the others.
 
+// pretty-expanded FIXME #23616
+
 use std::marker::PhantomData;
 use std::ops::Deref;
 
index 57e9230336c1e082a0b203cca2ec36801f9f1bff..5729fab475b7868c0d0949ace21b4a63184f87c0 100644 (file)
@@ -8,32 +8,34 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait SignedUnsigned {
     type Opposite;
     fn convert(self) -> Self::Opposite;
 }
 
-impl SignedUnsigned for int {
-    type Opposite = uint;
+impl SignedUnsigned for isize {
+    type Opposite = usize;
 
-    fn convert(self) -> uint {
-        self as uint
+    fn convert(self) -> usize {
+        self as usize
     }
 }
 
-impl SignedUnsigned for uint {
-    type Opposite = int;
+impl SignedUnsigned for usize {
+    type Opposite = isize;
 
-    fn convert(self) -> int {
-        self as int
+    fn convert(self) -> isize {
+        self as isize
     }
 }
 
-fn get(x: int) -> <int as SignedUnsigned>::Opposite {
+fn get(x: isize) -> <isize as SignedUnsigned>::Opposite {
     x.convert()
 }
 
 fn main() {
     let x = get(22);
-    assert_eq!(22_usize, x);
+    assert_eq!(22, x);
 }
index 7365e052171eff975809517f89c5a5a7b8d056ce..5dc289194ff3b8d64bcfa9489cf1b603b8d8bfc7 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn pairwise_sub(mut t: Box<DoubleEndedIterator<Item=int>>) -> int {
+fn pairwise_sub(mut t: Box<DoubleEndedIterator<Item=isize>>) -> isize {
     let mut result = 0;
     loop {
         let front = t.next();
@@ -25,6 +27,7 @@ fn pairwise_sub(mut t: Box<DoubleEndedIterator<Item=int>>) -> int {
 
 fn main() {
     let v = vec!(1, 2, 3, 4, 5, 6);
-    let r = pairwise_sub(box v.into_iter());
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let r = pairwise_sub(Box::new(v.into_iter()));
     assert_eq!(r, 9);
 }
index 8b7ea61dc77e9cec9d560c2ea9f88485bf955a91..8ca3bc02548346864635ee80deac399b3ce64ef3 100644 (file)
@@ -12,6 +12,8 @@
 // (modulo bound lifetime names) appears in the environment
 // twice. Issue #21965.
 
+// pretty-expanded FIXME #23616
+
 fn foo<T>(t: T) -> i32
     where T : for<'a> Fn(&'a u8) -> i32,
           T : for<'b> Fn(&'b u8) -> i32,
index 62ac21879520bf324e29fa056a0a6cb4e144672d..5878f5dd51b2a213ae5d497d572f8507965c6941 100644 (file)
@@ -11,6 +11,8 @@
 // Check that we do not report ambiguities when the same predicate
 // appears in the environment twice. Issue #21965.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
     type B;
 
index a499aa6733aae0783532874e7292b1c91db1263d..8cf97fe62fea50639b7754502e8b48cb7d5179d6 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test associated types appearing in struct-like enum variants.
 
+// pretty-expanded FIXME #23616
+
 use self::VarValue::*;
 
 pub trait UnifyKey {
index e710c53327ec76840697ba206a91c28b4af6803c..3c57da6b4a3ebee8bcee6ad51129b71c4067c3eb 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test associated types appearing in tuple-like enum variants.
 
+// pretty-expanded FIXME #23616
+
 use self::VarValue::*;
 
 pub trait UnifyKey {
index 0ec8a3661906f7aaee7806a151ba4718339eb7da..feccd1d2dcec0daf2ca82cf80511b67b8aaf1b17 100644 (file)
 
 // Test equality constraints on associated types inside of an object type
 
+// pretty-expanded FIXME #23616
+
 pub trait Foo {
     type A;
     fn boo(&self) -> <Self as Foo>::A;
 }
 
-struct Bar;
+pub struct Bar;
 
 impl Foo for char {
     type A = Bar;
index 0ae61037154728837200000a2174cbc53e907154..2a1b9bdd2faf64b0eb9363d63df5293c57bd5684 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Get {
     type Value;
     fn get(&self) -> &<Self as Get>::Value;
@@ -17,12 +19,12 @@ trait Get {
 }
 
 struct Struct {
-    x: int,
+    x: isize,
 }
 
 impl Get for Struct {
-    type Value = int;
-    fn get(&self) -> &int {
+    type Value = isize;
+    fn get(&self) -> &isize {
         &self.x
     }
 }
index 4104f520a0c5d714827f33f6cd384c9aedfafa3e..40b10fbfcaca66b56d073cd2cb220c3c9b9e6dfc 100644 (file)
@@ -8,18 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Get {
     type Value;
     fn get(&self) -> &<Self as Get>::Value;
 }
 
 struct Struct {
-    x: int,
+    x: isize,
 }
 
 impl Get for Struct {
-    type Value = int;
-    fn get(&self) -> &int {
+    type Value = isize;
+    fn get(&self) -> &isize {
         &self.x
     }
 }
index 59f05e1184285c531c284be909093d127822a38b..99a9b7c23febdc2f53d3ecdb277fa9a9d66a0f8d 100644 (file)
@@ -8,18 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Get {
     type Value;
     fn get(&self) -> &<Self as Get>::Value;
 }
 
 struct Struct {
-    x: int,
+    x: isize,
 }
 
 impl Get for Struct {
-    type Value = int;
-    fn get(&self) -> &int {
+    type Value = isize;
+    fn get(&self) -> &isize {
         &self.x
     }
 }
index 951497709fd69955e6c7408b4f2f38e27bf12a51..0012d9d75963271e4a082976d571ce4abc50a6bf 100644 (file)
@@ -8,18 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Get {
     type Value;
     fn get(&self) -> &<Self as Get>::Value;
 }
 
 struct Struct {
-    x: int,
+    x: isize,
 }
 
 impl Get for Struct {
-    type Value = int;
-    fn get(&self) -> &int {
+    type Value = isize;
+    fn get(&self) -> &isize {
         &self.x
     }
 }
index a253fbde5633f112d400adf95e997a5149f1c36d..718ea542799bbdb62ccd5e61a6298ebbffdd52a3 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test references to `Self::Item` in the trait. Issue #20220.
 
+// pretty-expanded FIXME #23616
+
 use std::vec;
 
 trait IntoIteratorX {
index 40ef7f3531cb5caf17247568f52fbc1ccd8a1de0..a601dc0739a467715a400448c1fd4945a0f9c7bd 100644 (file)
 // Test that we are able to have an impl that defines an associated type
 // before the actual trait.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::marker::MarkerTrait;
 
-impl X for f64 { type Y = int; }
+impl X for f64 { type Y = isize; }
 trait X : MarkerTrait { type Y; }
 fn main() {}
index 3c91577362a7d4a27657ff5ebb20a72fa4990478..057677a008785f11fe8ed4c25753e63f78ae6d5b 100644 (file)
@@ -13,6 +13,8 @@
 // where clauses in the environment which in turn required normalizing
 // `Self::Input`.
 
+// pretty-expanded FIXME #23616
+
 pub trait Parser {
     type Input;
 
index f8258466a7d43d529d534b89e42c0297e67789a3..24c5a3e9a8375040c5a90287ca002f549be0d715 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn pairwise_sub<T:DoubleEndedIterator<Item=int>>(mut t: T) -> int {
+// pretty-expanded FIXME #23616
+
+fn pairwise_sub<T:DoubleEndedIterator<Item=isize>>(mut t: T) -> isize {
     let mut result = 0;
     loop {
         let front = t.next();
index 2ee8ef0d3ddac5a51267efcc4226697cf639bb28..a26b428a4eacf2db945eb1b0654ff920bc31b996 100644 (file)
 
 // Test that we can resolve nested projection types. Issue #20666.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::marker::MarkerTrait;
 use std::slice;
 
index de96af83f59171e040223af451d43f71d59b8f0d..d95ad2e883471dacb595f5db819e22428758ff6f 100644 (file)
@@ -11,6 +11,9 @@
 // Test that we normalize associated types that appear in a bound that
 // contains a binding. Issue #21664.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
 #![allow(dead_code)]
 
 use std::marker::MarkerTrait;
index 8617750ca538ea02472b33bd0e77781960fba9df..d8e4c5218d9cf68dbb9972267e5a56b4a0630cfb 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
+// pretty-expanded FIXME #23616
+
 use std::marker::PhantomData;
 
 struct Splits<'a, T:'a, P>(PhantomData<(&'a T, P)>);
index 94cfcb83653812347657560b6d6654cf16b65116..ff08e7b69bdd87ab524fa3e7c345fef254c4b23e 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
+// pretty-expanded FIXME #23616
+
 use std::marker::PhantomData;
 
 struct Splits<'a, T, P>(PhantomData<(&'a(),T,P)>);
index 2288e19aae0bceaaa59131547736cc9cc3653fc9..3dffae99292c61b1c487c8c7d8e1f4d1e18dbffb 100644 (file)
 // various special paths in the `type_is_immediate` function.
 
 
+// pretty-expanded FIXME #23616
+
 pub trait OffsetState: Sized {}
 pub trait Offset {
     type State: OffsetState;
     fn dummy(&self) { }
 }
 
-#[derive(Copy)] pub struct X;
+#[derive(Copy, Clone)] pub struct X;
 impl Offset for X { type State = Y; }
 
-#[derive(Copy)] pub struct Y;
+#[derive(Copy, Clone)] pub struct Y;
 impl OffsetState for Y {}
 
 pub fn now() -> DateTime<X> { from_utc(Y) }
diff --git a/src/test/run-pass/associated-types-project-from-type-param-via-bound-in-where-clause.rs b/src/test/run-pass/associated-types-project-from-type-param-via-bound-in-where-clause.rs
new file mode 100644 (file)
index 0000000..151a9da
--- /dev/null
@@ -0,0 +1,111 @@
+// Copyright 2015 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.
+
+// Various uses of `T::Item` syntax where the bound that supplies
+// `Item` originates in a where-clause, not the declaration of
+// `T`. Issue #20300.
+
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
+use std::marker::{MarkerTrait, PhantomData};
+use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
+use std::sync::atomic::Ordering::SeqCst;
+
+static COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
+
+// Preamble.
+trait Trait : MarkerTrait { type Item; }
+struct Struct;
+impl Trait for Struct {
+    type Item = u32;
+}
+
+// Where-clause attached on the method which declares `T`.
+struct A;
+impl A {
+    fn foo<T>(_x: T::Item) where T: Trait {
+        COUNTER.fetch_add(1, SeqCst);
+    }
+}
+
+// Where-clause attached on the method to a parameter from the struct.
+struct B<T>(PhantomData<T>);
+impl<T> B<T> {
+    fn foo(_x: T::Item) where T: Trait {
+        COUNTER.fetch_add(10, SeqCst);
+    }
+}
+
+// Where-clause attached to free fn.
+fn c<T>(_: T::Item) where T : Trait {
+    COUNTER.fetch_add(100, SeqCst);
+}
+
+// Where-clause attached to defaulted and non-defaulted trait method.
+trait AnotherTrait {
+    fn method<T>(&self, _: T::Item) where T: Trait;
+    fn default_method<T>(&self, _: T::Item) where T: Trait {
+        COUNTER.fetch_add(1000, SeqCst);
+    }
+}
+struct D;
+impl AnotherTrait for D {
+    fn method<T>(&self, _: T::Item) where T: Trait {
+        COUNTER.fetch_add(10000, SeqCst);
+    }
+}
+
+// Where-clause attached to trait and impl containing the method.
+trait YetAnotherTrait<T>
+    where T : Trait
+{
+    fn method(&self, _: T::Item);
+    fn default_method(&self, _: T::Item) {
+        COUNTER.fetch_add(100000, SeqCst);
+    }
+}
+struct E<T>(PhantomData<T>);
+impl<T> YetAnotherTrait<T> for E<T>
+    where T : Trait
+{
+    fn method(&self, _: T::Item) {
+        COUNTER.fetch_add(1000000, SeqCst);
+    }
+}
+
+// Where-clause attached to inherent impl containing the method.
+struct F<T>(PhantomData<T>);
+impl<T> F<T> where T : Trait {
+    fn method(&self, _: T::Item) {
+        COUNTER.fetch_add(10000000, SeqCst);
+    }
+}
+
+// Where-clause attached to struct.
+#[allow(dead_code)]
+struct G<T> where T : Trait {
+    data: T::Item,
+    phantom: PhantomData<T>,
+}
+
+fn main() {
+    A::foo::<Struct>(22);
+    B::<Struct>::foo(22);
+    c::<Struct>(22);
+    D.method::<Struct>(22);
+    D.default_method::<Struct>(22);
+    E(PhantomData::<Struct>).method(22);
+    E(PhantomData::<Struct>).default_method(22);
+    F(PhantomData::<Struct>).method(22);
+    G::<Struct> { data: 22, phantom: PhantomData };
+    assert_eq!(COUNTER.load(SeqCst), 11111111);
+}
index 24dae20b3e77e976a4b3d67b25e7753802afc901..e150d0158243711184ce23d73b9d635fe1f54ca4 100644 (file)
@@ -20,8 +20,8 @@ trait Not {
 }
 
 trait Int: Not<Result=Self> + Sized {
-    fn count_ones(self) -> uint;
-    fn count_zeros(self) -> uint {
+    fn count_ones(self) -> usize;
+    fn count_zeros(self) -> usize {
         // neither works
         let x: Self = self.not();
         0
index c65d2db9b0cf0f3125849028aae506a4680827af..2518ccf1cb47430076f854d7fa2e854e6283f03f 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test where the impl self type uses a projection from a constant type.
 
+// pretty-expanded FIXME #23616
+
 trait Int
 {
     type T;
index a9c34a605ce163a5f2cfb842929ad6a3a7ce249d..3b146792fdaded965b7873c9e919a9b471f31364 100644 (file)
@@ -13,6 +13,8 @@
 // appear in associated type bindings in object types, which were not
 // being properly flagged.
 
+// pretty-expanded FIXME #23616
+
 use std::ops::{Shl, Shr};
 use std::cell::RefCell;
 
index 4d2358fae27b183f3440d83020b21563e4ee9139..dbc2164c93a69c32c0989f96eb88ec18ed63bbe6 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we are handle to correctly handle a projection type
 // that appears in a supertrait bound. Issue #20559.
 
+// pretty-expanded FIXME #23616
+
 trait A
 {
     type TA;
index 3f3f4fbd1d628f46489096157ad484eb17cc8642..80e3aa09e3e613e614c28d6f36ed2a44e4ffb3ea 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test a where clause that uses a non-normalized projection type.
 
+// pretty-expanded FIXME #23616
+
 trait Int
 {
     type T;
index abbde16faefca14ffa4d81a441ad1cf9ba037c82..a69de216ab997dbca06d8222b932ed258ef66be7 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Foo<T> {
     type Bar;
     fn get_bar() -> <Self as Foo<T>>::Bar;
index 3c7cc7c4975344f173fb7b0594199df53182d533..ce09ec60bd6a52ba29ff76b0d4e63a9ed1499c09 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test associated type references in structure fields.
 
+// pretty-expanded FIXME #23616
+
 trait Test {
     type V;
 
index 67fe11d8feddec9cb3bd23833826746d2ce2b96b..945340008d876bae616261027958d13147872c99 100644 (file)
 
 // Test associated type references in a struct literal. Issue #20535.
 
+// pretty-expanded FIXME #23616
+
 pub trait Foo {
     type Bar;
 
     fn dummy(&self) { }
 }
 
-impl Foo for int {
-    type Bar = int;
+impl Foo for isize {
+    type Bar = isize;
 }
 
 struct Thing<F: Foo> {
index 03ab8f7e43136910ef3a75cb2672a875af6da184..16e49f146ab557b24d8c2047256b5f4eaf998e90 100644 (file)
@@ -11,6 +11,8 @@
 // Regression test for #20582. This test caused an ICE related to
 // inconsistent region erasure in trans.
 
+// pretty-expanded FIXME #23616
+
 struct Foo<'a> {
     buf: &'a[u8]
 }
index a4b0b1a6e03af4281e88164f7b91e238250438e3..824291ea60782db5c02b50be052b49aff79f8077 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Get<T> {
     fn get(&self) -> T;
 }
 
 trait Trait<'a> {
     type T: 'static;
-    type U: Get<&'a int>;
+    type U: Get<&'a isize>;
 
     fn dummy(&'a self) { }
 }
index fe24ab6bbeb1b453a21c8ac791820c2f10aeac7f..f190e81d8a6ad440d2e6a59d7d939af2db0723d1 100644 (file)
 
 // Test equality constraints on associated types in a where clause.
 
+// pretty-expanded FIXME #23616
+
 pub trait Foo {
     type A;
     fn boo(&self) -> <Self as Foo>::A;
 }
 
 #[derive(PartialEq)]
-struct Bar;
+pub struct Bar;
 
-impl Foo for int {
-    type A = uint;
-    fn boo(&self) -> uint { 42 }
+impl Foo for isize {
+    type A = usize;
+    fn boo(&self) -> usize { 42 }
 }
 
 impl Foo for Bar {
-    type A = int;
-    fn boo(&self) -> int { 43 }
+    type A = isize;
+    fn boo(&self) -> isize { 43 }
 }
 
 impl Foo for char {
@@ -43,7 +45,7 @@ fn foo2<I: Foo>(x: I) -> <I as Foo>::A {
 
 pub fn main() {
     let a = 42;
-    assert!(foo2(a) == 42_usize);
+    assert!(foo2(a) == 42);
 
     let a = Bar;
     assert!(foo2(a) == 43);
index 9e388dc3d347e7932e2cb7fcdd589dba8c0760a7..5a2761365bf301c868320f271502c8a225226c73 100644 (file)
@@ -8,18 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Get {
     type Value;
     fn get(&self) -> &<Self as Get>::Value;
 }
 
 struct Struct {
-    x: int,
+    x: isize,
 }
 
 impl Get for Struct {
-    type Value = int;
-    fn get(&self) -> &int {
+    type Value = isize;
+    fn get(&self) -> &isize {
         &self.x
     }
 }
index ef7fbe87b304744dd51ce8791b9783ae8433c48e..a2b7cf2106eb7af89dff81498ad27b6f3be80d73 100644 (file)
@@ -11,6 +11,8 @@
 // Test references to the trait `Stream` in the bounds for associated
 // types defined on `Stream`. Issue #20551.
 
+// pretty-expanded FIXME #23616
+
 trait Stream {
     type Car;
     type Cdr: Stream;
index 8667f6c8430aba03c706a9ae8d61bf273e920a5e..d1872e4fb55f4c86abc2352dfcf58a82fd1c5724 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we correctly normalize the type of a struct field
 // which has an associated type.
 
+// pretty-expanded FIXME #23616
+
 pub trait UnifyKey {
     type Value;
 
@@ -36,8 +38,8 @@ impl UnifyKey for u32 {
 
 pub fn main() {
     let node: Node<i32> = Node { key: 1, value: Some(22) };
-    assert_eq!(foo(&node), Some(22_u32));
+    assert_eq!(foo(&node), Some(22));
 
     let node: Node<u32> = Node { key: 1, value: Some(22) };
-    assert_eq!(foo(&node), Some(22_i32));
+    assert_eq!(foo(&node), Some(22));
 }
index 9503f78a71b908ed469cfc109a4a11f89f9151b6..3d97c503dca5f94848f7dbd8569934e7085e11dd 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we correctly normalize the type of a struct field
 // which has an associated type.
 
+// pretty-expanded FIXME #23616
+
 pub trait UnifyKey {
     type Value;
 
@@ -33,8 +35,8 @@ impl UnifyKey for u32 {
 
 pub fn main() {
     let node: Node<i32> = Node(1, Some(22));
-    assert_eq!(foo(&node), Some(22_u32));
+    assert_eq!(foo(&node), Some(22));
 
     let node: Node<u32> = Node(1, Some(22));
-    assert_eq!(foo(&node), Some(22_i32));
+    assert_eq!(foo(&node), Some(22));
 }
index c068065ac6ae7e2167636a4ae336398c1bec9b8a..353b49b49cedfc7d0cb22a2274f922bcb11b0754 100644 (file)
 
 // Test paths to associated types using the type-parameter-only sugar.
 
+// pretty-expanded FIXME #23616
+
 pub trait Foo {
     type A;
     fn boo(&self) -> Self::A;
 }
 
-impl Foo for int {
-    type A = uint;
-    fn boo(&self) -> uint {
+impl Foo for isize {
+    type A = usize;
+    fn boo(&self) -> usize {
         5
     }
 }
@@ -41,5 +43,5 @@ impl<T: Foo> C for B<T> {
 }
 
 pub fn main() {
-    let z: uint = bar(2, 4_usize);
+    let z: usize = bar(2, 4);
 }
index 0c6d91eda26af4ba9055beb05ea81b3da39c7d74..ef2dc48fe136474ae438f83e36b4e50f95ae8236 100644 (file)
@@ -13,6 +13,8 @@
 // carries a predicate that references the trait (`u32 : Trait1`,
 // substituted).
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 trait Trait1 : Trait2<SomeType<u32>> {
index 951a716879fce782c8f45effa67497ced90d438f..cdd1b96de1e6081e14f965d594457a9a6c847a2b 100644 (file)
@@ -10,7 +10,9 @@
 
 // error-pattern:expected item
 
-#![feature(custom_attribute)]
+// pretty-expanded FIXME #23616
+
+#![feature(custom_attribute, test)]
 
 #[foo = "bar"]
 extern crate test;
index ad8ce608bd05dcb30fe4f6067c5f93558cac8798..cd02b5a9e73109498a2ba5ff438371facffd170f 100644 (file)
@@ -10,7 +10,9 @@
 
 // error-pattern:expected item
 
-#![feature(custom_attribute)]
+// pretty-expanded FIXME #23616
+
+#![feature(custom_attribute, test)]
 
 mod m {
     #[foo = "bar"]
index fd0ae0729af2540fc69099043a1655eb0188c76a..4680f47fad6ce30e05e48f4edcf32ac49d9e7873 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(main)]
 
 pub fn main() {
index 29b504bed535d5af4a831fe7eefe53ad92aa29ae..e8a12ee3ac79161816a23f8460fd39c9fbcfb2b5 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(main)]
 
 #[main]
index 7980937ce2a159f84aa129871dbeb59b183906c1..bcfb4b330f5eda6ff3e46578601fb2eb40f47a2e 100644 (file)
@@ -7,6 +7,8 @@
 // <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.
+// pretty-expanded FIXME #23616
+
 #![allow(unused_attribute)]
 #![feature(custom_attribute)]
 
index bd799917842b124881ebc58b2c95fd5b1c66a5b9..af8e4b7d4a1a7e713cb627402697a5eba74f34fe 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 #![feature(unsafe_no_drop_flag)]
 
@@ -24,5 +26,5 @@ impl<T> Drop for Test<T> {
 }
 
 pub fn main() {
-    assert_eq!(size_of::<int>(), size_of::<Test<int>>());
+    assert_eq!(size_of::<isize>(), size_of::<Test<isize>>());
 }
index 2bf09404200a54e180ac54cdec6a99db05266457..bfafe04d6006c07eae7082f05f949c810faa7e93 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(start)]
 
 #[start]
-fn start(_argc: int, _argv: *const *const u8) -> int {
+fn start(_argc: isize, _argv: *const *const u8) -> isize {
     return 0;
 }
index 129d69b6e67ccd85851966bcd156dd910ee1fcbe..57e1b38c9c1664e133ab750c8d0a5eba586919d4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(main)]
 
 #[main]
index 7c126fc420aac7f6b5e5522a5dd33b00977c9f1c..2df0bb355979b1e92cd5a5f793512105cbcbd1c5 100644 (file)
@@ -43,7 +43,7 @@ fn test_rbml<'a, 'b, A:
 
 #[derive(Decodable, Encodable)]
 enum Expr {
-    Val(uint),
+    Val(usize),
     Plus(@Expr, @Expr),
     Minus(@Expr, @Expr)
 }
@@ -103,23 +103,23 @@ impl<T:cmp::Eq> cmp::Eq for Quark<T> {
 
 impl cmp::Eq for CLike {
     fn eq(&self, other: &CLike) -> bool {
-        (*self) as int == *other as int
+        (*self) as isize == *other as isize
     }
     fn ne(&self, other: &CLike) -> bool { !self.eq(other) }
 }
 
 #[derive(Decodable, Encodable, Eq)]
 struct Spanned<T> {
-    lo: uint,
-    hi: uint,
+    lo: usize,
+    hi: usize,
     node: T,
 }
 
 #[derive(Decodable, Encodable)]
-struct SomeStruct { v: Vec<uint> }
+struct SomeStruct { v: Vec<usize> }
 
 #[derive(Decodable, Encodable)]
-struct Point {x: uint, y: uint}
+struct Point {x: usize, y: usize}
 
 #[derive(Decodable, Encodable)]
 enum Quark<T> {
@@ -131,19 +131,19 @@ enum Quark<T> {
 enum CLike { A, B, C }
 
 pub fn main() {
-    let a = &Plus(@Minus(@Val(3_usize), @Val(10_usize)), @Plus(@Val(22_usize), @Val(5_usize)));
+    let a = &Plus(@Minus(@Val(3), @Val(10)), @Plus(@Val(22), @Val(5)));
     test_rbml(a);
 
-    let a = &Spanned {lo: 0_usize, hi: 5_usize, node: 22_usize};
+    let a = &Spanned {lo: 0, hi: 5, node: 22};
     test_rbml(a);
 
-    let a = &Point {x: 3_usize, y: 5_usize};
+    let a = &Point {x: 3, y: 5};
     test_rbml(a);
 
-    let a = &Top(22_usize);
+    let a = &Top(22);
     test_rbml(a);
 
-    let a = &Bottom(222_usize);
+    let a = &Bottom(222);
     test_rbml(a);
 
     let a = &A;
index cd4c66cb3218a65a3bb8acb89499b9fd9899dce7..4a1bfa3eb42668e5f2f30a33ab632d16cd5047c5 100644 (file)
@@ -10,7 +10,7 @@
 
 #[derive(Debug)]
 struct Pair<T, U> { a: T, b: U }
-struct Triple { x: int, y: int, z: int }
+struct Triple { x: isize, y: isize, z: isize }
 
 fn f<T,U>(x: T, y: U) -> Pair<T, U> { return Pair {a: x, b: y}; }
 
index 2cc7451e138944c27b371b27bf34a5c3ebd8dbe3..2e79183755a18094395ab9dcd414d4d8a1ddab75 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let mut sum = 0;
     let xs = vec!(1, 2, 3, 4, 5);
index ee3738518cd771f1f261277401b1cfb3659048e5..77ec0e1791f96e24a49e1486cc01415aba90b95b 100644 (file)
@@ -13,7 +13,7 @@ trait Foo {
 }
 
 struct Bar {
-    x: int
+    x: isize
 }
 
 trait Baz {
index 652f21c2ae3f829aeaff85b54ab1871492d9656c..6dab0e51971382a29ab7f1d3219632454a275779 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 trait Pushable<T> {
     fn push_val(&mut self, t: T);
 }
@@ -23,5 +25,5 @@ pub fn main() {
     let mut v = vec!(1);
     v.push_val(2);
     v.push_val(3);
-    assert_eq!(v, vec!(1, 2, 3));
+    assert_eq!(v, [1, 2, 3]);
 }
index 6dc679054275fbe47206761b2f861be9611466e5..0ad2303a7697bb67470cb5d66c3967257aff8e58 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct Foo {
-    x: int,
+    x: isize,
 }
 
 trait Stuff {
index ed471ed0079e3c5cd21166e7fbd7e47c397ffb9a..7d30b549ebea45076a61fa54f3bda3e29c27ebbc 100644 (file)
@@ -9,9 +9,11 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 fn f<T>(x: Vec<T>) -> T { return x.into_iter().next().unwrap(); }
 
-fn g<F>(act: F) -> int where F: FnOnce(Vec<int>) -> int { return act(vec!(1, 2, 3)); }
+fn g<F>(act: F) -> isize where F: FnOnce(Vec<isize>) -> isize { return act(vec!(1, 2, 3)); }
 
 pub fn main() {
     assert_eq!(g(f), 1);
index fc643ec594089a4cc62f9eca2343f6e4afc6ee01..a4c6cdd544c87fea2ac627a772f31f4139fae2af 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct Foo {
-    x: int,
+    x: isize,
 }
 
 impl Foo {
index 9e88eb6da6aea813b1f6472ce2206ead59bec651..d7eee85f50273b360ab2f05ae7b99bf542564ce3 100644 (file)
@@ -8,18 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 trait double {
-    fn double(self: Box<Self>) -> uint;
+    fn double(self: Box<Self>) -> usize;
 }
 
-impl double for uint {
-    fn double(self: Box<uint>) -> uint { *self * 2_usize }
+impl double for usize {
+    fn double(self: Box<usize>) -> usize { *self * 2 }
 }
 
 pub fn main() {
-    let x = box() (box 3_usize as Box<double>);
-    assert_eq!(x.double(), 6_usize);
+    let x: Box<_> = box() (box 3us as Box<double>);
+    assert_eq!(x.double(), 6);
 }
index 67dd25ddc5389154872251209486312aee9291ef..6c52035b708de72fbe82628e8088e03ad46a4a56 100644 (file)
@@ -8,22 +8,24 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 trait double {
-    fn double(self) -> uint;
+    fn double(self) -> usize;
 }
 
-impl double for uint {
-    fn double(self) -> uint { self }
+impl double for usize {
+    fn double(self) -> usize { self }
 }
 
-impl double for Box<uint> {
-    fn double(self) -> uint { *self * 2_usize }
+impl double for Box<usize> {
+    fn double(self) -> usize { *self * 2 }
 }
 
 pub fn main() {
-    let x = box 3_usize;
-    assert_eq!(x.double(), 6_usize);
+    let x: Box<_> = box 3;
+    assert_eq!(x.double(), 6);
 }
index 6437c78161c00f72d4fa104533ebc79216330130..809ab0a3521dd50209683d898a9c7d5f55a54e1b 100644 (file)
@@ -8,18 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 trait double {
-    fn double(self: Box<Self>) -> uint;
+    fn double(self: Box<Self>) -> usize;
 }
 
-impl double for Box<uint> {
-    fn double(self: Box<Box<uint>>) -> uint { **self * 2_usize }
+impl double for Box<usize> {
+    fn double(self: Box<Box<usize>>) -> usize { **self * 2 }
 }
 
 pub fn main() {
-    let x = box box box box box 3_usize;
-    assert_eq!(x.double(), 6_usize);
+    let x: Box<Box<Box<Box<Box<_>>>>> = box box box box box 3;
+    assert_eq!(x.double(), 6);
 }
index 8cbc151f0cd24af4930e5eaeb24296789b1983b1..9c7828c893895602f108af6185fa1ec2d18da67c 100644 (file)
@@ -8,18 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 trait double {
-    fn double(self: Box<Self>) -> uint;
+    fn double(self: Box<Self>) -> usize;
 }
 
-impl double for uint {
-    fn double(self: Box<uint>) -> uint { *self * 2_usize }
+impl double for usize {
+    fn double(self: Box<usize>) -> usize { *self * 2 }
 }
 
 pub fn main() {
-    let x = box box 3_usize;
-    assert_eq!(x.double(), 6_usize);
+    let x: Box<Box<_>> = box box 3;
+    assert_eq!(x.double(), 6);
 }
index c8fa3c9fd5fb505518d1e71e396f891d0321beb1..e63dd07eb07523f49e02dcfff9cfd27615d9f10b 100644 (file)
@@ -8,18 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 trait double {
-    fn double(self: Box<Self>) -> uint;
+    fn double(self: Box<Self>) -> usize;
 }
 
-impl double for uint {
-    fn double(self: Box<uint>) -> uint { *self * 2_usize }
+impl double for usize {
+    fn double(self: Box<usize>) -> usize { *self * 2 }
 }
 
 pub fn main() {
-    let x = box 3_usize;
-    assert_eq!(x.double(), 6_usize);
+    let x: Box<_> = box 3;
+    assert_eq!(x.double(), 6);
 }
index 87157b9334f167f0bf3a540a5dbcd132e9e37613..0f935776fc554b01513f8f6cde4be1e92c4a4d71 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -22,13 +24,13 @@ impl<T:Foo> Foo for Box<T> {
     }
 }
 
-impl Foo for uint {
+impl Foo for usize {
     fn foo(&self) -> String {
         format!("{}", *self)
     }
 }
 
 pub fn main() {
-    let x = box 3_usize;
+    let x: Box<_> = box 3;
     assert_eq!(x.foo(), "box 3".to_string());
 }
diff --git a/src/test/run-pass/backtrace-debuginfo-aux.rs b/src/test/run-pass/backtrace-debuginfo-aux.rs
new file mode 100644 (file)
index 0000000..f0d36ea
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2015 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.
+
+// ignore-test: not a test, used by backtrace-debuginfo.rs to test file!()
+
+#[inline(never)]
+pub fn callback<F>(f: F) where F: FnOnce((&'static str, u32)) {
+    f((file!(), line!()))
+}
+
+#[inline(always)]
+pub fn callback_inlined<F>(f: F) where F: FnOnce((&'static str, u32)) {
+    f((file!(), line!()))
+}
diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs
new file mode 100644 (file)
index 0000000..2a74e36
--- /dev/null
@@ -0,0 +1,161 @@
+// Copyright 2015 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:-g
+// ignore-pretty as this critically relies on line numbers
+
+use std::io;
+use std::io::prelude::*;
+use std::env;
+
+#[path = "backtrace-debuginfo-aux.rs"] mod aux;
+
+macro_rules! pos {
+    () => ((file!(), line!()))
+}
+
+#[cfg(all(unix,
+          not(target_os = "macos"),
+          not(target_os = "ios"),
+          not(target_os = "android"),
+          not(all(target_os = "linux", target_arch = "arm"))))]
+macro_rules! dump_and_die {
+    ($($pos:expr),*) => ({
+        // FIXME(#18285): we cannot include the current position because
+        // the macro span takes over the last frame's file/line.
+        dump_filelines(&[$($pos),*]);
+        panic!();
+    })
+}
+
+// this does not work on Windows, Android, OSX or iOS
+#[cfg(any(not(unix),
+          target_os = "macos",
+          target_os = "ios",
+          target_os = "android",
+          all(target_os = "linux", target_arch = "arm")))]
+macro_rules! dump_and_die {
+    ($($pos:expr),*) => ({ let _ = [$($pos),*]; })
+}
+
+// we can't use a function as it will alter the backtrace
+macro_rules! check {
+    ($counter:expr; $($pos:expr),*) => ({
+        if *$counter == 0 {
+            dump_and_die!($($pos),*)
+        } else {
+            *$counter -= 1;
+        }
+    })
+}
+
+type Pos = (&'static str, u32);
+
+// this goes to stdout and each line has to be occurred
+// in the following backtrace to stderr with a correct order.
+fn dump_filelines(filelines: &[Pos]) {
+    for &(file, line) in filelines.iter().rev() {
+        // extract a basename
+        let basename = file.split(&['/', '\\'][..]).last().unwrap();
+        println!("{}:{}", basename, line);
+    }
+}
+
+#[inline(never)]
+fn inner(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
+    check!(counter; main_pos, outer_pos);
+    check!(counter; main_pos, outer_pos);
+    let inner_pos = pos!(); aux::callback(|aux_pos| {
+        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
+    });
+    let inner_pos = pos!(); aux::callback_inlined(|aux_pos| {
+        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
+    });
+}
+
+#[inline(always)]
+fn inner_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
+    check!(counter; main_pos, outer_pos);
+    check!(counter; main_pos, outer_pos);
+
+    #[inline(always)]
+    fn inner_further_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos, inner_pos: Pos) {
+        check!(counter; main_pos, outer_pos, inner_pos);
+    }
+    inner_further_inlined(counter, main_pos, outer_pos, pos!());
+
+    let inner_pos = pos!(); aux::callback(|aux_pos| {
+        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
+    });
+    let inner_pos = pos!(); aux::callback_inlined(|aux_pos| {
+        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
+    });
+
+    // this tests a distinction between two independent calls to the inlined function.
+    // (un)fortunately, LLVM somehow merges two consecutive such calls into one node.
+    inner_further_inlined(counter, main_pos, outer_pos, pos!());
+}
+
+#[inline(never)]
+fn outer(mut counter: i32, main_pos: Pos) {
+    inner(&mut counter, main_pos, pos!());
+    inner_inlined(&mut counter, main_pos, pos!());
+}
+
+fn check_trace(output: &str, error: &str) {
+    // reverse the position list so we can start with the last item (which was the first line)
+    let mut remaining: Vec<&str> = output.lines().map(|s| s.trim()).rev().collect();
+
+    assert!(error.contains("stack backtrace"), "no backtrace in the error: {}", error);
+    for line in error.lines() {
+        if !remaining.is_empty() && line.contains(remaining.last().unwrap()) {
+            remaining.pop();
+        }
+    }
+    assert!(remaining.is_empty(),
+            "trace does not match position list: {}\n---\n{}", error, output);
+}
+
+fn run_test(me: &str) {
+    use std::str;
+    use std::process::Command;
+
+    let mut template = Command::new(me);
+    template.env("RUST_BACKTRACE", "1");
+
+    let mut i = 0;
+    loop {
+        let out = Command::new(me)
+                          .env("RUST_BACKTRACE", "1")
+                          .arg(i.to_string()).output().unwrap();
+        let output = str::from_utf8(&out.stdout).unwrap();
+        let error = str::from_utf8(&out.stderr).unwrap();
+        if out.status.success() {
+            assert!(output.contains("done."), "bad output for successful run: {}", output);
+            break;
+        } else {
+            check_trace(output, error);
+        }
+        i += 1;
+    }
+}
+
+#[inline(never)]
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    if args.len() >= 2 {
+        let case = args[1].parse().unwrap();
+        writeln!(&mut io::stderr(), "test case {}", case).unwrap();
+        outer(case, pos!());
+        println!("done.");
+    } else {
+        run_test(&args[0]);
+    }
+}
index 6f76322cb778d57a0401c4a333619c5dace9418f..14d8bce061f5aed20699783b800cd333377a08d9 100644 (file)
@@ -12,7 +12,7 @@
 // ignore-windows FIXME #13259
 
 #![feature(unboxed_closures)]
-#![feature(unsafe_destructor)]
+#![feature(unsafe_destructor, old_io, collections)]
 
 use std::env;
 use std::old_io::process::Command;
@@ -53,7 +53,9 @@ fn runtest(me: &str) {
             "bad output: {}", s);
 
     // Make sure the stack trace is *not* printed
-    let p = template.clone().arg("fail").spawn().unwrap();
+    // (Remove RUST_BACKTRACE from our own environment, in case developer
+    // is running `make check` with it on.)
+    let p = template.clone().arg("fail").env_remove("RUST_BACKTRACE").spawn().unwrap();
     let out = p.wait_with_output().unwrap();
     assert!(!out.status.success());
     let s = str::from_utf8(&out.error).unwrap();
@@ -78,9 +80,9 @@ fn runtest(me: &str) {
     let s = str::from_utf8(&out.error).unwrap();
     let mut i = 0;
     for _ in 0..2 {
-        i += s[i + 10..].find_str("stack backtrace").unwrap() + 10;
+        i += s[i + 10..].find("stack backtrace").unwrap() + 10;
     }
-    assert!(s[i + 10..].find_str("stack backtrace").is_none(),
+    assert!(s[i + 10..].find("stack backtrace").is_none(),
             "bad output4: {}", s);
 }
 
index 758776298e1463cc94699fc4f563dd4ecb94da23..e8118e90a9f3f7f329663f31828632337ebc1ec0 100644 (file)
@@ -35,4 +35,3 @@ fn main() {
     assert_eq!(call_g(g, "foo".to_string(), "bar".to_string()),
                "foobar");
 }
-
index 8afb33c7669f542158e198b0a0759ae41987cc83..ab9d892ce2b60cd963140e1dd75a44bd689ae366 100644 (file)
@@ -8,11 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
+// Catch mistakes in the overflowing literals lint.
+#![deny(overflowing_literals)]
+
 pub fn main() {
-    assert_eq!(0xffffffffu32, (-1 as u32));
-    assert_eq!(4294967295u32, (-1 as u32));
-    assert_eq!(0xffffffffffffffffu64, (-1 as u64));
-    assert_eq!(18446744073709551615u64, (-1 as u64));
+    assert_eq!(0xffffffff, (!0 as u32));
+    assert_eq!(4294967295, (!0 as u32));
+    assert_eq!(0xffffffffffffffff, (!0 as u64));
+    assert_eq!(18446744073709551615, (!0 as u64));
 
-    assert_eq!(-2147483648i32 - 1i32, 2147483647i32);
+    assert_eq!((-2147483648i32).wrapping_sub(1), 2147483647);
 }
index dc3b142f233762d22a6973ae01195c2379ff517d..1fe9dde844a4fe4602884c40460c6604cad837fb 100644 (file)
@@ -10,6 +10,8 @@
 
 // Check that issue #954 stays fixed
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     match -1 { -1 => {}, _ => panic!("wat") }
     assert_eq!(1-1, 0);
index a9fa8449d0f1ac654474da7fac604d30f43ac048..5a6e801501fcfc1f2ac3b9ef5e660ae35fe11a8b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::sync::Arc;
 fn dispose(_x: Arc<bool>) { }
 
index 470577d729730de9deac00676840a97c8c772275..e61ff61a2162284e251bc04f276640339a6247a2 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    struct Foo { x: int, y: int }
+    struct Foo { x: isize, y: isize }
     let mut f = Foo { x: 10, y: 0 };
     match f {
         Foo { ref mut x, .. } => *x = 11,
diff --git a/src/test/run-pass/binops-issue-22743.rs b/src/test/run-pass/binops-issue-22743.rs
new file mode 100644 (file)
index 0000000..da7a3ae
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2015 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 std::ops::Mul;
+
+#[derive(Copy, Clone)]
+pub struct Foo {
+    x: f64,
+}
+
+impl Mul<Foo> for f64 {
+    type Output = Foo;
+
+    fn mul(self, rhs: Foo) -> Foo {
+        // intentionally do something that is not *
+        Foo { x: self + rhs.x }
+    }
+}
+
+pub fn main() {
+    let f: Foo = Foo { x: 5.0 };
+    let val: f64 = 3.0;
+    let f2: Foo = val * f;
+    assert_eq!(f2.x, 8.0);
+}
index b36eb4bf2f62e493caea483f280b0344d69cab3a..2b8fcd303b66ed7dbf843d0ef370f7dcd9a3e43f 100644 (file)
@@ -61,11 +61,11 @@ fn test_ptr() {
 
 #[derive(PartialEq, Debug)]
 struct p {
-  x: int,
-  y: int,
+  x: isize,
+  y: isize,
 }
 
-fn p(x: int, y: int) -> p {
+fn p(x: isize, y: isize) -> p {
     p {
         x: x,
         y: y
@@ -78,8 +78,8 @@ fn test_class() {
 
   unsafe {
   println!("q = {:x}, r = {:x}",
-         (::std::mem::transmute::<*const p, uint>(&q)),
-         (::std::mem::transmute::<*const p, uint>(&r)));
+         (::std::mem::transmute::<*const p, usize>(&q)),
+         (::std::mem::transmute::<*const p, usize>(&r)));
   }
   assert_eq!(q, r);
   r.y = 17;
index 7bb9f042fe891ee418b2112c7f522f82fa54bbd7..c9a2e07dd8398eb3a1445f7ca5136e64e3d86792 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, collections)]
 
 extern crate collections;
 use std::collections::BitVec;
 
 fn bitv_test() {
-    let mut v1 = box BitVec::from_elem(31, false);
-    let v2 = box BitVec::from_elem(31, true);
+    let mut v1: Box<_> = box BitVec::from_elem(31, false);
+    let v2: Box<_> = box BitVec::from_elem(31, true);
     v1.union(&*v2);
 }
 
index 8418681b6b1903a112a77e71ccd4632723d65f2c..a9f19c12b0278e09b1d0f122028ae1f162671f7d 100644 (file)
@@ -8,20 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(negate_unsigned)]
 
 #[cfg(any(target_arch = "x86", target_arch = "arm"))]
 fn target() {
-    assert_eq!(-1000 as uint >> 3_usize, 536870787_usize);
+    assert_eq!(-1000 as usize >> 3_usize, 536870787_usize);
 }
 
 #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
 fn target() {
-    assert_eq!(-1000 as uint >> 3_usize, 2305843009213693827_usize);
+    assert_eq!(-1000 as usize >> 3_usize, 2305843009213693827_usize);
 }
 
 fn general() {
-    let mut a: int = 1;
-    let mut b: int = 2;
+    let mut a: isize = 1;
+    let mut b: isize = 2;
     a ^= b;
     b ^= a;
     a = a ^ b;
index 80c73e5e60b53ffe8a77023e911942a3f4939c81..3b6614c18faa8cf2855bdca36e8f85a38d1f5a3c 100644 (file)
@@ -11,6 +11,8 @@
 // aux-build:blind-item-mixed-crate-use-item-foo.rs
 // aux-build:blind-item-mixed-crate-use-item-foo2.rs
 
+// pretty-expanded FIXME #23616
+
 mod m {
     pub fn f<T>(_: T, _: (), _: ()) { }
     pub fn g<T>(_: T, _: (), _: ()) { }
@@ -19,14 +21,14 @@ mod m {
 const BAR: () = ();
 struct Data;
 use m::f;
-extern crate "blind-item-mixed-crate-use-item-foo" as foo;
+extern crate blind_item_mixed_crate_use_item_foo as foo;
 
 fn main() {
     const BAR2: () = ();
     struct Data2;
     use m::g;
 
-    extern crate "blind-item-mixed-crate-use-item-foo2" as foo2;
+    extern crate blind_item_mixed_crate_use_item_foo2 as foo2;
 
     f(Data, BAR, foo::X);
     g(Data2, BAR2, foo2::Y);
index a3dad01acf17b6c6a3eeb2dec84a9ea1ee959fe2..6244ba6fccf0b09bb21e19b7252a90d0eb9e28ec 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod m {
     pub fn f<T>(_: T, _: ()) { }
     pub fn g<T>(_: T, _: ()) { }
index d319aaa2f8e18b58e80317f319c50413f484d2b6..5944438e20d9a40ce7577e374c131a438dfb1a87 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn asBlock<F>(f: F) -> uint where F: FnOnce() -> uint {
+// pretty-expanded FIXME #23616
+
+fn asBlock<F>(f: F) -> usize where F: FnOnce() -> usize {
    return f();
 }
 
 pub fn main() {
-   let x = asBlock(|| 22_usize);
-   assert_eq!(x, 22_usize);
+   let x = asBlock(|| 22);
+   assert_eq!(x, 22);
 }
index 54b650d762bf46b2af5c0fa7c9004057c1d92e87..835d356d8aaa1d98106622ff8df38de6c514baae 100644 (file)
@@ -10,5 +10,5 @@
 
 pub fn main() {
     fn as_buf<T, F>(s: String, f: F) -> T where F: FnOnce(String) -> T { f(s) }
-    as_buf("foo".to_string(), |foo: String| -> () println!("{}", foo) );
+    as_buf("foo".to_string(), |foo: String| -> () { println!("{}", foo) });
 }
index ace372dd2d3d9346d8db8a084044689c2ad44199..01bd8ce10cd095aa672769bf62b7f5f1522020eb 100644 (file)
@@ -13,6 +13,8 @@
 
 // no-reformat
 
+// pretty-expanded FIXME #23616
+
 /*
  *
  *  When you write a block-expression thing followed by
index f3c874a5afcec13b801d006a754704754ea55b32..0addd33c1e4a3f5fd365c6d4f4f4584c23d1a463 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn force<F>(f: F) -> int where F: FnOnce() -> int { return f(); }
+// pretty-expanded FIXME #23616
+
+fn force<F>(f: F) -> isize where F: FnOnce() -> isize { return f(); }
 
 pub fn main() {
-    fn f() -> int { return 7; }
+    fn f() -> isize { return 7; }
     assert_eq!(force(f), 7);
     let g = {||force(f)};
     assert_eq!(g(), 7);
index d5d26f42ef0953cce28df180d701eaa9b81e3c04..7cbe8104deb5d939176929e563cd773983149072 100644 (file)
@@ -11,8 +11,8 @@
 fn iter_vec<T, F>(v: Vec<T> , mut f: F) where F: FnMut(&T) { for x in &v { f(x); } }
 
 pub fn main() {
-    let v = vec![1i32, 2, 3, 4, 5, 6, 7];
-    let mut odds = 0i32;
+    let v = vec![1, 2, 3, 4, 5, 6, 7];
+    let mut odds = 0;
     iter_vec(v, |i| {
         if *i % 2 == 1 {
             odds += 1;
index 8c079ca4b079afe2e3e600424abe294ba624f327..7701f6114ca6233a29b077919fd3c7b3247ae3ef 100644 (file)
@@ -11,7 +11,7 @@
 fn iter_vec<T, F>(v: Vec<T>, mut f: F) where F: FnMut(&T) { for x in &v { f(x); } }
 
 pub fn main() {
-    let v = vec![1i32, 2, 3, 4, 5];
+    let v = vec![1, 2, 3, 4, 5];
     let mut sum = 0;
     iter_vec(v.clone(), |i| {
         iter_vec(v.clone(), |j| {
index e98087810b2a42d4f92aa1d4269e237c49f0bd5e..c46684af6efda630afeeda4db3896e405482ef53 100644 (file)
@@ -11,6 +11,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     if !false { assert!((true)); } else { assert!((false)); }
     if !true { assert!((false)); } else { assert!((true)); }
index edf6b397ff8c8c7703a3a1bb1ade80ba8b41a9f8..a2b19d32054a5561c37804de7fd551f8d50f3f7f 100644 (file)
@@ -10,6 +10,8 @@
 
 // Basic boolean tests
 
+// pretty-expanded FIXME #23616
+
 use std::cmp::Ordering::{Equal, Greater, Less};
 use std::ops::{BitAnd, BitOr, BitXor};
 
index 4cc39b4b5d79ab063310382bda15dc489142e511..7efda12192a78e6a5f6415de5e347cdf3fb1b9f2 100644 (file)
@@ -9,11 +9,13 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
     fn foo(self);
 }
 
-impl<'a> Foo for &'a [int] {
+impl<'a> Foo for &'a [isize] {
     fn foo(self) {}
 }
 
index 2e5688d8b7497f1f32538f3eb5650aebd55b2e09..7cf61bd569dfb9b48d496c6c9487d3bc71669051 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo(int, int);
+// pretty-expanded FIXME #23616
+
+struct Foo(isize, isize);
 
 fn main() {
     let x = (1, 2);
index 10b5825cdd6242031a0ab653709f500785db090a..ee74a0544084e68d0221796e1c780c305c02e5c6 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     struct A {
-        a: int,
+        a: isize,
         w: B,
     }
     struct B {
-        a: int
+        a: isize
     }
     let mut p = A {
         a: 1,
index 34ad2b2def03f82a5d4de6a5838ff9064ce50931..10e9a1b51e2d1f8a6a79144de873483305cfca8a 100644 (file)
@@ -9,9 +9,11 @@
 // except according to those terms.
 
 
-struct F { f: Vec<int> }
+// pretty-expanded FIXME #23616
 
-fn impure(_v: &[int]) {
+struct F { f: Vec<isize> }
+
+fn impure(_v: &[isize]) {
 }
 
 pub fn main() {
index 9fcd87418bee30a65e2db03a96c89c65fb4ac327..24c7285b1fb6fa960ffe5da9c7c2a182a688146f 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn borrow<F>(x: &int, f: F) where F: FnOnce(&int) {
+fn borrow<F>(x: &isize, f: F) where F: FnOnce(&isize) {
     f(x)
 }
 
-fn test1(x: &Box<int>) {
+fn test1(x: &Box<isize>) {
     borrow(&*(*x).clone(), |p| {
-        let x_a = &**x as *const int;
-        assert!((x_a as uint) != (p as *const int as uint));
+        let x_a = &**x as *const isize;
+        assert!((x_a as usize) != (p as *const isize as usize));
         assert_eq!(unsafe{*x_a}, *p);
     })
 }
index b7aa2989ac5820466348e361385130bfb5a8ae98..b716a1a27a1955fe6786741df62bf4aafc07d86e 100644 (file)
 // Test that freezing an `&mut` pointer while referent is
 // frozen is legal.
 //
-// Example from src/middle/borrowck/doc.rs
+// Example from src/librustc_borrowck/borrowck/README.md
 
-fn foo<'a>(mut t0: &'a mut int,
-           mut t1: &'a mut int) {
-    let p: &int = &*t0; // Freezes `*t0`
+// pretty-expanded FIXME #23616
+
+fn foo<'a>(mut t0: &'a mut isize,
+           mut t1: &'a mut isize) {
+    let p: &isize = &*t0; // Freezes `*t0`
     let mut t2 = &t0;
-    let q: &int = &**t2; // Freezes `*t0`, but that's ok...
-    let r: &int = &*t0; // ...after all, could do same thing directly.
+    let q: &isize = &**t2; // Freezes `*t0`, but that's ok...
+    let r: &isize = &*t0; // ...after all, could do same thing directly.
 }
 
 pub fn main() {
index c907778339ec50b64e72f42343c9b25321975bd1..6ccb2203bca8e4ce2a3c5e2215a0a30bdc0da836 100644 (file)
 // that the main function can read the variable too while
 // the closures are in scope. Issue #6801.
 
+// pretty-expanded FIXME #23616
+
 fn a() -> i32 {
-    let mut x = 3i32;
+    let mut x = 3;
     x += 1;
     let c1 = || x * 4;
     let c2 = || x * 5;
@@ -27,7 +29,7 @@ fn get(x: &i32) -> i32 {
 }
 
 fn b() -> i32 {
-    let mut x = 3i32;
+    let mut x = 3;
     x += 1;
     let c1 = || get(&x);
     let c2 = || get(&x);
@@ -35,7 +37,7 @@ fn b() -> i32 {
 }
 
 fn c() -> i32 {
-    let mut x = 3i32;
+    let mut x = 3;
     x += 1;
     let c1 = || x * 5;
     let c2 = || get(&x);
index 89d80190042c78784b327d0f18ed51029937f833..d97564a29144fed9851cbd4ff33a40b2e741ca85 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct A { a: int, b: Box<int> }
-struct B { a: Box<int>, b: Box<int> }
+struct A { a: isize, b: Box<isize> }
+struct B { a: Box<isize>, b: Box<isize> }
 
 fn move_after_copy() {
     let x = A { a: 1, b: box 2 };
@@ -270,4 +272,3 @@ fn main() {
     borrow_after_assign_after_uninit();
     move_after_assign_after_uninit();
 }
-
index ee561fdb0be522857bcdc0cb86c92a46ede28fd6..3f38a8df04c577adf3d6c940bd62ec7078c36d56 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = [22];
     let y = &x[0];
index 30a921c9bd24fcb4da5cc032970a8e14addffe09..eaa78553d85c50b272b64f7e6b9707578d0fbbd5 100644 (file)
 
 // Test that a `&mut` inside of an `&` is freezable.
 
+// pretty-expanded FIXME #23616
+
 struct MutSlice<'a, T:'a> {
     data: &'a mut [T]
 }
 
-fn get<'a, T>(ms: &'a MutSlice<'a, T>, index: uint) -> &'a T {
+fn get<'a, T>(ms: &'a MutSlice<'a, T>, index: usize) -> &'a T {
     &ms.data[index]
 }
 
index 9b8fa8f9f79b2a0e48a244c55ddcdc35409f0bc2..f1f0274c5cc4891d1d77cd6cc4e7317783d19132 100644 (file)
@@ -9,17 +9,19 @@
 // except according to those terms.
 
 
-fn borrow(_v: &int) {}
+// pretty-expanded FIXME #23616
 
-fn borrow_from_arg_imm_ref(v: Box<int>) {
+fn borrow(_v: &isize) {}
+
+fn borrow_from_arg_imm_ref(v: Box<isize>) {
     borrow(&*v);
 }
 
-fn borrow_from_arg_mut_ref(v: &mut Box<int>) {
+fn borrow_from_arg_mut_ref(v: &mut Box<isize>) {
     borrow(&**v);
 }
 
-fn borrow_from_arg_copy(v: Box<int>) {
+fn borrow_from_arg_copy(v: Box<isize>) {
     borrow(&*v);
 }
 
index ae5734a09b3cd6fe618680c883ece68cb567ab22..b40504f37d4d93f2e50706727b89abc2aebd5ddc 100644 (file)
 // Check that we do not ICE when compiling this
 // macro, which reuses the expression `$id`
 
+// pretty-expanded FIXME #23616
+
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
 struct Foo {
-  a: int
+  a: isize
 }
 
 pub enum Bar {
-  Bar1, Bar2(int, Box<Bar>),
+  Bar1, Bar2(isize, Box<Bar>),
 }
 
 impl Foo {
@@ -36,7 +38,7 @@ impl Foo {
     }
   }
 
-  fn check_id(&mut self, s: int) { panic!() }
+  fn check_id(&mut self, s: isize) { panic!() }
 }
 
 pub fn main() { }
index 1be57674fa1ff4ad9c981e3bd59c924029011e39..7c03c6a9a489cf0c0c2dc6f8a5af3da478f44fb7 100644 (file)
@@ -8,13 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 #![feature(unboxed_closures)]
 
 pub fn main() {
-    let bar = box 3;
-    let h = || -> int *bar;
+    let bar: Box<_> = box 3;
+    let h = || -> isize { *bar };
     assert_eq!(h(), 3);
 }
-
index 2dbaec8fbb16796e8d072f80aa8e73e005876c6e..f535c5fcfc90463164adf28afbbc819dad149d9d 100644 (file)
@@ -14,9 +14,9 @@
 use std::mem::swap;
 
 #[derive(Debug)]
-struct Ints {sum: Box<int>, values: Vec<int> }
+struct Ints {sum: Box<isize>, values: Vec<isize> }
 
-fn add_int(x: &mut Ints, v: int) {
+fn add_int(x: &mut Ints, v: isize) {
     *x.sum += v;
     let mut values = Vec::new();
     swap(&mut values, &mut x.values);
@@ -24,18 +24,18 @@ fn add_int(x: &mut Ints, v: int) {
     swap(&mut values, &mut x.values);
 }
 
-fn iter_ints<F>(x: &Ints, mut f: F) -> bool where F: FnMut(&int) -> bool {
+fn iter_ints<F>(x: &Ints, mut f: F) -> bool where F: FnMut(&isize) -> bool {
     let l = x.values.len();
-    (0_usize..l).all(|i| f(&x.values[i]))
+    (0..l).all(|i| f(&x.values[i]))
 }
 
 pub fn main() {
-    let mut ints = box Ints {sum: box 0, values: Vec::new()};
+    let mut ints: Box<_> = box Ints {sum: box 0, values: Vec::new()};
     add_int(&mut *ints, 22);
     add_int(&mut *ints, 44);
 
     iter_ints(&*ints, |i| {
-        println!("int = {:?}", *i);
+        println!("isize = {:?}", *i);
         true
     });
 
index 092d7c1317029be72ec0abe99ec82fcae68a08e0..4d37bcb5a489652a7091d23d942fb7d8ddca792b 100644 (file)
@@ -9,13 +9,15 @@
 // except according to those terms.
 
 
-fn want_slice(v: &[int]) -> int {
+// pretty-expanded FIXME #23616
+
+fn want_slice(v: &[isize]) -> isize {
     let mut sum = 0;
     for i in v { sum += *i; }
     sum
 }
 
-fn has_mut_vec(v: Vec<int> ) -> int {
+fn has_mut_vec(v: Vec<isize> ) -> isize {
     want_slice(&v)
 }
 
index 315f6c80d4e11cb36277ee10166394c68abaedcf..fa50eaa6a88c1d914dadaf48466a72e744765ff3 100644 (file)
 
 // Test that (safe) nested calls with `&mut` receivers are permitted.
 
-struct Foo {a: uint, b: uint}
+struct Foo {a: usize, b: usize}
 
 impl Foo {
-    pub fn inc_a(&mut self, v: uint) { self.a += v; }
+    pub fn inc_a(&mut self, v: usize) { self.a += v; }
 
-    pub fn next_b(&mut self) -> uint {
+    pub fn next_b(&mut self) -> usize {
         let b = self.b;
         self.b += 1;
         b
index 74ce8ef2e453162e18315081926b65adc525b25b..b29cb63f6fa3b3f42cf638570183aca77612f740 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty
 
-fn match_ref(v: Option<int>) -> int {
+fn match_ref(v: Option<isize>) -> isize {
     match v {
       Some(ref i) => {
         *i
@@ -19,24 +19,24 @@ fn match_ref(v: Option<int>) -> int {
     }
 }
 
-fn match_ref_unused(v: Option<int>) {
+fn match_ref_unused(v: Option<isize>) {
     match v {
       Some(_) => {}
       None => {}
     }
 }
 
-fn impure(_i: int) {
+fn impure(_i: isize) {
 }
 
-fn match_imm_reg(v: &Option<int>) {
+fn match_imm_reg(v: &Option<isize>) {
     match *v {
       Some(ref i) => {impure(*i)} // OK because immutable
       None => {}
     }
 }
 
-fn match_mut_reg(v: &mut Option<int>) {
+fn match_mut_reg(v: &mut Option<isize>) {
     match *v {
       Some(ref i) => {impure(*i)} // OK, frozen
       None => {}
index 4ccbf6b5b0fedfb65a0a91ca3dc823a732917b90..c3b69333dc5552e56f8528310e4a99b9f641725c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let mut x = None;
     match x {
index d4de4ef34d39729d821b2a535bd07741e3cc4676..1b20f6c706162a81f447011e475d736ee98b6b2f 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct Counter {
-    value: uint
+    value: usize
 }
 
 impl Counter {
-    fn new(v: uint) -> Counter {
+    fn new(v: usize) -> Counter {
         Counter {value: v}
     }
 
@@ -22,11 +24,11 @@ impl Counter {
         self
     }
 
-    fn get(&self) -> uint {
+    fn get(&self) -> usize {
         self.value
     }
 
-    fn get_and_inc(&mut self) -> uint {
+    fn get_and_inc(&mut self) -> usize {
         let v = self.value;
         self.value += 1;
         v
index 02c7dc38db00fe9198b8b6ce2d62396177044f8c..36a84a62d48fbebc251f83645bd2af75cd8affdb 100644 (file)
 // limited to the deref operation itself, and does not infect the
 // block as a whole.
 
+// pretty-expanded FIXME #23616
+
 struct Box {
-    x: uint
+    x: usize
 }
 
 impl Box {
-    fn get(&self) -> &uint {
+    fn get(&self) -> &usize {
         &self.x
     }
-    fn set(&mut self, x: uint) {
+    fn set(&mut self, x: usize) {
         self.x = x;
     }
 }
index 366752f46b003e7ad22e45ee7b634b49b0c7f977..d51d0b1d2e1fd50c769f6280827ddc5f3c35f512 100644 (file)
@@ -10,6 +10,8 @@
 
 // Regression test for issue #7740
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     static A: &'static char = &'A';
 }
index a2b0fa566353041f8f6bc5720cf4629a18a398a8..0bfa8f48650bb30c327c45ffe64573f6b3184ec3 100644 (file)
@@ -11,6 +11,8 @@
 // This test verifies that casting from the same lifetime on a value
 // to the same lifetime on a trait succeeds. See issue #10766.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 use std::marker;
index 84bd70c78d4871c2ed5550fddb94c117889b476c..0ec87599c6391eabef316244cfcdc8bbe77a6812 100644 (file)
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 struct Rec {
-    f: Box<int>,
+    f: Box<isize>,
 }
 
 struct Outer {
@@ -22,12 +24,12 @@ struct Inner {
 }
 
 struct Innermost {
-    h: Box<int>,
+    h: Box<isize>,
 }
 
-fn borrow(_v: &int) {}
+fn borrow(_v: &isize) {}
 
-fn box_mut(v: &mut Box<int>) {
+fn box_mut(v: &mut Box<isize>) {
     borrow(&**v); // OK: &mut -> &imm
 }
 
@@ -39,7 +41,7 @@ fn box_mut_recs(v: &mut Outer) {
     borrow(&*v.f.g.h); // OK: &mut -> &imm
 }
 
-fn box_imm(v: &Box<int>) {
+fn box_imm(v: &Box<isize>) {
     borrow(&**v); // OK
 }
 
index d95594119b6bceb131d38aa6bb3a88be3f958607..a5c68c5ecf97671d4f8584a5daa810da87de61ef 100644 (file)
@@ -9,11 +9,13 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 use std::cell::Cell;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum newtype {
-    newvar(int)
+    newvar(isize)
 }
 
 pub fn main() {
index 7be12ff3cc9657f50ee11af49eed99709fe104d1..7ad81b6be6ef54f44a6a44eb7831753ff4fb3ccf 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct A { a: int, b: Box<int> }
+struct A { a: isize, b: Box<isize> }
 
 fn field_copy_after_field_borrow() {
     let mut x = A { a: 1, b: box 2 };
@@ -57,4 +59,3 @@ fn main() {
     field_move_after_field_borrow();
     fu_field_move_after_field_borrow();
 }
-
index efd932933db333504992493df3a2457ff88f6f7d..aaf962577ff24cdd9541b70b11b92b2825538d32 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn foo(s: &String) -> bool {
     match &**s {
         "kitty" => true,
index 030e055c4ccb7e0b7042d0f65f5f4ad77f0d3ddf..c8cc29b9bdacb3b623d9b8b71674742044cd8164 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo<'r>(s: &'r uint) -> bool {
+// pretty-expanded FIXME #23616
+
+fn foo<'r>(s: &'r usize) -> bool {
     match s {
         &3 => true,
         _ => false
index e57c001ea05b4f99a7234399038ea4fc87a91f5f..69cb27dcf899e806ab8adc92e96ffd7562dfed0a 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let (&x, &y) = (&3, &'a');
     assert_eq!(x, 3);
index 9f17b9d7f95b5811ed82a74dd3cae7b2ac877317..14b6c32a11e51a360d0c6d85339c0eab71b5ed03 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn select<'r>(x: &'r Option<int>, y: &'r Option<int>) -> &'r Option<int> {
+// pretty-expanded FIXME #23616
+
+fn select<'r>(x: &'r Option<isize>, y: &'r Option<isize>) -> &'r Option<isize> {
     match (x, y) {
         (&None, &None) => x,
         (&Some(_), _) => x,
index 7ccb40c8e7b37b4475e735dce12ed6ae70cbee60..52322c41236b82504a01a1aca2d201f6135bd305 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn foo<T:Clone>(x: &T) -> T{
     match x {
         &ref a => (*a).clone()
index 168218e1b1e274698d2aeefd9b70aefc9c62844b..a2d76d33993bafa72d74dc23c0f094c31ebe76dd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let _a = Box::new(1);
 }
diff --git a/src/test/run-pass/box-of-array-of-drop-1.rs b/src/test/run-pass/box-of-array-of-drop-1.rs
new file mode 100644 (file)
index 0000000..a93a488
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright 2015 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 we cleanup a fixed size Box<[D; k]> properly when D has a
+// destructor.
+
+use std::thread;
+use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
+
+static LOG: AtomicUsize = ATOMIC_USIZE_INIT;
+
+struct D(u8);
+
+impl Drop for D {
+    fn drop(&mut self) {
+        println!("Dropping {}", self.0);
+        let old = LOG.load(Ordering::SeqCst);
+        LOG.compare_and_swap(old, old << 4 | self.0 as usize, Ordering::SeqCst);
+    }
+}
+
+fn main() {
+    fn die() -> D { panic!("Oh no"); }
+    let g = thread::spawn(|| {
+        let _b1: Box<[D; 4]> = Box::new([D( 1), D( 2), D( 3), D( 4)]);
+        let _b2: Box<[D; 4]> = Box::new([D( 5), D( 6), D( 7), D( 8)]);
+        let _b3: Box<[D; 4]> = Box::new([D( 9), D(10), die(), D(12)]);
+        let _b4: Box<[D; 4]> = Box::new([D(13), D(14), D(15), D(16)]);
+    });
+    assert!(g.join().is_err());
+
+    // When the panic occurs, we will be in the midst of constructing
+    // the input to `_b3`.  Therefore, we drop the elements of the
+    // partially filled array first, before we get around to dropping
+    // the elements of `_b1` and _b2`.
+
+    // Issue 23222: The order in which the elements actually get
+    // dropped is a little funky. See similar notes in nested-vec-3;
+    // in essence, I would not be surprised if we change the ordering
+    // given in `expect` in the future.
+
+    let expect = 0x__A_9__5_6_7_8__1_2_3_4;
+    let actual = LOG.load(Ordering::SeqCst);
+    assert!(actual == expect, "expect: 0x{:x} actual: 0x{:x}", expect, actual);
+}
diff --git a/src/test/run-pass/box-of-array-of-drop-2.rs b/src/test/run-pass/box-of-array-of-drop-2.rs
new file mode 100644 (file)
index 0000000..7155713
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright 2015 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 we cleanup dynamic sized Box<[D]> properly when D has a
+// destructor.
+
+use std::thread;
+use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
+
+static LOG: AtomicUsize = ATOMIC_USIZE_INIT;
+
+struct D(u8);
+
+impl Drop for D {
+    fn drop(&mut self) {
+        println!("Dropping {}", self.0);
+        let old = LOG.load(Ordering::SeqCst);
+        LOG.compare_and_swap(old, old << 4 | self.0 as usize, Ordering::SeqCst);
+    }
+}
+
+fn main() {
+    fn die() -> D { panic!("Oh no"); }
+    let g = thread::spawn(|| {
+        let _b1: Box<[D; 4]> = Box::new([D( 1), D( 2), D( 3), D( 4)]);
+        let _b2: Box<[D; 4]> = Box::new([D( 5), D( 6), D( 7), D( 8)]);
+        let _b3: Box<[D; 4]> = Box::new([D( 9), D(10), die(), D(12)]);
+        let _b4: Box<[D; 4]> = Box::new([D(13), D(14), D(15), D(16)]);
+    });
+    assert!(g.join().is_err());
+
+    // When the panic occurs, we will be in the midst of constructing
+    // the input to `_b3`.  Therefore, we drop the elements of the
+    // partially filled array first, before we get around to dropping
+    // the elements of `_b1` and _b2`.
+
+    // Issue 23222: The order in which the elements actually get
+    // dropped is a little funky. See similar notes in nested-vec-3;
+    // in essence, I would not be surprised if we change the ordering
+    // given in `expect` in the future.
+
+    let expect = 0x__A_9__5_6_7_8__1_2_3_4;
+    let actual = LOG.load(Ordering::SeqCst);
+    assert!(actual == expect, "expect: 0x{:x} actual: 0x{:x}", expect, actual);
+}
index efc3ab32a1a813841420ecd0895371040b715922..e5a035fb562b1054b911d47b62f7d0d18c9a5f6a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn int_id(x: int) -> int { return x; }
+// pretty-expanded FIXME #23616
+
+fn int_id(x: isize) -> isize { return x; }
 
 pub fn main() { loop { int_id(break); } }
index 6498c4b461def60ad1e3d8da878c76210e4e4342..80934c48515dc8ab72a2bf7d196b8d0737a71be0 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let mut i = 0;
     while i < 20 { i += 1; if i == 10 { break; } }
index a3bb02d1d0037835f8cb96ed1d03c7047b74e810..5467ed10e98ea1ca310050d9592298354bdbd20c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Speak : Sized {
     fn say(&self, s:&str) -> String;
     fn hi(&self) -> String { hello(self) }
@@ -17,7 +19,7 @@ fn hello<S:Speak>(s:&S) -> String{
     s.say("hello")
 }
 
-impl Speak for int {
+impl Speak for isize {
     fn say(&self, s:&str) -> String {
         format!("{}: {}", s, *self)
     }
@@ -37,8 +39,8 @@ pub fn main() {
     assert_eq!(3.hi(), "hello: 3".to_string());
     assert_eq!(Some(Some(3)).hi(),
                "something!something!hello: 3".to_string());
-    assert_eq!(None::<int>.hi(), "hello - none".to_string());
+    assert_eq!(None::<isize>.hi(), "hello - none".to_string());
 
-    assert_eq!(Some(None::<int>).hi(), "something!hello - none".to_string());
+    assert_eq!(Some(None::<isize>).hi(), "something!hello - none".to_string());
     assert_eq!(Some(3).hi(), "something!hello: 3".to_string());
 }
index 143ebfdabfacefd6ce8cd1fdc05c430860e7f5a2..89fd51bd5f1dc0d618905b3e2fb862630e4f0fae 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub trait Foo<T> {
     fn func1<U>(&self, t: U, w: T);
 
index 379ac12a95424c3ac1880e95e39121cd7c17dfe0..eb6d1028331be06b76f48ef8caeac3f7f8558537 100644 (file)
@@ -14,6 +14,8 @@
 // a Send. Basically this just makes sure rustc is using
 // each_bound_trait_and_supertraits in type_contents correctly.
 
+// pretty-expanded FIXME #23616
+
 use std::sync::mpsc::{channel, Sender};
 
 trait Bar : Send { }
index cd019c21a3d056f1ad291581de645f2ac1cd0448..082f5944fd3da60c1cb90de46b960b9148509ec5 100644 (file)
@@ -14,6 +14,8 @@
 // Tests "capabilities" granted by traits with super-builtin-kinds,
 // even when using them cross-crate.
 
+// pretty-expanded FIXME #23616
+
 extern crate trait_superkinds_in_metadata;
 
 use std::sync::mpsc::{channel, Sender, Receiver};
@@ -30,7 +32,7 @@ fn foo<T: RequiresRequiresShareAndSend + 'static>(val: T, chan: Sender<T>) {
 }
 
 pub fn main() {
-    let (tx, rx): (Sender<X<int>>, Receiver<X<int>>) = channel();
+    let (tx, rx): (Sender<X<isize>>, Receiver<X<isize>>) = channel();
     foo(X(31337), tx);
     assert!(rx.recv().unwrap() == X(31337));
 }
index dc61508eec4fabf7acbb7bc55c029588ca1d7ac1..594fb5ec7078035641d92dde36f6a02819a7934d 100644 (file)
@@ -12,6 +12,8 @@
 // builtin-kinds, e.g., if a trait requires Send to implement, then
 // at usage site of that trait, we know we have the Send capability.
 
+// pretty-expanded FIXME #23616
+
 use std::sync::mpsc::{channel, Sender, Receiver};
 
 trait Foo : Send { }
@@ -23,7 +25,7 @@ fn foo<T: Foo + 'static>(val: T, chan: Sender<T>) {
 }
 
 pub fn main() {
-    let (tx, rx): (Sender<int>, Receiver<int>) = channel();
+    let (tx, rx): (Sender<isize>, Receiver<isize>) = channel();
     foo(31337, tx);
     assert!(rx.recv().unwrap() == 31337);
 }
index 7eaed910124d91ea2b31a1134f9ceb481e1d1994..c026ffc6d318d76e1bcbedef18c823fb4464c47a 100644 (file)
 
 // Tests (correct) usage of trait super-builtin-kinds cross-crate.
 
+// pretty-expanded FIXME #23616
+
 extern crate trait_superkinds_in_metadata;
 use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare};
-use trait_superkinds_in_metadata::{RequiresCopy};
+use trait_superkinds_in_metadata::RequiresCopy;
 use std::marker;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct X<T>(T);
 
 impl<T:Sync> RequiresShare for X<T> { }
index 964c28dc94517a1d5da90bee404dcf02b0e4e236..6bc81f4a36bcddf56a22302b88ff80c91e11a2e4 100644 (file)
@@ -12,6 +12,8 @@
 // super-builtin-kind of a trait, if the type parameter is never used,
 // the type can implement the trait anyway.
 
+// pretty-expanded FIXME #23616
+
 use std::marker;
 
 trait Foo : Send { }
index 1d05a7baa5352b938af0eee830201e6b023263a2..924a8c023f8b6ea8935fa181d690aa0cc43f5b1c 100644 (file)
@@ -11,6 +11,8 @@
 // Tests the ability for the Self type in default methods to use
 // capabilities granted by builtin kinds as supertraits.
 
+// pretty-expanded FIXME #23616
+
 use std::sync::mpsc::{Sender, channel};
 
 trait Foo : Send + Sized + 'static {
index 9643e2986d2e59e26028c8603e1d6acab29496e8..8a954de9d0a451e41f8fb351d14384ae39229f06 100644 (file)
 
 // Simple test case of implementing a trait with super-builtin-kinds.
 
+// pretty-expanded FIXME #23616
+
 trait Foo : Send { }
 
-impl Foo for int { }
+impl Foo for isize { }
 
 pub fn main() { }
index d96679c69fd1b14fb87e4bdd8f6e54379608bd52..6d41774c05bf1543d1110e38cd7ce94c49d746d5 100644 (file)
@@ -11,6 +11,8 @@
 // Tests correct implementation of traits with super-builtin-kinds
 // using a bounded type parameter.
 
+// pretty-expanded FIXME #23616
+
 trait Foo : Send { }
 
 impl <T: Send> Foo for T { }
index aa88004cd11994a6a82ed20887f8d09484b9d0af..464c24fc8b0326dd0671f3f939e7245dce15f18c 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct X {
-    a: int
+    a: isize
 }
 
 trait Changer {
index 874dbdc662b2946023f0411681727345acd41132..fbe2a65bc893719e4fec693f056314704ed1aec4 100644 (file)
 
 static FOO: u8 = b'\xF0';
 static BAR: &'static [u8] = b"a\xF0\t";
+static BAR_FIXED: &'static [u8; 3] = b"a\xF0\t";
 static BAZ: &'static [u8] = br"a\n";
 
 pub fn main() {
+    let bar: &'static [u8] = b"a\xF0\t";
+    let bar_fixed: &'static [u8; 3] = b"a\xF0\t";
+
     assert_eq!(b'a', 97u8);
     assert_eq!(b'\n', 10u8);
     assert_eq!(b'\r', 13u8);
@@ -44,8 +48,11 @@ pub fn main() {
                  b", expected);
     let expected: &[_] = &[97u8, 240u8, 9u8];
     assert_eq!(BAR, expected);
+    assert_eq!(BAR_FIXED, expected);
+    assert_eq!(bar, expected);
+    assert_eq!(bar_fixed, expected);
 
-    let val: &[_] = &[97u8, 10u8];
+    let val = &[97u8, 10u8];
     match val {
         b"a\n" => {},
         _ => panic!(),
@@ -53,9 +60,9 @@ pub fn main() {
 
     let buf = vec!(97u8, 98, 99, 100);
     assert_eq!(match &buf[0..3] {
-         b"def" => 1_usize,
-         b"abc" => 2_usize,
-         _ => 3_usize
+         b"def" => 1,
+         b"abc" => 2,
+         _ => 3
     }, 2);
 
     let expected: &[_] = &[97u8, 92u8, 110u8];
index 6a1dde24d6850509e209c0fcf9a495aa2389bf04..b678f149fa240d4317f386840dbe1dbdc9ddf093 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 mod rustrt {
     extern crate libc;
 
index 6246ee9c6c41a9ad4bdcd7c94cc8c8a1dfa9c82f..dcf1b5540067e23d9cf8885a069d87b2770b49d9 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-fast doesn't like extern crate
+
+// pretty-expanded FIXME #23616
+
+#![feature(libc, std_misc)]
 
 extern crate libc;
 
@@ -23,9 +26,9 @@ mod mlibc {
     }
 }
 
-fn atol(s: String) -> int {
+fn atol(s: String) -> isize {
     let c = CString::new(s).unwrap();
-    unsafe { mlibc::atol(c.as_ptr()) as int }
+    unsafe { mlibc::atol(c.as_ptr()) as isize }
 }
 
 fn atoll(s: String) -> i64 {
index 29fcdf504de6e53ca6ef5219b3f1ed51e59b244b..e3ee282ec2a4ebc1dcdc2a9b67dd9f319d997b15 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo() -> int { 22 }
+// pretty-expanded FIXME #23616
+
+fn foo() -> isize { 22 }
 
 pub fn main() {
-    let mut x: Vec<extern "Rust" fn() -> int> = Vec::new();
+    let mut x: Vec<extern "Rust" fn() -> isize> = Vec::new();
     x.push(foo);
     assert_eq!((x[0])(), 22);
 }
index 099374b593781fefe8c55e0190c7bfca065c9a5d..31b279335225f011a6f82246661d7b276b5dbc85 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
@@ -21,5 +23,3 @@ fn can_copy_copy<T:Copy>(v: T) {
 }
 
 pub fn main() {}
-
-
index 631133cc7ff8b6150fdf2093489def64c865742a..d2eb5c33eae8087f14545317e94334367cfec071 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
index 1a85797fa6db53917f9e8c81f64eb7fb81f20020..5bf6f5fb04891a749c0464dcff4f37330dabbe14 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn each<T, F>(x: &[T], mut f: F) where F: FnMut(&T) {
     for val in x {
         f(val)
@@ -20,4 +22,3 @@ fn main() {
     each(&elems, |val| sum += *val);
     assert_eq!(sum, 15);
 }
-
index dd417f1a9eb73ad53fe6d1d0135a6cded719368a..448ed76fe96b984a278bc4168e0e6d3e976d83bb 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 fn each<'a,T,F:FnMut(&'a T)>(x: &'a [T], mut f: F) {
@@ -17,8 +19,8 @@ fn each<'a,T,F:FnMut(&'a T)>(x: &'a [T], mut f: F) {
 }
 
 fn main() {
-    let mut sum = 0_usize;
-    let elems = [ 1_usize, 2, 3, 4, 5 ];
-    each(&elems, |val: &uint| sum += *val);
+    let mut sum = 0;
+    let elems = [ 1, 2, 3, 4, 5 ];
+    each(&elems, |val: &usize| sum += *val);
     assert_eq!(sum, 15);
 }
index 70cc0463a6e11bd927f153491775d0f9b1d070e3..f9b429a935a6a676a553f031f29023c050cdbc5f 100644 (file)
 
 // exec-env:RUST_LOG=info
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, old_io, rustc_private, std_misc)]
 
 #[macro_use]
 extern crate log;
@@ -19,8 +21,8 @@ extern crate log;
 use log::{set_logger, Logger, LogRecord};
 use std::sync::mpsc::channel;
 use std::fmt;
-use std::old_io::{ChanReader, ChanWriter};
-use std::thread::Thread;
+use std::old_io::{ChanReader, ChanWriter, Reader, Writer};
+use std::thread;
 
 struct MyWriter(ChanWriter);
 
@@ -34,7 +36,7 @@ impl Logger for MyWriter {
 fn main() {
     let (tx, rx) = channel();
     let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         set_logger(box MyWriter(w) as Box<Logger+Send>);
         debug!("debug");
         info!("info");
index 717ca3ff9feccb24bd9d289a2e7dfa4e9af20eb1..6f1fafba563ab5937104156bca382b2494059dce 100644 (file)
 
 
 // issues #10618 and #16382
-const SIZE: int = 25;
+// pretty-expanded FIXME #23616
+
+const SIZE: isize = 25;
 
 fn main() {
-    let _a: [bool; 1 as uint];
-    let _b: [int; SIZE as uint] = [1; SIZE as uint];
-    let _c: [bool; '\n' as uint] = [true; '\n' as uint];
-    let _d: [bool; true as uint] = [true; true as uint];
+    let _a: [bool; 1 as usize];
+    let _b: [isize; SIZE as usize] = [1; SIZE as usize];
+    let _c: [bool; '\n' as usize] = [true; '\n' as usize];
+    let _d: [bool; true as usize] = [true; true as usize];
 }
index a298a08a1b7a099bcce4a7e20e38168a0269a735..f5180ea260f8d84cee9495b91ed0b84b24b56322 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 pub fn main() {
-    let x = 3;
-    println!("&x={:x}", (&x as *const int as uint));
+    let x: isize = 3;
+    println!("&x={:x}", (&x as *const isize as usize));
 }
index f8a680b2a97ac74b53e5439f3f2151df38681604..03a73555f856a20cbd4e62174a38f22004c3ce7b 100644 (file)
@@ -8,14 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let i: int = 'Q' as int;
+    let i: isize = 'Q' as isize;
     assert_eq!(i, 0x51);
     let u: u32 = i as u32;
     assert_eq!(u, 0x51 as u32);
     assert_eq!(u, 'Q' as u32);
     assert_eq!(i as u8, 'Q' as u8);
     assert_eq!(i as u8 as i8, 'Q' as u8 as i8);
-    assert_eq!(0x51u8 as char, 'Q');
+    assert_eq!(0x51 as char, 'Q');
     assert_eq!(0 as u32, false as u32);
 }
index 00c600ed006f87d8125fa0ba0da420e3cb526cf2..cd8f783a2e523ab2756e1414791ed09c11fa0c4b 100644 (file)
@@ -17,8 +17,8 @@ extern crate cci_borrow_lib;
 use cci_borrow_lib::foo;
 
 pub fn main() {
-    let p = box 22_usize;
+    let p: Box<_> = box 22;
     let r = foo(&*p);
     println!("r={}", r);
-    assert_eq!(r, 22_usize);
+    assert_eq!(r, 22);
 }
index 8b2947ba3eef03f4f94623648bc1b70d5db58747..80b75af6e441e915cf36f77aefcd62c4f2af8e32 100644 (file)
@@ -13,6 +13,8 @@
 // This test makes sure we can do cross-crate inlining on functions
 // that use capture clauses.
 
+// pretty-expanded FIXME #23616
+
 extern crate cci_capture_clause;
 
 pub fn main() {
index c4b55b9962fb65027cb8482197db1853c66329d7..bda3b73e29c4927a3e7908253771e45732c40eb7 100644 (file)
@@ -17,7 +17,7 @@ pub fn main() {
     //let bt0 = sys::frame_address();
     //println!("%?", bt0);
 
-    3_usize.to(10_usize, |i| {
+    3.to(10, |i| {
         println!("{}", i);
 
         //let bt1 = sys::frame_address();
index e4b26ba74be0215fc9e5d86a21f9e34daf3807ac..5b91af7a19431b2e364c48bf0e6bbc739aefdb18 100644 (file)
 extern crate cci_iter_lib;
 
 pub fn main() {
-    //let bt0 = sys::rusti::frame_address(1u32);
+    //let bt0 = sys::rusti::frame_address(1);
     //println!("%?", bt0);
     cci_iter_lib::iter(&[1, 2, 3], |i| {
         println!("{}", *i);
-        //assert!(bt0 == sys::rusti::frame_address(2u32));
+        //assert!(bt0 == sys::rusti::frame_address(2));
     })
 }
index 778e82a8fe599f481b0b00eb8ac850cfe5180b71..665469883043c793ad5fb8125034f5050c0e1e72 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:cci_nested_lib.rs
 
+// pretty-expanded FIXME #23616
+
 #![feature(globs)]
 
 extern crate cci_nested_lib;
index 2040bd7ad713236ded387435a86988648ff9d6e3..cc76ed530c4b5e7fa491f5fba62cbcfed3a13ed3 100644 (file)
@@ -21,7 +21,7 @@ pub fn main() {
     // actually working.
     //let bt0 = sys::frame_address();
     //println!("%?", bt0);
-    iter(vec!(1_usize, 2_usize, 3_usize), |i| {
+    iter(vec!(1, 2, 3), |i| {
         println!("{}", i);
 
         //let bt1 = sys::frame_address();
index ea1d0b625fcd757eab2b37ecc478b7f0d32194f5..c87a3e8bb93d607e1f26c31a4049e49e47f539bf 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::cell::Cell;
 
 #[derive(Copy)]
 struct Foo {
-    x: int
+    x: isize
 }
 
 impl Clone for Foo {
index 09ab70194864f1b6905858c6f2a866620128f451..74022d4c6c8390b76a4b713dae37caac5e1a0036 100644 (file)
@@ -11,5 +11,7 @@
 // main is conditionally compiled, but the conditional compilation
 // is conditional too!
 
+// pretty-expanded FIXME #23616
+
 #[cfg_attr(foo, cfg(bar))]
 fn main() { }
index e6bd8afad280b98e928883216ea6c851512280df..25d689475fb4b1673c13a3eecc2a5126dbabe9dc 100644 (file)
@@ -10,6 +10,8 @@
 
 // https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044
 
+// pretty-expanded FIXME #23616
+
 #![cfg_attr(not_used, no_std)]
 
 fn main() { }
index 24120b69c7f0cc5a67ff209386c2d58c17d86eaf..415607aa72bfc4c47a62879eae6b7d1e2a46034a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[cfg(windows)]
 pub fn main() {
 }
index aeb6fcbbc0f01fb63f9e28a03aa29606eec6b74f..5fa1bc47f877a24c778ad768e4ee3ed9113413ef 100644 (file)
@@ -13,6 +13,8 @@
 // check that cfg correctly chooses between the macro impls (see also
 // cfg-macros-notfoo.rs)
 
+// pretty-expanded FIXME #23616
+
 #[cfg(foo)]
 #[macro_use]
 mod foo {
index adc27d556227e3fb22b3bf10e4c1216f53b50c72..7cddac160319f23e4f722f195a7ace546923fbca 100644 (file)
@@ -13,6 +13,8 @@
 // check that cfg correctly chooses between the macro impls (see also
 // cfg-macros-foo.rs)
 
+// pretty-expanded FIXME #23616
+
 #[cfg(foo)]
 #[macro_use]
 mod foo {
index 02f02862f688415bfeb566880b518bf903691156..05dc7d52424b13c281f263e3cc12395aaaa68eaf 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Foo {
     Bar,
     Baz,
index 784c9326a0186756556b567c6ee591f8eef3abbc..b6954f7c2eeaf389c72332675e28bcfdd774161d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[cfg(target_family = "windows")]
 pub fn main() {
 }
index 04912fc20037a1bd26fb9b6dc60141a5d3fe7935..b3d5ddc4283083236d3f5fde5afd297b187cf802 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:cfg_inner_static.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate cfg_inner_static;
 
 pub fn main() {
index b7cf3c4d22a3f8e33d2e041bc54f798744b9f141..5c22d5c869042a198ea844e734df31756f713f67 100644 (file)
 // compile-flags: --cfg fooA --cfg fooB
 
 // fooA AND !bar
+// pretty-expanded FIXME #23616
+
 #[cfg(all(fooA, not(bar)))]
-fn foo1() -> int { 1 }
+fn foo1() -> isize { 1 }
 
 // !fooA AND !bar
 #[cfg(all(not(fooA), not(bar)))]
-fn foo2() -> int { 2 }
+fn foo2() -> isize { 2 }
 
 // fooC OR (fooB AND !bar)
 #[cfg(any(fooC, all(fooB, not(bar))))]
-fn foo2() -> int { 3 }
+fn foo2() -> isize { 3 }
 
 // fooA AND bar
 #[cfg(all(fooA, bar))]
-fn foo3() -> int { 2 }
+fn foo3() -> isize { 2 }
 
 // !(fooA AND bar)
 #[cfg(not(all(fooA, bar)))]
-fn foo3() -> int { 3 }
+fn foo3() -> isize { 3 }
 
 pub fn main() {
     assert_eq!(1, foo1());
index f982d3723b4c2091cbeeec84762026a01a118c14..801b01918e10339ccbc87aa5413ed3295595237d 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let c: char = 'x';
     let d: char = 'x';
index af25c43005dd4c2a7b9ca3428f39dacfc572ba3b..19c3458ef7b28fc52088d60fab9e950edf3df7be 100644 (file)
@@ -10,7 +10,9 @@
 
 // Checks that mutable static items can have mutable slices
 
-static mut TEST: &'static mut [int] = &mut [1];
+// pretty-expanded FIXME #23616
+
+static mut TEST: &'static mut [isize] = &mut [1];
 
 pub fn main() {
     unsafe {
index 4e05c263a48bafddc0486e40b311ae2e865d62a4..554853ade5be61956a12ff5fe91a8783d9e6cbaf 100644 (file)
@@ -12,7 +12,9 @@
 
 // aux-build:check_static_recursion_foreign_helper.rs
 
-#![feature(custom_attribute)]
+// pretty-expanded FIXME #23616
+
+#![feature(custom_attribute, libc)]
 
 extern crate check_static_recursion_foreign_helper;
 extern crate libc;
index 6e2cfedf9ec3ebed8eabf9d6a166043bf8ec3a17..8a7ae1de9bc70f2b40984afcdc9a2620cb500e1e 100644 (file)
 // Check that the various ways of getting to a reference to a vec (both sized
 // and unsized) work properly.
 
-const aa: [int; 3] = [1, 2, 3];
-const ab: &'static [int; 3] = &aa;
-const ac: &'static [int] = ab;
-const ad: &'static [int] = &aa;
-const ae: &'static [int; 3] = &[1, 2, 3];
-const af: &'static [int] = &[1, 2, 3];
+// pretty-expanded FIXME #23616
 
-static ca: int = aa[0];
-static cb: int = ab[1];
-static cc: int = ac[2];
-static cd: int = ad[0];
-static ce: int = ae[1];
-static cf: int = af[2];
+const aa: [isize; 3] = [1, 2, 3];
+const ab: &'static [isize; 3] = &aa;
+const ac: &'static [isize] = ab;
+const ad: &'static [isize] = &aa;
+const ae: &'static [isize; 3] = &[1, 2, 3];
+const af: &'static [isize] = &[1, 2, 3];
+
+static ca: isize = aa[0];
+static cb: isize = ab[1];
+static cc: isize = ac[2];
+static cd: isize = ad[0];
+static ce: isize = ae[1];
+static cf: isize = af[2];
 
 fn main () {
-    let b: &[int] = &[1, 2, 3];
+    let b: &[isize] = &[1, 2, 3];
     assert!(ac == b);
     assert!(ad == b);
     assert!(af == b);
index 39af96a58e6e3b10b38504eeae868dcfbbcb534f..7da1416602f6daec46d6961d456da65febc39cc8 100644 (file)
 
 // Reported as issue #126, child leaks the string.
 
-use std::thread::Thread;
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc)]
+
+use std::thread;
 
 fn child2(_s: String) { }
 
 pub fn main() {
-    let _x = Thread::spawn(move|| child2("hi".to_string()));
+    let _x = thread::spawn(move|| child2("hi".to_string()));
 }
index 9a388c9bc241d99d0dfc0c2db473bb8af978feb3..da51ad761c70a15db384c8ae3e606d94dffdd420 100644 (file)
@@ -25,6 +25,6 @@ fn print_out(thing: Box<ToString>, expected: String) {
 }
 
 pub fn main() {
-  let nyan: Box<ToString> = box cat(0_usize, 2, "nyan".to_string()) as Box<ToString>;
+  let nyan: Box<ToString> = box cat(0, 2, "nyan".to_string()) as Box<ToString>;
   print_out(nyan, "nyan".to_string());
 }
index 4f1654e60317a01a271091b952b10c49ab528074..e5acad3a3ad340847594f343960dbf32d07d2561 100644 (file)
 
 
 trait noisy {
-  fn speak(&mut self) -> int;
+  fn speak(&mut self) -> isize;
 }
 
 struct dog {
-  barks: uint,
+  barks: usize,
 
-  volume: int,
+  volume: isize,
 }
 
 impl dog {
-    fn bark(&mut self) -> int {
+    fn bark(&mut self) -> isize {
       println!("Woof {} {}", self.barks, self.volume);
       self.barks += 1_usize;
       if self.barks % 3_usize == 0_usize {
@@ -35,7 +35,7 @@ impl dog {
 }
 
 impl noisy for dog {
-    fn speak(&mut self) -> int {
+    fn speak(&mut self) -> isize {
         self.bark()
     }
 }
@@ -49,26 +49,26 @@ fn dog() -> dog {
 
 #[derive(Clone)]
 struct cat {
-  meows: uint,
+  meows: usize,
 
-  how_hungry: int,
+  how_hungry: isize,
   name: String,
 }
 
 impl noisy for cat {
-    fn speak(&mut self) -> int {
-        self.meow() as int
+    fn speak(&mut self) -> isize {
+        self.meow() as isize
     }
 }
 
 impl cat {
-    pub fn meow_count(&self) -> uint {
+    pub fn meow_count(&self) -> usize {
         self.meows
     }
 }
 
 impl cat {
-    fn meow(&mut self) -> uint {
+    fn meow(&mut self) -> usize {
         println!("Meow");
         self.meows += 1_usize;
         if self.meows % 5_usize == 0_usize {
@@ -78,7 +78,7 @@ impl cat {
     }
 }
 
-fn cat(in_x: uint, in_y: int, in_name: String) -> cat {
+fn cat(in_x: usize, in_y: isize, in_name: String) -> cat {
     cat {
         meows: in_x,
         how_hungry: in_y,
index 476594c270ec3a2ed781ac81d71abc06fd62754c..adb0b6cd0a75f9b658faff605cf99954edf33186 100644 (file)
@@ -16,8 +16,8 @@ trait noisy {
 }
 
 struct cat {
-  meows: uint,
-  how_hungry: int,
+  meows: usize,
+  how_hungry: isize,
   name: String,
 }
 
@@ -42,14 +42,14 @@ impl cat {
 impl cat {
     fn meow(&mut self) {
       println!("Meow");
-      self.meows += 1_usize;
-      if self.meows % 5_usize == 0_usize {
+      self.meows += 1;
+      if self.meows % 5 == 0 {
           self.how_hungry += 1;
       }
     }
 }
 
-fn cat(in_x : uint, in_y : int, in_name: String) -> cat {
+fn cat(in_x : usize, in_y : isize, in_name: String) -> cat {
     cat {
         meows: in_x,
         how_hungry: in_y,
@@ -59,7 +59,7 @@ fn cat(in_x : uint, in_y : int, in_name: String) -> cat {
 
 
 pub fn main() {
-    let mut nyan = cat(0_usize, 2, "nyan".to_string());
+    let mut nyan = cat(0, 2, "nyan".to_string());
     let mut nyan: &mut noisy = &mut nyan;
     nyan.speak();
 }
index 14247ad775487cc7f7dc9d0c6f41d8376608bd63..05ec2bc0ac75d202c21c3f10ac29302713acede0 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct cat {
-  done : extern fn(uint),
-  meows : uint,
+  done : extern fn(usize),
+  meows : usize,
 }
 
 impl Drop for cat {
@@ -19,9 +21,9 @@ impl Drop for cat {
     }
 }
 
-fn cat(done: extern fn(uint)) -> cat {
+fn cat(done: extern fn(usize)) -> cat {
     cat {
-        meows: 0_usize,
+        meows: 0,
         done: done
     }
 }
index 4c7d0e6951ab64c33749a94710b612bba065f7ea..675acf1dd62e09193b6a2a470ca0b4e4d047d006 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 /* Test that exporting a class also exports its
    public fields and methods */
 
@@ -16,7 +17,7 @@ use kitty::cat;
 
 mod kitty {
     pub struct cat {
-        meows: uint,
+        meows: usize,
         name: String,
     }
 
@@ -27,7 +28,7 @@ mod kitty {
     pub fn cat(in_name: String) -> cat {
         cat {
             name: in_name,
-            meows: 0_usize
+            meows: 0
         }
     }
 }
index c3ced512afae4c01beee22a193b1fae1d1ef43a2..4c494293b517edbf83ca7de7439ebf42347a4844 100644 (file)
 
 use std::cmp;
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 enum cat_type { tuxedo, tabby, tortoiseshell }
 
 impl cmp::PartialEq for cat_type {
     fn eq(&self, other: &cat_type) -> bool {
-        ((*self) as uint) == ((*other) as uint)
+        ((*self) as usize) == ((*other) as usize)
     }
     fn ne(&self, other: &cat_type) -> bool { !(*self).eq(other) }
 }
 
 // Very silly -- this just returns the value of the name field
-// for any int value that's less than the meows field
+// for any isize value that's less than the meows field
 
 // ok: T should be in scope when resolving the trait ref for map
 struct cat<T> {
     // Yes, you can have negative meows
-    meows : int,
+    meows : isize,
 
-    how_hungry : int,
+    how_hungry : isize,
     name : T,
 }
 
@@ -46,26 +46,26 @@ impl<T> cat<T> {
             return false;
         }
     }
-    fn len(&self) -> uint { self.meows as uint }
+    fn len(&self) -> usize { self.meows as usize }
     fn is_empty(&self) -> bool { self.meows == 0 }
     fn clear(&mut self) {}
-    fn contains_key(&self, k: &int) -> bool { *k <= self.meows }
+    fn contains_key(&self, k: &isize) -> bool { *k <= self.meows }
 
-    fn find(&self, k: &int) -> Option<&T> {
+    fn find(&self, k: &isize) -> Option<&T> {
         if *k <= self.meows {
             Some(&self.name)
         } else {
             None
         }
     }
-    fn insert(&mut self, k: int, _: T) -> bool {
+    fn insert(&mut self, k: isize, _: T) -> bool {
         self.meows += k;
         true
     }
 
-    fn find_mut(&mut self, _k: &int) -> Option<&mut T> { panic!() }
+    fn find_mut(&mut self, _k: &isize) -> Option<&mut T> { panic!() }
 
-    fn remove(&mut self, k: &int) -> bool {
+    fn remove(&mut self, k: &isize) -> bool {
         if self.find(k).is_some() {
             self.meows -= *k; true
         } else {
@@ -73,20 +73,20 @@ impl<T> cat<T> {
         }
     }
 
-    fn pop(&mut self, _k: &int) -> Option<T> { panic!() }
+    fn pop(&mut self, _k: &isize) -> Option<T> { panic!() }
 
-    fn swap(&mut self, _k: int, _v: T) -> Option<T> { panic!() }
+    fn swap(&mut self, _k: isize, _v: T) -> Option<T> { panic!() }
 }
 
 impl<T> cat<T> {
-    pub fn get(&self, k: &int) -> &T {
+    pub fn get(&self, k: &isize) -> &T {
         match self.find(k) {
           Some(v) => { v }
           None    => { panic!("epic fail"); }
         }
     }
 
-    pub fn new(in_x: int, in_y: int, in_name: T) -> cat<T> {
+    pub fn new(in_x: isize, in_y: isize, in_name: T) -> cat<T> {
         cat{meows: in_x, how_hungry: in_y, name: in_name }
     }
 }
index bd05221b8c7534142b7abadb4765d5fa8d019b3c..5a1dc930efa541c71037032cfd0c2b770a9e41ff 100644 (file)
@@ -13,9 +13,9 @@ extern crate cci_class_trait;
 use cci_class_trait::animals::noisy;
 
 struct cat {
-  meows: uint,
+  meows: usize,
 
-  how_hungry : int,
+  how_hungry : isize,
   name : String,
 }
 
@@ -47,7 +47,7 @@ impl cat {
     }
 }
 
-fn cat(in_x : uint, in_y : int, in_name: String) -> cat {
+fn cat(in_x : usize, in_y : isize, in_name: String) -> cat {
     cat {
         meows: in_x,
         how_hungry: in_y,
index 87e6e5f675e995332da759cfc4a24231eb32f9a3..394af6b9ecd51c972c1f4d6b513aef97375cf54f 100644 (file)
@@ -15,9 +15,9 @@ trait noisy {
 
 #[derive(Clone)]
 struct cat {
-    meows : uint,
+    meows : usize,
 
-    how_hungry : int,
+    how_hungry : isize,
     name : String,
 }
 
@@ -48,7 +48,7 @@ impl noisy for cat {
     fn speak(&mut self) { self.meow(); }
 }
 
-fn cat(in_x : uint, in_y : int, in_name: String) -> cat {
+fn cat(in_x : usize, in_y : isize, in_name: String) -> cat {
     cat {
         meows: in_x,
         how_hungry: in_y,
index 47cc500e44ecb1ff05c63652ec8c87727c85625d..a5c60e3a7b53c9b51ff06d55e93f856ac0cb1ac0 100644 (file)
@@ -9,12 +9,14 @@
 // except according to those terms.
 
 // aux-build:cci_class_2.rs
+// pretty-expanded FIXME #23616
+
 extern crate cci_class_2;
 use cci_class_2::kitties::cat;
 
 pub fn main() {
-  let nyan : cat = cat(52_usize, 99);
-  let kitty = cat(1000_usize, 2);
+  let nyan : cat = cat(52, 99);
+  let kitty = cat(1000, 2);
   assert_eq!(nyan.how_hungry, 99);
   assert_eq!(kitty.how_hungry, 2);
   nyan.speak();
index d62a726dcdd55bb6d077508c7560bf7f05f30807..73abaf7d34bb880122072f4f60d49603b628eb1d 100644 (file)
@@ -9,14 +9,16 @@
 // except according to those terms.
 
 // aux-build:cci_class_3.rs
+// pretty-expanded FIXME #23616
+
 extern crate cci_class_3;
 use cci_class_3::kitties::cat;
 
 pub fn main() {
-    let mut nyan : cat = cat(52_usize, 99);
-    let kitty = cat(1000_usize, 2);
+    let mut nyan : cat = cat(52, 99);
+    let kitty = cat(1000, 2);
     assert_eq!(nyan.how_hungry, 99);
     assert_eq!(kitty.how_hungry, 2);
     nyan.speak();
-    assert_eq!(nyan.meow_count(), 53_usize);
+    assert_eq!(nyan.meow_count(), 53);
 }
index 18fb03ec935ed59fc2ee67246da1ffed3bb0802a..d454bdd73a1ac4b3aefcdc8402fbd3aa51d492f7 100644 (file)
@@ -8,18 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct cat {
-  meows : uint,
+  meows : usize,
 
-  how_hungry : int,
+  how_hungry : isize,
 }
 
 impl cat {
-    pub fn speak(&mut self) { self.meows += 1_usize; }
-    pub fn meow_count(&mut self) -> uint { self.meows }
+    pub fn speak(&mut self) { self.meows += 1; }
+    pub fn meow_count(&mut self) -> usize { self.meows }
 }
 
-fn cat(in_x: uint, in_y: int) -> cat {
+fn cat(in_x: usize, in_y: isize) -> cat {
     cat {
         meows: in_x,
         how_hungry: in_y
@@ -27,10 +29,10 @@ fn cat(in_x: uint, in_y: int) -> cat {
 }
 
 pub fn main() {
-  let mut nyan: cat = cat(52_usize, 99);
-  let kitty = cat(1000_usize, 2);
+  let mut nyan: cat = cat(52, 99);
+  let kitty = cat(1000, 2);
   assert_eq!(nyan.how_hungry, 99);
   assert_eq!(kitty.how_hungry, 2);
   nyan.speak();
-  assert_eq!(nyan.meow_count(), 53_usize);
+  assert_eq!(nyan.meow_count(), 53);
 }
index edbbc4f5b342181dc85d39591065ab035de776a6..6537a931fa615a63b03979062ea4b0f3c47859b1 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // aux-build:cci_class_6.rs
+// pretty-expanded FIXME #23616
+
 extern crate cci_class_6;
 use cci_class_6::kitties::cat;
 
index b529b0a077210b62012c2e9c5697b06d6941b518..27f872d532c7900a41e6dc9a2c8022c1f5ec40bf 100644 (file)
@@ -9,21 +9,23 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 struct cat<U> {
     info : Vec<U> ,
-    meows : uint,
+    meows : usize,
 
-    how_hungry : int,
+    how_hungry : isize,
 }
 
 impl<U> cat<U> {
     pub fn speak<T>(&mut self, stuff: Vec<T> ) {
         self.meows += stuff.len();
     }
-    pub fn meow_count(&mut self) -> uint { self.meows }
+    pub fn meow_count(&mut self) -> usize { self.meows }
 }
 
-fn cat<U>(in_x : uint, in_y : int, in_info: Vec<U> ) -> cat<U> {
+fn cat<U>(in_x : usize, in_y : isize, in_info: Vec<U> ) -> cat<U> {
     cat {
         meows: in_x,
         how_hungry: in_y,
@@ -32,12 +34,12 @@ fn cat<U>(in_x : uint, in_y : int, in_info: Vec<U> ) -> cat<U> {
 }
 
 pub fn main() {
-  let mut nyan : cat<int> = cat::<int>(52_usize, 99, vec!(9));
-  let mut kitty = cat(1000_usize, 2, vec!("tabby".to_string()));
+  let mut nyan : cat<isize> = cat::<isize>(52, 99, vec!(9));
+  let mut kitty = cat(1000, 2, vec!("tabby".to_string()));
   assert_eq!(nyan.how_hungry, 99);
   assert_eq!(kitty.how_hungry, 2);
   nyan.speak(vec!(1,2,3));
-  assert_eq!(nyan.meow_count(), 55_usize);
+  assert_eq!(nyan.meow_count(), 55);
   kitty.speak(vec!("meow".to_string(), "mew".to_string(), "purr".to_string(), "chirp".to_string()));
-  assert_eq!(kitty.meow_count(), 1004_usize);
+  assert_eq!(kitty.meow_count(), 1004);
 }
index 575c32baeac24782509cec1adde66b5fe4b377af..52853658c825b2cd897d0d4e022150d6ed2beabe 100644 (file)
@@ -14,9 +14,9 @@
 use std::fmt;
 
 struct cat {
-    meows : uint,
+    meows : usize,
 
-    how_hungry : int,
+    how_hungry : isize,
     name : String,
 }
 
@@ -39,14 +39,14 @@ impl cat {
 impl cat {
     fn meow(&mut self) {
         println!("Meow");
-        self.meows += 1_usize;
-        if self.meows % 5_usize == 0_usize {
+        self.meows += 1;
+        if self.meows % 5 == 0 {
             self.how_hungry += 1;
         }
     }
 }
 
-fn cat(in_x : uint, in_y : int, in_name: String) -> cat {
+fn cat(in_x : usize, in_y : isize, in_name: String) -> cat {
     cat {
         meows: in_x,
         how_hungry: in_y,
@@ -54,7 +54,7 @@ fn cat(in_x : uint, in_y : int, in_name: String) -> cat {
     }
 }
 
-impl fmt::String for cat {
+impl fmt::Display for cat {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{}", self.name)
     }
@@ -67,6 +67,6 @@ fn print_out(thing: Box<ToString>, expected: String) {
 }
 
 pub fn main() {
-  let nyan: Box<ToString> = box cat(0_usize, 2, "nyan".to_string()) as Box<ToString>;
+  let nyan: Box<ToString> = box cat(0, 2, "nyan".to_string()) as Box<ToString>;
   print_out(nyan, "nyan".to_string());
 }
index 2fb8610092bf993859092ba881d1a1bd1806e805..e3b9b56db0b5bbcc510e9d2091f7819f509a46f8 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct cat {
 
   name : String,
index b56a749d33bb85d9fef9501a9f777ce55b7e81da..cc9a118ba19d1e37a5e643d7771a3b99ccaa6692 100644 (file)
@@ -8,20 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::marker::PhantomData;
 
 struct cat<U> {
-    meows : uint,
-    how_hungry : int,
+    meows : usize,
+    how_hungry : isize,
     m: PhantomData<U>
 }
 
 impl<U> cat<U> {
-    pub fn speak(&mut self) { self.meows += 1_usize; }
-    pub fn meow_count(&mut self) -> uint { self.meows }
+    pub fn speak(&mut self) { self.meows += 1; }
+    pub fn meow_count(&mut self) -> usize { self.meows }
 }
 
-fn cat<U>(in_x : uint, in_y : int) -> cat<U> {
+fn cat<U>(in_x : usize, in_y : isize) -> cat<U> {
     cat {
         meows: in_x,
         how_hungry: in_y,
@@ -31,6 +33,6 @@ fn cat<U>(in_x : uint, in_y : int) -> cat<U> {
 
 
 pub fn main() {
-  let _nyan : cat<int> = cat::<int>(52_usize, 99);
-  //  let mut kitty = cat(1000_usize, 2);
+  let _nyan : cat<isize> = cat::<isize>(52, 99);
+  //  let mut kitty = cat(1000, 2);
 }
index aae17abcc5fc65d901e4bdc921e141ff57c7d59c..36d7bd6b3ca480ead3adf6b4fef8298fbb0c9e37 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // aux-build:cci_class_4.rs
+// pretty-expanded FIXME #23616
+
 extern crate cci_class_4;
 use cci_class_4::kitties::cat;
 
index a54a821a7b9b47bef62c3551c9b3580362a0d3a8..487d20729d4e780e9bb18f5173a44c2227df2e3f 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 struct kitten {
     cat: Option<cat>,
 }
index 8037d77807d1d76e0397328d0911452cdd55e4f2..cfa13dbe622f7b4e1c0427ba3a0ef77946564539 100644 (file)
@@ -9,12 +9,14 @@
 // except according to those terms.
 
 // aux-build:cci_class.rs
+// pretty-expanded FIXME #23616
+
 extern crate cci_class;
 use cci_class::kitties::cat;
 
 pub fn main() {
-  let nyan : cat = cat(52_usize, 99);
-  let kitty = cat(1000_usize, 2);
+  let nyan : cat = cat(52, 99);
+  let kitty = cat(1000, 2);
   assert_eq!(nyan.how_hungry, 99);
   assert_eq!(kitty.how_hungry, 2);
 }
index b15d6544fed29ddea62df03404cf82d2ae6056bb..0d9f859d2d14dfde4e1fdb1bba9587aab2e8713a 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct cat {
-    meows : uint,
+    meows : usize,
 
-    how_hungry : int,
+    how_hungry : isize,
 }
 
 impl cat {
     pub fn speak(&mut self) {}
 }
 
-fn cat(in_x : uint, in_y : int) -> cat {
+fn cat(in_x : usize, in_y : isize) -> cat {
     cat {
         meows: in_x,
         how_hungry: in_y
@@ -26,8 +28,8 @@ fn cat(in_x : uint, in_y : int) -> cat {
 }
 
 pub fn main() {
-  let mut nyan : cat = cat(52_usize, 99);
-  let kitty = cat(1000_usize, 2);
+  let mut nyan : cat = cat(52, 99);
+  let kitty = cat(1000, 2);
   assert_eq!(nyan.how_hungry, 99);
   assert_eq!(kitty.how_hungry, 2);
   nyan.speak();
index 9bf8df3ce4bc99182b2778961fcff012ddffa7a0..f520623a75ab572a6d1f666c857b14594ea50749 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct cat {
-    meows : uint,
+    meows : usize,
 
-    how_hungry : int,
+    how_hungry : isize,
 }
 
-fn cat(in_x : uint, in_y : int) -> cat {
+fn cat(in_x : usize, in_y : isize) -> cat {
     cat {
         meows: in_x,
         how_hungry: in_y
@@ -22,8 +24,8 @@ fn cat(in_x : uint, in_y : int) -> cat {
 }
 
 pub fn main() {
-  let nyan : cat = cat(52_usize, 99);
-  let kitty = cat(1000_usize, 2);
+  let nyan : cat = cat(52, 99);
+  let kitty = cat(1000, 2);
   assert_eq!(nyan.how_hungry, 99);
   assert_eq!(kitty.how_hungry, 2);
 }
index 4fabca491be93f88eda6ef8005dad5934bd31280..fa0dda11233a80ad768877474882bdb7fd7bde4b 100644 (file)
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 struct cat {
-    meows : uint,
+    meows : usize,
 
-    how_hungry : int,
+    how_hungry : isize,
     name : String,
 }
 
@@ -40,7 +40,7 @@ impl cat {
     }
 }
 
-fn cat(in_x : uint, in_y : int, in_name: String) -> cat {
+fn cat(in_x : usize, in_y : isize, in_name: String) -> cat {
     cat {
         meows: in_x,
         how_hungry: in_y,
index 0d155ae085c73baa21e8d222ee1720fe214f7c18..b62f2b2a8eb8fe5d0d6a8e22300f132079251f6b 100644 (file)
 // Test that cleanup scope for temporaries created in a match
 // arm is confined to the match arm itself.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, os)]
 
 use std::os;
 
-struct Test { x: int }
+struct Test { x: isize }
 
 impl Test {
-    fn get_x(&self) -> Option<Box<int>> {
+    fn get_x(&self) -> Option<Box<isize>> {
         Some(box self.x)
     }
 }
 
-fn do_something(t: &Test) -> int {
+fn do_something(t: &Test) -> isize {
 
     // The cleanup scope for the result of `t.get_x()` should be the
     // arm itself and not the match, otherwise we'll (potentially) get
@@ -52,4 +54,3 @@ pub fn main() {
     let t = Test { x: 1 };
     do_something(&t);
 }
-
index 83f93cb81a1e6156d7354e9ae193d11eeaa92a43..1d0030fd3d362d4c7bead5141b055d4c804c71a3 100644 (file)
 // This test verifies that temporaries created for `while`'s and `if`
 // conditions are dropped after the condition is evaluated.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 struct Temporary;
 
-static mut DROPPED: int = 0;
+static mut DROPPED: isize = 0;
 
 impl Drop for Temporary {
     fn drop(&mut self) {
index 96ae7e3d3368f2fdc5abed5d7c8fbbbdd5f16e85..3b5421e5aff4c66c183b4bd591d9402808c4c15c 100644 (file)
@@ -24,6 +24,8 @@
 // It's unclear how likely such a bug is to recur, but it seems like a
 // scenario worth testing.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -33,17 +35,17 @@ enum Conzabble {
     Bickwick(Foo)
 }
 
-struct Foo { field: Box<uint> }
+struct Foo { field: Box<usize> }
 
-fn do_it(x: &[uint]) -> Foo {
+fn do_it(x: &[usize]) -> Foo {
     panic!()
 }
 
-fn get_bar(x: uint) -> Vec<uint> { vec!(x * 2) }
+fn get_bar(x: usize) -> Vec<usize> { vec!(x * 2) }
 
 pub fn fails() {
     let x = 2;
-    let mut y = Vec::new();
+    let mut y: Vec<Box<_>> = Vec::new();
     y.push(box Conzabble::Bickwick(do_it(&get_bar(x))));
 }
 
index 59f63a79c3ddf93ffb088eb06443566ba6f69aff..0cfe739018c85adf5c2896e7537741ca4bc5f41d 100644 (file)
@@ -20,6 +20,8 @@
 
 // Test that cleanups for the RHS of shortcircuiting operators work.
 
+// pretty-expanded FIXME #23616
+
 use std::env;
 
 pub fn main() {
@@ -33,7 +35,6 @@ pub fn main() {
 
     if args.len() >= 2 && args[1] == "signal" {
         // Raise a segfault.
-        unsafe { *(0 as *mut int) = 0; }
+        unsafe { *(0 as *mut isize) = 0; }
     }
 }
-
index 8eeae7a28ac8543978d2078df31d197c7a466f24..16efceb9d7e0e1db35803a9620b0c2639889f30c 100644 (file)
@@ -8,20 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, std_misc)]
 
-use std::thread::Thread;
+use std::thread;
 
 struct Pair {
-    a: int,
-    b: int
+    a: isize,
+    b: isize
 }
 
 pub fn main() {
-    let z = box Pair { a : 10, b : 12};
+    let z: Box<_> = box Pair { a : 10, b : 12};
 
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         assert_eq!(z.a, 10);
         assert_eq!(z.b, 12);
     });
index 816b28c3a9ae1e3b8e074a9a9e5c491c6ca743f1..dbbac8a16333b53311cdce899a2c880e548346b7 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 use std::sync::mpsc::channel;
index 3bd0273216de31e352315a0d7dd93e9dfa7272b5..06b6e1b5abeddb6bffd7163a08d80054fd1a7b5d 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 fn foo(i: isize) -> isize { i + 1 }
 
 fn apply<A, F>(f: F, v: A) -> A where F: FnOnce(A) -> A { f(v) }
index fa16ea001452c79a52e825264ed202193dd55ace..328a27b3f1e8a6735c19814239f362df5511bae7 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test a rather underspecified example:
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let f = {|i| i};
     assert_eq!(f(2), 2);
index a4495c3c68e8b37f443d2e45619d5a02eff68906..fefab45714f77f1e8c515b7b019e1a8d7517c6c9 100644 (file)
@@ -11,7 +11,7 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, old_io)]
 
 use std::mem;
 use std::old_io::stdio::println;
@@ -66,4 +66,3 @@ pub fn main() {
 
     call_bare_again(println);
 }
-
index fd040d109108fe173ceedc95a6bbe046babfe5b4..2b7557c7bc563910760aecb85b47ca616baa58cf 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::cmp::Ordering;
 
 // Test default methods in PartialOrd and PartialEq
@@ -22,7 +24,7 @@ impl PartialEq for Fool {
     }
 }
 
-struct Int(int);
+struct Int(isize);
 
 impl PartialEq for Int {
     fn eq(&self, other: &Int) -> bool {
@@ -40,7 +42,7 @@ impl PartialOrd for Int {
     }
 }
 
-struct RevInt(int);
+struct RevInt(isize);
 
 impl PartialEq for RevInt {
     fn eq(&self, other: &RevInt) -> bool {
index ee19d9e69b3018788b4abd0e534f0fa065375dc9..6926879856cbc639c9b52e40815d4d7b645ede7a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -17,25 +19,34 @@ use std::fmt::Debug;
 // rvalue expressions to be unsized. See #20169 for more information.
 
 pub fn main() {
-    let _: Box<[int]> = box { [1, 2, 3] };
-    let _: Box<[int]> = box if true { [1, 2, 3] } else { [1, 3, 4] };
-    let _: Box<[int]> = box match true { true => [1, 2, 3], false => [1, 3, 4] };
-    let _: Box<Fn(int) -> _> = box { |x| (x as u8) };
-    let _: Box<Debug> = box if true { false } else { true };
-    let _: Box<Debug> = box match true { true => 'a', false => 'b' };
-
-    let _: &[int] = &{ [1, 2, 3] };
-    let _: &[int] = &if true { [1, 2, 3] } else { [1, 3, 4] };
-    let _: &[int] = &match true { true => [1, 2, 3], false => [1, 3, 4] };
-    let _: &Fn(int) -> _ = &{ |x| (x as u8) };
+    // FIXME #22405: We cannot infer the type `Box<[isize; k]>` for
+    // the r-value expression from the context `Box<[isize]>`, and
+    // therefore the `box EXPR` desugaring breaks down.
+    //
+    // One could reasonably claim that the `box EXPR` desugaring is
+    // effectively regressing half of Issue #20169. Hopefully we will
+    // eventually fix that, at which point the `Box::new` calls below
+    // should be replaced wth uses of `box`.
+
+    let _: Box<[isize]> = Box::new({ [1, 2, 3] });
+    let _: Box<[isize]> = Box::new(if true { [1, 2, 3] } else { [1, 3, 4] });
+    let _: Box<[isize]> = Box::new(match true { true => [1, 2, 3], false => [1, 3, 4] });
+    let _: Box<Fn(isize) -> _> = Box::new({ |x| (x as u8) });
+    let _: Box<Debug> = Box::new(if true { false } else { true });
+    let _: Box<Debug> = Box::new(match true { true => 'a', false => 'b' });
+
+    let _: &[isize] = &{ [1, 2, 3] };
+    let _: &[isize] = &if true { [1, 2, 3] } else { [1, 3, 4] };
+    let _: &[isize] = &match true { true => [1, 2, 3], false => [1, 3, 4] };
+    let _: &Fn(isize) -> _ = &{ |x| (x as u8) };
     let _: &Debug = &if true { false } else { true };
     let _: &Debug = &match true { true => 'a', false => 'b' };
 
-    let _: Box<[int]> = Box::new([1, 2, 3]);
-    let _: Box<Fn(int) -> _> = Box::new(|x| (x as u8));
+    let _: Box<[isize]> = Box::new([1, 2, 3]);
+    let _: Box<Fn(isize) -> _> = Box::new(|x| (x as u8));
 
-    let _: Vec<Box<Fn(int) -> _>> = vec![
+    let _: Vec<Box<Fn(isize) -> _>> = vec![
         Box::new(|x| (x as u8)),
-        box |x| (x as i16 as u8),
+        Box::new(|x| (x as i16 as u8)),
     ];
 }
index 34c9875f1de733543b32d53101fd3dc80bc2f10e..c2f6b4c4ac446674347865327547a70cb503bbf7 100644 (file)
 
 // Check that coercions are propagated through match and if expressions.
 
+// pretty-expanded FIXME #23616
+
 use std::boxed::Box;
 
 pub fn main() {
-    let _: Box<[int]> = if true { Box::new([1, 2, 3]) } else { Box::new([1]) };
+    let _: Box<[isize]> = if true { Box::new([1, 2, 3]) } else { Box::new([1]) };
 
-    let _: Box<[int]> = match true { true => Box::new([1, 2, 3]), false => Box::new([1]) };
+    let _: Box<[isize]> = match true { true => Box::new([1, 2, 3]), false => Box::new([1]) };
 
     // Check we don't get over-keen at propagating coercions in the case of casts.
     let x = if true { 42 } else { 42u8 } as u16;
index 098a08b07871d29a274736e4b0fb50ebba987e85..6bf5c4d596f08ce1471d77696b574a22c3351ca0 100644 (file)
 
 // Check that coercions are propagated through match and if expressions.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let _: Box<[int]> = if true { box [1, 2, 3] } else { box [1] };
+    let _: Box<[isize]> =
+        if true { let b: Box<_> = box [1, 2, 3]; b } else { let b: Box<_> = box [1]; b };
 
-    let _: Box<[int]> = match true { true => box [1, 2, 3], false => box [1] };
+    let _: Box<[isize]> = match true {
+        true => { let b: Box<_> = box [1, 2, 3]; b }
+        false => { let b: Box<_> = box [1]; b }
+    };
 
     // Check we don't get over-keen at propagating coercions in the case of casts.
     let x = if true { 42 } else { 42u8 } as u16;
index ec8d58616dc0fc66c902c48226b32a1d0fdaeb59..a053311a0403e43bf1a3c9a056a51e739270f963 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::rc::Rc;
 
 // Examples from the "deref coercions" RFC, at rust-lang/rfcs#241.
index 0bbabcb859993007f39415a493b8ff7162c45210..581764d4a3b2f70309cace732c37278f2fbfddf7 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn negate(x: &int) -> int {
+// pretty-expanded FIXME #23616
+
+fn negate(x: &isize) -> isize {
     -*x
 }
 
-fn negate_mut(y: &mut int) -> int {
+fn negate_mut(y: &mut isize) -> isize {
     negate(y)
 }
 
-fn negate_imm(y: &int) -> int {
+fn negate_imm(y: &isize) -> isize {
     negate(y)
 }
 
index 419df84bdf55ba1b914b441cdb425d584ec399ef..6000b358acf263a9f525f00d8deb0b5a90a5371c 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct SpeechMaker {
-    speeches: uint
+    speeches: usize
 }
 
 impl SpeechMaker {
-    pub fn how_many(&self) -> uint { self.speeches }
+    pub fn how_many(&self) -> usize { self.speeches }
 }
 
-fn foo(speaker: &SpeechMaker) -> uint {
+fn foo(speaker: &SpeechMaker) -> usize {
     speaker.how_many() + 33
 }
 
index b6b30e2fe9b217230b2c72643de1cc53c9007974..1786d5b54f3a2ad92f77b0c7ab8781db68a61e74 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn sum(x: &[int]) -> int {
+// pretty-expanded FIXME #23616
+
+fn sum(x: &[isize]) -> isize {
     let mut sum = 0;
     for y in x { sum += *y; }
     return sum;
 }
 
-fn sum_mut(y: &mut [int]) -> int {
+fn sum_mut(y: &mut [isize]) -> isize {
     sum(y)
 }
 
-fn sum_imm(y: &[int]) -> int {
+fn sum_imm(y: &[isize]) -> isize {
     sum(y)
 }
 
index ade18a71259678de4440b813b2837659cfc358af..2e41ff3a56041f6ada1ff2e13dc13428e9ae9471 100644 (file)
@@ -9,16 +9,18 @@
 // except according to those terms.
 
 
-fn bar(v: &mut [uint]) -> Vec<uint> {
+// pretty-expanded FIXME #23616
+
+fn bar(v: &mut [usize]) -> Vec<usize> {
     v.to_vec()
 }
 
-fn bip(v: &[uint]) -> Vec<uint> {
+fn bip(v: &[usize]) -> Vec<usize> {
     v.to_vec()
 }
 
 pub fn main() {
-    let mut the_vec = vec!(1_usize, 2, 3, 100);
+    let mut the_vec = vec!(1, 2, 3, 100);
     assert_eq!(the_vec.clone(), bar(&mut the_vec));
     assert_eq!(the_vec.clone(), bip(&the_vec));
 }
index 4a680027b46e2adb91f70047567acd5fd1e992e3..b70146ea2d363c3bdfad3ad9725d971243a6cea3 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct SpeechMaker {
-    speeches: uint
+    speeches: usize
 }
 
 fn talk(x: &mut SpeechMaker) {
index 2f866955ff46cafcf836287e646e1859d9379e66..5f4cc569ac4e775836126f9098ac2670a026b069 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct SpeechMaker {
-    speeches: uint
+    speeches: usize
 }
 
 impl SpeechMaker {
index f87f2e07c9de0f0ee2507023a37286cb905f3bee..803f86e0fb1014f0178c73d57b3419b0a3a451e2 100644 (file)
@@ -9,11 +9,13 @@
 // except according to those terms.
 
 
-fn reverse(v: &mut [uint]) {
+// pretty-expanded FIXME #23616
+
+fn reverse(v: &mut [usize]) {
     v.reverse();
 }
 
-fn bar(v: &mut [uint]) {
+fn bar(v: &mut [usize]) {
     reverse(v);
     reverse(v);
     reverse(v);
@@ -22,5 +24,5 @@ fn bar(v: &mut [uint]) {
 pub fn main() {
     let mut the_vec = vec!(1, 2, 3, 100);
     bar(&mut the_vec);
-    assert_eq!(the_vec, vec!(100, 3, 2, 1));
+    assert_eq!(the_vec, [100, 3, 2, 1]);
 }
index 4f97e6a20815d0014f06a8581abac69b50d8f69e..a5fac127356c8f8f4e6456fde5dca2fe2c653aec 100644 (file)
@@ -9,7 +9,9 @@
 // except according to those terms.
 
 
-fn bar(v: &mut [uint]) {
+// pretty-expanded FIXME #23616
+
+fn bar(v: &mut [usize]) {
     v.reverse();
     v.reverse();
     v.reverse();
@@ -18,5 +20,5 @@ fn bar(v: &mut [uint]) {
 pub fn main() {
     let mut the_vec = vec!(1, 2, 3, 100);
     bar(&mut the_vec);
-    assert_eq!(the_vec, vec!(100, 3, 2, 1));
+    assert_eq!(the_vec, [100, 3, 2, 1]);
 }
index eeba9042f7c3fcfbb140ba359eef73364ce06f5b..2299a03b2a4234f47f7b36a655fc9151475a0491 100644 (file)
@@ -11,6 +11,8 @@
 // Check that coercions unify the expected return type of a polymorphic
 // function call, instead of leaving the type variables as they were.
 
+// pretty-expanded FIXME #23616
+
 struct Foo;
 impl Foo {
     fn foo<T>(self, x: T) -> Option<T> { Some(x) }
index baf2f57206d6ae2d28264998288f686797015962..9ad4f6b9d75c732c384efa422ee0cfb73575b6e5 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-extern crate "coherence-lib" as lib;
+// pretty-expanded FIXME #23616
+
+extern crate coherence_lib as lib;
 use lib::Remote1;
 
 pub struct BigInt;
index cdc5bc11716550cc7c463e3281a8c5fa6a0f6e1f..ac4b98cfc8c8186c5f4bf094fcf423fe7068dba5 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-extern crate "coherence-lib" as lib;
+// pretty-expanded FIXME #23616
+
+extern crate coherence_lib as lib;
 use lib::Remote1;
 
 pub struct BigInt;
index e02117d1ca261f02b0c751c43d6ddb5b8189a76b..32743aafa823669a2280ad55a8016d54ee6d9fe8 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-extern crate "coherence-lib" as lib;
+// pretty-expanded FIXME #23616
+
+extern crate coherence_lib as lib;
 use lib::Remote1;
 
 pub trait Local {
index 27f1f2dafb003628399c7cbfccdb9a5c0582ad97..890470d8ac242e5f51f721b1d889774a8c42b504 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-extern crate "coherence-lib" as lib;
+// pretty-expanded FIXME #23616
+
+extern crate coherence_lib as lib;
 use lib::Remote;
 
 struct Foo<T>(T);
diff --git a/src/test/run-pass/coherence-cow-1.rs b/src/test/run-pass/coherence-cow-1.rs
deleted file mode 100644 (file)
index b380372..0000000
+++ /dev/null
@@ -1,23 +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.
-
-// aux-build:coherence-lib.rs
-
-// Test that it's ok for T to appear first in the self-type, as long
-// as it's covered somewhere.
-
-extern crate "coherence-lib" as lib;
-use lib::{Remote,Pair};
-
-pub struct Cover<T>(T);
-
-impl<T> Remote for Pair<T,Cover<T>> { }
-
-fn main() { }
diff --git a/src/test/run-pass/coherence-cow-2.rs b/src/test/run-pass/coherence-cow-2.rs
deleted file mode 100644 (file)
index 93e507c..0000000
+++ /dev/null
@@ -1,23 +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.
-
-// aux-build:coherence-lib.rs
-
-// Test that it's ok for T to appear second in the self-type, as long
-// as it's covered somewhere.
-
-extern crate "coherence-lib" as lib;
-use lib::{Remote,Pair};
-
-pub struct Cover<T>(T);
-
-impl<T> Remote for Pair<Cover<T>,T> { }
-
-fn main() { }
index 6edd7390f0f31a37ad0cf088a3dec7ff0e2ec070..b0630b516407b60f3490ce6d3f2bb920c9bff545 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    #[derive(Copy)]
+    #[derive(Copy, Clone)]
     enum x { foo }
     impl ::std::cmp::PartialEq for x {
         fn eq(&self, other: &x) -> bool {
-            (*self) as int == (*other) as int
+            (*self) as isize == (*other) as isize
         }
         fn ne(&self, other: &x) -> bool { !(*self).eq(other) }
     }
index 6dc2ff4588b6788a27b7cdfdbdc4e74c6b449689..04a6cd58827893c14d6e95f2612a0df543e95248 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-extern crate "coherence-lib" as lib;
+// pretty-expanded FIXME #23616
+
+extern crate coherence_lib as lib;
 use lib::Remote1;
 
 struct Foo<T>(T);
index 7077503f73ff9353fc82f77d48039a8e82a8fa3e..8a3301dee273dbf32ef931a6b984a0d5d59ad309 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:coherence-lib.rs
+// aux-build:coherence_lib.rs
 
-extern crate "coherence-lib" as lib;
+// pretty-expanded FIXME #23616
+
+extern crate coherence_lib as lib;
 use lib::Remote1;
 
 struct Foo<T>(T);
diff --git a/src/test/run-pass/coherence-local-1.rs b/src/test/run-pass/coherence-local-1.rs
deleted file mode 100644 (file)
index a9bc3dc..0000000
+++ /dev/null
@@ -1,20 +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.
-
-// aux-build:coherence-lib.rs
-
-extern crate "coherence-lib" as lib;
-use lib::Remote;
-
-struct Local;
-
-impl Remote for Vec<Local> { }
-
-fn main() { }
diff --git a/src/test/run-pass/coherence-local-2.rs b/src/test/run-pass/coherence-local-2.rs
deleted file mode 100644 (file)
index 07a830c..0000000
+++ /dev/null
@@ -1,20 +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.
-
-// aux-build:coherence-lib.rs
-
-extern crate "coherence-lib" as lib;
-use lib::Remote;
-
-struct Local<T>(T);
-
-impl<T> Remote for Vec<Local<T>> { }
-
-fn main() { }
index 04a69bbf3a2bc1b1748db4324e605c193f1804f4..07477f96c0d3de7bb643c3effa3b566eb5ce02b6 100644 (file)
@@ -8,22 +8,24 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::fmt::Show;
+// pretty-expanded FIXME #23616
+
+use std::fmt::Debug;
 use std::default::Default;
 
 // Test that an impl for homogeneous pairs does not conflict with a
 // heterogeneous pair.
 
 trait MyTrait {
-    fn get(&self) -> uint;
+    fn get(&self) -> usize;
 }
 
 impl<T> MyTrait for (T,T) {
-    fn get(&self) -> uint { 0 }
+    fn get(&self) -> usize { 0 }
 }
 
-impl MyTrait for (uint,int) {
-    fn get(&self) -> uint { 0 }
+impl MyTrait for (usize,isize) {
+    fn get(&self) -> usize { 0 }
 }
 
 fn main() {
index 7844ef3faca458ae8869d6f0a364a68a18f9d803..2f42ab4988acee517a741140e767db8cdfdbdc83 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(optin_builtin_traits)]
 
 use std::marker::Send;
index 9f980e161b0cfe0e631e527266db3853bfab566b..8ab340d1bff6515ad0931da857016b824466f8d7 100644 (file)
@@ -25,7 +25,7 @@ impl<T> MyTrait for T
 
 #[derive(Clone, Copy, Debug, PartialEq)]
 struct MyType {
-    dummy: uint
+    dummy: usize
 }
 
 impl MyTrait for MyType {
diff --git a/src/test/run-pass/coherence_copy_like.rs b/src/test/run-pass/coherence_copy_like.rs
new file mode 100644 (file)
index 0000000..db98936
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2015 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 we are able to introduce a negative constraint that
+// `MyType: !MyTrait` along with other "fundamental" wrappers.
+
+// aux-build:coherence_copy_like_lib.rs
+
+extern crate coherence_copy_like_lib as lib;
+
+use std::marker::MarkerTrait;
+
+struct MyType { x: i32 }
+
+trait MyTrait : MarkerTrait { }
+impl<T: lib::MyCopy> MyTrait for T { }
+impl MyTrait for MyType { }
+impl<'a> MyTrait for &'a MyType { }
+impl MyTrait for Box<MyType> { }
+impl<'a> MyTrait for &'a Box<MyType> { }
+
+fn main() { }
index 841aaa94e9b552e9f4de847450136245e7dff80e..21ff6d6938a3b718bdb4261826054e795e1b5f8f 100644 (file)
@@ -8,14 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// no-pretty-expanded
-
-#![allow(unused_must_use, dead_code, deprecated)]
-use std::old_io::MemWriter;
+use std::io::Write;
 use std::fmt;
 
 struct Foo<'a> {
-    writer: &'a mut (Writer+'a),
+    writer: &'a mut (Write+'a),
     other: &'a str,
 }
 
@@ -32,8 +29,8 @@ fn borrowing_writer_from_struct_and_formatting_struct_field(foo: Foo) {
 }
 
 fn main() {
-    let mut w = MemWriter::new();
-    write!(&mut w as &mut Writer, "");
+    let mut w = Vec::new();
+    write!(&mut w as &mut Write, "");
     write!(&mut w, ""); // should coerce
     println!("ok");
 
index 16a21adc3fcf90067067a902b385128f267b4869..859599596ae7bc114ad03a74968137ae96717d6a 100644 (file)
@@ -8,19 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+#![feature(std_misc)]
+
+use std::thread;
 use std::sync::mpsc::{channel, Sender};
 
 pub fn main() {
     let (tx, rx) = channel();
-    let _t = Thread::spawn(move|| { child(&tx) });
+    let _t = thread::scoped(move|| { child(&tx) });
     let y = rx.recv().unwrap();
     println!("received");
     println!("{}", y);
     assert_eq!(y, 10);
 }
 
-fn child(c: &Sender<int>) {
+fn child(c: &Sender<isize>) {
     println!("sending");
     c.send(10).unwrap();
     println!("value sent");
index c6f4fecf8acc617e0779e59d26ddf32771702381..69945584876d08c51b61f84bf8149f11065e5182 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type an_int = int;
+// pretty-expanded FIXME #23616
 
-fn cmp(x: Option<an_int>, y: Option<int>) -> bool {
+type an_int = isize;
+
+fn cmp(x: Option<an_int>, y: Option<isize>) -> bool {
     x == y
 }
 
index f8c8ac20d72af92370db00d36e143a9dd6442d3f..6bb9503c2b0e4c0600dc9858e61e7dc14796739b 100644 (file)
 
 
 
-type t = int;
+type t = isize;
 
 fn nothing() { }
 
 fn putstr(_s: String) { }
 
-fn putint(_i: int) {
-    let mut i: int = 33;
+fn putint(_i: isize) {
+    let mut i: isize = 33;
     while i < 36 { putstr("hi".to_string()); i = i + 1; }
 }
 
-fn zerg(i: int) -> int { return i; }
+fn zerg(i: isize) -> isize { return i; }
 
-fn foo(x: int) -> int {
+fn foo(x: isize) -> isize {
     let mut y: t = x + 2;
     putstr("hello".to_string());
     while y < 10 { putint(y); if y * 3 == 4 { y = y + 2; nothing(); } }
@@ -35,7 +35,7 @@ fn foo(x: int) -> int {
 }
 
 pub fn main() {
-    let x: int = 2 + 2;
+    let x: isize = 2 + 2;
     println!("{}", x);
     println!("hello, world");
     println!("{}", 10);
index b0c3a5922b6344f86e7f7dbaf88ce44617569c73..7441d1f21b0f92bccb423c507430f7828d7e51da 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     assert_eq!(format!(concat!("foo", "bar", "{}"), "baz"), "foobarbaz".to_string());
     assert_eq!(format!(concat!()), "".to_string());
@@ -15,12 +17,12 @@ pub fn main() {
     assert_eq!(concat!("qux", "quux",).to_string(), "quxquux".to_string());
 
     assert_eq!(
-        concat!(1, 2, 3_usize, 4f32, 4.0, 'a', true),
+        concat!(1, 2, 3, 4f32, 4.0, 'a', true),
         "12344.0atrue"
     );
 
     assert!(match "12344.0atrue" {
-        concat!(1, 2, 3_usize, 4f32, 4.0, 'a', true) => true,
+        concat!(1, 2, 3, 4f32, 4.0, 'a', true) => true,
         _ => false
     })
 }
index 0e9447bd2497d2fe23510bc5c674f77ddae8e1c4..e51270fdc8d21f50a31a1a4db1c6f23536bd0dfc 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[cfg(target_arch = "x86")]
 pub fn main() { }
 
index 178fc3dcd4f0dd1474d43ae3ad2dfd289482a041..e6660bb9ae8802541a3e1cdb1ba91821e1110e4d 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -10,6 +9,8 @@
 // except according to those terms.
 
 // Crate use statements
+// pretty-expanded FIXME #23616
+
 #[cfg(bogus)]
 use flippity;
 
@@ -30,7 +31,7 @@ mod rustrt {
 }
 
 #[cfg(bogus)]
-type t = int;
+type t = isize;
 
 type t = bool;
 
@@ -41,21 +42,21 @@ enum tg { bar, }
 
 #[cfg(bogus)]
 struct r {
-  i: int,
+  i: isize,
 }
 
 #[cfg(bogus)]
-fn r(i:int) -> r {
+fn r(i:isize) -> r {
     r {
         i: i
     }
 }
 
 struct r {
-  i: int,
+  i: isize,
 }
 
-fn r(i:int) -> r {
+fn r(i:isize) -> r {
     r {
         i: i
     }
@@ -99,8 +100,8 @@ fn test_in_fn_ctxt() {
     f();
 
     #[cfg(bogus)]
-    static i: int = 0;
-    static i: int = 1;
+    static i: isize = 0;
+    static i: isize = 1;
     assert_eq!(i, 1);
 }
 
@@ -121,7 +122,7 @@ mod test_use_statements {
 
 mod test_methods {
     struct Foo {
-        bar: uint
+        bar: usize
     }
 
     impl Fooable for Foo {
index b5a5f57d07abda322171f642cf19c29b7a9eec5f..192e647f5cb209519ef567d2baf4890c30c13a61 100644 (file)
@@ -8,9 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: --cfg ndebug
+// compile-flags: -C debug-assertions=no
 // exec-env:RUST_LOG=conditional-debug-macro-off=4
 
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_private)]
+
 #[macro_use]
 extern crate log;
 
index 71312fb387845b54f5bf18f5cb129fc2c4420f86..1349b7f814bb00f48e84b318af385524a207af29 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 static A: [u8; 1] = ['h' as u8];
 static B: u8 = (&A)[0];
 static C: &'static &'static &'static &'static [u8; 1] = & & & &A;
index ca1d79e83e92c492dd3b374b2599f7d8e413a96a..158c695c548d2cb4867ca4eaf638987b7ea5a43e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Foo {
     Bar(u32),
     Baz,
index 1268fc4e4350c3f3269f0f38682bdbd6d9a1c670..1a95220cda59c4278250980f982e49556f08e412 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! assert_approx_eq {
     ($a:expr, $b:expr) => ({
         use std::num::Float;
@@ -17,40 +19,40 @@ macro_rules! assert_approx_eq {
     })
 }
 
-static A: int = -4 + 3;
-static A2: uint = 3 + 3;
+static A: isize = -4 + 3;
+static A2: usize = 3 + 3;
 static B: f64 = 3.0 + 2.7;
 
-static C: int = 3 - 4;
-static D: uint = 3 - 3;
+static C: isize = 3 - 4;
+static D: usize = 3 - 3;
 static E: f64 = 3.0 - 2.7;
 
-static E2: int = -3 * 3;
-static F: uint = 3 * 3;
+static E2: isize = -3 * 3;
+static F: usize = 3 * 3;
 static G: f64 = 3.3 * 3.3;
 
-static H: int = 3 / -1;
-static I: uint = 3 / 3;
+static H: isize = 3 / -1;
+static I: usize = 3 / 3;
 static J: f64 = 3.3 / 3.3;
 
 static N: bool = true && false;
 
 static O: bool = true || false;
 
-static P: int = 3 & 1;
-static Q: uint = 1 & 3;
+static P: isize = 3 & 1;
+static Q: usize = 1 & 3;
 
-static R: int = 3 | 1;
-static S: uint = 1 | 3;
+static R: isize = 3 | 1;
+static S: usize = 1 | 3;
 
-static T: int = 3 ^ 1;
-static U: uint = 1 ^ 3;
+static T: isize = 3 ^ 1;
+static U: usize = 1 ^ 3;
 
-static V: int = 1 << 3;
+static V: isize = 1 << 3;
 
 // NOTE: better shr coverage
-static W: int = 1024 >> 4;
-static X: uint = 1024 >> 4;
+static W: isize = 1024 >> 4;
+static X: usize = 1024 >> 4;
 
 static Y: bool = 1 == 1;
 static Z: bool = 1.0f64 == 1.0;
index 16360ff08d059af52a1be1772bd3d516a597c8f5..853e8dc62bb704ebd8a7b6c78188749daf6650db 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:cci_const_block.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate cci_const_block;
 
 pub fn main() {
index 03afe798954d514afe053882edf4b35b0028c0cb..b9e8dbf41d77ffaaa88cba51d3d7fa55531997d1 100644 (file)
 // General test that function items in static blocks
 // can be generated with a macro.
 
+// pretty-expanded FIXME #23616
+
 struct MyType {
     desc: &'static str,
-    data: uint,
-    code: fn(uint, uint) -> uint
+    data: usize,
+    code: fn(usize, usize) -> usize
 }
 
 impl MyType {
-    fn eval(&self, a: uint) -> uint {
+    fn eval(&self, a: usize) -> usize {
         (self.code)(self.data, a)
     }
 }
@@ -26,7 +28,7 @@ impl MyType {
 macro_rules! codegen {
     ($e:expr, $v:expr) => {
         {
-            fn generated(a: uint, b: uint) -> uint {
+            fn generated(a: usize, b: usize) -> usize {
                 a - ($e * b)
             }
             MyType {
index d55b420db083e28f882e112cbb4d4643a3ef1092..897e53822614de6e9f18cb5bff2bd78385fd1e90 100644 (file)
@@ -8,37 +8,39 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod foo {
     pub trait Value {
-        fn value(&self) -> uint;
+        fn value(&self) -> usize;
     }
 }
 
-static BLOCK_USE: uint = {
+static BLOCK_USE: usize = {
     use foo::Value;
     100
 };
 
-static BLOCK_PUB_USE: uint = {
+static BLOCK_PUB_USE: usize = {
     pub use foo::Value;
     200
 };
 
-static BLOCK_STRUCT_DEF: uint = {
+static BLOCK_STRUCT_DEF: usize = {
     struct Foo {
-        a: uint
+        a: usize
     }
     Foo{ a: 300 }.a
 };
 
-static BLOCK_FN_DEF: fn(uint) -> uint = {
-    fn foo(a: uint) -> uint {
+static BLOCK_FN_DEF: fn(usize) -> usize = {
+    fn foo(a: usize) -> usize {
         a + 10
     }
     foo
 };
 
-static BLOCK_MACRO_RULES: uint = {
+static BLOCK_MACRO_RULES: usize = {
     macro_rules! baz {
         () => (412)
     }
index cdb96e5dcbfcd166be6d8cf44d12b20b8e808cbb..1337a91fe05d69d9152b655880cf919d3fb549b8 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 #![allow(unused_unsafe)]
 
@@ -58,6 +60,6 @@ pub fn main() {
     assert_eq!(BLOCK_FN(300), 300);
     assert_eq!(BLOCK_ENUM_CONSTRUCTOR(200), Some(200));
     // FIXME #13972
-    // assert_eq!(BLOCK_UNSAFE_SAFE_PTR as *const isize as usize, 0xdeadbeef_us);
-    // assert_eq!(BLOCK_UNSAFE_SAFE_PTR_2 as *const isize as usize, 0xdeadbeef_us);
+    // assert_eq!(BLOCK_UNSAFE_SAFE_PTR as *const isize as usize, 0xdeadbeef);
+    // assert_eq!(BLOCK_UNSAFE_SAFE_PTR_2 as *const isize as usize, 0xdeadbeef);
 }
index 93a7d3e1c36aa1bf095a89ac9f313e0f1468e861..5c2985ffa777df9013da24bb5a7100399655d02f 100644 (file)
 // Make sure const bounds work on things, and test that a few types
 // are const.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 fn foo<T: Sync>(x: T) -> T { x }
 
-struct F { field: int }
+struct F { field: isize }
 
 pub fn main() {
     /*foo(1);
     foo("hi".to_string());
     foo(~[1, 2, 3]);
     foo(F{field: 42});
-    foo((1, 2_usize));
+    foo((1, 2));
     foo(@1);*/
-    foo(box 1);
+    foo(Box::new(1));
 }
index 50e460bd1798a79c5752c4bc62c6683e8c5d9e0a..bbe3020ea1c654f5e9a79cc5072b0640013fbd6c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::ptr;
 
 struct TestStruct {
index b7e9c0338dd6375fdd84d395e49ee1cce538d418..f660dc5fa450e312502f668eb6a940a8b334ade1 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 extern crate libc;
 
 struct TestStruct {
index ba2947f73679028fc9eac4af5cfb3b0d27491df7..d75a5a7eb1c3bc399c464d391868d0be21a71354 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const a: int = 1;
-const b: int = a + 2;
+// pretty-expanded FIXME #23616
+
+const a: isize = 1;
+const b: isize = a + 2;
 
 pub fn main() {
     assert_eq!(b, 3);
index 616826f9f950239423880b52e32523503d18240e..2dfb88dee0bb839d9597743591a95b1f8fe389e8 100644 (file)
 
 // Issue #570
 
-static lsl : int = 1 << 2;
-static add : int = 1 + 2;
+// pretty-expanded FIXME #23616
+
+static lsl : isize = 1 << 2;
+static add : isize = 1 + 2;
 static addf : f64 = 1.0 + 2.0;
-static not : int = !0;
+static not : isize = !0;
 static notb : bool = !true;
-static neg : int = -(1);
+static neg : isize = -(1);
 
 pub fn main() {
     assert_eq!(lsl, 4);
index bcf58431d0dcd4b5ab9ddf528f60032e280c0317..e36a55361ec2836adec06397a563e5d1b6067ac9 100644 (file)
 
 // aux-build:cci_const.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate cci_const;
 static foo: &'static str = cci_const::foopy;
-static a: uint = cci_const::uint_val;
-static b: uint = cci_const::uint_expr + 5;
+static a: usize = cci_const::uint_val;
+static b: usize = cci_const::uint_expr + 5;
 
 pub fn main() {
     assert_eq!(a, 12);
index a299c74aa5b065b34e186d6b39c726191788d000..98f42f91245cd571a742a3d2d1acedec510288f9 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:cci_const.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate cci_const;
 use cci_const::bar;
 static foo: extern "C" fn() = bar;
index 480fb50a1ffe5170d19f29e5e724f90c82c68c78..1648332fe2c392b15ffb343428f0093de9865bc8 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const C: &'static int = &1000;
-static D: int = *C;
+// pretty-expanded FIXME #23616
+
+const C: &'static isize = &1000;
+static D: isize = *C;
 
 pub fn main() {
     assert_eq!(D, 1000);
index 25145bf3638403cf724ca830acf77cb71f643c7f..e99e1aac8afdb7c4f795d4a3b843d7c6a203cf13 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum E { V, VV(int) }
+// pretty-expanded FIXME #23616
+
+enum E { V, VV(isize) }
 static C: E = E::V;
 
 impl E {
index bc5daf41646b8d413228fdf94fcc11ae459156c3..4905eaace68203507606d877f9736f7c7c645a20 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum E { V, VV(int) }
+// pretty-expanded FIXME #23616
+
+enum E { V, VV(isize) }
 static C: E = E::V;
 
 fn f(a: &E) {
index 966effab33e681640d505223e43043c6c4aa0e43..3d73933c6f638cfc15955eca4d151c7c23b08acd 100644 (file)
@@ -8,14 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum A { A1, A2 }
 enum B { B1=0, B2=2 }
 
 pub fn main () {
-    static c1: int = A::A2 as int;
-    static c2: int = B::B2 as int;
-    let a1 = A::A2 as int;
-    let a2 = B::B2 as int;
+    static c1: isize = A::A2 as isize;
+    static c2: isize = B::B2 as isize;
+    let a1 = A::A2 as isize;
+    let a2 = B::B2 as isize;
     assert_eq!(c1, 1);
     assert_eq!(c2, 2);
     assert_eq!(a1, 1);
index 0953f35e4483ed62fe09af0c0d1fae5a7a2fcf84..d34b5381df9bf63c26d2b2577fbbe91a1c488220 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum E { V0, V1(int) }
+// pretty-expanded FIXME #23616
+
+enum E { V0, V1(isize) }
 static C: &'static E = &E::V0;
 
 pub fn main() {
index 0c3656e193cb7d69ace3cf8a0433e5036e3d7d1a..71a9703ec311a3d5d35e6e38e95b4240c5bf5389 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum E { V16(u16), V32(u32) }
 struct S { a: E, b: u16, c: u16 }
 static C: S = S { a: E::V16(0xDEAD), b: 0x600D, c: 0xBAD };
index 6996da8bc37e290a40e01a7b8fa28d0704cf7f26..ca56cb5b01a99f36ac8d67ab2c5c7151f3c69e02 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum E { V0, V16(u16) }
 struct S { a: E, b: u16, c: u16 }
 static C: S = S { a: E::V0, b: 0x600D, c: 0xBAD };
index ac48752b0a944aef659bf9436c40fd8822217eed..113f20e21e1df48618ff0c2013cdc81c3db50e9b 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum E {
     S0 { s: String },
-    S1 { u: uint }
+    S1 { u: usize }
 }
 
 static C: E = E::S1 { u: 23 };
index 7ea5a3fed7655698557df8162f0d44edb9b93ea4..2ab28f5fb23773d116f71af115b3ec3c447f7608 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum E { V16(u16), V32(u32) }
 static C: (E, u16, u16) = (E::V16(0xDEAD), 0x600D, 0xBAD);
 
index 968c45a3298dba6f4aef22b271ff6699e8f5a007..fe1b2e051c479f190c375fe6747ddcb4d4380c24 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum E { V0, V16(u16) }
 static C: (E, u16, u16) = (E::V0, 0x600D, 0xBAD);
 
index 697321e0c77e4df6a3f1f115ad79e802ee9855b3..7f9de49404d3a8d9276732aaeabaadbb329bc186 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum E { V16(u16), V32(u32) }
 struct S(E, u16, u16);
 static C: S = S(E::V16(0xDEAD), 0x600D, 0xBAD);
index 254580c4e69d13895345c883d262e0a2ff918330..3d7b6c9f49f78670c1bcbd3726d6d1e73433cc73 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum E { V0, V16(u16) }
 struct S(E, u16, u16);
 static C: S = S(E::V0, 0x600D, 0xBAD);
index 4c8124d28a24157c02dbe6669849294674cce707..fcaf8b8844b079992dacfd8d68c01256ba852313 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum E { V1(int), V0 }
+// pretty-expanded FIXME #23616
+
+enum E { V1(isize), V0 }
 const C: &'static [E] = &[E::V0, E::V1(0xDEADBEE)];
 static C0: E = C[0];
 static C1: E = C[1];
index d5c299fd86eec6d085a691b4bc51464056ec06c7..936d72ac65e2f6e13f6758decee6d643a0d75dca 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum E { V1(int), V0 }
+// pretty-expanded FIXME #23616
+
+enum E { V1(isize), V0 }
 static C: &'static [E] = &[E::V0, E::V1(0xDEADBEE), E::V0];
 
 pub fn main() {
index 6eb5c2dab38ba17fa680da8e14ccc31705d16292..6fdf0c3948fa0584452c04e540696529e59e7f69 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum E { V1(int), V0 }
+// pretty-expanded FIXME #23616
+
+enum E { V1(isize), V0 }
 static C: [E; 3] = [E::V0, E::V1(0xDEADBEE), E::V0];
 
 pub fn main() {
index 6317c2eec1801b34bf2a678a2c797fb43cc8108e..6cf9239e2e4edb85b1b0e9ffb9caf31171c5cdf0 100644 (file)
 // Check that constant expressions can be used for declaring the
 // type of a fixed length vector.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
 
-    const FOO: uint = 2;
-    let _v: [int; FOO*3];
+    const FOO: usize = 2;
+    let _v: [isize; FOO*3];
 
 }
index 0b097c0b060ce741380202c21ea1682843aaae54..fc3e6749f6e3ff1a421b3e61fbba5b8f04c13960 100644 (file)
 
 // Check that constant expressions can be used in vec repeat syntax.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
 
-    const FOO: uint = 2;
+    const FOO: usize = 2;
     let _v = [0; FOO*3*2/2];
 
 }
index 069ca6ecf49dd4c3f1ef83212d7e7fef3beebfa0..ff829711a4c6c701aeab1f9490f006e4fe868580 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 extern fn foopy() {}
 
 static f: extern "C" fn() = foopy;
index 0819e0becbf9564cb1ac9738cc04147a65167182..55d6b60c192859bba6f20b6ff00f28994df2c473 100644 (file)
@@ -8,21 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const x : [int; 4] = [1,2,3,4];
-static p : int = x[2];
-const y : &'static [int] = &[1,2,3,4];
-static q : int = y[2];
+const x : [isize; 4] = [1,2,3,4];
+static p : isize = x[2];
+const y : &'static [isize] = &[1,2,3,4];
+static q : isize = y[2];
 
-struct S {a: int, b: int}
+struct S {a: isize, b: isize}
 
 const s : S = S {a: 10, b: 20};
-static t : int = s.b;
+static t : isize = s.b;
 
-struct K {a: int, b: int, c: D}
-struct D { d: int, e: int }
+struct K {a: isize, b: isize, c: D}
+struct D { d: isize, e: isize }
 
 const k : K = K {a: 10, b: 20, c: D {d: 30, e: 40}};
-static m : int = k.c.e;
+static m : isize = k.c.e;
 
 pub fn main() {
     println!("{}", p);
index 8394c53cba5cb44c19da054f3a99ce9dc51075d2..3e1058dc27d9937b9fd797dc55c7baf553a70e3e 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo() -> int {
+// pretty-expanded FIXME #23616
+
+fn foo() -> isize {
     return 0xca7f000d;
 }
 
-struct Bar<F> where F: FnMut() -> int { f: F }
+struct Bar<F> where F: FnMut() -> isize { f: F }
 
-static mut b : Bar<fn() -> int> = Bar { f: foo as fn() -> int};
+static mut b : Bar<fn() -> isize> = Bar { f: foo as fn() -> isize};
 
 pub fn main() {
     unsafe { assert_eq!((b.f)(), 0xca7f000d); }
index 4e2be013c11e4c3088cabdb358b8a10a078dd845..59b2c3e36aaf9bad4e57de11457ac6736466474c 100644 (file)
@@ -10,7 +10,9 @@
 
 // Issue #358
 
-static toplevel_mod: int = -1;
+// pretty-expanded FIXME #23616
+
+static toplevel_mod: isize = -1;
 
 pub fn main() {
     assert_eq!(toplevel_mod, -1);
index 5397a29311a01bd577ba3926fcc50155113c1a9c..fcad89470d7c52edfd16270bc88d53470ad0e17b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Foo {
     Bar,
     Baz,
index 86b194f2eb3419b1f99e46aa291bf1142c91ef98..51926ececc2b1ff654334608cd8018bcace33459 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy)]
+// pretty-expanded FIXME #23616
+
+#[derive(Copy, Clone)]
 enum Foo {
     Bar = 0xDEADBEE
 }
@@ -16,8 +18,8 @@ enum Foo {
 static X: Foo = Foo::Bar;
 
 pub fn main() {
-    assert_eq!((X as uint), 0xDEADBEE);
-    assert_eq!((Y as uint), 0xDEADBEE);
+    assert_eq!((X as usize), 0xDEADBEE);
+    assert_eq!((Y as usize), 0xDEADBEE);
 }
 
 static Y: Foo = Foo::Bar;
diff --git a/src/test/run-pass/const-polymorphic-paths.rs b/src/test/run-pass/const-polymorphic-paths.rs
deleted file mode 100644 (file)
index dce1203..0000000
+++ /dev/null
@@ -1,107 +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.
-
-#![feature(macro_rules)]
-
-use std::borrow::{Cow, IntoCow};
-use std::collections::BitVec;
-use std::default::Default;
-use std::iter::FromIterator;
-use std::ops::Add;
-use std::option::IntoIter as OptionIter;
-use std::rand::Rand;
-use std::rand::XorShiftRng as DummyRng;
-// FIXME the glob std::prelude::*; import of Vec is missing non-static inherent methods.
-use std::vec::Vec;
-
-#[derive(PartialEq, Eq)]
-struct Newt<T>(T);
-
-fn id<T>(x: T) -> T { x }
-fn eq<T: Eq>(a: T, b: T) -> bool { a == b }
-fn u8_as_i8(x: u8) -> i8 { x as i8 }
-fn odd(x: uint) -> bool { x % 2 == 1 }
-fn dummy_rng() -> DummyRng { DummyRng::new_unseeded() }
-
-trait Size: Sized {
-    fn size() -> uint { std::mem::size_of::<Self>() }
-}
-impl<T> Size for T {}
-
-macro_rules! tests {
-    ($($expr:expr, $ty:ty, ($($test:expr),*);)+) => (pub fn main() {$({
-        const C: $ty = $expr;
-        static S: $ty = $expr;
-        assert!(eq(C($($test),*), $expr($($test),*)));
-        assert!(eq(S($($test),*), $expr($($test),*)));
-        assert!(eq(C($($test),*), S($($test),*)));
-    })+})
-}
-
-tests! {
-    // Free function.
-    id, fn(int) -> int, (5);
-    id::<int>, fn(int) -> int, (5);
-
-    // Enum variant constructor.
-    Some, fn(int) -> Option<int>, (5);
-    Some::<int>, fn(int) -> Option<int>, (5);
-
-    // Tuple struct constructor.
-    Newt, fn(int) -> Newt<int>, (5);
-    Newt::<int>, fn(int) -> Newt<int>, (5);
-
-    // Inherent static methods.
-    Vec::new, fn() -> Vec<()>, ();
-    Vec::<()>::new, fn() -> Vec<()>, ();
-    Vec::with_capacity, fn(uint) -> Vec<()>, (5);
-    Vec::<()>::with_capacity, fn(uint) -> Vec<()>, (5);
-    BitVec::from_fn, fn(uint, fn(uint) -> bool) -> BitVec, (5, odd);
-    BitVec::from_fn::<fn(uint) -> bool>, fn(uint, fn(uint) -> bool) -> BitVec, (5, odd);
-
-    // Inherent non-static method.
-    Vec::map_in_place, fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>, (vec![b'f', b'o', b'o'], u8_as_i8);
-    Vec::map_in_place::<i8, fn(u8) -> i8>, fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>,
-        (vec![b'f', b'o', b'o'], u8_as_i8);
-    // FIXME these break with "type parameter might not appear here pointing at `<u8>`.
-    // Vec::<u8>::map_in_place: fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>
-    //    , (vec![b'f', b'o', b'o'], u8_as_i8);
-    // Vec::<u8>::map_in_place::<i8, fn(u8) -> i8>: fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>
-    //    , (vec![b'f', b'o', b'o'], u8_as_i8);
-
-    // Trait static methods.
-    <bool as Size>::size, fn() -> uint, ();
-    Default::default, fn() -> int, ();
-    <int as Default>::default, fn() -> int, ();
-    Rand::rand, fn(&mut DummyRng) -> int, (&mut dummy_rng());
-    <int as Rand>::rand, fn(&mut DummyRng) -> int, (&mut dummy_rng());
-    Rand::rand::<DummyRng>, fn(&mut DummyRng) -> int, (&mut dummy_rng());
-    <int as Rand>::rand::<DummyRng>, fn(&mut DummyRng) -> int, (&mut dummy_rng());
-
-    // Trait non-static methods.
-    Clone::clone, fn(&int) -> int, (&5);
-    <int as Clone>::clone, fn(&int) -> int, (&5);
-    FromIterator::from_iter, fn(OptionIter<int>) -> Vec<int>, (Some(5).into_iter());
-    <Vec<_> as FromIterator<_>>::from_iter, fn(OptionIter<int>) -> Vec<int>,
-        (Some(5).into_iter());
-    <Vec<int> as FromIterator<_>>::from_iter, fn(OptionIter<int>) -> Vec<int>,
-        (Some(5).into_iter());
-    FromIterator::from_iter::<OptionIter<int>>, fn(OptionIter<int>) -> Vec<int>,
-        (Some(5).into_iter());
-    <Vec<int> as FromIterator<_>>::from_iter::<OptionIter<int>>, fn(OptionIter<int>) -> Vec<int>,
-        (Some(5).into_iter());
-    Add::add, fn(i32, i32) -> i32, (5, 6);
-    <i32 as Add<_>>::add, fn(i32, i32) -> i32, (5, 6);
-    <i32 as Add<i32>>::add, fn(i32, i32) -> i32, (5, 6);
-    <String as IntoCow<_>>::into_cow, fn(String) -> Cow<'static, str>,
-        ("foo".to_string());
-    <String as IntoCow<'static, _>>::into_cow, fn(String) -> Cow<'static, str>,
-        ("foo".to_string());
-}
index e8081005d4a8ff4695ddc124e364ea86305fc53a..8932853fbf485911362de2c6f95f6b69163adb40 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 type Big = [u64; 8];
-struct Pair<'a> { a: int, b: &'a Big }
+struct Pair<'a> { a: isize, b: &'a Big }
 const x: &'static Big = &([13, 14, 10, 13, 11, 14, 14, 15]);
 const y: &'static Pair<'static> = &Pair {a: 15, b: x};
 
index e5d3f0ece0cf5b94a254c8c88363a63ebe345a2f..c783d4b8184782e82aebf58139a49780aaeed56d 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Pair<'a> { a: int, b: &'a int }
+struct Pair<'a> { a: isize, b: &'a isize }
 
-const x: &'static int = &10;
+const x: &'static isize = &10;
 
 const y: &'static Pair<'static> = &Pair {a: 15, b: x};
 
index e846501be6ee5fc64854843b5ad73a0b929e3fe2..c5ff134ff0e9bb6dcf23913ef4757efafb4d1148 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::{str, string};
 
 const A: [u8; 2] = ['h' as u8, 'i' as u8];
index 98dbf1eaa69a4ab2f1221f7c7719f2c2923dda7e..4f38a6431b8eaa00adbdd51b0f657df00b749054 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Foo {
     IntVal(i32),
     Int64Val(i64)
index 27c514160c069be271285c34875094ef5e751617..3cd58c6c52afbadf3e88f5850a08db044323ddd0 100644 (file)
@@ -11,7 +11,7 @@
 use std::cmp;
 
 #[derive(Debug)]
-struct foo { a: int, b: int, c: int }
+struct foo { a: isize, b: isize, c: isize }
 
 impl cmp::PartialEq for foo {
     fn eq(&self, other: &foo) -> bool {
index 54116dd4082ed96221fbd9cfbbcacddc03305715..ccf1b06bacb5fd3114f32f0a37b38da354d3f2fe 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Bar(int, int);
+// pretty-expanded FIXME #23616
+
+struct Bar(isize, isize);
 
 static X: Bar = Bar(1, 2);
 
index 7e6d9f0bee9b92e76509e1479c054def6ac79484..320f41006e569807c8ff2f2c0c6bd73334c5ada4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct Foo;
 
 static X: Foo = Foo;
index 4b07b1d3b076e72c226422ebf5e11eb97a6ff3a2..f16fbac00797a78efcdc3d6b3b8fef3ab72e542a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 /*!
  * Try to double-check that static fns have the right size (with or
  * without dummy env ptr, as appropriate) by iterating a size-2 array.
index c0566277e4eb16e330b57f9b83638c07409d395d..a577bbd82788690542ba7f5bcbef7596e0d8699e 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(_: &[int]) {}
+// pretty-expanded FIXME #23616
+
+fn f(_: &[isize]) {}
 
 pub fn main() {
     let v = [ 1, 2, 3 ];
index 26874b9f9d52dfc1744b9db85931e1f30216241c..758812054cd9b2d30092c9390e29a73d9bb6d4a1 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static x : [int; 4] = [1,2,3,4];
-static y : &'static [int] = &[1,2,3,4];
-static z : &'static [int; 4] = &[1,2,3,4];
-static zz : &'static [int] = &[1,2,3,4];
+static x : [isize; 4] = [1,2,3,4];
+static y : &'static [isize] = &[1,2,3,4];
+static z : &'static [isize; 4] = &[1,2,3,4];
+static zz : &'static [isize] = &[1,2,3,4];
 
 pub fn main() {
     println!("{}", x[1]);
index 8f78d54c7013714c202f879be5989afbe90bdbfe..95ae514636e5cc42957632ff02ecf4b7243bd6f7 100644 (file)
@@ -10,6 +10,6 @@
 
 
 
-static i: int = 10;
+static i: isize = 10;
 
 pub fn main() { println!("{}", i); }
index e8f4948a16533b245003da4c82d2269d4408e21f..c2f7cf4d6256806fd9c502688a744d45cf3e8761 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const FOO: int = 10;
-const BAR: int = 3;
+// pretty-expanded FIXME #23616
+
+const FOO: isize = 10;
+const BAR: isize = 3;
 
 pub fn main() {
-    let x: int = 3;
+    let x: isize = 3;
     let y = match x {
         FOO => 1,
         BAR => 2,
index 2b57c1ea0da693bfc6b77587cc3be19fa70f756b..5c5765454d457adefd99ef00949d845a7302099d 100644 (file)
 //
 // (Compare with compile-fail/move-out-of-array-1.rs)
 
-struct C { _x: u8 }
+// pretty-expanded FIXME #23616
 
-impl Copy for C { }
+#[derive(Copy, Clone)]
+struct C { _x: u8 }
 
 fn main() {
     fn d() -> C { C { _x: 0 } }
index 88d5b74708e623804d7e348a8658259c39344044..03bf3851257dfa10c1644e751d1e55acdb7d335b 100644 (file)
@@ -16,6 +16,7 @@
 // instead of in std.
 
 #![reexport_test_harness_main = "test_main"]
+#![feature(old_io, libc, std_misc)]
 
 extern crate libc;
 
@@ -23,7 +24,7 @@ use std::old_io::{Process, Command, timer};
 use std::time::Duration;
 use std::str;
 use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
 
 macro_rules! succeed { ($e:expr) => (
     match $e { Ok(..) => {}, Err(e) => panic!("panic: {}", e) }
@@ -51,7 +52,7 @@ pub fn sleeper() -> Process {
 
 fn test_destroy_twice() {
     let mut p = sleeper();
-    succeed!(p.signal_exit()); // this shouldnt crash...
+    succeed!(p.signal_exit()); // this shouldn't crash...
     let _ = p.signal_exit(); // ...and nor should this (and nor should the destructor)
 }
 
@@ -85,7 +86,7 @@ pub fn test_destroy_actually_kills(force: bool) {
     let (tx, rx1) = channel();
     let mut t = timer::Timer::new().unwrap();
     let rx2 = t.oneshot(Duration::milliseconds(1000));
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         select! {
             _ = rx2.recv() => unsafe { libc::exit(1) },
             _ = rx1.recv() => {}
index d8b3371325b2f4944774db5390848e583807dca8..ede78ff803d00d277d41800680539e3cd9ece161 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     use ::std::mem;
     mem::drop(2_usize);
index 1a3e87b55b64b5f5a438c8bceda395f08ed8dde5..43507f0cb00bd475f22978c4401168c169b6ab25 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -22,7 +24,7 @@ extern crate crate_method_reexport_grrrrrrr2;
 pub fn main() {
     use crate_method_reexport_grrrrrrr2::rust::add;
     use crate_method_reexport_grrrrrrr2::rust::cx;
-    let x = box() ();
+    let x: Box<_> = box () ();
     x.cx();
     let y = ();
     y.add("hi".to_string());
index f04a760e5f65172e48289c7224a836df4caa86da..a108f4dc5687469f54a1879ab6d0ed8f2c8c02d7 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:--crate-name crate-name-attr-used -F unused-attributes
+// compile-flags:--crate-name crate_name_attr_used -F unused-attributes
 
-#![crate_name = "crate-name-attr-used"]
+// pretty-expanded FIXME #23616
+
+#![crate_name = "crate_name_attr_used"]
 
 fn main() {}
index 14be5773e84db4c53425045b820dd6250dc53195..a85541bb8ba5ff206f79486e707a56517975c86d 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:cci_const.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate cci_const;
 
 pub fn main() {
index c2083c8e705eecb18eb86421b5558568bd739960..986108c5d8fa666c23b2f70702ababb2a5afc855 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:newtype_struct_xc.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate newtype_struct_xc;
 
 pub fn main() {
diff --git a/src/test/run-pass/cycle-generic-bound.rs b/src/test/run-pass/cycle-generic-bound.rs
new file mode 100644 (file)
index 0000000..94e4665
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+// Regression test for #15477. This test just needs to compile.
+
+// pretty-expanded FIXME #23616
+
+use std::marker::PhantomFn;
+
+trait Chromosome<X: Chromosome<i32>> : PhantomFn<(Self,X)> {
+}
+
+fn main() { }
diff --git a/src/test/run-pass/cycle-trait-type-trait.rs b/src/test/run-pass/cycle-trait-type-trait.rs
new file mode 100644 (file)
index 0000000..50bc9e9
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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 a case where a supertrait references a type that references
+// the original trait. This poses no problem at the moment.
+
+// pretty-expanded FIXME #23616
+
+trait Chromosome: Get<Struct<i32>> {
+}
+
+trait Get<A> {
+    fn get(&self) -> A;
+}
+
+struct Struct<C:Chromosome> { c: C }
+
+fn main() { }
index b588ea9cfd025d76ac0114e0129f6c6d7ca3ab08..6e3f8a288129c04a3adf7d5d2962518a443c5706 100644 (file)
@@ -8,14 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![deny(dead_code)]
 
-static _X: uint = 0;
+static _X: usize = 0;
 
 fn _foo() {}
 
 struct _Y {
-    _z: uint
+    _z: usize
 }
 
 enum _Z {}
@@ -24,7 +26,7 @@ impl _Y {
     fn _bar() {}
 }
 
-type _A = int;
+type _A = isize;
 
 mod _bar {
     fn _qux() {}
index 2f82e729adf584a3ad24c8c4732aa8d230bd1127..16636fadbf8dc1ebe048092edbf3dc9649d9c560 100644 (file)
 
 
 
-fn f(x: int) -> int {
-    if x == 1 { return 1; } else { let y: int = 1 + f(x - 1); return y; }
+// pretty-expanded FIXME #23616
+
+fn f(x: isize) -> isize {
+    if x == 1 { return 1; } else { let y: isize = 1 + f(x - 1); return y; }
 }
 
 pub fn main() { assert!((f(5000) == 5000)); }
index 639ea59585efaf1e17161b5d4661a5c2c62a5d44..5ccb66a76bf76cd076ce171fbe5cb1afe2717caa 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
-    fn m(&self, _:int) { }
+    fn m(&self, _:isize) { }
 }
 
 pub fn main() { }
index 547f342243c2bc2de0d6fd0b76010bc4d4af055d..61de804a80a81100dc4e6c368cdb2a8690a7cfe6 100644 (file)
@@ -18,7 +18,7 @@ trait Foo {
 }
 
 struct A {
-    x: int
+    x: isize
 }
 
 impl Foo for A {
index 727cada21fa66549304cf788e1fbed9b4c3841d5..3b1e04be78d48d220bb8186715e49b19f65f1b1d 100644 (file)
 // Tests that we can call a function bounded over a supertrait from
 // a default method
 
-fn require_y<T: Y>(x: T) -> int { x.y() }
+fn require_y<T: Y>(x: T) -> isize { x.y() }
 
 trait Y {
-    fn y(self) -> int;
+    fn y(self) -> isize;
 }
 
 
 trait Z: Y + Sized {
-    fn x(self) -> int {
+    fn x(self) -> isize {
         require_y(self)
     }
 }
 
-impl Y for int {
-    fn y(self) -> int { self }
+impl Y for isize {
+    fn y(self) -> isize { self }
 }
 
-impl Z for int {}
+impl Z for isize {}
 
 pub fn main() {
     assert_eq!(12.x(), 12);
diff --git a/src/test/run-pass/deprecated-derive.rs b/src/test/run-pass/deprecated-derive.rs
new file mode 100644 (file)
index 0000000..494d62c
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2015 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.
+
+#[derive(Show)]
+//~^ WARNING derive(Show) is deprecated
+struct Test1;
+
+fn main() { }
diff --git a/src/test/run-pass/deprecated-no-split-stack.rs b/src/test/run-pass/deprecated-no-split-stack.rs
deleted file mode 100644 (file)
index 31ba5dd..0000000
+++ /dev/null
@@ -1,14 +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.
-
-//~ WARNING no_split_stack is a deprecated synonym for no_stack_check
-#[no_split_stack]
-fn main() {
-}
index 41c74250b3b0ef0a7ebfecb6cd900f3ded848553..fc97b22a4a99e3cedd167e1789ca91091854e4b6 100644 (file)
@@ -14,7 +14,7 @@
 use std::cell::Cell;
 
 pub fn main() {
-    let x = box Cell::new(5);
+    let x: Box<_> = box Cell::new(5);
     x.set(1000);
     println!("{}", x.get());
 }
index f43be17786299ec00c8985306c3529fc5e67c258..8820003d3b24dc5d12932445ac8ebd1130d21e11 100644 (file)
 
 // Test that `&mut T` implements `DerefMut<T>`
 
+// pretty-expanded FIXME #23616
+
 use std::ops::{Deref, DerefMut};
 
-fn inc<T: Deref<Target=int> + DerefMut>(mut t: T) {
+fn inc<T: Deref<Target=isize> + DerefMut>(mut t: T) {
     *t += 1;
 }
 
 fn main() {
-    let mut x: int = 5;
+    let mut x: isize = 5;
     inc(&mut x);
     assert_eq!(x, 6);
 }
index e95d942c8cf73c89a404aad4f7834b16a99faeae..84bfbd82297a7c763abc99fbefa0f4fd4a0722fd 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test that `&T` and `&mut T` implement `Deref<T>`
 
+// pretty-expanded FIXME #23616
+
 use std::ops::Deref;
 
 fn deref<U:Copy,T:Deref<Target=U>>(t: T) -> U {
@@ -17,11 +19,11 @@ fn deref<U:Copy,T:Deref<Target=U>>(t: T) -> U {
 }
 
 fn main() {
-    let x: int = 3;
+    let x: isize = 3;
     let y = deref(&x);
     assert_eq!(y, 3);
 
-    let mut x: int = 4;
+    let mut x: isize = 4;
     let y = deref(&mut x);
     assert_eq!(y, 4);
 }
index fbb8a3a1720f903ecc79b68c19fc9644e8ab9192..761b29258f2af0a995201462ed7dd71aef753b9e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::rc::Rc;
 
 fn main() {
index b4ee0246d87805ae4b06e22e5339db2a24e0001d..4722ddd64c8e4d561541826c6f6c2530f5bd52ec 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let x: Box<int> = box 10;
-    let _y: int = *x;
+    let x: Box<isize> = box 10;
+    let _y: isize = *x;
 }
index d3034c2d48529dfa21ed85c3fc4a4627a521b6c4..fbc6c28fd4a580e6e43e208aa5cdbe385d3cd773 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(no_std)]
+#![feature(no_std, core, rand, collections, rustc_private)]
 #![no_std]
 
 extern crate core;
 extern crate rand;
-extern crate "serialize" as rustc_serialize;
+extern crate serialize as rustc_serialize;
 extern crate collections;
 
 // Issue #16803
diff --git a/src/test/run-pass/deriving-associated-types.rs b/src/test/run-pass/deriving-associated-types.rs
new file mode 100644 (file)
index 0000000..59eb550
--- /dev/null
@@ -0,0 +1,210 @@
+// Copyright 2015 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(core, debug_builders)]
+
+pub trait DeclaredTrait {
+    type Type;
+}
+
+impl DeclaredTrait for i32 {
+    type Type = i32;
+}
+
+pub trait WhereTrait {
+    type Type;
+}
+
+impl WhereTrait for i32 {
+    type Type = i32;
+}
+
+// Make sure we don't add a bound that just shares a name with an associated
+// type.
+pub mod module {
+    pub type Type = i32;
+}
+
+#[derive(PartialEq, Debug)]
+struct PrivateStruct<T>(T);
+
+#[derive(PartialEq, Debug)]
+struct TupleStruct<A, B: DeclaredTrait, C>(
+    module::Type,
+    Option<module::Type>,
+    A,
+    PrivateStruct<A>,
+    B,
+    B::Type,
+    Option<B::Type>,
+    <B as DeclaredTrait>::Type,
+    Option<<B as DeclaredTrait>::Type>,
+    C,
+    C::Type,
+    Option<C::Type>,
+    <C as WhereTrait>::Type,
+    Option<<C as WhereTrait>::Type>,
+    <i32 as DeclaredTrait>::Type,
+) where C: WhereTrait;
+
+#[derive(PartialEq, Debug)]
+pub struct Struct<A, B: DeclaredTrait, C> where C: WhereTrait {
+    m1: module::Type,
+    m2: Option<module::Type>,
+    a1: A,
+    a2: PrivateStruct<A>,
+    b: B,
+    b1: B::Type,
+    b2: Option<B::Type>,
+    b3: <B as DeclaredTrait>::Type,
+    b4: Option<<B as DeclaredTrait>::Type>,
+    c: C,
+    c1: C::Type,
+    c2: Option<C::Type>,
+    c3: <C as WhereTrait>::Type,
+    c4: Option<<C as WhereTrait>::Type>,
+    d: <i32 as DeclaredTrait>::Type,
+}
+
+#[derive(PartialEq, Debug)]
+enum Enum<A, B: DeclaredTrait, C> where C: WhereTrait {
+    Unit,
+    Seq(
+        module::Type,
+        Option<module::Type>,
+        A,
+        PrivateStruct<A>,
+        B,
+        B::Type,
+        Option<B::Type>,
+        <B as DeclaredTrait>::Type,
+        Option<<B as DeclaredTrait>::Type>,
+        C,
+        C::Type,
+        Option<C::Type>,
+        <C as WhereTrait>::Type,
+        Option<<C as WhereTrait>::Type>,
+        <i32 as DeclaredTrait>::Type,
+    ),
+    Map {
+        m1: module::Type,
+        m2: Option<module::Type>,
+        a1: A,
+        a2: PrivateStruct<A>,
+        b: B,
+        b1: B::Type,
+        b2: Option<B::Type>,
+        b3: <B as DeclaredTrait>::Type,
+        b4: Option<<B as DeclaredTrait>::Type>,
+        c: C,
+        c1: C::Type,
+        c2: Option<C::Type>,
+        c3: <C as WhereTrait>::Type,
+        c4: Option<<C as WhereTrait>::Type>,
+        d: <i32 as DeclaredTrait>::Type,
+    },
+}
+
+fn main() {
+    let e: TupleStruct<
+        i32,
+        i32,
+        i32,
+    > = TupleStruct(
+        0,
+        None,
+        0,
+        PrivateStruct(0),
+        0,
+        0,
+        None,
+        0,
+        None,
+        0,
+        0,
+        None,
+        0,
+        None,
+        0,
+    );
+    assert_eq!(e, e);
+
+    let e: Struct<
+        i32,
+        i32,
+        i32,
+    > = Struct {
+        m1: 0,
+        m2: None,
+        a1: 0,
+        a2: PrivateStruct(0),
+        b: 0,
+        b1: 0,
+        b2: None,
+        b3: 0,
+        b4: None,
+        c: 0,
+        c1: 0,
+        c2: None,
+        c3: 0,
+        c4: None,
+        d: 0,
+    };
+    assert_eq!(e, e);
+
+    let e = Enum::Unit::<i32, i32, i32>;
+    assert_eq!(e, e);
+
+    let e: Enum<
+        i32,
+        i32,
+        i32,
+    > = Enum::Seq(
+        0,
+        None,
+        0,
+        PrivateStruct(0),
+        0,
+        0,
+        None,
+        0,
+        None,
+        0,
+        0,
+        None,
+        0,
+        None,
+        0,
+    );
+    assert_eq!(e, e);
+
+    let e: Enum<
+        i32,
+        i32,
+        i32,
+    > = Enum::Map {
+        m1: 0,
+        m2: None,
+        a1: 0,
+        a2: PrivateStruct(0),
+        b: 0,
+        b1: 0,
+        b2: None,
+        b3: 0,
+        b4: None,
+        c: 0,
+        c1: 0,
+        c2: None,
+        c3: 0,
+        c4: None,
+        d: 0,
+    };
+    assert_eq!(e, e);
+}
index 6869a60838c09e695b71fb4696414196161f4e5b..4204d9b5c3eaeb3006c3358e7b5ec6c6a31c2f89 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy)]
+// pretty-expanded FIXME #23616
+
+#[derive(Copy, Clone)]
 struct Test;
 
 pub fn main() {}
index ce34852a917a6053cc6a8436516bc2b33b113ed8..22daffc48699ade29693526a5287ebf58f6afae6 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(Clone)]
 enum E {
     A,
index e174ffae75de2e6371a4152434b953b6a42aad7c..8a07bad69618894ad0253426ede979d9d4f18caa 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(Clone)]
 enum E<T,U> {
     A(T),
@@ -16,5 +18,5 @@ enum E<T,U> {
 }
 
 pub fn main() {
-    let _ = E::A::<int, int>(1).clone();
+    let _ = E::A::<isize, isize>(1).clone();
 }
index 329c7dab3eb3af47a5e35bad49a3a4a88a98edd8..d80f14c36945b23bc02fcf0dc78fbde03ae498dc 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(Clone)]
 struct S<T> {
     foo: (),
index bb07b08859fdb95f72807fd1e11afb5ecacaae9d..f2f2ec3de76008d1378fcc5f41e046594452c87f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(Clone)]
 struct S<T>(T, ());
 
index 51e615b37021a96841685edee6f93c8553a5b2b3..8bca8345085508240645eaee5135f2ae4381520d 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(Clone)]
 struct S {
-    _int: int,
+    _int: isize,
     _i8: i8,
     _i16: i16,
     _i32: i32,
     _i64: i64,
 
-    _uint: uint,
+    _uint: usize,
     _u8: u8,
     _u16: u16,
     _u32: u32,
index e2784c26dbbaea4e526e936766034aa018dbeaf7..8be029ba2accc196c08addcdf4c26a2f2b6baf31 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(Clone)]
 struct S((), ());
 
index b3194d5820a4e90916c9b1b32e3f0d84d37b38ae..07ad8f706eb5ce0d29bd3b43afe2b06d241e1220 100644 (file)
@@ -10,6 +10,8 @@
 
 // no-pretty-expanded FIXME #15189
 
+// pretty-expanded FIXME #23616
+
 #[derive(PartialEq, Eq, PartialOrd, Ord)]
 enum E<T> {
     E0,
index 8b54536f3abac8f4205e758b31590737c7fc4a16..5f7d184f1949d584642c447fccca694d8db68799 100644 (file)
@@ -10,6 +10,8 @@
 
 // no-pretty-expanded FIXME #15189
 
+// pretty-expanded FIXME #23616
+
 #[derive(PartialEq, Eq, PartialOrd, Ord)]
 enum ES<T> {
     ES1 { x: T },
index 86887c3411f8fabb316422f08e1bc7834220f94f..ea0017380b275991f13a9d67762b41075f2cb83a 100644 (file)
@@ -10,6 +10,8 @@
 
 // no-pretty-expanded FIXME #15189
 
+// pretty-expanded FIXME #23616
+
 #[derive(PartialEq, Eq, PartialOrd, Ord)]
 struct S<T> {
     x: T,
index c7d7f8ded83f4471d77e402f81de7ab2d0374307..702071676b90ee88740f4babbf4e0224fbe5e996 100644 (file)
@@ -10,6 +10,8 @@
 
 // no-pretty-expanded FIXME #15189
 
+// pretty-expanded FIXME #23616
+
 #[derive(PartialEq, Eq, PartialOrd, Ord)]
 struct TS<T>(T,T);
 
index bc55b9132c836314b665fa11edf39971241c1ac6..1669f3fdd3d9ae2d368caa44e1c8d81cb9e681e8 100644 (file)
@@ -12,6 +12,8 @@
 // where possible, by having a type that panics when compared as the
 // second element, so this passes iff the instances shortcircuit.
 
+// pretty-expanded FIXME #23616
+
 use std::cmp::Ordering;
 
 pub struct FailCmp;
@@ -31,7 +33,7 @@ impl Ord for FailCmp {
 
 #[derive(PartialEq,PartialOrd,Eq,Ord)]
 struct ShortCircuit {
-    x: int,
+    x: isize,
     y: FailCmp
 }
 
index b00ceb6ed22c75b622f25e57b26278dfccd5d1bd..574a620ef0290e670aa740c0bb8f6c526fe68684 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -20,6 +22,7 @@ struct A {
 
 pub fn main() {
     let a: A = Default::default();
-    let b: Box<[_]> = box [];
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let b: Box<[_]> = Box::<[bool; 0]>::new([]);
     assert_eq!(a.foo, b);
 }
index 838d05cf0d53084873383d4c3cabd51529818619..6ccedb0ad982f129982a87ef47925557c59eadd3 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
-#![feature(old_orphan_check)]
+#![feature(rustc_private)]
 
 extern crate serialize;
 
@@ -23,7 +25,8 @@ struct A {
 }
 
 fn main() {
-    let obj = A { foo: box [true, false] };
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let obj = A { foo: Box::new([true, false]) };
     let s = json::encode(&obj).unwrap();
     let obj2: A = json::decode(&s).unwrap();
     assert!(obj.foo == obj2.foo);
index 7d581927c30b460a1aafd7dac9182fb90a294a11..d216062bb2da362c3c7369f79fc237a365e8cecc 100644 (file)
@@ -11,7 +11,9 @@
 // This briefly tests the capability of `Cell` and `RefCell` to implement the
 // `Encodable` and `Decodable` traits via `#[derive(Encodable, Decodable)]`
 
-#![feature(old_orphan_check)]
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_private)]
 
 extern crate serialize;
 
@@ -21,7 +23,7 @@ use serialize::json;
 
 #[derive(Encodable, Decodable)]
 struct A {
-    baz: int
+    baz: isize
 }
 
 #[derive(Encodable, Decodable)]
index ea43163775ce908172c827ff386abd5dc89a9847..cc6b88c788a7856d4b7458c2da1510aebd6ce3e0 100644 (file)
@@ -27,22 +27,22 @@ use serialize::{Encodable, Decodable};
 #[derive(Encodable, Decodable, Eq, Rand)]
 struct A;
 #[derive(Encodable, Decodable, Eq, Rand)]
-struct B(int);
+struct B(isize);
 #[derive(Encodable, Decodable, Eq, Rand)]
-struct C(int, int, uint);
+struct C(isize, isize, usize);
 
 #[derive(Encodable, Decodable, Eq, Rand)]
 struct D {
-    a: int,
-    b: uint,
+    a: isize,
+    b: usize,
 }
 
 #[derive(Encodable, Decodable, Eq, Rand)]
 enum E {
     E1,
-    E2(uint),
+    E2(usize),
     E3(D),
-    E4{ x: uint },
+    E4{ x: usize },
 }
 
 #[derive(Encodable, Decodable, Eq, Rand)]
@@ -74,6 +74,6 @@ pub fn main() {
     for _ in 0..20 {
         roundtrip::<E>();
         roundtrip::<F>();
-        roundtrip::<G<int>>();
+        roundtrip::<G<isize>>();
     }
 }
index 7ce7c5fd411055c5cff05fac663197491eb42d99..d45247c593e5a8e301c711ec3700368553010e31 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub type task_id = int;
+// pretty-expanded FIXME #23616
+
+pub type task_id = isize;
 
 #[derive(PartialEq)]
 pub enum Task {
index 3b89c943edb1c20f4f2cae307338e4699f4b7ee5..03c93d3ab949b1efa06265c00e3989819f0b0bb1 100644 (file)
@@ -8,15 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
 #[derive(PartialEq, PartialOrd, Eq, Ord)]
 struct Foo(Box<[u8]>);
 
 pub fn main() {
-    let a = Foo(box [0, 1, 2]);
-    let b = Foo(box [0, 1, 2]);
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let a = Foo(Box::new([0, 1, 2]));
+    let b = Foo(Box::new([0, 1, 2]));
     assert!(a == b);
     println!("{}", a != b);
     println!("{}", a < b);
index 6777cbdab960486a3b1e306301e5f7f7408597e6..105d421b4041567c49497d14b41adde4f2ce4fde 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(old_orphan_check)]
+#![feature(rand, rustc_private)]
 
 extern crate serialize;
 extern crate rand;
@@ -22,21 +22,21 @@ mod submod {
                Clone,
                Debug, Rand,
                Encodable, Decodable)]
-    enum A { A1(uint), A2(int) }
+    enum A { A1(usize), A2(isize) }
 
     #[derive(PartialEq, PartialOrd, Eq, Ord,
                Hash,
                Clone,
                Debug, Rand,
                Encodable, Decodable)]
-    struct B { x: uint, y: int }
+    struct B { x: usize, y: isize }
 
     #[derive(PartialEq, PartialOrd, Eq, Ord,
                Hash,
                Clone,
                Debug, Rand,
                Encodable, Decodable)]
-    struct C(uint, int);
+    struct C(usize, isize);
 
 }
 
index 5fe7c8bb94b4f2487b08aa027ea42af58a66a91b..ce7ba9f25eb0721659e1b039598af6794058c1c5 100644 (file)
@@ -8,13 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(hash)]
+
 use std::hash::{Hash, SipHasher};
 
 #[derive(Hash)]
 struct Person {
-    id: uint,
+    id: usize,
     name: String,
-    phone: uint,
+    phone: usize,
 }
 
 fn hash<T: Hash>(t: &T) -> u64 {
index bf2c2b01e6a51a0512e0cc084841eb17fd89e516..435d15aab8f26fbdebf94ad19f1a10d07dec6c22 100644 (file)
@@ -11,7 +11,7 @@
 pub fn main() {
     #[derive(Debug)]
     struct Foo {
-        foo: int,
+        foo: isize,
     }
 
     let f = Foo { foo: 10 };
index c9b60d22ecb7b9bd7a6e6a8cbd3172b198be353e..b23075e6d0af43035e07d90f7c2c28e260a01011 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! define_vec {
     () => (
         mod foo {
index 62ec2f8e5902d80bc3bc894a56108339bb05e1bb..a2d22699fcc1fe8250248a1516df39d4ef904796 100644 (file)
@@ -1,4 +1,3 @@
-
 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
@@ -9,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::hash::{Hash, SipHasher};
 
 // testing multiple separate deriving attributes
@@ -16,8 +17,8 @@ use std::hash::{Hash, SipHasher};
 #[derive(Clone)]
 #[derive(Hash)]
 struct Foo {
-    bar: uint,
-    baz: int
+    bar: usize,
+    baz: isize
 }
 
 fn hash<T: Hash>(_t: &T) {}
index 82cf9db3232c0f2251c2dded55bbff40820f931b..f1c930828d2aa585333634d18ec3f9eac98aa03c 100644 (file)
@@ -1,4 +1,3 @@
-
 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
@@ -9,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::hash::{Hash, SipHasher};
 
 #[derive(PartialEq, Clone, Hash)]
 struct Foo {
-    bar: uint,
-    baz: int
+    bar: usize,
+    baz: isize
 }
 
 fn hash<T: Hash>(_t: &T) {}
index eb3cb30594ea808880b998a5c1513c054f038cb8..4399d741cad1e104096c0b32851df7cde3005ca9 100644 (file)
@@ -8,19 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(core)]
+
 use std::num::FromPrimitive;
-use std::int;
+use std::isize;
 
 #[derive(PartialEq, FromPrimitive, Debug)]
 enum A {
-    Foo = int::MAX,
+    Foo = isize::MAX,
     Bar = 1,
     Baz = 3,
     Qux,
 }
 
 pub fn main() {
-    let x: Option<A> = FromPrimitive::from_int(int::MAX);
+    let x: Option<A> = FromPrimitive::from_int(isize::MAX);
     assert_eq!(x, Some(A::Foo));
 
     let x: Option<A> = FromPrimitive::from_int(1);
index d6e5fedf1824a0382d3543366f8dcd2a04eda2bb..b960c2ddd4a43c075e7af0650d9f09c68a5d2a2a 100644 (file)
@@ -8,13 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(rand)]
+
 use std::rand;
 
 #[derive(Rand)]
 struct A;
 
 #[derive(Rand)]
-struct B(int, int);
+struct B(isize, isize);
 
 #[derive(Rand)]
 struct C {
@@ -25,7 +29,7 @@ struct C {
 #[derive(Rand)]
 enum D {
     D0,
-    D1(uint),
+    D1(usize),
     D2 { x: (), y: () }
 }
 
index 3277435e485b1fbef8f03d9b94d07a93d8592d1f..7a0d35f6f499fdebaaf199b761f9bfdf51ce247c 100644 (file)
@@ -14,7 +14,7 @@ use std::cmp::Ordering::{Less,Equal,Greater};
 
 #[derive(Eq,Ord)]
 struct A<'a> {
-    x: &'a int
+    x: &'a isize
 }
 pub fn main() {
     let (a, b) = (A { x: &1 }, A { x: &2 });
index 44609b6d653ca5d710c74f1e24c95cc5fec6b11c..89771ed13bfcf2f50b8ef70f7a11cd2d6ebf8f70 100644 (file)
@@ -12,7 +12,7 @@
 
 #[derive(Eq,Ord)]
 struct A<'a> {
-    x: &'a int
+    x: &'a isize
 }
 
 pub fn main() {
index acd07bc98d319dce481e9a24a82c6c7b2d5dc64e..2b7438fd84540e4c89623c2315e67903ac829b05 100644 (file)
@@ -15,19 +15,19 @@ enum A {}
 #[derive(Debug)]
 enum B { B1, B2, B3 }
 #[derive(Debug)]
-enum C { C1(int), C2(B), C3(String) }
+enum C { C1(isize), C2(B), C3(String) }
 #[derive(Debug)]
-enum D { D1{ a: int } }
+enum D { D1{ a: isize } }
 #[derive(Debug)]
 struct E;
 #[derive(Debug)]
-struct F(int);
+struct F(isize);
 #[derive(Debug)]
-struct G(int, int);
+struct G(isize, isize);
 #[derive(Debug)]
-struct H { a: int }
+struct H { a: isize }
 #[derive(Debug)]
-struct I { a: int, b: int }
+struct I { a: isize, b: isize }
 #[derive(Debug)]
 struct J(Custom);
 
index 7986b97685f6af6f33a1b47233a2e4b54cd24571..1f30f3ecedc9682394888654c043a56183794520 100644 (file)
 struct Unit;
 
 #[derive(Debug)]
-struct Tuple(int, uint);
+struct Tuple(isize, usize);
 
 #[derive(Debug)]
-struct Struct { x: int, y: uint }
+struct Struct { x: isize, y: usize }
 
 #[derive(Debug)]
 enum Enum {
     Nullary,
-    Variant(int, uint),
-    StructVariant { x: int, y : uint }
+    Variant(isize, usize),
+    StructVariant { x: isize, y : usize }
 }
 
 macro_rules! t {
index 9761a87d4aa992ab51a901cb2ccc9fe37612e5c7..f43f5162196a7ebbcab1abd2ffc11a716186c056 100644 (file)
@@ -10,7 +10,7 @@
 
 #[derive(PartialEq, Debug)]
 enum Foo {
-    Bar(int, int),
+    Bar(isize, isize),
     Baz(f64, f64)
 }
 
index 10bd1b29444d2c1f73de5cfe249db485fe2003f1..249661f003f0644b62182dfb3edc2584a28a0c92 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(Hash)]
 enum Foo {
-    Bar(int, char),
-    Baz(char, int)
+    Bar(isize, char),
+    Baz(char, isize)
 }
 
 #[derive(Hash)]
index 19809def9a10d5fc0d941b3d4334e822db7def4b..42f0e4562708446efef03a35d5e0c8b169cdaec2 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(Hash)]
 struct Foo {
-    x: int,
-    y: int,
-    z: int
+    x: isize,
+    y: isize,
+    z: isize
 }
 
 pub fn main() {}
index ed92a3baab9aa6986846122c837b23f4bb8a6672..5f9d9b6fb21558701da2f31b363bc05786f788cc 100644 (file)
@@ -10,7 +10,7 @@
 
 #[derive(PartialEq, Debug)]
 enum S {
-    X { x: int, y: int },
+    X { x: isize, y: isize },
     Y
 }
 
index 9319a4f752dc62fa188850e469301d96537292c8..f9e1ea4a62384f979e17f625052a4272abe22a12 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #[derive(PartialEq, Debug)]
-struct Foo(int, int, String);
+struct Foo(isize, isize, String);
 
 pub fn main() {
   let a1 = Foo(5, 6, "abc".to_string());
index e32e080cacb0a99f9ed12aaf765dda4e41b09254..624fb4a58e1a135f5e55c86ba0d23d3a2f11337b 100644 (file)
@@ -10,9 +10,9 @@
 
 #[derive(PartialEq, Debug)]
 struct Foo {
-    x: int,
-    y: int,
-    z: int,
+    x: isize,
+    y: isize,
+    z: isize,
 }
 
 pub fn main() {
index 890b4e69783098ca6aa7da903a3a74cbc0c3ca6a..4d88dbbca37b9487ddafbc14d0f867d29f9f6f22 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -11,9 +10,9 @@
 
 #[derive(PartialEq, Hash, Debug)]
 struct Foo<T> {
-    x: int,
+    x: isize,
     y: T,
-    z: int
+    z: isize
 }
 
 pub fn main() {
index 43271162c18125b0f4d7b3e27e393639c941bb99..e2c96085714bac2394acf4ac88858a7a1044c76b 100644 (file)
 // Ensure that we can do a destructuring bind of a fixed-size array,
 // even when the element type has a destructor.
 
+// pretty-expanded FIXME #23616
+
+#![feature(slice_patterns)]
+
 struct D { x: u8 }
 
 impl Drop for D { fn drop(&mut self) { } }
index 565e33ce01e17721a17f2e98a08f11d274fc19a1..6a81ebe67ba80472f6641baa2068c109241b3a61 100644 (file)
 
 // Just testing that panic!() type checks in statement or expr
 
+// pretty-expanded FIXME #23616
+
 #![allow(unreachable_code)]
 
 fn f() {
     panic!();
 
-    let _x: int = panic!();
+    let _x: isize = panic!();
 }
 
 pub fn main() {
diff --git a/src/test/run-pass/discrim-explicit-23030.rs b/src/test/run-pass/discrim-explicit-23030.rs
new file mode 100644 (file)
index 0000000..aed7b15
--- /dev/null
@@ -0,0 +1,156 @@
+// Copyright 2015 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.
+
+// Issue 23030: Workaround overflowing discriminant
+// with explicit assignments.
+
+// See also compile-fail/overflow-discrim.rs, which shows what
+// happens if you leave the OhNo explicit cases out here.
+
+use std::{i8,u8,i16,u16,i32,u32,i64,u64,isize,usize};
+
+fn f_i8() {
+    #[repr(i8)]
+    enum A {
+        Ok = i8::MAX - 1,
+        Ok2,
+        OhNo = i8::MIN,
+        NotTheEnd = -1,
+        Zero,
+    }
+
+    let _x = (A::Ok, A::Ok2, A::OhNo);
+    let z = (A::NotTheEnd, A::Zero).1 as i8;
+    assert_eq!(z, 0);
+}
+
+fn f_u8() {
+    #[repr(u8)]
+    enum A {
+        Ok = u8::MAX - 1,
+        Ok2,
+        OhNo = u8::MIN,
+    }
+
+    let _x = (A::Ok, A::Ok2, A::OhNo);
+}
+
+fn f_i16() {
+    #[repr(i16)]
+    enum A {
+        Ok = i16::MAX - 1,
+        Ok2,
+        OhNo = i16::MIN,
+        NotTheEnd = -1,
+        Zero,
+    }
+
+    let _x = (A::Ok, A::Ok2, A::OhNo);
+    let z = (A::NotTheEnd, A::Zero).1 as i16;
+    assert_eq!(z, 0);
+}
+
+fn f_u16() {
+    #[repr(u16)]
+    enum A {
+        Ok = u16::MAX - 1,
+        Ok2,
+        OhNo = u16::MIN,
+    }
+
+    let _x = (A::Ok, A::Ok2, A::OhNo);
+}
+
+fn f_i32() {
+    #[repr(i32)]
+    enum A {
+        Ok = i32::MAX - 1,
+        Ok2,
+        OhNo = i32::MIN,
+        NotTheEnd = -1,
+        Zero,
+    }
+
+    let _x = (A::Ok, A::Ok2, A::OhNo);
+    let z = (A::NotTheEnd, A::Zero).1 as i32;
+    assert_eq!(z, 0);
+}
+
+fn f_u32() {
+    #[repr(u32)]
+    enum A {
+        Ok = u32::MAX - 1,
+        Ok2,
+        OhNo = u32::MIN,
+    }
+
+    let _x = (A::Ok, A::Ok2, A::OhNo);
+}
+
+fn f_i64() {
+    #[repr(i64)]
+    enum A {
+        Ok = i64::MAX - 1,
+        Ok2,
+        OhNo = i64::MIN,
+        NotTheEnd = -1,
+        Zero,
+    }
+
+    let _x = (A::Ok, A::Ok2, A::OhNo);
+    let z = (A::NotTheEnd, A::Zero).1 as i64;
+    assert_eq!(z, 0);
+}
+
+fn f_u64() {
+    #[repr(u64)]
+    enum A {
+        Ok = u64::MAX - 1,
+        Ok2,
+        OhNo = u64::MIN,
+    }
+
+    let _x = (A::Ok, A::Ok2, A::OhNo);
+}
+
+fn f_isize() {
+    #[repr(isize)]
+    enum A {
+        Ok = isize::MAX - 1,
+        Ok2,
+        OhNo = isize::MIN,
+        NotTheEnd = -1,
+        Zero,
+    }
+
+    let _x = (A::Ok, A::Ok2, A::OhNo);
+    let z = (A::NotTheEnd, A::Zero).1 as isize;
+    assert_eq!(z, 0);
+}
+
+fn f_usize() {
+    #[repr(usize)]
+    enum A {
+        Ok = usize::MAX - 1,
+        Ok2,
+        OhNo = usize::MIN,
+    }
+
+    let _x = (A::Ok, A::Ok2, A::OhNo);
+}
+
+fn main() {
+    f_i8(); f_u8();
+    f_i16(); f_u16();
+    f_i32(); f_u32();
+    f_i64(); f_u64();
+
+    f_isize(); f_usize();
+}
index 331cd36a69402f12c6dbabffbd38d92f3bdb3a52..237cfe19dc49b8218121fe77b13cde5e6f1c9fd4 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let x: int = 15;
-    let y: int = 5;
+    let x: isize = 15;
+    let y: isize = 5;
     assert_eq!(x / 5, 3);
     assert_eq!(x / 4, 3);
     assert_eq!(x / 3, 5);
index 8018f681f3833fcd89e270184f86ca0600c2f054..13ce6a07e3641ad0be295e31e5077a7925c34104 100644 (file)
@@ -8,24 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn check_expr() {
-    let _:         & uint =     &1_usize;
-    let _:       & & uint =    &&1_usize;
-    let _:     & & & uint =   &&&1_usize;
-    let _:     & & & uint =  & &&1_usize;
-    let _:   & & & & uint =  &&&&1_usize;
-    let _:   & & & & uint = & &&&1_usize;
-    let _: & & & & & uint = &&&&&1_usize;
+    let _:         & usize =     &1;
+    let _:       & & usize =    &&1;
+    let _:     & & & usize =   &&&1;
+    let _:     & & & usize =  & &&1;
+    let _:   & & & & usize =  &&&&1;
+    let _:   & & & & usize = & &&&1;
+    let _: & & & & & usize = &&&&&1;
 }
 
 fn check_ty() {
-    let _:     &uint =         & 1_usize;
-    let _:    &&uint =       & & 1_usize;
-    let _:   &&&uint =     & & & 1_usize;
-    let _:  & &&uint =     & & & 1_usize;
-    let _:  &&&&uint =   & & & & 1_usize;
-    let _: & &&&uint =   & & & & 1_usize;
-    let _: &&&&&uint = & & & & & 1_usize;
+    let _:     &usize =         & 1;
+    let _:    &&usize =       & & 1;
+    let _:   &&&usize =     & & & 1;
+    let _:  & &&usize =     & & & 1;
+    let _:  &&&&usize =   & & & & 1;
+    let _: & &&&usize =   & & & & 1;
+    let _: &&&&&usize = & & & & & 1;
 }
 
 fn check_pat() {
diff --git a/src/test/run-pass/drop-flag-sanity-check.rs b/src/test/run-pass/drop-flag-sanity-check.rs
new file mode 100644 (file)
index 0000000..02f6cc7
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright 2015 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: -Z force-dropflag-checks=on
+
+// Quick-and-dirty test to ensure -Z force-dropflag-checks=on works as
+// expected. Note that the inlined drop-flag is slated for removal
+// (RFC 320); when that happens, the -Z flag and this test should
+// simply be removed.
+//
+// See also drop-flag-skip-sanity-check.rs.
+
+#![feature(old_io)]
+
+use std::env;
+use std::old_io::process::{Command, ExitSignal, ExitStatus};
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    if args.len() > 1 && args[1] == "test" {
+        return test();
+    }
+
+    let mut p = Command::new(&args[0]).arg("test").spawn().unwrap();
+    // The invocation should fail due to the drop-flag sanity check.
+    assert!(!p.wait().unwrap().success());
+}
+
+#[derive(Debug)]
+struct Corrupted {
+    x: u8
+}
+
+impl Drop for Corrupted {
+    fn drop(&mut self) { println!("dropping"); }
+}
+
+fn test() {
+    {
+        let mut c1 = Corrupted { x: 1 };
+        let mut c2 = Corrupted { x: 2 };
+        unsafe {
+            let p1 = &mut c1 as *mut Corrupted as *mut u8;
+            let p2 = &mut c2 as *mut Corrupted as *mut u8;
+            for i in 0..std::mem::size_of::<Corrupted>() {
+                // corrupt everything, *including the drop flag.
+                //
+                // (We corrupt via two different means to safeguard
+                // against the hypothetical assignment of the
+                // dtor_needed/dtor_done values to v and v+k.  that
+                // happen to match with one of the corruption values
+                // below.)
+                *p1.offset(i as isize) += 2;
+                *p2.offset(i as isize) += 3;
+            }
+        }
+        // Here, at the end of the scope of `c1` and `c2`, the
+        // drop-glue should detect the corruption of (at least one of)
+        // the drop-flags.
+    }
+    println!("We should never get here.");
+}
diff --git a/src/test/run-pass/drop-flag-skip-sanity-check.rs b/src/test/run-pass/drop-flag-skip-sanity-check.rs
new file mode 100644 (file)
index 0000000..7066b40
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright 2015 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: -Z force-dropflag-checks=off
+
+// Quick-and-dirty test to ensure -Z force-dropflag-checks=off works as
+// expected. Note that the inlined drop-flag is slated for removal
+// (RFC 320); when that happens, the -Z flag and this test should
+// simply be removed.
+//
+// See also drop-flag-sanity-check.rs.
+
+#![feature(old_io)]
+
+use std::env;
+use std::old_io::process::{Command, ExitSignal, ExitStatus};
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    if args.len() > 1 && args[1] == "test" {
+        return test();
+    }
+
+    let mut p = Command::new(&args[0]).arg("test").spawn().unwrap();
+    // Invocatinn should succeed as drop-flag sanity check is skipped.
+    assert!(p.wait().unwrap().success());
+}
+
+#[derive(Debug)]
+struct Corrupted {
+    x: u8
+}
+
+impl Drop for Corrupted {
+    fn drop(&mut self) { println!("dropping"); }
+}
+
+fn test() {
+    {
+        let mut c1 = Corrupted { x: 1 };
+        let mut c2 = Corrupted { x: 2 };
+        unsafe {
+            let p1 = &mut c1 as *mut Corrupted as *mut u8;
+            let p2 = &mut c2 as *mut Corrupted as *mut u8;
+            for i in 0..std::mem::size_of::<Corrupted>() {
+                // corrupt everything, *including the drop flag.
+                //
+                // (We corrupt via two different means to safeguard
+                // against the hypothetical assignment of the
+                // dtor_needed/dtor_done values to v and v+k.  that
+                // happen to match with one of the corruption values
+                // below.)
+                *p1.offset(i as isize) += 2;
+                *p2.offset(i as isize) += 3;
+            }
+        }
+        // Here, at the end of the scope of `c1` and `c2`, the
+        // drop-glue should detect the corruption of (at least one of)
+        // the drop-flags.
+    }
+    println!("We should never get here.");
+}
index f875d0644a07da9136aacbce789621acb0f01c0b..268de8ec55c9cda97023b9e3a74b68f11bdd628c 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-enum t { foo(Box<int>), }
+enum t { foo(Box<isize>), }
 
 pub fn main() {
     let tt = t::foo(box 10);
index 0786974e112071b9dbde077a3fe536a2ca15fd35..fc517fa592f522fa60e97da57095a6f72830c5bf 100644 (file)
@@ -11,7 +11,9 @@
 
 
 
-fn f() -> int {
+// pretty-expanded FIXME #23616
+
+fn f() -> isize {
     if true {
         let _s: String = "should not leak".to_string();
         return 1;
index 7a3b6df539f142b3efed8ff676fba9d3b93cfbae..efb98160a3e61ae4e261be6b07aaafcdaa3e2a59 100644 (file)
 // Test that destructor on a struct runs successfully after the struct
 // is boxed and converted to an object.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-static mut value: uint = 0;
+static mut value: usize = 0;
 
 struct Cat {
-    name : uint,
+    name : usize,
 }
 
 trait Dummy {
-    fn get(&self) -> uint;
+    fn get(&self) -> usize;
 }
 
 impl Dummy for Cat {
-    fn get(&self) -> uint { self.name }
+    fn get(&self) -> usize { self.name }
 }
 
 impl Drop for Cat {
index f94da9fc747e695fb850e7d2f8f5645df66617d5..ce675547a68192cc379681cafa6701490be0d011 100644 (file)
@@ -32,7 +32,7 @@ impl Drop for SendOnDrop {
 
 enum Foo {
     SimpleVariant(Sender<Message>),
-    NestedVariant(Box<uint>, SendOnDrop, Sender<Message>),
+    NestedVariant(Box<usize>, SendOnDrop, Sender<Message>),
     FailingVariant { on_drop: SendOnDrop }
 }
 
@@ -62,7 +62,7 @@ pub fn main() {
 
     let (sender, receiver) = channel();
     {
-        let v = Foo::NestedVariant(box 42_usize, SendOnDrop { sender: sender.clone() }, sender);
+        let v = Foo::NestedVariant(box 42, SendOnDrop { sender: sender.clone() }, sender);
     }
     assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
     assert_eq!(receiver.recv().unwrap(), Message::Dropped);
@@ -79,10 +79,10 @@ pub fn main() {
     let (sender, receiver) = channel();
     let t = {
         thread::spawn(move|| {
-            let mut v = Foo::NestedVariant(box 42usize, SendOnDrop {
+            let mut v = Foo::NestedVariant(box 42, SendOnDrop {
                 sender: sender.clone()
             }, sender.clone());
-            v = Foo::NestedVariant(box 42_usize,
+            v = Foo::NestedVariant(box 42,
                                    SendOnDrop { sender: sender.clone() },
                                    sender.clone());
             v = Foo::SimpleVariant(sender.clone());
index 8cbfee6c78d304eccd65e78a31ebce23928bf805..21740eb393066e2560296f6cb96149bfa7a6617f 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct Foo {
-    x: int
+    x: isize
 }
 
 impl Drop for Foo {
index f8c54fbab8a4ec876a9ecef76ba4f7ee5c0a59a5..9fa085b6701dde0354f345240706d606764133e3 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Foo { }
 
 impl Drop for Foo {
index f9fcf8ced28bbf661f352727e8c4be3805be5597..ea9edff4945fe3c82feb7c46db9624c8d51809f1 100644 (file)
@@ -8,10 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(str_words)]
+
 fn main() {
     let foo = "hello".to_string();
     let foo: Vec<&str> = foo.words().collect();
     let invalid_string = &foo[0];
     assert_eq!(*invalid_string, "hello");
 }
-
index f3d79f0c7d558d78d565f1692aa18c3107fd3b7d..3d4af80e30bb57a98a3349b07eed10ef61e7b1fa 100644 (file)
@@ -8,10 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections)]
+
 fn main() {
     let args = vec!("foobie", "asdf::asdf");
-    let arr: Vec<&str> = args[1].split_str("::").collect();
+    let arr: Vec<&str> = args[1].split("::").collect();
     assert_eq!(arr[0], "asdf");
     assert_eq!(arr[0], "asdf");
 }
-
index ad71f725864f9f9c5ba1a578ee4dc169c125ae68..df29b8e10c7aa5114308b2df4e408bbe6a5d867f 100644 (file)
 // shows a similar setup, but restricts `f` so that the struct `C<'a>`
 // is force-fed a lifetime equal to that of the borrowed arena.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unstable)]
-#![feature(unsafe_destructor)]
+#![feature(unsafe_destructor, rustc_private)]
 
 extern crate arena;
 
index 30ed0b8e4024581b9f2c360208b4fb581bcd9cd2..6b5bd6ad35e759b8ffa4e684694ca6907eb38bde 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test coercions involving DST and/or raw pointers
 
+// pretty-expanded FIXME #23616
+
 struct S;
 trait T { fn dummy(&self) { } }
 impl T for S {}
index 909f7f4897a6ae8372e20dc2355f65de47976c48..3b2b7493fd0fa85a8c15c41c0df5956131348d15 100644 (file)
 
 // Test that a custom deref with a fat pointer return type does not ICE
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 use std::ops::{Deref, DerefMut};
 
 pub struct Arr {
-    ptr: Box<[uint]>
+    ptr: Box<[usize]>
 }
 
 impl Deref for Arr {
-    type Target = [uint];
+    type Target = [usize];
 
-    fn deref(&self) -> &[uint] {
+    fn deref(&self) -> &[usize] {
         panic!();
     }
 }
 
 impl DerefMut for Arr {
-    fn deref_mut(&mut self) -> &mut [uint] {
+    fn deref_mut(&mut self) -> &mut [usize] {
         &mut *self.ptr
     }
 }
 
 pub fn foo(arr: &mut Arr) {
-    let x: &mut [uint] = &mut **arr;
+    let x: &mut [usize] = &mut **arr;
     assert!(x[0] == 1);
     assert!(x[1] == 2);
     assert!(x[2] == 3);
 }
 
 fn main() {
-    let mut a = Arr { ptr: box [1, 2, 3] };
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let mut a = Arr { ptr: Box::new([1, 2, 3]) };
     foo(&mut a);
 }
index ad4456b5b592d1a05fc65715cbc7e35aff8e4a4e..c8e658beef81b356c73b713c74e6206c213e95d7 100644 (file)
 
 // Test that a custom deref with a fat pointer return type does not ICE
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 use std::ops::Deref;
 
 pub struct Arr {
-    ptr: Box<[uint]>
+    ptr: Box<[usize]>
 }
 
 impl Deref for Arr {
-    type Target = [uint];
+    type Target = [usize];
 
-    fn deref(&self) -> &[uint] {
+    fn deref(&self) -> &[usize] {
         &*self.ptr
     }
 }
 
 pub fn foo(arr: &Arr) {
     assert!(arr.len() == 3);
-    let x: &[uint] = &**arr;
+    let x: &[usize] = &**arr;
     assert!(x[0] == 1);
     assert!(x[1] == 2);
     assert!(x[2] == 3);
 }
 
 fn main() {
-    let a = Arr { ptr: box [1, 2, 3] };
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let a = Arr { ptr: Box::new([1, 2, 3]) };
     foo(&a);
 }
index 0c7ecfcefff34bcdc9bcf3cac4e53fd5eefe9dad..df4cd74740cdd377c0791981228f3aaf5345c067 100644 (file)
 // Test that overloaded index expressions with DST result types
 // work and don't ICE.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::ops::Index;
 use std::fmt::Debug;
 
 struct S;
 
-impl Index<uint> for S {
+impl Index<usize> for S {
     type Output = str;
 
-    fn index<'a>(&'a self, _: &uint) -> &'a str {
+    fn index<'a>(&'a self, _: usize) -> &'a str {
         "hello"
     }
 }
 
 struct T;
 
-impl Index<uint> for T {
+impl Index<usize> for T {
     type Output = Debug + 'static;
 
-    fn index<'a>(&'a self, idx: &uint) -> &'a (Debug + 'static) {
-        static X: uint = 42;
+    fn index<'a>(&'a self, idx: usize) -> &'a (Debug + 'static) {
+        static X: usize = 42;
         &X as &(Debug + 'static)
     }
 }
index 226025cd80e8c900a99aac08603fc39168ab9dbb..5e0e5bd03fe6fa5180d10535065c4d929701c0c6 100644 (file)
 
 // Test DST raw pointers
 
+// pretty-expanded FIXME #23616
+
 trait Trait {
-    fn foo(&self) -> int;
+    fn foo(&self) -> isize;
 }
 
 struct A {
-    f: int
+    f: isize
 }
 impl Trait for A {
-    fn foo(&self) -> int {
+    fn foo(&self) -> isize {
         self.f
     }
 }
@@ -54,7 +56,7 @@ pub fn main() {
     }
 
     // raw slice with explicit cast
-    let a = &[1, 2, 3] as *const [_];
+    let a = &[1, 2, 3] as *const [i32];
     unsafe {
         let b = (*a)[2];
         assert!(b == 3);
@@ -94,7 +96,7 @@ pub fn main() {
         assert!(len == 3);
     }
 
-    let a = &mut [1, 2, 3] as *mut [_];
+    let a = &mut [1, 2, 3] as *mut [i32];
     unsafe {
         let b = (*a)[2];
         assert!(b == 3);
index 74f4b9e923301732b7786d14adae54d5601dd307..9bf286c434219ba504b4d51f1b37f46ec1401a53 100644 (file)
 
 // As dst-struct.rs, but the unsized field is the only field in the struct.
 
+// pretty-expanded FIXME #23616
+
 struct Fat<T: ?Sized> {
     ptr: T
 }
 
 // x is a fat pointer
-fn foo(x: &Fat<[int]>) {
+fn foo(x: &Fat<[isize]>) {
     let y = &x.ptr;
     assert!(x.ptr.len() == 3);
     assert!(y[0] == 1);
@@ -30,7 +32,7 @@ fn foo2<T:ToBar>(x: &Fat<[T]>) {
     assert!(x.ptr[1].to_bar() == bar);
 }
 
-#[derive(Copy, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq)]
 struct Bar;
 
 trait ToBar {
@@ -49,11 +51,11 @@ pub fn main() {
     foo(&f1);
     let f2 = &f1;
     foo(f2);
-    let f3: &Fat<[int]> = f2;
+    let f3: &Fat<[isize]> = f2;
     foo(f3);
-    let f4: &Fat<[int]> = &f1;
+    let f4: &Fat<[isize]> = &f1;
     foo(f4);
-    let f5: &Fat<[int]> = &Fat { ptr: [1, 2, 3] };
+    let f5: &Fat<[isize]> = &Fat { ptr: [1, 2, 3] };
     foo(f5);
 
     // With a vec of Bars.
@@ -70,14 +72,14 @@ pub fn main() {
     foo2(f5);
 
     // Assignment.
-    let f5: &mut Fat<[int]> = &mut Fat { ptr: [1, 2, 3] };
+    let f5: &mut Fat<[isize]> = &mut Fat { ptr: [1, 2, 3] };
     f5.ptr[1] = 34;
     assert!(f5.ptr[0] == 1);
     assert!(f5.ptr[1] == 34);
     assert!(f5.ptr[2] == 3);
 
     // Zero size vec.
-    let f5: &Fat<[int]> = &Fat { ptr: [] };
+    let f5: &Fat<[isize]> = &Fat { ptr: [] };
     assert!(f5.ptr.len() == 0);
     let f5: &Fat<[Bar]> = &Fat { ptr: [] };
     assert!(f5.ptr.len() == 0);
index ee5193adbc6a4b1d93218a7d3ca0e6e4d3626e44..5198dd43d6db83380b0463ecd0c8bca4ce553d74 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 struct Fat<T: ?Sized> {
-    f1: int,
+    f1: isize,
     f2: &'static str,
     ptr: T
 }
 
 // x is a fat pointer
-fn foo(x: &Fat<[int]>) {
+fn foo(x: &Fat<[isize]>) {
     let y = &x.ptr;
     assert!(x.ptr.len() == 3);
     assert!(y[0] == 1);
@@ -37,7 +39,7 @@ fn foo2<T:ToBar>(x: &Fat<[T]>) {
     assert!(x.f2 == "some str");
 }
 
-fn foo3(x: &Fat<Fat<[int]>>) {
+fn foo3(x: &Fat<Fat<[isize]>>) {
     let y = &x.ptr.ptr;
     assert!(x.f1 == 5);
     assert!(x.f2 == "some str");
@@ -49,7 +51,7 @@ fn foo3(x: &Fat<Fat<[int]>>) {
 }
 
 
-#[derive(Copy, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq)]
 struct Bar;
 
 trait ToBar {
@@ -68,11 +70,11 @@ pub fn main() {
     foo(&f1);
     let f2 = &f1;
     foo(f2);
-    let f3: &Fat<[int]> = f2;
+    let f3: &Fat<[isize]> = f2;
     foo(f3);
-    let f4: &Fat<[int]> = &f1;
+    let f4: &Fat<[isize]> = &f1;
     foo(f4);
-    let f5: &Fat<[int]> = &Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
+    let f5: &Fat<[isize]> = &Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
     foo(f5);
 
     // With a vec of Bars.
@@ -89,14 +91,14 @@ pub fn main() {
     foo2(f5);
 
     // Assignment.
-    let f5: &mut Fat<[int]> = &mut Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
+    let f5: &mut Fat<[isize]> = &mut Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
     f5.ptr[1] = 34;
     assert!(f5.ptr[0] == 1);
     assert!(f5.ptr[1] == 34);
     assert!(f5.ptr[2] == 3);
 
     // Zero size vec.
-    let f5: &Fat<[int]> = &Fat { f1: 5, f2: "some str", ptr: [] };
+    let f5: &Fat<[isize]> = &Fat { f1: 5, f2: "some str", ptr: [] };
     assert!(f5.ptr.len() == 0);
     let f5: &Fat<[Bar]> = &Fat { f1: 5, f2: "some str", ptr: [] };
     assert!(f5.ptr.len() == 0);
@@ -106,25 +108,28 @@ pub fn main() {
     foo3(&f1);
     let f2 = &f1;
     foo3(f2);
-    let f3: &Fat<Fat<[int]>> = f2;
+    let f3: &Fat<Fat<[isize]>> = f2;
     foo3(f3);
-    let f4: &Fat<Fat<[int]>> = &f1;
+    let f4: &Fat<Fat<[isize]>> = &f1;
     foo3(f4);
-    let f5: &Fat<Fat<[int]>> =
+    let f5: &Fat<Fat<[isize]>> =
         &Fat { f1: 5, f2: "some str", ptr: Fat { f1: 8, f2: "deep str", ptr: [1, 2, 3]} };
     foo3(f5);
 
     // Box.
-    let f1 = box [1, 2, 3];
+    let f1 = Box::new([1, 2, 3]);
     assert!((*f1)[1] == 2);
-    let f2: Box<[int]> = f1;
+    let f2: Box<[isize]> = f1;
     assert!((*f2)[1] == 2);
 
     // Nested Box.
-    let f1 : Box<Fat<[int; 3]>> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
+    let f1 : Box<Fat<[isize; 3]>> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
     foo(&*f1);
-    let f2 : Box<Fat<[int]>> = f1;
+    let f2 : Box<Fat<[isize]>> = f1;
     foo(&*f2);
-    let f3 : Box<Fat<[int]>> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
+
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let f3 : Box<Fat<[isize]>> =
+        Box::<Fat<[_; 3]>>::new(Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] });
     foo(&*f3);
 }
index fd1c7247e375d501a9c637b0606c593fcbc9bb79..370bc2882271f5681d5a035af2db7daac2ea931c 100644 (file)
@@ -8,33 +8,35 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 struct Fat<T: ?Sized> {
-    f1: int,
+    f1: isize,
     f2: &'static str,
     ptr: T
 }
 
-#[derive(Copy, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq)]
 struct Bar;
 
-#[derive(Copy, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq)]
 struct Bar1 {
-    f: int
+    f: isize
 }
 
 trait ToBar {
     fn to_bar(&self) -> Bar;
-    fn to_val(&self) -> int;
+    fn to_val(&self) -> isize;
 }
 
 impl ToBar for Bar {
     fn to_bar(&self) -> Bar {
         *self
     }
-    fn to_val(&self) -> int {
+    fn to_val(&self) -> isize {
         0
     }
 }
@@ -42,7 +44,7 @@ impl ToBar for Bar1 {
     fn to_bar(&self) -> Bar {
         Bar
     }
-    fn to_val(&self) -> int {
+    fn to_val(&self) -> isize {
         self.f
     }
 }
@@ -95,7 +97,9 @@ pub fn main() {
     assert!(f6.ptr.to_bar() == Bar);
 
     // &*
-    let f7: Box<ToBar> = box Bar1 {f :42};
+    //
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let f7: Box<ToBar> = Box::new(Bar1 {f :42});
     bar(&*f7);
 
     // Deep nesting
index 30d6b934fa277a06b83e8bd7792bf218f741df18..d95f1506a9b9ea4a3b308b73cbda449b051416dc 100644 (file)
@@ -11,6 +11,8 @@
 // Regression test for a problem with the first mod attribute
 // being applied to every mod
 
+// pretty-expanded FIXME #23616
+
 #[cfg(target_os = "linux")]
 mod hello;
 
@@ -26,6 +28,9 @@ mod hello;
 #[cfg(target_os = "dragonfly")]
 mod hello;
 
+#[cfg(target_os = "bitrig")]
+mod hello;
+
 #[cfg(target_os = "android")]
 mod hello;
 
index 65e2b178abf7073668e85be9f1747fac5eb7a372..91c9887300935df525267c0e61f894493f9bbef6 100644 (file)
@@ -10,7 +10,8 @@
 
 // aux-build:anon-extern-mod-cross-crate-1.rs
 // aux-build:anon-extern-mod-cross-crate-1.rs
+// pretty-expanded FIXME #23616
+
 extern crate anonexternmod;
 
 pub fn main() { }
-
index 97e873e9aff953cb41b110a3ba9cafd236317c42..7bd292e66f2585975499986084be4eb6fd63132d 100644 (file)
@@ -8,5 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn wsucc(n: int) -> int { 0 + { return n + 1 } }
+// pretty-expanded FIXME #23616
+
+use std::num::Int;
+
+fn wsucc<T:Int>(n: T) -> T { n + { return n } }
+
 pub fn main() { }
index 89fee7358a11194df025bddf729eb2d9bc923d5d..2d2cf6fbf0a7fc60a7672eec85899ae7f1333f9e 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait thing<A> {
     fn foo(&self) -> Option<A>;
 }
-impl<A> thing<A> for int {
+impl<A> thing<A> for isize {
     fn foo(&self) -> Option<A> { None }
 }
 fn foo_func<A, B: thing<A>>(x: B) -> Option<A> { x.foo() }
 
-struct A { a: int }
+struct A { a: isize }
 
 pub fn main() {
     let _x: Option<f64> = foo_func(0);
index 476d3f42d6ee31375484ea1cbca68d3490a72ea8..79c2f45067884e90526ea0729f7b09e4124a1780 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     if 1 == 2 {
         assert!((false));
index 269e0ee6ce425662b5acd6ba452d547b205bf0bb..cec528fa0401cef21a3041cd090654b9e148ffea 100644 (file)
@@ -8,18 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
+// pretty-expanded FIXME #23616
 
 pub fn main() {
-    assert!(Some(box() ()).is_some());
+    assert!(Some(Box::new(())).is_some());
 
-    let xs: Box<[()]> = box [];
+    let xs: Box<[()]> = Box::<[(); 0]>::new([]);
     assert!(Some(xs).is_some());
 
     struct Foo;
-    assert!(Some(box Foo).is_some());
+    assert!(Some(Box::new(Foo)).is_some());
 
-    let ys: Box<[Foo]> = box [];
+    let ys: Box<[Foo]> = Box::<[Foo; 0]>::new([]);
     assert!(Some(ys).is_some());
 }
index e95d58c706b27689f96c016ac3d7581eac87d25a..f52a21a997d78a00dfff2a46f1592bf4e80b7d10 100644 (file)
@@ -8,9 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 pub fn main() {
-    let x = *box() ();
+    let x = *Box::new(());
 }
index 42a1e563285c583710ab05aedf75fb81244c5b27..757579faa17c7e53370e304557f2fc02a0c05b17 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unused_mut)]
 
 
-pub fn main() { let mut _v: Vec<int> = Vec::new(); }
+pub fn main() { let mut _v: Vec<isize> = Vec::new(); }
index 95af729e5e16545d88022e321a1b84e4d4bdde11..e60cd02ce9994524f192f7392c8576c0452c7b7a 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 enum chan { chan_t, }
 
 impl PartialEq for chan {
     fn eq(&self, other: &chan) -> bool {
-        ((*self) as uint) == ((*other) as uint)
+        ((*self) as usize) == ((*other) as usize)
     }
     fn ne(&self, other: &chan) -> bool { !(*self).eq(other) }
 }
index 27560986e02532a45fd9bf5362064459aa857134..df779d0d713fd5ab1a016e66553e9cb3c9ad3f5f 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
-fn addr_of<T>(ptr: &T) -> uint {
-    ptr as *const T as uint
+fn addr_of<T>(ptr: &T) -> usize {
+    ptr as *const T as usize
 }
 
 fn is_aligned<T>(ptr: &T) -> bool {
     unsafe {
-        let addr: uint = mem::transmute(ptr);
+        let addr: usize = mem::transmute(ptr);
         (addr % mem::min_align_of::<T>()) == 0
     }
 }
index 1cbcaac379f09c0f90d71c8e6ab6c3ea2518eb84..f129a5153414306773a3f7565dbd39207b8b06d6 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 /*!
  * C-like enums have to be represented as LLVM ints, not wrapped in a
  * struct, because it's important for the FFI that they interoperate
@@ -29,11 +31,11 @@ enum Foo {
 }
 
 #[inline(never)]
-extern "C" fn foo(_x: uint) -> Foo { Foo::B }
+extern "C" fn foo(_x: usize) -> Foo { Foo::B }
 
 pub fn main() {
   unsafe {
-    let f: extern "C" fn(uint) -> u32 = ::std::mem::transmute(foo);
+    let f: extern "C" fn(usize) -> u32 = ::std::mem::transmute(foo);
     assert_eq!(f(0xDEADBEEF), Foo::B as u32);
   }
 }
index 97997bec2616a085a74ae65baf669704179e53cc..5c01d544cf533f4739982f8962ffc134c8463e5d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Animal {
     Cat = 0,
     Dog = 1,
@@ -25,6 +27,6 @@ enum Hero {
 pub fn main() {
     let pet: Animal = Animal::Snake;
     let hero: Hero = Hero::Superman;
-    assert!(pet as uint == 3);
-    assert!(hero as int == -2);
+    assert!(pet as usize == 3);
+    assert!(hero as isize == -2);
 }
index ef34115739dd47c7a456ffd11ae86df73d64255c..239f9821b925bb4cd954c8334c156b87fdf5804e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem::size_of;
 
 enum Ei8 {
index 16eaac082abac25da57db21d0b938dda526ae8ff..b23cfa9f32b8e02bf72f0548d66a456edd0e7a1c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem::size_of;
 
 #[repr(i8)]
@@ -58,13 +60,13 @@ enum Eu64 {
     Bu64 = 1
 }
 
-#[repr(int)]
+#[repr(isize)]
 enum Eint {
     Aint = 0,
     Bint = 1
 }
 
-#[repr(uint)]
+#[repr(usize)]
 enum Euint {
     Auint = 0,
     Buint = 1
@@ -79,6 +81,6 @@ pub fn main() {
     assert_eq!(size_of::<Eu32>(), 4);
     assert_eq!(size_of::<Ei64>(), 8);
     assert_eq!(size_of::<Eu64>(), 8);
-    assert_eq!(size_of::<Eint>(), size_of::<int>());
-    assert_eq!(size_of::<Euint>(), size_of::<uint>());
+    assert_eq!(size_of::<Eint>(), size_of::<isize>());
+    assert_eq!(size_of::<Euint>(), size_of::<usize>());
 }
index b45040f6a1c53ee79244add4d4663ac6dbbf1ad6..f1306b3f08cffdbced0a14bf50e0917dffa99f48 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub enum E64 {
     H64 = 0x7FFF_FFFF_FFFF_FFFF,
     L64 = 0x8000_0000_0000_0000
index 0242e53aa8c4ff761ec5d0cb0b8a23ad0bcc4f94..46238c4572080837d90148a0c0962e0729088869 100644 (file)
@@ -12,7 +12,7 @@ macro_rules! check {
     ($m:ident, $t:ty, $v:expr) => {{
         mod $m {
             use std::mem::size_of;
-            #[derive(Copy, Debug)]
+            #[derive(Copy, Clone, Debug)]
             enum E {
                 V = $v,
                 A = 0
index a4bd361f1828e2c4b9b2b0bcfa2e580b1054ec5c..9a2f45d00790e5898852b8bfb4fe41c9aef43ccc 100644 (file)
@@ -10,6 +10,8 @@
 
 // pp-exact
 
+// pretty-expanded FIXME #23616
+
 enum color { red = 1, green, blue, imaginary = -1, }
 
 pub fn main() {
@@ -19,6 +21,6 @@ pub fn main() {
     test_color(color::imaginary, -1, "imaginary".to_string());
 }
 
-fn test_color(color: color, val: int, _name: String) {
-    assert!(color as int == val);
+fn test_color(color: color, val: isize, _name: String) {
+    assert!(color as isize == val);
 }
index 6330d6196a361b650d068899ed7ea1233aaf4dc8..4cf8fff2376450117c6f478ecb9a55d0fe622a58 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod a {
     pub enum Foo {
         Bar,
index 023376ce4736ee6833e205314e4017e885cd023e..9fc799a97f6b9011eef59a511d109f5f639e8fbc 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
 
 extern crate core;
 
@@ -20,13 +23,13 @@ trait Trait { fn dummy(&self) { } }
 
 fn main() {
     // Functions
-    assert_eq!(size_of::<fn(int)>(), size_of::<Option<fn(int)>>());
-    assert_eq!(size_of::<extern "C" fn(int)>(), size_of::<Option<extern "C" fn(int)>>());
+    assert_eq!(size_of::<fn(isize)>(), size_of::<Option<fn(isize)>>());
+    assert_eq!(size_of::<extern "C" fn(isize)>(), size_of::<Option<extern "C" fn(isize)>>());
 
     // Slices - &str / &[T] / &mut [T]
     assert_eq!(size_of::<&str>(), size_of::<Option<&str>>());
-    assert_eq!(size_of::<&[int]>(), size_of::<Option<&[int]>>());
-    assert_eq!(size_of::<&mut [int]>(), size_of::<Option<&mut [int]>>());
+    assert_eq!(size_of::<&[isize]>(), size_of::<Option<&[isize]>>());
+    assert_eq!(size_of::<&mut [isize]>(), size_of::<Option<&mut [isize]>>());
 
     // Traits - Box<Trait> / &Trait / &mut Trait
     assert_eq!(size_of::<Box<Trait>>(), size_of::<Option<Box<Trait>>>());
@@ -34,33 +37,33 @@ fn main() {
     assert_eq!(size_of::<&mut Trait>(), size_of::<Option<&mut Trait>>());
 
     // Pointers - Box<T>
-    assert_eq!(size_of::<Box<int>>(), size_of::<Option<Box<int>>>());
+    assert_eq!(size_of::<Box<isize>>(), size_of::<Option<Box<isize>>>());
 
     // The optimization can't apply to raw pointers
-    assert!(size_of::<Option<*const int>>() != size_of::<*const int>());
-    assert!(Some(0 as *const int).is_some()); // Can't collapse None to null
+    assert!(size_of::<Option<*const isize>>() != size_of::<*const isize>());
+    assert!(Some(0 as *const isize).is_some()); // Can't collapse None to null
 
     struct Foo {
-        _a: Box<int>
+        _a: Box<isize>
     }
-    struct Bar(Box<int>);
+    struct Bar(Box<isize>);
 
     // Should apply through structs
     assert_eq!(size_of::<Foo>(), size_of::<Option<Foo>>());
     assert_eq!(size_of::<Bar>(), size_of::<Option<Bar>>());
     // and tuples
-    assert_eq!(size_of::<(u8, Box<int>)>(), size_of::<Option<(u8, Box<int>)>>());
+    assert_eq!(size_of::<(u8, Box<isize>)>(), size_of::<Option<(u8, Box<isize>)>>());
     // and fixed-size arrays
-    assert_eq!(size_of::<[Box<int>; 1]>(), size_of::<Option<[Box<int>; 1]>>());
+    assert_eq!(size_of::<[Box<isize>; 1]>(), size_of::<Option<[Box<isize>; 1]>>());
 
     // Should apply to NonZero
-    assert_eq!(size_of::<NonZero<uint>>(), size_of::<Option<NonZero<uint>>>());
+    assert_eq!(size_of::<NonZero<usize>>(), size_of::<Option<NonZero<usize>>>());
     assert_eq!(size_of::<NonZero<*mut i8>>(), size_of::<Option<NonZero<*mut i8>>>());
 
     // Should apply to types that use NonZero internally
-    assert_eq!(size_of::<Vec<int>>(), size_of::<Option<Vec<int>>>());
-    assert_eq!(size_of::<Arc<int>>(), size_of::<Option<Arc<int>>>());
-    assert_eq!(size_of::<Rc<int>>(), size_of::<Option<Rc<int>>>());
+    assert_eq!(size_of::<Vec<isize>>(), size_of::<Option<Vec<isize>>>());
+    assert_eq!(size_of::<Arc<isize>>(), size_of::<Option<Arc<isize>>>());
+    assert_eq!(size_of::<Rc<isize>>(), size_of::<Option<Rc<isize>>>());
 
     // Should apply to types that have NonZero transitively
     assert_eq!(size_of::<String>(), size_of::<Option<String>>());
index 4b839d740fc7aeaecf574b9adf9f7394b734c0d4..3a7c7ea9a714b76fe995b72a30bc90cb8a9b8529 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::result::Result;
 use std::result::Result::Ok;
 
-static C: Result<(), Box<int>> = Ok(());
+static C: Result<(), Box<isize>> = Ok(());
 
 // This is because of yet another bad assertion (ICE) about the null side of a nullable enum.
 // So we won't actually compile if the bug is present, but we check the value in main anyway.
index 468e5f5f4b315f5255c2b55b8f8748d3c1d69171..99554aafb042715a2bba44cf0f00349e357d4672 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
index 39ab8316958a65b653ce9a83b157d791027d7a1a..0bf5df5d61021f204df4adc8ed402780ff5c6653 100644 (file)
@@ -17,26 +17,26 @@ enum Enum1 { }
 
 enum Enum2 { A, B, C }
 
-enum Enum3 { D(int), E, F }
+enum Enum3 { D(isize), E, F }
 
-enum Enum4 { H(int), I(int), J }
+enum Enum4 { H(isize), I(isize), J }
 
 enum Enum5 { //~ ERROR three times larger
-    L(int, int, int, int), //~ NOTE this variant is the largest
-    M(int),
+    L(isize, isize, isize, isize), //~ NOTE this variant is the largest
+    M(isize),
     N
 }
 
 enum Enum6<T, U> {
     O(T),
     P(U),
-    Q(int)
+    Q(isize)
 }
 
 #[allow(enum_size_variance)]
 enum Enum7 {
-    R(int, int, int, int),
-    S(int),
+    R(isize, isize, isize, isize),
+    S(isize),
     T
 }
 pub fn main() { }
index 4a3a1156698aa32e73bb81e2abc3a97f12e73eae..77e6141d5592d2ed01b86b690c0de8d1d1542ba8 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 #![allow(unused_variable)]
 
index 86a998100b0e46d978f1ca7d1bb63ae4853879d0..037ee5f77775886762457a3de5fb98460ec93651 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Flopsy {
     Bunny = 2
 }
 
-const BAR:uint = Flopsy::Bunny as uint;
-const BAR2:uint = BAR;
+const BAR:usize = Flopsy::Bunny as usize;
+const BAR2:usize = BAR;
 
 pub fn main() {
-    let _v = [0;  Flopsy::Bunny as uint];
+    let _v = [0;  Flopsy::Bunny as usize];
     let _v = [0;  BAR];
     let _v = [0;  BAR2];
-    const BAR3:uint = BAR2;
+    const BAR3:usize = BAR2;
     let _v = [0;  BAR3];
 }
index 0e1ab73c02d088ff73e275d7dd42998778e952d7..7fb96112125afaaae984810a19d6ad83bbfeff3e 100644 (file)
@@ -8,14 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(path)]
+
 use std::env::*;
+use std::path::PathBuf;
 
 #[cfg(unix)]
 fn main() {
     let oldhome = var("HOME");
 
     set_var("HOME", "/home/MountainView");
-    assert!(home_dir() == Some(Path::new("/home/MountainView")));
+    assert!(home_dir() == Some(PathBuf::from("/home/MountainView")));
 
     remove_var("HOME");
     if cfg!(target_os = "android") {
@@ -36,14 +41,14 @@ fn main() {
     assert!(home_dir().is_some());
 
     set_var("HOME", "/home/MountainView");
-    assert!(home_dir() == Some(Path::new("/home/MountainView")));
+    assert!(home_dir() == Some(PathBuf::from("/home/MountainView")));
 
     remove_var("HOME");
 
     set_var("USERPROFILE", "/home/MountainView");
-    assert!(home_dir() == Some(Path::new("/home/MountainView")));
+    assert!(home_dir() == Some(PathBuf::from("/home/MountainView")));
 
     set_var("HOME", "/home/MountainView");
     set_var("USERPROFILE", "/home/PaloAlto");
-    assert!(home_dir() == Some(Path::new("/home/MountainView")));
+    assert!(home_dir() == Some(PathBuf::from("/home/MountainView")));
 }
index 659e5b3a8c2f8a93a5e4c23c655d2a89bf67b893..33bc6c596dbd0b008c22b8f3d63beebe62f2965f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::env::*;
 
 fn main() {
index 2dcf6bf6d090757d0bd84950c8ea7358d08928ba..3ca254021e5b9320c083c181b66153d1fd6ff062 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(PartialEq)]
 struct Bar;
 struct Baz;
index b562558822cd1bf2064f346d670fa17a58526175..0b24658a8f331fb3e2ac96deb500275e6efc0d75 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 
 pub fn main() {
index 28b5f781b5cfd7d962cd5d6b434e8adf35ac58f9..b3771f38482ba3331742ac714ccb7265809fafd0 100644 (file)
 // Doesn't work; needs a design decision.
 
 pub fn main() {
-    let x : [int; 5] = [1,2,3,4,5];
-    let _y : [int; 5] = [1,2,3,4,5];
+    let x : [isize; 5] = [1,2,3,4,5];
+    let _y : [isize; 5] = [1,2,3,4,5];
     let mut z = [1,2,3,4,5];
     z = x;
     assert_eq!(z[0], 1);
     assert_eq!(z[4], 5);
 
-    let a : [int; 5] = [1,1,1,1,1];
-    let b : [int; 5] = [2,2,2,2,2];
-    let c : [int; 5] = [2,2,2,2,3];
+    let a : [isize; 5] = [1,1,1,1,1];
+    let b : [isize; 5] = [2,2,2,2,2];
+    let c : [isize; 5] = [2,2,2,2,3];
 
     log(debug, a);
 
index 734ac3066534e3d00207730351c1d5333b3e0a90..52ccbe52d460e5ca8ecaff70ec69bc921ae954bd 100644 (file)
 #![allow(dead_assignment)]
 
 pub fn main() {
-    let x : &[int] = &[1,2,3,4,5];
-    let mut z : &[int] = &[1,2,3,4,5];
+    let x : &[isize] = &[1,2,3,4,5];
+    let mut z : &[isize] = &[1,2,3,4,5];
     z = x;
     assert_eq!(z[0], 1);
     assert_eq!(z[4], 5);
 
-    let a : &[int] = &[1,1,1,1,1];
-    let b : &[int] = &[2,2,2,2,2];
-    let c : &[int] = &[2,2,2,2,3];
-    let cc : &[int] = &[2,2,2,2,2,2];
+    let a : &[isize] = &[1,1,1,1,1];
+    let b : &[isize] = &[2,2,2,2,2];
+    let c : &[isize] = &[2,2,2,2,3];
+    let cc : &[isize] = &[2,2,2,2,2,2];
 
     println!("{:?}", a);
 
index a71016fd88baaf6676c06df88de4340b424d1c1a..a24930732474feb6d30c262e1aa1faa14dbc41bb 100644 (file)
@@ -10,6 +10,8 @@
 
 // exec-env:TEST_EXEC_ENV=22
 
+// pretty-expanded FIXME #23616
+
 use std::env;
 
 pub fn main() {
index 96c58b106f3414ce89c984b75218a708f94bf957..fa3970b62805b808dd533260d80ddb5cd702fc0e 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let x: int = 8;
+    let x: isize = 8;
     let y = 9;
     x + y;
 
-    let q: int = -8;
+    let q: isize = -8;
     let r = -9;
     q + r;
 }
index ef9dc377bc7f7164c5db03428ccd102a869e032b..cb3a28d19d2e53c1fc8882fcd4651615a9b86f1c 100644 (file)
 
 // Test to make sure that explicit self params work inside closures
 
+// pretty-expanded FIXME #23616
+
 struct Box {
-    x: uint
+    x: usize
 }
 
 impl Box {
-    pub fn set_many(&mut self, xs: &[uint]) {
+    pub fn set_many(&mut self, xs: &[usize]) {
         for x in xs { self.x = *x; }
     }
 }
index 382c5c58e92ee70adfde48df8f9c2c248706f94b..ee50d3bdf0ee8334278373fde4acf2d29ef30031 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-#[derive(Copy)]
-struct LM { resize_at: uint, size: uint }
+#[derive(Copy, Clone)]
+struct LM { resize_at: usize, size: usize }
 
 enum HashMap<K,V> {
     HashMap_(LM, Vec<(K,V)>)
@@ -25,7 +27,7 @@ fn linear_map<K,V>() -> HashMap<K,V> {
 }
 
 impl<K,V> HashMap<K,V> {
-    pub fn len(&mut self) -> uint {
+    pub fn len(&mut self) -> usize {
         match *self {
             HashMap::HashMap_(ref l, _) => l.size
         }
@@ -33,6 +35,6 @@ impl<K,V> HashMap<K,V> {
 }
 
 pub fn main() {
-    let mut m = box linear_map::<(),()>();
+    let mut m: Box<_> = box linear_map::<(),()>();
     assert_eq!(m.len(), 0);
 }
index 501ba01b4ce1c28d011b8427a06eaa274e879e2f..08ea638f93a56bc163e2d8e7a18c1f50ebb0469b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -16,7 +18,7 @@ trait Foo {
 }
 
 struct S {
-    x: int
+    x: isize
 }
 
 impl Foo for S {
index e5d8ec3f8ad0d497ca6ae282fd3360343ae1f233..b81090555ea64ab89bbd64e60a5b1280fe2be645 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -50,7 +52,7 @@ struct thing {
 
 #[derive(Clone)]
 struct A {
-    a: int
+    a: isize
 }
 
 fn thing(x: A) -> thing {
@@ -60,17 +62,17 @@ fn thing(x: A) -> thing {
 }
 
 impl thing {
-    pub fn bar(self: Box<thing>) -> int { self.x.a }
-    pub fn quux(&self) -> int { self.x.a }
+    pub fn bar(self: Box<thing>) -> isize { self.x.a }
+    pub fn quux(&self) -> isize { self.x.a }
     pub fn baz<'a>(&'a self) -> &'a A { &self.x }
-    pub fn spam(self) -> int { self.x.a }
+    pub fn spam(self) -> isize { self.x.a }
 }
 
 trait Nus { fn f(&self); }
 impl Nus for thing { fn f(&self) {} }
 
 pub fn main() {
-    let y = box thing(A {a: 10});
+    let y: Box<_> = box thing(A {a: 10});
     assert_eq!(y.clone().bar(), 10);
     assert_eq!(y.quux(), 10);
 
index ee74fc0b0a3262dd34057eaaf0d54929da19bc05..eaaf92fbea9cea6b34244d4dbe40ec712af9fbb3 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:explicit_self_xcrate.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate explicit_self_xcrate;
 use explicit_self_xcrate::{Foo, Bar};
 
index bfe22712de8c3b2e0b4e5b2092fd6854b8a8b1da..7e947c0be4584d0cb9a4518caaf4d53f2451b8ff 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc)]
+
 use std::num::strconv::ExponentFormat::{ExpBin, ExpDec};
 use std::num::strconv::SignificantDigits::DigMax;
 use std::num::strconv::SignFormat::{SignAll, SignNeg};
index 983ebbee9872fc8e58026a4cc0a9f569055c4211..7333d739f4b68732bd6a0420e65cd9aacfb85aac 100644 (file)
@@ -11,6 +11,8 @@
 // We can export tags without exporting the variants to create a simple
 // sort of ADT.
 
+// pretty-expanded FIXME #23616
+
 mod foo {
     pub enum t { t1, }
 
index da0a3e9e107e6cad55d8a7f935b0fa73e50d5aeb..4f821ebcc185a67493d49c341d156724c16b9dce 100644 (file)
 
 // Modified to not use export since it's going away. --pcw
 
+// pretty-expanded FIXME #23616
+
 mod foo {
     use foo::bar::*;
     pub mod bar {
-        pub static a : int = 10;
+        pub static a : isize = 10;
     }
     pub fn zum() {
         let _b = a;
index 2e44bf5be5bc6009e10008cd8e18231a81936dab..e7c35fcd7562cdcf2dfd28af560a92d965e35aea 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use m::f;
 use m::g;
 
index 091c389840ac0bc25c3e98de656224ef45fa2ab3..b7ef4df7ed6c0c43cd3d4c2a66317376fa062931 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
index 01fcf02ec12f66542859dc0986cecac22699e608..6257332a665662152aa199d8457e1bc16e811960 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod foo {
     pub enum t { t1, }
 }
diff --git a/src/test/run-pass/export-unexported-dep.rs b/src/test/run-pass/export-unexported-dep.rs
deleted file mode 100644 (file)
index 807d28f..0000000
+++ /dev/null
@@ -1,31 +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.
-
-// This tests that exports can have visible dependencies on things
-// that are not exported, allowing for a sort of poor-man's ADT
-
-mod foo {
-    // not exported
-    #[derive(Copy)]
-    enum t { t1, t2, }
-
-    impl PartialEq for t {
-        fn eq(&self, other: &t) -> bool {
-            ((*self) as uint) == ((*other) as uint)
-        }
-        fn ne(&self, other: &t) -> bool { !(*self).eq(other) }
-    }
-
-    pub fn f() -> t { return t::t1; }
-
-    pub fn g(v: t) { assert!((v == t::t1)); }
-}
-
-pub fn main() { foo::g(foo::f()); }
index ed246e2cb7d7bd6008b8f2345bf2a0a00bf25239..c88721471b64cbed03eb749f58671e2e83b1fefb 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 fn test_fn() {
-    fn ten() -> int { return 10; }
+    fn ten() -> isize { return 10; }
     let rs = ten;
     assert!((rs() == 10));
 }
index e41ce37cc3a1d5794f7e5dd45136983c3bd95d02..bd2936773953ba477574b6c9aa3e125ca1323b6b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -17,8 +19,8 @@ fn test_generic<T, F>(expected: T, eq: F) where T: Clone, F: FnOnce(T, T) -> boo
 }
 
 fn test_vec() {
-    fn compare_vec(v1: Box<int>, v2: Box<int>) -> bool { return v1 == v2; }
-    test_generic::<Box<int>, _>(box 1, compare_vec);
+    fn compare_vec(v1: Box<isize>, v2: Box<isize>) -> bool { return v1 == v2; }
+    test_generic::<Box<isize>, _>(box 1, compare_vec);
 }
 
 pub fn main() { test_vec(); }
index 91b847d47cbcc679d6b9efda3c59594a2a674524..d26c6e62f536eb74a01bed7605ed9734aab964c6 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn test_generic<T: Clone, F>(expected: T, eq: F) where F: FnOnce(T, T) -> bool {
     let actual: T = { expected.clone() };
     assert!(eq(expected, actual));
@@ -20,8 +22,8 @@ fn test_bool() {
 
 #[derive(Clone)]
 struct Pair {
-    a: int,
-    b: int,
+    a: isize,
+    b: isize,
 }
 
 fn test_rec() {
index cfb764e85f8d379111513e998abb0248b6f3e65f..57b5a426f5c5cd8592038c756b29a316dcf6d0b0 100644 (file)
 
 // Regression test for issue #377
 
-struct A { a: int }
-struct V { v: int }
+// pretty-expanded FIXME #23616
+
+struct A { a: isize }
+struct V { v: isize }
 
 pub fn main() {
     let a = { let b = A {a: 3}; b };
index d10b209965f1374dfed9eedb68f3d1bb71f50152..496a575c6c8b5a503145e963c5a426f1e1de46ea 100644 (file)
@@ -9,7 +9,9 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-pub fn main() { let x = { box 100 }; assert!((*x == 100)); }
+pub fn main() { let x: Box<_> = { box 100 }; assert!((*x == 100)); }
index ee1d955b0d361d9bdf54c5f7e4b182623c94c5aa..64f86237ab3bb03d5d425022969a61cdf165ffde 100644 (file)
 
 
 // Tests for standalone blocks as expressions
+// pretty-expanded FIXME #23616
+
 fn test_basic() { let rs: bool = { true }; assert!((rs)); }
 
-struct RS { v1: int, v2: int }
+struct RS { v1: isize, v2: isize }
 
 fn test_rec() { let rs = { RS {v1: 10, v2: 20} }; assert!((rs.v2 == 20)); }
 
index 6c6c5085749bb9be42bad0c0a0583b2954891b10..ca394f991f29b76f30b9259bf465a5cc779870a1 100644 (file)
@@ -9,12 +9,14 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 fn f(arg: &mut A) {
     arg.a = 100;
 }
 
-#[derive(Copy)]
-struct A { a: int }
+#[derive(Copy, Clone)]
+struct A { a: isize }
 
 pub fn main() {
     let mut x = A {a: 10};
index afc7dfaf9b441bcfd51a03a5cd0c4ec4fe3f5d14..02ac2a0b67b14f1107a5790157bd7a86bbe24f3c 100644 (file)
@@ -10,6 +10,8 @@
 
 // Issue #521
 
+// pretty-expanded FIXME #23616
+
 fn f() {
     let _x = match true {
         true => { 10 }
index 0ea1f3fcdaffcb7874a711d6100a731d8c60fbe5..0c9151cec7df4b007df955ec6b4695964425a6d9 100644 (file)
@@ -9,13 +9,15 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 fn test_int() {
-    fn f() -> int { 10 }
+    fn f() -> isize { 10 }
     assert_eq!(f(), 10);
 }
 
 fn test_vec() {
-    fn f() -> Vec<int> { vec!(10, 11) }
+    fn f() -> Vec<isize> { vec!(10, 11) }
     let vect = f();
     assert_eq!(vect[1], 11);
 }
@@ -26,22 +28,22 @@ fn test_generic() {
 }
 
 fn test_alt() {
-    fn f() -> int { match true { false => { 10 } true => { 20 } } }
+    fn f() -> isize { match true { false => { 10 } true => { 20 } } }
     assert_eq!(f(), 20);
 }
 
 fn test_if() {
-    fn f() -> int { if true { 10 } else { 20 } }
+    fn f() -> isize { if true { 10 } else { 20 } }
     assert_eq!(f(), 10);
 }
 
 fn test_block() {
-    fn f() -> int { { 10 } }
+    fn f() -> isize { { 10 } }
     assert_eq!(f(), 10);
 }
 
 fn test_ret() {
-    fn f() -> int {
+    fn f() -> isize {
         return 10 // no semi
 
     }
@@ -51,7 +53,7 @@ fn test_ret() {
 
 // From issue #372
 fn test_372() {
-    fn f() -> int { let x = { 3 }; x }
+    fn f() -> isize { let x = { 3 }; x }
     assert_eq!(f(), 3);
 }
 
index fb2a120e6f4a17d839b2cccc2ca2736437deb667..47e79de6b11246bcda2dd5e7ecb8b9a71475dff8 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn test_generic<T, F>(expected: T, not_expected: T, eq: F) where
     T: Clone,
     F: FnOnce(T, T) -> bool,
@@ -23,8 +25,8 @@ fn test_bool() {
 
 #[derive(Clone)]
 struct Pair {
-    a: int,
-    b: int,
+    a: isize,
+    b: isize,
 }
 
 fn test_rec() {
index 52ccee05817a0ccb9ae407ccb9a0f6d294cd2c79..1e631c204798a1dab6da4958d24d63398686d7e5 100644 (file)
@@ -10,6 +10,8 @@
 
 // When all branches of an if expression result in panic, the entire if
 // expression results in panic.
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let _x = if true {
         10
index 87c7954fa49aae9387a4e23f1928089d024c4924..e8594db80393ba735178ccb675444ea2e3a8eeff 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn test_if_panic() {
     let x = if false { panic!() } else { 10 };
     assert!((x == 10));
index ee2c07150435e9cb9a51e7fec7d3da6ef285a0c9..e79daed4c33d7bd9ea9df42ed5e496e59052bf12 100644 (file)
 
 // Tests for if as expressions returning nominal types
 
-#[derive(Copy)]
-struct I { i: int }
+#[derive(Copy, Clone)]
+struct I { i: isize }
 
 fn test_rec() {
     let rs = if true { I {i: 100} } else { I {i: 101} };
     assert_eq!(rs.i, 100);
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 enum mood { happy, sad, }
 
 impl PartialEq for mood {
     fn eq(&self, other: &mood) -> bool {
-        ((*self) as uint) == ((*other) as uint)
+        ((*self) as usize) == ((*other) as usize)
     }
     fn ne(&self, other: &mood) -> bool { !(*self).eq(other) }
 }
index 317e54349301144d7f54355f48f810980e3c1572..99c5053588b1c3b9ae7cf11b919f1c6c2fb30063 100644 (file)
@@ -9,13 +9,15 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 
 // Tests for if as expressions returning boxed types
 fn test_box() {
-    let rs = if true { box 100 } else { box 101 };
+    let rs: Box<_> = if true { box 100 } else { box 101 };
     assert_eq!(*rs, 100);
 }
 
index 23446b3f650c5a4917f86a1350b55c74aefc4ae6..345f17707c408b664353db89f809d8f610b368c4 100644 (file)
@@ -13,6 +13,8 @@
 
 
 // Tests for if as expressions
+// pretty-expanded FIXME #23616
+
 fn test_if() { let rs: bool = if true { true } else { false }; assert!((rs)); }
 
 fn test_else() {
index 9de1379f480f1bda79b4cf81f9b9f9353923c310..7cd0f6a758999dd66eeb5dc0a29944c51b923f16 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
index 489cd8437d21faacf5b52ddf21de41a2ca2453d0..95f47d005d3d60aa9829deac2c466d50e0fd7cbc 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -20,8 +22,8 @@ fn test_generic<T: Clone, F>(expected: T, eq: F) where F: FnOnce(T, T) -> bool {
 }
 
 fn test_vec() {
-    fn compare_box(v1: Box<int>, v2: Box<int>) -> bool { return v1 == v2; }
-    test_generic::<Box<int>, _>(box 1, compare_box);
+    fn compare_box(v1: Box<isize>, v2: Box<isize>) -> bool { return v1 == v2; }
+    test_generic::<Box<isize>, _>(box 1, compare_box);
 }
 
 pub fn main() { test_vec(); }
index 8e66827e0198f252528d7ee45e8d06ec394b2705..f8e82de9a0a36f1121b6e7b4e55e2b4cc6643679 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 type compare<T> = extern "Rust" fn(T, T) -> bool;
 
 fn test_generic<T:Clone>(expected: T, eq: compare<T>) {
@@ -23,8 +25,8 @@ fn test_bool() {
 
 #[derive(Clone)]
 struct Pair {
-    a: int,
-    b: int,
+    a: isize,
+    b: isize,
 }
 
 fn test_rec() {
index 3a8955917d6496567237712b062df5c073f35752..664ead10aae09fbdc79932b6ae16038cf5f72872 100644 (file)
@@ -13,6 +13,8 @@
 
 // When all branches of a match expression result in panic, the entire
 // match expression results in panic.
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let _x =
         match true {
index da24d4c57cc798e1a2366facceeddaee1163c385..40e7a6175cf86161eb8731c35471c2f4e43b6f4d 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 fn test_simple() {
     let r = match true { true => { true } false => { panic!() } };
     assert_eq!(r, true);
index e4ce71200b5f315f3425e8e00485305f72972e71..2dcb0f833e4b327bf384c90654e59bc17be003b6 100644 (file)
 
 
 // Tests for match as expressions resulting in struct types
-#[derive(Copy)]
-struct R { i: int }
+#[derive(Copy, Clone)]
+struct R { i: isize }
 
 fn test_rec() {
     let rs = match true { true => R {i: 100}, _ => panic!() };
     assert_eq!(rs.i, 100);
 }
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 enum mood { happy, sad, }
 
 impl PartialEq for mood {
     fn eq(&self, other: &mood) -> bool {
-        ((*self) as uint) == ((*other) as uint)
+        ((*self) as usize) == ((*other) as usize)
     }
     fn ne(&self, other: &mood) -> bool { !(*self).eq(other) }
 }
index 57ccfe1d5e09253a72c2904093282b842ea1a1dd..51eda4c7663a846305778e3d45f770198fa5562e 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 // Tests for match as expressions resulting in boxed types
 fn test_box() {
-    let res = match true { true => { box 100 }, _ => panic!() };
+    let res: Box<_> = match true { true => { box 100 }, _ => panic!() };
     assert_eq!(*res, 100);
 }
 
index b8996de41999cedb851a7b55e144b479b01a9199..2282391ef6fb478dbd9bb856c802134e135a072e 100644 (file)
@@ -13,6 +13,8 @@
 
 
 // Tests for using match as an expression
+// pretty-expanded FIXME #23616
+
 fn test_basic() {
     let mut rs: bool = match true { true => { true } false => { false } };
     assert!((rs));
index 324ff59dcb8f0c1c421b1da0d6e1b20ffe0b10f4..a1d86218846d6166cb5689e086172f569d6f2fbb 100644 (file)
@@ -10,5 +10,7 @@
 
 // Regression test for issue #762
 
+// pretty-expanded FIXME #23616
+
 pub fn f() { }
 pub fn main() { return ::f(); }
index d204f808e4471d9fdb1db81dacde7979c2000518..46cd73e11527c51c4f4e246a7cb00792ff9dcbef 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 static FOO : &'static str = concat!(concat!("hel", "lo"), "world");
 
 pub fn main() {
index bba8cbdb83dd67d7314cf07ba0a3ee4c84b3b8fd..9a039e8bc3539e40dfff5eeabf1abb853a401735 100644 (file)
@@ -9,10 +9,12 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 use std::cell::Cell;
 
-#[derive(Copy)]
-struct Point {x: int, y: int, z: int}
+#[derive(Copy, Clone)]
+struct Point {x: isize, y: isize, z: isize}
 
 fn f(p: &Cell<Point>) {
     assert!((p.get().z == 12));
index e4b9b9dfa1686599c0e8eda763ee9dd38e4c7d3e..67f6a3e8fc48478cc952fd00085f51ad0ca4b384 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 extern fn f() {
 }
 
index 93a5752d004aa65f52d048e0abb7af4b744170d9..2138b12fb12aba7ee7a486fbc7d6a64ff0331a91 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(libc)]
+
 extern crate libc;
 
 mod rustrt {
index 3c4c1da52ea95c7e4c6ba90f18a56966b233ca50..198745f5b19fe7a11a96e5949d447057c920e124 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(libc)]
+
 extern crate libc;
-use std::thread::Thread;
+use std::thread;
 
 mod rustrt {
     extern crate libc;
@@ -40,9 +42,9 @@ fn count(n: libc::uintptr_t) -> libc::uintptr_t {
 pub fn main() {
     // Make sure we're on a task with small Rust stacks (main currently
     // has a large stack)
-    let _t = Thread::spawn(move|| {
+    thread::scoped(move|| {
         let result = count(1000);
         println!("result = {}", result);
         assert_eq!(result, 1000);
-    });
+    }).join();
 }
index 34d2b577f202c0210ccc5033437acc996e6e216f..38cd4a8d79d0d3918916b39eb6b35a8c937f8e74 100644 (file)
@@ -10,7 +10,9 @@
 
 // Test direct calls to extern fns.
 
-extern fn f(x: uint) -> uint { x * 2 }
+// pretty-expanded FIXME #23616
+
+extern fn f(x: usize) -> usize { x * 2 }
 
 pub fn main() {
     let x = f(22);
index 52697d96b32d97edd9f6477710aa560ae33ffa57..4f1abbeb5c7ed79be9096fc7eaeb9a67a9737aed 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(libc)]
+
 extern crate libc;
 
 mod rustrt {
index 0dca7514dc5cf1cfed2e426fead18ad0b1f56359..e8c9bc76335f7ab7500eed3b0ae0232535b22f82 100644 (file)
 // make sure the stack pointers are maintained properly in both
 // directions
 
+#![feature(libc, std_misc)]
+
 extern crate libc;
-use std::thread::Thread;
+use std::thread;
 
 mod rustrt {
     extern crate libc;
@@ -44,7 +46,7 @@ fn count(n: libc::uintptr_t) -> libc::uintptr_t {
 pub fn main() {
     // Make sure we're on a task with small Rust stacks (main currently
     // has a large stack)
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         let result = count(12);
         println!("result = {}", result);
         assert_eq!(result, 2048);
index bdb1326aa15c03f0e2b6c47395e32dca1ef8c0dd..12f9c22c91824d4db587f6f433b80325a32a3ce0 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:extern_calling_convention.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate extern_calling_convention;
 
 use extern_calling_convention::foo;
index 3febff18704deea2faf81c12c4d46e9966d6d09c..09411c9c6eb2972e5fcba8c39df1a080317278f1 100644 (file)
 
 // Tests that we can compare various kinds of extern fn signatures.
 
+// pretty-expanded FIXME #23616
+
 extern fn voidret1() {}
 extern fn voidret2() {}
 
-extern fn uintret() -> uint { 22 }
+extern fn uintret() -> usize { 22 }
 
-extern fn uintvoidret(_x: uint) {}
+extern fn uintvoidret(_x: usize) {}
 
-extern fn uintuintuintuintret(x: uint, y: uint, z: uint) -> uint { x+y+z }
-type uintuintuintuintret = extern fn(uint,uint,uint) -> uint;
+extern fn uintuintuintuintret(x: usize, y: usize, z: usize) -> usize { x+y+z }
+type uintuintuintuintret = extern fn(usize,usize,usize) -> usize;
 
 pub fn main() {
     assert!(voidret1 as extern fn() == voidret1 as extern fn());
     assert!(voidret1 as extern fn() != voidret2 as extern fn());
 
-    assert!(uintret as extern fn() -> uint == uintret as extern fn() -> uint);
+    assert!(uintret as extern fn() -> usize == uintret as extern fn() -> usize);
 
-    assert!(uintvoidret as extern fn(uint) == uintvoidret as extern fn(uint));
+    assert!(uintvoidret as extern fn(usize) == uintvoidret as extern fn(usize));
 
     assert!(uintuintuintuintret as uintuintuintuintret ==
             uintuintuintuintret as uintuintuintuintret);
 }
-
index 18e20332adc91e1693cf6c5c7dae6c9a127c4759..7157d0658be349944cdd20a5f6df698b065d70ef 100644 (file)
@@ -10,6 +10,8 @@
 
 //aux-build:extern-crosscrate-source.rs
 
+#![feature(libc)]
+
 extern crate externcallback;
 extern crate libc;
 
index 59ee9a14e2eac71a43029712023c11fc7bde6d7e..1757ff51fed3f64bcff298ba4905a2ae4ab5ce34 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-extern crate "std" as mystd;
+// pretty-expanded FIXME #23616
+
+extern crate std as mystd;
 
 pub fn main() {}
diff --git a/src/test/run-pass/extern-methods.rs b/src/test/run-pass/extern-methods.rs
new file mode 100644 (file)
index 0000000..246f659
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
+use std::marker::MarkerTrait;
+
+trait A : MarkerTrait {
+    extern "fastcall" fn test1(i: i32);
+    extern fn test2(i: i32);
+}
+
+struct S;
+impl S {
+    extern "stdcall" fn test3(i: i32) {
+        assert_eq!(i, 3);
+    }
+}
+
+impl A for S {
+    extern "fastcall" fn test1(i: i32) {
+        assert_eq!(i, 1);
+    }
+    extern fn test2(i: i32) {
+        assert_eq!(i, 2);
+    }
+}
+
+fn main() {
+    <S as A>::test1(1);
+    <S as A>::test2(2);
+    S::test3(3);
+}
index 84fd1b40bf7a50eed6bf3a823fae09bec5d45774..74f47f08703a2f9c7edfe489d63a5427e83d34c2 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 extern "C" {
     fn pow(x: f64, y: f64) -> f64;
 }
index d6c6389fdb63bda3465e870000c926b281099b1e..1c64716b822b5c90f2400f64c140179c21816399 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:extern_mod_ordering_lib.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate extern_mod_ordering_lib;
 
 use extern_mod_ordering_lib::extern_mod_ordering_lib as the_lib;
index 3e430b6e72881b24495ba44ca11a9a12f9f9d6ed..37404ee7e696c17a22641831e844a0c05d31b9e4 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -10,6 +9,7 @@
 // except according to those terms.
 
 #![allow(unused_imports)]
+#![feature(rustc_private)]
 
 extern crate serialize;
 use serialize::json::Object;
index 1f48dc3bcf1d7dbba1bf20a1ab25342dded4b0cd..9d304ea9e10b64c8b927a17d7e676a58b89b68d2 100644 (file)
@@ -11,7 +11,7 @@
 // Test a foreign function that accepts and returns a struct
 // by value.
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub struct TwoU16s {
     one: u16, two: u16
 }
index 171e2a647cc6386e9624b0f21908d0e9a04d17f9..8dae0473fd5ed64b203a585c701c297820a4031b 100644 (file)
@@ -11,7 +11,7 @@
 // Test a foreign function that accepts and returns a struct
 // by value.
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub struct TwoU32s {
     one: u32, two: u32
 }
index 83555f6bb1d51dd2a7ac5af64fd1fa60ad76ff42..14aeea34657985a3773149c9fb9f1a20876a0d8f 100644 (file)
@@ -11,7 +11,7 @@
 // Test a foreign function that accepts and returns a struct
 // by value.
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub struct TwoU64s {
     one: u64, two: u64
 }
index d2b13445e6a22d99d4b06dea9ca66992ec087080..75a109e442911c9b3d33893e74f03414b2f8828e 100644 (file)
@@ -11,7 +11,7 @@
 // Test a foreign function that accepts and returns a struct
 // by value.
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub struct TwoU8s {
     one: u8, two: u8
 }
index 49c3bf62dbc859a57236716eb8cf44ca49c7abb2..bbdf5cf64a127fee542efb803539a5c49af31493 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test a function that takes/returns a u8.
 
+// pretty-expanded FIXME #23616
+
 #[link(name = "rust_test_helpers")]
 extern {
     pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
@@ -17,6 +19,6 @@ extern {
 
 pub fn main() {
     unsafe {
-        assert_eq!(22_u8, rust_dbg_extern_identity_u8(22_u8));
+        assert_eq!(22, rust_dbg_extern_identity_u8(22));
     }
 }
index c33c9ee3027f761580ecc802a3c4b61ed9a9326a..24c461f43adf8919c97509c5b7baddf9637af1ef 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[link(name = "rust_test_helpers")]
 extern {
     pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
index 272dfc98148ca421186ee0d2a9ae1f6767372691..17b0bb580fce27e10a98c2945230db1a3eaed1f0 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test a foreign function that accepts empty struct.
 
+// pretty-expanded FIXME #23616
+
 struct TwoU8s {
     one: u8,
     two: u8,
index 07c04af8e1bfd9ce95901d2ae0456e684c81446a..f93d7a3ff9614f7a043b8385e9a81ebc412935d9 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test a function that takes/returns a u32.
 
+// pretty-expanded FIXME #23616
+
 #[link(name = "rust_test_helpers")]
 extern {
     pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
@@ -17,6 +19,6 @@ extern {
 
 pub fn main() {
     unsafe {
-        assert_eq!(22_u32, rust_dbg_extern_identity_u32(22_u32));
+        assert_eq!(22, rust_dbg_extern_identity_u32(22));
     }
 }
index e19c73ebe2054fa552c7b9dfcd9d7b63ee230abe..961a3dce16813117cad9a1237c4009ba02d0b96e 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test a call to a function that takes/returns a u64.
 
+// pretty-expanded FIXME #23616
+
 #[link(name = "rust_test_helpers")]
 extern {
     pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
@@ -17,6 +19,6 @@ extern {
 
 pub fn main() {
     unsafe {
-        assert_eq!(22_u64, rust_dbg_extern_identity_u64(22_u64));
+        assert_eq!(22, rust_dbg_extern_identity_u64(22));
     }
 }
index cefc266b5c764019ccda14b0211a607964d88eb2..29bcdef5dc9ec60da7e73c57b9d048ef265aff6f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 extern {
     pub fn free(p: *const u8);
 }
index ca9767307f42ed1834d60bfcadd2a424019089cb..f149a1346229a64f1dd968e55a49729748241522 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub struct TwoU16s {
     one: u16, two: u16
 }
index 8d650459daa8de31534e62479149975d76b23835..4e9c44ef75eec5c683bd3c44f56ee60a9cc927af 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub struct TwoU32s {
     one: u32, two: u32
 }
index 924aaf811f44a55e222eec01de148edc6cbff5d1..fffd77fa897354edaba7b2bcc9a00c7b3ddaa3e4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub struct TwoU64s {
     one: u64, two: u64
 }
index 1dbce403cc8a196e4e9299b47e97c556e84d8247..fdf43d4332a9d16b4c774c1b4b69fc6d2dbb2b9f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub struct TwoU8s {
     one: u8, two: u8
 }
index 8ba39a24514cb7d872798a02a370868e7ef16328..e7f707bc334d70f9dec37d3a201bb7139b00b4d3 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[repr(C)]
 pub struct Foo(u32);
 
diff --git a/src/test/run-pass/extern-stress.rs b/src/test/run-pass/extern-stress.rs
deleted file mode 100644 (file)
index b9e08e4..0000000
+++ /dev/null
@@ -1,49 +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.
-
-// This creates a bunch of descheduling tasks that run concurrently
-// while holding onto C stacks
-
-extern crate libc;
-use std::thread::Thread;
-
-mod rustrt {
-    extern crate libc;
-
-    #[link(name = "rust_test_helpers")]
-    extern {
-        pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
-                             data: libc::uintptr_t)
-                             -> libc::uintptr_t;
-    }
-}
-
-extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
-    if data == 1 {
-        data
-    } else {
-        Thread::yield_now();
-        count(data - 1) + count(data - 1)
-    }
-}
-
-fn count(n: libc::uintptr_t) -> libc::uintptr_t {
-    unsafe {
-        rustrt::rust_dbg_call(cb, n)
-    }
-}
-
-pub fn main() {
-    (0_usize..100).map(|_| {
-        Thread::scoped(move|| {
-            assert_eq!(count(5), 16);
-        })
-    }).collect::<Vec<_>>();
-}
index 1934ef8024fd4aead06bb52fc8f23b90e678a38f..c016e4e62f56f19a0cbb49e038fa0683fb2cb466 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 extern fn f() {
 }
 
diff --git a/src/test/run-pass/extern-yield.rs b/src/test/run-pass/extern-yield.rs
deleted file mode 100644 (file)
index 80428d7..0000000
+++ /dev/null
@@ -1,48 +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.
-
-extern crate libc;
-use std::thread::Thread;
-
-mod rustrt {
-    extern crate libc;
-
-    #[link(name = "rust_test_helpers")]
-    extern {
-        pub fn rust_dbg_call(cb: extern "C" fn (libc::uintptr_t) -> libc::uintptr_t,
-                             data: libc::uintptr_t)
-                             -> libc::uintptr_t;
-    }
-}
-
-extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
-    if data == 1 {
-        data
-    } else {
-        count(data - 1) + count(data - 1)
-    }
-}
-
-fn count(n: libc::uintptr_t) -> libc::uintptr_t {
-    unsafe {
-        Thread::yield_now();
-        rustrt::rust_dbg_call(cb, n)
-    }
-}
-
-pub fn main() {
-    (0..10_usize).map(|i| {
-        Thread::scoped(move|| {
-            let result = count(5);
-            println!("result = {}", result);
-            assert_eq!(result, 16);
-        })
-    }).collect::<Vec<_>>();
-}
index 891133c78d477fab0bf06b1cedb82a40b2a8a447..aaa8f6cf26f1d8330653a2ded9d5efbddbee93d6 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     assert!(option_env!("__HOPEFULLY_DOESNT_EXIST__").is_none());
 }
index 172ec2f09050ca8e5bf03a33e386292bba5d06a1..5cb2abbfb0a685d05016010b706131ab3b34de99 100644 (file)
@@ -11,7 +11,7 @@
 
 
 
-fn f(x: int) -> int {
+fn f(x: isize) -> isize {
     // println!("in f:");
 
     println!("{}", x);
@@ -22,7 +22,7 @@ fn f(x: int) -> int {
     } else {
         // println!("recurring");
 
-        let y: int = x * f(x - 1);
+        let y: isize = x * f(x - 1);
         // println!("returned");
 
         println!("{}", y);
index 1d4c08f0bb5def4231d1cc1fd5cf4a40e6298cd3..aab32a7e7bd3773d33ece0e2730636aac38e2dab 100644 (file)
@@ -21,6 +21,8 @@
 // declarations, but we currently run them top-to-bottom. I don't think the
 // order really matters that much as long as we define what it is.
 
+// pretty-expanded FIXME #23616
+
 struct A;
 struct B;
 struct C {
index 37f7d84aaf1e42a46742267fed395d0fc10b1d4e..fbdf817e9abb8552a9bccb4313c48299eaec2315 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     // Make sure that this view item is filtered out because otherwise it would
     // trigger a compilation error
index bbd7b9130e7b94e1afe1290803d562019bd5de81..019537a2ab8b03abbde0e833bdf1738c2f0454ba 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let arr = [1,2,3];
     let arr2 = arr;
index a673a67089a3a2289225b0572a44b05ea52cb3cd..900da3c2d6ab29830790a3ac7975d2d13be14242 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::ops::{Deref, DerefMut};
 
 // Generic unique/owned smaht pointer.
@@ -30,12 +32,12 @@ impl<T> DerefMut for Own<T> {
 }
 
 struct Point {
-    x: int,
-    y: int
+    x: isize,
+    y: isize
 }
 
 impl Point {
-    fn get(&mut self) -> (int, int) {
+    fn get(&mut self) -> (isize, isize) {
         (self.x, self.y)
     }
 }
index 4d9f7d507f0a50f316d729e9a5d2f0c6dcbb7b19..b375f122082ef1e2169501785ee70805f1cf580e 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc)]
+
 use std::num::Float;
 
 pub fn main() {
index 9c75979628f3c27c2a6b8eba4969dca8679fd6bc..f84cbe52354678633226f1007084bf432947ab0e 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let a = 1.5e6f64;
     let b = 1.5E6f64;
index 09df423d2dadc97d7df945c0bc5849e91d5553f9..d45c689bfdaa764556af81af164eea7892d827a8 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let f = 4.999999999999f64;
     assert!((f > 4.90f64));
index 0bbd5ecdc3f5c4603133272da3b48152d085addf..521ed6db65be1714c5d56210083de3e796ec3525 100644 (file)
@@ -11,6 +11,8 @@
 // Ensure that declarations and types which use `extern fn` both have the same
 // ABI (#9309).
 
+// pretty-expanded FIXME #23616
+
 extern {
     fn printf();
 }
index fd8721e29e9b83767d605418f13ef14837af601e..d83dc7858056f38ddd76f0f752f8d461e6038e30 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(i: int, called: &mut bool) {
+// pretty-expanded FIXME #23616
+
+fn f(i: isize, called: &mut bool) {
     assert_eq!(i, 10);
     *called = true;
 }
 
-fn g(f: fn(int, v: &mut bool), called: &mut bool) {
+fn g(f: fn(isize, v: &mut bool), called: &mut bool) {
     f(10, called);
 }
 
index 09508b9b136296423ce4e78f4bdbcf0173b79b0c..4ec32d23467f717d3a70564d65e01f112b5c8664 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn bare() {}
 
 fn likes_block<F>(f: F) where F: FnOnce() { f() }
index cdde98331e2d05859b27d3cf9511b89176ce3041..117cf13584f18ee35aa6f74081d2c69cefc39344 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
 pub fn main() {
     // Bare functions should just be a pointer
-    assert_eq!(mem::size_of::<extern "Rust" fn()>(), mem::size_of::<int>());
+    assert_eq!(mem::size_of::<extern "Rust" fn()>(), mem::size_of::<isize>());
 }
index 4fc2c69ceb34f3dfaa37ae78999f08d09a279935..0a3c8916270683e8b5136a7542a42873e2a30246 100644 (file)
 
 // This is what the signature to spawn should look like with bare functions
 
+// pretty-expanded FIXME #23616
+
 fn spawn<T:Send>(val: T, f: fn(T)) {
     f(val);
 }
 
-fn f(i: int) {
+fn f(i: isize) {
     assert_eq!(i, 100);
 }
 
index bf6926050ba96b2f780a885a1b96de8dfb06e8ed..74d107d15ab0f1a4b0d62437bd7edadc3f653585 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct r<F> where F: FnOnce() {
     field: F,
 }
index bfd02f5e27b0c4bced6290d6c5973584916c27b5..f8b1582c515776756907889a4359f386b190c3cb 100644 (file)
 
 // Test explicit coercions from a fn item type to a fn pointer type.
 
-fn foo(x: int) -> int { x * 2 }
-fn bar(x: int) -> int { x * 4 }
-type IntMap = fn(int) -> int;
+// pretty-expanded FIXME #23616
+
+fn foo(x: isize) -> isize { x * 2 }
+fn bar(x: isize) -> isize { x * 4 }
+type IntMap = fn(isize) -> isize;
 
 fn eq<T>(x: T, y: T) { }
 
index 8427a0f444621ce93cdbf25a07240b7eacfbbcdc..67899bfd683d861428ba2497c3bcbf87042c8781 100644 (file)
 
 // Test implicit coercions from a fn item type to a fn pointer type.
 
-fn foo(x: int) -> int { x * 2 }
-fn bar(x: int) -> int { x * 4 }
-type IntMap = fn(int) -> int;
+// pretty-expanded FIXME #23616
+
+fn foo(x: isize) -> isize { x * 2 }
+fn bar(x: isize) -> isize { x * 4 }
+type IntMap = fn(isize) -> isize;
 
 fn eq<T>(x: T, y: T) { }
 
index f21dbc6f987d21818962c88cce30d9680f37ed00..13c96f43468942f2f21016315a669e87161e228e 100644 (file)
 
 
 
-fn foo(_f: fn(int) -> int) { }
+// pretty-expanded FIXME #23616
 
-fn id(x: int) -> int { return x; }
+fn foo(_f: fn(isize) -> isize) { }
+
+fn id(x: isize) -> isize { return x; }
 
 pub fn main() { foo(id); }
index 4e2c8facaf8202ab01585456b9607c5d3bc3d25b..66a7123c795f7b1c44457bd4e6900c8d8fc1b56c 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub fn main() {
-    let v : &[(int,int)] = &[ (1, 2), (3, 4), (5, 6) ];
+    let v : &[(isize,isize)] = &[ (1, 2), (3, 4), (5, 6) ];
     for &(x, y) in v {
         println!("{}", y);
         println!("{}", x);
index 3e81ca5125ba4b84fa16383770577d52027dd7ce..352d0b13c640775631c707f877111711c7cef6a3 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let f = |(x, y): (int, int)| {
+    let f = |(x, y): (isize, isize)| {
         assert_eq!(x, 1);
         assert_eq!(y, 2);
     };
index 34417891197a422dd6db05cf34c80eabec933198..3e1674a97e089f5a311f9bdfd365fb8a77a623d7 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unused_variable)]
 
 pub fn main() {
index 7a9b8a45b2af10d308907dbd037d4c7e5adce2e0..9d8c432e98209eadccbb7a9dc27a29804deec3b4 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Pair { x: int, y: int }
+// pretty-expanded FIXME #23616
+
+struct Pair { x: isize, y: isize }
 
 pub fn main() {
     for elt in &(vec!(Pair {x: 10, y: 20}, Pair {x: 30, y: 0})) {
index 7754751120e489ffccb97ec3ca4736dcb3f54ecd..4b6b6dcf1d555f365523a53b4f3e22c43eb87be8 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum BogusOption<T> {
     None,
     Some(T),
 }
 
-type Iterator = int;
+type Iterator = isize;
 
 pub fn main() {
     let x = [ 3, 3, 3 ];
@@ -21,4 +23,3 @@ pub fn main() {
         assert_eq!(*i, 3);
     }
 }
-
index 7564efbd9e56ba483ebe65f102df68dbf1f06814..109ca26056fff49c7758c5feb6ec1d6f93e640c6 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test that for loops can do what RFC #235 claims
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let mut v = vec![1];
 
index 30c2aec33ad1ba51de99485c0fe4fc2b946b435c..6deaec1905960abf1d8fb1ecf7e4bd4dd4fe8cba 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, start, no_std)]
+// pretty-expanded FIXME #23616
+
+#![feature(lang_items, start, no_std, core, collections)]
 #![no_std]
 
-extern crate "std" as other;
+extern crate std as other;
 
 #[macro_use] extern crate core;
 #[macro_use] extern crate collections;
@@ -19,7 +21,7 @@ extern crate "std" as other;
 use core::slice::SliceExt;
 
 #[start]
-fn start(_argc: int, _argv: *const *const u8) -> int {
+fn start(_argc: isize, _argv: *const *const u8) -> isize {
     for _ in [1,2,3].iter() { }
     0
 }
index d2de1ed8c7e6f3ff032bfbfe4cbe635b586e2aa1..908932fe396bee513416d8e2390a748a52cedbf3 100644 (file)
@@ -9,4 +9,6 @@
 // except according to those terms.
 
 
-pub fn main() { let x: Vec<int> = Vec::new(); for _ in &x { panic!("moop"); } }
+// pretty-expanded FIXME #23616
+
+pub fn main() { let x: Vec<isize> = Vec::new(); for _ in &x { panic!("moop"); } }
index 25d625e27f6ddd40578fad4ef9424085a830778b..bc041259895f9c698ec384e0d7129a4cc1704109 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = [1; 100];
     let mut y = 0;
index a4988bf016cf2caeba27cba89f9e8c9939cba5a3..cc02ee1459b5ee0f04e8935dc317a03d902ba0ff 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections)]
+
 extern crate collections;
 
 use std::collections::HashMap;
index ed4328d94fe34b89a5eeddbac020979ae6131912..065e4cfb7682bfa76ec9d7832e32d7bf31950c0d 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections)]
+
 extern crate collections;
 
 use std::collections::HashMap;
index d9abed501237c15892c179958415a839468805b0..60cfc9be0787a5f5966ea0b03b9f7a25d1b892db 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = [1; 100];
     let mut y = 0;
index 3817e1b0edace950ce3f320474ef3881e92cf4d5..a075c08b737e04d9d7b09b2d2cbd7e4cbed02397 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = [1; 100];
     let y = [2; 100];
index 8403a1669ffcf5fecd6e2fe8f688fab6f1ec4fe0..2248132d828d15ef3bf7edfa232e1254846c1d4d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = [1; 100];
     let mut y = 0;
index f6466994955e79e537a65dd8779a46f2e079781b..075539b621ac71ec8b2d080164722cf700ba86ca 100644 (file)
@@ -9,13 +9,15 @@
 // except according to those terms.
 
 
-fn two<F>(mut it: F) where F: FnMut(int) { it(0); it(1); }
+// pretty-expanded FIXME #23616
+
+fn two<F>(mut it: F) where F: FnMut(isize) { it(0); it(1); }
 
 pub fn main() {
-    let mut a: Vec<int> = vec!(-1, -1, -1, -1);
-    let mut p: int = 0;
+    let mut a: Vec<isize> = vec!(-1, -1, -1, -1);
+    let mut p: isize = 0;
     two(|i| {
-        two(|j| { a[p as uint] = 10 * i + j; p += 1; })
+        two(|j| { a[p as usize] = 10 * i + j; p += 1; })
     });
     assert_eq!(a[0], 0);
     assert_eq!(a[1], 1);
index 029dddb7a21109734d92a3f14d05dc7f6cb0da24..028e31d76aa8070cdc6e03c7d1b0d5a71178868b 100644 (file)
 
 
 
-fn pairs<F>(mut it: F) where F: FnMut((int, int)) {
-    let mut i: int = 0;
-    let mut j: int = 0;
+fn pairs<F>(mut it: F) where F: FnMut((isize, isize)) {
+    let mut i: isize = 0;
+    let mut j: isize = 0;
     while i < 10 { it((i, j)); i += 1; j += i; }
 }
 
 pub fn main() {
-    let mut i: int = 10;
-    let mut j: int = 0;
+    let mut i: isize = 10;
+    let mut j: isize = 0;
     pairs(|p| {
         let (_0, _1) = p;
         println!("{}", _0);
index 9ccb2dd56cfdcd20ecc7b2df910c038d60e956c7..674c2e344823d20145eaea5a9f3e91a597e8c2ac 100644 (file)
 
 
 pub fn main() {
-    let mut sum: int = 0;
+    let mut sum: isize = 0;
     first_ten(|i| { println!("main"); println!("{}", i); sum = sum + i; });
     println!("sum");
     println!("{}", sum);
     assert_eq!(sum, 45);
 }
 
-fn first_ten<F>(mut it: F) where F: FnMut(int) {
-    let mut i: int = 0;
+fn first_ten<F>(mut it: F) where F: FnMut(isize) {
+    let mut i: isize = 0;
     while i < 10 { println!("first_ten"); it(i); i = i + 1; }
 }
index 3f226a1985e78e5d3ceccb37437d4b96067b9506..2d3ff62a00537e6744b238e76a5932144b70bb4c 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-aarch64
+#![feature(libc)]
+
 extern crate libc;
 
 use std::mem;
@@ -30,7 +33,7 @@ pub fn main() {
 
 extern fn callback(data: libc::uintptr_t) {
     unsafe {
-        let data: *const int = mem::transmute(data);
+        let data: *const isize = mem::transmute(data);
         assert_eq!(*data, 100);
     }
 }
index 39c7d6dda0d0a1f75cd0f0ed31b936c0ec8f5130..fd779d665071d337c0b57d94aafa8057a6a0218d 100644 (file)
 
 // calling pin_task and that's having weird side-effects.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 mod rustrt1 {
     extern crate libc;
 
index 24b711328a18ab0fb5681e0de0d07b15d844f3d1..5db83d50b61ec52ffb0bb4690ea04a7675bc8809 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-fast doesn't like extern crate
+
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc, libc)]
 
 extern crate libc;
 use std::ffi::CString;
@@ -22,15 +25,15 @@ mod mlibc {
     }
 }
 
-fn strlen(str: String) -> uint {
+fn strlen(str: String) -> usize {
     // C string is terminated with a zero
     let s = CString::new(str).unwrap();
     unsafe {
-        mlibc::my_strlen(s.as_ptr()) as uint
+        mlibc::my_strlen(s.as_ptr()) as usize
     }
 }
 
 pub fn main() {
     let len = strlen("Rust".to_string());
-    assert_eq!(len, 4_usize);
+    assert_eq!(len, 4);
 }
index 09317abce921d9383e5f28668220a2a1a938e16d..7883c22f909ddb40860c164be07fa3572b5615a3 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy)]
+// pretty-expanded FIXME #23616
+
+#[derive(Copy, Clone)]
 pub struct S {
     x: u64,
     y: u64,
index e1ed0b8ea3b0c0743ba2a5663c553f581f2b6b9e..70d4801ae3b3c54b6751307affcff0696be40840 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-fast doesn't like extern crate
+
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
 
 extern crate libc;
 
index 2af02feb21d771445e00d57e7356947e3dda1a12..a9b3f60566d4e9326008cda848a8fdb79b8dca18 100644 (file)
 
 // ABI is cdecl by default
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 mod rustrt {
     extern crate libc;
 
index e242071fb26bc42d37f21749da066166631b55ab..8b48731ee0ba05bb51f6edc64859793884e5f94c 100644 (file)
@@ -10,6 +10,8 @@
 
 // Passing enums by value
 
+// pretty-expanded FIXME #23616
+
 pub enum void { }
 
 mod bindgen {
index ce2f895566439433143810603ae1b87984796622..d83bd940d197808fd8c3af284097e6b6de44ea5a 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-fast doesn't like extern crate
+
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
 
 extern crate libc;
 
index 1024bc21d2b0a686bbb3730b815bc8e4933843de..bdbbeaa9511cdef86eaedd4de718a7408e23ed4d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     use std::f64;
     let x = "NaN".to_string();
@@ -15,4 +17,3 @@ pub fn main() {
     assert_eq!(format!("{:e}", f64::NAN), x);
     assert_eq!(format!("{:E}", f64::NAN), x);
 }
-
index a15a176c2238d576f1ec0ff7d4b4d9365496c8cd..9204cdfd755b63ab552a85b88e8e1782b0274ca4 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, start, no_std)]
+// pretty-expanded FIXME #23616
+
+#![feature(lang_items, start, no_std, core, collections)]
 #![no_std]
 
-extern crate "std" as other;
+extern crate std as other;
 
 #[macro_use] extern crate core;
 #[macro_use] extern crate collections;
@@ -19,7 +21,7 @@ extern crate "std" as other;
 use collections::string::ToString;
 
 #[start]
-fn start(_argc: int, _argv: *const *const u8) -> int {
+fn start(_argc: isize, _argv: *const *const u8) -> isize {
     let s = format!("{}", 1_isize);
     assert_eq!(s, "1".to_string());
 
index 2122759b3d3ee963224146f00e00c264e0745fed..ce26fbd4c00f9e7546f633c141e5ea237c338c51 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::cell::RefCell;
 
 pub fn main() {
index 0f8d7c24360fb40c874f5bd25a5eb53675843892..fecaf279d043d555e53b6bab600eb68c5361b215 100644 (file)
 // Issue 4691: Ensure that functional-struct-updates operates
 // correctly and moves rather than copy when appropriate.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, core)]
 
 use std::marker::NoCopy as NP;
 
-struct ncint { np: NP, v: int }
-fn ncint(v: int) -> ncint { ncint { np: NP, v: v } }
+struct ncint { np: NP, v: isize }
+fn ncint(v: isize) -> ncint { ncint { np: NP, v: v } }
 
-struct NoFoo { copied: int, nocopy: ncint, }
+struct NoFoo { copied: isize, nocopy: ncint, }
 impl NoFoo {
-    fn new(x:int,y:int) -> NoFoo { NoFoo { copied: x, nocopy: ncint(y) } }
+    fn new(x:isize,y:isize) -> NoFoo { NoFoo { copied: x, nocopy: ncint(y) } }
 }
 
-struct MoveFoo { copied: int, moved: Box<int>, }
+struct MoveFoo { copied: isize, moved: Box<isize>, }
 impl MoveFoo {
-    fn new(x:int,y:int) -> MoveFoo { MoveFoo { copied: x, moved: box y } }
+    fn new(x:isize,y:isize) -> MoveFoo { MoveFoo { copied: x, moved: box y } }
 }
 
 struct DropNoFoo { inner: NoFoo }
 impl DropNoFoo {
-    fn new(x:int,y:int) -> DropNoFoo { DropNoFoo { inner: NoFoo::new(x,y) } }
+    fn new(x:isize,y:isize) -> DropNoFoo { DropNoFoo { inner: NoFoo::new(x,y) } }
 }
 impl Drop for DropNoFoo { fn drop(&mut self) { } }
 
 struct DropMoveFoo { inner: MoveFoo }
 impl DropMoveFoo {
-    fn new(x:int,y:int) -> DropMoveFoo { DropMoveFoo { inner: MoveFoo::new(x,y) } }
+    fn new(x:isize,y:isize) -> DropMoveFoo { DropMoveFoo { inner: MoveFoo::new(x,y) } }
 }
 impl Drop for DropMoveFoo { fn drop(&mut self) { } }
 
index 3955bedb168aeb373fad6b1ce6fae029b18a0e37..0fe4bbcb7a2281e4620ca1119c09590d9f8a1868 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn ho<F>(f: F) -> int where F: FnOnce(int) -> int { let n: int = f(3); return n; }
+// pretty-expanded FIXME #23616
 
-fn direct(x: int) -> int { return x + 1; }
+fn ho<F>(f: F) -> isize where F: FnOnce(isize) -> isize { let n: isize = f(3); return n; }
+
+fn direct(x: isize) -> isize { return x + 1; }
 
 pub fn main() {
-    let a: int = direct(3); // direct
-    let b: int = ho(direct); // indirect unbound
+    let a: isize = direct(3); // direct
+    let b: isize = ho(direct); // indirect unbound
 
     assert_eq!(a, b);
 }
index 4bff06f2a03825f5f87bf8981930f8c1af736c0b..48dfcb73da45ca88cae215ddb941a387a258d05d 100644 (file)
 
 
 
-fn f() -> int { return 42; }
+// pretty-expanded FIXME #23616
+
+fn f() -> isize { return 42; }
 
 pub fn main() {
-    let g: fn() -> int = f;
-    let i: int = g();
+    let g: fn() -> isize = f;
+    let i: isize = g();
     assert_eq!(i, 42);
 }
index b23d8db3cfdd58890ab12cf9c765e74ad1194b9b..28337237085236c6728a57398b86fef4fbdf1d7a 100644 (file)
 // Test that we do not leak when the arg pattern must drop part of the
 // argument (in this case, the `y` field).
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 struct Foo {
-    x: Box<uint>,
-    y: Box<uint>,
+    x: Box<usize>,
+    y: Box<usize>,
 }
 
-fn foo(Foo {x, ..}: Foo) -> *const uint {
-    let addr: *const uint = &*x;
+fn foo(Foo {x, ..}: Foo) -> *const usize {
+    let addr: *const usize = &*x;
     addr
 }
 
 pub fn main() {
-    let obj = box 1;
-    let objptr: *const uint = &*obj;
+    let obj: Box<_> = box 1;
+    let objptr: *const usize = &*obj;
     let f = Foo {x: obj, y: box 2};
     let xptr = foo(f);
     assert_eq!(objptr, xptr);
index 5d44a9461bebcbaf7d30511917e84ea04f3ed0c8..fcc00afb00bdba58aa19fca2e40ef12438ee5df5 100644 (file)
 // boxes. Make sure that we don't free the box as we match the
 // pattern.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
-fn getaddr(box ref x: Box<uint>) -> *const uint {
-    let addr: *const uint = &*x;
+fn getaddr(box ref x: Box<usize>) -> *const usize {
+    let addr: *const usize = &*x;
     addr
 }
 
-fn checkval(box ref x: Box<uint>) -> uint {
+fn checkval(box ref x: Box<usize>) -> usize {
     *x
 }
 
 pub fn main() {
-    let obj = box 1;
-    let objptr: *const uint = &*obj;
+    let obj: Box<_> = box 1;
+    let objptr: *const usize = &*obj;
     let xptr = getaddr(obj);
     assert_eq!(objptr, xptr);
 
index 97ba561baea39a45450b5fad2d031a0474850a71..4f74ca0ff721597cb1b4baf8c0fcd3ee7661644b 100644 (file)
@@ -11,7 +11,9 @@
 // Test that we can compile code that uses a `_` in function argument
 // patterns.
 
-fn foo((x, _): (int, int)) -> int {
+// pretty-expanded FIXME #23616
+
+fn foo((x, _): (isize, isize)) -> isize {
     x
 }
 
index 8c686aba5f358d37df243008f0c4f0d828fc0305..240d49d718f331e84e0f6bac6e806fb45319ae69 100644 (file)
@@ -10,8 +10,8 @@
 
 #[derive(Debug)]
 struct Foo {
-    x: int,
-    y: int
+    x: isize,
+    y: isize
 }
 
 pub fn main() {
index db468ba1802a662f374f32325f86be7e193cbb51..b8d7c2140be6fcb5caf82718c0d27915a3a2018d 100644 (file)
@@ -14,8 +14,8 @@
 fn id<T:Send>(t: T) -> T { return t; }
 
 pub fn main() {
-    let expected = box 100;
-    let actual = id::<Box<int>>(expected.clone());
+    let expected: Box<_> = box 100;
+    let actual = id::<Box<isize>>(expected.clone());
     println!("{}", *actual);
     assert_eq!(*expected, *actual);
 }
index bf02b82d1a0754d5fbc8678965a4652417296aea..4cf9f93bcaccf642ebc72709d4c3cbbfb326cfe3 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:default_type_params_xc.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate default_type_params_xc;
 
 struct Vec<T, A = default_type_params_xc::Heap>(Option<(T,A)>);
@@ -17,8 +19,8 @@ struct Vec<T, A = default_type_params_xc::Heap>(Option<(T,A)>);
 struct Foo;
 
 fn main() {
-    let _a = Vec::<int>(None);
-    let _b = Vec::<int, default_type_params_xc::FakeHeap>(None);
-    let _c = default_type_params_xc::FakeVec::<int> { f: None };
-    let _d = default_type_params_xc::FakeVec::<int, Foo> { f: None };
+    let _a = Vec::<isize>(None);
+    let _b = Vec::<isize, default_type_params_xc::FakeHeap>(None);
+    let _c = default_type_params_xc::FakeVec::<isize> { f: None };
+    let _d = default_type_params_xc::FakeVec::<isize, Foo> { f: None };
 }
index e7ef1d42f5fc14486d2c97c77e7df61eeaa3930d..e30cb7657988d6bfa1c21fe0a61313e8d6c66d82 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<A = (int, char)> {
+struct Foo<A = (isize, char)> {
     a: A
 }
 
-impl Foo<int> {
-    fn bar_int(&self) -> int {
+impl Foo<isize> {
+    fn bar_int(&self) -> isize {
         self.a
     }
 }
@@ -26,7 +26,7 @@ impl Foo<char> {
 
 impl Foo {
     fn bar(&self) {
-        let (i, c): (int, char) = self.a;
+        let (i, c): (isize, char) = self.a;
         assert_eq!(Foo { a: i }.bar_int(), i);
         assert_eq!(Foo { a: c }.bar_char(), c);
     }
@@ -39,7 +39,7 @@ impl<A: Clone> Foo<A> {
 }
 
 fn default_foo(x: Foo) {
-    let (i, c): (int, char) = x.a;
+    let (i, c): (isize, char) = x.a;
     assert_eq!(i, 1);
     assert_eq!(c, 'a');
 
index 0db03b46748798f4d7d7f00aad3aac9ca1ab112a..74a71873e287ff276763d850fae2b1eaafed1484 100644 (file)
@@ -22,7 +22,7 @@ fn f<T:Clone>(t: T) -> Pair<T> {
 }
 
 pub fn main() {
-    let b = f::<int>(10);
+    let b = f::<isize>(10);
     println!("{}" ,b.a);
     println!("{}", b.b);
     assert_eq!(b.a, 10);
index a2f7bdfd81709f80ae7397647b9431a67c99fec2..0e3ce3869bf7b6da968ff525b48ceb14e40021b2 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -16,7 +18,7 @@ struct Recbox<T> {x: Box<T>}
 fn reclift<T>(t: T) -> Recbox<T> { return Recbox {x: box t}; }
 
 pub fn main() {
-    let foo: int = 17;
-    let rbfoo: Recbox<int> = reclift::<int>(foo);
+    let foo: isize = 17;
+    let rbfoo: Recbox<isize> = reclift::<isize>(foo);
     assert_eq!(*rbfoo.x, foo);
 }
index 6e3d19b05d4b1d9272fb0c03ad338132849d8f91..7a765703e23a0cedae5dba942f14c287d0e988fa 100644 (file)
@@ -8,11 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::num::Int;
+// pretty-expanded FIXME #23616
 
-extern "C" fn foo<T: Int>(a: T, b: T) -> T { a + b }
+#![feature(core)]
+
+use std::ops::Add;
+
+extern "C" fn foo<T: Add>(a: T, b: T) -> T::Output { a + b }
 
 fn main() {
-    assert_eq!(99u8, foo(255u8, 100u8));
-    assert_eq!(99u16, foo(65535u16, 100u16));
+    assert_eq!(100u8, foo(0u8, 100u8));
+    assert_eq!(100u16, foo(0u16, 100u16));
 }
index 2f88a54e3f5e0535bf1e51df0cd9fec312b4b60b..e01f507372216273c62a20adc093d24ad1ff8bd5 100644 (file)
@@ -13,6 +13,8 @@
 
 
 // Issue #45: infer type parameters in function applications
+// pretty-expanded FIXME #23616
+
 fn id<T>(x: T) -> T { return x; }
 
-pub fn main() { let x: int = 42; let y: int = id(x); assert!((x == y)); }
+pub fn main() { let x: isize = 42; let y: isize = id(x); assert!((x == y)); }
index 6b503e711e9d3787f139475e7852304019776716..b37c73f7f759c18e49037f7eaf5f3eb3272c7cce 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 mod foomod {
     pub fn foo<T>() { }
 }
 
-pub fn main() { foomod::foo::<int>(); foomod::foo::<int>(); }
+pub fn main() { foomod::foo::<isize>(); foomod::foo::<isize>(); }
index 8da8c6808478b799daef899eafaacb35802581a8..0ba0ed4bf7f979cae9cea0e8198c253757649d39 100644 (file)
@@ -12,8 +12,8 @@
 
 fn id<T>(x: T) -> T { return x; }
 
-#[derive(Copy)]
-struct Triple {x: int, y: int, z: int}
+#[derive(Copy, Clone)]
+struct Triple {x: isize, y: isize, z: isize}
 
 pub fn main() {
     let mut x = 62;
@@ -22,7 +22,7 @@ pub fn main() {
     let mut b = 'b';
     let p: Triple = Triple {x: 65, y: 66, z: 67};
     let mut q: Triple = Triple {x: 68, y: 69, z: 70};
-    y = id::<int>(x);
+    y = id::<isize>(x);
     println!("{}", y);
     assert_eq!(x, y);
     b = id::<char>(a);
index eb0546063f7154396245fd1a5735c19732f1e3d2..b14a6101225e799a8ebd5a61f969db5131cb26f6 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum wrapper<T> { wrapped(T), }
 
 pub fn main() { let _w = wrapper::wrapped(vec!(1, 2, 3, 4, 5)); }
index 4e3c820405263952d4eb897b0a002abd55bd6f4d..24b517280007894df71ac317d2862fa78e9582dd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct S<T>(T);
 
 pub fn main() {
index 986b35cbecf96ecbe4a795d60bbbc415da7c290d..44b32f62f9227742a6664bcfdd5d7c66121ec98f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -16,17 +18,17 @@ trait Foo<T> {
 }
 
 struct S {
-    x: int
+    x: isize
 }
 
-impl Foo<int> for S {
-    fn get(&self) -> int {
+impl Foo<isize> for S {
+    fn get(&self) -> isize {
         self.x
     }
 }
 
 pub fn main() {
     let x = box S { x: 1 };
-    let y = x as Box<Foo<int>>;
+    let y = x as Box<Foo<isize>>;
     assert_eq!(y.get(), 1);
 }
index 845375d9b840a6c0da7606cd5aea1a7cfbad4160..863e0d7e33332b37d3ff6f075618d9cd9665b912 100644 (file)
@@ -16,9 +16,9 @@
 enum list<T> { cons(Box<T>, Box<list<T>>), nil, }
 
 pub fn main() {
-    let _a: list<int> =
-        list::cons::<int>(box 10,
-        box list::cons::<int>(box 12,
-        box list::cons::<int>(box 13,
-        box list::nil::<int>)));
+    let _a: list<isize> =
+        list::cons::<isize>(box 10,
+        box list::cons::<isize>(box 12,
+        box list::cons::<isize>(box 13,
+        box list::nil::<isize>)));
 }
index 7f84efcdd5de8862cd5d26eb93381ce1819838d9..49f8d6a3adb520f89112a97519a30b9485ed09bd 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 trait vec_utils<T> {
     fn map_<U, F>(x: &Self, f: F) -> Vec<U> where F: FnMut(&T) -> U;
 }
@@ -24,5 +26,5 @@ impl<T> vec_utils<T> for Vec<T> {
 }
 
 pub fn main() {
-    assert_eq!(vec_utils::map_(&vec!(1,2,3), |&x| x+1), vec!(2,3,4));
+    assert_eq!(vec_utils::map_(&vec!(1,2,3), |&x| x+1), [2,3,4]);
 }
index e39957e2bf2ef879570b3da0e20d84ce4985da63..d61ae520ada890eaffb9efd315ce2729c02af2f8 100644 (file)
@@ -12,6 +12,8 @@
 
 
 // This used to cause memory corruption in stage 0.
+// pretty-expanded FIXME #23616
+
 enum thing<K> { some(K), }
 
 pub fn main() { let _x = thing::some("hi".to_string()); }
index 24c31ab4ee66f7236f44e615279b6fe1f56ae342..9518d590279fc2ce01aeba06d539282b8fc6af02 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 enum clam<T> { a(T), }
 
 pub fn main() { let _c = clam::a(3); }
index 64eb4e498691648adadead8587be98b7cb148872..830c982e13c80662ec898e9cd5d3b1acc6a2072a 100644 (file)
@@ -18,4 +18,4 @@ fn altfoo<T>(f: foo<T>) {
     assert!((hit));
 }
 
-pub fn main() { altfoo::<int>(foo::arm::<int>(10)); }
+pub fn main() { altfoo::<isize>(foo::arm::<isize>(10)); }
index 6ed85588363d1817feccbdc943d887f2444d3493..fef26593eac873dba06a4249883d7fee61f2d4a0 100644 (file)
 
 enum noption<T> { some(T), }
 
-struct Pair { x: int, y: int }
+struct Pair { x: isize, y: isize }
 
 pub fn main() {
-    let nop: noption<int> = noption::some::<int>(5);
-    match nop { noption::some::<int>(n) => { println!("{}", n); assert!((n == 5)); } }
+    let nop: noption<isize> = noption::some::<isize>(5);
+    match nop { noption::some::<isize>(n) => { println!("{}", n); assert!((n == 5)); } }
     let nop2: noption<Pair> = noption::some(Pair{x: 17, y: 42});
     match nop2 {
       noption::some(t) => {
index b0d4944ba540b6ea123061115409e857c2db6841..942bdb97ba20383b16fcb8fde05ae8d230dde877 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 #![allow(unused_variable)]
 #![allow(unknown_features)]
@@ -16,6 +18,6 @@
 enum option<T> { some(Box<T>), none, }
 
 pub fn main() {
-    let mut a: option<int> = option::some::<int>(box 10);
-    a = option::none::<int>;
+    let mut a: option<isize> = option::some::<isize>(box 10);
+    a = option::none::<isize>;
 }
index 3db794d88f025f73c7f7094ce16bc5f0488faafb..8b63fb94b52ee1af23fde8b630ac737fc622de92 100644 (file)
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 
-fn mk() -> int { return 1; }
+fn mk() -> isize { return 1; }
 
-fn chk(a: int) { println!("{}", a); assert!((a == 1)); }
+fn chk(a: isize) { println!("{}", a); assert!((a == 1)); }
 
 fn apply<T>(produce: fn() -> T,
             consume: fn(T)) {
@@ -19,7 +19,7 @@ fn apply<T>(produce: fn() -> T,
 }
 
 pub fn main() {
-    let produce: fn() -> int = mk;
-    let consume: fn(v: int) = chk;
-    apply::<int>(produce, consume);
+    let produce: fn() -> isize = mk;
+    let consume: fn(v: isize) = chk;
+    apply::<isize>(produce, consume);
 }
index a1cf581fe4a81eb35169e9d2052526949bdd5984..2b3bd5ead94a2049c7cca721ea6848260a5e64db 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 struct Foo<T> {
     a: T
 }
index 0ff7cedc6c5f1d64c3cf270b4e4a5160a7bb3e87..73fc3a0d8023629704a796053ffeee9fcefced0c 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 struct Pair<T> {x: T, y: T}
 
 pub fn main() {
-    let x: Pair<int> = Pair {x: 10, y: 12};
+    let x: Pair<isize> = Pair {x: 10, y: 12};
     assert_eq!(x.x, 10);
     assert_eq!(x.y, 12);
 }
index 1d39c47417c1002c8748149775b521a6f6bb0672..9cf98364eb9937df70d3887b16f88c3ec75c1a29 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -16,6 +18,6 @@ struct Triple<T> { x: T, y: T, z: T }
 fn box_it<T>(x: Triple<T>) -> Box<Triple<T>> { return box x; }
 
 pub fn main() {
-    let x: Box<Triple<int>> = box_it::<int>(Triple{x: 1, y: 2, z: 3});
+    let x: Box<Triple<isize>> = box_it::<isize>(Triple{x: 1, y: 2, z: 3});
     assert_eq!(x.y, 2);
 }
index 3c89900fe493bad40d3d106d3948b9cfebe9c862..52b06ab2928af8dc1884dac36a970b03f3e9ba55 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_private)]
+
 extern crate getopts;
 
 use getopts::{optopt, getopts};
index 618916e8569079822d47e5dd1ad087e85c3884f6..64d9368a88be8200efcb7a523c6f8444ff558692 100644 (file)
@@ -9,10 +9,12 @@
 // except according to those terms.
 
 
-pub fn f() -> int { return 1; }
+// pretty-expanded FIXME #23616
+
+pub fn f() -> isize { return 1; }
 
 pub mod foo {
-    pub fn f() -> int { return 2; }
+    pub fn f() -> isize { return 2; }
     pub fn g() { assert!((f() == 2)); assert!((::f() == 1)); }
 }
 
index addd6a63836f3512b033ba144a715b620f42d5f3..f5f80914937d3cf51140c2aba67dceb1b64d6479 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy)]
-enum Q { R(Option<uint>) }
+// pretty-expanded FIXME #23616
 
-fn xyzzy(q: Q) -> uint {
+#[derive(Copy, Clone)]
+enum Q { R(Option<usize>) }
+
+fn xyzzy(q: Q) -> usize {
     match q {
         Q::R(S) if S.is_some() => { 0 }
         _ => 1
index 188106ec107887ad751be3574a317afc526a2556..11c67b8af8107e11451e336d54f208052f4bb437 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy)]
-struct Pair { x: int, y: int }
+// pretty-expanded FIXME #23616
+
+#[derive(Copy, Clone)]
+struct Pair { x: isize, y: isize }
 
 pub fn main() {
-    let a: int =
+    let a: isize =
         match 10 { x if x < 7 => { 1 } x if x < 11 => { 2 } 10 => { 3 } _ => { 4 } };
     assert_eq!(a, 2);
 
-    let b: int =
+    let b: isize =
         match (Pair {x: 10, y: 20}) {
           x if x.x < 5 && x.y < 5 => { 1 }
           Pair {x: x, y: y} if x == 10 && y == 20 => { 2 }
index 677038af9a9c4e0de4609f0622e812f17f377486..5c96aaf4bd8902365862e4a14066d048d35ff374 100644 (file)
@@ -9,8 +9,7 @@
 // except according to those terms.
 
 #![allow(unknown_features)]
-#![feature(box_syntax)]
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, std_misc)]
 
 /**
    A somewhat reduced test case to expose some Valgrind issues.
@@ -26,26 +25,26 @@ mod map_reduce {
     use std::collections::HashMap;
     use std::sync::mpsc::{channel, Sender};
     use std::str;
-    use std::thread::Thread;
+    use std::thread;
 
     pub type putter<'a> = Box<FnMut(String, String) + 'a>;
 
     pub type mapper = extern fn(String, putter);
 
-    enum ctrl_proto { find_reducer(Vec<u8>, Sender<int>), mapper_done, }
+    enum ctrl_proto { find_reducer(Vec<u8>, Sender<isize>), mapper_done, }
 
     fn start_mappers(ctrl: Sender<ctrl_proto>, inputs: Vec<String>) {
         for i in &inputs {
             let ctrl = ctrl.clone();
             let i = i.clone();
-            Thread::spawn(move|| map_task(ctrl.clone(), i.clone()) );
+            thread::spawn(move|| map_task(ctrl.clone(), i.clone()) );
         }
     }
 
     fn map_task(ctrl: Sender<ctrl_proto>, input: String) {
         let mut intermediates = HashMap::new();
 
-        fn emit(im: &mut HashMap<String, int>,
+        fn emit(im: &mut HashMap<String, isize>,
                 ctrl: Sender<ctrl_proto>, key: String,
                 _val: String) {
             if im.contains_key(&key) {
@@ -61,7 +60,8 @@ mod map_reduce {
         }
 
         let ctrl_clone = ctrl.clone();
-        ::map(input, box |a,b| emit(&mut intermediates, ctrl.clone(), a, b) );
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        ::map(input, Box::new(|a,b| emit(&mut intermediates, ctrl.clone(), a, b)));
         ctrl_clone.send(ctrl_proto::mapper_done).unwrap();
     }
 
@@ -71,13 +71,13 @@ mod map_reduce {
         // This task becomes the master control task. It spawns others
         // to do the rest.
 
-        let mut reducers: HashMap<String, int>;
+        let mut reducers: HashMap<String, isize>;
 
         reducers = HashMap::new();
 
         start_mappers(tx, inputs.clone());
 
-        let mut num_mappers = inputs.len() as int;
+        let mut num_mappers = inputs.len() as isize;
 
         while num_mappers > 0 {
             match rx.recv().unwrap() {
index 5a793f7065a41fa6a0c93ac5c7e792a79fc1f1bb..bcd519bc25d202bff878a96db979f5065b89cecf 100644 (file)
 // `&Typer<'tcx>` was getting an incorrect binder level, yielding
 // weird compilation ICEs and so forth.
 
+// pretty-expanded FIXME #23616
+
 trait Typer<'tcx> {
-    fn method(&self, data: &'tcx int) -> &'tcx int { data }
+    fn method(&self, data: &'tcx isize) -> &'tcx isize { data }
 }
 
 struct Tcx<'tcx> {
-    fields: &'tcx int
+    fields: &'tcx isize
 }
 
 impl<'tcx> Typer<'tcx> for Tcx<'tcx> {
index 9e857a33245d16be5b060469a0d0a548e8a3ddc0..6761cc12876fe47ba9f23264aa4a1ce7f920528d 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Typer<'tcx> {
-    fn method(&self, data: &'tcx int) -> &'tcx int { data }
+    fn method(&self, data: &'tcx isize) -> &'tcx isize { data }
     fn dummy(&self) { }
 }
 
index c8992afe36ac71870b2d345fb6f7a3b054d8f64e..858179fb5fe76fc32188776aa43c713946eefff6 100644 (file)
 
 // A basic test of using a higher-ranked trait bound.
 
+// pretty-expanded FIXME #23616
+
 trait FnLike<A,R> {
     fn call(&self, arg: A) -> R;
 }
 
-type FnObject<'b> = for<'a> FnLike<&'a int, &'a int> + 'b;
+type FnObject<'b> = for<'a> FnLike<&'a isize, &'a isize> + 'b;
 
 struct Identity;
 
index 4067b922cfd6b18ef149758adb2e1851e7d3913f..8b4c2aec8452b667d546ba054f7190fce006bfb9 100644 (file)
@@ -10,6 +10,8 @@
 
 // A basic test of using a higher-ranked trait bound.
 
+// pretty-expanded FIXME #23616
+
 trait FnLike<A,R> {
     fn call(&self, arg: A) -> R;
 }
@@ -23,7 +25,7 @@ impl<'a, T> FnLike<&'a T, &'a T> for Identity {
 }
 
 fn call_repeatedly<F>(f: F)
-    where F : for<'a> FnLike<&'a int, &'a int>
+    where F : for<'a> FnLike<&'a isize, &'a isize>
 {
     let x = 3;
     let y = f.call(&x);
index 7b16bb867e79c30004a1ac777e9a0c8fc2efe591..b40f4d27a9c4d63a86e0b6d953fb37122682d2dc 100644 (file)
 // did not consider that a match (something I would like to revise in
 // a later PR).
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 use std::marker::PhantomData;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Foo<T> { x: T }
 
 type Ty<'tcx> = &'tcx TyS<'tcx>;
@@ -29,7 +31,7 @@ enum TyS<'tcx> {
     Boop(PhantomData<*mut &'tcx ()>)
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum Bar<'tcx> {
     Baz(Foo<Ty<'tcx>>)
 }
index d5307c09103a1351c01d24a2e5a71bd3658c9a7f..ecd0bc681c313c46cfe8ba09ac2d0d6fe5cbbf72 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we can parse all the various places that a `for` keyword
 // can appear representing universal quantification.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 #![allow(unused_variables)]
 #![allow(dead_code)]
index 88e6de6d3e6ff6fb93d8aef6bd74bf0cf616f804..bc00a0758f45e8cc6a54c328fe1598f5f82d4284 100644 (file)
@@ -8,25 +8,27 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
-// Test that `F : Fn(int) -> int + Send` is interpreted as two
+// Test that `F : Fn(isize) -> isize + Send` is interpreted as two
 // distinct bounds on `F`.
 
 fn foo1<F>(f: F)
-    where F : FnOnce(int) -> int + Send
+    where F : FnOnce(isize) -> isize + Send
 {
     bar(f);
 }
 
 fn foo2<F>(f: F)
-    where F : FnOnce(int) -> int + Send
+    where F : FnOnce(isize) -> isize + Send
 {
     baz(f);
 }
 
 fn bar<F:Send>(f: F) { }
 
-fn baz<F:FnOnce(int) -> int>(f: F) { }
+fn baz<F:FnOnce(isize) -> isize>(f: F) { }
 
 fn main() {}
index b59e7b67d4eddb4ad11b80ede4fe0193feb0ad4e..892f2f1ae9df7522bf52b8d64100a7421977a195 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
 #![feature(unboxed_closures)]
 
-// Test that `Fn(int) -> int + 'static` parses as `(Fn(int) -> int) +
-// 'static` and not `Fn(int) -> (int + 'static)`. The latter would
+// Test that `Fn(isize) -> isize + 'static` parses as `(Fn(isize) -> isize) +
+// 'static` and not `Fn(isize) -> (isize + 'static)`. The latter would
 // cause a compilation error. Issue #18772.
 
-fn adder(y: int) -> Box<Fn(int) -> int + 'static> {
-    box move |x| y + x
+fn adder(y: isize) -> Box<Fn(isize) -> isize + 'static> {
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    Box::new(move |x| y + x)
 }
 
 fn main() {}
index 9b37b8e49ef3c5c247639548a813c6f95ddd4af5..bdbcda89099e5558faa003dbe36cd260c39bd99f 100644 (file)
 
 // A basic test of using a higher-ranked trait bound.
 
+// pretty-expanded FIXME #23616
+
 trait FnLike<A,R> {
     fn call(&self, arg: A) -> R;
 }
 
-type FnObject<'b> = for<'a> FnLike<&'a int, &'a int> + 'b;
+type FnObject<'b> = for<'a> FnLike<&'a isize, &'a isize> + 'b;
 
 fn main() {
 }
index 1b62a8e809c89dd2b4842ab4a96372f6a6ddbe5d..7741f1904f6ab1ccbc5d1e3ed7104cbc5846b42c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 // A basic test of using a higher-ranked trait bound.
index c90c3643d4e54f8dd5d301ad635b662260f903c0..48d0959630f7d528f0507807fa4e5f68a40a22bf 100644 (file)
 // PrinterSupport<'b>`, gets properly expanded when it appears in a
 // closure type. This used to result in messed up De Bruijn indices.
 
+// pretty-expanded FIXME #23616
+
 trait PrinterSupport<'ast> {
-    fn ast_map(&self) -> Option<&'ast uint> { None }
+    fn ast_map(&self) -> Option<&'ast usize> { None }
 }
 
 struct NoAnn<'ast> {
-    f: Option<&'ast uint>
+    f: Option<&'ast usize>
 }
 
 impl<'ast> PrinterSupport<'ast> for NoAnn<'ast> {
 }
 
-fn foo<'ast, G>(f: Option<&'ast uint>, g: G) where G: FnOnce(&PrinterSupport) {
+fn foo<'ast, G>(f: Option<&'ast usize>, g: G) where G: FnOnce(&PrinterSupport) {
     let annotation = NoAnn { f: f };
     g(&annotation)
 }
index c34e1a4862f828502032508d0af68fe704b1f1a2..008e7ddbc9c5d9043a3902eb5ec27df4c1464ab8 100644 (file)
 
 #![feature(unboxed_closures)]
 
-fn foo<F:Fn(&int)>(f: F) {
+fn foo<F:Fn(&isize)>(f: F) {
     let x = 22;
     f(&x);
 }
 
 fn main() {
-    foo(|x: &int| println!("{}", *x));
+    foo(|x: &isize| println!("{}", *x));
 }
index 5083bd23207306be0fe056e17c259dde134666c0..2345bb01d8ae98e5564eb42ef689f1973d9e7b7e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem::size_of;
 
 #[cfg(target_pointer_width = "32")]
index 3969394a26b93a9daaa6a7c75722b1b268aa7db3..e5acc4a2edd68f7f9fa55acc03b75d920b72411d 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod x {
-    pub fn g() -> uint {14}
+    pub fn g() -> usize {14}
 }
 
 pub fn main(){
index cca0e5b163c434b17402ed91e538a047f271d678..589d6e1581bde7914ec3662c514991f800bf48da 100644 (file)
@@ -34,7 +34,7 @@ macro_rules! run_once {
 pub fn main() {
     let mut i = 0;
 
-    let j: int = {
+    let j: isize = {
         'x: loop {
             // this 'x should refer to the outer loop, lexically
             loop_x!(break 'x);
@@ -44,7 +44,7 @@ pub fn main() {
     };
     assert_eq!(j, 1);
 
-    let k: int = {
+    let k: isize = {
         'x: for _ in 0..1 {
             // ditto
             loop_x!(break 'x);
@@ -54,7 +54,7 @@ pub fn main() {
     };
     assert_eq!(k, 1);
 
-    let l: int = {
+    let l: isize = {
         'x: for _ in 0..1 {
             // ditto
             while_true!(break 'x);
@@ -64,7 +64,7 @@ pub fn main() {
     };
     assert_eq!(l, 1);
 
-    let n: int = {
+    let n: isize = {
         'x: for _ in 0..1 {
             // ditto
             run_once!(continue 'x);
index 0d8da2a93482f4649bd1ec7c351bd88cf63fba3b..2d530275ea21fda957fb6fa8ef31ced39ee9d139 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! loop_x {
     ($e: expr) => {
         // $e shouldn't be able to interact with this 'x
index e5451431adedfd2bc2aba36990872be000f874d5..2cc4e880bbf5ea27f12a509b7b87088f1bde1087 100644 (file)
@@ -11,4 +11,6 @@
 
 
 
-pub fn main() { let mut x: i32 = -400_i32; x = 0_i32 - x; assert!((x == 400_i32)); }
+// pretty-expanded FIXME #23616
+
+pub fn main() { let mut x: i32 = -400; x = 0 - x; assert!((x == 400)); }
index fbb4e446dd55e9d230031769305e46504a4b4be4..5dd53a268b1358a9e04fdcb2e47ed1446017a241 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let mut x: i8 = -12i8;
-    let y: i8 = -12i8;
-    x = x + 1i8;
-    x = x - 1i8;
+    let mut x: i8 = -12;
+    let y: i8 = -12;
+    x = x + 1;
+    x = x - 1;
     assert_eq!(x, y);
 }
index 44c834d233fe7f02d45fce3dc112a8c46140c676..e66a8c85723a0c5532afbb89e51742b5153c17ce 100644 (file)
@@ -9,6 +9,6 @@
 // except according to those terms.
 
 pub fn main() {
-    let i: int = if false { panic!() } else { 5 };
+    let i: isize = if false { panic!() } else { 5 };
     println!("{}", i);
 }
index d2a1a3c71a5fc1d365c9094e3d426b1262acab0f..c72cd10a082e95b7596909e96d66507d6a0ec45d 100644 (file)
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn even(x: uint) -> bool {
-    if x < 2_usize {
+fn even(x: usize) -> bool {
+    if x < 2 {
         return false;
-    } else if x == 2_usize { return true; } else { return even(x - 2_usize); }
+    } else if x == 2 { return true; } else { return even(x - 2); }
 }
 
-fn foo(x: uint) {
+fn foo(x: usize) {
     if even(x) {
         println!("{}", x);
     } else {
@@ -22,4 +22,4 @@ fn foo(x: uint) {
     }
 }
 
-pub fn main() { foo(2_usize); }
+pub fn main() { foo(2); }
index 2d2f77b099151037d97b4784f29df0d96cfcfe9a..c41d02f9b3365f42d526c81b3dc2d13e75627c8a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = Some(3);
     if let Some(y) = x {
@@ -20,7 +22,7 @@ pub fn main() {
         worked = true;
     }
     assert!(worked);
-    let clause: uint;
+    let clause: usize;
     if let None = Some("test") {
         clause = 1;
     } else if 4_usize > 5 {
@@ -40,8 +42,8 @@ pub fn main() {
 
     enum Foo {
         One,
-        Two(uint),
-        Three(String, int)
+        Two(usize),
+        Three(String, isize)
     }
 
     let foo = Foo::Three("three".to_string(), 42);
index b589c083a9789df02acc4d0b2eb7882d9b9eeb39..8d475a99b818833ac41830362b72b7ac02c4ed74 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn foo() { if (return) { } }
 
 pub fn main() { foo(); }
index ab83fb90d3f25ab3f47cdea68d77d7f4021a7b4b..41c859214e96b188cdc19f970946831ad3bf30f2 100644 (file)
@@ -17,6 +17,7 @@
 #![feature(box_syntax)]
 
 use std::fmt;
+use std::usize;
 
 struct A;
 struct B;
@@ -137,6 +138,13 @@ pub fn main() {
     t!(format!("{:+10.3e}", 1.2345e6f64),  "  +1.234e6");
     t!(format!("{:+10.3e}", -1.2345e6f64), "  -1.234e6");
 
+    // Test that pointers don't get truncated.
+    {
+        let val = usize::MAX;
+        let exp = format!("{:#x}", val);
+        t!(format!("{:p}", val as *const isize), exp);
+    }
+
     // Escaping
     t!(format!("{{"), "{");
     t!(format!("}}"), "}");
@@ -146,7 +154,7 @@ pub fn main() {
     test_order();
 
     // make sure that format! doesn't move out of local variables
-    let a = box 3;
+    let a: Box<_> = box 3;
     format!("{}", a);
     format!("{}", a);
 
index 65fc24ae74630d87def6c7cc88f3064b6d4c8c29..711f2dd6c66763db9aed1ba10bfc4b37688efb99 100644 (file)
@@ -8,10 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(advanced_slice_patterns)]
+#![feature(slice_patterns)]
 
-struct Foo(int, int, int, int);
-struct Bar{a: int, b: int, c: int, d: int}
+struct Foo(isize, isize, isize, isize);
+struct Bar{a: isize, b: isize, c: isize, d: isize}
 
 pub fn main() {
     let Foo(..) = Foo(5, 5, 5, 5);
index a33fc4f2e7402204de52172e1d39ea64071676ef..7f1d576e09944e9cceb2bbe541f18ce67a1fe5dc 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum option_<T> {
     none_,
     some_(T),
@@ -19,7 +21,7 @@ impl<T> option_<T> {
 
 enum option__ {
     none__,
-    some__(int)
+    some__(isize)
 }
 
 impl option__ {
diff --git a/src/test/run-pass/impl-inherent-non-conflict.rs b/src/test/run-pass/impl-inherent-non-conflict.rs
new file mode 100644 (file)
index 0000000..210bc34
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2015 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.
+
+// Ensure that an user-defined type admits multiple inherent methods
+// with the same name, which can be called on values that have a
+// precise enough type to allow distinguishing between the methods.
+
+// pretty-expanded FIXME #23616
+
+struct Foo<T>(T);
+
+impl Foo<usize> {
+    fn bar(&self) -> i32 { self.0 as i32 }
+}
+
+impl Foo<isize> {
+    fn bar(&self) -> i32 { -(self.0 as i32) }
+}
+
+fn main() {
+    let foo_u = Foo::<usize>(5);
+    assert_eq!(foo_u.bar(), 5);
+
+    let foo_i = Foo::<isize>(3);
+    assert_eq!(foo_i.bar(), -3);
+}
diff --git a/src/test/run-pass/impl-inherent-prefer-over-trait.rs b/src/test/run-pass/impl-inherent-prefer-over-trait.rs
new file mode 100644 (file)
index 0000000..26f12e9
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+struct Foo;
+
+trait Trait {
+    fn bar(&self);
+}
+
+// Inherent impls should be preferred over trait ones.
+impl Foo {
+    fn bar(&self) {}
+}
+
+impl Trait {
+    fn baz(_: &Foo) {}
+}
+
+impl Trait for Foo {
+    fn bar(&self) { panic!("wrong method called!") }
+}
+
+fn main() {
+    Foo.bar();
+    Foo::bar(&Foo);
+    <Foo>::bar(&Foo);
+
+    // Should work even if Trait::baz doesn't exist.
+    // N.B: `<Trait>::bar` would be ambiguous.
+    <Trait>::baz(&Foo);
+}
diff --git a/src/test/run-pass/impl-not-adjacent-to-type.rs b/src/test/run-pass/impl-not-adjacent-to-type.rs
new file mode 100644 (file)
index 0000000..2ba7375
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+mod foo {
+    pub struct Point {
+        pub x: i32,
+        pub y: i32,
+    }
+}
+
+impl foo::Point {
+    fn x(&self) -> i32 { self.x }
+}
+
+fn main() {
+    assert_eq!((foo::Point { x: 1, y: 3}).x(), 1);
+}
index d7e53f3c38ff793eafb667a9df41e8addc6d6adc..97945f4c4dac347630c06c3f8f80f5ef98ed40e9 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:impl_privacy_xc_1.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate impl_privacy_xc_1;
 
 pub fn main() {
diff --git a/src/test/run-pass/import-crate-with-invalid-spans.rs b/src/test/run-pass/import-crate-with-invalid-spans.rs
new file mode 100644 (file)
index 0000000..39c175f
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2015 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.
+
+// aux-build:crate_with_invalid_spans.rs
+
+// pretty-expanded FIXME #23616
+
+extern crate crate_with_invalid_spans;
+
+fn main() {
+    // The AST of `exported_generic` stored in crate_with_invalid_spans's
+    // metadata should contain an invalid span where span.lo > span.hi.
+    // Let's make sure the compiler doesn't crash when encountering this.
+    let _ = crate_with_invalid_spans::exported_generic(32u32, 7u32);
+}
index bbf914411fde4a0c0956b939ef6907013261f433..9ac35fbb38756b9530f4a55a85d014e54341f852 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use spam::{ham, eggs};
 
 mod spam {
index f7874cc56fc77ecd81ccdb0b1a442d9f1c38f1c3..eb9ec6fe985ac94334a89683f1b0d3f4023fa236 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 
 use std::mem::*;
index 4567651e892f5c14cd9fbb532cf34806871e8165..532cdbbee3cd49e3ae9ad7efdfe5954b4f6ff377 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     use std::mem::replace;
     let mut x = 5;
index 42a90b3e39a4e95efd9d0c242295e6b30644e778..c47448536223ca2b162fd0d9d5899c9d2b6a6933 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use foo::bar::{baz, quux,};
 
 mod foo {
index 3470b54ccbbbc333d31ba6d34cedd855bd40a95f..c2b459d2887276dec1b00ef5df41b86da0161797 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 mod foo {
-    pub fn x(y: int) { println!("{}", y); }
+    pub fn x(y: isize) { println!("{}", y); }
 }
 
 mod bar {
index d684c30aca1b80e26e64a281acb5433f4d4e0f30..4086acc0a8eb43eb0093e36cdf5b00e596f74b96 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
index 4a3358488d8a3ae92d05fbd3b81bcbbb450f090c..2c09eff7b12e5bc5563ef36cf8cec9a262032934 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
index 44f6b6140fbffaeca2bdd1617d32b65c84280c32..229813ff55ceb827f80b95187404e72dbbefcaae 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
index 18cc1aa08482a3317c31f005691adf5f0a4b1264..0cad094d55dd716aed875e41ad601eb7d19f938b 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
index 802dfc1f2ed148062d09dec487da44a48d71af87..545bd7cee5ea8d1f30b4c35ac76455f5c9dddd4c 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
index 15e935c8f4f5f2edba0b736d97c0f4c0acb0e002..4b9d1328951fe50f2b2f6cf6a02929e343308b4e 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
index 119107404d74d60096f186b2627108ec766f5e6a..0f3891bf06715f9ca7d69100bed80de1c77fbb90 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -14,7 +13,7 @@ use foo::x;
 use foo::x as z;
 
 mod foo {
-    pub fn x(y: int) { println!("{}", y); }
+    pub fn x(y: isize) { println!("{}", y); }
 }
 
 pub fn main() { x(10); z(10); }
index d87b59537df8f120968480a5940df427dfc4dd62..9a0d8e201c24391229b548042b71551bedf51026 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn foo(_: &[&str]) {}
 
 fn bad(a: &str, b: &str) {
diff --git a/src/test/run-pass/infer-container-across-object-cast.rs b/src/test/run-pass/infer-container-across-object-cast.rs
deleted file mode 100644 (file)
index 979e76b..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2015 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.
-
-// Given `<expr> as Box<Trait>`, we should be able to infer that a
-// `Box<_>` is the expected type.
-
-trait Foo { fn foo(&self) -> u32; }
-impl Foo for u32 { fn foo(&self) -> u32 { *self } }
-
-// (another impl to ensure trait-matching cannot just choose from a singleton set)
-impl Foo for  () { fn foo(&self) -> u32 { -176 } }
-
-trait Boxed { fn make() -> Self; }
-impl Boxed for Box<u32> { fn make() -> Self { Box::new(7) } }
-
-// (another impl to ensure trait-matching cannot just choose from a singleton set)
-impl Boxed for () { fn make() -> Self { () } }
-
-fn boxed_foo() {
-    let b7 = Boxed::make() as Box<Foo>;
-    assert_eq!(b7.foo(), 7);
-}
-
-trait Refed<'a,T> { fn make(&'a T) -> Self; }
-impl<'a> Refed<'a, u32> for &'a u32 { fn make(x: &'a u32) -> Self { x } }
-
-// (another impl to ensure trait-matching cannot just choose from a singleton set)
-impl<'a,'b> Refed<'a, ()> for &'b () { fn make(_: &'a ()) -> Self { static U: () = (); &U } }
-
-fn refed_foo() {
-    let a = 8;
-    let b7 = Refed::make(&a) as &Foo;
-    assert_eq!(b7.foo(), 8);
-}
-
-fn check_subtyping_works() {
-    fn inner<'short, 'long:'short>(_s: &'short u32,
-                                   l: &'long u32) -> &'short (Foo+'short) {
-        Refed::make(l) as &Foo
-    }
-
-    let a = 9;
-    let b = 10;
-    let r = inner(&b, &a);
-    assert_eq!(r.foo(), 9);
-}
-
-pub fn main() {
-    boxed_foo();
-    refed_foo();
-    check_subtyping_works();
-}
index f240a5e6de55fd64d5650cbb69cf90969bb0a731..f00005fc7d0b58c8fadf64c80937111339a82d47 100644 (file)
@@ -11,6 +11,8 @@
 // issue #680
 
 
-fn f() -> Vec<int> { Vec::new() }
+// pretty-expanded FIXME #23616
+
+fn f() -> Vec<isize> { Vec::new() }
 
 pub fn main() { }
index be561dfffa6f91a34bd539a29999c8024aabcaae..fcbd4b332318eb6072adfaa04a819c478063be25 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = 2;
     let x_message = match x {
index e4168ea145212aa9afc0f219171b68c0a959cbb9..e8c5996f4fa098791f139e52b50183cea94386ef 100644 (file)
@@ -14,7 +14,7 @@
 */
 // ignore-test
 
-fn loopy(n: int) {
+fn loopy(n: isize) {
     if n > 0 { spawn(move|| { loopy(n - 1) }); spawn(move|| { loopy(n - 1) }); }
     loop { }
 }
index 6643636c5704d8afba613a1fcff4f53271a3bb7f..042268435c7af88460ef206dca345c3572afd18b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct Foo;
 
 impl Foo {
@@ -31,4 +33,3 @@ fn main() {
     let x = &(&(&Foo));
     x.foo();
 }
-
index 8ee6054f8ba5634cdcdb97663cfedbe33ce5cc30..26d58d34b9dea1e4dc373adcaeaff2057590b4c9 100644 (file)
 // Doing it incorrectly causes massive slowdown in LLVM during
 // optimisation.
 
-#![feature(intrinsics)]
+// pretty-expanded FIXME #23616
 
-use std::thread::Thread;
+#![feature(intrinsics, std_misc)]
+
+use std::thread;
 
 extern "rust-intrinsic" {
     pub fn init<T>() -> T;
@@ -24,7 +26,7 @@ const SIZE: usize = 1024 * 1024;
 
 fn main() {
     // do the test in a new thread to avoid (spurious?) stack overflows
-    let _ = Thread::scoped(|| {
+    let _ = thread::scoped(|| {
         let _memory: [u8; SIZE] = unsafe { init() };
     }).join();
 }
index ee793359fbc89b522786b7c281d93987f0b35b24..eb50fbed774e41d28e9c67741822c0c9c1ef9364 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 #![feature(unsafe_destructor)]
@@ -18,7 +20,7 @@ use std::cell::Cell;
 // as a move unless the stored thing is used afterwards.
 
 struct r<'a> {
-    i: &'a Cell<int>,
+    i: &'a Cell<isize>,
 }
 
 struct BoxR<'a> { x: r<'a> }
@@ -30,7 +32,7 @@ impl<'a> Drop for r<'a> {
     }
 }
 
-fn r(i: &Cell<int>) -> r {
+fn r(i: &Cell<isize>) -> r {
     r {
         i: i
     }
@@ -67,7 +69,7 @@ fn test_tup() {
 fn test_unique() {
     let i = &Cell::new(0);
     {
-        let _a = box r(i);
+        let _a: Box<_> = box r(i);
     }
     assert_eq!(i.get(), 1);
 }
@@ -75,7 +77,7 @@ fn test_unique() {
 fn test_unique_rec() {
     let i = &Cell::new(0);
     {
-        let _a = box BoxR {
+        let _a: Box<_> = box BoxR {
             x: r(i)
         };
     }
index afb2b21b04ffa637add6be24dee423b7585ccd02..a807e582ff464ce71f9f0cdb66bfde8907131f9c 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 struct Foo;
 
 impl Foo {
index e4026a8fd0118a7fd5ea44920cabf0072ddb4548..48f2006ed59ba142dcdae26e10a027d58b33a2da 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:inner_static.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate inner_static;
 
 pub fn main() {
index 35897d5b823f1e9dcc628dabb704fad5eb58a0f8..28fba70eb24d96c5daccc484c2d902b0278ab4d2 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::ptr;
 
 // check that we do not report a type like this as uninstantiable,
 // even though it would be if the nxt field had type @foo:
 struct foo(X);
 
-struct X { x: uint, nxt: *const foo }
+struct X { x: usize, nxt: *const foo }
 
 pub fn main() {
     let _x = foo(X {x: 0, nxt: ptr::null()});
index 169be054282043a0ed38f74ddf50ae7c1d56d9c9..9495552af409bd7930794864b27391170a2734bf 100644 (file)
@@ -11,4 +11,6 @@
 
 
 
-pub fn main() { let _x: int = 10; }
+// pretty-expanded FIXME #23616
+
+pub fn main() { let _x: isize = 10; }
index ea8825d22dffde280dc3530abb4f92007aaa114c..b782925fa93572387ac00fcbd5df9dbcdd12ddf2 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let a = 0xBEEF_isize;
     let b = 0o755_isize;
index 05973a545a20d1ab5165be24f83a266f0cf9b162..e953cf2fda1af9bce4a83dceeba8a765845e7ca9 100644 (file)
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn foo(_: *const ()) {}
 
 fn main() {
     let a = 3;
     foo(&a as *const _ as *const ());
 }
-
index 05b275a0d8cabb05ae9519914560835120907aa0..31aca964def1cbc6155927b5d6363e50564af674 100644 (file)
@@ -11,4 +11,3 @@
 fn main() {
     println!("{}", std::mem::size_of_val(&1));
 }
-
index 542efe334597f83c682dd07f85126dce2f9f75ba..57f80bb14e2fec8a4c0048e78a79e09c9b993a63 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     fn id_i8(n: i8) -> i8 { n }
     fn id_i16(n: i16) -> i16 { n }
     fn id_i32(n: i32) -> i32 { n }
     fn id_i64(n: i64) -> i64 { n }
 
-    fn id_uint(n: uint) -> uint { n }
+    fn id_uint(n: usize) -> usize { n }
     fn id_u8(n: u8) -> u8 { n }
     fn id_u16(n: u16) -> u16 { n }
     fn id_u32(n: u32) -> u32 { n }
@@ -40,7 +42,7 @@ pub fn main() {
     id_i64(j);
     id_i64(-9_223_372_036_854_775_808);
 
-    let _i: uint = 1;
+    let _i: usize = 1;
     let j = 1;
     id_uint(j);
     id_uint(1);
index 26a0abc76aee2a668fa4d38e4a801e2fdcc2adf2..9ccf1c3bbb80381be78e003fcc9e477a8f2ac33d 100644 (file)
@@ -9,10 +9,14 @@
 // except according to those terms.
 
 // Regression test for type inference failure around shifting. In this
-// case, the iteration yields an int, but we hadn't run the full type
+// case, the iteration yields an isize, but we hadn't run the full type
 // propagation yet, and so we just saw a type variable, yielding an
 // error.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::u8;
 
 trait IntoIterator {
@@ -31,7 +35,7 @@ impl<I> IntoIterator for I where I: Iterator {
 
 fn desugared_for_loop_bad(byte: u8) -> u8 {
     let mut result = 0;
-    let mut x = IntoIterator::into_iter(range(0, u8::BITS));
+    let mut x = IntoIterator::into_iter(0..u8::BITS);
     let mut y = Iterator::next(&mut x);
     let mut z = y.unwrap();
     byte >> z;
index f852bac404861a8d9683e3fa47c2c7412a773837..44dd191eb3ee39d14ab266e519c48ff109e2f296 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(intrinsics, main)]
 
 mod rusti {
     extern "rust-intrinsic" {
-        pub fn pref_align_of<T>() -> uint;
-        pub fn min_align_of<T>() -> uint;
+        pub fn pref_align_of<T>() -> usize;
+        pub fn min_align_of<T>() -> usize;
     }
 }
 
@@ -27,8 +29,8 @@ mod m {
     #[cfg(target_arch = "x86")]
     pub fn main() {
         unsafe {
-            assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize);
-            assert_eq!(::rusti::min_align_of::<u64>(), 4_usize);
+            assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+            assert_eq!(::rusti::min_align_of::<u64>(), 4);
         }
     }
 
@@ -36,8 +38,20 @@ mod m {
     #[cfg(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64"))]
     pub fn main() {
         unsafe {
-            assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize);
-            assert_eq!(::rusti::min_align_of::<u64>(), 8_usize);
+            assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+            assert_eq!(::rusti::min_align_of::<u64>(), 8);
+        }
+    }
+}
+
+#[cfg(target_os = "bitrig")]
+mod m {
+    #[main]
+    #[cfg(target_arch = "x86_64")]
+    pub fn main() {
+        unsafe {
+            assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+            assert_eq!(::rusti::min_align_of::<u64>(), 8);
         }
     }
 }
@@ -48,8 +62,8 @@ mod m {
     #[cfg(target_arch = "x86")]
     pub fn main() {
         unsafe {
-            assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize);
-            assert_eq!(::rusti::min_align_of::<u64>(), 8_usize);
+            assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+            assert_eq!(::rusti::min_align_of::<u64>(), 8);
         }
     }
 
@@ -57,8 +71,8 @@ mod m {
     #[cfg(target_arch = "x86_64")]
     pub fn main() {
         unsafe {
-            assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize);
-            assert_eq!(::rusti::min_align_of::<u64>(), 8_usize);
+            assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+            assert_eq!(::rusti::min_align_of::<u64>(), 8);
         }
     }
 }
@@ -69,8 +83,8 @@ mod m {
     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
     pub fn main() {
         unsafe {
-            assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize);
-            assert_eq!(::rusti::min_align_of::<u64>(), 8_usize);
+            assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+            assert_eq!(::rusti::min_align_of::<u64>(), 8);
         }
     }
 }
index abf9b94c59d8a6f113bc68e1563941904a25bf7d..fc886d7e30165023cf33926a5c62677f9d99f051 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::intrinsics::assume;
 
 unsafe fn f(x: i32) -> i32 {
@@ -22,4 +26,3 @@ fn main() {
     let x = unsafe { f(34) };
     assert_eq!(x, 42);
 }
-
index e6a81dbe5d95f9d68c774ac27c87b702c7d9f062..c5fe02b9190d4dd28799d72ca526d76a670d8795 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:cci_intrinsic.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate cci_intrinsic;
 use cci_intrinsic::atomic_xchg;
 
index d3f62f9d04ad030555d7e393432d5c152cd3976c..61a9f6109a3e8882b2836d125a16c50a4bfea732 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 #![feature(intrinsics)]
@@ -40,7 +42,7 @@ mod rusti {
 
 pub fn main() {
     unsafe {
-        let mut x = box 1;
+        let mut x: Box<_> = box 1;
 
         assert_eq!(rusti::atomic_load(&*x), 1);
         *x = 5;
index 0daf661c2f6c5bd04f882d018065e1774893f666..98f069f77f3f03bcb257c0eba6c0f58cbf1a9a9d 100644 (file)
@@ -8,11 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 #![feature(intrinsics)]
+// needed to check for drop fill word.
+#![feature(filling_drop)]
 
-use std::mem::transmute;
+use std::mem::{self, transmute};
 
 mod rusti {
     extern "rust-intrinsic" {
@@ -23,11 +27,12 @@ mod rusti {
 
 pub fn main() {
     unsafe {
-        let x = box 1;
+        let x: Box<_> = box 1;
         let mut y = rusti::init();
-        let mut z: *const uint = transmute(&x);
+        let mut z: *const usize = transmute(&x);
         rusti::move_val_init(&mut y, x);
         assert_eq!(*y, 1);
-        assert_eq!(*z, 0); // `x` is nulled out, not directly visible
+        // `x` is nulled out, not directly visible
+        assert_eq!(*z, mem::POST_DROP_USIZE);
     }
 }
index 91af669340d61a95448406e5bb6021d24264f45d..1ff910356eb9860d873e023b4d7c87deebffbfe0 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(intrinsics)]
 
 use std::ptr;
@@ -22,9 +24,9 @@ extern "rust-intrinsic" {
     fn return_address() -> *const u8;
 }
 
-fn f(result: &mut uint) -> Point {
+fn f(result: &mut usize) -> Point {
     unsafe {
-        *result = return_address() as uint;
+        *result = return_address() as usize;
         Point {
             x: 1.0,
             y: 2.0,
@@ -37,7 +39,6 @@ fn f(result: &mut uint) -> Point {
 fn main() {
     let mut intrinsic_reported_address = 0;
     let pt = f(&mut intrinsic_reported_address);
-    let actual_address = &pt as *const Point as uint;
+    let actual_address = &pt as *const Point as usize;
     assert_eq!(intrinsic_reported_address, actual_address);
 }
-
index 34fd8effd4912de05a826f1a6002ba0491017ee9..3d2c1ec5c197746e512b07468a6dbadae56ad300 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(intrinsics)]
 
 mod rusti {
@@ -16,5 +18,5 @@ mod rusti {
     }
 }
 pub fn main() {
-    let _a : int = unsafe {rusti::uninit()};
+    let _a : isize = unsafe {rusti::uninit()};
 }
index 5e8b758cdf68f873dec08f8ff88690caa65a7c99..86a370a0942d965ea4060911219bbd1c42e0b99b 100644 (file)
@@ -8,11 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::intrinsics;
 
 // See also src/test/run-make/intrinsic-unreachable.
 
-unsafe fn f(x: uint) -> uint {
+unsafe fn f(x: usize) -> usize {
     match x {
         17 => 23,
         _ => intrinsics::unreachable(),
index 2b0f7cc7d7d3214dad905b149475b645f79303ac..15dbe796ef589ebde03e193cc3bc819dd8685f90 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(negate_unsigned)]
 #![feature(intrinsics)]
 
 mod rusti {
@@ -37,83 +40,83 @@ pub fn main() {
     unsafe {
         use rusti::*;
 
-        assert_eq!(ctpop8(0u8), 0u8);
-        assert_eq!(ctpop16(0u16), 0u16);
-        assert_eq!(ctpop32(0u32), 0u32);
-        assert_eq!(ctpop64(0u64), 0u64);
-
-        assert_eq!(ctpop8(1u8), 1u8);
-        assert_eq!(ctpop16(1u16), 1u16);
-        assert_eq!(ctpop32(1u32), 1u32);
-        assert_eq!(ctpop64(1u64), 1u64);
-
-        assert_eq!(ctpop8(10u8), 2u8);
-        assert_eq!(ctpop16(10u16), 2u16);
-        assert_eq!(ctpop32(10u32), 2u32);
-        assert_eq!(ctpop64(10u64), 2u64);
-
-        assert_eq!(ctpop8(100u8), 3u8);
-        assert_eq!(ctpop16(100u16), 3u16);
-        assert_eq!(ctpop32(100u32), 3u32);
-        assert_eq!(ctpop64(100u64), 3u64);
-
-        assert_eq!(ctpop8(-1u8), 8u8);
-        assert_eq!(ctpop16(-1u16), 16u16);
-        assert_eq!(ctpop32(-1u32), 32u32);
-        assert_eq!(ctpop64(-1u64), 64u64);
-
-        assert_eq!(ctlz8(0u8), 8u8);
-        assert_eq!(ctlz16(0u16), 16u16);
-        assert_eq!(ctlz32(0u32), 32u32);
-        assert_eq!(ctlz64(0u64), 64u64);
-
-        assert_eq!(ctlz8(1u8), 7u8);
-        assert_eq!(ctlz16(1u16), 15u16);
-        assert_eq!(ctlz32(1u32), 31u32);
-        assert_eq!(ctlz64(1u64), 63u64);
-
-        assert_eq!(ctlz8(10u8), 4u8);
-        assert_eq!(ctlz16(10u16), 12u16);
-        assert_eq!(ctlz32(10u32), 28u32);
-        assert_eq!(ctlz64(10u64), 60u64);
-
-        assert_eq!(ctlz8(100u8), 1u8);
-        assert_eq!(ctlz16(100u16), 9u16);
-        assert_eq!(ctlz32(100u32), 25u32);
-        assert_eq!(ctlz64(100u64), 57u64);
-
-        assert_eq!(cttz8(-1u8), 0u8);
-        assert_eq!(cttz16(-1u16), 0u16);
-        assert_eq!(cttz32(-1u32), 0u32);
-        assert_eq!(cttz64(-1u64), 0u64);
-
-        assert_eq!(cttz8(0u8), 8u8);
-        assert_eq!(cttz16(0u16), 16u16);
-        assert_eq!(cttz32(0u32), 32u32);
-        assert_eq!(cttz64(0u64), 64u64);
-
-        assert_eq!(cttz8(1u8), 0u8);
-        assert_eq!(cttz16(1u16), 0u16);
-        assert_eq!(cttz32(1u32), 0u32);
-        assert_eq!(cttz64(1u64), 0u64);
-
-        assert_eq!(cttz8(10u8), 1u8);
-        assert_eq!(cttz16(10u16), 1u16);
-        assert_eq!(cttz32(10u32), 1u32);
-        assert_eq!(cttz64(10u64), 1u64);
-
-        assert_eq!(cttz8(100u8), 2u8);
-        assert_eq!(cttz16(100u16), 2u16);
-        assert_eq!(cttz32(100u32), 2u32);
-        assert_eq!(cttz64(100u64), 2u64);
-
-        assert_eq!(cttz8(-1u8), 0u8);
-        assert_eq!(cttz16(-1u16), 0u16);
-        assert_eq!(cttz32(-1u32), 0u32);
-        assert_eq!(cttz64(-1u64), 0u64);
-
-        assert_eq!(bswap16(0x0A0Bu16), 0x0B0Au16);
-        assert_eq!(bswap32(0x0ABBCC0Du32), 0x0DCCBB0Au32);
-        assert_eq!(bswap64(0x0122334455667708u64), 0x0877665544332201u64);
+        assert_eq!(ctpop8(0), 0);
+        assert_eq!(ctpop16(0), 0);
+        assert_eq!(ctpop32(0), 0);
+        assert_eq!(ctpop64(0), 0);
+
+        assert_eq!(ctpop8(1), 1);
+        assert_eq!(ctpop16(1), 1);
+        assert_eq!(ctpop32(1), 1);
+        assert_eq!(ctpop64(1), 1);
+
+        assert_eq!(ctpop8(10), 2);
+        assert_eq!(ctpop16(10), 2);
+        assert_eq!(ctpop32(10), 2);
+        assert_eq!(ctpop64(10), 2);
+
+        assert_eq!(ctpop8(100), 3);
+        assert_eq!(ctpop16(100), 3);
+        assert_eq!(ctpop32(100), 3);
+        assert_eq!(ctpop64(100), 3);
+
+        assert_eq!(ctpop8(-1), 8);
+        assert_eq!(ctpop16(-1), 16);
+        assert_eq!(ctpop32(-1), 32);
+        assert_eq!(ctpop64(-1), 64);
+
+        assert_eq!(ctlz8(0), 8);
+        assert_eq!(ctlz16(0), 16);
+        assert_eq!(ctlz32(0), 32);
+        assert_eq!(ctlz64(0), 64);
+
+        assert_eq!(ctlz8(1), 7);
+        assert_eq!(ctlz16(1), 15);
+        assert_eq!(ctlz32(1), 31);
+        assert_eq!(ctlz64(1), 63);
+
+        assert_eq!(ctlz8(10), 4);
+        assert_eq!(ctlz16(10), 12);
+        assert_eq!(ctlz32(10), 28);
+        assert_eq!(ctlz64(10), 60);
+
+        assert_eq!(ctlz8(100), 1);
+        assert_eq!(ctlz16(100), 9);
+        assert_eq!(ctlz32(100), 25);
+        assert_eq!(ctlz64(100), 57);
+
+        assert_eq!(cttz8(-1), 0);
+        assert_eq!(cttz16(-1), 0);
+        assert_eq!(cttz32(-1), 0);
+        assert_eq!(cttz64(-1), 0);
+
+        assert_eq!(cttz8(0), 8);
+        assert_eq!(cttz16(0), 16);
+        assert_eq!(cttz32(0), 32);
+        assert_eq!(cttz64(0), 64);
+
+        assert_eq!(cttz8(1), 0);
+        assert_eq!(cttz16(1), 0);
+        assert_eq!(cttz32(1), 0);
+        assert_eq!(cttz64(1), 0);
+
+        assert_eq!(cttz8(10), 1);
+        assert_eq!(cttz16(10), 1);
+        assert_eq!(cttz32(10), 1);
+        assert_eq!(cttz64(10), 1);
+
+        assert_eq!(cttz8(100), 2);
+        assert_eq!(cttz16(100), 2);
+        assert_eq!(cttz32(100), 2);
+        assert_eq!(cttz64(100), 2);
+
+        assert_eq!(cttz8(-1), 0);
+        assert_eq!(cttz16(-1), 0);
+        assert_eq!(cttz32(-1), 0);
+        assert_eq!(cttz64(-1), 0);
+
+        assert_eq!(bswap16(0x0A0B), 0x0B0A);
+        assert_eq!(bswap32(0x0ABBCC0D), 0x0DCCBB0A);
+        assert_eq!(bswap64(0x0122334455667708), 0x0877665544332201);
     }
 }
index ed88b3c65e09c8f428c3740c77e693a0a9b82c2e..841ff297a2ac7ded3ac3396af8d6b8d2c078cad3 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(intrinsics)]
+// pretty-expanded FIXME #23616
+
+#![feature(intrinsics, core)]
 
 macro_rules! assert_approx_eq {
     ($a:expr, $b:expr) => ({
@@ -65,8 +66,8 @@ pub fn main() {
         assert_approx_eq!(sqrtf32(64f32), 8f32);
         assert_approx_eq!(sqrtf64(64f64), 8f64);
 
-        assert_approx_eq!(powif32(25f32, -2i32), 0.0016f32);
-        assert_approx_eq!(powif64(23.2f64, 2i32), 538.24f64);
+        assert_approx_eq!(powif32(25f32, -2), 0.0016f32);
+        assert_approx_eq!(powif64(23.2f64, 2), 538.24f64);
 
         assert_approx_eq!(sinf32(0f32), 0f32);
         assert_approx_eq!(sinf64(f64::consts::PI / 2f64), 1f64);
index ef5ef2f215cc25fdcab8966cc3ff9d75cee4f0cb..1aae8131d80080e301a46abd23a7a3ef65c099f5 100644 (file)
@@ -14,6 +14,8 @@
 // successfully (and safely) invoke external, cdecl
 // functions from outside the crate.
 
+// pretty-expanded FIXME #23616
+
 extern crate foreign_lib;
 
 pub fn main() {
index 51adeea394ca9371bf04023b5342f10165743629..0c2fbb01f48f475179b6a3ad366c1dcdca007126 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let ((),()) = ((),());
 }
index 8f494ea81fcb329517be35aab0da3a8303151a9d..1ca2476a1013b7f953a37726a1ac91777fcab31e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 unsafe extern fn foo() {}
 unsafe extern "C" fn bar() {}
 
index 826c23a782bf18a5ff1312029ebc7f6ffe40e97b..53d6f67f119eef142111718147b1c07b73bde5e9 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-10028.rs
 
-extern crate "issue-10028" as issue10028;
+// pretty-expanded FIXME #23616
+
+extern crate issue_10028 as issue10028;
 
 use issue10028::ZeroLengthThingWithDestructor;
 
index a94ed4ed5b90a29df8cf37423256e164eebd903c..4dc1487b9af949fe515929a89ced95ff375a3d0d 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // aux-build:issue_10031_aux.rs
+// pretty-expanded FIXME #23616
+
 extern crate issue_10031_aux;
 
 pub fn main() {
index 52b6677428727dd13f76bf6610d3ad496f883ec9..b5c97bd10edfe8082791e79334e54bf6031a0e28 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum StdioContainer {
     CreatePipe(bool)
 }
index 1aa9c96de1a9418f66ae165e73fd98cac338e52e..2d695c75d30446fd28a07ca510e0ca812fad52b5 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct A { foo: int }
-struct B { a: int, b: int, c: int }
+// pretty-expanded FIXME #23616
+
+struct A { foo: isize }
+struct B { a: isize, b: isize, c: isize }
 
 fn mka() -> A { panic!() }
 fn mkb() -> B { panic!() }
index da73c4b27ac4420e8b2145fc0b0a49c0e0f108c4..10b4162305432e5391df1a1b5211725a01ffc06f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub struct Foo;
 
 pub trait Bar {
index 29e4801d0a9aac66aed21b86449825d18234fd72..2c0811b69e020916669b925221e8540eae816d16 100644 (file)
@@ -12,6 +12,8 @@
 // Make sure that if a process doesn't have its stdio/stderr descriptors set up
 // that we don't die in a large ball of fire
 
+#![feature(old_io)]
+
 use std::env;
 use std::old_io::process;
 
index bc77b4c534311f0115a3fe3966238d206d4882d5..379bdffbbb22f11a289c0945ebd3a1fa0937d8a4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     //// I am not a doc comment!
     ////////////////// still not a doc comment
index 883e52b61d081bdaae2e6e4d46c399ff9922d2bc..c049bdfe83cf142216dcdc8f535e0aec49b0b2f9 100644 (file)
 // Regression test for issue #10682
 // Nested `proc` usage can't use outer owned data
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn work(_: Box<int>) {}
+fn work(_: Box<isize>) {}
 fn foo<F:FnOnce()>(_: F) {}
 
 pub fn main() {
index a01d2e6f1a9ed90873de03e2efd58fa2e64f1c41..eb2177202a22b526240471c39bec9acfd6e0109c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::ascii::AsciiExt;
 
 static NAME: &'static str = "hello world";
index 90e87f96f7899e54edec7a9dad75b6d9fa140c65..795ad8fb35b82389df0ebe328083c21b6677fc0b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum v {}
 pub fn main() {
     let y: v = unsafe { ::std::mem::uninitialized() };
index c3ec3fc40e30a77559d095e4d16ddef29ff17fbe..0a6e454e181a493972fc84f51d3a9b9f7cb29d50 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 fn f<F:FnOnce()>(p: F) {
index a6af2327c9e8096f73cea2876aadb63e41742a2f..49694f2755c234da6ae5072c79dfa62ce2b0373f 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_no_drop_flag)]
 
-static mut drop_count: uint = 0;
+static mut drop_count: usize = 0;
 
 #[unsafe_no_drop_flag]
 struct Foo {
index 92ea6026ff66cd06f54b0ad4364d55797c459188..3789b93ad76c9a684f67ab3ab6ceb57bd3ea7cd1 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 extern "Rust" fn foo() {}
 
 fn main() {}
index f824b5fd4dcd8db53b67744a8a5949e8a69ea615..cfabf699fa278ea02fc290187114b2285d2a830e 100644 (file)
@@ -8,4 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 extern "Rust" fn main() {}
index c717053cffc74d10424f7fc5fac0afccd6161e41..9d680d1962f8f7a515e0a4146eef4aea0c256360 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
index 174a69e1135cdf7a766ada2f71a70984dd537e7d..bb322635094e549357638065e6fe738d8451e2c3 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -42,13 +44,13 @@ impl  Whatever {
 
 fn main() {
     {
-        let f = box DroppableStruct;
+        let f: Box<_> = box DroppableStruct;
         let _a = Whatever::new(box f as Box<MyTrait>);
     }
     assert!(unsafe { DROPPED });
     unsafe { DROPPED = false; }
     {
-        let f = box DroppableEnum::DroppableVariant1;
+        let f: Box<_> = box DroppableEnum::DroppableVariant1;
         let _a = Whatever::new(box f as Box<MyTrait>);
     }
     assert!(unsafe { DROPPED });
index 69a23e8099076a6ebe94b85d6559debca3ec8890..49883f15d3192e62c8f4882c198fa0b484d6e228 100644 (file)
@@ -9,30 +9,32 @@
 // except according to those terms.
 
 
-pub fn foo() -> int {
+// pretty-expanded FIXME #23616
+
+pub fn foo() -> isize {
     3
 }
-pub fn bar() -> int {
+pub fn bar() -> isize {
     4
 }
 
 pub mod baz {
     use {foo, bar};
-    pub fn quux() -> int {
+    pub fn quux() -> isize {
         foo() + bar()
     }
 }
 
 pub mod grault {
     use {foo};
-    pub fn garply() -> int {
+    pub fn garply() -> isize {
         foo()
     }
 }
 
 pub mod waldo {
     use {};
-    pub fn plugh() -> int {
+    pub fn plugh() -> isize {
         0
     }
 }
index 1717075885d7a1bfd2449762e9d68b41bd1e208b..2e6d278037902459c4e3416eaa9e7ab98401199e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![deny(missing_docs)]
 #![doc="module"]
 
index 7fab6662ee01c3d3ee02d3bca9b5e9cf55228654..9f0417a8be9ba78b20cda8f0cb74cdd7f5a230bc 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub mod two_tuple {
     pub trait T { fn dummy(&self) { } }
     pub struct P<'a>(&'a (T + 'a), &'a (T + 'a));
index 9440e0c2874a0cfc1ec1b000bbd2aaa21c30adb0..c024c6297bf10304afe9ef08baf08c2bf546ca99 100644 (file)
 
 // compile-flags: --cfg foo
 
+// pretty-expanded FIXME #23616
+
 struct Foo {
     #[cfg(fail)]
     bar: baz,
-    foo: int,
+    foo: isize,
 }
 
 struct Foo2 {
     #[cfg(foo)]
-    foo: int,
+    foo: isize,
 }
 
 enum Bar1 {
@@ -35,8 +37,8 @@ enum Bar2 {
 enum Bar3 {
     Bar3_1 {
         #[cfg(fail)]
-        foo: int,
-        bar: int,
+        foo: isize,
+        bar: isize,
     }
 }
 
index 22c88c874f096a70a92c8112ff941e438f73ec2d..3d131b51033dc447ede56af358a95496e5c4ce1e 100644 (file)
@@ -11,6 +11,8 @@
 // Issue #1112
 // Alignment of interior pointers to dynamic-size types
 
+// pretty-expanded FIXME #23616
+
 struct X<T> {
     a: T,
     b: u8,
@@ -22,23 +24,23 @@ struct X<T> {
 }
 
 pub fn main() {
-    let x: X<int> = X {
+    let x: X<isize> = X {
         a: 12345678,
-        b: 9u8,
+        b: 9,
         c: true,
-        d: 10u8,
-        e: 11u16,
-        f: 12u8,
-        g: 13u8
+        d: 10,
+        e: 11,
+        f: 12,
+        g: 13
     };
     bar(x);
 }
 
 fn bar<T>(x: X<T>) {
-    assert_eq!(x.b, 9u8);
+    assert_eq!(x.b, 9);
     assert_eq!(x.c, true);
-    assert_eq!(x.d, 10u8);
-    assert_eq!(x.e, 11u16);
-    assert_eq!(x.f, 12u8);
-    assert_eq!(x.g, 13u8);
+    assert_eq!(x.d, 10);
+    assert_eq!(x.e, 11);
+    assert_eq!(x.f, 12);
+    assert_eq!(x.g, 13);
 }
index 1325b51a54ff2b6a4380f38bb7d64f8d9420846f..41b54727b662fe30ac9c784fca0f55e36e4b380c 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
 
 trait Foo { fn dummy(&self) { } }
-impl Foo for int {}
+impl Foo for isize {}
 fn foo(_: [&Foo; 2]) {}
 fn foos(_: &[&Foo]) {}
 fn foog<T>(_: &[T], _: &[T]) {}
@@ -39,16 +41,16 @@ fn main() {
     let r = &1;
     foog(x, &[r]);
 
-    let x: [Box<Foo>; 2] = [box 1, box 2];
+    let x: [Box<Foo>; 2] = [Box::new(1), Box::new(2)];
     bar(x);
-    bar([box 1, box 2]);
+    bar([Box::new(1), Box::new(2)]);
 
-    let x: &[Box<Foo>] = &[box 1, box 2];
+    let x: &[Box<Foo>] = &[Box::new(1), Box::new(2)];
     bars(x);
-    bars(&[box 1, box 2]);
+    bars(&[Box::new(1), Box::new(2)]);
 
-    let x: &[Box<Foo>] = &[box 1, box 2];
-    foog(x, &[box 1]);
+    let x: &[Box<Foo>] = &[Box::new(1), Box::new(2)];
+    foog(x, &[Box::new(1)]);
 
     struct T<'a> {
         t: [&'a (Foo+'a); 2]
@@ -85,9 +87,9 @@ fn main() {
         t: &'a [Box<Foo+'static>]
     }
     let _n = M {
-        t: &[box 1, box 2]
+        t: &[Box::new(1), Box::new(2)]
     };
-    let x: [Box<Foo>; 2] = [box 1, box 2];
+    let x: [Box<Foo>; 2] = [Box::new(1), Box::new(2)];
     let _n = M {
         t: &x
     };
index 02c82d9c9474b0913473ffa7615db31f85cf948a..14017ee1789242db25ec2182e5445459a7532f0b 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:issue-11224.rs
 
-extern crate "issue-11224" as unused;
+// pretty-expanded FIXME #23616
+
+extern crate issue_11224 as unused;
 
 pub fn main() {}
index a45d129ade2f9fec24923885d2b237f77ce7a7ee..a74fdbe3de472b0112a06f076b90c19b2fd744a8 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-11225-1.rs
 
-extern crate "issue-11225-1" as foo;
+// pretty-expanded FIXME #23616
+
+extern crate issue_11225_1 as foo;
 
 pub fn main() {
     foo::foo(1);
index f07957b30ec9fe4afb9db680109df052bdbf9c62..c6fc5e8b484e03e81edd38d200604f77086e4fd1 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-11225-2.rs
 
-extern crate "issue-11225-2" as foo;
+// pretty-expanded FIXME #23616
+
+extern crate issue_11225_2 as foo;
 
 pub fn main() {
     foo::foo(1);
index 6fb2c532e0c0b1f48300f3d3740138c80e6092da..1a1227c7920193c4e07d3aa7bbd6fafe2633618c 100644 (file)
@@ -15,11 +15,11 @@ struct Empty;
 trait T<U> {
     fn next(&mut self) -> Option<U>;
 }
-impl T<int> for Empty {
-    fn next(&mut self) -> Option<int> { None }
+impl T<isize> for Empty {
+    fn next(&mut self) -> Option<isize> { None }
 }
 
-fn do_something_with(a : &mut T<int>) {
+fn do_something_with(a : &mut T<isize>) {
     println!("{:?}", a.next())
 }
 
index 26634fabf5a1542f51726873c768f0689c67057b..5b4bd6c9f2bfc2edb42f6da74739bb287194d4bd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Common { fn dummy(&self) { } }
 
 impl<'t, T> Common for (T, &'t T) {}
index 1fc72fd2cbef6f1f648afd7b6c93dab6a166c810..21ed30683f50fb9d6af2c7d9efb8bc3e142dd841 100644 (file)
@@ -10,7 +10,7 @@
 
 // aux-build:issue-11508.rs
 
-extern crate "issue-11508" as rand;
+extern crate issue_11508 as rand;
 
 use rand::{Closed01, random};
 
index 4a74e4be4ce573811e82fd5461975633530eb696..e5d95874be61fda8f16a8b0b2c7c38c9c175b177 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-11529.rs
 
-extern crate "issue-11529" as a;
+// pretty-expanded FIXME #23616
+
+extern crate issue_11529 as a;
 
 fn main() {
     let one = 1;
index b99a5b7ab37c51198f1a18e3f15f086a5de5f419..1f91c6aaa4d0ae1275db4fa309f3d44246a1c3fa 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
@@ -15,7 +17,7 @@
 #[derive(Clone)]
 enum Noun
 {
-    Atom(int),
+    Atom(isize),
     Cell(Box<Noun>, Box<Noun>)
 }
 
index 687de48474058dd857b1cb5543317b8d68f6a257..ecb7a3a3691ca9cb95e66ab1f6aa3a9f6db2f8a9 100644 (file)
@@ -1,3 +1,5 @@
+// pretty-expanded FIXME #23616
+
  // 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.
 // Destructuring struct variants would ICE where regular structs wouldn't
 
 enum Foo {
-    VBar { num: int }
+    VBar { num: isize }
 }
 
-struct SBar { num: int }
+struct SBar { num: isize }
 
 pub fn main() {
     let vbar = Foo::VBar { num: 1 };
diff --git a/src/test/run-pass/issue-11592.rs b/src/test/run-pass/issue-11592.rs
new file mode 100644 (file)
index 0000000..432e7ff
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+//! Ensure the private trait Bar isn't complained about.
+
+#![deny(missing_docs)]
+
+mod foo {
+    trait Bar { fn bar(&self) { } }
+    impl Bar for i8 { fn bar(&self) { } }
+}
+
+fn main() { }
index 3c69377b375c6597cd865aa23f5af8cdb3ef1125..de1b0525d84976f16feda9021c353d9ef6fa8805 100644 (file)
@@ -12,6 +12,8 @@
 // We weren't updating the auto adjustments with all the resolved
 // type information after type check.
 
+// pretty-expanded FIXME #23616
+
 trait A { fn dummy(&self) { } }
 
 struct B<'a, T:'a> {
index 7cccac4483d49da1edfed2dd0c397493dc45c16d..a3eec42831f2036fafc0bfc71aed826f4c3dc9d1 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
-#![allow(unknown_features)]
-#![feature(box_syntax)]
 
 // this code used to cause an ICE
 
@@ -24,9 +24,10 @@ struct S<T> {f: Box<X<T>+'static>,
              g: Box<X<T>+'static>}
 
 struct F;
-impl X<int> for F {
+impl X<isize> for F {
 }
 
 fn main() {
-  S {f: box F, g: box F};
+  // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+  S {f: Box::new(F), g: Box::new(F) };
 }
index 4a07b5fc432c2bd99770e7cc59877eb09a695e6d..3ad78f088f9c9f5fe26e92187f40e0cee21218d7 100644 (file)
@@ -15,6 +15,8 @@
 // when this bug was opened. The cases where the compiler
 // panics before the fix have a comment.
 
+#![feature(std_misc)]
+
 use std::thunk::Thunk;
 
 struct S {x:()}
@@ -23,7 +25,7 @@ fn test(slot: &mut Option<Thunk<(),Thunk>>) -> () {
   let a = slot.take();
   let _a = match a {
     // `{let .. a(); }` would break
-    Some(a) => { let _a = a.invoke(()); },
+    Some(a) => { let _a = a(); },
     None => (),
   };
 }
index b901e95ff55edb453c6a7b8642af99e394850d67..fde04efc8bad9c63f204da244196403c0c719475 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections)]
+
 extern crate collections;
 
 use std::collections::BitVec;
@@ -15,9 +19,9 @@ use std::num::Float;
 
 fn main() {
     // Generate sieve of Eratosthenes for n up to 1e6
-    let n = 1000000_usize;
+    let n = 1000000;
     let mut sieve = BitVec::from_elem(n+1, true);
-    let limit: uint = (n as f32).sqrt() as uint;
+    let limit: usize = (n as f32).sqrt() as usize;
     for i in 2..limit+1 {
         if sieve[i] {
             let mut j = 0;
@@ -32,4 +36,3 @@ fn main() {
         }
     }
 }
-
diff --git a/src/test/run-pass/issue-11820.rs b/src/test/run-pass/issue-11820.rs
new file mode 100644 (file)
index 0000000..6d2243d
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+struct NoClone;
+
+fn main() {
+  let rnc = &NoClone;
+  let rsnc = &Some(NoClone);
+
+  let _: &NoClone = rnc.clone();
+  let _: &Option<NoClone> = rsnc.clone();
+}
index 12a6d9a82c7b014d2b019eeaa9df4ede82d44ddb..8a9b3e4b1434e8678c18d4a49f2d2568f79f7f5d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct A {
     a: String
 }
index 10d694957f57e10101d7eea864cf81af06a458fc..35c25b33a9764c2976889ffdf7877dfc4f24a030 100644 (file)
@@ -8,21 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(old_orphan_check)]
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_private, old_io)]
 
 extern crate rbml;
 extern crate serialize;
 
-use std::old_io;
+use std::io::Cursor;
+use std::io::prelude::*;
 use std::fmt;
-use std::old_io::{IoResult, SeekStyle};
 use std::slice;
 
 use serialize::{Encodable, Encoder};
 use serialize::json;
 
 use rbml::writer;
-use rbml::io::SeekableMemWriter;
 
 #[derive(Encodable)]
 struct Foo {
@@ -31,7 +32,7 @@ struct Foo {
 
 #[derive(Encodable)]
 struct Bar {
-    froboz: uint,
+    froboz: usize,
 }
 
 enum WireProtocol {
@@ -40,17 +41,17 @@ enum WireProtocol {
     // ...
 }
 
-fn encode_json<T: Encodable>(val: &T, wr: &mut SeekableMemWriter) {
+fn encode_json<T: Encodable>(val: &T, wr: &mut Cursor<Vec<u8>>) {
     write!(wr, "{}", json::as_json(val));
 }
-fn encode_rbml<T: Encodable>(val: &T, wr: &mut SeekableMemWriter) {
+fn encode_rbml<T: Encodable>(val: &T, wr: &mut Cursor<Vec<u8>>) {
     let mut encoder = writer::Encoder::new(wr);
     val.encode(&mut encoder);
 }
 
 pub fn main() {
     let target = Foo{baz: false,};
-    let mut wr = SeekableMemWriter::new();
+    let mut wr = Cursor::new(Vec::new());
     let proto = WireProtocol::JSON;
     match proto {
         WireProtocol::JSON => encode_json(&target, &mut wr),
index 1540679b099b43b45f8fcaeb302ceefb1385fc2d..8732def0a1a1100ff85bcb66973fa41b17c41cf8 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 const TEST_STR: &'static str = "abcd";
 
 fn main() {
index 00613f35f17bb71a1257021477671d01f7ba02cc..def85b4766783ff499e58efd9a8859a995968c03 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![forbid(warnings)]
+#![feature(std_misc)]
 
 // Pretty printing tests complain about `use std::predule::*`
 #![allow(unused_imports)]
@@ -19,6 +22,6 @@
 use std::thunk::Thunk;
 
 pub fn main() {
-    let mut x = 1i32;
-    let _thunk = Thunk::new(move|| { x = 2; });
+    let mut x = 1;
+    let _thunk = Box::new(move|| { x = 2; });
 }
index bf5976e9217f24792d646b99a32512fac2e305ae..d47bb818c4946641687517a34dd36cadc0362753 100644 (file)
@@ -11,7 +11,9 @@
 // aux-build:issue-12133-rlib.rs
 // aux-build:issue-12133-dylib.rs
 
-extern crate "issue-12133-rlib" as a;
-extern crate "issue-12133-dylib" as b;
+// pretty-expanded FIXME #23616
+
+extern crate issue_12133_rlib as a;
+extern crate issue_12133_dylib as b;
 
 fn main() {}
index 50977a7e039e4e8a91b2e6b0036f9bf1d031418e..580c487af0de9a803ba092b3ad63d32bb3c71e15 100644 (file)
@@ -12,7 +12,9 @@
 // aux-build:issue-12133-dylib.rs
 // no-prefer-dynamic
 
-extern crate "issue-12133-rlib" as a;
-extern crate "issue-12133-dylib" as b;
+// pretty-expanded FIXME #23616
+
+extern crate issue_12133_rlib as a;
+extern crate issue_12133_dylib as b;
 
 fn main() {}
index ab990e55295aa2c92d8e0a927fc7b557a0e6b180..79a530785452ac58c1bfa1d0f8694a452aae9594 100644 (file)
@@ -12,6 +12,8 @@
 // aux-build:issue-12133-dylib.rs
 // aux-build:issue-12133-dylib2.rs
 
-extern crate "issue-12133-dylib2" as other;
+// pretty-expanded FIXME #23616
+
+extern crate issue_12133_dylib2 as other;
 
 fn main() {}
index 563771212aa3df8df9860b57b2143ae166a037d8..3a5b7e86920d74313c0ed0ab5534d8283eb33fea 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct S;
 
 fn main() {
index debb7df112597252612e0d3cebaac5898d68ce6e..ddd30ed3bb0c08a1ecee892225a43ec94a9b8155 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 #![crate_id="rust_get_test_int"]
 
 mod rustrt {
index 7d5bd9d6a74db57c3614deece86a932dab8f0bbf..44ebe362c729dacd0d1d65eaf712fc33a75fc8b1 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main () {
   let mut line = "".to_string();
   let mut i = 0;
index 9ceb7366e403db935cf242145f27fd1e14519ce8..bdf8f84a9597d711411dce041997ef19ee20ff04 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:issue-12612-1.rs
-// aux-build:issue-12612-2.rs
+// aux-build:issue_12612_1.rs
+// aux-build:issue_12612_2.rs
 
-extern crate "issue-12612-1" as foo;
-extern crate "issue-12612-2" as bar;
+// pretty-expanded FIXME #23616
+
+extern crate issue_12612_1 as foo;
+extern crate issue_12612_2 as bar;
 
 mod test {
     use bar::baz;
index 6b3fa587bc55b5560d54984f4996289cc2b60780..331f9d991d681ab0173059ad9673d1d001122076 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:issue-12660-aux.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate issue12660aux;
 
 use issue12660aux::{my_fn, MyStruct};
index ef68daa8ce592a594d30e4b0b1fc1f5287b98024..493bdb30e35bcb7ec28c0bc3e91859ab53dbe1f4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let s = "Hello";
     let first = s.bytes();
index e66b5d21e17fabf498b081f82d788b015a246802..2b89915516469b4b0efcc55c425420f838bbe5ef 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(old_io, std_misc)]
+
 use std::time::Duration;
 use std::thread;
 
index b55d64777537ec4424f14a5fab03ac2725d36e52..ac5a9b728b992270655cacd6ada89a195318b721 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(old_io, std_misc)]
+
 use std::old_io::timer;
 use std::time::Duration;
 
diff --git a/src/test/run-pass/issue-12729.rs b/src/test/run-pass/issue-12729.rs
new file mode 100644 (file)
index 0000000..1852ed2
--- /dev/null
@@ -0,0 +1,22 @@
+// 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.
+
+// pretty-expanded FIXME #23616
+
+pub struct Foo;
+
+mod bar {
+    use Foo;
+
+    impl Foo {
+        fn baz(&self) {}
+    }
+}
+fn main() {}
index 2f7ba315aa1f6ae073f1e5d8f0c3f684070131e4..56d1d3599c7fde3dcb7e3cfd8a49c5a88cc46d2f 100644 (file)
@@ -8,10 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
 fn main() {
-    fn test() -> Box<std::any::Any + 'static> { box 1 }
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    fn test() -> Box<std::any::Any + 'static> { Box::new(1) }
     println!("{:?}", test())
 }
index a05cc9c0f74c241a16f0331650fb57b1f34e7e0d..dddfb9bacf9e211e016d5c31de5c1c9f0aa9a4c9 100644 (file)
@@ -8,16 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections)]
 
 extern crate collections;
 
 use std::collections::HashSet;
 
-#[derive(Copy, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 struct XYZ {
-    x: int,
-    y: int,
-    z: int
+    x: isize,
+    y: isize,
+    z: isize
 }
 
 fn main() {
index b7dc98b92e0db21feed21496f54a6ef675e43711..e15321907301c183cf1ceb32ce4e71fe57679f6c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::collections::HashMap;
 
 fn copy<T: Copy>(&x: &T) -> T {
@@ -15,12 +17,12 @@ fn copy<T: Copy>(&x: &T) -> T {
 }
 
 fn main() {
-    let arr = [(1, 1_usize), (2, 2), (3, 3)];
+    let arr = [(1, 1), (2, 2), (3, 3)];
 
     let v1: Vec<&_> = arr.iter().collect();
     let v2: Vec<_> = arr.iter().map(copy).collect();
 
     let m1: HashMap<_, _> = arr.iter().map(copy).collect();
-    let m2: HashMap<int, _> = arr.iter().map(copy).collect();
-    let m3: HashMap<_, uint> = arr.iter().map(copy).collect();
+    let m2: HashMap<isize, _> = arr.iter().map(copy).collect();
+    let m3: HashMap<_, usize> = arr.iter().map(copy).collect();
 }
index 056c86b01f7346c92ab6c179f0a7bbfebd567dc1..dadd480dc6a2cd644106fd5443aa9f5f3d63e24e 100644 (file)
 // Tests that match expression handles overlapped literal and range
 // properly in the presence of guard function.
 
-fn val() -> uint { 1 }
+#![feature(slice_patterns)]
 
-static CONST: uint = 1;
+fn val() -> usize { 1 }
+
+static CONST: usize = 1;
 
 pub fn main() {
     lit_shadow_range();
@@ -174,7 +176,7 @@ fn range_shadow_multi_pats() {
 
 fn misc() {
     enum Foo {
-        Bar(uint, bool)
+        Bar(usize, bool)
     }
     // This test basically mimics how trace_macros! macro is implemented,
     // which is a rare combination of vector patterns, multiple wild-card
index 64807dc44e061002632daecc7ade4bcb8a94eb7c..14de9e90306bc6b8adf31f455d1298c61fe272fd 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::marker::MarkerTrait;
 
 trait Foo : MarkerTrait {
index 21b54ba0e793b2807261ac09ac89a8c7694fea8e..414f6768e0a6b0b0ba8e6a328bfc7b37c7581b4c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::slice;
 
 pub struct PhfMapEntries<'a, T: 'a> {
@@ -21,7 +23,7 @@ impl<'a, T> Iterator for PhfMapEntries<'a, T> {
         self.iter.by_ref().map(|&(key, ref value)| (key, value)).next()
     }
 
-    fn size_hint(&self) -> (uint, Option<uint>) {
+    fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
 }
index c29dc4319dc0cb87ed2065414c6c9079c9f270f2..ec9d777974bb01d23ff5e78a9ae96be92d7dc6c8 100644 (file)
 // Test that when instantiating trait default methods, typeck handles
 // lifetime parameters defined on the method bound correctly.
 
+// pretty-expanded FIXME #23616
+
 pub trait Foo {
-    fn bar<'a, I: Iterator<Item=&'a ()>>(&self, it: I) -> uint {
+    fn bar<'a, I: Iterator<Item=&'a ()>>(&self, it: I) -> usize {
         let mut xs = it.filter(|_| true);
         xs.count()
     }
index 191e9ce8b6febfcc249b293cdf72e35ba065af98..7a3d3f4ff485a8e0e1ba04f6ad228e1e36488b2c 100644 (file)
@@ -11,6 +11,8 @@
 // defining static with struct that contains enum
 // with &'static str variant used to cause ICE
 
+// pretty-expanded FIXME #23616
+
 pub enum Foo {
     Bar,
     Baz(&'static str),
index 329ab7c921dda3ebe476af0fb67d00ba0e6d6e3f..34960b264567db037ec4a02c1da52efbba6d4bd3 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 extern crate libc;
 
 #[cfg(windows)]
index 3c76a827fb2958e546f145bd2e865bc489602b7e..7acabf31c85a17587ed16823161e47b8545becf3 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::ops::Deref;
 
 struct Root {
@@ -22,7 +24,7 @@ impl Deref for Root {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct JSRef {
     node: *const Node
 }
@@ -60,10 +62,10 @@ impl JSRef {
 struct Node;
 
 impl Node {
-    fn RemoveChild(&self, _a: uint) {
+    fn RemoveChild(&self, _a: usize) {
     }
 
-    fn AddChild(&self, _a: uint) {
+    fn AddChild(&self, _a: usize) {
     }
 }
 
index 4a7d6be55a1625fa4730c38d3d43a8feaaf8e83b..c260aa95b57f1d556bdf83f77826ba120ab0ea7c 100644 (file)
@@ -8,10 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-fast
+// ignore-aarch64
+#![feature(io, process_capture)]
 
 use std::env;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
+use std::process::{Command, Stdio};
 use std::str;
 
 fn main() {
@@ -25,17 +28,19 @@ fn main() {
 
 fn parent() {
     let args: Vec<String> = env::args().collect();
-    let mut p = old_io::process::Command::new(&args[0])
-                                     .arg("child").spawn().unwrap();
-    p.stdin.as_mut().unwrap().write_str("test1\ntest2\ntest3").unwrap();
+    let mut p = Command::new(&args[0]).arg("child")
+                        .stdout(Stdio::piped())
+                        .stdin(Stdio::piped())
+                        .spawn().unwrap();
+    p.stdin.as_mut().unwrap().write_all(b"test1\ntest2\ntest3").unwrap();
     let out = p.wait_with_output().unwrap();
     assert!(out.status.success());
-    let s = str::from_utf8(&out.output).unwrap();
-    assert_eq!(s, "test1\n\ntest2\n\ntest3\n");
+    let s = str::from_utf8(&out.stdout).unwrap();
+    assert_eq!(s, "test1\ntest2\ntest3\n");
 }
 
 fn child() {
-    let mut stdin = old_io::stdin();
+    let mut stdin = io::stdin();
     for line in stdin.lock().lines() {
         println!("{}", line.unwrap());
     }
index 44167ad2096decc595eb7e352de1ebeb11bc8740..90d16aaf145af8f5348d7361ee468ca29ef2baea 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
diff --git a/src/test/run-pass/issue-13352.rs b/src/test/run-pass/issue-13352.rs
deleted file mode 100644 (file)
index a834371..0000000
+++ /dev/null
@@ -1,22 +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.
-
-extern crate libc;
-
-use std::thunk::Thunk;
-
-fn foo(_: Thunk) {}
-
-fn main() {
-    foo(loop {
-        unsafe { libc::exit(0 as libc::c_int); }
-    });
-    2_usize + (loop {});
-}
index 05943943d9533391aeab2afc783414819ebef044..c8b26dc4aed15cab7af054569f1ff8fa7cbaab23 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct Foo<'a> {
     i: &'a bool,
-    j: Option<&'a int>,
+    j: Option<&'a isize>,
 }
 
 impl<'a> Foo<'a> {
-    fn bar(&mut self, j: &int) {
+    fn bar(&mut self, j: &isize) {
         let child = Foo {
             i: self.i,
             j: Some(j)
index 95562d75c3ea476ab3e6e8f2972b1a056095d48e..d1b1647de7881244887f8011abd854374a4ce71a 100644 (file)
 // This test may not always fail, but it can be flaky if the race it used to
 // expose is still present.
 
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc)]
+
 use std::sync::mpsc::{channel, Sender, Receiver};
-use std::thread::Thread;
+use std::thread;
 
 fn helper(rx: Receiver<Sender<()>>) {
     for tx in rx.iter() {
@@ -22,8 +26,8 @@ fn helper(rx: Receiver<Sender<()>>) {
 
 fn main() {
     let (tx, rx) = channel();
-    let _t = Thread::spawn(move|| { helper(rx) });
-    let (snd, rcv) = channel::<int>();
+    let _t = thread::scoped(move|| { helper(rx) });
+    let (snd, rcv) = channel::<isize>();
     for _ in 1..100000 {
         snd.send(1).unwrap();
         let (tx2, rx2) = channel();
@@ -33,4 +37,5 @@ fn main() {
             _ = rcv.recv() => ()
         }
     }
+    drop(tx);
 }
index 1c0283070a249be5cf66c7a9240b5ea55a656c95..0b35ccf26f3f798a9c8f612ebf3752412b6d7149 100644 (file)
@@ -9,6 +9,11 @@
 // except according to those terms.
 
 // aux-build:issue13507.rs
+
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 extern crate issue13507;
 use issue13507::testtypes;
 
index c67dd4b93a048da2e67887508bb636151c274883..4c46831418707bb0c95cda5b6497c23d88d396e3 100644 (file)
@@ -11,7 +11,9 @@
 // aux-build:issue-13620-1.rs
 // aux-build:issue-13620-2.rs
 
-extern crate "issue-13620-2" as crate2;
+// pretty-expanded FIXME #23616
+
+extern crate issue_13620_2 as crate2;
 
 fn main() {
     (crate2::FOO2.foo)();
index 81a8b29461c78a6a82abfa9ea8ec0a032ea79ac2..11219b04f2b97003e55434f34b4f1312af2fe1c2 100644 (file)
@@ -8,13 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, core)]
 use std::ops::Fn;
 
 struct Foo<T>(T);
 
 impl<T: Copy> Fn<()> for Foo<T> {
-    type Output = T;
     extern "rust-call" fn call(&self, _: ()) -> T {
       match *self {
         Foo(t) => t
@@ -22,6 +21,20 @@ impl<T: Copy> Fn<()> for Foo<T> {
     }
 }
 
+impl<T: Copy> FnMut<()> for Foo<T> {
+    extern "rust-call" fn call_mut(&mut self, _: ()) -> T {
+        self.call(())
+    }
+}
+
+impl<T: Copy> FnOnce<()> for Foo<T> {
+    type Output = T;
+
+    extern "rust-call" fn call_once(self, _: ()) -> T {
+        self.call(())
+    }
+}
+
 fn main() {
   let t: u8 = 1;
   println!("{}", Foo(t)());
index 5ccbe9a7980e8a04bcef5082cb63c5eb0eb1a3f8..f4902c8e0ac38d7d5ee83e1058a1d18972742ecc 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn foo<'r>() {
   let maybe_value_ref: Option<&'r u8> = None;
 
index c9c78f6408bac74473da9ef3b2b1736c6ec7394d..173b8dda05795a45d6883bd83e5a3648e278a0cb 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub struct Foo<'a, 'b: 'a> { foo: &'a &'b int }
+// pretty-expanded FIXME #23616
+
+pub struct Foo<'a, 'b: 'a> { foo: &'a &'b isize }
 pub fn foo<'a, 'b>(x: Foo<'a, 'b>, _o: Option<&   &   ()>) { let _y = x.foo; }
 fn main() {}
index 81b6892b0f97ac4f97922a6125b02c11c82a6f44..fb82cccc871e71032bb50dba67fd96cdbf28fade 100644 (file)
@@ -8,11 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::u8;
 
-const NUM: uint = u8::BITS as uint;
+const NUM: usize = u8::BITS as usize;
 
-struct MyStruct { nums: [uint; 8] }
+struct MyStruct { nums: [usize; 8] }
 
 
 fn main() {
index 8731662afa307a30a167e14e8a1e2879220c0dea..3b70bea719b2ff8b382e41d463fe77ead3008b77 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
-    fn bar(&self, int) {}
+    fn bar(&self, isize) {}
 }
 
 fn main() {}
index 3c5ece87b737dabae0d7d16709bd68175e3a9cbb..c85c0117581a5f771657a9a91cc23a57748cefa4 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 struct Foo<'a> {
     listener: Box<FnMut() + 'a>,
@@ -17,7 +16,8 @@ struct Foo<'a> {
 
 impl<'a> Foo<'a> {
     fn new<F>(listener: F) -> Foo<'a> where F: FnMut() + 'a {
-        Foo { listener: box listener }
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        Foo { listener: Box::new(listener) }
     }
 }
 
index c6847ce55dec2ca7090c97bdb090a74ceb98caa6..d90b9cffb6abdec60c30567e0ac2fd33c8d3d093 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct TestStruct {
-    x: *const [int; 2]
+    x: *const [isize; 2]
 }
 
 unsafe impl Sync for TestStruct {}
 
-static TEST_VALUE : TestStruct = TestStruct{x: 0x1234 as *const [int; 2]};
+static TEST_VALUE : TestStruct = TestStruct{x: 0x1234 as *const [isize; 2]};
 
 fn main() {}
index 960884c4aa501711ef55d93ca7c127df50f23ee7..a902e141bb6ca4a935a7f3c0be304ae91b41066c 100644 (file)
 // Test that codegen works correctly when there are multiple refutable
 // patterns in match expression.
 
+// pretty-expanded FIXME #23616
+
 enum Foo {
-    FooUint(uint),
+    FooUint(usize),
     FooNullary,
 }
 
index a58477e647f3af3899dd3308afd4859482235c9e..e9fb7945d04007215093f75d3e69827273be0c2c 100644 (file)
@@ -12,7 +12,9 @@
 // aux-build:issue-13872-2.rs
 // aux-build:issue-13872-3.rs
 
-extern crate "issue-13872-3" as other;
+// pretty-expanded FIXME #23616
+
+extern crate issue_13872_3 as other;
 
 fn main() {
     other::foo();
index e850ecbba6e560d6d2ad12b0ac9c0153a44f47b1..907967d115d583ec7ecc67ce5e7e6ddc6fede761 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(old_orphan_check)]
+#![feature(rustc_private)]
 
 extern crate serialize;
 
index dd9a7c97c9ab5f5ca8a2431955e28e321607be8d..d159d55c77c560431233eaaf880bf678c76ace77 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unused_imports, dead_code)]
 
 use foo::Foo;
index ad4ed03e6e2c82386f09c1add758975a89ce71d5..ed96eee6ddffb8072487b6d4b0c5f88d167dfad9 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
     fn bar(&self);
     fn baz(&self) { }
@@ -15,7 +17,7 @@ trait Foo {
 }
 
 struct BarTy {
-    x : int,
+    x : isize,
     y : f64,
 }
 
@@ -66,34 +68,34 @@ impl Foo for Box<BarTy> {
 }
 
 // If these fail, it's necessary to update rustc_resolve and the cfail tests.
-impl Foo for *const int {
+impl Foo for *const isize {
     fn bar(&self) {
         self.baz();
-        Foo::bah(None::<*const int>);
+        Foo::bah(None::<*const isize>);
     }
 }
 
 // If these fail, it's necessary to update rustc_resolve and the cfail tests.
-impl<'a> Foo for &'a int {
+impl<'a> Foo for &'a isize {
     fn bar(&self) {
         self.baz();
-        Foo::bah(None::<&int>);
+        Foo::bah(None::<&isize>);
     }
 }
 
 // If these fail, it's necessary to update rustc_resolve and the cfail tests.
-impl<'a> Foo for &'a mut int {
+impl<'a> Foo for &'a mut isize {
     fn bar(&self) {
         self.baz();
-        Foo::bah(None::<&mut int>);
+        Foo::bah(None::<&mut isize>);
     }
 }
 
 // If these fail, it's necessary to update rustc_resolve and the cfail tests.
-impl Foo for Box<int> {
+impl Foo for Box<isize> {
     fn bar(&self) {
         self.baz();
-        Foo::bah(None::<Box<int>>);
+        Foo::bah(None::<Box<isize>>);
     }
 }
 
index 0e4b4a2c9cf326ca260c26a6189bc7520c1cf06b..f67d0946e9823429ed4f3182d55196ecc649df94 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct A(int);
+// pretty-expanded FIXME #23616
+
+struct A(isize);
 struct B;
 
 fn main() {
index f983f233ee35680e8697439ab39d43e9fab1e40b..dd5b7e722fe7bb775d533dc4b12d45d9d0fbb0aa 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[macro_use] extern crate "std" as std2;
+// pretty-expanded FIXME #23616
+
+#[macro_use] extern crate std as std2;
 
 fn main() {}
index 6c9c7e2fd3f141978aa78d1c68b4bf36c3cbb86b..88af65074951ddcdf3101bd71f156afd8b05291b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     match ("", 1_usize) {
         (_, 42_usize) => (),
index db7eacce9d10b007292ae09dce9b550eef54543f..aa91f125e48e276a2e52729759d277518a4bc4ef 100644 (file)
@@ -13,6 +13,8 @@
 // value was coerced to a trait object. (v.clone() returns Box<B1>
 // which is coerced to Box<A>).
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -23,6 +25,6 @@ trait A { fn foo(&self) {} }
 impl A for B1 {}
 
 fn main() {
-    let v = box B1;
+    let v: Box<_> = box B1;
     let _c: Box<A> = v.clone();
 }
index c595f98cd0e4ae4650daed752a44d9d94a15c57b..046d888030f0c4acc929a054a9df1e24d9b23670 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-14421.rs
 
-extern crate "issue-14421" as bug_lib;
+// pretty-expanded FIXME #23616
+
+extern crate issue_14421 as bug_lib;
 
 use bug_lib::B;
 use bug_lib::make;
@@ -19,4 +21,3 @@ pub fn main() {
     let mut an_A: B = make();
     an_A.foo();
 }
-
index 439998c597d936d86327370e9fd43aabfeae6593..178a219f5bfc0b03d55f75ba451ab3da7da88409 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-14422.rs
 
-extern crate "issue-14422" as bug_lib;
+// pretty-expanded FIXME #23616
+
+extern crate issue_14422 as bug_lib;
 
 use bug_lib::B;
 use bug_lib::make;
index 723db9485ca6ee110b2ced81aad5f69b60f193ae..ab9633ca1fe90e0ba46d921e66b16264792c5279 100644 (file)
@@ -8,11 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(io, process_capture)]
 
-use std::old_io::process;
-use std::old_io::Command;
-use std::old_io;
 use std::env;
+use std::io::prelude::*;
+use std::io;
+use std::process::{Command, Stdio};
 
 fn main() {
     let args: Vec<String> = env::args().collect();
@@ -21,22 +24,23 @@ fn main() {
     }
 
     test();
-
 }
 
 fn child() {
-    old_io::stdout().write_line("foo").unwrap();
-    old_io::stderr().write_line("bar").unwrap();
-    let mut stdin = old_io::stdin();
-    assert_eq!(stdin.lock().read_line().err().unwrap().kind, old_io::EndOfFile);
+    writeln!(&mut io::stdout(), "foo").unwrap();
+    writeln!(&mut io::stderr(), "bar").unwrap();
+    let mut stdin = io::stdin();
+    let mut s = String::new();
+    stdin.lock().read_line(&mut s).unwrap();
+    assert_eq!(s.len(), 0);
 }
 
 fn test() {
     let args: Vec<String> = env::args().collect();
     let mut p = Command::new(&args[0]).arg("child")
-                                     .stdin(process::Ignored)
-                                     .stdout(process::Ignored)
-                                     .stderr(process::Ignored)
+                                     .stdin(Stdio::piped())
+                                     .stdout(Stdio::piped())
+                                     .stderr(Stdio::piped())
                                      .spawn().unwrap();
     assert!(p.wait().unwrap().success());
 }
index 027826e99cb1f8b878f8b09aa5416168edc6dc4e..1cbe986e88af0ebd77cbc91d32e3a86233c6215f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unused_variable)]
 
 struct T { f: extern "Rust" fn() }
index 71d88ee6215103a991f81a0a2ea904f45ad3cf16..b0893e21af7e92eeef90baa34c9d1d98bbefc39f 100644 (file)
 // All 3 expressions should work in that the argument gets
 // coerced to a trait object
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
+// pretty-expanded FIXME #23616
 
 fn main() {
-    send::<Box<Foo>>(box Output(0));
-    Test::<Box<Foo>>::foo(box Output(0));
-    Test::<Box<Foo>>::new().send(box Output(0));
+    send::<Box<Foo>>(Box::new(Output(0)));
+    Test::<Box<Foo>>::foo(Box::new(Output(0)));
+    Test::<Box<Foo>>::new().send(Box::new(Output(0)));
 }
 
 fn send<T>(_: T) {}
@@ -30,5 +31,5 @@ impl<T> Test<T> {
 }
 
 trait Foo { fn dummy(&self) { }}
-struct Output(int);
+struct Output(isize);
 impl Foo for Output {}
index 44465fe5f80ee493fdacb95d5c2245638483c9f6..6e1cfc7186299e0eabc40c9c20ed32e5ce8e380a 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    {|i| if 1 == i { }};
+    {|i: u32| if 1 == i { }};
 }
index 1155027d426da833262e0f9e1bb80ec4a25d22d5..5589acdda37e14fc2ae7cd018c607eef3b928ad9 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[deny(dead_code)]
 pub enum Foo {
     Bar {
-        baz: int
+        baz: isize
     }
 }
 
index c322346c2a605dc0430aa3f9280bc67fdff131e6..e78736b77fd93bc1283d6b81f5710f174fe88542 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum X {
-    Foo(uint),
+    Foo(usize),
     Bar(bool)
 }
 
index abb15dae00df614e3a1451693de0e34e2b9a6415..7e7886e3a6e7659b82a5cbce04af4bb3ae420a1f 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(old_io)]
+
 use std::old_io::Reader;
 
 enum Wrapper<'a> {
index 933e7e40f06d34ce23ae96de299da6a594acb62b..371e926ab18d5f05062de87439c779215453e732 100644 (file)
@@ -8,11 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 trait Matcher {
-    fn next_match(&mut self) -> Option<(uint, uint)>;
+    fn next_match(&mut self) -> Option<(usize, usize)>;
 }
 
 struct CharPredMatcher<'a, 'b> {
@@ -21,7 +20,7 @@ struct CharPredMatcher<'a, 'b> {
 }
 
 impl<'a, 'b> Matcher for CharPredMatcher<'a, 'b> {
-    fn next_match(&mut self) -> Option<(uint, uint)> {
+    fn next_match(&mut self) -> Option<(usize, usize)> {
         None
     }
 }
@@ -32,9 +31,10 @@ trait IntoMatcher<'a, T> {
 
 impl<'a, 'b, F> IntoMatcher<'a, CharPredMatcher<'a, 'b>> for F where F: FnMut(char) -> bool + 'b {
     fn into_matcher(self, s: &'a str) -> CharPredMatcher<'a, 'b> {
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
         CharPredMatcher {
             str: s,
-            pred: box self,
+            pred: Box::new(self),
         }
     }
 }
@@ -44,9 +44,9 @@ struct MatchIndices<M> {
 }
 
 impl<M: Matcher> Iterator for MatchIndices<M> {
-    type Item = (uint, uint);
+    type Item = (usize, usize);
 
-    fn next(&mut self) -> Option<(uint, uint)> {
+    fn next(&mut self) -> Option<(usize, usize)> {
         self.matcher.next_match()
     }
 }
@@ -59,5 +59,5 @@ fn match_indices<'a, M, T: IntoMatcher<'a, M>>(s: &'a str, from: T) -> MatchIndi
 fn main() {
     let s = "abcbdef";
     match_indices(s, |c: char| c == 'b')
-        .collect::<Vec<(uint, uint)>>();
+        .collect::<Vec<(usize, usize)>>();
 }
index 549ed08aaf37a54130f49bcf1c6e3dbd4ba74416..f6815b76083048e508e4268c928465c31e879c3d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub type BigRat<T = int> = T;
+// pretty-expanded FIXME #23616
+
+pub type BigRat<T = isize> = T;
 
 fn main() {}
index ace1f00b023b58a8847ab40dae2cf496d1c98cd7..2361c385b4148c451196733cfd7aa4331e981326 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(asm)]
 
 type History = Vec<&'static str>;
@@ -20,8 +22,8 @@ fn wrap<A>(x:A, which: &'static str, history: &mut History) -> A {
 macro_rules! demo {
     ( $output_constraint:tt ) => {
         {
-            let mut x: int = 0;
-            let y: int = 1;
+            let mut x: isize = 0;
+            let y: isize = 1;
 
             let mut history: History = vec!();
             unsafe {
index ed0e3bddbe515b8d3a5b6abce07d2528ea72ac61..a530384d368c06036bcd8530c4f03b1ec15264ef 100644 (file)
@@ -8,13 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(old_io, io)]
+
 use std::env;
-use std::old_io::{stdio, Command};
+use std::process::Command;
+use std::io::{self, Write};
 
 fn main() {
     let mut args = env::args();
     if args.len() > 1 {
-        let mut out = stdio::stdout();
+        let mut out = io::stdout();
         out.write(&['a' as u8; 128 * 1024]).unwrap();
     } else {
         let out = Command::new(&args.next().unwrap()).arg("child").output();
index 6335f79be6c7aae7b547f67e33baa240f352fce9..ec482a776def32f4e3bf940b0a09272130179b91 100644 (file)
@@ -8,17 +8,27 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, core)]
 
 trait Foo { fn dummy(&self) { }}
 
 struct Bar;
 
 impl<'a> std::ops::Fn<(&'a (Foo+'a),)> for Bar {
-    type Output = ();
     extern "rust-call" fn call(&self, _: (&'a Foo,)) {}
 }
 
+impl<'a> std::ops::FnMut<(&'a (Foo+'a),)> for Bar {
+    extern "rust-call" fn call_mut(&mut self, a: (&'a Foo,)) { self.call(a) }
+}
+
+impl<'a> std::ops::FnOnce<(&'a (Foo+'a),)> for Bar {
+    type Output = ();
+    extern "rust-call" fn call_once(self, a: (&'a Foo,)) { self.call(a) }
+}
+
 struct Baz;
 
 impl Foo for Baz {}
index 53d0f7dae05773bf0c3f630d61114779c89d3c52..5accaf363490fae2b1e45692d78e2e9156ef7941 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, core)]
 
 use std::ops::Fn;
 
@@ -34,9 +36,21 @@ impl Alloy {
 }
 
 impl<'b> Fn<(&'b mut (Response+'b),)> for SendFile {
+    extern "rust-call" fn call(&self, (_res,): (&'b mut (Response+'b),)) {}
+}
+
+impl<'b> FnMut<(&'b mut (Response+'b),)> for SendFile {
+    extern "rust-call" fn call_mut(&mut self, (_res,): (&'b mut (Response+'b),)) {
+        self.call((_res,))
+    }
+}
+
+impl<'b> FnOnce<(&'b mut (Response+'b),)> for SendFile {
     type Output = ();
 
-    extern "rust-call" fn call(&self, (_res,): (&'b mut (Response+'b),)) {}
+    extern "rust-call" fn call_once(self, (_res,): (&'b mut (Response+'b),)) {
+        self.call((_res,))
+    }
 }
 
 impl<Rq: Request, Rs: Response> Ingot<Rq, Rs> for HelloWorld {
index edca9cbaa30fe48cb402e84b0ae43b7628fba480..adf56388acd69d93f427dbe3aec503b5f0286b03 100644 (file)
@@ -8,14 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(warnings)]
 
 struct S<T>(T);
 
-static s1: S<S<uint>>=S(S(0));
-static s2: S<uint>=S(0);
+static s1: S<S<usize>>=S(S(0));
+static s2: S<usize>=S(0);
 
 fn main() {
-    let foo: S<S<uint>>=S(S(0));
-    let foo: S<uint>=S(0);
+    let foo: S<S<usize>>=S(S(0));
+    let foo: S<usize>=S(0);
 }
index 9752b01e52bc1416ab0ea3cbfa23b626b834c7a3..4369dc6292c36909b73b078a42b50d176e6eeb9c 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(slice_patterns)]
+
 fn main() {
     let mut x: &[_] = &[1, 2, 3, 4];
 
index c6c9e8004558cce19afae47a568bd14ef69e7e5f..db04e10cfe383c36991390399d591a535a0d225e 100644 (file)
@@ -8,11 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(slice_patterns)]
+
 fn main() {
     assert_eq!(count_members(&[1, 2, 3, 4]), 4);
 }
 
-fn count_members(v: &[uint]) -> uint {
+fn count_members(v: &[usize]) -> usize {
     match v {
         []         => 0,
         [_]        => 1,
index 8ae3d072362ed6b5db81a00be3becce691926a7f..aaf1e5fc18320ec81cc5e9afe44ad9c4e0ed731e 100644 (file)
@@ -8,4 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {}
index 6782310fa0aa52a7fe90ea7887a231009e854b40..54705c6bf1301133d70ff9f4da29357f03e2cb4d 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub enum T {
     T1(()),
     T2(())
 }
 
 pub enum V {
-    V1(int),
+    V1(isize),
     V2(bool)
 }
 
index aa176d5b0f04197fa482b9a929f3df414a539fc4..ee348d9cb0ccfe7ebb6aa8534e6fee9960fb7abc 100644 (file)
@@ -1,5 +1,3 @@
-// no-prefer-dynamic
-
 // 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.
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::slice::SliceExt;
-use std::old_io::{fs, USER_RWX};
-use std::process;
+// no-prefer-dynamic
+
+// pretty-expanded FIXME #23616
+
+#![feature(fs, process, env, path, rand)]
+
 use std::env;
-use std::old_path::BytesContainer;
+use std::fs;
+use std::process;
 use std::rand::random;
+use std::str;
 
 fn main() {
     // If we're the child, make sure we were invoked correctly
@@ -25,7 +28,7 @@ fn main() {
         // checking that it ends_with the executable name. This
         // is needed because of Windows, which has a different behavior.
         // See #15149 for more info.
-        return assert!(args[0].ends_with(&format!("mytest{}", env::consts::EXE_SUFFIX)[]));
+        return assert!(args[0].ends_with(&format!("mytest{}", env::consts::EXE_SUFFIX)));
     }
 
     test();
@@ -34,21 +37,20 @@ fn main() {
 fn test() {
     // If we're the parent, copy our own binary to a new directory.
     let my_path = env::current_exe().unwrap();
-    let my_dir  = my_path.dir_path();
+    let my_dir  = my_path.parent().unwrap();
 
     let random_u32: u32 = random();
-    let child_dir = Path::new(my_dir.join(format!("issue-15149-child-{}",
-                                                  random_u32)));
-    fs::mkdir(&child_dir, USER_RWX).unwrap();
+    let child_dir = my_dir.join(&format!("issue-15149-child-{}", random_u32));
+    fs::create_dir(&child_dir).unwrap();
 
-    let child_path = child_dir.join(format!("mytest{}",
-                                            env::consts::EXE_SUFFIX));
+    let child_path = child_dir.join(&format!("mytest{}",
+                                             env::consts::EXE_SUFFIX));
     fs::copy(&my_path, &child_path).unwrap();
 
     // Append the new directory to our own PATH.
     let path = {
         let mut paths: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap()).collect();
-        paths.push(child_dir.clone());
+        paths.push(child_dir.to_path_buf());
         env::join_paths(paths.iter()).unwrap()
     };
 
@@ -58,9 +60,9 @@ fn test() {
 
     assert!(child_output.status.success(),
             format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}",
-                    child_output.stdout.container_as_str().unwrap(),
-                    child_output.stderr.container_as_str().unwrap()));
+                    str::from_utf8(&child_output.stdout).unwrap(),
+                    str::from_utf8(&child_output.stderr).unwrap()));
 
-    fs::rmdir_recursive(&child_dir).unwrap();
+    fs::remove_dir_all(&child_dir).unwrap();
 
 }
index 3a63e63355cd09b0eda51acee61a0bd6dd8d7f28..e1ecaaab026cf275ad0b9a4779e4ec1460043859 100644 (file)
@@ -28,5 +28,3 @@ fn main() {
     test_trait::<TraitWithSend>();
     test_trait::<IndirectTraitWithSend>();
 }
-
-
index 49e5b14aff8058c5821e8268a29db5cb6720b9e9..bb89fb2fa102f8c218956085b4ccf3a66e1dfa55 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! inner {
     ($e:pat ) => ($e)
 }
@@ -20,4 +22,3 @@ fn main() {
     let outer!(g1) = 13;
     g1;
 }
-
index fbbd40895b283d126930b6e164ce673dba9bf00c..239fef1232639cdc1feea1f12dda2323eddf6402 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static mut n_mut: uint = 0;
+// pretty-expanded FIXME #23616
 
-static n: &'static uint = unsafe{ &n_mut };
+static mut n_mut: usize = 0;
+
+static n: &'static usize = unsafe{ &n_mut };
 
 fn main() {}
index 0f4978d78dd86700d0961236461cb6a7ca632250..e9a9eabcd917fcffadef52101bbe508ad389b24b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait MyTrait {
     fn foo(&self);
 }
@@ -20,11 +22,11 @@ fn bar<T: MyTrait>(t: &T) {
     t.foo()
 }
 
-fn thing(a: int, b: int) -> int {
+fn thing(a: isize, b: isize) -> isize {
     a + b
 }
 
 fn main() {
-    let thing: fn(int, int) -> int = thing; // coerce to fn type
+    let thing: fn(isize, isize) -> isize = thing; // coerce to fn type
     bar(&thing);
 }
index 82f53ea7cd408a0333fef195c72d7269aebaf7c4..f1ef57e44b1d5f54c1e1b5a056dcf6e847eaafb2 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-15562.rs
 
-extern crate "issue-15562" as i;
+// pretty-expanded FIXME #23616
+
+extern crate issue_15562 as i;
 
 pub fn main() {
     extern {
index ab9554f65d4c89d93aa6c813b883551d737809ea..3dc76f4a089d9a50114b79b3be8ebcc38ce3f58d 100644 (file)
@@ -12,7 +12,7 @@
 #![feature(box_syntax)]
 
 fn match_on_local() {
-    let mut foo = Some(box 5);
+    let mut foo: Option<Box<_>> = Some(box 5);
     match foo {
         None => {},
         Some(x) => {
@@ -33,7 +33,7 @@ fn match_on_arg(mut foo: Option<Box<i32>>) {
 }
 
 fn match_on_binding() {
-    match Some(box 7) {
+    match Some(Box::new(7)) {
         mut foo => {
             match foo {
                 None => {},
@@ -47,7 +47,7 @@ fn match_on_binding() {
 }
 
 fn match_on_upvar() {
-    let mut foo = Some(box 8i32);
+    let mut foo: Option<Box<_>> = Some(box 8);
     let f = move|| {
         match foo {
             None => {},
index a6b8a04eeb60ed63a88133466eb4933fa09885d8..6c76f1595dc0de1d748e6ebac54ec76fe7357127 100644 (file)
@@ -8,8 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::iter::AdditiveIterator;
 fn main() {
     let x: [u64; 3] = [1, 2, 3];
-    assert_eq!(6, (0_usize..3).map(|i| x[i]).sum());
+    assert_eq!(6, (0..3).map(|i| x[i]).sum());
 }
index 06e9e652ed25bfc06c3ed1f2a7e4c8f5df74d1e6..9fc1cce56b767d4527eb3c0d71d4135038541409 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(PartialEq)]
 enum Test<'a> {
-    Slice(&'a int)
+    Slice(&'a isize)
 }
 
 fn main() {
index 8da82c498b0b7d1eba2f76eb55e570fe94267012..922b18c01d9ebdf03482355e4982ec266204fc1e 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(Clone)]
 enum Test<'a> {
-    Slice(&'a int)
+    Slice(&'a isize)
 }
 
 fn main() {}
index 72daa0cba4104abcb20783e2f34d66589fabdb16..929580019ff64fc389804736868f44382d925a4c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let mut array = [1, 2, 3];
     let pie_slice = &array[1..2];
index e66ac8ff53c1f76e6511cd13b9e8987cd31baa44..67ce6a1c44f0db4b2866889bdbaaec565dd92f43 100644 (file)
 // If `Index` used an associated type for its output, this test would
 // work more smoothly.
 
-#![feature(old_orphan_check)]
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
 
 use std::ops::Index;
 
-struct Mat<T> { data: Vec<T>, cols: uint, }
+struct Mat<T> { data: Vec<T>, cols: usize, }
 
 impl<T> Mat<T> {
-    fn new(data: Vec<T>, cols: uint) -> Mat<T> {
+    fn new(data: Vec<T>, cols: usize) -> Mat<T> {
         Mat { data: data, cols: cols }
     }
-    fn row<'a>(&'a self, row: uint) -> Row<&'a Mat<T>> {
+    fn row<'a>(&'a self, row: usize) -> Row<&'a Mat<T>> {
         Row { mat: self, row: row, }
     }
 }
 
-impl<T> Index<(uint, uint)> for Mat<T> {
+impl<T> Index<(usize, usize)> for Mat<T> {
     type Output = T;
 
-    fn index<'a>(&'a self, &(row, col): &(uint, uint)) -> &'a T {
+    fn index<'a>(&'a self, (row, col): (usize, usize)) -> &'a T {
         &self.data[row * self.cols + col]
     }
 }
 
-impl<'a, T> Index<(uint, uint)> for &'a Mat<T> {
+impl<'a, T> Index<(usize, usize)> for &'a Mat<T> {
     type Output = T;
 
-    fn index<'b>(&'b self, index: &(uint, uint)) -> &'b T {
+    fn index<'b>(&'b self, index: (usize, usize)) -> &'b T {
         (*self).index(index)
     }
 }
 
-struct Row<M> { mat: M, row: uint, }
+struct Row<M> { mat: M, row: usize, }
 
-impl<T, M: Index<(uint, uint), Output=T>> Index<uint> for Row<M> {
+impl<T, M: Index<(usize, usize), Output=T>> Index<usize> for Row<M> {
     type Output = T;
 
-    fn index<'a>(&'a self, col: &uint) -> &'a T {
-        &self.mat[(self.row, *col)]
+    fn index<'a>(&'a self, col: usize) -> &'a T {
+        &self.mat[(self.row, col)]
     }
 }
 
 fn main() {
-    let m = Mat::new(vec!(1_usize, 2, 3, 4, 5, 6), 3);
+    let m = Mat::new(vec!(1, 2, 3, 4, 5, 6), 3);
     let r = m.row(1);
 
-    assert!(r.index(&2) == &6);
+    assert!(r.index(2) == &6);
+    assert!(r[2] == 6);
     assert!(r[2] == 6);
-    assert!(r[2_usize] == 6_usize);
     assert!(6 == r[2]);
 
     let e = r[2];
     assert!(e == 6);
 
-    let e: uint = r[2];
+    let e: usize = r[2];
     assert!(e == 6);
 }
index 7bfd8e0ab718942444aef42f8adf76889799e924..b5251d63ff09e392a7a6be6ef4858a61fb732b8d 100644 (file)
@@ -13,7 +13,7 @@
 
 #[derive(PartialEq, Debug)]
 struct Bar {
-    x: int
+    x: isize
 }
 impl Drop for Bar {
     fn drop(&mut self) {
@@ -24,17 +24,17 @@ impl Drop for Bar {
 #[derive(PartialEq, Debug)]
 struct Foo {
     x: Bar,
-    a: int
+    a: isize
 }
 
-fn foo() -> Result<Foo, int> {
+fn foo() -> Result<Foo, isize> {
     return Ok(Foo {
         x: Bar { x: 22 },
         a: return Err(32)
     });
 }
 
-fn baz() -> Result<Foo, int> {
+fn baz() -> Result<Foo, isize> {
     Ok(Foo {
         x: Bar { x: 22 },
         a: return Err(32)
@@ -42,41 +42,41 @@ fn baz() -> Result<Foo, int> {
 }
 
 // explicit immediate return
-fn aa() -> int {
+fn aa() -> isize {
     return 3;
 }
 
 // implicit immediate return
-fn bb() -> int {
+fn bb() -> isize {
     3
 }
 
 // implicit outptr return
-fn cc() -> Result<int, int> {
+fn cc() -> Result<isize, isize> {
     Ok(3)
 }
 
 // explicit outptr return
-fn dd() -> Result<int, int> {
+fn dd() -> Result<isize, isize> {
     return Ok(3);
 }
 
 trait A {
-    fn aaa(&self) -> int {
+    fn aaa(&self) -> isize {
         3
     }
-    fn bbb(&self) -> int {
+    fn bbb(&self) -> isize {
         return 3;
     }
-    fn ccc(&self) -> Result<int, int> {
+    fn ccc(&self) -> Result<isize, isize> {
         Ok(3)
     }
-    fn ddd(&self) -> Result<int, int> {
+    fn ddd(&self) -> Result<isize, isize> {
         return Ok(3);
     }
 }
 
-impl A for int {}
+impl A for isize {}
 
 fn main() {
     assert_eq!(foo(), Err(32));
@@ -87,12 +87,12 @@ fn main() {
     assert_eq!(cc().unwrap(), 3);
     assert_eq!(dd().unwrap(), 3);
 
-    let i = box 32 as Box<A>;
+    let i = box 32is as Box<A>;
     assert_eq!(i.aaa(), 3);
-    let i = box 32 as Box<A>;
+    let i = box 32is as Box<A>;
     assert_eq!(i.bbb(), 3);
-    let i = box 32 as Box<A>;
+    let i = box 32is as Box<A>;
     assert_eq!(i.ccc().unwrap(), 3);
-    let i = box 32 as Box<A>;
+    let i = box 32is as Box<A>;
     assert_eq!(i.ddd().unwrap(), 3);
 }
index 77fa862f7d4f64b18b924d360de634affcbba37b..eb3322e037058a36d57e03cbaab7aad9f10dd81c 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![deny(warnings)]
 #![allow(unused_imports)]
 
-enum Foo { A }
+pub enum Foo { A }
 mod bar {
     pub fn normal(x: ::Foo) {
         use Foo::A;
index 933fa881eed5488054c89554c237e061b9e5f49a..21baf47ee661071c78c75852b3f2fdc3da4281c2 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum NestedEnum {
     First,
     Second,
@@ -19,7 +21,7 @@ enum Enum {
 }
 
 #[inline(never)]
-fn foo(x: Enum) -> int {
+fn foo(x: Enum) -> isize {
     match x {
         Enum::Variant1(true) => 1,
         Enum::Variant1(false) => 2,
index 6a4f78442d149943ded6817b5663f3580dbf339c..265db3fe1336a6520a4d92dfd0e63e3c96c3f014 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 
 static mut DROP_RAN: bool = false;
@@ -23,7 +25,7 @@ impl Bar for BarImpl {
 }
 
 
-struct Foo<B>(B);
+struct Foo<B: Bar>(B);
 
 #[unsafe_destructor]
 impl<B: Bar> Drop for Foo<B> {
index 18e1918aea44747e945eb0056b618300c084b109..6b75e4e47978e789281d275d51b0f14c837ecccd 100644 (file)
@@ -10,6 +10,8 @@
 //
 // regression test for the model lexer handling the DOTDOTDOT syntax (#15877)
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     match 5_usize {
       1_usize...5_usize => {}
index 88b250af1c09636a8a07ac1f2150de2bda0fb1c5..e544585745de3dfc21839f252614879bc2e19d44 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unsafe_destructor)]
+// pretty-expanded FIXME #23616
+
+#![feature(unsafe_destructor, rustc_private)]
 
 extern crate serialize;
 
@@ -16,7 +18,7 @@ use std::fmt;
 use serialize::{Encoder, Encodable};
 use serialize::json;
 
-struct Foo<T> {
+struct Foo<T: Encodable> {
     v: T,
 }
 
index 5401d6a6fdcedb4fc3cb07d30335b87da3ce53b6..242bcb69be60d1cdb6afb38b2f090f3aadeedfa5 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
-static mut DROP_COUNT: uint = 0;
+static mut DROP_COUNT: usize = 0;
 
 struct Fragment;
 
@@ -35,4 +37,3 @@ fn main() {
         assert_eq!(DROP_COUNT, 3);
     }
 }
-
index 48ea3a93296e3194420f2e9c79c05e23c907cade..b994fcb46b09673d7dcba4d7d4bbb96a215724b4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let mut buf = Vec::new();
     |c: u8| buf.push(c);
index 3bab78ab0df9f0ca3959ff1ea010a0f9a5ff0b0b..9562d113ada7059e5d7c487e4225ddb938ea74f0 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::old_io::{process, Command};
+// ignore-aarch64
+
+use std::process::Command;
 use std::env;
 
 fn main() {
@@ -22,10 +24,8 @@ fn main() {
 }
 
 fn test() {
-    let status = Command::new(env::current_exe().unwrap())
+    let status = Command::new(&env::current_exe().unwrap())
                          .arg("foo").arg("")
-                         .stdout(process::InheritFd(1))
-                         .stderr(process::InheritFd(2))
                          .status().unwrap();
     assert!(status.success());
 }
index ade312da21b7036853db790473cb1fe6bb088631..41af72db20089024d647d3a4b25eb0b75b0f625b 100644 (file)
@@ -17,4 +17,3 @@ fn main() {assert_eq!(b"", b"\
 assert_eq!(b"\n", b"
 ");
 }
-
index 62c36e1d8863661c6331d925223b5bafe3ae48fa..4624953dea3fa85c761442f69e56de0c0349fa05 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct Empty;
 
 // This used to cause an ICE
index da480207490ca294864da6e20dfa799468cdb647..b6056d0ab8ca902df1ee403579ed9c8ecbae7d72 100644 (file)
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     if true { return }
     match () {
-        () => { static MAGIC: uint = 0; }
+        () => { static MAGIC: usize = 0; }
     }
 }
-
index 67af19b85175984aa49e64cfe613483f9b2af11a..fcb0462766291073da2f2de7c2fe787e56f0ca70 100644 (file)
@@ -16,12 +16,12 @@ use std::rc::Rc;
 use std::cell::Cell;
 
 struct Field {
-    number: uint,
-    state: Rc<Cell<uint>>
+    number: usize,
+    state: Rc<Cell<usize>>
 }
 
 impl Field {
-    fn new(number: uint, state: Rc<Cell<uint>>) -> Field {
+    fn new(number: usize, state: Rc<Cell<usize>>) -> Field {
         Field {
             number: number,
             state: state
index 7e3b796235d26a25367cf348590d65cf0018cc16..bf33221431ae026418b9b3d8016517929bc1c96c 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(hash)]
+
 use std::hash::{SipHasher, hash};
 
 #[derive(Hash)]
index 9448e605937f728b36c2410841f3ec3d68af1054..33842fab6989cecf2df6720b630aadb74599b6bf 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 use std::thread;
@@ -15,7 +17,7 @@ use std::mem;
 
 fn main() {
     let y = 0u8;
-    let closure = move |x| y + x;
+    let closure = move |x: u8| y + x;
 
     // Check that both closures are capturing by value
     assert_eq!(1, mem::size_of_val(&closure));
index 1ba7b142e5e15c957f35d44fd3de35ebc9f36f70..743dbbc9b99564e408bcf2d025f87a3a779e1aa6 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait MatrixRow { fn dummy(&self) { }}
 
 struct Mat;
index 72e948e613b2e2b70f2cd2b1362bc06003186cd4..d074095dbdedd796e2c1d781c31250415100ae43 100644 (file)
@@ -15,5 +15,5 @@ mod test {
     use super::*;
 
     #[test]
-    fn test(){}
+    pub fn test(){}
 }
index 5c8b4be0cee1a4a642bf375639f510378e6b0c36..2a59c3051d5cb9a0a1d1a7fb9cf2dd34fb103949 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    static _x: int = 1<<2;
+    static _x: isize = 1<<2;
 }
index 4e57c55c5f755fd994b1b416f79dd3c6263a8016..54572296df7e0c4ecb9b9b91ccb4cf6c5eb499e3 100644 (file)
 
 // aux-build:issue-16643.rs
 
-extern crate "issue-16643" as i;
+// pretty-expanded FIXME #23616
+
+extern crate issue_16643 as i;
 
 pub fn main() {
-    i::TreeBuilder { h: 3u }.process_token();
+    i::TreeBuilder { h: 3 }.process_token();
 }
index 0b58df56b6f767bc2a38201c14f15df47970365c..f0ff9ce7554b5c3cb23c58e885cfc82d576b6572 100644 (file)
@@ -8,8 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(slice_patterns)]
+
 fn main() {
-    let x: (int, &[int]) = (2, &[1, 2]);
+    let x: (isize, &[isize]) = (2, &[1, 2]);
     assert_eq!(match x {
         (0, [_, _]) => 0,
         (1, _) => 1,
index daf09047bef723649a519d9d5a952376ce28b4ec..786c701a0427bf0808c321b14002c872c25f1c4e 100644 (file)
@@ -11,7 +11,6 @@
 // ignore-pretty
 
 #![allow(unknown_features)]
-#![feature(box_syntax)]
 #![feature(unboxed_closures)]
 
 struct Parser<'a, I, O> {
@@ -20,13 +19,14 @@ struct Parser<'a, I, O> {
 
 impl<'a, I: 'a, O: 'a> Parser<'a, I, O> {
     fn compose<K: 'a>(mut self, mut rhs: Parser<'a, O, K>) -> Parser<'a, I, K> {
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
         Parser {
-            parse: box move |x: I| {
+            parse: Box::new(move |x: I| {
                 match (self.parse)(x) {
                     Ok(r) => (rhs.parse)(r),
                     Err(e) => Err(e)
                 }
-            }
+            })
         }
     }
 }
index b06c4923c16c1af370ea3f443e1932d4a3a7d475..1ebe3a7f068acc7184c3e334e70876dc919dcaf8 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// DON'T REENABLE THIS UNLESS YOU'VE ACTUALLY FIXED THE UNDERLYING ISSUE
+// ignore-android seems to block forever
 
 #![forbid(warnings)]
 
 // A var moved into a proc, that has a mutable loan path should
 // not trigger a misleading unused_mut warning.
 
+use std::io::prelude::*;
 use std::thread;
 
 pub fn main() {
-    let mut stdin = std::old_io::stdin();
+    let mut stdin = std::io::stdin();
     thread::spawn(move|| {
-        let _ = stdin.read_to_end();
-    });
+        let mut v = Vec::new();
+        let _ = stdin.read_to_end(&mut v);
+    }).join().ok().unwrap();
 }
index 389baecafd14402eaa5776c593746d897035f428..99ddaba4e5514513291796aa2d90198757bf776d 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, core)]
 
 // Test that unboxing shim for calling rust-call ABI methods through a
 // trait box works and does not cause an ICE.
 struct Foo { foo: u32 }
 
 impl FnMut<()> for Foo {
-    type Output = u32;
     extern "rust-call" fn call_mut(&mut self, _: ()) -> u32 { self.foo }
 }
 
-impl FnMut<(u32,)> for Foo {
+impl FnOnce<()> for Foo {
     type Output = u32;
+    extern "rust-call" fn call_once(mut self, _: ()) -> u32 { self.call_mut(()) }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+impl FnMut<(u32,)> for Foo {
     extern "rust-call" fn call_mut(&mut self, (x,): (u32,)) -> u32 { self.foo + x }
 }
 
-impl FnMut<(u32,u32)> for Foo {
+impl FnOnce<(u32,)> for Foo {
     type Output = u32;
+    extern "rust-call" fn call_once(mut self, args: (u32,)) -> u32 { self.call_mut(args) }
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+impl FnMut<(u32,u32)> for Foo {
     extern "rust-call" fn call_mut(&mut self, (x, y): (u32, u32)) -> u32 { self.foo + x + y }
 }
 
+impl FnOnce<(u32,u32)> for Foo {
+    type Output = u32;
+    extern "rust-call" fn call_once(mut self, args: (u32,u32)) -> u32 { self.call_mut(args) }
+}
+
 fn main() {
     let mut f = box Foo { foo: 42 } as Box<FnMut() -> u32>;
     assert_eq!(f.call_mut(()), 42);
index 26661302242bc9c20622aa6ee684d56576aff153..17d0969ce1c023e9044387ddc0d5dfb7b1742d55 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 #![feature(box_patterns)]
@@ -15,7 +17,7 @@
 
 use std::ops::{Deref, DerefMut};
 
-struct X(Box<int>);
+struct X(Box<isize>);
 
 static mut DESTRUCTOR_RAN: bool = false;
 
@@ -29,16 +31,16 @@ impl Drop for X {
 }
 
 impl Deref for X {
-    type Target = int;
+    type Target = isize;
 
-    fn deref(&self) -> &int {
+    fn deref(&self) -> &isize {
         let &X(box ref x) = self;
         x
     }
 }
 
 impl DerefMut for X {
-    fn deref_mut(&mut self) -> &mut int {
+    fn deref_mut(&mut self) -> &mut isize {
         let &mut X(box ref mut x) = self;
         x
     }
index c2bcbe045c0cc07ac5c51e59a4cbfffd1e46893b..33cdbca14e3675853e6f05a0b773f88fabfbee0f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = [1, 2, 3];
     let y = x;
diff --git a/src/test/run-pass/issue-16922.rs b/src/test/run-pass/issue-16922.rs
new file mode 100644 (file)
index 0000000..1fdc27e
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+use std::any::Any;
+
+fn foo(_: &u8) {
+}
+
+fn main() {
+    let _ = &foo as &Any;
+}
index 40e112d6fbf7637ab56636048881c872456cb5de..4c6c200c7164e9890f70e19341de145be9661443 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(collections)]
+
 extern crate collections;
 
 use std::collections::HashMap;
index 9dc78ce0d4f1ad2fbdfefb273081c44928967cb6..b8c51f2cd31129632e165e1a3c9d75a7eb7d59fd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum pattern { tabby, tortoiseshell, calico }
 enum breed { beagle, rottweiler, pug }
 type name = String;
index a0e6f2c9be96e3117bdf6e0ca65932d02792c91a..55a6d4cdbace7f43000a0386225496241fc11261 100644 (file)
@@ -10,7 +10,9 @@
 
 // Test that regionck creates the right region links in the pattern
 // binding of a for loop
-fn foo<'a>(v: &'a [uint]) -> &'a uint {
+// pretty-expanded FIXME #23616
+
+fn foo<'a>(v: &'a [usize]) -> &'a usize {
     for &ref x in v { return x; }
     unreachable!()
 }
index d367e0e908e32565ae186dc55d9ebefb69511e54..08c313ab0a42b397404a8dcf547b4a8621f88516 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static X2: u64 = -1 as u16 as u64;
-static Y2: u64 = -1 as u32 as u64;
-const X: u64 = -1 as u16 as u64;
-const Y: u64 = -1 as u32 as u64;
+// pretty-expanded FIXME #23616
+
+static X2: u64 = !0 as u16 as u64;
+static Y2: u64 = !0 as u32 as u64;
+const X: u64 = !0 as u16 as u64;
+const Y: u64 = !0 as u32 as u64;
 
 fn main() {
     assert_eq!(match 1 {
index 2f0b8c9f19beb1c0f57ded4062ceb73d33ca23bc..366ef7543fdbb9cc1a0c73d76da0cd5769213fcc 100644 (file)
@@ -8,31 +8,31 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::old_io::BufReader;
-use std::old_io::BufferedReader;
-use std::old_io::File;
-use std::old_io::IoResult;
+// pretty-expanded FIXME #23616
 
-struct Lexer<R: Reader>
+use std::fs::File;
+use std::io::{self, BufReader, Read};
+
+struct Lexer<R: Read>
 {
-    reader: BufferedReader<R>,
+    reader: BufReader<R>,
 }
 
-impl<R: Reader> Lexer<R>
+impl<R: Read> Lexer<R>
 {
     pub fn new_from_reader(r: R) -> Lexer<R>
     {
-        Lexer{reader: BufferedReader::new(r)}
+        Lexer{reader: BufReader::new(r)}
     }
 
-    pub fn new_from_file(p: Path) -> IoResult<Lexer<File>>
+    pub fn new_from_file(p: &str) -> io::Result<Lexer<File>>
     {
-        Ok(Lexer::new_from_reader(try!(File::open(&p))))
+        Ok(Lexer::new_from_reader(try!(File::open(p))))
     }
 
-    pub fn new_from_str<'a>(s: &'a str) -> Lexer<BufReader<'a>>
+    pub fn new_from_str<'a>(s: &'a str) -> Lexer<&'a [u8]>
     {
-        Lexer::new_from_reader(BufReader::new(s.as_bytes()))
+        Lexer::new_from_reader(s.as_bytes())
     }
 }
 
index ce5a0aa96e3d308493653125406e769e10e8bce1..f17834e8d36dc31d530cc13d18d1ad94c42ed7c0 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 
 struct Leak<'a> {
@@ -25,9 +27,7 @@ fn main() {
     let mut dropped = false;
     {
         let leak = Leak { dropped: &mut dropped };
-        // FIXME(#21721) "hack" used to be () but that can cause
-        // certain LLVM versions to abort during optimizations.
-        for (_, leaked) in Some(("hack", leak)).into_iter() {}
+        for ((), leaked) in Some(((), leak)).into_iter() {}
     }
 
     assert!(dropped);
diff --git a/src/test/run-pass/issue-17233.rs b/src/test/run-pass/issue-17233.rs
new file mode 100644 (file)
index 0000000..756822d
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+const X1: &'static [u8] = &[b'1'];
+const X2: &'static [u8] = b"1";
+const X3: &'static [u8; 1] = &[b'1'];
+const X4: &'static [u8; 1] = b"1";
+
+static Y1: u8 = X1[0];
+static Y2: u8 = X2[0];
+static Y3: u8 = X3[0];
+static Y4: u8 = X4[0];
+
+fn main() {
+    assert_eq!(Y1, Y2);
+    assert_eq!(Y1, Y3);
+    assert_eq!(Y1, Y4);
+}
index b2abf2d2b1a9c60238af56ad651827f953f8092a..35bd07c896bb6bae66a2cce7348530aa79951ec6 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 static mut DROPPED: [bool; 2] = [false, false];
 
-struct A(uint);
-struct Foo { _a: A, _b: int }
+struct A(usize);
+struct Foo { _a: A, _b: isize }
 
 impl Drop for A {
     fn drop(&mut self) {
index dd1cfb5e342832e9b50f87bae8687cfd0aaeae18..a9f5476d0f86c758350057a9ec9ed57f777f1107 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, io)]
 
-use std::old_io;
+use std::io::{self, Write};
 
-fn f(wr: &mut Writer) {
-    wr.write_str("hello").ok().expect("failed");
+fn f(wr: &mut Write) {
+    wr.write_all(b"hello").ok().expect("failed");
 }
 
 fn main() {
-    let mut wr = box old_io::stdout() as Box<Writer + 'static>;
+    let mut wr = box io::stdout() as Box<Write>;
     f(&mut wr);
 }
index 0966d4ea45eec9d17393252bca98b1d4031a7883..6e93194647ad2c8aea38bbfa4e80361f5100b485 100644 (file)
@@ -8,6 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
+trait Str { fn foo(&self) {} }
+impl Str for str {}
+impl<'a, S: ?Sized> Str for &'a S where S: Str {}
+
 fn main() {
     let _: &Str = &"x";
 }
index 092bcf661a76a2b5e2ecd7a4cef68790f0fd4196..354b0861758c5dfd87b157c3845c22c87e8d8f88 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test that astconv doesn't forget about mutability of &mut str
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     fn foo<T: ?Sized>(_: &mut T) {}
     let _f: fn(&mut str) = foo;
index a071224999be094bcfc0d598fce7b86eebd1c2de..796277ce74d1428a63e69d6cd504b6e64ea09993 100644 (file)
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 fn main() {
-    let s: &[int] = &[0, 1, 2, 3, 4];
-    let ss: &&[int] = &s;
-    let sss: &&&[int] = &ss;
+    let s: &[isize] = &[0, 1, 2, 3, 4];
+    let ss: &&[isize] = &s;
+    let sss: &&&[isize] = &ss;
 
     println!("{:?}", &s[..3]);
     println!("{:?}", &ss[3..]);
index 7bd41cc5b52a2fa06453d197100c5574c0b5daa4..36e12b96c8744dd88b6f9c75f5f9335871ac5ecb 100644 (file)
 
 // aux-build:issue-17662.rs
 
-extern crate "issue-17662" as i;
+// pretty-expanded FIXME #23616
+
+extern crate issue_17662 as i;
 
 use std::marker;
 
 struct Bar<'a> { m: marker::PhantomData<&'a ()> }
 
-impl<'a> i::Foo<'a, uint> for Bar<'a> {
-    fn foo(&self) -> uint { 5_usize }
+impl<'a> i::Foo<'a, usize> for Bar<'a> {
+    fn foo(&self) -> usize { 5 }
 }
 
 pub fn main() {
index 3ca6f473a7900a6fe3de06c98b6166b16ea04e44..1fc8f3274d459cfb4bc2b7c1c353d9dca713acb5 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const FOO: uint = 3;
+// pretty-expanded FIXME #23616
+
+const FOO: usize = 3;
 
 fn main() {
     assert_eq!(FOO, 3);
index cdd03244df14567d8e4b12db36f191c59b366686..29d72000d07cc0271fd70c7510d2565ef7f6a215 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::marker;
 use std::cell::UnsafeCell;
 
@@ -32,13 +36,13 @@ enum UnsafeEnum<T> {
 
 unsafe impl<T: Send> Sync for UnsafeEnum<T> {}
 
-static STATIC1: UnsafeEnum<int> = UnsafeEnum::VariantSafe;
+static STATIC1: UnsafeEnum<isize> = UnsafeEnum::VariantSafe;
 
-static STATIC2: MyUnsafePack<int> = MyUnsafePack(UnsafeCell { value: 1 });
-const CONST: MyUnsafePack<int> = MyUnsafePack(UnsafeCell { value: 1 });
-static STATIC3: MyUnsafe<int> = MyUnsafe{value: CONST};
+static STATIC2: MyUnsafePack<isize> = MyUnsafePack(UnsafeCell { value: 1 });
+const CONST: MyUnsafePack<isize> = MyUnsafePack(UnsafeCell { value: 1 });
+static STATIC3: MyUnsafe<isize> = MyUnsafe{value: CONST};
 
-static STATIC4: &'static MyUnsafePack<int> = &STATIC2;
+static STATIC4: &'static MyUnsafePack<isize> = &STATIC2;
 
 struct Wrap<T> {
     value: T
@@ -46,8 +50,8 @@ struct Wrap<T> {
 
 unsafe impl<T: Send> Sync for Wrap<T> {}
 
-static UNSAFE: MyUnsafePack<int> = MyUnsafePack(UnsafeCell{value: 2});
-static WRAPPED_UNSAFE: Wrap<&'static MyUnsafePack<int>> = Wrap { value: &UNSAFE };
+static UNSAFE: MyUnsafePack<isize> = MyUnsafePack(UnsafeCell{value: 2});
+static WRAPPED_UNSAFE: Wrap<&'static MyUnsafePack<isize>> = Wrap { value: &UNSAFE };
 
 fn main() {
     let a = &STATIC1;
index e4782e28928748b584c031bc4405658fb70df79d..13e082eada884be65a7a5d69cbb649474782eafd 100644 (file)
 
 // aux-build:issue-17718.rs
 
-extern crate "issue-17718" as other;
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
+extern crate issue_17718 as other;
 
 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 
-const C1: uint = 1;
+const C1: usize = 1;
 const C2: AtomicUsize = ATOMIC_USIZE_INIT;
 const C3: fn() = foo;
-const C4: uint = C1 * C1 + C1 / C1;
-const C5: &'static uint = &C4;
-const C6: uint = {
-    const C: uint = 3;
+const C4: usize = C1 * C1 + C1 / C1;
+const C5: &'static usize = &C4;
+const C6: usize = {
+    const C: usize = 3;
     C
 };
 
-static S1: uint = 3;
+static S1: usize = 3;
 static S2: AtomicUsize = ATOMIC_USIZE_INIT;
 
 mod test {
-    static A: uint = 4;
-    static B: &'static uint = &A;
-    static C: &'static uint = &(A);
+    static A: usize = 4;
+    static B: &'static usize = &A;
+    static C: &'static usize = &(A);
 }
 
 fn foo() {}
index de9611f259227caf28b801016b3fec51c246774c..9a678f00157e67231a9256c16d0c9fa7fc83953e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Person {
     type string;
     fn dummy(&self) { }
index 3cff16409cb9b811c2b6fdf782bb18fdb7824578..3cf9c62b40d4911209fbe83c1c353772c4f9869a 100644 (file)
@@ -10,8 +10,7 @@
 
 // Test that generating drop glue for Box<str> doesn't ICE
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 fn f(s: Box<str>) -> Box<str> {
     s
@@ -19,7 +18,9 @@ fn f(s: Box<str>) -> Box<str> {
 
 fn main() {
     // There is currently no safe way to construct a `Box<str>`, so improvise
-    let box_arr: Box<[u8]> = box ['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8];
+    //
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let box_arr: Box<[u8]> = Box::new(['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8]);
     let box_str: Box<str> = unsafe { std::mem::transmute(box_arr) };
     assert_eq!(&*box_str, "hello");
     f(box_str);
diff --git a/src/test/run-pass/issue-17746.rs b/src/test/run-pass/issue-17746.rs
new file mode 100644 (file)
index 0000000..a66d5e1
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2015 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.
+
+// Regression test for #17746
+
+fn main() {}
+
+struct A;
+
+impl A {
+    fn b(&mut self) {
+        self.a()
+    }
+}
+
+trait Foo {
+    fn dummy(&self) {}
+}
+trait Bar {
+    fn a(&self);
+}
+
+impl Foo for A {}
+impl<T> Bar for T where T: Foo {
+    fn a(&self) {}
+}
index 2f1b0342b8e04ad599d56f9ee164aa53b569a6f3..fc821441330a5277fbd95653170fca71b33d8003 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Aaa { fn dummy(&self) { } }
 
 impl<'a> Aaa for &'a mut (Aaa + 'a) {}
index a976eccf89ec4c3166d9e366d66f1c4cc6635499..65a0b51095c80cbd450c5bd0f465aa3306c998c0 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 use std::marker::PhantomData;
 
 fn main() {
     struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F, marker: PhantomData<&'a ()> }
-    let f = |x: Vec<&str>| -> &str "foobar";
+    let f = |x: Vec<&str>| -> &str { "foobar" };
     let sym = Symbol { function: f, marker: PhantomData };
     (sym.function)(vec![]);
 }
index a7d9e6a4be6d840596171e06e354e18bb9afd000..41fab9d9d54e0f905613e2200d58f5bd0b09846c 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(slice_patterns)]
+
 fn main() {
     assert_eq!(match [0u8; 1024] {
         _ => 42_usize,
index 3774aaa190333b97e687a0e4d76842c3e5781cfb..cf8c54fdd808667afc3262f7791369e8746e8ec6 100644 (file)
@@ -8,14 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, std_misc)]
 
 use std::thunk::Thunk;
 
-fn action(cb: Thunk<uint, uint>) -> uint {
-    cb.invoke(1)
+fn action(cb: Thunk<(usize,), usize>) -> usize {
+    cb(1)
 }
 
 pub fn main() {
-    println!("num: {}", action(Thunk::with_arg(move |u| u)));
+    println!("num: {}", action(Box::new(move |u| u)));
 }
index 58a0872a5719b1ee2ef54d5ab7a338d3bf35ff95..994001a82ce337e5f1ef7a91c0acc932b7580e62 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we can parse where clauses on various forms of tuple
 // structs.
 
+// pretty-expanded FIXME #23616
+
 struct Bar<T>(T) where T: Copy;
 struct Bleh<T, U>(T, U) where T: Copy, U: Sized;
 struct Baz<T> where T: Copy {
index 3d6b23c8805fc4e96814096db3dbc64595cf0e90..eecdea66cf6f7c02535609a23d219adb3750e869 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     ({return},);
 }
index a4b09eb08e0f663392de8cbbdcd25f47e8a01523..059d25173c2ad75e57f88fa3f2b979a13092eeb2 100644 (file)
@@ -8,19 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, std_misc)]
 
 use std::thunk::Thunk;
 
 pub trait Promisable: Send + Sync {}
 impl<T: Send + Sync> Promisable for T {}
-pub fn propagate<'a, T, E, F, G>(action: F) -> Thunk<'a,Result<T, E>, Result<T, E>>
+pub fn propagate<'a, T, E, F, G>(action: F) -> Thunk<'a, (Result<T, E>,), Result<T, E>>
     where
         T: Promisable + Clone + 'a,
         E: Promisable + Clone + 'a,
         F: FnOnce(&T) -> Result<T, E> + Send + 'a,
         G: FnOnce(Result<T, E>) -> Result<T, E> + 'a {
-    Thunk::with_arg(move |result: Result<T, E>| {
+    Box::new(move |result: Result<T, E>| {
         match result {
             Ok(ref t) => action(t),
             Err(ref e) => Err(e.clone()),
index b7c4bb0fe00460817b2a257ebab7dfc01b5d8ef7..bdff5ba484dc8928f2623b01f993c0afdee9f29e 100644 (file)
@@ -11,6 +11,8 @@
 // Issue #1821 - Don't recurse trying to typecheck this
 
 
+// pretty-expanded FIXME #23616
+
 enum t {
     foo(Vec<t>)
 }
index 67b3239d35197044725b5f79c1011e4b9ef40af5..376d6523ccb98c0c6dcdd5202e7291428565f4af 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct Cursor<'a>(::std::marker::PhantomData<&'a ()>);
 
 trait CursorNavigator {
index e5532b4550baab32c48a59b2191a8ee617f53141..4e60a7d9b5fbbe87a68d3c769a213b05b6f9785e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 const X: &'static str = "12345";
 
 fn test(s: String) -> bool {
index c734c1a322245c0e516179f1465bfe24ce9be83e..1386c9d0daa5b886661f5d388b8bb1debfd157d0 100644 (file)
@@ -11,6 +11,8 @@
 // Test that wrapping an unsized struct in an enum which gets optimised does
 // not ICE.
 
+// pretty-expanded FIXME #23616
+
 struct Str {
     f: [u8]
 }
index 63f57e0a2e85eaea056cfe042e1ca0c2e6bbbea8..41dacd3320379c5eeb3abf6f7aba5a42a5a835a7 100644 (file)
 // Test that non-static methods can be assigned to local variables as
 // function pointers.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
-    fn foo(&self) -> uint;
+    fn foo(&self) -> usize;
 }
 
-struct A(uint);
+struct A(usize);
 
 impl A {
-    fn bar(&self) -> uint { self.0 }
+    fn bar(&self) -> usize { self.0 }
 }
 
 impl Foo for A {
-    fn foo(&self) -> uint { self.bar() }
+    fn foo(&self) -> usize { self.bar() }
 }
 
 fn main() {
index ec7481ead0482dd29af975617cf66ad6bd2ae045..eb7e504ae14518eb187d821e6797de4638d5f1bf 100644 (file)
@@ -11,9 +11,8 @@
 // Check that trans doesn't ICE when translating an array repeat
 // expression with a count of 1 and a non-Copy element type.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 fn main() {
-    let _ = [box 1_usize; 1];
+    let _ = [Box::new(1_usize); 1];
 }
index ce026942948ca82c96597b997a8022bcc1414692..fb8158c6ddc600a24fc35582d11098add01e38cb 100644 (file)
@@ -13,7 +13,9 @@
 // translating the def ID of the trait during AST decoding.
 
 // aux-build:issue-18501.rs
-extern crate "issue-18501" as issue;
+// pretty-expanded FIXME #23616
+
+extern crate issue_18501 as issue;
 
 fn main() {
     issue::pass_method();
index c75abd62deba6721bcd7c0f851044cae09ef2137..b0b2f068bb74bb1be4f67cd62deee78da9bb132d 100644 (file)
@@ -15,7 +15,9 @@
 // impl.
 
 // aux-build:issue-18514.rs
-extern crate "issue-18514" as ice;
+// pretty-expanded FIXME #23616
+
+extern crate issue_18514 as ice;
 use ice::{Tr, St};
 
 fn main() {
index ce56f3e8d72875b996ec4c0ad66dc258997af30b..8de2d1e4259cfafafd6354d03f878a2b1f27666d 100644 (file)
 // Test that coercing bare fn's that return a zero sized type to
 // a closure doesn't cause an LLVM ERROR
 
+// pretty-expanded FIXME #23616
+
 struct Foo;
 
-fn uint_to_foo(_: uint) -> Foo {
+fn uint_to_foo(_: usize) -> Foo {
     Foo
 }
 
 #[allow(unused_must_use)]
 fn main() {
-    (0_usize..10).map(uint_to_foo);
+    (0..10).map(uint_to_foo);
 }
index 6b6296b0bd929f264fbd9c638189ad31f2f241ce..a256e619216862d5e9205ef0c7432fae46f5f4c7 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(old_io)]
+
 use std::old_io::FileType;
 
 pub fn main() {
index 8f560258d9f4795fe0aae54431c215b2df1d184b..a3affb7bf86f0a27bd292ac374033bff6aa12218 100644 (file)
@@ -12,6 +12,8 @@
 // once closure as an optimization by trans.  This used to hit an
 // incorrect assert.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 fn main() {
index 10ae2749a090202073e148129e2c2bc1e86ffbb3..2c346b93f5e8014dbb5d42f502e43837c3e4c6d1 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod a {
-    pub type rust_task = uint;
+    pub type rust_task = usize;
     pub mod rustrt {
         use super::rust_task;
         extern {
index bb2907241c2c6bfc06c5754f46f79e04c2f7bc09..302f5ddcc6c60c5041bbd5c95fd9e66fc4706634 100644 (file)
@@ -11,7 +11,9 @@
 // Test that param substitutions from the correct environment are
 // used when translating unboxed closure calls.
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, core)]
 
 pub fn inside<F: Fn()>(c: F) {
     c.call(());
index 698b61e5759ad98268aece46d4ccec0bbf109963..e4537e158d1231c6f947168a0823685936724a48 100644 (file)
@@ -11,6 +11,8 @@
 // Test that the self param space is not used in a conflicting
 // manner by unboxed closures within a default method on a trait
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 trait Tr {
index 0338a4eff22389e2ac1dc9a88dc51459437dcddd..277ad3260c514845eb81e830856e5579b23ca5f3 100644 (file)
 // Test that we don't panic on a RefCell borrow conflict in certain
 // code paths involving unboxed closures.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 // aux-build:issue-18711.rs
-extern crate "issue-18711" as issue;
+extern crate issue_18711 as issue;
 
 fn main() {
     (|| issue::inner(()))();
index 30ad827c697230d76fdcc2669839bc26240f70fc..a92fcb01f5b302d9a6dd3599901014fdc28c377d 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(Eq, PartialEq, PartialOrd, Ord)]
 enum Test<'a> {
-    Int(&'a int),
+    Int(&'a isize),
     Slice(&'a [u8]),
 }
 
index 2f23b8028ecb905fb0feec7f7c80188c2e00004e..8e51a900c0cae9cef114c2a5c5c7cdc61dca931a 100644 (file)
@@ -11,6 +11,8 @@
 // Test that regionck uses the right memcat for patterns in for loops
 // and doesn't ICE.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     for &&x in Some(&0_usize).iter() {
         assert_eq!(x, 0)
index 490f7eb6bea4b7f29e9e388cb2bc2df2fed553d2..16e6c99f0e31d3d187511d9b93b0569ab98bdb4a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod foo {
     pub mod bar {
         pub mod baz {
@@ -19,6 +21,6 @@ mod foo {
 }
 
 fn main() {
-    assert_eq!(module_path!(), "issue-18859");
-    assert_eq!(foo::bar::baz::name(), "issue-18859::foo::bar::baz");
+    assert_eq!(module_path!(), "issue_18859");
+    assert_eq!(foo::bar::baz::name(), "issue_18859::foo::bar::baz");
 }
index 16dd84315ed2cdadfcd1a7300b7ef1572aca864b..7cc61dd2532760d9021ac9092e2b17dab34f0ab5 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub trait Borrow<Borrowed: ?Sized> {
         fn borrow(&self) -> &Borrowed;
 }
index ac181c8db7185d02f53148c0aae27d33b50ffdb0..0735693a4bd468006ecb9bdfa692006cc8a0e423 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct Str([u8]);
 
 #[derive(Clone)]
index ef95b4d4f00c5834c14b31f0d82b5286942414f4..a0368063f2c1f6399a1ccb9e5cb8f14d53e81a91 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, core)]
 
 pub trait Handler {
     fn handle(&self, &mut String);
index 26eacd682efddbdbe958a471dfa1ea3b37da8a1b..0fd4b4394dc271ab32e2df0e7b40deecbde298d7 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum Foo {
     Bar,
     Baz
index 222f67af437ef327ad3232e8a972e05ef3c67d0b..e02d001ee98ad69ac67b31a3d1d1976e20676bce 100644 (file)
@@ -11,6 +11,8 @@
 // Test that a partially specified trait object with unspecified associated
 // type does not ICE.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
     type A;
 
index bc43874bfb3c02b16028eb3358fc1d90137aab0b..c5eb5069328016d45024acb51efda418d472fc9e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 fn foo<T, F: FnOnce(T) -> T>(f: F) {}
index 3436871b4d1fef7f16331e5b8041ef09e454faec..f9b605c44e9186f742461779195ee2a16e0c63ec 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Trait<Input> {
     type Output;
 
index cf0f48e025a0e037dd508ee1612c3a0555300f66..47b8aaacdadb8f98fde6d53ac8f2ebe4f4f92d54 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Trait<Input> {
     type Output;
 
index 9af4d30c4f640739d62a48b834b7bf3aea7f5404..f25450a8918270aef0f5a05134c94eb0caccae95 100644 (file)
@@ -8,14 +8,37 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct MyStruct { field: uint }
+// pretty-expanded FIXME #23616
+
+struct MyStruct { field: usize }
+struct Nested { nested: MyStruct }
+struct Mix2 { nested: ((usize,),) }
+
 const STRUCT: MyStruct = MyStruct { field: 42 };
-const TUP: (uint,) = (43,);
+const TUP: (usize,) = (43,);
+const NESTED_S: Nested = Nested { nested: MyStruct { field: 5 } };
+const NESTED_T: ((usize,),) = ((4,),);
+const MIX_1: ((Nested,),) = ((Nested { nested: MyStruct { field: 3 } },),);
+const MIX_2: Mix2 = Mix2 { nested: ((2,),) };
+const INSTANT_1: usize = (MyStruct { field: 1 }).field;
+const INSTANT_2: usize = (0,).0;
 
 fn main() {
     let a = [0; STRUCT.field];
     let b = [0; TUP.0];
+    let c = [0; NESTED_S.nested.field];
+    let d = [0; (NESTED_T.0).0];
+    let e = [0; (MIX_1.0).0.nested.field];
+    let f = [0; (MIX_2.nested.0).0];
+    let g = [0; INSTANT_1];
+    let h = [0; INSTANT_2];
 
-    assert!(a.len() == 42);
-    assert!(b.len() == 43);
+    assert_eq!(a.len(), 42);
+    assert_eq!(b.len(), 43);
+    assert_eq!(c.len(), 5);
+    assert_eq!(d.len(), 4);
+    assert_eq!(e.len(), 3);
+    assert_eq!(f.len(), 2);
+    assert_eq!(g.len(), 1);
+    assert_eq!(h.len(), 0);
 }
index 4a446a76de38923b2e50c78222a0112d529f0268..95ca3efb099c7d0d4c891bb873673bbdf1bfc287 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // aux-build:issue_19293.rs
+// pretty-expanded FIXME #23616
+
 extern crate issue_19293;
 use issue_19293::{Foo, MyEnum};
 
index 2f466d4ca8c47f59a72dc9b2e4c964955e99d8ea..e553c244c865313d5e62f3826a32ef5bc4b48d6e 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-19340-1.rs
 
-extern crate "issue-19340-1" as lib;
+// pretty-expanded FIXME #23616
+
+extern crate issue_19340_1 as lib;
 
 use lib::Homura;
 
index 8300220edeaff11310fc5bedc06ec6013cfee7b6..d7747201cbe4660abc616e68d89f32ee1195e1c2 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Homura {
     Madoka {
         name: String,
index 8b5269ab92f03f89848ce94021d39671c56d70e6..c0c210b3e96a468a61d88a1e75a178eceafb2bcc 100644 (file)
@@ -20,7 +20,7 @@ struct Bar<T> where T: Trait {
     bar: T,
 }
 
-impl Trait for int {}
+impl Trait for isize {}
 
 fn main() {
     let a = Foo { foo: 12 };
index e603167b26be0a0c41b741d9d482e521fc4a128e..2dc5a6e99799abed0a0f3179caddaabccf09fe11 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait T {
     unsafe extern "Rust" fn foo(&self);
 }
index 38a7af3a69597b72b3b48412ccfc2a0e490d5358..7557c1b44e0dc33b5df970cab8625468769f7fed 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Base {
     fn dummy(&self) { }
 }
index 0578db8f854fcbadd9e9d9bde0160a1f4582b4b7..069ceadf91627b0e9aea35f86ac94832a5a87701 100644 (file)
@@ -14,6 +14,8 @@
 // reasonable examples) let to ambiguity errors about not being able
 // to infer sufficient type information.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let n = 0;
     let it = Some(1_usize).into_iter().inspect(|_| {n;});
index 7bb0d055b844d9279925252e47810a88588aa10e..562d2e4169e66317c8fbb558b1fe1738908718f5 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait PoolManager {
     type C;
     fn dummy(&self) { }
index 4339339d74c88761f865def4492e3abf71e0cc01..1cb20011c2145fb5e90aa9807392291f59b0e242 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait PoolManager {
     type C;
     fn dummy(&self) { }
index 9d71aea01d01da7931a94c0a53a0e161fda80adc..7b33b4e7a4f391f8c268174a4f673eb33697884a 100644 (file)
@@ -10,6 +10,8 @@
 
 // Issue 1974
 // Don't double free the condition allocation
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let s = "hej".to_string();
     while s != "".to_string() {
index 23400859e54f1daa7cb464123bf7f6a845ff157c..5b415c63885e6f8446dc7e81ab375799f6731e5d 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections)]
+
 fn main() {
     let mut escaped = String::from_str("");
     for c in '\u{10401}'.escape_unicode() {
index a9ce6c7a9eb48bc7f399de8ecd60d20aae7ee8d8..15ca6a9d4c1d244df9546e14507f5c9b37722f3f 100644 (file)
 // Test that `<Type as Trait>::Output` and `Self::Output` are accepted as type annotations in let
 // bindings
 
+// pretty-expanded FIXME #23616
+
 trait Int {
     fn one() -> Self;
-    fn leading_zeros(self) -> uint;
+    fn leading_zeros(self) -> usize;
 }
 
 trait Foo {
diff --git a/src/test/run-pass/issue-19982.rs b/src/test/run-pass/issue-19982.rs
new file mode 100644 (file)
index 0000000..9442b03
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+#![feature(core,unboxed_closures)]
+
+#[allow(dead_code)]
+struct Foo;
+
+impl<'a> Fn<(&'a (),)> for Foo {
+    extern "rust-call" fn call(&self, (_,): (&(),)) {}
+}
+
+impl<'a> FnMut<(&'a (),)> for Foo {
+    extern "rust-call" fn call_mut(&mut self, (_,): (&(),)) {}
+}
+
+impl<'a> FnOnce<(&'a (),)> for Foo {
+    type Output = ();
+
+    extern "rust-call" fn call_once(self, (_,): (&(),)) {}
+}
+
+fn main() {}
index 374460487d8f211dead321386806720688fe59ab..9d433eabe62970d2f24aaab776fcddcd5d9651a3 100644 (file)
@@ -10,6 +10,8 @@
 
 // Check that associated types are `Sized`
 
+// pretty-expanded FIXME #23616
+
 trait Trait {
     type Output;
 
index 572a0d825282e7c5425690b47ef056f02954ae8b..7e89cfe24e16aeaef2ed23204a2852845b9664ad 100644 (file)
@@ -41,10 +41,10 @@ pub fn foo(box_1: fn () -> Box<[i8; 1]>,
 }
 
 pub fn main() {
-    fn box_1() -> Box<[i8; 1]> { Box::new( [1i8; 1] ) }
-    fn box_2() -> Box<[i8; 2]> { Box::new( [1i8; 2] ) }
-    fn box_3() -> Box<[i8; 3]> { Box::new( [1i8; 3] ) }
-    fn box_4() -> Box<[i8; 4]> { Box::new( [1i8; 4] ) }
+    fn box_1() -> Box<[i8; 1]> { Box::new( [1; 1] ) }
+    fn box_2() -> Box<[i8; 2]> { Box::new( [1; 2] ) }
+    fn box_3() -> Box<[i8; 3]> { Box::new( [1; 3] ) }
+    fn box_4() -> Box<[i8; 4]> { Box::new( [1; 4] ) }
 
     foo(box_1, box_2, box_3, box_4);
 }
index f751be6f13bc10ac9ee5ce2fbf1b78c0670c4376..5af5186e94f3748137dd8ebf8fe4bd90ba7afb74 100644 (file)
@@ -29,10 +29,10 @@ pub fn foo(box_1: fn () -> Box<[i8; 1]>,
 }
 
 pub fn main() {
-    fn box_1() -> Box<[i8; 1]> { Box::new( [1i8] ) }
-    fn box_2() -> Box<[i8; 20]> { Box::new( [1i8; 20] ) }
-    fn box_3() -> Box<[i8; 300]> { Box::new( [1i8; 300] ) }
-    fn box_4() -> Box<[i8; 4000]> { Box::new( [1i8; 4000] ) }
+    fn box_1() -> Box<[i8; 1]> { Box::new( [1] ) }
+    fn box_2() -> Box<[i8; 20]> { Box::new( [1; 20] ) }
+    fn box_3() -> Box<[i8; 300]> { Box::new( [1; 300] ) }
+    fn box_4() -> Box<[i8; 4000]> { Box::new( [1; 4000] ) }
 
     foo(box_1, box_2, box_3, box_4);
 }
index 4d20e6360ad4fdda2654b0047b475e37b2fcdaac..1fe443484665bc059d7dccc1ad9c88dc99b029a3 100644 (file)
@@ -8,14 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-windows currently windows requires UTF-8 for spawning processes
-
-use std::old_io::Command;
-use std::env;
+// ignore-aarch64
+#![feature(std_misc, os)]
 
+#[cfg(unix)]
 fn main() {
+    use std::process::Command;
+    use std::env;
+    use std::os::unix::prelude::*;
+    use std::ffi::OsStr;
+
     if env::args().len() == 1 {
-        assert!(Command::new(env::current_exe().unwrap()).arg(b"\xff")
+        assert!(Command::new(&env::current_exe().unwrap())
+                        .arg(<OsStr as OsStrExt>::from_bytes(b"\xff"))
                         .status().unwrap().success())
     }
 }
+
+#[cfg(windows)]
+fn main() {}
index 47791ceecb67d3144850b758c6001cb9970e2335..0e5eaf857f35cee588d4a068fe890e867cb789c2 100644 (file)
@@ -7,6 +7,8 @@
 // <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.
+// pretty-expanded FIXME #23616
+
 #![feature(link_llvm_intrinsics)]
 
 extern {
index 2f9e8feed248234be96d211da10bc540442f03f7..70064f4e2670c5f7fdc7f4e29aebc76da954f80b 100644 (file)
@@ -10,6 +10,8 @@
 
 // Regression test for Issue #20343.
 
+// pretty-expanded FIXME #23616
+
 #![deny(dead_code)]
 
 struct B { b: u32 }
index 877cec48b5dc77c54e72542dd48e4f01df9ec246..03c7e9f8db72b4e86371959700d4a41fee72d870 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:issue_20389.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate issue_20389;
 
 struct Foo;
diff --git a/src/test/run-pass/issue-20396.rs b/src/test/run-pass/issue-20396.rs
new file mode 100644 (file)
index 0000000..f607ed3
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+#![allow(dead_code)]
+
+trait Foo<T> {
+    fn noop(&self, _: T);
+}
+
+enum Bar<T> { Bla(T) }
+
+struct Baz<'a> {
+    inner: for<'b> Foo<Bar<&'b ()>> + 'a,
+}
+
+fn main() {}
index 92865c419b662055708dc82d373b503d50d8f10a..d2e2d9bd6efcf052e8774af622739811cbc43044 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Trait {
-        fn method(self) -> int;
+        fn method(self) -> isize;
 }
 
 struct Wrapper<T> {
@@ -17,7 +19,7 @@ struct Wrapper<T> {
 }
 
 impl<'a, T> Trait for &'a Wrapper<T> where &'a T: Trait {
-    fn method(self) -> int {
+    fn method(self) -> isize {
         let r: &'a T = &self.field;
         Trait::method(r); // these should both work
         r.method()
index fbc4cca800875b30c37b7e830cd65afe9cd79de5..d527d9519cfbc4eee484caa8bca030b6f3c492d4 100644 (file)
@@ -8,12 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(std_misc)]
+
 use std::thread;
 
-fn main() {
-    thread::Thread::spawn(move || { // no need for -> ()
+fn _foo() {
+    let _t = thread::scoped(move || { // no need for -> ()
         loop {
             println!("hello");
         }
     });
 }
+
+fn main() {}
index f83150b95184b15167322500172257ba08346325..e73492e7a7ee5216a72c41203eaa8f0a7b8b8ab6 100644 (file)
 
 // Test that overloaded calls work with zero arity closures
 
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 fn main() {
-    let functions: [Box<Fn() -> Option<()>>; 1] = [box || None];
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let functions: [Box<Fn() -> Option<()>>; 1] = [Box::new(|| None)];
 
     let _: Option<Vec<()>> = functions.iter().map(|f| (*f)()).collect();
 }
index 0d482548cc0bf933241d8a6f7407b83e7cba93ec..72ccd82a21ec74fc1349ac571a1ab271373c19e3 100644 (file)
 // A reduced version of the rustbook ice. The problem this encountered
 // had to do with trans ignoring binders.
 
-#![feature(associated_types)]
-#![feature(macro_rules)]
+// pretty-expanded FIXME #23616
+
+#![feature(os)]
 
 use std::iter;
 use std::os;
-use std::old_io::File;
+use std::fs::File;
+use std::io::prelude::*;
+use std::env;
+use std::path::Path;
 
-#[allow(unused)]
-pub fn parse_summary<R: Reader>(_: R, _: &Path) {
+pub fn parse_summary<R: Read>(_: R, _: &Path) {
      let path_from_root = Path::new("");
-     Path::new(iter::repeat("../")
+     Path::new(&iter::repeat("../")
                .take(path_from_root.components().count() - 1)
                .collect::<String>());
  }
 
-fn main() {
-    let cwd = os::getcwd().unwrap();
+fn foo() {
+    let cwd = env::current_dir().unwrap();
     let src = cwd.clone();
-    let summary = File::open(&src.join("SUMMARY.md"));
+    let summary = File::open(&src.join("SUMMARY.md")).unwrap();
     let _ = parse_summary(summary, &src);
 }
+
+fn main() {}
index 01a2322ae939919c397dbe71d8902180cccbdabf..df4c3923853416702aace351603b1454c83bb924 100644 (file)
 // UFCS-style calls to a method in `Trait` where `Self` was bound to a
 // trait object of type `Trait`. See also `ufcs-trait-object.rs`.
 
+// pretty-expanded FIXME #23616
+
 use std::fmt;
 
 fn main() {
-    let a: &fmt::Debug = &1_i32;
+    let a: &fmt::Debug = &1;
     format!("{:?}", a);
 }
index 5f2805ed354553f58dfd5d28847b20adea5cc15d..bd844b7720c868a6f1d8031966e4c92f03db0677 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(non_camel_case_types)]
 
 pub fn main() {
     let one = || {
         enum r { a };
-        r::a as uint
+        r::a as usize
     };
     let two = || {
         enum r { a };
-        r::a as uint
+        r::a as usize
     };
     one(); two();
 }
index 97c06ac98265fd6a8bec89b6cf5b93eaead6c849..98270099df9044f955ffb09d93b0d4067cb0c1bd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait T0 {
     type O;
     fn dummy(&self) { }
index d97017635718cfbcda8e502094d2b161c79ad09d..340670b41203658515a70d5a24c5db17bc161d7d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait T0 {
     type O;
     fn dummy(&self) { }
index 049e08d2b94f5b9838a44f8e34c23f8b62e050ab..8b5e6f837d852f070591e1591ba25f302c6cb866 100644 (file)
@@ -8,35 +8,42 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-android
-// ignore-windows
-
 // Regression test for #20797.
 
+// pretty-expanded FIXME #23616
+
 use std::default::Default;
-use std::old_io::IoResult;
-use std::old_io::fs;
-use std::old_io::fs::PathExtensions;
+use std::io;
+use std::fs;
+use std::path::PathBuf;
+
+pub trait PathExtensions {
+    fn is_dir(&self) -> bool { false }
+}
+
+impl PathExtensions for PathBuf {}
 
 /// A strategy for acquiring more subpaths to walk.
 pub trait Strategy {
-  type P: PathExtensions;
-  /// Get additional subpaths from a given path.
-  fn get_more(&self, item: &Self::P) -> IoResult<Vec<Self::P>>;
-  /// Determine whether a path should be walked further.
-  /// This is run against each item from `get_more()`.
-  fn prune(&self, p: &Self::P) -> bool;
+    type P: PathExtensions;
+    /// Get additional subpaths from a given path.
+    fn get_more(&self, item: &Self::P) -> io::Result<Vec<Self::P>>;
+    /// Determine whether a path should be walked further.
+    /// This is run against each item from `get_more()`.
+    fn prune(&self, p: &Self::P) -> bool;
 }
 
 /// The basic fully-recursive strategy. Nothing is pruned.
-#[derive(Copy, Default)]
+#[derive(Copy, Clone, Default)]
 pub struct Recursive;
 
 impl Strategy for Recursive {
-  type P = Path;
-  fn get_more(&self, p: &Path) -> IoResult<Vec<Path>> { fs::readdir(p) }
+    type P = PathBuf;
+    fn get_more(&self, p: &PathBuf) -> io::Result<Vec<PathBuf>> {
+        Ok(fs::read_dir(p).unwrap().map(|s| s.unwrap().path()).collect())
+    }
 
-  fn prune(&self, _: &Path) -> bool { false }
+    fn prune(&self, _: &PathBuf) -> bool { false }
 }
 
 /// A directory walker of `P` using strategy `S`.
@@ -46,49 +53,51 @@ pub struct Subpaths<S: Strategy> {
 }
 
 impl<S: Strategy> Subpaths<S> {
-  /// Create a directory walker with a root path and strategy.
-  pub fn new(p: &S::P, strategy: S) -> IoResult<Subpaths<S>> {
-    let stack = try!(strategy.get_more(p));
-    Ok(Subpaths { stack: stack, strategy: strategy })
-  }
+    /// Create a directory walker with a root path and strategy.
+    pub fn new(p: &S::P, strategy: S) -> io::Result<Subpaths<S>> {
+        let stack = try!(strategy.get_more(p));
+        Ok(Subpaths { stack: stack, strategy: strategy })
+    }
 }
 
 impl<S: Default + Strategy> Subpaths<S> {
-  /// Create a directory walker with a root path and a default strategy.
-  pub fn walk(p: &S::P) -> IoResult<Subpaths<S>> {
-      Subpaths::new(p, Default::default())
-  }
+    /// Create a directory walker with a root path and a default strategy.
+    pub fn walk(p: &S::P) -> io::Result<Subpaths<S>> {
+        Subpaths::new(p, Default::default())
+    }
 }
 
 impl<S: Default + Strategy> Default for Subpaths<S> {
-  fn default() -> Subpaths<S> {
-    Subpaths { stack: Vec::new(), strategy: Default::default() }
-  }
+    fn default() -> Subpaths<S> {
+        Subpaths { stack: Vec::new(), strategy: Default::default() }
+    }
 }
 
 impl<S: Strategy> Iterator for Subpaths<S> {
-  type Item = S::P;
-  fn next (&mut self) -> Option<S::P> {
-    let mut opt_path = self.stack.pop();
-    while opt_path.is_some() && self.strategy.prune(opt_path.as_ref().unwrap()) {
-      opt_path = self.stack.pop();
-    }
-    match opt_path {
-      Some(path) => {
-        if PathExtensions::is_dir(&path) {
-          let result = self.strategy.get_more(&path);
-          match result {
-            Ok(dirs) => { self.stack.extend(dirs.into_iter()); },
-            Err(..) => { }
-          }
+    type Item = S::P;
+    fn next (&mut self) -> Option<S::P> {
+        let mut opt_path = self.stack.pop();
+        while opt_path.is_some() && self.strategy.prune(opt_path.as_ref().unwrap()) {
+            opt_path = self.stack.pop();
+        }
+        match opt_path {
+            Some(path) => {
+                if path.is_dir() {
+                    let result = self.strategy.get_more(&path);
+                    match result {
+                        Ok(dirs) => { self.stack.extend(dirs.into_iter()); },
+                        Err(..) => { }
+                    }
+                }
+                Some(path)
+            }
+            None => None,
         }
-        Some(path)
-      }
-      None => None,
     }
-  }
 }
 
-fn main() {
-  let mut walker: Subpaths<Recursive> = Subpaths::walk(&Path::new("/home")).unwrap();
+fn _foo() {
+    let _walker: Subpaths<Recursive> = Subpaths::walk(&PathBuf::from("/home")).unwrap();
 }
+
+fn main() {}
index 561b61954768e69835f1cf72348c79930a6c6282..c297998b6493a08575bb65b5f8c4392735dab09a 100644 (file)
@@ -14,4 +14,4 @@
 #![deny(unstable)]
 
 #[test]
-fn foo() {}
+pub fn foo() {}
index 30c166cc67b9f45eacc6f26abfd4546e8bd94cbf..00e792c9a006ce048e12125d4db9a6db003c181a 100644 (file)
@@ -7,6 +7,8 @@
 // <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.
+// pretty-expanded FIXME #23616
+
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
index 3cdd57aed5a1ccef3c37438a0981005eee8f1e9a..d7a656be7afb0d4d3c35f1e8529f02fe146991c1 100644 (file)
@@ -8,22 +8,25 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
 
 struct NT(str);
 struct DST { a: u32, b: str }
 
 fn main() {
-    // get_tydesc should support unsized types
+    // type_name should support unsized types
     assert_eq!(unsafe {(
         // Slice
-        (*std::intrinsics::get_tydesc::<[u8]>()).name,
+        std::intrinsics::type_name::<[u8]>(),
         // str
-        (*std::intrinsics::get_tydesc::<str>()).name,
+        std::intrinsics::type_name::<str>(),
         // Trait
-        (*std::intrinsics::get_tydesc::<Copy>()).name,
+        std::intrinsics::type_name::<Copy>(),
         // Newtype
-        (*std::intrinsics::get_tydesc::<NT>()).name,
+        std::intrinsics::type_name::<NT>(),
         // DST
-        (*std::intrinsics::get_tydesc::<DST>()).name
+        std::intrinsics::type_name::<DST>()
     )}, ("[u8]", "str", "core::marker::Copy", "NT", "DST"));
 }
index 9205b247e1352e0edcb5b85a69824000b0e3a776..75d064a00fa89ad2e54d9aaf2677eba47c4ebef0 100644 (file)
@@ -13,6 +13,8 @@
 // insufficient type propagation caused the type of the iterator to be
 // incorrectly unified with the `*const` type to which it is coerced.
 
+// pretty-expanded FIXME #23616
+
 use std::ptr;
 
 trait IntoIterator {
index f91fb064ae27fcc8d7d5952fdf59a147b6ee44aa..5e2ac61caa216e239291bd01c63eafd014cefd35 100644 (file)
@@ -8,8 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[forbid(raw_pointer_derive)]
 #[derive(Copy)]
 struct Test(*const i32);
 
+impl Clone for Test {
+    fn clone(&self) -> Test { *self }
+}
+
 fn main() {}
index 235dddefacb4d2548f9299ac8f26086ccd3da82d..cabda0b500bd5d16f5b0d0a496419faba6e33561 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::sync::Arc;
 
 fn main() {
index feafee90372d68a1dbec97e64d3edfaddf3dd8b1..ff205cd694c3a848fab7c06bc9f37d343cf391a6 100644 (file)
@@ -10,6 +10,8 @@
 
 // Make sure that "bare sequences" don't ICE in follow checking
 
+// pretty-expanded FIXME #23616
+
 macro_rules! bare {
     $($id:expr),+ => ( $($id)+ )
 }
index bb20b3a321569a8f2f24acf940002350b06c56a1..ef86634125ebddf041c04c6701cb7bd62fb16102 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let v = vec![1, 2, 3];
     let boxed: Box<Iterator<Item=i32>> = Box::new(v.into_iter());
index 71bb3d39fe1d6c01dd61832864ebea9030ad0bb7..608c60d03b3e7aa0b599dc85186427a32cac5ff0 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![no_implicit_prelude]
 
 trait Iterator {
index 1d3984deac2095dfbdb109782360496138498810..41a9ca840b1782a3750538286f94c55bf118bc99 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use ::std::ops::RangeFull;
 
 fn test<T : Clone>(arg: T) -> T {
@@ -15,7 +17,7 @@ fn test<T : Clone>(arg: T) -> T {
 }
 
 #[derive(PartialEq)]
-struct Test(int);
+struct Test(isize);
 
 fn main() {
     // Check that ranges implement clone
index 6be7cea29280d5ef2b9b426f03b08d96f188e725..7fd329da2b72ae370285d6bae7a211356db8d0bb 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(Hash)]
 struct Foo {
     a: Vec<bool>,
diff --git a/src/test/run-pass/issue-21475.rs b/src/test/run-pass/issue-21475.rs
new file mode 100644 (file)
index 0000000..0666a1f
--- /dev/null
@@ -0,0 +1,27 @@
+// 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.
+
+// pretty-expanded FIXME #23616
+
+use m::{START, END};
+
+fn main() {
+    match 42 {
+        m::START...m::END => {},
+        0...m::END => {},
+        m::START...59 => {},
+        _  => {},
+    }
+}
+
+mod m {
+  pub const START: u32 = 4;
+  pub const END:   u32 = 14;
+}
index 3a813641a3f37490b8b34d94b4ac4105174993a3..b512fd4919356554e2f3fd0837fd4ab192559ae9 100644 (file)
@@ -11,6 +11,8 @@
 // Test that the requirement (in `Bar`) that `T::Bar : 'static` does
 // not wind up propagating to `T`.
 
+// pretty-expanded FIXME #23616
+
 pub trait Foo {
     type Bar;
 
@@ -26,4 +28,3 @@ struct Bar<T:Foo>
 }
 
 fn main() { }
-
index e5a2790917ff0a638424375e9721d5ecefd2f052..fe540e1aabef8b6a4582d9c13025901fac25ea41 100644 (file)
@@ -9,14 +9,16 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 fn main() {
-    if let Ok(x) = "3.1415".parse() {
+    if let Ok(x) = "3.1415".parse::<f64>() {
         assert_eq!(false, x <= 0.0);
     }
-    if let Ok(x) = "3.1415".parse() {
+    if let Ok(x) = "3.1415".parse::<f64>() {
         assert_eq!(3.1415, x + 0.0);
     }
-    if let Ok(mut x) = "3.1415".parse() {
+    if let Ok(mut x) = "3.1415".parse::<f64>() {
         assert_eq!(8.1415, { x += 5.0; x });
     }
 }
index b9b1e5f3337cd1b7791785550c8b191dc069321a..cb87770c565c0b117781e1e967d05ac94a5d4401 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn test(it: &mut Iterator<Item=i32>) {
     for x in it {
         assert_eq!(x, 1)
diff --git a/src/test/run-pass/issue-21721.rs b/src/test/run-pass/issue-21721.rs
new file mode 100644 (file)
index 0000000..c34ab1b
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+fn main() {
+    static NONE: Option<((), &'static u8)> = None;
+    let ptr = unsafe {
+        *(&NONE as *const _ as *const *const u8)
+    };
+    assert!(ptr.is_null());
+}
index 09d1a3bca6901723076782e3c107d73cc7a771c2..e1d1b908e0117131c6dbd919169570fad1e1074e 100644 (file)
@@ -12,6 +12,8 @@
 // subtyping of projection types that resulted in an unconstrained
 // region, yielding region inference failures.
 
+// pretty-expanded FIXME #23616
+
 fn main() { }
 
 fn foo<'a>(s: &'a str) {
index 20ff8d29b7076bc4dc7d7028ad33ac8bc75dabd2..fb0d2f0ad85057a36583c443aa4a44f519a1e05d 100644 (file)
@@ -17,8 +17,8 @@
 //
 // Running /usr/local/bin/rustc:
 // issue-2185.rs:24:0: 26:1 error: conflicting implementations for a trait
-// issue-2185.rs:24 impl iterable<uint> for 'static ||uint|| {
-// issue-2185.rs:25     fn iter(&self, blk: |v: uint|) { self( |i| blk(i) ) }
+// issue-2185.rs:24 impl iterable<usize> for 'static ||usize|| {
+// issue-2185.rs:25     fn iter(&self, blk: |v: usize|) { self( |i| blk(i) ) }
 // issue-2185.rs:26 }
 // issue-2185.rs:20:0: 22:1 note: note conflicting implementation here
 // issue-2185.rs:20 impl<A> iterable<A> for 'static ||A|| {
@@ -26,7 +26,7 @@
 // issue-2185.rs:22 }
 //
 // … so it looks like it's just not possible to implement both
-// the generic iterable<uint> and iterable<A> for the type iterable<uint>.
+// the generic iterable<usize> and iterable<A> for the type iterable<usize>.
 // Is it okay if I just remove this test?
 //
 // but Niko responded:
@@ -50,8 +50,8 @@ impl<A> iterable<A> for 'static ||A|| {
     fn iter(&self, blk: |A|) { self(blk); }
 }
 
-impl iterable<uint> for 'static ||uint|| {
-    fn iter(&self, blk: |v: uint|) { self( |i| blk(i) ) }
+impl iterable<usize> for 'static ||usize|| {
+    fn iter(&self, blk: |v: usize|) { self( |i| blk(i) ) }
 }
 
 fn filter<A,IA:iterable<A>>(self: IA, prd: 'static |A| -> bool, blk: |A|) {
@@ -68,21 +68,21 @@ fn foldl<A,B,IA:iterable<A>>(self: IA, b0: B, blk: |B, A| -> B) -> B {
     b
 }
 
-fn range(lo: uint, hi: uint, it: |uint|) {
+fn range(lo: usize, hi: usize, it: |usize|) {
     let mut i = lo;
     while i < hi {
         it(i);
-        i += 1_usize;
+        i += 1;
     }
 }
 
 pub fn main() {
-    let range: 'static ||uint|| = |a| range(0_usize, 1000_usize, a);
-    let filt: 'static ||v: uint|| = |a| filter(
+    let range: 'static ||usize|| = |a| range(0, 1000, a);
+    let filt: 'static ||v: usize|| = |a| filter(
         range,
-        |&&n: uint| n % 3_usize != 0_usize && n % 5_usize != 0_usize,
+        |&&n: usize| n % 3 != 0 && n % 5 != 0,
         a);
-    let sum = foldl(filt, 0_usize, |accum, &&n: uint| accum + n );
+    let sum = foldl(filt, 0, |accum, &&n: usize| accum + n );
 
     println!("{}", sum);
 }
index d6e6f23191e240dd0e26096f0423277dd399011a..0e35de7cdcbaffccbf08bfaf72f17f40ff9ae911 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static foo: [uint; 3] = [1, 2, 3];
+// pretty-expanded FIXME #23616
 
-static slice_1: &'static [uint] = &foo;
-static slice_2: &'static [uint] = &foo;
+static foo: [usize; 3] = [1, 2, 3];
+
+static slice_1: &'static [usize] = &foo;
+static slice_2: &'static [usize] = &foo;
 
 fn main() {}
index 3025741694f43b4068850047628e81c0d902257f..5c84c30aa7fa3631a7fc277f4697f3cb8def9f1e 100644 (file)
@@ -8,17 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc)]
+
 use std::thread::Builder;
 use std::thunk::Thunk;
 
-static generations: uint = 1024+256+128+49;
+static generations: usize = 1024+256+128+49;
 
 fn spawn(f: Thunk<'static>) {
-    Builder::new().stack_size(32 * 1024).spawn(move|| f.invoke(()));
+    Builder::new().stack_size(32 * 1024).spawn(move|| f());
 }
 
-fn child_no(x: uint) -> Thunk<'static> {
-    Thunk::new(move|| {
+fn child_no(x: usize) -> Thunk<'static> {
+    Box::new(move|| {
         if x < generations {
             spawn(child_no(x+1));
         }
index 55b61dd1945566f88f5740d7de4503aaad6c3439..6a5d76de8d3f89dc0d9dc9082ceece061b039075 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait A<X> {
     fn dummy(&self, arg: X);
 }
index c06a29c09f78eeda9eb6e5354c243976f48a03f3..e02ce5441a7d42f6533ad9c3fb38697d1cc3274b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait DigitCollection: Sized {
     type Iter: Iterator<Item = u8>;
     fn digit_iter(self) -> Self::Iter;
@@ -28,6 +30,6 @@ impl<I> DigitCollection for I where I: Iterator<Item=u8> {
 }
 
 fn main() {
-    let xs = vec![1u8, 2, 3, 4, 5];
+    let xs = vec![1, 2, 3, 4, 5];
     assert_eq!(xs.into_iter().digit_sum(), 15);
 }
index a319ee5e600cc5046bafbcb2252279a32377f810..38895e1414ceef04d59f0d65de1082879cc0d715 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,18 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 extern crate libc;
 
 use std::mem;
 use libc::{c_double, c_int};
 
-fn to_c_int(v: &mut int) -> &mut c_int {
+fn to_c_int(v: &mut isize) -> &mut c_int {
     unsafe {
         mem::transmute_copy(&v)
     }
 }
 
-fn lgamma(n: c_double, value: &mut int) -> c_double {
+fn lgamma(n: c_double, value: &mut isize) -> c_double {
     unsafe {
         return m::lgamma(n, to_c_int(value));
     }
@@ -41,7 +44,7 @@ mod m {
 }
 
 pub fn main() {
-  let mut y: int = 5;
-  let x: &mut int = &mut y;
+  let mut y: isize = 5;
+  let x: &mut isize = &mut y;
   assert_eq!(lgamma(1.0 as c_double, x), 0.0 as c_double);
 }
diff --git a/src/test/run-pass/issue-22356.rs b/src/test/run-pass/issue-22356.rs
new file mode 100644 (file)
index 0000000..a544903
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+use std::marker::{PhantomData, PhantomFn};
+
+pub struct Handle<T, I>(T, I);
+
+impl<T, I> Handle<T, I> {
+    pub fn get_info(&self) -> &I {
+        let Handle(_, ref info) = *self;
+        info
+    }
+}
+
+pub struct BufferHandle<D: Device, T> {
+    raw: RawBufferHandle<D>,
+    _marker: PhantomData<T>,
+}
+
+impl<D: Device, T> BufferHandle<D, T> {
+    pub fn get_info(&self) -> &String {
+        self.raw.get_info()
+    }
+}
+
+pub type RawBufferHandle<D: Device> = Handle<<D as Device>::Buffer, String>;
+
+pub trait Device: PhantomFn<Self> {
+    type Buffer;
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-22426.rs b/src/test/run-pass/issue-22426.rs
new file mode 100644 (file)
index 0000000..ad6ade4
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+fn main() {
+  match 42 {
+    x if x < 7 => (),
+    _ => ()
+  }
+}
diff --git a/src/test/run-pass/issue-22536-copy-mustnt-zero.rs b/src/test/run-pass/issue-22536-copy-mustnt-zero.rs
new file mode 100644 (file)
index 0000000..8a0f04a
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright 2015 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.
+
+// Regression test for Issue #22536: If a type implements Copy, then
+// moving it must not zero the original memory.
+
+// pretty-expanded FIXME #23616
+
+trait Resources {
+    type Buffer: Copy;
+    fn foo(&self) {}
+}
+
+struct BufferHandle<R: Resources> {
+    raw: <R as Resources>::Buffer,
+}
+impl<R: Resources> Copy for BufferHandle<R> {}
+impl<R: Resources> Clone for BufferHandle<R> {
+    fn clone(&self) -> BufferHandle<R> { *self }
+}
+
+enum Res {}
+impl Resources for Res {
+    type Buffer = u32;
+}
+
+fn main() {
+    let b: BufferHandle<Res> = BufferHandle { raw: 1 };
+    let c = b;
+    assert_eq!(c.raw, b.raw)
+}
diff --git a/src/test/run-pass/issue-22577.rs b/src/test/run-pass/issue-22577.rs
new file mode 100644 (file)
index 0000000..2c4141b
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+#![feature(fs, net, fs_walk)]
+
+use std::{fs, net};
+
+fn assert_both<T: Send + Sync>() {}
+fn assert_send<T: Send>() {}
+
+fn main() {
+    assert_both::<fs::File>();
+    assert_both::<fs::Metadata>();
+    assert_both::<fs::ReadDir>();
+    assert_both::<fs::DirEntry>();
+    assert_send::<fs::WalkDir>();
+    assert_both::<fs::OpenOptions>();
+    assert_both::<fs::Permissions>();
+
+    assert_both::<net::TcpStream>();
+    assert_both::<net::TcpListener>();
+    assert_both::<net::UdpSocket>();
+    assert_both::<net::SocketAddr>();
+    assert_both::<net::SocketAddrV4>();
+    assert_both::<net::SocketAddrV6>();
+    assert_both::<net::Ipv4Addr>();
+    assert_both::<net::Ipv6Addr>();
+}
diff --git a/src/test/run-pass/issue-22629.rs b/src/test/run-pass/issue-22629.rs
new file mode 100644 (file)
index 0000000..07ca792
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2015 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 transitive analysis for associated types. Collected types
+// should be normalized and new obligations generated.
+
+// pretty-expanded FIXME #23616
+
+use std::borrow::{ToOwned, Cow};
+
+fn assert_send<T: Send>(_: T) {}
+
+fn main() {
+    assert_send(Cow::Borrowed("foo"));
+}
diff --git a/src/test/run-pass/issue-22777.rs b/src/test/run-pass/issue-22777.rs
new file mode 100644 (file)
index 0000000..2dc4d77
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright 2015 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.
+
+// This test is reduced from libsyntax.  It is just checking that we
+// can successfully deal with a "deep" structure, which the drop-check
+// was hitting a recursion limit on at one point.
+
+// pretty-expanded FIXME #23616
+
+#![allow(non_camel_case_types)]
+
+pub fn noop_fold_impl_item() -> SmallVector<ImplItem> {
+    loop  { }
+}
+
+pub struct SmallVector<T>(P<T>);
+pub struct ImplItem(P<S01_Method>);
+
+struct P<T>(Box<T>);
+
+struct S01_Method(P<S02_Generics>);
+struct S02_Generics(P<S03_TyParam>);
+struct S03_TyParam(P<S04_TyParamBound>);
+struct S04_TyParamBound(S05_PolyTraitRef);
+struct S05_PolyTraitRef(S06_TraitRef);
+struct S06_TraitRef(S07_Path);
+struct S07_Path(Vec<S08_PathSegment>);
+struct S08_PathSegment(S09_PathParameters);
+struct S09_PathParameters(P<S10_ParenthesizedParameterData>);
+struct S10_ParenthesizedParameterData(Option<P<S11_Ty>>);
+struct S11_Ty(P<S12_Expr>);
+struct S12_Expr(P<S13_Block>);
+struct S13_Block(Vec<P<S14_Stmt>>);
+struct S14_Stmt(P<S15_Decl>);
+struct S15_Decl(P<S16_Local>);
+struct S16_Local(P<S17_Pat>);
+struct S17_Pat(P<S18_Mac>);
+struct S18_Mac(Vec<P<S19_TokenTree>>);
+struct S19_TokenTree(P<S20_Token>);
+struct S20_Token(P<S21_Nonterminal>);
+struct S21_Nonterminal(P<S22_Item>);
+struct S22_Item(P<S23_EnumDef>);
+struct S23_EnumDef(Vec<P<S24_Variant>>);
+struct S24_Variant(P<S25_VariantKind>);
+struct S25_VariantKind(P<S26_StructDef>);
+struct S26_StructDef(Vec<P<S27_StructField>>);
+struct S27_StructField(P<S28_StructFieldKind>);
+struct S28_StructFieldKind;
+
+pub fn main() {}
diff --git a/src/test/run-pass/issue-22828.rs b/src/test/run-pass/issue-22828.rs
new file mode 100644 (file)
index 0000000..d6a4d78
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2015 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 transitive analysis for associated types. Collected types
+// should be normalized and new obligations generated.
+
+// pretty-expanded FIXME #23616
+
+trait Foo {
+    type A;
+    fn foo(&self) {}
+}
+
+impl Foo for usize {
+    type A = usize;
+}
+
+struct Bar<T: Foo> { inner: T::A }
+
+fn is_send<T: Send>() {}
+
+fn main() {
+    is_send::<Bar<usize>>();
+}
index b8c9ada8b1e23abe8573819a5c6c15fe26ba8ec7..d606c52607ab013c0ef5965edeb2391dbbce553f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Send {
     fn f(&self);
 }
index 18bb6fe55299d0a0c362b11ab04de38e554e24b6..d16655a68554a2b654999f19ddda31c7e3efc848 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -15,7 +17,7 @@ trait clam<A> {
   fn chowder(&self, y: A);
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct foo<A> {
   x: A,
 }
@@ -38,6 +40,6 @@ fn f<A>(x: Box<clam<A>>, a: A) {
 pub fn main() {
 
   let c = foo(42);
-  let d: Box<clam<int>> = box c as Box<clam<int>>;
+  let d: Box<clam<isize>> = box c as Box<clam<isize>>;
   f(d, c.x);
 }
diff --git a/src/test/run-pass/issue-23037.rs b/src/test/run-pass/issue-23037.rs
new file mode 100644 (file)
index 0000000..5257daa
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 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(core)]
+
+use std::simd::i32x4;
+fn main() {
+    let foo = i32x4(1,2,3,4);
+    let bar = i32x4(40,30,20,10);
+    let baz = foo + bar;
+    assert!(baz.0 == 41 && baz.1 == 32 && baz.2 == 23 && baz.3 == 14);
+}
index 5529d51b408c0782dde9c985ee71c364f211a5f3..c76bbaf968a6539c6637b115407e0f0fe3626ac9 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait clam<A> {
     fn get(self) -> A;
 }
index b6b3114e2a487c3a07963eb8a6a1e39bfb2b1219..5a086fd6fc2dc6fe9e9b9318873996a73bee725b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait clam<A> { fn get(self) -> A; }
 trait foo<A> {
    fn bar<B,C:clam<A>>(&self, c: C) -> B;
index 3f273b56efd6cc4ab90cfec83fa4f28d3979e2d1..fa056191e671e81ea6ca16274ba1a140c5596728 100644 (file)
 
 // Testing that the B's are resolved
 
+// pretty-expanded FIXME #23616
+
 trait clam<A> { fn get(self) -> A; }
 
-struct foo(int);
+struct foo(isize);
 
 impl foo {
     pub fn bar<B,C:clam<B>>(&self, _c: C) -> B { panic!(); }
index a6fac423bb6772f1ea86a1de55e6447df7453db1..158e4570f2c702b11289efd8ec0db0ba7bdf2bc1 100644 (file)
@@ -11,6 +11,8 @@
 // aux-build:issue_2316_a.rs
 // aux-build:issue_2316_b.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate issue_2316_b;
 use issue_2316_b::cloth;
 
diff --git a/src/test/run-pass/issue-23435.rs b/src/test/run-pass/issue-23435.rs
new file mode 100644 (file)
index 0000000..9b72782
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2015 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 we do not ICE when a default method implementation has
+// requirements (in this case, `Self : Baz`) that do not hold for some
+// specific impl (in this case, `Foo : Bar`). This causes problems
+// only when building a vtable, because that goes along and
+// instantiates all the methods, even those that could not otherwise
+// be called.
+
+// pretty-expanded FIXME #23616
+
+struct Foo {
+    x: i32
+}
+
+trait Bar {
+    fn bar(&self) where Self : Baz { self.baz(); }
+}
+
+trait Baz {
+    fn baz(&self);
+}
+
+impl Bar for Foo {
+}
+
+fn main() {
+    let x: &Bar = &Foo { x: 22 };
+}
diff --git a/src/test/run-pass/issue-23485.rs b/src/test/run-pass/issue-23485.rs
new file mode 100644 (file)
index 0000000..f176c60
--- /dev/null
@@ -0,0 +1,58 @@
+// 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 for an ICE that occurred when a default method implementation
+// was applied to a type that did not meet the prerequisites. The
+// problem occurred specifically because normalizing
+// `Self::Item::Target` was impossible in this case.
+
+use std::boxed::Box;
+use std::marker::Sized;
+use std::clone::Clone;
+use std::ops::Deref;
+use std::option::Option;
+use std::option::Option::{Some,None};
+
+trait Iterator {
+    type Item;
+
+    fn next(&mut self) -> Option<Self::Item>;
+
+    fn clone_first(mut self) -> Option<<Self::Item as Deref>::Target> where
+        Self: Sized,
+        Self::Item: Deref,
+        <Self::Item as Deref>::Target: Clone,
+    {
+        self.next().map(|x| x.clone())
+    }
+}
+
+struct Counter {
+    value: i32
+}
+
+struct Token {
+    value: i32
+}
+
+impl Iterator for Counter {
+    type Item = Token;
+
+    fn next(&mut self) -> Option<Token> {
+        let x = self.value;
+        self.value += 1;
+        Some(Token { value: x })
+    }
+}
+
+fn main() {
+    let mut x: Box<Iterator<Item=Token>> = Box::new(Counter { value: 22 });
+    assert_eq!(x.next().unwrap().value, 22);
+}
diff --git a/src/test/run-pass/issue-23550.rs b/src/test/run-pass/issue-23550.rs
new file mode 100644 (file)
index 0000000..9b5ca23
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2015 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(core)]
+#![allow(warnings)]
+
+use std::intrinsics;
+
+#[derive(Copy, Clone)]
+struct Wrap(i64);
+
+// These volatile and atomic intrinsics used to cause an ICE
+
+unsafe fn test_bool(p: &mut bool, v: bool) {
+    intrinsics::volatile_load(p);
+    intrinsics::volatile_store(p, v);
+    intrinsics::atomic_load(p);
+    intrinsics::atomic_cxchg(p, v, v);
+    intrinsics::atomic_store(p, v);
+    intrinsics::atomic_xchg(p, v);
+}
+
+unsafe fn test_immediate_fca(p: &mut Wrap, v: Wrap) {
+    intrinsics::volatile_load(p);
+    intrinsics::volatile_store(p, v);
+    intrinsics::atomic_load(p);
+    intrinsics::atomic_cxchg(p, v, v);
+    intrinsics::atomic_store(p, v);
+    intrinsics::atomic_xchg(p, v);
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-23781.rs b/src/test/run-pass/issue-23781.rs
new file mode 100644 (file)
index 0000000..23ac8d2
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright 2015 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 std::fmt;
+
+struct Foo;
+impl fmt::Debug for Foo {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        println!("<Foo as Debug>::fmt()");
+
+        write!(fmt, "")
+    }
+}
+
+fn test1() {
+    let foo_str = format!("{:?}", Foo);
+
+    println!("{}", foo_str);
+}
+
+fn test2() {
+    println!("{:?}", Foo);
+}
+
+fn main() {
+    // This works fine
+    test1();
+
+    // This fails
+    test2();
+}
index 22976aac6e774ae3e5a93412c0ba96fcfdec6e10..b7041624247131d34e26f9ea779479f93d1cd89d 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:issue-2380.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate a;
 
 pub fn main() {
index a5a05283f80fde1f97420b3d90fe724bb63f414d..9c400aac1dcf1d36402e680d74c487c4caee5aa6 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections)]
+
 extern crate collections;
 use std::collections::VecDeque;
 
index 0b891fbddccf14a7b04d312491dbf36de5b22cac..2e047ae0127c7396a687487f6ca2578918ed897f 100644 (file)
@@ -11,6 +11,8 @@
 // aux-build:issue-2414-a.rs
 // aux-build:issue-2414-b.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate b;
 
 pub fn main() {}
index 7ed26428be04e46898aadde8037572f612c2cb6d..402eb0349ab232e933cb2a5bd0a953790546564d 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let _foo = 100;
-    const quux: int = 5;
+    const quux: isize = 5;
 
     enum Stuff {
         Bar = quux
     }
 
-    assert_eq!(Stuff::Bar as int, quux);
+    assert_eq!(Stuff::Bar as isize, quux);
 }
index 91f76fc5ae0610298b65e9b7b23241ee31e0c4d0..c1d17d263d6d68691f547ed15ed6bcfcfff96af9 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct c1<T> {
     x: T,
 }
 
 impl<T> c1<T> {
-    pub fn f1(&self, _x: int) {
+    pub fn f1(&self, _x: isize) {
     }
 }
 
@@ -24,12 +26,12 @@ fn c1<T>(x: T) -> c1<T> {
 }
 
 impl<T> c1<T> {
-    pub fn f2(&self, _x: int) {
+    pub fn f2(&self, _x: isize) {
     }
 }
 
 
 pub fn main() {
-    c1::<int>(3).f1(4);
-    c1::<int>(3).f2(4);
+    c1::<isize>(3).f1(4);
+    c1::<isize>(3).f2(4);
 }
index 6356c87bfc9610d8a25695ab6517279d191302dd..0b6cf5890fd3ea002786f1532e8478b7422a1937 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct c1<T> {
     x: T,
 }
@@ -28,6 +30,6 @@ impl<T> c1<T> {
 
 
 pub fn main() {
-    c1::<int>(3).f1(4);
-    c1::<int>(3).f2(4);
+    c1::<isize>(3).f1(4);
+    c1::<isize>(3).f2(4);
 }
index 051ebd1ec045fbd7c526be391be553db1695a5d8..f0b0614535bdf531ba3fd15743ce21c2c559e229 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Pair { f: int, g: int }
+// pretty-expanded FIXME #23616
+
+struct Pair { f: isize, g: isize }
 
 pub fn main() {
 
index 53b0042405b0bb7c6175cc9fe624479a4cfee860..0cbdbda63756a4aa2db99411e610aa97597bad24 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:issue_2472_b.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate issue_2472_b;
 
 use issue_2472_b::{S, T};
index aa61d52b2a32d4b1648d3eca2c897ffaac72962a..76450b351f4570a37000b4abc0616ab280d1ba1e 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct socket {
-    sock: int,
+    sock: isize,
 
 }
 
@@ -31,6 +33,6 @@ fn socket() -> socket {
 
 fn closure<F>(f: F) where F: FnOnce() { f() }
 
-fn setsockopt_bytes(_sock: int) { }
+fn setsockopt_bytes(_sock: isize) { }
 
 pub fn main() {}
index a62e329f106f542914543a8062475755ead843d7..63179cd14acda5deac6f904d71ad949ed0f53927 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 struct font<'a> {
     fontbuf: &'a Vec<u8> ,
 }
index 18c59dc9adc8e828b05dd79d570aa3a57042b0b8..0c68c47023194fab2067ac2021fd1d1fc9eb182c 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:issue-2526.rs
 
+// pretty-expanded FIXME #23616
+
 #![allow(unused_imports)]
 
 extern crate issue_2526;
index 395b2c4b459eba638256e89466b0290f8e2661b2..87b0b198f9b67c7acc17c310719d09f9a5bacb2a 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct C {
-    x: uint,
+    x: usize,
 }
 
-fn C(x: uint) -> C {
+fn C(x: usize) -> C {
     C {
         x: x
     }
@@ -22,5 +24,5 @@ fn f<T>(_x: T) {
 }
 
 pub fn main() {
-    f(C(1_usize));
+    f(C(1));
 }
index c005699ce30b4f19911944ed5d64f60730a917f5..8cf80333e97222fcafce4495777e86a0e20ec0de 100644 (file)
 // Tests that impls are allowed to have looser, more permissive bounds
 // than the traits require.
 
+// pretty-expanded FIXME #23616
+
 trait A {
   fn b<C:Sync,D>(&self, x: C) -> C;
 }
 
 struct E {
- f: int
+ f: isize
 }
 
 impl A for E {
index 84f046499e439ca1f96c64e15c626a0a401760a2..7413ebd35046059abfa82a2b0199b272daa1dbef 100644 (file)
@@ -11,6 +11,8 @@
 
 // aux-build:issue-2631-a.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate req;
 
 use req::request;
@@ -22,5 +24,5 @@ pub fn main() {
   let v = vec!(Rc::new("hi".to_string()));
   let mut m: req::header_map = HashMap::new();
   m.insert("METHOD".to_string(), Rc::new(RefCell::new(v)));
-  request::<int>(&m);
+  request::<isize>(&m);
 }
index 80e9ca470251775107a4ab4c03961df14ae64c86..7b5a055d33435de68f6a0745a99c96cb2fe5ea69 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 
-fn a_val(x: Box<int>, y: Box<int>) -> int {
+fn a_val(x: Box<isize>, y: Box<isize>) -> isize {
     *x + *y
 }
 
 pub fn main() {
-    let z = box 22;
+    let z: Box<_> = box 22;
     a_val(z.clone(), z.clone());
 }
index de99141c80311381a47ca48841732d40c6e26142..5841a9ec176cdc6c13690250852145acdd7a2a86 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct cat {
     meow: extern "Rust" fn(),
 }
@@ -23,7 +23,7 @@ fn cat() -> cat {
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct KittyInfo {kitty: cat}
 
 // Code compiles and runs successfully if we add a + before the first arg
index dc6015545421cc61539ee61c28445983a2ee37b2..f0bc31fb391c082d89ec74c9e8f7012987e8f160 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn f() {
-   let _x: uint = loop { loop { break; } };
+   let _x: usize = loop { loop { break; } };
 }
 
 pub fn main() {
index 1f072af0f5a64c44c7739f47e7c414bc40490b4c..d3916db3f755b6bdf75b2606ddf5429cbb1f842d 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 struct Font {
-    fontbuf: uint,
-    cairo_font: uint,
-    font_dtor: uint,
+    fontbuf: usize,
+    cairo_font: usize,
+    font_dtor: usize,
 
 }
 
@@ -31,5 +33,5 @@ fn Font() -> Font {
 }
 
 pub fn main() {
-    let _f = box Font();
+    let _f: Box<_> = box Font();
 }
index b8a541a0fc4de70876fe5240ec7efebbbc8e6192..71d1439dd2bc8f3f14d197137c50853a27e506fe 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
 //
 // ignore-lexer-test FIXME #15883
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-#![feature(unsafe_destructor)]
+#![feature(unsafe_destructor, std_misc)]
 
-pub type Task = int;
+pub type Task = isize;
 
 // tjc: I don't know why
 pub mod pipes {
@@ -24,7 +21,7 @@ pub mod pipes {
     use std::mem::{forget, transmute};
     use std::mem::{replace, swap};
     use std::mem;
-    use std::thread::Thread;
+    use std::thread;
     use std::marker::Send;
 
     pub struct Stuff<T> {
@@ -34,7 +31,7 @@ pub mod pipes {
     }
 
     #[derive(PartialEq, Debug)]
-    #[repr(int)]
+    #[repr(isize)]
     pub enum state {
         empty,
         full,
@@ -52,19 +49,19 @@ pub mod pipes {
 
     pub fn packet<T:Send>() -> *const packet<T> {
         unsafe {
-            let p: *const packet<T> = mem::transmute(box Stuff{
+            let p: *const packet<T> = mem::transmute(Box::new(Stuff{
                 state: empty,
                 blocked_task: None::<Task>,
                 payload: None::<T>
-            });
+            }));
             p
         }
     }
 
     mod rusti {
-      pub fn atomic_xchg(_dst: &mut int, _src: int) -> int { panic!(); }
-      pub fn atomic_xchg_acq(_dst: &mut int, _src: int) -> int { panic!(); }
-      pub fn atomic_xchg_rel(_dst: &mut int, _src: int) -> int { panic!(); }
+      pub fn atomic_xchg(_dst: &mut isize, _src: isize) -> isize { panic!(); }
+      pub fn atomic_xchg_acq(_dst: &mut isize, _src: isize) -> isize { panic!(); }
+      pub fn atomic_xchg_rel(_dst: &mut isize, _src: isize) -> isize { panic!(); }
     }
 
     // We should consider moving this to ::std::unsafe, although I
@@ -75,13 +72,13 @@ pub mod pipes {
 
     pub fn swap_state_acq(dst: &mut state, src: state) -> state {
         unsafe {
-            transmute(rusti::atomic_xchg_acq(transmute(dst), src as int))
+            transmute(rusti::atomic_xchg_acq(transmute(dst), src as isize))
         }
     }
 
     pub fn swap_state_rel(dst: &mut state, src: state) -> state {
         unsafe {
-            transmute(rusti::atomic_xchg_rel(transmute(dst), src as int))
+            transmute(rusti::atomic_xchg_rel(transmute(dst), src as isize))
         }
     }
 
@@ -118,7 +115,7 @@ pub mod pipes {
             let old_state = swap_state_acq(&mut (*p).state,
                                            blocked);
             match old_state {
-              empty | blocked => { Thread::yield_now(); }
+              empty | blocked => { thread::yield_now(); }
               full => {
                 let payload = replace(&mut p.payload, None);
                 return Some(payload.unwrap())
@@ -165,7 +162,7 @@ pub mod pipes {
         }
     }
 
-    pub struct send_packet<T> {
+    pub struct send_packet<T:Send> {
         p: Option<*const packet<T>>,
     }
 
@@ -195,7 +192,7 @@ pub mod pipes {
         }
     }
 
-    pub struct recv_packet<T> {
+    pub struct recv_packet<T:Send> {
         p: Option<*const packet<T>>,
     }
 
index bab7b0d24db70f2af04493989d13c80425d29f81..7fee2fc16cbed96edbce3668dfccc6459231eec1 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:issue_2723_a.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate issue_2723_a;
 use issue_2723_a::f;
 
index a7b53db6b0553f173988fa4b63e33ada1eac2fca..18cd9a87e6b05418fbf0ce1bc0427067e360c7b6 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
index 0d1cf1c339227689787ff76a3712ea3719973ff3..1506b2d6bf089440705d3b8124691dbefcbf23f4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 
 use std::cell::Cell;
index 658183cf6ff5437b64fc1c74f1d58b55aa033b02..2282334d66d106b991d7ed6911f9377088c57063 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 
 use std::cell::Cell;
index 1594b94879cee099cdb31a22a7eb6bc9f1c2921d..cd6c6a59e2a6c2d30ff530820cf4404c6449442f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
index 23e26ca5665c5a5a3e658baa1f153c85a1198915..ac1e65ee77634de9a641b482eee0e613da90c456 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct CMap<'a> {
     buf: &'a [u8],
 }
index 3ca8d49eb864d2f53a5429c5d877d6c50bf70a7a..8f30d262f41f5a6e6a7e11ed4e8e583811c9257b 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn thing<'r>(x: &'r [int]) -> &'r [int] { x }
+// pretty-expanded FIXME #23616
+
+fn thing<'r>(x: &'r [isize]) -> &'r [isize] { x }
 
 pub fn main() {
     let x = &[1,2,3];
index 952ea1e9d3de7c57be62cc14caf535872f98d21d..6afb31619d1caf87077ffa5164457e1a006b1281 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
 // Minimized version of issue-2804.rs. Both check that callee IDs don't
 // clobber the previous node ID in a macro expr
 
+#![feature(collections)]
+
 extern crate collections;
 
 use std::collections::HashMap;
 
-fn add_interfaces(managed_ip: String, device: HashMap<String, int>)  {
-     println!("{}, {}", managed_ip, device["interfaces".to_string()]);
+fn add_interfaces(managed_ip: String, device: HashMap<String, isize>)  {
+     println!("{}, {}", managed_ip, device["interfaces"]);
 }
 
 pub fn main() {}
index 25b933b8f96fe01041012509adcb5402abdfd21b..a2b4e218a079b74f5d4de69e0be0129d4a073548 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(collections)]
+#![feature(rustc_private)]
+
 extern crate collections;
 extern crate serialize;
 
@@ -37,7 +39,7 @@ fn lookup(table: json::Object, key: String, default: String) -> String
     }
 }
 
-fn add_interface(_store: int, managed_ip: String, data: json::Json) -> (String, object)
+fn add_interface(_store: isize, managed_ip: String, data: json::Json) -> (String, object)
 {
     match &data {
         &Json::Object(ref interface) => {
@@ -55,10 +57,9 @@ fn add_interface(_store: int, managed_ip: String, data: json::Json) -> (String,
     }
 }
 
-fn add_interfaces(store: int, managed_ip: String, device: HashMap<String, json::Json>)
+fn add_interfaces(store: isize, managed_ip: String, device: HashMap<String, json::Json>)
 -> Vec<(String, object)> {
-    match device["interfaces".to_string()]
-    {
+    match device["interfaces"] {
         Json::Array(ref interfaces) =>
         {
           interfaces.iter().map(|interface| {
@@ -68,7 +69,7 @@ fn add_interfaces(store: int, managed_ip: String, device: HashMap<String, json::
         _ =>
         {
             println!("Expected list for {} interfaces, found {}", managed_ip,
-                   device["interfaces".to_string()]);
+                     device["interfaces"]);
             Vec::new()
         }
     }
index 5f7a4d87b9ae27ff984d235395cfc82058081242..3f4c630cc2b0a3e47899c142ce3237eabc2cb51a 100644 (file)
@@ -8,14 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
 struct Cat {
-    x: int
+    x: isize
 }
 
 struct Kitty {
-    x: int,
+    x: isize,
 }
 
 impl Drop for Kitty {
@@ -24,12 +26,12 @@ impl Drop for Kitty {
 
 #[cfg(any(target_arch = "x86_64", target_arch="aarch64"))]
 pub fn main() {
-    assert_eq!(mem::size_of::<Cat>(), 8 as uint);
-    assert_eq!(mem::size_of::<Kitty>(), 16 as uint);
+    assert_eq!(mem::size_of::<Cat>(), 8 as usize);
+    assert_eq!(mem::size_of::<Kitty>(), 16 as usize);
 }
 
 #[cfg(any(target_arch = "x86", target_arch = "arm"))]
 pub fn main() {
-    assert_eq!(mem::size_of::<Cat>(), 4 as uint);
-    assert_eq!(mem::size_of::<Kitty>(), 8 as uint);
+    assert_eq!(mem::size_of::<Cat>(), 4 as usize);
+    assert_eq!(mem::size_of::<Kitty>(), 8 as usize);
 }
index b55f369135868aa5db8c5180330aee011fb034e4..b05baa24b7aa11c6cd1429b9f37564127a1f5cff 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -10,7 +9,9 @@
 // except according to those terms.
 
 
-/// Map representation
+// Map representation
+
+#![feature(old_io)]
 
 use std::old_io;
 use std::fmt;
index 31599d0caadeeee981557c3a874df23db7a1db0f..fd8e1e6b036baa8123567679e216a977b352af55 100644 (file)
@@ -11,7 +11,7 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-//type t = { a: int };
+//type t = { a: isize };
 // type t = { a: bool };
 type t = bool;
 
@@ -28,7 +28,7 @@ pub fn main() {
   //   let y = box ({a: 4});
   //    let z = box ({a: 4} as it);
   //    let z = box ({a: true} as it);
-    let z = box() (box true as Box<it>);
+    let z: Box<_> = box () (box true as Box<it>);
     //  x.f();
     // y.f();
     // (*z).f();
index 183eb6e079f059a9af9a73fc0ca4e8db81771526..5c63230f5d0ca63b9bccb0f7935b5fe375f436f2 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait bar<T> {
     fn get_bar(&self) -> T;
 }
@@ -17,22 +19,22 @@ fn foo<T, U: bar<T>>(b: U) -> T {
 }
 
 struct cbar {
-    x: int,
+    x: isize,
 }
 
-impl bar<int> for cbar {
-    fn get_bar(&self) -> int {
+impl bar<isize> for cbar {
+    fn get_bar(&self) -> isize {
         self.x
     }
 }
 
-fn cbar(x: int) -> cbar {
+fn cbar(x: isize) -> cbar {
     cbar {
         x: x
     }
 }
 
 pub fn main() {
-    let x: int = foo::<int, cbar>(cbar(5));
+    let x: isize = foo::<isize, cbar>(cbar(5));
     assert_eq!(x, 5);
 }
index 8767d397b647a19149e766c8d54fca765bf5bac2..8b6eb12f102ee24c5b7c7cc220e55ffcf926cdef 100644 (file)
@@ -21,11 +21,11 @@ impl methods for () {
 // the position of this function is significant! - if it comes before methods
 // then it works, if it comes after it then it doesn't!
 fn to_bools(bitv: Storage) -> Vec<bool> {
-    (0_usize..8).map(|i| {
+    (0..8).map(|i| {
         let w = i / 64;
         let b = i % 64;
-        let x = 1u64 & (bitv.storage[w] >> b);
-        x == 1u64
+        let x = 1 & (bitv.storage[w] >> b);
+        x == 1
     }).collect()
 }
 
@@ -35,7 +35,7 @@ pub fn main() {
     let bools = vec!(false, false, true, false, false, true, true, false);
     let bools2 = to_bools(Storage{storage: vec!(0b01100100)});
 
-    for i in 0_usize..8 {
+    for i in 0..8 {
         println!("{} => {} vs {}", i, bools[i], bools2[i]);
     }
 
index de2d4374d787fdf15915dbcf5b082fdb862fd69e..ecce5df0fc200359877a986b716df9c4edaade46 100644 (file)
 
 // aux-build:issue-3012-1.rs
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, libc)]
 
 extern crate socketlib;
 extern crate libc;
@@ -20,5 +22,5 @@ use socketlib::socket;
 
 pub fn main() {
     let fd: libc::c_int = 1 as libc::c_int;
-    let _sock = box socket::socket_handle(fd);
+    let _sock: Box<_> = box socket::socket_handle(fd);
 }
index 25663f2605fcb4233cc47bc27743d738068f188b..d8499992f94d180d732dd21e8ef37b7f34c8ce35 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, collections)]
 
 extern crate collections;
 
 use std::collections::HashMap;
 
 pub fn main() {
-    let x;
-    let mut buggy_map: HashMap<uint, &uint> = HashMap::new();
+    let x: Box<_>;
+    let mut buggy_map: HashMap<usize, &usize> = HashMap::new();
     x = box 1;
     buggy_map.insert(42, &*x);
 }
index 1555098f2911be5d5df7100abba6f28eb8ce0fbb..83a522a69e3d12df77f97e43f32288a1cfaf577f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum what { }
 
 fn what_to_string(x: what) -> String
index 3e7deee6ec10720b4690df4336df72e1beae4bca..8f013ee4f3a0fb9039ea195fb4e87ab3a718b876 100644 (file)
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 type Connection = Box<FnMut(Vec<u8>) + 'static>;
 
 fn f() -> Option<Connection> {
-    let mock_connection: Connection = box |_| {};
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let mock_connection: Connection = Box::new(|_| {});
     Some(mock_connection)
 }
 
index c4c2c2b7da8785a92d951e6e73a696150b504b0b..8e59e46fc3c4c1a4587249d5d7eca3b0c27809ff 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = 1;
     let y = 1;
index b6ed85e9e4a49b5e42ee049c3d4e3096033dba73..777e5bf7a6dedfe37f1cbd02b7ddad32eb11a3dc 100644 (file)
@@ -8,14 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum side { mayo, catsup, vinegar }
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum order { hamburger, fries(side), shake }
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum meal { to_go(order), for_here(order) }
 
 fn foo(m: Box<meal>, cond: bool) {
index ab64fb4fbfa1f22cb03d8d580a40b5353c636a56..fa33bd8fce80bdc3ce68810aa0dcb1ef3c7a7163 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn Matrix4<T>(m11: T, m12: T, m13: T, m14: T,
               m21: T, m22: T, m23: T, m24: T,
               m31: T, m32: T, m33: T, m34: T,
index 9c44a7cfcc3073f50044d038aa353ab6d937fa7c..0a37a013037775b38942cccc6e7ec663d5527a43 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct thing { x: int, }
+// pretty-expanded FIXME #23616
+
+struct thing { x: isize, }
 
 impl Drop for thing {
     fn drop(&mut self) {}
index c8d6e69801fa13094a05b57347bcf9ab35c8bd9a..3fa5b72c348f35f946c41f91e86f02ccb842f23f 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-   let mut x = box 3;
+   let mut x: Box<_> = box 3;
    x = x;
    assert_eq!(*x, 3);
 }
index 1217f32826f6d3be179ba888f22374baeba3443a..b611f11a0a1247db2386cd43f8c15a842df0cfb5 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn quux<T>(x: T) -> T { let f = id::<T>; return f(x); }
 
 fn id<T>(x: T) -> T { return x; }
index 0d85f61e51350d7dbc3715882505ab855f3f3d6e..29d963bb704688c3c1171b38f3e9b07a7e617760 100644 (file)
 // rustc --test ignores2.rs && ./ignores2
 
 #![allow(unknown_features)]
-#![feature(box_syntax)]
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, old_path, std_misc)]
 
-use std::old_path::{Path};
+use std::old_path::Path;
 use std::old_path;
 use std::result;
 use std::thunk::Thunk;
@@ -23,9 +22,10 @@ type rsrc_loader = Box<FnMut(&Path) -> (result::Result<String, String>) + 'stati
 
 fn tester()
 {
-    let mut loader: rsrc_loader = box move|_path| {
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let mut loader: rsrc_loader = Box::new(move|_path| {
         result::Result::Ok("more blah".to_string())
-    };
+    });
 
     let path = old_path::Path::new("blah");
     assert!(loader(&path).is_ok());
index e331a1a2d0c1dfd75c0b1ac7fedda7b79612b36f..325a3ec715124ea3c3b35e803a884f2f19c66e80 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
   let x = 1_usize;
   let y = || x;
index 99def5476f9a0bc563c83160df9e309334a7299f..f1d9f888b081612c6ac5410d2d9035358fc53843 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = &Some(1);
     match x {
index 754412ea949381c7059b1a6d6472d9f7a76d2489..c2ea24ac6ba9996db809fe90bd45333d86f6718e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(collections)]
+
 extern crate collections;
 
 use std::collections::HashMap;
@@ -24,6 +26,6 @@ pub fn main() {
     let mut table = HashMap::new();
     table.insert("one".to_string(), 1);
     table.insert("two".to_string(), 2);
-    assert!(check_strs(&format!("{:?}", table), "HashMap {\"one\": 1, \"two\": 2}") ||
-            check_strs(&format!("{:?}", table), "HashMap {\"two\": 2, \"one\": 1}"));
+    assert!(check_strs(&format!("{:?}", table), "{\"one\": 1, \"two\": 2}") ||
+            check_strs(&format!("{:?}", table), "{\"two\": 2, \"one\": 1}"));
 }
index 2cf29296b859165479841616e28705dcbe4db682..65c21317cf247727a0961558416bb7b3a46a78c4 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Canvas {
-    fn add_point(&self, point: &int);
-    fn add_points(&self, shapes: &[int]) {
+    fn add_point(&self, point: &isize);
+    fn add_points(&self, shapes: &[isize]) {
         for pt in shapes {
             self.add_point(pt)
         }
index f4b85e03eaeac031dfb37f2e8de0f9cb7effcdbe..cfdc54a362274e91c926e5b8b740909ecaba2558 100644 (file)
 // that are already linked in. Using WriterUtil allows us to use the write_line
 // method.
 
+#![feature(core)]
+
 use std::fmt;
 use std::iter::repeat;
 use std::slice;
 
 // Represents a position on a canvas.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Point {
-    x: int,
-    y: int,
+    x: isize,
+    y: isize,
 }
 
 // Represents an offset on a canvas. (This has the same structure as a Point.
 // but different semantics).
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Size {
-    width: int,
-    height: int,
+    width: isize,
+    height: isize,
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Rect {
     top_left: Point,
     size: Size,
@@ -49,8 +51,8 @@ struct Rect {
 
 // Contains the information needed to do shape rendering via ASCII art.
 struct AsciiArt {
-    width: uint,
-    height: uint,
+    width: usize,
+    height: usize,
     fill: char,
     lines: Vec<Vec<char> > ,
 
@@ -65,7 +67,7 @@ impl Drop for AsciiArt {
 // It's common to define a constructor sort of function to create struct instances.
 // If there is a canonical constructor it is typically named the same as the type.
 // Other constructor sort of functions are typically named from_foo, from_bar, etc.
-fn AsciiArt(width: uint, height: uint, fill: char) -> AsciiArt {
+fn AsciiArt(width: usize, height: usize, fill: char) -> AsciiArt {
     // Use an anonymous function to build a vector of vectors containing
     // blank characters for each position in our canvas.
     let mut lines = Vec::new();
@@ -80,12 +82,12 @@ fn AsciiArt(width: uint, height: uint, fill: char) -> AsciiArt {
 
 // Methods particular to the AsciiArt struct.
 impl AsciiArt {
-    fn add_pt(&mut self, x: int, y: int) {
-        if x >= 0 && x < self.width as int {
-            if y >= 0 && y < self.height as int {
+    fn add_pt(&mut self, x: isize, y: isize) {
+        if x >= 0 && x < self.width as isize {
+            if y >= 0 && y < self.height as isize {
                 // Note that numeric types don't implicitly convert to each other.
-                let v = y as uint;
-                let h = x as uint;
+                let v = y as usize;
+                let h = x as usize;
 
                 // Vector subscripting will normally copy the element, but &v[i]
                 // will return a reference which is what we need because the
@@ -101,7 +103,7 @@ impl AsciiArt {
 
 // Allows AsciiArt to be converted to a string using the libcore ToString trait.
 // Note that the %s fmt! specifier will not call this automatically.
-impl fmt::String for AsciiArt {
+impl fmt::Display for AsciiArt {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         // Convert each line into a string.
         let lines = self.lines.iter()
index e31f2ade125eb08d284bb47b53152b4244089a90..9a521ba376dc2eb2a2402c11edab0b5d8c4733a0 100644 (file)
@@ -10,6 +10,8 @@
 
 // rustc --test match_borrowed_str.rs.rs && ./match_borrowed_str.rs
 
+// pretty-expanded FIXME #23616
+
 fn compare(x: &str, y: &str) -> bool {
     match x {
         "foo" => y == "foo",
index 4a28c34e5d9f4299683811b7159e100fe59a5823..2167a3df9766ffd471abad9e07e154448ae16308 100644 (file)
@@ -9,11 +9,10 @@
 // except according to those terms.
 
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(std_misc)]
 
-use std::thread::Thread;
+use std::thread;
 use std::sync::mpsc::Sender;
-use std::thunk::Invoke;
 
 type RingBuffer = Vec<f64> ;
 type SamplesFn = Box<FnMut(&RingBuffer) + Send>;
@@ -24,12 +23,12 @@ enum Msg
 }
 
 fn foo(name: String, samples_chan: Sender<Msg>) {
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         let mut samples_chan = samples_chan;
 
-        // `box() (...)` syntax is needed to make pretty printer converge in one try:
-        let callback: SamplesFn = box() (move |buffer| {
-            for i in 0_usize..buffer.len() {
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        let callback: SamplesFn = Box::new(move |buffer| {
+            for i in 0..buffer.len() {
                 println!("{}: {}", i, buffer[i])
             }
         });
index 8a39676ca17ac44a40e7266c1523e41800e53872..10930474799c5fbde163a24b0e941e3864189e00 100644 (file)
 // Incorrect struct size computation in the FFI, because of not taking
 // the alignment of elements into account.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 extern crate libc;
 use libc::{c_uint, uint32_t, c_void};
 
index e6c816666e798247c1c506720060f7969c5dbb3f..096eec803ffa1716aa51facbbb46d11ff6a82904 100644 (file)
 
 
 trait Foo {
-    fn a(&self) -> int;
-    fn b(&self) -> int {
+    fn a(&self) -> isize;
+    fn b(&self) -> isize {
         self.a() + 2
     }
 }
 
-impl Foo for int {
-    fn a(&self) -> int {
+impl Foo for isize {
+    fn a(&self) -> isize {
         3
     }
 }
index 03699ff8d60369d7657c9ecad9b6ea00f0f9086f..cd62c04a32581ea28e9bf35799d938a75df36d11 100644 (file)
 
 // If `Mul` used an associated type for its output, this test would
 // work more smoothly.
-#![feature(old_orphan_check)]
 
 use std::ops::Mul;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Vec2 {
     x: f64,
     y: f64
index 58d7aa276f15a6611ce5e1b4f34c65e60d8a6965..e81025d8464507b1cd5ffc55b89d781062a3ca4f 100644 (file)
 // Issue Name: pub method preceded by attribute can't be parsed
 // Abstract: Visibility parsing failed when compiler parsing
 
+#![feature(core)]
+
 use std::f64;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Point {
     x: f64,
     y: f64
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub enum Shape {
     Circle(Point, f64),
     Rectangle(Point, Point)
index 6ac252c07ef793eb918e0dda836166dce90919b3..3d5f38e38cc56e37e0534ab644a8938e0c7e1b1d 100644 (file)
@@ -17,7 +17,7 @@ trait T {
 
 #[derive(Debug)]
 struct S {
-    s: int,
+    s: isize,
 }
 
 impl T for S {
index 9216c8aa1aef92c9218ac182cd3c43bf8e5e2f62..bd3a726991b915d43b08a1e4f5ed7dc2a467d9a2 100644 (file)
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 mod buildings {
-    pub struct Tower { pub height: uint }
+    pub struct Tower { pub height: usize }
 }
 
 pub fn main() {
     let sears = buildings::Tower { height: 1451 };
-    let h: uint = match sears {
+    let h: usize = match sears {
         buildings::Tower { height: h } => { h }
     };
 
index 9226bebd2dcea424a93b4d919480c729d39bad59..a29a26758654e8dd1ae842ba0b1f1ebae6ad531a 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum PureCounter { PureCounterVariant(uint) }
+// pretty-expanded FIXME #23616
 
-fn each<F>(thing: PureCounter, blk: F) where F: FnOnce(&uint) {
+enum PureCounter { PureCounterVariant(usize) }
+
+fn each<F>(thing: PureCounter, blk: F) where F: FnOnce(&usize) {
     let PureCounter::PureCounterVariant(ref x) = thing;
     blk(x);
 }
index c1d19f228db617511960278bbb2f5dbfb016fe32..c98110b9054bedc5bea0342ff049ecd0d0a68647 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(path_statement)]
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let y = box 1;
+    let y: Box<_> = box 1;
     y;
 }
index bf3d0b786af65c48b53ce212626d61732bc305b7..24c1a5d05c89f1e4f05cf5f220b15d01ff65137e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn vec_peek<'r, T>(v: &'r [T]) -> &'r [T] {
     &v[1..5]
 }
index b2254001320c4c90916b883f489c426ca41dd644..ca6d9faf88f4a32b264cb6bad3c9674c7bf08b8b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     enum State { BadChar, BadSyntax }
 
index f534f744a20305f7aced7081dadf122daa14c4aa..1e200e01628a501e48d3bfef96ef5ad0559dd1ec 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(PartialEq)]
 struct Bike {
     name: String,
index 39e9f5dcd2d8d466b0a4e83d16501d279b7033a4..4cd3c04bac3c260627386cd994f5b11e93c96975 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait A {
     fn a_method(&self);
 }
index 180bd292f8433152f5ae77367bb1ba45954d2321..61708acf7f317f0d36e5eadc564a29471cdf7e43 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::ops::Add;
 
 trait Positioned<S> {
@@ -22,18 +24,18 @@ trait Movable<S: Add<Output=S>>: Positioned<S> {
   }
 }
 
-struct Point { x: int, y: int }
+struct Point { x: isize, y: isize }
 
-impl Positioned<int> for Point {
-    fn SetX(&mut self, x: int) {
+impl Positioned<isize> for Point {
+    fn SetX(&mut self, x: isize) {
         self.x = x;
     }
-    fn X(&self) -> int {
+    fn X(&self) -> isize {
         self.x
     }
 }
 
-impl Movable<int> for Point {}
+impl Movable<isize> for Point {}
 
 pub fn main() {
     let mut p = Point{ x: 1, y: 2};
index a062b4c71752f5a4c038415274e48d9ede867304..0784877849ad108e6bc4f5967eaac76eda99a875 100644 (file)
@@ -9,16 +9,18 @@
 // except according to those terms.
 
 // aux-build:issue_3979_traits.rs
+// pretty-expanded FIXME #23616
+
 extern crate issue_3979_traits;
 use issue_3979_traits::{Positioned, Movable};
 
-struct Point { x: int, y: int }
+struct Point { x: isize, y: isize }
 
 impl Positioned for Point {
-    fn SetX(&mut self, x: int) {
+    fn SetX(&mut self, x: isize) {
         self.x = x;
     }
-    fn X(&self) -> int {
+    fn X(&self) -> isize {
         self.x
     }
 }
index 4f69342830b93c22a90fa2be936dbc533eea0d26..341866e4982ff96d4965ae158e83880b84506898 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,25 +8,27 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Positioned {
-  fn SetX(&mut self, int);
-  fn X(&self) -> int;
+  fn SetX(&mut self, isize);
+  fn X(&self) -> isize;
 }
 
 trait Movable: Positioned {
-  fn translate(&mut self, dx: int) {
+  fn translate(&mut self, dx: isize) {
     let x = self.X();
     self.SetX(x + dx);
   }
 }
 
-struct Point { x: int, y: int }
+struct Point { x: isize, y: isize }
 
 impl Positioned for Point {
-    fn SetX(&mut self, x: int) {
+    fn SetX(&mut self, x: isize) {
         self.x = x;
     }
-    fn X(&self) -> int {
+    fn X(&self) -> isize {
         self.x
     }
 }
index 37144fb9cce771f62332a09f96cf1a00b672f614..d89cf8c2e1064cf349d6bb275467ee49238f1b48 100644 (file)
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 struct HasNested {
-    nest: Vec<Vec<int> > ,
+    nest: Vec<Vec<isize> > ,
 }
 
 impl HasNested {
index 220332f63548af28921350fec8d9cd2fe38f1c55..122de97c99c1cd283ed34542121480a56814b76c 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_private)]
 
 extern crate serialize;
 
index 48e32922ce7085bc144b7357f2e6edfedeee3d4a..ae7bb8a6842243c2f72b75085d9bb2f4d9805d7d 100644 (file)
 // Issue #4036: Test for an issue that arose around fixing up type inference
 // byproducts in vtable records.
 
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_private)]
+
 extern crate serialize;
 
 use serialize::{json, Decodable};
@@ -19,5 +23,5 @@ use serialize::{json, Decodable};
 pub fn main() {
     let json = json::from_str("[1]").unwrap();
     let mut decoder = json::Decoder::new(json);
-    let _x: Vec<int> = Decodable::decode(&mut decoder).unwrap();
+    let _x: Vec<isize> = Decodable::decode(&mut decoder).unwrap();
 }
index d660f300ada99f4ac26cb4a86734966443c22d19..18025c315c95c9abf6eaa5ecaf8be87ee2e16331 100644 (file)
@@ -8,21 +8,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let _id: &Mat2<f64> = &Matrix::identity(1.0);
 }
 
 pub trait Index<Index,Result> { fn get(&self, Index) -> Result { panic!() } }
-pub trait Dimensional<T>: Index<uint, T> { }
+pub trait Dimensional<T>: Index<usize, T> { }
 
 pub struct Mat2<T> { x: T }
 pub struct Vec2<T> { x: T }
 
 impl<T> Dimensional<Vec2<T>> for Mat2<T> { }
-impl<T> Index<uint, Vec2<T>> for Mat2<T> { }
+impl<T> Index<usize, Vec2<T>> for Mat2<T> { }
 
 impl<T> Dimensional<T> for Vec2<T> { }
-impl<T> Index<uint, T> for Vec2<T> { }
+impl<T> Index<usize, T> for Vec2<T> { }
 
 pub trait Matrix<T,V>: Dimensional<V> {
     fn identity(t:T) -> Self;
index c186f1e57f9a1dab6b8ef92b335f1b5a8315c275..52f5d53c046abc96df6238a1885912e8bb38d9ca 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:issue-4208-cc.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate numeric;
 use numeric::{sin, Angle};
 
index 8cae8dd7915a0673cf3404f763e897e7ad28914e..3d283849b1f9cdefaf9e90dac66cadcf4ab179f2 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct Foo;
 
 impl Foo {
index 89cf2f69b34ec456197260dbcebe7e84f4cad6df..c650fc25ee1636805e3d3ed8b4e408f7db897cfb 100644 (file)
@@ -15,23 +15,23 @@ extern crate extra;
 use extra::net::tcp::TcpSocketBuf;
 
 use std::io;
-use std::int;
+use std::isize;
 
 use std::io::{ReaderUtil,WriterUtil};
 
 enum Result {
   Nil,
-  Int(int),
+  Int(isize),
   Data(~[u8]),
   List(~[Result]),
   Error(String),
   Status(String)
 }
 
-priv fn parse_data(len: uint, io: @io::Reader) -> Result {
+priv fn parse_data(len: usize, io: @io::Reader) -> Result {
   let res =
       if (len > 0) {
-      let bytes = io.read_bytes(len as uint);
+      let bytes = io.read_bytes(len as usize);
       assert_eq!(bytes.len(), len);
       Data(bytes)
   } else {
@@ -42,7 +42,7 @@ priv fn parse_data(len: uint, io: @io::Reader) -> Result {
   return res;
 }
 
-priv fn parse_list(len: uint, io: @io::Reader) -> Result {
+priv fn parse_list(len: usize, io: @io::Reader) -> Result {
     let mut list: ~[Result] = ~[];
     for _ in 0..len {
         let v = match io.read_char() {
@@ -60,26 +60,26 @@ priv fn chop(s: String) -> String {
 }
 
 priv fn parse_bulk(io: @io::Reader) -> Result {
-    match from_str::<int>(chop(io.read_line())) {
+    match from_str::<isize>(chop(io.read_line())) {
     None => panic!(),
     Some(-1) => Nil,
-    Some(len) if len >= 0 => parse_data(len as uint, io),
+    Some(len) if len >= 0 => parse_data(len as usize, io),
     Some(_) => panic!()
     }
 }
 
 priv fn parse_multi(io: @io::Reader) -> Result {
-    match from_str::<int>(chop(io.read_line())) {
+    match from_str::<isize>(chop(io.read_line())) {
     None => panic!(),
     Some(-1) => Nil,
     Some(0) => List(~[]),
-    Some(len) if len >= 0 => parse_list(len as uint, io),
+    Some(len) if len >= 0 => parse_list(len as usize, io),
     Some(_) => panic!()
     }
 }
 
 priv fn parse_int(io: @io::Reader) -> Result {
-    match from_str::<int>(chop(io.read_line())) {
+    match from_str::<isize>(chop(io.read_line())) {
     None => panic!(),
     Some(i) => Int(i)
     }
index 9d5f8576c633ee83a31c6bf78f33778135c4cf83..73ef35f0457d8650431cbd286d292c6f4206395e 100644 (file)
@@ -18,10 +18,10 @@ trait X {
 }
 
 #[derive(Debug)]
-struct Y(int);
+struct Y(isize);
 
 #[derive(Debug)]
-struct Z<T> {
+struct Z<T: X+std::fmt::Debug> {
     x: T
 }
 
index 28ab3c3ef12537956feed46fcdfdc587f12bde1b..48753e15a705d2775d00a2b951ee9f844a423c29 100644 (file)
@@ -8,9 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::old_io;
+// pretty-expanded FIXME #23616
+
+#![feature(io)]
+
+use std::io;
 
 pub fn main() {
-    let stdout = &mut old_io::stdout() as &mut old_io::Writer;
+    let stdout = &mut io::stdout() as &mut io::Write;
     stdout.write(b"Hello!");
 }
index 02601ba2f2a02780b878189c3d091a92159bfc76..9c4ae04bf7b7fd6f73319660f11e94390de3a2cd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let _foo = [0; 2*4];
 }
index b40a726a2c397223e3746eba91e9f1be0e09847f..9f8d93461a2635805376af1a941f32c4fdf46b72 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(old_io)]
+
 use std::old_io::println;
 use std::sync::mpsc::channel;
 use std::thread;
index ef30f9182ba69b2dd77f2d810068b61e204366d4..d5d3122f6834bb81436cbd02510fac574da1c707 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::sync::mpsc::channel;
 use std::thread;
 
index 33a5c7a167f9991ab9a121c95dd3bae5188cc6ab..675ca2c3b7ef879dcf97e84fc9d0bbeb3094a357 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn broken(v: &[u8], i: uint, j: uint) -> &[u8] { &v[i..j] }
+// pretty-expanded FIXME #23616
+
+fn broken(v: &[u8], i: usize, j: usize) -> &[u8] { &v[i..j] }
 
 pub fn main() {}
index 521e1b40f992e5d1b305172840ee6aaa9257bad0..23e8f5b0bda0427a8591f64c473444f3763c4acc 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::env;
 
 pub fn main() {
index bf03b4c45326e6871c5b1ecf38e924e9b3b2d35d..6cb7ccc0e9543bec6e27c0c1a91ed9a01847d7e8 100644 (file)
@@ -10,5 +10,7 @@
 
 // aux-build:issue-4545.rs
 
-extern crate "issue-4545" as somelib;
-pub fn main() { somelib::mk::<int>(); }
+// pretty-expanded FIXME #23616
+
+extern crate issue_4545 as somelib;
+pub fn main() { somelib::mk::<isize>(); }
index c08d3503fa4c13b59abf741f8c3170c7450faab9..82925852a6a3d0408a256e31ab929b6be256ad22 100644 (file)
 // Ensures that destructors are run for expressions of the form "e;" where
 // `e` is a type which requires a destructor.
 
+// pretty-expanded FIXME #23616
+
 #![allow(path_statement)]
 
-struct A { n: int }
+struct A { n: isize }
 struct B;
 
-static mut NUM_DROPS: uint = 0;
+static mut NUM_DROPS: usize = 0;
 
 impl Drop for A {
     fn drop(&mut self) {
index bf422bd0405a1c9343f82af2cd38fb63abcbc3e1..56e69a9f36e789b2489345ad535506221d849227 100644 (file)
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-fast doesn't like extern crate
+
+// pretty-expanded FIXME #23616
 
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, libc)]
 
 extern crate libc;
 
@@ -23,12 +24,12 @@ struct NonCopyable(*const c_void);
 impl Drop for NonCopyable {
     fn drop(&mut self) {
         let NonCopyable(p) = *self;
-        let _v = unsafe { transmute::<*const c_void, Box<int>>(p) };
+        let _v = unsafe { transmute::<*const c_void, Box<isize>>(p) };
     }
 }
 
 pub fn main() {
     let t = box 0;
-    let p = unsafe { transmute::<Box<int>, *const c_void>(t) };
+    let p = unsafe { transmute::<Box<isize>, *const c_void>(t) };
     let _z = NonCopyable(p);
 }
index ce2f488b90c7b6adf7bde9917ce62b05cdc1b26a..3532a395b7a2d8aebc0a2f623f7b751b9320bcd0 100644 (file)
@@ -7,9 +7,9 @@
 // <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.
-//
-// ignore-lexer-test FIXME #15877
+
+// pretty-expanded FIXME #23616
 
 trait U { fn f(self); }
-impl U for int { fn f(self) {} }
+impl U for isize { fn f(self) {} }
 pub fn main() { 4.f(); }
index 2245e80971a907cb7fe9c2c1580d060e6c50b49d..a26d6b05d7ee7ad8a8b8600008bd51da636c48fa 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct T { a: Box<int> }
+struct T { a: Box<isize> }
 
 trait U {
     fn f(self);
 }
 
-impl U for Box<int> {
+impl U for Box<isize> {
     fn f(self) { }
 }
 
@@ -25,4 +27,3 @@ pub fn main() {
     let T { a: a } = T { a: box 0 };
     a.f();
 }
-
index 7fc1c10895ef627cd928cdb0aae219d2a0a8a02e..f615767c215587fc455f3dcb86b2f6bbcab7341e 100644 (file)
@@ -9,9 +9,11 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 pub struct Scheduler {
     /// The event loop used to drive the scheduler and perform I/O
-    event_loop: Box<int>
+    event_loop: Box<isize>
 }
 
 pub fn main() { }
index 9c1e782ffce19cdf24e0d162854a56bcbc7567aa..7ac96c21c621a9c4072803a375235a72dd7f017a 100644 (file)
@@ -10,6 +10,8 @@
 
 // regression test for issue 4875
 
+// pretty-expanded FIXME #23616
+
 pub struct Foo<T> {
     data: T,
 }
index 7c3b0a5f1f0146fbd413735612440b2c8056aa63..5726f236e2e0b9f525d5a0de9c8d1a6a40b40007 100644 (file)
@@ -24,4 +24,3 @@ macro_rules! print_hd_tl {
 pub fn main() {
     print_hd_tl!(x, y, z, w)
 }
-
index a6f3771bf62b450aeb9c6ab0fbdca55dd98865d3..d8f7f25508dd8aa0fb1c10f9609a7765bca337b4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -16,7 +18,7 @@ pub trait EventLoop {
 }
 
 pub struct UvEventLoop {
-    uvio: int
+    uvio: isize
 }
 
 impl UvEventLoop {
index dd9a6fb35439e99929ab417e0e8a3ce46e6cd1c8..d8491070bd8b51d87a92f458a32fa36509975b2e 100644 (file)
 
 // Regression test for issue #5239
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let _f = |ref x: int| { *x };
+    let _f = |ref x: isize| { *x };
     let foo = 10;
     assert!(_f(foo) == 10);
 }
index f5d2c38147293fed1c1f72adc6da073505f547b9..eda0eea70712cd04c9af8944e294ae1bf2d2e549 100644 (file)
 // enough for trans to consider this as non-monomorphic,
 // which led to various assertions and failures in turn.
 
+// pretty-expanded FIXME #23616
+
 struct S<'a> {
-    v: &'a int
+    v: &'a isize
 }
 
 fn f<'lt>(_s: &'lt S<'lt>) {}
index 1d2e7b79931f98dce8b83dca090af4fb973c3928..b8532c55c4cb66166ba7941503401ae9d104ad5c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct A(bool);
 
 pub fn main() {
index 2ab41f7783862860932f85db8ca8815cd9071147..d0bc396c368bdf4b1f8aa49896bd93490ef72e84 100644 (file)
@@ -14,7 +14,7 @@ trait Fooable {
     fn yes(self);
 }
 
-impl Fooable for uint {
+impl Fooable for usize {
     fn yes(self) {
         for _ in 0..self { println!("yes"); }
     }
index 1f6493d961c5a847fd4578326f671b7ba7b8f615..34ef63572ae1ee0d2e5839007cf98767f8f97978 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 const INVALID_ENUM : u32 = 0;
 const INVALID_VALUE : u32 = 1;
 
index a28bc9f825d5d0ac3d3fc491d5d74b80eb2c6e4f..5981a0148a0af39f84c3ffb8717f10d5b4cd82f1 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:issue-5518.rs
 
-extern crate "issue-5518" as other;
+// pretty-expanded FIXME #23616
+
+extern crate issue_5518 as other;
 
 fn main() {}
index fb0e8e599eb2af9477cdbffce70a292b28b7ffd4..4ad729f1bc60a114b34bcb591d9a33d321582223 100644 (file)
 // aux-build:issue-5521.rs
 
 
-extern crate "issue-5521" as foo;
+// pretty-expanded FIXME #23616
+
+extern crate issue_5521 as foo;
 
 fn bar(a: foo::map) {
     if false {
         panic!();
     } else {
-        let _b = &(*a)[2];
+        let _b = &(*a)[&2];
     }
 }
 
index a9e1ffcb34510ecdc4af67b7a53a4dcd308ffbb6..50b9ca6e797d8dc868251a49f3780640a688ee28 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Enum {
-    Foo { foo: uint },
-    Bar { bar: uint }
+    Foo { foo: usize },
+    Bar { bar: usize }
 }
 
-fn fun1(e1: &Enum, e2: &Enum) -> uint {
+fn fun1(e1: &Enum, e2: &Enum) -> usize {
     match (e1, e2) {
         (&Enum::Foo { foo: _ }, &Enum::Foo { foo: _ }) => 0,
         (&Enum::Foo { foo: _ }, &Enum::Bar { bar: _ }) => 1,
@@ -22,7 +24,7 @@ fn fun1(e1: &Enum, e2: &Enum) -> uint {
     }
 }
 
-fn fun2(e1: &Enum, e2: &Enum) -> uint {
+fn fun2(e1: &Enum, e2: &Enum) -> usize {
     match (e1, e2) {
         (&Enum::Foo { foo: _ }, &Enum::Foo { foo: _ }) => 0,
         (&Enum::Foo { foo: _ }, _              ) => 1,
index f87f1d8af7649fb723fdd9c707311c72059207dd..91741f938a5a0c757ac492b40af990f91c60539d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 
 pub fn main() {
index 32fca7a182c1b7c465dfc2f915fa11cbb8912bd5..e8190a7245a1e88c2659b19027385081a8c8b027 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::default::Default;
 
 pub struct X<T> {
@@ -26,7 +28,7 @@ impl<T: Default + PartialEq> Default for X<T> {
 
 macro_rules! constants {
     () => {
-        let _ : X<int> = Default::default();
+        let _ : X<isize> = Default::default();
     }
 }
 
index 4e57ed94991cba315f4a00c69348fc6bf1f20b7b..6ae9dc68a5c675e644ceb3742f4e8a45564ccef1 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn foo<T: ::std::cmp::PartialEq>(_t: T) { }
 
 pub fn main() { }
index 4f304e3b4361c4c82bc9421f35b106dd451160a5..e28a929d527238c43773aba6bf2f3444622ae543 100644 (file)
@@ -35,4 +35,3 @@ pub fn main() {
         println!("{}", pup.bark());
     }
 }
-
index 9612c4bf181bd6d2a55b6e8991eb31d7bea31625..88ff103723c73265a9dcdc9fbe32f282e13146bc 100644 (file)
 
 ...should print &[1, 2, 3] but instead prints something like
 &[4492532864, 24]. It is pretty evident that the compiler messed up
-with the representation of [int; n] and [int] somehow, or at least
+with the representation of [isize; n] and [isize] somehow, or at least
 failed to typecheck correctly.
 */
 
-#[derive(Copy)]
-struct X { vec: &'static [int] }
+#[derive(Copy, Clone)]
+struct X { vec: &'static [isize] }
 
 static V: &'static [X] = &[X { vec: &[1, 2, 3] }];
 
index 59bca87bed0b61a8432cf09be88ff86ebaf2ea17..dfb560db10067f4c81fec2133926622f4f160bfb 100644 (file)
@@ -24,7 +24,7 @@ trait Inner {
     fn print(&self);
 }
 
-impl Inner for int {
+impl Inner for isize {
     fn print(&self) { print!("Inner: {}\n", *self); }
 }
 
@@ -41,7 +41,7 @@ impl<'a> Outer<'a> {
 }
 
 pub fn main() {
-    let inner = 5;
+    let inner: isize = 5;
     let outer = Outer::new(&inner as &Inner);
     outer.inner.print();
 }
index 36aa8a9cbca5d2c66e4f225328e6943117d380da..964809631d9cdc1b82287df666f83b7513a3988e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -16,15 +18,15 @@ struct Element;
 macro_rules! foo {
     ($tag: expr, $string: expr) => {
         if $tag == $string {
-            let element = box Element;
+            let element: Box<_> = box Element;
             unsafe {
-                return std::mem::transmute::<_, uint>(element);
+                return std::mem::transmute::<_, usize>(element);
             }
         }
     }
 }
 
-fn bar() -> uint {
+fn bar() -> usize {
     foo!("a", "b");
     0
 }
index 0aaa0c862410447143131e0fb8fce90e419d029b..5190bd95adadc89e368f085875ee5e61d44d4728 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unreachable_code)]
 
 pub fn main() {
index b2eeedfbdc9225071314aec2dc3d171ee6bafe03..e6bc516acc39fe07f83987b74af17e604f20d915 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct TwoDoubles {
     r: f64,
     i: f64
index 468f420624a5f8f44ede4e90b5b023fdca5c31ad..aad90bd4181d9f77e9dd4d9da133e5b37a1692f5 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 extern crate libc;
 
 extern {
index 6502c66d8582101a6dd7c120d9d5d60ffef628c3..2096bebd2b2d3c50126055b32ff7da1b86a45857 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub struct Foo {
-    a: int,
+    a: isize,
 }
 
 struct Bar<'a> {
-    a: Box<Option<int>>,
+    a: Box<Option<isize>>,
     b: &'a Foo,
 }
 
index 4518b503c0dc5a61172013c34e74e32ac7743d0d..d3a43b51dcff49e676429be211806535ab0cecdd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub mod foo {
     use super::Bar;
 
@@ -15,7 +17,7 @@ pub mod foo {
 }
 
 pub enum Bar {
-    Bar0 = 0 as int
+    Bar0 = 0 as isize
 }
 
 pub fn main() {}
index 5b6012673564d03447fa52a44ef99e7f6a362d11..7f741182f422313495d5f5061fde718ea8b11d26 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct T (&'static [int]);
+// pretty-expanded FIXME #23616
+
+struct T (&'static [isize]);
 static t : T = T (&[5, 4, 3]);
 pub fn main () {
     let T(ref v) = t;
index c9413258e0fb8d82442e3b8b76955124eb931cd2..b0e01db14d85a381385db3e26322042e193f351e 100644 (file)
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 pub use local as local_alias;
 
-mod local { }
+pub mod local { }
 
 pub fn main() {}
index 1ad48d326eaca423d151628cc4a1b579c071e2e5..8ec88d55721d30d69c80766c3fcc492d8c96479e 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(old_io)]
+
 use std::old_io;
 trait B {
     fn f(&self);
index 0ce8823bc99aae8b9f81489779cc37287e77b4cf..48923bc82b4e0c4f13bbd75b3b9722181fed568a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn f<T>() -> bool {
     enum E<T> { V(T) }
 
@@ -17,6 +19,6 @@ fn f<T>() -> bool {
 }
 
 fn main() {
-    let b = f::<int>();
+    let b = f::<isize>();
     assert!(b);
 }
index 93edffdcb477fc9c62a7801c3bf302a4f062875e..555272974021a5d4fbe5fb79660cf9f06600fc3d 100644 (file)
@@ -8,13 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 enum Either<T, U> { Left(T), Right(U) }
 
 pub fn main() {
-    match Either::Left(box 17) {
+    match Either::Left(Box::new(17)) {
         Either::Right(()) => {}
         _ => {}
     }
index 1746a6281dc2694a33144dc917a69f8b32327af9..baf829bc269b626bebe04767a10a828c5b0e3c1c 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, collections)]
 
 extern crate collections;
 
@@ -21,16 +23,16 @@ trait Graph<Node, Edge> {
 
 }
 
-impl<E> Graph<int, E> for HashMap<int, int> {
+impl<E> Graph<isize, E> for HashMap<isize, isize> {
     fn f(&self, _e: E) {
         panic!();
     }
-    fn g(&self, _e: int) {
+    fn g(&self, _e: isize) {
         panic!();
     }
 }
 
 pub fn main() {
-    let g : Box<HashMap<int,int>> = box HashMap::new();
-    let _g2 : Box<Graph<int,int>> = g as Box<Graph<int,int>>;
+    let g : Box<HashMap<isize,isize>> = box HashMap::new();
+    let _g2 : Box<Graph<isize,isize>> = g as Box<Graph<isize,isize>>;
 }
index 93429ff10dcd1f9fe356e7f4ece7856e42e35f3f..6f158339169cbeea971fc422bc106be01e0889e6 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![deny(type_limits)]
 
 pub fn main() {
-    let i: uint = 0;
-    assert!(i <= 0xFFFF_FFFF_usize);
+    let i: usize = 0;
+    assert!(i <= 0xFFFF_FFFF);
 
-    let i: int = 0;
-    assert!(i >= -0x8000_0000__isize);
-    assert!(i <= 0x7FFF_FFFF__isize);
+    let i: isize = 0;
+    assert!(i >= -0x8000_0000);
+    assert!(i <= 0x7FFF_FFFF);
 }
index b2b64e62c39a4d645043b54ceb800ac56d185ffc..c280ea31ebc4745fe88106173fe7c00d0da05c90 100644 (file)
@@ -9,7 +9,9 @@
 // except according to those terms.
 
 
-fn swap<F>(f: F) -> Vec<int> where F: FnOnce(Vec<int>) -> Vec<int> {
+// pretty-expanded FIXME #23616
+
+fn swap<F>(f: F) -> Vec<isize> where F: FnOnce(Vec<isize>) -> Vec<isize> {
     let x = vec!(1, 2, 3);
     f(x)
 }
index 39f387afaba048905de543623e8600b6f4c7b14b..c7832ae41e3fb86aa409a4205efd28a2cdad8ab2 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait OpInt { fn call(&mut self, int, int) -> int; }
+// pretty-expanded FIXME #23616
 
-impl<F> OpInt for F where F: FnMut(int, int) -> int {
-    fn call(&mut self, a:int, b:int) -> int {
+pub trait OpInt { fn call(&mut self, isize, isize) -> isize; }
+
+impl<F> OpInt for F where F: FnMut(isize, isize) -> isize {
+    fn call(&mut self, a:isize, b:isize) -> isize {
         (*self)(a, b)
     }
 }
 
-fn squarei<'a>(x: int, op: &'a mut OpInt) -> int { op.call(x, x) }
+fn squarei<'a>(x: isize, op: &'a mut OpInt) -> isize { op.call(x, x) }
 
-fn muli(x:int, y:int) -> int { x * y }
+fn muli(x:isize, y:isize) -> isize { x * y }
 
 pub fn main() {
     let mut f = |x, y| muli(x, y);
index 6e608d34bd5781d9a4777f27fb6b37d51d007ca9..12b71f519b1e62a59088ac15a1f50ec6a4fd5538 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -28,4 +30,3 @@ pub fn main() {
         Thing::A(_a) => 0,
     };
 }
-
index 67440b6ec1c9199749f7c337f4a68eab7fda905c..2f2dca8fe226c298598d842cbd29d0d1277e020d 100644 (file)
 // Tests that everything still compiles and runs fine even when
 // we reorder the bounds.
 
+// pretty-expanded FIXME #23616
+
 trait A {
-    fn a(&self) -> uint;
+    fn a(&self) -> usize;
 }
 
 trait B {
-    fn b(&self) -> uint;
+    fn b(&self) -> usize;
 }
 
 trait C {
-    fn combine<T:A+B>(&self, t: &T) -> uint;
+    fn combine<T:A+B>(&self, t: &T) -> usize;
 }
 
 struct Foo;
 
 impl A for Foo {
-    fn a(&self) -> uint { 1 }
+    fn a(&self) -> usize { 1 }
 }
 
 impl B for Foo {
-    fn b(&self) -> uint { 2 }
+    fn b(&self) -> usize { 2 }
 }
 
 struct Bar;
 
 impl C for Bar {
     // Note below: bounds in impl decl are in reverse order.
-    fn combine<T:B+A>(&self, t: &T) -> uint {
+    fn combine<T:B+A>(&self, t: &T) -> usize {
         (t.a() * 100) + t.b()
     }
 }
 
-fn use_c<S:C, T:B+A>(s: &S, t: &T) -> uint {
+fn use_c<S:C, T:B+A>(s: &S, t: &T) -> usize {
     s.combine(t)
 }
 
index 6e49c0435665df0a693a9acc532cba6c93297279..41abaa2c8b853abaf29e883bc8e50f59cc8c8de4 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[derive(PartialEq)]
-struct A { x: uint }
+struct A { x: usize }
 
 impl Drop for A {
     fn drop(&mut self) {}
index 65ee062a0396078f4b38fecaedb89138bb9c94bd..8449d9f572bf06c8e7eba90e7dad0ceadfc6ac57 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct A { x: uint }
+struct A { x: usize }
 
 impl Drop for A {
     fn drop(&mut self) {}
index ee99ec957b5a6c4a62632a4112e82aec23411b22..4bb23295c858c633c5d61003868a5c0403451670 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct A { x: uint }
+struct A { x: usize }
 
 impl Drop for A {
     fn drop(&mut self) {}
index 9a5fc7763f63b4a21535cbae5f497232c248e7fc..3b33a0ac86f697db94930af6d5e76c62f729cf0f 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Foo {
-    Bar(int),
+    Bar(isize),
     Baz,
 }
 
index ef164150804b99a98b4bff37a04e39b8473e3a59..9b5f78a14504a5e76b32300139a5748541e38917 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub mod Bar {
     pub struct Foo {
-        v: int,
+        v: isize,
     }
 
     extern {
index b9f4f1cf3bd51fafb7134062bc07121bbbba0661..eba87f418e48974c16e13afc6e7e3ce88fa3112e 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
-fn foo(box (_x, _y): Box<(int, int)>) {}
+fn foo(box (_x, _y): Box<(isize, isize)>) {}
 
 pub fn main() {}
index 557ec82233ddebca8a17538b5132abe162ffd6ef..4469dcc0ced81df203f2c649cd24c7b5bcfb6a91 100644 (file)
 // Ensures that destructors are run for expressions of the form "let _ = e;"
 // where `e` is a type which requires a destructor.
 
+// pretty-expanded FIXME #23616
+
 struct Foo;
-struct Bar { x: int }
-struct Baz(int);
-enum FooBar { _Foo(Foo), _Bar(uint) }
+struct Bar { x: isize }
+struct Baz(isize);
+enum FooBar { _Foo(Foo), _Bar(usize) }
 
-static mut NUM_DROPS: uint = 0;
+static mut NUM_DROPS: usize = 0;
 
 impl Drop for Foo {
     fn drop(&mut self) {
@@ -49,7 +51,7 @@ fn main() {
     assert_eq!(unsafe { NUM_DROPS }, 3);
     { let _x = FooBar::_Foo(Foo); }
     assert_eq!(unsafe { NUM_DROPS }, 5);
-    { let _x = FooBar::_Bar(42_usize); }
+    { let _x = FooBar::_Bar(42); }
     assert_eq!(unsafe { NUM_DROPS }, 6);
 
     { let _ = Foo; }
@@ -60,6 +62,6 @@ fn main() {
     assert_eq!(unsafe { NUM_DROPS }, 9);
     { let _ = FooBar::_Foo(Foo); }
     assert_eq!(unsafe { NUM_DROPS }, 11);
-    { let _ = FooBar::_Bar(42_usize); }
+    { let _ = FooBar::_Bar(42); }
     assert_eq!(unsafe { NUM_DROPS }, 12);
 }
index 9e6293216bc116b18bac39236c8673b0553b241b..3138aad2c8cc9b5778e34a65717272301b35d2ab 100644 (file)
@@ -8,31 +8,35 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::intrinsics;
 
 /// Returns the size of a type
-pub fn size_of<T>() -> uint {
+pub fn size_of<T>() -> usize {
     TypeInfo::size_of(None::<T>)
 }
 
 /// Returns the size of the type that `val` points to
-pub fn size_of_val<T>(val: &T) -> uint {
+pub fn size_of_val<T>(val: &T) -> usize {
     val.size_of_val()
 }
 
 pub trait TypeInfo {
-    fn size_of(_lame_type_hint: Option<Self>) -> uint;
-    fn size_of_val(&self) -> uint;
+    fn size_of(_lame_type_hint: Option<Self>) -> usize;
+    fn size_of_val(&self) -> usize;
 }
 
 impl<T> TypeInfo for T {
     /// The size of the type in bytes.
-    fn size_of(_lame_type_hint: Option<T>) -> uint {
+    fn size_of(_lame_type_hint: Option<T>) -> usize {
         unsafe { intrinsics::size_of::<T>() }
     }
 
     /// Returns the size of the type of `self` in bytes.
-    fn size_of_val(&self) -> uint {
+    fn size_of_val(&self) -> usize {
         TypeInfo::size_of(None::<T>)
     }
 }
index c684c4d897b04b924f09f5f8928adcf3276cfa9f..3495c0eb1aed34503c4589d36c203616f433774f 100644 (file)
 
 // aux-build:iss.rs
 
+// pretty-expanded FIXME #23616
+
 #![crate_id="issue-6919"]
 extern crate issue6919_3;
 
 pub fn main() {
     let _ = issue6919_3::D.k;
 }
-
index 96db28f4a101fbaab6d30fe890a47e48d310e992..3a9864f3a766718cd277481995ceff45e5c76b9e 100644 (file)
@@ -18,11 +18,11 @@ would be printed, however the below prints false.
 struct signature<'a> { pattern : &'a [u32] }
 
 static test1: signature<'static> =  signature {
-  pattern: &[0x243f6a88u32,0x85a308d3u32,0x13198a2eu32,0x03707344u32,0xa4093822u32,0x299f31d0u32]
+  pattern: &[0x243f6a88,0x85a308d3,0x13198a2e,0x03707344,0xa4093822,0x299f31d0]
 };
 
 pub fn main() {
-  let test: &[u32] = &[0x243f6a88u32,0x85a308d3u32,0x13198a2eu32,
-                       0x03707344u32,0xa4093822u32,0x299f31d0u32];
+  let test: &[u32] = &[0x243f6a88,0x85a308d3,0x13198a2e,
+                       0x03707344,0xa4093822,0x299f31d0];
   println!("{}",test==test1.pattern);
 }
index 6ef740b2a50513c63d9682b996e6b81d364b14b0..0882203cb1ea51089a1ff49a4762c33f376e5631 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-7178.rs
 
-extern crate "issue-7178" as cross_crate_self;
+// pretty-expanded FIXME #23616
+
+extern crate issue_7178 as cross_crate_self;
 
 pub fn main() {
     let _ = cross_crate_self::Foo::new(&1);
index 65ea895c2c85fb88cc22d3b6bb60fc3f401cf267..1bf343e23f0c1617c6635ab9e27e399784ad1ffa 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     const FOO: f64 = 10.0;
 
@@ -16,4 +18,3 @@ pub fn main() {
         _ => ()
     }
 }
-
index 8aa95927312301e173692511acf7643277cd7fb2..626adfe292bfa421b86db957e436ad3be2511c7f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn foo<T: 'static>(_: T) {}
 
 fn bar<T>(x: &'static T) {
index 6e2ed27725c0fdfbd33e08e584ad3d42d3cb3e1d..fb348fb45380479a2fa76ff582e384bc967e25a3 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unreachable_code)]
 
 fn foo() -> bool { false }
index 75123243f47d6209119b0e68b2de07ae4587a6fb..c5c59407ab2311a3fc15684d4e039795e54894b7 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 /*
 #7519 ICE pattern matching unit in function argument
 */
index eda2057f6d6afbc70cb4266d4f6a5e2ef727828c..6d2a602fc8df7d7fdf5ad0e297e0d1d430d2ecc6 100644 (file)
@@ -13,9 +13,9 @@ trait IDummy {
 }
 
 #[derive(Debug)]
-struct A { a: int }
+struct A { a: isize }
 #[derive(Debug)]
-struct B<'a> { b: int, pa: &'a A }
+struct B<'a> { b: isize, pa: &'a A }
 
     impl IDummy for A {
         fn do_nothing(&self) {
index 77cfc7f0cf607dc2aa15b84089e2c1d9c11b170a..727ed91eadc6c41ba59dfc0e272ea7ca8cabcfd3 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
     fn new() -> bool { false }
     fn dummy(&self) { }
@@ -17,8 +19,8 @@ trait Bar {
     fn new(&self) -> bool { true }
 }
 
-impl Bar for int {}
-impl Foo for int {}
+impl Bar for isize {}
+impl Foo for isize {}
 
 fn main() {
     assert!(1.new());
diff --git a/src/test/run-pass/issue-7607-2.rs b/src/test/run-pass/issue-7607-2.rs
new file mode 100644 (file)
index 0000000..799513e
--- /dev/null
@@ -0,0 +1,24 @@
+// 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.
+
+// pretty-expanded FIXME #23616
+
+pub mod a {
+    pub struct Foo { a: usize }
+}
+
+pub mod b {
+    use a::Foo;
+    impl Foo {
+        fn bar(&self) { }
+    }
+}
+
+pub fn main() { }
index 9e36b1f5082d03dad3f1a48bc3ed9a38326eb600..b0ebc6c9cc82b16679953a83a9705069fef9fc88 100644 (file)
 // Regression test for issue 7660
 // rvalue lifetime too short when equivalent `match` works
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections)]
+
 extern crate collections;
 
 use std::collections::HashMap;
 
-struct A(int, int);
+struct A(isize, isize);
 
 pub fn main() {
-    let mut m: HashMap<int, A> = HashMap::new();
+    let mut m: HashMap<isize, A> = HashMap::new();
     m.insert(1, A(0, 0));
 
-    let A(ref _a, ref _b) = m[1];
-    let (a, b) = match m[1] { A(ref _a, ref _b) => (_a, _b) };
+    let A(ref _a, ref _b) = m[&1];
+    let (a, b) = match m[&1] { A(ref _a, ref _b) => (_a, _b) };
 }
index 0ff265e483efe226a29873ce9a495c3ad9822ddf..007127aeae186b1d87e0c6255a25f1744c9af57b 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unused_imports, dead_code)]
 
 mod test1 {
 
-    mod foo { pub fn p() -> int { 1 } }
-    mod bar { pub fn p() -> int { 2 } }
+    mod foo { pub fn p() -> isize { 1 } }
+    mod bar { pub fn p() -> isize { 2 } }
 
     pub mod baz {
         use test1::bar::p;
@@ -24,8 +26,8 @@ mod test1 {
 
 mod test2 {
 
-    mod foo { pub fn p() -> int { 1 } }
-    mod bar { pub fn p() -> int { 2 } }
+    mod foo { pub fn p() -> isize { 1 } }
+    mod bar { pub fn p() -> isize { 2 } }
 
     pub mod baz {
         use test2::bar::p;
index 736860947f23cb0c149718be36ba0a940a6bfd2b..43b5a997c19a523762fcfaaecfce957bfb4bb3dd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 /*
 
 #7673 Polymorphically creating traits barely works
index a61ee8c2a0bd1e22742d2ace0f28c716fd6d3c7e..e2016feeb0ad75dbb0c4cdf72c7397e46e1f5d4a 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(advanced_slice_patterns)]
+#![feature(slice_patterns)]
 
 use std::ops::Add;
 
index 4b3d46f483399c2354f34bbedf217c03d7ec7e21..a17565fa0ac5b0b572918e628d0b6aa14a974d4e 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-7899.rs
 
-extern crate "issue-7899" as testcrate;
+// pretty-expanded FIXME #23616
+
+extern crate issue_7899 as testcrate;
 
 fn main() {
     let f = testcrate::V2(1.0f32, 2.0f32);
index 504441e3ba96b4bab8eadbf7d3dd7083e6c72934..4f72409c36e1c9acd48256a94fec304e0c593760 100644 (file)
 
 // aux-build:issue-8044.rs
 
-extern crate "issue-8044" as minimal;
+// pretty-expanded FIXME #23616
+
+extern crate issue_8044 as minimal;
 use minimal::{BTree, leaf};
 
 pub fn main() {
-    BTree::<int> { node: leaf(1) };
+    BTree::<isize> { node: leaf(1) };
 }
index 3238c24163e17578ae572e570ae4ad02a3e779b6..92d1c7c5a1c3d3dda91c85cad98b7be84976b4d9 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 /*
 
 #8171 Self is not recognised as implementing kinds in default method implementations
index 7bc8dbe616ff31315a38f842227f17955ba6fdac..b58be361f15d02318cb05d71da2b7402ff68ae7e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait A {
     fn dummy(&self) { }
 }
@@ -20,4 +22,3 @@ pub fn main() {
     let mut b = B;
     foo(&mut b as &mut A);
 }
-
index 83c9e9bf4505334dd990dc3e6f6c4a81bd00cd05..3e65bc000ff84ae6427dbc82984f1907fbbc676e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait A {
     fn dummy(&self) { }
 }
@@ -24,4 +26,3 @@ fn foo(a: &mut A) {
 
 pub fn main() {
 }
-
index fb893873bc4d337bdb962d0f2eadf04d4bd66044..e7f09789c5ba05890d25751f80ff3f38d9f0bc2a 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-8259.rs
 
-extern crate "issue-8259" as other;
+// pretty-expanded FIXME #23616
+
+extern crate issue_8259 as other;
 static a: other::Foo<'static> = other::Foo::A;
 
 pub fn main() {}
index b7e6facc58187a44868ea261e697da5a7e61ff83..a11e14fb333671130c9d61277158fb76bcc7a778 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum E {
-    Foo{f: int},
+    Foo{f: isize},
     Bar,
 }
 
index 40e0b3a8eeccb6e9f162597349e3774ea9d21220..7cf221926a6d375d173ed28303dc4de2310831e8 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum E {
-    Foo{f: int, b: bool},
+    Foo{f: isize, b: bool},
     Bar,
 }
 
index 86c9b8c69646941d5f6809ed467018ae989f9661..bd2e2871bdb49489279c98bcb8545faaa7465ebb 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let x = match Some(1) {
         ref _y @ Some(_) => 1,
index e52e3295c6e0b1d3241191dbd9c9c8dbb5cfbfc1..8eb10a199eaaed3c99816df36a8b60ae5088f2b9 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(old_io, io)]
+
 use std::old_io;
 
 fn foo(a: &mut old_io::Writer) {
@@ -15,4 +19,3 @@ fn foo(a: &mut old_io::Writer) {
 }
 
 pub fn main(){}
-
index 1ca91366f362c76ca0d3fde53f070b791c597945..afdd572b129a3d5421db5e36b047c9a0bf52e373 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:issue_8401.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate issue_8401;
 
 pub fn main() {}
index 00339a4e84b2b470e4b54c5842f8131c30fea2d2..7d8c4ab210d002e1d09d60564f4d41e565aed1f7 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::num::Int;
 use std::thread;
 
@@ -21,19 +25,19 @@ fn main() {
     assert!(thread::spawn(move|| { min_val::<i16>() / -1; }).join().is_err());
     assert!(thread::spawn(move|| { min_val::<i32>() / -1; }).join().is_err());
     assert!(thread::spawn(move|| { min_val::<i64>() / -1; }).join().is_err());
-    assert!(thread::spawn(move|| { 1isize / zero(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i8 / zero(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i16 / zero(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i32 / zero(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i64 / zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1isize / zero::<isize>(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i8 / zero::<i8>(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i16 / zero::<i16>(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i32 / zero::<i32>(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i64 / zero::<i64>(); }).join().is_err());
     assert!(thread::spawn(move|| { min_val::<isize>() % -1; }).join().is_err());
     assert!(thread::spawn(move|| { min_val::<i8>() % -1; }).join().is_err());
     assert!(thread::spawn(move|| { min_val::<i16>() % -1; }).join().is_err());
     assert!(thread::spawn(move|| { min_val::<i32>() % -1; }).join().is_err());
     assert!(thread::spawn(move|| { min_val::<i64>() % -1; }).join().is_err());
-    assert!(thread::spawn(move|| { 1isize % zero(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i8 % zero(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i16 % zero(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i32 % zero(); }).join().is_err());
-    assert!(thread::spawn(move|| { 1i64 % zero(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1isize % zero::<isize>(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i8 % zero::<i8>(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i16 % zero::<i16>(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i32 % zero::<i32>(); }).join().is_err());
+    assert!(thread::spawn(move|| { 1i64 % zero::<i64>(); }).join().is_err());
 }
index 494b62178550349f2f545b5fee1c3c3d74690f90..825729b1e2a81509665c48ef890fd621d4ee7724 100644 (file)
@@ -8,18 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 pub fn main() {
-    match &[(box 5,box 7)] {
+    match &[(Box::new(5),Box::new(7))] {
         ps => {
            let (ref y, _) = ps[0];
            assert!(**y == 5);
         }
     }
 
-    match Some(&[(box 5,)]) {
+    match Some(&[(Box::new(5),)]) {
         Some(ps) => {
            let (ref y,) = ps[0];
            assert!(**y == 5);
@@ -27,7 +26,7 @@ pub fn main() {
         None => ()
     }
 
-    match Some(&[(box 5,box 7)]) {
+    match Some(&[(Box::new(5),Box::new(7))]) {
         Some(ps) => {
            let (ref y, ref z) = ps[0];
            assert!(**y == 5);
index 54dfe2b9dab51e86c49328af5a1edd2c2f1572da..24632a0d13a10d58434bb65375bfddb8b00eaa89 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 enum Either {
index 275fe740db157ca60c5e136efde82437d80bae4a..ce392f8d881d4d1389aebd815d7e176619bb4bfd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub struct UninterpretedOption_NamePart {
     name_part: Option<String>,
 }
index e47999fc468607c2dc3a13ff6df57c67c76554a2..64b463ddf5c68660b7da10d856fd7eac9f188f39 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn f<T, F>(g: F) -> T where F: FnOnce() -> T { g() }
 
 pub fn main() {
index 865905bf50441a9143b527b7af53924cf8f20573..6467262929810ab9d426656b859ff476f5d207ce 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! sty {
     ($t:ty) => (stringify!($t))
 }
@@ -17,6 +19,6 @@ macro_rules! spath {
 }
 
 fn main() {
-    assert_eq!(sty!(int), "int");
+    assert_eq!(sty!(isize), "isize");
     assert_eq!(spath!(std::option), "std::option");
 }
index 815e00e129143f0ee2d8c60e2cb14e4013ac450c..485a76ff7ece91c09b6acd9fb55cebcac6fe98f0 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::default::Default;
 
-struct X { pub x: uint }
+struct X { pub x: usize }
 impl Default for X {
     fn default() -> X {
-        X { x: 42_usize }
+        X { x: 42 }
     }
 }
 
index d7a8674954696b8a6291a645ab3719328572295d..280311af6fbd12ea94121129cc608f6f9a8f12f2 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+#![feature(std_misc)]
+
+use std::thread;
 use std::sync::mpsc::{channel, Receiver};
 
-fn periodical(n: int) -> Receiver<bool> {
+fn periodical(n: isize) -> Receiver<bool> {
     let (chan, port) = channel();
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         loop {
             for _ in 1..n {
                 match chan.send(false) {
@@ -30,9 +32,9 @@ fn periodical(n: int) -> Receiver<bool> {
     return port;
 }
 
-fn integers() -> Receiver<int> {
+fn integers() -> Receiver<isize> {
     let (chan, port) = channel();
-    Thread::spawn(move|| {
+    thread::spawn(move|| {
         let mut i = 1;
         loop {
             match chan.send(i) {
index b70711f9f39e25a393a5fafc2e59b3726e5ff92e..2a0c02b23e8eed2a5f2b07f48883c95bb0aef21c 100644 (file)
 // doesn't cause capture. Making this macro hygienic (as I've done)
 // could very well make this test case completely pointless....
 
+// pretty-expanded FIXME #23616
+
 enum T {
-    A(int),
-    B(uint)
+    A(isize),
+    B(usize)
 }
 
 macro_rules! test {
     ($id:ident, $e:expr) => (
-        fn foo(t: T) -> int {
+        fn foo(t: T) -> isize {
             match t {
                 T::A($id) => $e,
                 T::B($id) => $e
@@ -29,7 +31,7 @@ macro_rules! test {
     )
 }
 
-test!(y, 10 + (y as int));
+test!(y, 10 + (y as isize));
 
 pub fn main() {
     foo(T::A(20));
index 72e2a33b43eac55dad06ec1e9778da78cacff4da..8024eaeda83cbc791d396d17cd56c3ad5811317c 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static mut DROP: int = 0;
-static mut DROP_S: int = 0;
-static mut DROP_T: int = 0;
+// pretty-expanded FIXME #23616
+
+static mut DROP: isize = 0;
+static mut DROP_S: isize = 0;
+static mut DROP_T: isize = 0;
 
 struct S;
 impl Drop for S {
@@ -23,7 +25,7 @@ impl Drop for S {
 }
 fn f(ref _s: S) {}
 
-struct T { i: int }
+struct T { i: isize }
 impl Drop for T {
     fn drop(&mut self) {
         unsafe {
index b1c443dd0c51b5713a2721c538bf0d84b18bbc5d..a4cad1b263952cc289ee22f6e3926e1c3d1e7c48 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn assert_repr_eq<T: std::fmt::Debug>(obj : T, expected : String) {
     assert_eq!(expected, format!("{:?}", obj));
 }
index 99413819852188dd19a56482fe36208ce1ee767e..aa3e601c3a205d83716ff33036d2fcec9a9e517e 100644 (file)
@@ -10,7 +10,7 @@
 
 fn decode() -> String {
     'outer: loop {
-        let mut ch_start: uint;
+        let mut ch_start: usize;
         break 'outer;
     }
     "".to_string()
index 09d0f20c96d6c4d9eda35e3fdb22a6daf2780b4e..298ae5e6aaca81aa1fd7007b4685f495c4de30e1 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! silly_macro {
     () => (
         pub mod Qux {
index f66215aa43f8ca91fa2c224b0ce4f524df50bdfb..4da0c22a0b1bfa2321b16a2b37f0723b2258f50b 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:issue_9123.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate issue_9123;
 
 pub fn main() {}
index 6c843993040f38d65dcf0a77c0bb90801c982265..99db47c172e21fbba778f6dbdb0c7eb3d7bc5525 100644 (file)
@@ -17,7 +17,7 @@ pub trait bomb { fn boom(&self, Ident); }
 pub struct S;
 impl bomb for S { fn boom(&self, _: Ident) { } }
 
-pub struct Ident { name: uint }
+pub struct Ident { name: usize }
 
 // macro_rules! int3 { () => ( unsafe { asm!( "int3" ); } ) }
 macro_rules! int3 { () => ( { } ) }
index 31797deccf91ce878b80676e4e17dc9a1cc273ad..0bd8a8e0d9df27ad505d2101672ed3d002b4a9f2 100644 (file)
 
 // aux-build:issue_9188.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate issue_9188;
 
 pub fn main() {
     let a = issue_9188::bar();
-    let b = issue_9188::foo::<int>();
+    let b = issue_9188::foo::<isize>();
     assert_eq!(*a, *b);
 }
-
index 2795fd59c0c0d7cf156a3f64abd63a886888786b..e4d848dbd754cf8dc352cefc53f9a394a1c6037a 100644 (file)
@@ -8,5 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 static DATA:&'static [&'static str] = &["my string"];
 fn main() { }
index da5338b8c3c61438bdfdf74362909e788cb94fda..209c6b139612f08ee1fafe949240616d2516040d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct A<'a> {
     a: &'a [String],
     b: Option<&'a [String]>,
index c501420fa617a00c212fc6f5c2a609512da99d3e..2c84e202b26f1bd2dde7b9e7513727fa7c80fb1d 100644 (file)
@@ -1,3 +1,5 @@
+// pretty-expanded FIXME #23616
+
  // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 
 
 struct Thing1<'a> {
-    baz: &'a [Box<int>],
+    baz: &'a [Box<isize>],
     bar: Box<u64>,
 }
 
 struct Thing2<'a> {
-    baz: &'a [Box<int>],
+    baz: &'a [Box<isize>],
     bar: u64,
 }
 
index 7273a45d893269254727439f0bcfa37eec582bc4..148d0760e5c02f9f96b47e9fd012e86cbd8c2cde 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Base: Base2 + Base3{
     fn foo(&self) -> String;
     fn foo1(&self) -> String;
index a98d1aba04dfd716d65efe69e7caafebf34d69cc..bfaf060e43c30ac41d25f856663c430cbe8166c4 100644 (file)
@@ -8,14 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(old_io, std_misc)]
+
 use std::sync::mpsc::{TryRecvError, channel};
 use std::old_io::timer::Timer;
-use std::thread::Thread;
+use std::thread;
 use std::time::Duration;
 
 pub fn main() {
     let (tx, rx) = channel();
-    let _t = Thread::scoped(move||{
+    let _t = thread::scoped(move||{
         let mut timer = Timer::new().unwrap();
         timer.sleep(Duration::milliseconds(10));
         tx.send(()).unwrap();
index aa1e65efaa41e49b87a8651caa213af1b2091278..108f1a0d73daf6d1e76a17b62dcf62862e451761 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod a {
     pub enum Enum<T> {
         A(T),
@@ -16,32 +18,32 @@ mod a {
     pub trait X {
         fn dummy(&self) { }
     }
-    impl X for int {}
+    impl X for isize {}
 
     pub struct Z<'a>(Enum<&'a (X+'a)>);
-    fn foo() { let x = 42; let z = Z(Enum::A(&x as &X)); let _ = z; }
+    fn foo() { let x: isize = 42; let z = Z(Enum::A(&x as &X)); let _ = z; }
 }
 
 mod b {
     trait X {
         fn dummy(&self) { }
     }
-    impl X for int {}
+    impl X for isize {}
     struct Y<'a>{
         x:Option<&'a (X+'a)>,
     }
 
     fn bar() {
-        let x = 42;
+        let x: isize = 42;
         let _y = Y { x: Some(&x as &X) };
     }
 }
 
 mod c {
     pub trait X { fn f(&self); }
-    impl X for int { fn f(&self) {} }
+    impl X for isize { fn f(&self) {} }
     pub struct Z<'a>(Option<&'a (X+'a)>);
-    fn main() { let x = 42; let z = Z(Some(&x as &X)); let _ = z; }
+    fn main() { let x: isize = 42; let z = Z(Some(&x as &X)); let _ = z; }
 }
 
 pub fn main() {}
index 919f0aae38e0acb48a104fe9520d154ff0a75470..3283dc44f308398356de7a91f3452df05fa1255c 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 
 use std::cell::Cell;
 
 struct r<'a> {
-    b: &'a Cell<int>,
+    b: &'a Cell<isize>,
 }
 
 #[unsafe_destructor]
@@ -23,7 +25,7 @@ impl<'a> Drop for r<'a> {
     }
 }
 
-fn r(b: &Cell<int>) -> r {
+fn r(b: &Cell<isize>) -> r {
     r {
         b: b
     }
index 921965b280b28b90bf4bce7596256d7a4eef5dc6..84f848fc9cdb20381c929e21aa4887e2542b1bc2 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-9906.rs
 
-extern crate "issue-9906" as testmod;
+// pretty-expanded FIXME #23616
+
+extern crate issue_9906 as testmod;
 
 pub fn main() {
     testmod::foo();
index 240a134221d3473c2ff08b69d982c04f21797516..e81a07fa68325a5b870e106c1d5e7458347a9731 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     assert_eq!((0 + 0u8) as char, '\0');
 }
index c7dea71998646463b66b72a78680128f2df49787..222eb0c651815d11c7b44e60fe380e1d42cbcaa2 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    const S: uint = 23 as uint; [0; S]; ()
+    const S: usize = 23 as usize; [0; S]; ()
 }
diff --git a/src/test/run-pass/issue-9951.rs b/src/test/run-pass/issue-9951.rs
new file mode 100644 (file)
index 0000000..6380739
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+#![allow(unused_variables)]
+
+trait Bar {
+  fn noop(&self);
+}
+impl Bar for u8 {
+  fn noop(&self) {}
+}
+
+fn main() {
+    let (a, b) = (&5u8 as &Bar, &9u8 as &Bar);
+    let (c, d): (&Bar, &Bar) = (a, b);
+
+    let (a, b) = (Box::new(5u8) as Box<Bar>, Box::new(9u8) as Box<Bar>);
+    let (c, d): (&Bar, &Bar) = (&*a, &*b);
+
+    let (c, d): (&Bar, &Bar) = (&5, &9);
+}
index 2c9382be9b17c82768fe9e3cdab9fc44ceeb91f7..c8af811d13d8d799ac19e7c8e455aae844c051f7 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:issue-9968.rs
 
-extern crate "issue-9968" as lib;
+// pretty-expanded FIXME #23616
+
+extern crate issue_9968 as lib;
 
 use lib::{Trait, Struct};
 
index b4a41ef44f82d502298c382a7cadbf478efd2192..d126d1f6ce1d3886e9b79efa022538eb15cfe001 100644 (file)
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 // aux-build:issue2170lib.rs
+// pretty-expanded FIXME #23616
+
 extern crate issue2170lib;
 
 pub fn main() {
-   // let _ = issue2170lib::rsrc(2i32);
+   // let _ = issue2170lib::rsrc(2);
 }
index 3193e5c5fc2477f9005f9ba79580d93c41de4444..8538950a895c2cc8a969966be6ca95f6b146a041 100644 (file)
@@ -8,9 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 // This used to cause an ICE because the retslot for the "return" had the wrong type
 fn testcase<'a>() -> Box<Iterator<Item=usize> + 'a> {
-    return Box::new(range(0, 3).map(|i| { return i; }));
+    return Box::new((0..3).map(|i| { return i; }));
 }
 
 fn main() {
index a6fb993a96b0065517ab678f0416b536c4b97607..cffe3f9572b29b6b5785b58b2b50ef452670ef37 100644 (file)
@@ -10,5 +10,7 @@
 
 // aux-build:issue_3136_a.rc
 
+// pretty-expanded FIXME #23616
+
 extern crate issue_3136_a;
 pub fn main() {}
index 951cde3264b2c02d2584ee4a75112aad9cee377d..9db556bf9a22feaedfb499908fccafb6e55d532f 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:issue_9155.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate issue_9155;
 
 struct Baz;
index 15195482ed693921f39beac19f320a62450fb2a0..0013cb292e1c7d87c4914b711910be61dfc55d52 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(collections)]
+
 use std::string::String;
 
 fn test_stack_assign() {
index 6036af5c6275f9c3a68ebdb1057c07ad2158756b..c2ed68fc5d4003c6afea7e3aeef986b9e9bdee18 100644 (file)
@@ -12,7 +12,9 @@
 // for completeness since .rs files linked from .rc files support this
 // notation to specify their module's attributes
 
-#![feature(custom_attribute)]
+// pretty-expanded FIXME #23616
+
+#![feature(custom_attribute, libc)]
 #![allow(unused_attribute)]
 #![attr1 = "val"]
 #![attr2 = "val"]
@@ -28,7 +30,7 @@ mod test_first_item_in_file_mod {}
 
 mod test_single_attr_outer {
     #[attr = "val"]
-    pub static x: int = 10;
+    pub static x: isize = 10;
 
     #[attr = "val"]
     pub fn f() { }
@@ -45,7 +47,7 @@ mod test_single_attr_outer {
 mod test_multi_attr_outer {
     #[attr1 = "val"]
     #[attr2 = "val"]
-    pub static x: int = 10;
+    pub static x: isize = 10;
 
     #[attr1 = "val"]
     #[attr2 = "val"]
@@ -63,13 +65,13 @@ mod test_multi_attr_outer {
 
     #[attr1 = "val"]
     #[attr2 = "val"]
-    struct t {x: int}
+    struct t {x: isize}
 }
 
 mod test_stmt_single_attr_outer {
     pub fn f() {
         #[attr = "val"]
-        static x: int = 10;
+        static x: isize = 10;
 
         #[attr = "val"]
         fn f() { }
@@ -91,7 +93,7 @@ mod test_stmt_multi_attr_outer {
 
         #[attr1 = "val"]
         #[attr2 = "val"]
-        static x: int = 10;
+        static x: isize = 10;
 
         #[attr1 = "val"]
         #[attr2 = "val"]
@@ -174,8 +176,8 @@ mod test_foreign_items {
 /*mod test_literals {
     #![str = "s"]
     #![char = 'c']
-    #![int = 100]
-    #![uint = 100_usize]
+    #![isize = 100]
+    #![usize = 100_usize]
     #![mach_int = 100u32]
     #![float = 1.0]
     #![mach_float = 1.0f32]
index 9aefda4bc71164ab66a176e1e8b2b6d0953a5b30..2827a6df3373767f09fcf59581cf17a614301930 100644 (file)
@@ -11,6 +11,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 mod foo {
     pub fn baz() { }
 }
diff --git a/src/test/run-pass/iter-cloned-type-inference.rs b/src/test/run-pass/iter-cloned-type-inference.rs
new file mode 100644 (file)
index 0000000..12f6a7c
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2015 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 to see that the element type of .cloned() can be inferred
+// properly. Previously this would fail to deduce the type of `sum`.
+
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
+use std::iter::AdditiveIterator;
+
+fn square_sum(v: &[i64]) -> i64 {
+    let sum = v.iter().cloned().sum();
+    sum * sum
+}
+
+fn main() {
+    assert_eq!(36, square_sum(&[1,2,3]));
+}
index 29ac563878bc4ce7aec13a54c703a3681afb181c..a6130841b5c52d1948d09ac90b68569a7bb125b1 100644 (file)
 
 
 
-fn range_<F>(a: int, b: int, mut it: F) where F: FnMut(int) {
+fn range_<F>(a: isize, b: isize, mut it: F) where F: FnMut(isize) {
     assert!((a < b));
-    let mut i: int = a;
+    let mut i: isize = a;
     while i < b { it(i); i += 1; }
 }
 
 pub fn main() {
-    let mut sum: int = 0;
+    let mut sum: isize = 0;
     range_(0, 100, |x| sum += x );
     println!("{}", sum);
 }
index 36f0d3c1c52074028d74caf425b56931858abe13..62aa300578355027ff8fbf315d301a20bb560d96 100644 (file)
@@ -9,5 +9,7 @@
 // except according to those terms.
 
 
-fn f(_a: Vec<int> ) { }
+// pretty-expanded FIXME #23616
+
+fn f(_a: Vec<isize> ) { }
 pub fn main() { f(vec!(1, 2, 3, 4, 5)); }
index dd38a5f8b3ba7b23906bc3b11dede3688d8cfb41..8ae084dce8c37793a928b9deb41101647062325a 100644 (file)
@@ -8,18 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc)]
+
+use std::thread;
 use std::sync::mpsc::{channel, Sender};
 
 fn producer(tx: &Sender<Vec<u8>>) {
     tx.send(
-         vec!(1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8,
-          13u8)).unwrap();
+         vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+          13)).unwrap();
 }
 
 pub fn main() {
     let (tx, rx) = channel::<Vec<u8>>();
-    let _prod = Thread::spawn(move|| {
+    let _prod = thread::scoped(move|| {
         producer(&tx)
     });
 
index ff568b77f08ac205fffb295f9579855d92868b76..9838fe62394ce17b1696bdebac12201634c6a6d5 100644 (file)
 // mod -> module
 // match -> match
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
 }
 
 mod foo {
 }
 
-fn bar() -> int {
+fn bar() -> isize {
     match 0 {
       _ => { 0 }
     }
index f2d509ee61ddd4cb2f4054ce918d3cfdfd3616fa..11b1d70137deffe7046b5bf791b05bf8b3c83cfd 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+#![feature(std_misc)]
 
-fn user(_i: int) {}
+use std::thread;
+
+fn user(_i: isize) {}
 
 fn foo() {
     // Here, i is *copied* into the proc (heap closure).
     // Requires allocation.  The proc's copy is not mutable.
     let mut i = 0;
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         user(i);
         println!("spawned {}", i)
     });
@@ -29,7 +31,7 @@ fn bar() {
     // mutable outside of the proc.
     let mut i = 0;
     while i < 10 {
-        let _t = Thread::spawn(move|| {
+        let _t = thread::scoped(move|| {
             user(i);
         });
         i += 1;
@@ -40,7 +42,7 @@ fn car() {
     // Here, i must be shadowed in the proc to be mutable.
     let mut i = 0;
     while i < 10 {
-        let _t = Thread::spawn(move|| {
+        let _t = thread::scoped(move|| {
             let mut i = i;
             i += 1;
             user(i);
@@ -50,4 +52,3 @@ fn car() {
 }
 
 pub fn main() {}
-
index f05ac11d4138031683a6ed26ce769bbd72311d53..84156385ef438df611dfd93a1038e42b28bcd079 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
index 233db83d289bd2d2df1f86cae89932a5ac33d15e..84c5da1ad6c2adfcc096ca94b92a1a460750fd5d 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:kinds_in_metadata.rs
 
+// pretty-expanded FIXME #23616
+
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
@@ -20,6 +22,5 @@ extern crate kinds_in_metadata;
 use kinds_in_metadata::f;
 
 pub fn main() {
-    f::<int>();
+    f::<isize>();
 }
-
index 30c2495d590fee7bb6a8f9407fedb56ff9376662..fe2f35c5119e038619f176cd3d3b13e5cab29125 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     'foo: loop {
         loop {
index 3c2a3f355b412e15ecf549bba8e8318d559fc438..fca700f6e4a8460a803b1f8c4c5d548ce9b99a1f 100644 (file)
 // resolved when we finish typechecking the ||.
 
 
-struct Refs { refs: Vec<int> , n: int }
+struct Refs { refs: Vec<isize> , n: isize }
 
 pub fn main() {
     let mut e = Refs{refs: vec!(), n: 0};
     let _f = || println!("{}", e.n);
-    let x: &[int] = &e.refs;
+    let x: &[isize] = &e.refs;
     assert_eq!(x.len(), 0);
 }
index a6060bebbc5cde4ec793ec374d0e54d73469ada4..e5bdca1a06773a8773eada2ece519870980db73d 100644 (file)
@@ -15,7 +15,7 @@ macro_rules! bad_macro {
     ($ex:expr) => ({(|_x| { $ex }) (9) })
 }
 
-fn takes_x(_x : int) {
+fn takes_x(_x : isize) {
     assert_eq!(bad_macro!(_x),8);
 }
 fn main() {
index 350ec68a7d1495347ffe02ba11595b627cdb5ef9..f5b9bd4fbaa69b800f332b2e333afe0975358c90 100644 (file)
 
 // aux-build:lang-item-public.rs
 // ignore-android
-// ignore-windows #13361
 
 #![feature(lang_items, start, no_std)]
 #![no_std]
 
-extern crate "lang-item-public" as lang_lib;
+extern crate lang_item_public as lang_lib;
 
 #[cfg(target_os = "linux")]
 #[link(name = "c")]
@@ -37,7 +36,7 @@ extern {}
 #[link(name = "c")]
 extern {}
 
-#[cfg(target_os = "openbsd")]
+#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
 #[link(name = "c")]
 extern {}
 
@@ -46,6 +45,6 @@ extern {}
 extern {}
 
 #[start]
-fn main(_: int, _: *const *const u8) -> int {
-    1 % 1
+fn main(_: isize, _: *const *const u8) -> isize {
+    1_isize % 1_isize
 }
index 20ec058b9f4a1b8535b50b2e7151441a748f5ea7..e9c66093fb0cfe98f649f1b4ebf77c234fe57e4e 100644 (file)
 
 
 
-struct Large {a: int,
-             b: int,
-             c: int,
-             d: int,
-             e: int,
-             f: int,
-             g: int,
-             h: int,
-             i: int,
-             j: int,
-             k: int,
-             l: int}
+// pretty-expanded FIXME #23616
+
+struct Large {a: isize,
+             b: isize,
+             c: isize,
+             d: isize,
+             e: isize,
+             f: isize,
+             g: isize,
+             h: isize,
+             i: isize,
+             j: isize,
+             k: isize,
+             l: isize}
 fn f() {
     let _foo: Large =
         Large {a: 0,
index 8ef5df5d6969729f2365ee0f8f99ad8bfb61c107..28fe3bf0bd1fd4ef3b336d078b8a64496e0b766c 100644 (file)
@@ -10,6 +10,8 @@
 
 // Issue #1818
 
+// pretty-expanded FIXME #23616
+
 fn lp<T, F>(s: String, mut f: F) -> T where F: FnMut(String) -> T {
     while false {
         let r = f(s);
index 566d34e6d86df763a4c9f13ee51bed0ea8555dae..f9c8fe0f2d2d5945c5bea5fdcad10325f10b207b 100644 (file)
 
 // Make sure #1399 stays fixed
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, core)]
 
 struct A { a: Box<isize> }
 
 fn foo() -> Box<FnMut() -> isize + 'static> {
-    let k = box 22;
+    let k: Box<_> = box 22;
     let _u = A {a: k.clone()};
-    // FIXME(#16640) suffix in `22_isize` suffix shouldn't be necessary
-    let result  = || 22_isize;
-    box result
+    // FIXME(#16640) suffix in `22` suffix shouldn't be necessary
+    let result  = || 22;
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    Box::new(result)
 }
 
 pub fn main() {
index 19a780d180f2804d404971bf0f3de5827ccbc364..35a17150787775ce9f3fa79ed3aa297119786d01 100644 (file)
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct A { a: Box<int> }
+struct A { a: Box<isize> }
 
 pub fn main() {
     fn invoke<F>(f: F) where F: FnOnce() { f(); }
-    let k = box 22;
+    let k: Box<_> = box 22;
     let _u = A {a: k.clone()};
     invoke(|| println!("{}", k.clone()) )
 }
index 559c9e78945707a8321510fb0dd11738a9b8f4f0..500de64ae832ce0d7004e7fc29f29f9da9aef148 100644 (file)
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn incr(x: &mut int) -> bool { *x += 1; assert!((false)); return false; }
+fn incr(x: &mut isize) -> bool { *x += 1; assert!((false)); return false; }
 
 pub fn main() {
     let x = 1 == 2 || 3 == 3;
     assert!((x));
-    let mut y: int = 10;
+    let mut y: isize = 10;
     println!("{}", x || incr(&mut y));
     assert_eq!(y, 10);
     if true && x { assert!((true)); } else { assert!((false)); }
index 60f7689ecfa638b536111516e8ae9972d7ff1567..d71d7e751a045c2f24c2fcbcc5941e850a4f1119 100644 (file)
@@ -10,6 +10,6 @@
 
 
 
-fn foo(x: int) { println!("{}", x); }
+fn foo(x: isize) { println!("{}", x); }
 
-pub fn main() { let mut x: int; if 1 > 2 { x = 12; } else { x = 10; } foo(x); }
+pub fn main() { let mut x: isize; if 1 > 2 { x = 12; } else { x = 10; } foo(x); }
index 65808de3cf42b2122761a9704f6756fad40566b8..30838b3121a95692c2bb250fd68211a0c8f40849 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 fn leaky<T>(_t: T) { }
 
-pub fn main() { let x = box 10; leaky::<Box<int>>(x); }
+pub fn main() { let x = box 10; leaky::<Box<isize>>(x); }
index 9ac016d534f09c40c40ca235a1abdf74890b3fe0..c53bc83ef6b7862f24d085654bdac7987ca37683 100644 (file)
@@ -12,8 +12,8 @@
 #![feature(box_syntax)]
 
 fn f() {
-    let a = box 1;
-    let b: &int = &*a;
+    let a: Box<_> = box 1;
+    let b: &isize = &*a;
     println!("{}", b);
 }
 
index c0f674d03714f12d616df55b15d442bdabf13c78..0b38d16941bae9e79a3599478af1845e1a71a3ea 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = 3_usize;
     let ref y = x;
index d6409267eb6900219f22c281b2439b64b6f7cd95..c1e80aaf2d7b0f4f81312d48cc1dc28c2647fe32 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // shouldn't affect evaluation of $ex:
+// pretty-expanded FIXME #23616
+
 macro_rules! bad_macro {
     ($ex:expr) => ({let _x = 9; $ex})
 }
index 22a29279a67ae974c7d5a291098c5b844eefabce..80bd15578d1152d56d6d738ac385b2f7a5cc2d91 100644 (file)
@@ -17,7 +17,7 @@ pub fn main() {
     println!("{}", y);
     assert_eq!(y, 6);
     let s = "hello there".to_string();
-    let mut i: int = 0;
+    let mut i: isize = 0;
     for c in s.bytes() {
         if i == 0 { assert!((c == 'h' as u8)); }
         if i == 1 { assert!((c == 'e' as u8)); }
index 38b5a858aff083cd2358091b440392ea06947677..3336ce7e723de6e79050b89f347985f91b2c2045 100644 (file)
@@ -16,11 +16,11 @@ fn i_live_in_more_text() -> &'static str {
 
 #[cfg(not(target_os = "macos"))]
 #[link_section=".imm"]
-static magic: uint = 42;
+static magic: usize = 42;
 
 #[cfg(not(target_os = "macos"))]
 #[link_section=".mut"]
-static mut frobulator: uint = 0xdeadbeef;
+static mut frobulator: usize = 0xdeadbeef;
 
 #[cfg(target_os = "macos")]
 #[link_section="__TEXT,__moretext"]
@@ -30,11 +30,11 @@ fn i_live_in_more_text() -> &'static str {
 
 #[cfg(target_os = "macos")]
 #[link_section="__RODATA,__imm"]
-static magic: uint = 42;
+static magic: usize = 42;
 
 #[cfg(target_os = "macos")]
 #[link_section="__DATA,__mut"]
-static mut frobulator: uint = 0xdeadbeef;
+static mut frobulator: usize = 0xdeadbeef;
 
 pub fn main() {
     unsafe {
index 80a859c03bc3d70e969fac1bc91ed9d546dda28f..945cf9370f4149c6df1214d1643e59cc743f785d 100644 (file)
 // ignore-android: FIXME(#10379)
 // ignore-windows: std::dynamic_lib does not work on Windows well
 
-extern crate "linkage-visibility" as foo;
+#![feature(std_misc, old_path)]
+
+extern crate linkage_visibility as foo;
 
 pub fn main() {
     foo::test();
-    foo::foo2::<int>();
+    foo::foo2::<isize>();
     foo::foo();
 }
index 5cd741350d57195cd267e0b74a7c7d184c41cf9d..0794a5e0daf2f586af538cea6faac6bf810e1d61 100644 (file)
 
 #![feature(linkage)]
 
-extern crate "linkage1" as other;
+extern crate linkage1 as other;
 
 extern {
     #[linkage = "extern_weak"]
-    static foo: *const int;
+    static foo: *const isize;
     #[linkage = "extern_weak"]
-    static something_that_should_never_exist: *mut int;
+    static something_that_should_never_exist: *mut isize;
 }
 
 fn main() {
diff --git a/src/test/run-pass/lint-cstack.rs b/src/test/run-pass/lint-cstack.rs
deleted file mode 100644 (file)
index f180ffc..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2013 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.
-
-extern crate libc;
-
-extern {
-    fn rust_get_test_int() -> libc::intptr_t;
-}
-
-trait A {
-    fn foo(&self) {
-        unsafe {
-            rust_get_test_int();
-        }
-    }
-}
-
-pub fn main() {
-}
index 061f7025527567e24beba0554b5d97dd9761ba8f..6ddaee9c8bd5c1a669f1889bd8955e4cbaf00b2f 100644 (file)
@@ -20,6 +20,6 @@
 
 struct ヒ;
 
-static ラ: uint = 0;
+static ラ: usize = 0;
 
 pub fn main() {}
index f51312bc257719307836e0c27e81b5babcbb2416..3b4bd001e8dc051abba93eecb027eb383160c5e5 100644 (file)
@@ -10,7 +10,9 @@
 
 // This is ok because we often use the trailing underscore to mean 'prime'
 
+// pretty-expanded FIXME #23616
+
 #[forbid(non_camel_case_types)]
-type Foo_ = int;
+type Foo_ = isize;
 
 pub fn main() { }
index ce3518618d0b475b4b4ca552c74a98df48a98d30..aa5b3834c01786fc0d58684a6aaabfc69839649a 100644 (file)
@@ -9,9 +9,11 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 #![forbid(non_camel_case_types)]
 #![forbid(non_upper_case_globals)]
 
-static mut bar: int = 2;
+static mut bar: isize = 2;
 
 pub fn main() {}
index e55c1b36f3e24b357c90ca70b82e6c0bafe8822c..8f0cbf96b604999aaaf7baaf0657622821b837a8 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-enum list { cons(int, Box<list>), nil, }
+enum list { cons(isize, Box<list>), nil, }
 
 pub fn main() { list::cons(10, box list::cons(11, box list::cons(12, box list::nil))); }
index 143972fe299fe51db6dee4eddfd9a564528ca565..df89809ef1fed25a0dc86778e8b784790bedc9d8 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 #![allow(unreachable_code)]
 #![allow(unused_variable)]
 
 fn test(_cond: bool) {
-    let v: int;
+    let v: isize;
     v = 1;
     loop { } // loop never terminates, so no error is reported
     v = 2;
index f13e2826c8532bad73c5767f64d908ef51e01dbd..6fc15478f7a55e0d23d9b1a4fca5b83f8afe0e05 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unreachable_code)]
 
 fn test() {
-    let _v: int;
+    let _v: isize;
     _v = 1;
     return;
     _v = 2; //~ WARNING: unreachable statement
index 9120151051ea05ab2e1b38247650cd8b4da0750f..f9bb45ee4009b5a4bbddde49d83d014141ade072 100644 (file)
@@ -9,7 +9,9 @@
 // except according to those terms.
 
 
-fn take(x: int) -> int {x}
+// pretty-expanded FIXME #23616
+
+fn take(x: isize) -> isize {x}
 
 fn the_loop() {
     let mut list = Vec::new();
index c4b45ae0f0e62cf49b3db6293516414483aa1725..1991e2b178d51c4ddb76f25d19e5e5d6960884b3 100644 (file)
@@ -10,7 +10,7 @@
 
 #[derive(Clone, Debug)]
 enum foo {
-  a(uint),
+  a(usize),
   b(String),
 }
 
index 95a5f1003b6e356f8b39dd57e08bd7aac77513af..49328311867601af9aacbf15f81d9b446dee44cc 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(trace_macros, log_syntax)]
 
 // make sure these macros can be used as in the various places that
index 262d9b21eb48bddd57815f6d246e26151037ef4a..59f5b0af359131b3f2acd4c4394b2cff7c4ddfab 100644 (file)
@@ -8,9 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:--cfg ndebug
+// compile-flags:-C debug-assertions=no
 // exec-env:RUST_LOG=logging-enabled-debug=debug
 
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_private)]
+
 #[macro_use]
 extern crate log;
 
index 372cdc401b54929ee084e12cbf7bcb88a16caf89..294d4d1217952c9c1d4fb8f95122f57572417acb 100644 (file)
@@ -8,7 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// exec-env:RUST_LOG=logging-enabled=info
+// exec-env:RUST_LOG=logging_enabled=info
+
+// pretty-expanded FIXME #23616
+
+#![feature(rustc_private)]
 
 #[macro_use]
 extern crate log;
index b03c4b5ff47badc1e096c0b85d9298cb9ca0f159..575f087d8335f1b865c2c25fab6a0c4bcd5c1cc4 100644 (file)
@@ -15,7 +15,7 @@ use std::cell::Cell;
 use std::fmt;
 use std::thread;
 
-struct Foo(Cell<int>);
+struct Foo(Cell<isize>);
 
 impl fmt::Debug for Foo {
     fn fmt(&self, _fmt: &mut fmt::Formatter) -> fmt::Result {
index ced1fdc4455194f734595ed133c8c3d6b7fb4eef..7caeeb401244b3035c5cbb7b8215ab9a1fc763db 100644 (file)
 // longer happens by enabling logging for *this* crate and then invoking a
 // function in an external crate which will panic when logging is enabled.
 
+// pretty-expanded FIXME #23616
+
 extern crate logging_right_crate;
 
 pub fn main() {
     // this function panicks if logging is turned on
-    logging_right_crate::foo::<int>();
+    logging_right_crate::foo::<isize>();
 }
index 8526dfe72da134a5c96e16fd7c1459d4db099c56..b27080b65b78150629307bd83f0b3788518bb215 100644 (file)
@@ -10,6 +10,9 @@
 
 // ignore-windows
 // exec-env:RUST_LOG=debug
+// compile-flags:-C debug-assertions=y
+
+#![feature(old_io, rustc_private)]
 
 #[macro_use]
 extern crate log;
index 8a21d60e468b0d0c9960cc27eeb4697e17f88b3f..820285188ae4ee5e6b29f36eae4335a2f93b52c8 100644 (file)
@@ -16,4 +16,6 @@
 // this test will trigger "output during runtime initialization" to make sure
 // that the bug isn't re-introduced.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {}
index cbe26844708db79e082b2bce2dbab5fd55ccf00b..6e0f1bb87a5fb678e558d176249f7eeb99ed374e 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unused_variable)]
 
 pub fn main() {
-    let mut i: int = 0;
+    let mut i: isize = 0;
     while i < 1000000 {
         i += 1;
         let x = 3;
index d58d2a7139665bd08fb304999c2fd13e42305e8d..eaf69dbae00f99135bb116081070623639490f88 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
   let _i = 0_usize;
   loop {
index 9c46ba2cb9bbfefdc0e3f0c074ed5c0fc120a020..c2ad9a6ef73e1e3736c585dfe9ce3f04bd380692 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 /* Make sure a loop{} can be the tailexpr in the body
 of a diverging function */
 
index d96ff869fa0ab06567d81b4d1a1f8b4c263cb99e..399920a7e315cdb033feec21ad8c373994cff058 100644 (file)
 
 // Issue #12512.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let mut foo = Vec::new();
     'foo: for i in &[1, 2, 3] {
         foo.push(*i);
     }
 }
-
diff --git a/src/test/run-pass/loop-labeled-break-value.rs b/src/test/run-pass/loop-labeled-break-value.rs
new file mode 100644 (file)
index 0000000..4f03b45
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+fn main() {
+    'outer: loop {
+        let _: i32 = loop { break 'outer };
+    }
+    'outer: loop {
+        let _: i32 = loop { loop { break 'outer } };
+    }
+}
index 2582c2e61479c254a4c1c2f56420c05d0d287cf6..689e17c170d9069c99087f77df41bb58ed854929 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct S;
 // Ensure S is moved, not copied, on assignment.
 impl Drop for S { fn drop(&mut self) { } }
index 88711a4605962b76e98906a68624d57f1582bed0..70f2830555a4b134c33d41a44abb23dae38a10f9 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = vec!(10, 20, 30);
     let mut sum = 0;
index 80b2f408c1915674ad74da5987f5eb904bb59df5..d582fc3b721b4d0fc7cb3892908f415205e18233 100644 (file)
@@ -14,7 +14,7 @@ pub fn main() {
 
     macro_rules! mylambda_tt {
         ($x:ident, $body:expr) => ({
-            fn f($x: int) -> int { return $body; };
+            fn f($x: isize) -> isize { return $body; };
             f
         })
     }
index 521aef4b5ba5b0b02bebe2e30381d75fc3d8c512..2752fc88b456b2b45c171d1a19bdf4d27d4f768d 100644 (file)
@@ -10,6 +10,8 @@
 
 // ignore-pretty - token trees can't pretty print
 
+#![feature(custom_attribute)]
+
 macro_rules! compiles_fine {
     (#[$at:meta]) => {
         // test that the different types of attributes work
index 6c568d6d493ca9d2aa352280ea4a6f3ea5e21707..496534a5362f3bfd5cd33064ddab9d53f01d769e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! do_block{
     ($val:block) => {$val}
 }
index efee9ba963a1e97393f7fa146ec1d2468df1e170..58b09fa492192639d9749854675f3ea9a8ee09e8 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:macro_crate_def_only.rs
 
+// pretty-expanded FIXME #23616
+
 #[macro_use] #[no_link]
 extern crate macro_crate_def_only;
 
index cb919297b04064c2ef0042157ad8bf89c07cb322..ed7b1cbacadd7f401a516011944c9f6231a62708 100644 (file)
@@ -12,7 +12,7 @@
 // ignore-stage1
 
 #[macro_use]
-extern crate "macro_crate_nonterminal" as new_name;
+extern crate macro_crate_nonterminal as new_name;
 
 pub fn main() {
     new_name::check_local();
index fbbe0105cf4fe3dc8e64185c363d3bf64344238e..557f982713a17a52ea3ef61b34a9178a69071dc5 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn increment(x: uint) -> uint {
+// pretty-expanded FIXME #23616
+
+pub fn increment(x: usize) -> usize {
     x + 1
 }
 
index c4012e2cf3c7e4459d30492642b5d0b879d5ce1e..fd21ed0150ab04a0a081f53273ccd72ccc5d418d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! foo2 {
     () => {
         "foo"
index 01362f0f83f90ce4e287ffe488842966144a9520..6a3a495f2f1998f92755c080881775f4db6371c1 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     vec![1_usize, 2, 3].len();
 }
-
index 069aeb9220e604a70ecd87ebdf9988ca8072bbfe..e6b5d50b36e6d2808aaa14fa940dd9e6d1d95253 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! overly_complicated {
     ($fnname:ident, $arg:ident, $ty:ty, $body:block, $val:expr, $pat:pat, $res:path) =>
     ({
@@ -23,7 +25,7 @@ macro_rules! overly_complicated {
 }
 
 pub fn main() {
-    assert!(overly_complicated!(f, x, Option<uint>, { return Some(x); },
-                               Some(8_usize), Some(y), y) == 8_usize)
+    assert!(overly_complicated!(f, x, Option<usize>, { return Some(x); },
+                               Some(8), Some(y), y) == 8)
 
 }
index ce748967498387ad24166e01167ee5b23f872074..9fafeb6531dcade6b15956eda506c2636dc3c97d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! four {
     () => (4)
 }
index 47e3a0723993e2240f1fd499fd194d1758282efc..605cade2b3f7e556dbc864d34179cc713cbbd958 100644 (file)
@@ -38,4 +38,3 @@ pub fn main() {
     emit!(baz);
     println!("{}", MISTYPED);
 }
-
index fd16958d8964b9ab259951290d586acd97107c9c..cb1540459771b335c583807cad102ab020ce756d 100644 (file)
@@ -8,14 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct A;
 
-macro_rules! make_thirteen_method {() => (fn thirteen(&self)->int {13})}
+macro_rules! make_thirteen_method {() => (fn thirteen(&self)->isize {13})}
 impl A { make_thirteen_method!(); }
 
 fn main() {
     assert_eq!(A.thirteen(),13);
 }
-
-
-
index c6efc2f2bc83bbbd1180c747490c68d1bab8255c..f3367ff2b410f7ba426c473a8718eebba4709f8a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! list {
     ( ($($id:ident),*) ) => (());
     ( [$($id:ident),*] ) => (());
index 1a77eee824b6d31107c86294bb3d7afc39064eeb..ebd58f772284a77320fe68b6abbb9f53090e05f7 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! higher_order {
     (subst $lhs:tt => $rhs:tt) => ({
             macro_rules! anon { $lhs => $rhs }
index 6f2626a5af51ef7b45d8571893ff5d99bf42e014..659113d4e0c95e6c6393bb97758457ccca5a178b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! mypat {
     () => (
         Some('y')
@@ -38,7 +40,7 @@ macro_rules! ident_pat {
     )
 }
 
-fn f(c: Option<char>) -> uint {
+fn f(c: Option<char>) -> usize {
     match c {
         Some('x') => 1,
         mypat!() => 2,
@@ -47,9 +49,9 @@ fn f(c: Option<char>) -> uint {
 }
 
 pub fn main() {
-    assert_eq!(1_usize, f(Some('x')));
-    assert_eq!(2_usize, f(Some('y')));
-    assert_eq!(3_usize, f(None));
+    assert_eq!(1, f(Some('x')));
+    assert_eq!(2, f(Some('y')));
+    assert_eq!(3, f(None));
 
     assert_eq!(1, match Some('x') {
         Some(char_x!()) => 1,
index 4aa1587943413de7cc5fa0be6948fc642054c7ac..2e8806229778e7279d9d42e131a673aed48fbaac 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod m {
-    pub type t = int;
+    pub type t = isize;
 }
 
 macro_rules! foo {
index 3aa029870988a510c750571bf0817184f89865e4..0d8b86012d6e0285dcb9c04f596a40653b05f360 100644 (file)
@@ -12,7 +12,7 @@
 
 macro_rules! myfn {
     ( $f:ident, ( $( $x:ident ),* ), $body:block ) => (
-        fn $f( $( $x : int),* ) -> int $body
+        fn $f( $( $x : isize),* ) -> isize $body
     )
 }
 
index f180922a052a2c327969c5ca0b8f815a29cc305e..0938c16c30492985be9d483ec15f559c4c7cdc3e 100644 (file)
@@ -10,6 +10,8 @@
 
 // compile-flags: --cfg foo
 
+// pretty-expanded FIXME #23616
+
 #[cfg(foo)]
 macro_rules! foo { () => (1) }
 
index d683979462bd27b0747090fb35b3d8ae7e9e4bff..cf48c325f1f24b6c6d795abbf960a3502487cb95 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[cfg(foo)]
 macro_rules! foo { () => (1) }
 
@@ -17,4 +19,3 @@ macro_rules! foo { () => (2) }
 pub fn main() {
     assert_eq!(foo!(), 2);
 }
-
index cb52ba74bbd683088d2c1807cc72bb8c253766ac..4881a5ab647ec0996efde72f97ad3c368aae8120 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+#![feature(std_misc)]
+
+use std::thread;
 
 macro_rules! expr { ($e: expr) => { $e } }
 
 macro_rules! spawn {
     ($($code: tt)*) => {
-        expr!(Thread::spawn(move|| {$($code)*}))
+        expr!(thread::spawn(move|| {$($code)*}))
     }
 }
 
index 5c681b8e6e765c3a20fde78072d836235aff8ad1..9ecf186d5b11e5825c569a98d2eae534b11b9671 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:macro_with_super_1.rs
 
+// pretty-expanded FIXME #23616
+
 #[macro_use]
 extern crate macro_with_super_1;
 
index dfefe84518c405231f9fd26eead80853b69e0251..1b4dfb869d413dfb857aee0c1baa8412140f10d7 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct NewBool(bool);
 
 enum Direction {
@@ -36,8 +38,8 @@ const VARIANT2_NORTH: EnumWithStructVariants = EnumWithStructVariants::Variant2
     dir: Direction::North };
 
 pub mod glfw {
-    #[derive(Copy)]
-    pub struct InputState(uint);
+    #[derive(Copy, Clone)]
+    pub struct InputState(usize);
 
     pub const RELEASE  : InputState = InputState(0);
     pub const PRESS    : InputState = InputState(1);
@@ -99,7 +101,7 @@ fn issue_13731() {
 fn issue_15393() {
     #![allow(dead_code)]
     struct Flags {
-        bits: uint
+        bits: usize
     }
 
     const FOO: Flags = Flags { bits: 0x01 };
index b359614fa9adb2c365ec34174d72d8a2c858ae00..574c4b9f00eabb93de0a4520a06bb06364711e6f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unnecessary_allocation)]
 
 fn f1(ref_string: &str) -> String {
index 949fad11344de0bc6eef4eb52978c6c2fd0a22a1..4fa951b34794b142e586b467d6f761394ae33abf 100644 (file)
@@ -9,5 +9,7 @@
 // except according to those terms.
 
 // n.b. This was only ever failing with optimization disabled.
-fn a() -> int { match return 1 { 2 => 3, _ => panic!() } }
+// pretty-expanded FIXME #23616
+
+fn a() -> isize { match return 1 { 2 => 3, _ => panic!() } }
 pub fn main() { a(); }
index 74cf3faea46ee1646441319f0f7debae7b5a7fe3..7745410fa434a9adbb10a28633334083a1dba6cb 100644 (file)
@@ -10,7 +10,7 @@
 
 
 pub fn main() {
-    let i: int =
-        match Some::<int>(3) { None::<int> => { panic!() } Some::<int>(_) => { 5 } };
+    let i: isize =
+        match Some::<isize>(3) { None::<isize> => { panic!() } Some::<isize>(_) => { 5 } };
     println!("{}", i);
 }
index 5cc512abfe37c6aa516181a0743a84ea3a9ded86..06d19cec185bb3cf28775a8c5e69198bfa731869 100644 (file)
 
 // regression test for issue #5625
 
+// pretty-expanded FIXME #23616
+
 enum E {
-    Foo{f : int},
+    Foo{f : isize},
     Bar
 }
 
index fdfadf8eb444fd55dbd7851818bdf26747bdb230..e4766f32a57f3d0e5623667eec36b2b64a2d3883 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum E {
-    Foo{f : int},
+    Foo{f : isize},
     Bar
 }
 
index 6883187c402f3a3af8aa398e141cfd8fe03e1711..d481c02eb410aa7828fd1b6d2250cadcba5105bd 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct Pair { a: Box<int>, b: Box<int> }
+struct Pair { a: Box<isize>, b: Box<isize> }
 
 pub fn main() {
-    let mut x = box Pair {a: box 10, b: box 20};
+    let mut x: Box<_> = box Pair {a: box 10, b: box 20};
     let x_internal = &mut *x;
     match *x_internal {
       Pair {a: ref mut a, b: ref mut _b} => {
index e4886ddaa0ed3155943fe8221cec54a23a66f638..27bbbc936ae5c4ae3f97a54d663841063a7393c5 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Foo {
-    B { b1: int, bb1: int},
+    B { b1: isize, bb1: isize},
 }
 
 macro_rules! match_inside_expansion {
index a9039885296b0020200ff23ade39b4753ebbd31d..b47732b325a9802e0c542bd38a4231c7c783f590 100644 (file)
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 fn foo<T>(y: Option<T>) {
-    let mut x: int;
-    let mut rs: Vec<int> = Vec::new();
+    let mut x: isize;
+    let mut rs: Vec<isize> = Vec::new();
     /* tests that x doesn't get put in the precondition for the
        entire if expression */
 
@@ -25,4 +25,4 @@ fn foo<T>(y: Option<T>) {
     return;
 }
 
-pub fn main() { println!("hello"); foo::<int>(Some::<int>(5)); }
+pub fn main() { println!("hello"); foo::<isize>(Some::<isize>(5)); }
index 433cf23626bbfa8f17b146cca75132c506e5837d..e558e88e03d9cc954e13de9ead6a87b6a715f279 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct X { x: int }
+// pretty-expanded FIXME #23616
+
+struct X { x: isize }
 
 pub fn main() {
     let _x = match 0 {
index fe12b7c1585681f23a182737ec57a6f373976723..a2b35e6558c47873c7fc860b2888759e6c74f523 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct X { x: int }
+// pretty-expanded FIXME #23616
+
+struct X { x: isize }
 
 pub fn main() {
     let _x = match 0 {
index b3c7f3db512b1823b4b05ab167abf20e77baa8e7..1b3594a0a792ef5b81ff434e53b4fc5febd24632 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 mod m1 {
     pub enum foo { foo1, foo2, }
 }
index abb78fc83107796484271a256be287d04e1e20ff..d230f18f2bd84fe8c92aa2604c70ccb8e66c0a20 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let value = Some(1);
     assert_eq!(match value {
index 4265d0a5406aa9c59b842c54ddd5a65f762d6182..33c77f33c44bdabf139a1f4284c4af34f1f3788b 100644 (file)
@@ -10,7 +10,7 @@
 
 
 
-fn altlit(f: int) -> int {
+fn altlit(f: isize) -> isize {
     match f {
       10 => { println!("case 10"); return 20; }
       11 => { println!("case 11"); return 22; }
index d76c8faa5b6ce3dbfde6029dea0cba7be846808f..ccf23b87ea3b8a9acbf98977dcd9a5ecce504878 100644 (file)
@@ -10,7 +10,7 @@
 
 enum maybe<T> { nothing, just(T), }
 
-fn foo(x: maybe<int>) {
+fn foo(x: maybe<isize>) {
     match x {
         maybe::nothing => { println!("A"); }
         maybe::just(_a) => { println!("B"); }
index 92a753902228d59f9838bff9960beca574238d45..8e729e2eab38628cf7ec102fa1e971f0e02b7a0d 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
-fn altsimple(f: int) { match f { _x => () } }
+// pretty-expanded FIXME #23616
+
+fn altsimple(f: isize) { match f { _x => () } }
 
 pub fn main() { }
index 2a0a2b208875fa97005f21eea6f733bdae28846c..ac070cb1f2542d593c25a798b971f63ae8207c52 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 #![allow(unused_variable)]
 
 enum thing { a, b, c, }
 
-fn foo<F>(it: F) where F: FnOnce(int) { it(10); }
+fn foo<F>(it: F) where F: FnOnce(isize) { it(10); }
 
 pub fn main() {
     let mut x = true;
index bdf12d22edd0f776dc6abf7305f1fc251b60274e..70d3639a785fa1574b48d4b3eab9867630af249c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn test1() {
     // from issue 6338
     match ((1, "a".to_string()), (2, "b".to_string())) {
index 0feeea70221a4aa3dd445f99bd745752cf2fcbd6..9aafcda1b02add7506e0697b741d176ef0658806 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const s: int = 1;
-const e: int = 42;
+// pretty-expanded FIXME #23616
+
+const s: isize = 1;
+const e: isize = 42;
 
 pub fn main() {
     match 7 {
diff --git a/src/test/run-pass/match-reassign.rs b/src/test/run-pass/match-reassign.rs
new file mode 100644 (file)
index 0000000..759296a
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2015 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.
+
+// Regression test for #23698: The reassignment checker only cared
+// about the last assigment in a match arm body
+
+// Use an extra function to make sure no extra assignments
+// are introduced by macros in the match statement
+fn check_eq(x: i32, y: i32) {
+    assert_eq!(x, y);
+}
+
+#[allow(unused_assignments)]
+fn main() {
+    let mut x = Box::new(1);
+    match x {
+        y => {
+            x = Box::new(2);
+            let _tmp = 1; // This assignment used to throw off the reassignment checker
+            check_eq(*y, 1);
+        }
+    }
+}
index a83bc73457e020b4bdac0682be4294f22cdff004..1e2ebf42a9911d914df05f1bd4bc2834aebba05e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::sync::Mutex;
 
 pub fn main() {
index 8d1e483bcd848cd3cc45d65a8b119e3c27b6aec1..41f00e58ff76915e7544cc6f96e2fd3e72c94933 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let mut v = Some(22);
     match v {
index 266f7cdde11af0281836105808fcd27b6628c018..26c91e1703cafed5486662d00f310410f0ce3da4 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct Rec {
-    f: int
+    f: isize
 }
 
 fn destructure(x: &mut Rec) {
index 0b613df18ee833668e2917cf859a94dee11b2dd0..826edb30b36f4ec38680c4510a27ee712518f9e1 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn destructure(x: Option<int>) -> int {
+// pretty-expanded FIXME #23616
+
+fn destructure(x: Option<isize>) -> isize {
     match x {
       None => 0,
       Some(ref v) => *v
diff --git a/src/test/run-pass/match-ref-unsized.rs b/src/test/run-pass/match-ref-unsized.rs
new file mode 100644 (file)
index 0000000..4de0282
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+// Binding unsized expressions to ref patterns
+
+pub fn main() {
+    let ref a = *"abcdef";
+    assert_eq!(a, "abcdef");
+
+    match *"12345" {
+        ref b => { assert_eq!(b, "12345") }
+    }
+}
index 164cc99e188eaa8cb8fd1d7fd3e0e7555f619843..21b806f80dee4ee17bee4a6b4b6dd473a0b30079 100644 (file)
 // around this problem locally by renaming the constant in the `use`
 // form to an uppercase identifier that placates the lint.
 
+// pretty-expanded FIXME #23616
+
 #![deny(non_upper_case_globals)]
 
-pub const A : int = 97;
+pub const A : isize = 97;
 
 fn f() {
     let r = match (0,0) {
@@ -35,7 +37,7 @@ fn f() {
 
 mod m {
     #[allow(non_upper_case_globals)]
-    pub const aha : int = 7;
+    pub const aha : isize = 7;
 }
 
 fn g() {
index 301d99a7e20b32b807b9dcce761162c782b01d47..5d8958c6b9e87775b61b3678cfbb5b4eaa5f33a0 100644 (file)
@@ -10,6 +10,8 @@
 
 // Issue #53
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     match "test" { "not-test" => panic!(), "test" => (), _ => panic!() }
 
index 6d5658aa13cbfcebc746a231053f359e761663ec..450b310b8f40813b09fdb345023d7e2a8606c1d7 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct Foo{
-    f : int,
+    f : isize,
 }
 
 pub fn main() {
index cf940a630569daece147b538e72a1b6477785d8e..82d29f9050bfc0d72555ad59ca3cb7e75e9bd2c6 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 enum color {
-    rgb(int, int, int),
-    rgba(int, int, int, int),
-    hsl(int, int, int),
+    rgb(isize, isize, isize),
+    rgba(isize, isize, isize, isize),
+    hsl(isize, isize, isize),
 }
 
-fn process(c: color) -> int {
-    let mut x: int;
+fn process(c: color) -> isize {
+    let mut x: isize;
     match c {
       color::rgb(r, _, _) => { x = r; }
       color::rgba(_, _, _, a) => { x = a; }
index beb125492b2c154ead23fd4230606e7af6c1a15a..d4f4f3bb27eac8b247993d8d59985dbd837fc565 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn foo(x: Option<Box<int>>, b: bool) -> int {
+fn foo(x: Option<Box<isize>>, b: bool) -> isize {
     match x {
       None => { 1 }
       Some(ref x) if b => { *x.clone() }
index eb6b2176e5140d5a0edf1a6a237446172b35ee5d..f9b49281bab0c648ef6db5e89f6da1bfcb00beb1 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(advanced_slice_patterns)]
+#![feature(slice_patterns)]
 
 fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) -> &'static str {
     match (l1, l2) {
@@ -57,22 +60,22 @@ fn match_nested_vecs_snoc<'a, T>(l1: Option<&'a [T]>, l2: Result<&'a [T], ()>) -
 fn main() {
     assert_eq!(match_vecs(&[1, 2], &[2, 3]), "both non-empty");
     assert_eq!(match_vecs(&[], &[1, 2, 3, 4]), "one empty");
-    assert_eq!(match_vecs::<uint>(&[], &[]), "both empty");
+    assert_eq!(match_vecs::<usize>(&[], &[]), "both empty");
     assert_eq!(match_vecs(&[1, 2, 3], &[]), "one empty");
 
     assert_eq!(match_vecs_cons(&[1, 2], &[2, 3]), "both non-empty");
     assert_eq!(match_vecs_cons(&[], &[1, 2, 3, 4]), "one empty");
-    assert_eq!(match_vecs_cons::<uint>(&[], &[]), "both empty");
+    assert_eq!(match_vecs_cons::<usize>(&[], &[]), "both empty");
     assert_eq!(match_vecs_cons(&[1, 2, 3], &[]), "one empty");
 
     assert_eq!(match_vecs_snoc(&[1, 2], &[2, 3]), "both non-empty");
     assert_eq!(match_vecs_snoc(&[], &[1, 2, 3, 4]), "one empty");
-    assert_eq!(match_vecs_snoc::<uint>(&[], &[]), "both empty");
+    assert_eq!(match_vecs_snoc::<usize>(&[], &[]), "both empty");
     assert_eq!(match_vecs_snoc(&[1, 2, 3], &[]), "one empty");
 
     assert_eq!(match_nested_vecs_cons(None, Ok::<&[_], ()>(&[4_usize, 2_usize])),
                "None, Ok(at least two elements)");
-    assert_eq!(match_nested_vecs_cons::<uint>(None, Err(())), "None, Ok(less than one element)");
+    assert_eq!(match_nested_vecs_cons::<usize>(None, Err(())), "None, Ok(less than one element)");
     assert_eq!(match_nested_vecs_cons::<bool>(Some::<&[_]>(&[]), Ok::<&[_], ()>(&[])),
                "Some(empty), Ok(empty)");
     assert_eq!(match_nested_vecs_cons(Some::<&[_]>(&[1]), Err(())), "Some(non-empty), any");
@@ -81,7 +84,7 @@ fn main() {
 
     assert_eq!(match_nested_vecs_snoc(None, Ok::<&[_], ()>(&[4_usize, 2_usize])),
                "None, Ok(at least two elements)");
-    assert_eq!(match_nested_vecs_snoc::<uint>(None, Err(())), "None, Ok(less than one element)");
+    assert_eq!(match_nested_vecs_snoc::<usize>(None, Err(())), "None, Ok(less than one element)");
     assert_eq!(match_nested_vecs_snoc::<bool>(Some::<&[_]>(&[]), Ok::<&[_], ()>(&[])),
                "Some(empty), Ok(empty)");
     assert_eq!(match_nested_vecs_snoc(Some::<&[_]>(&[1]), Err(())), "Some(non-empty), any");
index 04a0204d206a25722817e5825d52c9a2baa07ee8..e368aeb976934f5cec109cba1e986d6b2361e093 100644 (file)
@@ -11,6 +11,8 @@
 // Tests that matching rvalues with drops does not crash.
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     match vec!(1, 2, 3) {
         x => {
index 05c6aac90e39c9982830af973cf7a1b4119e9c5a..79b197f08e2718616db5e1bff9e6ce00a557baf9 100644 (file)
@@ -8,16 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::uint;
-
 pub fn main() {
     // sometimes we have had trouble finding
     // the right type for f, as we unified
     // bot and u32 here
-    let f = match "1234".parse::<uint>().ok() {
+    let f = match "1234".parse::<usize>().ok() {
         None => return (),
         Some(num) => num as u32
     };
-    assert_eq!(f, 1234u32);
+    assert_eq!(f, 1234);
     println!("{}", f)
 }
index e3c375f8b0fdea321aa5019b6ae821bb6cf367fc..f0844b8e1eb1770d24a5058aa71dfdaaa8798274 100644 (file)
@@ -9,27 +9,27 @@
 // except according to those terms.
 
 trait Product {
-    fn product(&self) -> int;
+    fn product(&self) -> isize;
 }
 
 struct Foo {
-    x: int,
-    y: int,
+    x: isize,
+    y: isize,
 }
 
 impl Foo {
-    pub fn sum(&self) -> int {
+    pub fn sum(&self) -> isize {
         self.x + self.y
     }
 }
 
 impl Product for Foo {
-    fn product(&self) -> int {
+    fn product(&self) -> isize {
         self.x * self.y
     }
 }
 
-fn Foo(x: int, y: int) -> Foo {
+fn Foo(x: isize, y: isize) -> Foo {
     Foo { x: x, y: y }
 }
 
index 92af96e0d8f2c81068f5958e1bd72ef810c47e73..400ecda411e18b98df5ebd1c5076a49e62bdb0f0 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // pp-exact - Make sure we print all the attributes
+// pretty-expanded FIXME #23616
+
 #![allow(unused_attribute)]
 #![feature(custom_attribute)]
 
@@ -21,7 +23,7 @@ trait frobable {
 }
 
 #[int_frobable]
-impl frobable for int {
+impl frobable for isize {
     #[frob_attr1]
     fn frob(&self) {
         #![frob_attr2]
index cec9753a2fecaed27bcb197162ed4f4fef01cde2..3babb543bf2a1d752283922c0367569036eefff1 100644 (file)
@@ -11,6 +11,8 @@
 // Check that we successfully handle methods where the `self` type has
 // an early-bound lifetime. Issue #18208.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 use std::marker;
index 0ad600dd85d9338a1ed33c230053c369fa0098c7..7cc762c93482665fac08891ed2119e393f2f98b5 100644 (file)
 // type is `&mut [u8]`, passes in a pointer to the lvalue and not a
 // temporary. Issue #19147.
 
-use std::raw;
+// pretty-expanded FIXME #23616
+
+#![feature(core, old_io)]
+
 use std::mem;
 use std::slice;
 use std::old_io::IoResult;
@@ -23,14 +26,14 @@ trait MyWriter {
 
 impl<'a> MyWriter for &'a mut [u8] {
     fn my_write(&mut self, buf: &[u8]) -> IoResult<()> {
-        slice::bytes::copy_memory(*self, buf);
+        slice::bytes::copy_memory(buf, *self);
 
         let write_len = buf.len();
         unsafe {
-            *self = mem::transmute(raw::Slice {
-                data: self.as_ptr().offset(write_len as int),
-                len: self.len() - write_len,
-            });
+            *self = slice::from_raw_parts_mut(
+                self.as_mut_ptr().offset(write_len as isize),
+                self.len() - write_len
+            );
         }
 
         Ok(())
@@ -38,7 +41,7 @@ impl<'a> MyWriter for &'a mut [u8] {
 }
 
 fn main() {
-    let mut buf = [0_u8; 6];
+    let mut buf = [0; 6];
 
     {
         let mut writer: &mut [_] = &mut buf;
index 73489948da5dee533eca22d7ada0e4347e80c758..3a1ce74a64c023b60bce4881d2769b27c5bf3ee9 100644 (file)
@@ -14,6 +14,8 @@
 // winnowing stage of method resolution failed to handle an associated
 // type projection.
 
+// pretty-expanded FIXME #23616
+
 #![feature(associated_types)]
 
 trait Hasher {
@@ -36,7 +38,7 @@ impl Hasher for SipHasher {
     fn finish(&self) -> u64 { 4 }
 }
 
-impl Hash<SipHasher> for int {
+impl Hash<SipHasher> for isize {
     fn hash(&self, h: &mut SipHasher) {}
 }
 
@@ -62,4 +64,3 @@ fn foo<K: Hash<SipHasher>>(map: &Map<SipState>) {
 }
 
 fn main() {}
-
index 6f72a163981c9d653e480ff4392c5089fa204a7e..3db726820708667d4cda13d77576beb6ded444f8 100644 (file)
 
 ///////////////////////////////////////////////////////////////////////////
 
+// pretty-expanded FIXME #23616
+
 trait MakeString {
     fn make_string(&self) -> String;
 }
 
-impl MakeString for int {
+impl MakeString for isize {
     fn make_string(&self) -> String {
         format!("{}", *self)
     }
 }
 
-impl MakeString for uint {
+impl MakeString for usize {
     fn make_string(&self) -> String {
         format!("{}", *self)
     }
@@ -44,13 +46,13 @@ fn foo<F:Foo>(f: &F) -> String {
 ///////////////////////////////////////////////////////////////////////////
 
 struct SomeStruct {
-    field: int,
+    field: isize,
 }
 
 impl Foo for SomeStruct {
-    type F = int;
+    type F = isize;
 
-    fn get(&self) -> &int {
+    fn get(&self) -> &isize {
         &self.field
     }
 }
@@ -58,13 +60,13 @@ impl Foo for SomeStruct {
 ///////////////////////////////////////////////////////////////////////////
 
 struct SomeOtherStruct {
-    field: uint,
+    field: usize,
 }
 
 impl Foo for SomeOtherStruct {
-    type F = uint;
+    type F = usize;
 
-    fn get(&self) -> &uint {
+    fn get(&self) -> &usize {
         &self.field
     }
 }
index 15eb2ae2e4b49dbfa97f5258e67d03a9c7b1d448..6877bf376a6589eaa0c45b90125f2b7d92bdc974 100644 (file)
@@ -13,6 +13,8 @@
 // know not to stop at the blanket, we have to recursively evaluate
 // the `T:Foo` bound.
 
+// pretty-expanded FIXME #23616
+
 use std::marker::Sized;
 
 // Note: this must be generic for the problem to show up
index e9a1e19d4bf8416494606a25cdb4285f61cd1910..768e7f94862acb194ad4858781d947f7f3dc7284 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test method calls with self as an argument (cross-crate)
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -26,5 +28,5 @@ fn main() {
 
     x.foo(&x);
 
-    assert!(method_self_arg1::get_count() == 2u64*3*3*3*5*5*5*7*7*7);
+    assert!(method_self_arg1::get_count() == 2*3*3*3*5*5*5*7*7*7);
 }
index 7fa810ce1549ad9f671caf94a6907225a87c887b..b40333c67c6ac2ec8aa82bcfbeb7ecc1bab52f4c 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test method calls with self as an argument (cross-crate)
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -30,5 +32,5 @@ fn main() {
 
     x.run_trait();
 
-    assert!(method_self_arg2::get_count() == 2u64*2*3*3*5*5*7*7*11*11*13*13*17);
+    assert!(method_self_arg2::get_count() == 2*2*3*3*5*5*7*7*11*11*13*13*17);
 }
index c79141d97950045a9b1f2e68e9bbe7ad44f6f67d..f0ca0a70acc96a4f828b835e99d4cb25b19d817f 100644 (file)
 
 // Test method calls with self as an argument
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 static mut COUNT: u64 = 1;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Foo;
 
 trait Bar : Sized {
@@ -75,5 +77,5 @@ fn main() {
 
     x.baz();
 
-    unsafe { assert!(COUNT == 2u64*2*3*3*5*5*7*7*11*11*13*13*17); }
+    unsafe { assert!(COUNT == 2*2*3*3*5*5*7*7*11*11*13*13*17); }
 }
index de24297c7b51af6f3fcd5d4147d04cd868d73697..dfc121192228d4a21fa27bf8087d44c464c3d06d 100644 (file)
 
 // Test method calls with self as an argument
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-static mut COUNT: uint = 1;
+static mut COUNT: usize = 1;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Foo;
 
 impl Foo {
@@ -54,5 +56,5 @@ fn main() {
 
     x.foo(&x);
 
-    unsafe { assert!(COUNT == 2_usize*3*3*3*5*5*5*7*7*7); }
+    unsafe { assert!(COUNT == 2*3*3*3*5*5*5*7*7*7); }
 }
index 414b08b4335c6ebab29138603d61b3a5263b5406..d0e0427f37808a602924bf355ba51379a46eeee3 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we pick which version of `foo` to run based on the
 // type that is (ultimately) inferred for `x`.
 
+// pretty-expanded FIXME #23616
+
 trait foo {
     fn foo(&self) -> i32;
 }
index 7463783be59892fe95a343a2eb4a220c5f773e45..2ceff22adb9eb4da6e5d204d9b00c8c6711056e1 100644 (file)
@@ -8,40 +8,49 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test that we pick which version of `Foo` to run based on whether
-// the type we (ultimately) inferred for `x` is copyable or not.
-//
-// In this case, the two versions are both impls of same trait, and
-// hence we we can resolve method even without knowing yet which
-// version will run (note that the `push` occurs after the call to
-// `foo()`).
+// Test that when we write `x.foo()`, we do nothave to know the
+// complete type of `x` in order to type-check the method call. In
+// this case, we know that `x: Vec<_1>`, but we don't know what type
+// `_1` is (because the call to `push` comes later). To pick between
+// the impls, we would have to know `_1`, since we have to know
+// whether `_1: MyCopy` or `_1 == Box<i32>`.  However (and this is the
+// point of the test), we don't have to pick between the two impls --
+// it is enough to know that `foo` comes from the `Foo` trait. We can
+// translate the call as `Foo::foo(&x)` and let the specific impl get
+// chosen later.
+
+// pretty-expanded FIXME #23616
 
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 trait Foo {
-    fn foo(&self) -> int;
+    fn foo(&self) -> isize;
 }
 
-impl<T:Copy> Foo for Vec<T> {
-    fn foo(&self) -> int {1}
+trait MyCopy { fn foo(&self) { } }
+impl MyCopy for i32 { }
+
+impl<T:MyCopy> Foo for Vec<T> {
+    fn foo(&self) -> isize {1}
 }
 
-impl<T> Foo for Vec<Box<T>> {
-    fn foo(&self) -> int {2}
+impl Foo for Vec<Box<i32>> {
+    fn foo(&self) -> isize {2}
 }
 
-fn call_foo_copy() -> int {
+fn call_foo_copy() -> isize {
     let mut x = Vec::new();
     let y = x.foo();
-    x.push(0_usize);
+    x.push(0_i32);
     y
 }
 
-fn call_foo_other() -> int {
-    let mut x = Vec::new();
+fn call_foo_other() -> isize {
+    let mut x: Vec<_> = Vec::new();
     let y = x.foo();
-    x.push(box 0);
+    let z: Box<i32> = box 0;
+    x.push(z);
     y
 }
 
index fbecb6851b68758dd44ad067850761c22dafde8b..77072bdec905190cb483a1cacd74e29c7fa49c36 100644 (file)
 // Test that we select between traits A and B. To do that, we must
 // consider the `Sized` bound.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 trait A {
     fn foo(self);
 }
@@ -28,7 +32,7 @@ impl<T> B for *const [T] {
 }
 
 fn main() {
-    let x: [int; 4] = [1,2,3,4];
-    let xptr = x.as_slice() as *const _;
+    let x: [isize; 4] = [1,2,3,4];
+    let xptr = &x[..] as *const [isize];
     xptr.foo();
 }
index 6337538a3329d4f075a4ed1285da077ae21c451e..f2ff0abfad8b8d53c2d2d3cd7520c67706784839 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we can use method notation to call methods based on a
 // where clause type, and not only type parameters.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
     fn foo(&self) -> i32;
 }
index 4a04a71f9a0162f4c4a828355dac1680d09468fe..3055f90ee259772e4472d49c75e278533d734d1d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct S<T> {
     contents: T,
 }
@@ -25,11 +27,11 @@ trait Trait<T> {
 }
 
 struct S2 {
-    contents: int,
+    contents: isize,
 }
 
-impl Trait<int> for S2 {
-    fn new<U>(x: int, _: U) -> S2 {
+impl Trait<isize> for S2 {
+    fn new<U>(x: isize, _: U) -> S2 {
         S2 {
             contents: x,
         }
@@ -37,7 +39,6 @@ impl Trait<int> for S2 {
 }
 
 pub fn main() {
-    let _ = S::<int>::new::<f64>(1, 1.0);
-    let _: S2 = Trait::<int>::new::<f64>(1, 1.0);
+    let _ = S::<isize>::new::<f64>(1, 1.0);
+    let _: S2 = Trait::<isize>::new::<f64>(1, 1.0);
 }
-
diff --git a/src/test/run-pass/minmax-stability-issue-23687.rs b/src/test/run-pass/minmax-stability-issue-23687.rs
new file mode 100644 (file)
index 0000000..86dd1a0
--- /dev/null
@@ -0,0 +1,83 @@
+// Copyright 2015 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(core)]
+use std::fmt::Debug;
+use std::cmp::{self, PartialOrd, Ordering};
+use std::iter::MinMaxResult::MinMax;
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+struct Foo {
+    n: u8,
+    name: &'static str
+}
+
+impl PartialOrd for Foo {
+    fn partial_cmp(&self, other: &Foo) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Foo {
+    fn cmp(&self, other: &Foo) -> Ordering {
+        self.n.cmp(&other.n)
+    }
+}
+
+fn main() {
+    let a = Foo { n: 4, name: "a" };
+    let b = Foo { n: 4, name: "b" };
+    let c = Foo { n: 8, name: "c" };
+    let d = Foo { n: 8, name: "d" };
+    let e = Foo { n: 22, name: "e" };
+    let f = Foo { n: 22, name: "f" };
+
+    let data = [a, b, c, d, e, f];
+
+    // `min` should return the left when the values are equal
+    assert_eq!(data.iter().min(), Some(&a));
+    assert_eq!(data.iter().min_by(|a| a.n), Some(&a));
+    assert_eq!(cmp::min(a, b), a);
+    assert_eq!(cmp::min(b, a), b);
+    assert_eq!(cmp::partial_min(a, b), Some(a));
+    assert_eq!(cmp::partial_min(b, a), Some(b));
+
+    // `max` should return the right when the values are equal
+    assert_eq!(data.iter().max(), Some(&f));
+    assert_eq!(data.iter().max_by(|a| a.n), Some(&f));
+    assert_eq!(cmp::max(e, f), f);
+    assert_eq!(cmp::max(f, e), e);
+    assert_eq!(cmp::partial_max(e, f), Some(f));
+    assert_eq!(cmp::partial_max(f, e), Some(e));
+
+    // Similar for `min_max`
+    assert_eq!(data.iter().min_max(), MinMax(&a, &f));
+    assert_eq!(data[1..5].iter().min_max(), MinMax(&b, &e));
+    assert_eq!(data[2..4].iter().min_max(), MinMax(&c, &d));
+
+    let mut presorted = data.to_vec();
+    presorted.sort();
+    assert_stable(&presorted);
+
+    let mut presorted = data.to_vec();
+    presorted.sort_by(|a, b| a.cmp(b));
+    assert_stable(&presorted);
+
+    // Assert that sorted and min/max are the same
+    fn assert_stable<T: Ord + Debug>(presorted: &[T]) {
+        for slice in presorted.windows(2) {
+            let a = &slice[0];
+            let b = &slice[1];
+
+            assert_eq!(a, cmp::min(a, b));
+            assert_eq!(b, cmp::max(a, b));
+        }
+    }
+}
index 388d2e4905fab9f07148e7c15d3a9c25d7403f93..836f2960d717465c6c8d5825355563456e8cf832 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f() -> int {
+// pretty-expanded FIXME #23616
+
+fn f() -> isize {
     mod m {
-        pub fn g() -> int { 720 }
+        pub fn g() -> isize { 720 }
     }
 
     m::g()
index f03ec7b6f3e125a00595214df670d4a4ea4176ec..ba23197b83c7f202678f886f18b366728b526513 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
 // pretty-print such view items. If that happens again, this should
 // begin failing.
 
+// pretty-expanded FIXME #23616
+
 mod m {
-    pub fn f() -> Vec<int> { Vec::new() }
+    pub fn f() -> Vec<isize> { Vec::new() }
 }
 
 pub fn main() { let _x = m::f(); }
index a3c1628725a07ed4b8525df1c021d8dcc0da0d50..58c1beee3be70324333f93e76f4ff6dca68ca20e 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn foo() -> int { 10 }
+pub fn foo() -> isize { 10 }
index a3c1628725a07ed4b8525df1c021d8dcc0da0d50..58c1beee3be70324333f93e76f4ff6dca68ca20e 100644 (file)
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn foo() -> int { 10 }
+pub fn foo() -> isize { 10 }
index 4d18decdc13a48fa3ca255efd31a630e913aaf0a..b7470811f6034bb1a547807d3b4219528ef7ca84 100644 (file)
@@ -10,4 +10,4 @@
 
 // ignore-test Not a test. Used by other tests
 
-pub fn foo() -> int { 10 }
+pub fn foo() -> isize { 10 }
index b1c1b64ba40033ef98c1f81f343d61320cc1aa2d..d6844f0f4abde59a177e5f3a74c6e263af23ae57 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod m {
     pub struct S {
-        pub x: int,
-        pub y: int
+        pub x: isize,
+        pub y: isize
     }
 }
 
index 457c0a35fd70f9a963fccd81f224b1dff69f41cf..9ccb8f2e6fdd9cb74b94a3c90afae36f77351223 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 trait vec_monad<A> {
     fn bind<B, F>(&self, f: F ) -> Vec<B> where F: FnMut(&A) -> Vec<B> ;
 }
@@ -37,18 +39,18 @@ impl<A> option_monad<A> for Option<A> {
     }
 }
 
-fn transform(x: Option<int>) -> Option<String> {
+fn transform(x: Option<isize>) -> Option<String> {
     x.bind(|n| Some(*n + 1) ).bind(|n| Some(n.to_string()) )
 }
 
 pub fn main() {
     assert_eq!(transform(Some(10)), Some("11".to_string()));
     assert_eq!(transform(None), None);
-    assert!((vec!("hi".to_string()))
+    assert_eq!((vec!("hi".to_string()))
         .bind(|x| vec!(x.clone(), format!("{}!", x)) )
-        .bind(|x| vec!(x.clone(), format!("{}?", x)) ) ==
-        vec!("hi".to_string(),
-             "hi?".to_string(),
-             "hi!".to_string(),
-             "hi!?".to_string()));
+        .bind(|x| vec!(x.clone(), format!("{}?", x)) ),
+        ["hi".to_string(),
+         "hi?".to_string(),
+         "hi!".to_string(),
+         "hi!?".to_string()]);
 }
index 726f205f5c4201f295a5d6a5517426ef09f571db..00e97ebc24e7ba5f5f1fa4b6a616a2cec0d6bc55 100644 (file)
@@ -18,7 +18,7 @@
  * and apply the wrong instance of the method `unwrap`.
  */
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct S<T> { i:u8, t:T }
 
 impl<T> S<T> {
@@ -27,10 +27,10 @@ impl<T> S<T> {
     }
 }
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 struct A((u32, u32));
 
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 struct B(u64);
 
 pub fn main() {
index 1164ef1a3c98e2406e83e7c0992cd2b0440c383a..12162ba9022aec3b0a6a07c526e0322f6124aef0 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::marker::MarkerTrait;
 
 trait Serializer : MarkerTrait {
@@ -17,7 +21,7 @@ trait Serializable {
     fn serialize<S:Serializer>(&self, s: S);
 }
 
-impl Serializable for int {
+impl Serializable for isize {
     fn serialize<S:Serializer>(&self, _s: S) { }
 }
 
@@ -29,7 +33,7 @@ impl<A:Serializable> Serializable for F<A> {
     }
 }
 
-impl Serializer for int {
+impl Serializer for isize {
 }
 
 pub fn main() {
index 018cd440cad343523c65327f3661fb0273f58bdb..ab9770b13d4514897846f30df797390957e5a8fe 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 #[derive(Clone)]
 struct Triple {
-    x: int,
-    y: int,
-    z: int,
+    x: isize,
+    y: isize,
+    z: isize,
 }
 
-fn test(x: bool, foo: Box<Triple>) -> int {
+fn test(x: bool, foo: Box<Triple>) -> isize {
     let bar = foo;
     let mut y: Box<Triple>;
     if x { y = bar; } else { y = box Triple{x: 4, y: 5, z: 6}; }
@@ -26,7 +28,7 @@ fn test(x: bool, foo: Box<Triple>) -> int {
 }
 
 pub fn main() {
-    let x = box Triple{x: 1, y: 2, z: 3};
+    let x: Box<_> = box Triple{x: 1, y: 2, z: 3};
     assert_eq!(test(true, x.clone()), 2);
     assert_eq!(test(true, x.clone()), 2);
     assert_eq!(test(true, x.clone()), 2);
index 50187ef8baad23fb8768c8e242b79c0a4e0ed139..c65e58a7b65023cce65ddb39c3e77c7ae993e00f 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct X { x: int, y: int, z: int }
+struct X { x: isize, y: isize, z: isize }
 
 pub fn main() {
-    let x = box X{x: 1, y: 2, z: 3};
+    let x: Box<_> = box X{x: 1, y: 2, z: 3};
     let y = x;
     assert!((y.y == 2));
 }
index 6561a9b2d5b565c24a3f6c525400170ee4d7b4af..054b57b2f432efdfe4b44f21bd8c521b00e3f5c5 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct X { x: int, y: int, z: int }
+struct X { x: isize, y: isize, z: isize }
 
-pub fn main() { let x = box X {x: 1, y: 2, z: 3}; let y = x; assert!((y.y == 2)); }
+pub fn main() { let x: Box<_> = box X {x: 1, y: 2, z: 3}; let y = x; assert!((y.y == 2)); }
index 07d0594b494d966d1f5df70c0e05ffcf9423ac2d..6036fa26ccf991d84b329997fc776e39f8ff02e6 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 #[derive(Clone)]
 struct Triple {
-    x: int,
-    y: int,
-    z: int,
+    x: isize,
+    y: isize,
+    z: isize,
 }
 
-fn test(x: bool, foo: Box<Triple>) -> int {
+fn test(x: bool, foo: Box<Triple>) -> isize {
     let bar = foo;
     let mut y: Box<Triple>;
     if x { y = bar; } else { y = box Triple {x: 4, y: 5, z: 6}; }
@@ -26,7 +28,7 @@ fn test(x: bool, foo: Box<Triple>) -> int {
 }
 
 pub fn main() {
-    let x = box Triple{x: 1, y: 2, z: 3};
+    let x: Box<_> = box Triple{x: 1, y: 2, z: 3};
     for _ in 0_usize..10000_usize {
         assert_eq!(test(true, x.clone()), 2);
     }
index 9e5eeef75527c1595ba1a601c4988a5d4e852ac0..79a1b294da9bb3914c1db650af60077c5bc6f79b 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct Triple {a: int, b: int, c: int}
+struct Triple {a: isize, b: isize, c: isize}
 
 fn test(foo: Box<Triple>) -> Box<Triple> {
     let foo = foo;
index c902677c645314b41ad8e998dac7b2824a078b69..16ef95023542b7f75ea41d11fc72928f60ebf6f7 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct Triple { a: int, b: int, c: int }
+struct Triple { a: isize, b: isize, c: isize }
 
 fn test(foo: Box<Triple>) -> Box<Triple> {
     let foo = foo;
index e496e9e2105334fcc74ca8abbbcb392fcfda9b78..7aec948c8d4725dd4a08ca208ed788eea999d1f5 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn test(foo: Box<Vec<int>> ) { assert!(((*foo)[0] == 10)); }
+fn test(foo: Box<Vec<isize>> ) { assert!(((*foo)[0] == 10)); }
 
 pub fn main() {
     let x = box vec!(10);
index fdb6799b90f793cb9857007e3030c98666eef39e..69b66d81e4355bbe18f6633ce8130f135e295224 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn test(foo: Box<Vec<int>>) { assert!(((*foo)[0] == 10)); }
+fn test(foo: Box<Vec<isize>>) { assert!(((*foo)[0] == 10)); }
 
 pub fn main() {
     let x = box vec!(10);
index 87db5cbe2f13ed2a4e049f0b3deff663ea8d6e15..3d9eba8c09f20a12b3185372bb542ca7c29268f1 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn test(foo: int) { assert!((foo == 10)); }
+// pretty-expanded FIXME #23616
+
+fn test(foo: isize) { assert!((foo == 10)); }
 
 pub fn main() { let x = 10; test(x); }
diff --git a/src/test/run-pass/move-guard-const.rs b/src/test/run-pass/move-guard-const.rs
new file mode 100644 (file)
index 0000000..6e49538
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+#![feature(box_syntax)]
+
+fn main() {
+    let x: Box<_> = box 1;
+
+    let v = (1, 2);
+
+    match v {
+        (2, 1) if take(x) => (),
+        (1, 2) if take(x) => (),
+        _ => (),
+    }
+}
+
+fn take<T>(_: T) -> bool { false }
index b7cd3003e750c4204394ce865daf9209bd80654f..cec1e43997206a485cc4e2096acebe8de2809951 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // Issue #922
+// pretty-expanded FIXME #23616
+
 fn f2<F>(_thing: F) where F: FnOnce() { }
 
 fn f<F>(thing: F) where F: FnOnce() {
index cb487a34f338876dc9e60557be588322c8577b2c..a0eba4685b88734c1b486dbdaf43c5ae6f18d4b6 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::string::String;
 
 struct StringBuffer {
index 845cb8ab6011ec10d310af52142a57f73f826c3e..a5b0a8b9bf482faa6756bad2efec52f622ea3eae 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
 
-    let y: int = 42;
-    let mut x: int;
+    let y: isize = 42;
+    let mut x: isize;
     x = y;
     assert_eq!(x, 42);
 }
index 3596fa1a0063ffb5b31fcdeb2b91a1689730d95d..b6509d280366a2e295b2998a27c9be2eed7a9464 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+#![feature(std_misc)]
+
+use std::thread;
 
 pub fn main() {
     let x = "Hello world!".to_string();
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         println!("{}", x);
     });
 }
index 16f15804e0e927fd1e45d49fc72a3e4762953529..a313ec998f0a1c7f5c1794450bcf1116f6ea227d 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:moves_based_on_type_lib.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate moves_based_on_type_lib;
 use moves_based_on_type_lib::f;
 
index eb1444be37844d8d7e3d6412343a5a21ad760e68..658b34e13f99badd0ccd22b834443b6fd20f0ada 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let x = 10;
     let y = x;
index b9435afdc7a934b93d89eb4e4a6b14c86af87f1b..fdf9f95b274d44fd61c4716188a693c4559797c1 100644 (file)
@@ -8,19 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::fmt::Debug;
 
 trait MyTrait<T> {
     fn get(&self) -> T;
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct MyType {
-    dummy: uint
+    dummy: usize
 }
 
-impl MyTrait<uint> for MyType {
-    fn get(&self) -> uint { self.dummy }
+impl MyTrait<usize> for MyType {
+    fn get(&self) -> usize { self.dummy }
 }
 
 impl MyTrait<u8> for MyType {
@@ -36,6 +38,6 @@ where T : Eq + Debug,
 
 pub fn main() {
     let value = MyType { dummy: 256 + 22 };
-    test_eq::<uint, _>(value, value.dummy);
+    test_eq::<usize, _>(value, value.dummy);
     test_eq::<u8, _>(value, value.dummy as u8);
 }
index 6b52ea9dfa7a33c19fd424b80993bb21b8548793..75c6c5ac7d16543338cf0f3484f41000afb45584 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::fmt::Debug;
 use std::default::Default;
 
@@ -23,13 +25,13 @@ impl<T> MyTrait<T> for T
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct MyType {
-    dummy: uint
+    dummy: usize
 }
 
-impl MyTrait<uint> for MyType {
-    fn get(&self) -> uint { self.dummy }
+impl MyTrait<usize> for MyType {
+    fn get(&self) -> usize { self.dummy }
 }
 
 fn test_eq<T,M>(m: M, v: T)
index 6203d47be5e6b8a62b0497fabbfab2d8f983c619..8c74326d1c34af0d4e496203f17610a0fc061038 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 /*
  * This is a multi-line oldcomment.
  */
index 7ce1afb52a274dec37491d016c8100f733af8e17..2746205b637dcb3cbe5915751522cc11f7ab2f45 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn f<T:PartialEq + PartialOrd>(_: T) {
 }
 
index b1f7da17c8f80767bee34c713ab15627319fe355..644e45575521e28f2ac6e449a261c4ecd802c0db 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn f(mut y: Box<int>) {
+fn f(mut y: Box<isize>) {
     *y = 5;
     assert_eq!(*y, 5);
 }
 
 fn g() {
-    let frob = |mut q: Box<int>| { *q = 2; assert!(*q == 2); };
+    let frob = |mut q: Box<isize>| { *q = 2; assert!(*q == 2); };
     let w = box 37;
     frob(w);
 
index d3ae80861f231c5f29aaa57ed211104b7c59c5b8..2a8f6f1fc31eae3bc8830b8c7be8b41634f683c6 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
-    fn foo(&self, mut x: int) -> int {
+    fn foo(&self, mut x: isize) -> isize {
         let val = x;
         x = 37 * x;
         val + x
@@ -30,7 +32,7 @@ pub fn main() {
     assert_eq!(X.foo(2), 76);
 
     enum Bar {
-       Foo(int),
+       Foo(isize),
        Baz(f32, u8)
     }
 
@@ -61,14 +63,14 @@ pub fn main() {
         }
     }
 
-    fn foo1((x, mut y): (f64, int), mut z: int) -> int {
+    fn foo1((x, mut y): (f64, isize), mut z: isize) -> isize {
         y = 2 * 6;
-        z = y + (x as int);
+        z = y + (x as isize);
         y - z
     }
 
     struct A {
-        x: int
+        x: isize
     }
     let A { x: mut x } = A { x: 10 };
     assert_eq!(x, 10);
index a276e902fbcfca6172680ed17d0e94e7b18ff3c2..503f3ce5f9b2ff5e29ae3461d6bc3561397e6af5 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let _x: &mut [int] = &mut [ 1, 2, 3 ];
+    let _x: &mut [isize] = &mut [ 1, 2, 3 ];
 }
index e074c3fb3d7834fe262f97db131cdad8dd752a1f..bed3b87def58b30b4ec940aa2bfe941639dca6d4 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn test1() {
     let mut ints = [0; 32];
     ints[0] += 1;
index 28dd89edd629d79d758dc2c49bc5090342be3bc7..3f90cedca9b5a92e1f76342190e400b63bbe3a83 100644 (file)
@@ -8,16 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn grow(v: &mut Vec<int> ) {
+fn grow(v: &mut Vec<isize> ) {
     v.push(1);
 }
 
 pub fn main() {
-    let mut v: Vec<int> = Vec::new();
+    let mut v: Vec<isize> = Vec::new();
     grow(&mut v);
     grow(&mut v);
     grow(&mut v);
     let len = v.len();
     println!("{}", len);
-    assert_eq!(len, 3 as uint);
+    assert_eq!(len, 3 as usize);
 }
index 8444a632fe889c699f0cf932b524f83a1a56be3a..72a8847094b2c08630fc7412b940a19a81eecb23 100644 (file)
@@ -9,12 +9,14 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 enum colour { red, green, blue, }
 
 enum tree { children(Box<list>), leaf(colour), }
 
 enum list { cons(Box<tree>, Box<list>), nil, }
 
-enum small_list { kons(int, Box<small_list>), neel, }
+enum small_list { kons(isize, Box<small_list>), neel, }
 
 pub fn main() { }
index 680cdf14e8f2a8832fe7679e8536f2780f540957..f275e9b7425bd960abf6c21a15e7c6b27e0f84e0 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:namespaced_enum_emulate_flat.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate namespaced_enum_emulate_flat;
 
 use namespaced_enum_emulate_flat::{Foo, A, B, C};
@@ -28,4 +30,3 @@ fn _f2(f: Bar) {
 }
 
 pub fn main() {}
-
index e4a8ec19eb8e84ce231739a702cff4bf956f3e92..0f85c20d3151bda20a0267917b1ea2b241542d23 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub use Foo::*;
 use nest::{Bar, D, E, F};
 
 pub enum Foo {
     A,
-    B(int),
-    C { a: int },
+    B(isize),
+    C { a: isize },
 }
 
 impl Foo {
@@ -32,8 +34,8 @@ mod nest {
 
     pub enum Bar {
         D,
-        E(int),
-        F { a: int },
+        E(isize),
+        F { a: isize },
     }
 
     impl Bar {
index e5317c2f57302ae63ee84e3ff237f5a18ee783b1..7bfe90bad7f4facd8138e37d315328831b1bf6a7 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:namespaced_enums.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate namespaced_enums;
 
 fn _f(f: namespaced_enums::Foo) {
index c48be3af248f0982577fa3671a5ee3712b8dd168..f506ea11f848be7c5af6f80484c888ca908f14d1 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod m2 {
     pub enum Foo {
         A,
-        B(int),
-        C { a: int },
+        B(isize),
+        C { a: isize },
     }
 
     impl Foo {
index 7545908dcbbf6ad71a051a288b6e6c96540b29ec..0046d80e086d1ed24d28d1415bbf582083709e27 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:namespaced_enums.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate namespaced_enums;
 
 use namespaced_enums::Foo;
@@ -21,4 +23,3 @@ fn _foo (f: Foo) {
 }
 
 pub fn main() {}
-
index 13f70f6a740aef76ed24b76fd1a9d67544e73064..3e72f73bc4894f1b5b502ce34180955835dec434 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Foo {
     A,
-    B(int),
-    C { a: int },
+    B(isize),
+    C { a: isize },
 }
 
 fn _foo (f: Foo) {
index b151eddb94e5dd3fd7d054a44f3847c6931cea14..deb0b5030614e651e653f85ef9e9e9e4acb7bad2 100644 (file)
@@ -11,7 +11,7 @@
 #![feature(start)]
 
 #[start]
-pub fn main(_: int, _: *const *const u8) -> int {
+pub fn main(_: isize, _: *const *const u8) -> isize {
     println!("hello");
     0
 }
index 435382666f1a2dde3e99c01973a5b8d234fd6bbb..c5b6a6a035bbaa1b518eeb9ab12a58b0ad19134d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     match -5 {
       -5 => {}
index a6d932935ade6b1a227112b36af992e3a8a89974..650e28548c17a800eeba6336ff881f554380ab15 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 /* This test checks that nested comments are supported
 
    /*
index 19eba0808c88237cdc4f5b79430a57ad24dfd238..86197d44a689dc25b459994ca0bd12937121a204 100644 (file)
@@ -8,22 +8,24 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     struct b {
-        i: int,
+        i: isize,
     }
 
     impl b {
-        fn do_stuff(&self) -> int { return 37; }
+        fn do_stuff(&self) -> isize { return 37; }
     }
 
-    fn b(i:int) -> b {
+    fn b(i:isize) -> b {
         b {
             i: i
         }
     }
 
-    //  fn b(x:int) -> int { panic!(); }
+    //  fn b(x:isize) -> isize { panic!(); }
 
     let z = b(42);
     assert_eq!(z.i, 42);
index 33c4ed6234eaa772fbef539564cf5101edeb373c..c0baab66c597ad03d5ffa7a07e74d3d6466afcc8 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 /*
 
 #7770 ICE with sibling methods containing same-name-enum containing
index b2a47e0ccb88b0145113f4c17ef84dab4cc59d74..e0a3b1adfe49fd1dbef4a8f4a1d43e0029e50096 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo { foo: bool, bar: Option<int>, baz: int }
+// pretty-expanded FIXME #23616
+
+struct Foo { foo: bool, bar: Option<isize>, baz: isize }
 
 pub fn main() {
     match (Foo{foo: true, bar: Some(10), baz: 20}) {
index f697f0b59d65f7c837d5ebe4b32a672931eb2ca7..28f3438f9862b451e4207ccb5857941c239747c0 100644 (file)
 //
 // Issue #8587
 
+// pretty-expanded FIXME #23616
+
 pub struct X;
 
 impl X {
-    fn f(&self) -> int {
+    fn f(&self) -> isize {
         #[inline(never)]
-        fn inner() -> int {
+        fn inner() -> isize {
             0
         }
         inner()
     }
 
-    fn g(&self) -> int {
+    fn g(&self) -> isize {
         #[inline(never)]
-        fn inner_2() -> int {
+        fn inner_2() -> isize {
             1
         }
         inner_2()
     }
 
-    fn h(&self) -> int {
+    fn h(&self) -> isize {
         #[inline(never)]
-        fn inner() -> int {
+        fn inner() -> isize {
             2
         }
         inner()
index b0ac9fb597a241d10539e8b4559d0845fabe7ff4..46d30b68f78980c5f00e20800447aa1b1bc615a3 100644 (file)
 fn baz() -> ! { panic!(); }
 
 fn foo() {
-    match Some::<int>(5) {
-      Some::<int>(_x) => {
+    match Some::<isize>(5) {
+      Some::<isize>(_x) => {
         let mut bar;
-        match None::<int> { None::<int> => { bar = 5; } _ => { baz(); } }
+        match None::<isize> { None::<isize> => { bar = 5; } _ => { baz(); } }
         println!("{}", bar);
       }
-      None::<int> => { println!("hello"); }
+      None::<isize> => { println!("hello"); }
     }
 }
 
index 14a84484f649c01d13a8091b14cc690b7547059d..f9abdd56fa4447eb3f501b9c80a85445ec489463 100644 (file)
 
 // a bug was causing this to complain about leaked memory on exit
 
-enum t { foo(int, uint), bar(int, Option<int>), }
+enum t { foo(isize, usize), bar(isize, Option<isize>), }
 
 fn nested(o: t) {
     match o {
-        t::bar(_i, Some::<int>(_)) => { println!("wrong pattern matched"); panic!(); }
+        t::bar(_i, Some::<isize>(_)) => { println!("wrong pattern matched"); panic!(); }
         _ => { println!("succeeded"); }
     }
 }
 
-pub fn main() { nested(t::bar(1, None::<int>)); }
+pub fn main() { nested(t::bar(1, None::<isize>)); }
diff --git a/src/test/run-pass/nested-vec-1.rs b/src/test/run-pass/nested-vec-1.rs
new file mode 100644 (file)
index 0000000..2b92ed3
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2015 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 using the `vec!` macro nested within itself works
+
+fn main() {
+    let nested = vec![vec![1u32, 2u32, 3u32]];
+    assert_eq!(nested[0][1], 2);
+}
diff --git a/src/test/run-pass/nested-vec-2.rs b/src/test/run-pass/nested-vec-2.rs
new file mode 100644 (file)
index 0000000..669f9e4
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2015 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 using the `vec!` macro nested within itself works
+// when the contents implement Drop
+
+struct D(u32);
+
+impl Drop for D {
+    fn drop(&mut self) { println!("Dropping {}", self.0); }
+}
+
+fn main() {
+    let nested = vec![vec![D(1u32), D(2u32), D(3u32)]];
+    assert_eq!(nested[0][1].0, 2);
+}
diff --git a/src/test/run-pass/nested-vec-3.rs b/src/test/run-pass/nested-vec-3.rs
new file mode 100644 (file)
index 0000000..60cf795
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright 2015 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 using the `vec!` macro nested within itself works when
+// the contents implement Drop and we hit a panic in the middle of
+// construction.
+
+
+use std::thread;
+use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
+
+static LOG: AtomicUsize = ATOMIC_USIZE_INIT;
+
+struct D(u8);
+
+impl Drop for D {
+    fn drop(&mut self) {
+        println!("Dropping {}", self.0);
+        let old = LOG.load(Ordering::SeqCst);
+        LOG.compare_and_swap(old, old << 4 | self.0 as usize, Ordering::SeqCst);
+    }
+}
+
+fn main() {
+    fn die() -> D { panic!("Oh no"); }
+    let g = thread::spawn(|| {
+        let _nested = vec![vec![D( 1), D( 2), D( 3), D( 4)],
+                           vec![D( 5), D( 6), D( 7), D( 8)],
+                           vec![D( 9), D(10), die(), D(12)],
+                           vec![D(13), D(14), D(15), D(16)]];
+    });
+    assert!(g.join().is_err());
+
+    // When the panic occurs, we will be in the midst of constructing the
+    // second inner vector.  Therefore, we drop the elements of the
+    // partially filled vector first, before we get around to dropping
+    // the elements of the filled vector.
+
+    // Issue 23222: The order in which the elements actually get
+    // dropped is a little funky: as noted above, we'll drop the 9+10
+    // first, but due to #23222, they get dropped in reverse
+    // order. Likewise, again due to #23222, we will drop the second
+    // filled vec before the first filled vec.
+    //
+    // If Issue 23222 is "fixed", then presumably the corrected
+    // expected order of events will be 0x__9_A__1_2_3_4__5_6_7_8;
+    // that is, we would still drop 9+10 first, since they belong to
+    // the more deeply nested expression when the panic occurs.
+
+    let expect = 0x__A_9__5_6_7_8__1_2_3_4;
+    let actual = LOG.load(Ordering::SeqCst);
+    assert!(actual == expect, "expect: 0x{:x} actual: 0x{:x}", expect, actual);
+}
index d73fba561430a53c9476fe8ea97ef79ecf0b9afd..f7adfe36695d2da907f2149c4675353f6e85babc 100644 (file)
 
 // aux-build:nested_item.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate nested_item;
 
 pub fn main() {
     assert_eq!(2, nested_item::foo::<()>());
-    assert_eq!(2, nested_item::foo::<int>());
+    assert_eq!(2, nested_item::foo::<isize>());
 }
index 3d4847a119a55ca41af953e62f7111e0d76680df..95168b1bff7886a54df50f8b20f5d78c9baacfcb 100644 (file)
@@ -8,24 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, alloc)]
 
 // Tests that the new `box` syntax works with unique pointers.
 
 use std::boxed::{Box, HEAP};
 
 struct Structure {
-    x: int,
-    y: int,
+    x: isize,
+    y: isize,
 }
 
 pub fn main() {
-    let x: Box<int> = box(HEAP) 2;
-    let y: Box<int> = box 2;
-    let b: Box<int> = box()(1 + 2);
+    let x: Box<isize> = box(HEAP) 2;
+    let y: Box<isize> = box 2;
+    let b: Box<isize> = box()(1 + 2);
     let c = box()(3 + 4);
 }
index 1f2207ad87378915a31258783a73a77277fabebf..17f71c3de432fce4273e6721a5140dbae0d9a790 100644 (file)
@@ -11,8 +11,8 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn f(x: Box<int>) {
-    let y: &int = &*x;
+fn f(x: Box<isize>) {
+    let y: &isize = &*x;
     println!("{}", *x);
     println!("{}", *y);
 }
@@ -39,4 +39,3 @@ fn main() {
     f(box 1234);
     g(box Struct as Box<Trait>);
 }
-
index bd0a53b620c0a9252d512a82fdda5be261944cd8..554fab53e4b589eb0fa00ba94efeee5414c55ec1 100644 (file)
@@ -11,8 +11,8 @@
 use std::fmt;
 
 struct Thingy {
-    x: int,
-    y: int
+    x: isize,
+    y: isize
 }
 
 impl fmt::Debug for Thingy {
index fa681c81398fecfa1cedaa55739b3bfed5b8b007..36d66d1e12b6bbd4df9bffbe3c669c1c4cba4b3a 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: int = 3;
+static FOO: isize = 3;
 
 pub fn main() {
     println!("{}", FOO);
index e06461daed0c93c9afea708e96e195bf276283cc..4d9f0394eb4407368353add8da4a3b8a6792c572 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: [int; 3] = [1, 2, 3];
+static FOO: [isize; 3] = [1, 2, 3];
 
 pub fn main() {
     println!("{} {} {}", FOO[0], FOO[1], FOO[2]);
index 7430f730f3b17d0799c24873434ea9e184128053..8c2d5e09adb47edb90bab4ec422644a05d1af6a3 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections)]
+
 pub fn main() {
     let s = "\u{2603}";
     assert_eq!(s, "☃");
index 96ccb1a37a2a01fbbf38ca403ee28ce0f7138177..a0d631046a6354498d3bdcf02d492d90bee2c746 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
-    let _a: *const int = 3 as *const int;
-    let _a: *mut int = 3 as *mut int;
+    let _a: *const isize = 3 as *const isize;
+    let _a: *mut isize = 3 as *mut isize;
 }
index 130cdc85b013d6af888468b6e809197e4c5d264b..543dbb36b2850a218001fb9513774018b73f4e6a 100644 (file)
 // Test that the lambda kind is inferred correctly as a return
 // expression
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+// pretty-expanded FIXME #23616
 
-fn unique() -> Box<FnMut()+'static> { return box || (); }
+fn unique() -> Box<FnMut()+'static> { return Box::new(|| ()); }
 
 pub fn main() {
 }
index 0952bedd6e309a2fbfdcc798db2e30f2657064c7..e8297173a58345fe8e383a9de7056c87e50f637a 100644 (file)
 // Test that the lambda kind is inferred correctly as a return
 // expression
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+// pretty-expanded FIXME #23616
 
-fn unique() -> Box<FnMut()+'static> { box || () }
+fn unique() -> Box<FnMut()+'static> { Box::new(|| ()) }
 
 pub fn main() {
 }
index 01875288aef0e97cdbc73e40769567af7a6f2826..c6fa7cc35fd9af3b92a2b1a4ed8955f185fb5e15 100644 (file)
@@ -10,7 +10,9 @@
 
 // Tests for the new |args| expr lambda syntax
 
-fn f<F>(i: int, f: F) -> int where F: FnOnce(int) -> int { f(i) }
+// pretty-expanded FIXME #23616
+
+fn f<F>(i: isize, f: F) -> isize where F: FnOnce(isize) -> isize { f(i) }
 
 fn g<G>(_g: G) where G: FnOnce() { }
 
index 4b7dbdc9e5b9ec6262437f8bcbff09847e237f68..424d518895cfb129de656804e008716397a5036d 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 #[derive(Clone)]
 struct myvec<X>(Vec<X> );
 
index 8c35abad7f1e61e273b53a0595acb7a92e6ee06f..2d162ba7e336bfcd8d93d88a4ed2f4c69159baae 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 
 // Make sure the destructor is run for newtype structs.
 
 use std::cell::Cell;
 
-struct Foo<'a>(&'a Cell<int>);
+struct Foo<'a>(&'a Cell<isize>);
 
 #[unsafe_destructor]
 impl<'a> Drop for Foo<'a> {
index 8631755f37fd9a7895ab5678957c2cda5f509eec..d1ad5614e3f35f36e0855c971aa4aff1ab0e51af 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-fast doesn't like extern crate
+
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
 
 extern crate libc;
 use libc::c_int;
index 0302a0588e4cfece646c26c558292a047b3c1e85..ac03f65750df5a213c3f039a4daed16f47c7d490 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:newtype_struct_xc.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate newtype_struct_xc;
 use newtype_struct_xc::Au;
 
index 3e375c48316c86d16a2b627f0bd045451b6d4ed0..0cac4530faf32604e3830d009c014a3c5119246e 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:newtype_struct_xc.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate newtype_struct_xc;
 
 pub fn main() {
index 5952258e46c32f61ae1a6a155a4d46da7ca6788e..19790a488b58e09864527d2939f4788283270924 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #[derive(PartialEq, Debug)]
-struct Foo(uint);
+struct Foo(usize);
 
 fn foo() -> Foo {
     Foo(42)
index 869ae4a37d22a62b4e881ea58c71130f843ca881..818ea4c9f23262429aec69bc932fbad5d7cbce87 100644 (file)
@@ -8,16 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct mytype(Mytype);
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Mytype {
-    compute: fn(mytype) -> int,
-    val: int,
+    compute: fn(mytype) -> isize,
+    val: isize,
 }
 
-fn compute(i: mytype) -> int {
+fn compute(i: mytype) -> isize {
     let mytype(m) = i;
     return m.val + 20;
 }
index e23c970e29a582baa3e827fee9ebc3225edaa692..97ee237771f3fae9bd6e8e307f8c1d44714c63f4 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // Issue #901
+// pretty-expanded FIXME #23616
+
 mod libc {
     extern {
         pub fn printf(x: ());
index 329590b547db3a5aaa525d86f47f7ce5d8c6c0a1..342644e03843725b332a86a8baf5a91b0a26d0c9 100644 (file)
@@ -8,4 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() { let x = (); match x { () => { } } }
index 5ce32e4fe2ccb54975d20fe9c3db3dc826ace517..da57c81a66978422319c4f7ff243011d355652b9 100644 (file)
@@ -10,6 +10,8 @@
 
 // compile-flags: -Z no-landing-pads
 
+// pretty-expanded FIXME #23616
+
 use std::thread;
 
 static mut HIT: bool = false;
index f5f34607aff7b8955a8e0081915c83604503c253..43f6b27d64fc41dfad448be4b268a98f73147d8d 100644 (file)
@@ -30,7 +30,7 @@ pub mod linkhack {
 }
 
 #[start]
-pub fn main(_: int, _: **u8, _: *u8) -> int {
+pub fn main(_: isize, _: **u8, _: *u8) -> isize {
     no_std_crate::foo();
     0
 }
index 8b41670734f95bee52407cf7c9065ef205728e05..6c0df5f4c14e753c3c966b0bc1f0909179d2d424 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! quote_tokens { () => (()) }
 
 pub fn main() {
index e422cb803215bb591be773f40c4413a555290a0b..5f1c69bb4b6542c985f3d0fa07b4030c298e1cdb 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct X {
-    repr: int
+    repr: isize
 }
 
 fn apply<T, F>(x: T, f: F) where F: FnOnce(T) {
     f(x);
 }
 
-fn check_int(x: int) {
+fn check_int(x: isize) {
     assert_eq!(x, 22);
 }
 
index bbce9a8f4a6ad20db285f21fd2ef7c87ae94fb3b..a28f2b15b92856f1333a94c74ce3fce9b5257e5c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::cell::Cell;
 
 struct C<'a> {
index 22786c0abc89b9bd6487882d021967e18abb377f..25c111daad597331010d1a51568cd8962130a908 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main()
 {
-    let all_nuls1 = "\0\x00\u0000\U00000000";
-    let all_nuls2 = "\U00000000\u0000\x00\0";
-    let all_nuls3 = "\u0000\U00000000\x00\0";
-    let all_nuls4 = "\x00\u0000\0\U00000000";
+    let all_nuls1 = "\0\x00\u{0}\u{0}";
+    let all_nuls2 = "\u{0}\u{0}\x00\0";
+    let all_nuls3 = "\u{0}\u{0}\x00\0";
+    let all_nuls4 = "\x00\u{0}\0\u{0}";
 
     // sizes for two should suffice
     assert_eq!(all_nuls1.len(), 4);
@@ -35,8 +37,8 @@ pub fn main()
 
     // testing equality between explicit character literals
     assert_eq!('\0', '\x00');
-    assert_eq!('\u0000', '\x00');
-    assert_eq!('\u0000', '\U00000000');
+    assert_eq!('\u{0}', '\x00');
+    assert_eq!('\u{0}', '\u{0}');
 
     // NUL characters should make a difference
     assert!("Hello World" != "Hello \0World");
index 32432c07dcf415fd84f59f228c9cfa5210939c55..22aa09c718a747c0019e00cd2fe19b12518fd962 100644 (file)
 // then we simply express the enum as just a pointer and not wrap it
 // in a struct.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
 #[inline(never)]
-extern "C" fn foo<'a>(x: &'a int) -> Option<&'a int> { Some(x) }
+extern "C" fn foo<'a>(x: &'a isize) -> Option<&'a isize> { Some(x) }
 
-static FOO: int = 0xDEADBEE;
+static FOO: isize = 0xDEADBEE;
 
 pub fn main() {
     unsafe {
-        let f: for<'a> extern "C" fn(&'a int) -> &'a int = mem::transmute(foo);
+        let f: for<'a> extern "C" fn(&'a isize) -> &'a isize = mem::transmute(foo);
         assert_eq!(*f(&FOO), FOO);
     }
 }
index bb62b1599a4fe5aa5f99563b90877e8036b4a863..ad2716e00de56f76993bf7905ab6849308811227 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -21,7 +23,7 @@ use std::{option, mem};
 // trying to get assert failure messages that at least identify which case
 // failed.
 
-enum E<T> { Thing(int, T), Nothing((), ((), ()), [i8; 0]) }
+enum E<T> { Thing(isize, T), Nothing((), ((), ()), [i8; 0]) }
 impl<T> E<T> {
     fn is_none(&self) -> bool {
         match *self {
@@ -29,7 +31,7 @@ impl<T> E<T> {
             E::Nothing(..) => true
         }
     }
-    fn get_ref(&self) -> (int, &T) {
+    fn get_ref(&self) -> (isize, &T) {
         match *self {
             E::Nothing(..) => panic!("E::get_ref(Nothing::<{}>)",  stringify!(T)),
             E::Thing(x, ref y) => (x, y)
@@ -55,7 +57,7 @@ macro_rules! check_fancy {
         check_fancy!($e, $T, |ptr| assert!(*ptr == $e));
     }};
     ($e:expr, $T:ty, |$v:ident| $chk:expr) => {{
-        assert!(E::Nothing::<$T>((), ((), ()), [23i8; 0]).is_none());
+        assert!(E::Nothing::<$T>((), ((), ()), [23; 0]).is_none());
         let e = $e;
         let t_ = E::Thing::<$T>(23, e);
         match t_.get_ref() {
@@ -74,11 +76,11 @@ macro_rules! check_type {
 }
 
 pub fn main() {
-    check_type!(&17, &int);
-    check_type!(box 18, Box<int>);
+    check_type!(&17, &isize);
+    check_type!(box 18, Box<isize>);
     check_type!("foo".to_string(), String);
-    check_type!(vec!(20, 22), Vec<int> );
-    let mint: uint = unsafe { mem::transmute(main) };
+    check_type!(vec!(20, 22), Vec<isize> );
+    let mint: usize = unsafe { mem::transmute(main) };
     check_type!(main, fn(), |pthing| {
         assert!(mint == unsafe { mem::transmute(*pthing) })
     });
index 02fc0cf0291d43ba23e1eee7986f7efa39460e93..6e3f438575e2a850cd9d3316ae74162d73a24b8b 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
-enum E<T> { Thing(int, T), Nothing((), ((), ()), [i8; 0]) }
-struct S<T>(int, T);
+enum E<T> { Thing(isize, T), Nothing((), ((), ()), [i8; 0]) }
+struct S<T>(isize, T);
 
 // These are macros so we get useful assert messages.
 
@@ -35,7 +37,7 @@ macro_rules! check_type {
 }
 
 pub fn main() {
-    check_type!(&'static int);
-    check_type!(Box<int>);
+    check_type!(&'static isize);
+    check_type!(Box<isize>);
     check_type!(extern fn());
 }
index 565ef278d5d7c307f6a9de8b1e4e994e079b1aa9..f4cfc80827498350d6d2731ad5b95a9b437161c6 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum blah { a, b, }
 
-fn or_alt(q: blah) -> int {
+fn or_alt(q: blah) -> isize {
   match q { blah::a | blah::b => { 42 } }
 }
 
index eccc2a41a8d2d3f6bd15eb9ab8485a403c46e400..cb41949a722c2b64f4d5bba64a71d07469489bcc 100644 (file)
 // necessary. Testing the methods of the impls is done within the source
 // file for each numeric type.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::ops::Add;
 use std::num::ToPrimitive;
 
index c385a0195b6b20868b36a53180df2fdd9ca79c1b..1b631f171eb79f9e9ea1f12b561bbc78a7fa6a2a 100644 (file)
@@ -11,6 +11,8 @@
 // Test that `Box<Test>` is equivalent to `Box<Test+'static>`, both in
 // fields and fn arguments.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 trait Test {
index 24da9603679065f404866242f82aa9210200de87..910d933d46f0879bd726e7f8efb2d8cb22b547b9 100644 (file)
@@ -11,6 +11,8 @@
 // Test that the lifetime of the enclosing `&` is used for the object
 // lifetime bound.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 trait Test {
index 825800e1d4447e1fd9daf28db8ad0c47610612e0..e2047ee3256d1a1ef6808686b6d1657e52d84c07 100644 (file)
@@ -11,6 +11,8 @@
 // Test that the lifetime from the enclosing `&` is "inherited"
 // through the `Box` struct.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 trait Test {
index 0f34d945c8fb9976e7dc7884a48ed166b43a1815..edd0bdb32c2b1778b6f5151ae4eac4009ba22b7c 100644 (file)
@@ -11,6 +11,8 @@
 // Test that the lifetime of the enclosing `&` is used for the object
 // lifetime bound.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 trait Test {
index 9d5dac536f10ade4c0e41136cfc8d56876e737a5..3c2419e420d3da6d2d2e124143c90866598a2b49 100644 (file)
@@ -11,6 +11,8 @@
 // Test that the lifetime from the enclosing `&` is "inherited"
 // through the `MyBox` struct.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 trait Test {
index b7a28a5c524156764809cf9a2443635e46d4e837..d9e0b22fbfa4be5bcc34cf9d3ddf3358c0cfd81e 100644 (file)
@@ -11,6 +11,8 @@
 // Test that the lifetime of the enclosing `&` is used for the object
 // lifetime bound.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 trait Test {
index 8da753acb966ef292e0d982d86273cb5eaf93701..8b8c56aee83911c45a8e3091ff7147ec399cf7d9 100644 (file)
@@ -11,6 +11,8 @@
 // Test for using an object with an associated type binding as the
 // instantiation for a generic type with a bound.
 
+// pretty-expanded FIXME #23616
+
 trait SomeTrait {
     type SomeType;
 
@@ -29,7 +31,7 @@ impl SomeTrait for i32 {
 }
 
 fn main() {
-    let x = 22_i32;
+    let x = 22;
     let x1: &SomeTrait<SomeType=i32> = &x;
     let y = get_int(x1);
     assert_eq!(x, y);
index f8a3ce7cda01708bb6e0ddf4faec337b4f974313..aa2dbf03bb2c4f69cb84cba5d14ee941818f52e1 100644 (file)
 use std::any::Any;
 
 trait Wrap {
-    fn get(&self) -> int;
+    fn get(&self) -> isize;
     fn wrap(self: Box<Self>) -> Box<Any+'static>;
 }
 
-impl Wrap for int {
-    fn get(&self) -> int {
+impl Wrap for isize {
+    fn get(&self) -> isize {
         *self
     }
-    fn wrap(self: Box<int>) -> Box<Any+'static> {
+    fn wrap(self: Box<isize>) -> Box<Any+'static> {
         self as Box<Any+'static>
     }
 }
 
-fn is<T:'static>(x: &Any) -> bool {
+fn is<T:Any>(x: &Any) -> bool {
     x.is::<T>()
 }
 
 fn main() {
-    let x = box 22 as Box<Wrap>;
+    let x = box 22isize as Box<Wrap>;
     println!("x={}", x.get());
     let y = x.wrap();
 }
diff --git a/src/test/run-pass/object-safety-sized-self-by-value-self.rs b/src/test/run-pass/object-safety-sized-self-by-value-self.rs
new file mode 100644 (file)
index 0000000..b735743
--- /dev/null
@@ -0,0 +1,48 @@
+// 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 that a trait is still object-safe (and usable) if it has
+// methods with by-value self so long as they require `Self : Sized`.
+
+// pretty-expanded FIXME #23616
+
+trait Counter {
+    fn tick(&mut self) -> u32;
+    fn get(self) -> u32 where Self : Sized;
+}
+
+struct CCounter {
+    c: u32
+}
+
+impl Counter for CCounter {
+    fn tick(&mut self) -> u32 { self.c += 1; self.c }
+    fn get(self) -> u32 where Self : Sized { self.c }
+}
+
+fn tick1<C:Counter>(mut c: C) -> u32 {
+    tick2(&mut c);
+    c.get()
+}
+
+fn tick2(c: &mut Counter) {
+    tick3(c);
+}
+
+fn tick3<C:?Sized+Counter>(c: &mut C) {
+    c.tick();
+    c.tick();
+}
+
+fn main() {
+    let mut c = CCounter { c: 0 };
+    let value = tick1(c);
+    assert_eq!(value, 2);
+}
diff --git a/src/test/run-pass/object-safety-sized-self-generic-method.rs b/src/test/run-pass/object-safety-sized-self-generic-method.rs
new file mode 100644 (file)
index 0000000..696c5a0
--- /dev/null
@@ -0,0 +1,48 @@
+// 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 that a trait is still object-safe (and usable) if it has
+// generic methods so long as they require `Self : Sized`.
+
+// pretty-expanded FIXME #23616
+
+trait Counter {
+    fn tick(&mut self) -> u32;
+    fn with<F:FnOnce(u32)>(&self, f: F) where Self : Sized;
+}
+
+struct CCounter {
+    c: u32
+}
+
+impl Counter for CCounter {
+    fn tick(&mut self) -> u32 { self.c += 1; self.c }
+    fn with<F:FnOnce(u32)>(&self, f: F) { f(self.c); }
+}
+
+fn tick1<C:Counter>(c: &mut C) {
+    tick2(c);
+    c.with(|i| ());
+}
+
+fn tick2(c: &mut Counter) {
+    tick3(c);
+}
+
+fn tick3<C:?Sized+Counter>(c: &mut C) {
+    c.tick();
+    c.tick();
+}
+
+fn main() {
+    let mut c = CCounter { c: 0 };
+    tick1(&mut c);
+    assert_eq!(c.tick(), 3);
+}
diff --git a/src/test/run-pass/object-safety-sized-self-return-Self.rs b/src/test/run-pass/object-safety-sized-self-return-Self.rs
new file mode 100644 (file)
index 0000000..17c41f2
--- /dev/null
@@ -0,0 +1,49 @@
+// 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 that a trait is still object-safe (and usable) if it has
+// methods that return `Self` so long as they require `Self : Sized`.
+
+// pretty-expanded FIXME #23616
+
+trait Counter {
+    fn new() -> Self where Self : Sized;
+    fn tick(&mut self) -> u32;
+}
+
+struct CCounter {
+    c: u32
+}
+
+impl Counter for CCounter {
+    fn new() -> CCounter { CCounter { c: 0 } }
+    fn tick(&mut self) -> u32 { self.c += 1; self.c }
+}
+
+fn preticked<C:Counter>() -> C {
+    let mut c: C = Counter::new();
+    tick(&mut c);
+    c
+}
+
+fn tick(c: &mut Counter) {
+    tick_generic(c);
+}
+
+fn tick_generic<C:?Sized+Counter>(c: &mut C) {
+    c.tick();
+    c.tick();
+}
+
+fn main() {
+    let mut c = preticked::<CCounter>();
+    tick(&mut c);
+    assert_eq!(c.tick(), 5);
+}
index 998af27c338dc88210fb1f56e02b20a73a178419..686924a31400a1fd80e647e4d151e07cbfc6995e 100644 (file)
 
 // Test that we can coerce an `@Object` to an `&Object`
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
-    fn foo(&self) -> uint;
-    fn bar(&mut self) -> uint;
+    fn foo(&self) -> usize;
+    fn bar(&mut self) -> usize;
 }
 
-impl Foo for uint {
-    fn foo(&self) -> uint {
+impl Foo for usize {
+    fn foo(&self) -> usize {
         *self
     }
 
-    fn bar(&mut self) -> uint {
+    fn bar(&mut self) -> usize {
         *self += 1;
         *self
     }
@@ -34,15 +36,15 @@ fn do_it_mut(obj: &mut Foo) {
     do_it_imm(obj, y);
 }
 
-fn do_it_imm(obj: &Foo, v: uint) {
+fn do_it_imm(obj: &Foo, v: usize) {
     let y = obj.foo();
     assert_eq!(v, y);
 }
 
 pub fn main() {
-    let mut x = 22_usize;
+    let mut x: usize = 22;
     let obj = &mut x as &mut Foo;
     do_it_mut(obj);
-    do_it_imm(obj, 23_usize);
+    do_it_imm(obj, 23);
     do_it_mut(obj);
 }
index 30a8c270bd7944c36fa43f0833b3621663906de4..9a1cdd2922f7a7deabe8feb02dbc8c0b1503163f 100644 (file)
 // closed over do not contain managed values, and thus the boxes do
 // not have headers.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 
 trait FooTrait {
-    fn foo(&self) -> uint;
+    fn foo(&self) -> usize;
 }
 
 struct BarStruct {
-    x: uint
+    x: usize
 }
 
 impl FooTrait for BarStruct {
-    fn foo(&self) -> uint {
+    fn foo(&self) -> usize {
         self.x
     }
 }
@@ -37,7 +39,7 @@ pub fn main() {
         box BarStruct{ x: 2 } as Box<FooTrait>
     );
 
-    for i in 0_usize..foos.len() {
+    for i in 0..foos.len() {
         assert_eq!(i, foos[i].foo());
     }
 }
index d355999c506068115f15991eab5a3a4ae0d93acc..4357adbf65bfd98617d0c8cec634df0256366698 100644 (file)
 // closed over contain managed values. This implies that the boxes
 // will have headers that must be skipped over.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 trait FooTrait {
-    fn foo(self: Box<Self>) -> uint;
+    fn foo(self: Box<Self>) -> usize;
 }
 
 struct BarStruct {
-    x: uint
+    x: usize
 }
 
 impl FooTrait for BarStruct {
-    fn foo(self: Box<BarStruct>) -> uint {
+    fn foo(self: Box<BarStruct>) -> usize {
         self.x
     }
 }
index 8fe57a655aa5334b3400e93bd0042ac74af28c67..7bf8b693d9bbf844918082ef1c42d64952f60168 100644 (file)
@@ -11,6 +11,8 @@
 // Testing guarantees provided by once functions.
 
 
+// pretty-expanded FIXME #23616
+
 use std::sync::Arc;
 
 fn foo<F:FnOnce()>(blk: F) {
index 8377a45a1d8a079672c58aa9f4fc613e109be3bd..6520e42dbe3f8ad3e3c14dad8e786aaf1771ac84 100644 (file)
@@ -10,6 +10,8 @@
 
 // Why one-tuples? Because macros.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     match ('c',) {
         (x,) => {
index 3f00cf7d18400e6b783a98b54b9e29972571cd27..f5f0928ff144a74954246f6db837b68c60cde812 100644 (file)
@@ -12,7 +12,7 @@
 
 
 pub fn main() {
-    let mut x: int = 1;
+    let mut x: isize = 1;
     x *= 2;
     println!("{}", x);
     assert_eq!(x, 2);
index bee6d23a27d6245eef08d96588f22910c95cb9da..ccfdb83ab8aa14e61edc85e4591d5a4011f81760 100644 (file)
@@ -12,4 +12,6 @@
 
 
 // Testcase for issue #130, operator associativity.
+// pretty-expanded FIXME #23616
+
 pub fn main() { assert!((3 * 5 / 2 == 7)); }
index 4ce6fcee8c78e06dfaf0efc7fcebe45f99cbea25..af7deef11b6b2f95af3341d238925b5572e2677b 100644 (file)
@@ -15,8 +15,8 @@ use std::ops;
 
 #[derive(Debug,PartialEq,Eq)]
 struct Point {
-    x: int,
-    y: int
+    x: isize,
+    y: isize
 }
 
 impl ops::Add for Point {
@@ -27,10 +27,10 @@ impl ops::Add for Point {
     }
 }
 
-impl ops::Add<int> for Point {
+impl ops::Add<isize> for Point {
     type Output = Point;
 
-    fn add(self, other: int) -> Point {
+    fn add(self, other: isize) -> Point {
         Point {x: self.x + other,
                y: self.y + other}
     }
index 3ddc666cd384c0ce2c551b5df122201a48992a4a..045af79189acd36cb74f4200a8011bfd76b055de 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(core)]
+
 use std::cmp;
 use std::ops;
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 struct Point {
-    x: int,
-    y: int
+    x: isize,
+    y: isize
 }
 
 impl ops::Add for Point {
@@ -50,10 +52,10 @@ impl ops::Not for Point {
 }
 
 impl ops::Index<bool> for Point {
-    type Output = int;
+    type Output = isize;
 
-    fn index(&self, x: &bool) -> &int {
-        if *x {
+    fn index(&self, x: bool) -> &isize {
+        if x {
             &self.x
         } else {
             &self.y
@@ -85,4 +87,4 @@ pub fn main() {
     result(p[true]);
 }
 
-fn result(i: int) { }
+fn result(i: isize) { }
index 7a816f913350130dfc9b53efcbb023099ea5f8ba..03ba6097cd9297ad6d120e223b749912966abfbe 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(collections)]
+
 pub fn main() {
     let thing = "{{ f }}";
-    let f = thing.find_str("{{");
+    let f = thing.find("{{");
 
     if f.is_none() {
         println!("None!");
index 71323016e835e4ed965e2bfd8a7b551054700d4e..4902038667cd87784ba8e554a006afb731e47551 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 
 use std::cell::Cell;
 
 struct dtor<'a> {
-    x: &'a Cell<int>,
+    x: &'a Cell<isize>,
 }
 
 #[unsafe_destructor]
index 654d2429a0ba06fb83428c44aa97eb8fa8751c41..3ab78e8d053447ba9750ae3fa75393b0d9d2bf54 100644 (file)
@@ -8,14 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum blah { a(int, int, uint), b(int, int), c, }
+// pretty-expanded FIXME #23616
 
-fn or_alt(q: blah) -> int {
+enum blah { a(isize, isize, usize), b(isize, isize), c, }
+
+fn or_alt(q: blah) -> isize {
     match q { blah::a(x, y, _) | blah::b(x, y) => { return x + y; } blah::c => { return 0; } }
 }
 
 pub fn main() {
     assert_eq!(or_alt(blah::c), 0);
-    assert_eq!(or_alt(blah::a(10, 100, 0_usize)), 110);
+    assert_eq!(or_alt(blah::a(10, 100, 0)), 110);
     assert_eq!(or_alt(blah::b(20, 200)), 220);
 }
index 3710f1b9d3052e2a27c08e3376a44f00f8649d80..c8a2ba0af47cb98a8c31ad36d6a6b19c244734a6 100644 (file)
 // in ORDER matching up to when it ran.
 // Correct order is: matched, inner, outer
 
-static mut ORDER: [uint; 3] = [0, 0, 0];
-static mut INDEX: uint = 0;
+// pretty-expanded FIXME #23616
+
+static mut ORDER: [usize; 3] = [0, 0, 0];
+static mut INDEX: usize = 0;
 
 struct A;
 impl Drop for A {
index aa4e91320f755b7191aef46ab1f8cfdd9f192677..41b34dc79bd954d274f098a255ad2560576819ca 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 extern crate libc;
 
 #[cfg(target_os = "macos")]
index f574259c375fc86886bda5882c28f1987479e760..f08ed6e7f9cdc06cee25fd99c63689cf8488a0d2 100644 (file)
 //ignore-freebsd
 //ignore-ios
 //ignore-dragonfly
+//ignore-bitrig
 
-#![feature(asm)]
+#![feature(asm, old_io, std_misc)]
 
 use std::old_io::process::Command;
 use std::env;
-use std::thread::Thread;
+use std::thread;
 
 // lifted from the test module
 // Inlining to avoid llvm turning the recursive functions into tail calls,
@@ -36,7 +37,7 @@ fn recurse() {
 fn main() {
     let args: Vec<String> = env::args().collect();
     if args.len() > 1 && args[1] == "recurse" {
-        let _t = Thread::scoped(recurse);
+        let _t = thread::scoped(recurse);
     } else {
         let recurse = Command::new(&args[0]).arg("recurse").output().unwrap();
         assert!(!recurse.status.success());
index 948c4d064d723ef7f9302e763324853c13a14b39..8887e1937c6f7b1308d55143453df7abe117b26a 100644 (file)
@@ -13,8 +13,9 @@
 //ignore-freebsd
 //ignore-ios
 //ignore-dragonfly
+//ignore-bitrig
 
-#![feature(asm)]
+#![feature(asm, old_io)]
 
 use std::old_io::process::Command;
 use std::env;
index cc5eb69bb87e39ced535bccb2618f5bf29af23da..47f83eab4c1f4a569661dd1cbaba4b1a01287876 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-android: FIXME (#20004)
 
-#![feature(asm)]
+#![feature(asm, old_io)]
 
 use std::old_io::process::Command;
 use std::env;
index eee9838da21ee68a96ef021397c716d49a4efb2c..0a58411041e640df28eb16c58b2134e7e8124123 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy)]
+// pretty-expanded FIXME #23616
+
+#[derive(Copy, Clone)]
 pub struct Foo {
-    f1: int,
-    _f2: int,
+    f1: isize,
+    _f2: isize,
 }
 
 #[inline(never)]
index fb87cd5eb69cd25096874acba50f235237f26cdd..33489688d4a5c60ada36996534e109a5951ddca3 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 #![allow(unused_variable)]
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct A { a: int, b: int }
-struct Abox { a: Box<int>, b: Box<int> }
+struct A { a: isize, b: isize }
+struct Abox { a: Box<isize>, b: Box<isize> }
 
-fn ret_int_i() -> int { 10 }
+fn ret_int_i() -> isize { 10 }
 
-fn ret_ext_i() -> Box<int> { box 10 }
+fn ret_ext_i() -> Box<isize> { box 10 }
 
 fn ret_int_rec() -> A { A {a: 10, b: 10} }
 
@@ -29,8 +31,8 @@ fn ret_ext_mem() -> Abox { Abox {a: box 10, b: box 10} }
 fn ret_ext_ext_mem() -> Box<Abox> { box Abox{a: box 10, b: box 10} }
 
 pub fn main() {
-    let mut int_i: int;
-    let mut ext_i: Box<int>;
+    let mut int_i: isize;
+    let mut ext_i: Box<isize>;
     let mut int_rec: A;
     let mut ext_rec: Box<A>;
     let mut ext_mem: Abox;
index 1118638fe071345d3987346dcd925200c1e261f0..e4e07941470a815655bf5fdb73c603a4e7b2c066 100644 (file)
@@ -10,8 +10,8 @@
 
 // Regression test for issue #152.
 pub fn main() {
-    let mut b: uint = 1_usize;
-    while b <= 32_usize {
+    let mut b: usize = 1_usize;
+    while b < std::mem::size_of::<usize>() {
         0_usize << b;
         b <<= 1_usize;
         println!("{}", b);
index cc36b625c35d50f728902e1ee8c2c80e3c77e119..14a9cc4c2489a5b005d2c2368f5f24bb0e74bdd6 100644 (file)
@@ -13,8 +13,8 @@ use std::ops::{Deref, DerefMut};
 
 #[derive(PartialEq)]
 struct DerefCounter<T> {
-    count_imm: Cell<uint>,
-    count_mut: uint,
+    count_imm: Cell<usize>,
+    count_mut: usize,
     value: T
 }
 
@@ -27,7 +27,7 @@ impl<T> DerefCounter<T> {
         }
     }
 
-    fn counts(&self) -> (uint, uint) {
+    fn counts(&self) -> (usize, usize) {
         (self.count_imm.get(), self.count_mut)
     }
 }
@@ -50,12 +50,12 @@ impl<T> DerefMut for DerefCounter<T> {
 
 #[derive(PartialEq, Debug)]
 struct Point {
-    x: int,
-    y: int
+    x: isize,
+    y: isize
 }
 
 impl Point {
-    fn get(&self) -> (int, int) {
+    fn get(&self) -> (isize, isize) {
         (self.x, self.y)
     }
 }
index 4cb7ece4ab87643248f6ce60f9206d8465c82a83..fdf42423b662b25fc8d3124c9a75fc204d21ee7d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::ops::Deref;
 
 struct DerefArray<'a, T:'a> {
index d023a01f4b1ddf16a253faf3b6832bed75d1ad06..6880032e69f66f5f2909a7ab25fd9c26ffedbeb4 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::rc::Rc;
 use std::ops::Deref;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct DerefWrapper<X, Y> {
     x: X,
     y: Y
@@ -34,7 +36,7 @@ impl<X, Y> Deref for DerefWrapper<X, Y> {
 mod priv_test {
     use std::ops::Deref;
 
-    #[derive(Copy)]
+    #[derive(Copy, Clone)]
     pub struct DerefWrapperHideX<X, Y> {
         x: X,
         pub y: Y
index d50f2efe0e7b4cab54f64e42ffb2c990619cfa43..38bf68b746946c1ca52bb3259612d4a3de16ccbd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::ops::Deref;
 
 struct DerefWithHelper<H, T> {
@@ -33,10 +35,10 @@ impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> {
     }
 }
 
-struct Foo {x: int}
+struct Foo {x: isize}
 
 impl Foo {
-    fn foo(&self) -> int {self.x}
+    fn foo(&self) -> isize {self.x}
 }
 
 pub fn main() {
index f8dd729ec67dcd9bf2c919e86e299c886c1d911a..b97fb491124842af4d635b0433086ba7962a3b4e 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:overloaded_autoderef_xc.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate overloaded_autoderef_xc;
 
 fn main() {
index f40c9dc45cab1c592adc549c22d50c1e557934e3..ddd6ae4d0a090cf4fcce7c5973f50b677d3bf4a3 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, collections, core)]
 
 use std::cell::RefCell;
 use std::rc::Rc;
@@ -17,14 +17,15 @@ use std::num::ToPrimitive;
 
 #[derive(PartialEq, Debug)]
 struct Point {
-    x: int,
-    y: int
+    x: isize,
+    y: isize
 }
 
 pub fn main() {
-    let box_5 = box 5_usize;
+    let box_5: Box<_> = box 5_usize;
     assert_eq!(Rc::new(5_usize).to_uint(), Some(5));
-    assert_eq!((box &box &Rc::new(box box &box_5)).to_uint(), Some(5));
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    assert_eq!((Box::new(&Box::new(&Rc::new(Box::new(Box::new(&box_5)))))).to_uint(), Some(5));
     let point = Rc::new(Point {x: 2, y: 4});
     assert_eq!(point.x, 2);
     assert_eq!(point.y, 4);
index 25b63cd14c4357f2a70bca5c8116a391d4255875..291d2c6498f999ccf9ec7b755d7865ee09eed289 100644 (file)
@@ -11,7 +11,9 @@
 // Tests calls to closure arguments where the closure takes 1 argument.
 // This is a bit tricky due to rust-call ABI.
 
-fn foo(f: &mut FnMut(int) -> int) -> int {
+// pretty-expanded FIXME #23616
+
+fn foo(f: &mut FnMut(isize) -> isize) -> isize {
     f(22)
 }
 
index 026ebc308408fcac54583dc2f2892e94c90aef84..42c71572a3a94301c947de2da95f3def2f0b61f3 100644 (file)
@@ -11,7 +11,9 @@
 // Tests calls to closure arguments where the closure takes 2 arguments.
 // This is a bit tricky due to rust-call ABI.
 
-fn foo(f: &mut FnMut(int, int) -> int) -> int {
+// pretty-expanded FIXME #23616
+
+fn foo(f: &mut FnMut(isize, isize) -> isize) -> isize {
     f(1, 2)
 }
 
index b38f8213b4ab83480908be73aa047f05466734a5..9bc6c9f042835bf34157103340518dca167c3444 100644 (file)
@@ -11,7 +11,9 @@
 // Tests calls to closure arguments where the closure takes 0 arguments.
 // This is a bit tricky due to rust-call ABI.
 
-fn foo(f: &mut FnMut() -> int) -> int {
+// pretty-expanded FIXME #23616
+
+fn foo(f: &mut FnMut() -> isize) -> isize {
     f()
 }
 
index 2ef9e08134cf7259fcf5dde6a4f99a59ac889bdb..597075c550051bc8664e3b0e63853468757f8932 100644 (file)
@@ -10,7 +10,9 @@
 
 // Tests that nested vtables work with overloaded calls.
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, core)]
 
 use std::marker::PhantomData;
 use std::ops::Fn;
@@ -19,14 +21,21 @@ use std::ops::Add;
 struct G<A>(PhantomData<A>);
 
 impl<'a, A: Add<i32, Output=i32>> Fn<(A,)> for G<A> {
-    type Output = i32;
-
     extern "rust-call" fn call(&self, (arg,): (A,)) -> i32 {
         arg.add(1)
     }
 }
 
+impl<'a, A: Add<i32, Output=i32>> FnMut<(A,)> for G<A> {
+    extern "rust-call" fn call_mut(&mut self, args: (A,)) -> i32 { self.call(args) }
+}
+
+impl<'a, A: Add<i32, Output=i32>> FnOnce<(A,)> for G<A> {
+    type Output = i32;
+    extern "rust-call" fn call_once(self, args: (A,)) -> i32 { self.call(args) }
+}
+
 fn main() {
     // ICE trigger
-    (G(PhantomData))(1_i32);
+    (G(PhantomData))(1);
 }
index f9e838d9b3d342cd9618a26b2b690eeb17b0d273..eeb705a2e3c99b5db12af2de0530c1a98b1c1399 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(lang_items, unboxed_closures, core)]
 
 use std::ops::{Fn, FnMut, FnOnce};
 
@@ -18,24 +20,38 @@ struct S1 {
 }
 
 impl FnMut<(i32,)> for S1 {
-    type Output = i32;
     extern "rust-call" fn call_mut(&mut self, (z,): (i32,)) -> i32 {
         self.x * self.y * z
     }
 }
 
+impl FnOnce<(i32,)> for S1 {
+    type Output = i32;
+    extern "rust-call" fn call_once(mut self, args: (i32,)) -> i32 {
+        self.call_mut(args)
+    }
+}
+
 struct S2 {
     x: i32,
     y: i32,
 }
 
 impl Fn<(i32,)> for S2 {
-    type Output = i32;
     extern "rust-call" fn call(&self, (z,): (i32,)) -> i32 {
         self.x * self.y * z
     }
 }
 
+impl FnMut<(i32,)> for S2 {
+    extern "rust-call" fn call_mut(&mut self, args: (i32,)) -> i32 { self.call(args) }
+}
+
+impl FnOnce<(i32,)> for S2 {
+    type Output = i32;
+    extern "rust-call" fn call_once(self, args: (i32,)) -> i32 { self.call(args) }
+}
+
 struct S3 {
     x: i32,
     y: i32,
@@ -70,4 +86,3 @@ fn main() {
     let ans = s(3, 1);
     assert_eq!(ans, 27);
 }
-
index ce7395673b390a7c8ddd2199b59fe3ae675d21ad..8df4adf6713c423223670463cff85d842a68ab48 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
 
-use std::ops::{FnMut};
+#![feature(unboxed_closures, core)]
+
+use std::ops::FnMut;
 
 struct S {
     x: i32,
@@ -18,12 +20,16 @@ struct S {
 }
 
 impl FnMut<()> for S {
-    type Output = i32;
     extern "rust-call" fn call_mut(&mut self, (): ()) -> i32 {
         self.x * self.y
     }
 }
 
+impl FnOnce<()> for S {
+    type Output = i32;
+    extern "rust-call" fn call_once(mut self, args: ()) -> i32 { self.call_mut(args) }
+}
+
 fn main() {
     let mut s = S {
         x: 3,
@@ -32,5 +38,3 @@ fn main() {
     let ans = s();
     assert_eq!(ans, 9);
 }
-
-
index f3091b53e8badc02e5223d2b4a30feb595f0889e..5f6eb87ae1be41198f635fec5230e1758e98cfc7 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::cell::Cell;
 use std::ops::{Deref, DerefMut};
 use std::vec::Vec;
 
 struct DerefCounter<T> {
-    count_imm: Cell<uint>,
-    count_mut: uint,
+    count_imm: Cell<usize>,
+    count_mut: usize,
     value: T
 }
 
@@ -27,7 +29,7 @@ impl<T> DerefCounter<T> {
         }
     }
 
-    fn counts(&self) -> (uint, uint) {
+    fn counts(&self) -> (usize, usize) {
         (self.count_imm.get(), self.count_mut)
     }
 }
index f56e7d56fe16aec00df2034f97375ea37f461eb2..6d8bb30c83755ffd37a5928d6f4ee5ec61ec53d2 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(collections)]
 
 use std::cell::RefCell;
 use std::rc::Rc;
@@ -17,13 +16,13 @@ use std::string::String;
 
 #[derive(PartialEq, Debug)]
 struct Point {
-    x: int,
-    y: int
+    x: isize,
+    y: isize
 }
 
 pub fn main() {
     assert_eq!(*Rc::new(5), 5);
-    assert_eq!(***Rc::new(box box 5), 5);
+    assert_eq!(***Rc::new(Box::new(Box::new(5))), 5);
     assert_eq!(*Rc::new(Point {x: 2, y: 4}), Point {x: 2, y: 4});
 
     let i = Rc::new(RefCell::new(2));
index 0064748e883699dc3968e813eae7c5c389ed89b9..131098d7c94e2af8e35fa8d5218a379c813ae018 100644 (file)
 // Test overloading of the `[]` operator.  In particular test that it
 // takes its argument *by reference*.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::ops::Index;
 
 struct AssociationList<K,V> {
@@ -28,7 +32,7 @@ impl<K,V> AssociationList<K,V> {
     }
 }
 
-impl<K: PartialEq + std::fmt::Debug, V:Clone> Index<K> for AssociationList<K,V> {
+impl<'a, K: PartialEq + std::fmt::Debug, V:Clone> Index<&'a K> for AssociationList<K,V> {
     type Output = V;
 
     fn index<'a>(&'a self, index: &K) -> &'a V {
@@ -49,9 +53,9 @@ pub fn main() {
     list.push(foo.clone(), 22);
     list.push(bar.clone(), 44);
 
-    assert!(list[foo] == 22);
-    assert!(list[bar] == 44);
+    assert!(list[&foo] == 22);
+    assert!(list[&bar] == 44);
 
-    assert!(list[foo] == 22);
-    assert!(list[bar] == 44);
+    assert!(list[&foo] == 22);
+    assert!(list[&bar] == 44);
 }
index d5ccf8cd2befb0f4f18e29fc0021ba49f4d814bf..56d71edd56cd00a4d1c4ed6d7be2d7cc3cb94bee 100644 (file)
 
 // Test overloaded indexing combined with autoderef.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, core)]
 
 use std::ops::{Index, IndexMut};
 
 struct Foo {
-    x: int,
-    y: int,
+    x: isize,
+    y: isize,
 }
 
-impl Index<int> for Foo {
-    type Output = int;
+impl Index<isize> for Foo {
+    type Output = isize;
 
-    fn index(&self, z: &int) -> &int {
-        if *z == 0 {
+    fn index(&self, z: isize) -> &isize {
+        if z == 0 {
             &self.x
         } else {
             &self.y
@@ -32,9 +34,9 @@ impl Index<int> for Foo {
     }
 }
 
-impl IndexMut<int> for Foo {
-    fn index_mut(&mut self, z: &int) -> &mut int {
-        if *z == 0 {
+impl IndexMut<isize> for Foo {
+    fn index_mut(&mut self, z: isize) -> &mut isize {
+        if z == 0 {
             &mut self.x
         } else {
             &mut self.y
@@ -43,19 +45,19 @@ impl IndexMut<int> for Foo {
 }
 
 trait Int {
-    fn get(self) -> int;
-    fn get_from_ref(&self) -> int;
+    fn get(self) -> isize;
+    fn get_from_ref(&self) -> isize;
     fn inc(&mut self);
 }
 
-impl Int for int {
-    fn get(self) -> int { self }
-    fn get_from_ref(&self) -> int { *self }
+impl Int for isize {
+    fn get(self) -> isize { self }
+    fn get_from_ref(&self) -> isize { *self }
     fn inc(&mut self) { *self += 1; }
 }
 
 fn main() {
-    let mut f = box Foo {
+    let mut f: Box<_> = box Foo {
         x: 1,
         y: 2,
     };
index 487fb93c9fee8f3a09135d7503989ade445b6158..bc53836aca3ef9dc6b3371fa59120d2b4a62dca0 100644 (file)
 // Test using overloaded indexing when the "map" is stored in a
 // field. This caused problems at some point.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::ops::Index;
 
 struct Foo {
-    x: int,
-    y: int,
+    x: isize,
+    y: isize,
 }
 
 struct Bar {
     foo: Foo
 }
 
-impl Index<int> for Foo {
-    type Output = int;
+impl Index<isize> for Foo {
+    type Output = isize;
 
-    fn index(&self, z: &int) -> &int {
-        if *z == 0 {
+    fn index(&self, z: isize) -> &isize {
+        if z == 0 {
             &self.x
         } else {
             &self.y
@@ -35,14 +39,14 @@ impl Index<int> for Foo {
 }
 
 trait Int {
-    fn get(self) -> int;
-    fn get_from_ref(&self) -> int;
+    fn get(self) -> isize;
+    fn get_from_ref(&self) -> isize;
     fn inc(&mut self);
 }
 
-impl Int for int {
-    fn get(self) -> int { self }
-    fn get_from_ref(&self) -> int { *self }
+impl Int for isize {
+    fn get(self) -> isize { self }
+    fn get_from_ref(&self) -> isize { *self }
     fn inc(&mut self) { *self += 1; }
 }
 
index 10ca3804eaedbc187ab128e619f45d20cd7c41dd..4f8cf0e9e38efd6867f49cfff464df8b2a0b3d1d 100644 (file)
@@ -8,18 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::ops::{Index, IndexMut};
 
 struct Foo {
-    x: int,
-    y: int,
+    x: isize,
+    y: isize,
 }
 
-impl Index<int> for Foo {
-    type Output = int;
+impl Index<isize> for Foo {
+    type Output = isize;
 
-    fn index(&self, z: &int) -> &int {
-        if *z == 0 {
+    fn index(&self, z: isize) -> &isize {
+        if z == 0 {
             &self.x
         } else {
             &self.y
@@ -27,9 +31,9 @@ impl Index<int> for Foo {
     }
 }
 
-impl IndexMut<int> for Foo {
-    fn index_mut(&mut self, z: &int) -> &mut int {
-        if *z == 0 {
+impl IndexMut<isize> for Foo {
+    fn index_mut(&mut self, z: isize) -> &mut isize {
+        if z == 0 {
             &mut self.x
         } else {
             &mut self.y
@@ -38,14 +42,14 @@ impl IndexMut<int> for Foo {
 }
 
 trait Int {
-    fn get(self) -> int;
-    fn get_from_ref(&self) -> int;
+    fn get(self) -> isize;
+    fn get_from_ref(&self) -> isize;
     fn inc(&mut self);
 }
 
-impl Int for int {
-    fn get(self) -> int { self }
-    fn get_from_ref(&self) -> int { *self }
+impl Int for isize {
+    fn get(self) -> isize { self }
+    fn get_from_ref(&self) -> isize { *self }
     fn inc(&mut self) { *self += 1; }
 }
 
index 2db6f7ffaaa61ccab311c3ecb93a978c91ddc04a..f698b660751aba3872dd8dcb5860a3b668618b53 100644 (file)
@@ -8,11 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 fn f<T: 'static>(_x: T) {}
 
 pub fn main() {
-    f(box 5);
+    f(Box::new(5));
 }
index c6c74fe3fda1d59aac5fca873a4c64d78b904091..8819b201361055b68848c08a7b2df8b6ddce6ca9 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[repr(packed)]
 struct Foo {
     bar: u8,
-    baz: uint
+    baz: usize
 }
 
 pub fn main() {
index 004a30220183ed101a9b5b28010625286121a397..5d518749d9aefec9bf221b6ecc191ccc998f7f4b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
 #[repr(packed)]
index 45791332bbedfae08a6b635a1cf3da428ef73c86..6c24b71971e3876aa5f15cd6ad08037ea36a6145 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
 #[repr(packed)]
index 9e94502a92a6384199380bd85bc708ed62d80cea..5d2454be2fbd5ee26cc358d7475c2d10fef7aa31 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
 #[repr(packed)]
index 46ffed0cba9684004caddf2f751bfb65b4c0c0b9..3c3d632222e192ade9653e81a976ff3f7bdb6af4 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #[repr(packed)]
 struct Foo {
     bar: u8,
-    baz: uint
+    baz: usize
 }
 
 pub fn main() {
index c2968956785faa3032c21321d077db0ff87350c7..b7ea720caf76d3829a778fe03ac0708cc493608d 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:packed.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate packed;
 
 use std::mem;
index 846d51e2e7ecc916e29e1fad89a53541ab5bc610..3d748c404228bcae59536346aee914b29b489e46 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
 #[repr(packed)]
index cfe49c38c5267835a1e1b4c57c06895634d5b857..9a327eb567266bf0da01211ba00f160c4ebb0af1 100644 (file)
@@ -13,7 +13,7 @@
 use std::mem;
 
 #[repr(packed)]
-#[derive(Copy, PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 struct Foo {
     bar: u8,
     baz: u64
@@ -24,7 +24,7 @@ pub fn main() {
 
     assert_eq!(mem::size_of::<[Foo; 10]>(), 90);
 
-    for i in 0_usize..10 {
+    for i in 0..10 {
         assert_eq!(foos[i], Foo { bar: 1, baz: 2});
     }
 
index c41d678b0f5b702826f1b7e098112bc9a5b37f5d..9d96adc29dd36e614d4030cc4961bfb90f60cd57 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
 #[repr(packed)]
index a0b88ea53c5a4f3d60d54de588ffbeba0e8cd883..7b7cd5929883d3b07694da74cf2e447eedab555f 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
 #[repr(packed)]
index 6da15b97acaae220453ed519593bd5c2e992251f..4226fba9d3e37ea9e1972def5576ea344d7a70f1 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::thread;
 
 static mut dropped: bool = false;
@@ -17,7 +19,7 @@ struct A {
 }
 
 struct B {
-    foo: int,
+    foo: isize,
 }
 
 impl Drop for A {
index 061c9168955a49c73db68dc7ba3700ed72b20a3d..3e74341d819812f3bf98940a1372755c773367e6 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 
@@ -21,7 +23,7 @@ mod foo {
 
 fn foo1<T>(_: &(A<T> + Send)) {}
 fn foo2<T>(_: Box<A<T> + Send + Sync>) {}
-fn foo3<T>(_: Box<B<int, uint> + 'static>) {}
+fn foo3<T>(_: Box<B<isize, usize> + 'static>) {}
 fn foo4<'a, T>(_: Box<C<'a, T> + 'static + Send>) {}
 fn foo5<'a, T>(_: Box<foo::D<'a, T> + 'static + Send>) {}
 
index 5649c4c784dafdab7a19cb563ab3dbe76e10a544..c81677220539e90ddb10ff5732013ed6c72bd1b3 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
     type T;
     fn foo() -> Box<<Self as Foo>::T>;
index 0995910fd4cf64ffbc9c786330f40a0fc7884866..e4c9fd9d8ef836494597ab48416a6ba8ed3d8279 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test parsing binary operators after macro invocations.
 
+// pretty-expanded FIXME #23616
+
 #![feature(macro_rules)]
 
 macro_rules! id {
index 02d8602d59e311618fd820922d239d3aa851e4eb..fddc2744eb1745c2e90c856ddd91afecdd619d18 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 mod foo {
-    pub fn bar(_offset: uint) { }
+    pub fn bar(_offset: usize) { }
 }
 
-pub fn main() { foo::bar(0_usize); }
+pub fn main() { foo::bar(0); }
index 7d9c3d324f070c227f8cac3a2db2303981409a65..1ab578b93325789d328f3b0a90ebf14e9ae35df7 100644 (file)
@@ -12,7 +12,9 @@
 // pattern-bound var is an upvar (when translating
 // the for-each body)
 
-fn foo(src: uint) {
+// pretty-expanded FIXME #23616
+
+fn foo(src: usize) {
 
     match Some(src) {
       Some(src_id) => {
index e4f1df2d6376df916c553f21a2e8ec7abbaf7d17..909ed985d7f48804c6184587331231e3586c33cf 100644 (file)
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 struct Foo {
-    x: int,
-    y: int
+    x: isize,
+    y: isize
 }
 
 pub fn main() {
-    let f = |(x, _): (int, int)| println!("{}", x + 1);
+    let f = |(x, _): (isize, isize)| println!("{}", x + 1);
     let g = |Foo { x: x, y: _y }: Foo| println!("{}", x + 1);
     f((2, 3));
     g(Foo { x: 1, y: 2 });
index 7ad93d271a989556b892772fda0a3e2638e78d53..7ac624e6814dbb6c95eeb97ff32c58ef5961ff5c 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(rustc_private)]
+
 extern crate arena;
 use arena::Arena;
 
index 15bf05fc0cbec3f56ade87a4229a776b0216dd87..f0f3d3d7bd886fa9cb1921f4f639af278632ee7d 100644 (file)
@@ -11,6 +11,8 @@
 // this checks that a pred with a non-bool return
 // type is rejected, even if the pred is never used
 
-fn bad(_a: int) -> int { return 37; } //~ ERROR Non-boolean return type
+// pretty-expanded FIXME #23616
+
+fn bad(_a: isize) -> isize { return 37; } //~ ERROR Non-boolean return type
 
 pub fn main() { }
index bcfc39ee7e4e65c947d8247af0adf5eb6b0ce219..7e5e41820e99947a1ed3ad3a99df9945c9d174ad 100644 (file)
 // note: halfway done porting to modern rust
 use std::comm;
 
-fn starve_main(alive: Receiver<int>) {
+fn starve_main(alive: Receiver<isize>) {
     println!("signalling main");
     alive.recv();
     println!("starving main");
-    let mut i: int = 0;
+    let mut i: isize = 0;
     loop { i += 1; }
 }
 
@@ -29,7 +29,7 @@ pub fn main() {
     spawn(move|| {
         starve_main(port);
     });
-    let mut i: int = 0;
+    let mut i: isize = 0;
     println!("main waiting for alive signal");
     chan.send(i);
     println!("main got alive signal");
index 679aa3d668f49286868a7e7f116f1fb4d4ba2883..aa2db260dd4ae3ca424d9247766e5355af0cb5a4 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:priv-impl-prim-ty.rs
 
-extern crate "priv-impl-prim-ty" as bar;
+// pretty-expanded FIXME #23616
+
+extern crate priv_impl_prim_ty as bar;
 
 pub fn main() {
     bar::frob(1);
index e9b8e694d60605c3e445102a97571429b1eaada5..8082816c4361159dec9d05f3d9748ac377508c44 100644 (file)
@@ -12,6 +12,8 @@
 // Check we do the correct privacy checks when we import a name and there is an
 // item with that name in both the value and type namespaces.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 #![allow(unused_imports)]
 
index b40aacdafc1faa4c2f8f58500899c4565ac3a65c..d9d107d900b6a946cb6bb760795857f845c242c2 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:privacy_reexport.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate privacy_reexport;
 
 pub fn main() {
index 7a07c97090223c4434193ac6ae482b204db786f8..329c4aaa873a98de6ce1387836012ecc99c3a0bf 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub mod test2 {
     // This used to generate an ICE (make sure that default functions are
     // parented to their trait to find the first private thing as the trait).
index c7380b362fbbad794447b2b2e7de26072d37f8b8..d32ac4b90821f8ccf657e1c5901e6e4e1388c1e3 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct cat {
-    meows : uint,
+    meows : usize,
 
-    how_hungry : int,
+    how_hungry : isize,
 }
 
 impl cat {
-  pub fn meow_count(&mut self) -> uint { self.meows }
+  pub fn meow_count(&mut self) -> usize { self.meows }
 }
 
-fn cat(in_x : uint, in_y : int) -> cat {
+fn cat(in_x : usize, in_y : isize) -> cat {
     cat {
         meows: in_x,
         how_hungry: in_y
@@ -26,6 +28,6 @@ fn cat(in_x : uint, in_y : int) -> cat {
 }
 
 pub fn main() {
-    let mut nyan : cat = cat(52_usize, 99);
-    assert_eq!(nyan.meow_count(), 52_usize);
+    let mut nyan : cat = cat(52, 99);
+    assert_eq!(nyan.meow_count(), 52);
 }
index 498bd04e37cc2a2bbdd92270163183198ed08b0a..0d6e6010c56c84c719a6eaafde7ed554e7de0623 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct cat {
-    meows : uint,
+    meows : usize,
 
-    how_hungry : int,
+    how_hungry : isize,
 }
 
 impl cat {
@@ -25,7 +27,7 @@ impl cat {
     fn nap(&mut self) { for _ in 1_usize..10_usize { } }
 }
 
-fn cat(in_x : uint, in_y : int) -> cat {
+fn cat(in_x : usize, in_y : isize) -> cat {
     cat {
         meows: in_x,
         how_hungry: in_y
diff --git a/src/test/run-pass/process-exit.rs b/src/test/run-pass/process-exit.rs
new file mode 100644 (file)
index 0000000..9ef66ff
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2015 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 std::env;
+use std::process::{self, Command, Stdio};
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    if args.len() > 1 && args[1] == "child" {
+        child();
+    } else {
+        parent();
+    }
+}
+
+fn parent() {
+    let args: Vec<String> = env::args().collect();
+    let status = Command::new(&args[0]).arg("child").status().unwrap();
+    assert_eq!(status.code(), Some(2));
+}
+
+fn child() -> i32 {
+    process::exit(2);
+}
index 9eb7d624c9921bf602fbc7ab34ddebcd994d73d9..6429352f4491888728de2894ec380baeb792d70d 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(old_io)]
+
 use std::old_io::Command;
 use std::env;
 
index 017784990f4178ece9fcc4dff70c6cbca120b35e..32448d100fb9b0b4dfff27a9ae50685c0656edd8 100644 (file)
 // non-ASCII characters.  The child process ensures all the strings are
 // intact.
 
-use std::old_io;
-use std::old_io::fs;
-use std::old_io::Command;
+// ignore-aarch64
+#![feature(path, fs, os, io, old_path)]
+
+use std::io::prelude::*;
+use std::io;
+use std::fs;
+use std::process::Command;
 use std::os;
 use std::env;
-use std::old_path::Path;
+use std::path::{Path, PathBuf};
 
 fn main() {
     let my_args = env::args().collect::<Vec<_>>();
-    let my_cwd  = os::getcwd().unwrap();
+    let my_cwd  = env::current_dir().unwrap();
     let my_env  = env::vars().collect::<Vec<_>>();
-    let my_path = Path::new(os::self_exe_name().unwrap());
-    let my_dir  = my_path.dir_path();
-    let my_ext  = my_path.extension_str().unwrap_or("");
+    let my_path = env::current_exe().unwrap();
+    let my_dir  = my_path.parent().unwrap();
+    let my_ext  = my_path.extension().and_then(|s| s.to_str()).unwrap_or("");
 
     // some non-ASCII characters
-    let blah       = "\u03c0\u042f\u97f3\u00e6\u221e";
+    let blah       = "\u{3c0}\u{42f}\u{97f3}\u{e6}\u{221e}";
 
     let child_name = "child";
     let child_dir  = format!("process-spawn-with-unicode-params-{}", blah);
 
     // parameters sent to child / expected to be received from parent
     let arg = blah;
-    let cwd = my_dir.join(Path::new(child_dir.clone()));
+    let cwd = my_dir.join(&child_dir);
     let env = ("RUST_TEST_PROC_SPAWN_UNICODE".to_string(), blah.to_string());
 
     // am I the parent or the child?
@@ -47,24 +51,22 @@ fn main() {
 
         let child_filestem = Path::new(child_name);
         let child_filename = child_filestem.with_extension(my_ext);
-        let child_path     = cwd.join(child_filename);
+        let child_path     = cwd.join(&child_filename);
 
         // make a separate directory for the child
-        drop(fs::mkdir(&cwd, old_io::USER_RWX).is_ok());
-        assert!(fs::copy(&my_path, &child_path).is_ok());
-        let mut my_env = my_env;
-        my_env.push(env);
+        let _ = fs::create_dir(&cwd);
+        fs::copy(&my_path, &child_path).unwrap();
 
         // run child
         let p = Command::new(&child_path)
                         .arg(arg)
-                        .cwd(&cwd)
-                        .env_set_all(&my_env)
+                        .current_dir(&cwd)
+                        .env(&env.0, &env.1)
                         .spawn().unwrap().wait_with_output().unwrap();
 
         // display the output
-        assert!(old_io::stdout().write(&p.output).is_ok());
-        assert!(old_io::stderr().write(&p.error).is_ok());
+        io::stdout().write_all(&p.stdout).unwrap();
+        io::stderr().write_all(&p.stderr).unwrap();
 
         // make sure the child succeeded
         assert!(p.status.success());
@@ -72,7 +74,7 @@ fn main() {
     } else {                            // child
 
         // check working directory (don't try to compare with `cwd` here!)
-        assert!(my_cwd.ends_with_path(&Path::new(child_dir)));
+        assert!(my_cwd.ends_with(&child_dir));
 
         // check arguments
         assert_eq!(&*my_args[1], arg);
index a6a8890101c5b04ceaf1f8585a41606631134da3..ac1b6aebec5b1cd1785a5389115a5a8ac6d11ba8 100644 (file)
 
 // Test coercions between pointers which don't do anything fancy like unsizing.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     // &mut -> &
-    let x: &mut int = &mut 42;
-    let x: &int = x;
+    let x: &mut isize = &mut 42;
+    let x: &isize = x;
 
-    let x: &int = &mut 42;
+    let x: &isize = &mut 42;
 
     // & -> *const
-    let x: &int = &42;
-    let x: *const int = x;
+    let x: &isize = &42;
+    let x: *const isize = x;
 
-    let x: *const int = &42;
+    let x: *const isize = &42;
 
     // &mut -> *const
-    let x: &mut int = &mut 42;
-    let x: *const int = x;
+    let x: &mut isize = &mut 42;
+    let x: *const isize = x;
 
-    let x: *const int = &mut 42;
+    let x: *const isize = &mut 42;
 
     // *mut -> *const
-    let x: *mut int = &mut 42;
-    let x: *const int = x;
+    let x: *mut isize = &mut 42;
+    let x: *const isize = x;
 }
index 7428377b59fc40e53922bee2d6cb8dedab1b0006..b9a3f788f9794445eda83e51b64303718e371ab2 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem::transmute;
 
 mod a {
index 442eea13d6bacb6c8cf69c767be40d3c8d6d68ba..d082ca624e0989b7a204641c98008e3fda57f5f8 100644 (file)
@@ -10,6 +10,8 @@
 
 // Issue #14660
 
+// pretty-expanded FIXME #23616
+
 mod bleh {
     macro_rules! foo {
         () => {
index af2f217c1fbb2ca31d6a03f7e74fe74d554222d0..2e2e261b6d021d5e4b729fb367e3f17e01fb3aed 100644 (file)
@@ -10,6 +10,8 @@
 
 // Issue #17436
 
+// pretty-expanded FIXME #23616
+
 mod bleh {
     macro_rules! foo {
         () => {
index cdc184898fd68b9d020ef586f0e6ae21c5fb4d5a..3318c0380be74f3e493ecd26f7c31786c1bb4647 100644 (file)
@@ -11,6 +11,8 @@
 // aux-build:pub_use_xcrate1.rs
 // aux-build:pub_use_xcrate2.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate pub_use_xcrate2;
 
 use pub_use_xcrate2::Foo;
index ceba89523b5f9f3f8a2a208d18cdc58e8ea9d0ca..9373b7945d55abb6c3d83e48ee6ec30cffd6a95b 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:pub_use_mods_xcrate.rs
 
+// pretty-expanded FIXME #23616
+
 #![allow(unused_imports)]
 
 extern crate pub_use_mods_xcrate;
index f7adb0f6e444b91a18adedd6e70817a352dfe351..c27b95e1f135d5e533c18d299af18041989ffac5 100644 (file)
 
 // Check that functions can modify local state.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn sums_to(v: Vec<int> , sum: int) -> bool {
-    let mut i = 0_usize;
+fn sums_to(v: Vec<isize> , sum: isize) -> bool {
+    let mut i = 0;
     let mut sum0 = 0;
     while i < v.len() {
         sum0 += v[i];
-        i += 1_usize;
+        i += 1;
     }
     return sum0 == sum;
 }
 
-fn sums_to_using_uniq(v: Vec<int> , sum: int) -> bool {
-    let mut i = 0_usize;
-    let mut sum0 = box 0;
+fn sums_to_using_uniq(v: Vec<isize> , sum: isize) -> bool {
+    let mut i = 0;
+    let mut sum0: Box<_> = box 0;
     while i < v.len() {
         *sum0 += v[i];
-        i += 1_usize;
+        i += 1;
     }
     return *sum0 == sum;
 }
 
-fn sums_to_using_rec(v: Vec<int> , sum: int) -> bool {
-    let mut i = 0_usize;
+fn sums_to_using_rec(v: Vec<isize> , sum: isize) -> bool {
+    let mut i = 0;
     let mut sum0 = F {f: 0};
     while i < v.len() {
         sum0.f += v[i];
-        i += 1_usize;
+        i += 1;
     }
     return sum0.f == sum;
 }
 
 struct F<T> { f: T }
 
-fn sums_to_using_uniq_rec(v: Vec<int> , sum: int) -> bool {
-    let mut i = 0_usize;
-    let mut sum0 = F {f: box 0};
+fn sums_to_using_uniq_rec(v: Vec<isize> , sum: isize) -> bool {
+    let mut i = 0;
+    let mut sum0 = F::<Box<_>> {f: box 0};
     while i < v.len() {
         *sum0.f += v[i];
-        i += 1_usize;
+        i += 1;
     }
     return *sum0.f == sum;
 }
index 51945a4677d916c41a81dd48cc90b77717fc659f..2d664c00ed527ff628f41844e11b72259874b249 100644 (file)
@@ -12,6 +12,8 @@
 // good as the old one. Check out issue #21672, #21595 and #21649 for
 // more details.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let xs = (0..8).map(|i| i == 1u64).collect::<Vec<_>>();
     assert_eq!(xs[1], true);
index 50b90b1a5ee0b409bc14e5d88b5334333dca47f7..4633f73b9a007a0994a7b81b815cd444c2274100 100644 (file)
@@ -10,7 +10,9 @@
 
 // Test range syntax.
 
-fn foo() -> int { 42 }
+// pretty-expanded FIXME #23616
+
+fn foo() -> isize { 42 }
 
 // Test that range syntax works in return statements
 fn return_range_to() -> ::std::ops::RangeTo<i32> { return ..1; }
index db414abb7ffc87478820738a37b5fdaa43b6148c..870d7a0bc0873009d6e4d3ad126c4883ba4eb8ef 100644 (file)
 // Test that the precedence of ranges is correct
 
 
+// pretty-expanded FIXME #23616
+
 struct Foo {
-    foo: uint,
+    foo: usize,
 }
 
 impl Foo {
-    fn bar(&self) -> uint { 5 }
+    fn bar(&self) -> usize { 5 }
 }
 
 fn main() {
@@ -38,7 +40,7 @@ fn main() {
     let x = ..1+3;
     assert!(x == (..4));
 
-    let a = &[0i32, 1, 2, 3, 4, 5, 6];
+    let a = &[0, 1, 2, 3, 4, 5, 6];
     let x = &a[1+1..2+2];
     assert!(x == &a[2..4]);
     let x = &a[..1+2];
@@ -58,4 +60,3 @@ fn main() {
     let y = ..;
     assert!(y == (..));
 }
-
index 35e863d05a177dd06262b4d4302b5f40886ed0aa..298ac8f77eb11dd6f5a4a63ea68920e34a5e7d61 100644 (file)
Binary files a/src/test/run-pass/raw-str.rs and b/src/test/run-pass/raw-str.rs differ
index 84a230fd5767c201b25a00b417a735ebd4b39ff6..6e9769ea2b9282a8037ee21d99d6f102b30db4c6 100644 (file)
 #![feature(box_syntax)]
 
 trait get {
-    fn get(self) -> int;
+    fn get(self) -> isize;
 }
 
 // Note: impl on a slice; we're checking that the pointers below
-// correctly get borrowed to `&`. (similar to impling for `int`, with
+// correctly get borrowed to `&`. (similar to impling for `isize`, with
 // `&self` instead of `self`.)
-impl<'a> get for &'a int {
-    fn get(self) -> int {
+impl<'a> get for &'a isize {
+    fn get(self) -> isize {
         return *self;
     }
 }
 
 pub fn main() {
-    let x = box 6;
+    let x: Box<_> = box 6;
     let y = x.get();
     println!("y={}", y);
     assert_eq!(y, 6);
index 6a5da0149947abd8225cc0b4bd02cdf745a4e480..1ec16747181c2b2d0a7efabbcc477065d4c23d22 100644 (file)
 
 
 trait sum {
-    fn sum_(self) -> int;
+    fn sum_(self) -> isize;
 }
 
 // Note: impl on a slice
-impl<'a> sum for &'a [int] {
-    fn sum_(self) -> int {
+impl<'a> sum for &'a [isize] {
+    fn sum_(self) -> isize {
         self.iter().fold(0, |a, &b| a + b)
     }
 }
 
-fn call_sum(x: &[int]) -> int { x.sum_() }
+fn call_sum(x: &[isize]) -> isize { x.sum_() }
 
 pub fn main() {
     let x = vec!(1, 2, 3);
index 51e955c47610939248611f4910204c118e5f0ea0..d3b9e56f7d07938f7dbccd0e83ba8a88e4b3e994 100644 (file)
@@ -11,7 +11,9 @@
 
 
 
-struct Point {x: int, y: int, z: int}
+// pretty-expanded FIXME #23616
+
+struct Point {x: isize, y: isize, z: isize}
 
 fn f(p: Point) { assert!((p.z == 12)); }
 
index de5b14104c5300da7dd50c8b9f66def1104699d2..cd9cc0901202c45d6d061c449b8e9ec7481d7ba8 100644 (file)
@@ -13,6 +13,8 @@
 // Ideally this would be revised to use no_std, but for now it serves
 // well enough to reproduce (and illustrate) the bug from #16687.
 
+#![feature(alloc)]
+
 extern crate alloc;
 
 use alloc::heap;
@@ -26,49 +28,49 @@ fn main() {
 }
 
 unsafe fn test_triangle() -> bool {
-    static COUNT : uint = 16;
+    static COUNT : usize = 16;
     let mut ascend = repeat(ptr::null_mut()).take(COUNT).collect::<Vec<_>>();
     let ascend = &mut *ascend;
-    static ALIGN : uint = 1;
+    static ALIGN : usize = 1;
 
     // Checks that `ascend` forms triangle of ascending size formed
     // from pairs of rows (where each pair of rows is equally sized),
     // and the elements of the triangle match their row-pair index.
     unsafe fn sanity_check(ascend: &[*mut u8]) {
-        for i in 0_usize..COUNT / 2 {
+        for i in 0..COUNT / 2 {
             let (p0, p1, size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
-            for j in 0_usize..size {
-                assert_eq!(*p0.offset(j as int), i as u8);
-                assert_eq!(*p1.offset(j as int), i as u8);
+            for j in 0..size {
+                assert_eq!(*p0.offset(j as isize), i as u8);
+                assert_eq!(*p1.offset(j as isize), i as u8);
             }
         }
     }
 
     static PRINT : bool = false;
 
-    unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
+    unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
         if PRINT { println!("allocate(size={} align={})", size, align); }
 
         let ret = heap::allocate(size, align);
         if ret.is_null() { alloc::oom() }
 
         if PRINT { println!("allocate(size={} align={}) ret: 0x{:010x}",
-                            size, align, ret as uint);
+                            size, align, ret as usize);
         }
 
         ret
     }
-    unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) {
+    unsafe fn deallocate(ptr: *mut u8, size: usize, align: usize) {
         if PRINT { println!("deallocate(ptr=0x{:010x} size={} align={})",
-                            ptr as uint, size, align);
+                            ptr as usize, size, align);
         }
 
         heap::deallocate(ptr, size, align);
     }
-    unsafe fn reallocate(ptr: *mut u8, old_size: uint, size: uint, align: uint) -> *mut u8 {
+    unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
         if PRINT {
             println!("reallocate(ptr=0x{:010x} old_size={} size={} align={})",
-                     ptr as uint, old_size, size, align);
+                     ptr as usize, old_size, size, align);
         }
 
         let ret = heap::reallocate(ptr, old_size, size, align);
@@ -77,29 +79,29 @@ unsafe fn test_triangle() -> bool {
         if PRINT {
             println!("reallocate(ptr=0x{:010x} old_size={} size={} align={}) \
                       ret: 0x{:010x}",
-                     ptr as uint, old_size, size, align, ret as uint);
+                     ptr as usize, old_size, size, align, ret as usize);
         }
         ret
     }
 
-    fn idx_to_size(i: uint) -> uint { (i+1) * 10 }
+    fn idx_to_size(i: usize) -> usize { (i+1) * 10 }
 
     // Allocate pairs of rows that form a triangle shape.  (Hope is
     // that at least two rows will be allocated near each other, so
     // that we trigger the bug (a buffer overrun) in an observable
     // way.)
-    for i in 0_usize..COUNT / 2 {
+    for i in 0..COUNT / 2 {
         let size = idx_to_size(i);
         ascend[2*i]   = allocate(size, ALIGN);
         ascend[2*i+1] = allocate(size, ALIGN);
     }
 
     // Initialize each pair of rows to distinct value.
-    for i in 0_usize..COUNT / 2 {
+    for i in 0..COUNT / 2 {
         let (p0, p1, size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
         for j in 0..size {
-            *p0.offset(j as int) = i as u8;
-            *p1.offset(j as int) = i as u8;
+            *p0.offset(j as isize) = i as u8;
+            *p1.offset(j as isize) = i as u8;
         }
     }
 
@@ -109,7 +111,7 @@ unsafe fn test_triangle() -> bool {
     test_3(ascend); // triangle -> square
     test_4(ascend); // square -> triangle
 
-    for i in 0_usize..COUNT / 2 {
+    for i in 0..COUNT / 2 {
         let size = idx_to_size(i);
         deallocate(ascend[2*i], size, ALIGN);
         deallocate(ascend[2*i+1], size, ALIGN);
@@ -123,7 +125,7 @@ unsafe fn test_triangle() -> bool {
     // rows as we go.
     unsafe fn test_1(ascend: &mut [*mut u8]) {
         let new_size = idx_to_size(COUNT-1);
-        for i in 0_usize..COUNT / 2 {
+        for i in 0..COUNT / 2 {
             let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
             assert!(old_size < new_size);
 
@@ -138,7 +140,7 @@ unsafe fn test_triangle() -> bool {
     // Test 2: turn the square back into a triangle, top to bottom.
     unsafe fn test_2(ascend: &mut [*mut u8]) {
         let old_size = idx_to_size(COUNT-1);
-        for i in 0_usize..COUNT / 2 {
+        for i in 0..COUNT / 2 {
             let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
             assert!(new_size < old_size);
 
@@ -153,7 +155,7 @@ unsafe fn test_triangle() -> bool {
     // Test 3: turn triangle into a square, bottom to top.
     unsafe fn test_3(ascend: &mut [*mut u8]) {
         let new_size = idx_to_size(COUNT-1);
-        for i in (0_usize..COUNT / 2).rev() {
+        for i in (0..COUNT / 2).rev() {
             let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
             assert!(old_size < new_size);
 
@@ -168,7 +170,7 @@ unsafe fn test_triangle() -> bool {
     // Test 4: turn the square back into a triangle, bottom to top.
     unsafe fn test_4(ascend: &mut [*mut u8]) {
         let old_size = idx_to_size(COUNT-1);
-        for i in (0_usize..COUNT / 2).rev() {
+        for i in (0..COUNT / 2).rev() {
             let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
             assert!(new_size < old_size);
 
index 51b800bc9f01f2e101e541ad090d2a9478409d83..e5d76c3e67abd5f6c76dfde5afc00b35f04f6863 100644 (file)
@@ -16,8 +16,8 @@ use std::mem;
 
 mod rusti {
     extern "rust-intrinsic" {
-        pub fn pref_align_of<T>() -> uint;
-        pub fn min_align_of<T>() -> uint;
+        pub fn pref_align_of<T>() -> usize;
+        pub fn min_align_of<T>() -> usize;
     }
 }
 
@@ -38,19 +38,19 @@ struct Outer {
 
 #[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "aarch64"))]
 mod m {
-    pub fn align() -> uint { 4_usize }
-    pub fn size() -> uint { 8_usize }
+    pub fn align() -> usize { 4 }
+    pub fn size() -> usize { 8 }
 }
 
 #[cfg(target_arch = "x86_64")]
 mod m {
-    pub fn align() -> uint { 4_usize }
-    pub fn size() -> uint { 8_usize }
+    pub fn align() -> usize { 4 }
+    pub fn size() -> usize { 8 }
 }
 
 pub fn main() {
     unsafe {
-        let x = Outer {c8: 22u8, t: Inner {c64: 44u32}};
+        let x = Outer {c8: 22, t: Inner {c64: 44}};
 
         // Send it through the shape code
         let y = format!("{:?}", x);
index cf23a1a0f25b29bba539818075ae1b2596d9279c..bae95bcb50f50d2beee9c0422df10a11fc1c1748 100644 (file)
@@ -16,8 +16,8 @@ use std::mem;
 
 mod rusti {
     extern "rust-intrinsic" {
-        pub fn pref_align_of<T>() -> uint;
-        pub fn min_align_of<T>() -> uint;
+        pub fn pref_align_of<T>() -> usize;
+        pub fn min_align_of<T>() -> usize;
     }
 }
 
@@ -44,14 +44,23 @@ struct Outer {
 mod m {
     #[cfg(target_arch = "x86")]
     pub mod m {
-        pub fn align() -> uint { 4_usize }
-        pub fn size() -> uint { 12_usize }
+        pub fn align() -> usize { 4 }
+        pub fn size() -> usize { 12 }
     }
 
     #[cfg(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64"))]
     pub mod m {
-        pub fn align() -> uint { 8_usize }
-        pub fn size() -> uint { 16_usize }
+        pub fn align() -> usize { 8 }
+        pub fn size() -> usize { 16 }
+    }
+}
+
+#[cfg(target_os = "bitrig")]
+mod m {
+    #[cfg(target_arch = "x86_64")]
+    pub mod m {
+        pub fn align() -> usize { 8 }
+        pub fn size() -> usize { 16 }
     }
 }
 
@@ -59,14 +68,14 @@ mod m {
 mod m {
     #[cfg(target_arch = "x86")]
     pub mod m {
-        pub fn align() -> uint { 8_usize }
-        pub fn size() -> uint { 16_usize }
+        pub fn align() -> usize { 8 }
+        pub fn size() -> usize { 16 }
     }
 
     #[cfg(target_arch = "x86_64")]
     pub mod m {
-        pub fn align() -> uint { 8_usize }
-        pub fn size() -> uint { 16_usize }
+        pub fn align() -> usize { 8 }
+        pub fn size() -> usize { 16 }
     }
 }
 
@@ -74,14 +83,14 @@ mod m {
 mod m {
     #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
     pub mod m {
-        pub fn align() -> uint { 8_usize }
-        pub fn size() -> uint { 16_usize }
+        pub fn align() -> usize { 8 }
+        pub fn size() -> usize { 16 }
     }
 }
 
 pub fn main() {
     unsafe {
-        let x = Outer {c8: 22u8, t: Inner {c64: 44u64}};
+        let x = Outer {c8: 22, t: Inner {c64: 44}};
 
         let y = format!("{:?}", x);
 
index de2e937ee84c0bf92ff3c5ab8151d8b18834b9f2..1071df84cd2bb957fa6216442dd806aa6d7a21b1 100644 (file)
@@ -11,7 +11,9 @@
 
 
 
-struct Point {x: int, y: int}
+// pretty-expanded FIXME #23616
+
+struct Point {x: isize, y: isize}
 
 pub fn main() {
     let origin: Point = Point {x: 0, y: 0};
index dab7d26cc820039db62ed98f70a80afa3d10f866..1644a1694269adb77b86a1b46ad4be717498a1fa 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy)]
-struct Point {x: int, y: int}
+// pretty-expanded FIXME #23616
+
+#[derive(Copy, Clone)]
+struct Point {x: isize, y: isize}
 
 type rect = (Point, Point);
 
 fn fst(r: rect) -> Point { let (fst, _) = r; return fst; }
 fn snd(r: rect) -> Point { let (_, snd) = r; return snd; }
 
-fn f(r: rect, x1: int, y1: int, x2: int, y2: int) {
+fn f(r: rect, x1: isize, y1: isize, x2: isize, y2: isize) {
     assert_eq!(fst(r).x, x1);
     assert_eq!(fst(r).y, y1);
     assert_eq!(snd(r).x, x2);
@@ -30,7 +32,7 @@ pub fn main() {
     assert_eq!(snd(r).x, 11);
     assert_eq!(snd(r).y, 22);
     let r2 = r;
-    let x: int = fst(r2).x;
+    let x: isize = fst(r2).x;
     assert_eq!(x, 10);
     f(r, 10, 20, 11, 22);
     f(r2, 10, 20, 11, 22);
index f59538c51a07802b1ed6e453bb935c599826b5e7..a422aaba84b30677c7848ee57fa7930f40ecc290 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[derive(Copy)]
-struct Rect {x: int, y: int, w: int, h: int}
+// pretty-expanded FIXME #23616
 
-fn f(r: Rect, x: int, y: int, w: int, h: int) {
+#[derive(Copy, Clone)]
+struct Rect {x: isize, y: isize, w: isize, h: isize}
+
+fn f(r: Rect, x: isize, y: isize, w: isize, h: isize) {
     assert_eq!(r.x, x);
     assert_eq!(r.y, y);
     assert_eq!(r.w, w);
@@ -25,7 +27,7 @@ pub fn main() {
     assert_eq!(r.w, 100);
     assert_eq!(r.h, 200);
     let r2: Rect = r;
-    let x: int = r2.x;
+    let x: isize = r2.x;
     assert_eq!(x, 10);
     f(r, 10, 20, 100, 200);
     f(r2, 10, 20, 100, 200);
index 282a24a407c95d2252f5fdfae96115d9eb47d7de..6b39cc196f1e6ba951c7eda79fa4ff1330dc23eb 100644 (file)
@@ -8,18 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum t1 { a(int), b(uint), }
-struct T2 {x: t1, y: int}
-enum t3 { c(T2, uint), }
+// pretty-expanded FIXME #23616
 
-fn m(input: t3) -> int {
+enum t1 { a(isize), b(usize), }
+struct T2 {x: t1, y: isize}
+enum t3 { c(T2, usize), }
+
+fn m(input: t3) -> isize {
     match input {
       t3::c(T2 {x: t1::a(m), ..}, _) => { return m; }
-      t3::c(T2 {x: t1::b(m), y: y}, z) => { return ((m + z) as int) + y; }
+      t3::c(T2 {x: t1::b(m), y: y}, z) => { return ((m + z) as isize) + y; }
     }
 }
 
 pub fn main() {
-    assert_eq!(m(t3::c(T2 {x: t1::a(10), y: 5}, 4_usize)), 10);
-    assert_eq!(m(t3::c(T2 {x: t1::b(10_usize), y: 5}, 4_usize)), 19);
+    assert_eq!(m(t3::c(T2 {x: t1::a(10), y: 5}, 4)), 10);
+    assert_eq!(m(t3::c(T2 {x: t1::b(10), y: 5}, 4)), 19);
 }
index ba74386f975fb967e8ce72546cb4cf403fe39bbf..1243d72af5efb4cd68ac6a3e73535adcb55c5488 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:reexport-should-still-link.rs
 
-extern crate "reexport-should-still-link" as foo;
+// pretty-expanded FIXME #23616
+
+extern crate reexport_should_still_link as foo;
 
 pub fn main() {
     foo::bar();
index 22ca737d421987ac99cfe78fcc3b5c17083b3543..a8d052f407fcc2c847dd6eac90c7c2739f72bfa2 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 mod a {
     pub fn f() {}
     pub fn g() {}
index 5399f3cfd359752bf8d7d0d3ff9f86082ab706ac..3efd913cf543c935789d7a69a52dfc0723895fb5 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // aux-build:reexported_static_methods.rs
+// pretty-expanded FIXME #23616
+
 extern crate reexported_static_methods;
 
 use reexported_static_methods::Foo;
@@ -17,8 +19,8 @@ use reexported_static_methods::Boz;
 use reexported_static_methods::Bort;
 
 pub fn main() {
-    assert_eq!(42, Foo::foo());
-    assert_eq!(84, Baz::bar());
+    assert_eq!(42_isize, Foo::foo());
+    assert_eq!(84_isize, Baz::bar());
     assert!(Boz::boz(1));
     assert_eq!("bort()".to_string(), Bort::bort());
 }
index bb2885a21778525045bc9cae919fa85a8d2013f0..4839067e53d1fb5923b1d21dff479baf86a23265 100644 (file)
@@ -9,16 +9,18 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 struct Point {
-    x: int,
-    y: int
+    x: isize,
+    y: isize
 }
 
 struct Character {
     pos: Box<Point>,
 }
 
-fn get_x(x: &Character) -> &int {
+fn get_x(x: &Character) -> &isize {
     // interesting case because the scope of this
     // borrow of the unique pointer is in fact
     // larger than the fn itself
index a046ba456a6b06e9eb306a764986fca97bfb0ec3..3baf2fa2de5174a058ad8b07429f9bf69ffad71f 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(x: &int) -> &int {
+fn f(x: &isize) -> &isize {
     return &*x;
 }
 
index 77e1a214764540d7226f6fe1f543f6fdb0986442..b51d62f490f3c8dfe10c56616a8c5fc36009f5fd 100644 (file)
@@ -11,6 +11,8 @@
 // Test that the compiler considers the 'a bound declared in the
 // trait. Issue #20890.
 
+// pretty-expanded FIXME #23616
+
 trait Foo<'a> {
     type Value: 'a;
 
index 80ae371e5091e76638e104697a0ff63799b7a450..344f707aefc0149c833f63daa1e5d11b2b3d2597 100644 (file)
@@ -11,6 +11,8 @@
 // Test that the compiler considers the 'static bound declared in the
 // trait. Issue #20890.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
     type Value: 'static;
     fn dummy(&self) { }
index 89779fa4d2d46283df19b5420768fa98ebaa617b..83a82041af937d9590b3c0bb7766b8b4aae0273e 100644 (file)
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn foo(x: &uint) -> uint {
+fn foo(x: &usize) -> usize {
     *x
 }
 
 pub fn main() {
-    let p = box 22_usize;
+    let p: Box<_> = box 22;
     let r = foo(&*p);
     println!("r={}", r);
-    assert_eq!(r, 22_usize);
+    assert_eq!(r, 22);
 }
index 0264e64f70d2a4ef659fe3df13cecde2863752f5..7f3db86783060685bf1ec724533d321ac4a2e800 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo(x: &[int]) -> int {
+// pretty-expanded FIXME #23616
+
+fn foo(x: &[isize]) -> isize {
     x[0]
 }
 
index 16eeb99982e91411c9504b861be391263683c8cd..adf88037d284161467f62a8414baf5d2be35f79e 100644 (file)
@@ -9,7 +9,9 @@
 // except according to those terms.
 
 
-fn foo(x: &[int]) -> int {
+// pretty-expanded FIXME #23616
+
+fn foo(x: &[isize]) -> isize {
     x[0]
 }
 
index a1af7159a93d99235a5927b467d75e16e222b4ed..01a4e9c20ca5b693f906822ec8f6a63a32d7c50e 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn foo(x: &uint) -> uint {
+fn foo(x: &usize) -> usize {
     *x
 }
 
 pub fn main() {
-    let p = box 3_usize;
+    let p: Box<_> = box 3;
     let r = foo(&*p);
-    assert_eq!(r, 3_usize);
+    assert_eq!(r, 3);
 }
index 75c52f63041a5f037d445f1839162f11bf13904f..269e30741f47a25f82ed4e89f73e7f0073b44491 100644 (file)
 
 // A very limited test of the "bottom" region
 
+// pretty-expanded FIXME #23616
+
 fn produce_static<T>() -> &'static T { panic!(); }
 
-fn foo<T>(_x: &T) -> &uint { produce_static() }
+fn foo<T>(_x: &T) -> &usize { produce_static() }
 
 pub fn main() {
 }
index 3922cb1219c03655564b6c97c4e9ae82890b26ea..cc417219ee3df06ac15d927e0985b0efdef0af33 100644 (file)
 // A test where we (successfully) close over a reference into
 // an object.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-trait SomeTrait { fn get(&self) -> int; }
+trait SomeTrait { fn get(&self) -> isize; }
 
-impl<'a> SomeTrait for &'a int {
-    fn get(&self) -> int {
+impl<'a> SomeTrait for &'a isize {
+    fn get(&self) -> isize {
         **self
     }
 }
@@ -27,7 +29,7 @@ fn make_object<'a,A:SomeTrait+'a>(v: A) -> Box<SomeTrait+'a> {
 }
 
 fn main() {
-    let i: int = 22;
+    let i: isize = 22;
     let obj = make_object(&i);
     assert_eq!(22, obj.get());
 }
index 6ebef9f34ad6619d54bd1798288acd183bf532d1..9e3fe79197d5d9109d9802c0d9d68a41211b611e 100644 (file)
@@ -8,9 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, core)]
 
 struct closure_box<'a> {
     cl: Box<FnMut() + 'a>,
@@ -21,11 +22,12 @@ fn box_it<'a>(x: Box<FnMut() + 'a>) -> closure_box<'a> {
 }
 
 pub fn main() {
-    let mut i = 3i32;
+    let mut i = 3;
     assert_eq!(i, 3);
     {
         let cl = || i += 1;
-        let mut cl_box = box_it(box cl);
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        let mut cl_box = box_it(Box::new(cl));
         cl_box.cl.call_mut(());
     }
     assert_eq!(i, 4);
index f23626643e7c7dfddbe53795b391c454dbebaf34..66d28f5afa17a2a32cf9a95be0dc05392c9fb622 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum ast<'a> {
-    num(uint),
+    num(usize),
     add(&'a ast<'a>, &'a ast<'a>)
 }
 
index c7d26e2d92b597d40c4b2ecd56a37d5f78c3942e..4bd12863e2a3d5e9553f86ff6d951d1e8acbb99a 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum ast<'a> {
-    num(uint),
+    num(usize),
     add(&'a ast<'a>, &'a ast<'a>)
 }
 
index b9d3ed49c625f6bb1376a2993c18d294e8d45883..9f2d27f024bb0925ce9a90c8e09abed55f733b27 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct ctxt<'tcx> {
     x: &'tcx i32
 }
index b51be0f0f79f7d0f0bde57e4ed6f90dd56ba30d2..123806a4d9d175d21fa0a7f70e29d77d4a204cb5 100644 (file)
@@ -11,6 +11,8 @@
 // Test lifetimes are linked properly when we create dependent region pointers.
 // Issue #3148.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
@@ -20,67 +22,67 @@ struct A {
 }
 
 struct B {
-    v1: int,
-    v2: [int; 3],
-    v3: Vec<int> ,
+    v1: isize,
+    v2: [isize; 3],
+    v3: Vec<isize> ,
     v4: C,
     v5: Box<C>,
     v6: Option<C>
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct C {
-    f: int
+    f: isize
 }
 
-fn get_v1(a: &A) -> &int {
+fn get_v1(a: &A) -> &isize {
     // Region inferencer must deduce that &v < L2 < L1
     let foo = &a.value; // L1
     &foo.v1             // L2
 }
 
-fn get_v2(a: &A, i: uint) -> &int {
+fn get_v2(a: &A, i: usize) -> &isize {
     let foo = &a.value;
     &foo.v2[i]
 }
 
-fn get_v3(a: &A, i: uint) -> &int {
+fn get_v3(a: &A, i: usize) -> &isize {
     let foo = &a.value;
     &foo.v3[i]
 }
 
-fn get_v4(a: &A, _i: uint) -> &int {
+fn get_v4(a: &A, _i: usize) -> &isize {
     let foo = &a.value;
     &foo.v4.f
 }
 
-fn get_v5(a: &A, _i: uint) -> &int {
+fn get_v5(a: &A, _i: usize) -> &isize {
     let foo = &a.value;
     &foo.v5.f
 }
 
-fn get_v6_a(a: &A, _i: uint) -> &int {
+fn get_v6_a(a: &A, _i: usize) -> &isize {
     match a.value.v6 {
         Some(ref v) => &v.f,
         None => panic!()
     }
 }
 
-fn get_v6_b(a: &A, _i: uint) -> &int {
+fn get_v6_b(a: &A, _i: usize) -> &isize {
     match *a {
         A { value: B { v6: Some(ref v), .. } } => &v.f,
         _ => panic!()
     }
 }
 
-fn get_v6_c(a: &A, _i: uint) -> &int {
+fn get_v6_c(a: &A, _i: usize) -> &isize {
     match a {
         &A { value: B { v6: Some(ref v), .. } } => &v.f,
         _ => panic!()
     }
 }
 
-fn get_v5_ref(a: &A, _i: uint) -> &int {
+fn get_v5_ref(a: &A, _i: usize) -> &isize {
     match &a.value {
         &B {v5: box C {f: ref v}, ..} => v
     }
index e7dc5e99c2bb97e05b6d981ff62e64f2a0560df9..ef05fc595df14bba4a57016e7b927f798bff4ea0 100644 (file)
@@ -11,6 +11,8 @@
 // Test lifetimes are linked properly when we autoslice a vector.
 // Issue #3148.
 
+// pretty-expanded FIXME #23616
+
 fn subslice<F>(v: F) -> F where F: FnOnce() { v }
 
 fn both<F>(v: F) -> F where F: FnOnce() {
index bcf74729fdbfba1acf7a3b7c2f5b7c6ea0c08b82..fd0d8121f5fc6df925ea96889bbc23f1c66fa639 100644 (file)
 // Issue #3148.
 
 
-fn subslice1<'r>(v: &'r [uint]) -> &'r [uint] { v }
+// pretty-expanded FIXME #23616
 
-fn both<'r>(v: &'r [uint]) -> &'r [uint] {
+fn subslice1<'r>(v: &'r [usize]) -> &'r [usize] { v }
+
+fn both<'r>(v: &'r [usize]) -> &'r [usize] {
     subslice1(subslice1(v))
 }
 
index 980fcfb2e9eb9e0abe55963e21bc9eb4e77030c4..1b869e462b0ff93e654daaf11278491dbf06a5d9 100644 (file)
@@ -11,7 +11,9 @@
 // Test lifetimes are linked properly when we take reference
 // to interior.
 
-struct Foo(int);
+// pretty-expanded FIXME #23616
+
+struct Foo(isize);
 pub fn main() {
     // Here the lifetime of the `&` should be at least the
     // block, since a ref binding is created to the interior.
index bdc0d41c94e823cdaa9777b1589aa5fb278c3f86..9aed91551243469c3b8e49c1ca82dac1e38b3091 100644 (file)
@@ -14,6 +14,8 @@
 // lifetime parameters must be early bound in the type of the
 // associated item.
 
+// pretty-expanded FIXME #23616
+
 use std::marker;
 
 pub enum Value<'v> {
@@ -26,7 +28,7 @@ pub trait Decoder<'v> {
 }
 
 pub trait Decodable<'v, D: Decoder<'v>>
-    : marker::PhantomFn<(), &'v int>
+    : marker::PhantomFn<(), &'v isize>
 {
     fn decode(d: &mut D) -> Self;
 }
index 3f434a4838d42bb10f720f278e4be48660b5ea11..738f5dbb7b9adf75ba85caf6180e3b350ebb6053 100644 (file)
 // Tests that you can use an early-bound lifetime parameter as
 // on of the generic parameters in a trait.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 trait Trait<'a> {
-    fn long(&'a self) -> int;
-    fn short<'b>(&'b self) -> int;
+    fn long(&'a self) -> isize;
+    fn short<'b>(&'b self) -> isize;
 }
 
-fn poly_invoke<'c, T: Trait<'c>>(x: &'c T) -> (int, int) {
+fn poly_invoke<'c, T: Trait<'c>>(x: &'c T) -> (isize, isize) {
     let l = x.long();
     let s = x.short();
     (l,s)
 }
 
-fn object_invoke1<'d>(x: &'d Trait<'d>) -> (int, int) {
+fn object_invoke1<'d>(x: &'d Trait<'d>) -> (isize, isize) {
     let l = x.long();
     let s = x.short();
     (l,s)
@@ -35,7 +37,7 @@ struct Struct1<'e> {
     f: &'e (Trait<'e>+'e)
 }
 
-fn field_invoke1<'f, 'g>(x: &'g Struct1<'f>) -> (int,int) {
+fn field_invoke1<'f, 'g>(x: &'g Struct1<'f>) -> (isize,isize) {
     let l = x.f.long();
     let s = x.f.short();
     (l,s)
@@ -45,11 +47,11 @@ struct Struct2<'h, 'i> {
     f: &'h (Trait<'i>+'h)
 }
 
-fn object_invoke2<'j, 'k>(x: &'k Trait<'j>) -> int {
+fn object_invoke2<'j, 'k>(x: &'k Trait<'j>) -> isize {
     x.short()
 }
 
-fn field_invoke2<'l, 'm, 'n>(x: &'n Struct2<'l,'m>) -> int {
+fn field_invoke2<'l, 'm, 'n>(x: &'n Struct2<'l,'m>) -> isize {
     x.f.short()
 }
 
@@ -69,28 +71,31 @@ fn make_ref<'r, T:RefMakerTrait<'r>>(t:T) -> &'r T {
     RefMakerTrait::mk(t)
 }
 
-impl<'s> Trait<'s> for (int,int) {
-    fn long(&'s self) -> int {
+impl<'s> Trait<'s> for (isize,isize) {
+    fn long(&'s self) -> isize {
         let &(x,_) = self;
         x
     }
-    fn short<'b>(&'b self) -> int {
+    fn short<'b>(&'b self) -> isize {
         let &(_,y) = self;
         y
     }
 }
 
 impl<'t> MakerTrait for Box<Trait<'t>+'static> {
-    fn mk() -> Box<Trait<'t>+'static> { box() (4,5) as Box<Trait> }
+    fn mk() -> Box<Trait<'t>+'static> {
+        let tup: Box<(isize, isize)> = box() (4,5);
+        tup as Box<Trait>
+    }
 }
 
 enum List<'l> {
-    Cons(int, &'l List<'l>),
+    Cons(isize, &'l List<'l>),
     Null
 }
 
 impl<'l> List<'l> {
-    fn car<'m>(&'m self) -> int {
+    fn car<'m>(&'m self) -> isize {
         match self {
             &List::Cons(car, _) => car,
             &List::Null => panic!(),
index 410415e57a0679be7fe84e6203a99e9722ff1696..6ad89951238893ea8fdbcf90ffbdd11e7b738d81 100644 (file)
 // Tests that you can use a fn lifetime parameter as part of
 // the value for a type parameter in a bound.
 
+// pretty-expanded FIXME #23616
+
 trait GetRef<'a> {
-    fn get(&self) -> &'a int;
+    fn get(&self) -> &'a isize;
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Box<'a> {
-    t: &'a int
+    t: &'a isize
 }
 
 impl<'a> GetRef<'a> for Box<'a> {
-    fn get(&self) -> &'a int {
+    fn get(&self) -> &'a isize {
         self.t
     }
 }
 
 impl<'a> Box<'a> {
-    fn add<'b,G:GetRef<'b>>(&self, g2: G) -> int {
+    fn add<'b,G:GetRef<'b>>(&self, g2: G) -> isize {
         *self.t + *g2.get()
     }
 }
index a3602c5fbec14aa911753d29c0092fcf8902bb91..6ab95d6e497bc9455f313b08c7c90170da423421 100644 (file)
 // Tests that you can use a fn lifetime parameter as part of
 // the value for a type parameter in a bound.
 
+// pretty-expanded FIXME #23616
+
 trait GetRef<'a, T> {
     fn get(&self) -> &'a T;
 }
 
+#[derive(Copy, Clone)]
 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
     }
 }
 
-fn add<'a,G:GetRef<'a, int>>(g1: G, g2: G) -> int {
+fn add<'a,G:GetRef<'a, isize>>(g1: G, g2: G) -> isize {
     *g1.get() + *g2.get()
 }
 
index caef4e3fa9cbe85be2a2ee3e9e75606a92bacca5..dc991e9493fe46cf569b3c1f4b596c3229b84413 100644 (file)
 // Tests that you can use a fn lifetime parameter as part of
 // the value for a type parameter in a bound.
 
+// pretty-expanded FIXME #23616
+
 trait Get<T> {
     fn get(&self) -> T;
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Box<T> {
     t: T
 }
@@ -26,7 +28,7 @@ impl<T:Clone> Get<T> for Box<T> {
     }
 }
 
-fn add<'a,G:Get<&'a int>>(g1: G, g2: G) -> int {
+fn add<'a,G:Get<&'a isize>>(g1: G, g2: G) -> isize {
     *g1.get() + *g2.get()
 }
 
index b15f9d34859932fb4af53a03fbe10081c3cdb274..3e2fec717f9976d2c73a46421871565ee9265053 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn foo(x: &uint) -> &uint { x }
-fn bar(x: &uint) -> uint { *x }
+fn foo(x: &usize) -> &usize { x }
+fn bar(x: &usize) -> usize { *x }
 
 pub fn main() {
-    let p = box 3_usize;
+    let p: Box<_> = box 3;
     assert_eq!(bar(foo(&*p)), 3);
 }
index 58c13885e036cea44a8998eadb16de9ed69c21c2..7ad3c3f4e1713fcc2701547ce05f4caf1cbc5a39 100644 (file)
 
 // Test that you can insert an explicit lifetime in explicit self.
 
+// pretty-expanded FIXME #23616
+
 struct Foo {
-    f: uint
+    f: usize
 }
 
 impl Foo {
index 70c90ee05b35764713de34b22b72f89c8e1886aa..7f2fc11cb8e0e7f765958ac3bd20771c9f1c114b 100644 (file)
 // Here, `f` is a function that takes a pointer `x` and a function
 // `g`, where `g` requires its argument `y` to be in the same region
 // that `x` is in.
-fn has_same_region(f: Box<for<'a> FnMut(&'a int, Box<FnMut(&'a int)>)>) {
+// pretty-expanded FIXME #23616
+
+fn has_same_region(f: Box<for<'a> FnMut(&'a isize, Box<FnMut(&'a isize)>)>) {
     // `f` should be the type that `wants_same_region` wants, but
     // right now the compiler complains that it isn't.
     wants_same_region(f);
 }
 
-fn wants_same_region(_f: Box<for<'b> FnMut(&'b int, Box<FnMut(&'b int)>)>) {
+fn wants_same_region(_f: Box<for<'b> FnMut(&'b isize, Box<FnMut(&'b isize)>)>) {
 }
 
 pub fn main() {
index faa9b37bdcc630807125881fe3046d737f42ae4b..e5b652c306f4df744b91e3cb8d679bb209bd97d8 100644 (file)
 
 // Issue #2263.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 #![allow(unused_variable)]
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
 
 // Should pass region checking.
-fn ok(f: Box<FnMut(&uint)>) {
-    // Here, g is a function that can accept a uint pointer with
-    // lifetime r, and f is a function that can accept a uint pointer
+fn ok(f: Box<FnMut(&usize)>) {
+    // Here, g is a function that can accept a usize pointer with
+    // lifetime r, and f is a function that can accept a usize pointer
     // with any lifetime.  The assignment g = f should be OK (i.e.,
     // f's type should be a subtype of g's type), because f can be
     // used in any context that expects g's type.  But this currently
     // fails.
-    let mut g: Box<for<'r> FnMut(&'r uint)> = box |x| { };
+    let mut g: Box<for<'r> FnMut(&'r usize)> = Box::new(|x| { });
     g = f;
 }
 
 // This version is the same as above, except that here, g's type is
 // inferred.
-fn ok_inferred(f: Box<FnMut(&uint)>) {
-    let mut g: Box<for<'r> FnMut(&'r uint)> = box |_| {};
+fn ok_inferred(f: Box<FnMut(&usize)>) {
+    let mut g: Box<for<'r> FnMut(&'r usize)> = Box::new(|_| {});
     g = f;
 }
 
index 9f1a383fd64b869880d6cf2ccad55c73f618e506..5d171811732a12a96505f263feed571f4ce64f31 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem::swap;
 
 pub fn main() {
index 1fdf3a92a3fdbdea5fbb4bd419e122374cd0ee9c..9c200a370ad85e456333d09c1b151055e5d01275 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 fn view<T>(x: &[T]) -> &[T] {x}
 
 pub fn main() {
index d07110fd7217f74f5a7673d94581cb9eaea9d433..59221afcefffef0f6247c2b1ea30fae9399af903 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 fn borrow<T>(x: &T) -> &T {x}
 
 pub fn main() {
-    let x = box 3;
+    let x: Box<_> = box 3;
     loop {
         let y = borrow(&*x);
         assert_eq!(*x, *y);
index 708d031a68a6351e9051b6e97885810a323d711a..3289da3cfd87ea814d20e766920fb6ec0c4ff0a5 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct Point {x: int, y: int}
+struct Point {x: isize, y: isize}
 
-fn x_coord(p: &Point) -> &int {
+fn x_coord(p: &Point) -> &isize {
     return &p.x;
 }
 
 pub fn main() {
-    let p = box Point {x: 3, y: 4};
+    let p: Box<_> = box Point {x: 3, y: 4};
     let xc = x_coord(&*p);
     assert_eq!(*xc, 3);
 }
index cfb6c8585634d7049a4ded78a2992c78e7936bfb..7e6767b0de422c0c8c46f0c1ee321f1be875f0df 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn takes_two(x: &int, y: &int) -> int { *x + *y }
+// pretty-expanded FIXME #23616
 
-fn with<T, F>(f: F) -> T where F: FnOnce(&int) -> T {
+fn takes_two(x: &isize, y: &isize) -> isize { *x + *y }
+
+fn with<T, F>(f: F) -> T where F: FnOnce(&isize) -> T {
     f(&20)
 }
 
-fn has_one<'a>(x: &'a int) -> int {
+fn has_one<'a>(x: &'a isize) -> isize {
     with(|y| takes_two(x, y))
 }
 
index fdb7485efc35bcf176e65f16501659b8db450abc..bc752a1d504e3b32010fc110679f0094075ef672 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn takes_two(x: &int, y: &int) -> int { *x + *y }
+// pretty-expanded FIXME #23616
 
-fn has_two<'a,'b>(x: &'a int, y: &'b int) -> int {
+fn takes_two(x: &isize, y: &isize) -> isize { *x + *y }
+
+fn has_two<'a,'b>(x: &'a isize, y: &'b isize) -> isize {
     takes_two(x, y)
 }
 
index 7e328f3bb0354ce453f80f52b913e0dfdb26acf1..73cfbcddd9aa76800992ab6a78020da6588f4e17 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct boxed_int<'a> {
-    f: &'a int,
+    f: &'a isize,
 }
 
-fn max<'r>(bi: &'r boxed_int, f: &'r int) -> int {
+fn max<'r>(bi: &'r boxed_int, f: &'r isize) -> isize {
     if *bi.f > *f {*bi.f} else {*f}
 }
 
-fn with(bi: &boxed_int) -> int {
+fn with(bi: &boxed_int) -> isize {
     let i = 22;
     max(bi, &i)
 }
index efe3994dbb7b98e928fb735fb4b635d014f7b81d..2349b6c3bc14602ad5a3bf98b71742300f40ce8e 100644 (file)
 // Test an edge case in region inference: the lifetime of the borrow
 // of `*x` must be extended to at least 'a.
 
-fn foo<'a,'b>(x: &'a &'b mut int) -> &'a int {
-    let y = &*x; // should be inferred to have type &'a &'b mut int...
+// pretty-expanded FIXME #23616
 
-    // ...because if we inferred, say, &'x &'b mut int where 'x <= 'a,
+fn foo<'a,'b>(x: &'a &'b mut isize) -> &'a isize {
+    let y = &*x; // should be inferred to have type &'a &'b mut isize...
+
+    // ...because if we inferred, say, &'x &'b mut isize where 'x <= 'a,
     // this reborrow would be illegal:
     &**y
 }
index 9174b53be86e6bd595834e25e92d0e169f9fcbc0..a8418f967fdb3d7307ee6571bf60d4d3aaf342a3 100644 (file)
@@ -9,9 +9,11 @@
 // except according to those terms.
 
 
-// check that the &int here does not cause us to think that `foo`
+// check that the &isize here does not cause us to think that `foo`
 // contains region pointers
-struct foo(Box<FnMut(&int)+'static>);
+// pretty-expanded FIXME #23616
+
+struct foo(Box<FnMut(&isize)+'static>);
 
 fn take_foo<T:'static>(x: T) {}
 
index cb45b8e131d284f2414a565beebebd28efa90d1a..403dfbf655f3b1ad6c9108b0f1a2454f232117ce 100644 (file)
 // region variables contained within (otherwise, region inference will
 // give `x` a very short lifetime).
 
-static i: uint = 3;
+// pretty-expanded FIXME #23616
+
+static i: usize = 3;
 fn foo<F:FnOnce()+'static>(_: F) {}
-fn read(_: uint) { }
+fn read(_: usize) { }
 pub fn main() {
     let x = &i;
     foo(move|| {
index c59bf15afc3b0205dfbb790b51939e2222f23f57..ecc170a1462aabfc1423defa31d7d92f02f243df 100644 (file)
@@ -12,6 +12,8 @@
 // add inference constraints that the operands of a binary operator
 // should outlive the binary operation itself.
 
+// pretty-expanded FIXME #23616
+
 pub struct P<'a> {
     _ptr: *const &'a u8,
 }
index f5c34d6b34e9d8761be05546615cb4056c9ab21e..16236f94655948c0b1c3a62900573685f0bac694 100644 (file)
@@ -11,6 +11,8 @@
 // Regression test for issue #22246 -- we should be able to deduce
 // that `&'a B::Owned` implies that `B::Owned : 'a`.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 use std::ops::Deref;
index a2b6d569ac9a72f0937219612d86e43c47a0a1be..a2c07d27288d23f074ddd868ad48075f7f4f825e 100644 (file)
 // doing region-folding, when really all clients of the region-folding
 // case only want to see FREE lifetime variables, not bound ones.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
     fn explicit() {
-        fn test<F>(_x: Option<Box<F>>) where F: FnMut(Box<for<'a> FnMut(&'a int)>) {}
-        test(Some(box |_f: Box<for<'a> FnMut(&'a int)>| {}));
+        fn test<F>(_x: Option<Box<F>>) where F: FnMut(Box<for<'a> FnMut(&'a isize)>) {}
+        test(Some(box |_f: Box<for<'a> FnMut(&'a isize)>| {}));
     }
 
     // The code below is shorthand for the code above (and more likely
     // to represent what one encounters in practice).
     fn implicit() {
-        fn test<F>(_x: Option<Box<F>>) where F: FnMut(Box<        FnMut(&   int)>) {}
-        test(Some(box |_f: Box<        FnMut(&   int)>| {}));
+        fn test<F>(_x: Option<Box<F>>) where F: FnMut(Box<        FnMut(&   isize)>) {}
+        test(Some(box |_f: Box<        FnMut(&   isize)>| {}));
     }
 
     explicit();
index b16b934d73cc64dcd2df66a34be0fd641c890a0d..451c745358ae6dea08aa8f4de2a07b7c17e93f39 100644 (file)
@@ -11,6 +11,8 @@
 // This test verifies that temporary lifetime is correctly computed
 // for static objects in enclosing scopes.
 
+// pretty-expanded FIXME #23616
+
 use std::cmp::PartialEq;
 
 fn f<T:PartialEq>(o: &mut Option<T>) {
@@ -23,5 +25,5 @@ pub fn main() {
         static C: E = E::V;
     }
 
-    f::<int>(&mut None);
+    f::<isize>(&mut None);
 }
index 8822d3880397a8f57ef12370bc4fba3f4d7ba53b..9e8ce6160487ea16cfc47feef15ff3384bbaf04f 100644 (file)
 // Test that region inference correctly links up the regions when a
 // `ref` borrow occurs inside a fn argument.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
-fn with<'a, F>(_: F) where F: FnOnce(&'a Vec<int>) -> &'a Vec<int> { }
+fn with<'a, F>(_: F) where F: FnOnce(&'a Vec<isize>) -> &'a Vec<isize> { }
 
 fn foo() {
     with(|&ref ints| ints);
index bf789d5364500df680752103028111dccdb92c33..ed3cec465eff894ce54233eb78676666030b8150 100644 (file)
@@ -15,6 +15,8 @@
 // - Multiple lifetime parameters
 // - Arenas
 
+#![feature(rustc_private, libc, collections)]
+
 extern crate arena;
 extern crate collections;
 extern crate libc;
@@ -27,7 +29,7 @@ use std::mem;
 
 type Type<'tcx> = &'tcx TypeStructure<'tcx>;
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 enum TypeStructure<'tcx> {
     TypeInt,
     TypeFunction(Type<'tcx>, Type<'tcx>),
@@ -54,7 +56,7 @@ struct TypeContext<'tcx, 'ast> {
     type_table: HashMap<NodeId, Type<'tcx>>,
 
     ast_arena: &'ast AstArena<'ast>,
-    ast_counter: uint,
+    ast_counter: usize,
 }
 
 impl<'tcx,'ast> TypeContext<'tcx, 'ast> {
@@ -92,23 +94,23 @@ impl<'tcx,'ast> TypeContext<'tcx, 'ast> {
     }
 }
 
-#[derive(Copy, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
 struct NodeId {
-    id: uint
+    id: usize
 }
 
 type Ast<'ast> = &'ast AstStructure<'ast>;
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct AstStructure<'ast> {
     id: NodeId,
     kind: AstKind<'ast>
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum AstKind<'ast> {
     ExprInt,
-    ExprVar(uint),
+    ExprVar(usize),
     ExprLambda(Ast<'ast>),
 }
 
index e6b997f758814475e30f21cc634ea1d7e782e048..b67612c94b00955ab2c74c33ff71714fae54ebe3 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 extern crate libc;
 use std::mem;
 
@@ -23,7 +27,7 @@ struct Fcx<'a> {
 }
 
 struct Ccx {
-    x: int
+    x: isize
 }
 
 fn alloc<'a>(_bcx : &'a arena) -> &'a Bcx<'a> {
index 5964ac65d5f6e977dc24b1bc0c7226ab93ed3146..6cc32301cc46eb6c9bd2cec41e7acd42930ab4ce 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 
 use std::marker;
index 80c478afa644f2b2b1be49301bb3fd75fef35f18..89bdbfaed9e0a465259c30a8ea75e6aa535b609b 100644 (file)
@@ -12,6 +12,8 @@
 // should not upset the variance inference for actual occurrences of
 // that lifetime in type expressions.
 
+// pretty-expanded FIXME #23616
+
 pub trait HasLife<'a> {
     fn dummy(&'a self) { } // just to induce a variance on 'a
 }
index e1359725f9b9fb6a82bd3266d867e2ed59ea8b62..ae55b97dc932da5f2b80ff2a7e5ad0fa83a3d0e9 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum roption<'a> {
-    a, b(&'a uint)
+    a, b(&'a usize)
 }
 
-fn mk(cond: bool, ptr: &uint) -> roption {
+fn mk(cond: bool, ptr: &usize) -> roption {
     if cond {roption::a} else {roption::b(ptr)}
 }
 
index c71953e20f8af12bd0f3ba4337367c44958431b7..5002fcce96b96ca0a3786d3b7c051c85c1edfffd 100644 (file)
@@ -9,11 +9,13 @@
 // except according to those terms.
 
 
-fn region_identity(x: &uint) -> &uint { x }
+// pretty-expanded FIXME #23616
+
+fn region_identity(x: &usize) -> &usize { x }
 
 fn apply<T, F>(t: T, f: F) -> T where F: FnOnce(T) -> T { f(t) }
 
-fn parameterized(x: &uint) -> uint {
+fn parameterized(x: &usize) -> usize {
     let z = apply(x, ({|y|
         region_identity(y)
     }));
@@ -21,6 +23,6 @@ fn parameterized(x: &uint) -> uint {
 }
 
 pub fn main() {
-    let x = 3_usize;
-    assert_eq!(parameterized(&x), 3_usize);
+    let x = 3;
+    assert_eq!(parameterized(&x), 3);
 }
index ecf79de6222225dae29db4ff1f68bf3968cb2abd..b29cc8f90368ab47f73dc49e04a705288779f404 100644 (file)
@@ -12,7 +12,9 @@
 // started out with a longer lifetime and was reassigned to a shorter
 // one (it should infer to be the intersection).
 
-fn foo(x: &int) {
+// pretty-expanded FIXME #23616
+
+fn foo(x: &isize) {
     let a = 1;
     let mut z = x;
     z = &a;
index 18312b17339ce3ab29a7dfa983637530bc75c8bf..58d4f556a79cb3261589e7546b0f0b9ab9301929 100644 (file)
@@ -12,7 +12,9 @@
 // started out with a longer lifetime and was reassigned to a shorter
 // one (it should infer to be the intersection).
 
-fn foo(x: &int) {
+// pretty-expanded FIXME #23616
+
+fn foo(x: &isize) {
     let a = 1;
     match x {
         mut z => {
index a224017780e2d936419b6ca4f6ec7e235b527b9c..63525b36206a419d1b78fb4e9259a531bca3876f 100644 (file)
 // attempting to bootstrap librustc with new destructor lifetime
 // semantics.
 
+// pretty-expanded FIXME #23616
+
 use std::collections::HashMap;
 use std::cell::RefCell;
 
 // This version does not yet work (associated type issues)...
 #[cfg(cannot_use_this_yet)]
 fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) {
-    let one = [1_usize];
+    let one = [1];
     assert_eq!(map.borrow().get("one"), Some(&one[..]));
 }
 
@@ -26,8 +28,8 @@ fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) {
 // ... and this version does not work (the lifetime of `one` is
 // supposed to match the lifetime `'a`) ...
 fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) {
-    let one = [1_usize];
-    assert_eq!(map.borrow().get("one"), Some(&one.as_slice()));
+    let one = [1];
+    assert_eq!(map.borrow().get("one"), Some(&&one[..]));
 }
 
 #[cfg(all(not(cannot_use_this_yet),not(cannot_use_this_yet_either)))]
@@ -41,9 +43,9 @@ fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) {
 }
 
 fn main() {
-    let zer = [0u8];
-    let one = [1u8];
-    let two = [2u8];
+    let zer = [0];
+    let one = [1];
+    let two = [2];
     let mut map = HashMap::new();
     map.insert("zero", &zer[..]);
     map.insert("one",  &one[..]);
index e779e002b299005b33c9db21b1ea21bfb0f834ef..a36c1b30ead0bef62cabc8b16492aa8bcd145a40 100644 (file)
 // changes were caught. However, those uses in the compiler could
 // easily get changed or refactored away in the future.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 struct Ctxt<'tcx> {
-    x: &'tcx Vec<int>
+    x: &'tcx Vec<isize>
 }
 
 struct Foo<'a,'tcx:'a> {
@@ -29,8 +31,9 @@ struct Foo<'a,'tcx:'a> {
 }
 
 impl<'a,'tcx> Foo<'a,'tcx> {
-    fn bother(&mut self) -> int {
-        self.elaborate_bounds(box |this| {
+    fn bother(&mut self) -> isize {
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        self.elaborate_bounds(Box::new(|this| {
             // (*) Here: type of `this` is `&'f0 Foo<&'f1, '_2>`,
             // where `'f0` and `'f1` are fresh, free regions that
             // result from the bound regions on the closure, and `'2`
@@ -44,17 +47,17 @@ impl<'a,'tcx> Foo<'a,'tcx> {
             // `region_inference.rs` file (and the `givens` field, in
             // particular) for more details.
             this.foo()
-        })
+        }))
     }
 
-    fn foo(&mut self) -> int {
+    fn foo(&mut self) -> isize {
         22
     }
 
     fn elaborate_bounds(
         &mut self,
-        mut mk_cand: Box<for<'b> FnMut(&mut Foo<'b, 'tcx>) -> int>)
-        -> int
+        mut mk_cand: Box<for<'b> FnMut(&mut Foo<'b, 'tcx>) -> isize>)
+        -> isize
     {
         mk_cand(self)
     }
index ee1d66873077b5f48b257a250606adef8b4f7aa9..e6ab4a81426c25db15d77c772741d69f8cd2473d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn get<T>(opt: &Option<T>) -> &T {
     match *opt {
       Some(ref v) => v,
index e5ef88006c7df9925f52b9cee8a46b403c27d7c2..185d5db1f511202146702e72e78186548ed1a199 100644 (file)
@@ -16,6 +16,8 @@
 // wrong path. The new algorithm avoids this problem and hence this
 // example typechecks correctly.
 
+// pretty-expanded FIXME #23616
+
 enum ScopeChain<'a> {
     Link(Scope<'a>),
     End
index b30b3cfa47695f6049ce054486881086d3919a66..26e3fbfab9e6157bd4094106fb968af882e64385 100644 (file)
@@ -9,15 +9,15 @@
 // except according to those terms.
 
 struct Clam<'a> {
-    chowder: &'a int
+    chowder: &'a isize
 }
 
 trait get_chowder<'a> {
-    fn get_chowder(&self) -> &'a int;
+    fn get_chowder(&self) -> &'a isize;
 }
 
 impl<'a> get_chowder<'a> for Clam<'a> {
-    fn get_chowder(&self) -> &'a int { return self.chowder; }
+    fn get_chowder(&self) -> &'a isize { return self.chowder; }
 }
 
 pub fn main() {
index ab0b4acc7698ada6f8500b47068b04a6e86ac792..9ff20e93a0dfcc64451a225d2c35b585e747ba6b 100644 (file)
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 enum int_wrapper<'a> {
-    int_wrapper_ctor(&'a int)
+    int_wrapper_ctor(&'a isize)
 }
 
 pub fn main() {
     let x = 3;
     let y = int_wrapper::int_wrapper_ctor(&x);
-    let mut z : &int;
+    let mut z : &isize;
     match y {
         int_wrapper::int_wrapper_ctor(zz) => { z = zz; }
     }
index d540605180a4eea87041576a2ee7ff6659b8e66f..f4fe73131fe3cecbef59f2ebbaf91cb5fba4440d 100644 (file)
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 pub fn main() {
-    let mut x: int = 3;
-    let y: &mut int = &mut x;
+    let mut x: isize = 3;
+    let y: &mut isize = &mut x;
     *y = 5;
     println!("{}", *y);
 }
index 7198c35944f9a0f5b0e764cb55108a5346375ca0..ae39c266808946bb7dda387a7f9ce478023a89c3 100644 (file)
@@ -10,7 +10,7 @@
 
 #![allow(unknown_features)]
 #![feature(box_syntax)]
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, core)]
 
 struct closure_box<'a> {
     cl: Box<FnMut() + 'a>,
@@ -25,6 +25,7 @@ fn call_static_closure(mut cl: closure_box<'static>) {
 }
 
 pub fn main() {
-    let cl_box = box_it(box || println!("Hello, world!"));
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let cl_box = box_it(Box::new(|| println!("Hello, world!")));
     call_static_closure(cl_box);
 }
index eb3bec773266670d241bb68fbbbb6ec4bb43b803..d23529885793992663897840b3d39a801c27063a 100644 (file)
@@ -12,6 +12,8 @@
 // attempting to bootstrap libsyntax; it is adapted from
 // `syntax::ext::tt::generic_extension`.
 
+// pretty-expanded FIXME #23616
+
 pub struct E<'a> {
     pub f: &'a u8,
 }
@@ -37,7 +39,7 @@ fn extension<'e>(x: &'e E<'e>) -> Box<M+'e> {
 }
 
 fn main() {
-    let w = E { f: &10u8 };
+    let w = E { f: &10 };
     let o = extension(&w);
-    assert_eq!(o.n(), 10u8);
+    assert_eq!(o.n(), 10);
 }
index ffc2f07a1530e0b118dd08a9e050108d187c3b28..5e5be1c25877d51db9e2930b5f3b6858c033b44f 100644 (file)
 // Note: see compile-fail/variance-regions-*.rs for the tests that check that the
 // variance inference works in the first place.
 
+// pretty-expanded FIXME #23616
+
 struct Contravariant<'a> {
-    f: &'a int
+    f: &'a isize
 }
 
 fn use_<'a>(c: Contravariant<'a>) {
@@ -26,7 +28,7 @@ fn use_<'a>(c: Contravariant<'a>) {
     // if 'call <= 'a, which is true, so no error.
     collapse(&x, c);
 
-    fn collapse<'b>(x: &'b int, c: Contravariant<'b>) { }
+    fn collapse<'b>(x: &'b isize, c: Contravariant<'b>) { }
 }
 
 pub fn main() {}
index 7e0ca41501833a1ae8746d8d28d6421c7247df90..02562781373a88e0da179a617ca0442317eb4fa0 100644 (file)
 // This is covariant with respect to 'a, meaning that
 // Covariant<'foo> <: Covariant<'static> because
 // 'foo <= 'static
+// pretty-expanded FIXME #23616
+
 struct Covariant<'a> {
-    f: extern "Rust" fn(&'a int)
+    f: extern "Rust" fn(&'a isize)
 }
 
 fn use_<'a>(c: Covariant<'a>) {
diff --git a/src/test/run-pass/rename-directory.rs b/src/test/run-pass/rename-directory.rs
deleted file mode 100644 (file)
index abe6ffe..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2013-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.
-
-// This test can't be a unit test in std,
-// because it needs TempDir, which is in extra
-
-extern crate libc;
-
-use std::ffi::CString;
-use std::old_io::TempDir;
-use std::old_io::fs::PathExtensions;
-use std::old_io::fs;
-use std::old_io;
-use std::os;
-
-fn rename_directory() {
-    unsafe {
-        static U_RWX: i32 = (libc::S_IRUSR | libc::S_IWUSR | libc::S_IXUSR) as i32;
-
-        let tmpdir = TempDir::new("rename_directory").ok().expect("rename_directory failed");
-        let tmpdir = tmpdir.path();
-        let old_path = tmpdir.join_many(&["foo", "bar", "baz"]);
-        fs::mkdir_recursive(&old_path, old_io::USER_RWX);
-        let test_file = &old_path.join("temp.txt");
-
-        /* Write the temp input file */
-        let fromp = CString::new(test_file.as_vec()).unwrap();
-        let modebuf = CString::new(b"w+b").unwrap();
-        let ostream = libc::fopen(fromp.as_ptr(), modebuf.as_ptr());
-        assert!((ostream as uint != 0_usize));
-        let s = "hello".to_string();
-        let buf = CString::new(b"hello").unwrap();
-        let write_len = libc::fwrite(buf.as_ptr() as *mut _,
-                                     1_usize as libc::size_t,
-                                     (s.len() + 1_usize) as libc::size_t,
-                                     ostream);
-        assert_eq!(write_len, (s.len() + 1) as libc::size_t);
-        assert_eq!(libc::fclose(ostream), (0_usize as libc::c_int));
-
-        let new_path = tmpdir.join_many(&["quux", "blat"]);
-        fs::mkdir_recursive(&new_path, old_io::USER_RWX);
-        fs::rename(&old_path, &new_path.join("newdir"));
-        assert!(new_path.join("newdir").is_dir());
-        assert!(new_path.join_many(&["newdir", "temp.txt"]).exists());
-    }
-}
-
-pub fn main() { rename_directory() }
index a53f1da4ce605ee7a1bdc3bbb8bd115c2ba10732..5a4475ae947b6d943d93c36554538f489c2e29f2 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: [int; 4] = [32; 4];
-static BAR: [int; 4] = [32, 32, 32, 32];
+// pretty-expanded FIXME #23616
+
+static FOO: [isize; 4] = [32; 4];
+static BAR: [isize; 4] = [32, 32, 32, 32];
 
 pub fn main() {
     assert!(FOO == BAR);
index 016357b5df985ee41cd98a1d6011c8317ea8b68c..bad5b83b5484c0176dfa4df109a5ff49f9f5d97a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const foo: int = 4 >> 1;
+// pretty-expanded FIXME #23616
+
+const foo: isize = 4 >> 1;
 enum bs { thing = foo }
-pub fn main() { assert!((bs::thing as int == foo)); }
+pub fn main() { assert!((bs::thing as isize == foo)); }
index abc33e9f2e64cb49186aae72b34c8ae1bfb63e82..ba63c2db7cf59052e690bf1f6fc53c91d067d15e 100644 (file)
@@ -14,7 +14,7 @@ use std::cell::Cell;
 
 #[derive(Debug)]
 struct r<'a> {
-    i: &'a Cell<int>,
+    i: &'a Cell<isize>,
 }
 
 #[unsafe_destructor]
@@ -24,7 +24,7 @@ impl<'a> Drop for r<'a> {
     }
 }
 
-fn r(i: &Cell<int>) -> r {
+fn r(i: &Cell<isize>) -> r {
     r {
         i: i
     }
index 71bf6cc626153d38e962626512f59fd66a4c9c96..229ceba08b0ff3730be40d6134f214796717cdbe 100644 (file)
@@ -13,7 +13,7 @@
 use std::cell::Cell;
 
 struct shrinky_pointer<'a> {
-  i: &'a Cell<int>,
+  i: &'a Cell<isize>,
 }
 
 #[unsafe_destructor]
@@ -24,10 +24,10 @@ impl<'a> Drop for shrinky_pointer<'a> {
 }
 
 impl<'a> shrinky_pointer<'a> {
-    pub fn look_at(&self) -> int { return self.i.get(); }
+    pub fn look_at(&self) -> isize { return self.i.get(); }
 }
 
-fn shrinky_pointer(i: &Cell<int>) -> shrinky_pointer {
+fn shrinky_pointer(i: &Cell<isize>) -> shrinky_pointer {
     shrinky_pointer {
         i: i
     }
index 33ae0af250a5397fdcb378aa046ab78b38abfce2..a8426f90cc4890db7dde965c84dbcfc0b7101855 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 
 // Ensures that class dtors run if the object is inside an enum
index 74227192cabbefae06eb916fbcc1e002f37934ca..7d4d0218112270cbdd087a60eeced047bdfcdcf5 100644 (file)
 
 fn my_err(s: String) -> ! { println!("{}", s); panic!(); }
 
-fn okay(i: uint) -> int {
-    if i == 3_usize {
+fn okay(i: usize) -> isize {
+    if i == 3 {
         my_err("I don't like three".to_string());
     } else {
         return 42;
     }
 }
 
-pub fn main() { okay(4_usize); }
+pub fn main() { okay(4); }
index 8d7faffae7f338aff10f4aac929b467d70655fdb..032a4b662cb1a3dbb4c640ae0060067a8e0cd03b 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 enum option<T> { none, some(T), }
 
 fn f<T>() -> option<T> { return option::none; }
 
-pub fn main() { f::<int>(); }
+pub fn main() { f::<isize>(); }
index 60856ee60425b310f1441f41b5960099f596b7ee..4395f6fcb4b7cfc36431026e56efa4a839666c8b 100644 (file)
 
 // just to make sure that `return` is only returning from the closure,
 // not the surrounding function.
-static mut calls: uint = 0;
+// pretty-expanded FIXME #23616
+
+static mut calls: usize = 0;
 
 fn surrounding() {
-    let return_works = |n: int| {
+    let return_works = |n: isize| {
         unsafe { calls += 1 }
 
         if n >= 0 { return; }
@@ -23,7 +25,7 @@ fn surrounding() {
     return_works(10);
     return_works(20);
 
-    let return_works_proc = |n: int| {
+    let return_works_proc = |n: isize| {
         unsafe { calls += 1 }
 
         if n >= 0 { return; }
index b5a81268a2dcf7a3c9332e35bc66feb92ceda939..fe4244084cb194ff398d0dfa2fad10b8bd80d984 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 fn f() { let x: () = (); return x; }
 
 pub fn main() { let _x = f(); }
index ec033b74dd1cde1714b84dbf7b37636ed9aef1a7..abad08c7ac6b31bc57593547184b2134c7349323 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(start)]
+#![feature(start, os, std_misc, old_io)]
 
-use std::ffi;
+use std::ffi::CStr;
 use std::old_io::process::{Command, ProcessOutput};
 use std::os;
 use std::rt::unwind::try;
@@ -20,7 +20,7 @@ use std::thread::Thread;
 use std::thunk::Thunk;
 
 #[start]
-fn start(argc: int, argv: *const *const u8) -> int {
+fn start(argc: isize, argv: *const *const u8) -> isize {
     if argc > 1 {
         unsafe {
             match **argv.offset(1) {
@@ -36,22 +36,22 @@ fn start(argc: int, argv: *const *const u8) -> int {
     }
 
     let args = unsafe {
-        (0..argc as uint).map(|i| {
-            let ptr = *argv.offset(i as int) as *const _;
-            ffi::c_str_to_bytes(&ptr).to_vec()
+        (0..argc as usize).map(|i| {
+            let ptr = *argv.offset(i as isize) as *const _;
+            CStr::from_ptr(ptr).to_bytes().to_vec()
         }).collect::<Vec<_>>()
     };
     let me = &*args[0];
 
-    let x: &[u8] = &[1u8];
+    let x: &[u8] = &[1];
     pass(Command::new(me).arg(x).output().unwrap());
-    let x: &[u8] = &[2u8];
+    let x: &[u8] = &[2];
     pass(Command::new(me).arg(x).output().unwrap());
-    let x: &[u8] = &[3u8];
+    let x: &[u8] = &[3];
     pass(Command::new(me).arg(x).output().unwrap());
-    let x: &[u8] = &[4u8];
+    let x: &[u8] = &[4];
     pass(Command::new(me).arg(x).output().unwrap());
-    let x: &[u8] = &[5u8];
+    let x: &[u8] = &[5];
     pass(Command::new(me).arg(x).output().unwrap());
 
     0
index 5d6657c7e12e653e9a4bd837dfb4c47b23fb345a..660b1e2036d3311dcd838ef12d5f25d2b37c44b6 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// exec-env:RUST_LOG=rust-log-filter/foo
+// exec-env:RUST_LOG=rust_log_filter/foo
+
+// pretty-expanded FIXME #23616
 
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, std_misc, rustc_private)]
 
 #[macro_use]
 extern crate log;
 
 use std::sync::mpsc::{channel, Sender, Receiver};
-use std::thread::Thread;
+use std::thread;
 
 pub struct ChannelLogger {
     tx: Sender<String>
@@ -39,7 +41,7 @@ impl log::Logger for ChannelLogger {
 pub fn main() {
     let (logger, rx) = ChannelLogger::new();
 
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         log::set_logger(logger);
 
         info!("foo");
index 492736c2252a0148612a2e948a6ebb6ceb169bb2..6eb9600cf8b5393faa3e9641ac099106390205f3 100644 (file)
@@ -8,13 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(old_io)]
+
 use std::old_io::process::Command;
 use std::env;
 
 fn main() {
     let args: Vec<String> = env::args().collect();
     if args.len() > 1 && args[1] == "segfault" {
-        unsafe { *(0 as *mut int) = 1 }; // trigger a segfault
+        unsafe { *(0 as *mut isize) = 1 }; // trigger a segfault
     } else {
         let segfault = Command::new(&args[0]).arg("segfault").output().unwrap();
         assert!(!segfault.status.success());
index af2b2de8ab8ba19473b9108dc5601be028ea88e9..c32773aa88c2aaf5a91eee4500777479eabeb187 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test that we can use `Self` types in impls in the expected way.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -32,7 +34,7 @@ trait Bar<X> {
     fn dummy(&self, x: X) { }
 }
 
-impl Bar<int> for Box<Baz<int>> {
+impl Bar<isize> for Box<Baz<isize>> {
     fn bar(_x: Self, _y: &Self, _z: Box<Self>) -> Self {
         box Baz { f: 42 }
     }
@@ -40,7 +42,7 @@ impl Bar<int> for Box<Baz<int>> {
 
 fn main() {
     let _: Foo = Foo::foo(Foo, &Foo, box Foo);
-    let _: Box<Baz<int>> = Bar::bar(box Baz { f: 42 },
+    let _: Box<Baz<isize>> = Bar::bar(box Baz { f: 42 },
                                     &box Baz { f: 42 },
                                     box box Baz { f: 42 });
 }
index e934498ea05066b34de6bea90afdf6f8dc92a682..f8502137be129992733aa8842d4dae7b2f7f3360 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 struct X {
-    a: int
+    a: isize
 }
 
 trait Changer : Sized {
@@ -26,11 +28,11 @@ trait Changer : Sized {
         self
     }
 
-    fn set_to(&mut self, a: int);
+    fn set_to(&mut self, a: isize);
 }
 
 impl Changer for X {
-    fn set_to(&mut self, a: int) {
+    fn set_to(&mut self, a: isize) {
         self.a = a;
     }
 }
@@ -40,7 +42,7 @@ pub fn main() {
     let new_x = x.change();
     assert_eq!(new_x.a, 55);
 
-    let x = box new_x;
+    let x: Box<_> = box new_x;
     let new_x = x.change_again();
     assert_eq!(new_x.a, 45);
 }
index a4b5ea1d682823e1d93e8ab401ac1940fb19c5d1..fa9ad9f6517a609c6ddff771ad0141bf60a6ed43 100644 (file)
 // Assert that `mut self` on an immediate value doesn't
 // allow mutating the original - issue #10615.
 
-#[derive(Copy)]
+// pretty-expanded FIXME #23616
+
+#[derive(Copy, Clone)]
 struct Value {
-    n: int
+    n: isize
 }
 
 impl Value {
index cf09737e32efd5fc45d3302f40b693ef5310a310..b3c81cab3c1cea7bfffc98529081f8aa82aa629d 100644 (file)
 // Ensure assigning an owned or managed variable to itself works. In particular,
 // that we do not glue_drop before we glue_take (#3290).
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 use std::rc::Rc;
 
 pub fn main() {
-   let mut x = box 3;
+   let mut x: Box<_> = box 3;
    x = x;
    assert!(*x == 3);
 
index 19fdd04069edbc38068727353884a7e5a4c34187..5de1686ef9d8dc419653170fce36c6e0d9baf6f8 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod a {
     pub mod b {
         pub mod a {
-            pub fn foo() -> int { return 1; }
+            pub fn foo() -> isize { return 1; }
         }
     }
 }
index 5c4e2f5ebd52b297e557424eac52d1a18c42101b..ac810606a93285eb0ea953c6b856799d8a93bac8 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait MyTrait {
     fn f(&self) -> Self;
 }
 
 struct S {
-    x: int
+    x: isize
 }
 
 impl MyTrait for S {
old mode 100755 (executable)
new mode 100644 (file)
index c6b64d9..99ae3b7
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(core, std_misc)]
-use std::thread::Thread;
+use std::thread;
 use std::sync::Mutex;
 
 fn par_for<I, F>(iter: I, f: F)
@@ -19,7 +21,7 @@ fn par_for<I, F>(iter: I, f: F)
 {
     let f = &f;
     let _guards: Vec<_> = iter.map(|elem| {
-        Thread::scoped(move || {
+        thread::scoped(move || {
             f(elem)
         })
     }).collect();
index a920d76e7ca1b75bc942e2f58e421501036082af..3f64b2adb639538f490fc5a3c601606e99854175 100644 (file)
@@ -8,18 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc)]
+
+use std::thread;
 use std::sync::mpsc::channel;
 
 struct test {
-  f: int,
+  f: isize,
 }
 
 impl Drop for test {
     fn drop(&mut self) {}
 }
 
-fn test(f: int) -> test {
+fn test(f: isize) -> test {
     test {
         f: f
     }
@@ -28,7 +32,7 @@ fn test(f: int) -> test {
 pub fn main() {
     let (tx, rx) = channel();
 
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         let (tx2, rx2) = channel();
         tx.send(tx2).unwrap();
 
index 60093803f0b77745e77c7fde8879d070ab39fbbb..84d491d052404a2d0f06e00093e04a5d47b1637a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::sync::mpsc::{channel, Sender};
 
 // tests that ctrl's type gets inferred properly
index 33e4fa85bcb81003f155d1f4030e98c37b84acac..16a695f08fe6e463d625579e104b9ec80336334d 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections, into_cow)]
+
 extern crate collections;
 
 use std::collections::HashMap;
@@ -16,7 +20,7 @@ use std::borrow::{Cow, IntoCow};
 type SendStr = Cow<'static, str>;
 
 pub fn main() {
-    let mut map: HashMap<SendStr, uint> = HashMap::new();
+    let mut map: HashMap<SendStr, usize> = HashMap::new();
     assert!(map.insert("foo".into_cow(), 42).is_none());
     assert!(map.insert("foo".to_string().into_cow(), 42).is_some());
     assert!(map.insert("foo".into_cow(), 42).is_some());
index 3390369242d13943222cd5d9077b53712d0d9f29..d56657ee4d5170e64b359d6f386987355da08ac4 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections, into_cow)]
+
 extern crate collections;
 
 use self::collections::BTreeMap;
@@ -16,7 +20,7 @@ use std::borrow::{Cow, IntoCow};
 type SendStr = Cow<'static, str>;
 
 pub fn main() {
-    let mut map: BTreeMap<SendStr, uint> = BTreeMap::new();
+    let mut map: BTreeMap<SendStr, usize> = BTreeMap::new();
     assert!(map.insert("foo".into_cow(), 42).is_none());
     assert!(map.insert("foo".to_string().into_cow(), 42).is_some());
     assert!(map.insert("foo".into_cow(), 42).is_some());
index 8691d5e875bfc401fa3c0878b05a7d159b20a0b0..4fb1c32952f8ecea44a407ce288ad6fdeb55749e 100644 (file)
 
 // Test that a class with only sendable fields can be sent
 
+// pretty-expanded FIXME #23616
+
 use std::sync::mpsc::channel;
 
 struct foo {
-  i: int,
+  i: isize,
   j: char,
 }
 
-fn foo(i:int, j: char) -> foo {
+fn foo(i:isize, j: char) -> foo {
     foo {
         i: i,
         j: j
index 18519573c26a6ea6ddb08c801559ec82f968293d..59b92ec6a48daa26b9dbc11813728f71a7964653 100644 (file)
@@ -9,11 +9,13 @@
 // except according to those terms.
 
 
-fn test<F>(f: F) -> uint where F: FnOnce(uint) -> uint {
-    return f(22_usize);
+// pretty-expanded FIXME #23616
+
+fn test<F>(f: F) -> usize where F: FnOnce(usize) -> usize {
+    return f(22);
 }
 
 pub fn main() {
-    let y = test(|x| 4_usize * x);
-    assert_eq!(y, 88_usize);
+    let y = test(|x| 4 * x);
+    assert_eq!(y, 88);
 }
index 523b7528103ad55026b10a4306707b69943e052d..63ffa552405bea33680bcc7195ce5f5367217ff8 100644 (file)
@@ -15,13 +15,13 @@ use std::thread;
 
 pub fn main() { test05(); }
 
-fn test05_start<F:FnOnce(int)>(f: F) {
+fn test05_start<F:FnOnce(isize)>(f: F) {
     f(22);
 }
 
 fn test05() {
-    let three = box 3;
-    let fn_to_send = move|n:int| {
+    let three: Box<_> = box 3;
+    let fn_to_send = move|n:isize| {
         println!("{}", *three + n); // will copy x into the closure
         assert_eq!(*three, 3);
     };
index 0178b5e786d65c6d36b73dd5e4ee52eacde77492..6a92f32c0b314c29b08db88bebd2b5aa4e3c2cae 100644 (file)
 
 // Test accessing cross-crate inlined items from multiple compilation units.
 
+// pretty-expanded FIXME #23616
+
 extern crate sepcomp_cci_lib;
 use sepcomp_cci_lib::{cci_fn, CCI_STATIC};
 
-fn call1() -> uint {
+fn call1() -> usize {
     cci_fn() + CCI_STATIC
 }
 
 mod a {
     use sepcomp_cci_lib::{cci_fn, CCI_STATIC};
-    pub fn call2() -> uint {
+    pub fn call2() -> usize {
         cci_fn() + CCI_STATIC
     }
 }
 
 mod b {
     use sepcomp_cci_lib::{cci_fn, CCI_STATIC};
-    pub fn call3() -> uint {
+    pub fn call3() -> usize {
         cci_fn() + CCI_STATIC
     }
 }
index a5506e3fc761dc1deddd1a589041e17444168f42..f91c3d1ff3775c9cdeebdd9a712a0c87ce36b492 100644 (file)
 
 // Test accessing external items from multiple compilation units.
 
-#[link(name = "sepcomp-extern-lib")]
+// pretty-expanded FIXME #23616
+
+#[link(name = "sepcomp_extern_lib")]
 extern {
     #[allow(ctypes)]
-    fn foo() -> uint;
+    fn foo() -> usize;
 }
 
-fn call1() -> uint {
+fn call1() -> usize {
     unsafe { foo() }
 }
 
 mod a {
-    pub fn call2() -> uint {
+    pub fn call2() -> usize {
         unsafe { ::foo() }
     }
 }
 
 mod b {
-    pub fn call3() -> uint {
+    pub fn call3() -> usize {
         unsafe { ::foo() }
     }
 }
index 61f008ad854ebaef3432f2d61d2038d9587a3fe2..2e510082e2773e54f902dfbd4e18afe0347c7d5a 100644 (file)
 // Generate some code in the first compilation unit before declaring any
 // modules.  This ensures that the first module doesn't go into the same
 // compilation unit as the top-level module.
-fn pad() -> uint { 0 }
+// pretty-expanded FIXME #23616
+
+fn pad() -> usize { 0 }
 
 mod b {
-    pub fn three() -> uint {
+    pub fn three() -> usize {
         ::one() + ::a::two()
     }
 }
 
 mod a {
-    pub fn two() -> uint {
+    pub fn two() -> usize {
         ::one() + ::one()
     }
 }
 
-fn one() -> uint {
+fn one() -> usize {
     1
 }
 
@@ -38,4 +40,3 @@ fn main() {
     assert_eq!(a::two(), 2);
     assert_eq!(b::three(), 3);
 }
-
index 09f2a4281be084021c8d7c8af21f58330de3149d..f4fa0ed56981284af8c552f55cd56e088474ee30 100644 (file)
 // Generate some code in the first compilation unit before declaring any
 // modules.  This ensures that the first module doesn't go into the same
 // compilation unit as the top-level module.
-fn one() -> uint { 1 }
+// pretty-expanded FIXME #23616
+
+fn one() -> usize { 1 }
 
 mod a {
-    pub fn two() -> uint {
+    pub fn two() -> usize {
         ::one() + ::one()
     }
 }
 
 mod b {
-    pub fn three() -> uint {
+    pub fn three() -> usize {
         ::one() + ::a::two()
     }
 }
index f0b6a505929c66e9a67bcb6ec08034c3fbdcd4a9..b159b128333f0e39aea8386d3c20679d53825240 100644 (file)
@@ -14,6 +14,7 @@
 // aux-build:sepcomp_lib.rs
 // compile-flags: -C lto
 // no-prefer-dynamic
+// ignore-android FIXME #18800
 
 extern crate sepcomp_lib;
 use sepcomp_lib::a::one;
index 28adb55399b44afdb998e0f0d11de88b3460d331..00e83a570579d2bdaad709bef7910ad83a75e1bc 100644 (file)
@@ -12,6 +12,8 @@
 
 // Test linking against a library built with -C codegen-units > 1
 
+// pretty-expanded FIXME #23616
+
 extern crate sepcomp_lib;
 use sepcomp_lib::a::one;
 use sepcomp_lib::b::two;
index 26a5c4d1c5026cb6b9dd4d0c8e634dfb813be9e8..e926114e21924c0b6b1b04e60e06f8cd3cb30054 100644 (file)
 
 // Test references to static items across compilation units.
 
-fn pad() -> uint { 0 }
+// pretty-expanded FIXME #23616
 
-const ONE: uint = 1;
+fn pad() -> usize { 0 }
+
+const ONE: usize = 1;
 
 mod b {
     // Separate compilation always switches to the LLVM module with the fewest
     // instructions.  Make sure we have some instructions in this module so
     // that `a` and `b` don't go into the same compilation unit.
-    fn pad() -> uint { 0 }
+    fn pad() -> usize { 0 }
 
-    pub static THREE: uint = ::ONE + ::a::TWO;
+    pub static THREE: usize = ::ONE + ::a::TWO;
 }
 
 mod a {
-    fn pad() -> uint { 0 }
+    fn pad() -> usize { 0 }
 
-    pub const TWO: uint = ::ONE + ::ONE;
+    pub const TWO: usize = ::ONE + ::ONE;
 }
 
 fn main() {
@@ -36,4 +38,3 @@ fn main() {
     assert_eq!(a::TWO, 2);
     assert_eq!(b::THREE, 3);
 }
-
index 21c5a6fc83a123fc54f697b52516677716dfe6fc..71d3d91e84fde89f2c9cd6ee20d50d3c6e12b8bf 100644 (file)
 // In any case, this test should let us know if enabling parallel codegen ever
 // breaks unwinding.
 
+// pretty-expanded FIXME #23616
+
 use std::thread;
 
-fn pad() -> uint { 0 }
+fn pad() -> usize { 0 }
 
 mod a {
     pub fn f() {
index ef14e0ba931b5525d42131e35a5315c1ab610ec5..743f54abcfa662ebaa3cddd99041c47a8e04792c 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     assert!(("hello".to_string() < "hellr".to_string()));
     assert!(("hello ".to_string() > "hello".to_string()));
index 6e03c1e4a80f2eb3d8de27d2262c7d66e5d7dc72..3b719d1806e1138b545de7f674c9ce40473d900a 100644 (file)
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo(c: Vec<int> ) {
-    let a: int = 5;
-    let mut b: Vec<int> = Vec::new();
+fn foo(c: Vec<isize> ) {
+    let a: isize = 5;
+    let mut b: Vec<isize> = Vec::new();
 
 
-    match t::none::<int> {
-        t::some::<int>(_) => {
+    match t::none::<isize> {
+        t::some::<isize>(_) => {
             for _i in &c {
                 println!("{}", a);
                 let a = 17;
diff --git a/src/test/run-pass/shift-near-oflo.rs b/src/test/run-pass/shift-near-oflo.rs
new file mode 100644 (file)
index 0000000..4ff058f
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright 2015 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: -C debug-assertions
+
+// Check that we do *not* overflow on a number of edge cases.
+// (compare with test/run-fail/overflowing-{lsh,rsh}*.rs)
+
+// (Work around constant-evaluation)
+fn id<T>(x: T) -> T { x }
+
+fn main() {
+    test_left_shift();
+    test_right_shift();
+}
+
+fn test_left_shift() {
+    // negative rhs can panic, but values in [0,N-1] are okay for iN
+
+    macro_rules! tests {
+        ($iN:ty, $uN:ty, $max_rhs:expr, $expect_i:expr, $expect_u:expr) => { {
+            let x = (1 as $iN) << id(0);
+            assert_eq!(x, 1);
+            let x = (1 as $uN) << id(0);
+            assert_eq!(x, 1);
+            let x = (1 as $iN) << id($max_rhs);
+            assert_eq!(x, $expect_i);
+            let x = (1 as $uN) << id($max_rhs);
+            assert_eq!(x, $expect_u);
+            // high-order bits on LHS are silently discarded without panic.
+            let x = (3 as $iN) << id($max_rhs);
+            assert_eq!(x, $expect_i);
+            let x = (3 as $uN) << id($max_rhs);
+            assert_eq!(x, $expect_u);
+        } }
+    }
+
+    let x = 1_i8 << id(0);
+    assert_eq!(x, 1);
+    let x = 1_u8 << id(0);
+    assert_eq!(x, 1);
+    let x = 1_i8 << id(7);
+    assert_eq!(x, std::i8::MIN);
+    let x = 1_u8 << id(7);
+    assert_eq!(x, 0x80);
+    // high-order bits on LHS are silently discarded without panic.
+    let x = 3_i8 << id(7);
+    assert_eq!(x, std::i8::MIN);
+    let x = 3_u8 << id(7);
+    assert_eq!(x, 0x80);
+
+    // above is (approximately) expanded from:
+    tests!(i8, u8, 7, std::i8::MIN, 0x80_u8);
+
+    tests!(i16, u16, 15, std::i16::MIN, 0x8000_u16);
+    tests!(i32, u32, 31, std::i32::MIN, 0x8000_0000_u32);
+    tests!(i64, u64, 63, std::i64::MIN, 0x8000_0000_0000_0000_u64);
+}
+
+fn test_right_shift() {
+    // negative rhs can panic, but values in [0,N-1] are okay for iN
+
+    macro_rules! tests {
+        ($iN:ty, $uN:ty, $max_rhs:expr,
+         $signbit_i:expr, $highbit_i:expr, $highbit_u:expr) =>
+        { {
+            let x = (1 as $iN) >> id(0);
+            assert_eq!(x, 1);
+            let x = (1 as $uN) >> id(0);
+            assert_eq!(x, 1);
+            let x = ($highbit_i) >> id($max_rhs-1);
+            assert_eq!(x, 1);
+            let x = ($highbit_u) >> id($max_rhs);
+            assert_eq!(x, 1);
+            // sign-bit is carried by arithmetic right shift
+            let x = ($signbit_i) >> id($max_rhs);
+            assert_eq!(x, -1);
+            // low-order bits on LHS are silently discarded without panic.
+            let x = ($highbit_i + 1) >> id($max_rhs-1);
+            assert_eq!(x, 1);
+            let x = ($highbit_u + 1) >> id($max_rhs);
+            assert_eq!(x, 1);
+            let x = ($signbit_i + 1) >> id($max_rhs);
+            assert_eq!(x, -1);
+        } }
+    }
+
+    tests!(i8, u8, 7, std::i8::MIN, 0x40_i8, 0x80_u8);
+    tests!(i16, u16, 15, std::i16::MIN, 0x4000_u16, 0x8000_u16);
+    tests!(i32, u32, 31, std::i32::MIN, 0x4000_0000_u32, 0x8000_0000_u32);
+    tests!(i64, u64, 63, std::i64::MIN,
+           0x4000_0000_0000_0000_u64, 0x8000_0000_0000_0000_u64);
+}
index 2f56e09b2df83ea5f5d4974bb564d02842f7a245..b0ab72c650d74fb599e543243a97e236d76a6d3b 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test that we can do shifts by any integral type.
 
+// pretty-expanded FIXME #23616
+
 struct Panolpy {
     i8: i8,
     i16: i16,
@@ -25,17 +27,17 @@ struct Panolpy {
 }
 
 fn foo(p: &Panolpy) {
-    assert_eq!(22_i32 >> p.i8, 11_i32);
-    assert_eq!(22_i32 >> p.i16, 11_i32);
-    assert_eq!(22_i32 >> p.i32, 11_i32);
-    assert_eq!(22_i32 >> p.i64, 11_i32);
-    assert_eq!(22_i32 >> p.isize, 11_i32);
-
-    assert_eq!(22_i32 >> p.u8, 11_i32);
-    assert_eq!(22_i32 >> p.u16, 11_i32);
-    assert_eq!(22_i32 >> p.u32, 11_i32);
-    assert_eq!(22_i32 >> p.u64, 11_i32);
-    assert_eq!(22_i32 >> p.usize, 11_i32);
+    assert_eq!(22 >> p.i8, 11);
+    assert_eq!(22 >> p.i16, 11);
+    assert_eq!(22 >> p.i32, 11);
+    assert_eq!(22 >> p.i64, 11);
+    assert_eq!(22 >> p.isize, 11);
+
+    assert_eq!(22 >> p.u8, 11);
+    assert_eq!(22 >> p.u16, 11);
+    assert_eq!(22 >> p.u32, 11);
+    assert_eq!(22 >> p.u64, 11);
+    assert_eq!(22 >> p.usize, 11);
 }
 
 fn main() {
index 918da535099272fdb43e703393301ddb1d32f7c9..f1637fe1e0931fad9475d94fd8391501fc51ecb2 100644 (file)
@@ -11,6 +11,8 @@
 // Testing shifts for various combinations of integers
 // Issue #1570
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     test_misc();
     test_expr();
@@ -22,60 +24,60 @@ fn test_misc() {
 }
 
 fn test_expr() {
-    let v10 = 10 as uint;
+    let v10 = 10 as usize;
     let v4 = 4 as u8;
     let v2 = 2 as u8;
-    assert_eq!(v10 >> v2 as uint, v2 as uint);
-    assert_eq!(v10 << v4 as uint, 160 as uint);
+    assert_eq!(v10 >> v2 as usize, v2 as usize);
+    assert_eq!(v10 << v4 as usize, 160 as usize);
 
     let v10 = 10 as u8;
-    let v4 = 4 as uint;
-    let v2 = 2 as uint;
-    assert_eq!(v10 >> v2 as uint, v2 as u8);
-    assert_eq!(v10 << v4 as uint, 160 as u8);
+    let v4 = 4 as usize;
+    let v2 = 2 as usize;
+    assert_eq!(v10 >> v2 as usize, v2 as u8);
+    assert_eq!(v10 << v4 as usize, 160 as u8);
 
-    let v10 = 10 as int;
+    let v10 = 10 as isize;
     let v4 = 4 as i8;
     let v2 = 2 as i8;
-    assert_eq!(v10 >> v2 as uint, v2 as int);
-    assert_eq!(v10 << v4 as uint, 160 as int);
+    assert_eq!(v10 >> v2 as usize, v2 as isize);
+    assert_eq!(v10 << v4 as usize, 160 as isize);
 
     let v10 = 10 as i8;
-    let v4 = 4 as int;
-    let v2 = 2 as int;
-    assert_eq!(v10 >> v2 as uint, v2 as i8);
-    assert_eq!(v10 << v4 as uint, 160 as i8);
+    let v4 = 4 as isize;
+    let v2 = 2 as isize;
+    assert_eq!(v10 >> v2 as usize, v2 as i8);
+    assert_eq!(v10 << v4 as usize, 160 as i8);
 
-    let v10 = 10 as uint;
-    let v4 = 4 as int;
-    let v2 = 2 as int;
-    assert_eq!(v10 >> v2 as uint, v2 as uint);
-    assert_eq!(v10 << v4 as uint, 160 as uint);
+    let v10 = 10 as usize;
+    let v4 = 4 as isize;
+    let v2 = 2 as isize;
+    assert_eq!(v10 >> v2 as usize, v2 as usize);
+    assert_eq!(v10 << v4 as usize, 160 as usize);
 }
 
 fn test_const() {
-    static r1_1: uint = 10_usize >> 2_usize;
-    static r2_1: uint = 10_usize << 4_usize;
-    assert_eq!(r1_1, 2 as uint);
-    assert_eq!(r2_1, 160 as uint);
+    static r1_1: usize = 10_usize >> 2_usize;
+    static r2_1: usize = 10_usize << 4_usize;
+    assert_eq!(r1_1, 2 as usize);
+    assert_eq!(r2_1, 160 as usize);
 
     static r1_2: u8 = 10u8 >> 2_usize;
     static r2_2: u8 = 10u8 << 4_usize;
     assert_eq!(r1_2, 2 as u8);
     assert_eq!(r2_2, 160 as u8);
 
-    static r1_3: int = 10 >> 2_usize;
-    static r2_3: int = 10 << 4_usize;
-    assert_eq!(r1_3, 2 as int);
-    assert_eq!(r2_3, 160 as int);
+    static r1_3: isize = 10 >> 2_usize;
+    static r2_3: isize = 10 << 4_usize;
+    assert_eq!(r1_3, 2 as isize);
+    assert_eq!(r2_3, 160 as isize);
 
     static r1_4: i8 = 10i8 >> 2_usize;
     static r2_4: i8 = 10i8 << 4_usize;
     assert_eq!(r1_4, 2 as i8);
     assert_eq!(r2_4, 160 as i8);
 
-    static r1_5: uint = 10_usize >> 2_usize;
-    static r2_5: uint = 10_usize << 4_usize;
-    assert_eq!(r1_5, 2 as uint);
-    assert_eq!(r2_5, 160 as uint);
+    static r1_5: usize = 10_usize >> 2_usize;
+    static r2_5: usize = 10_usize << 4_usize;
+    assert_eq!(r1_5, 2 as usize);
+    assert_eq!(r2_5, 160 as usize);
 }
index f496765edca9882266cb850a8fc4399d93018680..03971668182acd98ff8d1607b2f6dad8033dfa98 100644 (file)
@@ -8,12 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
 #[derive(Debug)]
 struct Foo(Box<[u8]>);
 
 pub fn main() {
-    println!("{:?}", Foo(box [0, 1, 2]));
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    println!("{:?}", Foo(Box::new([0, 1, 2])));
 }
index 776d897938dd3c5ae556c8043430aae50cd0b90c..bfc4aee7757a59800ba8bb337877a765e2568990 100644 (file)
@@ -10,6 +10,9 @@
 
 // ignore-windows
 
+#![feature(old_io)]
+#![feature(os)]
+
 use std::env;
 use std::old_io::process::{Command, ExitSignal, ExitStatus};
 
@@ -17,7 +20,7 @@ pub fn main() {
     let args: Vec<String> = env::args().collect();
     if args.len() >= 2 && args[1] == "signal" {
         // Raise a segfault.
-        unsafe { *(0 as *mut int) = 0; }
+        unsafe { *(0 as *mut isize) = 0; }
     } else {
         let status = Command::new(&args[0]).arg("signal").status().unwrap();
         // Windows does not have signal, so we get exit status 0xC0000028 (STATUS_BAD_STACK).
index 2acb93f48f92619fc1c78e519e54207c5a48cbf4..7167236438088e3139fea255c3cedb5225f4aa29 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum test { thing = -5 >> 1_usize }
 pub fn main() {
-    assert_eq!(test::thing as int, -3);
+    assert_eq!(test::thing as isize, -3);
 }
index d1428c6be19ef880f06645c74a59908b90dd7b04..4a05b487ae24e58a2a98ee2b2c54830a00b92c4c 100644 (file)
 // Be sure that when a SIGPIPE would have been received that the entire process
 // doesn't die in a ball of fire, but rather it's gracefully handled.
 
-use std::os;
+// ignore-aarch64
+// pretty-expanded FIXME #23616
+
 use std::env;
-use std::old_io::PipeStream;
-use std::old_io::Command;
+use std::io::prelude::*;
+use std::io;
+use std::process::{Command, Stdio};
 
 fn test() {
-    let os::Pipe { reader, writer } = unsafe { os::pipe().unwrap() };
-    let reader = PipeStream::open(reader);
-    let mut writer = PipeStream::open(writer);
-    drop(reader);
-
-    let _ = writer.write(&[1]);
+    let _ = io::stdin().read_line(&mut String::new());
+    io::stdout().write(&[1]);
+    assert!(io::stdout().flush().is_err());
 }
 
 fn main() {
@@ -32,6 +32,9 @@ fn main() {
     }
 
     let mut p = Command::new(&args[0])
+                        .stdout(Stdio::piped())
+                        .stdin(Stdio::piped())
                         .arg("test").spawn().unwrap();
+    drop(p.stdout.take());
     assert!(p.wait().unwrap().success());
 }
index 779e507f43dfdff3cd77aafb98dfa53c0682a084..9f7b78e4e3354fae1e16d0bd6978e673f61e5e57 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
 
 use std::simd::{i32x4, f32x4, u32x4};
 
@@ -29,6 +32,7 @@ pub fn main() {
     assert!(eq_u32x4(u32x4(1, 2, 3, 4) + u32x4(4, 3, 2, 1), u32x4(5, 5, 5, 5)));
     assert!(eq_u32x4(u32x4(4, 5, 6, 7) - u32x4(4, 3, 2, 1), u32x4(0, 2, 4, 6)));
     assert!(eq_u32x4(u32x4(1, 2, 3, 4) * u32x4(4, 3, 2, 1), u32x4(4, 6, 6, 4)));
+    assert!(eq_u32x4(u32x4(1, 2, 3, 4) / u32x4(4, 3, 2, 1), u32x4(0, 0, 1, 4)));
     assert!(eq_u32x4(u32x4(1, 2, 3, 4) & u32x4(4, 3, 2, 1), u32x4(0, 2, 2, 0)));
     assert!(eq_u32x4(u32x4(1, 2, 3, 4) | u32x4(4, 3, 2, 1), u32x4(5, 3, 3, 5)));
     assert!(eq_u32x4(u32x4(1, 2, 3, 4) ^ u32x4(4, 3, 2, 1), u32x4(5, 1, 1, 5)));
@@ -38,6 +42,7 @@ pub fn main() {
     assert!(eq_i32x4(i32x4(1, 2, 3, 4) + i32x4(4, 3, 2, 1), i32x4(5, 5, 5, 5)));
     assert!(eq_i32x4(i32x4(1, 2, 3, 4) - i32x4(4, 3, 2, 1), i32x4(-3, -1, 1, 3)));
     assert!(eq_i32x4(i32x4(1, 2, 3, 4) * i32x4(4, 3, 2, 1), i32x4(4, 6, 6, 4)));
+    assert!(eq_i32x4(i32x4(1, 2, 3, 4) / i32x4(4, 3, 2, 1), i32x4(0, 0, 1, 4)));
     assert!(eq_i32x4(i32x4(1, 2, 3, 4) & i32x4(4, 3, 2, 1), i32x4(0, 2, 2, 0)));
     assert!(eq_i32x4(i32x4(1, 2, 3, 4) | i32x4(4, 3, 2, 1), i32x4(5, 3, 3, 5)));
     assert!(eq_i32x4(i32x4(1, 2, 3, 4) ^ i32x4(4, 3, 2, 1), i32x4(5, 1, 1, 5)));
index 1371c4cc5f4ad7f6405eaa290ad719d4bbbc4727..867f028a3fb3c14aa977bca9dee19fbfa4f00025 100644 (file)
@@ -9,12 +9,14 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 #![feature(simd)]
 
 use std::ops;
 
 #[simd]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct f32x4(f32, f32, f32, f32);
 
 fn add<T: ops::Add<Output=T>>(lhs: T, rhs: T) -> T {
index 7f1be4b7d7060f0b8ac5ca485ffddc11ded05a64..8dca78b28e802d686b1568373a2c04ac178a594e 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
 
+#![feature(core)]
 #![feature(simd)]
 
 pub fn main() {
index 582810f0def339528bf4d6316901f18974636b6b..8324efc64172771199e51c8738c861c60e09d98c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(simd)]
 #![allow(non_camel_case_types)]
 
index a1a7457811280304cd856a4caf2e43ffb75026a7..540666f41ae2bb4328128cd793d962c85930f37f 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 #![feature(simd)]
 
 #[simd]
index 27d4f105f3740c33e654bf0a8d7324d1ce04e7f4..02fc2a61d017bfe619c4476664549abe9f5d088a 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 enum clam<T> { a(T), }
 
-pub fn main() { let c = clam::a(2); match c { clam::a::<int>(_) => { } } }
+pub fn main() { let c = clam::a(2); match c { clam::a::<isize>(_) => { } } }
index 8a36f9e17f383c66ef8bb73a2be144ec172b1a4e..2e8d8f61bc8a74331f6f3574c574d056bc1c0e71 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 enum clam<T> { a(T), }
 
 pub fn main() { }
index 2217dddbd21f0884a2efa04a48e7a97fb0a8ade6..52989b3666924bf43ad9157916cfeba3d3ac4d90 100644 (file)
@@ -11,9 +11,9 @@
 enum opt<T> { none, some(T) }
 
 pub fn main() {
-    let x = opt::none::<int>;
+    let x = opt::none::<isize>;
     match x {
-        opt::none::<int> => { println!("hello world"); }
+        opt::none::<isize> => { println!("hello world"); }
         opt::some(_) => { }
     }
 }
diff --git a/src/test/run-pass/single-derive-attr-with-gate.rs b/src/test/run-pass/single-derive-attr-with-gate.rs
new file mode 100644 (file)
index 0000000..addc56e
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+#![feature(custom_derive)]
+
+#[derive_Clone]
+struct Test;
+
+pub fn main() {
+    Test.clone();
+}
index 4b587ae70a1c262481cf2008abd7a77debdd614d..007ce52d7c455bdf8a17ab03c5e0461f4fefa28b 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum clam<T> { a(T, int), b, }
+enum clam<T> { a(T, isize), b, }
 
 fn uhoh<T>(v: Vec<clam<T>> ) {
     match v[1] {
@@ -22,6 +22,6 @@ fn uhoh<T>(v: Vec<clam<T>> ) {
 }
 
 pub fn main() {
-    let v: Vec<clam<int>> = vec!(clam::b::<int>, clam::b::<int>, clam::a::<int>(42, 17));
-    uhoh::<int>(v);
+    let v: Vec<clam<isize>> = vec!(clam::b::<isize>, clam::b::<isize>, clam::a::<isize>(42, 17));
+    uhoh::<isize>(v);
 }
index 348b7562f8460ae139a67cbda83fc1bf0cc6daaf..76c06d560d754417f786c7f4a09d8634acaee546 100644 (file)
@@ -10,6 +10,8 @@
 
 // Possibly-dynamic size of typaram should be cleared at pointer boundary.
 
+// pretty-expanded FIXME #23616
+
 fn bar<T: Sized>() { }
 fn foo<T>() { bar::<&T>() }
 pub fn main() { }
index e64917a97a637f6cc312fe138595fa80a66e0a0d..d3a6b104dba55f441f526482f63c69d680258c55 100644 (file)
@@ -11,6 +11,8 @@
 // Possibly-dynamic size of typaram should be cleared at pointer boundary.
 
 
+// pretty-expanded FIXME #23616
+
 fn bar<T: Sized>() { }
 fn foo<T>() { bar::<Box<T>>() }
 pub fn main() { }
index 6e256be69dac74c1d463ebe30f493c2518e0c306..7f34b94ad04b09e51fddda165cad1cbf44cead33 100644 (file)
 
 // Test slicing expressions on slices and Vecs.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
-    let x: &[int] = &[1, 2, 3, 4, 5];
-    let cmp: &[int] = &[1, 2, 3, 4, 5];
+    let x: &[isize] = &[1, 2, 3, 4, 5];
+    let cmp: &[isize] = &[1, 2, 3, 4, 5];
     assert!(&x[..] == cmp);
-    let cmp: &[int] = &[3, 4, 5];
+    let cmp: &[isize] = &[3, 4, 5];
     assert!(&x[2..] == cmp);
-    let cmp: &[int] = &[1, 2, 3];
+    let cmp: &[isize] = &[1, 2, 3];
     assert!(&x[..3] == cmp);
-    let cmp: &[int] = &[2, 3, 4];
+    let cmp: &[isize] = &[2, 3, 4];
     assert!(&x[1..4] == cmp);
 
-    let x: Vec<int> = vec![1, 2, 3, 4, 5];
-    let cmp: &[int] = &[1, 2, 3, 4, 5];
+    let x: Vec<isize> = vec![1, 2, 3, 4, 5];
+    let cmp: &[isize] = &[1, 2, 3, 4, 5];
     assert!(&x[..] == cmp);
-    let cmp: &[int] = &[3, 4, 5];
+    let cmp: &[isize] = &[3, 4, 5];
     assert!(&x[2..] == cmp);
-    let cmp: &[int] = &[1, 2, 3];
+    let cmp: &[isize] = &[1, 2, 3];
     assert!(&x[..3] == cmp);
-    let cmp: &[int] = &[2, 3, 4];
+    let cmp: &[isize] = &[2, 3, 4];
     assert!(&x[1..4] == cmp);
 
-    let x: &mut [int] = &mut [1, 2, 3, 4, 5];
+    let x: &mut [isize] = &mut [1, 2, 3, 4, 5];
     {
-        let cmp: &mut [int] = &mut [1, 2, 3, 4, 5];
+        let cmp: &mut [isize] = &mut [1, 2, 3, 4, 5];
         assert!(&mut x[..] == cmp);
     }
     {
-        let cmp: &mut [int] = &mut [3, 4, 5];
+        let cmp: &mut [isize] = &mut [3, 4, 5];
         assert!(&mut x[2..] == cmp);
     }
     {
-        let cmp: &mut [int] = &mut [1, 2, 3];
+        let cmp: &mut [isize] = &mut [1, 2, 3];
         assert!(&mut x[..3] == cmp);
     }
     {
-        let cmp: &mut [int] = &mut [2, 3, 4];
+        let cmp: &mut [isize] = &mut [2, 3, 4];
         assert!(&mut x[1..4] == cmp);
     }
 
-    let mut x: Vec<int> = vec![1, 2, 3, 4, 5];
+    let mut x: Vec<isize> = vec![1, 2, 3, 4, 5];
     {
-        let cmp: &mut [int] = &mut [1, 2, 3, 4, 5];
+        let cmp: &mut [isize] = &mut [1, 2, 3, 4, 5];
         assert!(&mut x[..] == cmp);
     }
     {
-        let cmp: &mut [int] = &mut [3, 4, 5];
+        let cmp: &mut [isize] = &mut [3, 4, 5];
         assert!(&mut x[2..] == cmp);
     }
     {
-        let cmp: &mut [int] = &mut [1, 2, 3];
+        let cmp: &mut [isize] = &mut [1, 2, 3];
         assert!(&mut x[..3] == cmp);
     }
     {
-        let cmp: &mut [int] = &mut [2, 3, 4];
+        let cmp: &mut [isize] = &mut [2, 3, 4];
         assert!(&mut x[1..4] == cmp);
     }
 }
index 639ffd56002ec381da9d7c0a10725b0bb11a0193..a4f737f74619cababf55e5864f74abef27ddbde1 100644 (file)
 
 // Test that if a slicing expr[..] fails, the correct cleanups happen.
 
+// pretty-expanded FIXME #23616
+
 use std::thread;
 
 struct Foo;
 
-static mut DTOR_COUNT: int = 0;
+static mut DTOR_COUNT: isize = 0;
 
 impl Drop for Foo {
     fn drop(&mut self) { unsafe { DTOR_COUNT += 1; } }
index 4a2038175d2e63b6ec8bfc7569c41a06813f44d9..f02a84b9070bf8cdf1f94b260f4d7ad0d69f542d 100644 (file)
 
 // Test that if a slicing expr[..] fails, the correct cleanups happen.
 
+// pretty-expanded FIXME #23616
+
 use std::thread;
 
 struct Foo;
 
-static mut DTOR_COUNT: int = 0;
+static mut DTOR_COUNT: isize = 0;
 
 impl Drop for Foo {
     fn drop(&mut self) { unsafe { DTOR_COUNT += 1; } }
 }
 
-fn bar() -> uint {
+fn bar() -> usize {
     panic!();
 }
 
index 30b53dbb0ad5bea0bdf96b7ddb419345e2749ad6..edc5f6b18462474a2e047696bac0c638e7370261 100644 (file)
 
 // Test slicing sugar.
 
-#![feature(associated_types)]
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
 
 extern crate core;
 use core::ops::{Index, IndexMut, Range, RangeTo, RangeFrom, RangeFull};
 
-static mut COUNT: uint = 0;
+static mut COUNT: usize = 0;
 
 struct Foo;
 
 impl Index<Range<Foo>> for Foo {
     type Output = Foo;
-    fn index(&self, index: &Range<Foo>) -> &Foo {
+    fn index(&self, index: Range<Foo>) -> &Foo {
         unsafe { COUNT += 1; }
         self
     }
 }
 impl Index<RangeTo<Foo>> for Foo {
     type Output = Foo;
-    fn index(&self, index: &RangeTo<Foo>) -> &Foo {
+    fn index(&self, index: RangeTo<Foo>) -> &Foo {
         unsafe { COUNT += 1; }
         self
     }
 }
 impl Index<RangeFrom<Foo>> for Foo {
     type Output = Foo;
-    fn index(&self, index: &RangeFrom<Foo>) -> &Foo {
+    fn index(&self, index: RangeFrom<Foo>) -> &Foo {
         unsafe { COUNT += 1; }
         self
     }
 }
 impl Index<RangeFull> for Foo {
     type Output = Foo;
-    fn index(&self, _index: &RangeFull) -> &Foo {
+    fn index(&self, _index: RangeFull) -> &Foo {
         unsafe { COUNT += 1; }
         self
     }
 }
 
 impl IndexMut<Range<Foo>> for Foo {
-    fn index_mut(&mut self, index: &Range<Foo>) -> &mut Foo {
+    fn index_mut(&mut self, index: Range<Foo>) -> &mut Foo {
         unsafe { COUNT += 1; }
         self
     }
 }
 impl IndexMut<RangeTo<Foo>> for Foo {
-    fn index_mut(&mut self, index: &RangeTo<Foo>) -> &mut Foo {
+    fn index_mut(&mut self, index: RangeTo<Foo>) -> &mut Foo {
         unsafe { COUNT += 1; }
         self
     }
 }
 impl IndexMut<RangeFrom<Foo>> for Foo {
-    fn index_mut(&mut self, index: &RangeFrom<Foo>) -> &mut Foo {
+    fn index_mut(&mut self, index: RangeFrom<Foo>) -> &mut Foo {
         unsafe { COUNT += 1; }
         self
     }
 }
 impl IndexMut<RangeFull> for Foo {
-    fn index_mut(&mut self, _index: &RangeFull) -> &mut Foo {
+    fn index_mut(&mut self, _index: RangeFull) -> &mut Foo {
         unsafe { COUNT += 1; }
         self
     }
index 35283e466c1c099f4c6a6993cf5aa439652d8ff0..9515da6fcbc8d2207add789f4c3172cec508a5b2 100644 (file)
@@ -8,27 +8,32 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+// this is for the wrapping_add call below.
+#![feature(core)]
+
 /*!
  * Tests the range assertion wraparound case in trans::middle::adt::load_discr.
  */
 
 #[repr(u8)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum Eu { Lu = 0, Hu = 255 }
 
 static CLu: Eu = Eu::Lu;
 static CHu: Eu = Eu::Hu;
 
 #[repr(i8)]
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum Es { Ls = -128, Hs = 127 }
 
 static CLs: Es = Es::Ls;
 static CHs: Es = Es::Hs;
 
 pub fn main() {
-    assert_eq!((Eu::Hu as u8) + 1, Eu::Lu as u8);
-    assert_eq!((Es::Hs as i8) + 1, Es::Ls as i8);
+    assert_eq!((Eu::Hu as u8).wrapping_add(1), Eu::Lu as u8);
+    assert_eq!((Es::Hs as i8).wrapping_add(1), Es::Ls as i8);
     assert_eq!(CLu as u8, Eu::Lu as u8);
     assert_eq!(CHu as u8, Eu::Hu as u8);
     assert_eq!(CLs as i8, Es::Ls as i8);
index 475af8f2b8ef05fa70cc1f46c6013705024ac8c6..86eed715f325a925b5e2954351363e21b9e3a71a 100644 (file)
@@ -29,14 +29,14 @@ macro_rules! check {
 pub fn main() {
     check!(Option<u8>, 2,
            None, "None",
-           Some(129u8), "Some(129)");
+           Some(129), "Some(129)");
     check!(Option<i16>, 4,
            None, "None",
-           Some(-20000i16), "Some(-20000)");
+           Some(-20000), "Some(-20000)");
     check!(Either<u8, i8>, 2,
-           Either::Left(132u8), "Left(132)",
-           Either::Right(-32i8), "Right(-32)");
+           Either::Left(132), "Left(132)",
+           Either::Right(-32), "Right(-32)");
     check!(Either<u8, i16>, 4,
-           Either::Left(132u8), "Left(132)",
-           Either::Right(-20000i16), "Right(-20000)");
+           Either::Left(132), "Left(132)",
+           Either::Right(-20000), "Right(-20000)");
 }
index 61b2fc8b50f5b6ac13fc49dd14a4aa0368164f52..5e84ce19de1efa21b5f64b96c3cb732de5970101 100644 (file)
@@ -10,7 +10,9 @@
 
 // Smallest "hello world" with a libc runtime
 
-#![feature(intrinsics, lang_items, start, no_std)]
+// pretty-expanded FIXME #23616
+
+#![feature(intrinsics, lang_items, start, no_std, libc)]
 #![no_std]
 
 extern crate libc;
@@ -24,9 +26,9 @@ extern "rust-intrinsic" { fn transmute<T, U>(t: T) -> U; }
 
 #[start]
 #[no_stack_check]
-fn main(_: int, _: *const *const u8) -> int {
+fn main(_: isize, _: *const *const u8) -> isize {
     unsafe {
-        let (ptr, _): (*const u8, uint) = transmute("Hello!\0");
+        let (ptr, _): (*const u8, usize) = transmute("Hello!\0");
         puts(ptr);
     }
     return 0;
index 2220761a026667cbcf408b9d794536cda8785f44..90ea7537c6e607aea721549fca788db37ea8c6d7 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(non_ascii_idents)]
 #![deny(non_snake_case)]
 
index c8fe400c4c3c617bbb4203aac35a6a88c51a4777..efddf0455cd5fbe472bb57e6158e1dff84739a08 100644 (file)
@@ -8,21 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+use std::thread;
 
-fn x(s: String, n: int) {
+fn x(s: String, n: isize) {
     println!("{}", s);
     println!("{}", n);
 }
 
 pub fn main() {
-    let _t = Thread::spawn(|| x("hello from first spawned fn".to_string(), 65) );
-    let _t = Thread::spawn(|| x("hello from second spawned fn".to_string(), 66) );
-    let _t = Thread::spawn(|| x("hello from third spawned fn".to_string(), 67) );
-    let mut i: int = 30;
+    let _t = thread::scoped(|| x("hello from first spawned fn".to_string(), 65) );
+    let _t = thread::scoped(|| x("hello from second spawned fn".to_string(), 66) );
+    let _t = thread::scoped(|| x("hello from third spawned fn".to_string(), 67) );
+    let mut i = 30;
     while i > 0 {
         i = i - 1;
         println!("parent sleeping");
-        Thread::yield_now();
+        thread::yield_now();
     }
 }
index bf2f03b3e6de9bf3da43927036129a99e95d90e4..aab292a940afbb25c3cfc0b939136de06f6c370e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 /*
   Make sure we can spawn tasks that take different types of
   parameters. This is based on a test case for #520 provided by Rob
 use std::thread;
 use std::sync::mpsc::{channel, Sender};
 
-type ctx = Sender<int>;
+type ctx = Sender<isize>;
 
 fn iotask(_tx: &ctx, ip: String) {
     assert_eq!(ip, "localhost".to_string());
 }
 
 pub fn main() {
-    let (tx, _rx) = channel::<int>();
+    let (tx, _rx) = channel::<isize>();
     let t = thread::spawn(move|| iotask(&tx, "localhost".to_string()) );
     t.join().ok().unwrap();
 }
index 90b47f4986bfb95ca5726c9220d040ca9184c09c..1c34634c73da27990d689550c84964b95e511715 100644 (file)
@@ -14,4 +14,4 @@ pub fn main() {
     thread::spawn(move|| child(10)).join().ok().unwrap();
 }
 
-fn child(i: int) { println!("{}", i); assert!((i == 10)); }
+fn child(i: isize) { println!("{}", i); assert!((i == 10)); }
index 91edb5fd9c1e837e162fd600b7d6e867663b9b0a..93dc3faaa205dfb47e72ef6fe27f10a75e7b7d94 100644 (file)
@@ -12,10 +12,10 @@ use std::thread;
 
 pub fn main() {
     let t = thread::spawn(move|| child((10, 20, 30, 40, 50, 60, 70, 80, 90)) );
-    t.join().ok().unwrap();
+    t.join().ok().unwrap(); // forget Err value, since it doesn't implement Debug
 }
 
-fn child(args: (int, int, int, int, int, int, int, int, int)) {
+fn child(args: (isize, isize, isize, isize, isize, isize, isize, isize, isize)) {
     let (i1, i2, i3, i4, i5, i6, i7, i8, i9) = args;
     println!("{}", i1);
     println!("{}", i2);
index 515198f7a71eb0faa4bdaffc4301c93346fda479..f93600195dc259cc89275f650375ee9b1bf1507c 100644 (file)
@@ -10,7 +10,9 @@
 
 // Issue #2040
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let foo = 1;
-    assert_eq!(&foo as *const int, &foo as *const int);
+    let foo: isize = 1;
+    assert_eq!(&foo as *const isize, &foo as *const isize);
 }
diff --git a/src/test/run-pass/stat.rs b/src/test/run-pass/stat.rs
deleted file mode 100644 (file)
index 87d7376..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-// 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.
-//
-// 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 std::old_io::fs::PathExtensions;
-use std::old_io::{File, TempDir};
-
-pub fn main() {
-    let dir = TempDir::new_in(&Path::new("."), "").unwrap();
-    let path = dir.path().join("file");
-
-    {
-        match File::create(&path) {
-            Err(..) => unreachable!(),
-            Ok(f) => {
-                let mut f = f;
-                for _ in 0_usize..1000 {
-                    f.write(&[0]);
-                }
-            }
-        }
-    }
-
-    assert!(path.exists());
-    assert_eq!(path.stat().unwrap().size, 1000);
-}
index f8fd81b9365159f6bcc21f72e46515172385720f..e5583a3c697b6714f269b4dccd1e511d411e1f04 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(static_assert)]
+
 #[static_assert]
 static b: bool = true;
 
index efc374e25bbff097011a424e5644dfd5cacf1d4c..80de65c0e9f656daba5bcce0d6946693def88c35 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:static_fn_inline_xc_aux.rs
 
-extern crate "static_fn_inline_xc_aux" as mycore;
+// pretty-expanded FIXME #23616
+
+extern crate static_fn_inline_xc_aux as mycore;
 
 use mycore::num;
 
index cb9f7c3da02485d237c834120b36e85e4189ec56..550e03c8b12fbedd17b4fdeb06646a1ff1927e1c 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:static_fn_trait_xc_aux.rs
 
-extern crate "static_fn_trait_xc_aux" as mycore;
+// pretty-expanded FIXME #23616
+
+extern crate static_fn_trait_xc_aux as mycore;
 
 use mycore::num;
 
index 6e12c5fa73de15c4c217d806a077f9cdd6f5f64b..55f3b0883b9d90728ad9be9a600a9200958ef8fe 100644 (file)
@@ -9,9 +9,11 @@
 // except according to those terms.
 
 // aux-build:static-function-pointer-aux.rs
-extern crate "static-function-pointer-aux" as aux;
+// pretty-expanded FIXME #23616
 
-fn f(x: int) -> int { x }
+extern crate static_function_pointer_aux as aux;
+
+fn f(x: isize) -> isize { x }
 
 pub fn main() {
     assert_eq!(aux::F(42), -42);
index ff1091e07ef169ebcdb1d19363e3fbfdaf06be6c..67cc033f7cf755d8d79e53ab1b625161897e0969 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(x: int) -> int { x }
-fn g(x: int) -> int { 2 * x }
+// pretty-expanded FIXME #23616
 
-static F: fn(int) -> int = f;
-static mut G: fn(int) -> int = f;
+fn f(x: isize) -> isize { x }
+fn g(x: isize) -> isize { 2 * x }
+
+static F: fn(isize) -> isize = f;
+static mut G: fn(isize) -> isize = f;
 
 pub fn main() {
     assert_eq!(F(42), 42);
index b66999c8e67229083cb4a52328a701f7b317ea9b..aff2797c1acce41b55b0eb33b639f06147cf1794 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 pub trait plus {
-    fn plus(&self) -> int;
+    fn plus(&self) -> isize;
 }
 
 mod a {
     use plus;
-    impl plus for uint { fn plus(&self) -> int { *self as int + 20 } }
+    impl plus for usize { fn plus(&self) -> isize { *self as isize + 20 } }
 }
 
 mod b {
     use plus;
-    impl plus for String { fn plus(&self) -> int { 200 } }
+    impl plus for String { fn plus(&self) -> isize { 200 } }
 }
 
 trait uint_utils {
     fn str(&self) -> String;
-    fn multi<F>(&self, f: F) where F: FnMut(uint);
+    fn multi<F>(&self, f: F) where F: FnMut(usize);
 }
 
-impl uint_utils for uint {
+impl uint_utils for usize {
     fn str(&self) -> String {
         self.to_string()
     }
-    fn multi<F>(&self, mut f: F) where F: FnMut(uint) {
+    fn multi<F>(&self, mut f: F) where F: FnMut(usize) {
         let mut c = 0_usize;
         while c < *self { f(c); c += 1_usize; }
     }
 }
 
 trait vec_utils<T> {
-    fn length_(&self, ) -> uint;
+    fn length_(&self, ) -> usize;
     fn iter_<F>(&self, f: F) where F: FnMut(&T);
     fn map_<U, F>(&self, f: F) -> Vec<U> where F: FnMut(&T) -> U;
 }
 
 impl<T> vec_utils<T> for Vec<T> {
-    fn length_(&self) -> uint { self.len() }
+    fn length_(&self) -> usize { self.len() }
     fn iter_<F>(&self, mut f: F) where F: FnMut(&T) { for x in self { f(x); } }
     fn map_<U, F>(&self, mut f: F) -> Vec<U> where F: FnMut(&T) -> U {
         let mut r = Vec::new();
@@ -64,7 +66,7 @@ pub fn main() {
     assert_eq!((vec!(1)).length_().str(), "1".to_string());
     let vect = vec!(3, 4).map_(|a| *a + 4);
     assert_eq!(vect[0], 7);
-    let vect = (vec!(3, 4)).map_::<uint, _>(|a| *a as uint + 4_usize);
+    let vect = (vec!(3, 4)).map_::<usize, _>(|a| *a as usize + 4_usize);
     assert_eq!(vect[0], 7_usize);
     let mut x = 0_usize;
     10_usize.multi(|_n| x += 2_usize );
index d1fcc4659b93764a7550ce3617e9b990c24a7aa3..4ccb044bbd2caacd4aa2f52cf41997d59fddb07a 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Deserializer {
-    fn read_int(&self) -> int;
+    fn read_int(&self) -> isize;
 }
 
 trait Deserializable<D:Deserializer> {
     fn deserialize(d: &D) -> Self;
 }
 
-impl<D:Deserializer> Deserializable<D> for int {
-    fn deserialize(d: &D) -> int {
+impl<D:Deserializer> Deserializable<D> for isize {
+    fn deserialize(d: &D) -> isize {
         return d.read_int();
     }
 }
@@ -25,11 +27,11 @@ impl<D:Deserializer> Deserializable<D> for int {
 struct FromThinAir { dummy: () }
 
 impl Deserializer for FromThinAir {
-    fn read_int(&self) -> int { 22 }
+    fn read_int(&self) -> isize { 22 }
 }
 
 pub fn main() {
     let d = FromThinAir { dummy: () };
-    let i: int = Deserializable::deserialize(&d);
+    let i: isize = Deserializable::deserialize(&d);
     assert_eq!(i, 22);
 }
index 076c56bcc4d2af1f7c8f172ffb9deb642cdb0206..d0b69b430a69244557b180317602245208610393 100644 (file)
 
 // aux-build:static-methods-crate.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate static_methods_crate;
 
 use static_methods_crate::read;
 
 pub fn main() {
-    let result: int = read("5".to_string());
+    let result: isize = read("5".to_string());
     assert_eq!(result, 5);
     assert_eq!(read::readMaybe("false".to_string()), Some(false));
     assert_eq!(read::readMaybe("foo".to_string()), None::<bool>);
index 5f6dc4f2a536285ba445671b3e5576d6214dbc87..cb23feb05a59dd09460deb65b3689a8d28dd0ff7 100644 (file)
@@ -8,27 +8,29 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod a {
     pub trait Foo {
         fn foo() -> Self;
     }
 
-    impl Foo for int {
-        fn foo() -> int {
+    impl Foo for isize {
+        fn foo() -> isize {
             3
         }
     }
 
-    impl Foo for uint {
-        fn foo() -> uint {
-            5_usize
+    impl Foo for usize {
+        fn foo() -> usize {
+            5
         }
     }
 }
 
 pub fn main() {
-    let x: int = a::Foo::foo();
-    let y: uint = a::Foo::foo();
+    let x: isize = a::Foo::foo();
+    let y: usize = a::Foo::foo();
     assert_eq!(x, 3);
     assert_eq!(y, 5);
 }
index d0448de2c49705302b0f80dc1e317a0e39a46903..cd8406983fbb34c97bca3d02f30d7e5ecf3a03f5 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub trait Number: NumConv {
     fn from<T:Number>(n: T) -> Self;
 }
index e5d4591361a6351d257f4bcbeb633e434ce96f57..c6b919c9738d4e3e37c913225c6cbb8d5a58d0cc 100644 (file)
 // statics cannot. This ensures that there's some form of error if this is
 // attempted.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc)]
+
 extern crate libc;
 
 #[link(name = "rust_test_helpers")]
index 5aa28ad80fae8a0bda8187f9805fe3c5d1cf8942..0456d17bdc4b4277015f470117af0679acd6b03b 100644 (file)
 
 // aux-build:static_mut_xc.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate static_mut_xc;
 
-unsafe fn static_bound(_: &'static int) {}
+unsafe fn static_bound(_: &'static isize) {}
 
-fn static_bound_set(a: &'static mut int) {
+fn static_bound_set(a: &'static mut isize) {
     *a = 3;
 }
 
@@ -41,5 +43,5 @@ pub fn main() {
 }
 
 pub mod inner {
-    pub static mut a: int = 4;
+    pub static mut a: isize = 4;
 }
diff --git a/src/test/run-pass/std-sync-right-kind-impls.rs b/src/test/run-pass/std-sync-right-kind-impls.rs
new file mode 100644 (file)
index 0000000..058777b
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc, alloc)]
+
+use std::sync;
+
+fn assert_both<T: Sync + Send>() {}
+
+fn main() {
+    assert_both::<sync::StaticMutex>();
+    assert_both::<sync::StaticCondvar>();
+    assert_both::<sync::StaticRwLock>();
+    assert_both::<sync::Mutex<()>>();
+    assert_both::<sync::Condvar>();
+    assert_both::<sync::RwLock<()>>();
+    assert_both::<sync::Semaphore>();
+    assert_both::<sync::Barrier>();
+    assert_both::<sync::Arc<()>>();
+    assert_both::<sync::Weak<()>>();
+    assert_both::<sync::Once>();
+}
index 918715f81e85a58bef879ed3ed624a7f8cdf16a0..0d0d56fcafb0b16ab17850842379e6ef026930c7 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let a: String = "this \
 is a test".to_string();
index 7abe8276a97823b67e314c2b8b304b9fa2d5f294..e0fc1c4ce46a7e791f579d95b313430e1a88ad03 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let x = "\\\\\
     ";
index 359c14ea7b0c0d45ec129a7dff4c3e913a026998..cef7a93aeeddcf89aae499d2536cb4faa8642bd4 100644 (file)
@@ -12,12 +12,12 @@ pub fn main() {
     // Make sure we properly handle repeated self-appends.
     let mut a: String = "A".to_string();
     let mut i = 20;
-    let mut expected_len = 1_usize;
+    let mut expected_len = 1;
     while i > 0 {
         println!("{}", a.len());
         assert_eq!(a.len(), expected_len);
         a = format!("{}{}", a, a);
         i -= 1;
-        expected_len *= 2_usize;
+        expected_len *= 2;
     }
 }
index 9046cafe7579ac7767ebfc97c4e062f2fd40512a..17cb8acea6fadda71cae36233bfc15dd6afbe45c 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // aux-build:xcrate_struct_aliases.rs
+// pretty-expanded FIXME #23616
+
 extern crate xcrate_struct_aliases;
 
 use xcrate_struct_aliases::{S, S2};
@@ -28,4 +30,3 @@ fn main() {
         }
     }
 }
-
index 2cf961a5c0c947caaaa7517ef34df4e23e87c865..79e7960cfb27c9fbb40f2f068ff5cb9d7dc41b50 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct S {
-    x: int,
-    y: int,
+    x: isize,
+    y: isize,
 }
 
 type S2 = S;
@@ -30,4 +32,3 @@ fn main() {
         }
     }
 }
-
index 2de2bcc958471c2566f0106dbb9030486c45a2ae..5fed712bd663a026e3c695d7c4f193fb587dbadf 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:struct_destructuring_cross_crate.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate struct_destructuring_cross_crate;
 
 pub fn main() {
index 364c6da980393263bd5075f6e753371738d61858..a55e5143a0bfba8f003e9ccdc3d34f27ef9e8253 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Foo {
     Bar {
-        a: int,
-        b: int
+        a: isize,
+        b: isize
     },
     Baz {
         c: f64,
index 3afa44a3142b40b8d40fac406b3cd4417f17946f..f072d315d72bf2f0af8bdf9af5bb2d9400adce72 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Foo {
     Bar {
-        x: int,
-        y: int
+        x: isize,
+        y: isize
     },
     Baz {
         x: f64,
index 21eb0ae99b4af9f39cb50ea3a15f7506afd594bc..73f27448f81a48d0206e39106b4f176a62221752 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct Foo {
-    new: int,
+    new: isize,
 }
 
 pub fn main() {
index 6cebd17496a52b07d9aa4d0e389842f5af2caf64..49ec695a1228b133b14284c415e73fddec7c5ffe 100644 (file)
@@ -8,15 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct S { f0: String, f1: int }
+// pretty-expanded FIXME #23616
+
+struct S { f0: String, f1: isize }
 
 pub fn main() {
     let s = "Hello, world!".to_string();
-    let _s = S {
+    let s = S {
         f0: s.to_string(),
         ..S {
             f0: s,
             f1: 23
         }
     };
+    assert_eq!(s.f0, "Hello, world!");
 }
index 786f080bb9ee3c6350fe6244fdbcfdacdd9b1edf..45755608ff56a780bb67ff3606efc3ed39d7688f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 struct S {
     f0: String,
     f1: String,
@@ -15,8 +17,9 @@ struct S {
 
 pub fn main() {
     let s = "Hello, world!".to_string();
-    let _s = S {
+    let s = S {
         f1: s.to_string(),
         f0: s
     };
+    assert_eq!(s.f0, "Hello, world!");
 }
diff --git a/src/test/run-pass/struct-order-of-eval-3.rs b/src/test/run-pass/struct-order-of-eval-3.rs
new file mode 100644 (file)
index 0000000..37b6de8
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright 2015 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.
+
+// Checks that functional-record-update order-of-eval is as expected
+// even when no Drop-implementations are involved.
+
+// pretty-expanded FIXME #23616
+
+use std::sync::atomic::{Ordering, AtomicUsize, ATOMIC_USIZE_INIT};
+
+struct W { wrapped: u32 }
+struct S { f0: W, _f1: i32 }
+
+pub fn main() {
+    const VAL: u32 = 0x89AB_CDEF;
+    let w = W { wrapped: VAL };
+    let s = S {
+        f0: { event(0x01); W { wrapped: w.wrapped + 1 } },
+        ..S {
+            f0: { event(0x02); w},
+            _f1: 23
+        }
+    };
+    assert_eq!(s.f0.wrapped, VAL + 1);
+    let actual = event_log();
+    let expect = 0x01_02;
+    assert!(expect == actual,
+            "expect: 0x{:x} actual: 0x{:x}", expect, actual);
+}
+
+static LOG: AtomicUsize = ATOMIC_USIZE_INIT;
+
+fn event_log() -> usize {
+    LOG.load(Ordering::SeqCst)
+}
+
+fn event(tag: u8) {
+    let old_log = LOG.load(Ordering::SeqCst);
+    let new_log = (old_log << 8) + tag as usize;
+    LOG.store(new_log, Ordering::SeqCst);
+}
diff --git a/src/test/run-pass/struct-order-of-eval-4.rs b/src/test/run-pass/struct-order-of-eval-4.rs
new file mode 100644 (file)
index 0000000..1b53895
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright 2015 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.
+
+// Checks that struct-literal expression order-of-eval is as expected
+// even when no Drop-implementations are involved.
+
+// pretty-expanded FIXME #23616
+
+use std::sync::atomic::{Ordering, AtomicUsize, ATOMIC_USIZE_INIT};
+
+struct W { wrapped: u32 }
+struct S { f0: W, _f1: i32 }
+
+pub fn main() {
+    const VAL: u32 = 0x89AB_CDEF;
+    let w = W { wrapped: VAL };
+    let s = S {
+        _f1: { event(0x01); 23 },
+        f0: { event(0x02); w },
+    };
+    assert_eq!(s.f0.wrapped, VAL);
+    let actual = event_log();
+    let expect = 0x01_02;
+    assert!(expect == actual,
+            "expect: 0x{:x} actual: 0x{:x}", expect, actual);
+}
+
+static LOG: AtomicUsize = ATOMIC_USIZE_INIT;
+
+fn event_log() -> usize {
+    LOG.load(Ordering::SeqCst)
+}
+
+fn event(tag: u8) {
+    let old_log = LOG.load(Ordering::SeqCst);
+    let new_log = (old_log << 8) + tag as usize;
+    LOG.store(new_log, Ordering::SeqCst);
+}
index 8f75b763d9635641b3d1a4b56637f8762878e298..3b04bfc1acca04ba6ff7b0ba0076f3235838df5a 100644 (file)
@@ -12,8 +12,8 @@
 pub struct Partial<T> { x: T, y: T }
 
 #[derive(PartialEq, Debug)]
-struct S { val: int }
-impl S { fn new(v: int) -> S { S { val: v } } }
+struct S { val: isize }
+impl S { fn new(v: isize) -> S { S { val: v } } }
 impl Drop for S { fn drop(&mut self) { } }
 
 pub fn f<T, F>((b1, b2): (T, T), mut f: F) -> Partial<T> where F: FnMut(T) -> T {
index 377e9e6b89afcb0b402dd8662ea1b4e3f94ff0cb..b9c697c71eaaad6924abca02eafbd9573e9627f2 100644 (file)
@@ -12,8 +12,8 @@
 pub struct Partial<T> { x: T, y: T }
 
 #[derive(PartialEq, Debug)]
-struct S { val: int }
-impl S { fn new(v: int) -> S { S { val: v } } }
+struct S { val: isize }
+impl S { fn new(v: isize) -> S { S { val: v } } }
 impl Drop for S { fn drop(&mut self) { } }
 
 pub type Two<T> = (Partial<T>, Partial<T>);
index 6033554d0cbeeef5001f5db809d911ea039a0738..9c3ce54f36914f6c542ac42e3de98714f607986b 100644 (file)
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 struct Foo {
-    x: int,
-    y: int,
+    x: isize,
+    y: isize,
 }
 
 pub fn main() {
index c8768731e2bdb5c19022a99f92bd134cb53d0ffe..1ff13d4eaeacb1c2129beb4835fb40ed722f0dbe 100644 (file)
 //
 // ignore-lexer-test FIXME #15883
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct Floats { a: f64, b: u8, c: f64 }
 
 mod rustrt {
@@ -28,19 +28,19 @@ mod rustrt {
 
 fn test1() {
     unsafe {
-        let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa_u64,
-                 b: 0xbbbb_bbbb_bbbb_bbbb_u64,
-                 c: 0xcccc_cccc_cccc_cccc_u64,
-                 d: 0xdddd_dddd_dddd_dddd_u64 };
+        let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa,
+                 b: 0xbbbb_bbbb_bbbb_bbbb,
+                 c: 0xcccc_cccc_cccc_cccc,
+                 d: 0xdddd_dddd_dddd_dddd };
         let qq = rustrt::rust_dbg_abi_1(q);
-        println!("a: {:x}", qq.a as uint);
-        println!("b: {:x}", qq.b as uint);
-        println!("c: {:x}", qq.c as uint);
-        println!("d: {:x}", qq.d as uint);
-        assert_eq!(qq.a, q.c + 1u64);
-        assert_eq!(qq.b, q.d - 1u64);
-        assert_eq!(qq.c, q.a + 1u64);
-        assert_eq!(qq.d, q.b - 1u64);
+        println!("a: {:x}", qq.a as usize);
+        println!("b: {:x}", qq.b as usize);
+        println!("c: {:x}", qq.c as usize);
+        println!("d: {:x}", qq.d as usize);
+        assert_eq!(qq.a, q.c + 1);
+        assert_eq!(qq.b, q.d - 1);
+        assert_eq!(qq.c, q.a + 1);
+        assert_eq!(qq.d, q.b - 1);
     }
 }
 
@@ -48,14 +48,14 @@ fn test1() {
 fn test2() {
     unsafe {
         let f = Floats { a: 1.234567890e-15_f64,
-                 b: 0b_1010_1010_u8,
+                 b: 0b_1010_1010,
                  c: 1.0987654321e-15_f64 };
         let ff = rustrt::rust_dbg_abi_2(f);
         println!("a: {}", ff.a as f64);
-        println!("b: {}", ff.b as uint);
+        println!("b: {}", ff.b as usize);
         println!("c: {}", ff.c as f64);
         assert_eq!(ff.a, f.c + 1.0f64);
-        assert_eq!(ff.b, 0xff_u8);
+        assert_eq!(ff.b, 0xff);
         assert_eq!(ff.c, f.a - 1.0f64);
     }
 }
index aad3ba01a487e24c21bdac5c354c0cc1045c54af..b6e7846e96d03c96514691c2991376da9c24607d 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod foo {
     pub enum Foo {
-        Bar { a: int }
+        Bar { a: isize }
     }
 }
 
index 923a1427869f53bd1f73e251d33049a519be4860..602650e4e06a3444fe740eb66e59d3fc499dfbf4 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // aux-build:struct_variant_xc_aux.rs
+// pretty-expanded FIXME #23616
+
 extern crate struct_variant_xc_aux;
 
 use struct_variant_xc_aux::Enum::StructVariant;
index 41dcb7ddbc86bc084853500799c585aadb1358ea..f43dd2332a17a1cbd2089b7369fa89f289d420ed 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // aux-build:struct_variant_xc_aux.rs
+// pretty-expanded FIXME #23616
+
 extern crate struct_variant_xc_aux;
 
 use struct_variant_xc_aux::Enum::{StructVariant, Variant};
index 12d8fe8f4c8c3131da6591d6956496e02dcd3562..7974366c395fc922f0c4b2e728322a2e576f7d8d 100644 (file)
 
 
 
-#[derive(Copy, Debug)]
+#[derive(Copy, Clone, Debug)]
 enum foo { large, small, }
 
 impl PartialEq for foo {
     fn eq(&self, other: &foo) -> bool {
-        ((*self) as uint) == ((*other) as uint)
+        ((*self) as usize) == ((*other) as usize)
     }
     fn ne(&self, other: &foo) -> bool { !(*self).eq(other) }
 }
index f00ba36a00450e1c8fa2646b51bb8115e75c413a..69ec0a2222ddbc50e84ba5b22c26e129e97e30dc 100644 (file)
@@ -14,7 +14,7 @@
 //
 // Big stack is needed for pretty printing, a little sad...
 
-static a: int =
+static a: isize =
 (((((((((((((((((((((((((((((((((((((((((((((((((((
 (((((((((((((((((((((((((((((((((((((((((((((((((((
 (((((((((((((((((((((((((((((((((((((((((((((((((((
index 95aeff425e8a90c6fe090d822f3e894b1c6e1b14..51520c77751b0678b56bfa09b47f212b86a9722a 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub mod a {
     pub fn f() {}
     pub mod b {
index e158ae672aa5e038f07bebcbfab4723fd0b8f82c..351c4259b5ef3bc2df3a9671cd710f57d550c673 100644 (file)
@@ -10,6 +10,8 @@
 
 // There is some other borrowck bug, so we make the stuff not mut.
 
+// pretty-expanded FIXME #23616
+
 use std::ops::Add;
 
 trait Positioned<S> {
index 3fffef060a1b4514841ddc1261bfb4432765e6ce..811b9dce4bc32889d2234fa4aba2ed6e97dee3ca 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(libc)]
+
 extern crate libc;
 
 pub fn main() {
   let f = 1_usize as *const libc::FILE;
-  println!("{:?}", f as int);
-  println!("{:?}", f as uint);
+  println!("{:?}", f as isize);
+  println!("{:?}", f as usize);
   println!("{:?}", f as i8);
   println!("{:?}", f as i16);
   println!("{:?}", f as i32);
@@ -23,8 +25,8 @@ pub fn main() {
   println!("{:?}", f as u32);
   println!("{:?}", f as u64);
 
-  println!("{:?}", 1 as int);
-  println!("{:?}", 1 as uint);
+  println!("{:?}", 1 as isize);
+  println!("{:?}", 1 as usize);
   println!("{:?}", 1 as *const libc::FILE);
   println!("{:?}", 1 as i8);
   println!("{:?}", 1 as i16);
@@ -37,8 +39,8 @@ pub fn main() {
   println!("{:?}", 1 as f32);
   println!("{:?}", 1 as f64);
 
-  println!("{:?}", 1_usize as int);
-  println!("{:?}", 1_usize as uint);
+  println!("{:?}", 1_usize as isize);
+  println!("{:?}", 1_usize as usize);
   println!("{:?}", 1_usize as *const libc::FILE);
   println!("{:?}", 1_usize as i8);
   println!("{:?}", 1_usize as i16);
@@ -51,8 +53,8 @@ pub fn main() {
   println!("{:?}", 1_usize as f32);
   println!("{:?}", 1_usize as f64);
 
-  println!("{:?}", 1i8 as int);
-  println!("{:?}", 1i8 as uint);
+  println!("{:?}", 1i8 as isize);
+  println!("{:?}", 1i8 as usize);
   println!("{:?}", 1i8 as *const libc::FILE);
   println!("{:?}", 1i8 as i8);
   println!("{:?}", 1i8 as i16);
@@ -65,8 +67,8 @@ pub fn main() {
   println!("{:?}", 1i8 as f32);
   println!("{:?}", 1i8 as f64);
 
-  println!("{:?}", 1u8 as int);
-  println!("{:?}", 1u8 as uint);
+  println!("{:?}", 1u8 as isize);
+  println!("{:?}", 1u8 as usize);
   println!("{:?}", 1u8 as *const libc::FILE);
   println!("{:?}", 1u8 as i8);
   println!("{:?}", 1u8 as i16);
@@ -79,8 +81,8 @@ pub fn main() {
   println!("{:?}", 1u8 as f32);
   println!("{:?}", 1u8 as f64);
 
-  println!("{:?}", 1i16 as int);
-  println!("{:?}", 1i16 as uint);
+  println!("{:?}", 1i16 as isize);
+  println!("{:?}", 1i16 as usize);
   println!("{:?}", 1i16 as *const libc::FILE);
   println!("{:?}", 1i16 as i8);
   println!("{:?}", 1i16 as i16);
@@ -93,8 +95,8 @@ pub fn main() {
   println!("{:?}", 1i16 as f32);
   println!("{:?}", 1i16 as f64);
 
-  println!("{:?}", 1u16 as int);
-  println!("{:?}", 1u16 as uint);
+  println!("{:?}", 1u16 as isize);
+  println!("{:?}", 1u16 as usize);
   println!("{:?}", 1u16 as *const libc::FILE);
   println!("{:?}", 1u16 as i8);
   println!("{:?}", 1u16 as i16);
@@ -107,8 +109,8 @@ pub fn main() {
   println!("{:?}", 1u16 as f32);
   println!("{:?}", 1u16 as f64);
 
-  println!("{:?}", 1i32 as int);
-  println!("{:?}", 1i32 as uint);
+  println!("{:?}", 1i32 as isize);
+  println!("{:?}", 1i32 as usize);
   println!("{:?}", 1i32 as *const libc::FILE);
   println!("{:?}", 1i32 as i8);
   println!("{:?}", 1i32 as i16);
@@ -121,8 +123,8 @@ pub fn main() {
   println!("{:?}", 1i32 as f32);
   println!("{:?}", 1i32 as f64);
 
-  println!("{:?}", 1u32 as int);
-  println!("{:?}", 1u32 as uint);
+  println!("{:?}", 1u32 as isize);
+  println!("{:?}", 1u32 as usize);
   println!("{:?}", 1u32 as *const libc::FILE);
   println!("{:?}", 1u32 as i8);
   println!("{:?}", 1u32 as i16);
@@ -135,8 +137,8 @@ pub fn main() {
   println!("{:?}", 1u32 as f32);
   println!("{:?}", 1u32 as f64);
 
-  println!("{:?}", 1i64 as int);
-  println!("{:?}", 1i64 as uint);
+  println!("{:?}", 1i64 as isize);
+  println!("{:?}", 1i64 as usize);
   println!("{:?}", 1i64 as *const libc::FILE);
   println!("{:?}", 1i64 as i8);
   println!("{:?}", 1i64 as i16);
@@ -149,8 +151,8 @@ pub fn main() {
   println!("{:?}", 1i64 as f32);
   println!("{:?}", 1i64 as f64);
 
-  println!("{:?}", 1u64 as int);
-  println!("{:?}", 1u64 as uint);
+  println!("{:?}", 1u64 as isize);
+  println!("{:?}", 1u64 as usize);
   println!("{:?}", 1u64 as *const libc::FILE);
   println!("{:?}", 1u64 as i8);
   println!("{:?}", 1u64 as i16);
@@ -163,8 +165,8 @@ pub fn main() {
   println!("{:?}", 1u64 as f32);
   println!("{:?}", 1u64 as f64);
 
-  println!("{:?}", 1u64 as int);
-  println!("{:?}", 1u64 as uint);
+  println!("{:?}", 1u64 as isize);
+  println!("{:?}", 1u64 as usize);
   println!("{:?}", 1u64 as *const libc::FILE);
   println!("{:?}", 1u64 as i8);
   println!("{:?}", 1u64 as i16);
@@ -177,8 +179,8 @@ pub fn main() {
   println!("{:?}", 1u64 as f32);
   println!("{:?}", 1u64 as f64);
 
-  println!("{:?}", true as int);
-  println!("{:?}", true as uint);
+  println!("{:?}", true as isize);
+  println!("{:?}", true as usize);
   println!("{:?}", true as *const libc::FILE);
   println!("{:?}", true as i8);
   println!("{:?}", true as i16);
@@ -191,8 +193,8 @@ pub fn main() {
   println!("{:?}", true as f32);
   println!("{:?}", true as f64);
 
-  println!("{:?}", 1f32 as int);
-  println!("{:?}", 1f32 as uint);
+  println!("{:?}", 1f32 as isize);
+  println!("{:?}", 1f32 as usize);
   println!("{:?}", 1f32 as i8);
   println!("{:?}", 1f32 as i16);
   println!("{:?}", 1f32 as i32);
@@ -204,8 +206,8 @@ pub fn main() {
   println!("{:?}", 1f32 as f32);
   println!("{:?}", 1f32 as f64);
 
-  println!("{:?}", 1f64 as int);
-  println!("{:?}", 1f64 as uint);
+  println!("{:?}", 1f64 as isize);
+  println!("{:?}", 1f64 as usize);
   println!("{:?}", 1f64 as i8);
   println!("{:?}", 1f64 as i16);
   println!("{:?}", 1f64 as i32);
index 235c4e74d085740f5fa9408b65ce2097c245af55..4d7b61e08f51922f47cb6a3a0ccf90afc1781359 100644 (file)
@@ -13,6 +13,8 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-comment.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate a;
 extern crate b;
 
index 365960b96e4e956a2de4b7cabf09baa7b6f50b10..ea07ebe364661a01fad995170177a26aed84aad8 100644 (file)
@@ -13,6 +13,8 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-doc.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate a;
 extern crate b;
 
index a0dbc96cdb02abe7eddcc721f9016a439d381c00..4e0192c40c230af5858937426a264beaa32db283 100644 (file)
@@ -13,6 +13,8 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-macro.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate a;
 extern crate b;
 
index 98b7663c58ebb1f9e3e0d239cdda759036511d38..9aa56ed2a769da1f00a0f49345e84acd0293de7d 100644 (file)
@@ -13,6 +13,8 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-no-change.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate a;
 extern crate b;
 
index 650f76d729a54a676fe64c6748ca566d110445a0..2da3004aaf1e527a108a62fc3885a3e83b555cee 100644 (file)
@@ -13,6 +13,8 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-redundant-cfg.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate a;
 extern crate b;
 
index 6612c93e90bc536e8b41ecb8c13a2fde180fff9f..bfc676bde263adaf28c533e10a4b04307cfd4b74 100644 (file)
@@ -13,6 +13,8 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-whitespace.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate a;
 extern crate b;
 
index 82a76512e08f7d5d1895f57f2067479e664f8ddf..e60c672f00f9b7d6027dc5db70c034a487690286 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem::swap;
 
 pub fn main() {
index 1dbd29a781effb127c488a3769c1a88a39dfbc5b..3891376e463c7308394020942f99b5703690bec4 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem::swap;
 
 pub fn main() {
-    let mut a: Vec<int> = vec!(0, 1, 2, 3, 4, 5, 6);
+    let mut a: Vec<isize> = vec!(0, 1, 2, 3, 4, 5, 6);
     a.swap(2, 4);
     assert_eq!(a[2], 4);
     assert_eq!(a[4], 2);
index b25b350aa4b72320ae95ae8a75be596b0cbf4056..2e5386d6866edefa56136210f1648fd0651dce22 100644 (file)
@@ -10,6 +10,8 @@
 
 // Issue #5041 - avoid overlapping memcpy when src and dest of a swap are the same
 
+// pretty-expanded FIXME #23616
+
 use std::ptr;
 
 pub fn main() {
@@ -34,8 +36,8 @@ pub enum TestName {
 }
 
 pub enum TestFn {
-    DynTestFn(int),
-    DynBenchFn(int),
+    DynTestFn(isize),
+    DynBenchFn(isize),
 }
 
 pub struct TestDesc {
diff --git a/src/test/run-pass/sync-send-iterators-in-libcollections.rs b/src/test/run-pass/sync-send-iterators-in-libcollections.rs
new file mode 100644 (file)
index 0000000..447b4de
--- /dev/null
@@ -0,0 +1,100 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+#![allow(unused_mut)]
+#![feature(collections)]
+
+extern crate collections;
+
+use collections::BinaryHeap;
+use collections::{BitSet, BitVec};
+use collections::{BTreeMap, BTreeSet};
+use collections::EnumSet;
+use collections::LinkedList;
+use collections::Vec;
+use collections::VecDeque;
+use collections::VecMap;
+
+use collections::Bound::Included;
+use collections::enum_set::CLike;
+use std::mem;
+
+fn is_sync<T>(_: T) where T: Sync {}
+fn is_send<T>(_: T) where T: Send {}
+
+macro_rules! all_sync_send {
+    ($ctor:expr, $($iter:ident),+) => ({
+        $(
+            let mut x = $ctor;
+            is_sync(x.$iter());
+            let mut y = $ctor;
+            is_send(y.$iter());
+        )+
+    })
+}
+
+macro_rules! is_sync_send {
+    ($ctor:expr, $iter:ident($($param:expr),+)) => ({
+        let mut x = $ctor;
+        is_sync(x.$iter($( $param ),+));
+        let mut y = $ctor;
+        is_send(y.$iter($( $param ),+));
+    })
+}
+
+fn main() {
+    // The iterator "generator" list should exhaust what corresponding
+    // implementations have where `Sync` and `Send` semantics apply.
+    all_sync_send!(BinaryHeap::<usize>::new(), iter, drain, into_iter);
+
+    all_sync_send!(BitVec::new(), iter);
+
+    all_sync_send!(BitSet::new(), iter);
+    is_sync_send!(BitSet::new(), union(&BitSet::new()));
+    is_sync_send!(BitSet::new(), intersection(&BitSet::new()));
+    is_sync_send!(BitSet::new(), difference(&BitSet::new()));
+    is_sync_send!(BitSet::new(), symmetric_difference(&BitSet::new()));
+
+    all_sync_send!(BTreeMap::<usize, usize>::new(), iter, iter_mut, into_iter, keys, values);
+    is_sync_send!(BTreeMap::<usize, usize>::new(), range(Included(&0), Included(&9)));
+    is_sync_send!(BTreeMap::<usize, usize>::new(), range_mut(Included(&0), Included(&9)));
+
+    all_sync_send!(BTreeSet::<usize>::new(), iter, into_iter);
+    is_sync_send!(BTreeSet::<usize>::new(), range(Included(&0), Included(&9)));
+    is_sync_send!(BTreeSet::<usize>::new(), difference(&BTreeSet::<usize>::new()));
+    is_sync_send!(BTreeSet::<usize>::new(), symmetric_difference(&BTreeSet::<usize>::new()));
+    is_sync_send!(BTreeSet::<usize>::new(), intersection(&BTreeSet::<usize>::new()));
+    is_sync_send!(BTreeSet::<usize>::new(), union(&BTreeSet::<usize>::new()));
+
+    all_sync_send!(LinkedList::<usize>::new(), iter, iter_mut, into_iter);
+
+    #[derive(Copy, Clone)]
+    #[repr(usize)]
+    #[allow(dead_code)]
+    enum Foo { A, B, C }
+    impl CLike for Foo {
+        fn to_usize(&self) -> usize {
+            *self as usize
+        }
+
+        fn from_usize(v: usize) -> Foo {
+            unsafe { mem::transmute(v) }
+        }
+    }
+    all_sync_send!(EnumSet::<Foo>::new(), iter);
+
+    all_sync_send!(VecDeque::<usize>::new(), iter, iter_mut, drain, into_iter);
+
+    all_sync_send!(VecMap::<usize>::new(), iter, iter_mut, drain, into_iter, keys, values);
+
+    all_sync_send!(Vec::<usize>::new(), into_iter, drain);
+}
index 8c888ff03624f701aed29c3f1c38bc38b2cfbe49..8766cba5dbb450e11803969d383fdaad140cfde1 100644 (file)
@@ -10,6 +10,8 @@
 
 // compile-flags: --cfg foo --cfg qux="foo"
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     // check
     if ! cfg!(foo) { panic!() }
index dea7f99fcbace35c6da7c123fb882f683c0583db..61d6d3fdd3b717dd08c9753588096038b02033ca 100644 (file)
@@ -2,6 +2,6 @@
 
 {
     assert!(file!().ends_with("includeme.fragment"));
-    assert!(line!() == 5_usize);
+    assert!(line!() == 5u32);
     format!("victory robot {}", line!())
 }
index 349a676a433e366eceb45021cb10186a2f22453a..8834fd39d1d8845f135e14abf1bd9f56d1587e17 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(core)]
+
 // This test is brittle!
 // ignore-pretty - the pretty tests lose path information, breaking include!
 
@@ -22,9 +24,9 @@ pub mod m1 {
 macro_rules! indirect_line { () => ( line!() ) }
 
 pub fn main() {
-    assert_eq!(line!(), 25);
-    //assert!((column!() == 11));
-    assert_eq!(indirect_line!(), 27);
+    assert_eq!(line!(), 27);
+    assert!((column!() == 4));
+    assert_eq!(indirect_line!(), 29);
     assert!((file!().ends_with("syntax-extension-source-utils.rs")));
     assert_eq!(stringify!((2*3) + 5).to_string(), "( 2 * 3 ) + 5".to_string());
     assert!(include!("syntax-extension-source-utils-files/includeme.\
@@ -34,7 +36,6 @@ pub fn main() {
     assert!(
         include_str!("syntax-extension-source-utils-files/includeme.\
                       fragment").to_string()
-        .as_slice()
         .starts_with("/* this is for "));
     assert!(
         include_bytes!("syntax-extension-source-utils-files/includeme.fragment")
@@ -42,8 +43,5 @@ pub fn main() {
     // The Windows tests are wrapped in an extra module for some reason
     assert!((m1::m2::where_am_i().ends_with("m1::m2")));
 
-    assert!(match (45, "( 2 * 3 ) + 5") {
-        (line!(), stringify!((2*3) + 5)) => true,
-        _ => false
-    })
+    assert_eq!((46, "( 2 * 3 ) + 5"), (line!(), stringify!((2*3) + 5)));
 }
index 340ad2a531a738188d19b7596dd5e99f859c81da..ba8a3f77aacefe0b65d679f6403fe70de64372db 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(optin_builtin_traits)]
+// pretty-expanded FIXME #23616
+
+#![feature(optin_builtin_traits, core)]
 
 use std::marker::{MarkerTrait, Send};
 
index b7fe4983b01b4289ac535efae9ada0e8f4499516..a9f5875023f18217ba1797afae1ca7bf69244fbe 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-linux #7340 fails on 32-bit Linux
-// ignore-macos #7340 fails on 32-bit macos
+// pretty-expanded FIXME #23616
 
 use std::mem;
 
@@ -23,15 +22,16 @@ struct Rec {
 }
 
 fn mk_rec() -> Rec {
-    return Rec { c8:0u8, t:Tag::Tag2(0u64) };
+    return Rec { c8:0, t:Tag::Tag2(0) };
 }
 
-fn is_8_byte_aligned(u: &Tag<u64>) -> bool {
-    let p: uint = unsafe { mem::transmute(u) };
-    return (p & 7_usize) == 0_usize;
+fn is_u64_aligned(u: &Tag<u64>) -> bool {
+    let p: usize = unsafe { mem::transmute(u) };
+    let u64_align = std::mem::min_align_of::<u64>();
+    return (p & (u64_align - 1)) == 0;
 }
 
 pub fn main() {
     let x = mk_rec();
-    assert!(is_8_byte_aligned(&x.t));
+    assert!(is_u64_aligned(&x.t));
 }
index cb298e720ed825211244db994021c6331b6ff72a..90b583e2e5072963041a7320eff4187f40750348 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-linux #7340 fails on 32-bit Linux
-// ignore-macos #7340 fails on 32-bit macos
+// pretty-expanded FIXME #23616
 
 use std::mem;
 
@@ -26,15 +25,15 @@ struct Rec<A,B> {
 }
 
 fn mk_rec<A,B>(a: A, b: B) -> Rec<A,B> {
-    Rec { chA:0u8, tA:Tag::VarA(a), chB:1u8, tB:Tag::VarB(b) }
+    Rec { chA:0, tA:Tag::VarA(a), chB:1, tB:Tag::VarB(b) }
 }
 
-fn is_aligned<A>(amnt: uint, u: &A) -> bool {
-    let p: uint = unsafe { mem::transmute(u) };
-    return (p & (amnt-1_usize)) == 0_usize;
+fn is_aligned<A>(amnt: usize, u: &A) -> bool {
+    let p: usize = unsafe { mem::transmute(u) };
+    return (p & (amnt-1)) == 0;
 }
 
-fn variant_data_is_aligned<A,B>(amnt: uint, u: &Tag<A,B>) -> bool {
+fn variant_data_is_aligned<A,B>(amnt: usize, u: &Tag<A,B>) -> bool {
     match u {
       &Tag::VarA(ref a) => is_aligned(amnt, a),
       &Tag::VarB(ref b) => is_aligned(amnt, b)
@@ -42,33 +41,34 @@ fn variant_data_is_aligned<A,B>(amnt: uint, u: &Tag<A,B>) -> bool {
 }
 
 pub fn main() {
+    let u64_align = std::mem::min_align_of::<u64>();
     let x = mk_rec(22u64, 23u64);
-    assert!(is_aligned(8_usize, &x.tA));
-    assert!(variant_data_is_aligned(8_usize, &x.tA));
-    assert!(is_aligned(8_usize, &x.tB));
-    assert!(variant_data_is_aligned(8_usize, &x.tB));
+    assert!(is_aligned(u64_align, &x.tA));
+    assert!(variant_data_is_aligned(u64_align, &x.tA));
+    assert!(is_aligned(u64_align, &x.tB));
+    assert!(variant_data_is_aligned(u64_align, &x.tB));
 
     let x = mk_rec(22u64, 23u32);
-    assert!(is_aligned(8_usize, &x.tA));
-    assert!(variant_data_is_aligned(8_usize, &x.tA));
-    assert!(is_aligned(8_usize, &x.tB));
-    assert!(variant_data_is_aligned(4_usize, &x.tB));
+    assert!(is_aligned(u64_align, &x.tA));
+    assert!(variant_data_is_aligned(u64_align, &x.tA));
+    assert!(is_aligned(u64_align, &x.tB));
+    assert!(variant_data_is_aligned(4, &x.tB));
 
     let x = mk_rec(22u32, 23u64);
-    assert!(is_aligned(8_usize, &x.tA));
-    assert!(variant_data_is_aligned(4_usize, &x.tA));
-    assert!(is_aligned(8_usize, &x.tB));
-    assert!(variant_data_is_aligned(8_usize, &x.tB));
+    assert!(is_aligned(u64_align, &x.tA));
+    assert!(variant_data_is_aligned(4, &x.tA));
+    assert!(is_aligned(u64_align, &x.tB));
+    assert!(variant_data_is_aligned(u64_align, &x.tB));
 
     let x = mk_rec(22u32, 23u32);
-    assert!(is_aligned(4_usize, &x.tA));
-    assert!(variant_data_is_aligned(4_usize, &x.tA));
-    assert!(is_aligned(4_usize, &x.tB));
-    assert!(variant_data_is_aligned(4_usize, &x.tB));
+    assert!(is_aligned(4, &x.tA));
+    assert!(variant_data_is_aligned(4, &x.tA));
+    assert!(is_aligned(4, &x.tB));
+    assert!(variant_data_is_aligned(4, &x.tB));
 
     let x = mk_rec(22f64, 23f64);
-    assert!(is_aligned(8_usize, &x.tA));
-    assert!(variant_data_is_aligned(8_usize, &x.tA));
-    assert!(is_aligned(8_usize, &x.tB));
-    assert!(variant_data_is_aligned(8_usize, &x.tB));
+    assert!(is_aligned(u64_align, &x.tA));
+    assert!(variant_data_is_aligned(u64_align, &x.tA));
+    assert!(is_aligned(u64_align, &x.tB));
+    assert!(variant_data_is_aligned(u64_align, &x.tB));
 }
index cc0a75181db96aee22a6432e9ec4b0d632e2836b..5db886c815b2a875039142007894407caf97c881 100644 (file)
@@ -20,7 +20,7 @@ struct t_rec {
 }
 
 pub fn main() {
-    let x = t_rec {c8: 22u8, t: a_tag::a_tag_var(44u64)};
+    let x = t_rec {c8: 22, t: a_tag::a_tag_var(44)};
     let y = format!("{:?}", x);
     println!("y = {:?}", y);
     assert_eq!(y, "t_rec { c8: 22, t: a_tag_var(44) }".to_string());
index 713f55cc10c0ad08497120bab0341ee26503cf54..e922ac3b4668e5915de1dba28719ce8b3540ed34 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-linux #7340 fails on 32-bit Linux
-// ignore-macos #7340 fails on 32-bit macos
+// pretty-expanded FIXME #23616
 
 use std::mem;
 
@@ -23,15 +22,16 @@ struct Rec {
 }
 
 fn mk_rec() -> Rec {
-    return Rec { c8:0u8, t:Tag::TagInner(0u64) };
+    return Rec { c8:0, t:Tag::TagInner(0) };
 }
 
-fn is_8_byte_aligned(u: &Tag) -> bool {
-    let p: uint = unsafe { mem::transmute(u) };
-    return (p & 7_usize) == 0_usize;
+fn is_u64_aligned(u: &Tag) -> bool {
+    let p: usize = unsafe { mem::transmute(u) };
+    let u64_align = std::mem::min_align_of::<u64>();
+    return (p & (u64_align - 1)) == 0;
 }
 
 pub fn main() {
     let x = mk_rec();
-    assert!(is_8_byte_aligned(&x.t));
+    assert!(is_u64_aligned(&x.t));
 }
index 2eff97d31b25d4875a39ce06c9127b2f9b8a51c8..d797fd2e54f4659d8a73968a1f65fea7ca82c45d 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 use alder::*;
 
 mod alder {
index 4cb189ee43ffeeab6d4141791a5ebc592a433284..f1a820c8d816e0afc7014b113b1ccab6886d0fe8 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 fn foo() {
     fn zed(_z: bar) { }
     enum bar { nil, }
index 7e4bd9ab2738c93ba30a0d6cd3353599f0e9e447..d31eacc99769fc2e056d25feb9e787d15beb8134 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum color {
     red = 1,
     blue = 2,
index 915a0b5b7e3b76bb87c3dc2ba76e5aa4d756e527..a063801032e3decc613f8f016e4143780d6f6892 100644 (file)
@@ -7,9 +7,11 @@
 // <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.
+// pretty-expanded FIXME #23616
+
 use color::{red, green, blue, black, white, imaginary, purple, orange};
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 enum color {
     red = 0xff0000,
     green = 0x00ff00,
@@ -23,7 +25,7 @@ enum color {
 
 impl PartialEq for color {
     fn eq(&self, other: &color) -> bool {
-        ((*self) as uint) == ((*other) as uint)
+        ((*self) as usize) == ((*other) as usize)
     }
     fn ne(&self, other: &color) -> bool { !(*self).eq(other) }
 }
@@ -39,9 +41,9 @@ pub fn main() {
     test_color(orange, 4, "orange".to_string());
 }
 
-fn test_color(color: color, val: int, name: String) {
+fn test_color(color: color, val: isize, name: String) {
     //assert!(unsafe::transmute(color) == val);
-    assert_eq!(color as int, val);
+    assert_eq!(color as isize, val);
     assert!(get_color_alt(color) == name);
     assert!(get_color_if(color) == name);
 }
index 45b6871e401bdfe1a78afba03c342ab1e06798da..dbd65ee6bd483b5b974d6a2e2bc37f95e4b0cd30 100644 (file)
@@ -9,7 +9,9 @@
 // except according to those terms.
 
 
-enum colour { red(int, int), green, }
+// pretty-expanded FIXME #23616
+
+enum colour { red(isize, isize), green, }
 
 impl PartialEq for colour {
     fn eq(&self, other: &colour) -> bool {
index a5447606d87c8b29788f6ff85b9aa499f3cebebb..8842e1b85915b767702d4d0c8581275fc0770f5a 100644 (file)
@@ -12,6 +12,8 @@
 
 
 // use of tail calls causes arg slot leaks, issue #160.
+// pretty-expanded FIXME #23616
+
 fn inner(dummy: String, b: bool) { if b { return inner(dummy, false); } }
 
 pub fn main() {
index 6f03f385a83e4a638db87806b3a33355ace5f9ae..b6313905923d6c69f06220ac81cace53489b2a11 100644 (file)
@@ -12,13 +12,13 @@ fn checktrue(rs: bool) -> bool { assert!((rs)); return true; }
 
 pub fn main() { let k = checktrue; evenk(42, k); oddk(45, k); }
 
-fn evenk(n: int, k: fn(bool) -> bool) -> bool {
+fn evenk(n: isize, k: fn(bool) -> bool) -> bool {
     println!("evenk");
     println!("{}", n);
     if n == 0 { return k(true); } else { return oddk(n - 1, k); }
 }
 
-fn oddk(n: int, k: fn(bool) -> bool) -> bool {
+fn oddk(n: isize, k: fn(bool) -> bool) -> bool {
     println!("oddk");
     println!("{}", n);
     if n == 0 { return k(false); } else { return evenk(n - 1, k); }
index fd03d28050326d68a07b3e37fa0f142501f0a285..01fc18af34332edd151870d20d7332d094a9a681 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() { assert!((even(42))); assert!((odd(45))); }
 
-fn even(n: int) -> bool { if n == 0 { return true; } else { return odd(n - 1); } }
+fn even(n: isize) -> bool { if n == 0 { return true; } else { return odd(n - 1); } }
 
-fn odd(n: int) -> bool { if n == 0 { return false; } else { return even(n - 1); } }
+fn odd(n: isize) -> bool { if n == 0 { return false; } else { return even(n - 1); } }
index 78826666f53ffc0407aa796ee2c97cd68158c2ad..786dd2c76123e4a02e7975ccfd26fee519593f79 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+#![feature(std_misc)]
+
+use std::thread;
 use std::sync::mpsc::{channel, Sender};
 
 pub fn main() { test05(); }
 
-fn test05_start(tx : &Sender<int>) {
+fn test05_start(tx : &Sender<isize>) {
     tx.send(10).unwrap();
     println!("sent 10");
     tx.send(20).unwrap();
@@ -24,8 +26,8 @@ fn test05_start(tx : &Sender<int>) {
 
 fn test05() {
     let (tx, rx) = channel();
-    let _t = Thread::spawn(move|| { test05_start(&tx) });
-    let mut value: int = rx.recv().unwrap();
+    let _t = thread::scoped(move|| { test05_start(&tx) });
+    let mut value: isize = rx.recv().unwrap();
     println!("{}", value);
     value = rx.recv().unwrap();
     println!("{}", value);
index 180f6e09ba99bb12b0f341e85dfa5c215912e306..9c3466f162b03f365e1dd824689c590c30cabaea 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+#![feature(std_misc)]
+
+use std::thread;
 
 pub fn main() { test00(); }
 
 fn start() { println!("Started / Finished task."); }
 
 fn test00() {
-    let _ = Thread::scoped(move|| start() ).join();
+    let _ = thread::scoped(move|| start() ).join();
     println!("Completing.");
 }
index 60af3afec2b3d9b77fcb4ec4cf913752e26289f8..f25bb3ff71ae8fe9803c9b58f73e4775460a5404 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+#![feature(std_misc)]
+
+use std::thread;
 use std::sync::mpsc::{channel, Sender};
 
 fn start(tx: &Sender<Sender<String>>) {
@@ -27,10 +29,10 @@ fn start(tx: &Sender<Sender<String>>) {
 
 pub fn main() {
     let (tx, rx) = channel();
-    let _child = Thread::spawn(move|| { start(&tx) });
+    let _child = thread::scoped(move|| { start(&tx) });
 
     let mut c = rx.recv().unwrap();
     c.send("A".to_string()).unwrap();
     c.send("B".to_string()).unwrap();
-    Thread::yield_now();
+    thread::yield_now();
 }
index 1740c49c7720b347636f95cd6c21b74c42b22c72..ec9ed53c1dca0cb21dc6c3b9ddced2b97554c6cf 100644 (file)
@@ -8,17 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc)]
+
 use std::sync::mpsc::{channel, Sender};
-use std::thread::Thread;
+use std::thread;
 
-fn start(tx: &Sender<Sender<int>>) {
+fn start(tx: &Sender<Sender<isize>>) {
     let (tx2, _rx) = channel();
     tx.send(tx2).unwrap();
 }
 
 pub fn main() {
     let (tx, rx) = channel();
-    let _child = Thread::spawn(move|| {
+    let _child = thread::scoped(move|| {
         start(&tx)
     });
     let _tx = rx.recv().unwrap();
index 08dce2a76489b7df79c876e4851ff50835d8e046..03305091a2d074cddcece5ee5185786f1b15e3ef 100644 (file)
@@ -8,22 +8,24 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+#![feature(std_misc)]
+
+use std::thread;
 
 pub fn main() { test00(); }
 
-fn start(_task_number: int) { println!("Started / Finished task."); }
+fn start(_task_number: isize) { println!("Started / Finished task."); }
 
 fn test00() {
-    let i: int = 0;
-    let mut result = Thread::scoped(move|| {
+    let i: isize = 0;
+    let mut result = thread::scoped(move|| {
         start(i)
     });
 
     // Sleep long enough for the task to finish.
     let mut i = 0_usize;
     while i < 10000 {
-        Thread::yield_now();
+        thread::yield_now();
         i += 1;
     }
 
index 429c6ce9fb3711531cf0f1765730d8839b29182c..15ceacd672f8bb8a16a4d91f78762762227367f5 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(std_misc)]
+
 use std::sync::mpsc::{channel, Sender};
-use std::thread::Thread;
+use std::thread;
 
-fn start(tx: &Sender<int>, start: int, number_of_messages: int) {
-    let mut i: int = 0;
+fn start(tx: &Sender<isize>, start: isize, number_of_messages: isize) {
+    let mut i: isize = 0;
     while i< number_of_messages { tx.send(start + i).unwrap(); i += 1; }
 }
 
 pub fn main() {
     println!("Check that we don't deadlock.");
     let (tx, rx) = channel();
-    let _ = Thread::scoped(move|| { start(&tx, 0, 10) }).join();
+    let _t = thread::scoped(move|| { start(&tx, 0, 10) }).join();
     println!("Joined task");
 }
index 0735e3996eec10ec81986948a1157616b598d143..1e2d9fe52df154f1869fc1abc873c1e42737fd48 100644 (file)
@@ -8,18 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(std_misc)]
+
 use std::sync::mpsc::{channel, Sender};
-use std::thread::Thread;
+use std::thread;
 
 pub fn main() {
     let (tx, rx) = channel();
 
-    // Spawn 10 tasks each sending us back one int.
+    // Spawn 10 tasks each sending us back one isize.
     let mut i = 10;
     while (i > 0) {
         println!("{}", i);
         let tx = tx.clone();
-        Thread::spawn({let i = i; move|| { child(i, &tx) }});
+        thread::scoped({let i = i; move|| { child(i, &tx) }});
         i = i - 1;
     }
 
@@ -36,7 +38,7 @@ pub fn main() {
     println!("main thread exiting");
 }
 
-fn child(x: int, tx: &Sender<int>) {
+fn child(x: isize, tx: &Sender<isize>) {
     println!("{}", x);
     tx.send(x).unwrap();
 }
index 28eea784f361cac61a813bbc1aa1f3e50175e0ab..2663595aecfa18570c0130436313f578ee290e65 100644 (file)
@@ -8,10 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc)]
+
 use std::sync::mpsc::{channel, Sender};
-use std::thread::Thread;
+use std::thread;
 
-fn start(tx: &Sender<int>, i0: int) {
+fn start(tx: &Sender<isize>, i0: isize) {
     let mut i = i0;
     while i > 0 {
         tx.send(0).unwrap();
@@ -25,7 +29,7 @@ pub fn main() {
     // the child's point of view the receiver may die. We should
     // drop messages on the floor in this case, and not crash!
     let (tx, rx) = channel();
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         start(&tx, 10)
     });
     rx.recv();
index 1d297c04c825764f6925acfc7574f1093cfc0784..c6d8f3c0d9b0bb490dfb722aba34b6ee67bf5da0 100644 (file)
@@ -13,21 +13,21 @@ use std::cmp;
 
 // Tests of ports and channels on various types
 fn test_rec() {
-    struct R {val0: int, val1: u8, val2: char}
+    struct R {val0: isize, val1: u8, val2: char}
 
     let (tx, rx) = channel();
-    let r0: R = R {val0: 0, val1: 1u8, val2: '2'};
+    let r0: R = R {val0: 0, val1: 1, val2: '2'};
     tx.send(r0).unwrap();
     let mut r1: R;
     r1 = rx.recv().unwrap();
     assert_eq!(r1.val0, 0);
-    assert_eq!(r1.val1, 1u8);
+    assert_eq!(r1.val1, 1);
     assert_eq!(r1.val2, '2');
 }
 
 fn test_vec() {
     let (tx, rx) = channel();
-    let v0: Vec<int> = vec!(0, 1, 2);
+    let v0: Vec<isize> = vec!(0, 1, 2);
     tx.send(v0).unwrap();
     let v1 = rx.recv().unwrap();
     assert_eq!(v1[0], 0);
@@ -49,8 +49,8 @@ fn test_str() {
 #[derive(Debug)]
 enum t {
     tag1,
-    tag2(int),
-    tag3(int, u8, char)
+    tag2(isize),
+    tag3(isize, u8, char)
 }
 
 impl cmp::PartialEq for t {
@@ -84,14 +84,14 @@ fn test_tag() {
     let (tx, rx) = channel();
     tx.send(t::tag1).unwrap();
     tx.send(t::tag2(10)).unwrap();
-    tx.send(t::tag3(10, 11u8, 'A')).unwrap();
+    tx.send(t::tag3(10, 11, 'A')).unwrap();
     let mut t1: t;
     t1 = rx.recv().unwrap();
     assert_eq!(t1, t::tag1);
     t1 = rx.recv().unwrap();
     assert_eq!(t1, t::tag2(10));
     t1 = rx.recv().unwrap();
-    assert_eq!(t1, t::tag3(10, 11u8, 'A'));
+    assert_eq!(t1, t::tag3(10, 11, 'A'));
 }
 
 fn test_chan() {
@@ -102,7 +102,7 @@ fn test_chan() {
     // Does the transmitted channel still work?
 
     tx2.send(10).unwrap();
-    let mut i: int;
+    let mut i: isize;
     i = rx2.recv().unwrap();
     assert_eq!(i, 10);
 }
index 9db5465f7e96e77e03d0dbaa66fdb1490644f28b..de334c77aa310e5b947c83581f14245043648314 100644 (file)
@@ -8,15 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc)]
+
 // Issue #922
 
 // This test is specifically about spawning temporary closures.
 
-use std::thread::Thread;
+use std::thread;
 
 fn f() {
 }
 
 pub fn main() {
-    let _t = Thread::scoped(move|| f() ).join();
+    let _t = thread::scoped(move|| f() ).join();
 }
index 902829468381de01093ec8d74bbe3bfb59451699..254ad653c48132ba6a676270774d9a60c4dea121 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(std_misc)]
+
 // no-pretty-expanded FIXME #15189
 
-use std::thread::Thread;
+use std::thread;
 use std::sync::mpsc::{channel, Sender};
 
 pub fn main() { println!("===== WITHOUT THREADS ====="); test00(); }
 
-fn test00_start(ch: &Sender<int>, message: int, count: int) {
+fn test00_start(ch: &Sender<isize>, message: isize, count: isize) {
     println!("Starting test00_start");
-    let mut i: int = 0;
+    let mut i: isize = 0;
     while i < count {
         println!("Sending Message");
         ch.send(message + 0).unwrap();
@@ -27,20 +29,20 @@ fn test00_start(ch: &Sender<int>, message: int, count: int) {
 }
 
 fn test00() {
-    let number_of_tasks: int = 16;
-    let number_of_messages: int = 4;
+    let number_of_tasks: isize = 16;
+    let number_of_messages: isize = 4;
 
     println!("Creating tasks");
 
     let (tx, rx) = channel();
 
-    let mut i: int = 0;
+    let mut i: isize = 0;
 
     // Create and spawn tasks...
     let mut results = Vec::new();
     while i < number_of_tasks {
         let tx = tx.clone();
-        results.push(Thread::scoped({
+        results.push(thread::scoped({
             let i = i;
             move|| {
                 test00_start(&tx, i, number_of_messages)
index 1f1b750aa5727fd63ad51d39185a840a227df769..e70a00591d6c9be247bdd6a4a9f0eb9b53f7b349 100644 (file)
@@ -15,8 +15,8 @@ use std::sync::mpsc::channel;
 pub fn main() { test00(); }
 
 fn test00() {
-    let mut r: int = 0;
-    let mut sum: int = 0;
+    let mut r: isize = 0;
+    let mut sum: isize = 0;
     let (tx, rx) = channel();
     tx.send(1).unwrap();
     tx.send(2).unwrap();
index 039308d5cfed736c903f87f5ff4bc4248e811bdc..cd3d97b88bade11a7ada0630642b124c77bebe97 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::sync::mpsc::channel;
 
 pub fn main() { test00(); }
 
 fn test00() {
-    let _r: int = 0;
-    let mut sum: int = 0;
+    let _r: isize = 0;
+    let mut sum: isize = 0;
     let (tx, rx) = channel();
-    let number_of_messages: int = 1000;
-    let mut i: int = 0;
+    let number_of_messages: isize = 1000;
+    let mut i: isize = 0;
     while i < number_of_messages { tx.send(i + 0).unwrap(); i += 1; }
     i = 0;
     while i < number_of_messages { sum += rx.recv().unwrap(); i += 1; }
index 7cdfddcdeb113ff4fe3fd2c9ffca3d3aebad30a0..80e777d242cfcc3cb253bc7bf497e42ee84e8866 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 
 use std::sync::mpsc::channel;
@@ -15,15 +17,15 @@ use std::sync::mpsc::channel;
 pub fn main() { test00(); }
 
 fn test00() {
-    let mut r: int = 0;
-    let mut sum: int = 0;
+    let mut r: isize = 0;
+    let mut sum: isize = 0;
     let (tx, rx) = channel();
     let mut tx0 = tx.clone();
     let mut tx1 = tx.clone();
     let mut tx2 = tx.clone();
     let mut tx3 = tx.clone();
-    let number_of_messages: int = 1000;
-    let mut i: int = 0;
+    let number_of_messages: isize = 1000;
+    let mut i: isize = 0;
     while i < number_of_messages {
         tx0.send(i + 0).unwrap();
         tx1.send(i + 0).unwrap();
index 6f3b47b8bfa7a607e870496ce87d9636194a43b6..b05e36552a24c16b849168c61ad775e921829f99 100644 (file)
@@ -8,43 +8,46 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc)]
 #![allow(dead_assignment)]
 
 use std::sync::mpsc::{channel, Sender};
-use std::thread::Thread;
+use std::thread;
 
 pub fn main() { test00(); }
 
-fn test00_start(c: &Sender<int>, start: int,
-                number_of_messages: int) {
-    let mut i: int = 0;
+fn test00_start(c: &Sender<isize>, start: isize,
+                number_of_messages: isize) {
+    let mut i: isize = 0;
     while i < number_of_messages { c.send(start + i).unwrap(); i += 1; }
 }
 
 fn test00() {
-    let mut r: int = 0;
-    let mut sum: int = 0;
+    let mut r: isize = 0;
+    let mut sum: isize = 0;
     let (tx, rx) = channel();
-    let number_of_messages: int = 10;
+    let number_of_messages: isize = 10;
 
     let tx2 = tx.clone();
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         test00_start(&tx2, number_of_messages * 0, number_of_messages);
     });
     let tx2 = tx.clone();
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         test00_start(&tx2, number_of_messages * 1, number_of_messages);
     });
     let tx2 = tx.clone();
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         test00_start(&tx2, number_of_messages * 2, number_of_messages);
     });
     let tx2 = tx.clone();
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         test00_start(&tx2, number_of_messages * 3, number_of_messages);
     });
 
-    let mut i: int = 0;
+    let mut i: isize = 0;
     while i < number_of_messages {
         r = rx.recv().unwrap();
         sum += r;
index 6d8de4a6a53d6c090b2cfa7fae564fe5b1739bec..758764aa9fdcca766ee17564cda123e36303d244 100644 (file)
@@ -8,27 +8,29 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+#![feature(std_misc)]
+
+use std::thread;
 use std::sync::mpsc::{channel, Sender};
 
 pub fn main() { test00(); }
 
-fn test00_start(c: &Sender<int>, number_of_messages: int) {
-    let mut i: int = 0;
+fn test00_start(c: &Sender<isize>, number_of_messages: isize) {
+    let mut i: isize = 0;
     while i < number_of_messages { c.send(i + 0).unwrap(); i += 1; }
 }
 
 fn test00() {
-    let r: int = 0;
-    let mut sum: int = 0;
+    let r: isize = 0;
+    let mut sum: isize = 0;
     let (tx, rx) = channel();
-    let number_of_messages: int = 10;
+    let number_of_messages: isize = 10;
 
-    let result = Thread::scoped(move|| {
+    let result = thread::scoped(move|| {
         test00_start(&tx, number_of_messages);
     });
 
-    let mut i: int = 0;
+    let mut i: isize = 0;
     while i < number_of_messages {
         sum += rx.recv().unwrap();
         println!("{}", r);
index 78a42632001d0dec1208b3c5022724e79982071f..77571504fea274f27100020317538f3a2e5838de 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::sync::mpsc::channel;
 
 // rustboot can't transmit nils across channels because they don't have
index 3f229926480a95ef300ace0bbd599e9eb4d7b339..b97f4355b3ee08bb297b0d2d4f4a458628830b9a 100644 (file)
@@ -8,10 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+// pretty-expanded FIXME #23616
+
+#![feature(std_misc)]
+
+use std::thread;
 
 pub fn main() {
-    let _t = Thread::spawn(move|| child("Hello".to_string()) );
+    let _t = thread::scoped(move|| child("Hello".to_string()) );
 }
 
 fn child(_s: String) {
index ca2a8cf5506eec1486b46550bfa9cacae87d1061..aa7b61bf112f90627cd4516e53d3d63ecd7d200a 100644 (file)
@@ -8,20 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, std_misc)]
 
-use std::thread::Thread;
+use std::thread;
 use std::sync::mpsc::channel;
 
 pub fn main() {
-    let (tx, rx) = channel::<uint>();
+    let (tx, rx) = channel::<usize>();
 
-    let x = box 1;
-    let x_in_parent = &(*x) as *const int as uint;
+    let x: Box<isize> = box 1;
+    let x_in_parent = &(*x) as *const isize as usize;
 
-    let _t = Thread::spawn(move || {
-        let x_in_child = &(*x) as *const int as uint;
+    let _t = thread::scoped(move || {
+        let x_in_child = &(*x) as *const isize as usize;
         tx.send(x_in_child).unwrap();
     });
 
index 1c263b19dd182cb25cba0ada0777b688aaad37df..7bcde7b83cd1b6c7b5012c92d95b0a2c0c6f2e00 100644 (file)
@@ -8,24 +8,35 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, old_io, std_misc, io, set_panic, set_stdio)]
 
-use std::sync::mpsc::channel;
-use std::old_io::{ChanReader, ChanWriter};
+use std::io::prelude::*;
+use std::io;
+use std::str;
+use std::sync::{Arc, Mutex};
 use std::thread;
 
-fn main() {
-    let (tx, rx) = channel();
-    let mut reader = ChanReader::new(rx);
-    let stderr = ChanWriter::new(tx);
+struct Sink(Arc<Mutex<Vec<u8>>>);
+impl Write for Sink {
+    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
+        Write::write(&mut *self.0.lock().unwrap(), data)
+    }
+    fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
 
-    let res = thread::Builder::new().stderr(box stderr as Box<Writer + Send>)
-                                    .spawn(move|| -> () {
+fn main() {
+    let data = Arc::new(Mutex::new(Vec::new()));
+    let sink = Sink(data.clone());
+    let res = thread::Builder::new().spawn(move|| -> () {
+        io::set_panic(Box::new(sink));
         panic!("Hello, world!")
     }).unwrap().join();
     assert!(res.is_err());
 
-    let output = reader.read_to_string().unwrap();
+    let output = data.lock().unwrap();
+    let output = str::from_utf8(&output).unwrap();
     assert!(output.contains("Hello, world!"));
 }
index b87718ba4680c00e83bf2db4db6b53224943a943..00467e563347a32174c7cb5a693448d75a7b68dc 100644 (file)
 //              quite quickly and it takes a few seconds for the sockets to get
 //              recycled.
 
+#![feature(old_io, io, std_misc)]
+
 use std::old_io::{TcpListener, Listener, Acceptor, EndOfFile, TcpStream};
 use std::sync::Arc;
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
 
-static N: uint = 8;
-static M: uint = 20;
+static N: usize = 8;
+static M: usize = 20;
 
 fn main() {
     test();
@@ -38,7 +40,7 @@ fn test() {
         let a = a.clone();
         let cnt = cnt.clone();
         let srv_tx = srv_tx.clone();
-        Thread::scoped(move|| {
+        thread::scoped(move|| {
             let mut a = a;
             loop {
                 match a.accept() {
@@ -57,7 +59,7 @@ fn test() {
 
     let _t = (0..N).map(|_| {
         let cli_tx = cli_tx.clone();
-        Thread::scoped(move|| {
+        thread::scoped(move|| {
             for _ in 0..M {
                 let _s = TcpStream::connect(addr).unwrap();
             }
index d1a3edcfbc52931cb341ed9bf6c2dc0fae0429ec..64f07a60b3503858390cadc58b92687422f0c8d9 100644 (file)
@@ -10,7 +10,7 @@
 
 // ignore-pretty
 // compile-flags:--test
-// exec-env:RUST_TEST_TASKS=1
+// exec-env:RUST_TEST_THREADS=1
 
 // Tests for the connect_timeout() function on a TcpStream. This runs with only
 // one test task to ensure that errors are timeouts, not file descriptor
 #![reexport_test_harness_main = "test_main"]
 
 #![allow(unused_imports)]
+#![feature(old_io, std_misc, io)]
 
 use std::old_io::*;
 use std::old_io::test::*;
 use std::old_io;
 use std::time::Duration;
 use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
 
 #[cfg_attr(target_os = "freebsd", ignore)]
 fn eventual_timeout() {
@@ -33,7 +34,7 @@ fn eventual_timeout() {
 
     let (tx1, rx1) = channel();
     let (_tx2, rx2) = channel::<()>();
-    let _t = Thread::spawn(move|| {
+    let _t = thread::scoped(move|| {
         let _l = TcpListener::bind(addr).unwrap().listen();
         tx1.send(()).unwrap();
         let _ = rx2.recv();
index 82584c83de059da98438d880ca4f08924b182502..4209d5986ba506c8fc3d1a69180273bfa94ca4c5 100644 (file)
 // ignore-openbsd system ulimit (Too many open files)
 // exec-env:RUST_LOG=debug
 
+#![feature(rustc_private, libc, old_io, io, std_misc)]
+#![allow(deprecated, unused_must_use)]
+
 #[macro_use]
 extern crate log;
 extern crate libc;
 
 use std::sync::mpsc::channel;
 use std::old_io::net::tcp::{TcpListener, TcpStream};
-use std::old_io::{Acceptor, Listener};
-use std::thread::{Builder, Thread};
+use std::old_io::{Acceptor, Listener, Reader, Writer};
+use std::thread::{self, Builder};
 use std::time::Duration;
 
 fn main() {
     // This test has a chance to time out, try to not let it time out
-    Thread::spawn(move|| -> () {
+    thread::spawn(move|| -> () {
         use std::old_io::timer;
         timer::sleep(Duration::milliseconds(30 * 1000));
         println!("timed out!");
@@ -33,7 +36,7 @@ fn main() {
     });
 
     let (tx, rx) = channel();
-    Thread::spawn(move || -> () {
+    thread::spawn(move || -> () {
         let mut listener = TcpListener::bind("127.0.0.1:0").unwrap();
         tx.send(listener.socket_name().unwrap()).unwrap();
         let mut acceptor = listener.listen();
@@ -52,7 +55,7 @@ fn main() {
     let addr = rx.recv().unwrap();
 
     let (tx, rx) = channel();
-    for _ in 0_usize..1000 {
+    for _ in 0..1000 {
         let tx = tx.clone();
         Builder::new().stack_size(64 * 1024).spawn(move|| {
             match TcpStream::connect(addr) {
@@ -71,7 +74,7 @@ fn main() {
     // Wait for all clients to exit, but don't wait for the server to exit. The
     // server just runs infinitely.
     drop(tx);
-    for _ in 0_usize..1000 {
+    for _ in 0..1000 {
         rx.recv().unwrap();
     }
     unsafe { libc::exit(0) }
index 053df3a57f329361b33707084f23e329b99dc7b8..49fac24d0b3a5b7e921233856ad3dff79776f99a 100644 (file)
 // they're in a different location than before. Hence, these tests are all run
 // serially here.
 
+#![feature(old_io, old_path, os, old_fs)]
+
+use std::old_path::{Path, GenericPath};
 use std::old_io::fs::PathExtensions;
 use std::old_io::{fs, TempDir};
 use std::old_io;
-use std::os;
+use std::env;
 use std::sync::mpsc::channel;
 use std::thread;
 
@@ -126,7 +129,7 @@ fn test_rm_tempdir_close() {
 // to depend on std
 fn recursive_mkdir_rel() {
     let path = Path::new("frob");
-    let cwd = os::getcwd().unwrap();
+    let cwd = Path::new(env::current_dir().unwrap().to_str().unwrap());
     println!("recursive_mkdir_rel: Making: {} in cwd {} [{}]", path.display(),
            cwd.display(), path.exists());
     fs::mkdir_recursive(&path, old_io::USER_RWX);
@@ -144,7 +147,7 @@ fn recursive_mkdir_dot() {
 
 fn recursive_mkdir_rel_2() {
     let path = Path::new("./frob/baz");
-    let cwd = os::getcwd().unwrap();
+    let cwd = Path::new(env::current_dir().unwrap().to_str().unwrap());
     println!("recursive_mkdir_rel_2: Making: {} in cwd {} [{}]", path.display(),
            cwd.display(), path.exists());
     fs::mkdir_recursive(&path, old_io::USER_RWX);
@@ -193,7 +196,7 @@ pub fn dont_double_panic() {
 
 fn in_tmpdir<F>(f: F) where F: FnOnce() {
     let tmpdir = TempDir::new("test").ok().expect("can't make tmpdir");
-    assert!(os::change_dir(tmpdir.path()).is_ok());
+    assert!(env::set_current_dir(tmpdir.path().as_str().unwrap()).is_ok());
 
     f();
 }
index bef9efa9eb68dc47b99cc01393ab056366732d59..ec9e7de40dce1bdbdf1de74700214ce657deab1c 100644 (file)
 // Issue #787
 // Don't try to clean up uninitialized locals
 
+// pretty-expanded FIXME #23616
+
 use std::thread;
 
-fn test_break() { loop { let _x: Box<int> = break; } }
+fn test_break() { loop { let _x: Box<isize> = break; } }
 
-fn test_cont() { let mut i = 0; while i < 1 { i += 1; let _x: Box<int> = continue; } }
+fn test_cont() { let mut i = 0; while i < 1 { i += 1; let _x: Box<isize> = continue; } }
 
-fn test_ret() { let _x: Box<int> = return; }
+fn test_ret() { let _x: Box<isize> = return; }
 
 fn test_panic() {
-    fn f() { let _x: Box<int> = panic!(); }
+    fn f() { let _x: Box<isize> = panic!(); }
     thread::spawn(move|| f() ).join().err().unwrap();
 }
 
 fn test_panic_indirect() {
     fn f() -> ! { panic!(); }
-    fn g() { let _x: Box<int> = f(); }
+    fn g() { let _x: Box<isize> = f(); }
     thread::spawn(move|| g() ).join().err().unwrap();
 }
 
index 7c99c968e352317a3a313c79c20dd0074909ea76..d58b5d3a00fece428918bcfd2e27a060021b8114 100644 (file)
@@ -8,13 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(test)]
+
 // compile-flags: --test
 // no-pretty-expanded
 extern crate test;
 
 #[bench]
-fn bench_explicit_return_type(_: &mut ::test::Bencher) -> () {}
+pub fn bench_explicit_return_type(_: &mut ::test::Bencher) -> () {}
 
 #[test]
-fn test_explicit_return_type() -> () {}
-
+pub fn test_explicit_return_type() -> () {}
index dcb2fe6dfc07660a78be9646655e93b5df4bf3c8..28698499303a9ad0caf741bcdbd4f557d72d024c 100644 (file)
 // ignore-pretty: does not work well with `--test`
 
 #[test]
-#[should_fail(expected = "foo")]
-fn test_foo() {
+#[should_panic(expected = "foo")]
+pub fn test_foo() {
     panic!("foo bar")
 }
 
 #[test]
-#[should_fail(expected = "foo")]
-fn test_foo_dynamic() {
+#[should_panic(expected = "foo")]
+pub fn test_foo_dynamic() {
     panic!("{} bar", "foo")
 }
-
-
index abc2938df00bb8b19bf3d35b9b57a8f53d3504ec..969a42a6f8715624ad3543688927b7cbcd057e08 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::thread::Thread;
+#![feature(std_misc)]
+
+use std::thread;
 
 pub fn main() {
     let mut i = 10;
     while i > 0 {
-        Thread::scoped({let i = i; move|| child(i)});
+        thread::scoped({let i = i; move|| child(i)});
         i = i - 1;
     }
     println!("main thread exiting");
 }
 
-fn child(x: int) { println!("{}", x); }
+fn child(x: isize) { println!("{}", x); }
index 76c62a83e758c4cdeea93c688da99ac12992f01f..b9eda0846537fc5e0c1190dbe808282a37940074 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(advanced_slice_patterns,)]
+#![feature(slice_patterns)]
 
 fn f<T,>(_: T,) {}
 
@@ -17,24 +20,24 @@ struct Foo<T,>(T);
 struct Bar;
 
 impl Bar {
-    fn f(_: int,) {}
-    fn g(self, _: int,) {}
+    fn f(_: isize,) {}
+    fn g(self, _: isize,) {}
     fn h(self,) {}
 }
 
 enum Baz {
-    Qux(int,),
+    Qux(isize,),
 }
 
 #[allow(unused,)]
 pub fn main() {
-    f::<int,>(0,);
+    f::<isize,>(0,);
     let (_, _,) = (1, 1,);
     let [_, _,] = [1, 1,];
     let [_, _, .., _,] = [1, 1, 1, 1,];
     let [_, _, _.., _,] = [1, 1, 1, 1,];
 
-    let x: Foo<int,> = Foo::<int,>(1);
+    let x: Foo<isize,> = Foo::<isize,>(1);
 
     Bar::f(0,);
     Bar.g(0,);
index ed25bf8b02e88fd6852338287eab01bc53640638..50c9c43ba2b8ba892fb5d9348e02811cc9ee4af9 100644 (file)
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
 
 trait Foo : ::std::marker::MarkerTrait {
 }
index 5b744a4413271c6c2bcbc29c399fdf00899fc65d..33bfbc396035c55b6a72ea7800667c223fd74796 100644 (file)
 // trait exactly, as long as the implementation doesn't demand *more* bounds
 // than the trait.
 
+// pretty-expanded FIXME #23616
+
 trait A {
     fn foo<T: Eq + Ord>(&self);
 }
 
-impl A for int {
+impl A for isize {
     fn foo<T: Ord>(&self) {} // Ord implies Eq, so this is ok.
 }
 
 fn main() {}
-
-
index 26772a5b22c076c140adb0244b7ff98a1e7e28d2..02ea7037056051a5e2d1a1f79049f327c142f388 100644 (file)
 // ignore-pretty
 
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, std_misc)]
 #![feature(unboxed_closures)]
 
 use std::sync::Arc;
 use std::sync::mpsc::channel;
-use std::thread::Thread;
+use std::thread;
 
 trait Pet {
     fn name(&self, blk: Box<FnMut(&str)>);
-    fn num_legs(&self) -> uint;
+    fn num_legs(&self) -> usize;
     fn of_good_pedigree(&self) -> bool;
 }
 
 struct Catte {
-    num_whiskers: uint,
+    num_whiskers: usize,
     name: String,
 }
 
 struct Dogge {
-    bark_decibels: uint,
-    tricks_known: uint,
+    bark_decibels: usize,
+    tricks_known: usize,
     name: String,
 }
 
 struct Goldfyshe {
-    swim_speed: uint,
+    swim_speed: usize,
     name: String,
 }
 
 impl Pet for Catte {
     fn name(&self, mut blk: Box<FnMut(&str)>) { blk(&self.name) }
-    fn num_legs(&self) -> uint { 4 }
+    fn num_legs(&self) -> usize { 4 }
     fn of_good_pedigree(&self) -> bool { self.num_whiskers >= 4 }
 }
 impl Pet for Dogge {
     fn name(&self, mut blk: Box<FnMut(&str)>) { blk(&self.name) }
-    fn num_legs(&self) -> uint { 4 }
+    fn num_legs(&self) -> usize { 4 }
     fn of_good_pedigree(&self) -> bool {
         self.bark_decibels < 70 || self.tricks_known > 20
     }
 }
 impl Pet for Goldfyshe {
     fn name(&self, mut blk: Box<FnMut(&str)>) { blk(&self.name) }
-    fn num_legs(&self) -> uint { 0 }
+    fn num_legs(&self) -> usize { 0 }
     fn of_good_pedigree(&self) -> bool { self.swim_speed >= 500 }
 }
 
@@ -83,13 +83,13 @@ pub fn main() {
                             box dogge2 as Box<Pet+Sync+Send>));
     let (tx1, rx1) = channel();
     let arc1 = arc.clone();
-    let _t1 = Thread::spawn(move|| { check_legs(arc1); tx1.send(()); });
+    let _t1 = thread::scoped(move|| { check_legs(arc1); tx1.send(()); });
     let (tx2, rx2) = channel();
     let arc2 = arc.clone();
-    let _t2 = Thread::spawn(move|| { check_names(arc2); tx2.send(()); });
+    let _t2 = thread::scoped(move|| { check_names(arc2); tx2.send(()); });
     let (tx3, rx3) = channel();
     let arc3 = arc.clone();
-    let _t3 = Thread::spawn(move|| { check_pedigree(arc3); tx3.send(()); });
+    let _t3 = thread::scoped(move|| { check_pedigree(arc3); tx3.send(()); });
     rx1.recv();
     rx2.recv();
     rx3.recv();
@@ -104,9 +104,10 @@ fn check_legs(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
 }
 fn check_names(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
     for pet in &*arc {
-        pet.name(box |name| {
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        pet.name(Box::new(|name| {
             assert!(name.as_bytes()[0] == 'a' as u8 && name.as_bytes()[1] == 'l' as u8);
-        })
+        }))
     }
 }
 fn check_pedigree(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
index 976120908b27ab376ebbee497f13573a3b07bca0..60c1816b1632c2df873681e958595f964f9f23ff 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 trait U : ::std::marker::MarkerTrait {}
 trait T<X: U> { fn get(self) -> X; }
 
index 7135dad7d190c9d96950581753986c946157c04b..250390f70b448b29d9f8cecca1fbe4a002f9540f 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 trait I { fn i(&self) -> Self; }
 
 trait A<T:I> : ::std::marker::MarkerTrait {
index 7ec6ffbd46458f13dcdc05bb3928ba98bd21aeae..642119df15cbf20f39e90e3db5263cb07dc7753d 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait connection {
-    fn read(&self) -> int;
+    fn read(&self) -> isize;
 }
 
 trait connection_factory<C:connection> {
@@ -20,7 +22,7 @@ type my_connection = ();
 type my_connection_factory = ();
 
 impl connection for () {
-    fn read(&self) -> int { 43 }
+    fn read(&self) -> isize { 43 }
 }
 
 impl connection_factory<my_connection> for my_connection_factory {
index a5efb32079de854d3514c79f327c479de99dd1e0..9cc2b2fadc60713b39d8e7a5c17346893cb467a9 100644 (file)
@@ -13,6 +13,8 @@
 //
 // See issue #18209.
 
+// pretty-expanded FIXME #23616
+
 pub trait Foo {
     fn load_from() -> Box<Self>;
     fn load() -> Box<Self> {
index fa02dabb373b198690cd228533e818a2ead112d3..f9a22d5ccec6d07a867ae5a24c27e5492f31a8e2 100644 (file)
@@ -8,17 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
 trait Trait<T> {
     fn f(&self, x: T);
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Struct {
-    x: int,
-    y: int,
+    x: isize,
+    y: isize,
 }
 
 impl Trait<&'static str> for Struct {
@@ -29,9 +26,9 @@ impl Trait<&'static str> for Struct {
 
 pub fn main() {
     let a = Struct { x: 1, y: 2 };
-    let b: Box<Trait<&'static str>> = box a;
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let b: Box<Trait<&'static str>> = Box::new(a);
     b.f("Mary");
     let c: &Trait<&'static str> = &a;
     c.f("Joe");
 }
-
index 1ae9b3f0e959bb25d1a446075a37175532af6abe..fa31d9891aaf7c9a1b14e9e2377ba69a6e94b3aa 100644 (file)
@@ -9,18 +9,18 @@
 // except according to those terms.
 
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, old_io, io)]
 
-use std::old_io;
+use std::io::{self, Write};
 
 trait Trait {
     fn f(&self);
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Struct {
-    x: int,
-    y: int,
+    x: isize,
+    y: isize,
 }
 
 impl Trait for Struct {
@@ -29,18 +29,17 @@ impl Trait for Struct {
     }
 }
 
-fn foo(mut a: Box<Writer>) {
-    a.write(b"Hello\n");
-}
+fn foo(mut a: Box<Write>) {}
+
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
 
 pub fn main() {
     let a = Struct { x: 1, y: 2 };
-    let b: Box<Trait> = box a;
+    let b: Box<Trait> = Box::new(a);
     b.f();
     let c: &Trait = &a;
     c.f();
 
-    let out = old_io::stdout();
-    foo(box out);
+    let out = io::stdout();
+    foo(Box::new(out));
 }
-
index de130bf1b41fe05116086754be6ac58f4e8b8533..4138413c5b552809d857fde6f91707e82c96ab94 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
     fn foo(&self);
 }
index 19d76b889011837999e5d62ba05581d04b331084..17c68d64948ed2da3eb77f330fa6f8d67a226bcb 100644 (file)
@@ -38,5 +38,3 @@ fn main() {
     let x: Box<Foo+Send> = (box SFoo);
     wants_bar(&x);
 }
-
-
index 5f0e149eb288d854f5c84de360529682741d3c33..e936989537e0f7146f2538cc5b456c619e255582 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 trait A<T> {
     fn g<U>(&self, x: T, y: U) -> (T, U) { (x, y) }
 }
index 1ea3879e7faf88e1f52a62205c5a0f1a2dd573b4..4fedbba81f41a46458f3d935a1359b1278b8c468 100644 (file)
@@ -9,11 +9,13 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 trait A<T> {
     fn g(&self, x: T) -> T { x }
 }
 
-impl A<int> for int { }
+impl A<isize> for isize { }
 
 fn f<T, V: A<T>>(i: V, j: T) -> T {
     i.g(j)
index aff20ffe962a2323203a3e5e8f3867e6886960e2..4f749cbd3fdbd198851a74e4d9c0e73250df67f6 100644 (file)
@@ -9,11 +9,13 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 trait A {
     fn g<T>(&self, x: T, y: T) -> (T, T) { (x, y) }
 }
 
-impl A for int { }
+impl A for isize { }
 
 fn f<T, V: A>(i: V, j: T, k: T) -> (T, T) {
     i.g(j, k)
index 383849ca51267532abe21f9b51b960caa721ff84..6774569cd252ab5147b57cd107f6a0cd2fec2f86 100644 (file)
@@ -9,18 +9,20 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 trait A<T> {
-    fn g(&self, x: uint) -> uint { x }
+    fn g(&self, x: usize) -> usize { x }
     fn h(&self, x: T) { }
 }
 
-impl<T> A<T> for int { }
+impl<T> A<T> for isize { }
 
-fn f<T, V: A<T>>(i: V, j: uint) -> uint {
+fn f<T, V: A<T>>(i: V, j: usize) -> usize {
     i.g(j)
 }
 
 pub fn main () {
-    assert_eq!(f::<f64, int>(0, 2_usize), 2_usize);
-    assert_eq!(f::<uint, int>(0, 2_usize), 2_usize);
+    assert_eq!(f::<f64, isize>(0, 2), 2);
+    assert_eq!(f::<usize, isize>(0, 2), 2);
 }
index 8a2f1b1743b09f779d843baa4f4341a7d5b65709..4107540a47145c86637fd73f8d2e4ce098327191 100644 (file)
@@ -9,11 +9,13 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 trait A {
-    fn g(&self) -> int { 10 }
+    fn g(&self) -> isize { 10 }
 }
 
-impl A for int { }
+impl A for isize { }
 
 fn f<T:A>(i: T) {
     assert_eq!(i.g(), 10);
index b28e8bd24aa2b3d78277b5772164a7ac2293b08e..d4ed72704001690073c8c7f9312a29c770736f45 100644 (file)
 // aux-build:trait_default_method_xc_aux_2.rs
 
 
-extern crate "trait_default_method_xc_aux" as aux;
-extern crate "trait_default_method_xc_aux_2" as aux2;
+// pretty-expanded FIXME #23616
+
+extern crate trait_default_method_xc_aux as aux;
+extern crate trait_default_method_xc_aux_2 as aux2;
 use aux::A;
 use aux2::{a_struct, welp};
 
index 4745d057952aec524f2d7ee740b7fb20124f1846..65e8c53a25ec592e058b7ce02219133e736a1193 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:trait_default_method_xc_aux.rs
 
-extern crate "trait_default_method_xc_aux" as aux;
+// pretty-expanded FIXME #23616
+
+extern crate trait_default_method_xc_aux as aux;
 use aux::{A, TestEquality, Something};
 use aux::B;
 
@@ -18,16 +20,16 @@ fn f<T: aux::A>(i: T) {
     assert_eq!(i.g(), 10);
 }
 
-fn welp<T>(i: int, _x: &T) -> int {
+fn welp<T>(i: isize, _x: &T) -> isize {
     i.g()
 }
 
 mod stuff {
-    pub struct thing { pub x: int }
+    pub struct thing { pub x: isize }
 }
 
 impl A for stuff::thing {
-    fn f(&self) -> int { 10 }
+    fn f(&self) -> isize { 10 }
 }
 
 fn g<T, U, V: B<T>>(i: V, j: T, k: U) -> (T, U) {
@@ -67,7 +69,7 @@ pub fn main() {
 
     assert_eq!(0.thing(3.14f64, 1), (3.14f64, 1));
     assert_eq!(B::staticthing(&0, 3.14f64, 1), (3.14f64, 1));
-    assert_eq!(B::<f64>::staticthing::<int>(&0, 3.14, 1), (3.14, 1));
+    assert_eq!(B::<f64>::staticthing::<isize>(&0, 3.14, 1), (3.14, 1));
 
     assert_eq!(g(0, 3.14f64, 1), (3.14f64, 1));
     assert_eq!(g(false, 3.14f64, 1), (3.14, 1));
index ca66a106c437efab2ddf15ede1018e7bcfc42907..b9ca8971d3893eca4d3f1de21723be67f172bd05 100644 (file)
@@ -12,6 +12,8 @@
 // between the builtin rules for Sized and the where clause. Issue
 // #20959.
 
+// pretty-expanded FIXME #23616
+
 fn foo<K>(x: Option<K>)
     where Option<K> : Sized
 {
index 5f4b18df6e16b983f103a0fda7958b83c1648c6c..6ef0dacee746ad0728a099ea5478c69b30a00418 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 trait to_str {
     fn to_string_(&self) -> String;
 }
-impl to_str for int {
+impl to_str for isize {
     fn to_string_(&self) -> String { self.to_string() }
 }
 impl to_str for String {
@@ -44,9 +46,9 @@ fn bar<U:to_str,T:map<U>>(x: T) -> Vec<String> {
 }
 
 pub fn main() {
-    assert_eq!(foo(vec!(1)), vec!("hi".to_string()));
-    assert_eq!(bar::<int, Vec<int> >(vec!(4, 5)), vec!("4".to_string(), "5".to_string()));
+    assert_eq!(foo(vec!(1)), ["hi".to_string()]);
+    assert_eq!(bar::<isize, Vec<isize> >(vec!(4, 5)), ["4".to_string(), "5".to_string()]);
     assert_eq!(bar::<String, Vec<String> >(vec!("x".to_string(), "y".to_string())),
-               vec!("x".to_string(), "y".to_string()));
-    assert_eq!(bar::<(), Vec<()>>(vec!(())), vec!("()".to_string()));
+               ["x".to_string(), "y".to_string()]);
+    assert_eq!(bar::<(), Vec<()>>(vec!(())), ["()".to_string()]);
 }
diff --git a/src/test/run-pass/trait-impl-2.rs b/src/test/run-pass/trait-impl-2.rs
new file mode 100644 (file)
index 0000000..c94b517
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2015 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.
+
+// pretty-expanded FIXME #23616
+
+pub mod Foo {
+    pub trait Trait {
+        fn foo(&self);
+    }
+}
+
+mod Bar {
+    impl<'a> ::Foo::Trait+'a {
+        fn bar(&self) { self.foo() }
+    }
+}
+
+fn main() {}
index 325fba8a0ee4288fe1852189e716733692faa59f..95fd7bda474baa867d8bc5f6431205240f9b8a4b 100644 (file)
 // Test calling methods on an impl for a bare trait.
 
 // aux-build:traitimpl.rs
+// pretty-expanded FIXME #23616
+
 extern crate traitimpl;
 use traitimpl::Bar;
 
-static mut COUNT: uint = 1;
+static mut COUNT: usize = 1;
 
 trait T {
     fn t(&self) {}
@@ -29,7 +31,7 @@ impl<'a> T+'a {
     }
 }
 
-impl T for int {}
+impl T for isize {}
 
 struct Foo;
 impl<'a> Bar<'a> for Foo {}
index d45d7ebe90adc1a0374a5e3d831d63fd403e8533..128be2993ec1db26fda867ecfbf8536b94321de7 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:trait_inheritance_auto_xc_2_aux.rs
 
-extern crate "trait_inheritance_auto_xc_2_aux" as aux;
+// pretty-expanded FIXME #23616
+
+extern crate trait_inheritance_auto_xc_2_aux as aux;
 
 // aux defines impls of Foo, Bar and Baz for A
 use aux::{Foo, Bar, Baz, A};
index f4e1908aaeed972609d13bd54df84f030ab20803..827674c81adc1678ed661db9a1534ce2394876f4 100644 (file)
 
 // aux-build:trait_inheritance_auto_xc_aux.rs
 
-extern crate "trait_inheritance_auto_xc_aux" as aux;
+// pretty-expanded FIXME #23616
+
+extern crate trait_inheritance_auto_xc_aux as aux;
 
 use aux::{Foo, Bar, Baz, Quux};
 
-struct A { x: int }
+struct A { x: isize }
 
-impl Foo for A { fn f(&self) -> int { 10 } }
-impl Bar for A { fn g(&self) -> int { 20 } }
-impl Baz for A { fn h(&self) -> int { 30 } }
+impl Foo for A { fn f(&self) -> isize { 10 } }
+impl Bar for A { fn g(&self) -> isize { 20 } }
+impl Baz for A { fn h(&self) -> isize { 30 } }
 
 fn f<T:Quux>(a: &T) {
     assert_eq!(a.f(), 10);
index c5a7720e3c34139d5ba85056649502897a7cbcf6..1b72736cde439e7c4eb9668a25b3d1402c2deda4 100644 (file)
 
 // Testing that this impl turns A into a Quux, because
 // A is already a Foo Bar Baz
+// pretty-expanded FIXME #23616
+
 impl<T:Foo + Bar + Baz> Quux for T { }
 
-trait Foo { fn f(&self) -> int; }
-trait Bar { fn g(&self) -> int; }
-trait Baz { fn h(&self) -> int; }
+trait Foo { fn f(&self) -> isize; }
+trait Bar { fn g(&self) -> isize; }
+trait Baz { fn h(&self) -> isize; }
 
 trait Quux: Foo + Bar + Baz { }
 
-struct A { x: int }
+struct A { x: isize }
 
-impl Foo for A { fn f(&self) -> int { 10 } }
-impl Bar for A { fn g(&self) -> int { 20 } }
-impl Baz for A { fn h(&self) -> int { 30 } }
+impl Foo for A { fn f(&self) -> isize { 10 } }
+impl Bar for A { fn g(&self) -> isize { 20 } }
+impl Baz for A { fn h(&self) -> isize { 30 } }
 
 fn f<T:Quux>(a: &T) {
     assert_eq!(a.f(), 10);
index 46258902f9caef1781d459ab2f03d4fa34ce6593..c8df12392faf4ee23fd31cab6ecf051b0d1fa6d4 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo { fn f(&self) -> int; }
-trait Bar : Foo { fn g(&self) -> int; }
+// pretty-expanded FIXME #23616
 
-struct A { x: int }
+trait Foo { fn f(&self) -> isize; }
+trait Bar : Foo { fn g(&self) -> isize; }
 
-impl Foo for A { fn f(&self) -> int { 10 } }
-impl Bar for A { fn g(&self) -> int { 20 } }
+struct A { x: isize }
+
+impl Foo for A { fn f(&self) -> isize { 10 } }
+impl Bar for A { fn g(&self) -> isize { 20 } }
 
 // Call a function on Foo, given a T: Bar
-fn gg<T:Bar>(a: &T) -> int {
+fn gg<T:Bar>(a: &T) -> isize {
     a.f()
 }
 
index 7b79ad42ed2b3cb2632ff78d57e4e7b52289f1ba..fcd6143579c12b9762f553010fe5e00fa5f2b17d 100644 (file)
@@ -8,19 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo { fn f(&self) -> int; }
-trait Bar : Foo { fn g(&self) -> int; }
-trait Baz : Bar { fn h(&self) -> int; }
+// pretty-expanded FIXME #23616
 
-struct A { x: int }
+trait Foo { fn f(&self) -> isize; }
+trait Bar : Foo { fn g(&self) -> isize; }
+trait Baz : Bar { fn h(&self) -> isize; }
 
-impl Foo for A { fn f(&self) -> int { 10 } }
-impl Bar for A { fn g(&self) -> int { 20 } }
-impl Baz for A { fn h(&self) -> int { 30 } }
+struct A { x: isize }
+
+impl Foo for A { fn f(&self) -> isize { 10 } }
+impl Bar for A { fn g(&self) -> isize { 20 } }
+impl Baz for A { fn h(&self) -> isize { 30 } }
 
 // Call a function on Foo, given a T: Baz,
 // which is inherited via Bar
-fn gg<T:Baz>(a: &T) -> int {
+fn gg<T:Baz>(a: &T) -> isize {
     a.f()
 }
 
index 68a31ba9dbe64b179f8385694e1b5af9fb91c45d..3996ae850e84ef9a925fcf839a7c645663547b18 100644 (file)
 // Testing that we can cast to a subtrait and call subtrait
 // methods. Not testing supertrait methods
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
-    fn f(&self) -> int;
+    fn f(&self) -> isize;
 }
 
 trait Bar : Foo {
-    fn g(&self) -> int;
+    fn g(&self) -> isize;
 }
 
 struct A {
-    x: int
+    x: isize
 }
 
 impl Foo for A {
-    fn f(&self) -> int { 10 }
+    fn f(&self) -> isize { 10 }
 }
 
 impl Bar for A {
-    fn g(&self) -> int { 20 }
+    fn g(&self) -> isize { 20 }
 }
 
 pub fn main() {
index 51bc2751873faa566dc41c1b0f465248360a5574..7784ed2f26ae90398929d6f69e88dd68a3afdc1d 100644 (file)
 
 // Testing that supertrait methods can be called on subtrait object types
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
-    fn f(&self) -> int;
+    fn f(&self) -> isize;
 }
 
 trait Bar : Foo {
-    fn g(&self) -> int;
+    fn g(&self) -> isize;
 }
 
 struct A {
-    x: int
+    x: isize
 }
 
 impl Foo for A {
-    fn f(&self) -> int { 10 }
+    fn f(&self) -> isize { 10 }
 }
 
 impl Bar for A {
-    fn g(&self) -> int { 20 }
+    fn g(&self) -> isize { 20 }
 }
 
 pub fn main() {
index 3ee046e8bfe6cf434d54d7c1538c97036f4d4179..c665c35b418c0b9654751c0a5250f6e1149a1dce 100644 (file)
 
 // aux-build:trait_inheritance_cross_trait_call_xc_aux.rs
 
-extern crate "trait_inheritance_cross_trait_call_xc_aux" as aux;
+// pretty-expanded FIXME #23616
+
+extern crate trait_inheritance_cross_trait_call_xc_aux as aux;
 
 use aux::Foo;
 
 trait Bar : Foo {
-    fn g(&self) -> int;
+    fn g(&self) -> isize;
 }
 
 impl Bar for aux::A {
-    fn g(&self) -> int { self.f() }
+    fn g(&self) -> isize { self.f() }
 }
 
 pub fn main() {
index 7b047b5cc800a0c653caa21108d33dd40d0fe6c6..418986f961e5878806fbccc3aefa8e2566943313 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo { fn f(&self) -> int; }
-trait Bar : Foo { fn g(&self) -> int; }
+// pretty-expanded FIXME #23616
 
-struct A { x: int }
+trait Foo { fn f(&self) -> isize; }
+trait Bar : Foo { fn g(&self) -> isize; }
 
-impl Foo for A { fn f(&self) -> int { 10 } }
+struct A { x: isize }
+
+impl Foo for A { fn f(&self) -> isize { 10 } }
 
 impl Bar for A {
     // Testing that this impl can call the impl of Foo
-    fn g(&self) -> int { self.f() }
+    fn g(&self) -> isize { self.f() }
 }
 
 pub fn main() {
index 253c10ac6f1b037196c2d4980f20d9f3ed5123cc..07b1a79110f63fbaf957000b71dfcb195eb085ce 100644 (file)
 
 // B and C both require A, so D does as well, twice, but that's just fine
 
-trait A { fn a(&self) -> int; }
-trait B: A { fn b(&self) -> int; }
-trait C: A { fn c(&self) -> int; }
-trait D: B + C { fn d(&self) -> int; }
+// pretty-expanded FIXME #23616
+
+trait A { fn a(&self) -> isize; }
+trait B: A { fn b(&self) -> isize; }
+trait C: A { fn c(&self) -> isize; }
+trait D: B + C { fn d(&self) -> isize; }
 
 struct S { bogus: () }
 
-impl A for S { fn a(&self) -> int { 10 } }
-impl B for S { fn b(&self) -> int { 20 } }
-impl C for S { fn c(&self) -> int { 30 } }
-impl D for S { fn d(&self) -> int { 40 } }
+impl A for S { fn a(&self) -> isize { 10 } }
+impl B for S { fn b(&self) -> isize { 20 } }
+impl C for S { fn c(&self) -> isize { 30 } }
+impl D for S { fn d(&self) -> isize { 40 } }
 
 fn f<T:D>(x: &T) {
     assert_eq!(x.a(), 10);
index 6cd3d62473692cfe117c805c13c20b8f1f2751c6..b89246269542e445084a30fe5aeb69bec86774f8 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A { fn a(&self) -> int; }
-trait B: A { fn b(&self) -> int; }
-trait C: A { fn c(&self) -> int; }
+// pretty-expanded FIXME #23616
+
+trait A { fn a(&self) -> isize; }
+trait B: A { fn b(&self) -> isize; }
+trait C: A { fn c(&self) -> isize; }
 
 struct S { bogus: () }
 
-impl A for S { fn a(&self) -> int { 10 } }
-impl B for S { fn b(&self) -> int { 20 } }
-impl C for S { fn c(&self) -> int { 30 } }
+impl A for S { fn a(&self) -> isize { 10 } }
+impl B for S { fn b(&self) -> isize { 20 } }
+impl C for S { fn c(&self) -> isize { 30 } }
 
 // Both B and C inherit from A
 fn f<T:B + C>(x: &T) {
index b5524c6dda6cd2d667cd9ab45851b86082929973..37803edb752b1807d8230a223637fda0fd32a3ef 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A { fn a(&self) -> int; }
-trait B: A { fn b(&self) -> int; }
-trait C: A { fn c(&self) -> int; }
+// pretty-expanded FIXME #23616
+
+trait A { fn a(&self) -> isize; }
+trait B: A { fn b(&self) -> isize; }
+trait C: A { fn c(&self) -> isize; }
 
 struct S { bogus: () }
 
-impl A for S { fn a(&self) -> int { 10 } }
-impl B for S { fn b(&self) -> int { 20 } }
-impl C for S { fn c(&self) -> int { 30 } }
+impl A for S { fn a(&self) -> isize { 10 } }
+impl B for S { fn b(&self) -> isize { 20 } }
+impl C for S { fn c(&self) -> isize { 30 } }
 
 // Multiple type params, multiple levels of inheritance
 fn f<X:A,Y:B,Z:C>(x: &X, y: &Y, z: &Z) {
index 9a30d51f4c5ac4582eaf3ffe2f68566c8ce03d6c..4af049fc0c3af92b3892ae1ff7e7816fc0680146 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::cmp::{PartialEq, PartialOrd};
 use std::num::NumCast;
 
index d68b6a54f71355b6f9a554cb430771f33ab18e72..b7f9534935697b4f20afa7ff4ac60a92b078cee0 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
 
 // Extending Num and using inherited static methods
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::cmp::PartialOrd;
 use std::num::NumCast;
 
 pub trait Num {
-    fn from_int(i: int) -> Self;
+    fn from_int(i: isize) -> Self;
     fn gt(&self, other: &Self) -> bool;
 }
 
index 15fb5df46264ad098fd9709b9bb628866d2c8eb3..02ebf6bfa5375afd029f202c5adca1e65f400002 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::cmp::PartialOrd;
 use std::num::NumCast;
 
index f89eea46090d07884eb8d8795a54fb2a49d2c087..773fc387a2a34370bbff8732a942ad621c2d4755 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -11,6 +10,8 @@
 
 // A more complex example of numeric extensions
 
+#![feature(core)]
+
 use std::cmp::{PartialEq, PartialOrd};
 use std::num::NumCast;
 
@@ -20,13 +21,13 @@ impl TypeExt for u8 {}
 impl TypeExt for u16 {}
 impl TypeExt for u32 {}
 impl TypeExt for u64 {}
-impl TypeExt for uint {}
+impl TypeExt for usize {}
 
 impl TypeExt for i8 {}
 impl TypeExt for i16 {}
 impl TypeExt for i32 {}
 impl TypeExt for i64 {}
-impl TypeExt for int {}
+impl TypeExt for isize {}
 
 impl TypeExt for f32 {}
 impl TypeExt for f64 {}
@@ -38,13 +39,13 @@ impl NumExt for u8 {}
 impl NumExt for u16 {}
 impl NumExt for u32 {}
 impl NumExt for u64 {}
-impl NumExt for uint {}
+impl NumExt for usize {}
 
 impl NumExt for i8 {}
 impl NumExt for i16 {}
 impl NumExt for i32 {}
 impl NumExt for i64 {}
-impl NumExt for int {}
+impl NumExt for isize {}
 
 impl NumExt for f32 {}
 impl NumExt for f64 {}
@@ -56,7 +57,7 @@ impl UnSignedExt for u8 {}
 impl UnSignedExt for u16 {}
 impl UnSignedExt for u32 {}
 impl UnSignedExt for u64 {}
-impl UnSignedExt for uint {}
+impl UnSignedExt for usize {}
 
 
 pub trait SignedExt: NumExt {}
@@ -65,7 +66,7 @@ impl SignedExt for i8 {}
 impl SignedExt for i16 {}
 impl SignedExt for i32 {}
 impl SignedExt for i64 {}
-impl SignedExt for int {}
+impl SignedExt for isize {}
 
 impl SignedExt for f32 {}
 impl SignedExt for f64 {}
@@ -77,13 +78,13 @@ impl IntegerExt for u8 {}
 impl IntegerExt for u16 {}
 impl IntegerExt for u32 {}
 impl IntegerExt for u64 {}
-impl IntegerExt for uint {}
+impl IntegerExt for usize {}
 
 impl IntegerExt for i8 {}
 impl IntegerExt for i16 {}
 impl IntegerExt for i32 {}
 impl IntegerExt for i64 {}
-impl IntegerExt for int {}
+impl IntegerExt for isize {}
 
 
 pub trait FloatExt: NumExt {}
index 09015d983ea7cca35b5690dd3d2d96ea25e7e31f..b5cf25bc5a8f4cd6664824a9fa7c191b2f4d273d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(core)]
+
 use std::cmp::{PartialEq, PartialOrd};
 use std::num::NumCast;
 
index a21026839a7c1b3e2113d6c2285bba8fa3adff60..b2c3900bc0282886157664c1b0c5144a353d93ad 100644 (file)
@@ -8,18 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::cmp::PartialEq;
 use std::num::NumCast;
 
 pub trait NumExt: PartialEq + NumCast {}
 
 impl NumExt for f32 {}
-impl NumExt for int {}
+impl NumExt for isize {}
 
 fn num_eq_one<T:NumExt>() -> T {
     NumCast::from(1).unwrap()
 }
 
 pub fn main() {
-    num_eq_one::<int>(); // you need to actually use the function to trigger the ICE
+    num_eq_one::<isize>(); // you need to actually use the function to trigger the ICE
 }
index 4cd9fbeba9c1d59d5713480eefa5ff6ed2fb5c40..9c1f585fe450ba406be509fc36274c02b403a82e 100644 (file)
@@ -13,7 +13,7 @@ use std::cmp::PartialEq;
 trait MyNum : PartialEq { }
 
 #[derive(Debug)]
-struct MyInt { val: int }
+struct MyInt { val: isize }
 
 impl PartialEq for MyInt {
     fn eq(&self, other: &MyInt) -> bool { self.val == other.val }
@@ -26,7 +26,7 @@ fn f<T:MyNum>(x: T, y: T) -> bool {
     return x == y;
 }
 
-fn mi(v: int) -> MyInt { MyInt { val: v } }
+fn mi(v: isize) -> MyInt { MyInt { val: v } }
 
 pub fn main() {
     let (x, y, z) = (mi(3), mi(5), mi(3));
index 2a087e5e425ad23d976baf8a98ab48f131ddde20..f44c6927c87e082b5ce8b89289adee91ddf71c33 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:trait_inheritance_overloading_xc.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate trait_inheritance_overloading_xc;
 use trait_inheritance_overloading_xc::{MyNum, MyInt};
 
@@ -17,7 +19,7 @@ fn f<T:MyNum>(x: T, y: T) -> (T, T, T) {
     return (x.clone() + y.clone(), x.clone() - y.clone(), x * y);
 }
 
-fn mi(v: int) -> MyInt { MyInt { val: v } }
+fn mi(v: isize) -> MyInt { MyInt { val: v } }
 
 pub fn main() {
     let (x, y) = (mi(3), mi(5));
index 893f782cba4369dc16e5f2987c24bdc74acfb211..b7d0400dd892b334f979682f5c607544c0e08eae 100644 (file)
@@ -14,7 +14,7 @@ use std::ops::{Add, Sub, Mul};
 trait MyNum : Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + PartialEq + Clone { }
 
 #[derive(Clone, Debug)]
-struct MyInt { val: int }
+struct MyInt { val: isize }
 
 impl Add for MyInt {
     type Output = MyInt;
@@ -45,7 +45,7 @@ fn f<T:MyNum>(x: T, y: T) -> (T, T, T) {
     return (x.clone() + y.clone(), x.clone() - y.clone(), x * y);
 }
 
-fn mi(v: int) -> MyInt { MyInt { val: v } }
+fn mi(v: isize) -> MyInt { MyInt { val: v } }
 
 pub fn main() {
     let (x, y) = (mi(3), mi(5));
index 96f1c940dcf2cdabaf617be2e50683e08ae178e0..87a36ba7b90ccf9ff0978c753e8a6abdf6a847d6 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test for issue #4183: use of Self in supertraits.
 
+// pretty-expanded FIXME #23616
+
 use std::num::Float as StdFloat;
 
 pub static FUZZY_EPSILON: f64 = 0.1;
index 07b0929968dfeedeca924963e2954b57511cd784..7d975da4a2491b204648192c6ab5f1f76b27bf1f 100644 (file)
@@ -17,7 +17,7 @@ trait Bar : Foo<Self> {
 }
 
 struct S {
-    x: int
+    x: isize
 }
 
 impl Foo<S> for S {
index 113efa663afaf760ec6032e62ecae9f63f925067..ff89b1ee5d30df324ea8969c7fdb5564299a4dc2 100644 (file)
@@ -8,19 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo { fn f(&self) -> int; }
-trait Bar : Foo { fn g(&self) -> int; }
+// pretty-expanded FIXME #23616
 
-struct A { x: int }
+trait Foo { fn f(&self) -> isize; }
+trait Bar : Foo { fn g(&self) -> isize; }
 
-impl Foo for A { fn f(&self) -> int { 10 } }
-impl Bar for A { fn g(&self) -> int { 20 } }
+struct A { x: isize }
 
-fn ff<T:Foo>(a: &T) -> int {
+impl Foo for A { fn f(&self) -> isize { 10 } }
+impl Bar for A { fn g(&self) -> isize { 20 } }
+
+fn ff<T:Foo>(a: &T) -> isize {
     a.f()
 }
 
-fn gg<T:Bar>(a: &T) -> int {
+fn gg<T:Bar>(a: &T) -> isize {
     a.g()
 }
 
index 611c3e006ec1937b6a35efe34be3729c55108b60..9ed5fd0aaa53fb77b239a3ae3b59b66623090c79 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub trait MyNum {
-    fn from_int(int) -> Self;
+    fn from_int(isize) -> Self;
 }
 
 pub trait NumExt: MyNum { }
 
-struct S { v: int }
+struct S { v: isize }
 
 impl MyNum for S {
-    fn from_int(i: int) -> S {
+    fn from_int(i: isize) -> S {
         S {
             v: i
         }
index 8f3b325a513fe2f739a0d28f9c7ffd433d6de06e..9fe9d7fce7af5c66d712f97b2f6ed7eb842ab4ea 100644 (file)
@@ -8,20 +8,24 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 pub trait MyEq : ::std::marker::MarkerTrait { }
 
 pub trait MyNum : ::std::marker::MarkerTrait {
-    fn from_int(int) -> Self;
+    fn from_int(isize) -> Self;
 }
 
 pub trait NumExt: MyEq + MyNum { }
 
-struct S { v: int }
+struct S { v: isize }
 
 impl MyEq for S { }
 
 impl MyNum for S {
-    fn from_int(i: int) -> S {
+    fn from_int(i: isize) -> S {
         S {
             v: i
         }
index cd57e6a7dd05966caf8cf8cfccb07ef290bf2576..d35a937a5733d703978c1e9c6878df8c2899c762 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub trait Add<RHS,Result> {
     fn add(&self, rhs: &RHS) -> Result;
 }
 
 trait MyNum : Add<Self,Self> { }
 
-struct MyInt { val: int }
+struct MyInt { val: isize }
 
 impl Add<MyInt, MyInt> for MyInt {
     fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) }
@@ -26,7 +28,7 @@ fn f<T:MyNum>(x: T, y: T) -> T {
     return x.add(&y);
 }
 
-fn mi(v: int) -> MyInt { MyInt { val: v } }
+fn mi(v: isize) -> MyInt { MyInt { val: v } }
 
 pub fn main() {
     let (x, y) = (mi(3), mi(5));
index ebddfafc3b4381ffb262011469684e4e206a0c5d..e0be5759503c6bde71f4d28501d2ac07ce45e9fd 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Panda<T> {
     fn chomp(&self, bamboo: &T) -> T;
 }
@@ -18,7 +20,7 @@ trait Add<RHS,Result>: Panda<RHS> {
 
 trait MyNum : Add<Self,Self> { }
 
-struct MyInt { val: int }
+struct MyInt { val: isize }
 
 impl Panda<MyInt> for MyInt {
     fn chomp(&self, bamboo: &MyInt) -> MyInt {
@@ -36,7 +38,7 @@ fn f<T:MyNum>(x: T, y: T) -> T {
     return x.add(&y).chomp(&y);
 }
 
-fn mi(v: int) -> MyInt { MyInt { val: v } }
+fn mi(v: isize) -> MyInt { MyInt { val: v } }
 
 pub fn main() {
     let (x, y) = (mi(3), mi(5));
index 3cdedd884a42c22d7689ba466b048538221390f6..8c8b9232dee8c445378f6df7fab62d097c8107f9 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 mod traits {
-    pub trait Foo { fn f(&self) -> int; }
+    pub trait Foo { fn f(&self) -> isize; }
 
-    impl Foo for int { fn f(&self) -> int { 10 } }
+    impl Foo for isize { fn f(&self) -> isize { 10 } }
 }
 
 trait Quux: traits::Foo { }
index 7fa895ddf988802b1896224c67f1448b1e119962..9e721836d631909853c0909e223a161c33c90c78 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo { fn f(&self) -> int; }
-trait Bar { fn g(&self) -> int; }
-trait Baz { fn h(&self) -> int; }
+// pretty-expanded FIXME #23616
+
+trait Foo { fn f(&self) -> isize; }
+trait Bar { fn g(&self) -> isize; }
+trait Baz { fn h(&self) -> isize; }
 
 trait Quux: Foo + Bar + Baz { }
 
-struct A { x: int }
+struct A { x: isize }
 
-impl Foo for A { fn f(&self) -> int { 10 } }
-impl Bar for A { fn g(&self) -> int { 20 } }
-impl Baz for A { fn h(&self) -> int { 30 } }
+impl Foo for A { fn f(&self) -> isize { 10 } }
+impl Bar for A { fn g(&self) -> isize { 20 } }
+impl Baz for A { fn h(&self) -> isize { 30 } }
 impl Quux for A {}
 
 fn f<T:Quux + Foo + Bar + Baz>(a: &T) {
index 6f89490716f081d123628285840d0404d4c17222..63246b870cb594323b21cacf3797aac90c6431fc 100644 (file)
@@ -10,6 +10,8 @@
 
 // test for #8664
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -40,14 +42,14 @@ impl<A1, A2, A3> Impl<A1, A2, A3> {
 enum Type<T> { Constant(T) }
 
 trait Trait<K,V> {
-    fn method(&self,Type<(K,V)>) -> int;
+    fn method(&self,Type<(K,V)>) -> isize;
 }
 
 impl<V> Trait<u8,V> for () {
-    fn method(&self, _x: Type<(u8,V)>) -> int { 0 }
+    fn method(&self, _x: Type<(u8,V)>) -> isize { 0 }
 }
 
 pub fn main() {
     let a = box() () as Box<Trait<u8, u8>>;
-    assert_eq!(a.method(Type::Constant((1u8, 2u8))), 0);
+    assert_eq!(a.method(Type::Constant((1, 2))), 0);
 }
index 4e481910aa98fd215d9657ce77fb28cf6fa0832b..30a05ee1c562e3d1c36d50782d24dea1efbfa7bb 100644 (file)
@@ -11,6 +11,8 @@
 // Uncovered during work on new scoping rules for safe destructors
 // as an important use case to support properly.
 
+// pretty-expanded FIXME #23616
+
 pub struct E<'a> {
     pub f: &'a u8,
 }
@@ -36,7 +38,7 @@ fn extension<'e>(x: &'e E<'e>) -> Box<M+'e> {
 }
 
 fn main() {
-    let w = E { f: &10u8 };
+    let w = E { f: &10 };
     let o = extension(&w);
-    assert_eq!(o.n(), 10u8);
+    assert_eq!(o.n(), 10);
 }
index 412fb6625e33fa062a720975a05c927c20303cbc..95311e62e634338360ff068de8cdd00930a2ba21 100644 (file)
@@ -9,15 +9,15 @@
 // except according to those terms.
 
 trait Foo {
-    fn f(&self) -> int;
+    fn f(&self) -> isize;
 }
 
 struct A {
-    x: int
+    x: isize
 }
 
 impl Foo for A {
-    fn f(&self) -> int {
+    fn f(&self) -> isize {
         println!("Today's number is {}", self.x);
         return self.x;
     }
index 99203d3e24acc7e569a1be3e7fdb99637cdfe7e2..ada79399561a9265dc9411c16d06d39668811184 100644 (file)
@@ -8,23 +8,25 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:trait-safety-lib.rs
+// aux-build:trait_safety_lib.rs
 
 // Simple smoke test that unsafe traits can be compiled across crates.
 
-extern crate "trait-safety-lib" as lib;
+// pretty-expanded FIXME #23616
+
+extern crate trait_safety_lib as lib;
 
 use lib::Foo;
 
-struct Bar { x: int }
+struct Bar { x: isize }
 unsafe impl Foo for Bar {
-    fn foo(&self) -> int { self.x }
+    fn foo(&self) -> isize { self.x }
 }
 
-fn take_foo<F:Foo>(f: &F) -> int { f.foo() }
+fn take_foo<F:Foo>(f: &F) -> isize { f.foo() }
 
 fn main() {
-    let x: int = 22;
+    let x: isize = 22;
     assert_eq!(22, take_foo(&x));
 
     let x: Bar = Bar { x: 23 };
index a24796a7d0c31025929372e3a6a20464835d7ec9..3cd23aeaf27a532b96761b2fb1d72af1e80528ca 100644 (file)
 
 // Simple smoke test that unsafe traits can be compiled etc.
 
+// pretty-expanded FIXME #23616
+
 unsafe trait Foo {
-    fn foo(&self) -> int;
+    fn foo(&self) -> isize;
 }
 
-unsafe impl Foo for int {
-    fn foo(&self) -> int { *self }
+unsafe impl Foo for isize {
+    fn foo(&self) -> isize { *self }
 }
 
-fn take_foo<F:Foo>(f: &F) -> int { f.foo() }
+fn take_foo<F:Foo>(f: &F) -> isize { f.foo() }
 
 fn main() {
-    let x: int = 22;
+    let x: isize = 22;
     assert_eq!(22, take_foo(&x));
 }
index 10439d5c86aa35721e6bb5e8ea4b8fd3a1717d4f..31968da6ee31005dca4be59cb37d5a3857ede973 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
index ea8a5a28c34ff64414ab1b877a2cafb3e005719e..3d84092c062e6b5117169b7a69b048f5fa54ae84 100644 (file)
@@ -15,7 +15,7 @@ trait to_str {
     fn to_string_(&self) -> String;
 }
 
-impl to_str for int {
+impl to_str for isize {
     fn to_string_(&self) -> String { self.to_string() }
 }
 
index 772310d47335f0fcce37d795806cba825001a899..f3dcb51f97a291cc92118f40f9b9876e798ae4d9 100644 (file)
@@ -13,6 +13,8 @@
 //
 // Issue #18453.
 
+// pretty-expanded FIXME #23616
+
 use std::rc::Rc;
 
 pub trait Foo<M> {
index 6b2c5093c83bd3758a14f5336238942dfd5e8623..34a79c4cf31a05c547384312b15d8674bd75db25 100644 (file)
@@ -27,8 +27,8 @@ trait Getter<T: Clone> {
 
 }
 
-impl Getter<int> for int {
-    fn do_get(&self) -> int { *self }
+impl Getter<isize> for isize {
+    fn do_get(&self) -> isize { *self }
 }
 
 impl<T: Clone> Getter<T> for Option<T> {
diff --git a/src/test/run-pass/traits-assoc-type-in-supertrait.rs b/src/test/run-pass/traits-assoc-type-in-supertrait.rs
new file mode 100644 (file)
index 0000000..751cd50
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2015 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 case where an associated type is referenced from within the
+// supertrait definition. Issue #20220.
+
+// pretty-expanded FIXME #23616
+
+use std::vec::IntoIter;
+
+pub trait Foo: Iterator<Item=<Self as Foo>::Key> {
+    type Key;
+}
+
+impl Foo for IntoIter<i32> {
+    type Key = i32;
+}
+
+fn sum_foo<F:Foo<Key=i32>>(f: F) -> i32 {
+    f.fold(0, |a,b| a + b)
+}
+
+fn main() {
+    let x = sum_foo(vec![11, 10, 1].into_iter());
+    assert_eq!(x, 22);
+}
index 5af2d4ee806d225422b1d5de0cf4b487870a6792..0190b7b7b9628370a408733e302da67757825e24 100644 (file)
 // blanket impl for T:Copy coexists with an impl for Box<T>, because
 // Box does not impl Copy.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
+use std::marker::MarkerTrait;
+
 trait Get {
     fn get(&self) -> Self;
 }
 
-impl<T:Copy> Get for T {
-    fn get(&self) -> T { *self }
+trait MyCopy : MarkerTrait { fn copy(&self) -> Self; }
+impl MyCopy for u16 { fn copy(&self) -> Self { *self } }
+impl MyCopy for u32 { fn copy(&self) -> Self { *self } }
+impl MyCopy for i32 { fn copy(&self) -> Self { *self } }
+impl<T:Copy> MyCopy for Option<T> { fn copy(&self) -> Self { *self } }
+
+impl<T:MyCopy> Get for T {
+    fn get(&self) -> T { self.copy() }
 }
 
-impl<T:Get> Get for Box<T> {
-    fn get(&self) -> Box<T> { box get_it(&**self) }
+impl Get for Box<i32> {
+    fn get(&self) -> Box<i32> { box get_it(&**self) }
 }
 
 fn get_it<T:Get>(t: &T) -> T {
@@ -35,5 +45,5 @@ fn main() {
     assert_eq!(get_it(&1_u32), 1_u32);
     assert_eq!(get_it(&1_u16), 1_u16);
     assert_eq!(get_it(&Some(1_u16)), Some(1_u16));
-    assert_eq!(get_it(&box 1), box 1);
+    assert_eq!(get_it(&Box::new(1)), Box::new(1));
 }
index 92ba5aad05958f7f142c11027d5bb63f92f76ac6..65a48844620de2154683b1cc9e4d023bc13cabd8 100644 (file)
@@ -14,6 +14,8 @@
 
 // aux-build:go_trait.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate go_trait;
 
 use go_trait::{Go, GoMut, GoOnce, go, go_mut, go_once};
@@ -24,11 +26,11 @@ use std::cell::Cell;
 ///////////////////////////////////////////////////////////////////////////
 
 struct SomeGoableThing {
-    counter: Rc<Cell<int>>
+    counter: Rc<Cell<isize>>
 }
 
 impl Go for SomeGoableThing {
-    fn go(&self, arg: int) {
+    fn go(&self, arg: isize) {
         self.counter.set(self.counter.get() + arg);
     }
 }
@@ -36,11 +38,11 @@ impl Go for SomeGoableThing {
 ///////////////////////////////////////////////////////////////////////////
 
 struct SomeGoOnceableThing {
-    counter: Rc<Cell<int>>
+    counter: Rc<Cell<isize>>
 }
 
 impl GoOnce for SomeGoOnceableThing {
-    fn go_once(self, arg: int) {
+    fn go_once(self, arg: isize) {
         self.counter.set(self.counter.get() + arg);
     }
 }
index 245ae540ee89521db51c04918917a0bcf2f7e3ef..1ec58eac58bbd1dc8e14488fa3de1aaa4199e371 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
     fn bar(&self) -> String {
         format!("test")
index a3a1076ecba52fcbc1fc338d01ac3444770d5e68..3f61eb47233b6dc731196181e84d3fd411f72360 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 #![allow(unused_variable)]
 
 trait Foo {
-    fn foo(&self, mut v: int) { v = 1; }
+    fn foo(&self, mut v: isize) { v = 1; }
 }
 
 pub fn main() {}
index 270b95452187a309da9a009ca4ac3cbdb327a9c9..d9536108f4df3d77db84dc3178cf0c1fa5e7390e 100644 (file)
@@ -17,7 +17,7 @@ trait Cat {
     fn purr(&self) -> bool { true }
 }
 
-impl Cat for int {
+impl Cat for isize {
     fn meow(&self) -> bool {
         self.scratch()
     }
index 474632a7ffa58028e80bd8d5100ebc4013c15ac0..0e71fcab9d1476e461c21c0746994abe6cb5d3b2 100644 (file)
@@ -17,7 +17,7 @@ trait Cat {
     fn purr(&self) -> bool { true }
 }
 
-impl Cat for int {
+impl Cat for isize {
     fn meow(&self) -> bool {
         self.scratch()
     }
index 7e0f60d55a827acb3dbfff0b0e28408c1ce8b90f..2f3e0c64f6c117f899f61904ed27bb7d1e4ac2b3 100644 (file)
@@ -12,6 +12,8 @@
 // distinct scopes to be compared (`'g` and `'h`). The only important
 // thing is that compilation succeeds here.
 
+// pretty-expanded FIXME #23616
+
 #![allow(missing_copy_implementations)]
 #![allow(unused_variables)]
 
index 9cdcf4945d8ba6d52af24171c1bfb7ba26ff89f1..3da8c253978345f70aa3a1a781b20949f256f913 100644 (file)
@@ -12,6 +12,8 @@
 // and the blanket impl. The only important thing is that compilation
 // succeeds here. Issue #22110.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 trait Foo<A> {
diff --git a/src/test/run-pass/traits-issue-22655.rs b/src/test/run-pass/traits-issue-22655.rs
new file mode 100644 (file)
index 0000000..ded1742
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+// Regression test for issue #22655: This test should not lead to
+// infinite recursion.
+
+// pretty-expanded FIXME #23616
+
+unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
+
+pub struct Unique<T:?Sized> {
+    pointer: *const T,
+}
+
+pub struct Node<V> {
+    vals: V,
+    edges: Unique<Node<V>>,
+}
+
+fn is_send<T: Send>() {}
+
+fn main() {
+    is_send::<Node<&'static ()>>();
+}
diff --git a/src/test/run-pass/traits-issue-23003.rs b/src/test/run-pass/traits-issue-23003.rs
new file mode 100644 (file)
index 0000000..46cd22f
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2015 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 stack overflow triggered by evaluating the implications. To be
+// WF, the type `Receipt<Complete>` would require that `<Complete as
+// Async>::Cancel` be WF. This normalizes to `Receipt<Complete>`
+// again, leading to an infinite cycle. Issue #23003.
+
+// pretty-expanded FIXME #23616
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+use std::marker::PhantomData;
+
+trait Async {
+    type Cancel;
+}
+
+struct Receipt<A:Async> {
+    marker: PhantomData<A>,
+}
+
+struct Complete {
+    core: Option<()>,
+}
+
+impl Async for Complete {
+    type Cancel = Receipt<Complete>;
+}
+
+fn foo(r: Receipt<Complete>) { }
+
+fn main() { }
index 532ef7cbec6f37b3e6c31af5924025f2c4591ac2..1f1d1a46cf973cb4627ee333dfd9470b2b054c7b 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test that we can infer the Target based on the Self or vice versa.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
 trait Convert<Target> {
@@ -28,7 +30,7 @@ impl Convert<i16> for u32 {
     }
 }
 
-fn test<T,U>(_: T, _: U, t_size: uint, u_size: uint)
+fn test<T,U>(_: T, _: U, t_size: usize, u_size: usize)
 where T : Convert<U>
 {
     assert_eq!(mem::size_of::<T>(), t_size);
diff --git a/src/test/run-pass/traits-repeated-supertrait.rs b/src/test/run-pass/traits-repeated-supertrait.rs
new file mode 100644 (file)
index 0000000..509a6e3
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright 2015 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 a case of a trait which extends the same supertrait twice, but
+// with difference type parameters. Test that we can invoke the
+// various methods in various ways successfully.
+// See also `compile-fail/trait-repeated-supertrait-ambig.rs`.
+
+// pretty-expanded FIXME #23616
+
+trait CompareTo<T> {
+    fn same_as(&self, t: T) -> bool;
+}
+
+trait CompareToInts : CompareTo<i64> + CompareTo<u64> {
+}
+
+impl CompareTo<i64> for i64 {
+    fn same_as(&self, t: i64) -> bool { *self == t }
+}
+
+impl CompareTo<u64> for i64 {
+    fn same_as(&self, t: u64) -> bool { *self == (t as i64) }
+}
+
+impl CompareToInts for i64 { }
+
+fn with_obj(c: &CompareToInts) -> bool {
+    c.same_as(22_i64) && c.same_as(22_u64)
+}
+
+fn with_trait<C:CompareToInts>(c: &C) -> bool {
+    c.same_as(22_i64) && c.same_as(22_u64)
+}
+
+fn with_ufcs1<C:CompareToInts>(c: &C) -> bool {
+    CompareToInts::same_as(c, 22_i64) && CompareToInts::same_as(c, 22_u64)
+}
+
+fn with_ufcs2<C:CompareToInts>(c: &C) -> bool {
+    CompareTo::same_as(c, 22_i64) && CompareTo::same_as(c, 22_u64)
+}
+
+fn main() {
+    assert_eq!(22_i64.same_as(22_i64), true);
+    assert_eq!(22_i64.same_as(22_u64), true);
+    assert_eq!(with_trait(&22), true);
+    assert_eq!(with_obj(&22), true);
+    assert_eq!(with_ufcs1(&22), true);
+    assert_eq!(with_ufcs2(&22), true);
+}
index 6d0ae8f67cd4d9d291857da1830546f16fd6f7c7..3e2297f008f02b0e9ed175cf8af309c39b60e987 100644 (file)
@@ -21,6 +21,8 @@
 // Last 7 bytes of Request struct are not occupied by any fields.
 
 
+// pretty-expanded FIXME #23616
+
 enum TestOption<T> {
     TestNone,
     TestSome(T),
index 70a41f773a3e0a2c4cdd45ebfe12087525b6e630..bd705a909b0ec5a1d15df3335576fbfc791b6db7 100644 (file)
 // Issue #7988
 // Transmuting non-immediate type to immediate type
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     unsafe {
-        ::std::mem::transmute::<[int; 1],int>([1])
+        ::std::mem::transmute::<[isize; 1],isize>([1])
     };
 }
diff --git a/src/test/run-pass/trivial_casts.rs b/src/test/run-pass/trivial_casts.rs
new file mode 100644 (file)
index 0000000..3da1ba0
--- /dev/null
@@ -0,0 +1,71 @@
+// Copyright 2015 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 all coercions can actually be done using casts (modulo the lints).
+
+#![allow(trivial_casts, trivial_numeric_casts)]
+
+trait Foo {
+    fn foo(&self) {}
+}
+
+pub struct Bar;
+
+impl Foo for Bar {}
+
+pub fn main() {
+    // Numeric
+    let _ = 42_i32 as i32;
+    let _ = 42_u8 as u8;
+
+    // & to * pointers
+    let x: &u32 = &42;
+    let _ = x as *const u32;
+
+    let x: &mut u32 = &mut 42;
+    let _ = x as *mut u32;
+
+    // unsize array
+    let x: &[u32; 3] = &[42, 43, 44];
+    let _ = x as &[u32];
+    let _ = x as *const [u32];
+
+    let x: &mut [u32; 3] = &mut [42, 43, 44];
+    let _ = x as &mut [u32];
+    let _ = x as *mut [u32];
+
+    let x: Box<[u32; 3]> = Box::new([42, 43, 44]);
+    let _ = x as Box<[u32]>;
+
+    // unsize trait
+    let x: &Bar = &Bar;
+    let _ = x as &Foo;
+    let _ = x as *const Foo;
+
+    let x: &mut Bar = &mut Bar;
+    let _ = x as &mut Foo;
+    let _ = x as *mut Foo;
+
+    let x: Box<Bar> = Box::new(Bar);
+    let _ = x as Box<Foo>;
+
+    // functions
+    fn baz(_x: i32) {}
+    let _ = &baz as &Fn(i32);
+    let x = |_x: i32| {};
+    let _ = &x as &Fn(i32);
+}
+
+// subtyping
+pub fn test_subtyping<'a, 'b: 'a>(a: &'a Bar, b: &'b Bar) {
+    let _ = a as &'a Bar;
+    let _ = b as &'a Bar;
+    let _ = b as &'b Bar;
+}
index dd508d6e90ca0e2633cbfad1b8ade1d94c35ff0f..50687756e2abe34f8f7b794bbf23271ead6253db 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type point = (int, int);
+// pretty-expanded FIXME #23616
 
-fn f(p: point, x: int, y: int) {
+type point = (isize, isize);
+
+fn f(p: point, x: isize, y: isize) {
     let (a, b) = p;
     assert_eq!(a, x);
     assert_eq!(b, y);
index 924b861a911c82803bc7de58f2070f095616d12c..395531d1573a1a4fb8f49b0c3f749c9593ef73cb 100644 (file)
@@ -8,14 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<'a>(&'a [int]);
+// pretty-expanded FIXME #23616
+
+struct Foo<'a>(&'a [isize]);
 
 fn main() {
-    let x: &[int] = &[1, 2, 3];
+    let x: &[isize] = &[1, 2, 3];
     let y = (x,);
     assert_eq!(y.0, x);
 
-    let x: &[int] = &[1, 2, 3];
+    let x: &[isize] = &[1, 2, 3];
     let y = Foo(x);
     assert_eq!(y.0, x);
 }
index abdf6172779307ab642c2e9bbc626eb804b62636..a70b49296fa1937be1f3bc01900dfb1a6e5d1b9f 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Point(int, int);
+// pretty-expanded FIXME #23616
+
+struct Point(isize, isize);
 
 fn main() {
     let mut x = Point(3, 2);
index 7773bf647f9988acd389129e038dd889a9dd8c07..c40adf2260dd4df196f9637a4b852d2f99742ecc 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #[derive(Debug)]
-struct Foo(int, int);
+struct Foo(isize, isize);
 
 pub fn main() {
     let x = Foo(1, 2);
index bcd62e92b4619d1edfe8972ab279a4ce13ca4b4a..90cf94666deda229e64c89b9fede310b8fc54569 100644 (file)
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 #[derive(PartialEq, Debug)]
-struct Foo(int);
+struct Foo(isize);
 #[derive(PartialEq, Debug)]
-struct Bar(int, int);
+struct Bar(isize, isize);
 
 pub fn main() {
-    let f: fn(int) -> Foo = Foo;
-    let g: fn(int, int) -> Bar = Bar;
+    let f: fn(isize) -> Foo = Foo;
+    let g: fn(isize, isize) -> Bar = Bar;
     assert_eq!(f(42), Foo(42));
     assert_eq!(g(4, 7), Bar(4, 7));
 }
index ec7675abf833738c4278267255bf14ec9d174369..4b0eb26cf9484c75808e4983855c260938fcc6b3 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo(int, int);
+struct Foo(isize, isize);
 
 pub fn main() {
     let x = Foo(1, 2);
index f50b04059532d009c37b0c1d6d389078113b667d..b37302fce0830aabf09ab3e16239d87ee12db4e1 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo(int, int);
+struct Foo(isize, isize);
 
 pub fn main() {
     let x = Foo(1, 2);
index c22c812760c78e53ca2488275c98868f881de901..fa2c9768fcb5008f5b69e3a2db9d6fab7bd6c31b 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo(int, int, int);
+// pretty-expanded FIXME #23616
+
+struct Foo(isize, isize, isize);
 
 pub fn main() {
 }
index e3b148ac92db6fbe1e4a8e6c43027176454c1fc1..4ba7e786ec8d25fcc7c5c3e2c9e90fd87c7c2831 100644 (file)
@@ -8,8 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
 
-use std::intrinsics::get_tydesc;
+#![feature(core)]
+
+use std::intrinsics::type_name;
 
 struct Foo<T> {
     x: T
@@ -17,7 +20,7 @@ struct Foo<T> {
 
 pub fn main() {
     unsafe {
-        assert_eq!((*get_tydesc::<int>()).name, "isize");
-        assert_eq!((*get_tydesc::<Foo<uint>>()).name, "Foo<usize>");
+        assert_eq!(type_name::<isize>(), "isize");
+        assert_eq!(type_name::<Foo<usize>>(), "Foo<usize>");
     }
 }
index d33ebeadba86e7008e586df25ab1a99c366b3c96..ec5aa2863a0c58494feb2567eee9d0a3fbe28f8f 100644 (file)
 // Test that type IDs correctly account for higher-rank lifetimes
 // Also acts as a regression test for an ICE (issue #19791)
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
 
-use std::any::TypeId;
+#![feature(unboxed_closures, core)]
+
+use std::any::{Any, TypeId};
 
 fn main() {
     // Bare fns
     {
-        let a = TypeId::of::<fn(&'static int, &'static int)>();
-        let b = TypeId::of::<for<'a> fn(&'static int, &'a int)>();
-        let c = TypeId::of::<for<'a, 'b> fn(&'a int, &'b int)>();
-        let d = TypeId::of::<for<'a, 'b> fn(&'b int, &'a int)>();
+        let a = TypeId::of::<fn(&'static isize, &'static isize)>();
+        let b = TypeId::of::<for<'a> fn(&'static isize, &'a isize)>();
+        let c = TypeId::of::<for<'a, 'b> fn(&'a isize, &'b isize)>();
+        let d = TypeId::of::<for<'a, 'b> fn(&'b isize, &'a isize)>();
         assert!(a != b);
         assert!(a != c);
         assert!(a != d);
@@ -30,16 +32,16 @@ fn main() {
         assert_eq!(c, d);
 
         // Make sure De Bruijn indices are handled correctly
-        let e = TypeId::of::<for<'a> fn(fn(&'a int) -> &'a int)>();
-        let f = TypeId::of::<fn(for<'a> fn(&'a int) -> &'a int)>();
+        let e = TypeId::of::<for<'a> fn(fn(&'a isize) -> &'a isize)>();
+        let f = TypeId::of::<fn(for<'a> fn(&'a isize) -> &'a isize)>();
         assert!(e != f);
     }
     // Boxed unboxed closures
     {
-        let a = TypeId::of::<Box<Fn(&'static int, &'static int)>>();
-        let b = TypeId::of::<Box<for<'a> Fn(&'static int, &'a int)>>();
-        let c = TypeId::of::<Box<for<'a, 'b> Fn(&'a int, &'b int)>>();
-        let d = TypeId::of::<Box<for<'a, 'b> Fn(&'b int, &'a int)>>();
+        let a = TypeId::of::<Box<Fn(&'static isize, &'static isize)>>();
+        let b = TypeId::of::<Box<for<'a> Fn(&'static isize, &'a isize)>>();
+        let c = TypeId::of::<Box<for<'a, 'b> Fn(&'a isize, &'b isize)>>();
+        let d = TypeId::of::<Box<for<'a, 'b> Fn(&'b isize, &'a isize)>>();
         assert!(a != b);
         assert!(a != c);
         assert!(a != d);
@@ -48,20 +50,20 @@ fn main() {
         assert_eq!(c, d);
 
         // Make sure De Bruijn indices are handled correctly
-        let e = TypeId::of::<Box<for<'a> Fn(Box<Fn(&'a int) -> &'a int>)>>();
-        let f = TypeId::of::<Box<Fn(Box<for<'a> Fn(&'a int) -> &'a int>)>>();
+        let e = TypeId::of::<Box<for<'a> Fn(Box<Fn(&'a isize) -> &'a isize>)>>();
+        let f = TypeId::of::<Box<Fn(Box<for<'a> Fn(&'a isize) -> &'a isize>)>>();
         assert!(e != f);
     }
     // Raw unboxed closures
     // Note that every unboxed closure has its own anonymous type,
     // so no two IDs should equal each other, even when compatible
     {
-        let a = id(|_: &int, _: &int| {});
-        let b = id(|_: &int, _: &int| {});
+        let a = id(|_: &isize, _: &isize| {});
+        let b = id(|_: &isize, _: &isize| {});
         assert!(a != b);
     }
 
-    fn id<T:'static>(_: T) -> TypeId {
+    fn id<T:Any>(_: T) -> TypeId {
         TypeId::of::<T>()
     }
 }
index f0b7ee072ea5eecae00270f7ea3795b45068ff71..7e2360caa93ff3d8c925a08aefda2bd764946d87 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 mod a {
     pub mod b {
-        pub type t = int;
+        pub type t = isize;
 
         pub fn foo() { let _x: t = 10; }
     }
index e9b0324456a2f951292fc29ba91fd9cabbd5b109..c03ddd0c649f51b8c501c017ae4615d9635d6e9f 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct A { a: int }
+// pretty-expanded FIXME #23616
 
-fn a(a: A) -> int { return a.a; }
+struct A { a: isize }
+
+fn a(a: A) -> isize { return a.a; }
 
 pub fn main() { let x: A = A {a: 1}; assert!((a(x) == 1)); }
index 7d1fad5d281646281ce096e2cad70b83f08a451f..381f1b6825739859af992baaaba6834d54ba778d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -16,14 +18,14 @@ fn s_foo<T>(_shared: T) { }
 fn u_foo<T:Send>(_unique: T) { }
 
 struct r {
-  i: int,
+  i: isize,
 }
 
 impl Drop for r {
     fn drop(&mut self) {}
 }
 
-fn r(i:int) -> r {
+fn r(i:isize) -> r {
     r {
         i: i
     }
@@ -32,13 +34,13 @@ fn r(i:int) -> r {
 pub fn main() {
     p_foo(r(10));
 
-    p_foo(box r(10));
-    p_foo(box 10);
+    p_foo::<Box<_>>(box r(10));
+    p_foo::<Box<_>>(box 10);
     p_foo(10);
 
-    s_foo(box 10);
+    s_foo::<Box<_>>(box 10);
     s_foo(10);
 
-    u_foo(box 10);
+    u_foo::<Box<_>>(box 10);
     u_foo(10);
 }
index 209dade8d0c8d6819141185c1cf413e461dfd222..c59e40934fb4b2762ce69a1f734fa0ab1cfaff07 100644 (file)
@@ -10,6 +10,8 @@
 
 
 
+// pretty-expanded FIXME #23616
+
 type lteq<T> = extern fn(T) -> bool;
 
 pub fn main() { }
index cf8a09998daa01b6148fc0aafade82e0b17dab95..fea2bd978eb9692975f3dff98d7f1b7a4c44b3e0 100644 (file)
@@ -9,18 +9,20 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 struct S<T> {
     a: T,
-    b: uint,
+    b: usize,
 }
 
-fn range_<F>(lo: uint, hi: uint, mut it: F) where F: FnMut(uint) {
+fn range_<F>(lo: usize, hi: usize, mut it: F) where F: FnMut(usize) {
     let mut lo_ = lo;
-    while lo_ < hi { it(lo_); lo_ += 1_usize; }
+    while lo_ < hi { it(lo_); lo_ += 1; }
 }
 
-fn create_index<T>(_index: Vec<S<T>> , _hash_fn: extern fn(T) -> uint) {
-    range_(0_usize, 256_usize, |_i| {
+fn create_index<T>(_index: Vec<S<T>> , _hash_fn: extern fn(T) -> usize) {
+    range_(0, 256, |_i| {
         let _bucket: Vec<T> = Vec::new();
     })
 }
index 410e3df9e2ac9fa28321e0b0bd25b65e1c024665..67ead80c89b2562394b5a6ac53dfae2025bbda52 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(a: *const int) -> *const int { return a; }
+// pretty-expanded FIXME #23616
 
-fn g(a: *const int) -> *const int { let b = f(a); return b; }
+fn f(a: *const isize) -> *const isize { return a; }
+
+fn g(a: *const isize) -> *const isize { let b = f(a); return b; }
 
 pub fn main() { return; }
index 961a4472bd4e7cae4ed0e1d77889f196b7ebe019..8c1251feea26984819fcfd6a8a194ce167873ddb 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem::size_of;
 
 struct t {a: u8, b: i8}
 struct u {a: u8, b: i8, c: u8}
 struct v {a: u8, b: i8, c: v2, d: u32}
 struct v2 {u: char, v: u8}
-struct w {a: int, b: ()}
-struct x {a: int, b: (), c: ()}
-struct y {x: int}
+struct w {a: isize, b: ()}
+struct x {a: isize, b: (), c: ()}
+struct y {x: isize}
 
 enum e1 {
     a(u8, u32), b(u32), c
@@ -30,26 +32,26 @@ enum e3 {
 }
 
 pub fn main() {
-    assert_eq!(size_of::<u8>(), 1 as uint);
-    assert_eq!(size_of::<u32>(), 4 as uint);
-    assert_eq!(size_of::<char>(), 4 as uint);
-    assert_eq!(size_of::<i8>(), 1 as uint);
-    assert_eq!(size_of::<i32>(), 4 as uint);
-    assert_eq!(size_of::<t>(), 2 as uint);
-    assert_eq!(size_of::<u>(), 3 as uint);
+    assert_eq!(size_of::<u8>(), 1 as usize);
+    assert_eq!(size_of::<u32>(), 4 as usize);
+    assert_eq!(size_of::<char>(), 4 as usize);
+    assert_eq!(size_of::<i8>(), 1 as usize);
+    assert_eq!(size_of::<i32>(), 4 as usize);
+    assert_eq!(size_of::<t>(), 2 as usize);
+    assert_eq!(size_of::<u>(), 3 as usize);
     // Alignment causes padding before the char and the u32.
 
     assert!(size_of::<v>() ==
-                16 as uint);
-    assert_eq!(size_of::<int>(), size_of::<uint>());
-    assert_eq!(size_of::<w>(), size_of::<int>());
-    assert_eq!(size_of::<x>(), size_of::<int>());
-    assert_eq!(size_of::<int>(), size_of::<y>());
+                16 as usize);
+    assert_eq!(size_of::<isize>(), size_of::<usize>());
+    assert_eq!(size_of::<w>(), size_of::<isize>());
+    assert_eq!(size_of::<x>(), size_of::<isize>());
+    assert_eq!(size_of::<isize>(), size_of::<y>());
 
     // Make sure enum types are the appropriate size, mostly
     // around ensuring alignment is handled properly
 
-    assert_eq!(size_of::<e1>(), 8 as uint);
-    assert_eq!(size_of::<e2>(), 8 as uint);
-    assert_eq!(size_of::<e3>(), 4 as uint);
+    assert_eq!(size_of::<e1>(), 8 as usize);
+    assert_eq!(size_of::<e2>(), 8 as usize);
+    assert_eq!(size_of::<e3>(), 4 as usize);
 }
index 99c68ac8100c8df0206a98b3cbf841f656089d1e..6cef9c3be172db89268be5d97facab133fc97b52 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::ptr;
 
 pub fn main() {
index 673e852356266bafc5c35152453260d889201923..2da8b0a508ae4106add05fbef11cbe0feb5fe9af 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum T {
-    A(int),
+    A(isize),
     B(f64)
 }
 
index 48dc944382171395ff9ccfcb36b37eec4a564b31..53e78db68b19d485d7a4b81abc9fd4cfb0cd6c08 100644 (file)
 // This test checks that the `_` type placeholder works
 // correctly for enabling type inference.
 
+// pretty-expanded FIXME #23616
+
 struct TestStruct {
-    x: *const int
+    x: *const isize
 }
 
 unsafe impl Sync for TestStruct {}
 
-static CONSTEXPR: TestStruct = TestStruct{x: &413 as *const _};
+static CONSTEXPR: TestStruct = TestStruct{ x: &413 };
 
 
 pub fn main() {
-    let x: Vec<_> = (0_usize..5).collect();
-    let expected: &[uint] = &[0,1,2,3,4];
+    let x: Vec<_> = (0..5).collect();
+    let expected: &[usize] = &[0,1,2,3,4];
     assert_eq!(x, expected);
 
-    let x = (0_usize..5).collect::<Vec<_>>();
+    let x = (0..5).collect::<Vec<_>>();
     assert_eq!(x, expected);
 
     let y: _ = "hello";
     assert_eq!(y.len(), 5);
 
-    let ptr = &5_usize;
+    let ptr: &usize = &5;
     let ptr2 = ptr as *const _;
 
-    assert_eq!(ptr as *const uint as uint, ptr2 as uint);
+    assert_eq!(ptr as *const usize as usize, ptr2 as usize);
 }
index a251fcc7327201b51e68ebaf16fdf90505f48d1b..7a143ce5889155c9be6451631b2263627d0bf214 100644 (file)
 // aux-build:typeid-intrinsic.rs
 // aux-build:typeid-intrinsic2.rs
 
-extern crate "typeid-intrinsic" as other1;
-extern crate "typeid-intrinsic2" as other2;
+// pretty-expanded FIXME #23616
+
+#![feature(hash, core)]
+
+extern crate typeid_intrinsic as other1;
+extern crate typeid_intrinsic2 as other2;
 
 use std::hash::{self, SipHasher};
 use std::any::TypeId;
@@ -44,18 +48,18 @@ pub fn main() {
         assert_eq!(other1::id_G(), other2::id_G());
         assert_eq!(other1::id_H(), other2::id_H());
 
-        assert_eq!(TypeId::of::<int>(), other2::foo::<int>());
-        assert_eq!(TypeId::of::<int>(), other1::foo::<int>());
-        assert_eq!(other2::foo::<int>(), other1::foo::<int>());
+        assert_eq!(TypeId::of::<isize>(), other2::foo::<isize>());
+        assert_eq!(TypeId::of::<isize>(), other1::foo::<isize>());
+        assert_eq!(other2::foo::<isize>(), other1::foo::<isize>());
         assert_eq!(TypeId::of::<A>(), other2::foo::<A>());
         assert_eq!(TypeId::of::<A>(), other1::foo::<A>());
         assert_eq!(other2::foo::<A>(), other1::foo::<A>());
     }
 
     // sanity test of TypeId
-    let (a, b, c) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
+    let (a, b, c) = (TypeId::of::<usize>(), TypeId::of::<&'static str>(),
                      TypeId::of::<Test>());
-    let (d, e, f) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
+    let (d, e, f) = (TypeId::of::<usize>(), TypeId::of::<&'static str>(),
                      TypeId::of::<Test>());
 
     assert!(a != b);
@@ -67,7 +71,7 @@ pub fn main() {
     assert_eq!(c, f);
 
     // check it has a hash
-    let (a, b) = (TypeId::of::<uint>(), TypeId::of::<uint>());
+    let (a, b) = (TypeId::of::<usize>(), TypeId::of::<usize>());
 
     assert_eq!(hash::hash::<TypeId, SipHasher>(&a),
                hash::hash::<TypeId, SipHasher>(&b));
index 37d06bf4f830880c8ad9c87b276855f3ab772387..86184f6cf0f4370d06f4bc7cbf5394c30b1ef6da 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 #![allow(unused_variable)]
 
index 42910c47005811e95ad887cb2f4871534774db12..c7762a8464d6baac3d536c41a1f94c453c04ec3e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let (x, y) = (10, 20);
     let z = x + y;
index 6ad320580dfec289d227aeb9d595111997b8da80..4955ac8a4be6339ff66bf1260463585c36b3ed42 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let mut word: u32 = 200000u32;
-    word = word - 1u32;
-    assert_eq!(word, 199999u32);
+    let mut word: u32 = 200000;
+    word = word - 1;
+    assert_eq!(word, 199999);
 }
index 0a178b250af4f6d635bec9ebe05a26110be8be57..7c67d304edb681afecc1647dae51c0ade32552ca 100644 (file)
 
 // These constants were chosen because they aren't used anywhere
 // in the rest of the generated code so they're easily grep-able.
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let mut x: u8 = 19u8; // 0x13
+    let mut x: u8 = 19; // 0x13
 
-    let mut y: u8 = 35u8; // 0x23
+    let mut y: u8 = 35; // 0x23
 
-    x = x + 7u8; // 0x7
+    x = x + 7; // 0x7
 
-    y = y - 9u8; // 0x9
+    y = y - 9; // 0x9
 
     assert_eq!(x, y);
 }
index 90ed3a5eec3a2fa928589d3f5aef48db8a6f3ddc..e15576c3fabce2da9d09c7feff0a2f3f1c442c32 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let mut x: u8 = 12u8;
-    let y: u8 = 12u8;
-    x = x + 1u8;
-    x = x - 1u8;
+    let mut x: u8 = 12;
+    let y: u8 = 12;
+    x = x + 1;
+    x = x - 1;
     assert_eq!(x, y);
-    // x = 14u8;
-    // x = x + 1u8;
+    // x = 14;
+    // x = x + 1;
 
 }
index 2be9f75dae12ca2b1d071c262373524ee7b8c655..bd09a311b70fb24d0fec3bc1669d0c3e87816311 100644 (file)
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Foo {
-    f: int,
+    f: isize,
 }
 
 impl Foo {
-    fn foo(self: Foo, x: int) -> int {
+    fn foo(self: Foo, x: isize) -> isize {
         self.f + x
     }
-    fn bar(self: &Foo, x: int) -> int {
+    fn bar(self: &Foo, x: isize) -> isize {
         self.f + x
     }
-    fn baz(self: Box<Foo>, x: int) -> int {
+    fn baz(self: Box<Foo>, x: isize) -> isize {
         self.f + x
     }
 }
 
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 struct Bar<T> {
     f: T,
 }
 
 impl<T> Bar<T> {
-    fn foo(self: Bar<T>, x: int) -> int {
+    fn foo(self: Bar<T>, x: isize) -> isize {
         x
     }
-    fn bar<'a>(self: &'a Bar<T>, x: int) -> int {
+    fn bar<'a>(self: &'a Bar<T>, x: isize) -> isize {
         x
     }
-    fn baz(self: Bar<T>, x: int) -> int {
+    fn baz(self: Bar<T>, x: isize) -> isize {
         x
     }
 }
 
 fn main() {
-    let foo = box Foo {
+    let foo: Box<_> = box Foo {
         f: 1,
     };
     println!("{} {} {}", foo.foo(2), foo.bar(2), foo.baz(2));
-    let bar = box Bar {
+    let bar: Box<_> = box Bar {
         f: 1,
     };
     println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
-    let bar: Box<Bar<int>> = bar;
+    let bar: Box<Bar<isize>> = bar;
     println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
 }
-
diff --git a/src/test/run-pass/ufcs-polymorphic-paths.rs b/src/test/run-pass/ufcs-polymorphic-paths.rs
new file mode 100644 (file)
index 0000000..a6ea0f7
--- /dev/null
@@ -0,0 +1,134 @@
+// 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.
+
+// pretty-expanded FIXME #23616
+
+#![feature(collections, rand, into_cow)]
+
+use std::borrow::{Cow, IntoCow};
+use std::collections::BitVec;
+use std::default::Default;
+use std::iter::FromIterator;
+use std::ops::Add;
+use std::option::IntoIter as OptionIter;
+use std::rand::Rand;
+use std::rand::XorShiftRng as DummyRng;
+// FIXME the glob std::prelude::*; import of Vec is missing non-static inherent methods.
+use std::vec::Vec;
+
+#[derive(PartialEq, Eq)]
+struct Newt<T>(T);
+
+fn id<T>(x: T) -> T { x }
+fn eq<T: Eq>(a: T, b: T) -> bool { a == b }
+fn u8_as_i8(x: u8) -> i8 { x as i8 }
+fn odd(x: usize) -> bool { x % 2 == 1 }
+fn dummy_rng() -> DummyRng { DummyRng::new_unseeded() }
+
+trait Size: Sized {
+    fn size() -> usize { std::mem::size_of::<Self>() }
+}
+impl<T> Size for T {}
+
+macro_rules! tests {
+    ($($expr:expr, $ty:ty, ($($test:expr),*);)+) => (pub fn main() {$({
+        const C: $ty = $expr;
+        static S: $ty = $expr;
+        assert!(eq(C($($test),*), $expr($($test),*)));
+        assert!(eq(S($($test),*), $expr($($test),*)));
+        assert!(eq(C($($test),*), S($($test),*)));
+    })+})
+}
+
+tests! {
+    // Free function.
+    id, fn(i32) -> i32, (5);
+    id::<i32>, fn(i32) -> i32, (5);
+
+    // Enum variant constructor.
+    Some, fn(i32) -> Option<i32>, (5);
+    Some::<i32>, fn(i32) -> Option<i32>, (5);
+
+    // Tuple struct constructor.
+    Newt, fn(i32) -> Newt<i32>, (5);
+    Newt::<i32>, fn(i32) -> Newt<i32>, (5);
+
+    // Inherent static methods.
+    Vec::new, fn() -> Vec<()>, ();
+    Vec::<()>::new, fn() -> Vec<()>, ();
+    <Vec<()>>::new, fn() -> Vec<()>, ();
+    Vec::with_capacity, fn(usize) -> Vec<()>, (5);
+    Vec::<()>::with_capacity, fn(usize) -> Vec<()>, (5);
+    <Vec<()>>::with_capacity, fn(usize) -> Vec<()>, (5);
+    BitVec::from_fn, fn(usize, fn(usize) -> bool) -> BitVec, (5, odd);
+    BitVec::from_fn::<fn(usize) -> bool>, fn(usize, fn(usize) -> bool) -> BitVec, (5, odd);
+
+    // Inherent non-static method.
+    Vec::map_in_place, fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>, (vec![b'f', b'o', b'o'], u8_as_i8);
+    Vec::map_in_place::<i8, fn(u8) -> i8>, fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>,
+        (vec![b'f', b'o', b'o'], u8_as_i8);
+    // FIXME these break with "type parameter might not appear here pointing at `<u8>`.
+    // Vec::<u8>::map_in_place: fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>
+    //    , (vec![b'f', b'o', b'o'], u8_as_i8);
+    // Vec::<u8>::map_in_place::<i8, fn(u8) -> i8>: fn(Vec<u8>, fn(u8) -> i8) -> Vec<i8>
+    //    , (vec![b'f', b'o', b'o'], u8_as_i8);
+
+    // Trait static methods.
+    bool::size, fn() -> usize, ();
+    <bool>::size, fn() -> usize, ();
+    <bool as Size>::size, fn() -> usize, ();
+
+    Default::default, fn() -> i32, ();
+    i32::default, fn() -> i32, ();
+    <i32>::default, fn() -> i32, ();
+    <i32 as Default>::default, fn() -> i32, ();
+
+    Rand::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
+    i32::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
+    <i32>::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
+    <i32 as Rand>::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
+    Rand::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
+    i32::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
+    <i32>::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
+    <i32 as Rand>::rand::<DummyRng>, fn(&mut DummyRng) -> i32, (&mut dummy_rng());
+
+    // Trait non-static methods.
+    Clone::clone, fn(&i32) -> i32, (&5);
+    i32::clone, fn(&i32) -> i32, (&5);
+    <i32>::clone, fn(&i32) -> i32, (&5);
+    <i32 as Clone>::clone, fn(&i32) -> i32, (&5);
+
+    FromIterator::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());
+    Vec::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());
+    <Vec<_>>::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());
+    <Vec<_> as FromIterator<_>>::from_iter, fn(OptionIter<i32>) -> Vec<i32>,
+        (Some(5).into_iter());
+    <Vec<i32> as FromIterator<_>>::from_iter, fn(OptionIter<i32>) -> Vec<i32>,
+        (Some(5).into_iter());
+    FromIterator::from_iter::<OptionIter<i32>>, fn(OptionIter<i32>) -> Vec<i32>,
+        (Some(5).into_iter());
+    <Vec<i32> as FromIterator<_>>::from_iter::<OptionIter<i32>>, fn(OptionIter<i32>) -> Vec<i32>,
+        (Some(5).into_iter());
+
+    Add::add, fn(i32, i32) -> i32, (5, 6);
+    i32::add, fn(i32, i32) -> i32, (5, 6);
+    <i32>::add, fn(i32, i32) -> i32, (5, 6);
+    <i32 as Add<_>>::add, fn(i32, i32) -> i32, (5, 6);
+    <i32 as Add<i32>>::add, fn(i32, i32) -> i32, (5, 6);
+
+    String::into_cow, fn(String) -> Cow<'static, str>,
+        ("foo".to_string());
+    <String>::into_cow, fn(String) -> Cow<'static, str>,
+        ("foo".to_string());
+    <String as IntoCow<_>>::into_cow, fn(String) -> Cow<'static, str>,
+        ("foo".to_string());
+    <String as IntoCow<'static, _>>::into_cow, fn(String) -> Cow<'static, str>,
+        ("foo".to_string());
+}
index 2ae63040d17850c373b507aeeea377fa03332a41..b242018458dfc073214c208480e15fe6ee3a3120 100644 (file)
@@ -11,6 +11,8 @@
 // Test that when you use ufcs form to invoke a trait method (on a
 // trait object) everything works fine.
 
+// pretty-expanded FIXME #23616
+
 trait Foo {
     fn test(&self) -> i32;
 }
@@ -20,6 +22,6 @@ impl Foo for i32 {
 }
 
 fn main() {
-    let a: &Foo = &22_i32;
+    let a: &Foo = &22;
     assert_eq!(Foo::test(a), 22);
 }
index ccd5a225222da2e29bcbde97da17aa5cba88b76a..d72fde1a3332fb904d3692b6567eff565cb87502 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Foo<T> {
     fn get(&self) -> T;
 }
index 876e37c5351c15bec8c573d7b518fcd0ef133c90..a894d762979300f4f088cd1eec22a74e2686533f 100644 (file)
@@ -11,4 +11,6 @@
 
 
 
-pub fn main() { let _x: uint = 10 as uint; }
+// pretty-expanded FIXME #23616
+
+pub fn main() { let _x: usize = 10 as usize; }
index adbbf1aec9afc1204f15cf58d0c0c96b1fba8c6a..9d685e0263f22c007988fb52cda9d2f8e9e6a0e9 100644 (file)
@@ -26,7 +26,7 @@ pub fn main() {
     println!("{}", d_neg);
 
     let e = 1;
-    let e_neg: int = -e;
+    let e_neg: isize = -e;
     println!("{}", e_neg);
 
     // intentional overflows
@@ -48,6 +48,6 @@ pub fn main() {
     println!("{}", i_neg);
 
     let j = 1;
-    let j_neg: uint = -j;
+    let j_neg: usize = -j;
     println!("{}", j_neg);
 }
index 7e71e1da462fd1efc71fc771507939ec6b21723d..9ca8e5403a1302fc93e995e50140da65cacc2a2e 100644 (file)
@@ -8,24 +8,25 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(lang_items, unboxed_closures)]
 
-fn a<F:Fn(int, int) -> int>(f: F) -> int {
+fn a<F:Fn(isize, isize) -> isize>(f: F) -> isize {
     f(1, 2)
 }
 
-fn b<F:FnMut(int, int) -> int>(mut f: F) -> int {
+fn b<F:FnMut(isize, isize) -> isize>(mut f: F) -> isize {
     f(3, 4)
 }
 
-fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
+fn c<F:FnOnce(isize, isize) -> isize>(f: F) -> isize {
     f(5, 6)
 }
 
 fn main() {
-    let z: int = 7;
-    assert_eq!(a(move |x: int, y| x + y + z), 10);
-    assert_eq!(b(move |x: int, y| x + y + z), 14);
-    assert_eq!(c(move |x: int, y| x + y + z), 18);
+    let z: isize = 7;
+    assert_eq!(a(move |x: isize, y| x + y + z), 10);
+    assert_eq!(b(move |x: isize, y| x + y + z), 14);
+    assert_eq!(c(move |x: isize, y| x + y + z), 18);
 }
-
diff --git a/src/test/run-pass/unboxed-closures-blanket-fn-mut.rs b/src/test/run-pass/unboxed-closures-blanket-fn-mut.rs
new file mode 100644 (file)
index 0000000..37dccca
--- /dev/null
@@ -0,0 +1,37 @@
+// 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 you can supply `&F` where `F: FnMut()`.
+
+// pretty-expanded FIXME #23616
+
+#![feature(lang_items, unboxed_closures)]
+
+fn a<F:FnMut() -> i32>(mut f: F) -> i32 {
+    f()
+}
+
+fn b(f: &mut FnMut() -> i32) -> i32 {
+    a(f)
+}
+
+fn c<F:FnMut() -> i32>(f: &mut F) -> i32 {
+    a(f)
+}
+
+fn main() {
+    let z: isize = 7;
+
+    let x = b(&mut || 22);
+    assert_eq!(x, 22);
+
+    let x = c(&mut || 22);
+    assert_eq!(x, 22);
+}
diff --git a/src/test/run-pass/unboxed-closures-blanket-fn.rs b/src/test/run-pass/unboxed-closures-blanket-fn.rs
new file mode 100644 (file)
index 0000000..0f93966
--- /dev/null
@@ -0,0 +1,37 @@
+// 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 you can supply `&F` where `F: Fn()`.
+
+// pretty-expanded FIXME #23616
+
+#![feature(lang_items, unboxed_closures)]
+
+fn a<F:Fn() -> i32>(f: F) -> i32 {
+    f()
+}
+
+fn b(f: &Fn() -> i32) -> i32 {
+    a(f)
+}
+
+fn c<F:Fn() -> i32>(f: &F) -> i32 {
+    a(f)
+}
+
+fn main() {
+    let z: isize = 7;
+
+    let x = b(&|| 22);
+    assert_eq!(x, 22);
+
+    let x = c(&|| 22);
+    assert_eq!(x, 22);
+}
index d515ccf2ec0a50ca8e4367210004e298b2850a05..5dea6a7c6db3bba73ffb0ff8e23aecffd52cee03 100644 (file)
@@ -25,4 +25,3 @@ pub fn main() {
     println!("{}", z);
     assert_eq!(z, 5);
 }
-
index 178865897e5a9c9e940eea13f5c17481879a8310..7855cf6ba0c2a1e1ded5373f90a46c10fb78248c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 // Test by-ref capture of environment in unboxed closure types
index 0303954ce2a96733e122810f1fd5e872d630b9f9..6e92850ac2e592a942c044d3b300b6e84d1873c2 100644 (file)
 
 // Test that the call operator autoderefs when calling a bounded type parameter.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 use std::ops::FnMut;
 
-fn call_with_2(x: &fn(int) -> int) -> int
+fn call_with_2(x: &fn(isize) -> isize) -> isize
 {
     x(2) // look ma, no `*`
 }
 
-fn subtract_22(x: int) -> int { x - 22 }
+fn subtract_22(x: isize) -> isize { x - 22 }
 
 pub fn main() {
-    let subtract_22: fn(int) -> int = subtract_22;
+    let subtract_22: fn(isize) -> isize = subtract_22;
     let z = call_with_2(&subtract_22);
     assert_eq!(z, -20);
 }
index 305f496e668a8a97a7ea2b302651e10d5aba326b..402b4b0b85d4b36355eda1d368de0a405f785c5c 100644 (file)
 
 // Test that the call operator autoderefs when calling a bounded type parameter.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 use std::ops::FnMut;
 
-fn call_with_2<F>(x: &mut F) -> int
-    where F : FnMut(int) -> int
+fn call_with_2<F>(x: &mut F) -> isize
+    where F : FnMut(isize) -> isize
 {
     x(2) // look ma, no `*`
 }
index da647e90c00f6fdbb4b3389d2fbce7bcd0708838..c82026235c2a35a12a028fb885ab06f88e0b7b7f 100644 (file)
 // Test that the call operator autoderefs when calling to an object type.
 
 #![allow(unknown_features)]
-#![feature(box_syntax)]
 #![feature(unboxed_closures)]
 
 use std::ops::FnMut;
 
-fn make_adder(x: int) -> Box<FnMut(int)->int + 'static> {
-    box move |y| { x + y }
+fn make_adder(x: isize) -> Box<FnMut(isize)->isize + 'static> {
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    Box::new(move |y| { x + y })
 }
 
 pub fn main() {
@@ -26,4 +26,3 @@ pub fn main() {
     println!("{}", z);
     assert_eq!(z, 5);
 }
-
index 8ee3c96f580d1edb6521039950d50b779b98321a..629da1091ac5bfd153ab101b515ea6c1cbda5a10 100644 (file)
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 #![allow(unknown_features)]
-#![feature(box_syntax)]
 #![feature(unboxed_closures)]
 
 use std::ops::FnMut;
 
-fn make_adder(x: int) -> Box<FnMut(int)->int + 'static> {
-    box move |y| { x + y }
+fn make_adder(x: isize) -> Box<FnMut(isize)->isize + 'static> {
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    Box::new(move |y| { x + y })
 }
 
 pub fn main() {
@@ -24,4 +24,3 @@ pub fn main() {
     println!("{}", z);
     assert_eq!(z, 5);
 }
-
index 0b85916d224108922dc2b3bd735cf5464def66ce..792d17227766e34b6cb32729d11f0f7fe3354393 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test that we mutate a counter on the stack only when we expect to.
 
+// pretty-expanded FIXME #23616
+
 fn call<F>(f: F) where F : FnOnce() {
     f();
 }
index 96d75592627bec6e41e67f1a66dbd91a6cb36840..0c255c6bd6cb807beec069f05257cfba8b29cb3d 100644 (file)
@@ -12,7 +12,9 @@
 // Acts as a regression test for #16790, #18378 and #18543
 
 // aux-build:unboxed-closures-cross-crate.rs
-extern crate "unboxed-closures-cross-crate" as ubcc;
+// pretty-expanded FIXME #23616
+
+extern crate unboxed_closures_cross_crate as ubcc;
 
 fn main() {
     assert_eq!(ubcc::has_closures(), 2_usize);
index 0c49c8151708625ac095a0a639a9410240a6ffe4..c91aa6ed0d923e0523ec19a67cdb860fd538cebb 100644 (file)
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 fn main() {
     let mut unboxed = || {};
     unboxed();
 }
-
index f4a24c17e6e99834736346f868bb66bd8a46df9b..f0c6c0ff453ffc39141897ae02832f10e6d5082e 100644 (file)
 // A battery of tests to ensure destructors of unboxed closure environments
 // run at the right times.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
-static mut DROP_COUNT: uint = 0;
+static mut DROP_COUNT: usize = 0;
 
-fn drop_count() -> uint {
+fn drop_count() -> usize {
     unsafe {
         DROP_COUNT
     }
 }
 
 struct Droppable {
-    x: int,
+    x: isize,
 }
 
 impl Droppable {
@@ -41,27 +43,27 @@ impl Drop for Droppable {
     }
 }
 
-fn a<F:Fn(int, int) -> int>(f: F) -> int {
+fn a<F:Fn(isize, isize) -> isize>(f: F) -> isize {
     f(1, 2)
 }
 
-fn b<F:FnMut(int, int) -> int>(mut f: F) -> int {
+fn b<F:FnMut(isize, isize) -> isize>(mut f: F) -> isize {
     f(3, 4)
 }
 
-fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
+fn c<F:FnOnce(isize, isize) -> isize>(f: F) -> isize {
     f(5, 6)
 }
 
 fn test_fn() {
     {
-        a(move |a: int, b| { a + b });
+        a(move |a: isize, b| { a + b });
     }
     assert_eq!(drop_count(), 0);
 
     {
         let z = &Droppable::new();
-        a(move |a: int, b| { z; a + b });
+        a(move |a: isize, b| { z; a + b });
         assert_eq!(drop_count(), 0);
     }
     assert_eq!(drop_count(), 1);
@@ -69,7 +71,7 @@ fn test_fn() {
     {
         let z = &Droppable::new();
         let zz = &Droppable::new();
-        a(move |a: int, b| { z; zz; a + b });
+        a(move |a: isize, b| { z; zz; a + b });
         assert_eq!(drop_count(), 1);
     }
     assert_eq!(drop_count(), 3);
@@ -77,13 +79,13 @@ fn test_fn() {
 
 fn test_fn_mut() {
     {
-        b(move |a: int, b| { a + b });
+        b(move |a: isize, b| { a + b });
     }
     assert_eq!(drop_count(), 3);
 
     {
         let z = &Droppable::new();
-        b(move |a: int, b| { z; a + b });
+        b(move |a: isize, b| { z; a + b });
         assert_eq!(drop_count(), 3);
     }
     assert_eq!(drop_count(), 4);
@@ -91,7 +93,7 @@ fn test_fn_mut() {
     {
         let z = &Droppable::new();
         let zz = &Droppable::new();
-        b(move |a: int, b| { z; zz; a + b });
+        b(move |a: isize, b| { z; zz; a + b });
         assert_eq!(drop_count(), 4);
     }
     assert_eq!(drop_count(), 6);
@@ -99,13 +101,13 @@ fn test_fn_mut() {
 
 fn test_fn_once() {
     {
-        c(move |a: int, b| { a + b });
+        c(move |a: isize, b| { a + b });
     }
     assert_eq!(drop_count(), 6);
 
     {
         let z = Droppable::new();
-        c(move |a: int, b| { z; a + b });
+        c(move |a: isize, b| { z; a + b });
         assert_eq!(drop_count(), 7);
     }
     assert_eq!(drop_count(), 7);
@@ -113,7 +115,7 @@ fn test_fn_once() {
     {
         let z = Droppable::new();
         let zz = Droppable::new();
-        c(move |a: int, b| { z; zz; a + b });
+        c(move |a: isize, b| { z; zz; a + b });
         assert_eq!(drop_count(), 9);
     }
     assert_eq!(drop_count(), 9);
@@ -124,4 +126,3 @@ fn main() {
     test_fn_mut();
     test_fn_once();
 }
-
index df753f0f33eb6550d7e4e302c84eba83155c5afe..4af4b320d0e4ea82c4af88ca2f33128592e44b3e 100644 (file)
 
 // Checks that higher-ranked extern fn pointers implement the full range of Fn traits.
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, core)]
 
 use std::ops::{Fn,FnMut,FnOnce};
 
-fn square(x: &int) -> int { (*x) * (*x) }
+fn square(x: &isize) -> isize { (*x) * (*x) }
 
-fn call_it<F:Fn(&int)->int>(f: &F, x: int) -> int {
+fn call_it<F:Fn(&isize)->isize>(f: &F, x: isize) -> isize {
     (*f)(&x)
 }
 
-fn call_it_boxed(f: &Fn(&int) -> int, x: int) -> int {
+fn call_it_boxed(f: &Fn(&isize) -> isize, x: isize) -> isize {
     f.call((&x,))
 }
 
-fn call_it_mut<F:FnMut(&int)->int>(f: &mut F, x: int) -> int {
+fn call_it_mut<F:FnMut(&isize)->isize>(f: &mut F, x: isize) -> isize {
     (*f)(&x)
 }
 
-fn call_it_once<F:FnOnce(&int)->int>(f: F, x: int) -> int {
+fn call_it_once<F:FnOnce(&isize)->isize>(f: F, x: isize) -> isize {
     f(&x)
 }
 
@@ -42,4 +44,3 @@ fn main() {
     assert_eq!(y, square(&22));
     assert_eq!(z, square(&22));
 }
-
index a25f5e265e81494a8f7eb4db4867f0d3e053a7b6..d711ebbe4b8c243d957dd55d5ddd04128d33cece 100644 (file)
 
 // Checks that extern fn pointers implement the full range of Fn traits.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 #![feature(unboxed_closures)]
 
 use std::ops::{Fn,FnMut,FnOnce};
 
-fn square(x: int) -> int { x * x }
+fn square(x: isize) -> isize { x * x }
 
-fn call_it<F:Fn(int)->int>(f: &F, x: int) -> int {
+fn call_it<F:Fn(isize)->isize>(f: &F, x: isize) -> isize {
     f(x)
 }
 
-fn call_it_mut<F:FnMut(int)->int>(f: &mut F, x: int) -> int {
+fn call_it_mut<F:FnMut(isize)->isize>(f: &mut F, x: isize) -> isize {
     f(x)
 }
 
-fn call_it_once<F:FnOnce(int)->int>(f: F, x: int) -> int {
+fn call_it_once<F:FnOnce(isize)->isize>(f: F, x: isize) -> isize {
     f(x)
 }
 
@@ -37,4 +39,3 @@ fn main() {
     assert_eq!(y, square(22));
     assert_eq!(z, square(22));
 }
-
index 5d6029e703b82bca13ea7affc4cd0cd50da7e06c..9b71abf3653318c21fbc558cdb07822bba9845a5 100644 (file)
 // Checks that the Fn trait hierarchy rules permit
 // any Fn trait to be used where Fn is implemented.
 
-#![feature(unboxed_closures)]
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, core)]
 
 use std::ops::{Fn,FnMut,FnOnce};
 
 struct S;
 
 impl Fn<(i32,)> for S {
-    type Output = i32;
     extern "rust-call" fn call(&self, (x,): (i32,)) -> i32 {
         x * x
     }
 }
 
+impl FnMut<(i32,)> for S {
+    extern "rust-call" fn call_mut(&mut self, args: (i32,)) -> i32 { self.call(args) }
+}
+
+impl FnOnce<(i32,)> for S {
+    type Output = i32;
+    extern "rust-call" fn call_once(self, args: (i32,)) -> i32 { self.call(args) }
+}
+
 fn call_it<F:Fn(i32)->i32>(f: &F, x: i32) -> i32 {
     f(x)
 }
@@ -44,4 +53,3 @@ fn main() {
     assert_eq!(x, y);
     assert_eq!(y, z);
 }
-
index 95dae41c6840e301240643dde94f97eb06e87797..6261058b86742a2f9d4edc91597ab03ef65e2638 100644 (file)
 // Checks that the Fn trait hierarchy rules permit
 // FnMut or FnOnce to be used where FnMut is implemented.
 
-#![feature(unboxed_closures)]
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, core)]
 
 use std::ops::{FnMut,FnOnce};
 
 struct S;
 
 impl FnMut<(i32,)> for S {
-    type Output = i32;
-
     extern "rust-call" fn call_mut(&mut self, (x,): (i32,)) -> i32 {
         x * x
     }
 }
 
+impl FnOnce<(i32,)> for S {
+    type Output = i32;
+
+    extern "rust-call" fn call_once(mut self, args: (i32,)) -> i32 { self.call_mut(args) }
+}
+
 fn call_it_mut<F:FnMut(i32)->i32>(f: &mut F, x: i32) -> i32 {
     f(x)
 }
@@ -39,4 +44,3 @@ fn main() {
     let z = call_it_once(S, 22);
     assert_eq!(y, z);
 }
-
index f4af42a866b6d6a83c478c60311f7b46165f3c2e..47936ba938284264e5900195721f6a85873d6d5a 100644 (file)
@@ -22,4 +22,3 @@ pub fn main() {
     println!("{}", z);
     assert_eq!(z, 5);
 }
-
index 56de15961101f063f9da4785c6e6eb1c0086a919..d408612f9b8569e2846a5b91b950b901f38dabdd 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test that we are able to infer that the type of `x` is `int` based
+// Test that we are able to infer that the type of `x` is `isize` based
 // on the expected type from the object.
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, core)]
 
 use std::num::ToPrimitive;
 
@@ -22,5 +24,5 @@ fn doit<T,F>(val: T, f: &F)
 }
 
 pub fn main() {
-    doit(0, &|x /*: int*/ | { x.to_int(); });
+    doit(0, &|x /*: isize*/ | { x.to_int(); });
 }
index c74ed665e7a071d9d70f6c98c306a5e44538245b..c1e1ff3cd8e93738c5404c50c52f5b0ac65d72b4 100644 (file)
@@ -8,15 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test that we are able to infer that the type of `x` is `int` based
+// Test that we are able to infer that the type of `x` is `isize` based
 // on the expected type from the object.
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, core)]
 
 use std::num::ToPrimitive;
 
 fn doit<T>(val: T, f: &Fn(T)) { f.call((val,)) }
 
 pub fn main() {
-    doit(0, &|x /*: int*/ | { x.to_int(); });
+    doit(0, &|x /*: isize*/ | { x.to_int(); });
 }
index a61dd095a0d4da2e6792afcc1bfeef3bb8637e8a..99e2149de966a3e759a19c2d31a75fcba12dc020 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test that we are able to infer that the type of `x` is `int` based
+// Test that we are able to infer that the type of `x` is `isize` based
 // on the expected type from the object.
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, core)]
 
 use std::num::ToPrimitive;
 
@@ -22,5 +24,5 @@ fn doit<T,F>(val: T, f: &F)
 }
 
 pub fn main() {
-    doit(0, &|x /*: int*/ | { x.to_int(); });
+    doit(0, &|x /*: isize*/ | { x.to_int(); });
 }
index 09b8c8f4454b5ea3e11a9e1ba9134b1063fb18ea..798959f69d6879c83a6c2e7ec9ad921514bcf204 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we are able to infer a suitable kind for this closure
 // that is just called (`FnMut`).
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let mut counter = 0;
 
@@ -26,4 +28,3 @@ fn main() {
 
     assert_eq!(counter, 2);
 }
-
index 794527249bffaaf55d9da303bbd046c70de181e9..5b1e35a3e5c724f67d4b510636871f1f45aaf28f 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we are able to infer a suitable kind for this `move`
 // closure that is just called (`FnMut`).
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let mut counter = 0;
 
index 67f36b9a9203cfa0fe04b69df050ef7eb7665151..cd7f26bba2676813e325a314024a8bc0a2377b35 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we are able to infer a suitable kind for this closure
 // that is just called (`FnMut`).
 
+// pretty-expanded FIXME #23616
+
 fn main() {
     let mut counter = 0;
 
index 9f8fc80819bfd39331be9016d3de78e9ad4264ab..dc106614b53dd890b3963a4381da6a5ebbac31c1 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 
 // Test that we are able to infer a suitable kind for this `move`
index f0f10139c5b86fa3d4570789098fd1c4d5c58b9e..036b32a44d2557f30e88b524389403cb9efd1d9b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 
 // Test that we are able to infer a suitable kind for this closure
index 36c8400be7879dc1291fe1fdbea45a435555e8e5..edc01d91f58fc2e110cbc7d5e4b7ffddbdf330c8 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we can infer the "kind" of an unboxed closure based on
 // the expected type.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 // Test by-ref capture of environment in unboxed closure types
index 2d1ba7f39b27bbd8115525bf99c077c64d635279..e02784f917a97e71ca134242bfd9013ac55f188c 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(core,unboxed_closures)]
 
 use std::marker::PhantomData;
@@ -30,13 +32,20 @@ impl<F,A,R> YCombinator<F,A,R> {
 }
 
 impl<A,R,F : Fn(&Fn(A) -> R, A) -> R> Fn<(A,)> for YCombinator<F,A,R> {
-    type Output = R;
-
     extern "rust-call" fn call(&self, (arg,): (A,)) -> R {
         (self.func)(self, arg)
     }
 }
 
+impl<A,R,F : Fn(&Fn(A) -> R, A) -> R> FnMut<(A,)> for YCombinator<F,A,R> {
+    extern "rust-call" fn call_mut(&mut self, args: (A,)) -> R { self.call(args) }
+}
+
+impl<A,R,F : Fn(&Fn(A) -> R, A) -> R> FnOnce<(A,)> for YCombinator<F,A,R> {
+    type Output = R;
+    extern "rust-call" fn call_once(self, args: (A,)) -> R { self.call(args) }
+}
+
 fn main() {
     let factorial = |recur: &Fn(u32) -> u32, arg: u32| -> u32 {
         if arg == 0 {1} else {arg * recur(arg-1)}
index 087ef5dcf05e4a08bc529f342eb174f596269434..e29632b007b3fdc188bd4201efb181e148995236 100644 (file)
@@ -11,6 +11,8 @@
 // Test that the type variable in the type(`Vec<_>`) of a closed over
 // variable does not interfere with type inference.
 
+// pretty-expanded FIXME #23616
+
 fn f<F: FnMut()>(mut f: F) {
     f();
 }
@@ -18,5 +20,5 @@ fn f<F: FnMut()>(mut f: F) {
 fn main() {
     let mut v: Vec<_> = vec![];
     f(|| v.push(0));
-    assert_eq!(v, vec![0]);
+    assert_eq!(v, [0]);
 }
index 37075de0405ad884e303e244abad07db5fe83f98..38f15d6e4499b30c7f970eb83ebb482bbf025b45 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,20 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(unboxed_closures)]
+// pretty-expanded FIXME #23616
+
+#![feature(unboxed_closures, core)]
 
 use std::ops::FnMut;
 
 struct S;
 
 impl FnMut<(i32,)> for S {
-    type Output = i32;
-
     extern "rust-call" fn call_mut(&mut self, (x,): (i32,)) -> i32 {
         x * x
     }
 }
 
+impl FnOnce<(i32,)> for S {
+    type Output = i32;
+
+    extern "rust-call" fn call_once(mut self, args: (i32,)) -> i32 { self.call_mut(args) }
+}
+
 fn call_it<F:FnMut(i32)->i32>(mut f: F, x: i32) -> i32 {
     f(x) + 3
 }
@@ -37,4 +42,3 @@ fn main() {
     assert!(x == 4);
     assert!(y == 4);
 }
-
index 535c4562362c0d3ba9620e768aa66a9855ba4ad3..f16f757c6456f91952feab04138a70ffa5898711 100644 (file)
 
 #![allow(unknown_features)]
 #![feature(box_syntax)]
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, core)]
 
 fn main(){
     fn bar<'a, T:Clone+'a> (t: T) -> Box<FnMut()->T + 'a> {
-        box move || t.clone()
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        Box::new(move || t.clone())
     }
 
     let mut f = bar(42_u32);
@@ -31,7 +32,7 @@ fn main(){
     assert_eq!(f.call_mut(()), &x);
 
     #[derive(Clone, Copy, Debug, PartialEq)]
-    struct Foo(uint, &'static str);
+    struct Foo(usize, &'static str);
 
     let x = Foo(42, "forty-two");
     let mut f = bar(x);
index 069e93b86baaa7352b00d456dfae9f6438b63027..1aca3174e1fed9cc5514d2331486e941ae77cac2 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 #![deny(unused_mut)]
 
@@ -16,7 +18,7 @@
 // mutably so we do not get a spurious warning about it not needing to
 // be declared mutable (issue #18336 and #18769)
 
-fn set(x: &mut uint) { *x = 42; }
+fn set(x: &mut usize) { *x = 42; }
 
 fn main() {
     {
index 99663646254e73969c9a22bfeabbb40d26749540..b69153b73a3693bbc83a481a3fe9497b587f34bd 100644 (file)
@@ -11,6 +11,8 @@
 // Test that in a by-ref once closure we move some variables even as
 // we capture others by mutable reference.
 
+// pretty-expanded FIXME #23616
+
 fn call<F>(f: F) where F : FnOnce() {
     f();
 }
index c8f0d5fde45efea490bee262988152a5cd764987..313fb67637e08d4448d9ab72638200895aea9ba5 100644 (file)
 
 // Tests that the reexports of `FnOnce` et al from the prelude work.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
-#![feature(unboxed_closures)]
+#![feature(unboxed_closures, core)]
 
 fn main() {
-    let task: Box<Fn(int) -> int> = box |x| x;
+    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+    let task: Box<Fn(isize) -> isize> = Box::new(|x| x);
     task.call((0, ));
 
-    let mut task: Box<FnMut(int) -> int> = box |x| x;
+    let mut task: Box<FnMut(isize) -> isize> = Box::new(|x| x);
     task(0);
 
     call(|x| x, 22);
 }
 
-fn call<F:FnOnce(int) -> int>(f: F, x: int) -> int {
+fn call<F:FnOnce(isize) -> isize>(f: F, x: isize) -> isize {
     f(x)
 }
-
index 9f29e75be7ccaec301935a0a4b14b38188291fec..1443d305bce940f5d430a0a7d94dbae3c6911c1b 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 use std::ops::FnMut;
 
 pub fn main() {
-    let mut f = |x: int, y: int| -> int { x + y };
+    let mut f = |x: isize, y: isize| -> isize { x + y };
     let z = f(1, 2);
     assert_eq!(z, 3);
 }
index 9e543f925f82e2acdc60e1f1f5e0eb6b9a8be197..65a26d14e120bd3aa1b8216be02baab881448d2e 100644 (file)
 // Ensures that single-word environments work right in unboxed closures.
 // These take a different path in codegen.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
-fn a<F:Fn(int, int) -> int>(f: F) -> int {
+fn a<F:Fn(isize, isize) -> isize>(f: F) -> isize {
     f(1, 2)
 }
 
-fn b<F:FnMut(int, int) -> int>(mut f: F) -> int {
+fn b<F:FnMut(isize, isize) -> isize>(mut f: F) -> isize {
     f(3, 4)
 }
 
-fn c<F:FnOnce(int, int) -> int>(f: F) -> int {
+fn c<F:FnOnce(isize, isize) -> isize>(f: F) -> isize {
     f(5, 6)
 }
 
 fn main() {
     let z = 10;
-    assert_eq!(a(move |x: int, y| x + y + z), 13);
-    assert_eq!(b(move |x: int, y| x + y + z), 17);
-    assert_eq!(c(move |x: int, y| x + y + z), 21);
+    assert_eq!(a(move |x: isize, y| x + y + z), 13);
+    assert_eq!(b(move |x: isize, y| x + y + z), 17);
+    assert_eq!(c(move |x: isize, y| x + y + z), 21);
 }
-
index 7a6b68a5e09ec27113ad716f830cf6e5d120f68a..e90a3443610cb302addd834e1597a47d7dcd1209 100644 (file)
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 fn main() {
     let onetime = |x| x;
     onetime(0);
 }
-
index fff841a2f052d6511b77e04b1364ab609b1e72d6..77beeb13fb0295696126410de8c71aad2db7b41b 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test unboxed closure sugar used in object types.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 #![feature(unboxed_closures)]
 
index 5c36832d9f67f50557abd1d0034578bd224e9d8f..403b2ca9aaf39df74b95a18c234a7dafb49578b7 100644 (file)
 //
 //    error: internal compiler error: get_unique_type_id_of_type() -
 //    unexpected type: closure,
-//    ty_closure(syntax::ast::DefId{krate: 0u32, node: 66u32},
-//    ReScope(63u32))
+//    ty_closure(syntax::ast::DefId{krate: 0, node: 66},
+//    ReScope(63))
 //
 // This is a regression test for issue #17021.
 //
 // compile-flags: -g
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 use std::ptr;
@@ -28,8 +30,8 @@ pub fn replace_map<'a, T, F>(src: &mut T, prod: F) where F: FnOnce(T) -> T {
 }
 
 pub fn main() {
-    let mut a = 7_usize;
+    let mut a = 7;
     let b = &mut a;
-    replace_map(b, |x: uint| x * 2);
-    assert_eq!(*b, 14_usize);
+    replace_map(b, |x: usize| x * 2);
+    assert_eq!(*b, 14);
 }
index 8e3d44df798a7679333ad85536e334b4d73c906c..cb3a18a18c13a0480d74df161e5bb81bb449c7c1 100644 (file)
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 fn main() {
     let mut zero = || {};
     let () = zero();
 }
-
index 2af38047264fcf72f06ef428f3150d41f6ff8901..fceccb499c7b0e0baba97c09fca33260b2bfc405 100644 (file)
 
 // no-pretty-expanded FIXME #15189
 
+// pretty-expanded FIXME #23616
+
+#![feature(core)]
+
 use std::iter::Unfold;
 
 // Unfold had a bug with 'a that mean it didn't work
 // cross-crate
 
 pub fn main() {
-    fn count(st: &mut uint) -> Option<uint> {
+    fn count(st: &mut usize) -> Option<usize> {
         if *st < 10 {
             let ret = Some(*st);
             *st += 1;
index 1a65f685a5e82cb803c1a3a53a2195a8511ba955..01b55ebb8e26ef6aa191aa6c03a28dab8db3f777 100644 (file)
@@ -12,6 +12,8 @@
 // unified with the type *T, and so the type variable
 // in that type gets resolved.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
 fn null<T>() -> *const T {
@@ -20,4 +22,4 @@ fn null<T>() -> *const T {
     }
 }
 
-pub fn main() { null::<int>(); }
+pub fn main() { null::<isize>(); }
index a0cf984cbb901512bcc763c03ea52f2ff7d86fca..8c69704b3bd19441bb3c239fa0d5796a213e1b3a 100644 (file)
@@ -10,6 +10,8 @@
 
 // Test the uninit() construct returning various empty types.
 
+// pretty-expanded FIXME #23616
+
 use std::mem;
 
 #[derive(Clone)]
index b7980ed9021e2f9a241b01ccf131e724e0ea54bf..a6408128c3a28197f738afaa610306f9c1aa5ab8 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 struct X {
-    a: int
+    a: isize
 }
 
 trait Changer {
@@ -27,7 +29,7 @@ impl Changer for X {
 }
 
 pub fn main() {
-    let x = box X { a: 32 };
+    let x: Box<_> = box X { a: 32 };
     let new_x = x.change();
     assert_eq!(new_x.a, 55);
 }
index c19063fe46483e796bb66b287b989ab3f9e1deae..32a0713ca9397368d8853307f839a22e6d53abbf 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let mut i = box 1;
+    let mut i: Box<_> = box 1;
     // Should be a copy
     let mut j;
     j = i.clone();
index 241258f089c56cdf7fb95207ea0f121b365899b2..715fa548a7d767541d30206d1629e05bf99c5fa5 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_assignment)]
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let i = box 1;
-    let mut j = box 2;
+    let i: Box<_> = box 1;
+    let mut j: Box<_> = box 2;
     // Should drop the previous value of j
     j = i;
     assert_eq!(*j, 1);
index c8abb0808482fb813b3de7d03be0eaab10f8ee72..ca145479a381f939179f64c3fc3f6498176c41f5 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -18,6 +20,6 @@ fn f<T>(t: T) -> T {
 }
 
 pub fn main() {
-    let t = f(box 100);
+    let t = f::<Box<_>>(box 100);
     assert_eq!(t, box 100);
 }
index cbcb6afb4c88c51ac1bc901d6bf2cc9c0fdf06a6..e4e7b69671b8205ab1611fab3a77b13c15fb591b 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let mut i;
+    let mut i: Box<_>;
     i = box 1;
     assert_eq!(*i, 1);
 }
index aab7f4108fba659f5a2099ab3ad1058a26b04bd4..8ee1b28ea2e7ebfeca8d78e4c0eeaaa332f957a7 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct J { j: int }
+struct J { j: isize }
 
 pub fn main() {
-    let i = box J {
+    let i: Box<_> = box J {
         j: 100
     };
     assert_eq!(i.j, 100);
index 30c4b2d7b565cb5a8d991517a3e9e46d8665ab40..9dc98cf2e3c47db7245a73612809b84c017e5fbe 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let i = box vec!(100);
+    let i: Box<_> = box vec!(100);
     assert_eq!((*i)[0], 100);
 }
index a2962dc00d50300f34fac08b58d7e99697f472e8..be7e46c8699d7c0c32a3332a9e836278f363862a 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let i = box 100;
+    let i: Box<_> = box 100;
     assert!(i == box 100);
     assert!(i < box 101);
     assert!(i <= box 100);
index e4099c94c2f1a6e93941fc059f41f9d747535d08..ce5a2bed48de0e3bde72b17fe2a3f70c3f648107 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    enum t { t1(int), t2(int), }
+    enum t { t1(isize), t2(isize), }
 
-    let _x = box t::t1(10);
+    let _x: Box<_> = box t::t1(10);
 
     /*alt *x {
       t1(a) {
index 975f1e9da827f42245b551a67ccd7cbf9794d7ca..8469ae702009a72b95cfc6343f75a17029543a59 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    box 100;
+    let _: Box<_> = box 100;
 }
 
 fn vec() {
index 3af38784add9fbf1687e371f623295f92666563c..0840f1308cc1f530084eb7ed4e709d297a8dd364 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let mut i = box 1;
+    let mut i: Box<_> = box 1;
     // Should be a copy
     let mut j = i.clone();
     *i = 2;
index c9192748809af7a23b3d67c51ff3de686751b15e..1d5a44f45abbaa0ea4dbcbb2a688cb566708fa32 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let i = box 1;
+    let i: Box<_> = box 1;
     let j = i;
     assert_eq!(*j, 1);
 }
index 96dd9f51fbe8fb4c0d11b5c1efcc1ef80fe971bd..203a30e76bc1a5f00b484fedef56c6f4965926bd 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let i = box 100;
+    let i: Box<_> = box 100;
     let j = i;
     assert_eq!(*j, 100);
 }
index a902fef288f002dff362435962264d8573ae728e..7404e8887ebce1b0e9b889699f74b4c508e8ac1e 100644 (file)
@@ -9,10 +9,12 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let _: Box<int>;
+    let _: Box<isize>;
 }
 
-fn f(_i: Box<int>) -> Box<int> {
+fn f(_i: Box<isize>) -> Box<isize> {
     panic!();
 }
index 41d3b87a003c0e8bf7b0d30289cb2c8bc02b3124..44681742a7041129d22a919442d9fdc41e2bcc51 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let i = box 100;
+    let i: Box<_> = box 100;
     assert_eq!(*i, 100);
 }
index 9e71e850b3d4f69eefeb73d562a79d6ecb73e543..87bc6f6639d653cee89858cd8537068ba10cbcce 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
-struct Foo { a: int, b: int }
+struct Foo { a: isize, b: isize }
 
 pub fn main() {
     let box Foo{a, b} = box Foo{a: 100, b: 200};
index c5a0a4df2751da32803a7bdd0f36a2e408c1c334..056acd162082b795468cda8e7abf3b54eae8222f 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let _x = box vec!(0,0,0,0,0);
+    let _x: Box<_> = box vec!(0,0,0,0,0);
 }
index 1b3f7e72a4d61eb9e699e70b8a424d919bac2c0a..e608ab9b6367a1761abb9393bd425e04efe9c5b5 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn f(i: Box<int>) {
+fn f(i: Box<isize>) {
     assert_eq!(*i, 100);
 }
 
index e1d148cc9a555359d912a7777da1f124f2f21df3..f0d2abfe27cbcb14b988f6c240e58c20b47ee7b5 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn f(i: &mut Box<int>) {
+fn f(i: &mut Box<isize>) {
     *i = box 200;
 }
 
index 301994a74a85a6c5ca519227e86da6648f411fc8..3d7ef31d020e7a9c22ce5c51422d67dc1e64eb7b 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn f(i: Box<int>) {
+fn f(i: Box<isize>) {
     assert_eq!(*i, 100);
 }
 
index de2c265089bedfc1d2fdd1e36d9697bd0cbd9592..bb1948bf3c81bca99b6bd82d7dc005c7946aabf9 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-fn f() -> Box<int> {
+fn f() -> Box<isize> {
     box 100
 }
 
index 58470637a11e56bfdd828fd60cd06caaa234a331..2da3b9f05f68e1a17e84fb198a15762d8f73357a 100644 (file)
@@ -11,6 +11,8 @@
 // Issue #976
 
 
+// pretty-expanded FIXME #23616
+
 fn f<T>(x: Box<T>) {
     let _x2 = x;
 }
index 4f02018346bdb6b9ae9b90c45b133a8af3249501..0762b37ff8b89dd8f2873d6462af9dbcdd3838bf 100644 (file)
@@ -12,7 +12,7 @@
 #![feature(box_syntax)]
 
 fn test1() {
-    enum bar { u(Box<int>), w(int), }
+    enum bar { u(Box<isize>), w(isize), }
 
     let x = bar::u(box 10);
     assert!(match x {
index 3bde79fdce01be2c897aeec55285969293aff81d..129c0784cca5e85cbb16bdf3876d82a1e5f3afda 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let mut a = vec!(box 10);
+    let mut a: Vec<Box<_>> = vec!(box 10);
     let b = a.clone();
 
     assert_eq!(*a[0], 10);
index 05b0c7244deece4475096a0f13767794319f48d8..dc94fa6ca4fce89cacfe0903be68c4be64ab50b5 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let vect = vec!(box 100);
+    let vect : Vec<Box<_>> = vec!(box 100);
     assert!(vect[0] == box 100);
 }
index d3f13f1609f7551b936d7b8cef1060b679143060..bd7a64952604cf90b9316d5518b50c0d674320ee 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let _i = box 100;
+    let _i: Box<_> = box 100;
 }
index 4c93c379b488a0d428540eb627ffce80f5d9797f..96d54193ac86d1eca0f42e3d821fd3f5bfe8ec27 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
@@ -23,11 +25,11 @@ fn sendable() {
         assert!(i != j);
     }
 
-    let i = box 100;
-    let j = box 100;
+    let i: Box<_> = box 100;
+    let j: Box<_> = box 100;
     f(i, j);
-    let i = box 100;
-    let j = box 101;
+    let i: Box<_> = box 100;
+    let j: Box<_> = box 101;
     g(i, j);
 }
 
@@ -41,11 +43,11 @@ fn copyable() {
         assert!(i != j);
     }
 
-    let i = box 100;
-    let j = box 100;
+    let i: Box<_> = box 100;
+    let j: Box<_> = box 100;
     f(i, j);
-    let i = box 100;
-    let j = box 101;
+    let i: Box<_> = box 100;
+    let j: Box<_> = box 101;
     g(i, j);
 }
 
@@ -59,11 +61,11 @@ fn noncopyable() {
         assert!(i != j);
     }
 
-    let i = box 100;
-    let j = box 100;
+    let i: Box<_> = box 100;
+    let j: Box<_> = box 100;
     f(i, j);
-    let i = box 100;
-    let j = box 101;
+    let i: Box<_> = box 100;
+    let j: Box<_> = box 101;
     g(i, j);
 }
 
index 4b21b949f8836bd0b4d3883456013cea4862b605..148ca4757ae927eccb8f1c5cb89e20f19a27c52f 100644 (file)
@@ -12,6 +12,6 @@
 #![feature(box_syntax)]
 
 pub fn main() {
-    let i = box 100;
+    let i: Box<_> = box 100;
     println!("{}", i);
 }
index a1502c2eb8c0fa3ffda2425bf0e3984a7510fdf2..1b0392341e72d9ab40e85fb63d4fc88366896c32 100644 (file)
 
 // Issue #961
 
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// pretty-expanded FIXME #23616
 
 fn altsimple() {
-    match box true {
+    match Box::new(true) {
       _ => { }
     }
 }
index 705b9d6e92c53193212bed767210aebaaa97f089..e81095d548e07daa834a49c99ae174b7840b2238 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unused_variable)]
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let i = box 100;
-    let j = box 200;
+    let i: Box<_> = box 100;
+    let j: Box<_> = box 200;
     let j = i;
     assert_eq!(*j, 100);
 }
index b6c24f5be289a7a6e4b4f1c8532af04a1369eadb..634a1569acffdb8cfc8e1ec629c86ae9128781c9 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let mut i;
+    let mut i: Box<_>;
     i = box 100;
     assert_eq!(*i, 100);
 }
index ed13bf6a5c4f931378ba65f57ad14dd47bbea572..29bf113926572b572f38a2d910f56dc7b201cb84 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let i = box 100;
+    let i: Box<_> = box 100;
     let mut j;
     j = i;
     assert_eq!(*j, 100);
index 403b8bf18b823f31d357995039bf33318ad3ec23..106481e3189eed750dd8b724a60c4359b398ff9e 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let mut i = box 0;
+    let mut i: Box<_> = box 0;
     *i = 1;
     assert_eq!(*i, 1);
 }
index f01a56142e0730184635b00609050db1ce8333c6..4d120e7caf36528568335a8abab5b1d8ef8a6075 100644 (file)
 
 // Issue #5192
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub trait EventLoop { fn foo(&self) {} }
 
 pub struct UvEventLoop {
-    uvio: int
+    uvio: isize
 }
 
 impl EventLoop for UvEventLoop { }
index 5db96bc3564f56d39f6bdfcb4c90cb7573640e74..d16355af99fd55df392fb23e35251d76b768a9e1 100644 (file)
@@ -8,17 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
-struct Foo {a: int, b: uint}
+struct Foo {a: isize, b: usize}
 
-enum bar { u(Box<Foo>), w(int), }
+enum bar { u(Box<Foo>), w(isize), }
 
 pub fn main() {
-    assert!(match bar::u(box Foo{a: 10, b: 40_usize}) {
-              bar::u(box Foo{a: a, b: b}) => { a + (b as int) }
+    assert!(match bar::u(box Foo{a: 10, b: 40}) {
+              bar::u(box Foo{a: a, b: b}) => { a + (b as isize) }
               _ => { 66 }
             } == 50);
 }
index 42a4b1a9c0cbfc5c11db1b5998e8f8955ce88dd0..648e9599a979e994dfbff2d9d86eea91ed96fe15 100644 (file)
@@ -11,7 +11,7 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-enum bar { u(Box<int>), w(int), }
+enum bar { u(Box<isize>), w(isize), }
 
 pub fn main() {
     assert!(match bar::u(box 10) {
index bff2d4e917faee1211040a869f3eb158bb84392d..ae76179b5ec2243b79ba7ddcaacf8d0a6c32366f 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
index 756911d29fc8c3b3da3390898922bb17442186a6..7a09e241ca63983b429630a0f46118e49fc9e077 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-struct X { x: int }
+struct X { x: isize }
 
 pub fn main() {
-    let x = box X {x: 1};
+    let x: Box<_> = box X {x: 1};
     let bar = x;
     assert_eq!(bar.x, 1);
 }
index 43824812ec546c44a6f90c6adf8f8f5d19d475f0..99a3b64105318fd11b01aea77c5cd347b0139034 100644 (file)
@@ -8,30 +8,32 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 use std::sync::mpsc::{channel, Sender};
 use std::thread;
 
-fn child(tx: &Sender<Box<uint>>, i: uint) {
+fn child(tx: &Sender<Box<usize>>, i: usize) {
     tx.send(box i).unwrap();
 }
 
 pub fn main() {
     let (tx, rx) = channel();
-    let n = 100_usize;
-    let mut expected = 0_usize;
-    let _t = (0_usize..n).map(|i| {
+    let n = 100;
+    let mut expected = 0;
+    let _t = (0..n).map(|i| {
         expected += i;
         let tx = tx.clone();
-        thread::spawn(move|| {
+        thread::scoped(move|| {
             child(&tx, i)
         })
     }).collect::<Vec<_>>();
 
-    let mut actual = 0_usize;
-    for _ in 0_usize..n {
+    let mut actual = 0;
+    for _ in 0..n {
         let j = rx.recv().unwrap();
         actual += *j;
     }
index 2a462e9cdd83ca72b35e99835e14e29e19b09eb2..c9649ef60d303145e7109db52d2da68e6c5da40e 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 use std::sync::mpsc::channel;
 
 pub fn main() {
-    let (tx, rx) = channel();
+    let (tx, rx) = channel::<Box<_>>();
     tx.send(box 100).unwrap();
     let v = rx.recv().unwrap();
     assert_eq!(v, box 100);
index 2adb9c22f60c1563aebde48ccd08c6e3ac9b3640..454011a9ec31e8f8c5f1960d5cac9960f00ec35e 100644 (file)
@@ -8,14 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 use std::mem::swap;
 
 pub fn main() {
-    let mut i = box 100;
-    let mut j = box 200;
+    let mut i: Box<_> = box 100;
+    let mut j: Box<_> = box 200;
     swap(&mut i, &mut j);
     assert_eq!(i, box 200);
     assert_eq!(j, box 100);
index ac46187f03a71d90f09c3859a529b235779a52e7..c2db63ed251a5c72420d8189102f54cb230d5895 100644 (file)
 
 // Make sure the destructor is run for unit-like structs.
 
-use std::boxed::BoxAny;
+// pretty-expanded FIXME #23616
+
+#![feature(alloc)]
+
 use std::thread;
 
 struct Foo;
@@ -26,6 +29,6 @@ pub fn main() {
         let _b = Foo;
     }).join();
 
-    let s = x.err().unwrap().downcast::<&'static str>().ok().unwrap();
+    let s = x.err().unwrap().downcast::<&'static str>().unwrap();
     assert_eq!(&**s, "This panic should happen.");
 }
index 3b52dcce4bf61207840c02395c8484d7e5197c1c..2679c4c033121111574ef566c4cecea176ef5558 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unused_variable)]
 #![allow(dead_assignment)]
 
index d22a6652e16f3d29333ae449a4dca4b29a474737..d498a70be491eb64b463193761b388f99cd64633 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn good(_a: &int) {
+// pretty-expanded FIXME #23616
+
+fn good(_a: &isize) {
 }
 
-// unnamed argument &int is now parse x: &int
+// unnamed argument &isize is now parse x: &isize
 
-fn called<F>(_f: F) where F: FnOnce(&int) {
+fn called<F>(_f: F) where F: FnOnce(&isize) {
 }
 
 pub fn main() {
index d8a8913e58ad9b1bc8fdcd5cd34893940db3fa23..612beabb03586d74f3ad94f122862016993fc179 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unreachable_code)]
 #![allow(unused_variable)]
 
index a28dc2c1f1599669a465843b290c8913dcea3387..4f58df66256be5d0ca2979fb86cccc1dd30f60c1 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(path_statement)]
 #![allow(unreachable_code)]
 #![allow(unused_variable)]
diff --git a/src/test/run-pass/unsafe-coercion.rs b/src/test/run-pass/unsafe-coercion.rs
new file mode 100644 (file)
index 0000000..d0c633e
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2013-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 that safe fns are not a subtype of unsafe fns.
+
+// pretty-expanded FIXME #23616
+
+fn foo(x: i32) -> i32 {
+    x * 22
+}
+
+fn bar(x: fn(i32) -> i32) -> unsafe fn(i32) -> i32 {
+    x // OK, coercion!
+}
+
+fn main() {
+    let f = bar(foo);
+    let x = unsafe { f(2) };
+    assert_eq!(x, 44);
+}
index 4ce3f2c53b3e0c7e6a646c50afb5ec92f66dea17..f3a2ad749a16824c1f0cff7c0c4f20d4f110f8b9 100644 (file)
@@ -11,6 +11,8 @@
 //
 // See also: compile-fail/unsafe-fn-called-from-safe.rs
 
+// pretty-expanded FIXME #23616
+
 unsafe fn f() { return; }
 
 fn g() {
index e68b868a246940e0222c84da8200db98e6589d96..37c72ba8ab06565bb5cc9173a6fd823c0905a992 100644 (file)
@@ -11,6 +11,8 @@
 //
 // See also: compile-fail/unsafe-fn-called-from-safe.rs
 
+// pretty-expanded FIXME #23616
+
 unsafe fn f() { return; }
 
 unsafe fn g() {
index 7a624109a5507a72defdb859f0f53699737829a3..75c7cabfcb6d392865d678a999d3616df6218d63 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(x: *const int) {
+// pretty-expanded FIXME #23616
+
+fn f(x: *const isize) {
     unsafe {
         assert_eq!(*x, 3);
     }
index ae175d27b0a4ea09b08f9ae0bdbd75e7de00032a..8ff8169ef497cb89ae4320240f1778cae5919996 100644 (file)
@@ -7,11 +7,11 @@
 // <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.
-//
-// ignore-lexer-test FIXME #15879
 
 // Test syntax checks for `?Sized` syntax.
 
+// pretty-expanded FIXME #23616
+
 use std::marker::{PhantomData, PhantomFn};
 
 trait T1 : PhantomFn<Self> { }
index 10b2f2fb7092423c2a2e77c772baf71b68abed31..965ce6bad1668bf006e17383eef554ae43ceff86 100644 (file)
@@ -7,8 +7,8 @@
 // <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.
-//
-// ignore-lexer-test FIXME #15879
+
+// pretty-expanded FIXME #23616
 
 #![allow(unknown_features)]
 #![feature(box_syntax)]
@@ -96,14 +96,14 @@ struct S2<X: ?Sized> {
     f: X,
 }
 struct S3<X: ?Sized> {
-    f1: int,
+    f1: isize,
     f2: X,
 }
 enum E<X: ?Sized> {
     V1(X),
     V2{x: X},
-    V3(int, X),
-    V4{u: int, x: X},
+    V3(isize, X),
+    V4{u: isize, x: X},
 }
 
 pub fn main() {
index 983152cd056d9ba7747bc856f5fed89c8323f275..8db294bdcc1c055df7632cd63e5f23952d80a24a 100644 (file)
 
 // Test structs with always-unsized fields.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
-#![feature(box_syntax)]
+#![feature(box_syntax, core)]
 
 use std::mem;
 use std::raw;
+use std::slice;
 
 struct Foo<T> {
     f: [T],
 }
 
 struct Bar {
-    f1: uint,
-    f2: [uint],
+    f1: usize,
+    f2: [usize],
 }
 
 struct Baz {
-    f1: uint,
+    f1: usize,
     f2: str,
 }
 
 trait Tr {
-    fn foo(&self) -> uint;
+    fn foo(&self) -> usize;
 }
 
 struct St {
-    f: uint
+    f: usize
 }
 
 impl Tr for St {
-    fn foo(&self) -> uint {
+    fn foo(&self) -> usize {
         self.f
     }
 }
@@ -66,20 +69,19 @@ pub fn main() {
             f: [T; 3]
         }
 
-        let data = box Foo_{f: [1i32, 2, 3] };
-        let x: &Foo<i32> = mem::transmute(raw::Slice { len: 3, data: &*data });
+        let data: Box<Foo_<i32>> = box Foo_{f: [1, 2, 3] };
+        let x: &Foo<i32> = mem::transmute(slice::from_raw_parts(&*data, 3));
         assert!(x.f.len() == 3);
         assert!(x.f[0] == 1);
-        assert!(x.f[1] == 2);
-        assert!(x.f[2] == 3);
 
         struct Baz_ {
-            f1: uint,
+            f1: usize,
             f2: [u8; 5],
         }
 
-        let data = box Baz_{ f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] };
-        let x: &Baz = mem::transmute( raw::Slice { len: 5, data: &*data } );
+        let data: Box<_> = box Baz_ {
+            f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] };
+        let x: &Baz = mem::transmute(slice::from_raw_parts(&*data, 5));
         assert!(x.f1 == 42);
         let chs: Vec<char> = x.f2.chars().collect();
         assert!(chs.len() == 5);
@@ -96,7 +98,7 @@ pub fn main() {
         let obj: Box<St> = box St { f: 42 };
         let obj: &Tr = &*obj;
         let obj: raw::TraitObject = mem::transmute(&*obj);
-        let data = box Qux_{ f: St { f: 234 } };
+        let data: Box<_> = box Qux_{ f: St { f: 234 } };
         let x: &Qux = mem::transmute(raw::TraitObject { vtable: obj.vtable,
                                                         data: mem::transmute(&*data) });
         assert!(x.f.foo() == 234);
index 4e8fdda95631185c9fc4541c41e4af2b947c3491..b155620e5196ce4d58af4f6080137abe868ae497 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
-    let _x = box 1;
+    let _x: Box<_> = box 1;
     let lam_move = || {};
     lam_move();
 }
index d053b03a2ca8a298da6942129e7ce943cfbbd2fc..015b6f80946f837e2925783054574271058b6bf8 100644 (file)
 // Issue Name: Unused move causes a crash
 // Abstract: zero-fill to block after drop
 
+// pretty-expanded FIXME #23616
+
 #![allow(path_statement)]
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main()
 {
-    let y = box 1;
+    let y: Box<_> = box 1;
     y;
 }
index 52c09aadfbd7b17a34afa25a7472359f27d0677d..449e500edbe846345be09cb01ef50404d9f6aef9 100644 (file)
@@ -37,7 +37,8 @@ fn f(tx: Sender<bool>) {
 
 pub fn main() {
     let (tx, rx) = channel();
-    let _t = thread::spawn(move|| f(tx.clone()));
+    let t = thread::spawn(move|| f(tx.clone()));
     println!("hiiiiiiiii");
     assert!(rx.recv().unwrap());
+    drop(t.join());
 }
index d38b6e79eba66bccffd5632e441f5c9c345e31d4..1d6ce626c28c542641b08273916af7ad847ee73c 100644 (file)
@@ -8,16 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 use std::thread;
 
 fn f() {
-    let _a = box 0;
+    let _a: Box<_> = box 0;
     panic!();
 }
 
 pub fn main() {
-    let _t = thread::spawn(f);
+    let t = thread::spawn(f);
+    drop(t.join());
 }
index 4751b4666f1d59e2e7aeb3062c82730a5df464e6..98594183a00d0e95c79df10781901db98f6a5c87 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // Issue #1706
-extern crate "std" as stdlib;
+// pretty-expanded FIXME #23616
+
+extern crate std as stdlib;
 
 pub fn main() {}
index ec8033ff3b04e193343b755d92609c22a36e2e4a..044472606a53090e0711386977283c61f68a2896 100644 (file)
 
 
 
+// pretty-expanded FIXME #23616
+
 mod foo {
-    pub fn x() -> int { return 1; }
+    pub fn x() -> isize { return 1; }
 }
 
 mod bar {
-    pub fn y() -> int { return 1; }
+    pub fn y() -> isize { return 1; }
 }
 
 pub fn main() { foo::x(); bar::y(); }
index cca9c8f2df422cbb6b78f76eb2b01793a7491517..49ad171eaa2b6ff699cbebb22f91ff5441ff53a0 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub use foo::bar::{self, First};
 use self::bar::Second;
 
index 0b59ced98c908f4362a58c25e667aafc52e04da1..38952334e4d58800c2fe90f985352443515c4e53 100644 (file)
@@ -10,6 +10,8 @@
 
 // Issue #1761
 
-impl foo for int { fn foo(&self) -> int { 10 } }
-trait foo { fn foo(&self) -> int; }
+// pretty-expanded FIXME #23616
+
+impl foo for isize { fn foo(&self) -> isize { 10 } }
+trait foo { fn foo(&self) -> isize; }
 pub fn main() {}
index efa6a2c583421e13d1b35ec14d7cd6a397701721..9e606384f3fa1f1b058183335230b547fabf6ea5 100644 (file)
@@ -10,8 +10,8 @@
 
 
 
-fn foo<T>(o: myoption<T>) -> int {
-    let mut x: int = 5;
+fn foo<T>(o: myoption<T>) -> isize {
+    let mut x: isize = 5;
     match o {
         myoption::none::<T> => { }
         myoption::some::<T>(_t) => { x += 1; }
index f2b487b70341b367e3bdd3f3f4e11aed894a5e19..dc0a6a26bc0250d6f43d12cd87aafbc47c7428c9 100644 (file)
@@ -10,8 +10,8 @@
 
 
 
-fn foo<T>(o: myoption<T>) -> int {
-    let mut x: int;
+fn foo<T>(o: myoption<T>) -> isize {
+    let mut x: isize;
     match o {
         myoption::none::<T> => { panic!(); }
         myoption::some::<T>(_t) => { x = 5; }
index 65a392e63c51001007737b1046f3dc31f692871f..40ab4c86c6f253c76ff2f5f59adebe1c27b8ef76 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
@@ -9,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unused_imports)]
 #![feature(start, no_std)]
 #![no_std]
 
 extern crate std;
-extern crate "std" as zed;
+extern crate std as zed;
 
 use std::str;
 use zed::str as x;
@@ -23,4 +24,4 @@ mod baz {
 }
 
 #[start]
-pub fn start(_: int, _: *const *const u8) -> int { 0 }
+pub fn start(_: isize, _: *const *const u8) -> isize { 0 }
index 18cb478be38fdba0f88471734e23b659a5d935ae..0f55a357a00f48c791e8865028c42a3e862463f7 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:inline_dtor.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate inline_dtor;
 
 pub fn main() {
index 96bba01068f2b3ecb722497931c7f9ba70c93688..07fd7b297b4247e29c0a82c36b2a36094df3b9a8 100644 (file)
@@ -18,14 +18,14 @@ pub fn main() {
     let y_diaeresis: char = 'ÿ'; // 0xff
     let pi: char = 'Π'; // 0x3a0
 
-    assert_eq!(yen as int, 0xa5);
-    assert_eq!(c_cedilla as int, 0xe7);
-    assert_eq!(thorn as int, 0xfe);
-    assert_eq!(y_diaeresis as int, 0xff);
-    assert_eq!(pi as int, 0x3a0);
+    assert_eq!(yen as isize, 0xa5);
+    assert_eq!(c_cedilla as isize, 0xe7);
+    assert_eq!(thorn as isize, 0xfe);
+    assert_eq!(y_diaeresis as isize, 0xff);
+    assert_eq!(pi as isize, 0x3a0);
 
-    assert_eq!(pi as int, '\u03a0' as int);
-    assert_eq!('\x0a' as int, '\n' as int);
+    assert_eq!(pi as isize, '\u{3a0}' as isize);
+    assert_eq!('\x0a' as isize, '\n' as isize);
 
     let bhutan: String = "འབྲུག་ཡུལ།".to_string();
     let japan: String = "日本".to_string();
@@ -33,21 +33,21 @@ pub fn main() {
     let austria: String = "Österreich".to_string();
 
     let bhutan_e: String =
-        "\u0f60\u0f56\u0fb2\u0f74\u0f42\u0f0b\u0f61\u0f74\u0f63\u0f0d".to_string();
-    let japan_e: String = "\u65e5\u672c".to_string();
+        "\u{f60}\u{f56}\u{fb2}\u{f74}\u{f42}\u{f0b}\u{f61}\u{f74}\u{f63}\u{f0d}".to_string();
+    let japan_e: String = "\u{65e5}\u{672c}".to_string();
     let uzbekistan_e: String =
-        "\u040e\u0437\u0431\u0435\u043a\u0438\u0441\u0442\u043e\u043d".to_string();
-    let austria_e: String = "\u00d6sterreich".to_string();
+        "\u{40e}\u{437}\u{431}\u{435}\u{43a}\u{438}\u{441}\u{442}\u{43e}\u{43d}".to_string();
+    let austria_e: String = "\u{d6}sterreich".to_string();
 
     let oo: char = 'Ö';
-    assert_eq!(oo as int, 0xd6);
+    assert_eq!(oo as isize, 0xd6);
 
     fn check_str_eq(a: String, b: String) {
-        let mut i: int = 0;
+        let mut i: isize = 0;
         for ab in a.bytes() {
             println!("{}", i);
             println!("{}", ab);
-            let bb: u8 = b.as_bytes()[i as uint];
+            let bb: u8 = b.as_bytes()[i as usize];
             println!("{}", bb);
             assert_eq!(ab, bb);
             i += 1;
index 84f605eef57001f1a1a60b268e5f2781a5e420f9..45a3f2327aaa6b559f4e2c71c438658497028c1a 100644 (file)
 //
 // ignore-lexer-test FIXME #15679
 
+#![feature(collections, core, str_char)]
+
 use std::str;
 
 pub fn main() {
     // Chars of 1, 2, 3, and 4 bytes
-    let chs: Vec<char> = vec!('e', 'é', '€', '\U00010000');
+    let chs: Vec<char> = vec!('e', 'é', '€', '\u{10000}');
     let s: String = chs.iter().cloned().collect();
     let schs: Vec<char> = s.chars().collect();
 
-    assert!(s.len() == 10_usize);
-    assert!(s.chars().count() == 4_usize);
-    assert!(schs.len() == 4_usize);
+    assert!(s.len() == 10);
+    assert!(s.chars().count() == 4);
+    assert!(schs.len() == 4);
     assert!(schs.iter().cloned().collect::<String>() == s);
-    assert!(s.char_at(0_usize) == 'e');
-    assert!(s.char_at(1_usize) == 'é');
+    assert!(s.char_at(0) == 'e');
+    assert!(s.char_at(1) == 'é');
 
     assert!((str::from_utf8(s.as_bytes()).is_ok()));
     // invalid prefix
-    assert!((!str::from_utf8(&[0x80_u8]).is_ok()));
+    assert!((!str::from_utf8(&[0x80]).is_ok()));
     // invalid 2 byte prefix
-    assert!((!str::from_utf8(&[0xc0_u8]).is_ok()));
-    assert!((!str::from_utf8(&[0xc0_u8, 0x10_u8]).is_ok()));
+    assert!((!str::from_utf8(&[0xc0]).is_ok()));
+    assert!((!str::from_utf8(&[0xc0, 0x10]).is_ok()));
     // invalid 3 byte prefix
-    assert!((!str::from_utf8(&[0xe0_u8]).is_ok()));
-    assert!((!str::from_utf8(&[0xe0_u8, 0x10_u8]).is_ok()));
-    assert!((!str::from_utf8(&[0xe0_u8, 0xff_u8, 0x10_u8]).is_ok()));
+    assert!((!str::from_utf8(&[0xe0]).is_ok()));
+    assert!((!str::from_utf8(&[0xe0, 0x10]).is_ok()));
+    assert!((!str::from_utf8(&[0xe0, 0xff, 0x10]).is_ok()));
     // invalid 4 byte prefix
-    assert!((!str::from_utf8(&[0xf0_u8]).is_ok()));
-    assert!((!str::from_utf8(&[0xf0_u8, 0x10_u8]).is_ok()));
-    assert!((!str::from_utf8(&[0xf0_u8, 0xff_u8, 0x10_u8]).is_ok()));
-    assert!((!str::from_utf8(&[0xf0_u8, 0xff_u8, 0xff_u8, 0x10_u8]).is_ok()));
+    assert!((!str::from_utf8(&[0xf0]).is_ok()));
+    assert!((!str::from_utf8(&[0xf0, 0x10]).is_ok()));
+    assert!((!str::from_utf8(&[0xf0, 0xff, 0x10]).is_ok()));
+    assert!((!str::from_utf8(&[0xf0, 0xff, 0xff, 0x10]).is_ok()));
 }
index beb2f4d996910b9fcbe55613e087888e42627e0f..b11b7e83eb6713e979e948c88febf567fc41c765 100644 (file)
@@ -22,7 +22,7 @@ pub fn main() {
     assert_eq!(საჭმელად_გემრიელი_სადილი(), 0);
 }
 
-fn საჭმელად_გემრიელი_სადილი() -> int {
+fn საჭმელად_გემრიელი_სადილი() -> isize {
 
     // Lunch in several languages.
 
index 5a476ed9ee2f89958d02a0cbb6abd8537eace2d0..d81dc3afcd7af05d03d7ba52212eba2edeac57da 100644 (file)
@@ -8,12 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc, std_misc)]
+
 extern crate libc;
 
-use std::ffi::{self, CString};
+use std::ffi::{CStr, CString};
 use libc::{c_char, c_int};
 
-// ignore-fast doesn't like extern crate
 
 extern {
     fn sprintf(s: *mut c_char, format: *const c_char, ...) -> c_int;
@@ -22,18 +25,18 @@ extern {
 unsafe fn check<T, F>(expected: &str, f: F) where F: FnOnce(*mut c_char) -> T {
     let mut x = [0 as c_char; 50];
     f(&mut x[0] as *mut c_char);
-    assert_eq!(expected.as_bytes(), ffi::c_str_to_bytes(&x.as_ptr()));
+    assert_eq!(expected.as_bytes(), CStr::from_ptr(x.as_ptr()).to_bytes());
 }
 
 pub fn main() {
 
     unsafe {
         // Call with just the named parameter
-        let c = CString::new(b"Hello World\n").unwrap();
+        let c = CString::new(&b"Hello World\n"[..]).unwrap();
         check("Hello World\n", |s| sprintf(s, c.as_ptr()));
 
         // Call with variable number of arguments
-        let c = CString::new(b"%d %f %c %s\n").unwrap();
+        let c = CString::new(&b"%d %f %c %s\n"[..]).unwrap();
         check("42 42.500000 a %d %f %c %s\n\n", |s| {
             sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr());
         });
@@ -44,11 +47,11 @@ pub fn main() {
         // A function that takes a function pointer
         unsafe fn call(p: unsafe extern fn(*mut c_char, *const c_char, ...) -> c_int) {
             // Call with just the named parameter
-            let c = CString::new(b"Hello World\n").unwrap();
+            let c = CString::new(&b"Hello World\n"[..]).unwrap();
             check("Hello World\n", |s| sprintf(s, c.as_ptr()));
 
             // Call with variable number of arguments
-            let c = CString::new(b"%d %f %c %s\n").unwrap();
+            let c = CString::new(&b"%d %f %c %s\n"[..]).unwrap();
             check("42 42.500000 a %d %f %c %s\n\n", |s| {
                 sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr());
             });
index 948d68e0ccd7d7d84c402166413f4aa1c5ed8129..e21ea025d8ff4390ec900137eb4473bac862d7e6 100644 (file)
 // us from approximating the lifetimes of `field1` and `field2` to a
 // common intersection.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
+#![feature(core)]
 
 struct List<'l> {
     field1: &'l i32,
index 10441bee3cb9ff8381434ea6c040c4cf1c2e8d31..5a179bfc7d47f8b28c1384e822df68b2a660433d 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
 
 // Get<T> is covariant in T
@@ -45,5 +47,3 @@ fn main() {
     let y = get(&x);
     assert_eq!(y, 23);
 }
-
-
index caec6df5a4d81a56c5c16da8999f8a11786209e4..2f554c3c4f3f5f9854ba7ce2d9c22fafe4482d39 100644 (file)
 
 // Test that vec is now covariant in its argument type.
 
+// pretty-expanded FIXME #23616
+
 #![allow(dead_code)]
+#![feature(core)]
 
 fn foo<'a,'b>(v1: Vec<&'a i32>, v2: Vec<&'b i32>) -> i32 {
     bar(v1, v2).cloned().unwrap_or(0) // only type checks if we can intersect 'a and 'b
index 16dca2db396e7f716d3f13ef35fa5baf1c7eca92..18987d1e016b1fa6a1a7f9d9212d34bf952447a6 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // pp-exact - Make sure we actually print the attributes
+// pretty-expanded FIXME #23616
+
 #![feature(custom_attribute)]
 
 enum crew_of_enterprise_d {
index e078fa1485d14978fac563396a35283ea35ee889..6961cd4977d969bd73287f691bb850bb032342de 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 enum Foo {
-    Bar { x: int },
-    Baz { y: int }
+    Bar { x: isize },
+    Baz { y: isize }
 }
 
 pub fn main() { }
index 64c4c17386b3253341153b4fff7a0312105d8435..658c35ae8d5ea32047b87a0bea55b530a103901f 100644 (file)
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(collections)]
+
 use std::vec;
 
 pub fn main() {
-    let a: Vec<int> = vec!(1, 2, 3, 4, 5);
-    let b: Vec<int> = vec!(6, 7, 8, 9, 0);
-    let mut v: Vec<int> = a;
+    let a: Vec<isize> = vec!(1, 2, 3, 4, 5);
+    let b: Vec<isize> = vec!(6, 7, 8, 9, 0);
+    let mut v: Vec<isize> = a;
     v.push_all(&b);
     println!("{}", v[9]);
     assert_eq!(v[0], 1);
index 40073c2b742197834e58828d75efab50f125ab63..e88acb3838ba8ecd9ff1562132eebba31bfb9d64 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
 pub fn main() {
     // Tests for indexing into box/& [T; n]
-    let x: [int; 3] = [1, 2, 3];
-    let mut x: Box<[int; 3]> = box x;
+    let x: [isize; 3] = [1, 2, 3];
+    let mut x: Box<[isize; 3]> = box x;
     assert!(x[0] == 1);
     assert!(x[1] == 2);
     assert!(x[2] == 3);
@@ -23,8 +25,8 @@ pub fn main() {
     assert!(x[1] == 45);
     assert!(x[2] == 3);
 
-    let mut x: [int; 3] = [1, 2, 3];
-    let x: &mut [int; 3] = &mut x;
+    let mut x: [isize; 3] = [1, 2, 3];
+    let x: &mut [isize; 3] = &mut x;
     assert!(x[0] == 1);
     assert!(x[1] == 2);
     assert!(x[2] == 3);
index 015baea5fb5fe5f71a19a45a4e7b1907c844f889..4dadf53c772221649a0b5eb8eced2c8f7f9f624c 100644 (file)
@@ -8,20 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::mem::size_of;
 
 pub fn main() {
-    let x: [int; 4] = [1, 2, 3, 4];
+    let x: [isize; 4] = [1, 2, 3, 4];
     assert_eq!(x[0], 1);
     assert_eq!(x[1], 2);
     assert_eq!(x[2], 3);
     assert_eq!(x[3], 4);
 
-    assert_eq!(size_of::<[u8; 4]>(), 4_usize);
+    assert_eq!(size_of::<[u8; 4]>(), 4);
 
     // FIXME #10183
     // FIXME #18069
     //if cfg!(target_pointer_width = "64") {
-    //    assert_eq!(size_of::<[u8; (1 << 32)]>(), (1_usize << 32));
+    //    assert_eq!(size_of::<[u8; (1 << 32)]>(), (1 << 32));
     //}
 }
index b8626b9c8a9d6655820018c0c5c34d2f25a4772a..d5e6a9c4245155bc53eb27fd3d264bb7e288adda 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let mut v = vec!(1);
     v.push(2);
index dec0b3eaa78fbca3085e22bbb3f58810d52c8754..7a8c0739efeb978b792575ecb333649702fae806 100644 (file)
@@ -10,7 +10,7 @@
 
 
 pub fn main() {
-    let mut later: Vec<int> ;
+    let mut later: Vec<isize> ;
     if true { later = vec!(1); } else { later = vec!(2); }
     println!("{}", later[0]);
 }
index 47b87fce2abaf7b6d0669241a75ad48902178a73..948fe28cc621adf1c467f373ef80a4ee17f24ef4 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, start, no_std)]
+// pretty-expanded FIXME #23616
+
+#![feature(lang_items, start, no_std, core, libc, collections)]
 #![no_std]
 
-extern crate "std" as other;
+extern crate std as other;
 
 #[macro_use]
 extern crate core;
@@ -27,7 +29,7 @@ use collections::vec::Vec;
 // Issue #16806
 
 #[start]
-fn start(_argc: int, _argv: *const *const u8) -> int {
+fn start(_argc: isize, _argv: *const *const u8) -> isize {
     let x: Vec<u8> = vec![0, 1, 2];
     match x.last() {
         Some(&2) => (),
index 76e7b92ea046b1ae957db05dae51bd9a77c42bdf..2a83ccaba82e29f5e261f4b5edfad802fcbf2a06 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     assert_eq!(vec![1; 3], vec![1, 1, 1]);
     assert_eq!(vec![1; 2], vec![1, 1]);
index 68dedfc6a2e63084faf3f7a8f50935268901fc1e..5869558eacaffb2d88e06399457f1556733cba27 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 fn one() -> i32 { 1 }
 
 // Make sure the vec![...] macro doesn't introduce hidden rvalue
index 5d1f43fb230ed52ce67c17fbe755fd3863863f21..cccf807572a4246c61d22b7e4b25d4a44c725c9b 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 macro_rules! vec [
     ($($e:expr),*) => ({
         let mut _temp = ::std::vec::Vec::new();
index 07033d60497477c51630ba9f1ca231ae991cae53..3018a746b4a9db46c9ce44d83678f022f366184c 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     assert_eq!(vec!(1), vec!(1,));
     assert_eq!(vec!(1, 2, 3), vec!(1, 2, 3,));
index 4ed73dc230181260345c97ab004902244f7955c5..2b80ad81037f216710a5fc691287b2b7c6bd204d 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(slice_patterns)]
+
 pub fn main() {
     let x = [1, 2, 3];
     match x {
index 6ef1dc4ea26349a440d725c7258fb7b8b43ed0e1..1278eaf96a48c015c9b205352141bd7c794219ea 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(advanced_slice_patterns)]
+#![feature(slice_patterns)]
 
 fn a() {
     let x = [1, 2, 3];
index e72170cb7303c2c4294545242d5c8de60620a231..c375fc85bc1d35865cb251c0f6c5d8d3bd9af496 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(advanced_slice_patterns)]
+#![feature(slice_patterns)]
 
 fn foldl<T, U, F>(values: &[T],
                   initial: U,
index 64309906156ae8867db2120cde95e05a81a5c022..e7553c8e157e3ce3ba99771069d8d0fac65a472c 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(slice_patterns)]
+
 pub fn main() {
     let x = &[1, 2, 3, 4, 5];
-    let x: &[int] = &[1, 2, 3, 4, 5];
+    let x: &[isize] = &[1, 2, 3, 4, 5];
     if !x.is_empty() {
         let el = match x {
             [1, ref tail..] => &tail[0],
index 8dcf4612f47eb58403ea1638ff672a59c02ecb50..b81bdda613f7ccc07d486b502d5cc04ce9029e02 100644 (file)
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(advanced_slice_patterns)]
+#![feature(slice_patterns)]
 
 fn a() {
     let x = [1];
@@ -74,7 +77,7 @@ fn d() {
 }
 
 fn e() {
-    let x: &[int] = &[1, 2, 3];
+    let x: &[isize] = &[1, 2, 3];
     match x {
         [1, 2] => (),
         [..] => ()
index 33f01c5bd41c8b3bf37bd3645c3b5bcfa78c97b5..b69bd53cb8c4d739ce13d37ae15ed83fa622d9a1 100644 (file)
@@ -8,4 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() { let mut v = vec!(1, 2, 3); v.push(1); }
index 22ca6c37a8e6ca9c85d550827898655534e072ac..a6ca02d4fa90d5c065e2ca93184184119dce7841 100644 (file)
@@ -8,4 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub fn main() { let _a = [0; 1 as uint]; }
+// pretty-expanded FIXME #23616
+
+pub fn main() { let _a = [0; 1 as usize]; }
index 498ec0e8fbaf1ae8974bea837a057c763bd8ae43..1d749d4963c5eb5eb9c601c602c34347912ed65d 100644 (file)
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_destructor)]
 
 use std::cell::Cell;
 
 // Make sure that destructors get run on slice literals
 struct foo<'a> {
-    x: &'a Cell<int>,
+    x: &'a Cell<isize>,
 }
 
 #[unsafe_destructor]
@@ -24,7 +26,7 @@ impl<'a> Drop for foo<'a> {
     }
 }
 
-fn foo(x: &Cell<int>) -> foo {
+fn foo(x: &Cell<isize>) -> foo {
     foo {
         x: x
     }
index 5375e54e27f262bd5c1664fa1d966a37bb24613c..6baeb99df9e8cebfdbb79732e8090ecdb27bdc67 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let  v = vec![1,2,3,4,5];
     let v2 = &v[1..3];
index 401d629c3821b1e5aa66659d782c614a823c5702..091e3f03e7ac7dabfae546407a66f55bcbe1fa6b 100644 (file)
@@ -9,6 +9,10 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
+#![feature(slice_patterns)]
+
 struct Foo {
     string: String
 }
index 5d132b2a7491f5accbda5b34bb0c9577405052d0..a9bb68395c425b422b8a523c829d999db51ead83 100644 (file)
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     assert_eq!(format!("{:?}", vec!(0, 1)), "[0, 1]".to_string());
 
     let foo = vec!(3, 4);
-    let bar: &[int] = &[4, 5];
+    let bar: &[isize] = &[4, 5];
 
     assert_eq!(format!("{:?}", foo), "[3, 4]");
     assert_eq!(format!("{:?}", bar), "[4, 5]");
index 5e19868de1ddde2f933eca2c3b1f9209e34a63b4..ce20d452c403c126200777b8476eb31bd6d0d0cf 100644 (file)
@@ -9,11 +9,13 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
-    let v: Vec<int> = vec!(10, 20);
+    let v: Vec<isize> = vec!(10, 20);
     assert_eq!(v[0], 10);
     assert_eq!(v[1], 20);
-    let mut x: uint = 0;
+    let mut x: usize = 0;
     assert_eq!(v[x], 10);
     assert_eq!(v[x + 1], 20);
     x = x + 1;
index 6391893b9a4845c09475c4608965466935163ec4..10f71b3e12c251d34779a61edf10eedbbbe4ca1e 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-pub fn main() { let _quux: Box<Vec<uint>> = box Vec::new(); }
+pub fn main() { let _quux: Box<Vec<usize>> = box Vec::new(); }
index 08d39e58b7ce292c2b849b8c809a226a470dfc00..09ecdf45b939e3d4636a0f2eb6191f633c449381 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(rand, core)]
+
 use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 use std::rand::{thread_rng, Rng, Rand};
 use std::thread;
@@ -53,7 +57,7 @@ impl Drop for DropCounter {
 }
 
 pub fn main() {
-    assert!(MAX_LEN <= std::usize::BITS);
+    assert!(MAX_LEN <= std::usize::BITS as usize);
     // len can't go above 64.
     for len in 2..MAX_LEN {
         for _ in 0..REPEATS {
index 46e93b25697bbaa00be5edb94145c3cd24d62e0f..4aa0867ae478e4edd314f090d614815199ed7633 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(visible_private_types)]
 
 trait Foo { fn dummy(&self) { } }
@@ -19,4 +21,3 @@ struct Baz;
 pub fn f(_: Baz) {}
 
 fn main() {}
-
index dcbecb859e53720eaee053499769b03c0fa66447..079c97013abeec7953259b1c36b296f9581f78d9 100644 (file)
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(libc, old_io)]
+
 extern crate libc;
 
 use std::old_io::process::Command;
index 73121918259a73543379ebc7294f97ea8d69edc8..81a3c94eec3137fd612863539d7f595f6268cf45 100644 (file)
 
 // compile-flags:-D improper-ctypes
 
+// pretty-expanded FIXME #23616
+
 #![allow(improper_ctypes)]
 
 mod libc {
     extern {
-        pub fn malloc(size: int) -> *const u8;
+        pub fn malloc(size: isize) -> *const u8;
     }
 }
 
index 741e8be02f72c4250d9bfad06ba6d8ac3c797bd7..5a567758bf45f673b0e8dba0e8e7cb8a730ea58c 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:weak-lang-items.rs
 
-extern crate "weak-lang-items" as other;
+// pretty-expanded FIXME #23616
+
+extern crate weak_lang_items as other;
 
 use std::thread;
 
index baea1b8826a470214fcae45cadfac80ae7e217b3..b28760e6c91fb2977f1dd2e1be697d49a842411f 100644 (file)
@@ -54,18 +54,18 @@ fn zombiejesus() {
 }
 
 fn notsure() {
-    let mut _x: int;
+    let mut _x: isize;
     let mut _y = (_x = 0) == (_x = 0);
     let mut _z = (_x = 0) < (_x = 0);
     let _a = (_x += 0) == (_x = 0);
     let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z);
 }
 
-fn canttouchthis() -> uint {
+fn canttouchthis() -> usize {
     fn p() -> bool { true }
     let _a = (assert!((true)) == (assert!(p())));
     let _c = (assert!((p())) == ());
-    let _b: bool = (println!("{}", 0) == (return 0_usize));
+    let _b: bool = (println!("{}", 0) == (return 0));
 }
 
 fn angrydome() {
index 256b199d7292059d510575220494fc4f5101ad85..cdb5e3fe1d4ae59e4d23d427eb31252985281b71 100644 (file)
 // Test that the `wf` checker properly handles bound regions in object
 // types. Compiling this code used to trigger an ICE.
 
+// pretty-expanded FIXME #23616
+
 pub struct Context<'tcx> {
-    vec: &'tcx Vec<int>
+    vec: &'tcx Vec<isize>
 }
 
-pub type Cmd<'a> = &'a int;
+pub type Cmd<'a> = &'a isize;
 
 pub type DecodeInlinedItem<'a> =
-    Box<for<'tcx> FnMut(Cmd, &Context<'tcx>) -> Result<&'tcx int, ()> + 'a>;
+    Box<for<'tcx> FnMut(Cmd, &Context<'tcx>) -> Result<&'tcx isize, ()> + 'a>;
 
 fn foo(d: DecodeInlinedItem) {
 }
index 3374f47ed5f80b8908b395b106a5cdc803fc467c..d4823b8a33cc505be84c250e885fe97c53425810 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Bound {
     fn dummy(&self) { }
 }
index 4a149d4d3df44ed8050e5205dc1fcb90f682bdf8..b9f605ec548bc7fd29aa9e5dc50a9775be3e1bb0 100644 (file)
@@ -8,16 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait TheTrait { fn dummy(&self) { } }
 
-impl TheTrait for &'static int { }
+impl TheTrait for &'static isize { }
 
 fn foo<'a,T>(_: &'a T) where &'a T : TheTrait { }
 
 fn bar<T>(_: &'static T) where &'static T : TheTrait { }
 
 fn main() {
-    static x: int = 1;
+    static x: isize = 1;
     foo(&x);
     bar(&x);
 }
index ecc210ea579dbccb8d61f5c0d550f87e3f1c2ba9..d7aaa0b2f9ca34bfb3b9473aadf5a36e054647ba 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 trait Foo<T> { fn dummy(&self, arg: T) { } }
 
 trait Bar<A> {
@@ -27,4 +29,3 @@ impl Bar<X> for i32 {
 fn main() {
     1.method::<S>();
 }
-
index aa39325277e7c0c736fb2ac1b3b193f8f1a87d35..60df52bfeb922edbfc9320921e01bbedd997ad5a 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct A<'a, 'b> where 'a : 'b { x: &'a int, y: &'b int }
+// pretty-expanded FIXME #23616
+
+struct A<'a, 'b> where 'a : 'b { x: &'a isize, y: &'b isize }
 
 fn main() {
     let x = 1;
index b822abd67329e8da10be943633b355c0c9a58b95..1b349b25ef3c519b146af69508cad5feb3334c7d 100644 (file)
@@ -18,6 +18,5 @@ fn main() {
     println!("{}", equal(&1, &2));
     println!("{}", equal(&1, &1));
     println!("{}", "hello".equal(&"hello"));
-    println!("{}", "hello".equals::<int,&str>(&1, &1, &"foo", &"bar"));
+    println!("{}", "hello".equals::<isize,&str>(&1, &1, &"foo", &"bar"));
 }
-
index e3ea7cd80e78d04027ef9ec7f6917e26df5f3a10..bba20e8e92e666152e00466d72eb0ba24fb73c82 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo<'a, I>(mut it: I) where I: Iterator<Item=&'a int> {}
+// pretty-expanded FIXME #23616
+
+fn foo<'a, I>(mut it: I) where I: Iterator<Item=&'a isize> {}
 
 fn main() {
     foo([1, 2].iter());
index 7edcdf6429223d960d5c09df113f4e1b259e8c74..c509cbe2a5e99a0862573b2975caa79fa77aa93e 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unboxed_closures)]
 
 struct Bencher;
@@ -23,4 +25,3 @@ fn main() {
     // OK
     warm_up(|b| () );
 }
-
index 92bc7edf285643537af0746670566c3b6b42125d..ab1f30c3d14287f58cef9a0b8f67fa9ab5df5649 100644 (file)
@@ -32,6 +32,5 @@ fn main() {
     println!("{}", equal(&1, &2));
     println!("{}", equal(&1, &1));
     println!("{}", "hello".equal(&"hello"));
-    println!("{}", "hello".equals::<int,&str>(&1, &1, &"foo", &"bar"));
+    println!("{}", "hello".equals::<isize,&str>(&1, &1, &"foo", &"bar"));
 }
-
index 1fd223b0dd3f6bd8c8d8ffaa83bd6a59ee8d3370..8535d76d4714c08f0fd55b8c923bf84b1ac99a50 100644 (file)
@@ -11,6 +11,8 @@
 // Test that we can quantify lifetimes outside a constraint (i.e., including
 // the self type) in a where clause.
 
+// pretty-expanded FIXME #23616
+
 use std::marker::PhantomFn;
 
 static mut COUNT: u32 = 1;
@@ -55,11 +57,10 @@ fn foo2<T>(x: &T)
 }
 
 fn main() {
-    let x = 42u32;
+    let x = 42;
     foo1(&x);
     foo2(&x);
     unsafe {
         assert!(COUNT == 12);
     }
 }
-
index 8239afb3594d6289ff9f0c292098b58e9f5e0171..102a5a7558e0c8c7c5f65b191029d553154257fd 100644 (file)
@@ -10,4 +10,6 @@
 
 
 
-pub fn main() { let x: int = 10; while x == 10 && x == 11 { let _y = 0xf00_usize; } }
+// pretty-expanded FIXME #23616
+
+pub fn main() { let x: isize = 10; while x == 10 && x == 11 { let _y = 0xf00_usize; } }
index 4a3cd115d20433c14482242e437de008af429cb1..076ba8f428f061dcb2201183fcea709228ab6b3c 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 
+// pretty-expanded FIXME #23616
+
 pub fn main() {
     let mut i = 100;
     'w: while 1 + 1 == 2 {
index 1780445fb3b2d0ce18dcc04a3b931eb3cf28c1de..b1e80c86ec72d7cf9937edd5a995781eea203554 100644 (file)
@@ -8,9 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections)]
+
 use std::collections::BinaryHeap;
 
-fn make_pq() -> BinaryHeap<int> {
+fn make_pq() -> BinaryHeap<isize> {
     BinaryHeap::from_vec(vec![1,2,3])
 }
 
index 622b66d22a1dba495542ef2e1e118f51f5c64d7b..6e3392324753b42e5486755025c550564255c91d 100644 (file)
@@ -12,9 +12,9 @@
 #![allow(unused_variable)]
 
 pub fn main() {
-    let mut y: int = 42;
-    let mut z: int = 42;
-    let mut x: int;
+    let mut y: isize = 42;
+    let mut z: isize = 42;
+    let mut x: isize;
     while z < 50 {
         z += 1;
         while false { x = y; y = z; }
index bfabcb4d87b562df318e59bf34e14076baf277cf..88d5314a96ac59a1cf8e5e7dcff1082c9c31a45a 100644 (file)
@@ -8,12 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(collections)]
+
 use std::string::String;
 
 #[derive(PartialEq)]
 enum t { a, b(String), }
 
-fn make(i: int) -> t {
+fn make(i: isize) -> t {
     if i > 10 { return t::a; }
     let mut s = String::from_str("hello");
     // Ensure s is non-const.
index a7328267541ab9b7c47bef68edbf3a7b5b7ef106..ed149ad5109db8631e1c3c4e8cad349f04b695a4 100644 (file)
 
 
 pub fn main() {
-    let mut i: int = 90;
+    let mut i: isize = 90;
     while i < 100 {
         println!("{}", i);
         i = i + 1;
         if i == 95 {
-            let _v: Vec<int> =
+            let _v: Vec<isize> =
                 vec!(1, 2, 3, 4, 5); // we check that it is freed by break
 
             println!("breaking");
index bd8b1f0f088ab231465e0132d08171fc7b917993..bf56e76687fa5b98d629f05626cee312af7ecdc7 100644 (file)
@@ -11,8 +11,8 @@
 
 
 pub fn main() {
-    let mut x: int = 10;
-    let mut y: int = 0;
+    let mut x: isize = 10;
+    let mut y: isize = 0;
     while y < x { println!("{}", y); println!("hello"); y = y + 1; }
     while x > 0 {
         println!("goodbye");
index dacfeb0081925ab0bcd6d4fc617cc60c70d0a53f..10718e981ff59685f761b97067049b4a45219fb3 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 use std::sync::Mutex;
 
-struct Point {x: int, y: int, z: int}
+struct Point {x: isize, y: isize, z: isize}
 
 fn f(p: &mut Point) { p.z = 13; }
 
index 5dd0a5522c639b4feee382f758cd4f0ed1bcfcd3..b0bfb5c29c18c9b48ad736d0a2a07fc72bd746bc 100644 (file)
@@ -13,8 +13,8 @@
 #[cfg(windows)]
 mod kernel32 {
   extern "system" {
-    pub fn SetLastError(err: uint);
-    pub fn GetLastError() -> uint;
+    pub fn SetLastError(err: usize);
+    pub fn GetLastError() -> usize;
   }
 }
 
@@ -22,7 +22,7 @@ mod kernel32 {
 #[cfg(windows)]
 pub fn main() {
     unsafe {
-        let expected = 1234_usize;
+        let expected = 1234;
         kernel32::SetLastError(expected);
         let actual = kernel32::GetLastError();
         println!("actual = {}", actual);
@@ -34,6 +34,7 @@ pub fn main() {
           target_os = "linux",
           target_os = "freebsd",
           target_os = "dragonfly",
+          target_os = "bitrig",
           target_os = "openbsd",
           target_os = "android"))]
 pub fn main() { }
index 86c1ae0f51fd9c51ee0350d24cf010024b03b214..7b15531dacc33f45c5f6cb5d56ddda2d372c93aa 100644 (file)
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 pub type HANDLE = u32;
 pub type DWORD = u32;
 pub type SIZE_T = u32;
-pub type LPVOID = uint;
+pub type LPVOID = usize;
 pub type BOOL = u8;
 
 #[cfg(windows)]
@@ -30,10 +32,10 @@ mod kernel32 {
 #[cfg(windows)]
 pub fn main() {
     let heap = unsafe { kernel32::GetProcessHeap() };
-    let mem = unsafe { kernel32::HeapAlloc(heap, 0u32, 100u32) };
-    assert!(mem != 0_usize);
-    let res = unsafe { kernel32::HeapFree(heap, 0u32, mem) };
-    assert!(res != 0u8);
+    let mem = unsafe { kernel32::HeapAlloc(heap, 0, 100) };
+    assert!(mem != 0);
+    let res = unsafe { kernel32::HeapFree(heap, 0, mem) };
+    assert!(res != 0);
 }
 
 #[cfg(not(windows))]
index 236ff0838e59097ef1ebb27c111e9458d5d4ecb5..ac8b15d7bf58990e883430fa4e3d2facf7361acc 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:xcrate_address_insignificant.rs
 
-extern crate "xcrate_address_insignificant" as foo;
+// pretty-expanded FIXME #23616
+
+extern crate xcrate_address_insignificant as foo;
 
 pub fn main() {
     assert_eq!(foo::foo::<f64>(), foo::bar());
index 6afa02fce55149a45552a0953c317d684b9fe5d4..43bae9c7ce0725fb3961cd5189b48326ddebf3ca 100644 (file)
@@ -10,6 +10,8 @@
 
 // aux-build:xcrate_static_addresses.rs
 
+// pretty-expanded FIXME #23616
+
 extern crate xcrate_static_addresses;
 
 use xcrate_static_addresses as other;
index aa61237417e9e67d5030cb1be53be43577ea34df..62d62839ba31bc89b1d95492ad9ae3526111b8a3 100644 (file)
@@ -10,7 +10,9 @@
 
 // aux-build:xcrate-trait-lifetime-param.rs
 
-extern crate "xcrate-trait-lifetime-param" as other;
+// pretty-expanded FIXME #23616
+
+extern crate xcrate_trait_lifetime_param as other;
 
 struct Reader<'a> {
     b : &'a [u8]
index 30b5f47b2ae2e30e166affded3ab62a561fb4c61..78e92053a11204fec992e0e23ba5646c49415880 100644 (file)
@@ -9,6 +9,8 @@
 // except according to those terms.
 
 // aux-build:xcrate_unit_struct.rs
+// pretty-expanded FIXME #23616
+
 extern crate xcrate_unit_struct;
 
 const s1: xcrate_unit_struct::Struct = xcrate_unit_struct::Struct;
index 56dc02c6d2e673beab5235236d77d3aa08bf3fc4..acc55833133a33073c8cb582b87af892749ca289 100644 (file)
@@ -11,6 +11,6 @@
 use std::thread;
 
 pub fn main() {
-    let mut i: int = 0;
+    let mut i: isize = 0;
     while i < 100 { i = i + 1; println!("{}", i); thread::yield_now(); }
 }
index f4d03a5cda400aa603017f7d5d7b22daab2e97a2..dea9edf0582bd928d72214b3c6637e77919973e0 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
 #![feature(unsafe_no_drop_flag)]
 
-static mut destructions : int = 3;
+static mut destructions : isize = 3;
 
 pub fn foo() {
     #[unsafe_no_drop_flag]
index 65882d39375c3f0f7638081205ac594b6712c109..b98f907774b97984dc79f628254b3f58c6b55ddb 100644 (file)
@@ -8,12 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// pretty-expanded FIXME #23616
+
+#![feature(slice_patterns)]
+
 fn main() {
     let x = [(), ()];
 
     // The subslice used to go out of bounds for zero-sized array items, check that this doesn't
     // happen anymore
     match x {
-        [_, y..] => assert_eq!(&x[1] as *const _, &y[0] as *const _)
+        [_, y..] => assert_eq!(&x[1] as *const (), &y[0] as *const ())
     }
 }